Example #1
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 = isce3.core.DateTime("2003-02-26T17:55:22.976222")
    r = 826988.6900674499
    h = 1777.

    dem = isce3.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 = isce3.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 = isce3.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 #2
0
def main(opts):

    #instantiate slc object from NISAR SLC class
    slc = SLC(hdf5file=opts.product)

    # extract orbit
    orbit = slc.getOrbit()

    # extract the radar grid parameters
    radarGrid = slc.getRadarGrid()

    # construct ellipsoid which is by default WGS84
    ellipsoid = isce3.core.ellipsoid()

    # Create geo2rdr instance
    geo2rdrObj = isce3.geometry.geo2rdr(radarGrid=radarGrid,
                                        orbit=orbit,
                                        ellipsoid=ellipsoid)

    # Read topo multiband raster
    topoRaster = isce3.io.raster(
        filename=os.path.join(opts.topodir, 'topo.vrt'))

    # Init output directory
    if not os.path.isdir(opts.outdir):
        os.mkdir(opts.outdir)

    # Run geo2rdr
    geo2rdrObj.geo2rdr(topoRaster,
                       outputDir=opts.outdir,
                       azshift=opts.azoff,
                       rgshift=opts.rgoff)
Example #3
0
def main(opts):

    #instantiate slc object from NISAR SLC class
    slc = SLC(hdf5file=opts.product)

    # extract orbit
    orbit = slc.getOrbit()

    # extract the radar grid parameters
    radarGrid = slc.getRadarGrid()

    # construct ellipsoid which is by default WGS84
    ellipsoid = isce3.core.ellipsoid()

    rdr2geo = isce3.geometry.rdr2geo(radarGrid=radarGrid,
                                     orbit=orbit,
                                     ellipsoid=ellipsoid,
                                     computeMask=opts.mask)

    # Read DEM raster
    demRaster = isce3.io.raster(filename=opts.dem)

    # Init output directory
    if not os.path.isdir(opts.outdir):
        os.mkdir(opts.outdir)

    # Run rdr2geo
    rdr2geo.topo(demRaster, outputDir=opts.outdir)

    return 0
Example #4
0
def main(opts):
    """
    crossmul
    """
    # prepare input rasters
    masterSlc = SLC(hdf5file=opts.master)
    masterSlcDataset = masterSlc.getSlcDataset(opts.frequency,
                                               opts.polarization)
    masterSlcRaster = Raster('', h5=masterSlcDataset)
    slaveSlc = SLC(hdf5file=opts.slave)
    slaveSlcDataset = slaveSlc.getSlcDataset(opts.frequency, opts.polarization)
    slaveSlcRaster = Raster('', h5=slaveSlcDataset)

    # prepare mulitlooked interferogram dimensions
    masterGrid = masterSlc.getRadarGrid(opts.frequency)
    length = int(masterGrid.length / opts.alks)
    width = int(masterGrid.width / opts.rlks)

    # init output directory(s)
    initDir(opts.intPathAndPrefix)
    initDir(opts.cohPathAndPrefix)

    # prepare output rasters
    driver = gdal.GetDriverByName('ISCE')
    igramDataset = driver.Create(opts.intPathAndPrefix, width, length, 1,
                                 gdal.GDT_CFloat32)
    igramRaster = Raster('', dataset=igramDataset)
    cohDataset = driver.Create(opts.cohPathAndPrefix, width, length, 1,
                               gdal.GDT_Float32)
    cohRaster = Raster('', dataset=cohDataset)

    # prepare optional rasters
    if opts.rgoff:
        rgOffRaster = Raster(opts.rgoff)
    else:
        rgOffRaster = None

    if opts.azband:
        dopMaster = masterSlc.getDopplerCentroid()
        dopSlave = slaveSlc.getDopplerCentroid()
        prf = dopMaster.getRadarGrid(opts.frequency).prf
        azimuthBandwidth = opts.azband
    else:
        dopMaster = dopSlave = None
        prf = azimuthBandwidth = 0.0

    crossmul = Crossmul()
    crossmul.crossmul(masterSlcRaster,
                      slaveSlcRaster,
                      igramRaster,
                      cohRaster,
                      rngOffset=rgOffRaster,
                      refDoppler=dopMaster,
                      secDoppler=dopSlave,
                      rangeLooks=opts.rlks,
                      azimuthLooks=opts.alks,
                      prf=prf,
                      azimuthBandwidth=azimuthBandwidth)
Example #5
0
def main(opts):
    """
    resample SLC
    """

    # prep SLC dataset input
    productSlc = SLC(hdf5file=opts.product)

    # get grids needed for resamp object instantiation
    productGrid = productSlc.getRadarGrid(opts.frequency)

    # instantiate resamp object based on user input
    if 'cuda' not in dir(isce3) and opts.gpu:
        warnings.warn('CUDA resamp not available. Switching to CPU resamp')
        opts.gpu = False

    if opts.gpu:
        resamp = isce3.cuda.image.resampSlc(
            radarGrid=productGrid,
            doppler=productSlc.getDopplerCentroid(),
            wavelength=productGrid.wavelength)
    else:
        resamp = isce3.image.resampSlc(radarGrid=productGrid,
                                       doppler=productSlc.getDopplerCentroid(),
                                       wavelength=productGrid.wavelength)

    # set number of lines per tile if arg > 0
    if opts.linesPerTile:
        resamp.linesPerTile = opts.linesPerTile

    # Prepare input rasters
    inSlcDataset = productSlc.getSlcDataset(opts.frequency, opts.polarization)
    inSlcRaster = isce3.io.raster(filename='', h5=inSlcDataset)
    azOffsetRaster = isce3.io.raster(
        filename=os.path.join(opts.offsetdir, 'azimuth.off'))
    rgOffsetRaster = isce3.io.raster(
        filename=os.path.join(opts.offsetdir, 'range.off'))

    # Init output directory
    if opts.outFilePath:
        path, _ = os.path.split(opts.outFilePath)
        os.makedirs(path, exist_ok=True)

    # Prepare output raster
    driver = gdal.GetDriverByName('ISCE')
    outds = driver.Create(opts.outFilePath, rgOffsetRaster.width,
                          rgOffsetRaster.length, 1, gdal.GDT_CFloat32)
    outSlcRaster = isce3.io.raster(filename='', dataset=outds)

    # Run resamp
    resamp.resamp(inSlc=inSlcRaster,
                  outSlc=outSlcRaster,
                  rgoffRaster=rgOffsetRaster,
                  azoffRaster=azOffsetRaster)
Example #6
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.avg_lut2d_to_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 #7
0
def get_geo_polygon(ref_slc, min_height=-500.,
                    max_height=9000., pts_per_edge=5):
    """Create polygon (EPSG:4326) using RSLC radar grid and orbits

    Parameters:
    -----------
    ref_slc: str
        Path to RSLC product to stage the DEM for
    min_height: float
        Global minimum height (in m) for DEM interpolator
    max_height: float
        Global maximum height (in m) for DEM interpolator
    pts_per_edge: float
        Number of points per edge for min/max bounding box computation

    Returns:
    -------
    poly: shapely.Geometry.Polygon
        Bounding polygon corresponding to RSLC perimeter on the ground
    """
    from isce3.core import LUT2d
    from isce3.geometry import DEMInterpolator, get_geo_perimeter_wkt
    from nisar.products.readers import SLC

    # Prepare SLC dataset input
    productSlc = SLC(hdf5file=ref_slc)

    # Extract orbits, radar grid, and doppler for frequency A
    orbit = productSlc.getOrbit()
    radar_grid = productSlc.getRadarGrid(frequency='A')
    doppler = LUT2d()

    # Get min and max global height DEM interpolators
    dem_min = DEMInterpolator(height=min_height)
    dem_max = DEMInterpolator(height=max_height)

    # Get min and max bounding boxes
    box_min = get_geo_perimeter_wkt(radar_grid, orbit, doppler,
                                    dem_min, pts_per_edge)
    box_max = get_geo_perimeter_wkt(radar_grid, orbit, doppler,
                                    dem_max, pts_per_edge)

    # Determine minimum and maximum polygons
    poly_min = shapely.wkt.loads(box_min)
    poly_max = shapely.wkt.loads(box_max)

    # Get polygon from intersection of poly_min and poly_max
    poly = poly_min | poly_max

    return poly
Example #8
0
def determine_perimeter(opts):
    """
     Determine perimeter for DEM staging
    """
    from nisar.products.readers import SLC
    from isce3.geometry import deminterpolator
    from isce3.geometry import getGeoPerimeter
    from isce3.core import projection

    if opts.bbox is not None:
        print('Determine perimeter from bounding box')
        lat = opts.bbox[0:2]
        lon = opts.bbox[2:4]
        ring = LinearRing([(lon[0], lat[0]), (lon[0], lat[1]),
                           (lon[1], lat[1]), (lon[1], lat[0])])
    else:
        print('Determine perimeter from SLC radar grid')

    # Prepare SLC dataset input
    productSlc = SLC(hdf5file=opts.product)

    # Extract orbits and radar Grid parameters
    orbit = productSlc.getOrbit()
    radarGrid = productSlc.getRadarGrid()

    # Minimum and Maximum global heights
    dem_min = deminterpolator(height=-500.)
    dem_max = deminterpolator(height=9000.)

    # Get Minimum and Maximum bounding boxes
    epsg = projection(epsg=4326)
    box_min = getGeoPerimeter(radarGrid,
                              orbit,
                              epsg,
                              dem=dem_min,
                              pointsPerEdge=5)
    box_max = getGeoPerimeter(radarGrid,
                              orbit,
                              epsg,
                              dem=dem_max,
                              pointsPerEdge=5)

    dummy = json.loads(box_min)['coordinates'] + \
        json.loads(box_max)['coordinates']
    ring = LinearRing(dummy)

    return ring
Example #9
0
def main(opts):

    #instantiate slc object from NISAR SLC class
    slc = SLC(hdf5file=opts.product)

    # extract orbit
    orbit = slc.getOrbit()

    # extract the radar grid parameters
    radarGrid = slc.getRadarGrid()

    # construct ellipsoid which is by default WGS84
    ellipsoid = isce3.core.ellipsoid()

    # get doppler centroid
    doppler = slc.getDopplerCentroid()

    # instantiate geo2rdr object based on user input
    if 'cuda' not in dir(isce3) and opts.gpu:
        warnings.warn('CUDA geo2rdr not available. Switching to CPU geo2rdr')
        opts.gpu = False

    if opts.gpu:
        geo2rdrObj = isce3.cuda.geometry.geo2rdr(radarGrid=radarGrid,
                                                 orbit=orbit,
                                                 ellipsoid=ellipsoid,
                                                 doppler=doppler,
                                                 threshold=1e-9)
    else:
        geo2rdrObj = isce3.geometry.geo2rdr(radarGrid=radarGrid,
                                            orbit=orbit,
                                            ellipsoid=ellipsoid,
                                            doppler=doppler,
                                            threshold=1e-9)

    # Read topo multiband raster
    topoRaster = isce3.io.raster(filename=opts.topopath)

    # Init output directory
    os.makedirs(opts.outdir, exist_ok=True)

    # Run geo2rdr
    geo2rdrObj.geo2rdr(topoRaster,
                       outputDir=opts.outdir,
                       azshift=opts.azoff,
                       rgshift=opts.rgoff)
Example #10
0
def main(opts):

    #instantiate slc object from NISAR SLC class
    slc = SLC(hdf5file=opts.product)

    # extract orbit
    orbit = slc.getOrbit()

    # extract the radar grid parameters
    radarGrid = slc.getRadarGrid()

    # construct ellipsoid which is by default WGS84
    ellipsoid = isce3.core.ellipsoid()

    # get doppler centroid
    doppler = slc.getDopplerCentroid()

    # instantiate rdr2geo object based on user input
    if 'cuda' not in dir(isce3) and opts.gpu:
        warnings.warn('CUDA rdr2geo not available. Switching to CPU rdr2geo')
        opts.gpu = False

    if opts.gpu:
        rdr2geo = isce3.cuda.geometry.rdr2geo(radarGrid=radarGrid,
                                              orbit=orbit,
                                              ellipsoid=ellipsoid,
                                              computeMask=opts.mask,
                                              doppler=doppler)
    else:
        rdr2geo = isce3.geometry.rdr2geo(radarGrid=radarGrid,
                                         orbit=orbit,
                                         ellipsoid=ellipsoid,
                                         computeMask=opts.mask,
                                         doppler=doppler)

    # Read DEM raster
    demRaster = isce3.io.raster(filename=opts.dem)

    # Init output directory
    os.makedirs(opts.outdir, exist_ok=True)

    # Run rdr2geo
    rdr2geo.topo(demRaster, outputDir=opts.outdir)

    return 0
Example #11
0
def main(opts):
    """
    resample SLC
    """

    # prep SLC dataset input
    productSlc = SLC(hdf5file=opts.product)

    # get grids needed for resamp object instantiation
    productGrid = productSlc.getRadarGrid(opts.frequency)

    # instantiate resamp object
    resamp = ResampSlc(productGrid, productSlc.getDopplerCentroid(),
                       productGrid.wavelength)

    # set number of lines per tile if arg > 0
    if opts.linesPerTile:
        resamp.linesPerTile = opts.linesPerTile

    # Prepare input rasters
    inSlcDataset = productSlc.getSlcDataset(opts.frequency, opts.polarization)
    inSlcRaster = Raster('', h5=inSlcDataset)
    azOffsetRaster = Raster(
        filename=os.path.join(opts.offsetdir, 'azimuth.off'))
    rgOffsetRaster = Raster(filename=os.path.join(opts.offsetdir, 'range.off'))

    # Init output directory
    if opts.outPathAndFile:
        path, file = os.path.split(opts.outPathAndFile)
        if not os.path.isdir(path):
            os.makedirs(path)

    # Prepare output raster
    driver = gdal.GetDriverByName('ISCE')
    slcPathAndName = opts.outPathAndFile
    outds = driver.Create(os.path.join(slcPathAndName), rgOffsetRaster.width,
                          rgOffsetRaster.length, 1, gdal.GDT_CFloat32)
    outSlcRaster = Raster('', dataset=outds)

    # Run resamp
    resamp.resamp(inSlc=inSlcRaster,
                  outSlc=outSlcRaster,
                  rgoffRaster=rgOffsetRaster,
                  azoffRaster=azOffsetRaster)
Example #12
0
def run(cfg):
    '''
    run GCOV
    '''

    # pull parameters from cfg
    input_hdf5 = cfg['input_file_group']['input_file_path']
    output_hdf5 = cfg['product_path_group']['sas_output_file']
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']
    flag_fullcovariance = cfg['processing']['input_subset']['fullcovariance']
    flag_symmetrize_cross_pol_channels = \
        cfg['processing']['input_subset']['symmetrize_cross_pol_channels']
    scratch_path = cfg['product_path_group']['scratch_path']

    radar_grid_cubes_geogrid = cfg['processing']['radar_grid_cubes']['geogrid']
    radar_grid_cubes_heights = cfg['processing']['radar_grid_cubes']['heights']

    # DEM parameters
    dem_file = cfg['dynamic_ancillary_file_group']['dem_file']
    dem_margin = cfg['processing']['dem_margin']
    dem_interp_method_enum = cfg['processing']['dem_interpolation_method_enum']

    # unpack geocode run parameters
    geocode_dict = cfg['processing']['geocode']
    geocode_algorithm = geocode_dict['algorithm_type']
    output_mode = geocode_dict['output_mode']
    flag_apply_rtc = geocode_dict['apply_rtc']
    memory_mode = geocode_dict['memory_mode']
    geogrid_upsampling = geocode_dict['geogrid_upsampling']
    abs_cal_factor = geocode_dict['abs_rad_cal']
    clip_max = geocode_dict['clip_max']
    clip_min = geocode_dict['clip_min']
    geogrids = geocode_dict['geogrids']
    flag_upsample_radar_grid = geocode_dict['upsample_radargrid']
    flag_save_nlooks = geocode_dict['save_nlooks']
    flag_save_rtc = geocode_dict['save_rtc']
    flag_save_dem = geocode_dict['save_dem']

    # unpack RTC run parameters
    rtc_dict = cfg['processing']['rtc']
    output_terrain_radiometry = rtc_dict['output_type']
    rtc_algorithm = rtc_dict['algorithm_type']
    input_terrain_radiometry = rtc_dict['input_terrain_radiometry']
    rtc_min_value_db = rtc_dict['rtc_min_value_db']
    rtc_upsampling = rtc_dict['dem_upsampling']

    # unpack geo2rdr parameters
    geo2rdr_dict = cfg['processing']['geo2rdr']
    threshold = geo2rdr_dict['threshold']
    maxiter = geo2rdr_dict['maxiter']

    if (flag_apply_rtc and output_terrain_radiometry
            == isce3.geometry.RtcOutputTerrainRadiometry.SIGMA_NAUGHT):
        output_radiometry_str = "radar backscatter sigma0"
    elif (flag_apply_rtc and output_terrain_radiometry
          == isce3.geometry.RtcOutputTerrainRadiometry.GAMMA_NAUGHT):
        output_radiometry_str = 'radar backscatter gamma0'
    elif input_terrain_radiometry == isce3.geometry.RtcInputTerrainRadiometry.BETA_NAUGHT:
        output_radiometry_str = 'radar backscatter beta0'
    else:
        output_radiometry_str = 'radar backscatter sigma0'

    # unpack pre-processing
    preprocess = cfg['processing']['pre_process']
    rg_look = preprocess['range_looks']
    az_look = preprocess['azimuth_looks']
    radar_grid_nlooks = rg_look * az_look

    # init parameters shared between frequencyA and frequencyB sub-bands
    slc = SLC(hdf5file=input_hdf5)
    dem_raster = isce3.io.Raster(dem_file)
    zero_doppler = isce3.core.LUT2d()
    epsg = dem_raster.get_epsg()
    proj = isce3.core.make_projection(epsg)
    ellipsoid = proj.ellipsoid
    exponent = 2

    info_channel = journal.info("gcov.run")
    error_channel = journal.error("gcov.run")
    info_channel.log("starting geocode COV")

    t_all = time.time()
    for frequency in freq_pols.keys():

        t_freq = time.time()

        # unpack frequency dependent parameters
        radar_grid = slc.getRadarGrid(frequency)
        if radar_grid_nlooks > 1:
            radar_grid = radar_grid.multilook(az_look, rg_look)
        geogrid = geogrids[frequency]
        input_pol_list = freq_pols[frequency]

        # do no processing if no polarizations specified for current frequency
        if not input_pol_list:
            continue

        # set dict of input rasters
        input_raster_dict = {}

        # `input_pol_list` is the input list of polarizations that may include
        # HV and VH. `pol_list` is the actual list of polarizations to be
        # geocoded. It may include HV but it will not include VH if the
        # polarimetric symmetrization is performed
        pol_list = input_pol_list
        for pol in pol_list:
            temp_ref = \
                f'HDF5:"{input_hdf5}":/{slc.slcPath(frequency, pol)}'
            temp_raster = isce3.io.Raster(temp_ref)
            input_raster_dict[pol] = temp_raster
        # symmetrize cross-polarimetric channels (if applicable)
        if (flag_symmetrize_cross_pol_channels and 'HV' in input_pol_list
                and 'VH' in input_pol_list):

            # create output raster
            symmetrized_hv_temp = tempfile.NamedTemporaryFile(dir=scratch_path,
                                                              suffix='.tif')

            # get cross-polarimetric channels from input_raster_dict
            hv_raster_obj = input_raster_dict['HV']
            vh_raster_obj = input_raster_dict['VH']

            # create output symmetrized HV object
            symmetrized_hv_obj = isce3.io.Raster(symmetrized_hv_temp.name,
                                                 hv_raster_obj.width,
                                                 hv_raster_obj.length,
                                                 hv_raster_obj.num_bands,
                                                 hv_raster_obj.datatype(),
                                                 'GTiff')

            # call symmetrization function
            isce3.polsar.symmetrize_cross_pol_channels(hv_raster_obj,
                                                       vh_raster_obj,
                                                       symmetrized_hv_obj)

            # ensure changes are flushed to disk by closing & re-opening the
            # raster.
            del symmetrized_hv_obj
            symmetrized_hv_obj = isce3.io.Raster(symmetrized_hv_temp.name)

            # Since HV and VH were symmetrized into HV, remove VH from
            # `pol_list` and `from input_raster_dict`.
            pol_list.remove('VH')
            input_raster_dict.pop('VH')

            # Update `input_raster_dict` with the new `symmetrized_hv_obj`
            input_raster_dict['HV'] = symmetrized_hv_obj

        # construct input rasters
        input_raster_list = []
        for pol in pol_list:
            input_raster_list.append(input_raster_dict[pol])

        # set paths temporary files
        input_temp = tempfile.NamedTemporaryFile(dir=scratch_path,
                                                 suffix='.vrt')
        input_raster_obj = isce3.io.Raster(input_temp.name,
                                           raster_list=input_raster_list)

        # init Geocode object depending on raster type
        if input_raster_obj.datatype() == gdal.GDT_Float32:
            geo = isce3.geocode.GeocodeFloat32()
        elif input_raster_obj.datatype() == gdal.GDT_Float64:
            geo = isce3.geocode.GeocodeFloat64()
        elif input_raster_obj.datatype() == gdal.GDT_CFloat32:
            geo = isce3.geocode.GeocodeCFloat32()
        elif input_raster_obj.datatype() == gdal.GDT_CFloat64:
            geo = isce3.geocode.GeocodeCFloat64()
        else:
            err_str = 'Unsupported raster type for geocoding'
            error_channel.log(err_str)
            raise NotImplementedError(err_str)

        orbit = slc.getOrbit()

        # init geocode members
        geo.orbit = orbit
        geo.ellipsoid = ellipsoid
        geo.doppler = zero_doppler
        geo.threshold_geo2rdr = threshold
        geo.numiter_geo2rdr = maxiter
        geo.dem_block_margin = dem_margin

        # set data interpolator based on the geocode algorithm
        if output_mode == isce3.geocode.GeocodeOutputMode.INTERP:
            geo.data_interpolator = geocode_algorithm

        geo.geogrid(geogrid.start_x, geogrid.start_y, geogrid.spacing_x,
                    geogrid.spacing_y, geogrid.width, geogrid.length,
                    geogrid.epsg)

        # create output raster
        temp_output = tempfile.NamedTemporaryFile(dir=scratch_path,
                                                  suffix='.tif')

        output_raster_obj = isce3.io.Raster(temp_output.name, geogrid.width,
                                            geogrid.length,
                                            input_raster_obj.num_bands,
                                            gdal.GDT_Float32, 'GTiff')

        nbands_off_diag_terms = 0
        out_off_diag_terms_obj = None
        if flag_fullcovariance:
            nbands = input_raster_obj.num_bands
            nbands_off_diag_terms = (nbands**2 - nbands) // 2
            if nbands_off_diag_terms > 0:
                temp_off_diag = tempfile.NamedTemporaryFile(dir=scratch_path,
                                                            suffix='.tif')
                out_off_diag_terms_obj = isce3.io.Raster(
                    temp_off_diag.name, geogrid.width, geogrid.length,
                    nbands_off_diag_terms, gdal.GDT_CFloat32, 'GTiff')

        if flag_save_nlooks:
            temp_nlooks = tempfile.NamedTemporaryFile(dir=scratch_path,
                                                      suffix='.tif')
            out_geo_nlooks_obj = isce3.io.Raster(temp_nlooks.name,
                                                 geogrid.width, geogrid.length,
                                                 1, gdal.GDT_Float32, "GTiff")
        else:
            temp_nlooks = None
            out_geo_nlooks_obj = None

        if flag_save_rtc:
            temp_rtc = tempfile.NamedTemporaryFile(dir=scratch_path,
                                                   suffix='.tif')
            out_geo_rtc_obj = isce3.io.Raster(temp_rtc.name, geogrid.width,
                                              geogrid.length, 1,
                                              gdal.GDT_Float32, "GTiff")
        else:
            temp_rtc = None
            out_geo_rtc_obj = None

        if flag_save_dem:
            temp_interpolated_dem = tempfile.NamedTemporaryFile(
                dir=scratch_path, suffix='.tif')
            if (output_mode == isce3.geocode.GeocodeOutputMode.AREA_PROJECTION
                ):
                interpolated_dem_width = geogrid.width + 1
                interpolated_dem_length = geogrid.length + 1
            else:
                interpolated_dem_width = geogrid.width
                interpolated_dem_length = geogrid.length
            out_geo_dem_obj = isce3.io.Raster(temp_interpolated_dem.name,
                                              interpolated_dem_width,
                                              interpolated_dem_length, 1,
                                              gdal.GDT_Float32, "GTiff")
        else:
            temp_interpolated_dem = None
            out_geo_dem_obj = None

        # geocode rasters
        geo.geocode(radar_grid=radar_grid,
                    input_raster=input_raster_obj,
                    output_raster=output_raster_obj,
                    dem_raster=dem_raster,
                    output_mode=output_mode,
                    geogrid_upsampling=geogrid_upsampling,
                    flag_apply_rtc=flag_apply_rtc,
                    input_terrain_radiometry=input_terrain_radiometry,
                    output_terrain_radiometry=output_terrain_radiometry,
                    exponent=exponent,
                    rtc_min_value_db=rtc_min_value_db,
                    rtc_upsampling=rtc_upsampling,
                    rtc_algorithm=rtc_algorithm,
                    abs_cal_factor=abs_cal_factor,
                    flag_upsample_radar_grid=flag_upsample_radar_grid,
                    clip_min=clip_min,
                    clip_max=clip_max,
                    radargrid_nlooks=radar_grid_nlooks,
                    out_off_diag_terms=out_off_diag_terms_obj,
                    out_geo_nlooks=out_geo_nlooks_obj,
                    out_geo_rtc=out_geo_rtc_obj,
                    out_geo_dem=out_geo_dem_obj,
                    input_rtc=None,
                    output_rtc=None,
                    dem_interp_method=dem_interp_method_enum,
                    memory_mode=memory_mode)

        del output_raster_obj

        if flag_save_nlooks:
            del out_geo_nlooks_obj

        if flag_save_rtc:
            del out_geo_rtc_obj

        if flag_save_dem:
            del out_geo_dem_obj

        if flag_fullcovariance:
            # out_off_diag_terms_obj.close_dataset()
            del out_off_diag_terms_obj

        with h5py.File(output_hdf5, 'a') as hdf5_obj:
            hdf5_obj.attrs['Conventions'] = np.string_("CF-1.8")
            root_ds = f'/science/LSAR/GCOV/grids/frequency{frequency}'

            h5_ds = os.path.join(root_ds, 'listOfPolarizations')
            if h5_ds in hdf5_obj:
                del hdf5_obj[h5_ds]
            pol_list_s2 = np.array(pol_list, dtype='S2')
            dset = hdf5_obj.create_dataset(h5_ds, data=pol_list_s2)
            dset.attrs['description'] = np.string_(
                'List of processed polarization layers with frequency ' +
                frequency)

            h5_ds = os.path.join(root_ds, 'radiometricTerrainCorrectionFlag')
            if h5_ds in hdf5_obj:
                del hdf5_obj[h5_ds]
            dset = hdf5_obj.create_dataset(h5_ds, data=bool(flag_apply_rtc))

            # save GCOV diagonal elements
            xds = hdf5_obj[os.path.join(root_ds, 'xCoordinates')]
            yds = hdf5_obj[os.path.join(root_ds, 'yCoordinates')]
            cov_elements_list = [p.upper() + p.upper() for p in pol_list]

            # save GCOV imagery
            _save_hdf5_dataset(temp_output.name,
                               hdf5_obj,
                               root_ds,
                               yds,
                               xds,
                               cov_elements_list,
                               long_name=output_radiometry_str,
                               units='',
                               valid_min=clip_min,
                               valid_max=clip_max)

            # save listOfCovarianceTerms
            freq_group = hdf5_obj[root_ds]
            if not flag_fullcovariance:
                _save_list_cov_terms(cov_elements_list, freq_group)

            # save nlooks
            if flag_save_nlooks:
                _save_hdf5_dataset(temp_nlooks.name,
                                   hdf5_obj,
                                   root_ds,
                                   yds,
                                   xds,
                                   'numberOfLooks',
                                   long_name='number of looks',
                                   units='',
                                   valid_min=0)

            # save rtc
            if flag_save_rtc:
                _save_hdf5_dataset(temp_rtc.name,
                                   hdf5_obj,
                                   root_ds,
                                   yds,
                                   xds,
                                   'areaNormalizationFactor',
                                   long_name='RTC area factor',
                                   units='',
                                   valid_min=0)

            # save interpolated DEM
            if flag_save_dem:
                '''
                The DEM is interpolated over the geogrid pixels vertices
                rather than the pixels centers.
                '''
                if (output_mode ==
                        isce3.geocode.GeocodeOutputMode.AREA_PROJECTION):
                    dem_geogrid = isce3.product.GeoGridParameters(
                        start_x=geogrid.start_x - geogrid.spacing_x / 2,
                        start_y=geogrid.start_y - geogrid.spacing_y / 2,
                        spacing_x=geogrid.spacing_x,
                        spacing_y=geogrid.spacing_y,
                        width=int(geogrid.width) + 1,
                        length=int(geogrid.length) + 1,
                        epsg=geogrid.epsg)
                    yds_dem, xds_dem = \
                        set_get_geo_info(hdf5_obj, root_ds, dem_geogrid)
                else:
                    yds_dem = yds
                    xds_dem = xds

                _save_hdf5_dataset(temp_interpolated_dem.name,
                                   hdf5_obj,
                                   root_ds,
                                   yds_dem,
                                   xds_dem,
                                   'interpolatedDem',
                                   long_name='Interpolated DEM',
                                   units='')

            # save GCOV off-diagonal elements
            if flag_fullcovariance:
                off_diag_terms_list = []
                for b1, p1 in enumerate(pol_list):
                    for b2, p2 in enumerate(pol_list):
                        if (b2 <= b1):
                            continue
                        off_diag_terms_list.append(p1.upper() + p2.upper())
                _save_list_cov_terms(cov_elements_list + off_diag_terms_list,
                                     freq_group)
                _save_hdf5_dataset(temp_off_diag.name,
                                   hdf5_obj,
                                   root_ds,
                                   yds,
                                   xds,
                                   off_diag_terms_list,
                                   long_name=output_radiometry_str,
                                   units='',
                                   valid_min=clip_min,
                                   valid_max=clip_max)

            t_freq_elapsed = time.time() - t_freq
            info_channel.log(
                f'frequency {frequency} ran in {t_freq_elapsed:.3f} seconds')

            if frequency.upper() == 'B':
                continue

            cube_geogrid = isce3.product.GeoGridParameters(
                start_x=radar_grid_cubes_geogrid.start_x,
                start_y=radar_grid_cubes_geogrid.start_y,
                spacing_x=radar_grid_cubes_geogrid.spacing_x,
                spacing_y=radar_grid_cubes_geogrid.spacing_y,
                width=int(radar_grid_cubes_geogrid.width),
                length=int(radar_grid_cubes_geogrid.length),
                epsg=radar_grid_cubes_geogrid.epsg)

            cube_group_name = '/science/LSAR/GCOV/metadata/radarGrid'
            native_doppler = slc.getDopplerCentroid()
            '''
            The native-Doppler LUT bounds error is turned off to
            computer cubes values outside radar-grid boundaries
            '''
            native_doppler.bounds_error = False
            add_radar_grid_cubes_to_hdf5(hdf5_obj, cube_group_name,
                                         cube_geogrid,
                                         radar_grid_cubes_heights, radar_grid,
                                         orbit, native_doppler, zero_doppler,
                                         threshold, maxiter)

    t_all_elapsed = time.time() - t_all
    info_channel.log(
        f"successfully ran geocode COV in {t_all_elapsed:.3f} seconds")
Example #13
0
def run(cfg, resample_type):
    '''
    run resample_slc
    '''
    input_hdf5 = cfg['input_file_group']['secondary_file_path']
    scratch_path = pathlib.Path(cfg['product_path_group']['scratch_path'])
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']

    # According to the type of resampling, choose proper resample cfg
    resamp_args = cfg['processing'][f'{resample_type}_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 = isce3.core.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)

        # Open offsets
        offsets_dir = pathlib.Path(resamp_args['offsets_dir'])

        # Create separate directories for coarse and fine resample
        # Open corresponding range/azimuth offsets
        resample_slc_scratch_path = scratch_path / \
                                    f'{resample_type}_resample_slc' / f'freq{freq}'
        if resample_type == 'coarse':
            offsets_path = offsets_dir / 'geo2rdr' / f'freq{freq}'
            rg_off = isce3.io.Raster(str(offsets_path / 'range.off'))
            az_off = isce3.io.Raster(str(offsets_path / 'azimuth.off'))
        else:
            # We checked the existence of HH/VV offsets in resample_slc_runconfig.py
            # Select the first offsets available between HH and VV
            freq_offsets_path = offsets_dir / 'rubbersheet_offsets' / f'freq{freq}'
            if os.path.isdir(str(freq_offsets_path / 'HH')):
                offsets_path = freq_offsets_path / 'HH'
            else:
                offsets_path = freq_offsets_path / 'VV'
            rg_off = isce3.io.Raster(str(offsets_path / 'range.off.vrt'))
            az_off = isce3.io.Raster(str(offsets_path / 'azimuth.off.vrt'))

        # Create resample slc directory
        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)

        # 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']

        # Get polarization list for which resample SLCs
        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'/{slc.SwathPath}/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")
Example #14
0
def main(opts):
    """
    crossmul
    """
    # prepare input rasters
    referenceSlc = SLC(hdf5file=opts.reference)
    referenceSlcDataset = referenceSlc.getSlcDataset(opts.frequency,
                                                     opts.polarization)
    referenceSlcRaster = isce3.io.raster(filename='', h5=referenceSlcDataset)
    secondarySlc = SLC(hdf5file=opts.secondary)
    if opts.secondaryRaster:
        secondarySlcRaster = isce3.io.raster(filename=opts.secondaryRaster)
    else:
        secondarySlcDataset = secondarySlc.getSlcDataset(
            opts.frequency, opts.polarization)
        secondarySlcRaster = isce3.io.raster(filename='',
                                             h5=secondarySlcDataset)

    # prepare mulitlooked interferogram dimensions
    referenceGrid = referenceSlc.getRadarGrid(opts.frequency)
    length = int(referenceGrid.length / opts.alks)
    width = int(referenceGrid.width / opts.rlks)

    # init output directory(s)
    getDir = lambda filepath: os.path.split(filepath)[0]
    os.makedirs(getDir(opts.intFilePath), exist_ok=True)
    os.makedirs(getDir(opts.cohFilePath), exist_ok=True)

    # prepare output rasters
    driver = gdal.GetDriverByName('ISCE')
    igramDataset = driver.Create(opts.intFilePath, width, length, 1,
                                 gdal.GDT_CFloat32)
    igramRaster = isce3.io.raster(filename='', dataset=igramDataset)
    # coherence only generated when multilooked enabled
    if (opts.alks > 1 or opts.rlks > 1):
        cohDataset = driver.Create(opts.cohFilePath, width, length, 1,
                                   gdal.GDT_Float32)
        cohRaster = isce3.io.raster(filename='', dataset=cohDataset)
    else:
        cohRaster = None

    # prepare optional rasters
    if opts.rgoff:
        rgOffRaster = isce3.io.raster(filename=opts.rgoff)
    else:
        rgOffRaster = None

    if opts.azband:
        dopReference = referenceSlc.getDopplerCentroid()
        dopSecondary = secondarySlc.getDopplerCentroid()
        prf = referenceSlc.getSwathMetadata(
            opts.frequency).nominalAcquisitionPRF
        azimuthBandwidth = opts.azband
    else:
        dopReference = dopSecondary = None
        prf = azimuthBandwidth = 0.0

    # instantiate crossmul object based on user input
    if 'cuda' not in dir(isce3) and opts.gpu:
        warnings.warn('CUDA crossmul not available. Switching to CPU crossmul')
        opts.gpu = False

    if opts.gpu:
        crossmul = isce3.cuda.signal.crossmul()
    else:
        crossmul = isce3.signal.crossmul()

    crossmul.crossmul(referenceSlcRaster,
                      secondarySlcRaster,
                      igramRaster,
                      cohRaster,
                      rngOffset=rgOffRaster,
                      refDoppler=dopReference,
                      secDoppler=dopSecondary,
                      rangeLooks=opts.rlks,
                      azimuthLooks=opts.alks,
                      prf=prf,
                      azimuthBandwidth=azimuthBandwidth)
Example #15
0
def run(cfg):
    '''
    run geocodeSlc according to parameters in cfg dict
    '''
    # pull parameters from cfg
    input_hdf5 = cfg['input_file_group']['input_file_path']
    output_hdf5 = cfg['product_path_group']['sas_output_file']
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']
    geogrids = cfg['processing']['geocode']['geogrids']
    radar_grid_cubes_geogrid = cfg['processing']['radar_grid_cubes']['geogrid']
    radar_grid_cubes_heights = cfg['processing']['radar_grid_cubes']['heights']
    dem_file = cfg['dynamic_ancillary_file_group']['dem_file']
    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

                # output_raster_ref = f'HDF5:{output_hdf5}:/{dataset_path}'
                gslc_raster = isce3.io.Raster(
                    f"IH5:::ID={gslc_dataset.id.id}".encode("utf-8"))
                compute_stats_complex_data(gslc_raster, gslc_dataset)

                t_pol_elapsed = time.time() - t_pol
                info_channel.log(
                    f'polarization {polarization} ran in {t_pol_elapsed:.3f} seconds'
                )

            if freq.upper() == 'B':
                continue

            cube_geogrid = isce3.product.GeoGridParameters(
                start_x=radar_grid_cubes_geogrid.start_x,
                start_y=radar_grid_cubes_geogrid.start_y,
                spacing_x=radar_grid_cubes_geogrid.spacing_x,
                spacing_y=radar_grid_cubes_geogrid.spacing_y,
                width=int(radar_grid_cubes_geogrid.width),
                length=int(radar_grid_cubes_geogrid.length),
                epsg=radar_grid_cubes_geogrid.epsg)

            cube_group_name = '/science/LSAR/GSLC/metadata/radarGrid'

            native_doppler.bounds_error = False
            '''
            The native-Doppler LUT bounds error is turned off to
            computer cubes values outside radar-grid boundaries
            '''
            add_radar_grid_cubes_to_hdf5(dst_h5, cube_group_name, cube_geogrid,
                                         radar_grid_cubes_heights, radar_grid,
                                         orbit, native_doppler,
                                         image_grid_doppler, threshold_geo2rdr,
                                         iteration_geo2rdr)

    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 rdr2geo
    '''
    # pull parameters from cfg
    input_hdf5 = cfg['input_file_group']['input_file_path']
    dem_file = cfg['dynamic_ancillary_file_group']['dem_file']
    scratch_path = pathlib.Path(cfg['product_path_group']['scratch_path'])
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']
    threshold = cfg['processing']['rdr2geo']['threshold']
    numiter = cfg['processing']['rdr2geo']['numiter']
    extraiter = cfg['processing']['rdr2geo']['extraiter']
    lines_per_block = cfg['processing']['rdr2geo']['lines_per_block']

    # 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 rdr2geo")

    # check if gpu ok to use
    use_gpu = isce3.core.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,
                              threshold=threshold,
                              numiter=numiter,
                              extraiter=extraiter,
                              lines_per_block=lines_per_block)

        # dict of layer names keys to tuples of their output name and GDAL types
        layers = {
            'x': ('x', gdal.GDT_Float64),
            'y': ('y', gdal.GDT_Float64),
            'z': ('z', gdal.GDT_Float64),
            'incidence': ('incidence', gdal.GDT_Float32),
            'heading': ('heading', gdal.GDT_Float32),
            'local_incidence': ('localIncidence', gdal.GDT_Float32),
            'local_psi': ('localPsi', gdal.GDT_Float32),
            'simulated_amplitude': ('simamp', gdal.GDT_Float32),
            'layover_shadow': ('layoverShadowMask', gdal.GDT_Byte)
        }

        # get rdr2geo config dict from processing dict for brevity
        rdr2geo_cfg = cfg['processing']['rdr2geo']

        # list comprehend rasters to be written from layers dict
        raster_list = [
            get_raster_obj(f'{str(rdr2geo_scratch_path)}/{fname}.rdr',
                           radargrid, rdr2geo_cfg[f'write_{key_name}'], dtype)
            for key_name, (fname, dtype) in layers.items()
        ]

        # extract individual elements from dict as args for topo
        x_raster, y_raster, height_raster, incidence_raster,\
            heading_raster, local_incidence_raster, local_psi_raster,\
            simulated_amplitude_raster, shadow_raster = raster_list

        # run topo
        rdr2geo_obj.topo(dem_raster, x_raster, y_raster, height_raster,
                         incidence_raster, heading_raster,
                         local_incidence_raster, local_psi_raster,
                         simulated_amplitude_raster, shadow_raster)

        # remove undesired/None rasters from raster list
        raster_list = [raster for raster in raster_list if raster is not None]

        # save non-None rasters to vrt
        output_vrt = isce3.io.Raster(f'{str(rdr2geo_scratch_path)}/topo.vrt',
                                     raster_list)
        output_vrt.set_epsg(rdr2geo_obj.epsg_out)

    t_all_elapsed = time.time() - t_all
    info_channel.log(
        f"successfully ran rdr2geo in {t_all_elapsed:.3f} seconds")
Example #17
0
def run(cfg: dict, output_hdf5: str = None, resample_type='coarse'):
    '''
    run crossmul
    '''
    # pull parameters from cfg
    ref_hdf5 = cfg['input_file_group']['input_file_path']
    sec_hdf5 = cfg['input_file_group']['secondary_file_path']
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']
    flatten = cfg['processing']['crossmul']['flatten']

    if flatten is not None:
        flatten_path = cfg['processing']['crossmul']['flatten']

    if output_hdf5 is None:
        output_hdf5 = cfg['product_path_group']['sas_output_file']

    # init parameters shared by frequency A and B
    ref_slc = SLC(hdf5file=ref_hdf5)
    sec_slc = SLC(hdf5file=sec_hdf5)

    error_channel = journal.error('crossmul.run')
    info_channel = journal.info("crossmul.run")
    info_channel.log("starting crossmultipy")

    # check if gpu ok to use
    use_gpu = isce3.core.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)
        crossmul = isce3.cuda.signal.Crossmul()
    else:
        crossmul = isce3.signal.Crossmul()

    crossmul.range_looks = cfg['processing']['crossmul']['range_looks']
    crossmul.az_looks = cfg['processing']['crossmul']['azimuth_looks']
    crossmul.oversample = cfg['processing']['crossmul']['oversample']
    crossmul.rows_per_block = cfg['processing']['crossmul']['rows_per_block']

    # check if user provided path to raster(s) is a file or directory
    coregistered_slc_path = pathlib.Path(
        cfg['processing']['crossmul']['coregistered_slc_path'])
    coregistered_is_file = coregistered_slc_path.is_file()
    if not coregistered_is_file and not coregistered_slc_path.is_dir():
        err_str = f"{coregistered_slc_path} is invalid; needs to be a file or directory."
        error_channel.log(err_str)
        raise ValueError(err_str)

    t_all = time.time()
    with h5py.File(output_hdf5, 'a', libver='latest', swmr=True) as dst_h5:
        for freq, pol_list in freq_pols.items():
            # get 2d doppler, discard azimuth dependency, and set crossmul dopplers
            ref_dopp = isce3.core.avg_lut2d_to_lut1d(
                ref_slc.getDopplerCentroid(frequency=freq))
            sec_dopp = isce3.core.avg_lut2d_to_lut1d(
                sec_slc.getDopplerCentroid(frequency=freq))
            crossmul.set_dopplers(ref_dopp, sec_dopp)

            freq_group_path = f'/science/LSAR/RIFG/swaths/frequency{freq}'

            if flatten is not None:
                # set frequency dependent range offset raster
                flatten_raster = isce3.io.Raster(
                    f'{flatten_path}/geo2rdr/freq{freq}/range.off')

                # prepare range filter parameters
                rdr_grid = ref_slc.getRadarGrid(freq)
                rg_pxl_spacing = rdr_grid.range_pixel_spacing
                wavelength = rdr_grid.wavelength
                rg_sample_freq = isce3.core.speed_of_light / 2.0 / rg_pxl_spacing
                rg_bandwidth = ref_slc.getSwathMetadata(
                    freq).processed_range_bandwidth

                # set crossmul range filter
                crossmul.set_rg_filter(rg_sample_freq, rg_bandwidth,
                                       rg_pxl_spacing, wavelength)

            for pol in pol_list:
                pol_group_path = f'{freq_group_path}/interferogram/{pol}'

                # prepare reference input raster
                ref_raster_str = f'HDF5:{ref_hdf5}:/{ref_slc.slcPath(freq, pol)}'
                ref_slc_raster = isce3.io.Raster(ref_raster_str)

                # prepare secondary input raster
                if coregistered_is_file:
                    raster_str = f'HDF5:{sec_hdf5}:/{sec_slc.slcPath(freq, pol)}'
                else:
                    raster_str = str(
                        coregistered_slc_path /
                        f'{resample_type}_resample_slc/'
                        f'freq{freq}/{pol}/coregistered_secondary.slc')

                sec_slc_raster = isce3.io.Raster(raster_str)

                # access the HDF5 dataset for a given frequency and polarization
                dataset_path = f'{pol_group_path}/wrappedInterferogram'
                igram_dataset = dst_h5[dataset_path]

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

                # call crossmul with coherence if multilooked
                if crossmul.range_looks > 1 or crossmul.az_looks > 1:
                    # access the HDF5 dataset for a given frequency and polarization
                    dataset_path = f'{pol_group_path}/coherenceMagnitude'
                    coherence_dataset = dst_h5[dataset_path]

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

                    if flatten is not None:
                        crossmul.crossmul(ref_slc_raster, sec_slc_raster,
                                          flatten_raster, igram_raster,
                                          coherence_raster)
                    else:
                        crossmul.crossmul(ref_slc_raster, sec_slc_raster,
                                          igram_raster, coherence_raster)

                    # Allocate raster statistics for coherence
                    compute_stats_real_data(coherence_raster,
                                            coherence_dataset)

                    del coherence_raster
                else:
                    # no coherence without multilook
                    crossmul.crossmul(ref_slc_raster, sec_slc_raster,
                                      igram_raster)
                del igram_raster

                # Allocate stats for rubbersheet offsets
                stats_offsets(dst_h5, freq, pol)

    t_all_elapsed = time.time() - t_all
    info_channel.log(
        f"successfully ran crossmul in {t_all_elapsed:.3f} seconds")
Example #18
0
def cpu_run(cfg, runw_hdf5, output_hdf5):
    """ Geocode RUNW products on CPU

    Parameters
    ----------
    cfg : dict
        Dictionary containing run configuration
    runw_hdf5 : str
        Path input RUNW HDF5
    output_hdf5 : str
        Path to output GUNW HDF5
    """
    # pull parameters from cfg
    ref_hdf5 = cfg["input_file_group"]["input_file_path"]
    freq_pols = cfg["processing"]["input_subset"]["list_of_frequencies"]
    geogrids = cfg["processing"]["geocode"]["geogrids"]
    dem_file = cfg["dynamic_ancillary_file_group"]["dem_file"]
    threshold_geo2rdr = cfg["processing"]["geo2rdr"]["threshold"]
    iteration_geo2rdr = cfg["processing"]["geo2rdr"]["maxiter"]
    lines_per_block = cfg["processing"]["geocode"]["lines_per_block"]
    dem_block_margin = cfg["processing"]["dem_margin"]
    az_looks = cfg["processing"]["crossmul"]["azimuth_looks"]
    rg_looks = cfg["processing"]["crossmul"]["range_looks"]
    interp_method = cfg["processing"]["geocode"]["interp_method"]
    gunw_datasets = cfg["processing"]["geocode"]["datasets"]
    scratch_path = pathlib.Path(cfg['product_path_group']['scratch_path'])
    offset_cfg = cfg["processing"]["dense_offsets"]

    slc = SLC(hdf5file=ref_hdf5)

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

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

    # 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

    # init geocode object
    geo = isce3.geocode.GeocodeFloat32()

    # init geocode members
    orbit = slc.getOrbit()
    geo.orbit = orbit
    geo.ellipsoid = ellipsoid
    geo.doppler = grid_zero_doppler
    geo.threshold_geo2rdr = threshold_geo2rdr
    geo.numiter_geo2rdr = iteration_geo2rdr
    geo.dem_block_margin = dem_block_margin
    geo.lines_per_block = lines_per_block
    geo.data_interpolator = interp_method

    t_all = time.time()
    with h5py.File(output_hdf5, "a") as dst_h5:
        for freq, pol_list in freq_pols.items():
            radar_grid_slc = slc.getRadarGrid(freq)
            if az_looks > 1 or rg_looks > 1:
                radar_grid_mlook = radar_grid_slc.multilook(az_looks, rg_looks)

            geo_grid = geogrids[freq]
            geo.geogrid(
                geo_grid.start_x,
                geo_grid.start_y,
                geo_grid.spacing_x,
                geo_grid.spacing_y,
                geo_grid.width,
                geo_grid.length,
                geo_grid.epsg,
            )

            # Assign correct radar grid
            if az_looks > 1 or rg_looks > 1:
                radar_grid = radar_grid_mlook
            else:
                radar_grid = radar_grid_slc

            desired = ['coherence_magnitude', 'unwrapped_phase']
            geo.data_interpolator = interp_method
            cpu_geocode_rasters(geo, gunw_datasets, desired, freq, pol_list,
                                runw_hdf5, dst_h5, radar_grid, dem_raster)

            desired = ["connected_components"]
            geo.data_interpolator = 'NEAREST'
            cpu_geocode_rasters(geo, gunw_datasets, desired, freq, pol_list,
                                runw_hdf5, dst_h5, radar_grid, dem_raster)

            desired = ['along_track_offset', 'slant_range_offset']
            geo.data_interpolator = interp_method
            radar_grid_offset = get_offset_radar_grid(offset_cfg,
                                                      radar_grid_slc)
            cpu_geocode_rasters(geo, gunw_datasets, desired, freq, pol_list,
                                runw_hdf5, dst_h5, radar_grid_offset,
                                dem_raster)

            desired = ["layover_shadow_mask"]
            geo.data_interpolator = 'NEAREST'
            cpu_geocode_rasters(geo, gunw_datasets, desired, freq, pol_list,
                                runw_hdf5, dst_h5, radar_grid_slc, dem_raster,
                                scratch_path, compute_stats=False)

            # spec for NISAR GUNW does not require freq B so skip radar cube
            if freq.upper() == 'B':
                continue

            add_radar_grid_cube(cfg, freq, radar_grid, orbit, dst_h5)


    t_all_elapsed = time.time() - t_all
    info_channel.log(f"Successfully ran geocode in {t_all_elapsed:.3f} seconds")
Example #19
0
def create(cfg,
           frequency_group=None,
           frequency=None,
           geocode_dict=None,
           default_spacing_x=None,
           default_spacing_y=None):
    '''
    - frequency_group is the name of the sub-group that
    holds the fields x_posting and y_posting, which is usually
    the frequency groups "A" or "B". If these fields
    are direct member of the output_posting group, e.g 
    for radar_grid_cubes, the frequency_group should be left
     as None.
    - frequency is the frequency name, if not provided, it will be
    the same as the frequency_group.
    - geocode_dict overwrites the default geocode_dict from 
    processing.geocode
    - default_spacing_x is default pixel spacing in the X-direction
    - default_spacing_y is default pixel spacing in the Y-direction

    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
    if geocode_dict is None:
        geocode_dict = cfg['processing']['geocode']

    input_hdf5 = cfg['input_file_group']['input_file_path']
    dem_file = cfg['dynamic_ancillary_file_group']['dem_file']
    slc = SLC(hdf5file=input_hdf5)

    # unpack and check cfg dict values. default values set to trigger inside fix(...)
    epsg = geocode_dict['output_epsg']
    start_x = geocode_dict['top_left']['x_abs']
    start_y = geocode_dict['top_left']['y_abs']

    if frequency is None:
        frequency = frequency_group

    if frequency_group is None:
        spacing_x = geocode_dict['output_posting']['x_posting']
        spacing_y = geocode_dict['output_posting']['y_posting']
    else:
        spacing_x = geocode_dict['output_posting'][frequency_group][
            'x_posting']
        spacing_y = geocode_dict['output_posting'][frequency_group][
            '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

    # copy X spacing from default X spacing (if applicable)
    if spacing_x is None and default_spacing_x is not None:
        spacing_x = default_spacing_x

    # copy Y spacing from default Y spacing (if applicable)
    if spacing_y is None and default_spacing_y is not None:
        spacing_y = default_spacing_y

    if spacing_x is None or spacing_y is None:
        dem_raster = isce3.io.Raster(dem_file)

        # Set pixel spacing using the input DEM (same EPSG)
        if epsg == dem_raster.get_epsg():

            # 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)

        else:
            epsg_spatial_ref = osr.SpatialReference()
            epsg_spatial_ref.ImportFromEPSG(epsg)

            # Set pixel spacing in degrees (lat/lon)
            if epsg_spatial_ref.IsGeographic():
                if spacing_x is None:
                    spacing_x = 0.00017966305682390427
                if spacing_y is None:
                    spacing_y = -0.00017966305682390427

            # Set pixel spacing in meters
            else:
                if spacing_x is None:
                    spacing_x = 20
                if spacing_y is None:
                    spacing_y = -20

    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)

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

        # extract other geogrid params from radar grid and orbit constructed bounding box
        geogrid = isce3.product.bbox_to_geogrid(slc.getRadarGrid(frequency),
                                                slc.getOrbit(),
                                                isce3.core.LUT2d(), 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:
        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 = isce3.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 #20
0
def main(opts):
    """
    Runs isce::geocode::GeocodeCov for any GDAL raster with an associated HDF5 product.
    For example, to geocode a multilooked interferogram, provide the HDF5 product
    for the reference scene which defined the full-resolution radar geometry.
    """
    # Common driver for all output files
    driver = gdal.GetDriverByName('ISCE')

    # Open input raster
    input_raster = Raster(opts.raster)

    # Open its associated product
    slc = SLC(hdf5file=opts.h5)

    # Make ellipsoid
    ellps = isce3.core.ellipsoid()

    # Get radar grid
    radar_grid = slc.getRadarGrid()
    if (opts.alks > 1 or opts.rlks > 1):
        radar_grid = radar_grid.multilook(opts.alks, opts.rlks)

    # Get orbit
    orbit = slc.getOrbit()

    # Make reference epochs consistent
    orbit.referenceEpoch = radar_grid.referenceEpoch

    # Make a zero-Doppler LUT
    doppler = isce3.core.lut2d()

    # Compute DEM bounds for radar grid
    proj_win = isce3.geometry.geometry.getBoundsOnGround(
        orbit,
        ellps,
        doppler,
        radar_grid,
        0,
        0,
        radar_grid.width,
        radar_grid.length,
        margin=np.radians(0.01))
    # GDAL expects degrees
    proj_win = np.degrees(proj_win)

    # Extract virtual DEM covering radar bounds
    ds = gdal.Open(opts.dem, gdal.GA_ReadOnly)
    crop_dem_ds = gdal.Translate('/vsimem/dem.crop',
                                 ds,
                                 format='ISCE',
                                 projWin=proj_win)
    ds = None

    # Instantiate Geocode object
    geo = Geocode(orbit=orbit, ellipsoid=ellps, inputRaster=input_raster)

    # Set radar grid
    # geo.radarGrid(doppler,
    # 	radar_grid.referenceEpoch,
    # 	radar_grid.sensingStart,
    # 	1.0/radar_grid.prf,
    #             radar_grid.length,
    # 	radar_grid.startingRange,
    # 	radar_grid.rangePixelSpacing,
    #             radar_grid.wavelength,
    # 	radar_grid.width,
    # 	radar_grid.lookSide)

    # Get DEM geotransform from DEM raster
    lon0, dlon, _, lat0, _, dlat = crop_dem_ds.GetGeoTransform()
    ny_geo = crop_dem_ds.RasterYSize
    nx_geo = crop_dem_ds.RasterXSize
    crop_dem_ds = None
    print('Cropped DEM shape: (%d, %d)' % (ny_geo, nx_geo))

    # Open DEM raster as an ISCE raster
    dem_raster = Raster('/vsimem/dem.crop')

    # Set geographic grid
    geo.geoGrid(lon0, lat0, dlon, dlat, nx_geo, ny_geo, dem_raster.EPSG)

    # Create output raster
    if opts.outname == '':
        opts.outname = opts.raster + '.geo'
    odset = driver.Create(opts.outname, nx_geo, ny_geo, 1,
                          input_raster.getDatatype(band=1))
    output_raster = Raster('', dataset=odset)

    # Run geocoding
    geo.geocode(radar_grid, input_raster, output_raster, dem_raster)

    # Clean up
    crop_dem_ds = None
    odset = None
    gdal.Unlink('/vsimem/dem.crop')
Example #21
0
def gpu_run(cfg, runw_hdf5, output_hdf5):
    """ Geocode RUNW products on GPU

    Parameters
    ----------
    cfg : dict
        Dictionary containing run configuration
    runw_hdf5 : str
        Path input RUNW HDF5
    output_hdf5 : str
        Path to output GUNW HDF5
    """
    t_all = time.time()

    # Extract parameters from cfg dictionary
    dem_block_margin = cfg["processing"]["dem_margin"]
    ref_hdf5 = cfg["input_file_group"]["input_file_path"]
    dem_file = cfg["dynamic_ancillary_file_group"]["dem_file"]
    freq_pols = cfg["processing"]["input_subset"]["list_of_frequencies"]
    geogrids = cfg["processing"]["geocode"]["geogrids"]
    lines_per_block = cfg["processing"]["geocode"]["lines_per_block"]
    interp_method = cfg["processing"]["geocode"]["interp_method"]
    gunw_datasets = cfg["processing"]["geocode"]["datasets"]
    az_looks = cfg["processing"]["crossmul"]["azimuth_looks"]
    rg_looks = cfg["processing"]["crossmul"]["range_looks"]
    offset_cfg = cfg["processing"]["dense_offsets"]
    scratch_path = pathlib.Path(cfg['product_path_group']['scratch_path'])

    if interp_method == 'BILINEAR':
        interp_method = isce3.core.DataInterpMethod.BILINEAR
    if interp_method == 'BICUBIC':
        interp_method = isce3.core.DataInterpMethod.BICUBIC
    if interp_method == 'NEAREST':
        interp_method = isce3.core.DataInterpMethod.NEAREST
    if interp_method == 'BIQUINTIC':
        interp_method = isce3.core.DataInterpMethod.BIQUINTIC

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

    # Init frequency independent objects
    slc = SLC(hdf5file=ref_hdf5)
    grid_zero_doppler = isce3.core.LUT2d()
    dem_raster = isce3.io.Raster(dem_file)

    with h5py.File(output_hdf5, "a", libver='latest', swmr=True) as dst_h5:

        get_ds_names = lambda ds_dict, desired: [
            x for x, y in ds_dict.items() if y and x in desired]

        # Per frequency, init required geocode objects
        for freq, pol_list in freq_pols.items():

            geogrid = geogrids[freq]

            # Create frequency based radar grid
            radar_grid = slc.getRadarGrid(freq)
            if az_looks > 1 or rg_looks > 1:
                # Multilook radar grid if needed
                radar_grid = radar_grid.multilook(az_looks, rg_looks)

            desired = ['coherence_magnitude', 'unwrapped_phase']
            # Create radar grid geometry used by most datasets
            rdr_geometry = isce3.container.RadarGeometry(radar_grid,
                                                         slc.getOrbit(),
                                                         grid_zero_doppler)

            # Create geocode object other than offset and shadow layover datasets
            geocode_obj = isce3.cuda.geocode.Geocode(geogrid, rdr_geometry,
                                                     dem_raster,
                                                     dem_block_margin,
                                                     lines_per_block,
                                                     interp_method,
                                                     invalid_value=np.nan)

            gpu_geocode_rasters(gunw_datasets, desired, freq, pol_list,
                                runw_hdf5, dst_h5, geocode_obj)

            desired = ["connected_components"]
            '''
            connected_components raster has type unsigned char and an invalid
            value of NaN becomes 0 which conflicts with 0 being used to indicate
            an unmasked value/pixel. 255 is chosen as it is the most distant
            value from components assigned in ascending order [0, 1, ...)
            '''
            geocode_conn_comp_obj = isce3.cuda.geocode.Geocode(geogrid, rdr_geometry,
                                                     dem_raster,
                                                     dem_block_margin,
                                                     lines_per_block,
                                                     isce3.core.DataInterpMethod.NEAREST,
                                                     invalid_value=255)

            gpu_geocode_rasters(gunw_datasets, desired, freq, pol_list,
                                runw_hdf5, dst_h5, geocode_conn_comp_obj)

            desired = ['along_track_offset', 'slant_range_offset']
            # If needed create geocode object for offset datasets
            # Create offset unique radar grid
            radar_grid = get_offset_radar_grid(offset_cfg,
                                               slc.getRadarGrid(freq))

            # Create radar grid geometry required by offset datasets
            rdr_geometry = isce3.container.RadarGeometry(radar_grid,
                                                         slc.getOrbit(),
                                                         grid_zero_doppler)

            geocode_offset_obj = isce3.cuda.geocode.Geocode(geogrid,
                                                            rdr_geometry,
                                                            dem_raster,
                                                            dem_block_margin,
                                                            lines_per_block,
                                                            interp_method,
                                                            invalid_value=np.nan)

            gpu_geocode_rasters(gunw_datasets, desired, freq, pol_list,
                                runw_hdf5, dst_h5, geocode_offset_obj)

            desired = ["layover_shadow_mask"]
            # If needed create geocode object for shadow layover dataset
            # Create radar grid geometry required by layover shadow
            rdr_geometry = isce3.container.RadarGeometry(slc.getRadarGrid(freq),
                                                         slc.getOrbit(),
                                                         grid_zero_doppler)

            '''
            layover shadow raster has type char and an invalid
            value of NaN becomes 0 which conflicts with 0 being used
            to indicate an unmasked value/pixel. 127 is chosen as it is
            the most distant value from the allowed set of [0, 1, 2, 3].
            '''
            geocode_shadow_obj = isce3.cuda.geocode.Geocode(geogrid,
                                                            rdr_geometry,
                                                            dem_raster,
                                                            dem_block_margin,
                                                            lines_per_block,
                                                            isce3.core.DataInterpMethod.NEAREST,
                                                            invalid_value=127)

            gpu_geocode_rasters(gunw_datasets, desired, freq, pol_list,
                                runw_hdf5, dst_h5, geocode_shadow_obj, scratch_path,
                                compute_stats=False)

            # spec for NISAR GUNW does not require freq B so skip radar cube
            if freq.upper() == 'B':
                continue

            add_radar_grid_cube(cfg, freq, radar_grid, slc.getOrbit(), dst_h5)

    t_all_elapsed = time.time() - t_all
    info_channel.log(f"Successfully ran geocode in {t_all_elapsed:.3f} seconds")
Example #22
0
def run(cfg):
    '''
    run geo2rdr
    '''

    # Pull parameters from cfg dict
    sec_hdf5 = cfg['input_file_group']['secondary_file_path']
    dem_file = cfg['dynamic_ancillary_file_group']['dem_file']
    scratch_path = pathlib.Path(cfg['product_path_group']['scratch_path'])
    freq_pols = cfg['processing']['input_subset']['list_of_frequencies']
    threshold = cfg['processing']['geo2rdr']['threshold']
    numiter = cfg['processing']['geo2rdr']['maxiter']
    lines_per_block = cfg['processing']['geo2rdr']['lines_per_block']

    # 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 = isce3.core.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, numiter, lines_per_block)

        # 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 #23
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()

    # set input parameters
    input_terrain_radiometry = isce3.geometry.RtcInputTerrainRadiometry.BETA_NAUGHT
    output_terrain_radiometry = isce3.geometry.RtcOutputTerrainRadiometry.GAMMA_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_BILINEAR_DISTRIBUTION
                    and radar_grid_str == 'cropped'):
                continue
            elif (rtc_algorithm ==
                  isce3.geometry.RtcAlgorithm.RTC_BILINEAR_DISTRIBUTION):
                filename = './rtc_bilinear_distribution_' + 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.compute_rtc(radar_grid, orbit, doppler, dem_obj,
                                       out_raster, input_terrain_radiometry,
                                       output_terrain_radiometry,
                                       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_BILINEAR_DISTRIBUTION
                    and radar_grid_str == 'cropped'):
                continue
            elif (rtc_algorithm ==
                  isce3.geometry.RtcAlgorithm.RTC_BILINEAR_DISTRIBUTION):
                max_rmse = 0.7
                filename = './rtc_bilinear_distribution_' + 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)