def bbox_geo2radar(geo_box, atr_rdr=dict(), lookup_file=None, print_msg=False): """Calculate bounding box in x/y for file in radar coord, based on input geo box. Inputs: geo_box - tuple of 4 float, indicating the UL/LR lon/lat atr_rdr - dict, attributes of file in radar coord lookup_file - string / list of string, path of transformation file, i.e. geomap_4rlks.trans Output: pix_box - tuple of 4 int, indicating the UL/LR x/y of the bounding box in radar coord for the corresponding lat/lon coverage. """ lat = np.array([geo_box[3], geo_box[3], geo_box[1], geo_box[1]]) lon = np.array([geo_box[0], geo_box[2], geo_box[0], geo_box[2]]) if 'Y_FIRST' in atr_rdr.keys(): y = ut.coord_geo2radar(lat, atr_rdr, 'lat') x = ut.coord_geo2radar(lon, atr_rdr, 'lon') pix_box = (x[0], y[2], x[1], y[0]) else: y, x, y_res, x_res = ut.glob2radar(lat, lon, lookup_file, atr_rdr, print_msg=print_msg) buf = 2 * (np.max(np.abs([x_res, y_res]))) pix_box = (np.min(x) - buf, np.min(y) - buf, np.max(x) + buf, np.max(y) + buf) return pix_box
def subset_input_dict2box(subset_dict, meta_dict): """Convert subset inputs dict into box in radar and/or geo coord. Inputs: subset_dict : dict, including the following 4 objects: subset_x : list of 2 int, subset in x direction, default=None subset_y : list of 2 int, subset in y direction, default=None subset_lat : list of 2 float, subset in lat direction, default=None subset_lon : list of 2 float, subset in lon direction, default=None meta_dict : dict, including the following items: 'WIDTH' : int 'LENGTH': int 'X_FIRST' : float, optional 'Y_FIRST' : float, optional 'X_STEP' : float, optional 'Y_STEP' : float, optional Outputs: # box defined by 4-tuple of number, defining (left, upper, right, lower) coordinate, # (UL_X, UL_Y, LR_X, LR_Y ) pixel_box : 4-tuple of int, in pixel unit - 1 geo_box : 4-tuple of float, in lat/lon unit - degree None if file is in radar coordinate. example: subset_dict = {'subset_x': None, 'subset_y': None, 'subset_lat': [30.5, 31.0], 'subset_lon': [130.0, 131.0]} subset_dict = {'subset_x': [100, 1100], 'subset_y': [2050, 2550], 'subset_lat': None, 'subset_lon': None} pixel_box = subset_input_dict2box(subset_dict, pysar_meta_dict)[0] pixel_box, geo_box = subset_input_dict2box(subset_dict, pysar_meta_dict) """ # Data Coverage width = int(float(meta_dict['WIDTH'])) length = int(float(meta_dict['LENGTH'])) # Use subset_lat/lon input if existed, priority: lat/lon > y/x > len/wid if subset_dict['subset_lat']: sub_y = ut.coord_geo2radar(subset_dict['subset_lat'], meta_dict, 'latitude') elif subset_dict['subset_y']: sub_y = subset_dict['subset_y'] else: sub_y = [0, length] if subset_dict['subset_lon']: sub_x = ut.coord_geo2radar(subset_dict['subset_lon'], meta_dict, 'longitude') elif subset_dict['subset_x']: sub_x = subset_dict['subset_x'] else: sub_x = [0, width] # Get subset box in y/x sub_x = sorted(sub_x) sub_y = sorted(sub_y) pixel_box = (sub_x[0], sub_y[0], sub_x[1], sub_y[1]) # Get subset box in lat/lon from subset box in y/x geo_box = box_pixel2geo(pixel_box, meta_dict) return pixel_box, geo_box
def box_geo2pixel(geo_box, meta_dict): """Convert geo_box to pixel_box""" try: y = ut.coord_geo2radar([geo_box[1], geo_box[3]], meta_dict, 'latitude') x = ut.coord_geo2radar([geo_box[0], geo_box[2]], meta_dict, 'longitude') pixel_box = (x[0], y[0], x[1], y[1]) except: pixel_box = None return pixel_box
def plot_transect_location(ax, inps): print('plot profile line in the 1st input file') data0, atr0 = readfile.read(inps.file[0]) ax.imshow(data0) if inps.start_lalo and inps.end_lalo: [y0, y1] = ut.coord_geo2radar([inps.start_lalo[0], inps.end_lalo[0]], atr0, 'lat') [x0, x1] = ut.coord_geo2radar([inps.start_lalo[1], inps.end_lalo[1]], atr0, 'lon') inps.start_yx = [y0, x0] inps.end_yx = [y1, x1] ax.plot([inps.start_yx[1], inps.end_yx[1]], [inps.start_yx[0], inps.end_yx[0]], 'ro-') ax.set_xlim(0, np.shape(data0)[1]) ax.set_ylim(np.shape(data0)[0], 0) ax.set_title('Transect Line in ' + inps.file[0]) # Status bar def format_coord(x, y): col = int(x) row = int(y) if 0 <= col < data0.shape[1] and 0 <= row < data0.shape[0]: z = data0[row, col] if 'X_FIRST' in atr0.keys(): lat = ut.coord_radar2geo(row, atr0, 'row') lon = ut.coord_radar2geo(col, atr0, 'col') return 'lon=%.4f, lat=%.4f, x=%.0f, y=%.0f, value=%.4f' % ( lon, lat, x, y, z) else: return 'x=%.0f, y=%.0f, value=%.4f' % (x, y, z) else: return 'x=%.0f, y=%.0f' % (x, y) ax.format_coord = format_coord return
def main(iargs=None): inps = cmd_line_parse(iargs) # 1. Extract the common area of two input files # Basic info atr1 = readfile.read_attribute(inps.file[0]) atr2 = readfile.read_attribute(inps.file[1]) if any('X_FIRST' not in i for i in [atr1, atr2]): sys.exit('ERROR: Not all input files are geocoded.') k1 = atr1['FILE_TYPE'] print('Input 1st file is ' + k1) # Common AOI in lalo west, east, south, north = get_overlap_lalo(atr1, atr2) lon_step = float(atr1['X_STEP']) lat_step = float(atr1['Y_STEP']) width = int(round((east - west) / lon_step)) length = int(round((south - north) / lat_step)) # Read data in common AOI: LOS displacement, heading angle, incident angle u_los = np.zeros((2, width * length)) heading = [] incidence = [] for i in range(len(inps.file)): fname = inps.file[i] print('---------------------') print('reading ' + fname) atr = readfile.read_attribute(fname) [x0, x1] = ut.coord_geo2radar([west, east], atr, 'lon') [y0, y1] = ut.coord_geo2radar([north, south], atr, 'lat') V = readfile.read(fname, box=(x0, y0, x1, y1))[0] u_los[i, :] = V.flatten(0) heading_angle = float(atr['HEADING']) if heading_angle < 0.: heading_angle += 360. print('heading angle: ' + str(heading_angle)) heading_angle *= np.pi / 180. heading.append(heading_angle) inc_angle = float(ut.incidence_angle(atr, dimension=0)) inc_angle *= np.pi / 180. incidence.append(inc_angle) # 2. Project displacement from LOS to Horizontal and Vertical components # math for 3D: cos(theta)*Uz - cos(alpha)*sin(theta)*Ux + sin(alpha)*sin(theta)*Uy = Ulos # math for 2D: cos(theta)*Uv - sin(alpha-az)*sin(theta)*Uh = Ulos #Uh_perp = 0.0 # This could be easily modified to support multiple view geometry # (e.g. two adjcent tracks from asc & desc) to resolve 3D # Design matrix A = np.zeros((2, 2)) for i in range(len(inps.file)): A[i, 0] = np.cos(incidence[i]) A[i, 1] = np.sin(incidence[i]) * np.sin(heading[i] - inps.azimuth) A_inv = np.linalg.pinv(A) u_vh = np.dot(A_inv, u_los) u_v = np.reshape(u_vh[0, :], (length, width)) u_h = np.reshape(u_vh[1, :], (length, width)) # 3. Output # Attributes atr = atr1.copy() atr['WIDTH'] = str(width) atr['LENGTH'] = str(length) atr['X_FIRST'] = str(west) atr['Y_FIRST'] = str(north) atr['X_STEP'] = str(lon_step) atr['Y_STEP'] = str(lat_step) print('---------------------') outname = inps.outfile[0] print('writing vertical component to file: ' + outname) writefile.write(u_v, out_file=outname, metadata=atr) outname = inps.outfile[1] print('writing horizontal component to file: ' + outname) writefile.write(u_h, out_file=outname, metadata=atr) print('Done.') return
def read_subset_box(inpsDict): # Read subset info from template inpsDict['box'] = None inpsDict['box4geo_lut'] = None pix_box, geo_box = subset.read_subset_template2box( inpsDict['template_file']) # Grab required info to read input geo_box into pix_box try: lookupFile = [ glob.glob(str(inpsDict['pysar.load.lookupYFile']))[0], glob.glob(str(inpsDict['pysar.load.lookupXFile']))[0] ] except: lookupFile = None try: pathKey = [ i for i in datasetName2templateKey.values() if i in inpsDict.keys() ][0] file = glob.glob(str(inpsDict[pathKey]))[0] atr = readfile.read_attribute(file) except: atr = dict() geocoded = None if 'Y_FIRST' in atr.keys(): geocoded = True else: geocoded = False # Check conflict if geo_box and not geocoded and lookupFile is None: geo_box = None print(('WARNING: pysar.subset.lalo is not supported' ' if 1) no lookup file AND' ' 2) radar/unkonwn coded dataset')) print('\tignore it and continue.') if not geo_box and not pix_box: return inpsDict # geo_box --> pix_box if geo_box is not None: if geocoded: pix_box = (0, 0, 0, 0) pix_box[0:3:2] = ut.coord_geo2radar(geo_box[0:3:2], atr, 'lon') pix_box[1:4:2] = ut.coord_geo2radar(geo_box[1:4:2], atr, 'lat') else: pix_box = subset.bbox_geo2radar(geo_box, atr, lookupFile) print('input bounding box of interest in lalo: {}'.format(geo_box)) print('box to read for datasets in y/x: {}'.format(pix_box)) # Get box for geocoded lookup table (for gamma/roipac) box4geo_lut = None if lookupFile is not None: atrLut = readfile.read_attribute(lookupFile[0]) if not geocoded and 'Y_FIRST' in atrLut.keys(): geo_box = subset.bbox_radar2geo(pix_box, atr, lookupFile) box4geo_lut = subset.bbox_geo2radar(geo_box, atrLut) print('box to read for geocoded lookup file in y/x: {}'.format( box4geo_lut)) inpsDict['box'] = pix_box inpsDict['box4geo_lut'] = box4geo_lut return inpsDict
def transect_lalo(z, atr, start_lalo, end_lalo, interpolation='nearest'): """Extract 2D matrix (z) value along the line [start_lalo, end_lalo]""" [y0, y1] = ut.coord_geo2radar([start_lalo[0], end_lalo[0]], atr, 'lat') [x0, x1] = ut.coord_geo2radar([start_lalo[1], end_lalo[1]], atr, 'lon') transect = transect_yx(z, atr, [y0, x0], [y1, x1], interpolation) return transect
def read_reference_input(inps): atr = readfile.read_attribute(inps.file) length = int(atr['LENGTH']) width = int(atr['WIDTH']) inps.go_reference = True if inps.reset: remove_reference_pixel(inps.file) inps.outfile = inps.file inps.go_reference = False return inps print('-' * 50) # Check Input Coordinates # Read ref_y/x/lat/lon from reference/template # priority: Direct Input > Reference File > Template File if inps.template_file: print('reading reference info from template: ' + inps.template_file) inps = read_template_file2inps(inps.template_file, inps) if inps.reference_file: print('reading reference info from reference: ' + inps.reference_file) inps = read_reference_file2inps(inps.reference_file, inps) # Convert ref_lat/lon to ref_y/x if inps.ref_lat and inps.ref_lon: if 'X_FIRST' in atr.keys(): inps.ref_y = ut.coord_geo2radar(inps.ref_lat, atr, 'lat') inps.ref_x = ut.coord_geo2radar(inps.ref_lon, atr, 'lon') else: # Convert lat/lon to az/rg for radar coord file using geomap*.trans file inps.ref_y, inps.ref_x = ut.glob2radar(np.array(inps.ref_lat), np.array(inps.ref_lon), inps.lookup_file, atr)[0:2] print('input reference point in lat/lon: {}'.format( (inps.ref_lat, inps.ref_lon))) if inps.ref_y and inps.ref_x: print('input reference point in y/x: {}'.format( (inps.ref_y, inps.ref_x))) # Do not use ref_y/x outside of data coverage if (inps.ref_y and inps.ref_x and not (0 <= inps.ref_y <= length and 0 <= inps.ref_x <= width)): inps.ref_y = None inps.ref_x = None print('WARNING: input reference point is OUT of data coverage!') print('Continue with other method to select reference point.') # Do not use ref_y/x in masked out area if inps.ref_y and inps.ref_x and inps.maskFile: print('mask: ' + inps.maskFile) mask = readfile.read(inps.maskFile, datasetName='mask')[0] if mask[inps.ref_y, inps.ref_x] == 0: inps.ref_y = None inps.ref_x = None print('WARNING: input reference point is in masked OUT area!') print('Continue with other method to select reference point.') # Select method if not inps.ref_y or not inps.ref_x: print('no input reference y/x.') if not inps.method: # Use existing REF_Y/X if no ref_y/x input and no method input if not inps.force and 'REF_X' in atr.keys(): print('REF_Y/X exists in input file, skip updating.') print('REF_Y: ' + atr['REF_Y']) print('REF_X: ' + atr['REF_X']) inps.outfile = inps.file inps.go_reference = False # method to select reference point elif inps.coherenceFile and os.path.isfile(inps.coherenceFile): inps.method = 'maxCoherence' else: inps.method = 'random' print('reference point selection method: ' + str(inps.method)) print('-' * 50) return inps