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)
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")) orbit = rslc.getOrbit() native_doppler = rslc.getDopplerCentroid() native_doppler.bounds_error = False grid_doppler = native_doppler threshold_geo2rdr = 1e-8 numiter_geo2rdr = 25 delta_range = 1e-6 epsg = 4326 # get radar grid from HDF5 radar_grid = isce3.product.RadarGridParameters( os.path.join(iscetest.data, "envisat.h5")) radar_grid = radar_grid[::10, ::10] heights = [0.0, 1000.0] output_h5 = 'envisat_geolocation_cube.h5' fid = h5py.File(output_h5, 'w') cube_group_name = '/science/LSAR/SLC/metadata/radarGrid' add_geolocation_grid_cubes_to_hdf5(fid, cube_group_name, radar_grid, heights, orbit, native_doppler, grid_doppler, epsg, threshold_geo2rdr, numiter_geo2rdr, delta_range) print('saved file:', output_h5)
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
def test_run_raster_layers(): ''' check if topo runs ''' # prepare Rdr2Geo init params 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() # init Rdr2Geo class rdr2geo_obj = isce3.geometry.Rdr2Geo(radargrid, orbit, ellipsoid, doppler) # load test DEM dem_raster = isce3.io.Raster( os.path.join(iscetest.data, "srtm_cropped.tif")) x_raster = isce3.io.Raster("x.rdr", radargrid.width, radargrid.length, 1, gdal.GDT_Float64, 'ENVI') y_raster = isce3.io.Raster("y.rdr", radargrid.width, radargrid.length, 1, gdal.GDT_Float64, 'ENVI') height_raster = isce3.io.Raster("z.rdr", radargrid.width, radargrid.length, 1, gdal.GDT_Float64, 'ENVI') incidence_angle_raster = isce3.io.Raster("inc.rdr", radargrid.width, radargrid.length, 1, gdal.GDT_Float32, 'ENVI') heading_angle_raster = isce3.io.Raster("hgd.rdr", radargrid.width, radargrid.length, 1, gdal.GDT_Float32, 'ENVI') local_incidence_angle_raster = isce3.io.Raster("localInc.rdr", radargrid.width, radargrid.length, 1, gdal.GDT_Float32, 'ENVI') local_Psi_raster = isce3.io.Raster("localPsi.rdr", radargrid.width, radargrid.length, 1, gdal.GDT_Float32, 'ENVI') simulated_amplitude_raster = isce3.io.Raster("simamp.rdr", radargrid.width, radargrid.length, 1, gdal.GDT_Float32, 'ENVI') layover_shadow_raster = isce3.io.Raster("layoverShadowMask.rdr", radargrid.width, radargrid.length, 1, gdal.GDT_Float32, 'ENVI') # run rdr2geo_obj.topo(dem_raster, x_raster, y_raster, height_raster, incidence_angle_raster, heading_angle_raster, local_incidence_angle_raster, local_Psi_raster, simulated_amplitude_raster, layover_shadow_raster) topo_raster = isce3.io.Raster( "topo_layers.vrt", raster_list=[ x_raster, y_raster, height_raster, incidence_angle_raster, heading_angle_raster, local_incidence_angle_raster, local_Psi_raster, simulated_amplitude_raster ])
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)
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.image.ResampSlc(grid, slc.getDopplerCentroid()) 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)
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)
def test_cuda_geocode(): rslc = SLC(hdf5file=os.path.join(iscetest.data, "envisat.h5")) dem_raster = isce3.io.Raster( os.path.join(iscetest.data, "geocode/zeroHeightDEM.geo")) dem_margin = 0.1 # define geogrid epsg = 4326 geogrid = isce3.product.GeoGridParameters(start_x=-115.65, start_y=34.84, spacing_x=0.0002, spacing_y=-8.0e-5, width=500, length=500, epsg=epsg) geotrans = [ geogrid.start_x, geogrid.spacing_x, 0.0, geogrid.start_y, 0.0, geogrid.spacing_y ] # init RadarGeometry, orbit, and doppler from RSLC radargrid = isce3.product.RadarGridParameters( os.path.join(iscetest.data, "envisat.h5")) orbit = rslc.getOrbit() doppler = rslc.getDopplerCentroid() rdr_geometry = isce3.container.RadarGeometry(radargrid, orbit, doppler) # set interp method interp_method = isce3.core.DataInterpMethod.BILINEAR # init CUDA geocode obj for xy, suffix in itertools.product(['x', 'y'], ['', '_blocked']): lines_per_block = 126 if suffix else 1000 cu_geocode = isce3.cuda.geocode.Geocode(geogrid, rdr_geometry, dem_raster, dem_margin, lines_per_block, interp_method) output_raster = isce3.io.Raster(f"{xy}{suffix}.geo", geogrid.width, geogrid.length, 1, gdal.GDT_CFloat32, "ENVI") input_raster = isce3.io.Raster( os.path.join(iscetest.data, f"geocodeslc/{xy}.slc")) for i in range(cu_geocode.n_blocks): cu_geocode.set_block_radar_coord_grid(i) cu_geocode.geocode_raster_block(output_raster, input_raster) output_raster.set_geotransform(geotrans)
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)
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() # require geolocation accurate to one millionth of a pixel. tol_pixels = 1e-6 tol_seconds = tol_pixels / radargrid.prf # init Geo2Rdr class geo2rdr_obj = isce.cuda.geometry.Geo2Rdr(radargrid, orbit, ellipsoid, doppler, threshold=tol_seconds, numiter=50) # load rdr2geo unit test output rdr2geo_raster = isce.io.Raster("topo.vrt") # run geo2rdr_obj.geo2rdr(rdr2geo_raster, ".") # list of test outputs test_outputs = ["range.off", "azimuth.off"] # check each generated raster for test_output in test_outputs: # load dataset and get array test_ds = gdal.Open(test_output, gdal.GA_ReadOnly) test_arr = test_ds.GetRasterBand(1).ReadAsArray() # mask bad values test_arr = np.ma.masked_array(test_arr, mask=np.abs(test_arr) > 999.0) # compute max error (in pixels) test_err = np.max(np.abs(test_arr)) # Error may slightly exceed tolerance since Newton step size isn't a # perfect estimate of the error in the solution. assert (test_err < 2 * tol_pixels), f"{test_output} accumulated error fail"
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.geocode.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.numiter_geo2rdr = 25 geo_obj.lines_per_block = 1000 geo_obj.dem_block_margin = 1e-1 geo_obj.radar_block_margin = 10 geo_obj.data_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)
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
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
def add_radar_grid_cube(cfg, freq, radar_grid, orbit, dst_h5): ''' Write radar grid cube to HDF5 Parameters ---------- cfg : dict Dictionary containing run configuration freq : str Frequency in HDF5 to add cube to radar_grid : isce3.product.radar_grid Radar grid of current frequency of datasets other than offset and shadow layover datasets orbit : isce3.core.orbit Orbit object of current SLC dst_h5: str Path to output GUNW HDF5 ''' radar_grid_cubes_geogrid = cfg['processing']['radar_grid_cubes']['geogrid'] radar_grid_cubes_heights = cfg['processing']['radar_grid_cubes']['heights'] threshold_geo2rdr = cfg["processing"]["geo2rdr"]["threshold"] iteration_geo2rdr = cfg["processing"]["geo2rdr"]["maxiter"] ref_hdf5 = cfg["input_file_group"]["input_file_path"] slc = SLC(hdf5file=ref_hdf5) # get doppler centroid cube_geogrid_param = 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_path = '/science/LSAR/GUNW/metadata/radarGrid' native_doppler = slc.getDopplerCentroid(frequency=freq) grid_zero_doppler = isce3.core.LUT2d() ''' 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(dst_h5, cube_group_path, cube_geogrid_param, radar_grid_cubes_heights, radar_grid, orbit, native_doppler, grid_zero_doppler, threshold_geo2rdr, iteration_geo2rdr)
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['input_file_group']['input_file_path'] 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)
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
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)
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)
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
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)
def open_product(filename: str, product_type: str = None, root_path: str = None): ''' Open NISAR product (HDF5 file), instantianting an object of an existing product class (e.g. RSLC, RRSD), if defined, or a general product (GeneralProduct) otherwise. Parameters ---------- filename : str HDF5 filename product_type : str Preliminary product type to check (e.g. RCOV) before default product type list root_path : str Preliminary root path to check (e.g., XSAR, PSAR) before default root path list Returns ------- object Object derived from the base class ''' if root_path is None: root_path = get_hdf5_file_root_path(filename, root_path=root_path) product_type = get_hdf5_file_product_type(filename, product_type=product_type, root_path=root_path) # set keyword arguments for class constructors kwargs = {} kwargs['hdf5file'] = filename kwargs['_RootPath'] = root_path if (product_type == 'RSLC'): # return SLC obj from nisar.products.readers import SLC return SLC(**kwargs) elif (product_type == 'RRSD'): # return Raw obj from nisar.products.readers.Raw import Raw return Raw(**kwargs) kwargs['_ProductType'] = product_type # return ProductFactory obj return GenericProduct(**kwargs)
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")) orbit = rslc.getOrbit() native_doppler = rslc.getDopplerCentroid() native_doppler.bounds_error = False grid_doppler = native_doppler threshold_geo2rdr = 1e-8 numiter_geo2rdr = 25 delta_range = 1e-8 # prepare geogrid geogrid = isce3.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) # get radar grid from HDF5 radar_grid = isce3.product.RadarGridParameters( os.path.join(iscetest.data, "envisat.h5")) heights = [0.0, 1000.0] output_h5 = 'envisat_radar_grid_cube.h5' fid = h5py.File(output_h5, 'w') cube_group_name = '/science/LSAR/GCOV/metadata/radarGrid' add_radar_grid_cubes_to_hdf5(fid, cube_group_name, geogrid, heights, radar_grid, orbit, native_doppler, grid_doppler, threshold_geo2rdr, numiter_geo2rdr, delta_range) print('saved file:', output_h5)
def test_run(): ''' check if topo runs ''' # prepare Rdr2Geo init params 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() # init Rdr2Geo class rdr2geo_obj = isce3.cuda.geometry.Rdr2Geo(radargrid, orbit, ellipsoid, doppler) # load test DEM dem_raster = isce3.io.Raster(os.path.join(iscetest.data, "srtm_cropped.tif")) # run rdr2geo_obj.topo(dem_raster, ".")
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)
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')
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")
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)
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")
def slc_obj(self): if self._slc_obj is None: self._slc_obj = SLC(hdf5file=self.state.input_hdf5) return self._slc_obj
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