2019-01-16 19:40:08 +00:00
#!/usr/bin/env python3
#Author: Heresh Fattahi
import os , imp , sys , glob
import argparse
import configparser
import datetime
import numpy as np
import shelve
import isce
import isceobj
from mroipac . baseline . Baseline import Baseline
from Stack import config , run , selectPairs
filtStrength = ' 0.8 '
noMCF = ' False '
defoMax = ' 2 '
maxNodes = 72
def createParser ( ) :
parser = argparse . ArgumentParser ( description = ' Preparing the directory structure and config files for stack processing of Sentinel data ' )
parser . add_argument ( ' -s ' , ' --slc_directory ' , dest = ' slcDir ' , type = str , required = True ,
help = ' Directory with all stripmap SLCs ' )
parser . add_argument ( ' -x ' , ' --bbox ' , dest = ' bbox ' , type = str , default = None , help = ' Lat/Lon Bounding SNWE ' )
parser . add_argument ( ' -w ' , ' --working_directory ' , dest = ' workDir ' , type = str , default = ' ./ ' ,
help = ' Working directory ' )
parser . add_argument ( ' -d ' , ' --dem ' , dest = ' dem ' , type = str , required = True ,
help = ' Directory with the DEM (.xml and .vrt files) ' )
parser . add_argument ( ' -m ' , ' --master_date ' , dest = ' masterDate ' , type = str , default = None ,
help = ' Directory with master acquisition ' )
parser . add_argument ( ' -t ' , ' --time_threshold ' , dest = ' dtThr ' , type = float , default = 10000.0 ,
help = ' Time threshold (max temporal baseline in days) ' )
parser . add_argument ( ' -b ' , ' --baseline_threshold ' , dest = ' dbThr ' , type = float , default = 5000.0 ,
help = ' Baseline threshold (max bperp in meters) ' )
parser . add_argument ( ' -a ' , ' --azimuth_looks ' , dest = ' alks ' , type = str , default = ' 10 ' ,
help = ' Number of looks in azimuth (automaticly computed as AspectR*looks when " S " or " sensor " is defined to give approximately square multi-look pixels) ' )
parser . add_argument ( ' -r ' , ' --range_looks ' , dest = ' rlks ' , type = str , default = ' 10 ' ,
help = ' Number of looks in range ' )
parser . add_argument ( ' -S ' , ' --sensor ' , dest = ' sensor ' , type = str , required = False ,
help = ' SAR sensor used to define square multi-look pixels ' )
parser . add_argument ( ' -L ' , ' --low_band_frequency ' , dest = ' fL ' , type = str , default = None ,
help = ' low band frequency ' )
parser . add_argument ( ' -H ' , ' --high_band_frequency ' , dest = ' fH ' , type = str , default = None ,
help = ' high band frequency ' )
parser . add_argument ( ' -B ' , ' --subband_bandwidth ' , dest = ' bandWidth ' , type = str , default = None ,
help = ' sub-band band width ' )
parser . add_argument ( ' -u ' , ' --unw_method ' , dest = ' unwMethod ' , type = str , default = ' snaphu '
, help = ' unwrapping method (icu, snaphu, or snaphu2stage) ' )
2019-03-18 22:50:33 +00:00
parser . add_argument ( ' -f ' , ' --filter_strength ' , dest = ' filtStrength ' , type = str , default = filtStrength ,
help = ' strength of Goldstein filter applied to the wrapped phase before spatial coherence estimation. '
' Default: {} ' . format ( filtStrength ) )
2019-01-16 19:40:08 +00:00
parser . add_argument ( ' --filter_sigma_x ' , dest = ' filterSigmaX ' , type = str , default = ' 100 '
, help = ' filter sigma for gaussian filtering the dispersive and nonDispersive phase ' )
parser . add_argument ( ' --filter_sigma_y ' , dest = ' filterSigmaY ' , type = str , default = ' 100.0 ' ,
help = ' sigma of the gaussian filter in Y direction, default=100 ' )
parser . add_argument ( ' --filter_size_x ' , dest = ' filterSizeX ' , type = str , default = ' 800.0 ' ,
help = ' size of the gaussian kernel in X direction, default = 800 ' )
parser . add_argument ( ' --filter_size_y ' , dest = ' filterSizeY ' , type = str , default = ' 800.0 ' ,
help = ' size of the gaussian kernel in Y direction, default=800 ' )
parser . add_argument ( ' --filter_kernel_rotation ' , dest = ' filterKernelRotation ' , type = str , default = ' 0.0 ' ,
help = ' rotation angle of the filter kernel in degrees (default = 0.0) ' )
parser . add_argument ( ' -W ' , ' --workflow ' , dest = ' workflow ' , type = str , default = ' slc '
, help = ' The InSAR processing workflow : (slc, interferogram, ionosphere) ' )
parser . add_argument ( ' -z ' , ' --zero ' , dest = ' zerodop ' , action = ' store_true ' , default = False , help = ' Use zero doppler geometry for processing - Default : No ' )
parser . add_argument ( ' --nofocus ' , dest = ' nofocus ' , action = ' store_true ' , default = False , help = ' If input data is already focused to SLCs - Default : do focus ' )
parser . add_argument ( ' -c ' , ' --text_cmd ' , dest = ' text_cmd ' , type = str , default = ' '
, help = ' text command to be added to the beginning of each line of the run files. Example : source ~/.bash_profile; ' )
parser . add_argument ( ' -useGPU ' , ' --useGPU ' , dest = ' useGPU ' , action = ' store_true ' , default = False , help = ' Allow App to use GPU when available ' )
parser . add_argument ( ' --summary ' , dest = ' summary ' , action = ' store_true ' , default = False , help = ' Show summary only ' )
return parser
def cmdLineParse ( iargs = None ) :
parser = createParser ( )
inps = parser . parse_args ( args = iargs )
inps . slcDir = os . path . abspath ( inps . slcDir )
inps . workDir = os . path . abspath ( inps . workDir )
inps . dem = os . path . abspath ( inps . dem )
return inps
def get_dates ( inps ) :
dirs = glob . glob ( inps . slcDir + ' /* ' )
acuisitionDates = [ ]
for dirf in dirs :
if inps . nofocus :
expectedRaw = os . path . join ( dirf , os . path . basename ( dirf ) + ' .slc ' )
else :
expectedRaw = os . path . join ( dirf , os . path . basename ( dirf ) + ' .raw ' )
if os . path . exists ( expectedRaw ) :
acuisitionDates . append ( os . path . basename ( dirf ) )
acuisitionDates . sort ( )
print ( dirs )
print ( acuisitionDates )
if inps . masterDate not in acuisitionDates :
print ( ' master date was not found. The first acquisition will be considered as the stack master date. ' )
if inps . masterDate is None or inps . masterDate not in acuisitionDates :
inps . masterDate = acuisitionDates [ 0 ]
slaveDates = acuisitionDates . copy ( )
slaveDates . remove ( inps . masterDate )
return acuisitionDates , inps . masterDate , slaveDates
def slcStack ( inps , acquisitionDates , stackMasterDate , slaveDates , pairs , splitFlag = False , rubberSheet = False ) :
# A coregistered stack of SLCs
i = 0
if inps . bbox :
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _crop " )
config_prefix = " config_crop_ "
runObj . crop ( acquisitionDates , config_prefix , native = not inps . zerodop , israw = not inps . nofocus )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _master " )
config_prefix = " config_master_ "
runObj . master_focus_split_geometry ( stackMasterDate , config_prefix , split = splitFlag , focus = not inps . nofocus , native = not inps . zerodop )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _focus_split " )
config_prefix = " config_focus_split "
runObj . slaves_focus_split ( slaveDates , config_prefix , split = splitFlag , focus = not inps . nofocus , native = not inps . zerodop )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _geo2rdr_coarseResamp " )
config_prefix = " config_geo2rdr_coarseResamp_ "
runObj . slaves_geo2rdr_resampleSlc ( stackMasterDate , slaveDates , config_prefix , native = ( not inps . nofocus ) or ( not inps . zerodop ) )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _refineSlaveTiming " )
config_prefix = ' config_refineSlaveTiming_ '
runObj . refineSlaveTiming_Network ( pairs , stackMasterDate , slaveDates , config_prefix )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _invertMisreg " )
runObj . invertMisregPoly ( )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _fineResamp " )
config_prefix = ' config_fineResamp_ '
runObj . slaves_fine_resampleSlc ( stackMasterDate , slaveDates , config_prefix , split = splitFlag )
runObj . finalize ( )
if rubberSheet :
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _denseOffset " )
config_prefix = ' config_denseOffset_ '
runObj . denseOffsets_Network ( pairs , stackMasterDate , slaveDates , config_prefix )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _invertDenseOffsets " )
runObj . invertDenseOffsets ( )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _resampleOffset " )
config_prefix = ' config_resampOffsets_ '
runObj . resampleOffset ( slaveDates , config_prefix )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _replaceOffsets " )
runObj . replaceOffsets ( slaveDates )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _fineResamp " )
config_prefix = ' config_fineResamp_ '
runObj . slaves_fine_resampleSlc ( stackMasterDate , slaveDates , config_prefix , split = splitFlag )
runObj . finalize ( )
# adding the baseline grid generation
i + = 1
config_prefix = ' config_baselinegrid_ '
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _grid_baseline " )
runObj . gridBaseline ( stackMasterDate , slaveDates , config_prefix )
runObj . finalize ( )
return i
def interferogramStack ( inps , acquisitionDates , stackMasterDate , slaveDates , pairs ) :
# an interferogram stack without ionosphere correction.
# coregistration is with geometry + const offset
i = slcStack ( inps , acquisitionDates , stackMasterDate , slaveDates , pairs , splitFlag = False , rubberSheet = False )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _igram " )
config_prefix = ' config_igram_ '
low_or_high = " / "
runObj . igrams_network ( pairs , acquisitionDates , stackMasterDate , low_or_high , config_prefix )
runObj . finalize ( )
def interferogramIonoStack ( inps , acquisitionDates , stackMasterDate , slaveDates , pairs ) :
2019-03-24 16:57:26 +00:00
# raise exception for ALOS-1 if --fbd2fbs was used
run_unpack_file = os . path . join ( inps . workDir , ' run_unPackALOS ' )
if os . path . isfile ( run_unpack_file ) :
with open ( run_unpack_file , ' r ' ) as f :
lines = f . readlines ( )
if any ( ' fbd2fbs ' in line for line in lines ) :
msg = ' ALOS-1 FBD mode data exists with fbd2fbs enabled, which is not applicable for ionosphere workflow '
msg + = ' \n solution: restart from prepRawALOS.py WITHOUT --dual2single/--fbd2fbs option. '
raise ValueError ( msg )
2019-01-16 19:40:08 +00:00
# an interferogram stack with ionosphere correction.
# coregistration is with geometry + const offset + rubbersheeting
i = slcStack ( inps , acquisitionDates , stackMasterDate , slaveDates , pairs , splitFlag = True , rubberSheet = True )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _igram " )
config_prefix = ' config_igram_ '
low_or_high = " / "
runObj . igrams_network ( pairs , acquisitionDates , stackMasterDate , low_or_high , config_prefix )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _igramLowBand " )
config_prefix = ' config_igramLowBand_ '
low_or_high = " /LowBand/ "
runObj . igrams_network ( pairs , acquisitionDates , stackMasterDate , low_or_high , config_prefix )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _igramHighBand " )
config_prefix = ' config_igramHighBand_ '
low_or_high = " /HighBand/ "
runObj . igrams_network ( pairs , acquisitionDates , stackMasterDate , low_or_high , config_prefix )
runObj . finalize ( )
i + = 1
runObj = run ( )
runObj . configure ( inps , ' run_ ' + str ( i ) + " _iono " )
config_prefix = ' config_iono_ '
lowBand = ' /LowBand/ '
highBand = ' /HighBand/ '
runObj . dispersive_nonDispersive ( pairs , acquisitionDates , stackMasterDate ,
lowBand , highBand , config_prefix )
runObj . finalize ( )
def main ( iargs = None ) :
inps = cmdLineParse ( iargs )
# name of the folder of the coreg SLCs including baselines, SLC, geom_master subfolders
inps . stack_folder = ' merged '
inps . dense_offsets_folder = ' dense_offsets '
# check if a sensor is defined and update if needed azimuth looks to give square pixels
ar = 1
if inps . sensor :
if inps . sensor . lower ( ) == " alos " :
ar = 4
print ( " Looks like " + inps . sensor . lower ( ) + " , multi-look AR= " + str ( ar ) )
elif inps . sensor . lower ( ) == " envisat " or inps . sensor . lower ( ) == " ers " :
ar = 5
print ( " Looks like " + inps . sensor . lower ( ) + " , multi-look AR= " + str ( ar ) )
else :
print ( " Sensor is not hard-coded (ers, envisat, alos), will keep default alks " )
# sensor is not recognised, report to user and state default
inps . alks = str ( int ( inps . alks ) * int ( ar ) )
# getting the acquisitions
acquisitionDates , stackMasterDate , slaveDates = get_dates ( inps )
configDir = os . path . join ( inps . workDir , ' configs ' )
if not os . path . exists ( configDir ) :
os . makedirs ( configDir )
runDir = os . path . join ( inps . workDir , ' run_files ' )
if not os . path . exists ( runDir ) :
os . makedirs ( runDir )
2019-05-08 22:05:08 +00:00
if inps . sensor . lower ( ) == ' uavsar_stack ' : # don't try to calculate baselines for UAVSAR_STACK data
pairs = selectPairs ( inps , stackMasterDate , slaveDates , acquisitionDates , doBaselines = False )
else :
pairs = selectPairs ( inps , stackMasterDate , slaveDates , acquisitionDates , doBaselines = True )
2019-01-16 19:40:08 +00:00
print ( ' number of pairs: ' , len ( pairs ) )
###If only a summary is requested quit after this
if inps . summary :
return
#if cropping is requested, then change the slc directory:
inps . fullFrameSlcDir = inps . slcDir
if inps . bbox :
inps . slcDir = inps . slcDir + " _crop "
#############################
if inps . workflow == ' slc ' :
slcStack ( inps , acquisitionDates , stackMasterDate , slaveDates , pairs , splitFlag = False , rubberSheet = False )
elif inps . workflow == ' interferogram ' :
interferogramStack ( inps , acquisitionDates , stackMasterDate , slaveDates , pairs )
elif inps . workflow == ' ionosphere ' :
interferogramIonoStack ( inps , acquisitionDates , stackMasterDate , slaveDates , pairs )
if __name__ == " __main__ " :
# Main engine
main ( )