def cut_resampled_grid(outdir, filename, variable, config_params): # This is for metadata like lon, lat, and lookvector # Given an isce file and a set of bounds to cut the file, # Produce the isce data and gmtsar netcdf that match each pixel. temp = isce_read_write.read_scalar_data(outdir + "/" + filename) print("Shape of the " + variable + " file: ", np.shape(temp)) xbounds = [ float(config_params.xbounds.split(',')[0]), float(config_params.xbounds.split(',')[1]) ] ybounds = [ float(config_params.ybounds.split(',')[0]), float(config_params.ybounds.split(',')[1]) ] cut_grid = mask_and_interpolate.cut_grid(temp, xbounds, ybounds, fractional=True, buffer_rows=3) print("Shape of the cut lon file: ", np.shape(cut_grid)) nx = np.shape(cut_grid)[1] ny = np.shape(cut_grid)[0] isce_read_write.write_isce_data(cut_grid, nx, ny, "FLOAT", outdir + '/cut_' + variable + '.gdal') rwr.produce_output_netcdf(np.array(range(0, nx)), np.array(range(0, ny)), cut_grid, "degrees", outdir + '/cut_' + variable + '.nc') return
def test_read_write(filename): # A TEST OF READ/WRITE FUNCTIONS # Step 1: Read ISCE interferogram as phase # Step 2: Write it as ISCE format data # Step 3: Read ISCE interferogram again # Step 4: Write as .grd # Step 5: make plot. # RESULT: PRETTY GOOD! There is a flipup between the ISCE/GMTSAR conventions, # but it might never really be a problem. # Step 1: read phase slc = isce_read_write.read_phase_data(filename) print("Shape of slc is ", np.shape(slc)) isce_read_write.plot_complex_data(filename, aspect=1 / 10, outname="original.png") # Step 2: write ISCE data file ny, nx = np.shape(slc) # dtype = 'FLOAT'; isce_written = "isce_written_phase.phase" isce_read_write.write_isce_data(slc, nx, ny, dtype="FLOAT", filename=isce_written) # Step 3: read phase again. phase = isce_read_write.read_scalar_data(isce_written + ".vrt") print("Shape of phase is ", np.shape(phase)) isce_read_write.plot_scalar_data("isce_written_phase.phase", colormap='rainbow', aspect=1 / 10, outname="isce_written_phase.png") # Step 4: write that phase as grd. netcdfname = "netcdf_written_phase.grd" xdata = np.arange(0, nx) ydata = np.arange(0, ny) phase = np.flipud(phase) # THIS SEEMS TO BE NECESSARY TO SWITCH BETWEEN CONVENTIONS. GRD PLOTS ARE UPSIDE DOWN FROM ISCE. netcdf_read_write.produce_output_netcdf(xdata, ydata, phase, "radians", netcdfname) # Step 5: look at what's inside; netcdf_read_write.produce_output_plot(netcdfname, "phase", "grdstyle_phase.png", "radians", aspect=1 / 10) return
def alt_isce_unwrapping_workflow(date_string, xbounds, ybounds, coherence_cutoff): """ # Step 1: Read file, and read coherence. Plot. # Step 2: Perform appropriate cut. Plot. # Step 3: Perform appropriate mask. Plot. # Step 4: Perform interpolation. Plot. # Step 5: Unwrap. Plot. # Step 6: Save a 10-panel plot with all stages of processing. # Meant to be called from the TimeSeries directory. """ # CONFIGURATION PARAMETERS unw_max = 4 * np.pi # how high do we let the unwrapped colorscale go? plot_aspect = 1 / 5 # Based on multilooking, we may need an aspect ratio to make pretty plots filedir = "../Igrams/" + date_string + "/" # *** This may change based on where you're calling from? filestem = "filt_" + date_string orig_config_file = "../configs/config_igram_" + date_string # *** this may change alt_filedir = filedir + "alt_unwrapped/" subprocess.call(["mkdir", "-p", alt_filedir], shell=False) f, axarr = plt.subplots(2, 5, figsize=(18, 16)) # Step 1: Read the automatic data slc = isce_read_write.read_complex_data(filedir + filestem + ".int") cor = isce_read_write.read_scalar_data(filedir + filestem + ".cor") orig_unw = isce_read_write.read_scalar_data(filedir + filestem + "_snaphu.unw", band=2) # for unwrapped files, band = 2 orig_comps = isce_read_write.read_scalar_data(filedir + filestem + "_snaphu.unw.conncomp") axarr = add_plot(axarr, 0, slc, 'phasefilt', colormap='rainbow', is_complex=1) axarr = add_rectangle(axarr, 0, xbounds, ybounds) axarr = add_plot(axarr, 1, cor, 'coherence', colormap='gray', is_complex=0) axarr = add_rectangle(axarr, 1, xbounds, ybounds) # Step 2: Cut data slc_cut = mask_and_interpolate.cut_grid(slc, xbounds, ybounds, buffer_rows=3) cor_cut = mask_and_interpolate.cut_grid(cor, xbounds, ybounds, buffer_rows=3) unw_cut = mask_and_interpolate.cut_grid(orig_unw, xbounds, ybounds, buffer_rows=3) comps_cut = mask_and_interpolate.cut_grid(orig_comps, xbounds, ybounds, buffer_rows=3) axarr = add_plot(axarr, 2, slc_cut, 'phasefilt_cut', colormap='rainbow', aspect=plot_aspect, is_complex=1, vmin=-np.pi, vmax=np.pi) axarr = add_plot(axarr, 3, unw_cut, 'unwrapped', colormap='rainbow', aspect=plot_aspect, is_complex=0, vmin=0, vmax=unw_max) axarr = add_plot(axarr, 4, comps_cut, 'Connected Components', colormap='rainbow', aspect=plot_aspect, is_complex=0, vmin=0, vmax=8) if np.sum(np.isnan(cor_cut)) != 0: print("Error! There are %d nans in the Correlation grid!" % (np.sum(np.isnan(cor_cut)))) sys.exit(0) # Step 3: Perform appropriate mask coherence_mask = mask_and_interpolate.make_coherence_mask( cor_cut, coherence_cutoff) coherence_mask_liberal = mask_and_interpolate.make_coherence_mask( cor_cut, coherence_cutoff - 0.0) # an experiment to get more pixels back masked_slc = mask_and_interpolate.apply_coherence_mask(slc_cut, coherence_mask, is_complex=1) axarr = add_plot(axarr, 5, masked_slc, 'masked_phasefilt', colormap='rainbow', aspect=plot_aspect, is_complex=1, vmin=-np.pi, vmax=np.pi) # Step 4: Perform interpolation interp_array = mask_and_interpolate.interpolate_2d(masked_slc) # Step 5: Write the interpolated phase out. ny, nx = np.shape(slc_cut) isce_read_write.write_isce_data(interp_array, nx, ny, dtype='CFLOAT', filename=alt_filedir + filestem + "_manually_masked.int") manually_masked = isce_read_write.read_complex_data(alt_filedir + filestem + "_manually_masked.int") axarr = add_plot(axarr, 6, manually_masked, 'Interpolated', colormap='rainbow', aspect=plot_aspect, is_complex=1, vmin=-np.pi, vmax=np.pi) # Step 5a: Write the correlation out, which we use for unwrapping. isce_read_write.write_isce_data(cor_cut, nx, ny, dtype='FLOAT', filename=alt_filedir + filestem + "_cut.cor") # Step 6: UNWRAP # PUT THE LOCAL UNWRAP SCRIPT IN ALT-FILEDIR # CALL UNWRAPPING (stripmapWrapper start = Function-3, end = Function-3). target_file = alt_filedir + "config_igram_" + date_string + "_local" write_local_iscestack_config(orig_config_file, target_file, date_string, alt_unwrapping=1) subprocess.call([ 'stripmapWrapper.py', '-c', target_file, '-s', 'Function-3', '-e', 'Function-3' ], shell=False) post_unwrapping = isce_read_write.read_scalar_data( alt_filedir + filestem + "_manually_masked_snaphu.unw", band=2) axarr = add_plot(axarr, 7, post_unwrapping, 'Unwrapped', colormap='rainbow', aspect=plot_aspect, is_complex=0, vmin=0, vmax=unw_max) comps = alt_filedir + filestem + "_manually_masked_snaphu.unw.conncomp.vrt" comps = isce_read_write.read_scalar_data(comps) axarr = add_plot(axarr, 8, comps, 'ConnectedComps', colormap='rainbow', aspect=plot_aspect, is_complex=0, vmin=0, vmax=8) # Step 7: Re-apply the mask re_masked = mask_and_interpolate.apply_coherence_mask( post_unwrapping, coherence_mask_liberal, is_complex=0, is_float32=True) axarr = add_plot(axarr, 9, re_masked, 'UnwrappedMasked', colormap='rainbow', aspect=plot_aspect, is_complex=0, vmin=0, vmax=unw_max) # MUST WRITE THE FINAL MASKED UNWRAPPED PHASE BACK INTO A FILE. isce_read_write.write_isce_data(re_masked, nx, ny, dtype='FLOAT', filename=alt_filedir + filestem + "_fully_processed.uwrappedphase") # Color bar for wrapped phase. cbarax = f.add_axes([0.2, 0.35, 0.25, 0.8], visible=False) color_boundary_object = matplotlib.colors.Normalize(vmin=-np.pi, vmax=np.pi) custom_cmap = cm.ScalarMappable(norm=color_boundary_object, cmap='rainbow') custom_cmap.set_array(np.arange(-np.pi, np.pi)) cb = plt.colorbar(custom_cmap, aspect=12, fraction=0.2, orientation='horizontal') cb.set_label('Wrapped Phase (rad)', fontsize=18) cb.ax.tick_params(labelsize=12) # Color bar for unwrapped phase. cbarax = f.add_axes([0.6, 0.35, 0.25, 0.8], visible=False) color_boundary_object = matplotlib.colors.Normalize(vmin=0, vmax=unw_max) custom_cmap = cm.ScalarMappable(norm=color_boundary_object, cmap='rainbow') custom_cmap.set_array(np.arange(0, unw_max)) cb = plt.colorbar(custom_cmap, aspect=12, fraction=0.2, orientation='horizontal') cb.set_label('Unrapped Phase (rad)', fontsize=18) cb.ax.tick_params(labelsize=12) plt.savefig(filedir + date_string + '_image_development.png') return re_masked
lon = [] lat = [] hgt = [] num_pixels = len(llh_array) lat = llh_array[np.arange(0, num_pixels, 3)] lon = llh_array[np.arange(1, num_pixels, 3)] hgt = llh_array[np.arange(2, num_pixels, 3)] # We turn the llh data into 2D arrays. lat_array = np.reshape(lat, (llh_pixels_azimuth, llh_pixels_range)) lon_array = np.reshape(lon, (llh_pixels_azimuth, llh_pixels_range)) hgt_array = np.reshape(hgt, (llh_pixels_azimuth, llh_pixels_range)) # write the hgt into a GDAL format. isce_read_write.write_isce_data(np.abs(hgt_array), llh_pixels_range, llh_pixels_azimuth, "FLOAT", "hgt.gdal") # Reading the gdal array. ds = gdal.Open("hgt.gdal", gdal.GA_ReadOnly) data = ds.GetRasterBand(1).ReadAsArray() transform = ds.GetGeoTransform() print("Original geotransform: ") print(transform) # isce_read_write.plot_scalar_data("hgt.gdal", outname='hgt.png'); # Get a new geotransform. This will turn pixel/line numbers into the proper coordinates on the ground. new_transform = new_geo_transform(lon_array, lat_array) # NEXT: RESAMPLE IN THE SAME WAY AS THE INTERFEROGRAMS # NEXT: CUT THE GRID IN THE SAME WAY AS THE INTERFEROGRAMS
def geocode_UAVSAR_stack(config_params, geocoded_folder): # The goals here for UAVSAR: # Load lon/lat grids and look vector grids # Resample and cut the grids appropriately # Write pixel-wise metadata out in the output folder # All these grids have only single band. call(["mkdir", "-p", geocoded_folder], shell=False) llh_array = np.fromfile(config_params.llh_file, dtype=np.float32) # this is a vector. lkv_array = np.fromfile(config_params.lkv_file, dtype=np.float32) lon = [] lat = [] hgt = [] lkv_e = [] lkv_n = [] lkv_u = [] lat = llh_array[np.arange(0, len(llh_array), 3)] # ordered array opened from the provided UAVSAR files lon = llh_array[np.arange(1, len(llh_array), 3)] hgt = llh_array[np.arange(2, len(llh_array), 3)] lkv_e = lkv_array[np.arange(0, len(lkv_array), 3)] lkv_n = lkv_array[np.arange(1, len(lkv_array), 3)] lkv_u = lkv_array[np.arange(2, len(lkv_array), 3)] example_igram = glob.glob("../Igrams/????????_????????/*.int")[0] phase_array = isce_read_write.read_phase_data(example_igram) print("Shape of the interferogram: ", np.shape(phase_array)) # Determine the shape of the llh array # assuming there's a giant gap somewhere in the lat array # that can tell us how many elements are in the gridded array typical_gap = abs(lat[1] - lat[0]) for i in range(1, len(lat)): if abs(lat[i] - lat[i - 1]) > 100 * typical_gap: print(lat[i] - lat[i - 1]) print("There are %d columns in the lon/lat arrays" % i) llh_pixels_range = i break llh_pixels_azimuth = int(len(lon) / llh_pixels_range) print("llh_pixels_azimuth: ", llh_pixels_azimuth) print("llh_pixels_range: ", llh_pixels_range) # We turn the llh data into 2D arrays. # The look vector is in meters from the aircraft to the ground. lat_array = np.reshape(lat, (llh_pixels_azimuth, llh_pixels_range)) lon_array = np.reshape(lon, (llh_pixels_azimuth, llh_pixels_range)) lkve_array = np.reshape(lkv_e, (llh_pixels_azimuth, llh_pixels_range)) lkvn_array = np.reshape(lkv_n, (llh_pixels_azimuth, llh_pixels_range)) lkvu_array = np.reshape(lkv_u, (llh_pixels_azimuth, llh_pixels_range)) lkve_array, lkvn_array, lkvu_array = normalize_look_vector( lkve_array, lkvn_array, lkvu_array) azimuth, incidence = calc_rdr_azimuth_incidence_from_lkv_plane_down( lkve_array, lkvn_array, lkvu_array) # # write the data into a GDAL format. isce_read_write.write_isce_data(lon_array, llh_pixels_range, llh_pixels_azimuth, "FLOAT", geocoded_folder + "/lon_total.gdal") isce_read_write.write_isce_data(lat_array, llh_pixels_range, llh_pixels_azimuth, "FLOAT", geocoded_folder + "/lat_total.gdal") isce_read_write.write_isce_data(azimuth, llh_pixels_range, llh_pixels_azimuth, "FLOAT", geocoded_folder + "/azimuth_total.gdal") isce_read_write.write_isce_data(incidence, llh_pixels_range, llh_pixels_azimuth, "FLOAT", geocoded_folder + "/incidence_total.gdal") # Resampling in GDAL to match the interferogram sampling call([ 'gdalwarp', '-ts', str(np.shape(phase_array)[1]), str(np.shape(phase_array)[0]), '-r', 'bilinear', '-to', 'SRC_METHOD=NO_GEOTRANSFORM', '-to', 'DST_METHOD=NO_GEOTRANSFORM', geocoded_folder + '/lon_total.gdal', geocoded_folder + '/lon_igram_res.tif' ], shell=False) call([ 'gdalwarp', '-ts', str(np.shape(phase_array)[1]), str(np.shape(phase_array)[0]), '-r', 'bilinear', '-to', 'SRC_METHOD=NO_GEOTRANSFORM', '-to', 'DST_METHOD=NO_GEOTRANSFORM', geocoded_folder + '/lat_total.gdal', geocoded_folder + '/lat_igram_res.tif' ], shell=False) call([ 'gdalwarp', '-ts', str(np.shape(phase_array)[1]), str(np.shape(phase_array)[0]), '-r', 'bilinear', '-to', 'SRC_METHOD=NO_GEOTRANSFORM', '-to', 'DST_METHOD=NO_GEOTRANSFORM', geocoded_folder + '/incidence_total.gdal', geocoded_folder + '/incidence_igram_res.tif' ], shell=False) call([ 'gdalwarp', '-ts', str(np.shape(phase_array)[1]), str(np.shape(phase_array)[0]), '-r', 'bilinear', '-to', 'SRC_METHOD=NO_GEOTRANSFORM', '-to', 'DST_METHOD=NO_GEOTRANSFORM', geocoded_folder + '/azimuth_total.gdal', geocoded_folder + '/azimuth_igram_res.tif' ], shell=False) # Cut the data, and quality check. # Writing the cut lon/lat into new files. cut_resampled_grid(geocoded_folder, "lon_igram_res.tif", "lon", config_params) cut_resampled_grid(geocoded_folder, "lat_igram_res.tif", "lat", config_params) cut_resampled_grid(geocoded_folder, "incidence_igram_res.tif", "incidence", config_params) cut_resampled_grid(geocoded_folder, "azimuth_igram_res.tif", "azimuth", config_params) isce_read_write.plot_scalar_data(geocoded_folder + '/cut_lat.gdal', colormap='rainbow', aspect=1 / 4, outname=geocoded_folder + '/cut_lat_geocoded.png') cut_lon = isce_read_write.read_scalar_data(geocoded_folder + '/cut_lon.gdal') cut_lat = isce_read_write.read_scalar_data(geocoded_folder + '/cut_lat.gdal') W, E = np.min(cut_lon), np.max(cut_lon) S, N = np.min(cut_lat), np.max(cut_lat) # This last thing may not work when finding the reference pixel, only when geocoding at the very last. # Double checking the shape of the interferogram data (should match!) signalspread = isce_read_write.read_scalar_data( config_params.ts_output_dir + '/signalspread_cut.nc') print("For comparison, shape of cut data is: ", np.shape(signalspread)) return W, E, S, N