def main(argv=None): #%% Check argv if argv == None: argv = sys.argv start = time.time() print("{} {}".format(os.path.basename(argv[0]), ' '.join(argv[1:])), flush=True) #%% Set default tsadir = [] filtwidth_km = 2 filtwidth_yr = [] deg_ramp = [] maskflag = True cumname = 'cum.h5' #%% Read options try: try: opts, args = getopt.getopt(argv[1:], "ht:s:y:r:", ["help", "nomask"]) except getopt.error as msg: raise Usage(msg) for o, a in opts: if o == '-h' or o == '--help': print(__doc__) return 0 elif o == '-t': tsadir = a elif o == '-s': filtwidth_km = float(a) elif o == '-y': filtwidth_yr = float(a) elif o == '-r': deg_ramp = a elif o == '--nomask': maskflag = False if not tsadir: raise Usage('No tsa directory given, -t is not optional!') elif not os.path.isdir(tsadir): raise Usage('No {} dir exists!'.format(tsadir)) elif not os.path.exists(os.path.join(tsadir, cumname)): raise Usage('No {} exists in {}!'.format(cumname, tsadir)) except Usage as err: print("\nERROR:", file=sys.stderr, end='') print(" " + str(err.msg), file=sys.stderr) print("\nFor help, use -h or --help.\n", file=sys.stderr) return 2 #%% Directory and file setting tsadir = os.path.abspath(tsadir) cumfile = os.path.join(tsadir, cumname) resultsdir = os.path.join(tsadir, 'results') parmfile = os.path.join(tsadir, 'info', 'parameters.txt') pixsp_r = float(io_lib.get_param_par(parmfile, 'pixel_spacing_r')) pixsp_a = float(io_lib.get_param_par(parmfile, 'pixel_spacing_a')) x_stddev = filtwidth_km * 1000 / pixsp_r y_stddev = filtwidth_km * 1000 / pixsp_a wavelength = float(io_lib.get_param_par(parmfile, 'wavelength')) #meter coef_r2m = -wavelength / 4 / np.pi * 1000 #rad -> mm, positive is -LOS if wavelength > 0.2: ## L-band cycle = 1.5 # 2pi/cycle for comparison png elif wavelength <= 0.2: ## C-band cycle = 3 # 3*2pi/cycle for comparison png filtdir = os.path.join(tsadir, '16filt') if not os.path.exists(filtdir): os.mkdir(filtdir) cumffile = os.path.join(tsadir, 'cum_filt.h5') vconstfile = os.path.join(resultsdir, 'vintercept.filt') velfile = os.path.join(resultsdir, 'vel.filt') cumh5 = h5.File(cumfile, 'r') if os.path.exists(cumffile): os.remove(cumffile) cumfh5 = h5.File(cumffile, 'w') #%% Dates imdates = cumh5['imdates'][()].astype(str).tolist() cum_org = cumh5['cum'] n_im, length, width = cum_org.shape ### Calc dt in year imdates_dt = ([ dt.datetime.strptime(imd, '%Y%m%d').toordinal() for imd in imdates ]) dt_cum = np.float32((np.array(imdates_dt) - imdates_dt[0]) / 365.25) ### Save dates and refarea into cumf cumfh5.create_dataset('imdates', data=cumh5['imdates']) cumfh5.create_dataset('refarea', data=cumh5['refarea']) cumfh5.create_dataset('gap', data=cumh5['gap']) try: ## if dummy, no bperp field cumfh5.create_dataset('bperp', data=cumh5['bperp']) except: print('No bperp field found in {}. Skip.'.format(cumname)) try: cumfh5.create_dataset('corner_lat', data=cumh5['corner_lat']) cumfh5.create_dataset('corner_lon', data=cumh5['corner_lon']) cumfh5.create_dataset('post_lat', data=cumh5['post_lat']) cumfh5.create_dataset('post_lon', data=cumh5['post_lon']) except: ## not geocoded print('No latlon field found in {}. Skip.'.format(cumname)) ### temporal filter width if not filtwidth_yr and filtwidth_yr != 0: filtwidth_yr = dt_cum[-1] / (n_im - 1) * 3 ## avg interval*3 #%% Display settings print('') print('Size of image (w,l) : {0}, {1}'.format(width, length)) print('Number of images : {}'.format(n_im)) print('Width of filter in space : {} km ({:.1f}x{:.1f} pixel)'.format( filtwidth_km, x_stddev, y_stddev)) print('Width of filter in time : {:.3f} yr ({} days)'.format( filtwidth_yr, int(filtwidth_yr * 365.25))) print('Deramp flag : {}'.format(deg_ramp), flush=True) #%% Load Mask (1: unmask, 0: mask, nan: no cum data) if maskflag: maskfile = os.path.join(resultsdir, 'mask') mask = io_lib.read_img(maskfile, length, width) mask[mask == 0] = np.nan ## 0->nan else: mask = np.ones((length, width), dtype=np.float32) mask[np.isnan(cum_org[0, :, :])] = np.nan #%% First, deramp if indicated cum = np.zeros((cum_org.shape), dtype=np.float32) * np.nan if not deg_ramp: cum = cum_org[()] ## Remove past *_deramp.png if exist for png in glob.glob(os.path.join(filtdir, '*_deramp.png')): os.remove(png) else: print('\nDeramp ifgs with the degree of {}...'.format(deg_ramp), flush=True) ramp1 = [] for i in range(n_im): if np.mod(i, 10) == 0: print(" {0:3}/{1:3}th image...".format(i, n_im), flush=True) ramp, _ = tools_lib.fit2d(cum_org[i, :, :], deg=deg_ramp) cum[i, :, :] = cum_org[i, :, :] - ramp ## Output comparison image of deramp data3 = [ np.angle(np.exp(1j * (data / coef_r2m / cycle)) * cycle) for data in [cum_org[i, :, :] * mask, ramp, cum[i, :, :] * mask] ] title3 = [ 'Before deramp ({}pi/cycle)'.format(cycle * 2), 'ramp phase (deg:{}, {}pi/cycle)'.format(deg_ramp, cycle * 2), 'After deramp ({}pi/cycle)'.format(cycle * 2) ] pngfile = os.path.join(filtdir, imdates[i] + '_deramp.png') plot_lib.make_3im_png(data3, pngfile, 'insar', title3, vmin=-np.pi, vmax=np.pi, cbar=False) ## Output comparison image of deramp for increment if i != 0: data3 = [ np.angle(np.exp(1j * (data / coef_r2m / cycle)) * cycle) for data in [(cum_org[i, :, :] - cum_org[i - 1, :, :]) * mask, ramp - ramp1, (cum[i, :, :] - cum[i - 1, :, :]) * mask] ] title3 = [ 'Before deramp ({}pi/cycle)'.format(cycle * 2), 'ramp phase (deg:{}, {}pi/cycle)'.format( deg_ramp, cycle * 2), 'After deramp ({}pi/cycle)'.format(cycle * 2) ] pngfile = os.path.join( filtdir, '{}_{}_deramp.png'.format(imdates[i - 1], imdates[i])) plot_lib.make_3im_png(data3, pngfile, 'insar', title3, vmin=-np.pi, vmax=np.pi, cbar=False) ramp1 = ramp.copy() ## backup last ramp #%% Filter each image cum_filt = cumfh5.require_dataset('cum', (n_im, length, width), dtype=np.float32) cum_hptlps1 = [] print('\nHP filter in time, LP filter in space...', flush=True) for i in range(n_im): if np.mod(i, 10) == 0: print(" {0:3}/{1:3}th image...".format(i, n_im), flush=True) #%% Second, HP in time if filtwidth_yr == 0.0: cum_hpt = cum[i, :, :] ## No temporal filter else: time_diff_sq = (dt_cum[i] - dt_cum)**2 ## Limit reading data within filtwidth_yr**8 ixs = time_diff_sq < filtwidth_yr * 8 weight_factor = np.tile( np.exp(-time_diff_sq[ixs] / 2 / filtwidth_yr**2)[:, np.newaxis, np.newaxis], (1, length, width)) #len(ixs), length, width ## Take into account nan in cum weight_factor = weight_factor * (~np.isnan(cum[ixs, :, :])) ## Normalize weight with warnings.catch_warnings( ): ## To silence warning by zero division warnings.simplefilter('ignore', RuntimeWarning) weight_factor = weight_factor / np.sum(weight_factor, axis=0) cum_lpt = np.nansum(cum[ixs, :, :] * weight_factor, axis=0) cum_hpt = cum[i, :, :] - cum_lpt #%% Third, LP in space and subtract from original if filtwidth_km == 0.0: cum_filt[i, :, :] = cum[i, :, :] ## No spatial else: with warnings.catch_warnings(): ## To silence warning if i == 0: cum_hpt = cum_hpt + sys.float_info.epsilon ##To distinguish from 0 of filtered nodata # warnings.simplefilter('ignore', FutureWarning) warnings.simplefilter('ignore', RuntimeWarning) kernel = Gaussian2DKernel(x_stddev, y_stddev) cum_hptlps = convolve_fft( cum_hpt * mask, kernel, fill_value=np.nan, allow_huge=True) ## fill edge 0 for interpolation cum_hptlps[cum_hptlps == 0] = np.nan ## fill 0 with nan cum_filt[i, :, :] = cum[i, :, :] - cum_hptlps #%% Output comparison image data3 = [ np.angle(np.exp(1j * (data / coef_r2m / cycle)) * cycle) for data in [cum[i, :, :] * mask, cum_hptlps, cum_filt[i, :, :] * mask] ] title3 = [ 'Before filter ({}pi/cycle)'.format(cycle * 2), 'Filter phase ({}pi/cycle)'.format(cycle * 2), 'After filter ({}pi/cycle)'.format(cycle * 2) ] pngfile = os.path.join(filtdir, imdates[i] + '_filt.png') plot_lib.make_3im_png(data3, pngfile, 'insar', title3, vmin=-np.pi, vmax=np.pi, cbar=False) ### Output comparison image for increment if i != 0: data3 = [ np.angle(np.exp(1j * (data / coef_r2m / cycle)) * cycle) for data in [(cum[i, :, :] - cum[i - 1, :, :]) * mask, cum_hptlps - cum_hptlps1, (cum_filt[i, :, :] - cum_filt[i - 1, :, :]) * mask] ] title3 = [ 'Before filter ({}pi/cycle)'.format(cycle * 2), 'Filter phase ({}pi/cycle)'.format(cycle * 2), 'After filter ({}pi/cycle)'.format(cycle * 2) ] pngfile = os.path.join(filtdir, imdates[i] + '_filt.png') pngfile = os.path.join( filtdir, '{}_{}_filt.png'.format(imdates[i - 1], imdates[i])) plot_lib.make_3im_png(data3, pngfile, 'insar', title3, vmin=-np.pi, vmax=np.pi, cbar=False) cum_hptlps1 = cum_hptlps.copy() ## backup last filt phase #%% Calc filtered velocity print('\nCalculate velocity of filtered time series...', flush=True) G = np.stack((np.ones_like(dt_cum), dt_cum), axis=1) vconst = np.zeros((length, width), dtype=np.float32) * np.nan vel = np.zeros((length, width), dtype=np.float32) * np.nan bool_unnan = ~np.isnan(cum_filt[0, :, :]).reshape(length, width) ## not all nan cum_pt = cum_filt[()].reshape(n_im, length * width)[:, bool_unnan.ravel()] #n_im x n_pt n_pt_unnan = bool_unnan.sum() vconst_tmp = np.zeros((n_pt_unnan), dtype=np.float32) * np.nan vel_tmp = np.zeros((n_pt_unnan), dtype=np.float32) * np.nan bool_nonan_pt = np.all(~np.isnan(cum_pt), axis=0) ### First, calc vel point without nan print(' First, solving {0:6}/{1:6}th points with full cum...'.format( bool_nonan_pt.sum(), n_pt_unnan), flush=True) vconst_tmp[bool_nonan_pt], vel_tmp[bool_nonan_pt] = np.linalg.lstsq( G, cum_pt[:, bool_nonan_pt], rcond=None)[0] ### Next, calc vel point with nan print(' Next, solving {0:6}/{1:6}th points with nan in cum...'.format( (~bool_nonan_pt).sum(), n_pt_unnan), flush=True) mask_cum = ~np.isnan(cum_pt[:, ~bool_nonan_pt]) vconst_tmp[~bool_nonan_pt], vel_tmp[ ~bool_nonan_pt] = inv_lib.censored_lstsq_slow( G, cum_pt[:, ~bool_nonan_pt], mask_cum) vconst[bool_unnan], vel[bool_unnan] = vconst_tmp, vel_tmp vconst.tofile(vconstfile) vel.tofile(velfile) if maskflag: vel_mskd = vel * mask vconst_mskd = vconst * mask vconst_mskd.tofile(vconstfile + '.mskd') vel_mskd.tofile(velfile + '.mskd') cumfh5.create_dataset('vel', data=vel.reshape(length, width)) cumfh5.create_dataset('vintercept', data=vconst.reshape(length, width)) #%% Add info and close cumfh5.create_dataset('filtwidth_yr', data=filtwidth_yr) cumfh5.create_dataset('filtwidth_km', data=filtwidth_km) cumfh5.create_dataset('deramp_flag', data=deg_ramp) cumh5.close() cumfh5.close() #%% Output image cmap = 'jet' pngfile = os.path.join(resultsdir, 'vel.filt.png') title = 'Filtered velocity (mm/yr)' vmin = np.nanpercentile(vel, 1) vmax = np.nanpercentile(vel, 99) plot_lib.make_im_png(vel, pngfile, cmap, title, vmin, vmax) ## vintercept pngfile = os.path.join(resultsdir, 'vintercept.filt.png') title = 'Intercept of filtered velocity (mm)' vmin = np.nanpercentile(vconst, 1) vmax = np.nanpercentile(vconst, 99) plot_lib.make_im_png(vconst, pngfile, cmap, title, vmin, vmax) if maskflag: pngfile = os.path.join(resultsdir, 'vel.filt.mskd.png') title = 'Masked filtered velocity (mm/yr)' vmin = np.nanpercentile(vel_mskd, 1) vmax = np.nanpercentile(vel_mskd, 99) plot_lib.make_im_png(vel_mskd, pngfile, cmap, title, vmin, vmax) ## vintercept pngfile = os.path.join(resultsdir, 'vintercept.filt.mskd.png') title = 'Masked intercept of filtered velocity (mm)' vmin = np.nanpercentile(vconst_mskd, 1) vmax = np.nanpercentile(vconst_mskd, 99) plot_lib.make_im_png(vconst_mskd, pngfile, cmap, title, vmin, vmax) #%% Finish elapsed_time = time.time() - start hour = int(elapsed_time / 3600) minite = int(np.mod((elapsed_time / 60), 60)) sec = int(np.mod(elapsed_time, 60)) print("\nElapsed time: {0:02}h {1:02}m {2:02}s".format(hour, minite, sec)) print('\n{} Successfully finished!!\n'.format(os.path.basename(argv[0]))) print('Output: {}\n'.format(os.path.relpath(cumffile)), flush=True) print('To plot the time-series:') print('LiCSBAS_plot_ts.py -i {} &\n'.format(os.path.relpath(cumffile)))
def main(argv=None): #%% Check argv if argv == None: argv = sys.argv start = time.time() ver = 1.3 date = 20200909 author = "Y. Morishita" print("\n{} ver{} {} {}".format(os.path.basename(argv[0]), ver, date, author), flush=True) print("{} {}".format(os.path.basename(argv[0]), ' '.join(argv[1:])), flush=True) ## for parallel processing global cum, mask, deg_ramp, hgt_linearflag, hgt, hgt_min, hgt_max,\ filtcumdir, filtincdir, imdates, cycle, coef_r2m, models, \ filtwidth_yr, filtwidth_km, dt_cum, x_stddev, y_stddev ## global cum_org from hdf5 contaminate in paralell warpper? So pass them by arg. #%% Set default tsadir = [] filtwidth_km = 2 filtwidth_yr = [] deg_ramp = [] hgt_linearflag = False hgt_min = 200 ## meter hgt_max = 10000 ## meter maskflag = True n_para = len(os.sched_getaffinity(0)) cumname = 'cum.h5' cmap_vel = SCM.roma.reversed() cmap_noise_r = 'viridis_r' #%% Read options try: try: opts, args = getopt.getopt(argv[1:], "ht:s:y:r:", [ "help", "hgt_linear", "hgt_min=", "hgt_max=", "nomask", "n_para=" ]) except getopt.error as msg: raise Usage(msg) for o, a in opts: if o == '-h' or o == '--help': print(__doc__) return 0 elif o == '-t': tsadir = a elif o == '-s': filtwidth_km = float(a) elif o == '-y': filtwidth_yr = float(a) elif o == '-r': deg_ramp = a elif o == '--hgt_linear': hgt_linearflag = True elif o == '--hgt_min': hgt_min = int(a) elif o == '--hgt_max': hgt_max = int(a) elif o == '--nomask': maskflag = False elif o == '--n_para': n_para = int(a) if not tsadir: raise Usage('No tsa directory given, -t is not optional!') elif not os.path.isdir(tsadir): raise Usage('No {} dir exists!'.format(tsadir)) elif not os.path.exists(os.path.join(tsadir, cumname)): raise Usage('No {} exists in {}!'.format(cumname, tsadir)) except Usage as err: print("\nERROR:", file=sys.stderr, end='') print(" " + str(err.msg), file=sys.stderr) print("\nFor help, use -h or --help.\n", file=sys.stderr) return 2 #%% Directory and file setting tsadir = os.path.abspath(tsadir) cumfile = os.path.join(tsadir, cumname) resultsdir = os.path.join(tsadir, 'results') infodir = os.path.join(tsadir, 'info') inparmfile = os.path.join(infodir, '13parameters.txt') if not os.path.exists(inparmfile): ## for old LiCSBAS13 <v1.2 inparmfile = os.path.join(infodir, 'parameters.txt') outparmfile = os.path.join(infodir, '16parameters.txt') pixsp_r = float(io_lib.get_param_par(inparmfile, 'pixel_spacing_r')) pixsp_a = float(io_lib.get_param_par(inparmfile, 'pixel_spacing_a')) x_stddev = filtwidth_km * 1000 / pixsp_r y_stddev = filtwidth_km * 1000 / pixsp_a wavelength = float(io_lib.get_param_par(inparmfile, 'wavelength')) #meter coef_r2m = -wavelength / 4 / np.pi * 1000 #rad -> mm, positive is -LOS if wavelength > 0.2: ## L-band cycle = 1.5 # 2pi/cycle for comparison png elif wavelength <= 0.2: ## C-band cycle = 3 # 3*2pi/cycle for comparison png filtincdir = os.path.join(tsadir, '16filt_increment') if os.path.exists(filtincdir): shutil.rmtree(filtincdir) os.mkdir(filtincdir) filtcumdir = os.path.join(tsadir, '16filt_cum') if os.path.exists(filtcumdir): shutil.rmtree(filtcumdir) os.mkdir(filtcumdir) cumffile = os.path.join(tsadir, 'cum_filt.h5') vconstfile = os.path.join(resultsdir, 'vintercept.filt') velfile = os.path.join(resultsdir, 'vel.filt') cumh5 = h5.File(cumfile, 'r') if os.path.exists(cumffile): os.remove(cumffile) cumfh5 = h5.File(cumffile, 'w') #%% Dates imdates = cumh5['imdates'][()].astype(str).tolist() cum_org = cumh5['cum'] n_im, length, width = cum_org.shape if n_para > n_im: n_para = n_im ### Calc dt in year imdates_dt = ([ dt.datetime.strptime(imd, '%Y%m%d').toordinal() for imd in imdates ]) dt_cum = np.float32((np.array(imdates_dt) - imdates_dt[0]) / 365.25) ### Save dates and other info into cumf cumfh5.create_dataset('imdates', data=cumh5['imdates']) cumfh5.create_dataset('gap', data=cumh5['gap']) if 'bperp' in list(cumh5.keys()): ## if dummy, no bperp field cumfh5.create_dataset('bperp', data=cumh5['bperp']) else: print('No bperp field found in {}. Skip.'.format(cumname)) if 'corner_lat' in list(cumh5.keys()): lat1 = float(cumh5['corner_lat'][()]) lon1 = float(cumh5['corner_lon'][()]) dlat = float(cumh5['post_lat'][()]) dlon = float(cumh5['post_lon'][()]) cumfh5.create_dataset('corner_lat', data=cumh5['corner_lat']) cumfh5.create_dataset('corner_lon', data=cumh5['corner_lon']) cumfh5.create_dataset('post_lat', data=cumh5['post_lat']) cumfh5.create_dataset('post_lon', data=cumh5['post_lon']) else: ## not geocoded print('No latlon field found in {}. Skip.'.format(cumname)) ### temporal filter width if not filtwidth_yr and filtwidth_yr != 0: filtwidth_yr = dt_cum[-1] / (n_im - 1) * 3 ## avg interval*3 ### hgt_linear if hgt_linearflag: hgtfile = os.path.join(resultsdir, 'hgt') if not os.path.exists(hgtfile): print('\nERROR: No hgt file exist in results dir!', file=sys.stderr) print('--hgt_linear option cannot be used.', file=sys.stderr) return 2 hgt = io_lib.read_img(hgtfile, length, width) hgt[np.isnan(hgt)] = 0 else: hgt = [] #%% Display settings print('') print('Size of image (w,l) : {0}, {1}'.format(width, length)) print('Number of images : {}'.format(n_im)) print('Width of filter in space : {} km ({:.1f}x{:.1f} pixel)'.format( filtwidth_km, x_stddev, y_stddev)) print('Width of filter in time : {:.3f} yr ({} days)'.format( filtwidth_yr, int(filtwidth_yr * 365.25))) print('Deramp flag : {}'.format(deg_ramp), flush=True) print('hgt-linear flag : {}'.format(hgt_linearflag), flush=True) if hgt_linearflag: print('Minimum hgt : {} m'.format(hgt_min), flush=True) print('Maximum hgt : {} m'.format(hgt_max), flush=True) with open(outparmfile, "w") as f: print('filtwidth_km: {}'.format(filtwidth_km), file=f) print('filtwidth_xpixels: {:.1f}'.format(x_stddev), file=f) print('filtwidth_ypixels: {:.1f}'.format(y_stddev), file=f) print('filtwidth_yr: {:.3f}'.format(filtwidth_yr), file=f) print('filtwidth_day: {}'.format(int(filtwidth_yr * 365.25)), file=f) print('deg_ramp: {}'.format(deg_ramp), file=f) print('hgt_linear: {}'.format(hgt_linearflag * 1), file=f) print('hgt_min: {}'.format(hgt_min), file=f) print('hgt_max: {}'.format(hgt_max), file=f) #%% Load Mask (1: unmask, 0: mask, nan: no cum data) if maskflag: maskfile = os.path.join(resultsdir, 'mask') mask = io_lib.read_img(maskfile, length, width) mask[mask == 0] = np.nan ## 0->nan else: mask = np.ones((length, width), dtype=np.float32) mask[np.isnan(cum_org[0, :, :])] = np.nan #%% First, deramp and hgt-linear if indicated cum = np.zeros((cum_org.shape), dtype=np.float32) * np.nan if not deg_ramp and not hgt_linearflag: cum = cum_org[()] else: if not deg_ramp: print('\nEstimate hgt-linear component,', flush=True) elif not hgt_linearflag: print('\nDeramp ifgs with the degree of {},'.format(deg_ramp), flush=True) else: print('\nDeramp ifgs with the degree of {} and hgt-linear,'.format( deg_ramp), flush=True) print('with {} parallel processing...'.format(n_para), flush=True) args = [(i, cum_org[i, :, :]) for i in range(n_im)] ### Parallel processing p = multi.Pool(n_para) _result = np.array(p.map(deramp_wrapper, args), dtype=object) p.close() del args models = _result[:, 1] for i in range(n_im): cum[i, :, :] = _result[i, 0] del _result ### Only for output increment png files print( '\nCreate png for increment with {} parallel processing...'.format( n_para), flush=True) args = [(i, cum_org[i, :, :], cum_org[i - 1, :, :]) for i in range(1, n_im)] p = multi.Pool(n_para) p.map(deramp_wrapper2, args) p.close() del args #%% Filter each image cum_filt = cumfh5.require_dataset('cum', (n_im, length, width), dtype=np.float32) print('\nHP filter in time, LP filter in space,', flush=True) print('with {} parallel processing...'.format(n_para), flush=True) ### Parallel processing p = multi.Pool(n_para) cum_filt[:, :, :] = np.array(p.map(filter_wrapper, range(n_im)), dtype=np.float32) p.close() ### Only for output increment png files print('\nCreate png for increment with {} parallel processing...'.format( n_para), flush=True) args = [(i, cum_filt[i, :, :] - cum_filt[i - 1, :, :]) for i in range(1, n_im)] p = multi.Pool(n_para) p.map(filter_wrapper2, args) p.close() del args #%% Find stable ref point print('\nFind stable reference point...', flush=True) ### Compute RMS of time series with reference to all points sumsq_cum_wrt_med = np.zeros((length, width), dtype=np.float32) for i in range(n_im): sumsq_cum_wrt_med = sumsq_cum_wrt_med + ( cum_filt[i, :, :] - np.nanmedian(cum_filt[i, :, :]))**2 rms_cum_wrt_med = np.sqrt(sumsq_cum_wrt_med / n_im) * mask ### Mask by minimum n_gap n_gap = io_lib.read_img(os.path.join(resultsdir, 'n_gap'), length, width) min_n_gap = np.nanmin(n_gap) mask_n_gap = np.float32(n_gap == min_n_gap) mask_n_gap[mask_n_gap == 0] = np.nan rms_cum_wrt_med = rms_cum_wrt_med * mask_n_gap ### Find stable reference min_rms = np.nanmin(rms_cum_wrt_med) refy1s, refx1s = np.where(rms_cum_wrt_med == min_rms) refy1s, refx1s = refy1s[0], refx1s[0] ## Only first index refy2s, refx2s = refy1s + 1, refx1s + 1 print('Selected ref: {}:{}/{}:{}'.format(refx1s, refx2s, refy1s, refy2s), flush=True) ### Rerferencing cumulative displacement to new stable ref for i in range(n_im): cum_filt[i, :, :] = cum_filt[i, :, :] - cum[i, refy1s, refx1s] ### Save image rms_cum_wrt_med_file = os.path.join(infodir, '16rms_cum_wrt_med') with open(rms_cum_wrt_med_file, 'w') as f: rms_cum_wrt_med.tofile(f) pngfile = os.path.join(infodir, '16rms_cum_wrt_med.png') plot_lib.make_im_png(rms_cum_wrt_med, pngfile, cmap_noise_r, 'RMS of cum wrt median (mm)', np.nanpercentile(rms_cum_wrt_med, 1), np.nanpercentile(rms_cum_wrt_med, 99)) ### Save ref cumfh5.create_dataset('refarea', data='{}:{}/{}:{}'.format(refx1s, refx2s, refy1s, refy2s)) refsfile = os.path.join(infodir, '16ref.txt') with open(refsfile, 'w') as f: print('{}:{}/{}:{}'.format(refx1s, refx2s, refy1s, refy2s), file=f) if 'corner_lat' in list(cumh5.keys()): ## Geocoded ### Make ref_stable.kml reflat = lat1 + dlat * refy1s reflon = lon1 + dlon * refx1s io_lib.make_point_kml(reflat, reflon, os.path.join(infodir, '16ref.kml')) #%% Calc filtered velocity print('\nCalculate velocity of filtered time series...', flush=True) G = np.stack((np.ones_like(dt_cum), dt_cum), axis=1) vconst = np.zeros((length, width), dtype=np.float32) * np.nan vel = np.zeros((length, width), dtype=np.float32) * np.nan bool_unnan = ~np.isnan(cum_filt[0, :, :]).reshape(length, width) ## not all nan cum_pt = cum_filt[()].reshape(n_im, length * width)[:, bool_unnan.ravel()] #n_im x n_pt n_pt_unnan = bool_unnan.sum() vconst_tmp = np.zeros((n_pt_unnan), dtype=np.float32) * np.nan vel_tmp = np.zeros((n_pt_unnan), dtype=np.float32) * np.nan bool_nonan_pt = np.all(~np.isnan(cum_pt), axis=0) ### First, calc vel point without nan print(' First, solving {0:6}/{1:6}th points with full cum...'.format( bool_nonan_pt.sum(), n_pt_unnan), flush=True) vconst_tmp[bool_nonan_pt], vel_tmp[bool_nonan_pt] = np.linalg.lstsq( G, cum_pt[:, bool_nonan_pt], rcond=None)[0] ### Next, calc vel point with nan print(' Next, solving {0:6}/{1:6}th points with nan in cum...'.format( (~bool_nonan_pt).sum(), n_pt_unnan), flush=True) mask_cum = ~np.isnan(cum_pt[:, ~bool_nonan_pt]) vconst_tmp[~bool_nonan_pt], vel_tmp[ ~bool_nonan_pt] = inv_lib.censored_lstsq_slow( G, cum_pt[:, ~bool_nonan_pt], mask_cum) vconst[bool_unnan], vel[bool_unnan] = vconst_tmp, vel_tmp vconst.tofile(vconstfile) vel.tofile(velfile) if maskflag: vel_mskd = vel * mask vconst_mskd = vconst * mask vconst_mskd.tofile(vconstfile + '.mskd') vel_mskd.tofile(velfile + '.mskd') cumfh5.create_dataset('vel', data=vel.reshape(length, width)) cumfh5.create_dataset('vintercept', data=vconst.reshape(length, width)) #%% Add info and close cumfh5.create_dataset('filtwidth_yr', data=filtwidth_yr) cumfh5.create_dataset('filtwidth_km', data=filtwidth_km) cumfh5.create_dataset('deramp_flag', data=deg_ramp) cumfh5.create_dataset('hgt_linear_flag', data=hgt_linearflag * 1) cumh5.close() cumfh5.close() #%% Output image pngfile = os.path.join(resultsdir, 'vel.filt.png') title = 'Filtered velocity (mm/yr)' vmin = np.nanpercentile(vel, 1) vmax = np.nanpercentile(vel, 99) plot_lib.make_im_png(vel, pngfile, cmap_vel, title, vmin, vmax) ## vintercept pngfile = os.path.join(resultsdir, 'vintercept.filt.png') title = 'Intercept of filtered velocity (mm)' vmin = np.nanpercentile(vconst, 1) vmax = np.nanpercentile(vconst, 99) plot_lib.make_im_png(vconst, pngfile, cmap_vel, title, vmin, vmax) if maskflag: pngfile = os.path.join(resultsdir, 'vel.filt.mskd.png') title = 'Masked filtered velocity (mm/yr)' vmin = np.nanpercentile(vel_mskd, 1) vmax = np.nanpercentile(vel_mskd, 99) plot_lib.make_im_png(vel_mskd, pngfile, cmap_vel, title, vmin, vmax) ## vintercept pngfile = os.path.join(resultsdir, 'vintercept.filt.mskd.png') title = 'Masked intercept of filtered velocity (mm)' vmin = np.nanpercentile(vconst_mskd, 1) vmax = np.nanpercentile(vconst_mskd, 99) plot_lib.make_im_png(vconst_mskd, pngfile, cmap_vel, title, vmin, vmax) #%% Finish elapsed_time = time.time() - start hour = int(elapsed_time / 3600) minite = int(np.mod((elapsed_time / 60), 60)) sec = int(np.mod(elapsed_time, 60)) print("\nElapsed time: {0:02}h {1:02}m {2:02}s".format(hour, minite, sec)) print('\n{} Successfully finished!!\n'.format(os.path.basename(argv[0]))) print('Output: {}\n'.format(os.path.relpath(cumffile)), flush=True) print('To plot the time-series:') print('LiCSBAS_plot_ts.py -i {} &\n'.format(os.path.relpath(cumffile)))
def main(argv=None): #%% Check argv if argv == None: argv = sys.argv start = time.time() ver = 1.2 date = 20200228 author = "Y. Morishita" print("\n{} ver{} {} {}".format(os.path.basename(argv[0]), ver, date, author), flush=True) print("{} {}".format(os.path.basename(argv[0]), ' '.join(argv[1:])), flush=True) #%% Set default tsadir = [] filtwidth_km = 2 filtwidth_yr = [] deg_ramp = [] hgt_linearflag = False hgt_min = 200 ## meter hgt_max = 10000 ## meter maskflag = True cumname = 'cum.h5' cmap_vel = SCM.roma.reversed() cmap_noise_r = 'viridis_r' #%% Read options try: try: opts, args = getopt.getopt( argv[1:], "ht:s:y:r:", ["help", "hgt_linear", "hgt_min=", "hgt_max=", "nomask"]) except getopt.error as msg: raise Usage(msg) for o, a in opts: if o == '-h' or o == '--help': print(__doc__) return 0 elif o == '-t': tsadir = a elif o == '-s': filtwidth_km = float(a) elif o == '-y': filtwidth_yr = float(a) elif o == '-r': deg_ramp = a elif o == '--hgt_linear': hgt_linearflag = True elif o == '--hgt_min': hgt_min = int(a) elif o == '--hgt_max': hgt_max = int(a) elif o == '--nomask': maskflag = False if not tsadir: raise Usage('No tsa directory given, -t is not optional!') elif not os.path.isdir(tsadir): raise Usage('No {} dir exists!'.format(tsadir)) elif not os.path.exists(os.path.join(tsadir, cumname)): raise Usage('No {} exists in {}!'.format(cumname, tsadir)) except Usage as err: print("\nERROR:", file=sys.stderr, end='') print(" " + str(err.msg), file=sys.stderr) print("\nFor help, use -h or --help.\n", file=sys.stderr) return 2 #%% Directory and file setting tsadir = os.path.abspath(tsadir) cumfile = os.path.join(tsadir, cumname) resultsdir = os.path.join(tsadir, 'results') infodir = os.path.join(tsadir, 'info') inparmfile = os.path.join(infodir, '13parameters.txt') if not os.path.exists(inparmfile): ## for old LiCSBAS13 <v1.2 inparmfile = os.path.join(infodir, 'parameters.txt') outparmfile = os.path.join(infodir, '16parameters.txt') pixsp_r = float(io_lib.get_param_par(inparmfile, 'pixel_spacing_r')) pixsp_a = float(io_lib.get_param_par(inparmfile, 'pixel_spacing_a')) x_stddev = filtwidth_km * 1000 / pixsp_r y_stddev = filtwidth_km * 1000 / pixsp_a wavelength = float(io_lib.get_param_par(inparmfile, 'wavelength')) #meter coef_r2m = -wavelength / 4 / np.pi * 1000 #rad -> mm, positive is -LOS if wavelength > 0.2: ## L-band cycle = 1.5 # 2pi/cycle for comparison png elif wavelength <= 0.2: ## C-band cycle = 3 # 3*2pi/cycle for comparison png filtincdir = os.path.join(tsadir, '16filt_increment') if os.path.exists(filtincdir): shutil.rmtree(filtincdir) os.mkdir(filtincdir) filtcumdir = os.path.join(tsadir, '16filt_cum') if os.path.exists(filtcumdir): shutil.rmtree(filtcumdir) os.mkdir(filtcumdir) cumffile = os.path.join(tsadir, 'cum_filt.h5') vconstfile = os.path.join(resultsdir, 'vintercept.filt') velfile = os.path.join(resultsdir, 'vel.filt') cumh5 = h5.File(cumfile, 'r') if os.path.exists(cumffile): os.remove(cumffile) cumfh5 = h5.File(cumffile, 'w') #%% Dates imdates = cumh5['imdates'][()].astype(str).tolist() cum_org = cumh5['cum'] n_im, length, width = cum_org.shape ### Calc dt in year imdates_dt = ([ dt.datetime.strptime(imd, '%Y%m%d').toordinal() for imd in imdates ]) dt_cum = np.float32((np.array(imdates_dt) - imdates_dt[0]) / 365.25) ### Save dates and other info into cumf cumfh5.create_dataset('imdates', data=cumh5['imdates']) cumfh5.create_dataset('gap', data=cumh5['gap']) if 'bperp' in list(cumh5.keys()): ## if dummy, no bperp field cumfh5.create_dataset('bperp', data=cumh5['bperp']) else: print('No bperp field found in {}. Skip.'.format(cumname)) if 'corner_lat' in list(cumh5.keys()): lat1 = float(cumh5['corner_lat'][()]) lon1 = float(cumh5['corner_lon'][()]) dlat = float(cumh5['post_lat'][()]) dlon = float(cumh5['post_lon'][()]) cumfh5.create_dataset('corner_lat', data=cumh5['corner_lat']) cumfh5.create_dataset('corner_lon', data=cumh5['corner_lon']) cumfh5.create_dataset('post_lat', data=cumh5['post_lat']) cumfh5.create_dataset('post_lon', data=cumh5['post_lon']) else: ## not geocoded print('No latlon field found in {}. Skip.'.format(cumname)) ### temporal filter width if not filtwidth_yr and filtwidth_yr != 0: filtwidth_yr = dt_cum[-1] / (n_im - 1) * 3 ## avg interval*3 ### hgt_linear if hgt_linearflag: hgtfile = os.path.join(resultsdir, 'hgt') if not os.path.exists(hgtfile): print('\nERROR: No hgt file exist in results dir!', file=sys.stderr) print('--hgt_linear option cannot be used.', file=sys.stderr) return 2 hgt = io_lib.read_img(hgtfile, length, width) hgt[np.isnan(hgt)] = 0 else: hgt = [] #%% Display settings print('') print('Size of image (w,l) : {0}, {1}'.format(width, length)) print('Number of images : {}'.format(n_im)) print('Width of filter in space : {} km ({:.1f}x{:.1f} pixel)'.format( filtwidth_km, x_stddev, y_stddev)) print('Width of filter in time : {:.3f} yr ({} days)'.format( filtwidth_yr, int(filtwidth_yr * 365.25))) print('Deramp flag : {}'.format(deg_ramp), flush=True) print('hgt-linear flag : {}'.format(hgt_linearflag), flush=True) if hgt_linearflag: print('Minimum hgt : {} m'.format(hgt_min), flush=True) print('Maximum hgt : {} m'.format(hgt_max), flush=True) with open(outparmfile, "w") as f: print('filtwidth_km: {}'.format(filtwidth_km), file=f) print('filtwidth_xpixels: {:.1f}'.format(x_stddev), file=f) print('filtwidth_ypixels: {:.1f}'.format(y_stddev), file=f) print('filtwidth_yr: {:.3f}'.format(filtwidth_yr), file=f) print('filtwidth_day: {}'.format(int(filtwidth_yr * 365.25)), file=f) print('deg_ramp: {}'.format(deg_ramp), file=f) print('hgt_linear: {}'.format(hgt_linearflag * 1), file=f) print('hgt_min: {}'.format(hgt_min), file=f) print('hgt_max: {}'.format(hgt_max), file=f) #%% Load Mask (1: unmask, 0: mask, nan: no cum data) if maskflag: maskfile = os.path.join(resultsdir, 'mask') mask = io_lib.read_img(maskfile, length, width) mask[mask == 0] = np.nan ## 0->nan else: mask = np.ones((length, width), dtype=np.float32) mask[np.isnan(cum_org[0, :, :])] = np.nan #%% First, deramp and hgt-linear if indicated cum = np.zeros((cum_org.shape), dtype=np.float32) * np.nan if not deg_ramp and not hgt_linearflag: cum = cum_org[()] else: if not deg_ramp: print('\nEstimate hgt-linear component...', flush=True) elif not hgt_linearflag: print('\nDeramp ifgs with the degree of {}...'.format(deg_ramp), flush=True) else: print( '\nDeramp ifgs with the degree of {} and hgt-linear...'.format( deg_ramp), flush=True) ramp1 = [] ## backup last ramp to plot increment fit_hgt1 = [] ## backup last fit_hgt to plot increment model1 = [] deramp_title3 = [ 'Before deramp ({}pi/cycle)'.format(cycle * 2), 'ramp phase (deg:{})'.format(deg_ramp), 'After deramp ({}pi/cycle)'.format(cycle * 2) ] for i in range(n_im): if np.mod(i, 10) == 0: print(" {0:3}/{1:3}th image...".format(i, n_im), flush=True) fit, model = tools_lib.fit2dh(cum_org[i, :, :] * mask, deg_ramp, hgt, hgt_min, hgt_max) ## fit is not masked cum[i, :, :] = cum_org[i, :, :] - fit if hgt_linearflag: fit_hgt = hgt * model[ -1] * mask ## extract only hgt-linear component cum_bf = cum[ i, :, :] + fit_hgt ## After deramp before hgt-linear ## Output comparison image of hgt_linear std_before = np.nanstd(cum_bf) std_after = np.nanstd(cum[i, :, :] * mask) data3 = [ np.angle(np.exp(1j * (data / coef_r2m / cycle)) * cycle) for data in [cum_bf, fit_hgt, cum[i, :, :] * mask] ] title3 = [ 'Before hgt-linear (STD: {:.1f}mm)'.format(std_before), 'hgt-linear phase ({:.1f}mm/km)'.format(model[-1] * 1000), 'After hgt-linear (STD: {:.1f}mm)'.format(std_after) ] pngfile = os.path.join(filtcumdir, imdates[i] + '_hgt_linear.png') plot_lib.make_3im_png(data3, pngfile, 'insar', title3, vmin=-np.pi, vmax=np.pi, cbar=False) pngfile = os.path.join(filtcumdir, imdates[i] + '_hgt_corr.png') title = '{} ({:.1f}mm/km, based on {}<=hgt<={})'.format( imdates[i], model[-1] * 1000, hgt_min, hgt_max) plot_lib.plot_hgt_corr(cum_bf, fit_hgt, hgt, title, pngfile) ## Output comparison image of hgt_linear for increment if i != 0: ## first image has no increment inc = (cum[i, :, :] - cum[i - 1, :, :]) * mask std_before = np.nanstd(inc + fit_hgt - fit_hgt1) std_after = np.nanstd(inc) data3 = [ np.angle( np.exp(1j * (data / coef_r2m / cycle)) * cycle) for data in [inc + fit_hgt - fit_hgt1, fit_hgt - fit_hgt1, inc] ] title3 = [ 'Before hgt-linear (STD: {:.1f}mm)'.format(std_before), 'hgt-linear phase ({:.1f}mm/km)'.format( (model[-1] - model1) * 1000), 'After hgt-linear (STD: {:.1f}mm)'.format(std_after) ] pngfile = os.path.join( filtincdir, '{}_{}_hgt_linear.png'.format(imdates[i - 1], imdates[i])) plot_lib.make_3im_png(data3, pngfile, 'insar', title3, vmin=-np.pi, vmax=np.pi, cbar=False) pngfile = os.path.join( filtincdir, '{}_{}_hgt_corr.png'.format(imdates[i - 1], imdates[i])) title = '{}_{} ({:.1f}mm/km, based on {}<=hgt<={})'.format( imdates[i - 1], imdates[i], (model[-1] - model1) * 1000, hgt_min, hgt_max) plot_lib.plot_hgt_corr(inc + fit_hgt - fit_hgt1, fit_hgt - fit_hgt1, hgt, title, pngfile) fit_hgt1 = fit_hgt.copy() ## backup last fit_hgt model1 = model[-1] else: fit_hgt = 0 ## for plot deframp if deg_ramp: ramp = (fit - fit_hgt) * mask ## Output comparison image of deramp data3 = [ np.angle(np.exp(1j * (data / coef_r2m / cycle)) * cycle) for data in [ cum_org[i, :, :] * mask, ramp, cum_org[i, :, :] * mask - ramp ] ] pngfile = os.path.join(filtcumdir, imdates[i] + '_deramp.png') plot_lib.make_3im_png(data3, pngfile, 'insar', deramp_title3, vmin=-np.pi, vmax=np.pi, cbar=False) ## Output comparison image of deramp for increment if i != 0: ## first image has no increment inc_org = (cum_org[i, :, :] - cum_org[i - 1, :, :]) * mask data3 = [ np.angle( np.exp(1j * (data / coef_r2m / cycle)) * cycle) for data in [inc_org, ramp - ramp1, inc_org - (ramp - ramp1)] ] pngfile = os.path.join( filtincdir, '{}_{}_deramp.png'.format(imdates[i - 1], imdates[i])) plot_lib.make_3im_png(data3, pngfile, 'insar', deramp_title3, vmin=-np.pi, vmax=np.pi, cbar=False) ramp1 = ramp.copy() ## backup last ramp #%% Filter each image cum_filt = cumfh5.require_dataset('cum', (n_im, length, width), dtype=np.float32) cum_hptlps1 = [] print('\nHP filter in time, LP filter in space...', flush=True) for i in range(n_im): if np.mod(i, 10) == 0: print(" {0:3}/{1:3}th image...".format(i, n_im), flush=True) #%% Second, HP in time if filtwidth_yr == 0.0: cum_hpt = cum[i, :, :] ## No temporal filter else: time_diff_sq = (dt_cum[i] - dt_cum)**2 ## Limit reading data within filtwidth_yr**8 ixs = time_diff_sq < filtwidth_yr * 8 weight_factor = np.tile( np.exp(-time_diff_sq[ixs] / 2 / filtwidth_yr**2)[:, np.newaxis, np.newaxis], (1, length, width)) #len(ixs), length, width ## Take into account nan in cum weight_factor = weight_factor * (~np.isnan(cum[ixs, :, :])) ## Normalize weight with warnings.catch_warnings( ): ## To silence warning by zero division warnings.simplefilter('ignore', RuntimeWarning) weight_factor = weight_factor / np.sum(weight_factor, axis=0) cum_lpt = np.nansum(cum[ixs, :, :] * weight_factor, axis=0) cum_hpt = cum[i, :, :] - cum_lpt #%% Third, LP in space and subtract from original if filtwidth_km == 0.0: cum_filt[i, :, :] = cum[i, :, :] ## No spatial else: with warnings.catch_warnings(): ## To silence warning if i == 0: cum_hpt = cum_hpt + sys.float_info.epsilon ##To distinguish from 0 of filtered nodata # warnings.simplefilter('ignore', FutureWarning) warnings.simplefilter('ignore', RuntimeWarning) kernel = Gaussian2DKernel(x_stddev, y_stddev) cum_hptlps = convolve_fft( cum_hpt * mask, kernel, fill_value=np.nan, allow_huge=True) ## fill edge 0 for interpolation cum_hptlps[cum_hptlps == 0] = np.nan ## fill 0 with nan cum_filt[i, :, :] = cum[i, :, :] - cum_hptlps #%% Output comparison image data3 = [ np.angle(np.exp(1j * (data / coef_r2m / cycle)) * cycle) for data in [cum[i, :, :] * mask, cum_hptlps, cum_filt[i, :, :] * mask] ] title3 = [ 'Before filter ({}pi/cycle)'.format(cycle * 2), 'Filter phase ({}pi/cycle)'.format(cycle * 2), 'After filter ({}pi/cycle)'.format(cycle * 2) ] pngfile = os.path.join(filtcumdir, imdates[i] + '_filt.png') plot_lib.make_3im_png(data3, pngfile, 'insar', title3, vmin=-np.pi, vmax=np.pi, cbar=False) ### Output comparison image for increment if i != 0: data3 = [ np.angle(np.exp(1j * (data / coef_r2m / cycle)) * cycle) for data in [(cum[i, :, :] - cum[i - 1, :, :]) * mask, cum_hptlps - cum_hptlps1, (cum_filt[i, :, :] - cum_filt[i - 1, :, :]) * mask] ] title3 = [ 'Before filter ({}pi/cycle)'.format(cycle * 2), 'Filter phase ({}pi/cycle)'.format(cycle * 2), 'After filter ({}pi/cycle)'.format(cycle * 2) ] pngfile = os.path.join( filtincdir, '{}_{}_filt.png'.format(imdates[i - 1], imdates[i])) plot_lib.make_3im_png(data3, pngfile, 'insar', title3, vmin=-np.pi, vmax=np.pi, cbar=False) cum_hptlps1 = cum_hptlps.copy() ## backup last filt phase #%% Find stable ref point print('\nFind stable reference point...', flush=True) ### Compute RMS of time series with reference to all points sumsq_cum_wrt_med = np.zeros((length, width), dtype=np.float32) for i in range(n_im): sumsq_cum_wrt_med = sumsq_cum_wrt_med + ( cum_filt[i, :, :] - np.nanmedian(cum_filt[i, :, :]))**2 rms_cum_wrt_med = np.sqrt(sumsq_cum_wrt_med / n_im) * mask ### Mask by minimum n_gap n_gap = io_lib.read_img(os.path.join(resultsdir, 'n_gap'), length, width) min_n_gap = np.nanmin(n_gap) mask_n_gap = np.float32(n_gap == min_n_gap) mask_n_gap[mask_n_gap == 0] = np.nan rms_cum_wrt_med = rms_cum_wrt_med * mask_n_gap ### Find stable reference min_rms = np.nanmin(rms_cum_wrt_med) refy1s, refx1s = np.where(rms_cum_wrt_med == min_rms) refy1s, refx1s = refy1s[0], refx1s[0] ## Only first index refy2s, refx2s = refy1s + 1, refx1s + 1 print('Selected ref: {}:{}/{}:{}'.format(refx1s, refx2s, refy1s, refy2s), flush=True) ### Rerferencing cumulative displacement to new stable ref for i in range(n_im): cum_filt[i, :, :] = cum_filt[i, :, :] - cum[i, refy1s, refx1s] ### Save image rms_cum_wrt_med_file = os.path.join(infodir, '16rms_cum_wrt_med') with open(rms_cum_wrt_med_file, 'w') as f: rms_cum_wrt_med.tofile(f) pngfile = os.path.join(infodir, '16rms_cum_wrt_med.png') plot_lib.make_im_png(rms_cum_wrt_med, pngfile, cmap_noise_r, 'RMS of cum wrt median (mm)', np.nanpercentile(rms_cum_wrt_med, 1), np.nanpercentile(rms_cum_wrt_med, 99)) ### Save ref cumfh5.create_dataset('refarea', data='{}:{}/{}:{}'.format(refx1s, refx2s, refy1s, refy2s)) refsfile = os.path.join(infodir, '16ref.txt') with open(refsfile, 'w') as f: print('{}:{}/{}:{}'.format(refx1s, refx2s, refy1s, refy2s), file=f) if 'corner_lat' in list(cumh5.keys()): ## Geocoded ### Make ref_stable.kml reflat = lat1 + dlat * refy1s reflon = lon1 + dlon * refx1s io_lib.make_point_kml(reflat, reflon, os.path.join(infodir, '16ref.kml')) #%% Calc filtered velocity print('\nCalculate velocity of filtered time series...', flush=True) G = np.stack((np.ones_like(dt_cum), dt_cum), axis=1) vconst = np.zeros((length, width), dtype=np.float32) * np.nan vel = np.zeros((length, width), dtype=np.float32) * np.nan bool_unnan = ~np.isnan(cum_filt[0, :, :]).reshape(length, width) ## not all nan cum_pt = cum_filt[()].reshape(n_im, length * width)[:, bool_unnan.ravel()] #n_im x n_pt n_pt_unnan = bool_unnan.sum() vconst_tmp = np.zeros((n_pt_unnan), dtype=np.float32) * np.nan vel_tmp = np.zeros((n_pt_unnan), dtype=np.float32) * np.nan bool_nonan_pt = np.all(~np.isnan(cum_pt), axis=0) ### First, calc vel point without nan print(' First, solving {0:6}/{1:6}th points with full cum...'.format( bool_nonan_pt.sum(), n_pt_unnan), flush=True) vconst_tmp[bool_nonan_pt], vel_tmp[bool_nonan_pt] = np.linalg.lstsq( G, cum_pt[:, bool_nonan_pt], rcond=None)[0] ### Next, calc vel point with nan print(' Next, solving {0:6}/{1:6}th points with nan in cum...'.format( (~bool_nonan_pt).sum(), n_pt_unnan), flush=True) mask_cum = ~np.isnan(cum_pt[:, ~bool_nonan_pt]) vconst_tmp[~bool_nonan_pt], vel_tmp[ ~bool_nonan_pt] = inv_lib.censored_lstsq_slow( G, cum_pt[:, ~bool_nonan_pt], mask_cum) vconst[bool_unnan], vel[bool_unnan] = vconst_tmp, vel_tmp vconst.tofile(vconstfile) vel.tofile(velfile) if maskflag: vel_mskd = vel * mask vconst_mskd = vconst * mask vconst_mskd.tofile(vconstfile + '.mskd') vel_mskd.tofile(velfile + '.mskd') cumfh5.create_dataset('vel', data=vel.reshape(length, width)) cumfh5.create_dataset('vintercept', data=vconst.reshape(length, width)) #%% Add info and close cumfh5.create_dataset('filtwidth_yr', data=filtwidth_yr) cumfh5.create_dataset('filtwidth_km', data=filtwidth_km) cumfh5.create_dataset('deramp_flag', data=deg_ramp) cumfh5.create_dataset('hgt_linear_flag', data=hgt_linearflag * 1) cumh5.close() cumfh5.close() #%% Output image pngfile = os.path.join(resultsdir, 'vel.filt.png') title = 'Filtered velocity (mm/yr)' vmin = np.nanpercentile(vel, 1) vmax = np.nanpercentile(vel, 99) plot_lib.make_im_png(vel, pngfile, cmap_vel, title, vmin, vmax) ## vintercept pngfile = os.path.join(resultsdir, 'vintercept.filt.png') title = 'Intercept of filtered velocity (mm)' vmin = np.nanpercentile(vconst, 1) vmax = np.nanpercentile(vconst, 99) plot_lib.make_im_png(vconst, pngfile, cmap_vel, title, vmin, vmax) if maskflag: pngfile = os.path.join(resultsdir, 'vel.filt.mskd.png') title = 'Masked filtered velocity (mm/yr)' vmin = np.nanpercentile(vel_mskd, 1) vmax = np.nanpercentile(vel_mskd, 99) plot_lib.make_im_png(vel_mskd, pngfile, cmap_vel, title, vmin, vmax) ## vintercept pngfile = os.path.join(resultsdir, 'vintercept.filt.mskd.png') title = 'Masked intercept of filtered velocity (mm)' vmin = np.nanpercentile(vconst_mskd, 1) vmax = np.nanpercentile(vconst_mskd, 99) plot_lib.make_im_png(vconst_mskd, pngfile, cmap_vel, title, vmin, vmax) #%% Finish elapsed_time = time.time() - start hour = int(elapsed_time / 3600) minite = int(np.mod((elapsed_time / 60), 60)) sec = int(np.mod(elapsed_time, 60)) print("\nElapsed time: {0:02}h {1:02}m {2:02}s".format(hour, minite, sec)) print('\n{} Successfully finished!!\n'.format(os.path.basename(argv[0]))) print('Output: {}\n'.format(os.path.relpath(cumffile)), flush=True) print('To plot the time-series:') print('LiCSBAS_plot_ts.py -i {} &\n'.format(os.path.relpath(cumffile)))