Exemple #1
0
def load_cip_data(cip_15_file, cip_100_file, core_file, start_time, end_time,
                  reference):
    """
    Load CIP data into xarray.Dataset.

    This function loads and combines the data from the CIP15 and CIP100
    imaging probes into an 'xarray.Datset'.

    Args:
        cip_15_file: Path pointing to the file containing the CIP15 data.
        cip_100_file: Path pointing to the file containing the CIP100 data.
        core_file: Path pointing to the file containing the core data.
        start_time: Start time of the time period for which to extract the data.
        end_time: End time of the time period for which to extract the data.

    Return:
        An xarray.Dataset containing the combined CIP data.
    """
    cip_15 = xr.load_dataset(cip_15_file, decode_times=False)

    time = pd.Timestamp(start_time)
    year = time.year
    month = time.month
    day = time.day
    time_0 = np.datetime64(f"{year}-{month:02}-{day}T00:00:00")
    time = time_0 + cip_15["TIME"].data * np.timedelta64(1, "s")

    j_start = np.where(time > start_time)[0][0]
    j_end = np.where(time > end_time)[0][0]
    time = time[j_start:j_end]

    core = xr.load_dataset(core_file, decode_times=False)

    cip_15 = cip_15[{"TIME": slice(j_start, j_end)}]
    core = core.interp(Time=cip_15["TIME"])
    altitude = core["ALT_GIN"]
    latitude = core["LAT_GIN"]
    longitude = core["LON_GIN"]

    bins = cip_15["BIN_EDGES"][:] / 1e6
    x_15 = 0.5 * (bins[1:] + bins[:-1])
    n_15 = cip_15["SPEC"][:] * 1e6
    dndd_15 = n_15 / (np.diff(bins).reshape(-1, 1))

    cip_100 = xr.load_dataset(cip_100_file, decode_times=False)
    cip_100 = cip_100[{"TIME": slice(j_start, j_end)}]

    bins = cip_100["BIN_EDGES"][:] / 1e6
    x_100 = 0.5 * (bins[1:] + bins[:-1])
    n_100 = cip_100["SPEC"][:] * 1e6
    dndd_100 = n_100 / (np.diff(bins).reshape(-1, 1))

    start_15, end_15 = 0, 64
    start_100, end_100 = 9, 64
    x = np.concatenate([x_15[start_15:end_15], x_100[start_100:end_100]])
    y = np.concatenate([dndd_15[start_15:end_15], dndd_100[start_100:end_100]])
    n = np.concatenate([n_15[start_15:end_15], n_100[start_100:end_100]])

    data = {
        "time": (("time", ), time),
        "diameter": (("diameter", ), x),
        "dndd": (
            (
                "time",
                "diameter",
            ),
            y.T,
        ),
        "n": (
            (
                "time",
                "diameter",
            ),
            n.T,
        ),
        "altitude": (("time", ), altitude.data),
        "latitude": (("time", ), latitude.data),
        "longitude": (("time", ), longitude.data),
    }

    if reference:
        lons = reference["longitude"].data
        lats = reference["latitude"].data
        d = reference["d"].data
        reference_swath = geometry.SwathDefinition(lons=lons, lats=lats)
        cip_swath = geometry.SwathDefinition(lons=longitude, lats=latitude)
        d = kd_tree.resample_nearest(reference_swath,
                                     d,
                                     cip_swath,
                                     10e3,
                                     fill_value=np.nan)

    data["d"] = (("time", ), d)

    return xr.Dataset(data)
def srtm15plus_reproject(dct=None, gatts=None, sea_level=0):
    import os
    from pyproj import Proj
    import pyproj

    import acolite as ac
    import numpy as np
    from pyresample.bilinear import NumpyBilinearResampler
    from pyresample import geometry

    if dct is None:
        if gatts is None:
            print('No dct or gatts given.')
            return ()
        dct = {}
        dct['xrange'] = gatts['xrange']
        dct['yrange'] = gatts['yrange']
        dct['pixel_size'] = gatts['pixel_size']
        dct['xdim'] = (dct['xrange'][1] -
                       dct['xrange'][0]) / dct['pixel_size'][0]
        dct['ydim'] = (dct['yrange'][1] -
                       dct['yrange'][0]) / dct['pixel_size'][1]
        dct['p'] = pyproj.Proj(gatts['proj4_string'])

    file = '/Volumes/SSD/Data/Bathymetry/SRTM15_V2.3.nc'

    #dct = {'xrange': xrange, 'yrange': yrange, 'p': p,
    #       'pixel_size': target_pixel_size, 'xdim': nx, 'ydim': ny}
    #nc_projection = ac.shared.projection_netcdf(dct, add_half_pixel=True)

    xrange = dct['xrange']
    yrange = dct['yrange']
    nx = dct['xdim']
    ny = dct['ydim']
    projection = dct['p'].srs

    l_ = dct['p'](xrange, yrange, inverse=True)
    limit = l_[1][1], l_[0][0], l_[1][0], l_[0][1]

    ## set up target definition
    target_definition = geometry.AreaDefinition(
        'area_id', 'description', 'proj_id', projection, nx, ny,
        [xrange[0], yrange[1], xrange[1], yrange[0]])

    ## read lat/lon
    lat = ac.shared.nc_data(file, 'lat')
    lon = ac.shared.nc_data(file, 'lon')

    lonoff = 0.25
    latoff = 0.25
    sublon = np.where((lon >= limit[1] - lonoff) & (lon <= limit[3] + lonoff))
    sublat = np.where((lat >= limit[0] - latoff) & (lat <= limit[2] + latoff))

    sub = [
        sublon[0][0], sublat[0][0], sublon[0][-1] - sublon[0][0] + 1,
        sublat[0][-1] - sublat[0][0] + 1
    ]

    yi = lat[sublat].shape[0]
    xi = lon[sublon].shape[0]

    lons = np.tile(lon[sublon], yi).reshape(yi, xi)
    lats = np.rot90(np.tile(lat[sublat], xi).reshape(xi, yi))

    ## set up source definition
    source_definition = geometry.SwathDefinition(lons=lons, lats=lats)

    ## set up resampler
    resampler = NumpyBilinearResampler(source_definition, target_definition,
                                       30e3)

    zin, zatt = ac.shared.nc_data(file, 'z', attributes=True, sub=sub)
    zin = np.flipud(zin)

    zout = resampler.resample(zin)
    if sea_level is not None:
        zout[zout <= sea_level] = 0

    return (zout)
Exemple #3
0
def load_drop_sonde_data(path, results=None):

    data = []
    files = Path(PATH).glob("faam-dropsonde*.nc")

    for f in files:
        ds_data = xr.load_dataset(f)

        valid = (-90 <= ds_data["lat"].data) * (90 >= ds_data["lat"].data)
        ds_data = ds_data.loc[{"time": valid}]

        if results:
            lons = results["longitude"].data
            lats = results["latitude"].data
            retrieval_swath = geometry.SwathDefinition(lons=lons, lats=lats)
            lons = ds_data["lon"].data
            lats = ds_data["lat"].data
            ds_swath = geometry.SwathDefinition(lons=lons, lats=lats)
            ni = kd_tree.get_neighbour_info(retrieval_swath,
                                            ds_swath,
                                            radius_of_influence=100e3,
                                            neighbours=1)
            (valid_input_index, valid_output_index, index_array,
             distance_array) = ni

            n = ds_data.time.size
            n_levels = results.z.size

            t_r = np.zeros(n)
            t_a = np.zeros(n)
            h2o_r = np.zeros(n)
            h2o_a = np.zeros(n)

            t_z = np.zeros((n, n_levels))
            t_a_z = np.zeros((n, n_levels))
            h2o_z = np.zeros((n, n_levels))
            h2o_a_z = np.zeros((n, n_levels))
            z = np.zeros((n, n_levels))
            d = np.zeros((n))

            lats_r = kd_tree.get_sample_from_neighbour_info(
                "nn",
                (n, ),
                results["latitude"].data,
                valid_input_index,
                valid_output_index,
                index_array,
                fill_value=np.nan,
            )
            lons_r = kd_tree.get_sample_from_neighbour_info(
                "nn",
                (n, ),
                results["longitude"].data,
                valid_input_index,
                valid_output_index,
                index_array,
                fill_value=np.nan,
            )

            d = kd_tree.get_sample_from_neighbour_info(
                "nn",
                (n, ),
                results["d"].data,
                valid_input_index,
                valid_output_index,
                index_array,
                fill_value=np.nan,
            )

            for i in range(n_levels):
                # t_z[:, i] = kd_tree.get_sample_from_neighbour_info(
                #    "nn",
                #    (n,),
                #    results["temperature"][:, i].data,
                #    valid_input_index,
                #    valid_output_index,
                #    index_array,
                #    fill_value=np.nan)
                # t_a_z[:, i] = kd_tree.get_sample_from_neighbour_info(
                #    "nn",
                #    (n,),
                #    results["temperature_a_priori"][:, i].data,
                #    valid_input_index,
                #    valid_output_index,
                #    index_array,
                #    fill_value=np.nan)
                h2o_z[:, i] = kd_tree.get_sample_from_neighbour_info(
                    "nn",
                    (n, ),
                    results["H2O"][:, i].data,
                    valid_input_index,
                    valid_output_index,
                    index_array,
                    fill_value=np.nan,
                )
                h2o_a_z[:, i] = kd_tree.get_sample_from_neighbour_info(
                    "nn",
                    (n, ),
                    results["H2O_a_priori"][:, i].data,
                    valid_input_index,
                    valid_output_index,
                    index_array,
                    fill_value=np.nan,
                )
                z[:, i] = kd_tree.get_sample_from_neighbour_info(
                    "nn",
                    (n, ),
                    results["altitude"][:, i].data,
                    valid_input_index,
                    valid_output_index,
                    index_array,
                    fill_value=np.nan,
                )

            for i in range(n):
                if np.isnan(ds_data["alt"][i]):
                    t_r[i] = np.nan
                    t_a[i] = np.nan
                    h2o_r[i] = np.nan
                    h2o_a[i] = np.nan
                    continue

                t_r[i] = np.interp(ds_data["alt"][i], z[i, :], t_z[i, :])
                t_a[i] = np.interp(ds_data["alt"][i], z[i, :], t_a_z[i, :])
                h2o_r[i] = np.interp(ds_data["alt"][i], z[i, :], h2o_z[i, :])
                h2o_a[i] = np.interp(ds_data["alt"][i], z[i, :], h2o_a_z[i, :])

            ds_data["t_retrieved"] = (("time", ), t_r)
            ds_data["t_a_priori"] = (("time", ), t_a)
            ds_data["h2o_retrieved"] = (("time", ), h2o_r)
            ds_data["h2o_a_priori"] = (("time", ), h2o_a)
            ds_data["lons_r"] = (("time"), lons_r)
            ds_data["lats_r"] = (("time"), lats_r)
            ds_data["d"] = (("time"), d)
        data.append(ds_data)
    return data
Exemple #4
0
                #: Create pyresample area_def object for resampling
                area_def = prg.AreaDefinition(
                    'orthographic',
                    'orthographic',
                    'orthographic',
                    projection=crs.proj4_params,
                    width=lons.shape[1],
                    height=lons.shape[0],
                    area_extent=(crs.x_limits[0] * zoom_val,
                                 crs.y_limits[0] * zoom_val,
                                 crs.x_limits[1] * zoom_val,
                                 crs.y_limits[1] * zoom_val))

                # Remap to crs projection
                swath_def = prg.SwathDefinition(lons=lons, lats=lats)
                result3 = resample_nearest(swath_def,
                                           data3,
                                           area_def,
                                           radius_of_influence=lons.shape[0] *
                                           lons.shape[1] * 2.5,
                                           fill_value=None)
                result2 = resample_nearest(swath_def,
                                           data2,
                                           area_def,
                                           radius_of_influence=lons.shape[0] *
                                           lons.shape[1] * 2.5,
                                           fill_value=None)
                resultd = resample_nearest(swath_def,
                                           datad,
                                           area_def,
Exemple #5
0
    def load_dataset(self, satscene, filename=None, *args, **kwargs):
        """Read data from file and load it into *satscene*.
        """
        del args
        conf = ConfigParser()
        conf.read(os.path.join(CONFIG_PATH, satscene.fullname + ".cfg"))
        options = dict(conf.items(satscene.instrument_name + "-level2",
                                  raw=True))
        options["resolution"] = 1000
        options["geofile"] = os.path.join(options["dir"], options["geofile"])
        options.update(kwargs)

        fparser = Parser(options.get("filename"))
        gparser = Parser(options.get("geofile"))

        if isinstance(filename, (list, set, tuple)):
            # we got the entire dataset.
            for fname in filename:
                if fnmatch(os.path.basename(fname), fparser.globify()):
                    metadata = fparser.parse(os.path.basename(fname))
                    resolution = self.res[metadata["resolution"]]
                    self.datafiles[resolution] = fname
                elif fnmatch(os.path.basename(fname), gparser.globify()):
                    self.geofile = fname
        elif ((filename is not None) and
              fnmatch(os.path.basename(options["filename"]), fparser.globify())):
            # read just one file
            logger.debug("Reading from file: " + str(options["filename"]))
            filename = options["filename"]
            resolution = self.res[os.path.basename(filename)[5]]
            self.datafiles[resolution] = filename
        if not self.datafiles:
            # find files according to config
            logger.debug(
                "Didn't get any valid file as input, looking in defined places")
            resolution = int(options["resolution"]) or 1000

            for res in [250, 500, 1000]:
                datafile = globify(os.path.join(options['dir'],
                                                options["filename"]),
                                   {'resolution': self.inv_res[res],
                                    'start_time': satscene.time_slot})
                try:
                    self.datafiles[res] = check_filename(datafile)
                except IOError:
                    self.datafiles[res] = None
                    logger.warning("Can't find file for resolution %s with template: %s",
                                   str(res), datafile)

            try:
                self.geofile = check_filename(globify(options["geofile"],
                                                      {'start_time': satscene.time_slot}))
            except IOError:
                self.geofile = None
                logger.warning("Can't find geofile with template: %s",
                               options['geofile'])

        resolution = options["resolution"]
        cores = options.get("cores", max(multiprocessing.cpu_count() / 4, 1))

        datadict = {
            1000: ['EV_250_Aggr1km_RefSB',
                   'EV_500_Aggr1km_RefSB',
                   'EV_1KM_RefSB',
                   'EV_1KM_Emissive'],
            500: ['EV_250_Aggr500_RefSB',
                  'EV_500_RefSB'],
            250: ['EV_250_RefSB']}

        loaded_bands = []

        # process by dataset, reflective and emissive datasets separately

        resolutions = [250, 500, 1000]

        for res in resolutions:
            if res < resolution:
                continue
            logger.debug("Working on resolution %d", res)
            self.filename = self.datafiles[res]

            logger.debug("Using " + str(cores) + " cores for interpolation")

            try:
                self.data = SD(str(self.filename))
            except HDF4Error as err:
                logger.warning("Could not load data from " + str(self.filename)
                               + ": " + str(err))
                continue

            datasets = datadict[res]
            for dataset in datasets:
                subdata = self.data.select(dataset)
                band_names = subdata.attributes()["band_names"].split(",")
                if len(satscene.channels_to_load & set(band_names)) > 0:
                    # get the relative indices of the desired channels
                    indices = [i for i, band in enumerate(band_names)
                               if band in satscene.channels_to_load]
                    uncertainty = self.data.select(dataset + "_Uncert_Indexes")
                    if dataset.endswith('Emissive'):
                        array = calibrate_tb(
                            subdata, uncertainty, indices, band_names)
                    else:
                        array = calibrate_refl(subdata, uncertainty, indices)
                    for (i, idx) in enumerate(indices):
                        if band_names[idx] in loaded_bands:
                            continue
                        satscene[band_names[idx]] = array[i]
                        # fix the resolution to match the loaded data.
                        satscene[band_names[idx]].resolution = res
                        loaded_bands.append(band_names[idx])

        # Get the orbit number
        if not satscene.orbit:
            mda = self.data.attributes()["CoreMetadata.0"]
            orbit_idx = mda.index("ORBITNUMBER")
            satscene.orbit = int(mda[orbit_idx + 111:orbit_idx + 116])

        # Get the geolocation
        # if resolution != 1000:
        #    logger.warning("Cannot load geolocation at this resolution (yet).")
        #    return

        for band_name in loaded_bands:
            lon, lat = self.get_lonlat(
                satscene[band_name].resolution, satscene.time_slot, cores)
            area = geometry.SwathDefinition(lons=lon, lats=lat)
            satscene[band_name].area = area

        # Trimming out dead sensor lines (detectors) on aqua:
        # (in addition channel 21 is noisy)
        if satscene.satname == "aqua":
            for band in ["6", "27", "36"]:
                if not satscene[band].is_loaded() or satscene[band].data.mask.all():
                    continue
                width = satscene[band].data.shape[1]
                height = satscene[band].data.shape[0]
                indices = satscene[band].data.mask.sum(1) < width
                if indices.sum() == height:
                    continue
                satscene[band] = satscene[band].data[indices, :]
                satscene[band].area = geometry.SwathDefinition(
                    lons=satscene[band].area.lons[indices, :],
                    lats=satscene[band].area.lats[indices, :])

        # Trimming out dead sensor lines (detectors) on terra:
        # (in addition channel 27, 30, 34, 35, and 36 are nosiy)
        if satscene.satname == "terra":
            for band in ["29"]:
                if not satscene[band].is_loaded() or satscene[band].data.mask.all():
                    continue
                width = satscene[band].data.shape[1]
                height = satscene[band].data.shape[0]
                indices = satscene[band].data.mask.sum(1) < width
                if indices.sum() == height:
                    continue
                satscene[band] = satscene[band].data[indices, :]
                satscene[band].area = geometry.SwathDefinition(
                    lons=satscene[band].area.lons[indices, :],
                    lats=satscene[band].area.lats[indices, :])

        for band_name in loaded_bands:
            band_uid = hashlib.sha1(satscene[band_name].data.mask).hexdigest()
            satscene[band_name].area.area_id = ("swath_" + satscene.fullname + "_"
                                                + str(satscene.time_slot) + "_"
                                                +
                                                str(satscene[
                                                    band_name].shape) + "_"
                                                + str(band_uid))
            satscene[band_name].area_id = satscene[band_name].area.area_id
Exemple #6
0
def modisl1b_resample(mxd02file, mxd03file, chan_list, fill_value=-99999.):
    """
    given level1b 1km radiance file and geometry file
    return projected images plus supporting data.
    The resampling uses pyresample with a lambert azimuthal
    equal area projection with lat_0 and lon_0 at
    the scene center

    
    Parameters
    ----------

    mxd02file: str
        file name NASA Laadsweb level1b Terra (MOD02) or Aqua (MYD02) hdf file converted to h5
        format

    mxd03file: str
        file name NASA Laadsweb level geometry file for Terra (MOD03) or Aqua (MYD03) hdf file converted to h5 format

    chan_list: vecto of strings
        channels to resample onto lambert azimuthal projections, i.e. ['1','4','3']

    fill_value: float
        number to indicate missing grid data.  Make sure this number is not in the range of actual
        data values

    Returns
    -------

    dictionary with keys/values:

        channels: float32 3-dim array
           projected for each channel radiances (W/m^2/sr/micron for EV channels) or reflectances (no units for RefSB channels)
           dimensions:  [height,width,numchans]

        area_def_args: dict
           dictionary with projection information for pyresample

        basemap_args: dict
           dictionary with projection information for basemap

        geotiff_args: dict
           dictionary with projection information for geotiff

        fill_value: float32
           fill value for missing data in channels (these resampled pixels are set to
           np.nan after resample)
    """
    radiance_list = []
    for the_chan in chan_list:
        #
        # read channel channels
        #
        index = chan_dict[the_chan]['index']
        field_name = chan_dict[the_chan]['field_name']
        scale_name = chan_dict[the_chan]['scale']
        offset_name = chan_dict[the_chan]['offset']

        with h5py.File(mxd02file, 'r') as h5_file:
            chan = h5_file['MODIS_SWATH_Type_L1B']['Data Fields'][field_name][
                index, :, :]
            hdf_fill_value = h5_file['MODIS_SWATH_Type_L1B']['Data Fields'][
                field_name].attrs['_FillValue']
            chan = chan.astype(np.float32)
            #
            # problem with modis fill_value for channel 29 -- says it should be 65535 but it is actually 65531
            # accept anything larger than 60000
            #
            if hdf_fill_value == 65535:
                hit = chan > 65530
            else:
                hit = chan == hdf_fill_value
            chan[hit] = np.nan
            scale = h5_file['MODIS_SWATH_Type_L1B']['Data Fields'][
                field_name].attrs[scale_name][...]
            offset = h5_file['MODIS_SWATH_Type_L1B']['Data Fields'][
                field_name].attrs[offset_name][...]
            chan_calibrated = (chan - offset[index]) * scale[index]
            chan_calibrated = chan_calibrated.astype(
                np.float32)  #convert from 64 bit to 32bit to save space
            print('in e582lib.modis_resample: found {} bad pixels'.format(
                np.sum(np.isnan(chan_calibrated))))
            chan_calibrated = np.ma.masked_invalid(chan_calibrated)
            radiance_list.append(chan_calibrated)
    for index, chan in enumerate(radiance_list):
        print('index and mean {} {}'.format(index, np.mean(chan.ravel())))

    with h5py.File(mxd03file) as geo_file:
        lon_data = geo_file['MODIS_Swath_Type_GEO']['Geolocation Fields'][
            'Longitude'][...]
        lat_data = geo_file['MODIS_Swath_Type_GEO']['Geolocation Fields'][
            'Latitude'][...]
    #
    # set up the lambert azimuthal equal area projection with corners large enough
    # to fit image
    #
    corners = parseMeta(mxd02file)
    proj_id = 'laea'
    datum = 'WGS84'
    lat_0_txt = '{lat_0:5.2f}'.format_map(corners)
    lon_0_txt = '{lon_0:5.2f}'.format_map(corners)
    area_dict = dict(datum=datum,
                     lat_0=lat_0_txt,
                     lon_0=lon_0_txt,
                     proj=proj_id,
                     units='m')
    prj = pyproj.Proj(area_dict)
    x, y = prj(corners['lon_list'], corners['lat_list'])
    minx, maxx = np.min(x), np.max(x)
    miny, maxy = np.min(y), np.max(y)
    #
    # back transform these to lon/lat
    #
    llcrnrlon, llcrnrlat = prj(minx, miny, inverse=True)
    urcrnrlon, urcrnrlat = prj(maxx, maxy, inverse=True)
    #
    # 1300 m pixels are a reasonable compromise between the smallest 1km pixels and the biggest
    # 4 km pixels at the sides of the swath
    #
    area_extent = [minx, miny, maxx, maxy]
    x_pixel = 1.3e3
    y_pixel = 1.3e3
    #
    # figure out how many pixels in the image
    #
    xsize = int((area_extent[2] - area_extent[0]) / x_pixel)
    ysize = int((area_extent[3] - area_extent[1]) / y_pixel)
    #
    #  here's the dictionary we need for basemap
    #
    basemap_args = dict()
    basemap_args['ellps'] = 'WGS84'
    basemap_args['llcrnrlon'] = llcrnrlon
    basemap_args['llcrnrlat'] = llcrnrlat
    basemap_args['urcrnrlon'] = urcrnrlon
    basemap_args['urcrnrlat'] = urcrnrlat
    basemap_args['projection'] = area_dict['proj']
    basemap_args['lat_0'] = corners['lat_0']
    basemap_args['lon_0'] = corners['lon_0']
    #
    #
    # here is the dictionary for pyresample
    #
    area_id = 'granule'
    area_name = 'modis swath 5min granule'
    #
    # here are all the arguments pyresample needs to regrid the swath
    #
    #
    # first copy each of the reprojected channels into input_array,
    # which is dimensioned [height,width,num_chans]
    #
    #  pyresample will resample all num_chans channels onto the same grid
    #
    num_chans = len(chan_list)
    dim_list = list(radiance_list[0].shape)
    dim_list.append(num_chans)
    input_array = np.empty(dim_list, dtype=np.float32)
    for index, chan in enumerate(radiance_list):
        input_array[:, :, index] = chan[:, :]
    #
    # now project all the images onto the lambert map
    #
    area_def_args = dict(area_id=area_id,
                         area_name=area_name,
                         proj_id=proj_id,
                         area_dict=area_dict,
                         xsize=xsize,
                         ysize=ysize,
                         area_extent=area_extent)
    area_def = geometry.AreaDefinition(area_id, area_name, proj_id, area_dict,
                                       xsize, ysize, area_extent)
    swath_def = geometry.SwathDefinition(lons=lon_data, lats=lat_data)
    #
    # here is the resample step using 5 km region of influence (see pyresample docs)
    #
    channels = kd_tree.resample_nearest(swath_def,
                                        input_array,
                                        area_def,
                                        radius_of_influence=25000,
                                        nprocs=2,
                                        fill_value=None)
    # channels = kd_tree.resample_gauss(swath_def, input_array,
    #                                     area_def, radius_of_influence=50000,sigmas=[25000,25000],nprocs=2,fill_value=None)
    #
    # replace the  number used for fill_value with np.nan
    #
    # nan_fill_value = np.array([np.nan],dtype=np.float32)[0]
    # channels[channels==fill_value]=nan_fill_value
    print('running modisl1b_resample: here are the channels to be resampled')
    for index in range(num_chans):
        print('channel and mean {} {}'.format(
            chan_list[index], np.nanmean(channels[:, :, index].ravel())))
    #
    # replace negative fill_value with np.nan (32 bit)
    #
    print('pyresample area_def information:')
    print('\ndump area definition:\n{}\n'.format(area_def))
    print('\nx and y pixel dimensions in meters:\n{}\n{}\n'.format(
        area_def.pixel_size_x, area_def.pixel_size_y))
    #
    # here is the dictionary for geotiff creation -- save for future use in rasterio
    #
    adfgeotransform = [
        area_def.area_extent[0], area_def.pixel_size_x, 0,
        area_def.area_extent[3], 0, -area_def.pixel_size_y
    ]
    proj4_string = area_def.proj4_string
    proj_id = area_def.proj_id
    height, width, num_chans = channels.shape
    geotiff_args = dict(width=width,
                        height=height,
                        adfgeotransform=adfgeotransform,
                        proj4_string=proj4_string,
                        proj_id=proj_id)
    out_dict = dict(channels=channels,
                    area_def_args=area_def_args,
                    basemap_args=basemap_args,
                    geotiff_args=geotiff_args,
                    fill_value=fill_value)
    print('completed modisl1b_resample')
    return out_dict
Exemple #7
0
class Test(unittest.TestCase):

    pts_irregular = (np.array([[-1., 1.], ]),
                     np.array([[1., 2.], ]),
                     np.array([[-2., -1.], ]),
                     np.array([[2., -4.], ]))
    pts_vert_parallel = (np.array([[-1., 1.], ]),
                         np.array([[1., 2.], ]),
                         np.array([[-1., -1.], ]),
                         np.array([[1., -2.], ]))
    pts_both_parallel = (np.array([[-1., 1.], ]),
                         np.array([[1., 1.], ]),
                         np.array([[-1., -1.], ]),
                         np.array([[1., -1.], ]))

    # Area definition with four pixels
    target_def = geometry.AreaDefinition('areaD',
                                         'Europe (3km, HRV, VTC)',
                                         'areaD',
                                         {'a': '6378144.0',
                                          'b': '6356759.0',
                                          'lat_0': '50.00',
                                          'lat_ts': '50.00',
                                          'lon_0': '8.00',
                                          'proj': 'stere'},
                                         4, 4,
                                         [-1370912.72,
                                          -909968.64000000001,
                                          1029087.28,
                                          1490031.3600000001])

    # Input data around the target pixel at 0.63388324, 55.08234642,
    in_shape = (100, 100)
    data1 = np.ones((in_shape[0], in_shape[1]))
    data2 = 2. * data1
    lons, lats = np.meshgrid(np.linspace(-5., 5., num=in_shape[0]),
                             np.linspace(50., 60., num=in_shape[1]))
    swath_def = geometry.SwathDefinition(lons=lons, lats=lats)

    radius = 50e3
    neighbours = 32
    input_idxs, output_idxs, idx_ref, dists = \
        kd_tree.get_neighbour_info(swath_def, target_def,
                                   radius, neighbours=neighbours,
                                   nprocs=1)
    input_size = input_idxs.sum()
    index_mask = (idx_ref == input_size)
    idx_ref = np.where(index_mask, 0, idx_ref)

    def test_calc_abc(self):
        # No np.nan inputs
        pt_1, pt_2, pt_3, pt_4 = self.pts_irregular
        res = bil._calc_abc(pt_1, pt_2, pt_3, pt_4, 0.0, 0.0)
        self.assertFalse(np.isnan(res[0]))
        self.assertFalse(np.isnan(res[1]))
        self.assertFalse(np.isnan(res[2]))
        # np.nan input -> np.nan output
        res = bil._calc_abc(np.array([[np.nan, np.nan]]),
                            pt_2, pt_3, pt_4, 0.0, 0.0)
        self.assertTrue(np.isnan(res[0]))
        self.assertTrue(np.isnan(res[1]))
        self.assertTrue(np.isnan(res[2]))

    def test_get_ts_irregular(self):
        res = bil._get_ts_irregular(self.pts_irregular[0],
                                    self.pts_irregular[1],
                                    self.pts_irregular[2],
                                    self.pts_irregular[3],
                                    0., 0.)
        self.assertEqual(res[0], 0.375)
        self.assertEqual(res[1], 0.5)
        res = bil._get_ts_irregular(self.pts_vert_parallel[0],
                                    self.pts_vert_parallel[1],
                                    self.pts_vert_parallel[2],
                                    self.pts_vert_parallel[3],
                                    0., 0.)
        self.assertTrue(np.isnan(res[0]))
        self.assertTrue(np.isnan(res[1]))

    def test_get_ts_uprights_parallel(self):
        res = bil._get_ts_uprights_parallel(self.pts_vert_parallel[0],
                                            self.pts_vert_parallel[1],
                                            self.pts_vert_parallel[2],
                                            self.pts_vert_parallel[3],
                                            0., 0.)
        self.assertEqual(res[0], 0.5)
        self.assertEqual(res[1], 0.5)

    def test_get_ts_parallellogram(self):
        res = bil._get_ts_parallellogram(self.pts_both_parallel[0],
                                         self.pts_both_parallel[1],
                                         self.pts_both_parallel[2],
                                         0., 0.)
        self.assertEqual(res[0], 0.5)
        self.assertEqual(res[1], 0.5)

    def test_get_ts(self):
        out_x = np.array([[0.]])
        out_y = np.array([[0.]])
        res = bil._get_ts(self.pts_irregular[0],
                          self.pts_irregular[1],
                          self.pts_irregular[2],
                          self.pts_irregular[3],
                          out_x, out_y)
        self.assertEqual(res[0], 0.375)
        self.assertEqual(res[1], 0.5)
        res = bil._get_ts(self.pts_both_parallel[0],
                          self.pts_both_parallel[1],
                          self.pts_both_parallel[2],
                          self.pts_both_parallel[3],
                          out_x, out_y)
        self.assertEqual(res[0], 0.5)
        self.assertEqual(res[1], 0.5)
        res = bil._get_ts(self.pts_vert_parallel[0],
                          self.pts_vert_parallel[1],
                          self.pts_vert_parallel[2],
                          self.pts_vert_parallel[3],
                          out_x, out_y)
        self.assertEqual(res[0], 0.5)
        self.assertEqual(res[1], 0.5)

    def test_solve_quadratic(self):
        res = bil._solve_quadratic(1, 0, 0)
        self.assertEqual(res[0], 0.0)
        res = bil._solve_quadratic(1, 2, 1)
        self.assertTrue(np.isnan(res[0]))
        res = bil._solve_quadratic(1, 2, 1, min_val=-2.)
        self.assertEqual(res[0], -1.0)
        # Test that small adjustments work
        pt_1, pt_2, pt_3, pt_4 = self.pts_vert_parallel
        pt_1 = self.pts_vert_parallel[0].copy()
        pt_1[0][0] += 1e-7
        res = bil._calc_abc(pt_1, pt_2, pt_3, pt_4, 0.0, 0.0)
        res = bil._solve_quadratic(res[0], res[1], res[2])
        self.assertAlmostEqual(res[0], 0.5, 5)
        res = bil._calc_abc(pt_1, pt_3, pt_2, pt_4, 0.0, 0.0)
        res = bil._solve_quadratic(res[0], res[1], res[2])
        self.assertAlmostEqual(res[0], 0.5, 5)

    def test_get_output_xy(self):
        proj = Proj(self.target_def.proj4_string)
        out_x, out_y = bil._get_output_xy(self.target_def, proj)
        self.assertTrue(out_x.all())
        self.assertTrue(out_y.all())

    def test_get_input_xy(self):
        proj = Proj(self.target_def.proj4_string)
        in_x, in_y = bil._get_output_xy(self.swath_def, proj)
        self.assertTrue(in_x.all())
        self.assertTrue(in_y.all())

    def test_get_bounding_corners(self):
        proj = Proj(self.target_def.proj4_string)
        out_x, out_y = bil._get_output_xy(self.target_def, proj)
        in_x, in_y = bil._get_input_xy(self.swath_def, proj,
                                       self.input_idxs, self.idx_ref)
        res = bil._get_bounding_corners(in_x, in_y, out_x, out_y,
                                        self.neighbours, self.idx_ref)
        for i in range(len(res) - 1):
            pt_ = res[i]
            for j in range(2):
                # Only the sixth output location has four valid corners
                self.assertTrue(np.isfinite(pt_[5, j]))

    def test_get_bil_info(self):
        t__, s__, input_idxs, idx_arr = bil.get_bil_info(self.swath_def,
                                                         self.target_def)
        # Only 6th index should have valid values
        for i in range(len(t__)):
            if i == 5:
                self.assertAlmostEqual(t__[i], 0.684850870155, 5)
                self.assertAlmostEqual(s__[i], 0.775433912393, 5)
            else:
                self.assertTrue(np.isnan(t__[i]))
                self.assertTrue(np.isnan(s__[i]))

    def test_get_sample_from_bil_info(self):
        t__, s__, input_idxs, idx_arr = bil.get_bil_info(self.swath_def,
                                                         self.target_def)
        # Sample from data1
        res = bil.get_sample_from_bil_info(self.data1.ravel(), t__, s__,
                                           input_idxs, idx_arr)
        self.assertEqual(res[5], 1.)
        # Sample from data2
        res = bil.get_sample_from_bil_info(self.data2.ravel(), t__, s__,
                                           input_idxs, idx_arr)
        self.assertEqual(res[5], 2.)
        # Reshaping
        res = bil.get_sample_from_bil_info(self.data2.ravel(), t__, s__,
                                           input_idxs, idx_arr,
                                           output_shape=self.target_def.shape)
        res = res.shape
        self.assertEqual(res[0], self.target_def.shape[0])
        self.assertEqual(res[1], self.target_def.shape[1])

    def test_resample_bilinear(self):
        # Single array
        res = bil.resample_bilinear(self.data1,
                                    self.swath_def,
                                    self.target_def)
        self.assertEqual(res.size, self.target_def.size)
        # There should be only one pixel with value 1, all others are 0
        self.assertEqual(res.sum(), 1)

        # Single array with masked output
        res = bil.resample_bilinear(self.data1,
                                    self.swath_def,
                                    self.target_def, fill_value=None)
        self.assertTrue(hasattr(res, 'mask'))
        # There should be only one valid pixel
        self.assertEqual(self.target_def.size - res.mask.sum(), 1)

        # Two stacked arrays
        data = np.dstack((self.data1, self.data2))
        res = bil.resample_bilinear(data,
                                    self.swath_def,
                                    self.target_def)
        shp = res.shape
        self.assertEqual(shp[0], self.target_def.size)
        self.assertEqual(shp[1], 2)
Exemple #8
0
def project_acolite_netcdf(ncf, output=None, settings={}, target_file=None):

    import os
    from pyproj import Proj

    import acolite as ac
    import numpy as np
    from pyresample.bilinear import NumpyBilinearResampler
    from pyresample import image, geometry

    ## read gatts
    try:
        gatts = ac.shared.nc_gatts(ncf)
    except:
        print('Error accessing {}, is this a NetCDF file?'.format(ncf))
        return ()

    if ('sensor' not in gatts):
        print('No sensor attribute in file {}'.format(ncf))
        return ()

    ## read datasets
    datasets = ac.shared.nc_datasets(ncf)
    if ('lat' not in datasets) or ('lon' not in datasets):
        print('No lat/lon found in file {}'.format(ncf))
        return ()

    ## parse settings
    setu = ac.acolite.settings.parse(gatts['sensor'], settings=settings)

    if (setu['output_projection_limit'] is None) & (setu['limit'] is not None):
        setu['output_projection_limit'] = [l for l in setu['limit']]

    if setu['output_projection_resolution'] is not None:
        if len(setu['output_projection_resolution']) != 2:
            print('Provide a two element target_pixel_size.')
            return ()
        else:
            target_pixel_size = [
                float(v) for v in setu['output_projection_resolution']
            ]
    else:
        if setu['default_projection_resolution'] is not None:
            target_pixel_size = [
                float(v) for v in setu['default_projection_resolution']
            ]
            print('Using default grid size: {}x{}metres'.format(
                target_pixel_size[0], target_pixel_size[1]))

    if setu['output_projection_limit'] is not None:
        if len(setu['output_projection_limit']) != 4:
            print('Provide a four element output_projection_limit.')
            return ()
        else:
            limit = [float(v) for v in setu['output_projection_limit']]

        if (setu['output_projection_epsg'] is None) & \
           (setu['output_projection_proj4'] is None):
            lon = (limit[1] + limit[3]) / 2
            lat = (limit[0] + limit[2]) / 2
            utm_zone, epsg = ac.shared.utm_epsg(lon, lat)
            print(utm_zone, epsg)
            setu['output_projection_epsg'] = epsg
    else:
        if not setu['output_projection_metres']:
            print('Provide a four element output_projection_limit.')
            return ()

    ## projection
    if setu['output_projection_epsg'] is not None:
        #projection = '+init=EPSG:{}'.format(setu['output_projection_epsg'])
        if 'EPSG' not in setu['output_projection_epsg']:
            projection = 'EPSG:{}'.format(setu['output_projection_epsg'])
        else:
            projection = '{}'.format(setu['output_projection_epsg'])
    elif setu['output_projection_proj4'] is not None:
        projection = setu['output_projection_proj4']
    else:
        print('No EPSG or proj4 string provided.')
        return ()

    ## user provided x and yrange
    if setu['output_projection_metres']:
        xrange_region = setu['output_projection_xrange']
        yrange_region = setu['output_projection_yrange']
        if (xrange_region is None) or (yrange_region is None):
            print(
                'Provide a output_projection_xrange and output_projection_yrange.'
            )
            return ()
        if len(xrange_region) != 2:
            print('Provide a two element output_projection_xrange.')
            return ()
        if len(yrange_region) != 2:
            print('Provide a two element output_projection_yrange.')
            return ()

    ## create output file name
    bn = os.path.basename(ncf)
    bd = os.path.dirname(ncf)
    oname, nc = os.path.splitext(bn)
    if output is not None:
        bd = '{}'.format(output)
    elif setu['output'] is not None:
        bd = '{}'.format(setu['output'])
    ## add requested name or "reprojected"
    oname = '{}_{}'.format(
        oname, setu['output_projection_name']
        if setu['output_projection_name'] is not None else "projected")
    ncfo = '{}/{}{}'.format(bd, oname, nc)

    print('Setting up target projection.')
    p = Proj(projection)

    ## find region extent
    if not setu['output_projection_metres']:
        ## project lat lon to metres
        xrange_raw, yrange_raw = p((limit[1], limit[1], limit[3], limit[3]),
                                   (limit[0], limit[2], limit[2], limit[0]))
        xrange_raw = (min(xrange_raw), max(xrange_raw))
        yrange_raw = (min(yrange_raw), max(yrange_raw))
        xrange_region = [
            xrange_raw[0] - (xrange_raw[0] % target_pixel_size[0] * 2),
            xrange_raw[1] + target_pixel_size[0] * 2 -
            (xrange_raw[1] % target_pixel_size[0] * 2)
        ]
        yrange_region = [
            yrange_raw[1] + target_pixel_size[1] * 2 -
            (yrange_raw[1] % target_pixel_size[1] * 2),
            yrange_raw[0] - (yrange_raw[0] % target_pixel_size[1] * 2)
        ]

    ## align grid to pixel size
    if setu['output_projection_resolution_align']:
        x_grid_off = xrange_region[0] % target_pixel_size[0], xrange_region[
            1] % target_pixel_size[0]
        y_grid_off = yrange_region[0] % target_pixel_size[1], yrange_region[
            1] % target_pixel_size[1]
        xrange = (xrange_region[0] -
                  x_grid_off[0]), (xrange_region[1] +
                                   (target_pixel_size[0] - x_grid_off[1]))
        yrange = (yrange_region[0] -
                  y_grid_off[0]), (yrange_region[1] +
                                   (target_pixel_size[0] - y_grid_off[1]))
    else:
        xrange = [xrange_region[0], xrange_region[1]]
        yrange = [yrange_region[0], yrange_region[1]]

    ## pixel sizes
    ny = int((yrange[0] - yrange[1]) / target_pixel_size[1])
    nx = int((xrange[1] - xrange[0]) / target_pixel_size[0])
    print(xrange, yrange)
    print(nx, ny)

    ## set up projection dict and nc_projection
    dct = {
        'xrange': xrange,
        'yrange': yrange,
        'p': p,
        'pixel_size': target_pixel_size,
        'xdim': nx,
        'ydim': ny
    }
    nc_projection = ac.shared.projection_netcdf(dct, add_half_pixel=True)

    ## set up target definition
    target_definition = geometry.AreaDefinition(
        'area_id', 'description', 'proj_id', projection, nx, ny,
        [xrange[0], yrange[1], xrange[1], yrange[0]])

    ## read lat/lon
    lat = ac.shared.nc_data(ncf, 'lat')
    lon = ac.shared.nc_data(ncf, 'lon')

    ## set up source definition
    source_definition = geometry.SwathDefinition(lons=lon, lats=lat)

    ## set up resampler
    if setu['output_projection_resampling_method'] == 'bilinear':
        #resampler = NumpyBilinearResampler(source_definition, target_definition, 30e5, neighbours=81)
        resampler = NumpyBilinearResampler(source_definition,
                                           target_definition, 30e3)

    ## make new output attributes
    gatts_out = {k: gatts[k] for k in gatts}
    for k in dct:
        gatts_out[k] = dct[k]
    gatts_out['projection_key'] = [
        k for k in nc_projection if k not in ['x', 'y']
    ][0]
    ## update oname in gatts
    gatts_out['oname'] = oname

    ## run through datasets
    new = True
    for ds in datasets:
        data_in, att = ac.shared.nc_data(ncf, ds, attributes=True)
        if len(data_in.shape) != 2: continue
        print('Reprojecting {} to {} {}x{}'.format(ds, projection, nx, ny))
        data_out = resampler.resample(data_in)
        data_in = None

        if setu['output_projection_fillnans']:
            data_out[data_out == 0] = np.nan
            data_out = ac.shared.fillnan(data_out)

        lsd = None
        if ds not in ['lat', 'lon', 'vza', 'sza', 'vaa', 'saa', 'raa']:
            lsd = setu['netcdf_compression_least_significant_digit']

        ac.output.nc_write(
            ncfo,
            ds,
            data_out,
            attributes=gatts_out,
            netcdf_compression=setu['netcdf_compression'],
            netcdf_compression_level=setu['netcdf_compression_level'],
            netcdf_compression_least_significant_digit=lsd,
            nc_projection=nc_projection,
            dataset_attributes=att,
            new=new)
        data_out = None
        new = False
    print('Wrote {}'.format(ncfo))
    return (ncfo)
Exemple #9
0
def load_avhrr(satscene, options):
    """Read avhrr data from file and load it into *satscene*.
    """

    if "filename" not in options:
        raise IOError("No filename given, cannot load.")

    chns = satscene.channels_to_load & set(["1", "2", "3A", "3B", "4", "5"])
    if len(chns) == 0:
        return

    values = {
        "orbit": satscene.orbit,
        "satname": satscene.satname,
        "number": satscene.number,
        "instrument": satscene.instrument_name,
        "satellite": satscene.fullname
    }

    filename = os.path.join(
        satscene.time_slot.strftime(options["dir"]) % values,
        satscene.time_slot.strftime(options["filename"]) % values)

    file_list = glob.glob(filename)

    if len(file_list) > 1:
        raise IOError("More than one l1b file matching!")
    elif len(file_list) == 0:
        raise IOError("No l1b file matching!: " + filename)

    filename = file_list[0]

    LOG.debug("Loading from " + filename)

    import avhrr  # AHAMAP module

    avh = avhrr.avhrr(filename)
    avh.get_unprojected()
    instrument_data = avh.build_raw()

    available_channels = set([])
    data_channels = {}

    for chn in instrument_data.data:
        channel_name = chn.info.info["channel_id"][3:].upper()
        available_channels |= set([channel_name])
        data_channels[channel_name] = chn.data

    for chn in satscene.channels_to_load:
        if chn in available_channels:
            if chn in ["1", "2", "3A"]:
                gain = instrument_data.info["vis_gain"]
                intercept = instrument_data.info["vis_intercept"]
                units = "%"
            else:
                gain = instrument_data.info["ir_gain"]
                intercept = instrument_data.info["ir_intercept"]
                units = "K"

            chn_array = np.ma.array(data_channels[chn])
            missing_data = instrument_data.info["missing_data"]
            chn_array = np.ma.masked_inside(chn_array, missing_data - EPSILON,
                                            missing_data + EPSILON)
            no_data = instrument_data.info["nodata"]
            chn_array = np.ma.masked_inside(chn_array, no_data - EPSILON,
                                            no_data + EPSILON)

            satscene[chn] = chn_array
            satscene[chn].data = np.ma.masked_less(
                satscene[chn].data * gain + intercept, 0)

            satscene[chn].info['units'] = units
        else:
            LOG.warning("Channel " + str(chn) + " not available, not loaded.")

    # Compulsory global attribudes
    satscene.info["title"] = (satscene.satname.capitalize() + satscene.number +
                              " satellite, " +
                              satscene.instrument_name.capitalize() +
                              " instrument.")
    satscene.info["institution"] = "Original data disseminated by EumetCast."
    satscene.add_to_history("HRIT/LRIT data read by mipp/mpop.")
    satscene.info["references"] = "No reference."
    satscene.info["comments"] = "No comment."

    lons = instrument_data.londata / math.pi * 180
    lats = instrument_data.latdata / math.pi * 180

    try:
        from pyresample import geometry
        satscene.area = geometry.SwathDefinition(lons=lons, lats=lats)
    except ImportError:
        satscene.area = None
        satscene.lat = lats
        satscene.lon = lons
Exemple #10
0
    def setUpClass(cls):
        import xarray as xr
        import dask.array as da
        cls.area_def = geometry.AreaDefinition('areaD',
                                               'Europe (3km, HRV, VTC)',
                                               'areaD',
                                               {'a': '6378144.0',
                                                'b': '6356759.0',
                                                'lat_0': '50.00',
                                                'lat_ts': '50.00',
                                                'lon_0': '8.00',
                                                'proj': 'stere'},
                                               800,
                                               800,
                                               [-1370912.72,
                                                -909968.64000000001,
                                                1029087.28,
                                                1490031.3600000001])

        dfa = da.from_array  # shortcut
        cls.chunks = chunks = 5
        cls.tgrid = geometry.CoordinateDefinition(
            lons=dfa(np.array([
                [11.5, 12.562036, 12.9],
                [11.5, 12.562036, 12.9],
                [11.5, 12.562036, 12.9],
                [11.5, 12.562036, 12.9],
            ]), chunks=chunks),
            lats=dfa(np.array([
                [55.715613, 55.715613, 55.715613],
                [55.715613, 55.715613, 55.715613],
                [55.715613, np.nan, 55.715613],
                [55.715613, 55.715613, 55.715613],
            ]), chunks=chunks))

        cls.tdata_1d = xr.DataArray(
            dfa(np.array([1., 2., 3.]), chunks=chunks), dims=('my_dim1',))
        cls.tlons_1d = xr.DataArray(
            dfa(np.array([11.280789, 12.649354, 12.080402]), chunks=chunks),
            dims=('my_dim1',))
        cls.tlats_1d = xr.DataArray(
            dfa(np.array([56.011037, 55.629675, 55.641535]), chunks=chunks),
            dims=('my_dim1',))
        cls.tswath_1d = geometry.SwathDefinition(lons=cls.tlons_1d,
                                                 lats=cls.tlats_1d)

        cls.data_2d = xr.DataArray(
            da.from_array(np.fromfunction(lambda y, x: y * x, (50, 10)),
                          chunks=5),
            dims=('my_dim_y', 'my_dim_x'))
        cls.data_3d = xr.DataArray(
            da.from_array(np.fromfunction(lambda y, x, b: y * x * b, (50, 10, 3)),
                          chunks=5),
            dims=('my_dim_y', 'my_dim_x', 'bands'),
            coords={'bands': ['r', 'g', 'b']})
        cls.lons_2d = xr.DataArray(
            da.from_array(np.fromfunction(lambda y, x: 3 + x, (50, 10)),
                          chunks=5),
            dims=('my_dim_y', 'my_dim_x'))
        cls.lats_2d = xr.DataArray(
            da.from_array(np.fromfunction(lambda y, x: 75 - y, (50, 10)),
                          chunks=5),
            dims=('my_dim_y', 'my_dim_x'))
        cls.swath_def_2d = geometry.SwathDefinition(lons=cls.lons_2d,
                                                    lats=cls.lats_2d)
        cls.src_area_2d = geometry.AreaDefinition(
            'areaD_src', 'Europe (3km, HRV, VTC)', 'areaD',
            {'a': '6378144.0', 'b': '6356759.0', 'lat_0': '52.00',
             'lat_ts': '52.00', 'lon_0': '5.00', 'proj': 'stere'}, 50, 10,
            [-1370912.72, -909968.64000000001, 1029087.28,
             1490031.3600000001])
Exemple #11
0
)  # was readvar.getRasterHeight() in the following stanza
readvar = p.getBand('latitude')
lats = np.zeros(w * h, np.float32)
readvar.readPixels(0, 0, w, h, lats)
latmin = lats.min()
latmax = lats.max()
lats.shape = h, w
readvar = p.getBand('longitude')
lons = np.zeros(w * h, np.float32)
readvar.readPixels(0, 0, w, h, lons)
lonmin = lons.min()
lonmax = lons.max()
lons.shape = h, w

#definition of the swath object
swath = geometry.SwathDefinition(lons=lons, lats=lats)

start_time_str = str(p.getStartTime())
start_time = datetime.datetime.strptime(start_time_str, '%d-%b-%Y %H:%M:%S.%f')
stop_time_str = str(p.getEndTime())
stop_time = datetime.datetime.strptime(stop_time_str, '%d-%b-%Y %H:%M:%S.%f')

#test if swath and area overlap. If not, exit
if not (area.overlaps(swath)):
    if args.verbose:
        print "product outside of area"
    p.dispose()
    if (istar or iszip) and args.delete:
        rmtree(product)
    sys.exit()
Exemple #12
0
def load(scene, *args, **kwargs):
    """Loads the *channels* into the satellite *scene*.
    A possible *calibrate* keyword argument is passed to the AAPP reader
    Should be 0 for off, 1 for default, and 2 for radiances only.
    However, as the AAPP-lvl1b file contains radiances this reader cannot
    return counts, so calibrate=0 is not allowed/supported. The radiance to
    counts conversion is not possible.
    """

    del args
    calibrate = kwargs.get("calibrate", True)
    if calibrate == 0:
        raise ValueError('calibrate=0 is not supported! ' +
                         'This reader cannot return counts')

    if kwargs.get("filename") is not None:
        filename = kwargs["filename"]
    else:
        filename = (kwargs.get("filename", None)
                    or get_filename(scene, "level2"))

    if isinstance(filename, (list, tuple, set)):
        filenames = filename
    else:
        filenames = [filename]
    LOG.debug("Using file(s) %s", str(filename))
    readers = [EpsAvhrrL1bReader(filename) for filename in filenames]

    arrs = {}
    llons = []
    llats = []
    loaded_channels = set()

    for reader in readers:

        for chname, arr in reader.get_channels(scene.channels_to_load,
                                               calibrate).items():
            arrs.setdefault(chname, []).append(arr)
            loaded_channels.add(chname)

        if scene.orbit is None:
            scene.orbit = int(reader["ORBIT_START"][0])
            scene.info["orbit_number"] = scene.orbit
        lons, lats = reader.get_full_lonlats()
        llons.append(lons)
        llats.append(lats)

    for chname in loaded_channels:
        scene[chname] = np.vstack(arrs[chname])
        if chname in ["1", "2", "3A"]:
            scene[chname].info["units"] = "%"
        elif chname in ["4", "5", "3B"]:
            scene[chname].info["units"] = "K"

    lons = np.vstack(llons)
    lats = np.vstack(llats)

    try:
        scene.area = geometry.SwathDefinition(lons, lats)
    except NameError:
        scene.lons, scene.lats = lons, lats
Exemple #13
0
    def __init__(self,
                 in_area,
                 out_area,
                 in_latlons=None,
                 mode=None,
                 radius=10000,
                 nprocs=1):

        if (mode is not None and mode not in ["quick", "nearest"]):
            raise ValueError("Projector mode must be 'nearest' or 'quick'")

        self.area_file = get_area_file()

        self.in_area = None
        self.out_area = None
        self._cache = None
        self._filename = None
        self.mode = "quick"
        self.radius = radius
        self.conf = ConfigParser.ConfigParser()
        self.conf.read(os.path.join(CONFIG_PATH, "mpop.cfg"))

        # TODO:
        # - Rework so that in_area and out_area can be lonlats.
        # - Add a recompute flag ?

        # Setting up the input area
        try:
            self.in_area = get_area_def(in_area)
            in_id = in_area
        except (utils.AreaNotFound, AttributeError):
            try:
                in_id = in_area.area_id
                self.in_area = in_area
            except AttributeError:
                try:
                    self.in_area = geometry.SwathDefinition(lons=in_latlons[0],
                                                            lats=in_latlons[1])
                    in_id = in_area
                except TypeError:
                    raise utils.AreaNotFound(
                        "Input area " + str(in_area) + " must be defined in " +
                        self.area_file + ", be an area object"
                        " or longitudes/latitudes must be "
                        "provided.")

        # Setting up the output area
        try:
            self.out_area = get_area_def(out_area)
            out_id = out_area
        except (utils.AreaNotFound, AttributeError):
            try:
                out_id = out_area.area_id
                self.out_area = out_area
            except AttributeError:
                raise utils.AreaNotFound("Output area " + str(out_area) +
                                         " must be defined in " +
                                         self.area_file + " or "
                                         "be an area object.")

        #if self.in_area == self.out_area:
        #    return

        # choosing the right mode if necessary
        if mode is None:
            try:
                dicts = in_area.proj_dict, out_area.proj_dict
                del dicts
                self.mode = "quick"
            except AttributeError:
                self.mode = "nearest"
        else:
            self.mode = mode

        filename = (in_id + "2" + out_id + "_" +
                    str(_get_area_hash(self.in_area)) + "to" +
                    str(_get_area_hash(self.out_area)) + "_" + self.mode +
                    ".npz")

        projections_directory = "/var/tmp"
        try:
            projections_directory = self.conf.get("projector",
                                                  "projections_directory")
        except ConfigParser.NoSectionError:
            pass

        self._filename = os.path.join(projections_directory, filename)

        try:
            self._cache = {}
            self._file_cache = np.load(self._filename)
        except:
            logger.info("Computing projection from %s to %s...", in_id, out_id)

            if self.mode == "nearest":
                valid_index, valid_output_index, index_array, distance_array = \
                    kd_tree.get_neighbour_info(self.in_area,
                                               self.out_area,
                                               self.radius,
                                               neighbours=1,
                                               nprocs=nprocs)
                del distance_array
                self._cache = {}
                self._cache['valid_index'] = valid_index
                self._cache['valid_output_index'] = valid_output_index
                self._cache['index_array'] = index_array

            elif self.mode == "quick":
                ridx, cidx = \
                    utils.generate_quick_linesample_arrays(self.in_area,
                                                           self.out_area)
                self._cache = {}
                self._cache['row_idx'] = ridx
                self._cache['col_idx'] = cidx
Exemple #14
0
    def setUp(self):
        """Do some setup for common things."""
        import dask.array as da
        from xarray import DataArray
        from pyresample import geometry, kd_tree

        self.pts_irregular = (np.array([
            [-1., 1.],
        ]), np.array([
            [1., 2.],
        ]), np.array([
            [-2., -1.],
        ]), np.array([
            [2., -4.],
        ]))
        self.pts_vert_parallel = (np.array([
            [-1., 1.],
        ]), np.array([
            [1., 2.],
        ]), np.array([
            [-1., -1.],
        ]), np.array([
            [1., -2.],
        ]))
        self.pts_both_parallel = (np.array([
            [-1., 1.],
        ]), np.array([
            [1., 1.],
        ]), np.array([
            [-1., -1.],
        ]), np.array([
            [1., -1.],
        ]))

        # Area definition with four pixels
        self.target_def = geometry.AreaDefinition(
            'areaD', 'Europe (3km, HRV, VTC)', 'areaD', {
                'a': '6378144.0',
                'b': '6356759.0',
                'lat_0': '50.00',
                'lat_ts': '50.00',
                'lon_0': '8.00',
                'proj': 'stere'
            }, 4, 4,
            [-1370912.72, -909968.64000000001, 1029087.28, 1490031.3600000001])

        # Input data around the target pixel at 0.63388324, 55.08234642,
        in_shape = (100, 100)
        self.data1 = DataArray(da.ones((in_shape[0], in_shape[1])),
                               dims=('y', 'x'))
        self.data2 = 2. * self.data1
        self.data3 = self.data1 + 9.5
        lons, lats = np.meshgrid(np.linspace(-25., 40., num=in_shape[0]),
                                 np.linspace(45., 75., num=in_shape[1]))
        self.source_def = geometry.SwathDefinition(lons=lons, lats=lats)

        self.radius = 50e3
        self.neighbours = 32
        valid_input_index, output_idxs, index_array, dists = \
            kd_tree.get_neighbour_info(self.source_def, self.target_def,
                                       self.radius, neighbours=self.neighbours,
                                       nprocs=1)
        input_size = valid_input_index.sum()
        index_mask = (index_array == input_size)
        index_array = np.where(index_mask, 0, index_array)

        self.valid_input_index = valid_input_index
        self.index_array = index_array

        shp = self.source_def.shape
        self.cols, self.lines = np.meshgrid(np.arange(shp[1]),
                                            np.arange(shp[0]))
Exemple #15
0
    def test_init(self, gah, gni, gqla):
        """Creation of coverage.
        """

        # in case of wrong number of arguments

        self.assertRaises(TypeError, Projector)
        self.assertRaises(TypeError, Projector, random_string(20))

        # in case of string arguments

        in_area_id = random_string(20)
        out_area_id = random_string(20)

        area_type = utils.parse_area_file.return_value.__getitem__.return_value

        gni.side_effect = [("a", "b", "c", "d")] * 10

        self.proj = Projector(in_area_id, out_area_id)
        self.assertEquals(utils.parse_area_file.call_count, 2)
        area_file = mpop.projector.get_area_file()
        utils.parse_area_file.assert_any_call(area_file, in_area_id)
        utils.parse_area_file.assert_any_call(area_file, out_area_id)

        self.assertEquals(self.proj.in_area, area_type)
        self.assertEquals(self.proj.out_area, area_type)

        # in case of undefined areas

        mock = MagicMock(side_effect=Exception("raise"))
        with patch.object(utils, 'parse_area_file', mock):
            self.assertRaises(Exception, Projector, "raise", random_string(20))
            self.assertRaises(Exception, Projector, random_string(20), "raise")

        # in case of geometry objects as input

        with patch.object(utils, 'AreaNotFound', Exception):
            mock = MagicMock(
                side_effect=[utils.AreaNotFound("raise"),
                             MagicMock()])
            with patch.object(utils, 'parse_area_file', mock):
                in_area = geometry.AreaDefinition()
                self.proj = Projector(in_area, out_area_id)
                print self.proj.in_area
                self.assertEquals(self.proj.in_area, in_area)

        in_area = geometry.SwathDefinition()
        utils.parse_area_file.return_value.__getitem__.side_effect = [
            AttributeError, out_area_id
        ]
        self.proj = Projector(in_area, out_area_id)
        self.assertEquals(self.proj.in_area, in_area)

        out_area = geometry.AreaDefinition()
        utils.parse_area_file.return_value.__getitem__.side_effect = [
            in_area_id, AttributeError
        ]
        self.proj = Projector(in_area_id, out_area)
        self.assertEquals(self.proj.out_area, out_area)

        # in case of lon/lat is input

        utils.parse_area_file.return_value.__getitem__.side_effect = [
            AttributeError, out_area_id
        ]
        lonlats = ("great_lons", "even_greater_lats")

        self.proj = Projector("raise", out_area_id, lonlats)
        geometry.SwathDefinition.assert_called_with(lons=lonlats[0],
                                                    lats=lonlats[1])

        utils.parse_area_file.return_value.__getitem__.side_effect = None
        # in case of wrong mode

        self.assertRaises(ValueError,
                          Projector,
                          random_string(20),
                          random_string(20),
                          mode=random_string(20))

        utils.parse_area_file.return_value.__getitem__.side_effect = [
            "a", "b", "c", "d"
        ]
        gqla.side_effect = [("ridx", "cidx")]
        # quick mode cache
        self.proj = Projector(in_area_id, out_area_id, mode="quick")
        cache = getattr(self.proj, "_cache")
        self.assertTrue(cache['row_idx'] is not None)
        self.assertTrue(cache['col_idx'] is not None)

        # nearest mode cache

        self.proj = Projector(in_area_id, out_area_id, mode="nearest")
        cache = getattr(self.proj, "_cache")
        self.assertTrue(cache['valid_index'] is not None)
        self.assertTrue(cache['valid_output_index'] is not None)
        self.assertTrue(cache['index_array'] is not None)
Exemple #16
0
def load_virr(satscene, options):
    """Read the VIRR hdf5 file"""

    if "filename" not in options:
        raise IOError("No 1km virr filename given, cannot load")

    values = {
        "orbit": satscene.orbit,
        "satname": satscene.satname,
        "instrument": satscene.instrument_name,
        "satellite": satscene.fullname
    }

    filename = \
        os.path.join(satscene.time_slot.strftime(options["dir"]) % values,
                     satscene.time_slot.strftime(
                         options["filename"])
                     % values)

    LOGGER.debug("Filename= %s", filename)

    datasets = ['EV_Emissive', 'EV_RefSB']

    calibrate = options['calibrate']

    h5f = h5py.File(filename, 'r')

    # Get geolocation information
    lons = h5f['Longitude'][:]
    lats = h5f['Latitude'][:]
    sunz = h5f['SolarZenith'][:]
    slope = h5f['SolarZenith'].attrs['Slope'][0]
    intercept = h5f['SolarZenith'].attrs['Intercept'][0]
    sunz = sunz * slope + intercept
    sunz = np.where(np.greater(sunz, 85.0), 85.0, sunz)

    # Get the calibration information
    # Emissive radiance coefficients:
    emis_offs = h5f['Emissive_Radiance_Offsets'][:]
    emis_scales = h5f['Emissive_Radiance_Scales'][:]

    # Central wave number (unit =  cm-1) for the three IR bands
    # It is ordered according to decreasing wave number (increasing wavelength):
    # 3.7 micron, 10.8 micron, 12 micron
    emiss_centroid_wn = h5f.attrs['Emmisive_Centroid_Wave_Number']

    # VIS/NIR calibration stuff:
    refsb_cal_coeff = h5f.attrs['RefSB_Cal_Coefficients']
    visnir_scales = refsb_cal_coeff[0::2]
    visnir_offs = refsb_cal_coeff[1::2]

    refsb_effective_wl = h5f.attrs['RefSB_Effective_Wavelength']

    # Read the band data:
    for dset in datasets:
        band_data = h5f[dset]
        valid_range = band_data.attrs['valid_range']
        LOGGER.debug("valid-range = " + str(valid_range))
        fillvalue = band_data.attrs['_FillValue']
        band_names = band_data.attrs['band_name'].split(',')
        slope = band_data.attrs['Slope']
        intercept = band_data.attrs['Intercept']
        units = band_data.attrs['units']
        long_name = band_data.attrs['long_name']

        LOGGER.debug('band names = ' + str(band_names))

        for (i, band) in enumerate(band_names):
            if band not in satscene.channels_to_load:
                continue

            LOGGER.debug("Reading channel %s, i=%d", band, i)
            data = band_data[i]

            bandmask = np.logical_or(np.less(data, valid_range[0]),
                                     np.greater(data, valid_range[1]))

            if calibrate:
                if dset in ['EV_Emissive']:
                    data = (np.array([emis_offs[:, i]]).transpose() +
                            data * np.array([emis_scales[:, i]]).transpose())
                    # Radiance to Tb conversion.
                    # Pyspectral wants SI units,
                    # but radiance data are in mW/m^2/str/cm^-1 and wavenumbers are in cm^-1
                    # Therefore multply wavenumber by 100 and radiances by
                    # 10^-5
                    data = rad2temp(emiss_centroid_wn[i] * 100., data * 1e-5)
                if dset in ['EV_RefSB']:
                    data = (visnir_offs[i] + data * visnir_scales[i]) / np.cos(
                        np.deg2rad(sunz))

            satscene[band] = np.ma.masked_array(data,
                                                mask=bandmask,
                                                copy=False)

    from pyresample import geometry
    satscene.area = geometry.SwathDefinition(lons=lons, lats=lats)

    h5f.close()
def read_swath_and_create_geometry(dataFolder, fileIndex, year, printStatus):
    if printStatus:
        print(
            '    Step 2: Reading in the binary grid and creating the original geometry'
        )
        print('        Reading in binary data from file')

    fileID = ref.indexAndYearToFileID(fileIndex, year)
    metadata_dictionary = read_metadata_dictionary(dataFolder, fileID)

    swathID = ref.fileNameToSwathID(fileID)
    dataPath = dataFolder.joinpath('Raw', str(year), 'Data',
                                   swathID + '.hgt.grd')

    g = np.fromfile(str(dataPath), dtype='<f4')

    # cast to float 2
    g = g.astype(np.dtype('<f2'))

    grid = np.reshape(g, (metadata_dictionary['GRD Latitude Lines'],
                          metadata_dictionary['GRD Longitude Samples']))
    if printStatus:
        print('        Preparing original geometry of the swath from metadata')
    grid = np.where(grid > grid.min(), grid, np.nan)

    min_swath_lon = metadata_dictionary['GRD Starting Longitude']
    max_swath_lon = metadata_dictionary['GRD Starting Longitude'] + metadata_dictionary['GRD Longitude Samples'] * \
                    metadata_dictionary['GRD Longitude Spacing']
    min_swath_lat = metadata_dictionary['GRD Starting Latitude'] + metadata_dictionary['GRD Latitude Lines'] * \
                    metadata_dictionary['GRD Latitude Spacing']
    max_swath_lat = metadata_dictionary['GRD Starting Latitude']

    lats = np.linspace(min_swath_lat, max_swath_lat,
                       metadata_dictionary['GRD Latitude Lines'])
    lons = np.linspace(min_swath_lon, max_swath_lon,
                       metadata_dictionary['GRD Longitude Samples'])

    grid = np.flipud(grid)

    if printStatus:
        # print("            The grid shape is (" + str(len(lats)) + "," + str(len(lons)) + ")")
        print("            The grid shape is (" + str(np.shape(grid)[0]) +
              "," + str(np.shape(grid)[1]) + ")")

    # Original Area definition in swath geometry:
    Lons, Lats = np.meshgrid(lons, lats)
    Lons = np.reshape(Lons, (np.size(Lons), ))
    Lats = np.reshape(Lats, (np.size(Lats), ))
    grid = np.reshape(grid, (np.size(grid), ))

    # Remove nans so averaging is ubiquitous
    non_nans = np.invert(np.isnan(grid))
    if printStatus:
        print('            Removed ' + str(np.sum(np.isnan(grid))) +
              ' nan points out of ' + str(np.size(grid)) + ' grid points')
    Lons = Lons[non_nans]
    Lats = Lats[non_nans]
    grid = grid[non_nans]

    area_original = geometry.SwathDefinition(lons=Lons, lats=Lats)
    return (area_original, grid)
Exemple #18
0
    def setUpClass(cls):
        cls.pts_irregular = (np.array([
            [-1., 1.],
        ]), np.array([
            [1., 2.],
        ]), np.array([
            [-2., -1.],
        ]), np.array([
            [2., -4.],
        ]))
        cls.pts_vert_parallel = (np.array([
            [-1., 1.],
        ]), np.array([
            [1., 2.],
        ]), np.array([
            [-1., -1.],
        ]), np.array([
            [1., -2.],
        ]))
        cls.pts_both_parallel = (np.array([
            [-1., 1.],
        ]), np.array([
            [1., 1.],
        ]), np.array([
            [-1., -1.],
        ]), np.array([
            [1., -1.],
        ]))

        # Area definition with four pixels
        target_def = geometry.AreaDefinition(
            'areaD', 'Europe (3km, HRV, VTC)', 'areaD', {
                'a': '6378144.0',
                'b': '6356759.0',
                'lat_0': '50.00',
                'lat_ts': '50.00',
                'lon_0': '8.00',
                'proj': 'stere'
            }, 4, 4,
            [-1370912.72, -909968.64000000001, 1029087.28, 1490031.3600000001])

        # Input data around the target pixel at 0.63388324, 55.08234642,
        in_shape = (100, 100)
        cls.data1 = np.ones((in_shape[0], in_shape[1]))
        cls.data2 = 2. * cls.data1
        cls.data3 = cls.data1 + 9.5
        lons, lats = np.meshgrid(np.linspace(-25., 40., num=in_shape[0]),
                                 np.linspace(45., 75., num=in_shape[1]))
        cls.swath_def = geometry.SwathDefinition(lons=lons, lats=lats)

        radius = 50e3
        cls.neighbours = 32
        input_idxs, output_idxs, idx_ref, dists = \
            kd_tree.get_neighbour_info(cls.swath_def, target_def,
                                       radius, neighbours=cls.neighbours,
                                       nprocs=1)
        input_size = input_idxs.sum()
        index_mask = (idx_ref == input_size)
        idx_ref = np.where(index_mask, 0, idx_ref)

        cls.input_idxs = input_idxs
        cls.target_def = target_def
        cls.idx_ref = idx_ref
Exemple #19
0
    def load(self, satscene, *args, **kwargs):
        """Read data from file and load it into *satscene*.
        """
        lonlat_is_loaded = False

        prodfilename = kwargs.get('filename')

        if "SST" not in satscene.channels_to_load:
            LOG.warning("No SST product requested. Nothing to be done...")
            return

        try:
            area_name = satscene.area_id or satscene.area.area_id
        except AttributeError:
            area_name = "satproj_?????_?????"

        conf = ConfigParser()
        conf.read(os.path.join(CONFIG_PATH, satscene.fullname + ".cfg"))

        # Reading the products
        product = "sst"
        classes = {product: OsisafNarSstProduct}

        LOG.debug("Loading " + product)

        if isinstance(prodfilename, (list, tuple, set)):
            for fname in prodfilename:
                kwargs['filename'] = fname
                self.load(satscene, *args, **kwargs)
            return
        elif (prodfilename and 'OSISAF-L3C' in os.path.basename(prodfilename)):
            if os.path.basename(prodfilename).split("_")[2] == 'SST':
                filename = prodfilename
            else:
                LOG.warning("Product file name is not as expected: " +
                            str(prodfilename))
                return
        else:
            filename = get_filename(satscene, area_name)

        LOG.info("Filename = " + str(filename))

        chn = classes[product]()
        chn.read(filename, lonlat_is_loaded == False)
        satscene.channels.append(chn)

        lons, lats = chn.lon.data, chn.lat.data
        lonlat_is_loaded = True

        nodata_mask = False
        try:
            from pyresample import geometry
            lons = np.ma.masked_array(lons, nodata_mask)
            lats = np.ma.masked_array(lats, nodata_mask)
            area = geometry.SwathDefinition(lons=lons, lats=lats)
        except ImportError:
            area = None

        if area:
            chn.area = area
        else:
            chn.lon = lons
            chn.lat = lats

        LOG.info("Loading OSISAF SST parameters done")

        return
Exemple #20
0
class Test(unittest.TestCase):

    area_def = geometry.AreaDefinition(
        'areaD', 'Europe (3km, HRV, VTC)', 'areaD', {
            'a': '6378144.0',
            'b': '6356759.0',
            'lat_0': '50.00',
            'lat_ts': '50.00',
            'lon_0': '8.00',
            'proj': 'stere'
        }, 800, 800,
        [-1370912.72, -909968.64000000001, 1029087.28, 1490031.3600000001])

    tdata = numpy.array([1, 2, 3])
    tlons = numpy.array([11.280789, 12.649354, 12.080402])
    tlats = numpy.array([56.011037, 55.629675, 55.641535])
    tswath = geometry.SwathDefinition(lons=tlons, lats=tlats)
    tgrid = geometry.CoordinateDefinition(lons=numpy.array([12.562036]),
                                          lats=numpy.array([55.715613]))

    def test_nearest_base(self):
        res = kd_tree.resample_nearest(self.tswath,
                                       self.tdata.ravel(),
                                       self.tgrid,
                                       100000,
                                       reduce_data=False,
                                       segments=1)
        self.assertTrue(res[0] == 2, 'Failed to calculate nearest neighbour')

    def test_gauss_base(self):
        with catch_warnings() as w:
            res = kd_tree.resample_gauss(self.tswath,
                                         self.tdata.ravel(),
                                         self.tgrid,
                                         50000,
                                         25000,
                                         reduce_data=False,
                                         segments=1)
            self.assertFalse(len(w) != 1, 'Failed to create neighbour warning')
            self.assertFalse(('Searching' not in str(w[0].message)),
                             'Failed to create correct neighbour warning')
        self.assertAlmostEqual(res[0], 2.2020729, 5,
                               'Failed to calculate gaussian weighting')

    def test_custom_base(self):
        def wf(dist):
            return 1 - dist / 100000.0

        with catch_warnings() as w:
            res = kd_tree.resample_custom(self.tswath,
                                          self.tdata.ravel(),
                                          self.tgrid,
                                          50000,
                                          wf,
                                          reduce_data=False,
                                          segments=1)
            self.assertFalse(len(w) != 1, 'Failed to create neighbour warning')
            self.assertFalse(('Searching' not in str(w[0].message)),
                             'Failed to create correct neighbour warning')
        self.assertAlmostEqual(res[0], 2.4356757, 5,
                               'Failed to calculate custom weighting')

    def test_gauss_uncert(self):
        sigma = utils.fwhm2sigma(41627.730557884883)
        with catch_warnings() as w:
            res, stddev, count = kd_tree.resample_gauss(self.tswath,
                                                        self.tdata,
                                                        self.tgrid,
                                                        100000,
                                                        sigma,
                                                        with_uncert=True)
            self.assertTrue(len(w) > 0, 'Failed to create neighbour warning')
            self.assertTrue((any('Searching' in str(_w.message) for _w in w)),
                            'Failed to create correct neighbour warning')

        expected_res = 2.20206560694
        expected_stddev = 0.707115076173
        expected_count = 3
        self.assertAlmostEqual(
            res[0], expected_res, 5,
            'Failed to calculate gaussian weighting with uncertainty')
        self.assertAlmostEqual(
            stddev[0], expected_stddev, 5,
            'Failed to calculate uncertainty for gaussian weighting')
        self.assertEqual(
            count[0], expected_count,
            'Wrong data point count for gaussian weighting with uncertainty')

    def test_custom_uncert(self):
        def wf(dist):
            return 1 - dist / 100000.0

        with catch_warnings() as w:
            res, stddev, counts = kd_tree.resample_custom(self.tswath,
                                                          self.tdata,
                                                          self.tgrid,
                                                          100000,
                                                          wf,
                                                          with_uncert=True)
            self.assertTrue(len(w) > 0, 'Failed to create neighbour warning')
            self.assertTrue((any('Searching' in str(_w.message) for _w in w)),
                            'Failed to create correct neighbour warning')

        self.assertAlmostEqual(
            res[0], 2.32193149, 5,
            'Failed to calculate custom weighting with uncertainty')
        self.assertAlmostEqual(
            stddev[0], 0.81817972, 5,
            'Failed to calculate custom for gaussian weighting')
        self.assertEqual(
            counts[0], 3,
            'Wrong data point count for custom weighting with uncertainty')

    def test_nearest(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       data.ravel(),
                                       self.area_def,
                                       50000,
                                       segments=1)
        cross_sum = res.sum()
        expected = 15874591.0
        self.assertEqual(cross_sum,
                         expected,
                         msg='Swath resampling nearest failed')

    def test_nearest_1d(self):
        data = numpy.fromfunction(lambda x, y: x * y, (800, 800))
        lons = numpy.fromfunction(lambda x: 3 + x / 100., (500, ))
        lats = numpy.fromfunction(lambda x: 75 - x / 10., (500, ))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(self.area_def,
                                       data.ravel(),
                                       swath_def,
                                       50000,
                                       segments=1)
        cross_sum = res.sum()
        expected = 35821299.0
        self.assertEqual(res.shape, (500, ),
                         msg='Swath resampling nearest 1d failed')
        self.assertEqual(cross_sum,
                         expected,
                         msg='Swath resampling nearest 1d failed')

    def test_nearest_empty(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 165 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       data.ravel(),
                                       self.area_def,
                                       50000,
                                       segments=1)
        cross_sum = res.sum()
        expected = 0
        self.assertEqual(cross_sum,
                         expected,
                         msg='Swath resampling nearest empty failed')

    def test_nearest_empty_multi(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 165 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       data_multi,
                                       self.area_def,
                                       50000,
                                       segments=1)
        self.assertEqual(res.shape, (800, 800, 3),
                         msg='Swath resampling nearest empty multi failed')

    def test_nearest_empty_multi_masked(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 165 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       data_multi,
                                       self.area_def,
                                       50000,
                                       segments=1,
                                       fill_value=None)
        self.assertEqual(
            res.shape, (800, 800, 3),
            msg='Swath resampling nearest empty multi masked failed')

    def test_nearest_empty_masked(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 165 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       data.ravel(),
                                       self.area_def,
                                       50000,
                                       segments=1,
                                       fill_value=None)
        cross_sum = res.mask.sum()
        expected = res.size
        self.assertTrue(cross_sum == expected,
                        msg='Swath resampling nearest empty masked failed')

    def test_nearest_segments(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       data.ravel(),
                                       self.area_def,
                                       50000,
                                       segments=2)
        cross_sum = res.sum()
        expected = 15874591.0
        self.assertEqual(cross_sum,
                         expected,
                         msg='Swath resampling nearest segments failed')

    def test_nearest_remap(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       data.ravel(),
                                       self.area_def,
                                       50000,
                                       segments=1)
        remap = kd_tree.resample_nearest(self.area_def,
                                         res.ravel(),
                                         swath_def,
                                         5000,
                                         segments=1)
        cross_sum = remap.sum()
        expected = 22275.0
        self.assertEqual(cross_sum,
                         expected,
                         msg='Grid remapping nearest failed')

    def test_nearest_mp(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       data.ravel(),
                                       self.area_def,
                                       50000,
                                       nprocs=2,
                                       segments=1)
        cross_sum = res.sum()
        expected = 15874591.0
        self.assertEqual(cross_sum,
                         expected,
                         msg='Swath resampling mp nearest failed')

    def test_nearest_multi(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        res = kd_tree.resample_nearest(swath_def,
                                       data_multi,
                                       self.area_def,
                                       50000,
                                       segments=1)
        cross_sum = res.sum()
        expected = 3 * 15874591.0
        self.assertEqual(cross_sum,
                         expected,
                         msg='Swath multi channel resampling nearest failed')

    def test_nearest_multi_unraveled(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        data_multi = numpy.dstack((data, data, data))
        res = kd_tree.resample_nearest(swath_def,
                                       data_multi,
                                       self.area_def,
                                       50000,
                                       segments=1)
        cross_sum = res.sum()
        expected = 3 * 15874591.0
        self.assertEqual(cross_sum,
                         expected,
                         msg='Swath multi channel resampling nearest failed')

    def test_gauss_sparse(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_gauss(swath_def,
                                     data.ravel(),
                                     self.area_def,
                                     50000,
                                     25000,
                                     fill_value=-1,
                                     segments=1)
        cross_sum = res.sum()
        expected = 15387753.9852
        self.assertAlmostEqual(cross_sum,
                               expected,
                               places=3,
                               msg='Swath gauss sparse nearest failed')

    def test_gauss(self):
        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-5, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 3 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        with catch_warnings() as w:
            res = kd_tree.resample_gauss(swath_def,
                                         data.ravel(),
                                         self.area_def,
                                         50000,
                                         25000,
                                         segments=1)
            self.assertFalse(
                len(w) != 1, 'Failed to create neighbour radius warning')
            self.assertFalse(
                ('Possible more' not in str(w[0].message)),
                'Failed to create correct neighbour radius warning')
        cross_sum = res.sum()
        expected = 4872.81050892
        self.assertAlmostEqual(cross_sum,
                               expected,
                               msg='Swath resampling gauss failed')

    def test_gauss_fwhm(self):
        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-5, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 3 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        with catch_warnings() as w:
            res = kd_tree.resample_gauss(swath_def,
                                         data.ravel(),
                                         self.area_def,
                                         50000,
                                         utils.fwhm2sigma(41627.730557884883),
                                         segments=1)
            self.assertFalse(
                len(w) != 1, 'Failed to create neighbour radius warning')
            self.assertFalse(
                ('Possible more' not in str(w[0].message)),
                'Failed to create correct neighbour radius warning')
        cross_sum = res.sum()
        expected = 4872.81050892
        self.assertAlmostEqual(cross_sum,
                               expected,
                               msg='Swath resampling gauss failed')

    def test_gauss_multi(self):
        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-6, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 3 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        with catch_warnings() as w:
            res = kd_tree.resample_gauss(swath_def,
                                         data_multi,
                                         self.area_def,
                                         50000, [25000, 15000, 10000],
                                         segments=1)
            self.assertFalse(
                len(w) != 1, 'Failed to create neighbour radius warning')
            self.assertFalse(
                ('Possible more' not in str(w[0].message)),
                'Failed to create correct neighbour radius warning')
        cross_sum = res.sum()
        expected = 1461.84313918
        self.assertAlmostEqual(
            cross_sum,
            expected,
            msg='Swath multi channel resampling gauss failed')

    def test_gauss_multi_uncert(self):
        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-6, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 3 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        with catch_warnings() as w:
            # The assertion below checks if there is only one warning raised
            # and whether it contains a specific message from pyresample
            # On python 2.7.9+ the resample_gauss method raises multiple deprecation warnings
            # that cause to fail, so we ignore the unrelated warnings.
            res, stddev, counts = kd_tree.resample_gauss(swath_def,
                                                         data_multi,
                                                         self.area_def,
                                                         50000,
                                                         [25000, 15000, 10000],
                                                         segments=1,
                                                         with_uncert=True)
            self.assertTrue(
                len(w) >= 1, 'Failed to create neighbour radius warning')
            self.assertTrue(
                any(['Possible more' in str(x.message) for x in w]),
                'Failed to create correct neighbour radius warning')
        cross_sum = res.sum()
        cross_sum_counts = counts.sum()
        expected = 1461.84313918
        expected_stddev = [0.446193170875, 0.443606880035, 0.438586349519]
        expected_counts = 4934802.0
        self.assertTrue(res.shape == stddev.shape
                        and stddev.shape == counts.shape
                        and counts.shape == (800, 800, 3))
        self.assertAlmostEqual(
            cross_sum,
            expected,
            msg='Swath multi channel resampling gauss failed on data')
        for i, e_stddev in enumerate(expected_stddev):
            cross_sum_stddev = stddev[:, :, i].sum()
            print(cross_sum_stddev, e_stddev)
            self.assertAlmostEqual(
                cross_sum_stddev,
                e_stddev,
                msg=
                'Swath multi channel resampling gauss failed on stddev (channel {})'
                .format(i))
        self.assertAlmostEqual(
            cross_sum_counts,
            expected_counts,
            msg='Swath multi channel resampling gauss failed on counts')

    def test_gauss_multi_mp(self):
        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-6, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 3 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        with catch_warnings() as w:
            res = kd_tree.resample_gauss(swath_def,
                                         data_multi,
                                         self.area_def,
                                         50000, [25000, 15000, 10000],
                                         nprocs=2,
                                         segments=1)
            self.assertFalse(
                len(w) != 1, 'Failed to create neighbour radius warning')
            self.assertFalse(
                ('Possible more' not in str(w[0].message)),
                'Failed to create correct neighbour radius warning')
        cross_sum = res.sum()
        expected = 1461.84313918
        self.assertAlmostEqual(
            cross_sum,
            expected,
            msg='Swath multi channel resampling gauss failed')

    def test_gauss_multi_mp_segments(self):
        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-6, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 3 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        with catch_warnings() as w:
            res = kd_tree.resample_gauss(swath_def,
                                         data_multi,
                                         self.area_def,
                                         50000, [25000, 15000, 10000],
                                         nprocs=2,
                                         segments=1)
            self.assertFalse(
                len(w) != 1, 'Failed to create neighbour radius warning')
            self.assertFalse(
                ('Possible more' not in str(w[0].message)),
                'Failed to create correct neighbour radius warning')
        cross_sum = res.sum()
        expected = 1461.84313918
        self.assertAlmostEqual(
            cross_sum,
            expected,
            msg='Swath multi channel segments resampling gauss failed')

    def test_gauss_multi_mp_segments_empty(self):
        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-6, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 165 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        res = kd_tree.resample_gauss(swath_def,
                                     data_multi,
                                     self.area_def,
                                     50000, [25000, 15000, 10000],
                                     nprocs=2,
                                     segments=1)
        cross_sum = res.sum()
        self.assertTrue(cross_sum == 0,
                        msg=('Swath multi channel segments empty '
                             'resampling gauss failed'))

    def test_custom(self):
        def wf(dist):
            return 1 - dist / 100000.0

        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-5, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 3 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        with catch_warnings() as w:
            res = kd_tree.resample_custom(swath_def,
                                          data.ravel(),
                                          self.area_def,
                                          50000,
                                          wf,
                                          segments=1)
            self.assertFalse(
                len(w) != 1, 'Failed to create neighbour radius warning')
            self.assertFalse(
                ('Possible more' not in str(w[0].message)),
                'Failed to create correct neighbour radius warning')
        cross_sum = res.sum()
        expected = 4872.81050729
        self.assertAlmostEqual(cross_sum,
                               expected,
                               msg='Swath custom resampling failed')

    def test_custom_multi(self):
        def wf1(dist):
            return 1 - dist / 100000.0

        def wf2(dist):
            return 1

        def wf3(dist):
            return numpy.cos(dist)**2

        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-6, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 3 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        with catch_warnings() as w:
            res = kd_tree.resample_custom(swath_def,
                                          data_multi,
                                          self.area_def,
                                          50000, [wf1, wf2, wf3],
                                          segments=1)
            self.assertFalse(
                len(w) != 1, 'Failed to create neighbour radius warning')
            self.assertFalse(
                ('Possible more' not in str(w[0].message)),
                'Failed to create correct neighbour radius warning')
        cross_sum = res.sum()
        expected = 1461.842980746
        self.assertAlmostEqual(
            cross_sum,
            expected,
            msg='Swath multi channel custom resampling failed')

    def test_reduce(self):
        data = numpy.fromfunction(lambda y, x: (y + x), (1000, 1000))
        lons = numpy.fromfunction(lambda y, x: -180 + (360.0 / 1000) * x,
                                  (1000, 1000))
        lats = numpy.fromfunction(lambda y, x: -90 + (180.0 / 1000) * y,
                                  (1000, 1000))
        grid_lons, grid_lats = self.area_def.get_lonlats()
        lons, lats, data = data_reduce.swath_from_lonlat_grid(
            grid_lons, grid_lats, lons, lats, data, 7000)
        cross_sum = data.sum()
        expected = 20514375.0
        self.assertAlmostEqual(cross_sum, expected, msg='Reduce data failed')

    def test_reduce_boundary(self):
        data = numpy.fromfunction(lambda y, x: (y + x), (1000, 1000))
        lons = numpy.fromfunction(lambda y, x: -180 + (360.0 / 1000) * x,
                                  (1000, 1000))
        lats = numpy.fromfunction(lambda y, x: -90 + (180.0 / 1000) * y,
                                  (1000, 1000))
        boundary_lonlats = self.area_def.get_boundary_lonlats()
        lons, lats, data = data_reduce.swath_from_lonlat_boundaries(
            boundary_lonlats[0], boundary_lonlats[1], lons, lats, data, 7000)
        cross_sum = data.sum()
        expected = 20514375.0
        self.assertAlmostEqual(cross_sum, expected, msg='Reduce data failed')

    def test_cartesian_reduce(self):
        data = numpy.fromfunction(lambda y, x: (y + x), (1000, 1000))
        lons = numpy.fromfunction(lambda y, x: -180 + (360.0 / 1000) * x,
                                  (1000, 1000))
        lats = numpy.fromfunction(lambda y, x: -90 + (180.0 / 1000) * y,
                                  (1000, 1000))
        #grid = utils.generate_cartesian_grid(self.area_def)
        grid = self.area_def.get_cartesian_coords()
        lons, lats, data = data_reduce.swath_from_cartesian_grid(
            grid, lons, lats, data, 7000)
        cross_sum = data.sum()
        expected = 20514375.0
        self.assertAlmostEqual(cross_sum,
                               expected,
                               msg='Cartesian reduce data failed')

    def test_area_con_reduce(self):
        data = numpy.fromfunction(lambda y, x: (y + x), (1000, 1000))
        lons = numpy.fromfunction(lambda y, x: -180 + (360.0 / 1000) * x,
                                  (1000, 1000))
        lats = numpy.fromfunction(lambda y, x: -90 + (180.0 / 1000) * y,
                                  (1000, 1000))
        grid_lons, grid_lats = self.area_def.get_lonlats()
        valid_index = data_reduce.get_valid_index_from_lonlat_grid(
            grid_lons, grid_lats, lons, lats, 7000)
        data = data[valid_index]
        cross_sum = data.sum()
        expected = 20514375.0
        self.assertAlmostEqual(cross_sum, expected, msg='Reduce data failed')

    def test_area_con_cartesian_reduce(self):
        data = numpy.fromfunction(lambda y, x: (y + x), (1000, 1000))
        lons = numpy.fromfunction(lambda y, x: -180 + (360.0 / 1000) * x,
                                  (1000, 1000))
        lats = numpy.fromfunction(lambda y, x: -90 + (180.0 / 1000) * y,
                                  (1000, 1000))
        cart_grid = self.area_def.get_cartesian_coords()
        valid_index = data_reduce.get_valid_index_from_cartesian_grid(
            cart_grid, lons, lats, 7000)
        data = data[valid_index]
        cross_sum = data.sum()
        expected = 20514375.0
        self.assertAlmostEqual(cross_sum,
                               expected,
                               msg='Cartesian reduce data failed')

    def test_masked_nearest(self):
        data = numpy.ones((50, 10))
        data[:, 5:] = 2
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        mask = numpy.ones((50, 10))
        mask[:, :5] = 0
        masked_data = numpy.ma.array(data, mask=mask)
        res = kd_tree.resample_nearest(swath_def,
                                       masked_data.ravel(),
                                       self.area_def,
                                       50000,
                                       segments=1)
        expected_mask = numpy.fromfile(os.path.join(
            os.path.dirname(__file__), 'test_files',
            'mask_test_nearest_mask.dat'),
                                       sep=' ').reshape((800, 800))
        expected_data = numpy.fromfile(os.path.join(
            os.path.dirname(__file__), 'test_files',
            'mask_test_nearest_data.dat'),
                                       sep=' ').reshape((800, 800))
        self.assertTrue(numpy.array_equal(expected_mask, res.mask),
                        msg='Resampling of swath mask failed')
        self.assertTrue(numpy.array_equal(expected_data, res.data),
                        msg='Resampling of swath masked data failed')

    def test_masked_nearest_1d(self):
        data = numpy.ones((800, 800))
        data[:400, :] = 2
        lons = numpy.fromfunction(lambda x: 3 + x / 100., (500, ))
        lats = numpy.fromfunction(lambda x: 75 - x / 10., (500, ))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        mask = numpy.ones((800, 800))
        mask[400:, :] = 0
        masked_data = numpy.ma.array(data, mask=mask)
        res = kd_tree.resample_nearest(self.area_def,
                                       masked_data.ravel(),
                                       swath_def,
                                       50000,
                                       segments=1)
        self.assertEqual(res.mask.sum(),
                         108,
                         msg='Swath resampling masked nearest 1d failed')

    def test_masked_gauss(self):
        data = numpy.ones((50, 10))
        data[:, 5:] = 2
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        mask = numpy.ones((50, 10))
        mask[:, :5] = 0
        masked_data = numpy.ma.array(data, mask=mask)
        res = kd_tree.resample_gauss(swath_def,
                                     masked_data.ravel(),
                                     self.area_def,
                                     50000,
                                     25000,
                                     segments=1)
        expected_mask = numpy.fromfile(os.path.join(os.path.dirname(__file__),
                                                    'test_files',
                                                    'mask_test_mask.dat'),
                                       sep=' ').reshape((800, 800))
        expected_data = numpy.fromfile(os.path.join(os.path.dirname(__file__),
                                                    'test_files',
                                                    'mask_test_data.dat'),
                                       sep=' ').reshape((800, 800))
        expected = expected_data.sum()
        cross_sum = res.data.sum()

        self.assertTrue(numpy.array_equal(expected_mask, res.mask),
                        msg='Gauss resampling of swath mask failed')
        self.assertAlmostEqual(
            cross_sum,
            expected,
            places=3,
            msg='Gauss resampling of swath masked data failed')

    def test_masked_fill_float(self):
        data = numpy.ones((50, 10))
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       data.ravel(),
                                       self.area_def,
                                       50000,
                                       fill_value=None,
                                       segments=1)
        expected_fill_mask = numpy.fromfile(os.path.join(
            os.path.dirname(__file__), 'test_files',
            'mask_test_fill_value.dat'),
                                            sep=' ').reshape((800, 800))
        fill_mask = res.mask
        self.assertTrue(numpy.array_equal(fill_mask, expected_fill_mask),
                        msg='Failed to create fill mask on float data')

    def test_masked_fill_int(self):
        data = numpy.ones((50, 10)).astype('int')
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       data.ravel(),
                                       self.area_def,
                                       50000,
                                       fill_value=None,
                                       segments=1)
        expected_fill_mask = numpy.fromfile(os.path.join(
            os.path.dirname(__file__), 'test_files',
            'mask_test_fill_value.dat'),
                                            sep=' ').reshape((800, 800))
        fill_mask = res.mask
        self.assertTrue(numpy.array_equal(fill_mask, expected_fill_mask),
                        msg='Failed to create fill mask on integer data')

    def test_masked_full(self):
        data = numpy.ones((50, 10))
        data[:, 5:] = 2
        mask = numpy.ones((50, 10))
        mask[:, :5] = 0
        masked_data = numpy.ma.array(data, mask=mask)
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       masked_data.ravel(),
                                       self.area_def,
                                       50000,
                                       fill_value=None,
                                       segments=1)
        expected_fill_mask = numpy.fromfile(os.path.join(
            os.path.dirname(__file__), 'test_files',
            'mask_test_full_fill.dat'),
                                            sep=' ').reshape((800, 800))
        fill_mask = res.mask

        self.assertTrue(numpy.array_equal(fill_mask, expected_fill_mask),
                        msg='Failed to create fill mask on masked data')

    def test_masked_full_multi(self):
        data = numpy.ones((50, 10))
        data[:, 5:] = 2
        mask1 = numpy.ones((50, 10))
        mask1[:, :5] = 0
        mask2 = numpy.ones((50, 10))
        mask2[:, 5:] = 0
        mask3 = numpy.ones((50, 10))
        mask3[:25, :] = 0
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        mask_multi = numpy.column_stack(
            (mask1.ravel(), mask2.ravel(), mask3.ravel()))
        masked_data = numpy.ma.array(data_multi, mask=mask_multi)
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        res = kd_tree.resample_nearest(swath_def,
                                       masked_data,
                                       self.area_def,
                                       50000,
                                       fill_value=None,
                                       segments=1)
        expected_fill_mask = numpy.fromfile(os.path.join(
            os.path.dirname(__file__), 'test_files',
            'mask_test_full_fill_multi.dat'),
                                            sep=' ').reshape((800, 800, 3))
        fill_mask = res.mask
        cross_sum = res.sum()
        expected = 357140.0
        self.assertAlmostEqual(cross_sum,
                               expected,
                               msg='Failed to resample masked data')
        self.assertTrue(numpy.array_equal(fill_mask, expected_fill_mask),
                        msg='Failed to create fill mask on masked data')

    def test_dtype(self):
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        grid_def = geometry.GridDefinition(lons, lats)
        lons = numpy.asarray(lons, dtype='f4')
        lats = numpy.asarray(lats, dtype='f4')
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        valid_input_index, valid_output_index, index_array, distance_array = \
            kd_tree.get_neighbour_info(swath_def,
                                       grid_def,
                                       50000, neighbours=1, segments=1)

    def test_nearest_from_sample(self):
        data = numpy.fromfunction(lambda y, x: y * x, (50, 10))
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        valid_input_index, valid_output_index, index_array, distance_array = \
            kd_tree.get_neighbour_info(swath_def,
                                       self.area_def,
                                       50000, neighbours=1, segments=1)
        res = kd_tree.get_sample_from_neighbour_info('nn', (800, 800),
                                                     data.ravel(),
                                                     valid_input_index,
                                                     valid_output_index,
                                                     index_array)
        cross_sum = res.sum()
        expected = 15874591.0
        self.assertEqual(
            cross_sum,
            expected,
            msg='Swath resampling from neighbour info nearest failed')

    def test_custom_multi_from_sample(self):
        def wf1(dist):
            return 1 - dist / 100000.0

        def wf2(dist):
            return 1

        def wf3(dist):
            return numpy.cos(dist)**2

        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-6, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 3 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))

        with catch_warnings() as w:
            valid_input_index, valid_output_index, index_array, distance_array = \
                kd_tree.get_neighbour_info(swath_def,
                                           self.area_def,
                                           50000, segments=1)
            self.assertFalse(
                len(w) != 1, 'Failed to create neighbour radius warning')
            self.assertFalse(
                ('Possible more' not in str(w[0].message)),
                'Failed to create correct neighbour radius warning')

        res = kd_tree.get_sample_from_neighbour_info(
            'custom', (800, 800),
            data_multi,
            valid_input_index,
            valid_output_index,
            index_array,
            distance_array,
            weight_funcs=[wf1, wf2, wf3])

        cross_sum = res.sum()

        expected = 1461.842980746
        self.assertAlmostEqual(
            cross_sum,
            expected,
            msg=
            'Swath multi channel custom resampling from neighbour info failed 1'
        )
        res = kd_tree.get_sample_from_neighbour_info(
            'custom', (800, 800),
            data_multi,
            valid_input_index,
            valid_output_index,
            index_array,
            distance_array,
            weight_funcs=[wf1, wf2, wf3])

        # Look for error where input data has been manipulated
        cross_sum = res.sum()
        expected = 1461.842980746
        self.assertAlmostEqual(
            cross_sum,
            expected,
            msg=
            'Swath multi channel custom resampling from neighbour info failed 2'
        )

    def test_masked_multi_from_sample(self):
        data = numpy.ones((50, 10))
        data[:, 5:] = 2
        mask1 = numpy.ones((50, 10))
        mask1[:, :5] = 0
        mask2 = numpy.ones((50, 10))
        mask2[:, 5:] = 0
        mask3 = numpy.ones((50, 10))
        mask3[:25, :] = 0
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))
        mask_multi = numpy.column_stack(
            (mask1.ravel(), mask2.ravel(), mask3.ravel()))
        masked_data = numpy.ma.array(data_multi, mask=mask_multi)
        lons = numpy.fromfunction(lambda y, x: 3 + x, (50, 10))
        lats = numpy.fromfunction(lambda y, x: 75 - y, (50, 10))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        valid_input_index, valid_output_index, index_array, distance_array = \
            kd_tree.get_neighbour_info(swath_def,
                                       self.area_def,
                                       50000, neighbours=1, segments=1)
        res = kd_tree.get_sample_from_neighbour_info('nn', (800, 800),
                                                     masked_data,
                                                     valid_input_index,
                                                     valid_output_index,
                                                     index_array,
                                                     fill_value=None)
        expected_fill_mask = numpy.fromfile(os.path.join(
            os.path.dirname(__file__), 'test_files',
            'mask_test_full_fill_multi.dat'),
                                            sep=' ').reshape((800, 800, 3))
        fill_mask = res.mask
        self.assertTrue(numpy.array_equal(fill_mask, expected_fill_mask),
                        msg='Failed to create fill mask on masked data')
Exemple #21
0
def SDR2Geotiff(HDF, output_dir, areaid, radius):
    radiance, qf1_viirsdnbsdr, qf2_scan_sdr, lon_data, lat_data, LunarZenithAngle, qf2_viirssdrgeo, qf2_viirssdrgeo_tc = readhdfDatasets(
        HDF)
    HDF = ntpath.basename(HDF)  #get filename without path

    #QF Flags from https://ncc.nesdis.noaa.gov/documents/documentation/viirs-sdr-dataformat.pdf

    #1.VIIRS Fill Values (p.70)
    radiance_fillvalues = np.array([-999.3, -999.5, -999.8, -999.9])
    radiance_mask = np.isin(radiance, radiance_fillvalues)

    #2.Edge-of-swath pixels
    edge_of_swath_mask = np.zeros_like(radiance, dtype='bool')
    edge_of_swath_mask[:, 0:254] = 1
    edge_of_swath_mask[:, 3810:4064] = 1

    #3.QF1_VIIRSDNBSDR flags (p.73)
    #SDR_Quality_mask     = (qf1_viirsdnbsdr & 3)>0
    Saturated_Pixel_mask = ((qf1_viirsdnbsdr & 12) >> 2) > 0
    Missing_Data_mask = ((qf1_viirsdnbsdr & 48) >> 4) > 0
    Out_of_Range_mask = ((qf1_viirsdnbsdr & 64) >> 6) > 0

    #4.QF2_VIIRSSDRGEO flags (p.90)

    qf2_viirssdrgeo_do0_mask = (qf2_viirssdrgeo & 1) > 0
    qf2_viirssdrgeo_do1_mask = ((qf2_viirssdrgeo & 2) >> 1) > 0
    qf2_viirssdrgeo_do2_mask = ((qf2_viirssdrgeo & 4) >> 2) > 0
    qf2_viirssdrgeo_do3_mask = ((qf2_viirssdrgeo & 8) >> 3) > 0

    #Combine pixel level flags
    viirs_mask = np.logical_or.reduce((
        radiance_mask,
        edge_of_swath_mask,
        #SDR_Quality_mask,
        Saturated_Pixel_mask,
        Missing_Data_mask,
        Out_of_Range_mask,
        qf2_viirssdrgeo_do0_mask,
        qf2_viirssdrgeo_do1_mask,
        qf2_viirssdrgeo_do2_mask,
        qf2_viirssdrgeo_do3_mask,
    ))

    fill_value = 255.0
    radiance[viirs_mask] = fill_value  #set fill value for masked pixels in DNB
    LunarZenithAngle[
        viirs_mask] = fill_value  #set fill value for masked pixels in DNB

    swath_def = geometry.SwathDefinition(
        xr.DataArray(da.from_array(lon_data, chunks=4096), dims=('y', 'x')),
        xr.DataArray(da.from_array(lat_data, chunks=4096), dims=('y', 'x')))

    metadata_dict = {'name': 'dnb', 'area': swath_def}

    scn = Scene()
    scn['Radiance'] = xr.DataArray(
        da.from_array(radiance, chunks=4096),
        attrs=metadata_dict,
        dims=('y', 'x')
    )  #https://satpy.readthedocs.io/en/latest/dev_guide/xarray_migration.html#id1

    scn['LunarZenithAngle'] = xr.DataArray(da.from_array(LunarZenithAngle,
                                                         chunks=4096),
                                           attrs=metadata_dict,
                                           dims=('y', 'x'))

    scn.load(["Radiance"])
    scn.load(["LunarZenithAngle"])
    #print(scn)

    proj_scn = scn.resample(areaSettings.getarea(areaid),
                            radius_of_influence=radius)

    proj_scn.save_datasets(writer='geotiff',
                           base_dir=output_dir,
                           file_pattern="{}.{}.{}".format(
                               HDF, "{name}", "tif"),
                           enhancement_config=False,
                           dtype=np.float32,
                           fill_value=fill_value)
Exemple #22
0
    def test_custom_multi_from_sample(self):
        def wf1(dist):
            return 1 - dist / 100000.0

        def wf2(dist):
            return 1

        def wf3(dist):
            return numpy.cos(dist)**2

        data = numpy.fromfunction(lambda y, x: (y + x) * 10**-6, (5000, 100))
        lons = numpy.fromfunction(lambda y, x: 3 + (10.0 / 100) * x,
                                  (5000, 100))
        lats = numpy.fromfunction(lambda y, x: 75 - (50.0 / 5000) * y,
                                  (5000, 100))
        swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
        data_multi = numpy.column_stack(
            (data.ravel(), data.ravel(), data.ravel()))

        with catch_warnings() as w:
            valid_input_index, valid_output_index, index_array, distance_array = \
                kd_tree.get_neighbour_info(swath_def,
                                           self.area_def,
                                           50000, segments=1)
            self.assertFalse(
                len(w) != 1, 'Failed to create neighbour radius warning')
            self.assertFalse(
                ('Possible more' not in str(w[0].message)),
                'Failed to create correct neighbour radius warning')

        res = kd_tree.get_sample_from_neighbour_info(
            'custom', (800, 800),
            data_multi,
            valid_input_index,
            valid_output_index,
            index_array,
            distance_array,
            weight_funcs=[wf1, wf2, wf3])

        cross_sum = res.sum()

        expected = 1461.842980746
        self.assertAlmostEqual(
            cross_sum,
            expected,
            msg=
            'Swath multi channel custom resampling from neighbour info failed 1'
        )
        res = kd_tree.get_sample_from_neighbour_info(
            'custom', (800, 800),
            data_multi,
            valid_input_index,
            valid_output_index,
            index_array,
            distance_array,
            weight_funcs=[wf1, wf2, wf3])

        # Look for error where input data has been manipulated
        cross_sum = res.sum()
        expected = 1461.842980746
        self.assertAlmostEqual(
            cross_sum,
            expected,
            msg=
            'Swath multi channel custom resampling from neighbour info failed 2'
        )
Exemple #23
0
def resample_to_grid_only_valid_return(input_data,
                                       src_lon,
                                       src_lat,
                                       target_lon,
                                       target_lat,
                                       methods='nn',
                                       weight_funcs=None,
                                       min_neighbours=1,
                                       search_rad=18000,
                                       neighbours=8,
                                       fill_values=None):
    """
    resamples data from dictionary of numpy arrays using pyresample
    to given grid.
    Searches for the neighbours and then resamples the data
    to the grid given in togrid if at least
    min_neighbours neighbours are found

    Parameters
    ----------
    input_data : dict of numpy.arrays
    src_lon : numpy.array
        longitudes of the input data
    src_lat : numpy.array
        src_latitudes of the input data
    target_lon : numpy.array
        longitudes of the output data
    target_src_lat : numpy.array
        src_latitudes of the output data
    methods : string or dict, optional
        method of spatial averaging. this is given to pyresample
        and can be
        'nn' : nearest neighbour
        'custom' : custom weight function has to be supplied in weight_funcs
        see pyresample documentation for more details
        can also be a dictionary with a method for each array in input data dict
    weight_funcs : function or dict of functions, optional
        if method is 'custom' a function like func(distance) has to be given
        can also be a dictionary with a function for each array in input data dict
    min_neighbours: int, optional
        if given then only points with at least this number of neighbours will be
        resampled
        Default : 1
    search_rad : float, optional
        search radius in meters of neighbour search
        Default : 18000
    neighbours : int, optional
        maximum number of neighbours to look for for each input grid point
        Default : 8
    fill_values : number or dict, optional
        if given the output array will be filled with this value if no valid
        resampled value could be computed, if not a masked array will be returned
        can also be a dict with a fill value for each variable
    Returns
    -------
    data : dict of numpy.arrays
        resampled data on part of the target grid over which data was found
    mask: numpy.ndarray
        boolean mask into target grid that specifies where data was resampled

    Raises
    ------
    ValueError :
        if empty dataset is resampled
    """
    output_data = {}

    if target_lon.ndim == 2:
        target_lat = target_lat.ravel()
        target_lon = target_lon.ravel()

    input_swath = geometry.SwathDefinition(src_lon, src_lat)
    output_swath = geometry.SwathDefinition(target_lon, target_lat)

    (valid_input_index, valid_output_index, index_array,
     distance_array) = kd_tree.get_neighbour_info(input_swath,
                                                  output_swath,
                                                  search_rad,
                                                  neighbours=neighbours)

    # throw away points with less than min_neighbours neighbours
    # find points with valid neighbours
    # get number of found neighbours for each grid point/row
    if neighbours > 1:
        nr_neighbours = np.isfinite(distance_array).sum(1)
        neigh_condition = nr_neighbours >= min_neighbours
        mask = np.invert(neigh_condition)
        enough_neighbours = np.nonzero(neigh_condition)[0]
    if neighbours == 1:
        nr_neighbours = np.isfinite(distance_array)
        neigh_condition = nr_neighbours >= min_neighbours
        mask = np.invert(neigh_condition)
        enough_neighbours = np.nonzero(neigh_condition)[0]
        distance_array = np.reshape(distance_array,
                                    (distance_array.shape[0], 1))
        index_array = np.reshape(index_array, (index_array.shape[0], 1))

    if enough_neighbours.size == 0:
        raise ValueError("No points with at least %d neighbours found" %
                         min_neighbours)

    # remove neighbourhood info of input grid points that have no neighbours to not have to
    # resample to whole output grid for small input grid file
    distance_array = distance_array[enough_neighbours, :]
    index_array = index_array[enough_neighbours, :]
    valid_output_index = valid_output_index[enough_neighbours]

    for param in input_data:

        data = input_data[param]

        if type(methods) == dict:
            method = methods[param]
        else:
            method = methods

        if method is not 'nn':
            if type(weight_funcs) == dict:
                weight_func = weight_funcs[param]
            else:
                weight_func = weight_funcs
        else:
            weight_func = None

        neigh_slice = slice(None, None, None)
        # check if method is nn, if so only use first row of index_array and
        # distance_array
        if method == 'nn':
            neigh_slice = (slice(None, None, None), 0)

        if type(fill_values) == dict:
            fill_value = fill_values[param]
        else:
            fill_value = fill_values

        output_array = kd_tree.get_sample_from_neighbour_info(
            method,
            enough_neighbours.shape,
            data,
            valid_input_index,
            valid_output_index,
            index_array[neigh_slice],
            distance_array[neigh_slice],
            weight_funcs=weight_func,
            fill_value=fill_value)

        output_data[param] = output_array

    return output_data, mask
Exemple #24
0
    def load(self, keys):
        """Read data from file and return the corresponding projectables.
        """
        datadict = {
            1000: ['EV_250_Aggr1km_RefSB',
                   'EV_500_Aggr1km_RefSB',
                   'EV_1KM_RefSB',
                   'EV_1KM_Emissive'],
            500: ['EV_250_Aggr500_RefSB',
                  'EV_500_RefSB'],
            250: ['EV_250_RefSB']}

        projectables = []
        platform_name = self.mda['INVENTORYMETADATA']['ASSOCIATEDPLATFORMINSTRUMENTSENSOR'][
            'ASSOCIATEDPLATFORMINSTRUMENTSENSORCONTAINER']['ASSOCIATEDPLATFORMSHORTNAME']['VALUE']

        keys = [key for key in keys if key.resolution == self.resolution]
        if len(keys) == 0:
            logger.debug("Nothing to read in %s.", self.filename)
            return projectables
        datasets = datadict[self.resolution]
        key_names = [key.name for key in keys]
        for dataset in datasets:
            subdata = self.sd.select(dataset)
            band_names = subdata.attributes()["band_names"].split(",")

            if len(set(key_names) & set(band_names)) > 0:
                # get the relative indices of the desired channels
                indices = [i for i, band in enumerate(band_names)
                           if band in key_names]
                uncertainty = self.sd.select(dataset + "_Uncert_Indexes")
                if dataset.endswith('Emissive'):
                    array = calibrate_tb(
                        subdata, uncertainty, indices, band_names)
                else:
                    array = calibrate_refl(subdata, uncertainty, indices)
                for (i, idx) in enumerate(indices):
                    dsid = [key for key in keys if key.name ==
                            band_names[idx]][0]
                    area = self.navigation_reader.get_lonlats(self.resolution)
                    projectable = Projectable(array[i], id=dsid, area=area)
                    if ((platform_name == 'Aqua' and dsid.name in ["6", "27", "36"]) or
                            (platform_name == 'Terra' and dsid.name in ["29"])):
                        height, width = projectable.shape
                        row_indices = projectable.mask.sum(1) == width
                        if row_indices.sum() == height:
                            continue
                        projectable.mask[indices, :] = True

                    projectables.append(projectable)
        return projectables

        # Get the orbit number
        if not satscene.orbit:
            mda = self.data.attributes()["CoreMetadata.0"]
            orbit_idx = mda.index("ORBITNUMBER")
            satscene.orbit = mda[orbit_idx + 111:orbit_idx + 116]

        # Get the geolocation
        # if resolution != 1000:
        #    logger.warning("Cannot load geolocation at this resolution (yet).")
        #    return

        for band_name in loaded_bands:
            lon, lat = self.get_lonlat(satscene[band_name].resolution, cores)
            area = geometry.SwathDefinition(lons=lon, lats=lat)
            satscene[band_name].area = area

        # Trimming out dead sensor lines (detectors) on aqua:
        # (in addition channel 21 is noisy)
        if satscene.satname == "aqua":
            for band in ["6", "27", "36"]:
                if not satscene[band].is_loaded() or satscene[band].data.mask.all():
                    continue
                width = satscene[band].data.shape[1]
                height = satscene[band].data.shape[0]
                indices = satscene[band].data.mask.sum(1) < width
                if indices.sum() == height:
                    continue
                satscene[band] = satscene[band].data[indices, :]
                satscene[band].area = geometry.SwathDefinition(
                    lons=satscene[band].area.lons[indices, :],
                    lats=satscene[band].area.lats[indices, :])

        # Trimming out dead sensor lines (detectors) on terra:
        # (in addition channel 27, 30, 34, 35, and 36 are nosiy)
        if satscene.satname == "terra":
            for band in ["29"]:
                if not satscene[band].is_loaded() or satscene[band].data.mask.all():
                    continue
                width = satscene[band].data.shape[1]
                height = satscene[band].data.shape[0]
                indices = satscene[band].data.mask.sum(1) < width
                if indices.sum() == height:
                    continue
                satscene[band] = satscene[band].data[indices, :]
                satscene[band].area = geometry.SwathDefinition(
                    lons=satscene[band].area.lons[indices, :],
                    lats=satscene[band].area.lats[indices, :])

        for band_name in loaded_bands:
            band_uid = hashlib.sha1(satscene[band_name].data.mask).hexdigest()
            satscene[band_name].area.area_id = ("swath_" + satscene.fullname + "_"
                                                + str(satscene.time_slot) + "_"
                                                +
                                                str(satscene[
                                                    band_name].shape) + "_"
                                                + str(band_uid))
            satscene[band_name].area_id = satscene[band_name].area.area_id
Exemple #25
0
def load_generic(satscene, filename, resolution, cores):
    """Read modis data, generic part.
    """

    try:
        data = SD(str(filename))
    except HDF4Error as err:
        logger.warning("Could not load data from " + str(filename)
                       + ": " + str(err))
        return

    datadict = {
        1000: ['EV_250_Aggr1km_RefSB',
               'EV_500_Aggr1km_RefSB',
               'EV_1KM_RefSB',
               'EV_1KM_Emissive'],
        500: ['EV_250_Aggr500_RefSB',
              'EV_500_RefSB'],
        250: ['EV_250_RefSB']}

    datasets = datadict[resolution]

    loaded_bands = []

    # process by dataset, reflective and emissive datasets separately

    for dataset in datasets:
        subdata = data.select(dataset)
        band_names = subdata.attributes()["band_names"].split(",")
        if len(satscene.channels_to_load & set(band_names)) > 0:
            # get the relative indices of the desired channels
            indices = [i for i, band in enumerate(band_names)
                       if band in satscene.channels_to_load]
            uncertainty = data.select(dataset + "_Uncert_Indexes")
            if dataset.endswith('Emissive'):
                array = calibrate_tb(subdata, uncertainty, indices, band_names)
            else:
                array = calibrate_refl(subdata, uncertainty, indices)
            for (i, idx) in enumerate(indices):
                satscene[band_names[idx]] = array[i]
                # fix the resolution to match the loaded data.
                satscene[band_names[idx]].resolution = resolution
                loaded_bands.append(band_names[idx])

    # Get the orbit number
    if not satscene.orbit:
        mda = data.attributes()["CoreMetadata.0"]
        orbit_idx = mda.index("ORBITNUMBER")
        satscene.orbit = int(mda[orbit_idx + 111:orbit_idx + 116])

    # Get the geolocation
    # if resolution != 1000:
    #    logger.warning("Cannot load geolocation at this resolution (yet).")
    #    return

    lat, lon = get_lat_lon(satscene, resolution, filename, cores)
    area = geometry.SwathDefinition(lons=lon, lats=lat)
    for band_name in loaded_bands:
        satscene[band_name].area = area

    # Trimming out dead sensor lines (detectors) on aqua:
    # (in addition channel 21 is noisy)
    if satscene.satname == "aqua":
        for band in ["6", "27", "36"]:
            if not satscene[band].is_loaded() or satscene[band].data.mask.all():
                continue
            width = satscene[band].data.shape[1]
            height = satscene[band].data.shape[0]
            indices = satscene[band].data.mask.sum(1) < width
            if indices.sum() == height:
                continue
            satscene[band] = satscene[band].data[indices, :]
            satscene[band].area = geometry.SwathDefinition(
                lons=satscene[band].area.lons[indices, :],
                lats=satscene[band].area.lats[indices, :])
            satscene[band].area.area_id = ("swath_" + satscene.fullname + "_"
                                           + str(satscene.time_slot) + "_"
                                           + str(satscene[band].shape) + "_"
                                           + str(band))

    # Trimming out dead sensor lines (detectors) on terra:
    # (in addition channel 27, 30, 34, 35, and 36 are nosiy)
    if satscene.satname == "terra":
        for band in ["29"]:
            if not satscene[band].is_loaded() or satscene[band].data.mask.all():
                continue
            width = satscene[band].data.shape[1]
            height = satscene[band].data.shape[0]
            indices = satscene[band].data.mask.sum(1) < width
            if indices.sum() == height:
                continue
            satscene[band] = satscene[band].data[indices, :]
            satscene[band].area = geometry.SwathDefinition(
                lons=satscene[band].area.lons[indices, :],
                lats=satscene[band].area.lats[indices, :])
            satscene[band].area.area_id = ("swath_" + satscene.fullname + "_"
                                           + str(satscene.time_slot) + "_"
                                           + str(satscene[band].shape) + "_"
                                           + str(band))
Exemple #26
0
    def load(self, satscene, *args, **kwargs):
        """Read data from file and load it into *satscene*.
        """
        lonlat_is_loaded = False

        geofilename = kwargs.get('geofilename')
        prodfilename = kwargs.get('filename')

        products = []
        if "CTTH" in satscene.channels_to_load:
            products.append("ctth")
        if "CT" in satscene.channels_to_load:
            products.append("cloudtype")
        if "CMA" in satscene.channels_to_load:
            products.append("cloudmask")
        if "PC" in satscene.channels_to_load:
            products.append("precipclouds")
        if "CPP" in satscene.channels_to_load:
            products.append("cpp")

        if len(products) == 0:
            return

        try:
            area_name = satscene.area_id or satscene.area.area_id
        except AttributeError:
            area_name = "satproj_?????_?????"

        # Looking for geolocation file

        conf = ConfigParser()
        conf.read(os.path.join(CONFIG_PATH, satscene.fullname + ".cfg"))

        try:
            geodir = conf.get(satscene.instrument_name + "-level3",
                              "cloud_product_geodir",
                              vars=os.environ)
        except NoOptionError:
            LOG.warning("No option 'geodir' in level3 section")
            geodir = None

        if not geofilename and geodir:
            # Load geo file from config file:
            try:
                if not satscene.orbit:
                    orbit = ""
                else:
                    orbit = satscene.orbit
                geoname_tmpl = conf.get(satscene.instrument_name + "-level3",
                                        "cloud_product_geofilename",
                                        raw=True,
                                        vars=os.environ)
                filename_tmpl = (satscene.time_slot.strftime(geoname_tmpl)
                                 % {"orbit": str(orbit).zfill(5) or "*",
                                    "area": area_name,
                                    "satellite": satscene.satname + satscene.number})

                file_list = glob.glob(os.path.join(geodir, filename_tmpl))
                if len(file_list) > 1:
                    LOG.warning("More than 1 file matching for geoloaction: "
                                + str(file_list))
                elif len(file_list) == 0:
                    LOG.warning(
                        "No geolocation file matching!: "
                        + os.path.join(geodir, filename_tmpl))
                else:
                    geofilename = file_list[0]
            except NoOptionError:
                geofilename = None

        # Reading the products

        classes = {"ctth": CloudTopTemperatureHeight,
                   "cloudtype": CloudType,
                   "cloudmask": CloudMask,
                   "precipclouds": PrecipitationClouds,
                   "cpp": CloudPhysicalProperties
                   }

        nodata_mask = False

        area = None
        lons = None
        lats = None
        chn = None
        shape = None
        read_external_geo = {}
        for product in products:
            LOG.debug("Loading " + product)

            if isinstance(prodfilename, (list, tuple, set)):
                for fname in prodfilename:
                    kwargs['filename'] = fname
                    self.load(satscene, *args, **kwargs)
                return
            elif (prodfilename and
                  os.path.basename(prodfilename).startswith('S_NWC')):
                if os.path.basename(prodfilename).split("_")[2] == NEW_PRODNAMES[product]:
                    filename = prodfilename
                else:
                    continue
            else:
                filename = conf.get(satscene.instrument_name + "-level3",
                                    "cloud_product_filename",
                                    raw=True,
                                    vars=os.environ)
                directory = conf.get(satscene.instrument_name + "-level3",
                                     "cloud_product_dir",
                                     vars=os.environ)
                pathname_tmpl = os.path.join(directory, filename)
                LOG.debug("Path = " + str(pathname_tmpl))

                if not satscene.orbit:
                    orbit = ""
                else:
                    orbit = satscene.orbit

                filename_tmpl = (satscene.time_slot.strftime(pathname_tmpl)
                                 % {"orbit": str(orbit).zfill(5) or "*",
                                    "area": area_name,
                                    "satellite": satscene.satname + satscene.number,
                                    "product": product})

                file_list = glob.glob(filename_tmpl)
                if len(file_list) == 0:
                    product_name = NEW_PRODNAMES.get(product, product)
                    LOG.info("No " + str(product) +
                             " product in old format matching")
                    filename_tmpl = (satscene.time_slot.strftime(pathname_tmpl)
                                     % {"orbit": str(orbit).zfill(5) or "*",
                                        "area": area_name,
                                        "satellite": satscene.satname + satscene.number,
                                        "product": product_name})

                    file_list = glob.glob(filename_tmpl)

                if len(file_list) > 1:
                    LOG.warning("More than 1 file matching for " + product + "! "
                                + str(file_list))
                    continue
                elif len(file_list) == 0:
                    LOG.warning(
                        "No " + product + " matching!: " + filename_tmpl)
                    continue
                else:
                    filename = file_list[0]

            chn = classes[product]()
            chn.read(filename, lonlat_is_loaded == False)
            satscene.channels.append(chn)
            # Check if geolocation is loaded:
            if not chn.area:
                read_external_geo[product] = chn
                shape = chn.shape

        # Check if some 'channel'/product needs geolocation. If some product does
        # not have geolocation, get it from the geofilename:
        if not read_external_geo:
            LOG.info("Loading PPS parameters done.")
            return

        # Load geolocation
        interpolate = False
        if geofilename:
            geodict = get_lonlat(geofilename)
            lons, lats = geodict['lon'], geodict['lat']
            if lons.shape != shape or lats.shape != shape:
                interpolate = True
                row_indices = geodict['row_indices']
                column_indices = geodict['col_indices']

            lonlat_is_loaded = True
        else:
            LOG.warning("No Geo file specified: " +
                        "Geolocation will be loaded from product")

        if lonlat_is_loaded:
            if interpolate:
                from geotiepoints import SatelliteInterpolator

                cols_full = np.arange(shape[1])
                rows_full = np.arange(shape[0])

                satint = SatelliteInterpolator((lons, lats),
                                               (row_indices,
                                                column_indices),
                                               (rows_full, cols_full))
                # satint.fill_borders("y", "x")
                lons, lats = satint.interpolate()

            try:
                from pyresample import geometry
                lons = np.ma.masked_array(lons, nodata_mask)
                lats = np.ma.masked_array(lats, nodata_mask)
                area = geometry.SwathDefinition(lons=lons,
                                                lats=lats)
            except ImportError:
                area = None

        for chn in read_external_geo.values():
            if area:
                chn.area = area
            else:
                chn.lat = lats
                chn.lon = lons

        LOG.info("Loading PPS parameters done.")

        return