Example #1
0
def test_run():
    '''
    check if geo2rdr runs
    '''
    # prepare Geo2Rdr init params
    h5_path = os.path.join(iscetest.data, "envisat.h5")

    radargrid = isce.product.RadarGridParameters(h5_path)

    slc = SLC(hdf5file=h5_path)
    orbit = slc.getOrbit()
    doppler = slc.getDopplerCentroid()

    ellipsoid = isce.core.Ellipsoid()

    # init Geo2Rdr class
    geo2rdr_obj = isce.geometry.Geo2Rdr(radargrid,
                                        orbit,
                                        ellipsoid,
                                        doppler,
                                        threshold=1e-9,
                                        numiter=50)

    # load rdr2geo unit test output
    rdr2geo_raster = isce.io.Raster("topo.vrt")

    # run
    geo2rdr_obj.geo2rdr(rdr2geo_raster, ".")
Example #2
0
def test_run():
    '''
    check if topo runs
    '''
    # prepare Rdr2Geo init params
    h5_path = os.path.join(iscetest.data, "envisat.h5")

    radargrid = isce.product.RadarGridParameters(h5_path)

    slc = SLC(hdf5file=h5_path)
    orbit = slc.getOrbit()
    doppler = slc.getDopplerCentroid()

    ellipsoid = isce.core.Ellipsoid()

    # init Rdr2Geo class
    rdr2geo_obj = isce.cuda.geometry.Rdr2Geo(radargrid, orbit, ellipsoid,
                                             doppler)

    # load test DEM
    dem_raster = isce.io.Raster(os.path.join(iscetest.data,
                                             "srtm_cropped.tif"))

    # run
    rdr2geo_obj.topo(dem_raster, ".")
Example #3
0
def test_run():
    '''
    check if resamp runs
    '''
    # init params
    h5_path = os.path.join(iscetest.data, "envisat.h5")
    grid = isce3.product.RadarGridParameters(h5_path)
    slc = SLC(hdf5file=h5_path)

    # init resamp obj
    resamp = isce3.cuda.image.ResampSlc(grid, slc.getDopplerCentroid(),
                                        grid.wavelength)
    resamp.lines_per_tile = 249

    # prepare rasters
    h5_ds = f'//science/LSAR/SLC/swaths/frequencyA/HH'
    raster_ref = f'HDF5:{h5_path}:{h5_ds}'
    input_slc = isce3.io.Raster(raster_ref)

    az_off_raster = isce3.io.Raster(
        os.path.join(iscetest.data, "offsets/azimuth.off"))
    rg_off_raster = isce3.io.Raster(
        os.path.join(iscetest.data, "offsets/range.off"))

    output_slc = isce3.io.Raster('warped.slc', rg_off_raster.width,
                                 rg_off_raster.length, rg_off_raster.num_bands,
                                 gdal.GDT_CFloat32, 'ENVI')

    # run resamp
    resamp.resamp(input_slc, output_slc, rg_off_raster, az_off_raster)
Example #4
0
def test_point():
    # Subset of tests/cxx/isce3/geometry/geometry/geometry.cpp
    fn = os.path.join(iscetest.data, "envisat.h5")
    slc = SLC(hdf5file=fn)
    orbit = slc.getOrbit()
    subband = "A"
    doplut = slc.getDopplerCentroid(frequency=subband)
    grid = slc.getRadarGrid(frequency=subband)

    # First row of input_data.txt
    dt = isce.core.DateTime("2003-02-26T17:55:22.976222")
    r = 826988.6900674499
    h = 1777.

    dem = isce.geometry.DEMInterpolator(h)
    t = (dt - orbit.reference_epoch).total_seconds()
    dop = doplut.eval(t, r)
    wvl = grid.wavelength

    # native doppler, expect first row of output_data.txt
    llh = isce.geometry.rdr2geo(t, r, orbit, grid.lookside, dop, wvl, dem)
    assert np.isclose(np.degrees(llh[0]), -115.44101120961082)
    assert np.isclose(np.degrees(llh[1]), 35.28794014757191)
    assert np.isclose(llh[2], 1777.)

    # zero doppler, expect first row of output_data_zerodop.txt
    llh = isce.geometry.rdr2geo(t, r, orbit, grid.lookside, 0.0, dem=dem)
    assert np.isclose(np.degrees(llh[0]), -115.43883834023249)
    assert np.isclose(np.degrees(llh[1]), 35.29610867314526)
    assert np.isclose(llh[2], 1776.9999999993)
Example #5
0
def run(cfg):
    '''
    run rdr2geo
    '''
    # pull parameters from cfg
    input_hdf5 = cfg['InputFileGroup']['InputFilePath']
    dem_file = cfg['DynamicAncillaryFileGroup']['DEMFile']
    scratch_path = pathlib.Path(cfg['ProductPathGroup']['ScratchPath'])
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']

    # get params from SLC
    slc = SLC(hdf5file=input_hdf5)
    orbit = slc.getOrbit()

    # set defaults shared by both frequencies
    dem_raster = isce3.io.Raster(dem_file)
    epsg = dem_raster.get_epsg()
    proj = isce3.core.make_projection(epsg)
    ellipsoid = proj.ellipsoid

    # NISAR RSLC products are always zero doppler
    grid_doppler = isce3.core.LUT2d()

    info_channel = journal.info("rdr2geo.run")
    info_channel.log("starting geocode SLC")

    # check if gpu ok to use
    use_gpu = gpu_check.use_gpu(cfg['worker']['gpu_enabled'],
                                cfg['worker']['gpu_id'])
    if use_gpu:
        # Set the current CUDA device.
        device = isce3.cuda.core.Device(cfg['worker']['gpu_id'])
        isce3.cuda.core.set_device(device)

    t_all = time.time()
    for freq in freq_pols.keys():
        # get frequency specific parameters
        radargrid = slc.getRadarGrid(freq)

        # create seperate directory within scratch dir for rdr2geo run
        rdr2geo_scratch_path = scratch_path / 'rdr2geo' / f'freq{freq}'
        rdr2geo_scratch_path.mkdir(parents=True, exist_ok=True)

        # init CPU or CUDA object accordingly
        if use_gpu:
            Rdr2Geo = isce3.cuda.geometry.Rdr2Geo
        else:
            Rdr2Geo = isce3.geometry.Rdr2Geo

        rdr2geo_obj = Rdr2Geo(radargrid, orbit, ellipsoid, grid_doppler)

        # run
        rdr2geo_obj.topo(dem_raster, str(rdr2geo_scratch_path))

    t_all_elapsed = time.time() - t_all
    info_channel.log(f"successfully ran rdr2geo in {t_all_elapsed:.3f} seconds")
Example #6
0
def test_run():
    # load parameters shared across all test runs
    # init geocode object and populate members
    rslc = SLC(hdf5file=os.path.join(iscetest.data, "envisat.h5"))
    geo_obj = isce.geometry.GeocodeFloat64()
    geo_obj.orbit = rslc.getOrbit()
    geo_obj.doppler = rslc.getDopplerCentroid()
    geo_obj.ellipsoid = isce.core.Ellipsoid()
    geo_obj.threshold_geo2rdr = 1e-9
    geo_obj.num_iter_geo2rdr = 25
    geo_obj.lines_per_block = 1000
    geo_obj.dem_block_margin = 1e-1
    geo_obj.radar_block_margin = 10
    geo_obj.interpolator = 'biquintic'

    # prepare geogrid
    geogrid_start_x = -115.6
    geogrid_start_y = 34.832
    reduction_factor = 10
    geogrid_spacingX = reduction_factor * 0.0002
    geogrid_spacingY = reduction_factor * -8.0e-5
    geo_grid_length = int(380 / reduction_factor)
    geo_grid_width = int(400 / reduction_factor)
    epsgcode = 4326
    geo_obj.geogrid(geogrid_start_x, geogrid_start_y, geogrid_spacingX,
                    geogrid_spacingY, geo_grid_width, geo_grid_length,
                    epsgcode)

    # get radar grid from HDF5
    radar_grid = isce.product.RadarGridParameters(
        os.path.join(iscetest.data, "envisat.h5"))

    # load test DEM
    dem_raster = isce.io.Raster(
        os.path.join(iscetest.data, "geocode/zeroHeightDEM.geo"))

    # iterate thru axis
    for axis in input_axis:
        # load axis input raster
        input_raster = isce.io.Raster(
            os.path.join(iscetest.data, f"geocode/{axis}.rdr"))

        #  iterate thru geocode modes
        for key, value in geocode_modes.items():
            # prepare output raster
            output_path = f"{axis}_{key}.geo"
            output_raster = isce.io.Raster(output_path, geo_grid_width,
                                           geo_grid_length, 1,
                                           gdal.GDT_Float64, "ENVI")

            # geocode based on axis and mode
            geo_obj.geocode(radar_grid, input_raster, output_raster,
                            dem_raster, value)
Example #7
0
def test_run():
    '''
    run geocodeSlc bindings with same parameters as C++ test to make sure it does not crash
    '''
    # load h5 for doppler and orbit
    rslc = SLC(hdf5file=os.path.join(iscetest.data, "envisat.h5"))

    # define geogrid
    geogrid = isce.product.GeoGridParameters(start_x=-115.65,
        start_y=34.84,
        spacing_x=0.0002,
        spacing_y=-8.0e-5,
        width=500,
        length=500,
        epsg=4326)

    # define geotransform
    geotrans = [geogrid.start_x, geogrid.spacing_x, 0.0,
            geogrid.start_y, 0.0, geogrid.spacing_y]

    img_doppler = rslc.getDopplerCentroid()
    native_doppler = isce.core.LUT2d(img_doppler.x_start,
            img_doppler.y_start, img_doppler.x_spacing,
            img_doppler.y_spacing, np.zeros((geogrid.length,geogrid.width)))

    dem_raster = isce.io.Raster(os.path.join(iscetest.data, "geocode/zeroHeightDEM.geo"))

    radargrid = isce.product.RadarGridParameters(os.path.join(iscetest.data, "envisat.h5"))

    # geocode same 2 rasters as C++ version
    for xy in ['x', 'y']:
        out_raster = isce.io.Raster(f"{xy}.geo", geogrid.width, geogrid.length, 1,
                gdal.GDT_CFloat32, "ENVI")

        in_raster = isce.io.Raster(os.path.join(iscetest.data, f"geocodeslc/{xy}.slc"))

        isce.geocode.geocode_slc(output_raster=out_raster,
            input_raster=in_raster,
            dem_raster=dem_raster,
            radargrid=radargrid,
            geogrid=geogrid,
            orbit=rslc.getOrbit(),
            native_doppler=native_doppler,
            image_grid_doppler=img_doppler,
            ellipsoid=isce.core.Ellipsoid(),
            threshold_geo2rdr=1.0e-9,
            numiter_geo2rdr=25,
            lines_per_block=1000,
            dem_block_margin=0.1,
            flatten=False)

        out_raster.set_geotransform(geotrans)
Example #8
0
def common_crossmul_obj():
    '''
    instantiate and return common crossmul object for both run tests
    '''
    # make SLC object and extract parameters
    slc_obj = SLC(hdf5file=os.path.join(iscetest.data, 'envisat.h5'))
    dopp = isce.core.LUT1d(slc_obj.getDopplerCentroid())
    prf = slc_obj.getRadarGrid().prf

    crossmul = isce.signal.Crossmul()
    crossmul.set_dopplers(dopp, dopp)
    crossmul.set_az_filter(prf, 2000.0, 0.25)

    return crossmul
Example #9
0
    def prep_frequency_and_polarizations(self):
        '''
        check frequency and polarizations and fix as needed
        '''
        error_channel = journal.error(
            'RunConfig.prep_frequency_and_polarizations')
        input_path = self.cfg['InputFileGroup']['InputFilePath']
        freq_pols = self.cfg['processing']['input_subset'][
            'list_of_frequencies']

        slc = SLC(hdf5file=input_path)

        for freq in freq_pols.keys():
            if freq not in slc.frequencies:
                err_str = f"Frequency {freq} invalid; not found in source frequencies."
                error_channel.log(err_str)
                raise ValueError(err_str)

            # first check polarizations from source hdf5
            rslc_pols = slc.polarizations[freq]
            # use all RSLC polarizations if None provided
            if freq_pols[freq] is None:
                freq_pols[freq] = rslc_pols
                continue

            # use polarizations provided by user
            # check if user provided polarizations match RSLC ones
            for usr_pol in freq_pols[freq]:
                if usr_pol not in rslc_pols:
                    err_str = f"{usr_pol} invalid; not found in source polarizations."
                    error_channel.log(err_str)
                    raise ValueError(err_str)
Example #10
0
def test_point():
    h5_path = os.path.join(iscetest.data, "envisat.h5")

    radargrid = isce3.product.RadarGridParameters(h5_path)

    slc = SLC(hdf5file=h5_path)
    orbit = slc.getOrbit()
    doppler = slc.getDopplerCentroid()

    ellipsoid = isce3.core.Ellipsoid()

    llh = np.array([
        np.deg2rad(-115.72466801139711),
        np.deg2rad(34.65846532785868), 1772.0
    ])

    # run with native doppler
    aztime, slant_range = isce3.geometry.geo2rdr(llh,
                                                 ellipsoid,
                                                 orbit,
                                                 doppler,
                                                 radargrid.wavelength,
                                                 radargrid.lookside,
                                                 threshold=1.0e-10,
                                                 maxiter=50,
                                                 delta_range=10.0)

    azdate = orbit.reference_epoch + isce3.core.TimeDelta(aztime)
    assert azdate.isoformat() == "2003-02-26T17:55:33.993088889"
    npt.assert_almost_equal(slant_range, 830450.1859446081, decimal=6)

    # run again with zero doppler
    doppler = isce3.core.LUT2d()

    aztime, slant_range = isce3.geometry.geo2rdr(llh,
                                                 ellipsoid,
                                                 orbit,
                                                 doppler,
                                                 radargrid.wavelength,
                                                 radargrid.lookside,
                                                 threshold=1.0e-10,
                                                 maxiter=50,
                                                 delta_range=10.0)

    azdate = orbit.reference_epoch + isce3.core.TimeDelta(aztime)
    assert azdate.isoformat() == "2003-02-26T17:55:34.122893704"
    npt.assert_almost_equal(slant_range, 830449.6727720434, decimal=6)
Example #11
0
def run(cfg):
    '''
    run geo2rdr
    '''

    # Pull parameters from cfg dict
    sec_hdf5 = cfg['InputFileGroup']['SecondaryFilePath']
    dem_file = cfg['DynamicAncillaryFileGroup']['DEMFile']
    scratch_path = pathlib.Path(cfg['ProductPathGroup']['ScratchPath'])
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']

    # Get geo2rdr params
    geo2rdr_in = cfg['processing']['geo2rdr']

    # Get parameters from SLC
    slc = SLC(hdf5file=sec_hdf5)
    orbit = slc.getOrbit()

    # Set ellipsoid based on DEM epsg
    dem_raster = isce3.io.Raster(dem_file)
    epsg = dem_raster.get_epsg()
    proj = isce3.core.make_projection(epsg)
    ellipsoid = proj.ellipsoid

    # NISAR RSLC products are always zero doppler
    doppler_grid = isce3.core.LUT2d()

    info_channel = journal.info('geo2rdr.run')
    info_channel.log("starting geo2rdr")

    # check if gpu use if required
    use_gpu = gpu_check.use_gpu(cfg['worker']['gpu_enabled'],
                                cfg['worker']['gpu_id'])

    if use_gpu:
        # set CUDA device
        device = isce3.cuda.core.Device(cfg['worker']['gpu_id'])
        isce3.cuda.core.set_device(device)

    t_all = time.time()

    for freq in freq_pols.keys():

        # Get parameters specific for that frequency
        radar_grid = slc.getRadarGrid(frequency=freq)

        # Create geo2rdr directory
        geo2rdr_scratch_path = scratch_path / 'geo2rdr' / f'freq{freq}'
        geo2rdr_scratch_path.mkdir(parents=True, exist_ok=True)

        # Initialize CPU or GPU geo2rdr object accordingly
        if use_gpu:
            Geo2Rdr = isce3.cuda.geometry.Geo2Rdr
        else:
            Geo2Rdr = isce3.geometry.Geo2Rdr

        geo2rdr_obj = Geo2Rdr(radar_grid,
                              orbit,
                              ellipsoid,
                              doppler_grid,
                              threshold=geo2rdr_in['threshold'],
                              numiter=geo2rdr_in['maxiter'])
        # Opem Topo Raster
        topo_path = pathlib.Path(cfg['processing']['geo2rdr']['topo_path'])
        rdr2geo_topo_path = topo_path / 'rdr2geo' / f'freq{freq}' / 'topo.vrt'
        topo_raster = isce3.io.Raster(str(rdr2geo_topo_path))

        # Run geo2rdr
        geo2rdr_obj.geo2rdr(topo_raster, str(geo2rdr_scratch_path))

    t_all_elapsed = time.time() - t_all
    info_channel.log(
        f"Successfully ran geo2rdr in {t_all_elapsed:.3f} seconds")
Example #12
0
def create(cfg, frequency):
    '''
    For production we only fix epsgcode and snap value and will
    rely on the rslc product metadta to compute the bounding box of the geocoded products
    there is a place holder in SLC product for compute Bounding box
    when that method is populated we should be able to simply say
    bbox = self.slc_obj.computeBoundingBox(epsg=state.epsg)
    for now let's rely on the run config input
    '''
    error_channel = journal.error('geogrid.create')

    # unpack and init
    geocode_dict = cfg['processing']['geocode']
    input_hdf5 = cfg['InputFileGroup']['InputFilePath']
    dem_file = cfg['DynamicAncillaryFileGroup']['DEMFile']
    slc = SLC(hdf5file=input_hdf5)

    # unpack and check cfg dict values. default values set to trigger inside fix(...)
    epsg = geocode_dict['outputEPSG']
    start_x = geocode_dict['top_left']['x_abs']
    start_y = geocode_dict['top_left']['y_abs']
    spacing_x = geocode_dict['output_posting'][frequency]['x_posting']
    spacing_y = geocode_dict['output_posting'][frequency]['y_posting']
    end_x = geocode_dict['bottom_right']['x_abs']
    end_y = geocode_dict['bottom_right']['y_abs']

    assert epsg is not None
    assert 1024 <= epsg <= 32767

    if spacing_y is not None:

        # spacing_y from runconfig should be positive valued
        assert spacing_y > 0.0
        spacing_y = -1.0 * spacing_y

    # init geogrid
    if None in [start_x, start_y, spacing_x, spacing_y, epsg, end_x, end_y]:

        dem_raster = isce.io.Raster(dem_file)

        # copy X spacing from DEM
        if spacing_x is None:
            spacing_x = dem_raster.dx

            # DEM X spacing should be positive
            if spacing_x <= 0:
                err_str = f'Expected positive pixel spacing in the X/longitude direction'
                err_str += f' for DEM {dem_file}. Actual value: {spacing_x}.'
                error_channel.log(err_str)
                raise ValueError(err_str)

        # copy Y spacing from DEM
        if spacing_y is None:
            spacing_y = dem_raster.dy

            # DEM Y spacing should be negative
            if spacing_y >= 0:
                err_str = f'Expected negative pixel spacing in the Y/latitude direction'
                err_str += f' for DEM {dem_file}. Actual value: {spacing_y}.'
                error_channel.log(err_str)
                raise ValueError(err_str)

        # extract other geogrid params from radar grid and orbit constructed bounding box
        geogrid = isce.product.bbox_to_geogrid(
            slc.getRadarGrid(frequency), slc.getOrbit(),
            slc.getDopplerCentroid(frequency=frequency), spacing_x, spacing_y,
            epsg)

        # restore runconfig start_x (if provided)
        if start_x is not None:
            end_x_from_function = geogrid.start_x + geogrid.spacing_x * geogrid.width
            geogrid.start_x = start_x
            geogrid.width = int(
                np.ceil((end_x_from_function - start_x) / geogrid.spacing_x))

        # restore runconfig end_x (if provided)
        if end_x is not None:
            geogrid.width = int(
                np.ceil((end_x - geogrid.start_x) / geogrid.spacing_x))

        # restore runconfig start_y (if provided)
        if start_y is not None:
            end_y_from_function = geogrid.start_y + geogrid.spacing_y * geogrid.length
            geogrid.start_y = start_y
            geogrid.length = int(
                np.ceil((end_y_from_function - start_y) / geogrid.spacing_y))

        # restore runconfig end_y (if provided)
        if end_y is not None:
            geogrid.length = int(
                np.ceil((end_y - geogrid.start_y) / geogrid.spacing_y))

    else:
        if spacing_x == 0.0 or spacing_y == 0.0:
            err_str = 'spacing_x or spacing_y cannot be 0.0'
            error_channel.log(err_str)
            raise ValueError(err_str)

        width = _grid_size(end_x, start_x, spacing_x)
        length = _grid_size(end_y, start_y, -1.0 * spacing_y)

        # build from probably good user values
        geogrid = isce.product.GeoGridParameters(start_x, start_y, spacing_x,
                                                 spacing_y, width, length,
                                                 epsg)

    # recheck x+y end points before snap and length+width calculation
    end_pt = lambda start, sz, spacing: start + spacing * sz

    if end_x is None:
        end_x = end_pt(geogrid.start_x, geogrid.spacing_x, geogrid.width)

    if end_y is None:
        end_y = end_pt(geogrid.start_y, geogrid.spacing_y, geogrid.length)

    # snap all the things
    x_snap = geocode_dict['x_snap']
    y_snap = geocode_dict['y_snap']

    if x_snap is not None or y_snap is not None:
        # check snap values before proceeding
        if x_snap <= 0 or y_snap <= 0:
            err_str = 'Snap values must be > 0.'
            error_channel.log(err_str)
            raise ValueError(err_str)

        if x_snap % spacing_x != 0.0 or y_snap % spacing_y != 0:
            err_str = 'Snap values must be exact multiples of spacings. i.e. snap % spacing == 0.0'
            error_channel.log(err_str)
            raise ValueError(err_str)

        snap_coord = lambda val, snap, round_func: round_func(
            float(val) / snap) * snap
        geogrid.start_x = snap_coord(geogrid.start_x, x_snap, np.floor)
        geogrid.start_y = snap_coord(geogrid.start_y, y_snap, np.ceil)
        end_x = snap_coord(end_x, x_snap, np.ceil)
        end_y = snap_coord(end_y, y_snap, np.floor)
        geogrid.length = _grid_size(end_y, geogrid.start_y, geogrid.spacing_y)
        geogrid.width = _grid_size(end_x, geogrid.start_x, geogrid.spacing_x)

    return geogrid
Example #13
0
def test_rtc():

    # Open HDF5 file and create radar grid parameter
    print('iscetest.data:', iscetest.data)
    h5_path = os.path.join(iscetest.data, 'envisat.h5')
    slc_obj = SLC(hdf5file=h5_path)
    frequency = 'A'
    radar_grid_sl = slc_obj.getRadarGrid(frequency)

    # Open DEM raster
    dem_file = os.path.join(iscetest.data, 'srtm_cropped.tif')
    dem_obj = isce3.io.Raster(dem_file)

    # Crop original radar grid parameter
    radar_grid_cropped = \
            radar_grid_sl.offset_and_resize(30, 135, 128, 128)

    # Multi-look original radar grid parameter
    nlooks_az = 5
    nlooks_rg = 5
    radar_grid_ml = \
            radar_grid_sl.multilook(nlooks_az, nlooks_rg)

    # Create orbit and Doppler LUT
    orbit = slc_obj.getOrbit()
    doppler = slc_obj.getDopplerCentroid()
    doppler.bounds_error = False
    # doppler = isce3.core.LUT2d()

    # list input parameters
    inputRadiometry = isce3.geometry.RtcInputRadiometry.BETA_NAUGHT

    rtc_area_mode = isce3.geometry.RtcAreaMode.AREA_FACTOR

    for radar_grid_str in radar_grid_str_list:

        # Open DEM raster
        if (radar_grid_str == 'cropped'):
            radar_grid = radar_grid_cropped
        else:
            radar_grid = radar_grid_ml

        for rtc_algorithm in rtc_algorithm_list:

            geogrid_upsampling = 1

            # test removed because it requires high geogrid upsampling (too
            # slow)
            if (rtc_algorithm == isce3.geometry.RtcAlgorithm.RTC_DAVID_SMALL
                    and radar_grid_str == 'cropped'):
                continue
            elif (rtc_algorithm == isce3.geometry.RtcAlgorithm.RTC_DAVID_SMALL
                  ):
                filename = './rtc_david_small_' + radar_grid_str + '.bin'
            else:
                filename = './rtc_area_proj_' + radar_grid_str + '.bin'

            print('generating file:', filename)

            # Create output raster
            out_raster = isce3.io.Raster(filename, radar_grid.width,
                                         radar_grid.length, 1,
                                         gdal.GDT_Float32, 'ENVI')

            # Call RTC
            isce3.geometry.facet_rtc(radar_grid, orbit, doppler, dem_obj,
                                     out_raster, inputRadiometry,
                                     rtc_area_mode, rtc_algorithm,
                                     geogrid_upsampling)

            del out_raster

    # check results
    for radar_grid_str in radar_grid_str_list:
        for rtc_algorithm in rtc_algorithm_list:

            # test removed because it requires high geogrid upsampling (too
            # slow)
            if (rtc_algorithm == isce3.geometry.RtcAlgorithm.RTC_DAVID_SMALL
                    and radar_grid_str == 'cropped'):
                continue
            elif (rtc_algorithm == isce3.geometry.RtcAlgorithm.RTC_DAVID_SMALL
                  ):
                max_rmse = 0.7
                filename = './rtc_david_small_' + radar_grid_str + '.bin'
            else:
                max_rmse = 0.1
                filename = './rtc_area_proj_' + radar_grid_str + '.bin'

            print('evaluating file:', os.path.abspath(filename))

            # Open computed integrated-area raster
            test_gdal_dataset = gdal.Open(filename)

            # Open reference raster
            ref_filename = os.path.join(iscetest.data,
                                        'rtc/rtc_' + radar_grid_str + '.bin')

            ref_gdal_dataset = gdal.Open(ref_filename)
            print('reference file:', ref_filename)

            assert (
                test_gdal_dataset.RasterXSize == ref_gdal_dataset.RasterXSize)
            assert (
                test_gdal_dataset.RasterYSize == ref_gdal_dataset.RasterYSize)

            square_sum = 0.0  # sum of square difference
            n_nan = 0  # number of NaN pixels
            n_npos = 0  # number of non-positive pixels

            # read test and ref arrays
            test_array = test_gdal_dataset.GetRasterBand(1).ReadAsArray()
            ref_array = ref_gdal_dataset.GetRasterBand(1).ReadAsArray()

            n_valid = 0

            # iterates over rows (i) and columns (j)
            for i in range(ref_gdal_dataset.RasterYSize):
                for j in range(ref_gdal_dataset.RasterXSize):

                    # if nan, increment n_nan
                    if (np.isnan(test_array[i, j])
                            or np.isnan(ref_array[i, j])):
                        n_nan = n_nan + 1
                        continue

                    # if n_npos, incremennt n_npos
                    if (ref_array[i, j] <= 0 or test_array[i, j] <= 0):
                        n_npos = n_npos + 1
                        continue

                    # otherwise, increment n_valid
                    n_valid = n_valid + 1
                    square_sum += (test_array[i, j] - ref_array[i, j])**2
            print('    ----------------')
            print('    # total:', n_valid + n_nan + n_npos)
            print('    ----------------')
            print('    # valid:', n_valid)
            print('    # NaNs:', n_nan)
            print('    # non-positive:', n_npos)
            print('    ----------------')
            assert (n_valid != 0)

            # Compute average over entire image
            rmse = np.sqrt(square_sum / n_valid)

            print('    RMSE =', rmse)
            print('    ----------------')
            # Enforce bound on average pixel-error
            assert (rmse < max_rmse)

            # Enforce bound on number of ignored pixels
            assert (n_nan < 1e-4 * ref_gdal_dataset.RasterXSize *
                    ref_gdal_dataset.RasterYSize)
            assert (n_npos < 1e-4 * ref_gdal_dataset.RasterXSize *
                    ref_gdal_dataset.RasterYSize)
Example #14
0
def cp_geocode_meta(cfg, dst):
    '''
    Copy shared data from source HDF5 to GSLC, GCOV, INSAR
    HDF5 destinations
    Parameters:
    -----------
    cfg : dict
        Run configuration
    dst : str
        Name of destination node where data is to be copied
    '''
    is_insar = dst in ['GUNW', 'RUNW', 'RIFG']

    # unpack
    output_hdf5 = cfg['ProductPathGroup']['SASOutputFile']
    input_hdf5 = cfg['InputFileGroup']['InputFilePath']
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']
    if is_insar:
        secondary_hdf5 = cfg['InputFileGroup']['SecondaryFilePath']

    # rm anything and start from scratch
    try:
        os.remove(output_hdf5)
    except FileNotFoundError:
        pass

    slc = SLC(hdf5file=input_hdf5)

    # prelim setup
    common_parent_path = 'science/LSAR'
    src_h5 = h5py.File(input_hdf5, 'r', libver='latest', swmr=True)
    src_meta_path = slc.MetadataPath
    dst_meta_path = f'{common_parent_path}/{dst}/metadata'

    with h5py.File(input_hdf5, 'r', libver='latest', swmr=True) as src_h5, \
            h5py.File(output_hdf5, 'w', libver='latest', swmr=True) as dst_h5:

        # simple copies of identification, metadata/orbit, metadata/attitude groups
        identification_excludes = 'productType'
        if is_insar:
            identification_excludes = ['productType', 'listOfFrequencies']
        cp_h5_meta_data(src_h5,
                        dst_h5,
                        f'{common_parent_path}/identification',
                        excludes=identification_excludes)

        # Flag isGeocoded
        ident = dst_h5[f'{common_parent_path}/identification']
        dset = ident.create_dataset('isGeocoded', data=np.string_("True"))
        desc = "Flag to indicate radar geometry or geocoded product"
        dset.attrs["description"] = np.string_(desc)

        ident['productType'] = dst

        # copy orbit information group
        cp_h5_meta_data(src_h5, dst_h5, f'{src_meta_path}/orbit',
                        f'{dst_meta_path}/orbit')

        # copy attitude information group
        cp_h5_meta_data(src_h5, dst_h5, f'{src_meta_path}/attitude',
                        f'{dst_meta_path}/attitude')

        # copy radar grid information group
        cp_h5_meta_data(src_h5,
                        dst_h5,
                        f'{src_meta_path}/geolocationGrid',
                        f'{dst_meta_path}/radarGrid',
                        renames={
                            'coordinateX': 'xCoordinates',
                            'coordinateY': 'yCoordinates',
                            'zeroDopplerTime': 'zeroDopplerAzimuthTime'
                        })

        # Copy common metadata
        # TODO check differences in processingInformation
        cp_h5_meta_data(src_h5, dst_h5,
                        f'{src_meta_path}/processingInformation/algorithms',
                        f'{dst_meta_path}/processingInformation/algorithms')
        cp_h5_meta_data(src_h5,
                        dst_h5,
                        f'{src_meta_path}/processingInformation/inputs',
                        f'{dst_meta_path}/processingInformation/inputs',
                        excludes=[
                            'l0bGranules', 'demFiles', 'zeroDopplerTime',
                            'slantRange'
                        ])

        inputs = [input_hdf5]
        if is_insar:
            inputs += secondary_hdf5
        input_grp = dst_h5[os.path.join(dst_meta_path,
                                        'processingInformation/inputs')]
        dset = input_grp.create_dataset("l1SlcGranules",
                                        data=np.string_(inputs))
        desc = "List of input L1 products used"
        dset.attrs["description"] = np.string_(desc)

        # copy calibration information group and zeroDopplerTimeSpacing
        excludes = []
        if is_insar:
            excludes = ['nes0', 'elevationAntennaPattern']
        for freq in freq_pols.keys():
            frequency = f'frequency{freq}'

            # copy zeroDopplerTimeSpacing
            zero_doppler_time_spacing = src_h5[
                f'{common_parent_path}/SLC/swaths/zeroDopplerTimeSpacing'][...]
            dst_h5[f'{common_parent_path}/{dst}/grids/{frequency}'
                   '/zeroDopplerTimeSpacing/'] = zero_doppler_time_spacing

            pol_list = freq_pols[freq]
            if pol_list is None:
                continue
            for polarization in pol_list:
                cp_h5_meta_data(
                    src_h5,
                    dst_h5,
                    os.path.join(
                        src_meta_path,
                        f'calibrationInformation/{frequency}/{polarization}'),
                    os.path.join(
                        dst_meta_path,
                        f'calibrationInformation/{frequency}/{polarization}'),
                    excludes=excludes)
                if is_insar:
                    path = os.path.join(
                        dst_meta_path,
                        f'calibrationInformation/{frequency}/{polarization}')
                    descr = "Constant wrapped reference phase used to balance the interferogram"
                    _create_datasets(dst_h5[path], [0],
                                     np.float32,
                                     'referencePhase',
                                     descr=descr,
                                     units="radians")

        # copy processingInformation
        excludes = ['nes0', 'elevationAntennaPattern']
        if is_insar:
            excludes = [
                'frequencyA', 'frequencyB', 'azimuthChirpWeighting',
                'effectiveVelocity', 'rangeChirpWeighting', 'slantRange',
                'zeroDopplerTime'
            ]
        cp_h5_meta_data(src_h5,
                        dst_h5,
                        os.path.join(src_meta_path,
                                     'processingInformation/parameters'),
                        os.path.join(dst_meta_path,
                                     'processingInformation/parameters'),
                        excludes=excludes)

        # copy product specifics
        if is_insar:
            copy_insar_meta(cfg, src_meta_path, dst_meta_path, src_h5, dst_h5)
        else:
            copy_gslc_gcov_meta(slc.SwathPath, dst, src_h5, dst_h5)
Example #15
0
def run(cfg):
    '''
    run geocodeSlc according to parameters in cfg dict
    '''
    # pull parameters from cfg
    input_hdf5 = cfg['InputFileGroup']['InputFilePath']
    output_hdf5 = cfg['ProductPathGroup']['SASOutputFile']
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']
    geogrids = cfg['processing']['geocode']['geogrids']
    dem_file = cfg['DynamicAncillaryFileGroup']['DEMFile']
    threshold_geo2rdr = cfg['processing']['geo2rdr']['threshold']
    iteration_geo2rdr = cfg['processing']['geo2rdr']['maxiter']
    lines_per_block = cfg['processing']['blocksize']['y']
    dem_block_margin = cfg['processing']['dem_margin']
    flatten = cfg['processing']['flatten']

    # init parameters shared by frequency A and B
    slc = SLC(hdf5file=input_hdf5)
    orbit = slc.getOrbit()
    dem_raster = isce3.io.Raster(dem_file)
    epsg = dem_raster.get_epsg()
    proj = isce3.core.make_projection(epsg)
    ellipsoid = proj.ellipsoid

    # Doppler of the image grid (Zero for NISAR)
    image_grid_doppler = isce3.core.LUT2d()

    info_channel = journal.info("gslc.run")
    info_channel.log("starting geocode SLC")

    t_all = time.time()
    with h5py.File(output_hdf5, 'a') as dst_h5:
        for freq in freq_pols.keys():
            frequency = f"frequency{freq}"
            pol_list = freq_pols[freq]
            radar_grid = slc.getRadarGrid(freq)
            geo_grid = geogrids[freq]

            # get doppler centroid
            native_doppler = slc.getDopplerCentroid(frequency=freq)

            for polarization in pol_list:
                t_pol = time.time()

                output_dir = os.path.dirname(os.path.abspath(output_hdf5))
                os.makedirs(output_dir, exist_ok=True)

                raster_ref = f'HDF5:{input_hdf5}:/{slc.slcPath(freq, polarization)}'
                slc_raster = isce3.io.Raster(raster_ref)

                # access the HDF5 dataset for a given frequency and polarization
                dataset_path = f'/science/LSAR/GSLC/grids/{frequency}/{polarization}'
                gslc_dataset = dst_h5[dataset_path]

                # Construct the output ratster directly from HDF5 dataset
                gslc_raster = isce3.io.Raster(
                    f"IH5:::ID={gslc_dataset.id.id}".encode("utf-8"),
                    update=True)

                # run geocodeSlc
                isce3.geocode.geocode_slc(gslc_raster, slc_raster, dem_raster,
                                          radar_grid, geo_grid, orbit,
                                          native_doppler, image_grid_doppler,
                                          ellipsoid, threshold_geo2rdr,
                                          iteration_geo2rdr, lines_per_block,
                                          dem_block_margin, flatten)

                # the rasters need to be deleted
                del gslc_raster
                del slc_raster
                t_pol_elapsed = time.time() - t_pol
                info_channel.log(
                    f'polarization {polarization} ran in {t_pol_elapsed:.3f} seconds'
                )

    t_all_elapsed = time.time() - t_all
    info_channel.log(
        f"successfully ran geocode SLC in {t_all_elapsed:.3f} seconds")
Example #16
0
def run(cfg):
    '''
    run resample_slc
    '''
    input_hdf5 = cfg['InputFileGroup']['SecondaryFilePath']
    scratch_path = pathlib.Path(cfg['ProductPathGroup']['ScratchPath'])
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']

    resamp_args = cfg['processing']['resample']

    # Get SLC parameters
    slc = SLC(hdf5file=input_hdf5)

    info_channel = journal.info('resample_slc.run')
    info_channel.log('starting resampling SLC')

    # Check if use GPU or CPU resampling
    use_gpu = gpu_check.use_gpu(cfg['worker']['gpu_enabled'],
                                cfg['worker']['gpu_id'])

    if use_gpu:
        # Set current CUDA device
        device = isce3.cuda.core.Device(cfg['worker']['gpu_id'])
        isce3.cuda.core.set_device(device)

    t_all = time.time()

    for freq in freq_pols.keys():
        # Get frequency specific parameters
        radar_grid = slc.getRadarGrid(frequency=freq)
        native_doppler = slc.getDopplerCentroid(frequency=freq)

        # create separate directory within scratch for resample_slc
        resample_slc_scratch_path = scratch_path / 'resample_slc' / f'freq{freq}'
        resample_slc_scratch_path.mkdir(parents=True, exist_ok=True)

        # Initialize CPU or GPU resample object accordingly
        if use_gpu:
            Resamp = isce3.cuda.image.ResampSlc
        else:
            Resamp = isce3.image.ResampSlc

        resamp_obj = Resamp(radar_grid, native_doppler, radar_grid.wavelength)

        # If lines per tile is > 0, assign it to resamp_obj
        if resamp_args['lines_per_tile']:
            resamp_obj.lines_per_tile = resamp_args['lines_per_tile']

        # Open offsets
        offset_dir = pathlib.Path(cfg['processing']['resample']['offset_dir'])
        geo2rdr_off_path = offset_dir / 'geo2rdr' / f'freq{freq}'

        # Open offsets
        rg_off = isce3.io.Raster(str(geo2rdr_off_path / 'range.off'))
        az_off = isce3.io.Raster(str(geo2rdr_off_path / 'azimuth.off'))

        # Get polarization list to process
        pol_list = freq_pols[freq]

        for pol in pol_list:
            # Create directory for each polarization
            out_dir = resample_slc_scratch_path / pol
            out_dir.mkdir(parents=True, exist_ok=True)
            out_path = out_dir / 'coregistered_secondary.slc'

            # Extract and create raster of SLC to resample
            h5_ds = f'//science/LSAR/SLC/swaths/frequency{freq}/{pol}'
            raster_path = f'HDF5:{input_hdf5}:{h5_ds}'
            raster = isce3.io.Raster(raster_path)

            # Create output raster
            resamp_slc = isce3.io.Raster(str(out_path), rg_off.width,
                                         rg_off.length, rg_off.num_bands,
                                         gdal.GDT_CFloat32, 'ENVI')
            resamp_obj.resamp(raster, resamp_slc, rg_off, az_off)

    t_all_elapsed = time.time() - t_all
    info_channel.log(
        f"successfully ran resample in {t_all_elapsed:.3f} seconds")