new alosStack application
parent
3aa234c515
commit
e9bd7edeb3
|
|
@ -117,6 +117,13 @@ WBD = Application.Parameter('wbd',
|
||||||
mandatory=False,
|
mandatory=False,
|
||||||
doc='water body file')
|
doc='water body file')
|
||||||
|
|
||||||
|
DO_INSAR = Application.Parameter('doInSAR',
|
||||||
|
public_name='do InSAR',
|
||||||
|
default = True,
|
||||||
|
type = bool,
|
||||||
|
mandatory = False,
|
||||||
|
doc = 'do InSAR')
|
||||||
|
|
||||||
USE_VIRTUAL_FILE = Application.Parameter('useVirtualFile',
|
USE_VIRTUAL_FILE = Application.Parameter('useVirtualFile',
|
||||||
public_name = 'use virtual file',
|
public_name = 'use virtual file',
|
||||||
default=True,
|
default=True,
|
||||||
|
|
@ -331,6 +338,22 @@ SWATH_PHASE_DIFF_SNAP_ION = Application.Parameter('swathPhaseDiffSnapIon',
|
||||||
container = list,
|
container = list,
|
||||||
doc = 'swath phase difference snap to fixed values')
|
doc = 'swath phase difference snap to fixed values')
|
||||||
|
|
||||||
|
SWATH_PHASE_DIFF_LOWER_ION = Application.Parameter('swathPhaseDiffLowerIon',
|
||||||
|
public_name = 'swath phase difference of lower band',
|
||||||
|
default = None,
|
||||||
|
type = float,
|
||||||
|
mandatory = False,
|
||||||
|
container = list,
|
||||||
|
doc = 'swath phase difference of lower band')
|
||||||
|
|
||||||
|
SWATH_PHASE_DIFF_UPPER_ION = Application.Parameter('swathPhaseDiffUpperIon',
|
||||||
|
public_name = 'swath phase difference of upper band',
|
||||||
|
default = None,
|
||||||
|
type = float,
|
||||||
|
mandatory = False,
|
||||||
|
container = list,
|
||||||
|
doc = 'swath phase difference of upper band')
|
||||||
|
|
||||||
FIT_ION = Application.Parameter('fitIon',
|
FIT_ION = Application.Parameter('fitIon',
|
||||||
public_name = 'apply polynomial fit before filtering ionosphere phase',
|
public_name = 'apply polynomial fit before filtering ionosphere phase',
|
||||||
default = True,
|
default = True,
|
||||||
|
|
@ -352,6 +375,13 @@ FIT_ADAPTIVE_ION = Application.Parameter('fitAdaptiveIon',
|
||||||
mandatory = False,
|
mandatory = False,
|
||||||
doc = 'apply polynomial fit in adaptive filtering window')
|
doc = 'apply polynomial fit in adaptive filtering window')
|
||||||
|
|
||||||
|
FILT_SECONDARY_ION = Application.Parameter('filtSecondaryIon',
|
||||||
|
public_name = 'whether do secondary filtering of ionosphere phase',
|
||||||
|
default = True,
|
||||||
|
type = bool,
|
||||||
|
mandatory = False,
|
||||||
|
doc = 'whether do secondary filtering of ionosphere phase')
|
||||||
|
|
||||||
FILTERING_WINSIZE_MAX_ION = Application.Parameter('filteringWinsizeMaxIon',
|
FILTERING_WINSIZE_MAX_ION = Application.Parameter('filteringWinsizeMaxIon',
|
||||||
public_name='maximum window size for filtering ionosphere phase',
|
public_name='maximum window size for filtering ionosphere phase',
|
||||||
default=301,
|
default=301,
|
||||||
|
|
@ -366,6 +396,20 @@ FILTERING_WINSIZE_MIN_ION = Application.Parameter('filteringWinsizeMinIon',
|
||||||
mandatory=False,
|
mandatory=False,
|
||||||
doc='minimum window size for filtering ionosphere phase')
|
doc='minimum window size for filtering ionosphere phase')
|
||||||
|
|
||||||
|
FILTERING_WINSIZE_SECONDARY_ION = Application.Parameter('filteringWinsizeSecondaryIon',
|
||||||
|
public_name='window size of secondary filtering of ionosphere phase',
|
||||||
|
default=5,
|
||||||
|
type=int,
|
||||||
|
mandatory=False,
|
||||||
|
doc='window size of secondary filtering of ionosphere phase')
|
||||||
|
|
||||||
|
FILTER_STD_ION = Application.Parameter('filterStdIon',
|
||||||
|
public_name = 'standard deviation of ionosphere phase after filtering',
|
||||||
|
default = None,
|
||||||
|
type=float,
|
||||||
|
mandatory = False,
|
||||||
|
doc = 'standard deviation of ionosphere phase after filtering')
|
||||||
|
|
||||||
FILTER_SUBBAND_INT = Application.Parameter('filterSubbandInt',
|
FILTER_SUBBAND_INT = Application.Parameter('filterSubbandInt',
|
||||||
public_name = 'filter subband interferogram',
|
public_name = 'filter subband interferogram',
|
||||||
default = False,
|
default = False,
|
||||||
|
|
@ -601,6 +645,7 @@ class Alos2InSAR(Application):
|
||||||
DEM,
|
DEM,
|
||||||
DEM_GEO,
|
DEM_GEO,
|
||||||
WBD,
|
WBD,
|
||||||
|
DO_INSAR,
|
||||||
USE_VIRTUAL_FILE,
|
USE_VIRTUAL_FILE,
|
||||||
USE_GPU,
|
USE_GPU,
|
||||||
BURST_SYNCHRONIZATION_THRESHOLD,
|
BURST_SYNCHRONIZATION_THRESHOLD,
|
||||||
|
|
@ -631,11 +676,16 @@ class Alos2InSAR(Application):
|
||||||
NUMBER_AZIMUTH_LOOKS_ION,
|
NUMBER_AZIMUTH_LOOKS_ION,
|
||||||
MASKED_AREAS_ION,
|
MASKED_AREAS_ION,
|
||||||
SWATH_PHASE_DIFF_SNAP_ION,
|
SWATH_PHASE_DIFF_SNAP_ION,
|
||||||
|
SWATH_PHASE_DIFF_LOWER_ION,
|
||||||
|
SWATH_PHASE_DIFF_UPPER_ION,
|
||||||
FIT_ION,
|
FIT_ION,
|
||||||
FILT_ION,
|
FILT_ION,
|
||||||
FIT_ADAPTIVE_ION,
|
FIT_ADAPTIVE_ION,
|
||||||
|
FILT_SECONDARY_ION,
|
||||||
FILTERING_WINSIZE_MAX_ION,
|
FILTERING_WINSIZE_MAX_ION,
|
||||||
FILTERING_WINSIZE_MIN_ION,
|
FILTERING_WINSIZE_MIN_ION,
|
||||||
|
FILTERING_WINSIZE_SECONDARY_ION,
|
||||||
|
FILTER_STD_ION,
|
||||||
FILTER_SUBBAND_INT,
|
FILTER_SUBBAND_INT,
|
||||||
FILTER_STRENGTH_SUBBAND_INT,
|
FILTER_STRENGTH_SUBBAND_INT,
|
||||||
FILTER_WINSIZE_SUBBAND_INT,
|
FILTER_WINSIZE_SUBBAND_INT,
|
||||||
|
|
@ -775,6 +825,7 @@ class Alos2InSAR(Application):
|
||||||
## Add instance attribute RunWrapper functions, which emulate methods.
|
## Add instance attribute RunWrapper functions, which emulate methods.
|
||||||
def _add_methods(self):
|
def _add_methods(self):
|
||||||
self.runPreprocessor = Alos2Proc.createPreprocessor(self)
|
self.runPreprocessor = Alos2Proc.createPreprocessor(self)
|
||||||
|
self.runBaseline = Alos2Proc.createBaseline(self)
|
||||||
self.runDownloadDem = Alos2Proc.createDownloadDem(self)
|
self.runDownloadDem = Alos2Proc.createDownloadDem(self)
|
||||||
self.runPrepareSlc = Alos2Proc.createPrepareSlc(self)
|
self.runPrepareSlc = Alos2Proc.createPrepareSlc(self)
|
||||||
self.runSlcOffset = Alos2Proc.createSlcOffset(self)
|
self.runSlcOffset = Alos2Proc.createSlcOffset(self)
|
||||||
|
|
@ -793,6 +844,7 @@ class Alos2InSAR(Application):
|
||||||
self.runIonSubband = Alos2Proc.createIonSubband(self)
|
self.runIonSubband = Alos2Proc.createIonSubband(self)
|
||||||
self.runIonUwrap = Alos2Proc.createIonUwrap(self)
|
self.runIonUwrap = Alos2Proc.createIonUwrap(self)
|
||||||
self.runIonFilt = Alos2Proc.createIonFilt(self)
|
self.runIonFilt = Alos2Proc.createIonFilt(self)
|
||||||
|
self.runIonCorrect = Alos2Proc.createIonCorrect(self)
|
||||||
self.runFilt = Alos2Proc.createFilt(self)
|
self.runFilt = Alos2Proc.createFilt(self)
|
||||||
self.runUnwrapSnaphu = Alos2Proc.createUnwrapSnaphu(self)
|
self.runUnwrapSnaphu = Alos2Proc.createUnwrapSnaphu(self)
|
||||||
self.runGeocode = Alos2Proc.createGeocode(self)
|
self.runGeocode = Alos2Proc.createGeocode(self)
|
||||||
|
|
@ -822,6 +874,13 @@ class Alos2InSAR(Application):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.step('baseline',
|
||||||
|
func=self.runBaseline,
|
||||||
|
doc=(
|
||||||
|
"""compute baseline, burst synchronization etc"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.step('download_dem',
|
self.step('download_dem',
|
||||||
func=self.runDownloadDem,
|
func=self.runDownloadDem,
|
||||||
doc=(
|
doc=(
|
||||||
|
|
@ -934,6 +993,12 @@ class Alos2InSAR(Application):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.step('ion_correct', func=self.runIonCorrect,
|
||||||
|
doc=(
|
||||||
|
"""resample ionospheric phase and ionospheric correction"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.step('filt', func=self.runFilt,
|
self.step('filt', func=self.runFilt,
|
||||||
doc=(
|
doc=(
|
||||||
"""filter interferogram"""
|
"""filter interferogram"""
|
||||||
|
|
@ -995,6 +1060,8 @@ class Alos2InSAR(Application):
|
||||||
# Run a preprocessor for the two sets of frames
|
# Run a preprocessor for the two sets of frames
|
||||||
self.runPreprocessor()
|
self.runPreprocessor()
|
||||||
|
|
||||||
|
self.runBaseline()
|
||||||
|
|
||||||
self.runDownloadDem()
|
self.runDownloadDem()
|
||||||
|
|
||||||
self.runPrepareSlc()
|
self.runPrepareSlc()
|
||||||
|
|
@ -1031,6 +1098,8 @@ class Alos2InSAR(Application):
|
||||||
|
|
||||||
self.runIonFilt()
|
self.runIonFilt()
|
||||||
|
|
||||||
|
self.runIonCorrect()
|
||||||
|
|
||||||
self.runFilt()
|
self.runFilt()
|
||||||
|
|
||||||
self.runUnwrapSnaphu()
|
self.runUnwrapSnaphu()
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,22 @@ SWATH_PHASE_DIFF_SNAP_ION = Application.Parameter('swathPhaseDiffSnapIon',
|
||||||
container = list,
|
container = list,
|
||||||
doc = 'swath phase difference snap to fixed values')
|
doc = 'swath phase difference snap to fixed values')
|
||||||
|
|
||||||
|
SWATH_PHASE_DIFF_LOWER_ION = Application.Parameter('swathPhaseDiffLowerIon',
|
||||||
|
public_name = 'swath phase difference of lower band',
|
||||||
|
default = None,
|
||||||
|
type = float,
|
||||||
|
mandatory = False,
|
||||||
|
container = list,
|
||||||
|
doc = 'swath phase difference of lower band')
|
||||||
|
|
||||||
|
SWATH_PHASE_DIFF_UPPER_ION = Application.Parameter('swathPhaseDiffUpperIon',
|
||||||
|
public_name = 'swath phase difference of upper band',
|
||||||
|
default = None,
|
||||||
|
type = float,
|
||||||
|
mandatory = False,
|
||||||
|
container = list,
|
||||||
|
doc = 'swath phase difference of upper band')
|
||||||
|
|
||||||
FIT_ION = Application.Parameter('fitIon',
|
FIT_ION = Application.Parameter('fitIon',
|
||||||
public_name = 'apply polynomial fit before filtering ionosphere phase',
|
public_name = 'apply polynomial fit before filtering ionosphere phase',
|
||||||
default = True,
|
default = True,
|
||||||
|
|
@ -342,6 +358,13 @@ FIT_ADAPTIVE_ION = Application.Parameter('fitAdaptiveIon',
|
||||||
mandatory = False,
|
mandatory = False,
|
||||||
doc = 'apply polynomial fit in adaptive filtering window')
|
doc = 'apply polynomial fit in adaptive filtering window')
|
||||||
|
|
||||||
|
FILT_SECONDARY_ION = Application.Parameter('filtSecondaryIon',
|
||||||
|
public_name = 'whether do secondary filtering of ionosphere phase',
|
||||||
|
default = True,
|
||||||
|
type = bool,
|
||||||
|
mandatory = False,
|
||||||
|
doc = 'whether do secondary filtering of ionosphere phase')
|
||||||
|
|
||||||
FILTERING_WINSIZE_MAX_ION = Application.Parameter('filteringWinsizeMaxIon',
|
FILTERING_WINSIZE_MAX_ION = Application.Parameter('filteringWinsizeMaxIon',
|
||||||
public_name='maximum window size for filtering ionosphere phase',
|
public_name='maximum window size for filtering ionosphere phase',
|
||||||
default=301,
|
default=301,
|
||||||
|
|
@ -356,6 +379,20 @@ FILTERING_WINSIZE_MIN_ION = Application.Parameter('filteringWinsizeMinIon',
|
||||||
mandatory=False,
|
mandatory=False,
|
||||||
doc='minimum window size for filtering ionosphere phase')
|
doc='minimum window size for filtering ionosphere phase')
|
||||||
|
|
||||||
|
FILTERING_WINSIZE_SECONDARY_ION = Application.Parameter('filteringWinsizeSecondaryIon',
|
||||||
|
public_name='window size of secondary filtering of ionosphere phase',
|
||||||
|
default=5,
|
||||||
|
type=int,
|
||||||
|
mandatory=False,
|
||||||
|
doc='window size of secondary filtering of ionosphere phase')
|
||||||
|
|
||||||
|
FILTER_STD_ION = Application.Parameter('filterStdIon',
|
||||||
|
public_name = 'standard deviation of ionosphere phase after filtering',
|
||||||
|
default = None,
|
||||||
|
type=float,
|
||||||
|
mandatory = False,
|
||||||
|
doc = 'standard deviation of ionosphere phase after filtering')
|
||||||
|
|
||||||
FILTER_SUBBAND_INT = Application.Parameter('filterSubbandInt',
|
FILTER_SUBBAND_INT = Application.Parameter('filterSubbandInt',
|
||||||
public_name = 'filter subband interferogram',
|
public_name = 'filter subband interferogram',
|
||||||
default = False,
|
default = False,
|
||||||
|
|
@ -566,11 +603,16 @@ class Alos2burstInSAR(Application):
|
||||||
NUMBER_AZIMUTH_LOOKS_ION,
|
NUMBER_AZIMUTH_LOOKS_ION,
|
||||||
MASKED_AREAS_ION,
|
MASKED_AREAS_ION,
|
||||||
SWATH_PHASE_DIFF_SNAP_ION,
|
SWATH_PHASE_DIFF_SNAP_ION,
|
||||||
|
SWATH_PHASE_DIFF_LOWER_ION,
|
||||||
|
SWATH_PHASE_DIFF_UPPER_ION,
|
||||||
FIT_ION,
|
FIT_ION,
|
||||||
FILT_ION,
|
FILT_ION,
|
||||||
FIT_ADAPTIVE_ION,
|
FIT_ADAPTIVE_ION,
|
||||||
|
FILT_SECONDARY_ION,
|
||||||
FILTERING_WINSIZE_MAX_ION,
|
FILTERING_WINSIZE_MAX_ION,
|
||||||
FILTERING_WINSIZE_MIN_ION,
|
FILTERING_WINSIZE_MIN_ION,
|
||||||
|
FILTERING_WINSIZE_SECONDARY_ION,
|
||||||
|
FILTER_STD_ION,
|
||||||
FILTER_SUBBAND_INT,
|
FILTER_SUBBAND_INT,
|
||||||
FILTER_STRENGTH_SUBBAND_INT,
|
FILTER_STRENGTH_SUBBAND_INT,
|
||||||
FILTER_WINSIZE_SUBBAND_INT,
|
FILTER_WINSIZE_SUBBAND_INT,
|
||||||
|
|
@ -704,6 +746,7 @@ class Alos2burstInSAR(Application):
|
||||||
## Add instance attribute RunWrapper functions, which emulate methods.
|
## Add instance attribute RunWrapper functions, which emulate methods.
|
||||||
def _add_methods(self):
|
def _add_methods(self):
|
||||||
self.runPreprocessor = Alos2burstProc.createPreprocessor(self)
|
self.runPreprocessor = Alos2burstProc.createPreprocessor(self)
|
||||||
|
self.runBaseline = Alos2burstProc.createBaseline(self)
|
||||||
self.runExtractBurst = Alos2burstProc.createExtractBurst(self)
|
self.runExtractBurst = Alos2burstProc.createExtractBurst(self)
|
||||||
self.runDownloadDem = Alos2burstProc.createDownloadDem(self)
|
self.runDownloadDem = Alos2burstProc.createDownloadDem(self)
|
||||||
self.runCoregGeom = Alos2burstProc.createCoregGeom(self)
|
self.runCoregGeom = Alos2burstProc.createCoregGeom(self)
|
||||||
|
|
@ -723,6 +766,7 @@ class Alos2burstInSAR(Application):
|
||||||
self.runIonSubband = Alos2burstProc.createIonSubband(self)
|
self.runIonSubband = Alos2burstProc.createIonSubband(self)
|
||||||
self.runIonUwrap = Alos2burstProc.createIonUwrap(self)
|
self.runIonUwrap = Alos2burstProc.createIonUwrap(self)
|
||||||
self.runIonFilt = Alos2burstProc.createIonFilt(self)
|
self.runIonFilt = Alos2burstProc.createIonFilt(self)
|
||||||
|
self.runIonCorrect = Alos2burstProc.createIonCorrect(self)
|
||||||
self.runFilt = Alos2burstProc.createFilt(self)
|
self.runFilt = Alos2burstProc.createFilt(self)
|
||||||
self.runUnwrapSnaphu = Alos2burstProc.createUnwrapSnaphu(self)
|
self.runUnwrapSnaphu = Alos2burstProc.createUnwrapSnaphu(self)
|
||||||
self.runGeocode = Alos2burstProc.createGeocode(self)
|
self.runGeocode = Alos2burstProc.createGeocode(self)
|
||||||
|
|
@ -749,6 +793,12 @@ class Alos2burstInSAR(Application):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.step('baseline', func=self.runBaseline,
|
||||||
|
doc=(
|
||||||
|
"""compute baseline, burst synchronization etc"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.step('extract_burst', func=self.runExtractBurst,
|
self.step('extract_burst', func=self.runExtractBurst,
|
||||||
doc=(
|
doc=(
|
||||||
"""extract bursts from full aperture images"""
|
"""extract bursts from full aperture images"""
|
||||||
|
|
@ -863,6 +913,12 @@ class Alos2burstInSAR(Application):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.step('ion_correct', func=self.runIonCorrect,
|
||||||
|
doc=(
|
||||||
|
"""resample ionospheric phase and ionospheric correction"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.step('filt', func=self.runFilt,
|
self.step('filt', func=self.runFilt,
|
||||||
doc=(
|
doc=(
|
||||||
"""filter interferogram"""
|
"""filter interferogram"""
|
||||||
|
|
@ -916,6 +972,8 @@ class Alos2burstInSAR(Application):
|
||||||
# Run a preprocessor for the two sets of frames
|
# Run a preprocessor for the two sets of frames
|
||||||
self.runPreprocessor()
|
self.runPreprocessor()
|
||||||
|
|
||||||
|
self.runBaseline()
|
||||||
|
|
||||||
self.runExtractBurst()
|
self.runExtractBurst()
|
||||||
|
|
||||||
self.runDownloadDem()
|
self.runDownloadDem()
|
||||||
|
|
@ -954,6 +1012,8 @@ class Alos2burstInSAR(Application):
|
||||||
|
|
||||||
self.runIonFilt()
|
self.runIonFilt()
|
||||||
|
|
||||||
|
self.runIonCorrect()
|
||||||
|
|
||||||
self.runFilt()
|
self.runFilt()
|
||||||
|
|
||||||
self.runUnwrapSnaphu()
|
self.runUnwrapSnaphu()
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ def create_xml(fileName, width, length, fileType):
|
||||||
#image.finalizeImage()
|
#image.finalizeImage()
|
||||||
|
|
||||||
|
|
||||||
def multilook_v1(data, nalks, nrlks):
|
def multilook_v1(data, nalks, nrlks, mean=True):
|
||||||
'''
|
'''
|
||||||
doing multiple looking
|
doing multiple looking
|
||||||
ATTENSION: original array changed after running this function
|
ATTENSION: original array changed after running this function
|
||||||
|
|
@ -106,10 +106,13 @@ def multilook_v1(data, nalks, nrlks):
|
||||||
for i in range(1, nrlks):
|
for i in range(1, nrlks):
|
||||||
data[0:length2*nalks:nalks, 0:width2*nrlks:nrlks] += data[0:length2*nalks:nalks, i:width2*nrlks:nrlks]
|
data[0:length2*nalks:nalks, 0:width2*nrlks:nrlks] += data[0:length2*nalks:nalks, i:width2*nrlks:nrlks]
|
||||||
|
|
||||||
return data[0:length2*nalks:nalks, 0:width2*nrlks:nrlks] / nrlks / nalks
|
if mean:
|
||||||
|
return data[0:length2*nalks:nalks, 0:width2*nrlks:nrlks] / nrlks / nalks
|
||||||
|
else:
|
||||||
|
return data[0:length2*nalks:nalks, 0:width2*nrlks:nrlks]
|
||||||
|
|
||||||
|
|
||||||
def multilook(data, nalks, nrlks):
|
def multilook(data, nalks, nrlks, mean=True):
|
||||||
'''
|
'''
|
||||||
doing multiple looking
|
doing multiple looking
|
||||||
'''
|
'''
|
||||||
|
|
@ -125,7 +128,10 @@ def multilook(data, nalks, nrlks):
|
||||||
for i in range(1, nrlks):
|
for i in range(1, nrlks):
|
||||||
data2[:, 0:width2*nrlks:nrlks] += data2[:, i:width2*nrlks:nrlks]
|
data2[:, 0:width2*nrlks:nrlks] += data2[:, i:width2*nrlks:nrlks]
|
||||||
|
|
||||||
return data2[:, 0:width2*nrlks:nrlks] / nrlks / nalks
|
if mean:
|
||||||
|
return data2[:, 0:width2*nrlks:nrlks] / nrlks / nalks
|
||||||
|
else:
|
||||||
|
return data2[:, 0:width2*nrlks:nrlks]
|
||||||
|
|
||||||
|
|
||||||
def cal_coherence_1(inf, win=5):
|
def cal_coherence_1(inf, win=5):
|
||||||
|
|
@ -281,9 +287,9 @@ def reformatGeometricalOffset(rangeOffsetFile, azimuthOffsetFile, reformatedOffs
|
||||||
|
|
||||||
offsetsPlain = offsetsPlain + "{:8d} {:10.3f} {:8d} {:12.3f} {:11.5f} {:11.6f} {:11.6f} {:11.6f}\n".format(
|
offsetsPlain = offsetsPlain + "{:8d} {:10.3f} {:8d} {:12.3f} {:11.5f} {:11.6f} {:11.6f} {:11.6f}\n".format(
|
||||||
int(j*rangeStep+1),
|
int(j*rangeStep+1),
|
||||||
float(rgoff[i][j]),
|
float(rgoff[i][j])*rangeStep,
|
||||||
int(i*azimuthStep+1),
|
int(i*azimuthStep+1),
|
||||||
float(azoff[i][j]),
|
float(azoff[i][j])*azimuthStep,
|
||||||
float(22.00015),
|
float(22.00015),
|
||||||
float(0.000273),
|
float(0.000273),
|
||||||
float(0.002126),
|
float(0.002126),
|
||||||
|
|
@ -749,7 +755,7 @@ def snaphuUnwrap(track, t, wrapName, corName, unwrapName, nrlks, nalks, costMode
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def snaphuUnwrapOriginal(wrapName, corName, ampName, unwrapName, costMode = 's', initMethod = 'mcf'):
|
def snaphuUnwrapOriginal(wrapName, corName, ampName, unwrapName, costMode = 's', initMethod = 'mcf', snaphuConfFile = 'snaphu.conf'):
|
||||||
'''
|
'''
|
||||||
unwrap interferogram using original snaphu program
|
unwrap interferogram using original snaphu program
|
||||||
'''
|
'''
|
||||||
|
|
@ -762,7 +768,7 @@ def snaphuUnwrapOriginal(wrapName, corName, ampName, unwrapName, costMode = 's',
|
||||||
length = corImg.length
|
length = corImg.length
|
||||||
|
|
||||||
#specify coherence file format in configure file
|
#specify coherence file format in configure file
|
||||||
snaphuConfFile = 'snaphu.conf'
|
#snaphuConfFile = 'snaphu.conf'
|
||||||
if corImg.bands == 1:
|
if corImg.bands == 1:
|
||||||
snaphuConf = '''CORRFILEFORMAT FLOAT_DATA
|
snaphuConf = '''CORRFILEFORMAT FLOAT_DATA
|
||||||
CONNCOMPFILE {}
|
CONNCOMPFILE {}
|
||||||
|
|
@ -809,7 +815,7 @@ MAXNCOMPS 20'''.format(unwrapName+'.conncomp')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def getBboxGeo(track):
|
def getBboxGeo(track, useTrackOnly=False, numberOfSamples=1, numberOfLines=1, numberRangeLooks=1, numberAzimuthLooks=1):
|
||||||
'''
|
'''
|
||||||
get bounding box in geo-coordinate
|
get bounding box in geo-coordinate
|
||||||
'''
|
'''
|
||||||
|
|
@ -817,7 +823,15 @@ def getBboxGeo(track):
|
||||||
|
|
||||||
pointingDirection = {'right': -1, 'left' :1}
|
pointingDirection = {'right': -1, 'left' :1}
|
||||||
|
|
||||||
bboxRdr = getBboxRdr(track)
|
if useTrackOnly:
|
||||||
|
import datetime
|
||||||
|
rangeMin = track.startingRange + (numberRangeLooks-1.0)/2.0*track.rangePixelSize
|
||||||
|
rangeMax = rangeMin + (numberOfSamples-1) * numberRangeLooks * track.rangePixelSize
|
||||||
|
azimuthTimeMin = track.sensingStart + datetime.timedelta(seconds=(numberAzimuthLooks-1.0)/2.0*track.azimuthLineInterval)
|
||||||
|
azimuthTimeMax = azimuthTimeMin + datetime.timedelta(seconds=(numberOfLines-1) * numberAzimuthLooks * track.azimuthLineInterval)
|
||||||
|
bboxRdr = [rangeMin, rangeMax, azimuthTimeMin, azimuthTimeMax]
|
||||||
|
else:
|
||||||
|
bboxRdr = getBboxRdr(track)
|
||||||
|
|
||||||
rangeMin = bboxRdr[0]
|
rangeMin = bboxRdr[0]
|
||||||
rangeMax = bboxRdr[1]
|
rangeMax = bboxRdr[1]
|
||||||
|
|
@ -1254,8 +1268,199 @@ def snap(inputValue, fixedValues, snapThreshold):
|
||||||
return (outputValue, snapped)
|
return (outputValue, snapped)
|
||||||
|
|
||||||
|
|
||||||
|
modeProcParDict = {
|
||||||
|
'ALOS-2': {
|
||||||
|
#All SPT (SBS) modes are the same
|
||||||
|
'SBS': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 4,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 4,
|
||||||
|
'numberAzimuthLooks2': 4,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 16,
|
||||||
|
'numberAzimuthLooksIon': 16,
|
||||||
|
|
||||||
|
'filterStdIon': 0.015
|
||||||
|
},
|
||||||
|
#All SM1 (UBS, UBD) modes are the same
|
||||||
|
'UBS': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 3,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 4,
|
||||||
|
'numberAzimuthLooks2': 4,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 32,
|
||||||
|
'numberAzimuthLooksIon': 32,
|
||||||
|
|
||||||
|
'filterStdIon': 0.015
|
||||||
|
},
|
||||||
|
'UBD': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 3,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 4,
|
||||||
|
'numberAzimuthLooks2': 4,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 32,
|
||||||
|
'numberAzimuthLooksIon': 32,
|
||||||
|
|
||||||
|
'filterStdIon': 0.015
|
||||||
|
},
|
||||||
|
#All SM2 (HBS, HBD, HBQ) modes are the same
|
||||||
|
'HBS': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 4,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 4,
|
||||||
|
'numberAzimuthLooks2': 4,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 16,
|
||||||
|
'numberAzimuthLooksIon': 16,
|
||||||
|
|
||||||
|
'filterStdIon': 0.035
|
||||||
|
},
|
||||||
|
'HBD': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 4,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 4,
|
||||||
|
'numberAzimuthLooks2': 4,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 16,
|
||||||
|
'numberAzimuthLooksIon': 16,
|
||||||
|
|
||||||
|
'filterStdIon': 0.035
|
||||||
|
},
|
||||||
|
'HBQ': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 4,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 4,
|
||||||
|
'numberAzimuthLooks2': 4,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 16,
|
||||||
|
'numberAzimuthLooksIon': 16,
|
||||||
|
|
||||||
|
'filterStdIon': 0.035
|
||||||
|
},
|
||||||
|
#All SM3 (FBS, FBD, FBQ) modes are the same
|
||||||
|
'FBS': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 4,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 4,
|
||||||
|
'numberAzimuthLooks2': 4,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 16,
|
||||||
|
'numberAzimuthLooksIon': 16,
|
||||||
|
|
||||||
|
'filterStdIon': 0.075
|
||||||
|
},
|
||||||
|
'FBD': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 4,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 4,
|
||||||
|
'numberAzimuthLooks2': 4,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 16,
|
||||||
|
'numberAzimuthLooksIon': 16,
|
||||||
|
|
||||||
|
'filterStdIon': 0.075
|
||||||
|
},
|
||||||
|
'FBQ': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 4,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 4,
|
||||||
|
'numberAzimuthLooks2': 4,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 16,
|
||||||
|
'numberAzimuthLooksIon': 16,
|
||||||
|
|
||||||
|
'filterStdIon': 0.075
|
||||||
|
},
|
||||||
|
#All WD1 (WBS, WBD) modes are the same
|
||||||
|
'WBS': {
|
||||||
|
'numberRangeLooks1': 1,
|
||||||
|
'numberAzimuthLooks1': 14,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 5,
|
||||||
|
'numberAzimuthLooks2': 2,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 80,
|
||||||
|
'numberAzimuthLooksIon': 32,
|
||||||
|
|
||||||
|
'filterStdIon': 0.1
|
||||||
|
},
|
||||||
|
'WBD': {
|
||||||
|
'numberRangeLooks1': 1,
|
||||||
|
'numberAzimuthLooks1': 14,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 5,
|
||||||
|
'numberAzimuthLooks2': 2,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 80,
|
||||||
|
'numberAzimuthLooksIon': 32,
|
||||||
|
|
||||||
|
'filterStdIon': 0.1
|
||||||
|
},
|
||||||
|
#All WD1 (WWS, WWD) modes are the same
|
||||||
|
'WWS': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 14,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 5,
|
||||||
|
'numberAzimuthLooks2': 2,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 80,
|
||||||
|
'numberAzimuthLooksIon': 32,
|
||||||
|
|
||||||
|
'filterStdIon': 0.075
|
||||||
|
},
|
||||||
|
'WWD': {
|
||||||
|
'numberRangeLooks1': 2,
|
||||||
|
'numberAzimuthLooks1': 14,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 5,
|
||||||
|
'numberAzimuthLooks2': 2,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 80,
|
||||||
|
'numberAzimuthLooksIon': 32,
|
||||||
|
|
||||||
|
'filterStdIon': 0.075
|
||||||
|
},
|
||||||
|
#All WD2 (VBS, VBD) modes are the same
|
||||||
|
'VBS': {
|
||||||
|
'numberRangeLooks1': 1,
|
||||||
|
'numberAzimuthLooks1': 14,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 5,
|
||||||
|
'numberAzimuthLooks2': 2,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 80,
|
||||||
|
'numberAzimuthLooksIon': 32,
|
||||||
|
|
||||||
|
'filterStdIon': 0.1
|
||||||
|
},
|
||||||
|
'VBD': {
|
||||||
|
'numberRangeLooks1': 1,
|
||||||
|
'numberAzimuthLooks1': 14,
|
||||||
|
|
||||||
|
'numberRangeLooks2': 5,
|
||||||
|
'numberAzimuthLooks2': 2,
|
||||||
|
|
||||||
|
'numberRangeLooksIon': 80,
|
||||||
|
'numberAzimuthLooksIon': 32,
|
||||||
|
|
||||||
|
'filterStdIon': 0.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
import numpy as np
|
||||||
|
filterStdPolyIon = np.array([ 2.31536879e-05, -3.41687763e-03, 1.39904121e-01])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ InstallSameDir(
|
||||||
Alos2ProcPublic.py
|
Alos2ProcPublic.py
|
||||||
Factories.py
|
Factories.py
|
||||||
denseOffsetNote.txt
|
denseOffsetNote.txt
|
||||||
|
runBaseline.py
|
||||||
runCoherence.py
|
runCoherence.py
|
||||||
runDenseOffset.py
|
runDenseOffset.py
|
||||||
runDiffInterferogram.py
|
runDiffInterferogram.py
|
||||||
|
|
@ -16,6 +17,7 @@ InstallSameDir(
|
||||||
runGeo2Rdr.py
|
runGeo2Rdr.py
|
||||||
runGeocode.py
|
runGeocode.py
|
||||||
runGeocodeOffset.py
|
runGeocodeOffset.py
|
||||||
|
runIonCorrect.py
|
||||||
runIonFilt.py
|
runIonFilt.py
|
||||||
runIonSubband.py
|
runIonSubband.py
|
||||||
runIonUwrap.py
|
runIonUwrap.py
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ def createUnwrap2Stage(other, do_unwrap_2stage = None, unwrapperName = None):
|
||||||
|
|
||||||
|
|
||||||
createPreprocessor = _factory("runPreprocessor")
|
createPreprocessor = _factory("runPreprocessor")
|
||||||
|
createBaseline = _factory("runBaseline")
|
||||||
createDownloadDem = _factory("runDownloadDem")
|
createDownloadDem = _factory("runDownloadDem")
|
||||||
createPrepareSlc = _factory("runPrepareSlc")
|
createPrepareSlc = _factory("runPrepareSlc")
|
||||||
createSlcOffset = _factory("runSlcOffset")
|
createSlcOffset = _factory("runSlcOffset")
|
||||||
|
|
@ -92,6 +93,7 @@ createCoherence = _factory("runCoherence")
|
||||||
createIonSubband = _factory("runIonSubband")
|
createIonSubband = _factory("runIonSubband")
|
||||||
createIonUwrap = _factory("runIonUwrap")
|
createIonUwrap = _factory("runIonUwrap")
|
||||||
createIonFilt = _factory("runIonFilt")
|
createIonFilt = _factory("runIonFilt")
|
||||||
|
createIonCorrect = _factory("runIonCorrect")
|
||||||
createFilt = _factory("runFilt")
|
createFilt = _factory("runFilt")
|
||||||
createUnwrapSnaphu = _factory("runUnwrapSnaphu")
|
createUnwrapSnaphu = _factory("runUnwrapSnaphu")
|
||||||
createGeocode = _factory("runGeocode")
|
createGeocode = _factory("runGeocode")
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,6 @@ project = 'Alos2Proc'
|
||||||
|
|
||||||
install = os.path.join(envisceobj['PRJ_SCONS_INSTALL'],package,project)
|
install = os.path.join(envisceobj['PRJ_SCONS_INSTALL'],package,project)
|
||||||
|
|
||||||
listFiles = ['__init__.py', 'Factories.py', 'Alos2Proc.py', 'Alos2ProcPublic.py', 'runPreprocessor.py', 'runDownloadDem.py', 'runPrepareSlc.py', 'runSlcOffset.py', 'runFormInterferogram.py', 'runSwathOffset.py', 'runSwathMosaic.py', 'runFrameOffset.py', 'runFrameMosaic.py', 'runRdr2Geo.py', 'runGeo2Rdr.py', 'runRdrDemOffset.py', 'runRectRangeOffset.py', 'runDiffInterferogram.py', 'runLook.py', 'runCoherence.py', 'runIonSubband.py', 'runIonUwrap.py', 'runIonFilt.py', 'runFilt.py', 'runUnwrapSnaphu.py', 'runGeocode.py', 'srtm_no_swbd_tiles.txt', 'srtm_tiles.txt', 'swbd_tiles.txt', 'runSlcMosaic.py', 'runSlcMatch.py', 'runDenseOffset.py', 'runFiltOffset.py', 'runGeocodeOffset.py', 'denseOffsetNote.txt']
|
listFiles = ['__init__.py', 'Factories.py', 'Alos2Proc.py', 'Alos2ProcPublic.py', 'runPreprocessor.py', 'runBaseline.py', 'runDownloadDem.py', 'runPrepareSlc.py', 'runSlcOffset.py', 'runFormInterferogram.py', 'runSwathOffset.py', 'runSwathMosaic.py', 'runFrameOffset.py', 'runFrameMosaic.py', 'runRdr2Geo.py', 'runGeo2Rdr.py', 'runRdrDemOffset.py', 'runRectRangeOffset.py', 'runDiffInterferogram.py', 'runLook.py', 'runCoherence.py', 'runIonSubband.py', 'runIonUwrap.py', 'runIonFilt.py', 'runIonCorrect.py', 'runFilt.py', 'runUnwrapSnaphu.py', 'runGeocode.py', 'srtm_no_swbd_tiles.txt', 'srtm_tiles.txt', 'swbd_tiles.txt', 'runSlcMosaic.py', 'runSlcMatch.py', 'runDenseOffset.py', 'runFiltOffset.py', 'runGeocodeOffset.py', 'denseOffsetNote.txt']
|
||||||
envisceobj.Install(install,listFiles)
|
envisceobj.Install(install,listFiles)
|
||||||
envisceobj.Alias('install',install)
|
envisceobj.Alias('install',install)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,229 @@
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import logging
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isceobj
|
||||||
|
import isceobj.Sensor.MultiMode as MultiMode
|
||||||
|
from isceobj.Planet.Planet import Planet
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import getBboxRdr
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo
|
||||||
|
|
||||||
|
logger = logging.getLogger('isce.alos2insar.runBaseline')
|
||||||
|
|
||||||
|
def runBaseline(self):
|
||||||
|
'''compute baseline
|
||||||
|
'''
|
||||||
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
referenceTrack = self._insar.loadTrack(reference=True)
|
||||||
|
secondaryTrack = self._insar.loadTrack(reference=False)
|
||||||
|
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
#2. compute burst synchronization
|
||||||
|
##################################################
|
||||||
|
#burst synchronization may slowly change along a track as a result of the changing relative speed of the two flights
|
||||||
|
#in one frame, real unsynchronized time is the same for all swaths
|
||||||
|
unsynTime = 0
|
||||||
|
#real synchronized time/percentage depends on the swath burst length (synTime = burstlength - abs(unsynTime))
|
||||||
|
#synTime = 0
|
||||||
|
synPercentage = 0
|
||||||
|
|
||||||
|
numberOfFrames = len(self._insar.referenceFrames)
|
||||||
|
numberOfSwaths = self._insar.endingSwath - self._insar.startingSwath + 1
|
||||||
|
|
||||||
|
for i, frameNumber in enumerate(self._insar.referenceFrames):
|
||||||
|
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
||||||
|
referenceSwath = referenceTrack.frames[i].swaths[j]
|
||||||
|
secondarySwath = secondaryTrack.frames[i].swaths[j]
|
||||||
|
#using Piyush's code for computing range and azimuth offsets
|
||||||
|
midRange = referenceSwath.startingRange + referenceSwath.rangePixelSize * referenceSwath.numberOfSamples * 0.5
|
||||||
|
midSensingStart = referenceSwath.sensingStart + datetime.timedelta(seconds = referenceSwath.numberOfLines * 0.5 / referenceSwath.prf)
|
||||||
|
llh = referenceTrack.orbit.rdr2geo(midSensingStart, midRange)
|
||||||
|
slvaz, slvrng = secondaryTrack.orbit.geo2rdr(llh)
|
||||||
|
###Translate to offsets
|
||||||
|
#note that secondary range pixel size and prf might be different from reference, here we assume there is a virtual secondary with same
|
||||||
|
#range pixel size and prf
|
||||||
|
rgoff = ((slvrng - secondarySwath.startingRange) / referenceSwath.rangePixelSize) - referenceSwath.numberOfSamples * 0.5
|
||||||
|
azoff = ((slvaz - secondarySwath.sensingStart).total_seconds() * referenceSwath.prf) - referenceSwath.numberOfLines * 0.5
|
||||||
|
|
||||||
|
#compute burst synchronization
|
||||||
|
#burst parameters for ScanSAR wide mode not estimed yet
|
||||||
|
if self._insar.modeCombination == 21:
|
||||||
|
scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
|
||||||
|
#secondary burst start times corresponding to reference burst start times (100% synchronization)
|
||||||
|
scburstStartLines = np.arange(scburstStartLine - 100000*referenceSwath.burstCycleLength, \
|
||||||
|
scburstStartLine + 100000*referenceSwath.burstCycleLength, \
|
||||||
|
referenceSwath.burstCycleLength)
|
||||||
|
dscburstStartLines = -((secondarySwath.burstStartTime - secondarySwath.sensingStart).total_seconds() * secondarySwath.prf - scburstStartLines)
|
||||||
|
#find the difference with minimum absolute value
|
||||||
|
unsynLines = dscburstStartLines[np.argmin(np.absolute(dscburstStartLines))]
|
||||||
|
if np.absolute(unsynLines) >= secondarySwath.burstLength:
|
||||||
|
synLines = 0
|
||||||
|
if unsynLines > 0:
|
||||||
|
unsynLines = secondarySwath.burstLength
|
||||||
|
else:
|
||||||
|
unsynLines = -secondarySwath.burstLength
|
||||||
|
else:
|
||||||
|
synLines = secondarySwath.burstLength - np.absolute(unsynLines)
|
||||||
|
|
||||||
|
unsynTime += unsynLines / referenceSwath.prf
|
||||||
|
synPercentage += synLines / referenceSwath.burstLength * 100.0
|
||||||
|
|
||||||
|
catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(synLines / referenceSwath.burstLength * 100.0), 'runBaseline')
|
||||||
|
|
||||||
|
############################################################################################
|
||||||
|
#illustration of the sign of the number of unsynchronized lines (unsynLines)
|
||||||
|
#The convention is the same as ampcor offset, that is,
|
||||||
|
# secondaryLineNumber = referenceLineNumber + unsynLines
|
||||||
|
#
|
||||||
|
# |-----------------------| ------------
|
||||||
|
# | | ^
|
||||||
|
# | | |
|
||||||
|
# | | | unsynLines < 0
|
||||||
|
# | | |
|
||||||
|
# | | \ /
|
||||||
|
# | | |-----------------------|
|
||||||
|
# | | | |
|
||||||
|
# | | | |
|
||||||
|
# |-----------------------| | |
|
||||||
|
# Reference Burst | |
|
||||||
|
# | |
|
||||||
|
# | |
|
||||||
|
# | |
|
||||||
|
# | |
|
||||||
|
# |-----------------------|
|
||||||
|
# Secondary Burst
|
||||||
|
#
|
||||||
|
#
|
||||||
|
############################################################################################
|
||||||
|
|
||||||
|
##burst parameters for ScanSAR wide mode not estimed yet
|
||||||
|
elif self._insar.modeCombination == 31:
|
||||||
|
#scansar is reference
|
||||||
|
scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
|
||||||
|
#secondary burst start times corresponding to reference burst start times (100% synchronization)
|
||||||
|
for k in range(-100000, 100000):
|
||||||
|
saz_burstx = scburstStartLine + referenceSwath.burstCycleLength * k
|
||||||
|
st_burstx = secondarySwath.sensingStart + datetime.timedelta(seconds=saz_burstx / referenceSwath.prf)
|
||||||
|
if saz_burstx >= 0.0 and saz_burstx <= secondarySwath.numberOfLines -1:
|
||||||
|
secondarySwath.burstStartTime = st_burstx
|
||||||
|
secondarySwath.burstLength = referenceSwath.burstLength
|
||||||
|
secondarySwath.burstCycleLength = referenceSwath.burstCycleLength
|
||||||
|
secondarySwath.swathNumber = referenceSwath.swathNumber
|
||||||
|
break
|
||||||
|
#unsynLines = 0
|
||||||
|
#synLines = referenceSwath.burstLength
|
||||||
|
#unsynTime += unsynLines / referenceSwath.prf
|
||||||
|
#synPercentage += synLines / referenceSwath.burstLength * 100.0
|
||||||
|
catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(100.0), 'runBaseline')
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
#overwrite original frame parameter file
|
||||||
|
if self._insar.modeCombination == 31:
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
self._insar.saveProduct(secondaryTrack.frames[i], os.path.join(frameDir, self._insar.secondaryFrameParameter))
|
||||||
|
|
||||||
|
#getting average
|
||||||
|
if self._insar.modeCombination == 21:
|
||||||
|
unsynTime /= numberOfFrames*numberOfSwaths
|
||||||
|
synPercentage /= numberOfFrames*numberOfSwaths
|
||||||
|
elif self._insar.modeCombination == 31:
|
||||||
|
unsynTime = 0.
|
||||||
|
synPercentage = 100.
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
#record results
|
||||||
|
if (self._insar.modeCombination == 21) or (self._insar.modeCombination == 31):
|
||||||
|
self._insar.burstUnsynchronizedTime = unsynTime
|
||||||
|
self._insar.burstSynchronization = synPercentage
|
||||||
|
catalog.addItem('burst synchronization averaged', '%.1f%%'%(synPercentage), 'runBaseline')
|
||||||
|
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
#3. compute baseline
|
||||||
|
##################################################
|
||||||
|
#only compute baseline at four corners and center of the reference track
|
||||||
|
bboxRdr = getBboxRdr(referenceTrack)
|
||||||
|
|
||||||
|
rangeMin = bboxRdr[0]
|
||||||
|
rangeMax = bboxRdr[1]
|
||||||
|
azimuthTimeMin = bboxRdr[2]
|
||||||
|
azimuthTimeMax = bboxRdr[3]
|
||||||
|
|
||||||
|
azimuthTimeMid = azimuthTimeMin+datetime.timedelta(seconds=(azimuthTimeMax-azimuthTimeMin).total_seconds()/2.0)
|
||||||
|
rangeMid = (rangeMin + rangeMax) / 2.0
|
||||||
|
|
||||||
|
points = [[azimuthTimeMin, rangeMin],
|
||||||
|
[azimuthTimeMin, rangeMax],
|
||||||
|
[azimuthTimeMax, rangeMin],
|
||||||
|
[azimuthTimeMax, rangeMax],
|
||||||
|
[azimuthTimeMid, rangeMid]]
|
||||||
|
|
||||||
|
Bpar = []
|
||||||
|
Bperp = []
|
||||||
|
#modify Piyush's code for computing baslines
|
||||||
|
refElp = Planet(pname='Earth').ellipsoid
|
||||||
|
for x in points:
|
||||||
|
referenceSV = referenceTrack.orbit.interpolate(x[0], method='hermite')
|
||||||
|
target = referenceTrack.orbit.rdr2geo(x[0], x[1])
|
||||||
|
|
||||||
|
slvTime, slvrng = secondaryTrack.orbit.geo2rdr(target)
|
||||||
|
secondarySV = secondaryTrack.orbit.interpolateOrbit(slvTime, method='hermite')
|
||||||
|
|
||||||
|
targxyz = np.array(refElp.LLH(target[0], target[1], target[2]).ecef().tolist())
|
||||||
|
mxyz = np.array(referenceSV.getPosition())
|
||||||
|
mvel = np.array(referenceSV.getVelocity())
|
||||||
|
sxyz = np.array(secondarySV.getPosition())
|
||||||
|
|
||||||
|
#to fix abrupt change near zero in baseline grid. JUN-05-2020
|
||||||
|
mvelunit = mvel / np.linalg.norm(mvel)
|
||||||
|
sxyz = sxyz - np.dot ( sxyz-mxyz, mvelunit) * mvelunit
|
||||||
|
|
||||||
|
aa = np.linalg.norm(sxyz-mxyz)
|
||||||
|
costheta = (x[1]*x[1] + aa*aa - slvrng*slvrng)/(2.*x[1]*aa)
|
||||||
|
|
||||||
|
Bpar.append(aa*costheta)
|
||||||
|
|
||||||
|
perp = aa * np.sqrt(1 - costheta*costheta)
|
||||||
|
direction = np.sign(np.dot( np.cross(targxyz-mxyz, sxyz-mxyz), mvel))
|
||||||
|
Bperp.append(direction*perp)
|
||||||
|
|
||||||
|
catalog.addItem('parallel baseline at upperleft of reference track', Bpar[0], 'runBaseline')
|
||||||
|
catalog.addItem('parallel baseline at upperright of reference track', Bpar[1], 'runBaseline')
|
||||||
|
catalog.addItem('parallel baseline at lowerleft of reference track', Bpar[2], 'runBaseline')
|
||||||
|
catalog.addItem('parallel baseline at lowerright of reference track', Bpar[3], 'runBaseline')
|
||||||
|
catalog.addItem('parallel baseline at center of reference track', Bpar[4], 'runBaseline')
|
||||||
|
|
||||||
|
catalog.addItem('perpendicular baseline at upperleft of reference track', Bperp[0], 'runBaseline')
|
||||||
|
catalog.addItem('perpendicular baseline at upperright of reference track', Bperp[1], 'runBaseline')
|
||||||
|
catalog.addItem('perpendicular baseline at lowerleft of reference track', Bperp[2], 'runBaseline')
|
||||||
|
catalog.addItem('perpendicular baseline at lowerright of reference track', Bperp[3], 'runBaseline')
|
||||||
|
catalog.addItem('perpendicular baseline at center of reference track', Bperp[4], 'runBaseline')
|
||||||
|
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
#4. compute bounding box
|
||||||
|
##################################################
|
||||||
|
referenceBbox = getBboxGeo(referenceTrack)
|
||||||
|
secondaryBbox = getBboxGeo(secondaryTrack)
|
||||||
|
|
||||||
|
catalog.addItem('reference bounding box', referenceBbox, 'runBaseline')
|
||||||
|
catalog.addItem('secondary bounding box', secondaryBbox, 'runBaseline')
|
||||||
|
|
||||||
|
|
||||||
|
catalog.printToLog(logger, "runBaseline")
|
||||||
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -13,8 +13,12 @@ from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
logger = logging.getLogger('isce.alos2insar.runCoherence')
|
logger = logging.getLogger('isce.alos2insar.runCoherence')
|
||||||
|
|
||||||
def runCoherence(self):
|
def runCoherence(self):
|
||||||
'''Extract images.
|
'''estimate coherence
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,10 @@ logger = logging.getLogger('isce.alos2insar.runDiffInterferogram')
|
||||||
def runDiffInterferogram(self):
|
def runDiffInterferogram(self):
|
||||||
'''Extract images.
|
'''Extract images.
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,24 @@ logger = logging.getLogger('isce.alos2insar.runFilt')
|
||||||
def runFilt(self):
|
def runFilt(self):
|
||||||
'''filter interferogram
|
'''filter interferogram
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
#referenceTrack = self._insar.loadTrack(reference=True)
|
#referenceTrack = self._insar.loadTrack(reference=True)
|
||||||
#secondaryTrack = self._insar.loadTrack(reference=False)
|
#secondaryTrack = self._insar.loadTrack(reference=False)
|
||||||
|
|
||||||
|
filt(self)
|
||||||
|
|
||||||
|
catalog.printToLog(logger, "runFilt")
|
||||||
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
||||||
|
|
||||||
|
def filt(self):
|
||||||
|
|
||||||
insarDir = 'insar'
|
insarDir = 'insar'
|
||||||
os.makedirs(insarDir, exist_ok=True)
|
os.makedirs(insarDir, exist_ok=True)
|
||||||
os.chdir(insarDir)
|
os.chdir(insarDir)
|
||||||
|
|
@ -150,21 +162,17 @@ def runFilt(self):
|
||||||
print('\nmask filtered interferogram using: {}'.format(self._insar.multilookWbdOut))
|
print('\nmask filtered interferogram using: {}'.format(self._insar.multilookWbdOut))
|
||||||
|
|
||||||
if self.waterBodyMaskStartingStep=='filt':
|
if self.waterBodyMaskStartingStep=='filt':
|
||||||
if not os.path.exists(self._insar.multilookWbdOut):
|
#if not os.path.exists(self._insar.multilookWbdOut):
|
||||||
catalog.addItem('warning message', 'requested masking interferogram with water body, but water body does not exist', 'runFilt')
|
# catalog.addItem('warning message', 'requested masking interferogram with water body, but water body does not exist', 'runFilt')
|
||||||
else:
|
#else:
|
||||||
wbd = np.fromfile(self._insar.multilookWbdOut, dtype=np.int8).reshape(length, width)
|
wbd = np.fromfile(self._insar.multilookWbdOut, dtype=np.int8).reshape(length, width)
|
||||||
phsig=np.memmap(self._insar.multilookPhsig, dtype='float32', mode='r+', shape=(length, width))
|
phsig=np.memmap(self._insar.multilookPhsig, dtype='float32', mode='r+', shape=(length, width))
|
||||||
phsig[np.nonzero(wbd==-1)]=0
|
phsig[np.nonzero(wbd==-1)]=0
|
||||||
del phsig
|
del phsig
|
||||||
filt=np.memmap(self._insar.filteredInterferogram, dtype='complex64', mode='r+', shape=(length, width))
|
filt=np.memmap(self._insar.filteredInterferogram, dtype='complex64', mode='r+', shape=(length, width))
|
||||||
filt[np.nonzero(wbd==-1)]=0
|
filt[np.nonzero(wbd==-1)]=0
|
||||||
del filt
|
del filt
|
||||||
del wbd
|
del wbd
|
||||||
|
|
||||||
|
|
||||||
os.chdir('../')
|
os.chdir('../')
|
||||||
|
|
||||||
catalog.printToLog(logger, "runFilt")
|
|
||||||
self._insar.procDoc.addAllFromCatalog(catalog)
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ logger = logging.getLogger('isce.alos2insar.runFormInterferogram')
|
||||||
def runFormInterferogram(self):
|
def runFormInterferogram(self):
|
||||||
'''form interferograms.
|
'''form interferograms.
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@ logger = logging.getLogger('isce.alos2insar.runFrameMosaic')
|
||||||
def runFrameMosaic(self):
|
def runFrameMosaic(self):
|
||||||
'''mosaic frames
|
'''mosaic frames
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
@ -193,90 +197,107 @@ def frameMosaic(track, inputFiles, outputfile, rangeOffsets, azimuthOffsets, num
|
||||||
if i == 0:
|
if i == 0:
|
||||||
rinfs[i] = inf
|
rinfs[i] = inf
|
||||||
else:
|
else:
|
||||||
infImg = isceobj.createImage()
|
#no need to resample
|
||||||
infImg.load(inf+'.xml')
|
if (abs(rangeOffsets2[i] - round(rangeOffsets2[i])) < 0.0001) and (abs(azimuthOffsets2[i] - round(azimuthOffsets2[i])) < 0.0001):
|
||||||
rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
|
if os.path.isfile(rinfs[i]):
|
||||||
azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i])
|
os.remove(rinfs[i])
|
||||||
|
os.symlink(inf, rinfs[i])
|
||||||
|
#all of the following use of rangeOffsets2/azimuthOffsets2 is inside int(), we do the following in case it is like
|
||||||
|
#4.99999999999...
|
||||||
|
rangeOffsets2[i] = round(rangeOffsets2[i])
|
||||||
|
azimuthOffsets2[i] = round(azimuthOffsets2[i])
|
||||||
|
|
||||||
if resamplingMethod == 0:
|
infImg = isceobj.createImage()
|
||||||
rect_with_looks(inf,
|
infImg.load(inf+'.xml')
|
||||||
rinfs[i],
|
|
||||||
infImg.width, infImg.length,
|
|
||||||
infImg.width, infImg.length,
|
|
||||||
1.0, 0.0,
|
|
||||||
0.0, 1.0,
|
|
||||||
rangeOffsets2Frac, azimuthOffsets2Frac,
|
|
||||||
1,1,
|
|
||||||
1,1,
|
|
||||||
'COMPLEX',
|
|
||||||
'Bilinear')
|
|
||||||
if infImg.getImageType() == 'amp':
|
|
||||||
create_xml(rinfs[i], infImg.width, infImg.length, 'amp')
|
|
||||||
else:
|
|
||||||
create_xml(rinfs[i], infImg.width, infImg.length, 'int')
|
|
||||||
|
|
||||||
elif resamplingMethod == 1:
|
|
||||||
#decompose amplitude and phase
|
|
||||||
phaseFile = 'phase'
|
|
||||||
amplitudeFile = 'amplitude'
|
|
||||||
data = np.fromfile(inf, dtype=np.complex64).reshape(infImg.length, infImg.width)
|
|
||||||
phase = np.exp(np.complex64(1j) * np.angle(data))
|
|
||||||
phase[np.nonzero(data==0)] = 0
|
|
||||||
phase.astype(np.complex64).tofile(phaseFile)
|
|
||||||
amplitude = np.absolute(data)
|
|
||||||
amplitude.astype(np.float32).tofile(amplitudeFile)
|
|
||||||
|
|
||||||
#resampling
|
|
||||||
phaseRectFile = 'phaseRect'
|
|
||||||
amplitudeRectFile = 'amplitudeRect'
|
|
||||||
rect_with_looks(phaseFile,
|
|
||||||
phaseRectFile,
|
|
||||||
infImg.width, infImg.length,
|
|
||||||
infImg.width, infImg.length,
|
|
||||||
1.0, 0.0,
|
|
||||||
0.0, 1.0,
|
|
||||||
rangeOffsets2Frac, azimuthOffsets2Frac,
|
|
||||||
1,1,
|
|
||||||
1,1,
|
|
||||||
'COMPLEX',
|
|
||||||
'Sinc')
|
|
||||||
rect_with_looks(amplitudeFile,
|
|
||||||
amplitudeRectFile,
|
|
||||||
infImg.width, infImg.length,
|
|
||||||
infImg.width, infImg.length,
|
|
||||||
1.0, 0.0,
|
|
||||||
0.0, 1.0,
|
|
||||||
rangeOffsets2Frac, azimuthOffsets2Frac,
|
|
||||||
1,1,
|
|
||||||
1,1,
|
|
||||||
'REAL',
|
|
||||||
'Bilinear')
|
|
||||||
|
|
||||||
#recombine amplitude and phase
|
|
||||||
phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(infImg.length, infImg.width)
|
|
||||||
amplitude = np.fromfile(amplitudeRectFile, dtype=np.float32).reshape(infImg.length, infImg.width)
|
|
||||||
(phase*amplitude).astype(np.complex64).tofile(rinfs[i])
|
|
||||||
|
|
||||||
#tidy up
|
|
||||||
os.remove(phaseFile)
|
|
||||||
os.remove(amplitudeFile)
|
|
||||||
os.remove(phaseRectFile)
|
|
||||||
os.remove(amplitudeRectFile)
|
|
||||||
if infImg.getImageType() == 'amp':
|
if infImg.getImageType() == 'amp':
|
||||||
create_xml(rinfs[i], infImg.width, infImg.length, 'amp')
|
create_xml(rinfs[i], infImg.width, infImg.length, 'amp')
|
||||||
else:
|
else:
|
||||||
create_xml(rinfs[i], infImg.width, infImg.length, 'int')
|
create_xml(rinfs[i], infImg.width, infImg.length, 'int')
|
||||||
else:
|
else:
|
||||||
resamp(inf,
|
infImg = isceobj.createImage()
|
||||||
rinfs[i],
|
infImg.load(inf+'.xml')
|
||||||
'fake',
|
rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
|
||||||
'fake',
|
azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i])
|
||||||
infImg.width, infImg.length,
|
|
||||||
frames[i].swaths[0].prf,
|
if resamplingMethod == 0:
|
||||||
frames[i].swaths[0].dopplerVsPixel,
|
rect_with_looks(inf,
|
||||||
[rangeOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
rinfs[i],
|
||||||
[azimuthOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
|
infImg.width, infImg.length,
|
||||||
create_xml(rinfs[i], infImg.width, infImg.length, 'slc')
|
infImg.width, infImg.length,
|
||||||
|
1.0, 0.0,
|
||||||
|
0.0, 1.0,
|
||||||
|
rangeOffsets2Frac, azimuthOffsets2Frac,
|
||||||
|
1,1,
|
||||||
|
1,1,
|
||||||
|
'COMPLEX',
|
||||||
|
'Bilinear')
|
||||||
|
if infImg.getImageType() == 'amp':
|
||||||
|
create_xml(rinfs[i], infImg.width, infImg.length, 'amp')
|
||||||
|
else:
|
||||||
|
create_xml(rinfs[i], infImg.width, infImg.length, 'int')
|
||||||
|
|
||||||
|
elif resamplingMethod == 1:
|
||||||
|
#decompose amplitude and phase
|
||||||
|
phaseFile = 'phase'
|
||||||
|
amplitudeFile = 'amplitude'
|
||||||
|
data = np.fromfile(inf, dtype=np.complex64).reshape(infImg.length, infImg.width)
|
||||||
|
phase = np.exp(np.complex64(1j) * np.angle(data))
|
||||||
|
phase[np.nonzero(data==0)] = 0
|
||||||
|
phase.astype(np.complex64).tofile(phaseFile)
|
||||||
|
amplitude = np.absolute(data)
|
||||||
|
amplitude.astype(np.float32).tofile(amplitudeFile)
|
||||||
|
|
||||||
|
#resampling
|
||||||
|
phaseRectFile = 'phaseRect'
|
||||||
|
amplitudeRectFile = 'amplitudeRect'
|
||||||
|
rect_with_looks(phaseFile,
|
||||||
|
phaseRectFile,
|
||||||
|
infImg.width, infImg.length,
|
||||||
|
infImg.width, infImg.length,
|
||||||
|
1.0, 0.0,
|
||||||
|
0.0, 1.0,
|
||||||
|
rangeOffsets2Frac, azimuthOffsets2Frac,
|
||||||
|
1,1,
|
||||||
|
1,1,
|
||||||
|
'COMPLEX',
|
||||||
|
'Sinc')
|
||||||
|
rect_with_looks(amplitudeFile,
|
||||||
|
amplitudeRectFile,
|
||||||
|
infImg.width, infImg.length,
|
||||||
|
infImg.width, infImg.length,
|
||||||
|
1.0, 0.0,
|
||||||
|
0.0, 1.0,
|
||||||
|
rangeOffsets2Frac, azimuthOffsets2Frac,
|
||||||
|
1,1,
|
||||||
|
1,1,
|
||||||
|
'REAL',
|
||||||
|
'Bilinear')
|
||||||
|
|
||||||
|
#recombine amplitude and phase
|
||||||
|
phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(infImg.length, infImg.width)
|
||||||
|
amplitude = np.fromfile(amplitudeRectFile, dtype=np.float32).reshape(infImg.length, infImg.width)
|
||||||
|
(phase*amplitude).astype(np.complex64).tofile(rinfs[i])
|
||||||
|
|
||||||
|
#tidy up
|
||||||
|
os.remove(phaseFile)
|
||||||
|
os.remove(amplitudeFile)
|
||||||
|
os.remove(phaseRectFile)
|
||||||
|
os.remove(amplitudeRectFile)
|
||||||
|
if infImg.getImageType() == 'amp':
|
||||||
|
create_xml(rinfs[i], infImg.width, infImg.length, 'amp')
|
||||||
|
else:
|
||||||
|
create_xml(rinfs[i], infImg.width, infImg.length, 'int')
|
||||||
|
else:
|
||||||
|
resamp(inf,
|
||||||
|
rinfs[i],
|
||||||
|
'fake',
|
||||||
|
'fake',
|
||||||
|
infImg.width, infImg.length,
|
||||||
|
frames[i].swaths[0].prf,
|
||||||
|
frames[i].swaths[0].dopplerVsPixel,
|
||||||
|
[rangeOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
||||||
|
[azimuthOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
|
||||||
|
create_xml(rinfs[i], infImg.width, infImg.length, 'slc')
|
||||||
|
|
||||||
#determine output width and length
|
#determine output width and length
|
||||||
#actually no need to calculate in azimuth direction
|
#actually no need to calculate in azimuth direction
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ logger = logging.getLogger('isce.alos2insar.runFrameOffset')
|
||||||
def runFrameOffset(self):
|
def runFrameOffset(self):
|
||||||
'''estimate frame offsets.
|
'''estimate frame offsets.
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ logger = logging.getLogger('isce.alos2insar.runGeo2Rdr')
|
||||||
def runGeo2Rdr(self):
|
def runGeo2Rdr(self):
|
||||||
'''compute range and azimuth offsets
|
'''compute range and azimuth offsets
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,10 @@ logger = logging.getLogger('isce.alos2insar.runGeocode')
|
||||||
def runGeocode(self):
|
def runGeocode(self):
|
||||||
'''geocode final products
|
'''geocode final products
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import numpy as np
|
||||||
|
import numpy.matlib
|
||||||
|
|
||||||
|
import isceobj
|
||||||
|
|
||||||
|
logger = logging.getLogger('isce.alos2insar.runIonCorrect')
|
||||||
|
|
||||||
|
def runIonCorrect(self):
|
||||||
|
'''resample original ionosphere and ionospheric correction
|
||||||
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
if not self.doIon:
|
||||||
|
catalog.printToLog(logger, "runIonCorrect")
|
||||||
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
return
|
||||||
|
|
||||||
|
referenceTrack = self._insar.loadTrack(reference=True)
|
||||||
|
secondaryTrack = self._insar.loadTrack(reference=False)
|
||||||
|
|
||||||
|
from isceobj.Alos2Proc.runIonSubband import defineIonDir
|
||||||
|
ionDir = defineIonDir()
|
||||||
|
subbandPrefix = ['lower', 'upper']
|
||||||
|
|
||||||
|
ionCalDir = os.path.join(ionDir['ion'], ionDir['ionCal'])
|
||||||
|
os.makedirs(ionCalDir, exist_ok=True)
|
||||||
|
os.chdir(ionCalDir)
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# STEP 3. resample ionospheric phase
|
||||||
|
############################################################
|
||||||
|
from contrib.alos2proc_f.alos2proc_f import rect
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
from scipy.interpolate import interp1d
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
#################################################
|
||||||
|
#SET PARAMETERS HERE
|
||||||
|
#interpolation method
|
||||||
|
interpolationMethod = 1
|
||||||
|
#################################################
|
||||||
|
|
||||||
|
print('\ninterpolate ionosphere')
|
||||||
|
|
||||||
|
ml2 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon,
|
||||||
|
self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon)
|
||||||
|
|
||||||
|
ml3 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooks2,
|
||||||
|
self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooks2)
|
||||||
|
|
||||||
|
ionfiltfile = 'filt_ion'+ml2+'.ion'
|
||||||
|
#ionrectfile = 'filt_ion'+ml3+'.ion'
|
||||||
|
ionrectfile = self._insar.multilookIon
|
||||||
|
|
||||||
|
img = isceobj.createImage()
|
||||||
|
img.load(ionfiltfile + '.xml')
|
||||||
|
width2 = img.width
|
||||||
|
length2 = img.length
|
||||||
|
|
||||||
|
img = isceobj.createImage()
|
||||||
|
img.load(os.path.join('../../', ionDir['insar'], self._insar.multilookDifferentialInterferogram) + '.xml')
|
||||||
|
width3 = img.width
|
||||||
|
length3 = img.length
|
||||||
|
|
||||||
|
#number of range looks output
|
||||||
|
nrlo = self._insar.numberRangeLooks1*self._insar.numberRangeLooks2
|
||||||
|
#number of range looks input
|
||||||
|
nrli = self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon
|
||||||
|
#number of azimuth looks output
|
||||||
|
nalo = self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooks2
|
||||||
|
#number of azimuth looks input
|
||||||
|
nali = self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon
|
||||||
|
|
||||||
|
if (self._insar.numberRangeLooks2 != self._insar.numberRangeLooksIon) or \
|
||||||
|
(self._insar.numberAzimuthLooks2 != self._insar.numberAzimuthLooksIon):
|
||||||
|
#this should be faster using fortran
|
||||||
|
if interpolationMethod == 0:
|
||||||
|
rect(ionfiltfile, ionrectfile,
|
||||||
|
width2,length2,
|
||||||
|
width3,length3,
|
||||||
|
nrlo/nrli, 0.0,
|
||||||
|
0.0, nalo/nali,
|
||||||
|
(nrlo-nrli)/(2.0*nrli),
|
||||||
|
(nalo-nali)/(2.0*nali),
|
||||||
|
'REAL','Bilinear')
|
||||||
|
#finer, but slower method
|
||||||
|
else:
|
||||||
|
ionfilt = np.fromfile(ionfiltfile, dtype=np.float32).reshape(length2, width2)
|
||||||
|
index2 = np.linspace(0, width2-1, num=width2, endpoint=True)
|
||||||
|
index3 = np.linspace(0, width3-1, num=width3, endpoint=True) * nrlo/nrli + (nrlo-nrli)/(2.0*nrli)
|
||||||
|
ionrect = np.zeros((length3, width3), dtype=np.float32)
|
||||||
|
for i in range(length2):
|
||||||
|
f = interp1d(index2, ionfilt[i,:], kind='cubic', fill_value="extrapolate")
|
||||||
|
ionrect[i, :] = f(index3)
|
||||||
|
|
||||||
|
index2 = np.linspace(0, length2-1, num=length2, endpoint=True)
|
||||||
|
index3 = np.linspace(0, length3-1, num=length3, endpoint=True) * nalo/nali + (nalo-nali)/(2.0*nali)
|
||||||
|
for j in range(width3):
|
||||||
|
f = interp1d(index2, ionrect[0:length2, j], kind='cubic', fill_value="extrapolate")
|
||||||
|
ionrect[:, j] = f(index3)
|
||||||
|
ionrect.astype(np.float32).tofile(ionrectfile)
|
||||||
|
del ionrect
|
||||||
|
create_xml(ionrectfile, width3, length3, 'float')
|
||||||
|
|
||||||
|
os.rename(ionrectfile, os.path.join('../../insar', ionrectfile))
|
||||||
|
os.rename(ionrectfile+'.vrt', os.path.join('../../insar', ionrectfile)+'.vrt')
|
||||||
|
os.rename(ionrectfile+'.xml', os.path.join('../../insar', ionrectfile)+'.xml')
|
||||||
|
os.chdir('../../insar')
|
||||||
|
else:
|
||||||
|
shutil.copyfile(ionfiltfile, os.path.join('../../insar', ionrectfile))
|
||||||
|
os.chdir('../../insar')
|
||||||
|
create_xml(ionrectfile, width3, length3, 'float')
|
||||||
|
#now we are in 'insar'
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# STEP 4. correct interferogram
|
||||||
|
############################################################
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import renameFile
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
|
|
||||||
|
if self.applyIon:
|
||||||
|
print('\ncorrect interferogram')
|
||||||
|
if os.path.isfile(self._insar.multilookDifferentialInterferogramOriginal):
|
||||||
|
print('original interferogram: {} is already here, do not rename: {}'.format(self._insar.multilookDifferentialInterferogramOriginal, self._insar.multilookDifferentialInterferogram))
|
||||||
|
else:
|
||||||
|
print('renaming {} to {}'.format(self._insar.multilookDifferentialInterferogram, self._insar.multilookDifferentialInterferogramOriginal))
|
||||||
|
renameFile(self._insar.multilookDifferentialInterferogram, self._insar.multilookDifferentialInterferogramOriginal)
|
||||||
|
|
||||||
|
cmd = "imageMath.py -e='a*exp(-1.0*J*b)' --a={} --b={} -s BIP -t cfloat -o {}".format(
|
||||||
|
self._insar.multilookDifferentialInterferogramOriginal,
|
||||||
|
self._insar.multilookIon,
|
||||||
|
self._insar.multilookDifferentialInterferogram)
|
||||||
|
runCmd(cmd)
|
||||||
|
else:
|
||||||
|
print('\nionospheric phase estimation finished, but correction of interfeorgram not requested')
|
||||||
|
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
catalog.printToLog(logger, "runIonCorrect")
|
||||||
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
||||||
|
|
@ -15,6 +15,10 @@ logger = logging.getLogger('isce.alos2insar.runIonFilt')
|
||||||
def runIonFilt(self):
|
def runIonFilt(self):
|
||||||
'''compute and filter ionospheric phase
|
'''compute and filter ionospheric phase
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
@ -110,6 +114,7 @@ def runIonFilt(self):
|
||||||
############################################################
|
############################################################
|
||||||
# STEP 2. filter ionospheric phase
|
# STEP 2. filter ionospheric phase
|
||||||
############################################################
|
############################################################
|
||||||
|
import scipy.signal as ss
|
||||||
|
|
||||||
#################################################
|
#################################################
|
||||||
#SET PARAMETERS HERE
|
#SET PARAMETERS HERE
|
||||||
|
|
@ -117,22 +122,36 @@ def runIonFilt(self):
|
||||||
fit = self.fitIon
|
fit = self.fitIon
|
||||||
filt = self.filtIon
|
filt = self.filtIon
|
||||||
fitAdaptive = self.fitAdaptiveIon
|
fitAdaptive = self.fitAdaptiveIon
|
||||||
|
filtSecondary = self.filtSecondaryIon
|
||||||
if (fit == False) and (filt == False):
|
if (fit == False) and (filt == False):
|
||||||
raise Exception('either fit ionosphere or filt ionosphere should be True when doing ionospheric correction\n')
|
raise Exception('either fit ionosphere or filt ionosphere should be True when doing ionospheric correction\n')
|
||||||
|
|
||||||
#filtering window size
|
#filtering window size
|
||||||
size_max = self.filteringWinsizeMaxIon
|
size_max = self.filteringWinsizeMaxIon
|
||||||
size_min = self.filteringWinsizeMinIon
|
size_min = self.filteringWinsizeMinIon
|
||||||
|
size_secondary = self.filteringWinsizeSecondaryIon
|
||||||
if size_min > size_max:
|
if size_min > size_max:
|
||||||
print('\n\nWARNING: minimum window size for filtering ionosphere phase {} > maximum window size {}'.format(size_min, size_max))
|
print('\n\nWARNING: minimum window size for filtering ionosphere phase {} > maximum window size {}'.format(size_min, size_max))
|
||||||
print(' re-setting maximum window size to {}\n\n'.format(size_min))
|
print(' re-setting maximum window size to {}\n\n'.format(size_min))
|
||||||
size_max = size_min
|
size_max = size_min
|
||||||
|
if size_secondary % 2 != 1:
|
||||||
|
size_secondary += 1
|
||||||
|
print('window size of secondary filtering of ionosphere phase should be odd, window size changed to {}'.format(size_secondary))
|
||||||
|
|
||||||
#coherence threshold for fitting a polynomial
|
#coherence threshold for fitting a polynomial
|
||||||
corThresholdFit = 0.25
|
corThresholdFit = 0.25
|
||||||
|
|
||||||
#ionospheric phase standard deviation after filtering
|
#ionospheric phase standard deviation after filtering
|
||||||
std_out0 = 0.1
|
if self.filterStdIon is not None:
|
||||||
|
std_out0 = self.filterStdIon
|
||||||
|
else:
|
||||||
|
if referenceTrack.operationMode == secondaryTrack.operationMode:
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import modeProcParDict
|
||||||
|
std_out0 = modeProcParDict['ALOS-2'][referenceTrack.operationMode]['filterStdIon']
|
||||||
|
else:
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import filterStdPolyIon
|
||||||
|
std_out0 = np.polyval(filterStdPolyIon, referenceTrack.frames[0].swaths[0].rangeBandwidth/(1e6))
|
||||||
|
#std_out0 = 0.1
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
print('\nfiltering ionosphere')
|
print('\nfiltering ionosphere')
|
||||||
|
|
@ -271,6 +290,12 @@ def runIonFilt(self):
|
||||||
#filter the rest of the ionosphere
|
#filter the rest of the ionosphere
|
||||||
if filt:
|
if filt:
|
||||||
(ion_filt, std_out, window_size_out) = adaptive_gaussian(ion, std, size_min, size_max, std_out0, fit=fitAdaptive)
|
(ion_filt, std_out, window_size_out) = adaptive_gaussian(ion, std, size_min, size_max, std_out0, fit=fitAdaptive)
|
||||||
|
if filtSecondary:
|
||||||
|
print('applying secondary filtering with window size {}'.format(size_secondary))
|
||||||
|
g2d = gaussian(size_secondary, size_secondary/2.0, scale=1.0)
|
||||||
|
scale = ss.fftconvolve((ion_filt!=0), g2d, mode='same')
|
||||||
|
ion_filt = (ion_filt!=0) * ss.fftconvolve(ion_filt, g2d, mode='same') / (scale + (scale==0))
|
||||||
|
catalog.addItem('standard deviation of filtered ionospheric phase', std_out0, 'runIonFilt')
|
||||||
|
|
||||||
#get final results
|
#get final results
|
||||||
if (fit == True) and (filt == True):
|
if (fit == True) and (filt == True):
|
||||||
|
|
@ -291,114 +316,7 @@ def runIonFilt(self):
|
||||||
window_size_out.astype(np.float32).tofile(windowsizefiltfile)
|
window_size_out.astype(np.float32).tofile(windowsizefiltfile)
|
||||||
create_xml(windowsizefiltfile, width, length, 'float')
|
create_xml(windowsizefiltfile, width, length, 'float')
|
||||||
|
|
||||||
|
os.chdir('../../')
|
||||||
############################################################
|
|
||||||
# STEP 3. resample ionospheric phase
|
|
||||||
############################################################
|
|
||||||
from contrib.alos2proc_f.alos2proc_f import rect
|
|
||||||
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
|
||||||
from scipy.interpolate import interp1d
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
#SET PARAMETERS HERE
|
|
||||||
#interpolation method
|
|
||||||
interpolationMethod = 1
|
|
||||||
#################################################
|
|
||||||
|
|
||||||
print('\ninterpolate ionosphere')
|
|
||||||
|
|
||||||
ml3 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooks2,
|
|
||||||
self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooks2)
|
|
||||||
|
|
||||||
ionfiltfile = 'filt_ion'+ml2+'.ion'
|
|
||||||
#ionrectfile = 'filt_ion'+ml3+'.ion'
|
|
||||||
ionrectfile = self._insar.multilookIon
|
|
||||||
|
|
||||||
img = isceobj.createImage()
|
|
||||||
img.load(ionfiltfile + '.xml')
|
|
||||||
width2 = img.width
|
|
||||||
length2 = img.length
|
|
||||||
|
|
||||||
img = isceobj.createImage()
|
|
||||||
img.load(os.path.join('../../', ionDir['insar'], self._insar.multilookDifferentialInterferogram) + '.xml')
|
|
||||||
width3 = img.width
|
|
||||||
length3 = img.length
|
|
||||||
|
|
||||||
#number of range looks output
|
|
||||||
nrlo = self._insar.numberRangeLooks1*self._insar.numberRangeLooks2
|
|
||||||
#number of range looks input
|
|
||||||
nrli = self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon
|
|
||||||
#number of azimuth looks output
|
|
||||||
nalo = self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooks2
|
|
||||||
#number of azimuth looks input
|
|
||||||
nali = self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon
|
|
||||||
|
|
||||||
if (self._insar.numberRangeLooks2 != self._insar.numberRangeLooksIon) or \
|
|
||||||
(self._insar.numberAzimuthLooks2 != self._insar.numberAzimuthLooksIon):
|
|
||||||
#this should be faster using fortran
|
|
||||||
if interpolationMethod == 0:
|
|
||||||
rect(ionfiltfile, ionrectfile,
|
|
||||||
width2,length2,
|
|
||||||
width3,length3,
|
|
||||||
nrlo/nrli, 0.0,
|
|
||||||
0.0, nalo/nali,
|
|
||||||
(nrlo-nrli)/(2.0*nrli),
|
|
||||||
(nalo-nali)/(2.0*nali),
|
|
||||||
'REAL','Bilinear')
|
|
||||||
#finer, but slower method
|
|
||||||
else:
|
|
||||||
ionfilt = np.fromfile(ionfiltfile, dtype=np.float32).reshape(length2, width2)
|
|
||||||
index2 = np.linspace(0, width2-1, num=width2, endpoint=True)
|
|
||||||
index3 = np.linspace(0, width3-1, num=width3, endpoint=True) * nrlo/nrli + (nrlo-nrli)/(2.0*nrli)
|
|
||||||
ionrect = np.zeros((length3, width3), dtype=np.float32)
|
|
||||||
for i in range(length2):
|
|
||||||
f = interp1d(index2, ionfilt[i,:], kind='cubic', fill_value="extrapolate")
|
|
||||||
ionrect[i, :] = f(index3)
|
|
||||||
|
|
||||||
index2 = np.linspace(0, length2-1, num=length2, endpoint=True)
|
|
||||||
index3 = np.linspace(0, length3-1, num=length3, endpoint=True) * nalo/nali + (nalo-nali)/(2.0*nali)
|
|
||||||
for j in range(width3):
|
|
||||||
f = interp1d(index2, ionrect[0:length2, j], kind='cubic', fill_value="extrapolate")
|
|
||||||
ionrect[:, j] = f(index3)
|
|
||||||
ionrect.astype(np.float32).tofile(ionrectfile)
|
|
||||||
del ionrect
|
|
||||||
create_xml(ionrectfile, width3, length3, 'float')
|
|
||||||
|
|
||||||
os.rename(ionrectfile, os.path.join('../../insar', ionrectfile))
|
|
||||||
os.rename(ionrectfile+'.vrt', os.path.join('../../insar', ionrectfile)+'.vrt')
|
|
||||||
os.rename(ionrectfile+'.xml', os.path.join('../../insar', ionrectfile)+'.xml')
|
|
||||||
os.chdir('../../insar')
|
|
||||||
else:
|
|
||||||
shutil.copyfile(ionfiltfile, os.path.join('../../insar', ionrectfile))
|
|
||||||
os.chdir('../../insar')
|
|
||||||
create_xml(ionrectfile, width3, length3, 'float')
|
|
||||||
#now we are in 'insar'
|
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
# STEP 4. correct interferogram
|
|
||||||
############################################################
|
|
||||||
from isceobj.Alos2Proc.Alos2ProcPublic import renameFile
|
|
||||||
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
|
||||||
|
|
||||||
if self.applyIon:
|
|
||||||
print('\ncorrect interferogram')
|
|
||||||
if os.path.isfile(self._insar.multilookDifferentialInterferogramOriginal):
|
|
||||||
print('original interferogram: {} is already here, do not rename: {}'.format(self._insar.multilookDifferentialInterferogramOriginal, self._insar.multilookDifferentialInterferogram))
|
|
||||||
else:
|
|
||||||
print('renaming {} to {}'.format(self._insar.multilookDifferentialInterferogram, self._insar.multilookDifferentialInterferogramOriginal))
|
|
||||||
renameFile(self._insar.multilookDifferentialInterferogram, self._insar.multilookDifferentialInterferogramOriginal)
|
|
||||||
|
|
||||||
cmd = "imageMath.py -e='a*exp(-1.0*J*b)' --a={} --b={} -s BIP -t cfloat -o {}".format(
|
|
||||||
self._insar.multilookDifferentialInterferogramOriginal,
|
|
||||||
self._insar.multilookIon,
|
|
||||||
self._insar.multilookDifferentialInterferogram)
|
|
||||||
runCmd(cmd)
|
|
||||||
else:
|
|
||||||
print('\nionospheric phase estimation finished, but correction of interfeorgram not requested')
|
|
||||||
|
|
||||||
os.chdir('../')
|
|
||||||
|
|
||||||
catalog.printToLog(logger, "runIonFilt")
|
catalog.printToLog(logger, "runIonFilt")
|
||||||
self._insar.procDoc.addAllFromCatalog(catalog)
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@ logger = logging.getLogger('isce.alos2insar.runIonSubband')
|
||||||
def runIonSubband(self):
|
def runIonSubband(self):
|
||||||
'''create subband interferograms
|
'''create subband interferograms
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
@ -296,30 +300,38 @@ def runIonSubband(self):
|
||||||
#list of input files
|
#list of input files
|
||||||
inputInterferograms = []
|
inputInterferograms = []
|
||||||
inputAmplitudes = []
|
inputAmplitudes = []
|
||||||
phaseDiff = [None]
|
#phaseDiff = [None]
|
||||||
|
swathPhaseDiffIon = [self.swathPhaseDiffLowerIon, self.swathPhaseDiffUpperIon]
|
||||||
|
phaseDiff = swathPhaseDiffIon[k]
|
||||||
|
if swathPhaseDiffIon[k] is None:
|
||||||
|
phaseDiff = None
|
||||||
|
else:
|
||||||
|
phaseDiff = swathPhaseDiffIon[k][i]
|
||||||
|
phaseDiff.insert(0, None)
|
||||||
|
|
||||||
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
||||||
swathDir = 's{}'.format(swathNumber)
|
swathDir = 's{}'.format(swathNumber)
|
||||||
inputInterferograms.append(os.path.join('../', swathDir, self._insar.interferogram))
|
inputInterferograms.append(os.path.join('../', swathDir, self._insar.interferogram))
|
||||||
inputAmplitudes.append(os.path.join('../', swathDir, self._insar.amplitude))
|
inputAmplitudes.append(os.path.join('../', swathDir, self._insar.amplitude))
|
||||||
|
|
||||||
#compute phase needed to be compensated using startingRange
|
# #compute phase needed to be compensated using startingRange
|
||||||
if j >= 1:
|
# if j >= 1:
|
||||||
#phaseDiffSwath1 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange)/subbandRadarWavelength[k]
|
# #phaseDiffSwath1 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange)/subbandRadarWavelength[k]
|
||||||
#phaseDiffSwath2 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange)/subbandRadarWavelength[k]
|
# #phaseDiffSwath2 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange)/subbandRadarWavelength[k]
|
||||||
phaseDiffSwath1 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
|
# phaseDiffSwath1 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
|
||||||
-4.0 * np.pi * secondaryTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
|
# -4.0 * np.pi * secondaryTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
|
||||||
phaseDiffSwath2 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
|
# phaseDiffSwath2 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
|
||||||
-4.0 * np.pi * secondaryTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
|
# -4.0 * np.pi * secondaryTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
|
||||||
if referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange == \
|
# if referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange == \
|
||||||
referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange:
|
# referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange:
|
||||||
#phaseDiff.append(phaseDiffSwath2 - phaseDiffSwath1)
|
# #phaseDiff.append(phaseDiffSwath2 - phaseDiffSwath1)
|
||||||
#if reference and secondary versions are all before or after version 2.025 (starting range error < 0.5 m),
|
# #if reference and secondary versions are all before or after version 2.025 (starting range error < 0.5 m),
|
||||||
#it should be OK to do the above.
|
# #it should be OK to do the above.
|
||||||
#see results in neom where it meets the above requirement, but there is still phase diff
|
# #see results in neom where it meets the above requirement, but there is still phase diff
|
||||||
#to be less risky, we do not input values here
|
# #to be less risky, we do not input values here
|
||||||
phaseDiff.append(None)
|
# phaseDiff.append(None)
|
||||||
else:
|
# else:
|
||||||
phaseDiff.append(None)
|
# phaseDiff.append(None)
|
||||||
|
|
||||||
#note that frame parameters are updated after mosaicking, here no need to update parameters
|
#note that frame parameters are updated after mosaicking, here no need to update parameters
|
||||||
#mosaic amplitudes
|
#mosaic amplitudes
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import logging
|
import logging
|
||||||
import datetime
|
import datetime
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
@ -15,6 +16,10 @@ logger = logging.getLogger('isce.alos2insar.runIonUwrap')
|
||||||
def runIonUwrap(self):
|
def runIonUwrap(self):
|
||||||
'''unwrap subband interferograms
|
'''unwrap subband interferograms
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
@ -24,7 +29,17 @@ def runIonUwrap(self):
|
||||||
return
|
return
|
||||||
|
|
||||||
referenceTrack = self._insar.loadTrack(reference=True)
|
referenceTrack = self._insar.loadTrack(reference=True)
|
||||||
secondaryTrack = self._insar.loadTrack(reference=False)
|
#secondaryTrack = self._insar.loadTrack(reference=False)
|
||||||
|
|
||||||
|
ionUwrap(self, referenceTrack)
|
||||||
|
|
||||||
|
os.chdir('../../')
|
||||||
|
catalog.printToLog(logger, "runIonUwrap")
|
||||||
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
||||||
|
|
||||||
|
def ionUwrap(self, referenceTrack, latLonDir=None):
|
||||||
|
|
||||||
wbdFile = os.path.abspath(self._insar.wbd)
|
wbdFile = os.path.abspath(self._insar.wbd)
|
||||||
|
|
||||||
from isceobj.Alos2Proc.runIonSubband import defineIonDir
|
from isceobj.Alos2Proc.runIonSubband import defineIonDir
|
||||||
|
|
@ -73,8 +88,14 @@ def runIonUwrap(self):
|
||||||
|
|
||||||
#water body
|
#water body
|
||||||
if k == 0:
|
if k == 0:
|
||||||
look(os.path.join(fullbandDir, self._insar.latitude), 'lat'+ml2+'.lat', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 3, 0, 1)
|
if latLonDir is None:
|
||||||
look(os.path.join(fullbandDir, self._insar.longitude), 'lon'+ml2+'.lon', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 3, 0, 1)
|
latFile = os.path.join(fullbandDir, self._insar.latitude)
|
||||||
|
lonFile = os.path.join(fullbandDir, self._insar.longitude)
|
||||||
|
else:
|
||||||
|
latFile = os.path.join('../../', latLonDir, self._insar.latitude)
|
||||||
|
lonFile = os.path.join('../../', latLonDir, self._insar.longitude)
|
||||||
|
look(latFile, 'lat'+ml2+'.lat', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 3, 0, 1)
|
||||||
|
look(lonFile, 'lon'+ml2+'.lon', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 3, 0, 1)
|
||||||
create_xml('lat'+ml2+'.lat', width2, length2, 'double')
|
create_xml('lat'+ml2+'.lat', width2, length2, 'double')
|
||||||
create_xml('lon'+ml2+'.lon', width2, length2, 'double')
|
create_xml('lon'+ml2+'.lon', width2, length2, 'double')
|
||||||
waterBodyRadar('lat'+ml2+'.lat', 'lon'+ml2+'.lon', wbdFile, 'wbd'+ml2+'.wbd')
|
waterBodyRadar('lat'+ml2+'.lat', 'lon'+ml2+'.lon', wbdFile, 'wbd'+ml2+'.wbd')
|
||||||
|
|
@ -132,8 +153,9 @@ def runIonUwrap(self):
|
||||||
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
from mroipac.icu.Icu import Icu
|
from mroipac.icu.Icu import Icu
|
||||||
|
|
||||||
if self.filterSubbandInt:
|
for k in range(2):
|
||||||
for k in range(2):
|
#1. filtering subband interferogram
|
||||||
|
if self.filterSubbandInt:
|
||||||
toBeFiltered = 'tmp.int'
|
toBeFiltered = 'tmp.int'
|
||||||
if self.removeMagnitudeBeforeFilteringSubbandInt:
|
if self.removeMagnitudeBeforeFilteringSubbandInt:
|
||||||
cmd = "imageMath.py -e='a/(abs(a)+(a==0))' --a={} -o {} -t cfloat -s BSQ".format(subbandPrefix[k]+ml2+'.int', toBeFiltered)
|
cmd = "imageMath.py -e='a/(abs(a)+(a==0))' --a={} -o {} -t cfloat -s BSQ".format(subbandPrefix[k]+ml2+'.int', toBeFiltered)
|
||||||
|
|
@ -156,45 +178,50 @@ def runIonUwrap(self):
|
||||||
os.remove(toBeFiltered + '.vrt')
|
os.remove(toBeFiltered + '.vrt')
|
||||||
os.remove(toBeFiltered + '.xml')
|
os.remove(toBeFiltered + '.xml')
|
||||||
|
|
||||||
#create phase sigma for phase unwrapping
|
toBeUsedInPhsig = 'filt_'+subbandPrefix[k]+ml2+'.int'
|
||||||
#recreate filtered image
|
else:
|
||||||
filtImage = isceobj.createIntImage()
|
toBeUsedInPhsig = subbandPrefix[k]+ml2+'.int'
|
||||||
filtImage.load('filt_'+subbandPrefix[k]+ml2+'.int' + '.xml')
|
|
||||||
filtImage.setAccessMode('read')
|
|
||||||
filtImage.createImage()
|
|
||||||
|
|
||||||
#amplitude image
|
#2. create phase sigma for phase unwrapping
|
||||||
ampImage = isceobj.createAmpImage()
|
#recreate filtered image
|
||||||
ampImage.load(subbandPrefix[k]+ml2+'.amp' + '.xml')
|
filtImage = isceobj.createIntImage()
|
||||||
ampImage.setAccessMode('read')
|
filtImage.load(toBeUsedInPhsig + '.xml')
|
||||||
ampImage.createImage()
|
filtImage.setAccessMode('read')
|
||||||
|
filtImage.createImage()
|
||||||
|
|
||||||
#phase sigma correlation image
|
#amplitude image
|
||||||
phsigImage = isceobj.createImage()
|
ampImage = isceobj.createAmpImage()
|
||||||
phsigImage.setFilename(subbandPrefix[k]+ml2+'.phsig')
|
ampImage.load(subbandPrefix[k]+ml2+'.amp' + '.xml')
|
||||||
phsigImage.setWidth(width)
|
ampImage.setAccessMode('read')
|
||||||
phsigImage.dataType='FLOAT'
|
ampImage.createImage()
|
||||||
phsigImage.bands = 1
|
|
||||||
phsigImage.setImageType('cor')
|
|
||||||
phsigImage.setAccessMode('write')
|
|
||||||
phsigImage.createImage()
|
|
||||||
|
|
||||||
icu = Icu(name='insarapp_filter_icu')
|
#phase sigma correlation image
|
||||||
icu.configure()
|
phsigImage = isceobj.createImage()
|
||||||
icu.unwrappingFlag = False
|
phsigImage.setFilename(subbandPrefix[k]+ml2+'.phsig')
|
||||||
icu.icu(intImage = filtImage, ampImage=ampImage, phsigImage=phsigImage)
|
phsigImage.setWidth(filtImage.width)
|
||||||
|
phsigImage.dataType='FLOAT'
|
||||||
|
phsigImage.bands = 1
|
||||||
|
phsigImage.setImageType('cor')
|
||||||
|
phsigImage.setAccessMode('write')
|
||||||
|
phsigImage.createImage()
|
||||||
|
|
||||||
phsigImage.renderHdr()
|
icu = Icu(name='insarapp_filter_icu')
|
||||||
|
icu.configure()
|
||||||
|
icu.unwrappingFlag = False
|
||||||
|
icu.icu(intImage = filtImage, ampImage=ampImage, phsigImage=phsigImage)
|
||||||
|
|
||||||
filtImage.finalizeImage()
|
phsigImage.renderHdr()
|
||||||
ampImage.finalizeImage()
|
|
||||||
phsigImage.finalizeImage()
|
filtImage.finalizeImage()
|
||||||
|
ampImage.finalizeImage()
|
||||||
|
phsigImage.finalizeImage()
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
# STEP 4. phase unwrapping
|
# STEP 4. phase unwrapping
|
||||||
############################################################
|
############################################################
|
||||||
from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrap
|
from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrap
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrapOriginal
|
||||||
|
|
||||||
for k in range(2):
|
for k in range(2):
|
||||||
tmid = referenceTrack.sensingStart + datetime.timedelta(seconds=(self._insar.numberAzimuthLooks1-1.0)/2.0*referenceTrack.azimuthLineInterval+
|
tmid = referenceTrack.sensingStart + datetime.timedelta(seconds=(self._insar.numberAzimuthLooks1-1.0)/2.0*referenceTrack.azimuthLineInterval+
|
||||||
|
|
@ -207,16 +234,24 @@ def runIonUwrap(self):
|
||||||
toBeUnwrapped = subbandPrefix[k]+ml2+'.int'
|
toBeUnwrapped = subbandPrefix[k]+ml2+'.int'
|
||||||
coherenceFile = 'diff'+ml2+'.cor'
|
coherenceFile = 'diff'+ml2+'.cor'
|
||||||
|
|
||||||
snaphuUnwrap(referenceTrack, tmid,
|
#if shutil.which('snaphu') != None:
|
||||||
toBeUnwrapped,
|
#do not use original snaphu now
|
||||||
coherenceFile,
|
if False:
|
||||||
subbandPrefix[k]+ml2+'.unw',
|
print('\noriginal snaphu program found')
|
||||||
self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon,
|
print('unwrap {} using original snaphu, rather than that in ISCE'.format(toBeUnwrapped))
|
||||||
self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon,
|
snaphuUnwrapOriginal(toBeUnwrapped,
|
||||||
costMode = 'SMOOTH',initMethod = 'MCF', defomax = 2, initOnly = True)
|
subbandPrefix[k]+ml2+'.phsig',
|
||||||
|
subbandPrefix[k]+ml2+'.amp',
|
||||||
|
subbandPrefix[k]+ml2+'.unw',
|
||||||
os.chdir('../../')
|
costMode = 's',
|
||||||
catalog.printToLog(logger, "runIonUwrap")
|
initMethod = 'mcf',
|
||||||
self._insar.procDoc.addAllFromCatalog(catalog)
|
snaphuConfFile = '{}_snaphu.conf'.format(subbandPrefix[k]))
|
||||||
|
else:
|
||||||
|
snaphuUnwrap(referenceTrack, tmid,
|
||||||
|
toBeUnwrapped,
|
||||||
|
coherenceFile,
|
||||||
|
subbandPrefix[k]+ml2+'.unw',
|
||||||
|
self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon,
|
||||||
|
self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon,
|
||||||
|
costMode = 'SMOOTH',initMethod = 'MCF', defomax = 2, initOnly = True)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@ logger = logging.getLogger('isce.alos2insar.runLook')
|
||||||
def runLook(self):
|
def runLook(self):
|
||||||
'''take looks
|
'''take looks
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ from isceobj.Planet.Planet import Planet
|
||||||
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
from isceobj.Alos2Proc.Alos2ProcPublic import getBboxRdr
|
from isceobj.Alos2Proc.Alos2ProcPublic import getBboxRdr
|
||||||
from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo
|
from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import modeProcParDict
|
||||||
|
|
||||||
logger = logging.getLogger('isce.alos2insar.runPreprocessor')
|
logger = logging.getLogger('isce.alos2insar.runPreprocessor')
|
||||||
|
|
||||||
|
|
@ -110,81 +111,20 @@ def runPreprocessor(self):
|
||||||
self._insar.numberRangeLooksIon = self.numberRangeLooksIon
|
self._insar.numberRangeLooksIon = self.numberRangeLooksIon
|
||||||
self._insar.numberAzimuthLooksIon = self.numberAzimuthLooksIon
|
self._insar.numberAzimuthLooksIon = self.numberAzimuthLooksIon
|
||||||
|
|
||||||
if self._insar.numberRangeLooks1 == None:
|
if self._insar.numberRangeLooks1 is None:
|
||||||
if referenceMode in ['SBS']:
|
self._insar.numberRangeLooks1 = modeProcParDict['ALOS-2'][referenceMode]['numberRangeLooks1']
|
||||||
self._insar.numberRangeLooks1 = 2
|
if self._insar.numberAzimuthLooks1 is None:
|
||||||
elif referenceMode in ['UBS', 'UBD']:
|
self._insar.numberAzimuthLooks1 = modeProcParDict['ALOS-2'][referenceMode]['numberAzimuthLooks1']
|
||||||
self._insar.numberRangeLooks1 = 2
|
|
||||||
elif referenceMode in ['HBS', 'HBD', 'HBQ']:
|
|
||||||
self._insar.numberRangeLooks1 = 2
|
|
||||||
elif referenceMode in ['FBS', 'FBD', 'FBQ']:
|
|
||||||
self._insar.numberRangeLooks1 = 2
|
|
||||||
elif referenceMode in ['WBS', 'WBD']:
|
|
||||||
self._insar.numberRangeLooks1 = 1
|
|
||||||
elif referenceMode in ['WWS', 'WWD']:
|
|
||||||
self._insar.numberRangeLooks1 = 2
|
|
||||||
elif referenceMode in ['VBS', 'VBD']:
|
|
||||||
self._insar.numberRangeLooks1 = 1
|
|
||||||
else:
|
|
||||||
raise Exception('unknow acquisition mode')
|
|
||||||
|
|
||||||
if self._insar.numberAzimuthLooks1 == None:
|
if self._insar.numberRangeLooks2 is None:
|
||||||
if referenceMode in ['SBS']:
|
self._insar.numberRangeLooks2 = modeProcParDict['ALOS-2'][referenceMode]['numberRangeLooks2']
|
||||||
self._insar.numberAzimuthLooks1 = 4
|
if self._insar.numberAzimuthLooks2 is None:
|
||||||
elif referenceMode in ['UBS', 'UBD']:
|
self._insar.numberAzimuthLooks2 = modeProcParDict['ALOS-2'][referenceMode]['numberAzimuthLooks2']
|
||||||
self._insar.numberAzimuthLooks1 = 2
|
|
||||||
elif referenceMode in ['HBS', 'HBD', 'HBQ']:
|
|
||||||
self._insar.numberAzimuthLooks1 = 2
|
|
||||||
elif referenceMode in ['FBS', 'FBD', 'FBQ']:
|
|
||||||
self._insar.numberAzimuthLooks1 = 4
|
|
||||||
elif referenceMode in ['WBS', 'WBD']:
|
|
||||||
self._insar.numberAzimuthLooks1 = 14
|
|
||||||
elif referenceMode in ['WWS', 'WWD']:
|
|
||||||
self._insar.numberAzimuthLooks1 = 14
|
|
||||||
elif referenceMode in ['VBS', 'VBD']:
|
|
||||||
self._insar.numberAzimuthLooks1 = 14
|
|
||||||
else:
|
|
||||||
raise Exception('unknow acquisition mode')
|
|
||||||
|
|
||||||
if self._insar.numberRangeLooks2 == None:
|
if self._insar.numberRangeLooksIon is None:
|
||||||
if referenceMode in spotlightModes:
|
self._insar.numberRangeLooksIon = modeProcParDict['ALOS-2'][referenceMode]['numberRangeLooksIon']
|
||||||
self._insar.numberRangeLooks2 = 4
|
if self._insar.numberAzimuthLooksIon is None:
|
||||||
elif referenceMode in stripmapModes:
|
self._insar.numberAzimuthLooksIon = modeProcParDict['ALOS-2'][referenceMode]['numberAzimuthLooksIon']
|
||||||
self._insar.numberRangeLooks2 = 4
|
|
||||||
elif referenceMode in scansarModes:
|
|
||||||
self._insar.numberRangeLooks2 = 5
|
|
||||||
else:
|
|
||||||
raise Exception('unknow acquisition mode')
|
|
||||||
|
|
||||||
if self._insar.numberAzimuthLooks2 == None:
|
|
||||||
if referenceMode in spotlightModes:
|
|
||||||
self._insar.numberAzimuthLooks2 = 4
|
|
||||||
elif referenceMode in stripmapModes:
|
|
||||||
self._insar.numberAzimuthLooks2 = 4
|
|
||||||
elif referenceMode in scansarModes:
|
|
||||||
self._insar.numberAzimuthLooks2 = 2
|
|
||||||
else:
|
|
||||||
raise Exception('unknow acquisition mode')
|
|
||||||
|
|
||||||
if self._insar.numberRangeLooksIon == None:
|
|
||||||
if referenceMode in spotlightModes:
|
|
||||||
self._insar.numberRangeLooksIon = 16
|
|
||||||
elif referenceMode in stripmapModes:
|
|
||||||
self._insar.numberRangeLooksIon = 16
|
|
||||||
elif referenceMode in scansarModes:
|
|
||||||
self._insar.numberRangeLooksIon = 40
|
|
||||||
else:
|
|
||||||
raise Exception('unknow acquisition mode')
|
|
||||||
|
|
||||||
if self._insar.numberAzimuthLooksIon == None:
|
|
||||||
if referenceMode in spotlightModes:
|
|
||||||
self._insar.numberAzimuthLooksIon = 16
|
|
||||||
elif referenceMode in stripmapModes:
|
|
||||||
self._insar.numberAzimuthLooksIon = 16
|
|
||||||
elif referenceMode in scansarModes:
|
|
||||||
self._insar.numberAzimuthLooksIon = 16
|
|
||||||
else:
|
|
||||||
raise Exception('unknow acquisition mode')
|
|
||||||
|
|
||||||
|
|
||||||
#define processing file names
|
#define processing file names
|
||||||
|
|
@ -335,201 +275,6 @@ def runPreprocessor(self):
|
||||||
self._insar.saveProduct(self.secondary.track, self._insar.secondaryTrackParameter)
|
self._insar.saveProduct(self.secondary.track, self._insar.secondaryTrackParameter)
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
#2. compute burst synchronization
|
|
||||||
##################################################
|
|
||||||
#burst synchronization may slowly change along a track as a result of the changing relative speed of the two flights
|
|
||||||
#in one frame, real unsynchronized time is the same for all swaths
|
|
||||||
unsynTime = 0
|
|
||||||
#real synchronized time/percentage depends on the swath burst length (synTime = burstlength - abs(unsynTime))
|
|
||||||
#synTime = 0
|
|
||||||
synPercentage = 0
|
|
||||||
|
|
||||||
numberOfFrames = len(self._insar.referenceFrames)
|
|
||||||
numberOfSwaths = self._insar.endingSwath - self._insar.startingSwath + 1
|
|
||||||
|
|
||||||
for i, frameNumber in enumerate(self._insar.referenceFrames):
|
|
||||||
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
|
||||||
referenceSwath = self.reference.track.frames[i].swaths[j]
|
|
||||||
secondarySwath = self.secondary.track.frames[i].swaths[j]
|
|
||||||
#using Piyush's code for computing range and azimuth offsets
|
|
||||||
midRange = referenceSwath.startingRange + referenceSwath.rangePixelSize * referenceSwath.numberOfSamples * 0.5
|
|
||||||
midSensingStart = referenceSwath.sensingStart + datetime.timedelta(seconds = referenceSwath.numberOfLines * 0.5 / referenceSwath.prf)
|
|
||||||
llh = self.reference.track.orbit.rdr2geo(midSensingStart, midRange)
|
|
||||||
slvaz, slvrng = self.secondary.track.orbit.geo2rdr(llh)
|
|
||||||
###Translate to offsets
|
|
||||||
#note that secondary range pixel size and prf might be different from reference, here we assume there is a virtual secondary with same
|
|
||||||
#range pixel size and prf
|
|
||||||
rgoff = ((slvrng - secondarySwath.startingRange) / referenceSwath.rangePixelSize) - referenceSwath.numberOfSamples * 0.5
|
|
||||||
azoff = ((slvaz - secondarySwath.sensingStart).total_seconds() * referenceSwath.prf) - referenceSwath.numberOfLines * 0.5
|
|
||||||
|
|
||||||
#compute burst synchronization
|
|
||||||
#burst parameters for ScanSAR wide mode not estimed yet
|
|
||||||
if self._insar.modeCombination == 21:
|
|
||||||
scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
|
|
||||||
#secondary burst start times corresponding to reference burst start times (100% synchronization)
|
|
||||||
scburstStartLines = np.arange(scburstStartLine - 100000*referenceSwath.burstCycleLength, \
|
|
||||||
scburstStartLine + 100000*referenceSwath.burstCycleLength, \
|
|
||||||
referenceSwath.burstCycleLength)
|
|
||||||
dscburstStartLines = -((secondarySwath.burstStartTime - secondarySwath.sensingStart).total_seconds() * secondarySwath.prf - scburstStartLines)
|
|
||||||
#find the difference with minimum absolute value
|
|
||||||
unsynLines = dscburstStartLines[np.argmin(np.absolute(dscburstStartLines))]
|
|
||||||
if np.absolute(unsynLines) >= secondarySwath.burstLength:
|
|
||||||
synLines = 0
|
|
||||||
if unsynLines > 0:
|
|
||||||
unsynLines = secondarySwath.burstLength
|
|
||||||
else:
|
|
||||||
unsynLines = -secondarySwath.burstLength
|
|
||||||
else:
|
|
||||||
synLines = secondarySwath.burstLength - np.absolute(unsynLines)
|
|
||||||
|
|
||||||
unsynTime += unsynLines / referenceSwath.prf
|
|
||||||
synPercentage += synLines / referenceSwath.burstLength * 100.0
|
|
||||||
|
|
||||||
catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(synLines / referenceSwath.burstLength * 100.0), 'runPreprocessor')
|
|
||||||
|
|
||||||
############################################################################################
|
|
||||||
#illustration of the sign of the number of unsynchronized lines (unsynLines)
|
|
||||||
#The convention is the same as ampcor offset, that is,
|
|
||||||
# secondaryLineNumber = referenceLineNumber + unsynLines
|
|
||||||
#
|
|
||||||
# |-----------------------| ------------
|
|
||||||
# | | ^
|
|
||||||
# | | |
|
|
||||||
# | | | unsynLines < 0
|
|
||||||
# | | |
|
|
||||||
# | | \ /
|
|
||||||
# | | |-----------------------|
|
|
||||||
# | | | |
|
|
||||||
# | | | |
|
|
||||||
# |-----------------------| | |
|
|
||||||
# Reference Burst | |
|
|
||||||
# | |
|
|
||||||
# | |
|
|
||||||
# | |
|
|
||||||
# | |
|
|
||||||
# |-----------------------|
|
|
||||||
# Secondary Burst
|
|
||||||
#
|
|
||||||
#
|
|
||||||
############################################################################################
|
|
||||||
|
|
||||||
##burst parameters for ScanSAR wide mode not estimed yet
|
|
||||||
elif self._insar.modeCombination == 31:
|
|
||||||
#scansar is reference
|
|
||||||
scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
|
|
||||||
#secondary burst start times corresponding to reference burst start times (100% synchronization)
|
|
||||||
for k in range(-100000, 100000):
|
|
||||||
saz_burstx = scburstStartLine + referenceSwath.burstCycleLength * k
|
|
||||||
st_burstx = secondarySwath.sensingStart + datetime.timedelta(seconds=saz_burstx / referenceSwath.prf)
|
|
||||||
if saz_burstx >= 0.0 and saz_burstx <= secondarySwath.numberOfLines -1:
|
|
||||||
secondarySwath.burstStartTime = st_burstx
|
|
||||||
secondarySwath.burstLength = referenceSwath.burstLength
|
|
||||||
secondarySwath.burstCycleLength = referenceSwath.burstCycleLength
|
|
||||||
secondarySwath.swathNumber = referenceSwath.swathNumber
|
|
||||||
break
|
|
||||||
#unsynLines = 0
|
|
||||||
#synLines = referenceSwath.burstLength
|
|
||||||
#unsynTime += unsynLines / referenceSwath.prf
|
|
||||||
#synPercentage += synLines / referenceSwath.burstLength * 100.0
|
|
||||||
catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(100.0), 'runPreprocessor')
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
#overwrite original frame parameter file
|
|
||||||
if self._insar.modeCombination == 31:
|
|
||||||
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
|
||||||
self._insar.saveProduct(self.secondary.track.frames[i], os.path.join(frameDir, self._insar.secondaryFrameParameter))
|
|
||||||
|
|
||||||
#getting average
|
|
||||||
if self._insar.modeCombination == 21:
|
|
||||||
unsynTime /= numberOfFrames*numberOfSwaths
|
|
||||||
synPercentage /= numberOfFrames*numberOfSwaths
|
|
||||||
elif self._insar.modeCombination == 31:
|
|
||||||
unsynTime = 0.
|
|
||||||
synPercentage = 100.
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
#record results
|
|
||||||
if (self._insar.modeCombination == 21) or (self._insar.modeCombination == 31):
|
|
||||||
self._insar.burstUnsynchronizedTime = unsynTime
|
|
||||||
self._insar.burstSynchronization = synPercentage
|
|
||||||
catalog.addItem('burst synchronization averaged', '%.1f%%'%(synPercentage), 'runPreprocessor')
|
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
#3. compute baseline
|
|
||||||
##################################################
|
|
||||||
#only compute baseline at four corners and center of the reference track
|
|
||||||
bboxRdr = getBboxRdr(self.reference.track)
|
|
||||||
|
|
||||||
rangeMin = bboxRdr[0]
|
|
||||||
rangeMax = bboxRdr[1]
|
|
||||||
azimuthTimeMin = bboxRdr[2]
|
|
||||||
azimuthTimeMax = bboxRdr[3]
|
|
||||||
|
|
||||||
azimuthTimeMid = azimuthTimeMin+datetime.timedelta(seconds=(azimuthTimeMax-azimuthTimeMin).total_seconds()/2.0)
|
|
||||||
rangeMid = (rangeMin + rangeMax) / 2.0
|
|
||||||
|
|
||||||
points = [[azimuthTimeMin, rangeMin],
|
|
||||||
[azimuthTimeMin, rangeMax],
|
|
||||||
[azimuthTimeMax, rangeMin],
|
|
||||||
[azimuthTimeMax, rangeMax],
|
|
||||||
[azimuthTimeMid, rangeMid]]
|
|
||||||
|
|
||||||
Bpar = []
|
|
||||||
Bperp = []
|
|
||||||
#modify Piyush's code for computing baslines
|
|
||||||
refElp = Planet(pname='Earth').ellipsoid
|
|
||||||
for x in points:
|
|
||||||
referenceSV = self.reference.track.orbit.interpolate(x[0], method='hermite')
|
|
||||||
target = self.reference.track.orbit.rdr2geo(x[0], x[1])
|
|
||||||
|
|
||||||
slvTime, slvrng = self.secondary.track.orbit.geo2rdr(target)
|
|
||||||
secondarySV = self.secondary.track.orbit.interpolateOrbit(slvTime, method='hermite')
|
|
||||||
|
|
||||||
targxyz = np.array(refElp.LLH(target[0], target[1], target[2]).ecef().tolist())
|
|
||||||
mxyz = np.array(referenceSV.getPosition())
|
|
||||||
mvel = np.array(referenceSV.getVelocity())
|
|
||||||
sxyz = np.array(secondarySV.getPosition())
|
|
||||||
|
|
||||||
#to fix abrupt change near zero in baseline grid. JUN-05-2020
|
|
||||||
mvelunit = mvel / np.linalg.norm(mvel)
|
|
||||||
sxyz = sxyz - np.dot ( sxyz-mxyz, mvelunit) * mvelunit
|
|
||||||
|
|
||||||
aa = np.linalg.norm(sxyz-mxyz)
|
|
||||||
costheta = (x[1]*x[1] + aa*aa - slvrng*slvrng)/(2.*x[1]*aa)
|
|
||||||
|
|
||||||
Bpar.append(aa*costheta)
|
|
||||||
|
|
||||||
perp = aa * np.sqrt(1 - costheta*costheta)
|
|
||||||
direction = np.sign(np.dot( np.cross(targxyz-mxyz, sxyz-mxyz), mvel))
|
|
||||||
Bperp.append(direction*perp)
|
|
||||||
|
|
||||||
catalog.addItem('parallel baseline at upperleft of reference track', Bpar[0], 'runPreprocessor')
|
|
||||||
catalog.addItem('parallel baseline at upperright of reference track', Bpar[1], 'runPreprocessor')
|
|
||||||
catalog.addItem('parallel baseline at lowerleft of reference track', Bpar[2], 'runPreprocessor')
|
|
||||||
catalog.addItem('parallel baseline at lowerright of reference track', Bpar[3], 'runPreprocessor')
|
|
||||||
catalog.addItem('parallel baseline at center of reference track', Bpar[4], 'runPreprocessor')
|
|
||||||
|
|
||||||
catalog.addItem('perpendicular baseline at upperleft of reference track', Bperp[0], 'runPreprocessor')
|
|
||||||
catalog.addItem('perpendicular baseline at upperright of reference track', Bperp[1], 'runPreprocessor')
|
|
||||||
catalog.addItem('perpendicular baseline at lowerleft of reference track', Bperp[2], 'runPreprocessor')
|
|
||||||
catalog.addItem('perpendicular baseline at lowerright of reference track', Bperp[3], 'runPreprocessor')
|
|
||||||
catalog.addItem('perpendicular baseline at center of reference track', Bperp[4], 'runPreprocessor')
|
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
#4. compute bounding box
|
|
||||||
##################################################
|
|
||||||
referenceBbox = getBboxGeo(self.reference.track)
|
|
||||||
secondaryBbox = getBboxGeo(self.secondary.track)
|
|
||||||
|
|
||||||
catalog.addItem('reference bounding box', referenceBbox, 'runPreprocessor')
|
|
||||||
catalog.addItem('secondary bounding box', secondaryBbox, 'runPreprocessor')
|
|
||||||
|
|
||||||
|
|
||||||
catalog.printToLog(logger, "runPreprocessor")
|
catalog.printToLog(logger, "runPreprocessor")
|
||||||
self._insar.procDoc.addAllFromCatalog(catalog)
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@ logger = logging.getLogger('isce.alos2insar.runRdr2Geo')
|
||||||
def runRdr2Geo(self):
|
def runRdr2Geo(self):
|
||||||
'''compute lat/lon/hgt
|
'''compute lat/lon/hgt
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,20 @@ logger = logging.getLogger('isce.alos2insar.runRdrDemOffset')
|
||||||
def runRdrDemOffset(self):
|
def runRdrDemOffset(self):
|
||||||
'''estimate between radar image and dem
|
'''estimate between radar image and dem
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
referenceTrack = self._insar.loadTrack(reference=True)
|
referenceTrack = self._insar.loadTrack(reference=True)
|
||||||
|
|
||||||
|
rdrDemOffset(self, referenceTrack, catalog=catalog)
|
||||||
|
|
||||||
|
|
||||||
|
def rdrDemOffset(self, referenceTrack, catalog=None):
|
||||||
|
|
||||||
demFile = os.path.abspath(self._insar.dem)
|
demFile = os.path.abspath(self._insar.dem)
|
||||||
|
|
||||||
insarDir = 'insar'
|
insarDir = 'insar'
|
||||||
|
|
@ -96,13 +106,15 @@ def runRdrDemOffset(self):
|
||||||
if (landRatio <= 0.00125):
|
if (landRatio <= 0.00125):
|
||||||
print('\n\nWARNING: land area too small for estimating offsets between radar and dem')
|
print('\n\nWARNING: land area too small for estimating offsets between radar and dem')
|
||||||
print('do not estimate offsets between radar and dem\n\n')
|
print('do not estimate offsets between radar and dem\n\n')
|
||||||
self._insar.radarDemAffineTransform = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
|
if catalog is not None:
|
||||||
catalog.addItem('warning message', 'land area too small for estimating offsets between radar and dem', 'runRdrDemOffset')
|
self._insar.radarDemAffineTransform = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
|
||||||
|
catalog.addItem('warning message', 'land area too small for estimating offsets between radar and dem', 'runRdrDemOffset')
|
||||||
|
|
||||||
os.chdir('../../')
|
os.chdir('../../')
|
||||||
|
|
||||||
catalog.printToLog(logger, "runRdrDemOffset")
|
if catalog is not None:
|
||||||
self._insar.procDoc.addAllFromCatalog(catalog)
|
catalog.printToLog(logger, "runRdrDemOffset")
|
||||||
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -130,8 +142,9 @@ def runRdrDemOffset(self):
|
||||||
if numberOfOffsetsAzimuth < 10:
|
if numberOfOffsetsAzimuth < 10:
|
||||||
numberOfOffsetsAzimuth = 10
|
numberOfOffsetsAzimuth = 10
|
||||||
|
|
||||||
catalog.addItem('number of range offsets', '{}'.format(numberOfOffsetsRange), 'runRdrDemOffset')
|
if catalog is not None:
|
||||||
catalog.addItem('number of azimuth offsets', '{}'.format(numberOfOffsetsAzimuth), 'runRdrDemOffset')
|
catalog.addItem('number of range offsets', '{}'.format(numberOfOffsetsRange), 'runRdrDemOffset')
|
||||||
|
catalog.addItem('number of azimuth offsets', '{}'.format(numberOfOffsetsAzimuth), 'runRdrDemOffset')
|
||||||
|
|
||||||
#matching
|
#matching
|
||||||
ampcor = Ampcor(name='insarapp_slcs_ampcor')
|
ampcor = Ampcor(name='insarapp_slcs_ampcor')
|
||||||
|
|
@ -247,12 +260,14 @@ def runRdrDemOffset(self):
|
||||||
print('\n\nWARNING: too few points left after culling, {} left'.format(numCullOffsets))
|
print('\n\nWARNING: too few points left after culling, {} left'.format(numCullOffsets))
|
||||||
print('do not estimate offsets between radar and dem\n\n')
|
print('do not estimate offsets between radar and dem\n\n')
|
||||||
self._insar.radarDemAffineTransform = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
|
self._insar.radarDemAffineTransform = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
|
||||||
catalog.addItem('warning message', 'too few points left after culling, {} left'.format(numCullOffsets), 'runRdrDemOffset')
|
if catalog is not None:
|
||||||
|
catalog.addItem('warning message', 'too few points left after culling, {} left'.format(numCullOffsets), 'runRdrDemOffset')
|
||||||
|
|
||||||
os.chdir('../../')
|
os.chdir('../../')
|
||||||
|
|
||||||
catalog.printToLog(logger, "runRdrDemOffset")
|
if catalog is not None:
|
||||||
self._insar.procDoc.addAllFromCatalog(catalog)
|
catalog.printToLog(logger, "runRdrDemOffset")
|
||||||
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -277,8 +292,9 @@ def runRdrDemOffset(self):
|
||||||
os.chdir('../../')
|
os.chdir('../../')
|
||||||
|
|
||||||
|
|
||||||
catalog.printToLog(logger, "runRdrDemOffset")
|
if catalog is not None:
|
||||||
self._insar.procDoc.addAllFromCatalog(catalog)
|
catalog.printToLog(logger, "runRdrDemOffset")
|
||||||
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
||||||
|
|
||||||
def simulateRadar(hgtfile, simfile, scale=3.0, offset=100.0):
|
def simulateRadar(hgtfile, simfile, scale=3.0, offset=100.0):
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,10 @@ logger = logging.getLogger('isce.alos2insar.runRectRangeOffset')
|
||||||
def runRectRangeOffset(self):
|
def runRectRangeOffset(self):
|
||||||
'''rectify range offset
|
'''rectify range offset
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,30 @@ def runSlcMosaic(self):
|
||||||
if len(referenceTrack.frames) > 1:
|
if len(referenceTrack.frames) > 1:
|
||||||
matchingMode=1
|
matchingMode=1
|
||||||
|
|
||||||
|
#determine whether reference offset from matching is already done in previous InSAR processing.
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
referenceEstimated = False
|
||||||
|
else:
|
||||||
|
if self.frameOffsetMatching == False:
|
||||||
|
referenceEstimated = False
|
||||||
|
else:
|
||||||
|
referenceEstimated = True
|
||||||
|
else:
|
||||||
|
if self.frameOffsetMatching == False:
|
||||||
|
referenceEstimated = False
|
||||||
|
else:
|
||||||
|
referenceEstimated = True
|
||||||
|
|
||||||
#if reference offsets from matching are not already computed
|
#if reference offsets from matching are not already computed
|
||||||
if self.frameOffsetMatching == False:
|
#if self.frameOffsetMatching == False:
|
||||||
|
if referenceEstimated == False:
|
||||||
offsetReference = frameOffset(referenceTrack, self._insar.referenceSlc, self._insar.referenceFrameOffset,
|
offsetReference = frameOffset(referenceTrack, self._insar.referenceSlc, self._insar.referenceFrameOffset,
|
||||||
crossCorrelation=True, matchingMode=matchingMode)
|
crossCorrelation=True, matchingMode=matchingMode)
|
||||||
offsetSecondary = frameOffset(secondaryTrack, self._insar.secondarySlc, self._insar.secondaryFrameOffset,
|
offsetSecondary = frameOffset(secondaryTrack, self._insar.secondarySlc, self._insar.secondaryFrameOffset,
|
||||||
crossCorrelation=True, matchingMode=matchingMode)
|
crossCorrelation=True, matchingMode=matchingMode)
|
||||||
if self.frameOffsetMatching == False:
|
#if self.frameOffsetMatching == False:
|
||||||
|
if referenceEstimated == False:
|
||||||
self._insar.frameRangeOffsetMatchingReference = offsetReference[2]
|
self._insar.frameRangeOffsetMatchingReference = offsetReference[2]
|
||||||
self._insar.frameAzimuthOffsetMatchingReference = offsetReference[3]
|
self._insar.frameAzimuthOffsetMatchingReference = offsetReference[3]
|
||||||
self._insar.frameRangeOffsetMatchingSecondary = offsetSecondary[2]
|
self._insar.frameRangeOffsetMatchingSecondary = offsetSecondary[2]
|
||||||
|
|
@ -110,6 +127,43 @@ def runSlcMosaic(self):
|
||||||
secondaryTrack.dopplerVsPixel = secondaryTrack.frames[0].swaths[0].dopplerVsPixel
|
secondaryTrack.dopplerVsPixel = secondaryTrack.frames[0].swaths[0].dopplerVsPixel
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
#in case InSAR, and therefore runSwathMosaic, was not done previously
|
||||||
|
for i, frameNumber in enumerate(self._insar.referenceFrames):
|
||||||
|
#update frame parameters
|
||||||
|
#########################################################
|
||||||
|
frame = referenceTrack.frames[i]
|
||||||
|
#mosaic size
|
||||||
|
frame.numberOfSamples = frame.swaths[0].numberOfSamples
|
||||||
|
frame.numberOfLines = frame.swaths[0].numberOfLines
|
||||||
|
#NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
|
||||||
|
#range parameters
|
||||||
|
frame.startingRange = frame.swaths[0].startingRange
|
||||||
|
frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate
|
||||||
|
frame.rangePixelSize = frame.swaths[0].rangePixelSize
|
||||||
|
#azimuth parameters
|
||||||
|
frame.sensingStart = frame.swaths[0].sensingStart
|
||||||
|
frame.prf = frame.swaths[0].prf
|
||||||
|
frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize
|
||||||
|
frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval
|
||||||
|
|
||||||
|
#update frame parameters, secondary
|
||||||
|
#########################################################
|
||||||
|
frame = secondaryTrack.frames[i]
|
||||||
|
#mosaic size
|
||||||
|
frame.numberOfSamples = frame.swaths[0].numberOfSamples
|
||||||
|
frame.numberOfLines = frame.swaths[0].numberOfLines
|
||||||
|
#NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
|
||||||
|
#range parameters
|
||||||
|
frame.startingRange = frame.swaths[0].startingRange
|
||||||
|
frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate
|
||||||
|
frame.rangePixelSize = frame.swaths[0].rangePixelSize
|
||||||
|
#azimuth parameters
|
||||||
|
frame.sensingStart = frame.swaths[0].sensingStart
|
||||||
|
frame.prf = frame.swaths[0].prf
|
||||||
|
frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize
|
||||||
|
frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval
|
||||||
|
|
||||||
|
|
||||||
#mosaic reference slc
|
#mosaic reference slc
|
||||||
#########################################################
|
#########################################################
|
||||||
#choose offsets
|
#choose offsets
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,11 @@ logger = logging.getLogger('isce.alos2insar.runSlcOffset')
|
||||||
def runSlcOffset(self):
|
def runSlcOffset(self):
|
||||||
'''estimate SLC offsets
|
'''estimate SLC offsets
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
print('\nInSAR processing not requested, skip this and the remaining InSAR steps...')
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@ logger = logging.getLogger('isce.alos2insar.runSwathMosaic')
|
||||||
def runSwathMosaic(self):
|
def runSwathMosaic(self):
|
||||||
'''mosaic subswaths
|
'''mosaic subswaths
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
@ -211,8 +215,10 @@ def swathMosaic(frame, inputFiles, outputfile, rangeOffsets, azimuthOffsets, num
|
||||||
rectWidth.append( int(swaths[i].numberOfSamples / numberOfRangeLooks) )
|
rectWidth.append( int(swaths[i].numberOfSamples / numberOfRangeLooks) )
|
||||||
rectLength.append( int(swaths[i].numberOfLines / numberOfAzimuthLooks) )
|
rectLength.append( int(swaths[i].numberOfLines / numberOfAzimuthLooks) )
|
||||||
else:
|
else:
|
||||||
rectWidth.append( int(1.0 / rangeScale[i] * int(swaths[i].numberOfSamples / numberOfRangeLooks)) )
|
rectWidth.append( round(1.0 / rangeScale[i] * int(swaths[i].numberOfSamples / numberOfRangeLooks)) )
|
||||||
rectLength.append( int(1.0 / azimuthScale[i] * int(swaths[i].numberOfLines / numberOfAzimuthLooks)) )
|
rectLength.append( round(1.0 / azimuthScale[i] * int(swaths[i].numberOfLines / numberOfAzimuthLooks)) )
|
||||||
|
#rectWidth.append( int(1.0 / rangeScale[i] * int(swaths[i].numberOfSamples / numberOfRangeLooks)) )
|
||||||
|
#rectLength.append( int(1.0 / azimuthScale[i] * int(swaths[i].numberOfLines / numberOfAzimuthLooks)) )
|
||||||
|
|
||||||
#convert original offset to offset for images with looks
|
#convert original offset to offset for images with looks
|
||||||
#use list instead of np.array to make it consistent with the rest of the code
|
#use list instead of np.array to make it consistent with the rest of the code
|
||||||
|
|
@ -239,71 +245,80 @@ def swathMosaic(frame, inputFiles, outputfile, rangeOffsets, azimuthOffsets, num
|
||||||
os.remove(rinfs[i])
|
os.remove(rinfs[i])
|
||||||
os.symlink(inf, rinfs[i])
|
os.symlink(inf, rinfs[i])
|
||||||
else:
|
else:
|
||||||
infImg = isceobj.createImage()
|
#no need to resample
|
||||||
infImg.load(inf+'.xml')
|
if (abs(rangeOffsets2[i] - round(rangeOffsets2[i])) < 0.0001) and (abs(azimuthOffsets2[i] - round(azimuthOffsets2[i])) < 0.0001):
|
||||||
rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
|
if os.path.isfile(rinfs[i]):
|
||||||
azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i])
|
os.remove(rinfs[i])
|
||||||
|
os.symlink(inf, rinfs[i])
|
||||||
|
#all of the following use of rangeOffsets2/azimuthOffsets2 is inside int(), we do the following in case it is like
|
||||||
|
#4.99999999999...
|
||||||
|
rangeOffsets2[i] = round(rangeOffsets2[i])
|
||||||
|
azimuthOffsets2[i] = round(azimuthOffsets2[i])
|
||||||
|
else:
|
||||||
|
infImg = isceobj.createImage()
|
||||||
|
infImg.load(inf+'.xml')
|
||||||
|
rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
|
||||||
|
azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i])
|
||||||
|
|
||||||
|
if resamplingMethod == 0:
|
||||||
|
rect_with_looks(inf,
|
||||||
|
rinfs[i],
|
||||||
|
infImg.width, infImg.length,
|
||||||
|
rectWidth[i], rectLength[i],
|
||||||
|
rangeScale[i], 0.0,
|
||||||
|
0.0,azimuthScale[i],
|
||||||
|
rangeOffsets2Frac * rangeScale[i], azimuthOffsets2Frac * azimuthScale[i],
|
||||||
|
1,1,
|
||||||
|
1,1,
|
||||||
|
'COMPLEX',
|
||||||
|
'Bilinear')
|
||||||
|
elif resamplingMethod == 1:
|
||||||
|
#decompose amplitude and phase
|
||||||
|
phaseFile = 'phase'
|
||||||
|
amplitudeFile = 'amplitude'
|
||||||
|
data = np.fromfile(inf, dtype=np.complex64).reshape(infImg.length, infImg.width)
|
||||||
|
phase = np.exp(np.complex64(1j) * np.angle(data))
|
||||||
|
phase[np.nonzero(data==0)] = 0
|
||||||
|
phase.astype(np.complex64).tofile(phaseFile)
|
||||||
|
amplitude = np.absolute(data)
|
||||||
|
amplitude.astype(np.float32).tofile(amplitudeFile)
|
||||||
|
|
||||||
if resamplingMethod == 0:
|
#resampling
|
||||||
rect_with_looks(inf,
|
phaseRectFile = 'phaseRect'
|
||||||
rinfs[i],
|
amplitudeRectFile = 'amplitudeRect'
|
||||||
infImg.width, infImg.length,
|
rect_with_looks(phaseFile,
|
||||||
rectWidth[i], rectLength[i],
|
phaseRectFile,
|
||||||
rangeScale[i], 0.0,
|
infImg.width, infImg.length,
|
||||||
0.0,azimuthScale[i],
|
rectWidth[i], rectLength[i],
|
||||||
rangeOffsets2Frac * rangeScale[i], azimuthOffsets2Frac * azimuthScale[i],
|
rangeScale[i], 0.0,
|
||||||
1,1,
|
0.0,azimuthScale[i],
|
||||||
1,1,
|
rangeOffsets2Frac * rangeScale[i], azimuthOffsets2Frac * azimuthScale[i],
|
||||||
'COMPLEX',
|
1,1,
|
||||||
'Bilinear')
|
1,1,
|
||||||
elif resamplingMethod == 1:
|
'COMPLEX',
|
||||||
#decompose amplitude and phase
|
'Sinc')
|
||||||
phaseFile = 'phase'
|
rect_with_looks(amplitudeFile,
|
||||||
amplitudeFile = 'amplitude'
|
amplitudeRectFile,
|
||||||
data = np.fromfile(inf, dtype=np.complex64).reshape(infImg.length, infImg.width)
|
infImg.width, infImg.length,
|
||||||
phase = np.exp(np.complex64(1j) * np.angle(data))
|
rectWidth[i], rectLength[i],
|
||||||
phase[np.nonzero(data==0)] = 0
|
rangeScale[i], 0.0,
|
||||||
phase.astype(np.complex64).tofile(phaseFile)
|
0.0,azimuthScale[i],
|
||||||
amplitude = np.absolute(data)
|
rangeOffsets2Frac * rangeScale[i], azimuthOffsets2Frac * azimuthScale[i],
|
||||||
amplitude.astype(np.float32).tofile(amplitudeFile)
|
1,1,
|
||||||
|
1,1,
|
||||||
|
'REAL',
|
||||||
|
'Bilinear')
|
||||||
|
|
||||||
#resampling
|
#recombine amplitude and phase
|
||||||
phaseRectFile = 'phaseRect'
|
phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(rectLength[i], rectWidth[i])
|
||||||
amplitudeRectFile = 'amplitudeRect'
|
amplitude = np.fromfile(amplitudeRectFile, dtype=np.float32).reshape(rectLength[i], rectWidth[i])
|
||||||
rect_with_looks(phaseFile,
|
(phase*amplitude).astype(np.complex64).tofile(rinfs[i])
|
||||||
phaseRectFile,
|
|
||||||
infImg.width, infImg.length,
|
|
||||||
rectWidth[i], rectLength[i],
|
|
||||||
rangeScale[i], 0.0,
|
|
||||||
0.0,azimuthScale[i],
|
|
||||||
rangeOffsets2Frac * rangeScale[i], azimuthOffsets2Frac * azimuthScale[i],
|
|
||||||
1,1,
|
|
||||||
1,1,
|
|
||||||
'COMPLEX',
|
|
||||||
'Sinc')
|
|
||||||
rect_with_looks(amplitudeFile,
|
|
||||||
amplitudeRectFile,
|
|
||||||
infImg.width, infImg.length,
|
|
||||||
rectWidth[i], rectLength[i],
|
|
||||||
rangeScale[i], 0.0,
|
|
||||||
0.0,azimuthScale[i],
|
|
||||||
rangeOffsets2Frac * rangeScale[i], azimuthOffsets2Frac * azimuthScale[i],
|
|
||||||
1,1,
|
|
||||||
1,1,
|
|
||||||
'REAL',
|
|
||||||
'Bilinear')
|
|
||||||
|
|
||||||
#recombine amplitude and phase
|
#tidy up
|
||||||
phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(rectLength[i], rectWidth[i])
|
os.remove(phaseFile)
|
||||||
amplitude = np.fromfile(amplitudeRectFile, dtype=np.float32).reshape(rectLength[i], rectWidth[i])
|
os.remove(amplitudeFile)
|
||||||
(phase*amplitude).astype(np.complex64).tofile(rinfs[i])
|
os.remove(phaseRectFile)
|
||||||
|
os.remove(amplitudeRectFile)
|
||||||
#tidy up
|
|
||||||
os.remove(phaseFile)
|
|
||||||
os.remove(amplitudeFile)
|
|
||||||
os.remove(phaseRectFile)
|
|
||||||
os.remove(amplitudeRectFile)
|
|
||||||
|
|
||||||
|
|
||||||
#determine output width and length
|
#determine output width and length
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ logger = logging.getLogger('isce.alos2insar.runSwathOffset')
|
||||||
def runSwathOffset(self):
|
def runSwathOffset(self):
|
||||||
'''estimate swath offsets.
|
'''estimate swath offsets.
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,23 @@ logger = logging.getLogger('isce.alos2insar.runUnwrapSnaphu')
|
||||||
def runUnwrapSnaphu(self):
|
def runUnwrapSnaphu(self):
|
||||||
'''unwrap filtered interferogram
|
'''unwrap filtered interferogram
|
||||||
'''
|
'''
|
||||||
|
if hasattr(self, 'doInSAR'):
|
||||||
|
if not self.doInSAR:
|
||||||
|
return
|
||||||
|
|
||||||
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
self.updateParamemetersFromUser()
|
self.updateParamemetersFromUser()
|
||||||
|
|
||||||
referenceTrack = self._insar.loadTrack(reference=True)
|
referenceTrack = self._insar.loadTrack(reference=True)
|
||||||
#secondaryTrack = self._insar.loadTrack(reference=False)
|
#secondaryTrack = self._insar.loadTrack(reference=False)
|
||||||
|
|
||||||
|
unwrapSnaphu(self, referenceTrack)
|
||||||
|
|
||||||
|
catalog.printToLog(logger, "runUnwrapSnaphu")
|
||||||
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
||||||
|
|
||||||
|
def unwrapSnaphu(self, referenceTrack):
|
||||||
insarDir = 'insar'
|
insarDir = 'insar'
|
||||||
os.makedirs(insarDir, exist_ok=True)
|
os.makedirs(insarDir, exist_ok=True)
|
||||||
os.chdir(insarDir)
|
os.chdir(insarDir)
|
||||||
|
|
@ -70,21 +81,20 @@ def runUnwrapSnaphu(self):
|
||||||
wbdImage.load(self._insar.multilookWbdOut+'.xml')
|
wbdImage.load(self._insar.multilookWbdOut+'.xml')
|
||||||
width = wbdImage.width
|
width = wbdImage.width
|
||||||
length = wbdImage.length
|
length = wbdImage.length
|
||||||
if not os.path.exists(self._insar.multilookWbdOut):
|
#if not os.path.exists(self._insar.multilookWbdOut):
|
||||||
catalog.addItem('warning message', 'requested masking interferogram with water body, but water body does not exist', 'runUnwrapSnaphu')
|
# catalog.addItem('warning message', 'requested masking interferogram with water body, but water body does not exist', 'runUnwrapSnaphu')
|
||||||
else:
|
#else:
|
||||||
wbd = np.fromfile(self._insar.multilookWbdOut, dtype=np.int8).reshape(length, width)
|
wbd = np.fromfile(self._insar.multilookWbdOut, dtype=np.int8).reshape(length, width)
|
||||||
unw=np.memmap(self._insar.unwrappedInterferogram, dtype='float32', mode='r+', shape=(length*2, width))
|
unw=np.memmap(self._insar.unwrappedInterferogram, dtype='float32', mode='r+', shape=(length*2, width))
|
||||||
(unw[0:length*2:2, :])[np.nonzero(wbd==-1)]=0
|
(unw[0:length*2:2, :])[np.nonzero(wbd==-1)]=0
|
||||||
(unw[1:length*2:2, :])[np.nonzero(wbd==-1)]=0
|
(unw[1:length*2:2, :])[np.nonzero(wbd==-1)]=0
|
||||||
del unw
|
del unw
|
||||||
unw=np.memmap(self._insar.unwrappedMaskedInterferogram, dtype='float32', mode='r+', shape=(length*2, width))
|
unw=np.memmap(self._insar.unwrappedMaskedInterferogram, dtype='float32', mode='r+', shape=(length*2, width))
|
||||||
(unw[0:length*2:2, :])[np.nonzero(wbd==-1)]=0
|
(unw[0:length*2:2, :])[np.nonzero(wbd==-1)]=0
|
||||||
(unw[1:length*2:2, :])[np.nonzero(wbd==-1)]=0
|
(unw[1:length*2:2, :])[np.nonzero(wbd==-1)]=0
|
||||||
del unw, wbd
|
del unw, wbd
|
||||||
|
|
||||||
os.chdir('../')
|
os.chdir('../')
|
||||||
|
|
||||||
catalog.printToLog(logger, "runUnwrapSnaphu")
|
|
||||||
self._insar.procDoc.addAllFromCatalog(catalog)
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ def createUnwrap2Stage(other, do_unwrap_2stage = None, unwrapperName = None):
|
||||||
|
|
||||||
|
|
||||||
createPreprocessor = _factory("runPreprocessor")
|
createPreprocessor = _factory("runPreprocessor")
|
||||||
|
createBaseline = _factory("runBaseline", path = "isceobj.Alos2Proc.")
|
||||||
createExtractBurst = _factory("runExtractBurst")
|
createExtractBurst = _factory("runExtractBurst")
|
||||||
createDownloadDem = _factory("runDownloadDem", path = "isceobj.Alos2Proc.")
|
createDownloadDem = _factory("runDownloadDem", path = "isceobj.Alos2Proc.")
|
||||||
createCoregGeom = _factory("runCoregGeom")
|
createCoregGeom = _factory("runCoregGeom")
|
||||||
|
|
@ -93,6 +94,7 @@ createCoherence = _factory("runCoherence", path = "isceobj.Alos2Proc.")
|
||||||
createIonSubband = _factory("runIonSubband")
|
createIonSubband = _factory("runIonSubband")
|
||||||
createIonUwrap = _factory("runIonUwrap", path = "isceobj.Alos2Proc.")
|
createIonUwrap = _factory("runIonUwrap", path = "isceobj.Alos2Proc.")
|
||||||
createIonFilt = _factory("runIonFilt", path = "isceobj.Alos2Proc.")
|
createIonFilt = _factory("runIonFilt", path = "isceobj.Alos2Proc.")
|
||||||
|
createIonCorrect = _factory("runIonCorrect", path = "isceobj.Alos2Proc.")
|
||||||
createFilt = _factory("runFilt", path = "isceobj.Alos2Proc.")
|
createFilt = _factory("runFilt", path = "isceobj.Alos2Proc.")
|
||||||
createUnwrapSnaphu = _factory("runUnwrapSnaphu", path = "isceobj.Alos2Proc.")
|
createUnwrapSnaphu = _factory("runUnwrapSnaphu", path = "isceobj.Alos2Proc.")
|
||||||
createGeocode = _factory("runGeocode", path = "isceobj.Alos2Proc.")
|
createGeocode = _factory("runGeocode", path = "isceobj.Alos2Proc.")
|
||||||
|
|
|
||||||
|
|
@ -252,30 +252,38 @@ def runIonSubband(self):
|
||||||
#list of input files
|
#list of input files
|
||||||
inputInterferograms = []
|
inputInterferograms = []
|
||||||
inputAmplitudes = []
|
inputAmplitudes = []
|
||||||
phaseDiff = [None]
|
#phaseDiff = [None]
|
||||||
|
swathPhaseDiffIon = [self.swathPhaseDiffLowerIon, self.swathPhaseDiffUpperIon]
|
||||||
|
phaseDiff = swathPhaseDiffIon[k]
|
||||||
|
if swathPhaseDiffIon[k] is None:
|
||||||
|
phaseDiff = None
|
||||||
|
else:
|
||||||
|
phaseDiff = swathPhaseDiffIon[k][i]
|
||||||
|
phaseDiff.insert(0, None)
|
||||||
|
|
||||||
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
||||||
swathDir = 's{}'.format(swathNumber)
|
swathDir = 's{}'.format(swathNumber)
|
||||||
inputInterferograms.append(os.path.join('../', swathDir, self._insar.interferogram))
|
inputInterferograms.append(os.path.join('../', swathDir, self._insar.interferogram))
|
||||||
inputAmplitudes.append(os.path.join('../', swathDir, self._insar.amplitude))
|
inputAmplitudes.append(os.path.join('../', swathDir, self._insar.amplitude))
|
||||||
|
|
||||||
#compute phase needed to be compensated using startingRange
|
# #compute phase needed to be compensated using startingRange
|
||||||
if j >= 1:
|
# if j >= 1:
|
||||||
#phaseDiffSwath1 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange)/subbandRadarWavelength[k]
|
# #phaseDiffSwath1 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange)/subbandRadarWavelength[k]
|
||||||
#phaseDiffSwath2 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange)/subbandRadarWavelength[k]
|
# #phaseDiffSwath2 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange)/subbandRadarWavelength[k]
|
||||||
phaseDiffSwath1 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
|
# phaseDiffSwath1 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
|
||||||
-4.0 * np.pi * secondaryTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
|
# -4.0 * np.pi * secondaryTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
|
||||||
phaseDiffSwath2 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
|
# phaseDiffSwath2 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
|
||||||
-4.0 * np.pi * secondaryTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
|
# -4.0 * np.pi * secondaryTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
|
||||||
if referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange == \
|
# if referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange == \
|
||||||
referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange:
|
# referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange:
|
||||||
#phaseDiff.append(phaseDiffSwath2 - phaseDiffSwath1)
|
# #phaseDiff.append(phaseDiffSwath2 - phaseDiffSwath1)
|
||||||
#if reference and secondary versions are all before or after version 2.025 (starting range error < 0.5 m),
|
# #if reference and secondary versions are all before or after version 2.025 (starting range error < 0.5 m),
|
||||||
#it should be OK to do the above.
|
# #it should be OK to do the above.
|
||||||
#see results in neom where it meets the above requirement, but there is still phase diff
|
# #see results in neom where it meets the above requirement, but there is still phase diff
|
||||||
#to be less risky, we do not input values here
|
# #to be less risky, we do not input values here
|
||||||
phaseDiff.append(None)
|
# phaseDiff.append(None)
|
||||||
else:
|
# else:
|
||||||
phaseDiff.append(None)
|
# phaseDiff.append(None)
|
||||||
|
|
||||||
#note that frame parameters are updated after mosaicking
|
#note that frame parameters are updated after mosaicking
|
||||||
#mosaic amplitudes
|
#mosaic amplitudes
|
||||||
|
|
|
||||||
|
|
@ -258,201 +258,6 @@ def runPreprocessor(self):
|
||||||
self._insar.saveProduct(self.secondary.track, self._insar.secondaryTrackParameter)
|
self._insar.saveProduct(self.secondary.track, self._insar.secondaryTrackParameter)
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
#2. compute burst synchronization
|
|
||||||
##################################################
|
|
||||||
#burst synchronization may slowly change along a track as a result of the changing relative speed of the two flights
|
|
||||||
#in one frame, real unsynchronized time is the same for all swaths
|
|
||||||
unsynTime = 0
|
|
||||||
#real synchronized time/percentage depends on the swath burst length (synTime = burstlength - abs(unsynTime))
|
|
||||||
#synTime = 0
|
|
||||||
synPercentage = 0
|
|
||||||
|
|
||||||
numberOfFrames = len(self._insar.referenceFrames)
|
|
||||||
numberOfSwaths = self._insar.endingSwath - self._insar.startingSwath + 1
|
|
||||||
|
|
||||||
for i, frameNumber in enumerate(self._insar.referenceFrames):
|
|
||||||
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
|
||||||
referenceSwath = self.reference.track.frames[i].swaths[j]
|
|
||||||
secondarySwath = self.secondary.track.frames[i].swaths[j]
|
|
||||||
#using Piyush's code for computing range and azimuth offsets
|
|
||||||
midRange = referenceSwath.startingRange + referenceSwath.rangePixelSize * referenceSwath.numberOfSamples * 0.5
|
|
||||||
midSensingStart = referenceSwath.sensingStart + datetime.timedelta(seconds = referenceSwath.numberOfLines * 0.5 / referenceSwath.prf)
|
|
||||||
llh = self.reference.track.orbit.rdr2geo(midSensingStart, midRange)
|
|
||||||
slvaz, slvrng = self.secondary.track.orbit.geo2rdr(llh)
|
|
||||||
###Translate to offsets
|
|
||||||
#note that secondary range pixel size and prf might be different from reference, here we assume there is a virtual secondary with same
|
|
||||||
#range pixel size and prf
|
|
||||||
rgoff = ((slvrng - secondarySwath.startingRange) / referenceSwath.rangePixelSize) - referenceSwath.numberOfSamples * 0.5
|
|
||||||
azoff = ((slvaz - secondarySwath.sensingStart).total_seconds() * referenceSwath.prf) - referenceSwath.numberOfLines * 0.5
|
|
||||||
|
|
||||||
#compute burst synchronization
|
|
||||||
#burst parameters for ScanSAR wide mode not estimed yet
|
|
||||||
if self._insar.modeCombination == 21:
|
|
||||||
scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
|
|
||||||
#secondary burst start times corresponding to reference burst start times (100% synchronization)
|
|
||||||
scburstStartLines = np.arange(scburstStartLine - 100000*referenceSwath.burstCycleLength, \
|
|
||||||
scburstStartLine + 100000*referenceSwath.burstCycleLength, \
|
|
||||||
referenceSwath.burstCycleLength)
|
|
||||||
dscburstStartLines = -((secondarySwath.burstStartTime - secondarySwath.sensingStart).total_seconds() * secondarySwath.prf - scburstStartLines)
|
|
||||||
#find the difference with minimum absolute value
|
|
||||||
unsynLines = dscburstStartLines[np.argmin(np.absolute(dscburstStartLines))]
|
|
||||||
if np.absolute(unsynLines) >= secondarySwath.burstLength:
|
|
||||||
synLines = 0
|
|
||||||
if unsynLines > 0:
|
|
||||||
unsynLines = secondarySwath.burstLength
|
|
||||||
else:
|
|
||||||
unsynLines = -secondarySwath.burstLength
|
|
||||||
else:
|
|
||||||
synLines = secondarySwath.burstLength - np.absolute(unsynLines)
|
|
||||||
|
|
||||||
unsynTime += unsynLines / referenceSwath.prf
|
|
||||||
synPercentage += synLines / referenceSwath.burstLength * 100.0
|
|
||||||
|
|
||||||
catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(synLines / referenceSwath.burstLength * 100.0), 'runPreprocessor')
|
|
||||||
|
|
||||||
############################################################################################
|
|
||||||
#illustration of the sign of the number of unsynchronized lines (unsynLines)
|
|
||||||
#The convention is the same as ampcor offset, that is,
|
|
||||||
# secondaryLineNumber = referenceLineNumber + unsynLines
|
|
||||||
#
|
|
||||||
# |-----------------------| ------------
|
|
||||||
# | | ^
|
|
||||||
# | | |
|
|
||||||
# | | | unsynLines < 0
|
|
||||||
# | | |
|
|
||||||
# | | \ /
|
|
||||||
# | | |-----------------------|
|
|
||||||
# | | | |
|
|
||||||
# | | | |
|
|
||||||
# |-----------------------| | |
|
|
||||||
# Reference Burst | |
|
|
||||||
# | |
|
|
||||||
# | |
|
|
||||||
# | |
|
|
||||||
# | |
|
|
||||||
# |-----------------------|
|
|
||||||
# Secondary Burst
|
|
||||||
#
|
|
||||||
#
|
|
||||||
############################################################################################
|
|
||||||
|
|
||||||
##burst parameters for ScanSAR wide mode not estimed yet
|
|
||||||
elif self._insar.modeCombination == 31:
|
|
||||||
#scansar is reference
|
|
||||||
scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
|
|
||||||
#secondary burst start times corresponding to reference burst start times (100% synchronization)
|
|
||||||
for k in range(-100000, 100000):
|
|
||||||
saz_burstx = scburstStartLine + referenceSwath.burstCycleLength * k
|
|
||||||
st_burstx = secondarySwath.sensingStart + datetime.timedelta(seconds=saz_burstx / referenceSwath.prf)
|
|
||||||
if saz_burstx >= 0.0 and saz_burstx <= secondarySwath.numberOfLines -1:
|
|
||||||
secondarySwath.burstStartTime = st_burstx
|
|
||||||
secondarySwath.burstLength = referenceSwath.burstLength
|
|
||||||
secondarySwath.burstCycleLength = referenceSwath.burstCycleLength
|
|
||||||
secondarySwath.swathNumber = referenceSwath.swathNumber
|
|
||||||
break
|
|
||||||
#unsynLines = 0
|
|
||||||
#synLines = referenceSwath.burstLength
|
|
||||||
#unsynTime += unsynLines / referenceSwath.prf
|
|
||||||
#synPercentage += synLines / referenceSwath.burstLength * 100.0
|
|
||||||
catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(100.0), 'runPreprocessor')
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
#overwrite original frame parameter file
|
|
||||||
if self._insar.modeCombination == 31:
|
|
||||||
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
|
||||||
self._insar.saveProduct(self.secondary.track.frames[i], os.path.join(frameDir, self._insar.secondaryFrameParameter))
|
|
||||||
|
|
||||||
#getting average
|
|
||||||
if self._insar.modeCombination == 21:
|
|
||||||
unsynTime /= numberOfFrames*numberOfSwaths
|
|
||||||
synPercentage /= numberOfFrames*numberOfSwaths
|
|
||||||
elif self._insar.modeCombination == 31:
|
|
||||||
unsynTime = 0.
|
|
||||||
synPercentage = 100.
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
#record results
|
|
||||||
if (self._insar.modeCombination == 21) or (self._insar.modeCombination == 31):
|
|
||||||
self._insar.burstUnsynchronizedTime = unsynTime
|
|
||||||
self._insar.burstSynchronization = synPercentage
|
|
||||||
catalog.addItem('burst synchronization averaged', '%.1f%%'%(synPercentage), 'runPreprocessor')
|
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
#3. compute baseline
|
|
||||||
##################################################
|
|
||||||
#only compute baseline at four corners and center of the reference track
|
|
||||||
bboxRdr = getBboxRdr(self.reference.track)
|
|
||||||
|
|
||||||
rangeMin = bboxRdr[0]
|
|
||||||
rangeMax = bboxRdr[1]
|
|
||||||
azimuthTimeMin = bboxRdr[2]
|
|
||||||
azimuthTimeMax = bboxRdr[3]
|
|
||||||
|
|
||||||
azimuthTimeMid = azimuthTimeMin+datetime.timedelta(seconds=(azimuthTimeMax-azimuthTimeMin).total_seconds()/2.0)
|
|
||||||
rangeMid = (rangeMin + rangeMax) / 2.0
|
|
||||||
|
|
||||||
points = [[azimuthTimeMin, rangeMin],
|
|
||||||
[azimuthTimeMin, rangeMax],
|
|
||||||
[azimuthTimeMax, rangeMin],
|
|
||||||
[azimuthTimeMax, rangeMax],
|
|
||||||
[azimuthTimeMid, rangeMid]]
|
|
||||||
|
|
||||||
Bpar = []
|
|
||||||
Bperp = []
|
|
||||||
#modify Piyush's code for computing baslines
|
|
||||||
refElp = Planet(pname='Earth').ellipsoid
|
|
||||||
for x in points:
|
|
||||||
referenceSV = self.reference.track.orbit.interpolate(x[0], method='hermite')
|
|
||||||
target = self.reference.track.orbit.rdr2geo(x[0], x[1])
|
|
||||||
|
|
||||||
slvTime, slvrng = self.secondary.track.orbit.geo2rdr(target)
|
|
||||||
secondarySV = self.secondary.track.orbit.interpolateOrbit(slvTime, method='hermite')
|
|
||||||
|
|
||||||
targxyz = np.array(refElp.LLH(target[0], target[1], target[2]).ecef().tolist())
|
|
||||||
mxyz = np.array(referenceSV.getPosition())
|
|
||||||
mvel = np.array(referenceSV.getVelocity())
|
|
||||||
sxyz = np.array(secondarySV.getPosition())
|
|
||||||
|
|
||||||
#to fix abrupt change near zero in baseline grid. JUN-05-2020
|
|
||||||
mvelunit = mvel / np.linalg.norm(mvel)
|
|
||||||
sxyz = sxyz - np.dot ( sxyz-mxyz, mvelunit) * mvelunit
|
|
||||||
|
|
||||||
aa = np.linalg.norm(sxyz-mxyz)
|
|
||||||
costheta = (x[1]*x[1] + aa*aa - slvrng*slvrng)/(2.*x[1]*aa)
|
|
||||||
|
|
||||||
Bpar.append(aa*costheta)
|
|
||||||
|
|
||||||
perp = aa * np.sqrt(1 - costheta*costheta)
|
|
||||||
direction = np.sign(np.dot( np.cross(targxyz-mxyz, sxyz-mxyz), mvel))
|
|
||||||
Bperp.append(direction*perp)
|
|
||||||
|
|
||||||
catalog.addItem('parallel baseline at upperleft of reference track', Bpar[0], 'runPreprocessor')
|
|
||||||
catalog.addItem('parallel baseline at upperright of reference track', Bpar[1], 'runPreprocessor')
|
|
||||||
catalog.addItem('parallel baseline at lowerleft of reference track', Bpar[2], 'runPreprocessor')
|
|
||||||
catalog.addItem('parallel baseline at lowerright of reference track', Bpar[3], 'runPreprocessor')
|
|
||||||
catalog.addItem('parallel baseline at center of reference track', Bpar[4], 'runPreprocessor')
|
|
||||||
|
|
||||||
catalog.addItem('perpendicular baseline at upperleft of reference track', Bperp[0], 'runPreprocessor')
|
|
||||||
catalog.addItem('perpendicular baseline at upperright of reference track', Bperp[1], 'runPreprocessor')
|
|
||||||
catalog.addItem('perpendicular baseline at lowerleft of reference track', Bperp[2], 'runPreprocessor')
|
|
||||||
catalog.addItem('perpendicular baseline at lowerright of reference track', Bperp[3], 'runPreprocessor')
|
|
||||||
catalog.addItem('perpendicular baseline at center of reference track', Bperp[4], 'runPreprocessor')
|
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
#4. compute bounding box
|
|
||||||
##################################################
|
|
||||||
referenceBbox = getBboxGeo(self.reference.track)
|
|
||||||
secondaryBbox = getBboxGeo(self.secondary.track)
|
|
||||||
|
|
||||||
catalog.addItem('reference bounding box', referenceBbox, 'runPreprocessor')
|
|
||||||
catalog.addItem('secondary bounding box', secondaryBbox, 'runPreprocessor')
|
|
||||||
|
|
||||||
|
|
||||||
catalog.printToLog(logger, "runPreprocessor")
|
catalog.printToLog(logger, "runPreprocessor")
|
||||||
self._insar.procDoc.addAllFromCatalog(catalog)
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,17 @@ class TerraSARX(Sensor):
|
||||||
self.populateMetadata()
|
self.populateMetadata()
|
||||||
fp.close()
|
fp.close()
|
||||||
|
|
||||||
|
def grab_from_xml(self, path):
|
||||||
|
try:
|
||||||
|
res = self._xml_root.find(path).text
|
||||||
|
except:
|
||||||
|
raise Exception('Tag= %s not found'%(path))
|
||||||
|
|
||||||
|
if res is None:
|
||||||
|
raise Exception('Tag = %s not found'%(path))
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
def populateMetadata(self):
|
def populateMetadata(self):
|
||||||
"""
|
"""
|
||||||
Populate our Metadata objects
|
Populate our Metadata objects
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,9 @@
|
||||||
cycle
|
cycle
|
||||||
endif
|
endif
|
||||||
|
|
||||||
r_dop = evalPoly2d_f(dopplerPoly, r_at, r_rt)
|
!r_dop = evalPoly2d_f(dopplerPoly, r_at, r_rt)
|
||||||
|
! doppler should be computed using secondary's coordinate. Cunren Liang, 12-AUG-2020
|
||||||
|
r_dop = evalPoly2d_f(dopplerPoly, r_at+r_ao, r_rt+r_ro)
|
||||||
|
|
||||||
!!!!!!Data chip without the carriers
|
!!!!!!Data chip without the carriers
|
||||||
do jj=1,sincone
|
do jj=1,sincone
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
@ -1755,6 +1756,8 @@ void SolveCS2(signed char **residue, short **mstcosts, long nrow, long ncol,
|
||||||
double cost, c_max;
|
double cost, c_max;
|
||||||
short *cap; /* cap changed to short by CWC */
|
short *cap; /* cap changed to short by CWC */
|
||||||
|
|
||||||
|
long row_index, col_index; /* report out-of-bounds index by Cunren, 18-aug-2020 */
|
||||||
|
|
||||||
short **rowcost, **colcost;
|
short **rowcost, **colcost;
|
||||||
short **rowflow, **colflow;
|
short **rowflow, **colflow;
|
||||||
|
|
||||||
|
|
@ -1808,19 +1811,10 @@ void SolveCS2(signed char **residue, short **mstcosts, long nrow, long ncol,
|
||||||
exit(ABNORMAL_EXIT);
|
exit(ABNORMAL_EXIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(from==(to+1)){
|
/* node indices are indexed from 1, not 0 */
|
||||||
num=from+(int )((from-1)/nNrow);
|
/* node indices are in column major order, not row major */
|
||||||
colflow[(num-1) % (nNrow+1)][(int )(num-1)/(nNrow+1)]-=flow;
|
/* handle flow to/from ground first */
|
||||||
}else if(from==(to-1)){
|
if((from==ground) || (to==ground)){
|
||||||
num=from+(int )((from-1)/nNrow)+1;
|
|
||||||
colflow[(num-1) % (nNrow+1)][(int )(num-1)/(nNrow+1)]+=flow;
|
|
||||||
}else if(from==(to-nNrow)){
|
|
||||||
num=from+nNrow;
|
|
||||||
rowflow[(num-1) % nNrow][(int )((num-1)/nNrow)]+=flow;
|
|
||||||
}else if(from==(to+nNrow)){
|
|
||||||
num=from;
|
|
||||||
rowflow[(num-1) % nNrow][(int )((num-1)/nNrow)]-=flow;
|
|
||||||
}else if((from==ground) || (to==ground)){
|
|
||||||
if(to==ground){
|
if(to==ground){
|
||||||
num=to;
|
num=to;
|
||||||
to=from;
|
to=from;
|
||||||
|
|
@ -1828,17 +1822,69 @@ void SolveCS2(signed char **residue, short **mstcosts, long nrow, long ncol,
|
||||||
flow=-flow;
|
flow=-flow;
|
||||||
}
|
}
|
||||||
if(!((to-1) % nNrow)){
|
if(!((to-1) % nNrow)){
|
||||||
colflow[0][(int )((to-1)/nNrow)]+=flow;
|
row_index = 0;
|
||||||
|
col_index = (int )((to-1)/nNrow);
|
||||||
|
if (0 <= row_index && row_index <= nrow-1 && 0 <= col_index && col_index <= ncol-2)
|
||||||
|
colflow[row_index][col_index]+=flow;
|
||||||
|
else
|
||||||
|
fprintf(sp0,"Warning: out-of-bounds index in computing flow\n");
|
||||||
}else if(to<=nNrow){
|
}else if(to<=nNrow){
|
||||||
rowflow[to-1][0]+=flow;
|
row_index = to-1;
|
||||||
|
col_index = 0;
|
||||||
|
if (0 <= row_index && row_index <= nrow-2 && 0 <= col_index && col_index <= ncol-1)
|
||||||
|
rowflow[row_index][col_index]+=flow;
|
||||||
|
else
|
||||||
|
fprintf(sp0,"Warning: out-of-bounds index in computing flow\n");
|
||||||
}else if(to>=(ground-nNrow-1)){
|
}else if(to>=(ground-nNrow-1)){
|
||||||
rowflow[(to-1) % nNrow][nNcol]-=flow;
|
row_index = (to-1) % nNrow;
|
||||||
|
col_index = nNcol;
|
||||||
|
if (0 <= row_index && row_index <= nrow-2 && 0 <= col_index && col_index <= ncol-1)
|
||||||
|
rowflow[row_index][col_index]-=flow;
|
||||||
|
else
|
||||||
|
fprintf(sp0,"Warning: out-of-bounds index in computing flow\n");
|
||||||
}else if(!(to % nNrow)){
|
}else if(!(to % nNrow)){
|
||||||
colflow[nNrow][(int )((to/nNrow)-1)]-=flow;
|
row_index = nNrow;
|
||||||
|
col_index = (int )((to/nNrow)-1);
|
||||||
|
if (0 <= row_index && row_index <= nrow-1 && 0 <= col_index && col_index <= ncol-2)
|
||||||
|
colflow[row_index][col_index]-=flow;
|
||||||
|
else
|
||||||
|
fprintf(sp0,"Warning: out-of-bounds index in computing flow\n");
|
||||||
}else{
|
}else{
|
||||||
fprintf(sp0,"Unassigned ground arc parsing cs2 solution\nAbort\n");
|
fprintf(sp0,"Unassigned ground arc parsing cs2 solution\nAbort\n");
|
||||||
exit(ABNORMAL_EXIT);
|
exit(ABNORMAL_EXIT);
|
||||||
}
|
}
|
||||||
|
}else if(from==(to+1)){
|
||||||
|
num=from+(int )((from-1)/nNrow);
|
||||||
|
row_index = (num-1) % (nNrow+1);
|
||||||
|
col_index = (int )(num-1)/(nNrow+1);
|
||||||
|
if (0 <= row_index && row_index <= nrow-1 && 0 <= col_index && col_index <= ncol-2)
|
||||||
|
colflow[row_index][col_index]-=flow;
|
||||||
|
else
|
||||||
|
fprintf(sp0,"Warning: out-of-bounds index in computing flow\n");
|
||||||
|
}else if(from==(to-1)){
|
||||||
|
num=from+(int )((from-1)/nNrow)+1;
|
||||||
|
row_index = (num-1) % (nNrow+1);
|
||||||
|
col_index = (int )(num-1)/(nNrow+1);
|
||||||
|
if (0 <= row_index && row_index <= nrow-1 && 0 <= col_index && col_index <= ncol-2)
|
||||||
|
colflow[row_index][col_index]+=flow;
|
||||||
|
else
|
||||||
|
fprintf(sp0,"Warning: out-of-bounds index in computing flow\n");
|
||||||
|
}else if(from==(to-nNrow)){
|
||||||
|
num=from+nNrow;
|
||||||
|
row_index = (num-1) % nNrow;
|
||||||
|
col_index = (int )((num-1)/nNrow);
|
||||||
|
if (0 <= row_index && row_index <= nrow-2 && 0 <= col_index && col_index <= ncol-1)
|
||||||
|
rowflow[row_index][col_index]+=flow;
|
||||||
|
else
|
||||||
|
fprintf(sp0,"Warning: out-of-bounds index in computing flow\n");
|
||||||
|
}else if(from==(to+nNrow)){
|
||||||
|
num=from;
|
||||||
|
row_index = (num-1) % nNrow;
|
||||||
|
col_index = (int )((num-1)/nNrow);
|
||||||
|
if (0 <= row_index && row_index <= nrow-2 && 0 <= col_index && col_index <= ncol-1)
|
||||||
|
rowflow[row_index][col_index]-=flow;
|
||||||
|
else
|
||||||
|
fprintf(sp0,"Warning: out-of-bounds index in computing flow\n");
|
||||||
}else{
|
}else{
|
||||||
fprintf(sp0,"Non-grid arc parsing cs2 solution\nAbort\n");
|
fprintf(sp0,"Non-grid arc parsing cs2 solution\nAbort\n");
|
||||||
exit(ABNORMAL_EXIT);
|
exit(ABNORMAL_EXIT);
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,18 @@ Read the document for each stack processor for details.
|
||||||
|
|
||||||
+ [stripmapStack](./stripmapStack/README.md)
|
+ [stripmapStack](./stripmapStack/README.md)
|
||||||
+ [topsStack](./topsStack/README.md)
|
+ [topsStack](./topsStack/README.md)
|
||||||
|
+ [alosStack](./alosStack/alosStack_tutorial.txt)
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
To use the TOPS or Stripmap stack processors you need to:
|
To use a stack processor you need to:
|
||||||
|
|
||||||
1. Install ISCE as usual
|
1. Install ISCE as usual
|
||||||
|
|
||||||
2. Depending on which stack processor you need to try, add the path of the folder containing the python scripts to your `$PATH` environment variable as follows:
|
2. Depending on which stack processor you need to try, add the path of the folder containing the python scripts to your `$PATH` environment variable as follows:
|
||||||
- add the full path of your **contrib/stack/topsStack** to `$PATH` to use the topsStack for processing a stack of Sentinel-1 TOPS data
|
- add the full path of your **contrib/stack/topsStack** to `$PATH` to use the topsStack for processing a stack of Sentinel-1 TOPS data
|
||||||
- add the full path of your **contrib/stack/stripmapStack** to `$PATH` to use the stripmapStack for processing a stack of StripMap data
|
- add the full path of your **contrib/stack/stripmapStack** to `$PATH` to use the stripmapStack for processing a stack of StripMap data
|
||||||
|
- set environment variable `$PATH_ALOSSTACK` by doing: export PATH_ALOSSTACK=CODE_DIR/contrib/stack/alosStack to use the alosStack for processing a stack of ALOS-2 data
|
||||||
|
|
||||||
Note: The stack processors do not show up in the install directory of your isce software. They can be found in the isce source directory.
|
Note: The stack processors do not show up in the install directory of your isce software. They can be found in the isce source directory.
|
||||||
|
|
||||||
|
|
@ -32,3 +34,4 @@ For StripMap stack processor and ionospheric phase estimation:
|
||||||
For TOPS stack processing:
|
For TOPS stack processing:
|
||||||
|
|
||||||
+ H. Fattahi, P. Agram, and M. Simons, “A network-based enhanced spectral diversity approach for TOPS time-series analysis,” IEEE Trans. Geosci. Remote Sens., vol. 55, no. 2, pp. 777–786, Feb. 2017. (https://ieeexplore.ieee.org/abstract/document/7637021/)
|
+ H. Fattahi, P. Agram, and M. Simons, “A network-based enhanced spectral diversity approach for TOPS time-series analysis,” IEEE Trans. Geosci. Remote Sens., vol. 55, no. 2, pp. 777–786, Feb. 2017. (https://ieeexplore.ieee.org/abstract/document/7637021/)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,426 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
import isce
|
||||||
|
import isceobj
|
||||||
|
import iscesys
|
||||||
|
from iscesys.Component.Application import Application
|
||||||
|
|
||||||
|
|
||||||
|
DATA_DIR = Application.Parameter('dataDir',
|
||||||
|
public_name='data directory',
|
||||||
|
default=None,
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="directory of data, where data of each date are in an individual directory")
|
||||||
|
|
||||||
|
FRAMES = Application.Parameter('frames',
|
||||||
|
public_name = 'frames',
|
||||||
|
default = None,
|
||||||
|
type=str,
|
||||||
|
container=list,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'frames to process')
|
||||||
|
|
||||||
|
POLARIZATION = Application.Parameter('polarization',
|
||||||
|
public_name='polarization',
|
||||||
|
default='HH',
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="polarization to process")
|
||||||
|
|
||||||
|
STARTING_SWATH = Application.Parameter('startingSwath',
|
||||||
|
public_name='starting swath',
|
||||||
|
default=None,
|
||||||
|
type=int,
|
||||||
|
mandatory=False,
|
||||||
|
doc="starting swath to process")
|
||||||
|
|
||||||
|
ENDING_SWATH = Application.Parameter('endingSwath',
|
||||||
|
public_name='ending swath',
|
||||||
|
default=None,
|
||||||
|
type=int,
|
||||||
|
mandatory=False,
|
||||||
|
doc="ending swath to process")
|
||||||
|
|
||||||
|
DEM = Application.Parameter('dem',
|
||||||
|
public_name='dem for coregistration',
|
||||||
|
default=None,
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc='dem for coregistration file')
|
||||||
|
|
||||||
|
DEM_GEO = Application.Parameter('demGeo',
|
||||||
|
public_name='dem for geocoding',
|
||||||
|
default=None,
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc='dem for geocoding file')
|
||||||
|
|
||||||
|
WBD = Application.Parameter('wbd',
|
||||||
|
public_name='water body',
|
||||||
|
default=None,
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc='water body file')
|
||||||
|
|
||||||
|
DATE_REFERENCE_STACK = Application.Parameter('dateReferenceStack',
|
||||||
|
public_name='reference date of the stack',
|
||||||
|
default=None,
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="reference date of the stack")
|
||||||
|
|
||||||
|
GRID_FRAME = Application.Parameter('gridFrame',
|
||||||
|
public_name='grid frame',
|
||||||
|
default=None,
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="resample all frames/swaths to the grid size of this frame")
|
||||||
|
|
||||||
|
GRID_SWATH = Application.Parameter('gridSwath',
|
||||||
|
public_name='grid swath',
|
||||||
|
default=None,
|
||||||
|
type=int,
|
||||||
|
mandatory=False,
|
||||||
|
doc="resample all frames/swaths to the grid size of this swath")
|
||||||
|
|
||||||
|
NUMBER_OF_SUBSEQUENT_DATES = Application.Parameter('numberOfSubsequentDates',
|
||||||
|
public_name='number of subsequent dates',
|
||||||
|
default=4,
|
||||||
|
type=int,
|
||||||
|
mandatory=False,
|
||||||
|
doc="number of subsequent dates used to form pairs")
|
||||||
|
|
||||||
|
PAIR_TIME_SPAN_MINIMUM = Application.Parameter('pairTimeSpanMinimum',
|
||||||
|
public_name = 'pair time span minimum in years',
|
||||||
|
default = None,
|
||||||
|
type=float,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'pair time span minimum in years')
|
||||||
|
|
||||||
|
PAIR_TIME_SPAN_MAXIMUM = Application.Parameter('pairTimeSpanMaximum',
|
||||||
|
public_name = 'pair time span maximum in years',
|
||||||
|
default = None,
|
||||||
|
type=float,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'pair time span maximum in years')
|
||||||
|
|
||||||
|
DATES_INCLUDED = Application.Parameter('datesIncluded',
|
||||||
|
public_name = 'dates to be included',
|
||||||
|
default = None,
|
||||||
|
type=str,
|
||||||
|
container=list,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'dates to be included')
|
||||||
|
|
||||||
|
#MUST BE FIRST DATE - SECOND DATE!!!
|
||||||
|
PAIRS_INCLUDED = Application.Parameter('pairsIncluded',
|
||||||
|
public_name = 'pairs to be included',
|
||||||
|
default = None,
|
||||||
|
type=str,
|
||||||
|
container=list,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'pairs to be included')
|
||||||
|
|
||||||
|
DATES_EXCLUDED = Application.Parameter('datesExcluded',
|
||||||
|
public_name = 'dates to be excluded',
|
||||||
|
default = None,
|
||||||
|
type=str,
|
||||||
|
container=list,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'dates to be excluded')
|
||||||
|
|
||||||
|
#MUST BE FIRST DATE - SECOND DATE!!!
|
||||||
|
PAIRS_EXCLUDED = Application.Parameter('pairsExcluded',
|
||||||
|
public_name = 'pairs to be excluded',
|
||||||
|
default = None,
|
||||||
|
type=str,
|
||||||
|
container=list,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'pairs to be excluded')
|
||||||
|
|
||||||
|
DATE_REFERENCE_STACK_ION = Application.Parameter('dateReferenceStackIon',
|
||||||
|
public_name='reference date of the stack for estimating ionosphere',
|
||||||
|
default=None,
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="reference date of the stack in estimating ionosphere")
|
||||||
|
|
||||||
|
NUMBER_OF_SUBSEQUENT_DATES_ION = Application.Parameter('numberOfSubsequentDatesIon',
|
||||||
|
public_name='number of subsequent dates for estimating ionosphere',
|
||||||
|
default=4,
|
||||||
|
type=int,
|
||||||
|
mandatory=False,
|
||||||
|
doc="number of subsequent dates used to form pairs for estimating ionosphere")
|
||||||
|
|
||||||
|
PAIR_TIME_SPAN_MINIMUM_ION = Application.Parameter('pairTimeSpanMinimumIon',
|
||||||
|
public_name = 'pair time span minimum in years for estimating ionosphere',
|
||||||
|
default = None,
|
||||||
|
type=float,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'pair time span minimum in years for estimating ionosphere')
|
||||||
|
|
||||||
|
PAIR_TIME_SPAN_MAXIMUM_ION = Application.Parameter('pairTimeSpanMaximumIon',
|
||||||
|
public_name = 'pair time span maximum in years for estimating ionosphere',
|
||||||
|
default = None,
|
||||||
|
type=float,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'pair time span maximum in years for estimating ionosphere')
|
||||||
|
|
||||||
|
DATES_INCLUDED_ION = Application.Parameter('datesIncludedIon',
|
||||||
|
public_name = 'dates to be included for estimating ionosphere',
|
||||||
|
default = None,
|
||||||
|
type=str,
|
||||||
|
container=list,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'dates to be included for estimating ionosphere')
|
||||||
|
|
||||||
|
#MUST BE FIRST DATE - SECOND DATE!!!
|
||||||
|
PAIRS_INCLUDED_ION = Application.Parameter('pairsIncludedIon',
|
||||||
|
public_name = 'pairs to be included for estimating ionosphere',
|
||||||
|
default = None,
|
||||||
|
type=str,
|
||||||
|
container=list,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'pairs to be included for estimating ionosphere')
|
||||||
|
|
||||||
|
DATES_EXCLUDED_ION = Application.Parameter('datesExcludedIon',
|
||||||
|
public_name = 'dates to be excluded for estimating ionosphere',
|
||||||
|
default = None,
|
||||||
|
type=str,
|
||||||
|
container=list,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'dates to be excluded for estimating ionosphere')
|
||||||
|
|
||||||
|
#MUST BE FIRST DATE - SECOND DATE!!!
|
||||||
|
PAIRS_EXCLUDED_ION = Application.Parameter('pairsExcludedIon',
|
||||||
|
public_name = 'pairs to be excluded for estimating ionosphere',
|
||||||
|
default = None,
|
||||||
|
type=str,
|
||||||
|
container=list,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'pairs to be excluded for estimating ionosphere')
|
||||||
|
|
||||||
|
DATES_REPROCESS = Application.Parameter('datesReprocess',
|
||||||
|
public_name = 'reprocess already processed dates',
|
||||||
|
default=False,
|
||||||
|
type=bool,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'reprocess already processed dates')
|
||||||
|
|
||||||
|
PAIRS_REPROCESS = Application.Parameter('pairsReprocess',
|
||||||
|
public_name = 'reprocess already processed pairs',
|
||||||
|
default=False,
|
||||||
|
type=bool,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'reprocess already processed pairs')
|
||||||
|
|
||||||
|
PAIRS_REPROCESS_ION = Application.Parameter('pairsReprocessIon',
|
||||||
|
public_name = 'reprocess already processed pairs for estimating ionosphere',
|
||||||
|
default=False,
|
||||||
|
type=bool,
|
||||||
|
mandatory=False,
|
||||||
|
doc = 'reprocess already processed pairs for estimating ionosphere')
|
||||||
|
|
||||||
|
DATES_PROCESSING_DIR = Application.Parameter('datesProcessingDir',
|
||||||
|
public_name='dates processing directory',
|
||||||
|
default='dates',
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="directory for processing all dates")
|
||||||
|
|
||||||
|
DATES_RESAMPLED_DIR = Application.Parameter('datesResampledDir',
|
||||||
|
public_name='dates resampled directory',
|
||||||
|
default='dates_resampled',
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="directory for all dates resampled")
|
||||||
|
|
||||||
|
PAIRS_PROCESSING_DIR = Application.Parameter('pairsProcessingDir',
|
||||||
|
public_name='pairs processing directory',
|
||||||
|
default='pairs',
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="directory for processing all pairs")
|
||||||
|
|
||||||
|
BASELINE_DIR = Application.Parameter('baselineDir',
|
||||||
|
public_name='baseline directory',
|
||||||
|
default='baseline',
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="directory for baselines")
|
||||||
|
|
||||||
|
DATES_DIR_ION = Application.Parameter('datesDirIon',
|
||||||
|
public_name='dates directory for ionosphere',
|
||||||
|
default='dates_ion',
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="dates directory for ionosphere")
|
||||||
|
|
||||||
|
PAIRS_PROCESSING_DIR_ION = Application.Parameter('pairsProcessingDirIon',
|
||||||
|
public_name='pairs processing directory for estimating ionosphere',
|
||||||
|
default='pairs_ion',
|
||||||
|
type=str,
|
||||||
|
mandatory=False,
|
||||||
|
doc="directory for processing all pairs for estimating ionosphere")
|
||||||
|
|
||||||
|
#import insar processing parameters from alos2App.py
|
||||||
|
#from alos2App import REFERENCE_DIR
|
||||||
|
#from alos2App import SECONDARY_DIR
|
||||||
|
#from alos2App import REFERENCE_FRAMES
|
||||||
|
#from alos2App import SECONDARY_FRAMES
|
||||||
|
#from alos2App import REFERENCE_POLARIZATION
|
||||||
|
#from alos2App import SECONDARY_POLARIZATION
|
||||||
|
#from alos2App import STARTING_SWATH
|
||||||
|
#from alos2App import ENDING_SWATH
|
||||||
|
#from alos2App import DEM
|
||||||
|
#from alos2App import DEM_GEO
|
||||||
|
#from alos2App import WBD
|
||||||
|
from alos2App import USE_VIRTUAL_FILE
|
||||||
|
from alos2App import USE_GPU
|
||||||
|
#from alos2App import BURST_SYNCHRONIZATION_THRESHOLD
|
||||||
|
#from alos2App import CROP_SLC
|
||||||
|
from alos2App import USE_WBD_FOR_NUMBER_OFFSETS
|
||||||
|
from alos2App import NUMBER_RANGE_OFFSETS
|
||||||
|
from alos2App import NUMBER_AZIMUTH_OFFSETS
|
||||||
|
from alos2App import NUMBER_RANGE_LOOKS1
|
||||||
|
from alos2App import NUMBER_AZIMUTH_LOOKS1
|
||||||
|
from alos2App import NUMBER_RANGE_LOOKS2
|
||||||
|
from alos2App import NUMBER_AZIMUTH_LOOKS2
|
||||||
|
from alos2App import NUMBER_RANGE_LOOKS_SIM
|
||||||
|
from alos2App import NUMBER_AZIMUTH_LOOKS_SIM
|
||||||
|
from alos2App import SWATH_OFFSET_MATCHING
|
||||||
|
from alos2App import FRAME_OFFSET_MATCHING
|
||||||
|
from alos2App import FILTER_STRENGTH
|
||||||
|
from alos2App import FILTER_WINSIZE
|
||||||
|
from alos2App import FILTER_STEPSIZE
|
||||||
|
from alos2App import REMOVE_MAGNITUDE_BEFORE_FILTERING
|
||||||
|
from alos2App import WATERBODY_MASK_STARTING_STEP
|
||||||
|
#from alos2App import GEOCODE_LIST
|
||||||
|
from alos2App import GEOCODE_BOUNDING_BOX
|
||||||
|
from alos2App import GEOCODE_INTERP_METHOD
|
||||||
|
#ionospheric correction parameters
|
||||||
|
from alos2App import DO_ION
|
||||||
|
from alos2App import APPLY_ION
|
||||||
|
from alos2App import NUMBER_RANGE_LOOKS_ION
|
||||||
|
from alos2App import NUMBER_AZIMUTH_LOOKS_ION
|
||||||
|
from alos2App import MASKED_AREAS_ION
|
||||||
|
from alos2App import SWATH_PHASE_DIFF_SNAP_ION
|
||||||
|
from alos2App import SWATH_PHASE_DIFF_LOWER_ION
|
||||||
|
from alos2App import SWATH_PHASE_DIFF_UPPER_ION
|
||||||
|
from alos2App import FIT_ION
|
||||||
|
from alos2App import FILT_ION
|
||||||
|
from alos2App import FIT_ADAPTIVE_ION
|
||||||
|
from alos2App import FILT_SECONDARY_ION
|
||||||
|
from alos2App import FILTERING_WINSIZE_MAX_ION
|
||||||
|
from alos2App import FILTERING_WINSIZE_MIN_ION
|
||||||
|
from alos2App import FILTERING_WINSIZE_SECONDARY_ION
|
||||||
|
from alos2App import FILTER_STD_ION
|
||||||
|
from alos2App import FILTER_SUBBAND_INT
|
||||||
|
from alos2App import FILTER_STRENGTH_SUBBAND_INT
|
||||||
|
from alos2App import FILTER_WINSIZE_SUBBAND_INT
|
||||||
|
from alos2App import FILTER_STEPSIZE_SUBBAND_INT
|
||||||
|
from alos2App import REMOVE_MAGNITUDE_BEFORE_FILTERING_SUBBAND_INT
|
||||||
|
|
||||||
|
|
||||||
|
## Common interface for all insar applications.
|
||||||
|
class Stack(Application):
|
||||||
|
family = 'stackinsar'
|
||||||
|
parameter_list = (DATA_DIR,
|
||||||
|
FRAMES,
|
||||||
|
POLARIZATION,
|
||||||
|
STARTING_SWATH,
|
||||||
|
ENDING_SWATH,
|
||||||
|
DEM,
|
||||||
|
DEM_GEO,
|
||||||
|
WBD,
|
||||||
|
DATE_REFERENCE_STACK,
|
||||||
|
GRID_FRAME,
|
||||||
|
GRID_SWATH,
|
||||||
|
NUMBER_OF_SUBSEQUENT_DATES,
|
||||||
|
PAIR_TIME_SPAN_MINIMUM,
|
||||||
|
PAIR_TIME_SPAN_MAXIMUM,
|
||||||
|
DATES_INCLUDED,
|
||||||
|
PAIRS_INCLUDED,
|
||||||
|
DATES_EXCLUDED,
|
||||||
|
PAIRS_EXCLUDED,
|
||||||
|
DATE_REFERENCE_STACK_ION,
|
||||||
|
NUMBER_OF_SUBSEQUENT_DATES_ION,
|
||||||
|
PAIR_TIME_SPAN_MINIMUM_ION,
|
||||||
|
PAIR_TIME_SPAN_MAXIMUM_ION,
|
||||||
|
DATES_INCLUDED_ION,
|
||||||
|
PAIRS_INCLUDED_ION,
|
||||||
|
DATES_EXCLUDED_ION,
|
||||||
|
PAIRS_EXCLUDED_ION,
|
||||||
|
DATES_REPROCESS,
|
||||||
|
PAIRS_REPROCESS,
|
||||||
|
PAIRS_REPROCESS_ION,
|
||||||
|
DATES_PROCESSING_DIR,
|
||||||
|
DATES_RESAMPLED_DIR,
|
||||||
|
PAIRS_PROCESSING_DIR,
|
||||||
|
BASELINE_DIR,
|
||||||
|
DATES_DIR_ION,
|
||||||
|
PAIRS_PROCESSING_DIR_ION,
|
||||||
|
#insar processing parameters, same as those in alos2App.py
|
||||||
|
USE_VIRTUAL_FILE,
|
||||||
|
USE_GPU,
|
||||||
|
USE_WBD_FOR_NUMBER_OFFSETS,
|
||||||
|
NUMBER_RANGE_OFFSETS,
|
||||||
|
NUMBER_AZIMUTH_OFFSETS,
|
||||||
|
NUMBER_RANGE_LOOKS1,
|
||||||
|
NUMBER_AZIMUTH_LOOKS1,
|
||||||
|
NUMBER_RANGE_LOOKS2,
|
||||||
|
NUMBER_AZIMUTH_LOOKS2,
|
||||||
|
NUMBER_RANGE_LOOKS_SIM,
|
||||||
|
NUMBER_AZIMUTH_LOOKS_SIM,
|
||||||
|
SWATH_OFFSET_MATCHING,
|
||||||
|
FRAME_OFFSET_MATCHING,
|
||||||
|
FILTER_STRENGTH,
|
||||||
|
FILTER_WINSIZE,
|
||||||
|
FILTER_STEPSIZE,
|
||||||
|
REMOVE_MAGNITUDE_BEFORE_FILTERING,
|
||||||
|
WATERBODY_MASK_STARTING_STEP,
|
||||||
|
GEOCODE_BOUNDING_BOX,
|
||||||
|
GEOCODE_INTERP_METHOD,
|
||||||
|
#ionospheric correction parameters
|
||||||
|
DO_ION,
|
||||||
|
APPLY_ION,
|
||||||
|
NUMBER_RANGE_LOOKS_ION,
|
||||||
|
NUMBER_AZIMUTH_LOOKS_ION,
|
||||||
|
MASKED_AREAS_ION,
|
||||||
|
SWATH_PHASE_DIFF_SNAP_ION,
|
||||||
|
SWATH_PHASE_DIFF_LOWER_ION,
|
||||||
|
SWATH_PHASE_DIFF_UPPER_ION,
|
||||||
|
FIT_ION,
|
||||||
|
FILT_ION,
|
||||||
|
FIT_ADAPTIVE_ION,
|
||||||
|
FILT_SECONDARY_ION,
|
||||||
|
FILTERING_WINSIZE_MAX_ION,
|
||||||
|
FILTERING_WINSIZE_MIN_ION,
|
||||||
|
FILTERING_WINSIZE_SECONDARY_ION,
|
||||||
|
FILTER_STD_ION,
|
||||||
|
FILTER_SUBBAND_INT,
|
||||||
|
FILTER_STRENGTH_SUBBAND_INT,
|
||||||
|
FILTER_WINSIZE_SUBBAND_INT,
|
||||||
|
FILTER_STEPSIZE_SUBBAND_INT,
|
||||||
|
REMOVE_MAGNITUDE_BEFORE_FILTERING_SUBBAND_INT)
|
||||||
|
|
||||||
|
facility_list = ()
|
||||||
|
|
||||||
|
def __init__(self, family='', name='',cmdline=None):
|
||||||
|
import isceobj
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
family=family if family else self.__class__.family, name=name,
|
||||||
|
cmdline=cmdline)
|
||||||
|
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,325 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
def loadInsarUserParameters(filename):
|
||||||
|
import os
|
||||||
|
from isce.applications.alos2App import Alos2InSAR
|
||||||
|
|
||||||
|
#application object cannot recognize extension
|
||||||
|
if filename.endswith('.xml'):
|
||||||
|
filename = os.path.splitext(filename)[0]
|
||||||
|
|
||||||
|
#here, Alos2InSAR object is only used for reading and storing parameters
|
||||||
|
#none of its other attibutes or functions are used.
|
||||||
|
insar = Alos2InSAR(name=filename)
|
||||||
|
insar.configure()
|
||||||
|
|
||||||
|
return insar
|
||||||
|
|
||||||
|
|
||||||
|
def loadStackUserParameters(filename):
|
||||||
|
import os
|
||||||
|
from Stack import Stack
|
||||||
|
|
||||||
|
#application object cannot recognize extension
|
||||||
|
if filename.endswith('.xml'):
|
||||||
|
filename = os.path.splitext(filename)[0]
|
||||||
|
|
||||||
|
stack = Stack(name=filename)
|
||||||
|
stack.configure()
|
||||||
|
|
||||||
|
return stack
|
||||||
|
|
||||||
|
|
||||||
|
def loadInsarProcessingParameters(name):
|
||||||
|
import os
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
from isceobj.Alos2Proc import Alos2Proc
|
||||||
|
|
||||||
|
try:
|
||||||
|
toLoad = Alos2Proc()
|
||||||
|
toLoad.load(name + '.xml')
|
||||||
|
with open(name, 'rb') as f:
|
||||||
|
setattr(toLoad, 'procDoc', pickle.load(f))
|
||||||
|
except IOError:
|
||||||
|
print("Cannot open %s" % (name))
|
||||||
|
|
||||||
|
return toLoad
|
||||||
|
|
||||||
|
|
||||||
|
def dumpInsarProcessingParameters(obj, name):
|
||||||
|
import os
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
##############################
|
||||||
|
#do this to output important paramters to xml (alos2Proc.xml) after each step.
|
||||||
|
#self.renderProcDoc()
|
||||||
|
##############################
|
||||||
|
|
||||||
|
os.makedirs(os.path.dirname(name), exist_ok=True)
|
||||||
|
try:
|
||||||
|
toDump = obj
|
||||||
|
toDump.dump(name + '.xml')
|
||||||
|
#dump the procDoc separately
|
||||||
|
with open(name, 'wb') as f:
|
||||||
|
pickle.dump(getattr(toDump, 'procDoc'), f,
|
||||||
|
protocol=pickle.HIGHEST_PROTOCOL)
|
||||||
|
except IOError:
|
||||||
|
print("Cannot dump %s" % (name))
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def loadProduct(xmlname):
|
||||||
|
'''
|
||||||
|
Load the product using Product Manager.
|
||||||
|
'''
|
||||||
|
|
||||||
|
from iscesys.Component.ProductManager import ProductManager as PM
|
||||||
|
|
||||||
|
pm = PM()
|
||||||
|
pm.configure()
|
||||||
|
|
||||||
|
obj = pm.loadProduct(xmlname)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
def saveProduct(obj, xmlname):
|
||||||
|
'''
|
||||||
|
Save the product to an XML file using Product Manager.
|
||||||
|
'''
|
||||||
|
|
||||||
|
from iscesys.Component.ProductManager import ProductManager as PM
|
||||||
|
|
||||||
|
pm = PM()
|
||||||
|
pm.configure()
|
||||||
|
|
||||||
|
pm.dumpProduct(obj, xmlname)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def loadTrack(trackDir, date):
|
||||||
|
'''
|
||||||
|
Load the track using Product Manager.
|
||||||
|
trackDir: where *.track.xml is located
|
||||||
|
date: YYMMDD
|
||||||
|
'''
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
|
||||||
|
|
||||||
|
frames = sorted(glob.glob(os.path.join(trackDir, 'f*_*/{}.frame.xml'.format(date))))
|
||||||
|
track = loadProduct(os.path.join(trackDir, '{}.track.xml'.format(date)))
|
||||||
|
|
||||||
|
track.frames = []
|
||||||
|
for x in frames:
|
||||||
|
track.frames.append(loadProduct(x))
|
||||||
|
|
||||||
|
return track
|
||||||
|
|
||||||
|
|
||||||
|
def saveTrack(track, date):
|
||||||
|
'''
|
||||||
|
Save the track to XML files using Product Manager.
|
||||||
|
track: track object
|
||||||
|
#trackDir: where *.track.xml is located
|
||||||
|
date: YYMMDD
|
||||||
|
'''
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
|
||||||
|
#dump track object
|
||||||
|
#os.chdir(trackDir)
|
||||||
|
saveProduct(track, date+'.track.xml')
|
||||||
|
|
||||||
|
for i in range(len(track.frames)):
|
||||||
|
#find frame folder
|
||||||
|
frameDirs = sorted(glob.glob('f{}_*'.format(i+1)))
|
||||||
|
if frameDirs == []:
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, track.frames[i].frameNumber)
|
||||||
|
print('no existing frame folder found at frame {}, create a frame folder {}'.format(i+1, frameDir))
|
||||||
|
else:
|
||||||
|
frameDir = frameDirs[0]
|
||||||
|
|
||||||
|
#dump frame object
|
||||||
|
if track.frames[i].frameNumber != frameDir[-4:]:
|
||||||
|
print('frame number in track object {} is different from that in frame folder name: {} at frame {}'.format(
|
||||||
|
track.frames[i].frameNumber, frameDir[-4:], i+1))
|
||||||
|
print('dumping it to {}'.format(frameDir))
|
||||||
|
|
||||||
|
os.chdir(frameDir)
|
||||||
|
saveProduct(track.frames[i], date+'.frame.xml')
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def datesFromPairs(pairs):
|
||||||
|
dates = []
|
||||||
|
for x in pairs:
|
||||||
|
dateReference = x.split('-')[0]
|
||||||
|
dateSecondary = x.split('-')[1]
|
||||||
|
if dateReference not in dates:
|
||||||
|
dates.append(dateReference)
|
||||||
|
if dateSecondary not in dates:
|
||||||
|
dates.append(dateSecondary)
|
||||||
|
dates = sorted(dates)
|
||||||
|
return dates
|
||||||
|
|
||||||
|
|
||||||
|
def stackDateStatistics(idir, dateReference):
|
||||||
|
'''
|
||||||
|
idir: input directory where data of each date is located. only folders are recognized
|
||||||
|
dateReference: reference date, str type format: 'YYMMDD'
|
||||||
|
'''
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
|
||||||
|
#get date folders
|
||||||
|
dateDirs = sorted(glob.glob(os.path.join(os.path.abspath(idir), '*')))
|
||||||
|
dateDirs = [x for x in dateDirs if os.path.isdir(x)]
|
||||||
|
|
||||||
|
#find index of reference date:
|
||||||
|
dates = []
|
||||||
|
dateIndexReference = None
|
||||||
|
for i in range(len(dateDirs)):
|
||||||
|
date = os.path.basename(dateDirs[i])
|
||||||
|
dates.append(date)
|
||||||
|
if date == dateReference:
|
||||||
|
dateIndexReference = i
|
||||||
|
if dateIndexReference is None:
|
||||||
|
raise Exception('cannot get reference date {} from the data list, pleasae check your input'.format(dateReference))
|
||||||
|
else:
|
||||||
|
print('reference date index {}'.format(dateIndexReference))
|
||||||
|
|
||||||
|
#use one date to find frames and swaths. any date should work, here we use dateIndexReference
|
||||||
|
frames = sorted([x[-4:] for x in glob.glob(os.path.join(dateDirs[dateIndexReference], 'f*_*'))])
|
||||||
|
swaths = sorted([int(x[-1]) for x in glob.glob(os.path.join(dateDirs[dateIndexReference], 'f1_*', 's*'))])
|
||||||
|
|
||||||
|
ndate = len(dates)
|
||||||
|
nframe = len(frames)
|
||||||
|
nswath = len(swaths)
|
||||||
|
|
||||||
|
#print result
|
||||||
|
print('\nlist of dates:')
|
||||||
|
print(' index date frames')
|
||||||
|
print('=======================================================')
|
||||||
|
for i in range(ndate):
|
||||||
|
if dates[i] == dateReference:
|
||||||
|
print(' %03d %s'%(i, dates[i])+' {}'.format(frames)+' reference')
|
||||||
|
else:
|
||||||
|
print(' %03d %s'%(i, dates[i])+' {}'.format(frames))
|
||||||
|
print('\n')
|
||||||
|
|
||||||
|
|
||||||
|
# str list, str list, str list, int list int
|
||||||
|
return (dateDirs, dates, frames, swaths, dateIndexReference)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def acquisitionModesAlos2():
|
||||||
|
'''
|
||||||
|
return ALOS-2 acquisition mode
|
||||||
|
'''
|
||||||
|
|
||||||
|
spotlightModes = ['SBS']
|
||||||
|
stripmapModes = ['UBS', 'UBD', 'HBS', 'HBD', 'HBQ', 'FBS', 'FBD', 'FBQ']
|
||||||
|
scansarNominalModes = ['WBS', 'WBD', 'WWS', 'WWD']
|
||||||
|
scansarWideModes = ['VBS', 'VBD']
|
||||||
|
scansarModes = ['WBS', 'WBD', 'WWS', 'WWD', 'VBS', 'VBD']
|
||||||
|
|
||||||
|
return (spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes)
|
||||||
|
|
||||||
|
|
||||||
|
def hasGPU():
|
||||||
|
'''
|
||||||
|
Determine if GPU modules are available.
|
||||||
|
'''
|
||||||
|
|
||||||
|
flag = False
|
||||||
|
try:
|
||||||
|
from zerodop.GPUtopozero.GPUtopozero import PyTopozero
|
||||||
|
from zerodop.GPUgeo2rdr.GPUgeo2rdr import PyGeo2rdr
|
||||||
|
flag = True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return flag
|
||||||
|
|
||||||
|
|
||||||
|
class createObject(object):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def subbandParameters(track):
|
||||||
|
'''
|
||||||
|
compute subband parameters
|
||||||
|
'''
|
||||||
|
#speed of light from: components/isceobj/Planet/AstronomicalHandbook.py
|
||||||
|
SPEED_OF_LIGHT = 299792458.0
|
||||||
|
|
||||||
|
#using 1/3, 1/3, 1/3 band split
|
||||||
|
radarWavelength = track.radarWavelength
|
||||||
|
rangeBandwidth = track.frames[0].swaths[0].rangeBandwidth
|
||||||
|
rangeSamplingRate = track.frames[0].swaths[0].rangeSamplingRate
|
||||||
|
radarWavelengthLower = SPEED_OF_LIGHT/(SPEED_OF_LIGHT / radarWavelength - rangeBandwidth / 3.0)
|
||||||
|
radarWavelengthUpper = SPEED_OF_LIGHT/(SPEED_OF_LIGHT / radarWavelength + rangeBandwidth / 3.0)
|
||||||
|
subbandRadarWavelength = [radarWavelengthLower, radarWavelengthUpper]
|
||||||
|
subbandBandWidth = [rangeBandwidth / 3.0 / rangeSamplingRate, rangeBandwidth / 3.0 / rangeSamplingRate]
|
||||||
|
subbandFrequencyCenter = [-rangeBandwidth / 3.0 / rangeSamplingRate, rangeBandwidth / 3.0 / rangeSamplingRate]
|
||||||
|
|
||||||
|
subbandPrefix = ['lower', 'upper']
|
||||||
|
|
||||||
|
return (subbandRadarWavelength, subbandBandWidth, subbandFrequencyCenter, subbandPrefix)
|
||||||
|
|
||||||
|
|
||||||
|
def formInterferogram(slcReference, slcSecondary, interferogram, amplitude, numberRangeLooks, numberAzimuthLooks):
|
||||||
|
import numpy as np
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import multilook
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
|
||||||
|
img = isceobj.createImage()
|
||||||
|
img.load(slcReference+'.xml')
|
||||||
|
width = img.width
|
||||||
|
length = img.length
|
||||||
|
|
||||||
|
width2 = int(width / numberRangeLooks)
|
||||||
|
length2 = int(length / numberAzimuthLooks)
|
||||||
|
|
||||||
|
fpRef = open(slcReference,'rb')
|
||||||
|
fpSec = open(slcSecondary,'rb')
|
||||||
|
fpInf = open(interferogram,'wb')
|
||||||
|
fpAmp = open(amplitude,'wb')
|
||||||
|
|
||||||
|
for k in range(length2):
|
||||||
|
if (((k+1)%200) == 0):
|
||||||
|
print("processing line %6d of %6d" % (k+1, length2), end='\r', flush=True)
|
||||||
|
ref = np.fromfile(fpRef, dtype=np.complex64, count=numberAzimuthLooks * width).reshape(numberAzimuthLooks, width)
|
||||||
|
sec = np.fromfile(fpSec, dtype=np.complex64, count=numberAzimuthLooks * width).reshape(numberAzimuthLooks, width)
|
||||||
|
inf = multilook(ref*np.conjugate(sec), numberAzimuthLooks, numberRangeLooks, mean=False)
|
||||||
|
amp = np.sqrt(multilook(ref.real*ref.real+ref.imag*ref.imag, numberAzimuthLooks, numberRangeLooks, mean=False)) + 1j * \
|
||||||
|
np.sqrt(multilook(sec.real*sec.real+sec.imag*sec.imag, numberAzimuthLooks, numberRangeLooks, mean=False))
|
||||||
|
index = np.nonzero( (np.real(amp)==0) + (np.imag(amp)==0) )
|
||||||
|
amp[index]=0
|
||||||
|
inf.tofile(fpInf)
|
||||||
|
amp.tofile(fpAmp)
|
||||||
|
print("processing line %6d of %6d" % (length2, length2))
|
||||||
|
fpRef.close()
|
||||||
|
fpSec.close()
|
||||||
|
fpInf.close()
|
||||||
|
fpAmp.close()
|
||||||
|
|
||||||
|
create_xml(interferogram, width2, length2, 'int')
|
||||||
|
create_xml(amplitude, width2, length2, 'amp')
|
||||||
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#Cunren Liang, 05-MAR-2020
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
import zipfile
|
||||||
|
import argparse
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
Command line parser.
|
||||||
|
'''
|
||||||
|
parser = argparse.ArgumentParser(description='prepare alos2App.py OR alos2burstApp.py input files')
|
||||||
|
parser.add_argument('-dir', dest='dir', type=str, required=True,
|
||||||
|
help = 'directory containing the alos-2 data directories [data dir format: YYMMDD]')
|
||||||
|
parser.add_argument('-xml', dest='xml', type=str, required=True,
|
||||||
|
help = 'example alos2App.py input file')
|
||||||
|
parser.add_argument('-num', dest='num', type=int, default=3,
|
||||||
|
help = 'number of pairs for each acquistion. default: 3')
|
||||||
|
parser.add_argument('-yr', dest='yr', type=float, default=1.0,
|
||||||
|
help = 'time span threshhold. default: 1.0 year')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
dates = sorted(glob.glob(os.path.join(inps.dir, '*')))
|
||||||
|
dates = sorted([os.path.basename(x) for x in dates])
|
||||||
|
#for x in dates:
|
||||||
|
# print(x)
|
||||||
|
|
||||||
|
#read standard configurations
|
||||||
|
tree = ET.parse(inps.xml)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
ndate = len(dates)
|
||||||
|
datefmt = "%y%m%d"
|
||||||
|
pairs_created = []
|
||||||
|
pairs_not_created = []
|
||||||
|
for i in range(ndate):
|
||||||
|
mdate = dates[i]
|
||||||
|
mtime = datetime.datetime.strptime(mdate, datefmt)
|
||||||
|
for j in range(inps.num):
|
||||||
|
if i+j+1 <= ndate - 1:
|
||||||
|
sdate = dates[i+j+1]
|
||||||
|
stime = datetime.datetime.strptime(sdate, datefmt)
|
||||||
|
pair = mdate + '-' + sdate
|
||||||
|
if np.absolute((stime - mtime).total_seconds()) < inps.yr * 365.0 * 24.0 * 3600:
|
||||||
|
pairs_created.append(pair)
|
||||||
|
print('creating pair: {}'.format(pair))
|
||||||
|
#create pair dir
|
||||||
|
if not os.path.exists(pair):
|
||||||
|
os.makedirs(pair)
|
||||||
|
#create xml
|
||||||
|
safe = root.find("component/property[@name='master directory']")
|
||||||
|
safe.text = '{}'.format(os.path.join(inps.dir, mdate))
|
||||||
|
safe = root.find("component/property[@name='slave directory']")
|
||||||
|
safe.text = '{}'.format(os.path.join(inps.dir, sdate))
|
||||||
|
tree.write(os.path.join(pair, 'alos2App.xml'))
|
||||||
|
else:
|
||||||
|
pairs_not_created.append(pair)
|
||||||
|
|
||||||
|
|
||||||
|
print('total number of pairs created: {}'.format(len(pairs_created)))
|
||||||
|
|
||||||
|
if pairs_not_created != []:
|
||||||
|
print('\nthe following pairs are not created because their time spans >= {} years'.format(inps.yr))
|
||||||
|
for x in pairs_not_created:
|
||||||
|
print(x)
|
||||||
|
print('total number of pairs not created: {}'.format(len(pairs_not_created)))
|
||||||
|
else:
|
||||||
|
print('\nall possible pairs are created')
|
||||||
|
|
@ -0,0 +1,379 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<stack>
|
||||||
|
<component name="stackinsar">
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
Set the following mandatory parameters to process data
|
||||||
|
==========================================================================================-->
|
||||||
|
|
||||||
|
<property name="data directory">../data/saf_d169</property>
|
||||||
|
|
||||||
|
<property name="dem for coregistration">../data/saf_d169_dem/dem_1_arcsec/demLat_N35_N44_Lon_W126_W118.dem.wgs84</property>
|
||||||
|
<property name="dem for geocoding">../data/saf_d169_dem/dem_3_arcsec/demLat_N35_N44_Lon_W126_W118.dem.wgs84</property>
|
||||||
|
<property name="water body">../data/saf_d169_dem/wbd_1_arcsec/swbdLat_N35_N44_Lon_W126_W118.wbd</property>
|
||||||
|
|
||||||
|
<property name="reference date of the stack">150408</property>
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
See also comments of parameters "number of range looks ion" and "number of azimuth looks ion"
|
||||||
|
below to set a smaller number of looks to avoid phase aliasing in some areas (such as edges of
|
||||||
|
Tibetan Plateau, where there might be strong tropospheric variations due to large height
|
||||||
|
differences).
|
||||||
|
==========================================================================================-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!--=====================================================================================================
|
||||||
|
instructions for ALOS-2 stack processor
|
||||||
|
|
||||||
|
This is the input file of ALOS-2 stack processor. Below are all parameters users can set.
|
||||||
|
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
||||||
|
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
||||||
|
parameter value.
|
||||||
|
|
||||||
|
For the techinques and algorithms implemented in the software, refer to:
|
||||||
|
|
||||||
|
1. ScanSAR or multi-mode InSAR processing
|
||||||
|
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
||||||
|
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
||||||
|
|
||||||
|
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
||||||
|
multi-aperture InSAR (MAI) processing
|
||||||
|
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
||||||
|
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
||||||
|
|
||||||
|
3. Ionospheric correction
|
||||||
|
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
||||||
|
data acquired by ALOS-2,"
|
||||||
|
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
||||||
|
======================================================================================================-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
Directory of unpacked ALOS-2 data containing data of all dates. Data of each date is in an
|
||||||
|
individual folder named YYMMDD, which is the acquistion date of the data and can be found in
|
||||||
|
ALOS-2 image or leader files (e.g. LED-ALOS2041062800-150225-WBDR1.1__D, 150225 is YYMMDD)
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="data directory">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
This is a list of frames, e.g., ['0680', '0690']. Here is how you can find frame number. Below
|
||||||
|
is a JAXA SLC product
|
||||||
|
0000168233_001001_ALOS2183010690-171012.zip
|
||||||
|
After you unpack the JAXA SLC product, you will find an image file like:
|
||||||
|
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
||||||
|
^^^^
|
||||||
|
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
||||||
|
file name, as it may be incorrect (like the above example).
|
||||||
|
|
||||||
|
If all dates have equal number of frames and the frames meet the following one-to-one
|
||||||
|
correspondence, there is no need to set frames.
|
||||||
|
|
||||||
|
Date1 Folder Date2 Folder Date3 Folder
|
||||||
|
Frame **** ... Frame **** ... Frame ****
|
||||||
|
Frame **** ... Frame **** ... Frame ****
|
||||||
|
Frame **** ... Frame **** ... Frame ****
|
||||||
|
Frame **** ... Frame **** ... Frame ****
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="frames">None</property>-->
|
||||||
|
<!--<property name="polarization">HH</property>-->
|
||||||
|
<!--<property name="starting swath">None</property>-->
|
||||||
|
<!--<property name="ending swath">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
Here is how you can download a DEM and water body.
|
||||||
|
#3 arcsec for geocoding
|
||||||
|
mkdir dem_3_arcsec
|
||||||
|
cd dem_3_arcsec
|
||||||
|
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
||||||
|
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
||||||
|
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
||||||
|
cd ../
|
||||||
|
|
||||||
|
#1 arcsec for creating differential interferogram
|
||||||
|
mkdir dem_1_arcsec
|
||||||
|
cd dem_1_arcsec
|
||||||
|
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
||||||
|
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
||||||
|
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
||||||
|
cd ../
|
||||||
|
|
||||||
|
#water body
|
||||||
|
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
||||||
|
#or simply follow the commands below
|
||||||
|
mkdir wbd_1_arcsec
|
||||||
|
cd wbd_1_arcsec
|
||||||
|
wbd.py 29 37 125 133
|
||||||
|
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
||||||
|
cd ../
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="dem for coregistration">None</property>-->
|
||||||
|
<!--<property name="dem for geocoding">None</property>-->
|
||||||
|
<!--<property name="water body">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
It must be set, and should be the same throughout all processings! Format must be YYMMDD.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="reference date of the stack">None</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
In the processing, all swaths of all frames will be resampled to the same sampling size of a
|
||||||
|
particular swath, whose swath and frame numbers can be set here. If not set, first swath of
|
||||||
|
first frame is used.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="grid frame">None</property>-->
|
||||||
|
<!--<property name="grid swath">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
Number of subsequent dates to pair up with a date.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="number of subsequent dates">4</property>-->
|
||||||
|
|
||||||
|
<!--<property name="pair time span minimum in years">None</property>-->
|
||||||
|
<!--<property name="pair time span maximum in years">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
The following parameters are lists. Date format must be YYMMDD. Pair format must be
|
||||||
|
FIRST_DATE(YYMMDD)-SECOND_DATE(YYMMDD). An example input of pairs to be included or excluded:
|
||||||
|
['150225-150408', '150225-150520']
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="dates to be included">None</property>-->
|
||||||
|
<!--<property name="pairs to be included">None</property>-->
|
||||||
|
<!--<property name="dates to be excluded">None</property>-->
|
||||||
|
<!--<property name="pairs to be excluded">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
Date in least squares estimation of ionospheric phase whose ionospheric phase is assumed to
|
||||||
|
be zero. Format must be YYMMDD. By default, first date of dates envolved in estimating
|
||||||
|
ionosphere is used.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="reference date of the stack for estimating ionosphere">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
The following parameters are the same as those above, but are for pairs for ionospheric
|
||||||
|
estimation. Formats are also same.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="number of subsequent dates for estimating ionosphere">4</property>-->
|
||||||
|
<!--<property name="pair time span minimum in years for estimating ionosphere">None</property>-->
|
||||||
|
<!--<property name="pair time span maximum in years for estimating ionosphere">None</property>-->
|
||||||
|
<!--<property name="dates to be included for estimating ionosphere">None</property>-->
|
||||||
|
<!--<property name="pairs to be included for estimating ionosphere">None</property>-->
|
||||||
|
<!--<property name="dates to be excluded for estimating ionosphere">None</property>-->
|
||||||
|
<!--<property name="pairs to be excluded for estimating ionosphere">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
Whether reprocess already processed dates or pairs.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="reprocess already processed dates">False</property>-->
|
||||||
|
<!--<property name="reprocess already processed pairs">False</property>-->
|
||||||
|
<!--<property name="reprocess already processed pairs for estimating ionosphere">False</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
Data processing directories.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="dates processing directory">dates</property>-->
|
||||||
|
<!--<property name="dates resampled directory">dates_resampled</property>-->
|
||||||
|
<!--<property name="pairs processing directory">pairs</property>-->
|
||||||
|
<!--<property name="baseline directory">baseline</property>-->
|
||||||
|
<!--<property name="dates directory for ionosphere">dates_ion</property>-->
|
||||||
|
<!--<property name="pairs processing directory for estimating ionosphere">pairs_ion</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
The following InSAR processing parameters are exactly the same as those in alos2App.py.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="use virtual file">True</property>-->
|
||||||
|
<!--<property name="use GPU">False</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
||||||
|
for areas where no water body data available, turn this off, otherwise the program will use
|
||||||
|
geometrical offset, which is not accuate enough. If it still does not work, set
|
||||||
|
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
||||||
|
For example, if you want to process two frames and three swaths, you can specify one of
|
||||||
|
these parameters as:
|
||||||
|
[[20, 30, 20],[15, 20, 20]]
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="number of range offsets for slc matching">None</property>-->
|
||||||
|
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--============================================================================================================================================
|
||||||
|
Instructions on number of looks used by the software
|
||||||
|
The software first takes number of range/azimuth looks 1, and then take any other number of range/azimuth looks (2, sim and ion).
|
||||||
|
|
||||||
|
Here are the purposes of these number of looks. Usually there is no need to set number of range/azimuth looks sim, so it is not explained here.
|
||||||
|
|
||||||
|
number of range/azimuth looks 1: save space, remove speckle noise, equalize sample size, match original resolution (full-aperture)
|
||||||
|
number of range/azimuth looks 2: make interferogram not too small or large
|
||||||
|
number of range/azimuth looks ion: make interferogram for ionosphere estimation not too small or large, facilitate ionosphere filtering
|
||||||
|
|
||||||
|
total number of looks of InSAR processing is: number of range/azimuth looks 1 * number of range/azimuth looks 2
|
||||||
|
total number of looks in ionosphere estimation is: number of range/azimuth looks 1 * number of range/azimuth looks ion
|
||||||
|
total number of looks in radar/DEM matching is: number of range/azimuth looks 1 * number of range/azimuth looks sim
|
||||||
|
|
||||||
|
Below is the default number of looks used by the software. REMEMBER, NORMALLY YOU ONLY NEED TO CHANGE number of range/azimuth looks 2!!!
|
||||||
|
|
||||||
|
============================================================================================================================================
|
||||||
|
Operation Mode | Mode (AUIG2) | Mode (in file name) | look1 (r*a) | look2 (r*a) | total insar (r*a) | look_ion (r*a) | total ion (r*a)
|
||||||
|
============================================================================================================================================
|
||||||
|
spotlight | SPT | SBS | 2*4 | 4*4 | 8*16 | 16*16 | 32*64
|
||||||
|
============================================================================================================================================
|
||||||
|
stripmap | SM1 | UBS, UBD | 2*3 | 4*4 | 8*12 | 32*32 | 64*96
|
||||||
|
| SM2 | HBS, HBD, HBQ | 2*4 | 4*4 | 8*16 | 16*16 | 32*64
|
||||||
|
| SM3 | FBS, FBD, FBQ | 2*4 | 4*4 | 8*16 | 16*16 | 32*64
|
||||||
|
============================================================================================================================================
|
||||||
|
ScanSAR | WD1 | WBS, WBD | 1*14 | 5*2 | 5*28 | 80*32 | 80*448
|
||||||
|
ScanSAR | WD1 | WWS, WWD | 2*14 | 5*2 | 10*28 | 80*32 | 160*448
|
||||||
|
| WD2 | VBS, VBD | 1*14 | 5*2 | 5*28 | 80*32 | 80*448
|
||||||
|
============================================================================================================================================
|
||||||
|
|
||||||
|
To find the acquisition mode code, check the unpacked ALOS-2 product. For example, in the following
|
||||||
|
file name
|
||||||
|
|
||||||
|
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
||||||
|
^^^
|
||||||
|
FBD (indicated by ^) is the acquisition mode code.
|
||||||
|
=============================================================================================================================================-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
These are the numbers of looks to be taken when forming the interferogram
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="number of range looks 1">None</property>-->
|
||||||
|
<!--<property name="number of azimuth looks 1">None</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="number of range looks 2">None</property>-->
|
||||||
|
<!--<property name="number of azimuth looks 2">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
||||||
|
This is for matching the radar image and DEM
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="number of range looks sim">None</property>-->
|
||||||
|
<!--<property name="number of azimuth looks sim">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
||||||
|
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
These are interferogram filtering parameters
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="interferogram filter strength">0.3</property>-->
|
||||||
|
<!--<property name="interferogram filter window size">32</property>-->
|
||||||
|
<!--<property name="interferogram filter step size">4</property>-->
|
||||||
|
<!--<property name="remove magnitude before filtering">True</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
water body mask starting step: None, filt, unwrap
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="water body mask starting step">unwrap</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="geocode bounding box">None</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="geocode interpolation method">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
These parameters are for ionospheric corrections
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="do ionospheric phase estimation">True</property>-->
|
||||||
|
<!--<property name="apply ionospheric phase correction">True</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
||||||
|
This is for ionospheric correction.
|
||||||
|
Use a larger number of looks results in smaller image size, which saves time in filtering in
|
||||||
|
ionosphere estimation. However, a larger number of looks may also lead to phase aliasing in
|
||||||
|
the resulting inteferograms and therefore lead to phase unwrapping errors, which causes
|
||||||
|
significant errors in ionosphere estimation.
|
||||||
|
If the area has strong troposhere or phase variations (normally in areas with large height
|
||||||
|
differences such as edges of Tibetan Plateau), a smaller number of looks should be used to
|
||||||
|
avoid phase aliasing after taking looks. E.g. 1/2 of the default number of range/azimuth looks
|
||||||
|
ion that can be found in the annotation of parameter 'number of range looks 1'.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="number of range looks ion">None</property>-->
|
||||||
|
<!--<property name="number of azimuth looks ion">None</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
||||||
|
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
||||||
|
your particular case) for areas to be masked out.
|
||||||
|
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
||||||
|
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
||||||
|
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
||||||
|
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
||||||
|
specify a 2-D list like:
|
||||||
|
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
||||||
|
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
||||||
|
as:
|
||||||
|
[[True, True, True, True], [False, True, True, True]]
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you want
|
||||||
|
to use a phase difference value 0.21 (rad) for swath 1 and 2 in frame 2, the parameter can be
|
||||||
|
specified as:
|
||||||
|
[[None, None, None, None], [0.21, None, None, None]]
|
||||||
|
This parameter has highest priority in determing phase difference between swaths.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="swath phase difference of lower band">None</property>-->
|
||||||
|
<!--<property name="swath phase difference of upper band">None</property>-->
|
||||||
|
|
||||||
|
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
||||||
|
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
||||||
|
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
||||||
|
<!--<property name="whether do secondary filtering of ionosphere phase">True</property>-->
|
||||||
|
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
||||||
|
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
||||||
|
<!--<property name="window size of secondary filtering of ionosphere phase">5</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
Normally no need to set this parameter, it will be automatically determined.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="standard deviation of ionosphere phase after filtering">None</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
parameters for filtering subband interferograms used for ionospheric phase estimation
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="filter subband interferogram">False</property>-->
|
||||||
|
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
||||||
|
<!--<property name="subband interferogram filter window size">32</property>-->
|
||||||
|
<!--<property name="subband interferogram filter step size">4</property>-->
|
||||||
|
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
||||||
|
|
||||||
|
</component>
|
||||||
|
</stack>
|
||||||
|
|
@ -0,0 +1,250 @@
|
||||||
|
######################################################################################
|
||||||
|
# Tutorial for alosStack
|
||||||
|
# Cunren Liang, October 2020
|
||||||
|
######################################################################################
|
||||||
|
|
||||||
|
This is the tutorial of alosStack processor.
|
||||||
|
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
# 0. SET ENVIRONMENT VARIABLE
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
Set environment variable 'PATH_ALOSSTACK'
|
||||||
|
export PATH_ALOSSTACK=CODE_DIR/contrib/stack/alosStack
|
||||||
|
|
||||||
|
where CODE_DIR is the directory of your isce code. Note that alosStack is not installed when you install
|
||||||
|
the software, so CODE_DIR is your code directory rather than installation directory.
|
||||||
|
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
# 1. PREPARE DATA
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
1. ALOS-2 data
|
||||||
|
Currently the processor only supports the processing of a stack of data acquired in the same mode.
|
||||||
|
|
||||||
|
To find the acquisition mode code, check the unpacked ALOS-2 product. For example, in the following
|
||||||
|
file name
|
||||||
|
|
||||||
|
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
||||||
|
^^^
|
||||||
|
FBD (indicated by ^) is the acquisition mode code. Here is the list of acquistion modes:
|
||||||
|
|
||||||
|
Operation Mode | Mode (AUIG2) | Mode (in file name)
|
||||||
|
--------------------------------------------------------------
|
||||||
|
spotlight | SPT | SBS
|
||||||
|
--------------------------------------------------------------
|
||||||
|
stripmap | SM1 | UBS, UBD
|
||||||
|
| SM2 | HBS, HBD, HBQ
|
||||||
|
| SM3 | FBS, FBD, FBQ
|
||||||
|
--------------------------------------------------------------
|
||||||
|
ScanSAR | WD1 | WBS, WBD, WWS, WWD
|
||||||
|
| WD2 | VBS, VBD
|
||||||
|
|
||||||
|
|
||||||
|
Create a folder such as 'saf_d169', and in this folder, unpack all frames of each date in an individual folder
|
||||||
|
named YYMMDD. YYMMDD is the acquistion date, and it must be in this format. Now the data directory should look
|
||||||
|
like
|
||||||
|
|
||||||
|
saf_d169_data-------150225-------IMG-HH-ALOS2041062800-150225-WBDR1.1__D-F1
|
||||||
|
|__150408 |__IMG-HH-ALOS2041062800-150225-WBDR1.1__D-F2
|
||||||
|
|__150520 |__IMG-HH-ALOS2041062800-150225-WBDR1.1__D-F3
|
||||||
|
|__150701 |__IMG-HH-ALOS2041062800-150225-WBDR1.1__D-F4
|
||||||
|
|__... |__IMG-HH-ALOS2041062800-150225-WBDR1.1__D-F5
|
||||||
|
|__IMG-HH-ALOS2041062850-150225-WBDR1.1__D-F1
|
||||||
|
|__IMG-HH-ALOS2041062850-150225-WBDR1.1__D-F2
|
||||||
|
|__IMG-HH-ALOS2041062850-150225-WBDR1.1__D-F3
|
||||||
|
|__IMG-HH-ALOS2041062850-150225-WBDR1.1__D-F4
|
||||||
|
|__IMG-HH-ALOS2041062850-150225-WBDR1.1__D-F5
|
||||||
|
|__LED-ALOS2041062800-150225-WBDR1.1__D
|
||||||
|
|__LED-ALOS2041062850-150225-WBDR1.1__D
|
||||||
|
|
||||||
|
2. DEM and water body
|
||||||
|
|
||||||
|
You MUST FIRST have an account to download DEM and water body. See
|
||||||
|
https://github.com/isce-framework/isce2#notes-on-digital-elevation-models
|
||||||
|
or
|
||||||
|
https://github.com/isce-framework/isce2
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
See input xml file alosStack.xml in this folder on how to download DEM and water body.
|
||||||
|
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
# 2. PROCESS DATA
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
1. Create and enter a folder for processing data, e.g.
|
||||||
|
mkdir saf_d169_proc
|
||||||
|
cd saf_d169_proc
|
||||||
|
|
||||||
|
2. Input xml file alosStack.xml can be found in code directory. Copy it to current folder and simply set
|
||||||
|
the parameters.
|
||||||
|
cp ${PATH_ALOSSTACK}/alosStack.xml ./
|
||||||
|
|
||||||
|
3. Create command files for processing data. Run
|
||||||
|
${PATH_ALOSSTACK}/create_cmds.py -stack_par alosStack.xml
|
||||||
|
|
||||||
|
4. Do most of the single date processing. Run
|
||||||
|
./cmd_1.sh
|
||||||
|
|
||||||
|
In all command files including cmd_1.sh, note that same commands for processing different dates either
|
||||||
|
listed repeatedly or in a loop can run parallelly. The 'resample to a common grid' step in cmd_1.sh is
|
||||||
|
a very time consuming step. These commands can of course run parallelly, but note that each command may
|
||||||
|
use up to 7G memory.
|
||||||
|
|
||||||
|
5. InSAR processing before ionosphere correction. Run
|
||||||
|
./cmd_2.sh
|
||||||
|
|
||||||
|
6. Ionosphere correction (if do ionospheric phase estimation, by default True). If the following parameter of
|
||||||
|
the input xml file is True (default)
|
||||||
|
|
||||||
|
<!--<property name="do ionospheric phase estimation">True</property>-->
|
||||||
|
|
||||||
|
Run
|
||||||
|
./cmd_3.sh
|
||||||
|
|
||||||
|
After it finishes, check the images in folder 'fig_ion' to see if ionosphere estimation is OK for each
|
||||||
|
pair. The anomalies include dense fringes or slight phase difference between adjacent swaths in ScanSAR
|
||||||
|
interferograms after removing ionosphere. There might also be dense fringes elsewhere. These are all anomalies
|
||||||
|
and the associated ionosphere estimation results should not be used in the next steps.
|
||||||
|
|
||||||
|
At the end of this command file, there is a step called 'estimate ionospheric phase for each date'. If you found
|
||||||
|
some pairs with ionosphere estimation anomalies, specify them by adding argument '-exc_pair' to the command ion_ls.py.
|
||||||
|
Make sure all dates are still connected after excluding these pairs, and then run ion_ls.py.
|
||||||
|
|
||||||
|
You can plot baselines to see if the pairs are fully connected, e.g.
|
||||||
|
${PATH_ALOSSTACK}/plot_baseline.py -baseline baseline/baseline_center.txt -pairs_dir pairs_ion -pairs_exc 150520-150701 -output baselines.pdf
|
||||||
|
|
||||||
|
If the following parameters of the input xml file are True (default)
|
||||||
|
|
||||||
|
<!--<property name="do ionospheric phase estimation">True</property>-->
|
||||||
|
<!--<property name="apply ionospheric phase correction">True</property>-->
|
||||||
|
|
||||||
|
there is a final step called 'correct ionosphere' in cmd_3.sh, uncomment the code marked by '#uncomment to run this command'
|
||||||
|
and then run the entire step.
|
||||||
|
|
||||||
|
7. InSAR processing after ionosphere correction. Run
|
||||||
|
./cmd_4.sh
|
||||||
|
|
||||||
|
If everything is OK, you may consider removing the huge slc files in folder dates_resampled. When you need them in
|
||||||
|
the future, you can re-run the commands in the '#resample to a common grid' step in cmd_1.sh.
|
||||||
|
|
||||||
|
Furthermore, you may consider removing the huge original data files you unpacked previously.
|
||||||
|
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
# 3. ADDING MORE DATES
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
Sometimes we want to add new acquistions to the already processed stack. To do this,
|
||||||
|
|
||||||
|
1. Upack the new acquistions in data directory following #1. PREPARE DATA.
|
||||||
|
|
||||||
|
2. Repeat the processing in #2. PROCESS DATA.
|
||||||
|
|
||||||
|
We recommend saving previous command files in a folder before new processing. Note that even the previously processed
|
||||||
|
pairs will be reprocessed again by cmd_4.sh if the following parameters of the input xml file are True (default)
|
||||||
|
|
||||||
|
<!--<property name="do ionospheric phase estimation">True</property>-->
|
||||||
|
<!--<property name="apply ionospheric phase correction">True</property>-->
|
||||||
|
|
||||||
|
because ionospheric phase will be estimated by ion_ls.py at the end of cmd_3.sh for each date with new pairs included,
|
||||||
|
and therefore all steps after ion_ls.py should be reprocessed.
|
||||||
|
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
# 4. CHECK RESULTS
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
baseline basline files
|
||||||
|
burst_synchronization.txt burst synchronization
|
||||||
|
dates original date of each date
|
||||||
|
dates_ion ionospheric phase of each date
|
||||||
|
dates_resampled resampled date of each date. Data of all other dates are coregistered to reference date.
|
||||||
|
The parameter xml files including *.track.xml and f*_*/*.frame.xml are in reference date
|
||||||
|
folder. These should be the files you should use in most cases, such as looking for data
|
||||||
|
parameters, preparing for time series analysis etc.
|
||||||
|
fig_ion figures for checking ionosphere estimation results
|
||||||
|
pairs pairs of InSAR processing
|
||||||
|
pairs_ion pairs for ionosphere estimation
|
||||||
|
|
||||||
|
If you want to know more details about the files in each folder, read
|
||||||
|
CODE_DIR/examples/input_files/alos2/alos2_tutorial.txt
|
||||||
|
File name conventions and directory structures are mostly the same.
|
||||||
|
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
# 5. KNOWN ISSUES
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
1. Issues with Ionospheric Correction
|
||||||
|
According to our experience, ionospheric correction works for most of the interferograms. Because it
|
||||||
|
relies on coherence and phase unwrapping, it does not work in some cases. These include:
|
||||||
|
|
||||||
|
(1) data have low coherence
|
||||||
|
(2) the majority of the imaged area is low coherence area like lake, ocean...
|
||||||
|
(3) the imaged area is completely divided into several isolated areas by low coherence areas, such as
|
||||||
|
islands.
|
||||||
|
|
||||||
|
In addition to the above issues, there are also data-mode-related issues.
|
||||||
|
(1) ScanSAR-ScanSAR interferometry. While you can process one single subswath, it's better to process
|
||||||
|
more than one subswath if the addistional subswath has good coherence. This is good for ionospheric
|
||||||
|
correction.
|
||||||
|
|
||||||
|
(2) Range distortions in JAXA product. This mostly happens in stripmap-stripmap interferometry using
|
||||||
|
data not covering Japan. If you see very dense fringes in the corrected inteferogram, probably it is
|
||||||
|
caused by this problem. This has been reported to JAXA and JAXA is working on debugging the focusing
|
||||||
|
program.
|
||||||
|
|
||||||
|
UPDATE: On November 20, 2018 (JST), JAXA updated the software for PALSAR-2 standard products. Therefore,
|
||||||
|
if your product is ordered after this time, you don't have this problem.
|
||||||
|
|
||||||
|
|
||||||
|
2. How do I improve ionospheric correction?
|
||||||
|
|
||||||
|
First of all, we recommend reading through cmd_3.sh before manually improving ionosphere estimation results.
|
||||||
|
|
||||||
|
Isolated areas lead to relative phase unwrapping errors, and therefore leads to significant errors in ionosphere
|
||||||
|
estimation result, usually shown as dense fringes in the corrected interferograms. If your scene covers an area
|
||||||
|
with two or more isolated areas and you are interested in one of the areas, you can mask out the other areas by
|
||||||
|
setting "areas masked out in ionospheric phase estimation".
|
||||||
|
|
||||||
|
Or if you have processed the data, you can also specify the argument -masked_areas in ion_filt.py in cmd_3.sh.
|
||||||
|
Then check the updated results following step '#check ionosphere estimation results' in cmd_3.sh
|
||||||
|
|
||||||
|
For ScanSAR, the software uses some accurate values for removing phase difference between adjacent swaths.
|
||||||
|
This, however, does not work well sometimes as a result of the inconistencies between different JAXA products,
|
||||||
|
especially products processed by different versions of JAXA software. As a result of this, you may see dense
|
||||||
|
fringes in the ionospheric correction result. In this case, you can try not to use aforementioned accurate
|
||||||
|
values by setting -snap in ion_subband.py in cmd_3.sh, and run this command and the remaining commands to see
|
||||||
|
if ionosphere estimation results have improvement.
|
||||||
|
|
||||||
|
Note that each time you updated ionosphere estimation results, you need to re-run the steps after
|
||||||
|
'#estimate ionospheric phase for each date' (including this step) in cmd_3.sh, as well as cmd_4.sh
|
||||||
|
|
||||||
|
4. ScanSAR burst synchronization
|
||||||
|
For ScanSAR data acquired before February 8, 2015, chances of having enough burst synchronization for
|
||||||
|
interferometry are very low. Don't include data acquired before this date in your stack processing.
|
||||||
|
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
# 6. REFRENCES
|
||||||
|
###########################################
|
||||||
|
The methods and algorithms implemented can be found in the following papers.
|
||||||
|
|
||||||
|
1. ScanSAR or multi-mode InSAR processing
|
||||||
|
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
||||||
|
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
||||||
|
|
||||||
|
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
||||||
|
multi-aperture InSAR (MAI) processing
|
||||||
|
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
||||||
|
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
||||||
|
|
||||||
|
3. Ionospheric correction
|
||||||
|
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
||||||
|
data acquired by ALOS-2,"
|
||||||
|
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,186 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import getBboxRdr
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
|
||||||
|
|
||||||
|
def computeBaseline(trackReference, trackSecondary, azimuthTime, rangeDistance):
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from isceobj.Planet.Planet import Planet
|
||||||
|
|
||||||
|
#modify Piyush's code for computing baslines
|
||||||
|
refElp = Planet(pname='Earth').ellipsoid
|
||||||
|
#for x in points:
|
||||||
|
referenceSV = trackReference.orbit.interpolate(azimuthTime, method='hermite')
|
||||||
|
target = trackReference.orbit.rdr2geo(azimuthTime, rangeDistance)
|
||||||
|
|
||||||
|
slvTime, slvrng = trackSecondary.orbit.geo2rdr(target)
|
||||||
|
secondarySV = trackSecondary.orbit.interpolateOrbit(slvTime, method='hermite')
|
||||||
|
|
||||||
|
targxyz = np.array(refElp.LLH(target[0], target[1], target[2]).ecef().tolist())
|
||||||
|
mxyz = np.array(referenceSV.getPosition())
|
||||||
|
mvel = np.array(referenceSV.getVelocity())
|
||||||
|
sxyz = np.array(secondarySV.getPosition())
|
||||||
|
|
||||||
|
#to fix abrupt change near zero in baseline grid. JUN-05-2020
|
||||||
|
mvelunit = mvel / np.linalg.norm(mvel)
|
||||||
|
sxyz = sxyz - np.dot ( sxyz-mxyz, mvelunit) * mvelunit
|
||||||
|
|
||||||
|
aa = np.linalg.norm(sxyz-mxyz)
|
||||||
|
costheta = (rangeDistance*rangeDistance + aa*aa - slvrng*slvrng)/(2.*rangeDistance*aa)
|
||||||
|
|
||||||
|
Bpar = aa*costheta
|
||||||
|
|
||||||
|
perp = aa * np.sqrt(1 - costheta*costheta)
|
||||||
|
direction = np.sign(np.dot( np.cross(targxyz-mxyz, sxyz-mxyz), mvel))
|
||||||
|
Bperp = direction*perp
|
||||||
|
|
||||||
|
return (Bpar, Bperp)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='compute baselines for a number of dates')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-odir', dest='odir', type=str, required=True,
|
||||||
|
help = 'output directory where baseline of each date is output')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, nargs='+', default=[],
|
||||||
|
help = 'a number of secondary dates seperated by blanks. format: YYMMDD YYMMDD YYMMDD. If provided, only compute baseline grids of these dates')
|
||||||
|
parser.add_argument('-baseline_center', dest='baseline_center', type=str, default=None,
|
||||||
|
help = 'output baseline file at image center for all dates. If not provided, it will not be computed')
|
||||||
|
parser.add_argument('-baseline_grid', dest='baseline_grid', action='store_true', default=False,
|
||||||
|
help='compute baseline grid for each date')
|
||||||
|
parser.add_argument('-baseline_grid_width', dest='baseline_grid_width', type=int, default=10,
|
||||||
|
help = 'baseline grid width if compute baseline grid, default: 10')
|
||||||
|
parser.add_argument('-baseline_grid_length', dest='baseline_grid_length', type=int, default=10,
|
||||||
|
help = 'baseline grid length if compute baseline grid, default: 10')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
odir = inps.odir
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
baselineCenterFile = inps.baseline_center
|
||||||
|
baselineGrid = inps.baseline_grid
|
||||||
|
|
||||||
|
widthBaseline = inps.baseline_grid_width
|
||||||
|
lengthBaseline = inps.baseline_grid_length
|
||||||
|
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
|
||||||
|
#get date statistics
|
||||||
|
dateDirs, dates, frames, swaths, dateIndexReference = stackDateStatistics(idir, dateReference)
|
||||||
|
ndate = len(dates)
|
||||||
|
nframe = len(frames)
|
||||||
|
nswath = len(swaths)
|
||||||
|
|
||||||
|
|
||||||
|
#create output directory if it does not already exist
|
||||||
|
if not os.path.isdir(odir):
|
||||||
|
print('output directory {} does not exist, create'.format(odir))
|
||||||
|
os.makedirs(odir, exist_ok=True)
|
||||||
|
os.chdir(odir)
|
||||||
|
|
||||||
|
|
||||||
|
#compute baseline
|
||||||
|
trackReference = loadTrack(dateDirs[dateIndexReference], dates[dateIndexReference])
|
||||||
|
bboxRdr = getBboxRdr(trackReference)
|
||||||
|
#at four corners
|
||||||
|
rangeMin = bboxRdr[0]
|
||||||
|
rangeMax = bboxRdr[1]
|
||||||
|
azimuthTimeMin = bboxRdr[2]
|
||||||
|
azimuthTimeMax = bboxRdr[3]
|
||||||
|
#at image center
|
||||||
|
azimuthTimeMid = azimuthTimeMin+datetime.timedelta(seconds=(azimuthTimeMax-azimuthTimeMin).total_seconds()/2.0)
|
||||||
|
rangeMid = (rangeMin + rangeMax) / 2.0
|
||||||
|
#grid size
|
||||||
|
rangeDelta = (rangeMax - rangeMin) / (widthBaseline - 1.0)
|
||||||
|
azimuthDelta = (azimuthTimeMax-azimuthTimeMin).total_seconds() / (lengthBaseline - 1.0)
|
||||||
|
|
||||||
|
#baseline at image center
|
||||||
|
if baselineCenterFile is not None:
|
||||||
|
baselineCenter = ' reference date secondary date parallel baseline [m] perpendicular baseline [m]\n'
|
||||||
|
baselineCenter += '===========================================================================================\n'
|
||||||
|
|
||||||
|
#baseline grid: two-band BIL image, first band: parallel baseline, perpendicular baseline
|
||||||
|
baseline = np.zeros((lengthBaseline*2, widthBaseline), dtype=np.float32)
|
||||||
|
|
||||||
|
#compute baseline
|
||||||
|
for i in range(ndate):
|
||||||
|
if i == dateIndexReference:
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
trackSecondary = loadTrack(dateDirs[i], dates[i])
|
||||||
|
|
||||||
|
#compute baseline at image center
|
||||||
|
if baselineCenterFile is not None:
|
||||||
|
(Bpar, Bperp) = computeBaseline(trackReference, trackSecondary, azimuthTimeMid, rangeMid)
|
||||||
|
baselineCenter += ' %s %s %9.3f %9.3f\n'%(dates[dateIndexReference], dates[i], Bpar, Bperp)
|
||||||
|
|
||||||
|
if dateSecondary != []:
|
||||||
|
if dates[i] not in dateSecondary:
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
#compute baseline grid
|
||||||
|
if baselineGrid:
|
||||||
|
baselineFile = '{}-{}.rmg'.format(dates[dateIndexReference], dates[i])
|
||||||
|
if os.path.isfile(baselineFile):
|
||||||
|
print('baseline grid file {} already exists, do not create'.format(baselineFile))
|
||||||
|
else:
|
||||||
|
for j in range(lengthBaseline):
|
||||||
|
for k in range(widthBaseline):
|
||||||
|
(baseline[j*2, k], baseline[j*2+1, k]) = computeBaseline(trackReference, trackSecondary,
|
||||||
|
azimuthTimeMin+datetime.timedelta(seconds=azimuthDelta*j),
|
||||||
|
rangeMin+rangeDelta*k)
|
||||||
|
baseline.astype(np.float32).tofile(baselineFile)
|
||||||
|
create_xml(baselineFile, widthBaseline, lengthBaseline, 'rmg')
|
||||||
|
|
||||||
|
#dump baseline at image center
|
||||||
|
if baselineCenterFile is not None:
|
||||||
|
print('\nbaselines at image centers')
|
||||||
|
print(baselineCenter)
|
||||||
|
with open(baselineCenterFile, 'w') as f:
|
||||||
|
f.write(baselineCenter)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,207 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
|
||||||
|
|
||||||
|
def computeBurstSynchronization(trackReference, trackSecondary):
|
||||||
|
'''compute burst synchronization
|
||||||
|
'''
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
frames = [frame.frameNumber for frame in trackReference.frames]
|
||||||
|
swaths = [swath.swathNumber for swath in trackReference.frames[0].swaths]
|
||||||
|
startingSwath = swaths[0]
|
||||||
|
endingSwath = swaths[-1]
|
||||||
|
|
||||||
|
#burst synchronization may slowly change along a track as a result of the changing relative speed of the two flights
|
||||||
|
#in one frame, real unsynchronized time is the same for all swaths
|
||||||
|
unsynTime = 0
|
||||||
|
#real synchronized time/percentage depends on the swath burst length (synTime = burstlength - abs(unsynTime))
|
||||||
|
#synTime = 0
|
||||||
|
synPercentage = 0
|
||||||
|
|
||||||
|
numberOfFrames = len(frames)
|
||||||
|
numberOfSwaths = endingSwath - startingSwath + 1
|
||||||
|
|
||||||
|
unsynTimeAll = []
|
||||||
|
synPercentageAll = []
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
unsynTimeAll0 = []
|
||||||
|
synPercentageAll0 = []
|
||||||
|
for j, swathNumber in enumerate(range(startingSwath, endingSwath + 1)):
|
||||||
|
referenceSwath = trackReference.frames[i].swaths[j]
|
||||||
|
secondarySwath = trackSecondary.frames[i].swaths[j]
|
||||||
|
#using Piyush's code for computing range and azimuth offsets
|
||||||
|
midRange = referenceSwath.startingRange + referenceSwath.rangePixelSize * referenceSwath.numberOfSamples * 0.5
|
||||||
|
midSensingStart = referenceSwath.sensingStart + datetime.timedelta(seconds = referenceSwath.numberOfLines * 0.5 / referenceSwath.prf)
|
||||||
|
llh = trackReference.orbit.rdr2geo(midSensingStart, midRange)
|
||||||
|
slvaz, slvrng = trackSecondary.orbit.geo2rdr(llh)
|
||||||
|
###Translate to offsets
|
||||||
|
#note that secondary range pixel size and prf might be different from reference, here we assume there is a virtual secondary with same
|
||||||
|
#range pixel size and prf
|
||||||
|
rgoff = ((slvrng - secondarySwath.startingRange) / referenceSwath.rangePixelSize) - referenceSwath.numberOfSamples * 0.5
|
||||||
|
azoff = ((slvaz - secondarySwath.sensingStart).total_seconds() * referenceSwath.prf) - referenceSwath.numberOfLines * 0.5
|
||||||
|
|
||||||
|
#compute burst synchronization
|
||||||
|
#burst parameters for ScanSAR wide mode not estimed yet
|
||||||
|
#if self._insar.modeCombination == 21:
|
||||||
|
scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
|
||||||
|
#secondary burst start times corresponding to reference burst start times (100% synchronization)
|
||||||
|
scburstStartLines = np.arange(scburstStartLine - 100000*referenceSwath.burstCycleLength, \
|
||||||
|
scburstStartLine + 100000*referenceSwath.burstCycleLength, \
|
||||||
|
referenceSwath.burstCycleLength)
|
||||||
|
dscburstStartLines = -((secondarySwath.burstStartTime - secondarySwath.sensingStart).total_seconds() * secondarySwath.prf - scburstStartLines)
|
||||||
|
#find the difference with minimum absolute value
|
||||||
|
unsynLines = dscburstStartLines[np.argmin(np.absolute(dscburstStartLines))]
|
||||||
|
if np.absolute(unsynLines) >= secondarySwath.burstLength:
|
||||||
|
synLines = 0
|
||||||
|
if unsynLines > 0:
|
||||||
|
unsynLines = secondarySwath.burstLength
|
||||||
|
else:
|
||||||
|
unsynLines = -secondarySwath.burstLength
|
||||||
|
else:
|
||||||
|
synLines = secondarySwath.burstLength - np.absolute(unsynLines)
|
||||||
|
|
||||||
|
unsynTime += unsynLines / referenceSwath.prf
|
||||||
|
synPercentage += synLines / referenceSwath.burstLength * 100.0
|
||||||
|
|
||||||
|
unsynTimeAll0.append(unsynLines / referenceSwath.prf)
|
||||||
|
synPercentageAll0.append(synLines / referenceSwath.burstLength * 100.0)
|
||||||
|
|
||||||
|
unsynTimeAll.append(unsynTimeAll0)
|
||||||
|
synPercentageAll.append(synPercentageAll0)
|
||||||
|
|
||||||
|
############################################################################################
|
||||||
|
#illustration of the sign of the number of unsynchronized lines (unsynLines)
|
||||||
|
#The convention is the same as ampcor offset, that is,
|
||||||
|
# secondaryLineNumber = referenceLineNumber + unsynLines
|
||||||
|
#
|
||||||
|
# |-----------------------| ------------
|
||||||
|
# | | ^
|
||||||
|
# | | |
|
||||||
|
# | | | unsynLines < 0
|
||||||
|
# | | |
|
||||||
|
# | | \ /
|
||||||
|
# | | |-----------------------|
|
||||||
|
# | | | |
|
||||||
|
# | | | |
|
||||||
|
# |-----------------------| | |
|
||||||
|
# Reference Burst | |
|
||||||
|
# | |
|
||||||
|
# | |
|
||||||
|
# | |
|
||||||
|
# | |
|
||||||
|
# |-----------------------|
|
||||||
|
# Secondary Burst
|
||||||
|
#
|
||||||
|
#
|
||||||
|
############################################################################################
|
||||||
|
|
||||||
|
#getting average
|
||||||
|
#if self._insar.modeCombination == 21:
|
||||||
|
unsynTime /= numberOfFrames*numberOfSwaths
|
||||||
|
synPercentage /= numberOfFrames*numberOfSwaths
|
||||||
|
|
||||||
|
return (unsynTimeAll, synPercentageAll)
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='compute burst synchronization for a number of dates')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-burst_sync_file', dest='burst_sync_file', type=str, required=True,
|
||||||
|
help = 'output burst synchronization file')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, nargs='+', default=[],
|
||||||
|
help = 'a number of secondary dates seperated by blanks. format: YYMMDD YYMMDD YYMMDD. If provided, only compute burst synchronization of these dates')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
burstSyncFile = inps.burst_sync_file
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
|
||||||
|
#get date statistics
|
||||||
|
dateDirs, dates, frames, swaths, dateIndexReference = stackDateStatistics(idir, dateReference)
|
||||||
|
ndate = len(dates)
|
||||||
|
nframe = len(frames)
|
||||||
|
nswath = len(swaths)
|
||||||
|
|
||||||
|
|
||||||
|
#compute burst synchronization
|
||||||
|
trackReference = loadTrack(dateDirs[dateIndexReference], dates[dateIndexReference])
|
||||||
|
|
||||||
|
frames = [frame.frameNumber for frame in trackReference.frames]
|
||||||
|
swaths = [swath.swathNumber for swath in trackReference.frames[0].swaths]
|
||||||
|
startingSwath = swaths[0]
|
||||||
|
endingSwath = swaths[-1]
|
||||||
|
|
||||||
|
burstSync = ' reference date secondary date frame swath burst UNsync time [ms] burst sync [%]\n'
|
||||||
|
burstSync += '==================================================================================================\n'
|
||||||
|
|
||||||
|
#compute burst synchronization
|
||||||
|
for i in range(ndate):
|
||||||
|
if i == dateIndexReference:
|
||||||
|
continue
|
||||||
|
if dateSecondary != []:
|
||||||
|
if dates[i] not in dateSecondary:
|
||||||
|
continue
|
||||||
|
|
||||||
|
trackSecondary = loadTrack(dateDirs[i], dates[i])
|
||||||
|
unsynTimeAll, synPercentageAll = computeBurstSynchronization(trackReference, trackSecondary)
|
||||||
|
|
||||||
|
for j in range(nframe):
|
||||||
|
for k in range(nswath):
|
||||||
|
if (j == 0) and (k == 0):
|
||||||
|
burstSync += ' %s %s %s %d %8.2f %6.2f\n'%\
|
||||||
|
(dates[dateIndexReference], dates[i], frames[j], swaths[k], unsynTimeAll[j][k]*1000.0, synPercentageAll[j][k])
|
||||||
|
else:
|
||||||
|
burstSync += ' %s %d %8.2f %6.2f\n'%\
|
||||||
|
(frames[j], swaths[k], unsynTimeAll[j][k]*1000.0, synPercentageAll[j][k])
|
||||||
|
|
||||||
|
burstSync += ' %8.2f (mean) %6.2f (mean)\n\n'%(np.mean(np.array(unsynTimeAll), dtype=np.float64)*1000.0, np.mean(np.array(synPercentageAll), dtype=np.float64))
|
||||||
|
|
||||||
|
|
||||||
|
#dump burstSync
|
||||||
|
print('\nburst synchronization')
|
||||||
|
print(burstSync)
|
||||||
|
with open(burstSyncFile, 'w') as f:
|
||||||
|
f.write(burstSync)
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,97 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
|
|
||||||
|
from StackPulic import loadProduct
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='form interferogram')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where resampled data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-ref_date_stack', dest='ref_date_stack', type=str, required=True,
|
||||||
|
help = 'reference date of stack. format: YYMMDD')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
dateReferenceStack = inps.ref_date_stack
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
|
||||||
|
dateDirs, dates, frames, swaths, dateIndexReference = stackDateStatistics(idir, dateReferenceStack)
|
||||||
|
|
||||||
|
trackParameter = os.path.join(dateDirs[dateIndexReference], dates[dateIndexReference]+'.track.xml')
|
||||||
|
trackReferenceStack = loadProduct(trackParameter)
|
||||||
|
|
||||||
|
rangePixelSize = numberRangeLooks1 * trackReferenceStack.rangePixelSize
|
||||||
|
radarWavelength = trackReferenceStack.radarWavelength
|
||||||
|
|
||||||
|
insarDir = 'insar'
|
||||||
|
os.makedirs(insarDir, exist_ok=True)
|
||||||
|
os.chdir(insarDir)
|
||||||
|
|
||||||
|
interferogram = pair + ml1 + '.int'
|
||||||
|
differentialInterferogram = 'diff_' + pair + ml1 + '.int'
|
||||||
|
|
||||||
|
if dateReference == dateReferenceStack:
|
||||||
|
rectRangeOffset = os.path.join('../', idir, dateSecondary, 'insar', dateSecondary + ml1 + '_rg_rect.off')
|
||||||
|
cmd = "imageMath.py -e='a*exp(-1.0*J*b*4.0*{}*{}/{})*(b!=0)' --a={} --b={} -o {} -t cfloat".format(np.pi, rangePixelSize, radarWavelength, interferogram, rectRangeOffset, differentialInterferogram)
|
||||||
|
elif dateSecondary == dateReferenceStack:
|
||||||
|
rectRangeOffset = os.path.join('../', idir, dateReference, 'insar', dateReference + ml1 + '_rg_rect.off')
|
||||||
|
cmd = "imageMath.py -e='a*exp(1.0*J*b*4.0*{}*{}/{})*(b!=0)' --a={} --b={} -o {} -t cfloat".format(np.pi, rangePixelSize, radarWavelength, interferogram, rectRangeOffset, differentialInterferogram)
|
||||||
|
else:
|
||||||
|
rectRangeOffset1 = os.path.join('../', idir, dateReference, 'insar', dateReference + ml1 + '_rg_rect.off')
|
||||||
|
rectRangeOffset2 = os.path.join('../', idir, dateSecondary, 'insar', dateSecondary + ml1 + '_rg_rect.off')
|
||||||
|
cmd = "imageMath.py -e='a*exp(1.0*J*(b-c)*4.0*{}*{}/{})*(b!=0)*(c!=0)' --a={} --b={} --c={} -o {} -t cfloat".format(np.pi, rangePixelSize, radarWavelength, interferogram, rectRangeOffset1, rectRangeOffset2, differentialInterferogram)
|
||||||
|
runCmd(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
os.chdir('../')
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.runFrameOffset import frameOffset
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='estimate frame offset')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'data directory')
|
||||||
|
parser.add_argument('-date', dest='date', type=str, required=True,
|
||||||
|
help = 'data acquisition date. format: YYMMDD')
|
||||||
|
parser.add_argument('-output', dest='output', type=str, required=True,
|
||||||
|
help = 'output file')
|
||||||
|
#parser.add_argument('-match', dest='match', type=int, default=1,
|
||||||
|
# help = 'do matching when computing adjacent frame offset. 0: no. 1: yes (default)')
|
||||||
|
parser.add_argument('-match', dest='match', action='store_true', default=False,
|
||||||
|
help='do matching when computing adjacent swath offset')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
date = inps.date
|
||||||
|
outputFile = inps.output
|
||||||
|
match = inps.match
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = acquisitionModesAlos2()
|
||||||
|
|
||||||
|
|
||||||
|
track = loadTrack(idir, date)
|
||||||
|
|
||||||
|
#save current dir
|
||||||
|
dirOriginal = os.getcwd()
|
||||||
|
os.chdir(idir)
|
||||||
|
|
||||||
|
|
||||||
|
if len(track.frames) > 1:
|
||||||
|
if track.operationMode in scansarModes:
|
||||||
|
matchingMode=0
|
||||||
|
else:
|
||||||
|
matchingMode=1
|
||||||
|
|
||||||
|
mosaicDir = 'insar'
|
||||||
|
os.makedirs(mosaicDir, exist_ok=True)
|
||||||
|
os.chdir(mosaicDir)
|
||||||
|
|
||||||
|
#compute swath offset
|
||||||
|
offsetReference = frameOffset(track, date+'.slc', 'frame_offset.txt',
|
||||||
|
crossCorrelation=match, matchingMode=matchingMode)
|
||||||
|
|
||||||
|
os.chdir('../')
|
||||||
|
else:
|
||||||
|
print('there is only one frame, no need to estimate frame offset')
|
||||||
|
|
||||||
|
|
@ -0,0 +1,392 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
import mroipac
|
||||||
|
from mroipac.ampcor.Ampcor import Ampcor
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import topo
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import geo2rdr
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import reformatGeometricalOffset
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import writeOffset
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import cullOffsets
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import computeOffsetFromOrbit
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='estimate offset between a pair of SLCs for a number of dates')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, nargs='+', default=[],
|
||||||
|
help = 'a number of secondary dates seperated by blanks. format: YYMMDD YYMMDD YYMMDD. If provided, only estimate offsets of these dates')
|
||||||
|
parser.add_argument('-wbd', dest='wbd', type=str, default=None,
|
||||||
|
help = 'water body used to determine number of offsets in range and azimuth')
|
||||||
|
parser.add_argument('-dem', dest='dem', type=str, default=None,
|
||||||
|
help = 'if water body is provided, dem file must also be provided')
|
||||||
|
parser.add_argument('-use_wbd_offset', dest='use_wbd_offset', action='store_true', default=False,
|
||||||
|
help='use water body to dertermine number of matching offsets')
|
||||||
|
parser.add_argument('-num_rg_offset', dest='num_rg_offset', type=int, nargs='+', action='append', default=[],
|
||||||
|
help = 'number of offsets in range. format (e.g. 2 frames, 3 swaths): -num_rg_offset 11 12 13 -num_rg_offset 14 15 16')
|
||||||
|
parser.add_argument('-num_az_offset', dest='num_az_offset', type=int, nargs='+', action='append', default=[],
|
||||||
|
help = 'number of offsets in azimuth. format (e.g. 2 frames, 3 swaths): -num_az_offset 11 12 13 -num_az_offset 14 15 16')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
wbd = inps.wbd
|
||||||
|
dem = inps.dem
|
||||||
|
useWbdForNumberOffsets = inps.use_wbd_offset
|
||||||
|
numberOfOffsetsRangeInput = inps.num_rg_offset
|
||||||
|
numberOfOffsetsAzimuthInput = inps.num_az_offset
|
||||||
|
|
||||||
|
|
||||||
|
if wbd is not None:
|
||||||
|
wbdFile = os.path.abspath(wbd)
|
||||||
|
else:
|
||||||
|
wbdFile = None
|
||||||
|
if dem is not None:
|
||||||
|
demFile = os.path.abspath(dem)
|
||||||
|
else:
|
||||||
|
demFile = None
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
|
||||||
|
spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = acquisitionModesAlos2()
|
||||||
|
|
||||||
|
|
||||||
|
warningMessage = ''
|
||||||
|
|
||||||
|
|
||||||
|
#get date statistics
|
||||||
|
dateDirs, dates, frames, swaths, dateIndexReference = stackDateStatistics(idir, dateReference)
|
||||||
|
ndate = len(dates)
|
||||||
|
nframe = len(frames)
|
||||||
|
nswath = len(swaths)
|
||||||
|
|
||||||
|
|
||||||
|
#load reference track
|
||||||
|
referenceTrack = loadTrack(dateDirs[dateIndexReference], dates[dateIndexReference])
|
||||||
|
|
||||||
|
|
||||||
|
#set number of matching points
|
||||||
|
numberOfOffsetsRangeUsed = [[None for j in range(nswath)] for i in range(nframe)]
|
||||||
|
numberOfOffsetsAzimuthUsed = [[None for j in range(nswath)] for i in range(nframe)]
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
|
||||||
|
print('determine number of range/azimuth offsets frame {}, swath {}'.format(frameNumber, swathNumber))
|
||||||
|
referenceSwath = referenceTrack.frames[i].swaths[j]
|
||||||
|
|
||||||
|
#1. set initinial numbers
|
||||||
|
#in case there are long time span pairs that have bad coherence
|
||||||
|
ratio = np.sqrt(1.5)
|
||||||
|
if referenceTrack.operationMode in scansarModes:
|
||||||
|
numberOfOffsetsRange = int(10*ratio+0.5)
|
||||||
|
numberOfOffsetsAzimuth = int(40*ratio+0.5)
|
||||||
|
else:
|
||||||
|
numberOfOffsetsRange = int(20*ratio+0.5)
|
||||||
|
numberOfOffsetsAzimuth = int(20*ratio+0.5)
|
||||||
|
|
||||||
|
#2. change the initial numbers using water body
|
||||||
|
if useWbdForNumberOffsets and (wbdFile is not None) and (demFile is not None):
|
||||||
|
numberRangeLooks=100
|
||||||
|
numberAzimuthLooks=100
|
||||||
|
|
||||||
|
#compute land ratio using topo module
|
||||||
|
latFile = 'lat_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
lonFile = 'lon_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
hgtFile = 'hgt_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
losFile = 'los_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
wbdRadarFile = 'wbd_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
|
||||||
|
topo(referenceSwath, referenceTrack, demFile, latFile, lonFile, hgtFile, losFile=losFile,
|
||||||
|
incFile=None, mskFile=None,
|
||||||
|
numberRangeLooks=numberRangeLooks, numberAzimuthLooks=numberAzimuthLooks, multilookTimeOffset=False)
|
||||||
|
waterBodyRadar(latFile, lonFile, wbdFile, wbdRadarFile)
|
||||||
|
|
||||||
|
wbdImg = isceobj.createImage()
|
||||||
|
wbdImg.load(wbdRadarFile+'.xml')
|
||||||
|
width = wbdImg.width
|
||||||
|
length = wbdImg.length
|
||||||
|
|
||||||
|
wbd = np.fromfile(wbdRadarFile, dtype=np.byte).reshape(length, width)
|
||||||
|
landRatio = np.sum(wbd==0) / (length*width)
|
||||||
|
|
||||||
|
if (landRatio <= 0.00125):
|
||||||
|
print('\n\nWARNING: land too small for estimating slc offsets at frame {}, swath {}'.format(frameNumber, swathNumber))
|
||||||
|
print('proceed to use geometric offsets for forming interferogram')
|
||||||
|
print('but please consider not using this swath\n\n')
|
||||||
|
warningMessage += 'land too small for estimating slc offsets at frame {}, swath {}, use geometric offsets\n'.format(frameNumber, swathNumber)
|
||||||
|
|
||||||
|
numberOfOffsetsRange = 0
|
||||||
|
numberOfOffsetsAzimuth = 0
|
||||||
|
else:
|
||||||
|
#put the results on a grid with a specified interval
|
||||||
|
interval = 0.2
|
||||||
|
axisRatio = int(np.sqrt(landRatio)/interval)*interval + interval
|
||||||
|
if axisRatio > 1:
|
||||||
|
axisRatio = 1
|
||||||
|
|
||||||
|
numberOfOffsetsRange = int(numberOfOffsetsRange/axisRatio)
|
||||||
|
numberOfOffsetsAzimuth = int(numberOfOffsetsAzimuth/axisRatio)
|
||||||
|
else:
|
||||||
|
warningMessage += 'no water mask used to determine number of matching points. frame {} swath {}\n'.format(frameNumber, swathNumber)
|
||||||
|
|
||||||
|
#3. user's settings
|
||||||
|
if numberOfOffsetsRangeInput != []:
|
||||||
|
numberOfOffsetsRange = numberOfOffsetsRangeInput[i][j]
|
||||||
|
if numberOfOffsetsAzimuthInput != []:
|
||||||
|
numberOfOffsetsAzimuth = numberOfOffsetsAzimuthInput[i][j]
|
||||||
|
|
||||||
|
#4. save final results
|
||||||
|
numberOfOffsetsRangeUsed[i][j] = numberOfOffsetsRange
|
||||||
|
numberOfOffsetsAzimuthUsed[i][j] = numberOfOffsetsAzimuth
|
||||||
|
|
||||||
|
|
||||||
|
#estimate offsets
|
||||||
|
for idate in range(ndate):
|
||||||
|
if idate == dateIndexReference:
|
||||||
|
continue
|
||||||
|
if dateSecondary != []:
|
||||||
|
if dates[idate] not in dateSecondary:
|
||||||
|
continue
|
||||||
|
|
||||||
|
secondaryTrack = loadTrack(dateDirs[idate], dates[idate])
|
||||||
|
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
|
||||||
|
print('estimating offset frame {}, swath {}'.format(frameNumber, swathNumber))
|
||||||
|
referenceDir = os.path.join(dateDirs[dateIndexReference], frameDir, swathDir)
|
||||||
|
secondaryDir = os.path.join(dateDirs[idate], frameDir, swathDir)
|
||||||
|
referenceSwath = referenceTrack.frames[i].swaths[j]
|
||||||
|
secondarySwath = secondaryTrack.frames[i].swaths[j]
|
||||||
|
|
||||||
|
#compute geometrical offsets
|
||||||
|
if (wbdFile is not None) and (demFile is not None) and (numberOfOffsetsRangeUsed[i][j] == 0) and (numberOfOffsetsAzimuthUsed[i][j] == 0):
|
||||||
|
#compute geomtricla offsets
|
||||||
|
latFile = 'lat_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
lonFile = 'lon_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
hgtFile = 'hgt_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
losFile = 'los_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
rgOffsetFile = 'rg_offset_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
azOffsetFile = 'az_offset_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
wbdRadarFile = 'wbd_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
geo2rdr(secondarySwath, secondaryTrack, latFile, lonFile, hgtFile, rgOffsetFile, azOffsetFile, numberRangeLooks=numberRangeLooks, numberAzimuthLooks=numberAzimuthLooks, multilookTimeOffset=False)
|
||||||
|
reformatGeometricalOffset(rgOffsetFile, azOffsetFile, os.path.join(secondaryDir, 'cull.off'), rangeStep=numberRangeLooks, azimuthStep=numberAzimuthLooks, maximumNumberOfOffsets=2000)
|
||||||
|
|
||||||
|
os.remove(rgOffsetFile)
|
||||||
|
os.remove(rgOffsetFile+'.vrt')
|
||||||
|
os.remove(rgOffsetFile+'.xml')
|
||||||
|
os.remove(azOffsetFile)
|
||||||
|
os.remove(azOffsetFile+'.vrt')
|
||||||
|
os.remove(azOffsetFile+'.xml')
|
||||||
|
#estimate offsets using ampcor
|
||||||
|
else:
|
||||||
|
ampcor = Ampcor(name='insarapp_slcs_ampcor')
|
||||||
|
ampcor.configure()
|
||||||
|
|
||||||
|
mSLC = isceobj.createSlcImage()
|
||||||
|
mSLC.load(os.path.join(referenceDir, dates[dateIndexReference]+'.slc.xml'))
|
||||||
|
mSLC.filename = os.path.join(referenceDir, dates[dateIndexReference]+'.slc')
|
||||||
|
mSLC.extraFilename = os.path.join(referenceDir, dates[dateIndexReference]+'.slc.vrt')
|
||||||
|
mSLC.setAccessMode('read')
|
||||||
|
mSLC.createImage()
|
||||||
|
|
||||||
|
sSLC = isceobj.createSlcImage()
|
||||||
|
sSLC.load(os.path.join(secondaryDir, dates[idate]+'.slc.xml'))
|
||||||
|
sSLC.filename = os.path.join(secondaryDir, dates[idate]+'.slc')
|
||||||
|
sSLC.extraFilename = os.path.join(secondaryDir, dates[idate]+'.slc.vrt')
|
||||||
|
sSLC.setAccessMode('read')
|
||||||
|
sSLC.createImage()
|
||||||
|
|
||||||
|
ampcor.setImageDataType1('complex')
|
||||||
|
ampcor.setImageDataType2('complex')
|
||||||
|
|
||||||
|
ampcor.setReferenceSlcImage(mSLC)
|
||||||
|
ampcor.setSecondarySlcImage(sSLC)
|
||||||
|
|
||||||
|
#MATCH REGION
|
||||||
|
#compute an offset at image center to use
|
||||||
|
rgoff, azoff = computeOffsetFromOrbit(referenceSwath, referenceTrack, secondarySwath, secondaryTrack,
|
||||||
|
referenceSwath.numberOfSamples * 0.5,
|
||||||
|
referenceSwath.numberOfLines * 0.5)
|
||||||
|
#it seems that we cannot use 0, haven't look into the problem
|
||||||
|
if rgoff == 0:
|
||||||
|
rgoff = 1
|
||||||
|
if azoff == 0:
|
||||||
|
azoff = 1
|
||||||
|
firstSample = 1
|
||||||
|
if rgoff < 0:
|
||||||
|
firstSample = int(35 - rgoff)
|
||||||
|
firstLine = 1
|
||||||
|
if azoff < 0:
|
||||||
|
firstLine = int(35 - azoff)
|
||||||
|
ampcor.setAcrossGrossOffset(rgoff)
|
||||||
|
ampcor.setDownGrossOffset(azoff)
|
||||||
|
ampcor.setFirstSampleAcross(firstSample)
|
||||||
|
ampcor.setLastSampleAcross(mSLC.width)
|
||||||
|
ampcor.setNumberLocationAcross(numberOfOffsetsRangeUsed[i][j])
|
||||||
|
ampcor.setFirstSampleDown(firstLine)
|
||||||
|
ampcor.setLastSampleDown(mSLC.length)
|
||||||
|
ampcor.setNumberLocationDown(numberOfOffsetsAzimuthUsed[i][j])
|
||||||
|
|
||||||
|
#MATCH PARAMETERS
|
||||||
|
#full-aperture mode
|
||||||
|
if referenceTrack.operationMode in scansarModes:
|
||||||
|
ampcor.setWindowSizeWidth(64)
|
||||||
|
ampcor.setWindowSizeHeight(512)
|
||||||
|
#note this is the half width/length of search area, number of resulting correlation samples: 32*2+1
|
||||||
|
ampcor.setSearchWindowSizeWidth(32)
|
||||||
|
ampcor.setSearchWindowSizeHeight(32)
|
||||||
|
#triggering full-aperture mode matching
|
||||||
|
ampcor.setWinsizeFilt(8)
|
||||||
|
ampcor.setOversamplingFactorFilt(64)
|
||||||
|
#regular mode
|
||||||
|
else:
|
||||||
|
ampcor.setWindowSizeWidth(64)
|
||||||
|
ampcor.setWindowSizeHeight(64)
|
||||||
|
ampcor.setSearchWindowSizeWidth(32)
|
||||||
|
ampcor.setSearchWindowSizeHeight(32)
|
||||||
|
|
||||||
|
#REST OF THE STUFF
|
||||||
|
ampcor.setAcrossLooks(1)
|
||||||
|
ampcor.setDownLooks(1)
|
||||||
|
ampcor.setOversamplingFactor(64)
|
||||||
|
ampcor.setZoomWindowSize(16)
|
||||||
|
#1. The following not set
|
||||||
|
#Matching Scale for Sample/Line Directions (-) = 1. 1.
|
||||||
|
#should add the following in Ampcor.py?
|
||||||
|
#if not set, in this case, Ampcor.py'value is also 1. 1.
|
||||||
|
#ampcor.setScaleFactorX(1.)
|
||||||
|
#ampcor.setScaleFactorY(1.)
|
||||||
|
|
||||||
|
#MATCH THRESHOLDS AND DEBUG DATA
|
||||||
|
#2. The following not set
|
||||||
|
#in roi_pac the value is set to 0 1
|
||||||
|
#in isce the value is set to 0.001 1000.0
|
||||||
|
#SNR and Covariance Thresholds (-) = {s1} {s2}
|
||||||
|
#should add the following in Ampcor?
|
||||||
|
#THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC
|
||||||
|
#ampcor.setThresholdSNR(0)
|
||||||
|
#ampcor.setThresholdCov(1)
|
||||||
|
ampcor.setDebugFlag(False)
|
||||||
|
ampcor.setDisplayFlag(False)
|
||||||
|
|
||||||
|
#in summary, only two things not set which are indicated by 'The following not set' above.
|
||||||
|
|
||||||
|
#run ampcor
|
||||||
|
ampcor.ampcor()
|
||||||
|
offsets = ampcor.getOffsetField()
|
||||||
|
ampcorOffsetFile = os.path.join(secondaryDir, 'ampcor.off')
|
||||||
|
writeOffset(offsets, ampcorOffsetFile)
|
||||||
|
|
||||||
|
#finalize image, and re-create it
|
||||||
|
#otherwise the file pointer is still at the end of the image
|
||||||
|
mSLC.finalizeImage()
|
||||||
|
sSLC.finalizeImage()
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
#3. cull offsets
|
||||||
|
##########################################
|
||||||
|
refinedOffsets = cullOffsets(offsets)
|
||||||
|
if refinedOffsets == None:
|
||||||
|
print('******************************************************************')
|
||||||
|
print('WARNING: There are not enough offsets left, so we are forced to')
|
||||||
|
print(' use offset without culling. frame {}, swath {}'.format(frameNumber, swathNumber))
|
||||||
|
print('******************************************************************')
|
||||||
|
warningMessage += 'not enough offsets left, use offset without culling. frame {} swath {}'.format(frameNumber, swathNumber)
|
||||||
|
refinedOffsets = offsets
|
||||||
|
|
||||||
|
cullOffsetFile = os.path.join(secondaryDir, 'cull.off')
|
||||||
|
writeOffset(refinedOffsets, cullOffsetFile)
|
||||||
|
|
||||||
|
#os.chdir('../')
|
||||||
|
#os.chdir('../')
|
||||||
|
|
||||||
|
|
||||||
|
#delete geometry files
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
|
||||||
|
if (wbdFile is not None) and (demFile is not None):
|
||||||
|
latFile = 'lat_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
lonFile = 'lon_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
hgtFile = 'hgt_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
losFile = 'los_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
wbdRadarFile = 'wbd_f{}_{}_s{}.rdr'.format(i+1, frameNumber, swathNumber)
|
||||||
|
|
||||||
|
os.remove(latFile)
|
||||||
|
os.remove(latFile+'.vrt')
|
||||||
|
os.remove(latFile+'.xml')
|
||||||
|
|
||||||
|
os.remove(lonFile)
|
||||||
|
os.remove(lonFile+'.vrt')
|
||||||
|
os.remove(lonFile+'.xml')
|
||||||
|
|
||||||
|
os.remove(hgtFile)
|
||||||
|
os.remove(hgtFile+'.vrt')
|
||||||
|
os.remove(hgtFile+'.xml')
|
||||||
|
|
||||||
|
os.remove(losFile)
|
||||||
|
os.remove(losFile+'.vrt')
|
||||||
|
os.remove(losFile+'.xml')
|
||||||
|
|
||||||
|
os.remove(wbdRadarFile)
|
||||||
|
os.remove(wbdRadarFile+'.vrt')
|
||||||
|
os.remove(wbdRadarFile+'.xml')
|
||||||
|
|
||||||
|
|
||||||
|
numberOfOffsetsUsedTxt = '\nnumber of offsets in cross correlation:\n'
|
||||||
|
numberOfOffsetsUsedTxt += ' frame swath range azimuth\n'
|
||||||
|
numberOfOffsetsUsedTxt += '============================================\n'
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
numberOfOffsetsUsedTxt += ' {} {} {} {}\n'.format(frameNumber, swathNumber, numberOfOffsetsRangeUsed[i][j], numberOfOffsetsAzimuthUsed[i][j])
|
||||||
|
print(numberOfOffsetsUsedTxt)
|
||||||
|
|
||||||
|
if warningMessage != '':
|
||||||
|
print('\n'+warningMessage+'\n')
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.runSwathOffset import swathOffset
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='estimate swath offset')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'data directory')
|
||||||
|
parser.add_argument('-date', dest='date', type=str, required=True,
|
||||||
|
help = 'data acquisition date. format: YYMMDD')
|
||||||
|
parser.add_argument('-output', dest='output', type=str, required=True,
|
||||||
|
help = 'output file')
|
||||||
|
#parser.add_argument('-match', dest='match', type=int, default=1,
|
||||||
|
# help = 'do matching when computing adjacent swath offset. 0: no. 1: yes (default)')
|
||||||
|
parser.add_argument('-match', dest='match', action='store_true', default=False,
|
||||||
|
help='do matching when computing adjacent swath offset')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
date = inps.date
|
||||||
|
outputFile = inps.output
|
||||||
|
match = inps.match
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = acquisitionModesAlos2()
|
||||||
|
|
||||||
|
|
||||||
|
frames = sorted([x[-4:] for x in glob.glob(os.path.join(idir, 'f*_*'))])
|
||||||
|
track = loadTrack(idir, date)
|
||||||
|
|
||||||
|
#save current dir
|
||||||
|
dirOriginal = os.getcwd()
|
||||||
|
os.chdir(idir)
|
||||||
|
|
||||||
|
|
||||||
|
if (track.operationMode in scansarModes) and (len(track.frames[0].swaths) >= 2):
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
os.chdir(frameDir)
|
||||||
|
|
||||||
|
mosaicDir = 'mosaic'
|
||||||
|
os.makedirs(mosaicDir, exist_ok=True)
|
||||||
|
os.chdir(mosaicDir)
|
||||||
|
|
||||||
|
#compute swath offset
|
||||||
|
offsetReference = swathOffset(track.frames[i], date+'.slc', outputFile,
|
||||||
|
crossCorrelation=match, numberOfAzimuthLooks=10)
|
||||||
|
|
||||||
|
os.chdir('../../')
|
||||||
|
else:
|
||||||
|
print('there is only one swath, no need to estimate swath offset')
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.runFilt import filt
|
||||||
|
|
||||||
|
from StackPulic import createObject
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='take more looks and compute coherence')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where resampled data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-ref_date_stack', dest='ref_date_stack', type=str, required=True,
|
||||||
|
help = 'reference date of stack. format: YYMMDD')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
parser.add_argument('-nrlks2', dest='nrlks2', type=int, default=1,
|
||||||
|
help = 'number of range looks 2. default: 1')
|
||||||
|
parser.add_argument('-nalks2', dest='nalks2', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 2. default: 1')
|
||||||
|
parser.add_argument('-alpha', dest='alpha', type=float, default=0.3,
|
||||||
|
help='filtering strength. default: 0.3')
|
||||||
|
parser.add_argument('-win', dest='win', type=int, default=32,
|
||||||
|
help = 'filter window size. default: 32')
|
||||||
|
parser.add_argument('-step', dest='step', type=int, default=4,
|
||||||
|
help = 'filter step size. default: 4')
|
||||||
|
parser.add_argument('-keep_mag', dest='keep_mag', action='store_true', default=False,
|
||||||
|
help='keep magnitude before filtering interferogram')
|
||||||
|
parser.add_argument('-wbd_msk', dest='wbd_msk', action='store_true', default=False,
|
||||||
|
help='mask filtered interferogram with water body')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
dateReferenceStack = inps.ref_date_stack
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
numberRangeLooks2 = inps.nrlks2
|
||||||
|
numberAzimuthLooks2 = inps.nalks2
|
||||||
|
filterStrength = inps.alpha
|
||||||
|
filterWinsize = inps.win
|
||||||
|
filterStepsize = inps.step
|
||||||
|
removeMagnitudeBeforeFiltering = not inps.keep_mag
|
||||||
|
waterBodyMaskStartingStep = inps.wbd_msk
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
ms = pair
|
||||||
|
ml2 = '_{}rlks_{}alks'.format(numberRangeLooks1*numberRangeLooks2, numberAzimuthLooks1*numberAzimuthLooks2)
|
||||||
|
|
||||||
|
self = createObject()
|
||||||
|
self._insar = createObject()
|
||||||
|
|
||||||
|
self.filterStrength = filterStrength
|
||||||
|
self.filterWinsize = filterWinsize
|
||||||
|
self.filterStepsize = filterStepsize
|
||||||
|
self.removeMagnitudeBeforeFiltering = removeMagnitudeBeforeFiltering
|
||||||
|
self._insar.multilookDifferentialInterferogram = 'diff_' + ms + ml2 + '.int'
|
||||||
|
self._insar.filteredInterferogram = 'filt_' + ms + ml2 + '.int'
|
||||||
|
self._insar.multilookAmplitude = ms + ml2 + '.amp'
|
||||||
|
self._insar.multilookPhsig = ms + ml2 + '.phsig'
|
||||||
|
self._insar.multilookWbdOut = os.path.join(idir, dateReferenceStack, 'insar', dateReferenceStack + ml2 + '.wbd')
|
||||||
|
if waterBodyMaskStartingStep:
|
||||||
|
self.waterBodyMaskStartingStep='filt'
|
||||||
|
else:
|
||||||
|
self.waterBodyMaskStartingStep=None
|
||||||
|
|
||||||
|
filt(self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import multilook
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
from StackPulic import formInterferogram
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='form interferogram')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
|
||||||
|
#use one date to find frames and swaths. any date should work, here we use dateIndexReference
|
||||||
|
frames = sorted([x[-4:] for x in glob.glob(os.path.join('./', 'f*_*'))])
|
||||||
|
swaths = sorted([int(x[-1]) for x in glob.glob(os.path.join('./', 'f1_*', 's*'))])
|
||||||
|
|
||||||
|
nframe = len(frames)
|
||||||
|
nswath = len(swaths)
|
||||||
|
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
os.chdir(frameDir)
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
os.chdir(swathDir)
|
||||||
|
|
||||||
|
print('processing swath {}, frame {}'.format(swathNumber, frameNumber))
|
||||||
|
|
||||||
|
slcReference = dateReference+'.slc'
|
||||||
|
slcSecondary = dateSecondary+'.slc'
|
||||||
|
interferogram = pair + ml1 + '.int'
|
||||||
|
amplitude = pair + ml1 + '.amp'
|
||||||
|
formInterferogram(slcReference, slcSecondary, interferogram, amplitude, numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
|
||||||
|
os.chdir('../')
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.runGeo2Rdr import geo2RdrCPU
|
||||||
|
from isceobj.Alos2Proc.runGeo2Rdr import geo2RdrGPU
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import hasGPU
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='compute range and azimuth offsets')
|
||||||
|
parser.add_argument('-date', dest='date', type=str, required=True,
|
||||||
|
help = 'date. format: YYMMDD')
|
||||||
|
parser.add_argument('-date_par_dir', dest='date_par_dir', type=str, default='./',
|
||||||
|
help = 'date parameter directory. default: ./')
|
||||||
|
parser.add_argument('-lat', dest='lat', type=str, required=True,
|
||||||
|
help = 'latitude file')
|
||||||
|
parser.add_argument('-lon', dest='lon', type=str, required=True,
|
||||||
|
help = 'longtitude file')
|
||||||
|
parser.add_argument('-hgt', dest='hgt', type=str, required=True,
|
||||||
|
help = 'height file')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
#parser.add_argument('-gpu', dest='gpu', type=int, default=1,
|
||||||
|
# help = 'use GPU when available. 0: no. 1: yes (default)')
|
||||||
|
parser.add_argument('-gpu', dest='gpu', action='store_true', default=False,
|
||||||
|
help='use GPU when available')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
date = inps.date
|
||||||
|
dateParDir = os.path.join('../', inps.date_par_dir)
|
||||||
|
latitude = os.path.join('../', inps.lat)
|
||||||
|
longitude = os.path.join('../', inps.lon)
|
||||||
|
height = os.path.join('../', inps.hgt)
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
useGPU = inps.gpu
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
insarDir = 'insar'
|
||||||
|
os.makedirs(insarDir, exist_ok=True)
|
||||||
|
os.chdir(insarDir)
|
||||||
|
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
|
||||||
|
rangeOffset = date + ml1 + '_rg.off'
|
||||||
|
azimuthOffset = date + ml1 + '_az.off'
|
||||||
|
|
||||||
|
|
||||||
|
if not os.path.isfile(os.path.basename(latitude)):
|
||||||
|
latitudeLink = True
|
||||||
|
os.symlink(latitude, os.path.basename(latitude))
|
||||||
|
os.symlink(latitude+'.vrt', os.path.basename(latitude)+'.vrt')
|
||||||
|
os.symlink(latitude+'.xml', os.path.basename(latitude)+'.xml')
|
||||||
|
else:
|
||||||
|
latitudeLink = False
|
||||||
|
|
||||||
|
if not os.path.isfile(os.path.basename(longitude)):
|
||||||
|
longitudeLink = True
|
||||||
|
os.symlink(longitude, os.path.basename(longitude))
|
||||||
|
os.symlink(longitude+'.vrt', os.path.basename(longitude)+'.vrt')
|
||||||
|
os.symlink(longitude+'.xml', os.path.basename(longitude)+'.xml')
|
||||||
|
else:
|
||||||
|
longitudeLink = False
|
||||||
|
|
||||||
|
if not os.path.isfile(os.path.basename(height)):
|
||||||
|
heightLink = True
|
||||||
|
os.symlink(height, os.path.basename(height))
|
||||||
|
os.symlink(height+'.vrt', os.path.basename(height)+'.vrt')
|
||||||
|
os.symlink(height+'.xml', os.path.basename(height)+'.xml')
|
||||||
|
else:
|
||||||
|
heightLink = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
track = loadTrack(dateParDir, date)
|
||||||
|
if useGPU and hasGPU():
|
||||||
|
geo2RdrGPU(track, numberRangeLooks1, numberAzimuthLooks1,
|
||||||
|
latitude, longitude, height, rangeOffset, azimuthOffset)
|
||||||
|
else:
|
||||||
|
geo2RdrCPU(track, numberRangeLooks1, numberAzimuthLooks1,
|
||||||
|
latitude, longitude, height, rangeOffset, azimuthOffset)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if latitudeLink == True:
|
||||||
|
os.remove(os.path.basename(latitude))
|
||||||
|
os.remove(os.path.basename(latitude)+'.vrt')
|
||||||
|
os.remove(os.path.basename(latitude)+'.xml')
|
||||||
|
|
||||||
|
if longitudeLink == True:
|
||||||
|
os.remove(os.path.basename(longitude))
|
||||||
|
os.remove(os.path.basename(longitude)+'.vrt')
|
||||||
|
os.remove(os.path.basename(longitude)+'.xml')
|
||||||
|
|
||||||
|
if heightLink == True:
|
||||||
|
os.remove(os.path.basename(height))
|
||||||
|
os.remove(os.path.basename(height)+'.vrt')
|
||||||
|
os.remove(os.path.basename(height)+'.xml')
|
||||||
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.runGeocode import geocode
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo
|
||||||
|
|
||||||
|
from StackPulic import loadProduct
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='geocode')
|
||||||
|
parser.add_argument('-ref_date_stack_track', dest='ref_date_stack_track', type=str, required=True,
|
||||||
|
help = 'track parameter of reference date of stack. format: YYMMDD.track.xml')
|
||||||
|
parser.add_argument('-dem', dest='dem', type=str, required=True,
|
||||||
|
help = 'dem file used for geocoding')
|
||||||
|
parser.add_argument('-input', dest='input', type=str, required=True,
|
||||||
|
help='input file to be geocoded')
|
||||||
|
parser.add_argument('-bbox', dest='bbox', type=str, default=None,
|
||||||
|
help = 'user input bounding box, format: s/n/w/e. default: bbox of ref_date_stack_track')
|
||||||
|
parser.add_argument('-interp_method', dest='interp_method', type=str, default='nearest',
|
||||||
|
help = 'interpolation method: sinc, bilinear, bicubic, nearest. default: nearest')
|
||||||
|
parser.add_argument('-nrlks', dest='nrlks', type=int, default=1,
|
||||||
|
help = 'total number of range looks = number of range looks 1 * number of range looks 2. default: 1')
|
||||||
|
parser.add_argument('-nalks', dest='nalks', type=int, default=1,
|
||||||
|
help = 'total number of azimuth looks = number of azimuth looks 1 * number of azimuth looks 2. default: 1')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
ref_date_stack_track = inps.ref_date_stack_track
|
||||||
|
demGeo = inps.dem
|
||||||
|
inputFile = inps.input
|
||||||
|
bbox = inps.bbox
|
||||||
|
geocodeInterpMethod = inps.interp_method
|
||||||
|
numberRangeLooks = inps.nrlks
|
||||||
|
numberAzimuthLooks = inps.nalks
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
demFile = os.path.abspath(demGeo)
|
||||||
|
trackReferenceStack = loadProduct(ref_date_stack_track)
|
||||||
|
|
||||||
|
#compute bounding box for geocoding
|
||||||
|
if bbox is not None:
|
||||||
|
bbox = [float(x) for x in bbox.split('/')]
|
||||||
|
if len(bbox)!=4:
|
||||||
|
raise Exception('user input bbox must have four elements')
|
||||||
|
else:
|
||||||
|
img = isceobj.createImage()
|
||||||
|
img.load(inputFile+'.xml')
|
||||||
|
bbox = getBboxGeo(trackReferenceStack, useTrackOnly=True, numberOfSamples=img.width, numberOfLines=img.length, numberRangeLooks=numberRangeLooks, numberAzimuthLooks=numberAzimuthLooks)
|
||||||
|
print('=====================================================================================================')
|
||||||
|
print('geocode bounding box: {}'.format(bbox))
|
||||||
|
print('=====================================================================================================')
|
||||||
|
|
||||||
|
interpMethod = geocodeInterpMethod
|
||||||
|
geocode(trackReferenceStack, demFile, inputFile, bbox, numberRangeLooks, numberAzimuthLooks, interpMethod, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='check ionospheric correction results')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where each pair (YYMMDD-YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-odir', dest='odir', type=str, required=True,
|
||||||
|
help = 'output directory for estimated ionospheric phase of each date')
|
||||||
|
parser.add_argument('-pairs', dest='pairs', type=str, nargs='+', default=None,
|
||||||
|
help = 'a number of pairs seperated by blanks. format: YYMMDD-YYMMDD YYMMDD-YYMMDD YYMMDD-YYMMDD... This argument has highest priority. When provided, only process these pairs')
|
||||||
|
# parser.add_argument('-nrlks', dest='nrlks', type=int, default=1,
|
||||||
|
# help = 'number of range looks 1 * number of range looks ion. default: 1')
|
||||||
|
# parser.add_argument('-nalks', dest='nalks', type=int, default=1,
|
||||||
|
# help = 'number of azimuth looks 1 * number of azimuth looks ion. default: 1')
|
||||||
|
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
odir = inps.odir
|
||||||
|
pairsUser = inps.pairs
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
if shutil.which('montage') is None:
|
||||||
|
raise Exception('this command requires montage in ImageMagick\n')
|
||||||
|
|
||||||
|
|
||||||
|
#get date folders
|
||||||
|
dateDirs = sorted(glob.glob(os.path.join(os.path.abspath(idir), '*')))
|
||||||
|
dateDirs = [os.path.basename(x) for x in dateDirs if os.path.isdir(x)]
|
||||||
|
if pairsUser is not None:
|
||||||
|
pairs = pairsUser
|
||||||
|
else:
|
||||||
|
pairs = dateDirs
|
||||||
|
|
||||||
|
os.makedirs(odir, exist_ok=True)
|
||||||
|
|
||||||
|
img = isceobj.createImage()
|
||||||
|
img.load(glob.glob(os.path.join(idir, pairs[0], 'ion', 'ion_cal', 'filt_ion_*rlks_*alks.ion'))[0] + '.xml')
|
||||||
|
width = img.width
|
||||||
|
length = img.length
|
||||||
|
|
||||||
|
widthMax = 600
|
||||||
|
if width >= widthMax:
|
||||||
|
ratio = widthMax / width
|
||||||
|
resize = ' -resize {}%'.format(ratio*100.0)
|
||||||
|
else:
|
||||||
|
ratio = 1.0
|
||||||
|
resize = ''
|
||||||
|
|
||||||
|
for ipair in pairs:
|
||||||
|
diffOriginal = glob.glob(os.path.join(idir, ipair, 'ion', 'ion_cal', 'diff_{}_*rlks_*alks_ori.int'.format(ipair)))[0]
|
||||||
|
ion = glob.glob(os.path.join(idir, ipair, 'ion', 'ion_cal', 'filt_ion_*rlks_*alks.ion'))[0]
|
||||||
|
diff = glob.glob(os.path.join(idir, ipair, 'ion', 'ion_cal', 'diff_{}_*rlks_*alks.int'.format(ipair)))[0]
|
||||||
|
|
||||||
|
runCmd('mdx {} -s {} -c8pha -cmap cmy -wrap 6.283185307179586 -addr -3.141592653589793 -P -workdir {}'.format(diffOriginal, width, odir))
|
||||||
|
runCmd('mv {} {}'.format(os.path.join(odir, 'out.ppm'), os.path.join(odir, 'out1.ppm')))
|
||||||
|
runCmd('mdx {} -s {} -cmap cmy -wrap 6.283185307179586 -addr -3.141592653589793 -P -workdir {}'.format(ion, width, odir))
|
||||||
|
runCmd('mv {} {}'.format(os.path.join(odir, 'out.ppm'), os.path.join(odir, 'out2.ppm')))
|
||||||
|
runCmd('mdx {} -s {} -c8pha -cmap cmy -wrap 6.283185307179586 -addr -3.141592653589793 -P -workdir {}'.format(diff, width, odir))
|
||||||
|
runCmd('mv {} {}'.format(os.path.join(odir, 'out.ppm'), os.path.join(odir, 'out3.ppm')))
|
||||||
|
runCmd("montage -pointsize {} -label 'original' {} -label 'ionosphere' {} -label 'corrected' {} -geometry +{} -compress LZW{} {}.tif".format(
|
||||||
|
int((ratio*width)/111*18+0.5),
|
||||||
|
os.path.join(odir, 'out1.ppm'),
|
||||||
|
os.path.join(odir, 'out2.ppm'),
|
||||||
|
os.path.join(odir, 'out3.ppm'),
|
||||||
|
int((ratio*width)/111*5+0.5),
|
||||||
|
resize,
|
||||||
|
os.path.join(odir, ipair)))
|
||||||
|
runCmd('rm {} {} {}'.format(
|
||||||
|
os.path.join(odir, 'out1.ppm'),
|
||||||
|
os.path.join(odir, 'out2.ppm'),
|
||||||
|
os.path.join(odir, 'out3.ppm')))
|
||||||
|
|
||||||
|
|
||||||
|
#create colorbar
|
||||||
|
width_colorbar = 100
|
||||||
|
length_colorbar = 20
|
||||||
|
colorbar = np.ones((length_colorbar, width_colorbar), dtype=np.float32) * \
|
||||||
|
(np.linspace(-np.pi, np.pi, num=width_colorbar,endpoint=True,dtype=np.float32))[None,:]
|
||||||
|
colorbar.astype(np.float32).tofile(os.path.join(odir, 'colorbar'))
|
||||||
|
runCmd('mdx {} -s {} -cmap cmy -wrap 6.283185307179586 -addr -3.141592653589793 -P -workdir {}'.format(os.path.join(odir, 'colorbar'), width_colorbar, odir))
|
||||||
|
runCmd('convert {} -compress LZW -resize 100% {}'.format(os.path.join(odir, 'out.ppm'), os.path.join(odir, 'colorbar_-pi_pi.tiff')))
|
||||||
|
runCmd('rm {} {}'.format(
|
||||||
|
os.path.join(odir, 'colorbar'),
|
||||||
|
os.path.join(odir, 'out.ppm')))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import renameFile
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='ionospheric correction')
|
||||||
|
parser.add_argument('-ion_dir', dest='ion_dir', type=str, required=True,
|
||||||
|
help = 'directory of ionospheric phase for each date')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
parser.add_argument('-nrlks2', dest='nrlks2', type=int, default=1,
|
||||||
|
help = 'number of range looks 2. default: 1')
|
||||||
|
parser.add_argument('-nalks2', dest='nalks2', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 2. default: 1')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
ion_dir = inps.ion_dir
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
numberRangeLooks2 = inps.nrlks2
|
||||||
|
numberAzimuthLooks2 = inps.nalks2
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
ms = pair
|
||||||
|
ml2 = '_{}rlks_{}alks'.format(numberRangeLooks1*numberRangeLooks2, numberAzimuthLooks1*numberAzimuthLooks2)
|
||||||
|
|
||||||
|
multilookDifferentialInterferogram = 'diff_' + ms + ml2 + '.int'
|
||||||
|
multilookDifferentialInterferogramOriginal = 'diff_' + ms + ml2 + '_ori.int'
|
||||||
|
|
||||||
|
ionosphereReference = os.path.join('../', ion_dir, 'filt_ion_'+dateReference+ml2+'.ion')
|
||||||
|
ionosphereSecondary = os.path.join('../', ion_dir, 'filt_ion_'+dateSecondary+ml2+'.ion')
|
||||||
|
|
||||||
|
|
||||||
|
insarDir = 'insar'
|
||||||
|
#os.makedirs(insarDir, exist_ok=True)
|
||||||
|
os.chdir(insarDir)
|
||||||
|
|
||||||
|
if not os.path.isfile(ionosphereReference):
|
||||||
|
raise Exception('ionospheric phase file: {} of reference date does not exist in {}.\n'.format(os.path.basename(ionosphereReference), ion_dir))
|
||||||
|
if not os.path.isfile(ionosphereSecondary):
|
||||||
|
raise Exception('ionospheric phase file: {} of secondary date does not exist in {}.\n'.format(os.path.basename(ionosphereSecondary), ion_dir))
|
||||||
|
|
||||||
|
#correct interferogram
|
||||||
|
if os.path.isfile(multilookDifferentialInterferogramOriginal):
|
||||||
|
print('original interferogram: {} is already here, do not rename: {}'.format(multilookDifferentialInterferogramOriginal, multilookDifferentialInterferogram))
|
||||||
|
else:
|
||||||
|
print('renaming {} to {}'.format(multilookDifferentialInterferogram, multilookDifferentialInterferogramOriginal))
|
||||||
|
renameFile(multilookDifferentialInterferogram, multilookDifferentialInterferogramOriginal)
|
||||||
|
|
||||||
|
cmd = "imageMath.py -e='a*exp(-1.0*J*(b-c))' --a={} --b={} --c={} -s BIP -t cfloat -o {}".format(
|
||||||
|
multilookDifferentialInterferogramOriginal,
|
||||||
|
ionosphereReference,
|
||||||
|
ionosphereSecondary,
|
||||||
|
multilookDifferentialInterferogram)
|
||||||
|
runCmd(cmd)
|
||||||
|
|
||||||
|
os.chdir('../')
|
||||||
|
|
@ -0,0 +1,499 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.runIonFilt import computeIonosphere
|
||||||
|
from isceobj.Alos2Proc.runIonFilt import gaussian
|
||||||
|
#from isceobj.Alos2Proc.runIonFilt import least_sqares
|
||||||
|
from isceobj.Alos2Proc.runIonFilt import polyfit_2d
|
||||||
|
from isceobj.Alos2Proc.runIonFilt import adaptive_gaussian
|
||||||
|
from isceobj.Alos2Proc.runIonFilt import reformatMaskedAreas
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import createObject
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
from StackPulic import subbandParameters
|
||||||
|
|
||||||
|
from compute_burst_sync import computeBurstSynchronization
|
||||||
|
|
||||||
|
|
||||||
|
def ionFilt(self, referenceTrack, catalog=None):
|
||||||
|
|
||||||
|
from isceobj.Alos2Proc.runIonSubband import defineIonDir
|
||||||
|
ionDir = defineIonDir()
|
||||||
|
subbandPrefix = ['lower', 'upper']
|
||||||
|
|
||||||
|
ionCalDir = os.path.join(ionDir['ion'], ionDir['ionCal'])
|
||||||
|
os.makedirs(ionCalDir, exist_ok=True)
|
||||||
|
os.chdir(ionCalDir)
|
||||||
|
|
||||||
|
log = ''
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# STEP 1. compute ionospheric phase
|
||||||
|
############################################################
|
||||||
|
from isceobj.Constants import SPEED_OF_LIGHT
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
|
||||||
|
###################################
|
||||||
|
#SET PARAMETERS HERE
|
||||||
|
#THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self)
|
||||||
|
corThresholdAdj = 0.97
|
||||||
|
corOrderAdj = 20
|
||||||
|
###################################
|
||||||
|
|
||||||
|
print('\ncomputing ionosphere')
|
||||||
|
#get files
|
||||||
|
ml2 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon,
|
||||||
|
self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon)
|
||||||
|
|
||||||
|
lowerUnwfile = subbandPrefix[0]+ml2+'.unw'
|
||||||
|
upperUnwfile = subbandPrefix[1]+ml2+'.unw'
|
||||||
|
corfile = 'diff'+ml2+'.cor'
|
||||||
|
|
||||||
|
#use image size from lower unwrapped interferogram
|
||||||
|
img = isceobj.createImage()
|
||||||
|
img.load(lowerUnwfile + '.xml')
|
||||||
|
width = img.width
|
||||||
|
length = img.length
|
||||||
|
|
||||||
|
lowerUnw = (np.fromfile(lowerUnwfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :]
|
||||||
|
upperUnw = (np.fromfile(upperUnwfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :]
|
||||||
|
cor = (np.fromfile(corfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :]
|
||||||
|
#amp = (np.fromfile(corfile, dtype=np.float32).reshape(length*2, width))[0:length*2:2, :]
|
||||||
|
|
||||||
|
#masked out user-specified areas
|
||||||
|
if self.maskedAreasIon != None:
|
||||||
|
maskedAreas = reformatMaskedAreas(self.maskedAreasIon, length, width)
|
||||||
|
for area in maskedAreas:
|
||||||
|
lowerUnw[area[0]:area[1], area[2]:area[3]] = 0
|
||||||
|
upperUnw[area[0]:area[1], area[2]:area[3]] = 0
|
||||||
|
cor[area[0]:area[1], area[2]:area[3]] = 0
|
||||||
|
|
||||||
|
#remove possible wired values in coherence
|
||||||
|
cor[np.nonzero(cor<0)] = 0.0
|
||||||
|
cor[np.nonzero(cor>1)] = 0.0
|
||||||
|
|
||||||
|
#remove water body
|
||||||
|
wbd = np.fromfile('wbd'+ml2+'.wbd', dtype=np.int8).reshape(length, width)
|
||||||
|
cor[np.nonzero(wbd==-1)] = 0.0
|
||||||
|
|
||||||
|
#remove small values
|
||||||
|
cor[np.nonzero(cor<corThresholdAdj)] = 0.0
|
||||||
|
|
||||||
|
#compute ionosphere
|
||||||
|
fl = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[0]
|
||||||
|
fu = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[1]
|
||||||
|
adjFlag = 1
|
||||||
|
ionos = computeIonosphere(lowerUnw, upperUnw, cor**corOrderAdj, fl, fu, adjFlag, 0)
|
||||||
|
|
||||||
|
#dump ionosphere
|
||||||
|
ionfile = 'ion'+ml2+'.ion'
|
||||||
|
# ion = np.zeros((length*2, width), dtype=np.float32)
|
||||||
|
# ion[0:length*2:2, :] = amp
|
||||||
|
# ion[1:length*2:2, :] = ionos
|
||||||
|
# ion.astype(np.float32).tofile(ionfile)
|
||||||
|
# img.filename = ionfile
|
||||||
|
# img.extraFilename = ionfile + '.vrt'
|
||||||
|
# img.renderHdr()
|
||||||
|
|
||||||
|
ionos.astype(np.float32).tofile(ionfile)
|
||||||
|
create_xml(ionfile, width, length, 'float')
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# STEP 2. filter ionospheric phase
|
||||||
|
############################################################
|
||||||
|
import scipy.signal as ss
|
||||||
|
|
||||||
|
#################################################
|
||||||
|
#SET PARAMETERS HERE
|
||||||
|
#fit and filter ionosphere
|
||||||
|
fit = self.fitIon
|
||||||
|
filt = self.filtIon
|
||||||
|
fitAdaptive = self.fitAdaptiveIon
|
||||||
|
filtSecondary = self.filtSecondaryIon
|
||||||
|
if (fit == False) and (filt == False):
|
||||||
|
raise Exception('either fit ionosphere or filt ionosphere should be True when doing ionospheric correction\n')
|
||||||
|
|
||||||
|
#filtering window size
|
||||||
|
size_max = self.filteringWinsizeMaxIon
|
||||||
|
size_min = self.filteringWinsizeMinIon
|
||||||
|
size_secondary = self.filteringWinsizeSecondaryIon
|
||||||
|
if size_min > size_max:
|
||||||
|
print('\n\nWARNING: minimum window size for filtering ionosphere phase {} > maximum window size {}'.format(size_min, size_max))
|
||||||
|
print(' re-setting maximum window size to {}\n\n'.format(size_min))
|
||||||
|
size_max = size_min
|
||||||
|
if size_secondary % 2 != 1:
|
||||||
|
size_secondary += 1
|
||||||
|
print('window size of secondary filtering of ionosphere phase should be odd, window size changed to {}'.format(size_secondary))
|
||||||
|
|
||||||
|
#coherence threshold for fitting a polynomial
|
||||||
|
corThresholdFit = 0.25
|
||||||
|
|
||||||
|
#ionospheric phase standard deviation after filtering
|
||||||
|
std_out0 = self.filterStdIon
|
||||||
|
#std_out0 = 0.1
|
||||||
|
#################################################
|
||||||
|
|
||||||
|
print('\nfiltering ionosphere')
|
||||||
|
|
||||||
|
#input files
|
||||||
|
ionfile = 'ion'+ml2+'.ion'
|
||||||
|
#corfile = 'diff'+ml2+'.cor'
|
||||||
|
corLowerfile = subbandPrefix[0]+ml2+'.cor'
|
||||||
|
corUpperfile = subbandPrefix[1]+ml2+'.cor'
|
||||||
|
#output files
|
||||||
|
ionfiltfile = 'filt_ion'+ml2+'.ion'
|
||||||
|
stdfiltfile = 'filt_ion'+ml2+'.std'
|
||||||
|
windowsizefiltfile = 'filt_ion'+ml2+'.win'
|
||||||
|
|
||||||
|
#read data
|
||||||
|
img = isceobj.createImage()
|
||||||
|
img.load(ionfile + '.xml')
|
||||||
|
width = img.width
|
||||||
|
length = img.length
|
||||||
|
|
||||||
|
ion = np.fromfile(ionfile, dtype=np.float32).reshape(length, width)
|
||||||
|
corLower = (np.fromfile(corLowerfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :]
|
||||||
|
corUpper = (np.fromfile(corUpperfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :]
|
||||||
|
cor = (corLower + corUpper) / 2.0
|
||||||
|
index = np.nonzero(np.logical_or(corLower==0, corUpper==0))
|
||||||
|
cor[index] = 0
|
||||||
|
del corLower, corUpper
|
||||||
|
|
||||||
|
#masked out user-specified areas
|
||||||
|
if self.maskedAreasIon != None:
|
||||||
|
maskedAreas = reformatMaskedAreas(self.maskedAreasIon, length, width)
|
||||||
|
for area in maskedAreas:
|
||||||
|
ion[area[0]:area[1], area[2]:area[3]] = 0
|
||||||
|
cor[area[0]:area[1], area[2]:area[3]] = 0
|
||||||
|
|
||||||
|
#remove possible wired values in coherence
|
||||||
|
cor[np.nonzero(cor<0)] = 0.0
|
||||||
|
cor[np.nonzero(cor>1)] = 0.0
|
||||||
|
|
||||||
|
#remove water body. Not helpful, just leave it here
|
||||||
|
wbd = np.fromfile('wbd'+ml2+'.wbd', dtype=np.int8).reshape(length, width)
|
||||||
|
cor[np.nonzero(wbd==-1)] = 0.0
|
||||||
|
|
||||||
|
# #applying water body mask here
|
||||||
|
# waterBodyFile = 'wbd'+ml2+'.wbd'
|
||||||
|
# if os.path.isfile(waterBodyFile):
|
||||||
|
# print('applying water body mask to coherence used to compute ionospheric phase')
|
||||||
|
# wbd = np.fromfile(waterBodyFile, dtype=np.int8).reshape(length, width)
|
||||||
|
# cor[np.nonzero(wbd!=0)] = 0.00001
|
||||||
|
|
||||||
|
#minimize the effect of low coherence pixels
|
||||||
|
#cor[np.nonzero( (cor<0.85)*(cor!=0) )] = 0.00001
|
||||||
|
#filt = adaptive_gaussian(ion, cor, size_max, size_min)
|
||||||
|
#cor**14 should be a good weight to use. 22-APR-2018
|
||||||
|
#filt = adaptive_gaussian_v0(ion, cor**corOrderFilt, size_max, size_min)
|
||||||
|
|
||||||
|
|
||||||
|
#1. compute number of looks
|
||||||
|
azimuthBandwidth = 0
|
||||||
|
for i, frameNumber in enumerate(self._insar.referenceFrames):
|
||||||
|
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
||||||
|
#azimuthBandwidth += 2270.575 * 0.85
|
||||||
|
azimuthBandwidth += referenceTrack.frames[i].swaths[j].azimuthBandwidth
|
||||||
|
azimuthBandwidth = azimuthBandwidth / (len(self._insar.referenceFrames)*(self._insar.endingSwath-self._insar.startingSwath+1))
|
||||||
|
|
||||||
|
#azimuth number of looks should also apply to burst mode
|
||||||
|
#assume range bandwidth of subband image is 1/3 of orginal range bandwidth, as in runIonSubband.py!!!
|
||||||
|
numberOfLooks = referenceTrack.azimuthLineInterval * self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon / (1.0/azimuthBandwidth) *\
|
||||||
|
referenceTrack.frames[0].swaths[0].rangeBandwidth / 3.0 / referenceTrack.rangeSamplingRate * self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon
|
||||||
|
|
||||||
|
#consider also burst characteristics. In ScanSAR-stripmap interferometry, azimuthBandwidth is from referenceTrack (ScanSAR)
|
||||||
|
if self._insar.modeCombination in [21, 31]:
|
||||||
|
numberOfLooks /= 5.0
|
||||||
|
if self._insar.modeCombination in [22, 32]:
|
||||||
|
numberOfLooks /= 7.0
|
||||||
|
if self._insar.modeCombination in [21]:
|
||||||
|
numberOfLooks *= (self._insar.burstSynchronization/100.0)
|
||||||
|
|
||||||
|
#numberOfLooks checked
|
||||||
|
print('number of looks to be used for computing subband interferogram standard deviation: {}'.format(numberOfLooks))
|
||||||
|
if catalog is not None:
|
||||||
|
catalog.addItem('number of looks of subband interferograms', numberOfLooks, 'runIonFilt')
|
||||||
|
log += 'number of looks of subband interferograms: {}\n'.format(numberOfLooks)
|
||||||
|
|
||||||
|
|
||||||
|
#2. compute standard deviation of the raw ionospheric phase
|
||||||
|
#f0 same as in runIonSubband.py!!!
|
||||||
|
def ion_std(fl, fu, numberOfLooks, cor):
|
||||||
|
'''
|
||||||
|
compute standard deviation of ionospheric phase
|
||||||
|
fl: lower band center frequency
|
||||||
|
fu: upper band center frequency
|
||||||
|
cor: coherence, must be numpy array
|
||||||
|
'''
|
||||||
|
f0 = (fl + fu) / 2.0
|
||||||
|
interferogramVar = (1.0 - cor**2) / (2.0 * numberOfLooks * cor**2 + (cor==0))
|
||||||
|
std = fl*fu/f0/(fu**2-fl**2)*np.sqrt(fu**2*interferogramVar+fl**2*interferogramVar)
|
||||||
|
std[np.nonzero(cor==0)] = 0
|
||||||
|
return std
|
||||||
|
std = ion_std(fl, fu, numberOfLooks, cor)
|
||||||
|
|
||||||
|
|
||||||
|
#3. compute minimum filter window size for given coherence and standard deviation of filtered ionospheric phase
|
||||||
|
cor2 = np.linspace(0.1, 0.9, num=9, endpoint=True)
|
||||||
|
std2 = ion_std(fl, fu, numberOfLooks, cor2)
|
||||||
|
std_out2 = np.zeros(cor2.size)
|
||||||
|
win2 = np.zeros(cor2.size, dtype=np.int32)
|
||||||
|
for i in range(cor2.size):
|
||||||
|
for size in range(9, 10001, 2):
|
||||||
|
#this window must be the same as those used in adaptive_gaussian!!!
|
||||||
|
gw = gaussian(size, size/2.0, scale=1.0)
|
||||||
|
scale = 1.0 / np.sum(gw / std2[i]**2)
|
||||||
|
std_out2[i] = scale * np.sqrt(np.sum(gw**2 / std2[i]**2))
|
||||||
|
win2[i] = size
|
||||||
|
if std_out2[i] <= std_out0:
|
||||||
|
break
|
||||||
|
print('if ionospheric phase standard deviation <= {} rad, minimum filtering window size required:'.format(std_out0))
|
||||||
|
print('coherence window size')
|
||||||
|
print('************************')
|
||||||
|
for x, y in zip(cor2, win2):
|
||||||
|
print(' %5.2f %5d'%(x, y))
|
||||||
|
print()
|
||||||
|
if catalog is not None:
|
||||||
|
catalog.addItem('coherence value', cor2, 'runIonFilt')
|
||||||
|
catalog.addItem('minimum filter window size', win2, 'runIonFilt')
|
||||||
|
log += 'coherence value: {}\n'.format(cor2)
|
||||||
|
log += 'minimum filter window size: {}\n'.format(win2)
|
||||||
|
|
||||||
|
|
||||||
|
#4. filter interferogram
|
||||||
|
#fit ionosphere
|
||||||
|
if fit:
|
||||||
|
#prepare weight
|
||||||
|
wgt = std**2
|
||||||
|
wgt[np.nonzero(cor<corThresholdFit)] = 0
|
||||||
|
index = np.nonzero(wgt!=0)
|
||||||
|
wgt[index] = 1.0/(wgt[index])
|
||||||
|
#fit
|
||||||
|
ion_fit, coeff = polyfit_2d(ion, wgt, 2)
|
||||||
|
ion -= ion_fit * (ion!=0)
|
||||||
|
#filter the rest of the ionosphere
|
||||||
|
if filt:
|
||||||
|
(ion_filt, std_out, window_size_out) = adaptive_gaussian(ion, std, size_min, size_max, std_out0, fit=fitAdaptive)
|
||||||
|
if filtSecondary:
|
||||||
|
g2d = gaussian(size_secondary, size_secondary/2.0, scale=1.0)
|
||||||
|
scale = ss.fftconvolve((ion_filt!=0), g2d, mode='same')
|
||||||
|
ion_filt = (ion_filt!=0) * ss.fftconvolve(ion_filt, g2d, mode='same') / (scale + (scale==0))
|
||||||
|
|
||||||
|
if catalog is not None:
|
||||||
|
catalog.addItem('standard deviation of filtered ionospheric phase', std_out0, 'runIonFilt')
|
||||||
|
log += 'standard deviation of filtered ionospheric phase: {}\n'.format(std_out0)
|
||||||
|
|
||||||
|
|
||||||
|
#get final results
|
||||||
|
if (fit == True) and (filt == True):
|
||||||
|
ion_final = ion_filt + ion_fit * (ion_filt!=0)
|
||||||
|
elif (fit == True) and (filt == False):
|
||||||
|
ion_final = ion_fit
|
||||||
|
elif (fit == False) and (filt == True):
|
||||||
|
ion_final = ion_filt
|
||||||
|
else:
|
||||||
|
ion_final = ion
|
||||||
|
|
||||||
|
#output results
|
||||||
|
ion_final.astype(np.float32).tofile(ionfiltfile)
|
||||||
|
create_xml(ionfiltfile, width, length, 'float')
|
||||||
|
if filt == True:
|
||||||
|
std_out.astype(np.float32).tofile(stdfiltfile)
|
||||||
|
create_xml(stdfiltfile, width, length, 'float')
|
||||||
|
window_size_out.astype(np.float32).tofile(windowsizefiltfile)
|
||||||
|
create_xml(windowsizefiltfile, width, length, 'float')
|
||||||
|
|
||||||
|
|
||||||
|
os.chdir('../../')
|
||||||
|
|
||||||
|
return log
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='unwrap subband interferograms for ionospheric correction')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where resampled data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-idir2', dest='idir2', type=str, required=True,
|
||||||
|
help = 'input directory where original data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-ref_date_stack', dest='ref_date_stack', type=str, required=True,
|
||||||
|
help = 'reference date of stack. format: YYMMDD')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
parser.add_argument('-nrlks2', dest='nrlks2', type=int, default=1,
|
||||||
|
help = 'number of range looks 2. default: 1')
|
||||||
|
parser.add_argument('-nalks2', dest='nalks2', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 2. default: 1')
|
||||||
|
parser.add_argument('-nrlks_ion', dest='nrlks_ion', type=int, default=1,
|
||||||
|
help = 'number of range looks ion. default: 1')
|
||||||
|
parser.add_argument('-nalks_ion', dest='nalks_ion', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks ion. default: 1')
|
||||||
|
parser.add_argument('-fit', dest='fit', action='store_true', default=False,
|
||||||
|
help='apply polynomial fit before filtering ionosphere phase')
|
||||||
|
parser.add_argument('-filt', dest='filt', action='store_true', default=False,
|
||||||
|
help='filtering ionosphere phase')
|
||||||
|
parser.add_argument('-fit_adaptive', dest='fit_adaptive', action='store_true', default=False,
|
||||||
|
help='apply polynomial fit in adaptive filtering window')
|
||||||
|
parser.add_argument('-filt_secondary', dest='filt_secondary', action='store_true', default=False,
|
||||||
|
help='secondary filtering of ionosphere phase')
|
||||||
|
parser.add_argument('-win_min', dest='win_min', type=int, default=11,
|
||||||
|
help = 'minimum filtering window size. default: 11')
|
||||||
|
parser.add_argument('-win_max', dest='win_max', type=int, default=301,
|
||||||
|
help = 'maximum filtering window size. default: 301')
|
||||||
|
parser.add_argument('-win_secondary', dest='win_secondary', type=int, default=5,
|
||||||
|
help = 'secondary filtering window size. default: 5')
|
||||||
|
parser.add_argument('-filter_std_ion', dest='filter_std_ion', type=float, default=None,
|
||||||
|
help = 'standard deviation after ionosphere filtering. default: None, automatically set by the program')
|
||||||
|
parser.add_argument('-masked_areas', dest='masked_areas', type=float, nargs='+', action='append', default=None,
|
||||||
|
help='This is a 2-d list. Each element in the 2-D list is a four-element list: [firstLine, lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the four elements is specified with -1, the program will use firstLine/lastLine/firstColumn/lastColumn instead. e.g. two areas masked out: -masked_areas 10 20 10 20 -masked_areas 110 120 110 120')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
idir2 = inps.idir2
|
||||||
|
dateReferenceStack = inps.ref_date_stack
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
numberRangeLooks2 = inps.nrlks2
|
||||||
|
numberAzimuthLooks2 = inps.nalks2
|
||||||
|
numberRangeLooksIon = inps.nrlks_ion
|
||||||
|
numberAzimuthLooksIon = inps.nalks_ion
|
||||||
|
fitIon = inps.fit
|
||||||
|
filtIon = inps.filt
|
||||||
|
fitAdaptiveIon = inps.fit_adaptive
|
||||||
|
filtSecondaryIon = inps.filt_secondary
|
||||||
|
filteringWinsizeMinIon = inps.win_min
|
||||||
|
filteringWinsizeMaxIon = inps.win_max
|
||||||
|
filteringWinsizeSecondaryIon = inps.win_secondary
|
||||||
|
filterStdIon = inps.filter_std_ion
|
||||||
|
maskedAreasIon = inps.masked_areas
|
||||||
|
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
ms = pair
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
ml2 = '_{}rlks_{}alks'.format(numberRangeLooks1*numberRangeLooks2, numberAzimuthLooks1*numberAzimuthLooks2)
|
||||||
|
dateDirs, dates, frames, swaths, dateIndexReference = stackDateStatistics(idir, dateReferenceStack)
|
||||||
|
dateDirs2, dates2, frames2, swaths2, dateIndexReference2 = stackDateStatistics(idir2, dateReferenceStack)
|
||||||
|
spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = acquisitionModesAlos2()
|
||||||
|
trackReferenceStack = loadTrack(os.path.join(idir, dateReferenceStack), dateReferenceStack)
|
||||||
|
trackReference = loadTrack(os.path.join(idir2, dateReference), dateReference)
|
||||||
|
trackSecondary = loadTrack(os.path.join(idir2, dateSecondary), dateSecondary)
|
||||||
|
subbandRadarWavelength, subbandBandWidth, subbandFrequencyCenter, subbandPrefix = subbandParameters(trackReferenceStack)
|
||||||
|
|
||||||
|
self = createObject()
|
||||||
|
self._insar = createObject()
|
||||||
|
self._insar.numberRangeLooks1 = numberRangeLooks1
|
||||||
|
self._insar.numberAzimuthLooks1 = numberAzimuthLooks1
|
||||||
|
self._insar.numberRangeLooks2 = numberRangeLooks2
|
||||||
|
self._insar.numberAzimuthLooks2 = numberAzimuthLooks2
|
||||||
|
self._insar.numberRangeLooksIon = numberRangeLooksIon
|
||||||
|
self._insar.numberAzimuthLooksIon = numberAzimuthLooksIon
|
||||||
|
|
||||||
|
self.fitIon = fitIon
|
||||||
|
self.filtIon = filtIon
|
||||||
|
self.fitAdaptiveIon = fitAdaptiveIon
|
||||||
|
self.filtSecondaryIon = filtSecondaryIon
|
||||||
|
self.filteringWinsizeMaxIon = filteringWinsizeMaxIon
|
||||||
|
self.filteringWinsizeMinIon = filteringWinsizeMinIon
|
||||||
|
self.filteringWinsizeSecondaryIon = filteringWinsizeSecondaryIon
|
||||||
|
self.maskedAreasIon = maskedAreasIon
|
||||||
|
self.applyIon = False
|
||||||
|
|
||||||
|
#ionospheric phase standard deviation after filtering
|
||||||
|
if filterStdIon is not None:
|
||||||
|
self.filterStdIon = filterStdIon
|
||||||
|
else:
|
||||||
|
if trackReference.operationMode == trackSecondary.operationMode:
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import modeProcParDict
|
||||||
|
self.filterStdIon = modeProcParDict['ALOS-2'][trackReference.operationMode]['filterStdIon']
|
||||||
|
else:
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import filterStdPolyIon
|
||||||
|
self.filterStdIon = np.polyval(filterStdPolyIon, trackReference.frames[0].swaths[0].rangeBandwidth/(1e6))
|
||||||
|
|
||||||
|
self._insar.referenceFrames = frames
|
||||||
|
self._insar.startingSwath = swaths[0]
|
||||||
|
self._insar.endingSwath = swaths[-1]
|
||||||
|
self._insar.subbandRadarWavelength = subbandRadarWavelength
|
||||||
|
|
||||||
|
self._insar.multilookIon = ms + ml2 + '.ion'
|
||||||
|
self._insar.multilookDifferentialInterferogram = 'diff_' + ms + ml2 + '.int'
|
||||||
|
self._insar.multilookDifferentialInterferogramOriginal = 'diff_' + ms + ml2 + '_ori.int'
|
||||||
|
|
||||||
|
#usable combinations
|
||||||
|
referenceMode = trackReference.operationMode
|
||||||
|
secondaryMode = trackSecondary.operationMode
|
||||||
|
if (referenceMode in spotlightModes) and (secondaryMode in spotlightModes):
|
||||||
|
self._insar.modeCombination = 0
|
||||||
|
elif (referenceMode in stripmapModes) and (secondaryMode in stripmapModes):
|
||||||
|
self._insar.modeCombination = 1
|
||||||
|
elif (referenceMode in scansarNominalModes) and (secondaryMode in scansarNominalModes):
|
||||||
|
self._insar.modeCombination = 21
|
||||||
|
elif (referenceMode in scansarWideModes) and (secondaryMode in scansarWideModes):
|
||||||
|
self._insar.modeCombination = 22
|
||||||
|
elif (referenceMode in scansarNominalModes) and (secondaryMode in stripmapModes):
|
||||||
|
self._insar.modeCombination = 31
|
||||||
|
elif (referenceMode in scansarWideModes) and (secondaryMode in stripmapModes):
|
||||||
|
self._insar.modeCombination = 32
|
||||||
|
else:
|
||||||
|
print('\n\nthis mode combination is not possible')
|
||||||
|
print('note that for ScanSAR-stripmap, ScanSAR must be reference\n\n')
|
||||||
|
raise Exception('mode combination not supported')
|
||||||
|
|
||||||
|
if self._insar.modeCombination in [21]:
|
||||||
|
unsynTimeAll, synPercentageAll = computeBurstSynchronization(trackReference, trackSecondary)
|
||||||
|
self._insar.burstSynchronization = np.mean(np.array(synPercentageAll), dtype=np.float64)
|
||||||
|
else:
|
||||||
|
self._insar.burstSynchronization = 100.0
|
||||||
|
|
||||||
|
#log output info
|
||||||
|
log = '{} at {}\n'.format(os.path.basename(__file__), datetime.datetime.now())
|
||||||
|
log += '================================================================================================\n'
|
||||||
|
log += ionFilt(self, trackReferenceStack)
|
||||||
|
log += '\n'
|
||||||
|
|
||||||
|
logFile = 'process.log'
|
||||||
|
with open(logFile, 'a') as f:
|
||||||
|
f.write(log)
|
||||||
|
|
@ -0,0 +1,339 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
|
||||||
|
from StackPulic import loadProduct
|
||||||
|
from StackPulic import datesFromPairs
|
||||||
|
|
||||||
|
|
||||||
|
def least_sqares(H, S, W=None):
|
||||||
|
'''
|
||||||
|
#This can make use multiple threads (set environment variable: OMP_NUM_THREADS)
|
||||||
|
linear equations: H theta = s
|
||||||
|
W: weight matrix
|
||||||
|
'''
|
||||||
|
|
||||||
|
S.reshape(H.shape[0], 1)
|
||||||
|
if W is None:
|
||||||
|
#use np.dot instead since some old python versions don't have matmul
|
||||||
|
m1 = np.linalg.inv(np.dot(H.transpose(), H))
|
||||||
|
Z = np.dot( np.dot(m1, H.transpose()) , S)
|
||||||
|
else:
|
||||||
|
#use np.dot instead since some old python versions don't have matmul
|
||||||
|
m1 = np.linalg.inv(np.dot(np.dot(H.transpose(), W), H))
|
||||||
|
Z = np.dot(np.dot(np.dot(m1, H.transpose()), W), S)
|
||||||
|
|
||||||
|
return Z.reshape(Z.size)
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='unwrap subband interferograms for ionospheric correction')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where each pair (YYMMDD-YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-odir', dest='odir', type=str, required=True,
|
||||||
|
help = 'output directory for estimated ionospheric phase of each date')
|
||||||
|
parser.add_argument('-ref_date_stack', dest='ref_date_stack', type=str, required=True,
|
||||||
|
help = 'reference date of stack. format: YYMMDD')
|
||||||
|
parser.add_argument('-zro_date', dest='zro_date', type=str, default=None,
|
||||||
|
help = 'date in least squares estimation whose ionospheric phase is assumed to be zero. format: YYMMDD. default: first date')
|
||||||
|
parser.add_argument('-pairs', dest='pairs', type=str, nargs='+', default=None,
|
||||||
|
help = 'pairs to be used in least squares estimation. This has highest priority. a number of pairs seperated by blanks. format: YYMMDD-YYMMDD YYMMDD-YYMMDD...')
|
||||||
|
parser.add_argument('-exc_date', dest='exc_date', type=str, nargs='+', default=[],
|
||||||
|
help = 'pairs involving these dates are excluded in least squares estimation. a number of dates seperated by blanks. format: YYMMDD YYMMDD YYMMDD...')
|
||||||
|
parser.add_argument('-exc_pair', dest='exc_pair', type=str, nargs='+', default=[],
|
||||||
|
help = 'pairs excluded in least squares estimation. a number of pairs seperated by blanks. format: YYMMDD-YYMMDD YYMMDD-YYMMDD...')
|
||||||
|
parser.add_argument('-tsmax', dest='tsmax', type=float, default=None,
|
||||||
|
help = 'maximum time span in years of pairs used in least squares estimation. default: None')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
parser.add_argument('-nrlks2', dest='nrlks2', type=int, default=1,
|
||||||
|
help = 'number of range looks 2. default: 1')
|
||||||
|
parser.add_argument('-nalks2', dest='nalks2', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 2. default: 1')
|
||||||
|
parser.add_argument('-nrlks_ion', dest='nrlks_ion', type=int, default=1,
|
||||||
|
help = 'number of range looks ion. default: 1')
|
||||||
|
parser.add_argument('-nalks_ion', dest='nalks_ion', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks ion. default: 1')
|
||||||
|
parser.add_argument('-ww', dest='ww', action='store_true', default=False,
|
||||||
|
help='use reciprocal of window size as weight')
|
||||||
|
parser.add_argument('-interp', dest='interp', action='store_true', default=False,
|
||||||
|
help='interpolate ionospheric phase to nrlks2/nalks2 sample size')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
odir = inps.odir
|
||||||
|
dateReferenceStack = inps.ref_date_stack
|
||||||
|
dateZero = inps.zro_date
|
||||||
|
pairsUser = inps.pairs
|
||||||
|
dateExcluded = inps.exc_date
|
||||||
|
pairExcluded = inps.exc_pair
|
||||||
|
tsmax = inps.tsmax
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
numberRangeLooks2 = inps.nrlks2
|
||||||
|
numberAzimuthLooks2 = inps.nalks2
|
||||||
|
numberRangeLooksIon = inps.nrlks_ion
|
||||||
|
numberAzimuthLooksIon = inps.nalks_ion
|
||||||
|
ww = inps.ww
|
||||||
|
interp = inps.interp
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
#all pair folders in order
|
||||||
|
pairDirs = sorted(glob.glob(os.path.join(os.path.abspath(idir), '*-*')))
|
||||||
|
pairDirs = [x for x in pairDirs if os.path.isdir(x)]
|
||||||
|
|
||||||
|
#all pairs in order
|
||||||
|
pairsAll = [os.path.basename(x) for x in pairDirs]
|
||||||
|
|
||||||
|
#all dates in order
|
||||||
|
datesAll = datesFromPairs(pairsAll)
|
||||||
|
|
||||||
|
|
||||||
|
if pairsUser is not None:
|
||||||
|
pairs = pairsUser
|
||||||
|
for x in pairs:
|
||||||
|
if x not in pairsAll:
|
||||||
|
raise Exception('pair {} provided by user is not in processed pair list'.format(x))
|
||||||
|
else:
|
||||||
|
#exclude
|
||||||
|
#pairs = [x for x in pairsAll if (x.split('-')[0] not in dateExcluded) and (x.split('-')[1] not in dateExcluded)]
|
||||||
|
#pairs = [x for x in pairsAll if x not in pairExcluded]
|
||||||
|
pairs = []
|
||||||
|
for x in pairsAll:
|
||||||
|
dateReference = x.split('-')[0]
|
||||||
|
dateSecondary = x.split('-')[1]
|
||||||
|
timeReference = datetime.datetime.strptime(dateReference, "%y%m%d")
|
||||||
|
timeSecondary = datetime.datetime.strptime(dateSecondary, "%y%m%d")
|
||||||
|
ts = np.absolute((timeSecondary - timeReference).total_seconds()) / (365.0 * 24.0 * 3600)
|
||||||
|
if (dateReference in dateExcluded) and (dateSecondary in dateExcluded):
|
||||||
|
continue
|
||||||
|
if (x in pairExcluded):
|
||||||
|
continue
|
||||||
|
if tsmax is not None:
|
||||||
|
if ts > tsmax:
|
||||||
|
continue
|
||||||
|
pairs.append(x)
|
||||||
|
|
||||||
|
dates = datesFromPairs(pairs)
|
||||||
|
if dateZero is not None:
|
||||||
|
if dateZero not in dates:
|
||||||
|
raise Exception('zro_date provided by user not in the dates involved in least squares estimation.')
|
||||||
|
else:
|
||||||
|
dateZero = dates[0]
|
||||||
|
|
||||||
|
print('all pairs:\n{}'.format(' '.join(pairsAll)))
|
||||||
|
print('all dates:\n{}'.format(' '.join(datesAll)))
|
||||||
|
print('used pairs:\n{}'.format(' '.join(pairs)))
|
||||||
|
print('used dates:\n{}'.format(' '.join(dates)))
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################################
|
||||||
|
print('\nSTEP 1. read files')
|
||||||
|
####################################################################################
|
||||||
|
|
||||||
|
ndate = len(dates)
|
||||||
|
npair = len(pairs)
|
||||||
|
|
||||||
|
ml2 = '_{}rlks_{}alks'.format(numberRangeLooks1*numberRangeLooksIon, numberAzimuthLooks1*numberAzimuthLooksIon)
|
||||||
|
ionfiltfile = 'filt_ion'+ml2+'.ion'
|
||||||
|
stdfiltfile = 'filt_ion'+ml2+'.std'
|
||||||
|
windowsizefiltfile = 'filt_ion'+ml2+'.win'
|
||||||
|
ionfiltfile1 = os.path.join(idir, pairs[0], 'ion/ion_cal', ionfiltfile)
|
||||||
|
|
||||||
|
img = isceobj.createImage()
|
||||||
|
img.load(ionfiltfile1+'.xml')
|
||||||
|
width = img.width
|
||||||
|
length = img.length
|
||||||
|
|
||||||
|
ionPairs = np.zeros((npair, length, width), dtype=np.float32)
|
||||||
|
stdPairs = np.zeros((npair, length, width), dtype=np.float32)
|
||||||
|
winPairs = np.zeros((npair, length, width), dtype=np.float32)
|
||||||
|
for i in range(npair):
|
||||||
|
ionfiltfile1 = os.path.join(idir, pairs[i], 'ion/ion_cal', ionfiltfile)
|
||||||
|
stdfiltfile1 = os.path.join(idir, pairs[i], 'ion/ion_cal', stdfiltfile)
|
||||||
|
windowsizefiltfile1 = os.path.join(idir, pairs[i], 'ion/ion_cal', windowsizefiltfile)
|
||||||
|
|
||||||
|
ionPairs[i, :, :] = np.fromfile(ionfiltfile1, dtype=np.float32).reshape(length, width)
|
||||||
|
stdPairs[i, :, :] = np.fromfile(stdfiltfile1, dtype=np.float32).reshape(length, width)
|
||||||
|
winPairs[i, :, :] = np.fromfile(windowsizefiltfile1, dtype=np.float32).reshape(length, width)
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################################
|
||||||
|
print('\nSTEP 2. do least squares')
|
||||||
|
####################################################################################
|
||||||
|
import copy
|
||||||
|
from numpy.linalg import matrix_rank
|
||||||
|
dates2 = copy.deepcopy(dates)
|
||||||
|
dates2.remove(dateZero)
|
||||||
|
|
||||||
|
#observation matrix
|
||||||
|
H0 = np.zeros((npair, ndate-1))
|
||||||
|
for k in range(npair):
|
||||||
|
dateReference = pairs[k].split('-')[0]
|
||||||
|
dateSecondary = pairs[k].split('-')[1]
|
||||||
|
if dateReference != dateZero:
|
||||||
|
dateReference_i = dates2.index(dateReference)
|
||||||
|
H0[k, dateReference_i] = 1
|
||||||
|
if dateSecondary != dateZero:
|
||||||
|
dateSecondary_i = dates2.index(dateSecondary)
|
||||||
|
H0[k, dateSecondary_i] = -1
|
||||||
|
rank = matrix_rank(H0)
|
||||||
|
if rank < ndate-1:
|
||||||
|
raise Exception('dates to be estimated are not fully connected by the pairs used in least squares')
|
||||||
|
else:
|
||||||
|
print('number of pairs to be used in least squares: {}'.format(npair))
|
||||||
|
print('number of dates to be estimated: {}'.format(ndate-1))
|
||||||
|
print('observation matrix rank: {}'.format(rank))
|
||||||
|
|
||||||
|
ts = np.zeros((ndate-1, length, width), dtype=np.float32)
|
||||||
|
for i in range(length):
|
||||||
|
if (i+1) % 50 == 0 or (i+1) == length:
|
||||||
|
print('processing line: %6d of %6d' % (i+1, length), end='\r')
|
||||||
|
if (i+1) == length:
|
||||||
|
print()
|
||||||
|
for j in range(width):
|
||||||
|
|
||||||
|
#observed signal
|
||||||
|
S0 = ionPairs[:, i, j]
|
||||||
|
|
||||||
|
if ww == False:
|
||||||
|
#observed signal
|
||||||
|
S = S0
|
||||||
|
H = H0
|
||||||
|
else:
|
||||||
|
#add weight
|
||||||
|
#https://stackoverflow.com/questions/19624997/understanding-scipys-least-square-function-with-irls
|
||||||
|
#https://stackoverflow.com/questions/27128688/how-to-use-least-squares-with-weight-matrix-in-python
|
||||||
|
wgt = winPairs[:, i, j]
|
||||||
|
W = np.sqrt(1.0/wgt)
|
||||||
|
H = H0 * W[:, None]
|
||||||
|
S = S0 * W
|
||||||
|
|
||||||
|
#do least-squares estimation
|
||||||
|
#[theta, residuals, rank, singular] = np.linalg.lstsq(H, S)
|
||||||
|
#make W full matrix if use W here (which is a slower method)
|
||||||
|
#'using W before this' is faster
|
||||||
|
theta = least_sqares(H, S, W=None)
|
||||||
|
ts[:, i, j] = theta
|
||||||
|
|
||||||
|
# #dump raw estimate
|
||||||
|
# cdir = os.getcwd()
|
||||||
|
# os.makedirs(odir, exist_ok=True)
|
||||||
|
# os.chdir(odir)
|
||||||
|
|
||||||
|
# for i in range(ndate-1):
|
||||||
|
# file_name = 'filt_ion_'+dates2[i]+ml2+'.ion'
|
||||||
|
# ts[i, :, :].astype(np.float32).tofile(file_name)
|
||||||
|
# create_xml(file_name, width, length, 'float')
|
||||||
|
# file_name = 'filt_ion_'+dateZero+ml2+'.ion'
|
||||||
|
# (np.zeros((length, width), dtype=np.float32)).astype(np.float32).tofile(file_name)
|
||||||
|
# create_xml(file_name, width, length, 'float')
|
||||||
|
|
||||||
|
# os.chdir(cdir)
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################################
|
||||||
|
print('\nSTEP 3. interpolate ionospheric phase')
|
||||||
|
####################################################################################
|
||||||
|
from scipy.interpolate import interp1d
|
||||||
|
|
||||||
|
ml3 = '_{}rlks_{}alks'.format(numberRangeLooks1*numberRangeLooks2,
|
||||||
|
numberAzimuthLooks1*numberAzimuthLooks2)
|
||||||
|
|
||||||
|
width2 = width
|
||||||
|
length2 = length
|
||||||
|
|
||||||
|
#ionrectfile1 = os.path.join(idir, pairs[0], 'insar', pairs[0] + ml3 + '.ion')
|
||||||
|
#multilookDifferentialInterferogram = os.path.join(idir, pairs[0], 'insar', 'diff_' + pairs[0] + ml3 + '.int')
|
||||||
|
#img = isceobj.createImage()
|
||||||
|
#img.load(multilookDifferentialInterferogram + '.xml')
|
||||||
|
#width3 = img.width
|
||||||
|
#length3 = img.length
|
||||||
|
|
||||||
|
trackParameter = os.path.join(idir, pairs[0], dateReferenceStack + '.track.xml')
|
||||||
|
trackTmp = loadProduct(trackParameter)
|
||||||
|
width3 = int(trackTmp.numberOfSamples / numberRangeLooks2)
|
||||||
|
length3 = int(trackTmp.numberOfLines / numberAzimuthLooks2)
|
||||||
|
|
||||||
|
#number of range looks output
|
||||||
|
nrlo = numberRangeLooks1*numberRangeLooks2
|
||||||
|
#number of range looks input
|
||||||
|
nrli = numberRangeLooks1*numberRangeLooksIon
|
||||||
|
#number of azimuth looks output
|
||||||
|
nalo = numberAzimuthLooks1*numberAzimuthLooks2
|
||||||
|
#number of azimuth looks input
|
||||||
|
nali = numberAzimuthLooks1*numberAzimuthLooksIon
|
||||||
|
|
||||||
|
cdir = os.getcwd()
|
||||||
|
os.makedirs(odir, exist_ok=True)
|
||||||
|
os.chdir(odir)
|
||||||
|
|
||||||
|
for idate in range(ndate-1):
|
||||||
|
print('interplate {}'.format(dates2[idate]))
|
||||||
|
if interp and ((numberRangeLooks2 != numberRangeLooksIon) or (numberAzimuthLooks2 != numberAzimuthLooksIon)):
|
||||||
|
ionfilt = ts[idate, :, :]
|
||||||
|
index2 = np.linspace(0, width2-1, num=width2, endpoint=True)
|
||||||
|
index3 = np.linspace(0, width3-1, num=width3, endpoint=True) * nrlo/nrli + (nrlo-nrli)/(2.0*nrli)
|
||||||
|
ionrect = np.zeros((length3, width3), dtype=np.float32)
|
||||||
|
for i in range(length2):
|
||||||
|
f = interp1d(index2, ionfilt[i,:], kind='cubic', fill_value="extrapolate")
|
||||||
|
ionrect[i, :] = f(index3)
|
||||||
|
|
||||||
|
index2 = np.linspace(0, length2-1, num=length2, endpoint=True)
|
||||||
|
index3 = np.linspace(0, length3-1, num=length3, endpoint=True) * nalo/nali + (nalo-nali)/(2.0*nali)
|
||||||
|
for j in range(width3):
|
||||||
|
f = interp1d(index2, ionrect[0:length2, j], kind='cubic', fill_value="extrapolate")
|
||||||
|
ionrect[:, j] = f(index3)
|
||||||
|
|
||||||
|
ionrectfile = 'filt_ion_'+dates2[idate]+ml3+'.ion'
|
||||||
|
ionrect.astype(np.float32).tofile(ionrectfile)
|
||||||
|
create_xml(ionrectfile, width3, length3, 'float')
|
||||||
|
else:
|
||||||
|
ionrectfile = 'filt_ion_'+dates2[idate]+ml2+'.ion'
|
||||||
|
ts[idate, :, :].astype(np.float32).tofile(ionrectfile)
|
||||||
|
create_xml(ionrectfile, width, length, 'float')
|
||||||
|
|
||||||
|
if interp and ((numberRangeLooks2 != numberRangeLooksIon) or (numberAzimuthLooks2 != numberAzimuthLooksIon)):
|
||||||
|
ionrectfile = 'filt_ion_'+dateZero+ml3+'.ion'
|
||||||
|
(np.zeros((length3, width3), dtype=np.float32)).astype(np.float32).tofile(ionrectfile)
|
||||||
|
create_xml(ionrectfile, width3, length3, 'float')
|
||||||
|
else:
|
||||||
|
ionrectfile = 'filt_ion_'+dateZero+ml2+'.ion'
|
||||||
|
(np.zeros((length, width), dtype=np.float32)).astype(np.float32).tofile(ionrectfile)
|
||||||
|
create_xml(ionrectfile, width, length, 'float')
|
||||||
|
|
||||||
|
os.chdir(cdir)
|
||||||
|
|
@ -0,0 +1,619 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Constants import SPEED_OF_LIGHT
|
||||||
|
from isceobj.Alos2Proc.runSwathOffset import swathOffset
|
||||||
|
from isceobj.Alos2Proc.runFrameOffset import frameOffset
|
||||||
|
from isceobj.Alos2Proc.runIonSubband import defineIonDir
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import createObject
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
|
||||||
|
def runIonSubband(self, referenceTrack, idir, dateReferenceStack, dateReference, dateSecondary):
|
||||||
|
'''create subband interferograms
|
||||||
|
'''
|
||||||
|
#catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
||||||
|
#self.updateParamemetersFromUser()
|
||||||
|
|
||||||
|
#if not self.doIon:
|
||||||
|
# catalog.printToLog(logger, "runIonSubband")
|
||||||
|
# self._insar.procDoc.addAllFromCatalog(catalog)
|
||||||
|
# return
|
||||||
|
|
||||||
|
#referenceTrack = self._insar.loadTrack(reference=True)
|
||||||
|
#secondaryTrack = self._insar.loadTrack(reference=False)
|
||||||
|
|
||||||
|
#using 1/3, 1/3, 1/3 band split
|
||||||
|
radarWavelength = referenceTrack.radarWavelength
|
||||||
|
rangeBandwidth = referenceTrack.frames[0].swaths[0].rangeBandwidth
|
||||||
|
rangeSamplingRate = referenceTrack.frames[0].swaths[0].rangeSamplingRate
|
||||||
|
radarWavelengthLower = SPEED_OF_LIGHT/(SPEED_OF_LIGHT / radarWavelength - rangeBandwidth / 3.0)
|
||||||
|
radarWavelengthUpper = SPEED_OF_LIGHT/(SPEED_OF_LIGHT / radarWavelength + rangeBandwidth / 3.0)
|
||||||
|
subbandRadarWavelength = [radarWavelengthLower, radarWavelengthUpper]
|
||||||
|
subbandBandWidth = [rangeBandwidth / 3.0 / rangeSamplingRate, rangeBandwidth / 3.0 / rangeSamplingRate]
|
||||||
|
subbandFrequencyCenter = [-rangeBandwidth / 3.0 / rangeSamplingRate, rangeBandwidth / 3.0 / rangeSamplingRate]
|
||||||
|
|
||||||
|
subbandPrefix = ['lower', 'upper']
|
||||||
|
|
||||||
|
'''
|
||||||
|
ionDir = {
|
||||||
|
ionDir['swathMosaic'] : 'mosaic',
|
||||||
|
ionDir['insar'] : 'insar',
|
||||||
|
ionDir['ion'] : 'ion',
|
||||||
|
ionDir['subband'] : ['lower', 'upper'],
|
||||||
|
ionDir['ionCal'] : 'ion_cal'
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
#define upper level directory names
|
||||||
|
ionDir = defineIonDir()
|
||||||
|
|
||||||
|
|
||||||
|
#self._insar.subbandRadarWavelength = subbandRadarWavelength
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# STEP 1. create directories
|
||||||
|
############################################################
|
||||||
|
#create and enter 'ion' directory
|
||||||
|
#after finishing each step, we are in this directory
|
||||||
|
os.makedirs(ionDir['ion'], exist_ok=True)
|
||||||
|
os.chdir(ionDir['ion'])
|
||||||
|
|
||||||
|
#create insar processing directories
|
||||||
|
for k in range(2):
|
||||||
|
subbandDir = ionDir['subband'][k]
|
||||||
|
for i, frameNumber in enumerate(self._insar.referenceFrames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
fullDir = os.path.join(subbandDir, frameDir, swathDir)
|
||||||
|
os.makedirs(fullDir, exist_ok=True)
|
||||||
|
|
||||||
|
#create ionospheric phase directory
|
||||||
|
os.makedirs(ionDir['ionCal'], exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# STEP 2. create subband interferograms
|
||||||
|
############################################################
|
||||||
|
#import numpy as np
|
||||||
|
#import stdproc
|
||||||
|
#from iscesys.StdOEL.StdOELPy import create_writer
|
||||||
|
#from isceobj.Alos2Proc.Alos2ProcPublic import readOffset
|
||||||
|
#from contrib.alos2proc.alos2proc import rg_filter
|
||||||
|
from StackPulic import formInterferogram
|
||||||
|
|
||||||
|
for i, frameNumber in enumerate(self._insar.referenceFrames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
|
||||||
|
#skip this time consuming process, if interferogram already exists
|
||||||
|
if os.path.isfile(os.path.join(ionDir['subband'][0], frameDir, swathDir, self._insar.interferogram)) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][0], frameDir, swathDir, self._insar.interferogram+'.vrt')) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][0], frameDir, swathDir, self._insar.interferogram+'.xml')) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][0], frameDir, swathDir, self._insar.amplitude)) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][0], frameDir, swathDir, self._insar.amplitude+'.vrt')) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][0], frameDir, swathDir, self._insar.amplitude+'.xml')) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][1], frameDir, swathDir, self._insar.interferogram)) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][1], frameDir, swathDir, self._insar.interferogram+'.vrt')) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][1], frameDir, swathDir, self._insar.interferogram+'.xml')) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][1], frameDir, swathDir, self._insar.amplitude)) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][1], frameDir, swathDir, self._insar.amplitude+'.vrt')) and \
|
||||||
|
os.path.isfile(os.path.join(ionDir['subband'][1], frameDir, swathDir, self._insar.amplitude+'.xml')):
|
||||||
|
print('interferogram already exists at swath {}, frame {}'.format(swathNumber, frameNumber))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# #filter reference and secondary images
|
||||||
|
# for slcx in [self._insar.referenceSlc, self._insar.secondarySlc]:
|
||||||
|
# slc = os.path.join('../', frameDir, swathDir, slcx)
|
||||||
|
# slcLower = os.path.join(ionDir['subband'][0], frameDir, swathDir, slcx)
|
||||||
|
# slcUpper = os.path.join(ionDir['subband'][1], frameDir, swathDir, slcx)
|
||||||
|
# rg_filter(slc, 2,
|
||||||
|
# [slcLower, slcUpper],
|
||||||
|
# subbandBandWidth,
|
||||||
|
# subbandFrequencyCenter,
|
||||||
|
# 257, 2048, 0.1, 0, 0.0)
|
||||||
|
#resample
|
||||||
|
for k in range(2):
|
||||||
|
os.chdir(os.path.join(ionDir['subband'][k], frameDir, swathDir))
|
||||||
|
slcReference = os.path.join('../../../../', idir, dateReference, frameDir, swathDir, dateReference+'_{}.slc'.format(ionDir['subband'][k]))
|
||||||
|
slcSecondary = os.path.join('../../../../', idir, dateSecondary, frameDir, swathDir, dateSecondary+'_{}.slc'.format(ionDir['subband'][k]))
|
||||||
|
formInterferogram(slcReference, slcSecondary, self._insar.interferogram, self._insar.amplitude, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1)
|
||||||
|
os.chdir('../../../')
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# STEP 3. mosaic swaths
|
||||||
|
############################################################
|
||||||
|
from isceobj.Alos2Proc.runSwathMosaic import swathMosaic
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
|
||||||
|
|
||||||
|
#log output info
|
||||||
|
log = 'mosaic swaths in {} at {}\n'.format(os.path.basename(__file__), datetime.datetime.now())
|
||||||
|
log += '================================================================================================\n'
|
||||||
|
|
||||||
|
for k in range(2):
|
||||||
|
os.chdir(ionDir['subband'][k])
|
||||||
|
for i, frameNumber in enumerate(self._insar.referenceFrames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
os.chdir(frameDir)
|
||||||
|
|
||||||
|
mosaicDir = ionDir['swathMosaic']
|
||||||
|
os.makedirs(mosaicDir, exist_ok=True)
|
||||||
|
os.chdir(mosaicDir)
|
||||||
|
|
||||||
|
if not (self._insar.endingSwath-self._insar.startingSwath >= 1):
|
||||||
|
import shutil
|
||||||
|
swathDir = 's{}'.format(referenceTrack.frames[i].swaths[0].swathNumber)
|
||||||
|
|
||||||
|
# if not os.path.isfile(self._insar.interferogram):
|
||||||
|
# os.symlink(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram)
|
||||||
|
# shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
|
||||||
|
# shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
|
||||||
|
# if not os.path.isfile(self._insar.amplitude):
|
||||||
|
# os.symlink(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude)
|
||||||
|
# shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
|
||||||
|
# shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')
|
||||||
|
|
||||||
|
os.rename(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram)
|
||||||
|
os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
|
||||||
|
os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
|
||||||
|
os.rename(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude)
|
||||||
|
os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
|
||||||
|
os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')
|
||||||
|
|
||||||
|
#no need to update frame parameters here
|
||||||
|
os.chdir('../')
|
||||||
|
#no need to save parameter file here
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
#choose offsets
|
||||||
|
numberOfFrames = len(referenceTrack.frames)
|
||||||
|
numberOfSwaths = len(referenceTrack.frames[i].swaths)
|
||||||
|
# if self.swathOffsetMatching:
|
||||||
|
# #no need to do this as the API support 2-d list
|
||||||
|
# #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingReference)).reshape(numberOfFrames, numberOfSwaths)
|
||||||
|
# #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingReference)).reshape(numberOfFrames, numberOfSwaths)
|
||||||
|
# rangeOffsets = self._insar.swathRangeOffsetMatchingReference
|
||||||
|
# azimuthOffsets = self._insar.swathAzimuthOffsetMatchingReference
|
||||||
|
|
||||||
|
# else:
|
||||||
|
# #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalReference)).reshape(numberOfFrames, numberOfSwaths)
|
||||||
|
# #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalReference)).reshape(numberOfFrames, numberOfSwaths)
|
||||||
|
# rangeOffsets = self._insar.swathRangeOffsetGeometricalReference
|
||||||
|
# azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalReference
|
||||||
|
|
||||||
|
# rangeOffsets = rangeOffsets[i]
|
||||||
|
# azimuthOffsets = azimuthOffsets[i]
|
||||||
|
|
||||||
|
|
||||||
|
#compute swath offset using reference stack
|
||||||
|
#geometrical offset is enough now
|
||||||
|
offsetReferenceStack = swathOffset(referenceTrack.frames[i], dateReference+'.slc', 'swath_offset_' + dateReference + '.txt',
|
||||||
|
crossCorrelation=False, numberOfAzimuthLooks=10)
|
||||||
|
#we can faithfully make it integer.
|
||||||
|
#this can also reduce the error due to floating point computation
|
||||||
|
rangeOffsets = [float(round(x)) for x in offsetReferenceStack[0]]
|
||||||
|
azimuthOffsets = [float(round(x)) for x in offsetReferenceStack[1]]
|
||||||
|
|
||||||
|
#list of input files
|
||||||
|
inputInterferograms = []
|
||||||
|
inputAmplitudes = []
|
||||||
|
#phaseDiff = [None]
|
||||||
|
swathPhaseDiffIon = [self.swathPhaseDiffLowerIon, self.swathPhaseDiffUpperIon]
|
||||||
|
phaseDiff = swathPhaseDiffIon[k]
|
||||||
|
if swathPhaseDiffIon[k] is None:
|
||||||
|
phaseDiff = None
|
||||||
|
else:
|
||||||
|
phaseDiff = swathPhaseDiffIon[k][i]
|
||||||
|
phaseDiff.insert(0, None)
|
||||||
|
|
||||||
|
for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
inputInterferograms.append(os.path.join('../', swathDir, self._insar.interferogram))
|
||||||
|
inputAmplitudes.append(os.path.join('../', swathDir, self._insar.amplitude))
|
||||||
|
|
||||||
|
# #compute phase needed to be compensated using startingRange
|
||||||
|
# if j >= 1:
|
||||||
|
# #phaseDiffSwath1 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange)/subbandRadarWavelength[k]
|
||||||
|
# #phaseDiffSwath2 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange)/subbandRadarWavelength[k]
|
||||||
|
# phaseDiffSwath1 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
|
||||||
|
# -4.0 * np.pi * secondaryTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
|
||||||
|
# phaseDiffSwath2 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
|
||||||
|
# -4.0 * np.pi * secondaryTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
|
||||||
|
# if referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange == \
|
||||||
|
# referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange:
|
||||||
|
# #phaseDiff.append(phaseDiffSwath2 - phaseDiffSwath1)
|
||||||
|
# #if reference and secondary versions are all before or after version 2.025 (starting range error < 0.5 m),
|
||||||
|
# #it should be OK to do the above.
|
||||||
|
# #see results in neom where it meets the above requirement, but there is still phase diff
|
||||||
|
# #to be less risky, we do not input values here
|
||||||
|
# phaseDiff.append(None)
|
||||||
|
# else:
|
||||||
|
# phaseDiff.append(None)
|
||||||
|
|
||||||
|
#note that frame parameters are updated after mosaicking, here no need to update parameters
|
||||||
|
#mosaic amplitudes
|
||||||
|
swathMosaic(referenceTrack.frames[i], inputAmplitudes, self._insar.amplitude,
|
||||||
|
rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, resamplingMethod=0)
|
||||||
|
#mosaic interferograms
|
||||||
|
#These are for ALOS-2, may need to change for ALOS-4!
|
||||||
|
phaseDiffFixed = [0.0, 0.4754024578084084, 0.9509913179406437, 1.4261648478671614, 2.179664007520499, 2.6766909968024932, 3.130810857]
|
||||||
|
|
||||||
|
#if (referenceTrack.frames[i].processingSoftwareVersion == '2.025' and secondaryTrack.frames[i].processingSoftwareVersion == '2.023') or \
|
||||||
|
# (referenceTrack.frames[i].processingSoftwareVersion == '2.023' and secondaryTrack.frames[i].processingSoftwareVersion == '2.025'):
|
||||||
|
|
||||||
|
# # changed value number of samples to estimate new value new values estimate area
|
||||||
|
# ###########################################################################################################################
|
||||||
|
# # 2.6766909968024932-->2.6581660335779866 1808694 d169-f2850, north CA
|
||||||
|
# # 2.179664007520499 -->2.204125866652153 131120 d169-f2850, north CA
|
||||||
|
|
||||||
|
# phaseDiffFixed = [0.0, 0.4754024578084084, 0.9509913179406437, 1.4261648478671614, 2.204125866652153, 2.6581660335779866, 3.130810857]
|
||||||
|
|
||||||
|
snapThreshold = 0.2
|
||||||
|
|
||||||
|
#the above preparetions only applies to 'self._insar.modeCombination == 21'
|
||||||
|
#looks like it also works for 31 (scansarNominalModes-stripmapModes)
|
||||||
|
# if self._insar.modeCombination != 21:
|
||||||
|
# phaseDiff = None
|
||||||
|
# phaseDiffFixed = None
|
||||||
|
# snapThreshold = None
|
||||||
|
|
||||||
|
#whether snap for each swath
|
||||||
|
if self.swathPhaseDiffSnapIon == None:
|
||||||
|
snapSwath = [[True for jjj in range(numberOfSwaths-1)] for iii in range(numberOfFrames)]
|
||||||
|
else:
|
||||||
|
snapSwath = self.swathPhaseDiffSnapIon
|
||||||
|
if len(snapSwath) != numberOfFrames:
|
||||||
|
raise Exception('please specify each frame for parameter: swath phase difference snap to fixed values')
|
||||||
|
for iii in range(numberOfFrames):
|
||||||
|
if len(snapSwath[iii]) != (numberOfSwaths-1):
|
||||||
|
raise Exception('please specify correct number of swaths for parameter: swath phase difference snap to fixed values')
|
||||||
|
|
||||||
|
(phaseDiffEst, phaseDiffUsed, phaseDiffSource, numberOfValidSamples) = swathMosaic(referenceTrack.frames[i], inputInterferograms, self._insar.interferogram,
|
||||||
|
rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, updateFrame=False,
|
||||||
|
phaseCompensation=True, phaseDiff=phaseDiff, phaseDiffFixed=phaseDiffFixed, snapThreshold=snapThreshold, snapSwath=snapSwath[i], pcRangeLooks=1, pcAzimuthLooks=4,
|
||||||
|
filt=False, resamplingMethod=1)
|
||||||
|
|
||||||
|
#the first item is meaningless for all the following list, so only record the following items
|
||||||
|
if phaseDiff == None:
|
||||||
|
phaseDiff = [None for iii in range(self._insar.startingSwath, self._insar.endingSwath + 1)]
|
||||||
|
#catalog.addItem('frame {} {} band swath phase diff input'.format(frameNumber, ionDir['subband'][k]), phaseDiff[1:], 'runIonSubband')
|
||||||
|
#catalog.addItem('frame {} {} band swath phase diff estimated'.format(frameNumber, ionDir['subband'][k]), phaseDiffEst[1:], 'runIonSubband')
|
||||||
|
#catalog.addItem('frame {} {} band swath phase diff used'.format(frameNumber, ionDir['subband'][k]), phaseDiffUsed[1:], 'runIonSubband')
|
||||||
|
#catalog.addItem('frame {} {} band swath phase diff used source'.format(frameNumber, ionDir['subband'][k]), phaseDiffSource[1:], 'runIonSubband')
|
||||||
|
#catalog.addItem('frame {} {} band swath phase diff samples used'.format(frameNumber, ionDir['subband'][k]), numberOfValidSamples[1:], 'runIonSubband')
|
||||||
|
|
||||||
|
log += 'frame {} {} band swath phase diff input: {}\n'.format(frameNumber, ionDir['subband'][k], phaseDiff[1:])
|
||||||
|
log += 'frame {} {} band swath phase diff estimated: {}\n'.format(frameNumber, ionDir['subband'][k], phaseDiffEst[1:])
|
||||||
|
log += 'frame {} {} band swath phase diff used: {}\n'.format(frameNumber, ionDir['subband'][k], phaseDiffUsed[1:])
|
||||||
|
log += 'frame {} {} band swath phase diff used source: {}\n'.format(frameNumber, ionDir['subband'][k], phaseDiffSource[1:])
|
||||||
|
log += 'frame {} {} band swath phase diff samples used: {}\n'.format(frameNumber, ionDir['subband'][k], numberOfValidSamples[1:])
|
||||||
|
|
||||||
|
#check if there is value around 3.130810857, which may not be stable
|
||||||
|
phaseDiffUnstableExist = False
|
||||||
|
for xxx in phaseDiffUsed:
|
||||||
|
if abs(abs(xxx) - 3.130810857) < 0.2:
|
||||||
|
phaseDiffUnstableExist = True
|
||||||
|
#catalog.addItem('frame {} {} band swath phase diff unstable exists'.format(frameNumber, ionDir['subband'][k]), phaseDiffUnstableExist, 'runIonSubband')
|
||||||
|
log += 'frame {} {} band swath phase diff unstable exists: {}\n'.format(frameNumber, ionDir['subband'][k], phaseDiffUnstableExist)
|
||||||
|
log += '\n'
|
||||||
|
|
||||||
|
create_xml(self._insar.amplitude, referenceTrack.frames[i].numberOfSamples, referenceTrack.frames[i].numberOfLines, 'amp')
|
||||||
|
create_xml(self._insar.interferogram, referenceTrack.frames[i].numberOfSamples, referenceTrack.frames[i].numberOfLines, 'int')
|
||||||
|
|
||||||
|
#update secondary frame parameters here, here no need to update parameters
|
||||||
|
os.chdir('../')
|
||||||
|
#save parameter file, here no need to save parameter file
|
||||||
|
os.chdir('../')
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# STEP 4. mosaic frames
|
||||||
|
############################################################
|
||||||
|
from isceobj.Alos2Proc.runFrameMosaic import frameMosaic
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
|
||||||
|
log += 'mosaic frames in {} at {}\n'.format(os.path.basename(__file__), datetime.datetime.now())
|
||||||
|
log += '================================================================================================\n'
|
||||||
|
|
||||||
|
|
||||||
|
spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = acquisitionModesAlos2()
|
||||||
|
for k in range(2):
|
||||||
|
os.chdir(ionDir['subband'][k])
|
||||||
|
|
||||||
|
mosaicDir = ionDir['insar']
|
||||||
|
os.makedirs(mosaicDir, exist_ok=True)
|
||||||
|
os.chdir(mosaicDir)
|
||||||
|
|
||||||
|
numberOfFrames = len(referenceTrack.frames)
|
||||||
|
if numberOfFrames == 1:
|
||||||
|
import shutil
|
||||||
|
frameDir = os.path.join('f1_{}/mosaic'.format(self._insar.referenceFrames[0]))
|
||||||
|
# if not os.path.isfile(self._insar.interferogram):
|
||||||
|
# os.symlink(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram)
|
||||||
|
# #shutil.copy2() can overwrite
|
||||||
|
# shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
|
||||||
|
# shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
|
||||||
|
# if not os.path.isfile(self._insar.amplitude):
|
||||||
|
# os.symlink(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude)
|
||||||
|
# shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
|
||||||
|
# shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')
|
||||||
|
|
||||||
|
os.rename(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram)
|
||||||
|
os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
|
||||||
|
os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
|
||||||
|
os.rename(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude)
|
||||||
|
os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
|
||||||
|
os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')
|
||||||
|
|
||||||
|
#update track parameters, no need to update track parameters here
|
||||||
|
|
||||||
|
else:
|
||||||
|
# #choose offsets
|
||||||
|
# if self.frameOffsetMatching:
|
||||||
|
# rangeOffsets = self._insar.frameRangeOffsetMatchingReference
|
||||||
|
# azimuthOffsets = self._insar.frameAzimuthOffsetMatchingReference
|
||||||
|
# else:
|
||||||
|
# rangeOffsets = self._insar.frameRangeOffsetGeometricalReference
|
||||||
|
# azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalReference
|
||||||
|
|
||||||
|
if referenceTrack.operationMode in scansarModes:
|
||||||
|
matchingMode=0
|
||||||
|
else:
|
||||||
|
matchingMode=1
|
||||||
|
|
||||||
|
#geometrical offset is enough
|
||||||
|
offsetReferenceStack = frameOffset(referenceTrack, dateReference+'.slc', 'frame_offset_' + dateReference + '.txt',
|
||||||
|
crossCorrelation=False, matchingMode=matchingMode)
|
||||||
|
|
||||||
|
#we can faithfully make it integer.
|
||||||
|
#this can also reduce the error due to floating point computation
|
||||||
|
rangeOffsets = [float(round(x)) for x in offsetReferenceStack[0]]
|
||||||
|
azimuthOffsets = [float(round(x)) for x in offsetReferenceStack[1]]
|
||||||
|
|
||||||
|
#list of input files
|
||||||
|
inputInterferograms = []
|
||||||
|
inputAmplitudes = []
|
||||||
|
for i, frameNumber in enumerate(self._insar.referenceFrames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
inputInterferograms.append(os.path.join('../', frameDir, 'mosaic', self._insar.interferogram))
|
||||||
|
inputAmplitudes.append(os.path.join('../', frameDir, 'mosaic', self._insar.amplitude))
|
||||||
|
|
||||||
|
#note that track parameters are updated after mosaicking
|
||||||
|
#mosaic amplitudes
|
||||||
|
frameMosaic(referenceTrack, inputAmplitudes, self._insar.amplitude,
|
||||||
|
rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1,
|
||||||
|
updateTrack=False, phaseCompensation=False, resamplingMethod=0)
|
||||||
|
#mosaic interferograms
|
||||||
|
(phaseDiffEst, phaseDiffUsed, phaseDiffSource, numberOfValidSamples) = frameMosaic(referenceTrack, inputInterferograms, self._insar.interferogram,
|
||||||
|
rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1,
|
||||||
|
updateTrack=False, phaseCompensation=True, resamplingMethod=1)
|
||||||
|
|
||||||
|
create_xml(self._insar.amplitude, referenceTrack.numberOfSamples, referenceTrack.numberOfLines, 'amp')
|
||||||
|
create_xml(self._insar.interferogram, referenceTrack.numberOfSamples, referenceTrack.numberOfLines, 'int')
|
||||||
|
|
||||||
|
#if multiple frames, remove frame amplitudes/inteferograms to save space
|
||||||
|
for x in inputAmplitudes:
|
||||||
|
os.remove(x)
|
||||||
|
os.remove(x+'.vrt')
|
||||||
|
os.remove(x+'.xml')
|
||||||
|
|
||||||
|
for x in inputInterferograms:
|
||||||
|
os.remove(x)
|
||||||
|
os.remove(x+'.vrt')
|
||||||
|
os.remove(x+'.xml')
|
||||||
|
|
||||||
|
#catalog.addItem('{} band frame phase diff estimated'.format(ionDir['subband'][k]), phaseDiffEst[1:], 'runIonSubband')
|
||||||
|
#catalog.addItem('{} band frame phase diff used'.format(ionDir['subband'][k]), phaseDiffUsed[1:], 'runIonSubband')
|
||||||
|
#catalog.addItem('{} band frame phase diff used source'.format(ionDir['subband'][k]), phaseDiffSource[1:], 'runIonSubband')
|
||||||
|
#catalog.addItem('{} band frame phase diff samples used'.format(ionDir['subband'][k]), numberOfValidSamples[1:], 'runIonSubband')
|
||||||
|
|
||||||
|
log += '{} band frame phase diff estimated: {}\n'.format(ionDir['subband'][k], phaseDiffEst[1:])
|
||||||
|
log += '{} band frame phase diff used: {}\n'.format(ionDir['subband'][k], phaseDiffUsed[1:])
|
||||||
|
log += '{} band frame phase diff used source: {}\n'.format(ionDir['subband'][k], phaseDiffSource[1:])
|
||||||
|
log += '{} band frame phase diff samples used: {}\n'.format(ionDir['subband'][k], numberOfValidSamples[1:])
|
||||||
|
log += '\n'
|
||||||
|
|
||||||
|
#update secondary parameters here, no need to update secondary parameters here
|
||||||
|
|
||||||
|
os.chdir('../')
|
||||||
|
#save parameter file, no need to save parameter file here
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# STEP 5. clear frame processing files
|
||||||
|
############################################################
|
||||||
|
import shutil
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
|
|
||||||
|
for k in range(2):
|
||||||
|
os.chdir(ionDir['subband'][k])
|
||||||
|
for i, frameNumber in enumerate(self._insar.referenceFrames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
#keep subswath interferograms
|
||||||
|
#shutil.rmtree(frameDir)
|
||||||
|
#cmd = 'rm -rf {}'.format(frameDir)
|
||||||
|
#runCmd(cmd)
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# STEP 6. create differential interferograms
|
||||||
|
############################################################
|
||||||
|
import numpy as np
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
|
|
||||||
|
for k in range(2):
|
||||||
|
os.chdir(ionDir['subband'][k])
|
||||||
|
|
||||||
|
insarDir = ionDir['insar']
|
||||||
|
os.makedirs(insarDir, exist_ok=True)
|
||||||
|
os.chdir(insarDir)
|
||||||
|
|
||||||
|
rangePixelSize = self._insar.numberRangeLooks1 * referenceTrack.rangePixelSize
|
||||||
|
radarWavelength = subbandRadarWavelength[k]
|
||||||
|
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1)
|
||||||
|
if dateReference == dateReferenceStack:
|
||||||
|
rectRangeOffset = os.path.join('../../../', idir, dateSecondary, 'insar', dateSecondary + ml1 + '_rg_rect.off')
|
||||||
|
cmd = "imageMath.py -e='a*exp(-1.0*J*b*4.0*{}*{}/{})*(b!=0)' --a={} --b={} -o {} -t cfloat".format(np.pi, rangePixelSize, radarWavelength, self._insar.interferogram, rectRangeOffset, self._insar.differentialInterferogram)
|
||||||
|
elif dateSecondary == dateReferenceStack:
|
||||||
|
rectRangeOffset = os.path.join('../../../', idir, dateReference, 'insar', dateReference + ml1 + '_rg_rect.off')
|
||||||
|
cmd = "imageMath.py -e='a*exp(1.0*J*b*4.0*{}*{}/{})*(b!=0)' --a={} --b={} -o {} -t cfloat".format(np.pi, rangePixelSize, radarWavelength, self._insar.interferogram, rectRangeOffset, self._insar.differentialInterferogram)
|
||||||
|
else:
|
||||||
|
rectRangeOffset1 = os.path.join('../../../', idir, dateReference, 'insar', dateReference + ml1 + '_rg_rect.off')
|
||||||
|
rectRangeOffset2 = os.path.join('../../../', idir, dateSecondary, 'insar', dateSecondary + ml1 + '_rg_rect.off')
|
||||||
|
cmd = "imageMath.py -e='a*exp(1.0*J*(b-c)*4.0*{}*{}/{})*(b!=0)*(c!=0)' --a={} --b={} --c={} -o {} -t cfloat".format(np.pi, rangePixelSize, radarWavelength, self._insar.interferogram, rectRangeOffset1, rectRangeOffset2, self._insar.differentialInterferogram)
|
||||||
|
runCmd(cmd)
|
||||||
|
|
||||||
|
os.chdir('../../')
|
||||||
|
|
||||||
|
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
|
||||||
|
return log
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='create subband interferograms for ionospheric correction')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where resampled data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-ref_date_stack', dest='ref_date_stack', type=str, required=True,
|
||||||
|
help = 'reference date of stack. format: YYMMDD')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
# parser.add_argument('-nrlks_ion', dest='nrlks_ion', type=int, default=1,
|
||||||
|
# help = 'number of range looks ion. default: 1')
|
||||||
|
# parser.add_argument('-nalks_ion', dest='nalks_ion', type=int, default=1,
|
||||||
|
# help = 'number of azimuth looks ion. default: 1')
|
||||||
|
parser.add_argument('-snap', dest='snap', type=int, nargs='+', action='append', default=None,
|
||||||
|
help='swath phase difference snap to fixed values. e.g. you have 3 swaths and 2 frames. specify this parameter as: -snap 1 1 -snap 1 0, where 0 means no snap, 1 means snap')
|
||||||
|
parser.add_argument('-phase_diff_lower', dest='phase_diff_lower', type=str, nargs='+', action='append', default=None,
|
||||||
|
help='swath phase difference lower band. e.g. you have 3 swaths and 2 frames. specify this parameter as: -snap -1.3 2.37 -snap 0.1 None, where None means no user input phase difference value')
|
||||||
|
parser.add_argument('-phase_diff_upper', dest='phase_diff_upper', type=str, nargs='+', action='append', default=None,
|
||||||
|
help='swath phase difference upper band. e.g. you have 3 swaths and 2 frames. specify this parameter as: -snap -1.3 2.37 -snap 0.1 None, where None means no user input phase difference value')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
dateReferenceStack = inps.ref_date_stack
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
#numberRangeLooksIon = inps.nrlks_ion
|
||||||
|
#numberAzimuthLooksIon = inps.nalks_ion
|
||||||
|
swathPhaseDiffSnapIon = inps.snap
|
||||||
|
swathPhaseDiffLowerIon = inps.phase_diff_lower
|
||||||
|
swathPhaseDiffUpperIon = inps.phase_diff_upper
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
ms = pair
|
||||||
|
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
|
||||||
|
dateDirs, dates, frames, swaths, dateIndexReference = stackDateStatistics(idir, dateReferenceStack)
|
||||||
|
nframe = len(frames)
|
||||||
|
nswath = len(swaths)
|
||||||
|
|
||||||
|
trackReferenceStack = loadTrack('./', dates[dateIndexReference])
|
||||||
|
#trackReference = loadTrack('./', dateReference)
|
||||||
|
#trackSecondary = loadTrack('./', dateSecondary)
|
||||||
|
|
||||||
|
|
||||||
|
self = createObject()
|
||||||
|
self._insar = createObject()
|
||||||
|
self._insar.referenceFrames = frames
|
||||||
|
self._insar.startingSwath = swaths[0]
|
||||||
|
self._insar.endingSwath = swaths[-1]
|
||||||
|
|
||||||
|
self._insar.numberRangeLooks1 = numberRangeLooks1
|
||||||
|
self._insar.numberAzimuthLooks1 = numberAzimuthLooks1
|
||||||
|
|
||||||
|
self._insar.interferogram = ms + ml1 + '.int'
|
||||||
|
self._insar.amplitude = ms + ml1 + '.amp'
|
||||||
|
self._insar.differentialInterferogram = 'diff_' + ms + ml1 + '.int'
|
||||||
|
|
||||||
|
#set self.swathPhaseDiffSnapIon, self.swathPhaseDiffLowerIon, self.swathPhaseDiffUpperIon
|
||||||
|
if swathPhaseDiffSnapIon is not None:
|
||||||
|
swathPhaseDiffSnapIon = [[True if x==1 else False for x in y] for y in swathPhaseDiffSnapIon]
|
||||||
|
if len(swathPhaseDiffSnapIon) != nframe:
|
||||||
|
raise Exception('please specify each frame for parameter: -snap')
|
||||||
|
for i in range(nframe):
|
||||||
|
if len(snapSwath[i]) != (nswath-1):
|
||||||
|
raise Exception('please specify correct number of swaths for parameter: -snap')
|
||||||
|
|
||||||
|
if swathPhaseDiffLowerIon is not None:
|
||||||
|
swathPhaseDiffLowerIon = [[float(x) if x.upper() != 'NONE' else None for x in y] for y in swathPhaseDiffLowerIon]
|
||||||
|
if len(swathPhaseDiffLowerIon) != nframe:
|
||||||
|
raise Exception('please specify each frame for parameter: -phase_diff_lower')
|
||||||
|
for i in range(nframe):
|
||||||
|
if len(swathPhaseDiffLowerIon[i]) != (nswath-1):
|
||||||
|
raise Exception('please specify correct number of swaths for parameter: -phase_diff_lower')
|
||||||
|
|
||||||
|
if swathPhaseDiffUpperIon is not None:
|
||||||
|
swathPhaseDiffUpperIon = [[float(x) if x.upper() != 'NONE' else None for x in y] for y in swathPhaseDiffUpperIon]
|
||||||
|
if len(swathPhaseDiffUpperIon) != nframe:
|
||||||
|
raise Exception('please specify each frame for parameter: -phase_diff_upper')
|
||||||
|
for i in range(nframe):
|
||||||
|
if len(swathPhaseDiffUpperIon[i]) != (nswath-1):
|
||||||
|
raise Exception('please specify correct number of swaths for parameter: -phase_diff_upper')
|
||||||
|
|
||||||
|
self.swathPhaseDiffSnapIon = swathPhaseDiffSnapIon
|
||||||
|
self.swathPhaseDiffLowerIon = swathPhaseDiffLowerIon
|
||||||
|
self.swathPhaseDiffUpperIon = swathPhaseDiffUpperIon
|
||||||
|
|
||||||
|
log = runIonSubband(self, trackReferenceStack, idir, dateReferenceStack, dateReference, dateSecondary)
|
||||||
|
|
||||||
|
logFile = 'process.log'
|
||||||
|
with open(logFile, 'a') as f:
|
||||||
|
f.write(log)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.runIonUwrap import ionUwrap
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import createObject
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='unwrap subband interferograms for ionospheric correction')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where resampled data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-ref_date_stack', dest='ref_date_stack', type=str, required=True,
|
||||||
|
help = 'reference date of stack. format: YYMMDD')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-wbd', dest='wbd', type=str, required=True,
|
||||||
|
help = 'water body file')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
parser.add_argument('-nrlks_ion', dest='nrlks_ion', type=int, default=1,
|
||||||
|
help = 'number of range looks ion. default: 1')
|
||||||
|
parser.add_argument('-nalks_ion', dest='nalks_ion', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks ion. default: 1')
|
||||||
|
parser.add_argument('-filt', dest='filt', action='store_true', default=False,
|
||||||
|
help='filter subband interferograms')
|
||||||
|
parser.add_argument('-alpha', dest='alpha', type=float, default=0.3,
|
||||||
|
help='filtering strength. default: 0.3')
|
||||||
|
parser.add_argument('-win', dest='win', type=int, default=32,
|
||||||
|
help = 'filter window size. default: 32')
|
||||||
|
parser.add_argument('-step', dest='step', type=int, default=4,
|
||||||
|
help = 'filter step size. default: 4')
|
||||||
|
parser.add_argument('-keep_mag', dest='keep_mag', action='store_true', default=False,
|
||||||
|
help='keep magnitude before filtering subband interferogram')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
dateReferenceStack = inps.ref_date_stack
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
wbd = inps.wbd
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
numberRangeLooksIon = inps.nrlks_ion
|
||||||
|
numberAzimuthLooksIon = inps.nalks_ion
|
||||||
|
filterSubbandInt = inps.filt
|
||||||
|
filterStrengthSubbandInt = inps.alpha
|
||||||
|
filterWinsizeSubbandInt = inps.win
|
||||||
|
filterStepsizeSubbandInt = inps.step
|
||||||
|
removeMagnitudeBeforeFilteringSubbandInt = not inps.keep_mag
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
ms = pair
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
dateDirs, dates, frames, swaths, dateIndexReference = stackDateStatistics(idir, dateReferenceStack)
|
||||||
|
trackReference = loadTrack('./', dateReference)
|
||||||
|
|
||||||
|
self = createObject()
|
||||||
|
self._insar = createObject()
|
||||||
|
self._insar.wbd = wbd
|
||||||
|
self._insar.numberRangeLooks1 = numberRangeLooks1
|
||||||
|
self._insar.numberAzimuthLooks1 = numberAzimuthLooks1
|
||||||
|
self._insar.numberRangeLooksIon = numberRangeLooksIon
|
||||||
|
self._insar.numberAzimuthLooksIon = numberAzimuthLooksIon
|
||||||
|
|
||||||
|
self._insar.amplitude = ms + ml1 + '.amp'
|
||||||
|
self._insar.differentialInterferogram = 'diff_' + ms + ml1 + '.int'
|
||||||
|
self._insar.latitude = dateReferenceStack + ml1 + '.lat'
|
||||||
|
self._insar.longitude = dateReferenceStack + ml1 + '.lon'
|
||||||
|
self.filterSubbandInt = filterSubbandInt
|
||||||
|
self.filterStrengthSubbandInt = filterStrengthSubbandInt
|
||||||
|
self.filterWinsizeSubbandInt = filterWinsizeSubbandInt
|
||||||
|
self.filterStepsizeSubbandInt = filterStepsizeSubbandInt
|
||||||
|
self.removeMagnitudeBeforeFilteringSubbandInt = removeMagnitudeBeforeFilteringSubbandInt
|
||||||
|
|
||||||
|
ionUwrap(self, trackReference, latLonDir=os.path.join(idir, dates[dateIndexReference], 'insar'))
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from contrib.alos2proc.alos2proc import look
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
|
from isceobj.Alos2Proc.runCoherence import coherence
|
||||||
|
|
||||||
|
from StackPulic import loadProduct
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='take more looks and compute coherence')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
parser.add_argument('-nrlks2', dest='nrlks2', type=int, default=1,
|
||||||
|
help = 'number of range looks 2. default: 1')
|
||||||
|
parser.add_argument('-nalks2', dest='nalks2', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 2. default: 1')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
numberRangeLooks2 = inps.nrlks2
|
||||||
|
numberAzimuthLooks2 = inps.nalks2
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
ml2 = '_{}rlks_{}alks'.format(numberRangeLooks1*numberRangeLooks2, numberAzimuthLooks1*numberAzimuthLooks2)
|
||||||
|
|
||||||
|
insarDir = 'insar'
|
||||||
|
os.makedirs(insarDir, exist_ok=True)
|
||||||
|
os.chdir(insarDir)
|
||||||
|
|
||||||
|
amplitude = pair + ml1 + '.amp'
|
||||||
|
differentialInterferogram = 'diff_' + pair + ml1 + '.int'
|
||||||
|
multilookAmplitude = pair + ml2 + '.amp'
|
||||||
|
multilookDifferentialInterferogram = 'diff_' + pair + ml2 + '.int'
|
||||||
|
multilookCoherence = pair + ml2 + '.cor'
|
||||||
|
|
||||||
|
amp = isceobj.createImage()
|
||||||
|
amp.load(amplitude+'.xml')
|
||||||
|
width = amp.width
|
||||||
|
length = amp.length
|
||||||
|
width2 = int(width / numberRangeLooks2)
|
||||||
|
length2 = int(length / numberAzimuthLooks2)
|
||||||
|
|
||||||
|
|
||||||
|
if not ((numberRangeLooks2 == 1) and (numberAzimuthLooks2 == 1)):
|
||||||
|
#take looks
|
||||||
|
look(differentialInterferogram, multilookDifferentialInterferogram, width, numberRangeLooks2, numberAzimuthLooks2, 4, 0, 1)
|
||||||
|
look(amplitude, multilookAmplitude, width, numberRangeLooks2, numberAzimuthLooks2, 4, 1, 1)
|
||||||
|
#creat xml
|
||||||
|
create_xml(multilookDifferentialInterferogram, width2, length2, 'int')
|
||||||
|
create_xml(multilookAmplitude, width2, length2, 'amp')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (numberRangeLooks1*numberRangeLooks2*numberAzimuthLooks1*numberAzimuthLooks2 >= 9):
|
||||||
|
cmd = "imageMath.py -e='sqrt(b_0*b_1);abs(a)/(b_0+(b_0==0))/(b_1+(b_1==0))*(b_0!=0)*(b_1!=0)' --a={} --b={} -o {} -t float -s BIL".format(
|
||||||
|
multilookDifferentialInterferogram,
|
||||||
|
multilookAmplitude,
|
||||||
|
multilookCoherence)
|
||||||
|
runCmd(cmd)
|
||||||
|
else:
|
||||||
|
#estimate coherence using a moving window
|
||||||
|
coherence(multilookAmplitude, multilookDifferentialInterferogram, multilookCoherence,
|
||||||
|
method="cchz_wave", windowSize=5)
|
||||||
|
|
||||||
|
|
||||||
|
os.chdir('../')
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
from contrib.alos2proc.alos2proc import look
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='take more looks')
|
||||||
|
parser.add_argument('-date', dest='date', type=str, required=True,
|
||||||
|
help = 'date. format: YYMMDD')
|
||||||
|
parser.add_argument('-wbd', dest='wbd', type=str, required=True,
|
||||||
|
help = 'water body file')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
parser.add_argument('-nrlks2', dest='nrlks2', type=int, default=1,
|
||||||
|
help = 'number of range looks 2. default: 1')
|
||||||
|
parser.add_argument('-nalks2', dest='nalks2', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 2. default: 1')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
date = inps.date
|
||||||
|
wbdFile = inps.wbd
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
numberRangeLooks2 = inps.nrlks2
|
||||||
|
numberAzimuthLooks2 = inps.nalks2
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
#pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
ml2 = '_{}rlks_{}alks'.format(numberRangeLooks1*numberRangeLooks2, numberAzimuthLooks1*numberAzimuthLooks2)
|
||||||
|
|
||||||
|
|
||||||
|
latitude = date + ml1 + '.lat'
|
||||||
|
longitude = date + ml1 + '.lon'
|
||||||
|
height = date + ml1 + '.hgt'
|
||||||
|
los = date + ml1 + '.los'
|
||||||
|
|
||||||
|
multilookLatitude = date + ml2 + '.lat'
|
||||||
|
multilookLongitude = date + ml2 + '.lon'
|
||||||
|
multilookHeight = date + ml2 + '.hgt'
|
||||||
|
multilookLos = date + ml2 + '.los'
|
||||||
|
multilookWbdOut = date + ml2 + '.wbd'
|
||||||
|
|
||||||
|
wbdFile = os.path.abspath(wbdFile)
|
||||||
|
|
||||||
|
insarDir = 'insar'
|
||||||
|
os.makedirs(insarDir, exist_ok=True)
|
||||||
|
os.chdir(insarDir)
|
||||||
|
|
||||||
|
|
||||||
|
img = isceobj.createImage()
|
||||||
|
img.load(latitude+'.xml')
|
||||||
|
width = img.width
|
||||||
|
length = img.length
|
||||||
|
width2 = int(width / numberRangeLooks2)
|
||||||
|
length2 = int(length / numberAzimuthLooks2)
|
||||||
|
|
||||||
|
if not ((numberRangeLooks2 == 1) and (numberAzimuthLooks2 == 1)):
|
||||||
|
#take looks
|
||||||
|
look(latitude, multilookLatitude, width, numberRangeLooks2, numberAzimuthLooks2, 3, 0, 1)
|
||||||
|
look(longitude, multilookLongitude, width, numberRangeLooks2, numberAzimuthLooks2, 3, 0, 1)
|
||||||
|
look(height, multilookHeight, width, numberRangeLooks2, numberAzimuthLooks2, 3, 0, 1)
|
||||||
|
#creat xml
|
||||||
|
create_xml(multilookLatitude, width2, length2, 'double')
|
||||||
|
create_xml(multilookLongitude, width2, length2, 'double')
|
||||||
|
create_xml(multilookHeight, width2, length2, 'double')
|
||||||
|
#los has two bands, use look program in isce instead
|
||||||
|
#cmd = "looks.py -i {} -o {} -r {} -a {}".format(self._insar.los, self._insar.multilookLos, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2)
|
||||||
|
#runCmd(cmd)
|
||||||
|
|
||||||
|
#replace the above system call with function call
|
||||||
|
from mroipac.looks.Looks import Looks
|
||||||
|
from isceobj.Image import createImage
|
||||||
|
inImage = createImage()
|
||||||
|
inImage.load(los+'.xml')
|
||||||
|
|
||||||
|
lkObj = Looks()
|
||||||
|
lkObj.setDownLooks(numberAzimuthLooks2)
|
||||||
|
lkObj.setAcrossLooks(numberRangeLooks2)
|
||||||
|
lkObj.setInputImage(inImage)
|
||||||
|
lkObj.setOutputFilename(multilookLos)
|
||||||
|
lkObj.looks()
|
||||||
|
|
||||||
|
#water body
|
||||||
|
#this looking operation has no problems where there is only water and land, but there is also possible no-data area
|
||||||
|
#look(self._insar.wbdOut, self._insar.multilookWbdOut, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 0, 0, 1)
|
||||||
|
#create_xml(self._insar.multilookWbdOut, width2, length2, 'byte')
|
||||||
|
#use waterBodyRadar instead to avoid the problems of no-data pixels in water body
|
||||||
|
waterBodyRadar(multilookLatitude, multilookLongitude, wbdFile, multilookWbdOut)
|
||||||
|
|
||||||
|
|
||||||
|
os.chdir('../')
|
||||||
|
|
@ -0,0 +1,226 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
from isceobj.Alos2Proc.runSwathOffset import swathOffset
|
||||||
|
from isceobj.Alos2Proc.runFrameOffset import frameOffset
|
||||||
|
from isceobj.Alos2Proc.runSwathMosaic import swathMosaic
|
||||||
|
from isceobj.Alos2Proc.runFrameMosaic import frameMosaic
|
||||||
|
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='form interferogram')
|
||||||
|
parser.add_argument('-ref_date_stack', dest='ref_date_stack', type=str, required=True,
|
||||||
|
help = 'reference date of stack. format: YYMMDD')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
dateReferenceStack = inps.ref_date_stack
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
logFile = 'process.log'
|
||||||
|
|
||||||
|
pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
|
||||||
|
interferogram = pair + ml1 + '.int'
|
||||||
|
amplitude = pair + ml1 + '.amp'
|
||||||
|
|
||||||
|
spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = acquisitionModesAlos2()
|
||||||
|
|
||||||
|
#use one date to find frames and swaths. any date should work, here we use dateIndexReference
|
||||||
|
frames = sorted([x[-4:] for x in glob.glob(os.path.join('./', 'f*_*'))])
|
||||||
|
swaths = sorted([int(x[-1]) for x in glob.glob(os.path.join('./', 'f1_*', 's*'))])
|
||||||
|
|
||||||
|
nframe = len(frames)
|
||||||
|
nswath = len(swaths)
|
||||||
|
|
||||||
|
trackReferenceStack = loadTrack('./', dateReferenceStack)
|
||||||
|
|
||||||
|
#mosaic swaths
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
os.chdir(frameDir)
|
||||||
|
|
||||||
|
mosaicDir = 'mosaic'
|
||||||
|
os.makedirs(mosaicDir, exist_ok=True)
|
||||||
|
os.chdir(mosaicDir)
|
||||||
|
|
||||||
|
|
||||||
|
if not (swaths[-1] - swaths[0] >= 1):
|
||||||
|
|
||||||
|
swathDir = 's{}'.format(swaths[0])
|
||||||
|
if not os.path.isfile(interferogram):
|
||||||
|
os.symlink(os.path.join('../', swathDir, interferogram), interferogram)
|
||||||
|
shutil.copy2(os.path.join('../', swathDir, interferogram+'.vrt'), interferogram+'.vrt')
|
||||||
|
shutil.copy2(os.path.join('../', swathDir, interferogram+'.xml'), interferogram+'.xml')
|
||||||
|
if not os.path.isfile(amplitude):
|
||||||
|
os.symlink(os.path.join('../', swathDir, amplitude), amplitude)
|
||||||
|
shutil.copy2(os.path.join('../', swathDir, amplitude+'.vrt'), amplitude+'.vrt')
|
||||||
|
shutil.copy2(os.path.join('../', swathDir, amplitude+'.xml'), amplitude+'.xml')
|
||||||
|
|
||||||
|
os.chdir('../../')
|
||||||
|
|
||||||
|
else:
|
||||||
|
#compute swath offset using reference stack
|
||||||
|
#geometrical offset is enough now
|
||||||
|
offsetReferenceStack = swathOffset(trackReferenceStack.frames[i], dateReferenceStack+'.slc', 'swath_offset_' + dateReferenceStack + '.txt',
|
||||||
|
crossCorrelation=False, numberOfAzimuthLooks=10)
|
||||||
|
#we can faithfully make it integer.
|
||||||
|
#this can also reduce the error due to floating point computation
|
||||||
|
rangeOffsets = [float(round(x)) for x in offsetReferenceStack[0]]
|
||||||
|
azimuthOffsets = [float(round(x)) for x in offsetReferenceStack[1]]
|
||||||
|
|
||||||
|
#list of input files
|
||||||
|
inputInterferograms = []
|
||||||
|
inputAmplitudes = []
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
inputInterferograms.append(os.path.join('../', swathDir, interferogram))
|
||||||
|
inputAmplitudes.append(os.path.join('../', swathDir, amplitude))
|
||||||
|
|
||||||
|
#note that frame parameters do not need to be updated after mosaicking
|
||||||
|
#mosaic amplitudes
|
||||||
|
swathMosaic(trackReferenceStack.frames[i], inputAmplitudes, amplitude,
|
||||||
|
rangeOffsets, azimuthOffsets, numberRangeLooks1, numberAzimuthLooks1, resamplingMethod=0)
|
||||||
|
#mosaic interferograms
|
||||||
|
swathMosaic(trackReferenceStack.frames[i], inputInterferograms, interferogram,
|
||||||
|
rangeOffsets, azimuthOffsets, numberRangeLooks1, numberAzimuthLooks1, resamplingMethod=1)
|
||||||
|
|
||||||
|
create_xml(amplitude, trackReferenceStack.frames[i].numberOfSamples, trackReferenceStack.frames[i].numberOfLines, 'amp')
|
||||||
|
create_xml(interferogram, trackReferenceStack.frames[i].numberOfSamples, trackReferenceStack.frames[i].numberOfLines, 'int')
|
||||||
|
|
||||||
|
os.chdir('../../')
|
||||||
|
|
||||||
|
|
||||||
|
#mosaic frame
|
||||||
|
mosaicDir = 'insar'
|
||||||
|
os.makedirs(mosaicDir, exist_ok=True)
|
||||||
|
os.chdir(mosaicDir)
|
||||||
|
|
||||||
|
if nframe == 1:
|
||||||
|
frameDir = os.path.join('f1_{}/mosaic'.format(frames[0]))
|
||||||
|
if not os.path.isfile(interferogram):
|
||||||
|
os.symlink(os.path.join('../', frameDir, interferogram), interferogram)
|
||||||
|
#shutil.copy2() can overwrite
|
||||||
|
shutil.copy2(os.path.join('../', frameDir, interferogram+'.vrt'), interferogram+'.vrt')
|
||||||
|
shutil.copy2(os.path.join('../', frameDir, interferogram+'.xml'), interferogram+'.xml')
|
||||||
|
if not os.path.isfile(amplitude):
|
||||||
|
os.symlink(os.path.join('../', frameDir, amplitude), amplitude)
|
||||||
|
shutil.copy2(os.path.join('../', frameDir, amplitude+'.vrt'), amplitude+'.vrt')
|
||||||
|
shutil.copy2(os.path.join('../', frameDir, amplitude+'.xml'), amplitude+'.xml')
|
||||||
|
else:
|
||||||
|
if trackReferenceStack.operationMode in scansarModes:
|
||||||
|
matchingMode=0
|
||||||
|
else:
|
||||||
|
matchingMode=1
|
||||||
|
|
||||||
|
#geometrical offset is enough
|
||||||
|
offsetReferenceStack = frameOffset(trackReferenceStack, dateReferenceStack+'.slc', 'frame_offset_' + dateReferenceStack + '.txt',
|
||||||
|
crossCorrelation=False, matchingMode=matchingMode)
|
||||||
|
|
||||||
|
#we can faithfully make it integer.
|
||||||
|
#this can also reduce the error due to floating point computation
|
||||||
|
rangeOffsets = [float(round(x)) for x in offsetReferenceStack[0]]
|
||||||
|
azimuthOffsets = [float(round(x)) for x in offsetReferenceStack[1]]
|
||||||
|
|
||||||
|
#list of input files
|
||||||
|
inputInterferograms = []
|
||||||
|
inputAmplitudes = []
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
inputInterferograms.append(os.path.join('../', frameDir, 'mosaic', interferogram))
|
||||||
|
inputAmplitudes.append(os.path.join('../', frameDir, 'mosaic', amplitude))
|
||||||
|
|
||||||
|
#note that track parameters do not need to be updated after mosaicking
|
||||||
|
#mosaic amplitudes
|
||||||
|
frameMosaic(trackReferenceStack, inputAmplitudes, amplitude,
|
||||||
|
rangeOffsets, azimuthOffsets, numberRangeLooks1, numberAzimuthLooks1,
|
||||||
|
updateTrack=False, phaseCompensation=False, resamplingMethod=0)
|
||||||
|
#mosaic interferograms
|
||||||
|
(phaseDiffEst, phaseDiffUsed, phaseDiffSource, numberOfValidSamples) = \
|
||||||
|
frameMosaic(trackReferenceStack, inputInterferograms, interferogram,
|
||||||
|
rangeOffsets, azimuthOffsets, numberRangeLooks1, numberAzimuthLooks1,
|
||||||
|
updateTrack=False, phaseCompensation=True, resamplingMethod=1)
|
||||||
|
|
||||||
|
create_xml(amplitude, trackReferenceStack.numberOfSamples, trackReferenceStack.numberOfLines, 'amp')
|
||||||
|
create_xml(interferogram, trackReferenceStack.numberOfSamples, trackReferenceStack.numberOfLines, 'int')
|
||||||
|
|
||||||
|
#if multiple frames, remove frame amplitudes/inteferograms to save space
|
||||||
|
for x in inputAmplitudes:
|
||||||
|
os.remove(x)
|
||||||
|
os.remove(x+'.vrt')
|
||||||
|
os.remove(x+'.xml')
|
||||||
|
|
||||||
|
for x in inputInterferograms:
|
||||||
|
os.remove(x)
|
||||||
|
os.remove(x+'.vrt')
|
||||||
|
os.remove(x+'.xml')
|
||||||
|
|
||||||
|
#log output info
|
||||||
|
log = '{} at {}\n'.format(os.path.basename(__file__), datetime.datetime.now())
|
||||||
|
log += '================================================================================================\n'
|
||||||
|
log += 'frame phase diff estimated: {}\n'.format(phaseDiffEst[1:])
|
||||||
|
log += 'frame phase diff used: {}\n'.format(phaseDiffUsed[1:])
|
||||||
|
log += 'frame phase diff used source: {}\n'.format(phaseDiffSource[1:])
|
||||||
|
log += 'frame phase diff samples used: {}\n'.format(numberOfValidSamples[1:])
|
||||||
|
log += '\n'
|
||||||
|
with open(os.path.join('../', logFile), 'a') as f:
|
||||||
|
f.write(log)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,167 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import saveTrack
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='mosaic all swaths and frames to form an entire track')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, nargs='+', default=[],
|
||||||
|
help = 'a number of secondary dates seperated by blanks, can also include ref_date. format: YYMMDD YYMMDD YYMMDD. If provided, only process these dates')
|
||||||
|
parser.add_argument('-ref_frame', dest='ref_frame', type=str, default=None,
|
||||||
|
help = 'frame number of the swath whose grid is used as reference. e.g. 2800. default: first frame')
|
||||||
|
parser.add_argument('-ref_swath', dest='ref_swath', type=int, default=None,
|
||||||
|
help = 'swath number of the swath whose grid is used as reference. e.g. 1. default: first swath')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
frameReference = inps.ref_frame
|
||||||
|
swathReference = inps.ref_swath
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
DEBUG=False
|
||||||
|
|
||||||
|
spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = acquisitionModesAlos2()
|
||||||
|
|
||||||
|
#get date statistics
|
||||||
|
dateDirs, dates, frames, swaths, dateIndexReference = stackDateStatistics(idir, dateReference)
|
||||||
|
ndate = len(dates)
|
||||||
|
nframe = len(frames)
|
||||||
|
nswath = len(swaths)
|
||||||
|
|
||||||
|
#find frame and swath indexes of reference swath
|
||||||
|
if frameReference is None:
|
||||||
|
frameReference = frames[0]
|
||||||
|
if swathReference is None:
|
||||||
|
swathReference = swaths[0]
|
||||||
|
|
||||||
|
|
||||||
|
frameReferenceIndex = frames.index(frameReference)
|
||||||
|
swathReferenceIndex = swaths.index(swathReference)
|
||||||
|
|
||||||
|
print('resampling all frames and swaths to frame: {} (index: {}) swath: {} (index {})'.format(
|
||||||
|
frameReference, frameReferenceIndex, swathReference, swathReferenceIndex))
|
||||||
|
|
||||||
|
|
||||||
|
#mosaic parameters of each date
|
||||||
|
#strictly follow the actual image mosaicking processing of reference (after resampling adjustment in resample_common_grid.py)
|
||||||
|
#secondary sensingStart and startingRange are OK, no need to consider other things about secondary
|
||||||
|
os.chdir(idir)
|
||||||
|
for idate in range(ndate):
|
||||||
|
if dateSecondary != []:
|
||||||
|
if dates[idate] not in dateSecondary:
|
||||||
|
continue
|
||||||
|
|
||||||
|
print('processing: {}'.format(dates[idate]))
|
||||||
|
os.chdir(dates[idate])
|
||||||
|
|
||||||
|
track = loadTrack('./', dates[idate])
|
||||||
|
swathReference = track.frames[frameReferenceIndex].swaths[swathReferenceIndex]
|
||||||
|
#1. mosaic swaths
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
startingRange = []
|
||||||
|
sensingStart = []
|
||||||
|
endingRange = []
|
||||||
|
sensingEnd = []
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
swath = track.frames[i].swaths[j]
|
||||||
|
startingRange.append(swath.startingRange)
|
||||||
|
endingRange.append(swath.startingRange+swath.rangePixelSize*swath.numberOfSamples)
|
||||||
|
sensingStart.append(swath.sensingStart)
|
||||||
|
sensingEnd.append(swath.sensingStart+datetime.timedelta(seconds=swath.azimuthLineInterval*swath.numberOfLines))
|
||||||
|
|
||||||
|
#update frame parameters
|
||||||
|
#########################################################
|
||||||
|
frame = track.frames[i]
|
||||||
|
#mosaic size
|
||||||
|
frame.numberOfSamples = int(round((max(endingRange)-min(startingRange))/swathReference.rangePixelSize) / numberRangeLooks1)
|
||||||
|
frame.numberOfLines = int(round((max(sensingEnd)-min(sensingStart)).total_seconds()/swathReference.azimuthLineInterval) / numberAzimuthLooks1)
|
||||||
|
#NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
|
||||||
|
#range parameters
|
||||||
|
frame.startingRange = min(startingRange)
|
||||||
|
frame.rangeSamplingRate = swathReference.rangeSamplingRate
|
||||||
|
frame.rangePixelSize = swathReference.rangePixelSize
|
||||||
|
#azimuth parameters
|
||||||
|
frame.sensingStart = min(sensingStart)
|
||||||
|
frame.prf = swathReference.prf
|
||||||
|
frame.azimuthPixelSize = swathReference.azimuthPixelSize
|
||||||
|
frame.azimuthLineInterval = swathReference.azimuthLineInterval
|
||||||
|
|
||||||
|
|
||||||
|
#2. mosaic frames
|
||||||
|
startingRange = []
|
||||||
|
sensingStart = []
|
||||||
|
endingRange = []
|
||||||
|
sensingEnd = []
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
frame = track.frames[i]
|
||||||
|
startingRange.append(frame.startingRange)
|
||||||
|
endingRange.append(frame.startingRange+numberRangeLooks1*frame.rangePixelSize*frame.numberOfSamples)
|
||||||
|
sensingStart.append(frame.sensingStart)
|
||||||
|
sensingEnd.append(frame.sensingStart+datetime.timedelta(seconds=numberAzimuthLooks1*frame.azimuthLineInterval*frame.numberOfLines))
|
||||||
|
|
||||||
|
|
||||||
|
#update track parameters
|
||||||
|
#########################################################
|
||||||
|
#mosaic size
|
||||||
|
track.numberOfSamples = round((max(endingRange)-min(startingRange))/(numberRangeLooks1*swathReference.rangePixelSize))
|
||||||
|
track.numberOfLines = round((max(sensingEnd)-min(sensingStart)).total_seconds()/(numberAzimuthLooks1*swathReference.azimuthLineInterval))
|
||||||
|
#NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
|
||||||
|
#range parameters
|
||||||
|
track.startingRange = min(startingRange)
|
||||||
|
track.rangeSamplingRate = swathReference.rangeSamplingRate
|
||||||
|
track.rangePixelSize = swathReference.rangePixelSize
|
||||||
|
#azimuth parameters
|
||||||
|
track.sensingStart = min(sensingStart)
|
||||||
|
track.prf = swathReference.prf
|
||||||
|
track.azimuthPixelSize = swathReference.azimuthPixelSize
|
||||||
|
track.azimuthLineInterval = swathReference.azimuthLineInterval
|
||||||
|
|
||||||
|
#save mosaicking result
|
||||||
|
saveTrack(track, dates[idate])
|
||||||
|
os.chdir('../')
|
||||||
|
|
@ -0,0 +1,195 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='create InSAR pairs')
|
||||||
|
parser.add_argument('-idir1', dest='idir1', type=str, required=True,
|
||||||
|
help = 'input directory where original data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-idir2', dest='idir2', type=str, required=True,
|
||||||
|
help = 'input directory where resampled data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-xml', dest='xml', type=str, default=None,
|
||||||
|
help = 'alos2App.py input xml file, e.g. alos2App.xml. default: None')
|
||||||
|
parser.add_argument('-odir', dest='odir', type=str, required=True,
|
||||||
|
help = 'output directory')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date. format: YYMMDD')
|
||||||
|
parser.add_argument('-pairs', dest='pairs', type=str, nargs='+', default=None,
|
||||||
|
help = 'a number of pairs seperated by blanks. format: YYMMDD-YYMMDD YYMMDD-YYMMDD YYMMDD-YYMMDD... This argument has highest priority. When provided, only process these pairs')
|
||||||
|
parser.add_argument('-num', dest='num', type=int, default=None,
|
||||||
|
help = 'number of subsequent acquistions for each acquistion to pair up with. default: all pairs')
|
||||||
|
parser.add_argument('-exc_date', dest='exc_date', type=str, nargs='+', default=None,
|
||||||
|
help = 'a number of secondary dates seperated by blanks, can also include ref_date. format: YYMMDD YYMMDD YYMMDD. If provided, these dates will be excluded from pairing up')
|
||||||
|
parser.add_argument('-tsmin', dest='tsmin', type=float, default=None,
|
||||||
|
help = 'minimum time span in years for pairing up. default: None')
|
||||||
|
parser.add_argument('-tsmax', dest='tsmax', type=float, default=None,
|
||||||
|
help = 'maximum time span in years for pairing up. default: None')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir1 = inps.idir1
|
||||||
|
idir2 = inps.idir2
|
||||||
|
alos2AppXml = inps.xml
|
||||||
|
odir = inps.odir
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
pairsUser = inps.pairs
|
||||||
|
subsequentNum = inps.num
|
||||||
|
dateExcluded = inps.exc_date
|
||||||
|
tsmin = inps.tsmin
|
||||||
|
tsmax = inps.tsmax
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
DEBUG=False
|
||||||
|
|
||||||
|
spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = acquisitionModesAlos2()
|
||||||
|
|
||||||
|
#get date statistics, using resampled version
|
||||||
|
dateDirs, dates, frames, swaths, dateIndexReference = stackDateStatistics(idir2, dateReference)
|
||||||
|
ndate = len(dates)
|
||||||
|
nframe = len(frames)
|
||||||
|
nswath = len(swaths)
|
||||||
|
|
||||||
|
if subsequentNum is None:
|
||||||
|
subsequentNum = ndate - 1
|
||||||
|
|
||||||
|
#read standard configurations
|
||||||
|
if alos2AppXml is not None:
|
||||||
|
tree = ET.parse(alos2AppXml)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
datefmt = "%y%m%d"
|
||||||
|
pairsCreated = []
|
||||||
|
for i in range(ndate):
|
||||||
|
mdate = dates[i]
|
||||||
|
mtime = datetime.datetime.strptime(mdate, datefmt)
|
||||||
|
for j in range(subsequentNum):
|
||||||
|
if i+j+1 <= ndate - 1:
|
||||||
|
sdate = dates[i+j+1]
|
||||||
|
stime = datetime.datetime.strptime(sdate, datefmt)
|
||||||
|
pair = mdate + '-' + sdate
|
||||||
|
ts = np.absolute((stime - mtime).total_seconds()) / (365.0 * 24.0 * 3600)
|
||||||
|
|
||||||
|
#1. determine whether process this pair
|
||||||
|
if pairsUser is not None:
|
||||||
|
if pair not in pairsUser:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if dateExcluded is not None:
|
||||||
|
if (mdate in dateExcluded) or (sdate in dateExcluded):
|
||||||
|
continue
|
||||||
|
if tsmin is not None:
|
||||||
|
if ts < tsmin:
|
||||||
|
continue
|
||||||
|
if tsmax is not None:
|
||||||
|
if ts > tsmax:
|
||||||
|
continue
|
||||||
|
|
||||||
|
#2. create pair dir
|
||||||
|
pairsCreated.append(pair)
|
||||||
|
print('creating pair: {}'.format(pair))
|
||||||
|
pairDir = os.path.join(odir, pair)
|
||||||
|
os.makedirs(pairDir, exist_ok=True)
|
||||||
|
#create xml
|
||||||
|
if alos2AppXml is not None:
|
||||||
|
safe = root.find("component/property[@name='reference directory']")
|
||||||
|
#safe.text = '{}'.format(os.path.join(inps.dir, mdate))
|
||||||
|
safe.text = 'None'
|
||||||
|
safe = root.find("component/property[@name='secondary directory']")
|
||||||
|
#safe.text = '{}'.format(os.path.join(inps.dir, sdate))
|
||||||
|
safe.text = 'None'
|
||||||
|
tree.write(os.path.join(pairDir, 'alos2App.xml'))
|
||||||
|
|
||||||
|
#3. make frame/swath directories, and copy *.track.xml and *.frame.xml
|
||||||
|
if mdate != dates[dateIndexReference]:
|
||||||
|
shutil.copy2(os.path.join(idir1, mdate, mdate+'.track.xml'), pairDir)
|
||||||
|
if sdate != dates[dateIndexReference]:
|
||||||
|
shutil.copy2(os.path.join(idir1, sdate, sdate+'.track.xml'), pairDir)
|
||||||
|
shutil.copy2(os.path.join(idir2, dates[dateIndexReference], dates[dateIndexReference]+'.track.xml'), pairDir)
|
||||||
|
|
||||||
|
for iframe, frameNumber in enumerate(frames):
|
||||||
|
frameDir = 'f{}_{}'.format(iframe+1, frameNumber)
|
||||||
|
os.makedirs(os.path.join(pairDir, frameDir), exist_ok=True)
|
||||||
|
|
||||||
|
if mdate != dates[dateIndexReference]:
|
||||||
|
shutil.copy2(os.path.join(idir1, mdate, frameDir, mdate+'.frame.xml'), os.path.join(pairDir, frameDir))
|
||||||
|
if sdate != dates[dateIndexReference]:
|
||||||
|
shutil.copy2(os.path.join(idir1, sdate, frameDir, sdate+'.frame.xml'), os.path.join(pairDir, frameDir))
|
||||||
|
shutil.copy2(os.path.join(idir2, dates[dateIndexReference], frameDir, dates[dateIndexReference]+'.frame.xml'), os.path.join(pairDir, frameDir))
|
||||||
|
|
||||||
|
for jswath, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
os.makedirs(os.path.join(pairDir, frameDir, swathDir), exist_ok=True)
|
||||||
|
|
||||||
|
if os.path.isfile(os.path.join(pairDir, frameDir, swathDir, mdate+'.slc')):
|
||||||
|
os.remove(os.path.join(pairDir, frameDir, swathDir, mdate+'.slc'))
|
||||||
|
relpath = os.path.relpath(os.path.join(idir2, mdate, frameDir, swathDir), os.path.join(pairDir, frameDir, swathDir))
|
||||||
|
os.symlink(os.path.join(relpath, mdate+'.slc'), os.path.join(pairDir, frameDir, swathDir, mdate+'.slc'))
|
||||||
|
#os.symlink(os.path.join(idir2, mdate, frameDir, swathDir, mdate+'.slc'), os.path.join(pairDir, frameDir, swathDir, mdate+'.slc'))
|
||||||
|
shutil.copy2(os.path.join(idir2, mdate, frameDir, swathDir, mdate+'.slc.vrt'), os.path.join(pairDir, frameDir, swathDir))
|
||||||
|
shutil.copy2(os.path.join(idir2, mdate, frameDir, swathDir, mdate+'.slc.xml'), os.path.join(pairDir, frameDir, swathDir))
|
||||||
|
|
||||||
|
if os.path.isfile(os.path.join(pairDir, frameDir, swathDir, sdate+'.slc')):
|
||||||
|
os.remove(os.path.join(pairDir, frameDir, swathDir, sdate+'.slc'))
|
||||||
|
relpath = os.path.relpath(os.path.join(idir2, sdate, frameDir, swathDir), os.path.join(pairDir, frameDir, swathDir))
|
||||||
|
os.symlink(os.path.join(relpath, sdate+'.slc'), os.path.join(pairDir, frameDir, swathDir, sdate+'.slc'))
|
||||||
|
#os.symlink(os.path.join(idir2, sdate, frameDir, swathDir, sdate+'.slc'), os.path.join(pairDir, frameDir, swathDir, sdate+'.slc'))
|
||||||
|
shutil.copy2(os.path.join(idir2, sdate, frameDir, swathDir, sdate+'.slc.vrt'), os.path.join(pairDir, frameDir, swathDir))
|
||||||
|
shutil.copy2(os.path.join(idir2, sdate, frameDir, swathDir, sdate+'.slc.xml'), os.path.join(pairDir, frameDir, swathDir))
|
||||||
|
|
||||||
|
|
||||||
|
print('total number of pairs created: {}'.format(len(pairsCreated)))
|
||||||
|
if pairsUser is not None:
|
||||||
|
if sorted(pairsUser) != sorted(pairsCreated):
|
||||||
|
print()
|
||||||
|
print('WARNING: user has specified pairs to process, but pairs created are different from user specified pairs')
|
||||||
|
print(' user specified pairs: {}'.format(', '.join(pairsUser)))
|
||||||
|
print(' pairs created: {}'.format(', '.join(pairsCreated)))
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#Cunren Liang, JPL/Caltech, 28-NOV-2016
|
||||||
|
|
||||||
|
#https://matplotlib.org/3.1.1/gallery/text_labels_and_annotations/date.html
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import argparse
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.dates as mdates
|
||||||
|
|
||||||
|
|
||||||
|
def read_alosstack_baseline(baseline_file):
|
||||||
|
'''read baseline file generated by alosStack
|
||||||
|
'''
|
||||||
|
baseline_dict = {}
|
||||||
|
with open(baseline_file, 'r') as f:
|
||||||
|
lines = [line for line in f if line.strip() != '']
|
||||||
|
for x in lines[2:]:
|
||||||
|
blist = x.split()
|
||||||
|
#to fit into the format of other processors, all alos satellites are after 2000
|
||||||
|
#blist[0] = '20' + blist[0]
|
||||||
|
#blist[1] = '20' + blist[1]
|
||||||
|
baseline_dict[blist[1]] = float(blist[3])
|
||||||
|
baseline_dict[blist[0]] = 0
|
||||||
|
|
||||||
|
return baseline_dict
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
Command line parser.
|
||||||
|
'''
|
||||||
|
parser = argparse.ArgumentParser(description='plot baselines')
|
||||||
|
parser.add_argument('-baseline', dest='baseline', type=str, required=True,
|
||||||
|
help = 'baseline file')
|
||||||
|
parser.add_argument('-pairs_dir', dest='pairs_dir', type=str, required=True,
|
||||||
|
help = 'pairs directory containing YYMMDD-YYMMDD folders. Only folders are recognized.')
|
||||||
|
parser.add_argument('-pairs_exc', dest='pairs_exc', type=str, nargs='+', default=None,
|
||||||
|
help = 'a number of pairs seperated by blanks. format: YYMMDD-YYMMDD YYMMDD-YYMMDD... If provided, these pairs will be excluded from plotting')
|
||||||
|
parser.add_argument('-output', dest='output', type=str, default='baseline.pdf',
|
||||||
|
help = 'output file name')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
baseline = inps.baseline
|
||||||
|
pairs_dir = inps.pairs_dir
|
||||||
|
pairs_exc = inps.pairs_exc
|
||||||
|
output = inps.output
|
||||||
|
|
||||||
|
baseline_dict = read_alosstack_baseline(baseline)
|
||||||
|
pairs = [os.path.basename(x) for x in sorted(glob.glob(os.path.join(pairs_dir, '*-*'))) if os.path.isdir(x)]
|
||||||
|
if pairs_exc != None:
|
||||||
|
for x in pairs_exc:
|
||||||
|
if x in pairs:
|
||||||
|
pairs.remove(x)
|
||||||
|
|
||||||
|
#start plot
|
||||||
|
plt.rcParams['font.family'] = 'Times New Roman'
|
||||||
|
plt.rcParams['font.size'] = 12
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
|
||||||
|
time = [datetime.datetime.strptime(x, "%y%m%d") for x in baseline_dict]
|
||||||
|
baseline = [baseline_dict[x] for x in baseline_dict]
|
||||||
|
ax.plot(time, baseline, 'o', alpha=0.7, c='g')
|
||||||
|
|
||||||
|
year_min = datetime.datetime(min(time).year, 1, 1)
|
||||||
|
year_max = datetime.datetime(max(time).year+1, 1, 1)
|
||||||
|
|
||||||
|
for x in pairs:
|
||||||
|
rdate, sdate = x.split('-')
|
||||||
|
rtime = datetime.datetime.strptime(rdate, "%y%m%d")
|
||||||
|
stime = datetime.datetime.strptime(sdate, "%y%m%d")
|
||||||
|
time = [rtime, stime]
|
||||||
|
baseline = [baseline_dict[rdate], baseline_dict[sdate]]
|
||||||
|
ax.plot(time, baseline, '-', lw=.5, c='b')
|
||||||
|
|
||||||
|
ax.xaxis.set_major_locator(mdates.YearLocator())
|
||||||
|
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))
|
||||||
|
ax.xaxis.set_minor_locator(mdates.MonthLocator())
|
||||||
|
|
||||||
|
ax.minorticks_on()
|
||||||
|
ax.tick_params('both', length=7, which='major', width=1)
|
||||||
|
ax.tick_params('both', length=4, which='minor', width=0.5)
|
||||||
|
ax.set_xlim(year_min, year_max)
|
||||||
|
|
||||||
|
ax.format_xdata = mdates.DateFormatter('%Y-%m-%d')
|
||||||
|
|
||||||
|
# rotates and right aligns the x labels, and moves the bottom of the
|
||||||
|
# axes up to make room for them
|
||||||
|
#fig.autofmt_xdate()
|
||||||
|
|
||||||
|
|
||||||
|
ax.set_xlabel('Time [years]')
|
||||||
|
ax.set_ylabel('Perpendicular Baseline [meters]')
|
||||||
|
|
||||||
|
|
||||||
|
plt.savefig(os.path.splitext(output)[0]+'.pdf')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.runRdrDemOffset import rdrDemOffset
|
||||||
|
|
||||||
|
from StackPulic import loadProduct
|
||||||
|
from StackPulic import createObject
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='estimate offset between radar and dem')
|
||||||
|
parser.add_argument('-track', dest='track', type=str, required=True,
|
||||||
|
help = 'track parameter file')
|
||||||
|
parser.add_argument('-dem', dest='dem', type=str, required=True,
|
||||||
|
help = 'dem used for geometrical coregistration')
|
||||||
|
parser.add_argument('-wbd', dest='wbd', type=str, required=True,
|
||||||
|
help = 'water body in radar coordinate')
|
||||||
|
parser.add_argument('-hgt', dest='hgt', type=str, required=True,
|
||||||
|
help = 'height in radar coordinate computed in geometrical coregistration')
|
||||||
|
parser.add_argument('-amp', dest='amp', type=str, required=True,
|
||||||
|
help = 'amplitude image')
|
||||||
|
parser.add_argument('-output', dest='output', type=str, required=True,
|
||||||
|
help = 'output file for saving the affine transformation paramters')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
parser.add_argument('-nrlks_sim', dest='nrlks_sim', type=int, default=None,
|
||||||
|
help = 'number of range looks when simulating radar image')
|
||||||
|
parser.add_argument('-nalks_sim', dest='nalks_sim', type=int, default=None,
|
||||||
|
help = 'number of azimuth looks when simulating radar image')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
trackParameter = inps.track
|
||||||
|
demFile = inps.dem
|
||||||
|
wbdOut = inps.wbd
|
||||||
|
height = inps.hgt
|
||||||
|
amplitude = inps.amp
|
||||||
|
output = inps.output
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
numberRangeLooksSim = inps.nrlks_sim
|
||||||
|
numberAzimuthLooksSim = inps.nalks_sim
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
#prepare amplitude image
|
||||||
|
insarDir = 'insar'
|
||||||
|
os.makedirs(insarDir, exist_ok=True)
|
||||||
|
os.chdir(insarDir)
|
||||||
|
if not os.path.isfile(os.path.basename(amplitude)):
|
||||||
|
os.symlink(os.path.join('../', amplitude), os.path.basename(amplitude))
|
||||||
|
if not os.path.isfile(os.path.basename(amplitude)+'.vrt'):
|
||||||
|
os.symlink(os.path.join('../', amplitude)+'.vrt', os.path.basename(amplitude)+'.vrt')
|
||||||
|
if not os.path.isfile(os.path.basename(amplitude)+'.xml'):
|
||||||
|
os.symlink(os.path.join('../', amplitude)+'.xml', os.path.basename(amplitude)+'.xml')
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
simFile = 'radar_{}.sim'.format(ml1)
|
||||||
|
|
||||||
|
self = createObject()
|
||||||
|
self._insar = createObject()
|
||||||
|
|
||||||
|
self._insar.dem = demFile
|
||||||
|
self._insar.numberRangeLooksSim = numberRangeLooksSim
|
||||||
|
self._insar.numberRangeLooks1 = numberRangeLooks1
|
||||||
|
self._insar.numberAzimuthLooksSim = numberAzimuthLooksSim
|
||||||
|
self._insar.numberAzimuthLooks1 = numberAzimuthLooks1
|
||||||
|
self._insar.height = os.path.basename(height)
|
||||||
|
self._insar.sim = simFile
|
||||||
|
self._insar.amplitude = os.path.basename(amplitude)
|
||||||
|
self._insar.wbdOut = os.path.basename(wbdOut)
|
||||||
|
self._insar.radarDemAffineTransform = None
|
||||||
|
|
||||||
|
referenceTrack = loadProduct(trackParameter)
|
||||||
|
rdrDemOffset(self, referenceTrack, catalog=None)
|
||||||
|
|
||||||
|
os.chdir(insarDir)
|
||||||
|
#save the result
|
||||||
|
with open(output, 'w') as f:
|
||||||
|
f.write('{} {}\n{}'.format(self._insar.numberRangeLooksSim, self._insar.numberAzimuthLooksSim, self._insar.radarDemAffineTransform))
|
||||||
|
|
||||||
|
#remove amplitude image
|
||||||
|
os.remove(os.path.basename(amplitude))
|
||||||
|
os.remove(os.path.basename(amplitude)+'.vrt')
|
||||||
|
os.remove(os.path.basename(amplitude)+'.xml')
|
||||||
|
os.chdir('../')
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar
|
||||||
|
from isceobj.Alos2Proc.runRdr2Geo import topoCPU
|
||||||
|
from isceobj.Alos2Proc.runRdr2Geo import topoGPU
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import hasGPU
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='compute longitude, latitude, height and water body from radar parameters')
|
||||||
|
parser.add_argument('-date', dest='date', type=str, required=True,
|
||||||
|
help = 'date. format: YYMMDD')
|
||||||
|
parser.add_argument('-dem', dest='dem', type=str, required=True,
|
||||||
|
help = 'dem file')
|
||||||
|
parser.add_argument('-wbd', dest='wbd', type=str, required=True,
|
||||||
|
help = 'water body file')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
#parser.add_argument('-gpu', dest='gpu', type=int, default=1,
|
||||||
|
# help = 'use GPU when available. 0: no. 1: yes (default)')
|
||||||
|
parser.add_argument('-gpu', dest='gpu', action='store_true', default=False,
|
||||||
|
help='use GPU when available')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
date = inps.date
|
||||||
|
demFile = inps.dem
|
||||||
|
wbdFile = inps.wbd
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
useGPU = inps.gpu
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
demFile = os.path.abspath(demFile)
|
||||||
|
wbdFile = os.path.abspath(wbdFile)
|
||||||
|
|
||||||
|
insarDir = 'insar'
|
||||||
|
os.makedirs(insarDir, exist_ok=True)
|
||||||
|
os.chdir(insarDir)
|
||||||
|
|
||||||
|
ml1 = '_{}rlks_{}alks'.format(numberRangeLooks1, numberAzimuthLooks1)
|
||||||
|
|
||||||
|
latitude = date + ml1 + '.lat'
|
||||||
|
longitude = date + ml1 + '.lon'
|
||||||
|
height = date + ml1 + '.hgt'
|
||||||
|
los = date + ml1 + '.los'
|
||||||
|
wbdOut = date + ml1 + '.wbd'
|
||||||
|
|
||||||
|
|
||||||
|
track = loadTrack('../', date)
|
||||||
|
if useGPU and hasGPU():
|
||||||
|
topoGPU(track, numberRangeLooks1, numberAzimuthLooks1, demFile,
|
||||||
|
latitude, longitude, height, los)
|
||||||
|
else:
|
||||||
|
snwe = topoCPU(track, numberRangeLooks1, numberAzimuthLooks1, demFile,
|
||||||
|
latitude, longitude, height, los)
|
||||||
|
waterBodyRadar(latitude, longitude, wbdFile, wbdOut)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,301 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
import isceobj.Sensor.MultiMode as MultiMode
|
||||||
|
|
||||||
|
from StackPulic import saveProduct
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
|
||||||
|
|
||||||
|
def getAlos2StackDirs(dataDir):
|
||||||
|
'''
|
||||||
|
1. this function takes the data directory containing a list of folders, in each of
|
||||||
|
which data of a date is located, and then returns a list of date directory sorted
|
||||||
|
by acquisition date.
|
||||||
|
|
||||||
|
2. under dataDir, only folders are recognized
|
||||||
|
'''
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
|
||||||
|
def sorter(item):
|
||||||
|
#return date
|
||||||
|
return item.split('-')[-2]
|
||||||
|
|
||||||
|
#get only folders in dataDir
|
||||||
|
dateDirs = sorted(glob.glob(os.path.join(dataDir, '*')))
|
||||||
|
dateDirs = [x for x in dateDirs if os.path.isdir(x)]
|
||||||
|
ndate = len(dateDirs)
|
||||||
|
|
||||||
|
#get first LED files in dateDirs
|
||||||
|
dateFirstleaderFiles = [sorted(glob.glob(os.path.join(x, 'LED-ALOS2*-*-*')))[0] for x in dateDirs]
|
||||||
|
#sort first LED files using date in LED file name
|
||||||
|
dateFirstleaderFiles = sorted(dateFirstleaderFiles, key=sorter)
|
||||||
|
#keep only directory from the path
|
||||||
|
dateDirs = [os.path.dirname(x) for x in dateFirstleaderFiles]
|
||||||
|
|
||||||
|
return dateDirs
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='read a number of dates of data')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where data of each date is located. only folders are recognized')
|
||||||
|
parser.add_argument('-odir', dest='odir', type=str, required=True,
|
||||||
|
help = 'output directory where data of each date is output')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, nargs='+', default=[],
|
||||||
|
help = 'a number of secondary dates seperated by blanks, can also include reference date. format: YYMMDD YYMMDD YYMMDD. If provided, only read data of these dates')
|
||||||
|
parser.add_argument('-pol', dest='pol', type=str, default='HH',
|
||||||
|
help = 'polarization to process, default: HH')
|
||||||
|
parser.add_argument('-frames', dest='frames', type=str, nargs='+', default=None,
|
||||||
|
help = 'frames to process, must specify frame numbers of reference if frames are different among dates. e.g. -frames 2800 2850')
|
||||||
|
parser.add_argument('-starting_swath', dest='starting_swath', type=int, default=None,
|
||||||
|
help = 'starting swath to process.')
|
||||||
|
parser.add_argument('-ending_swath', dest='ending_swath', type=int, default=None,
|
||||||
|
help = 'starting swath to process')
|
||||||
|
parser.add_argument('-virtual', dest='virtual', action='store_true', default=False,
|
||||||
|
help='use virtual file')
|
||||||
|
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
odir = inps.odir
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
pol = inps.pol
|
||||||
|
framesInput = inps.frames
|
||||||
|
startingSwath = inps.starting_swath
|
||||||
|
endingSwath = inps.ending_swath
|
||||||
|
useVirtualFile = inps.virtual
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
|
||||||
|
#date directories sorted by acquistion date retrieved from filenames under each directory
|
||||||
|
dateDirs = getAlos2StackDirs(os.path.abspath(idir))
|
||||||
|
ndate = len(dateDirs)
|
||||||
|
|
||||||
|
if framesInput is not None:
|
||||||
|
framesInput = sorted(framesInput)
|
||||||
|
else:
|
||||||
|
framesInput = None
|
||||||
|
|
||||||
|
|
||||||
|
#1. find index of reference date:
|
||||||
|
dates = []
|
||||||
|
dateIndexReference = None
|
||||||
|
for i in range(ndate):
|
||||||
|
ledFiles = sorted(glob.glob(os.path.join(dateDirs[i], 'LED-ALOS2*-*-*')))
|
||||||
|
date = os.path.basename(ledFiles[0]).split('-')[-2]
|
||||||
|
dates.append(date)
|
||||||
|
if date == dateReference:
|
||||||
|
dateIndexReference = i
|
||||||
|
if dateIndexReference is None:
|
||||||
|
raise Exception('cannot get reference date {} from the data list, pleasae check your input'.format(dateReference))
|
||||||
|
|
||||||
|
|
||||||
|
#2. check if data are in the same mode
|
||||||
|
spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = acquisitionModesAlos2()
|
||||||
|
|
||||||
|
#first frame of reference date
|
||||||
|
ledFilesReference = sorted(glob.glob(os.path.join(dateDirs[dateIndexReference], 'LED-ALOS2*-*-*')))
|
||||||
|
modeReference = os.path.basename(ledFilesReference[0]).split('-')[-1][0:3]
|
||||||
|
|
||||||
|
if modeReference in spotlightModes:
|
||||||
|
modeGroupReference = spotlightModes
|
||||||
|
if modeReference in stripmapModes:
|
||||||
|
modeGroupReference = stripmapModes
|
||||||
|
if modeReference in scansarNominalModes:
|
||||||
|
modeGroupReference = scansarNominalModes
|
||||||
|
if modeReference in scansarWideModes:
|
||||||
|
modeGroupReference = scansarWideModes
|
||||||
|
|
||||||
|
#check aquistion mode of all frames of each date
|
||||||
|
for i in range(ndate):
|
||||||
|
ledFiles = sorted(glob.glob(os.path.join(dateDirs[i], 'LED-ALOS2*-*-*')))
|
||||||
|
nframe = len(ledFiles)
|
||||||
|
for j in range(nframe):
|
||||||
|
mode = os.path.basename(ledFiles[j]).split('-')[-1][0:3]
|
||||||
|
if mode not in modeGroupReference:
|
||||||
|
raise Exception('all data must be in the same acquistion mode: spotlight, stripmap, or ScanSAR mode')
|
||||||
|
|
||||||
|
|
||||||
|
#3. find frame numbers and save it in a 2-d list
|
||||||
|
frames = []
|
||||||
|
#if not set, find frames automatically
|
||||||
|
if framesInput is None:
|
||||||
|
for i in range(ndate):
|
||||||
|
frames0 = []
|
||||||
|
ledFiles = sorted(glob.glob(os.path.join(dateDirs[i], 'LED-ALOS2*-*-*')))
|
||||||
|
for led in ledFiles:
|
||||||
|
frames0.append( os.path.basename(led).split('-')[-3][-4:] )
|
||||||
|
frames.append(sorted(frames0))
|
||||||
|
else:
|
||||||
|
for i in range(ndate):
|
||||||
|
frames.append(framesInput)
|
||||||
|
|
||||||
|
framesReference = frames[dateIndexReference]
|
||||||
|
|
||||||
|
#check if there is equal number of frames
|
||||||
|
nframe = len(frames[dateIndexReference])
|
||||||
|
for i in range(ndate):
|
||||||
|
if nframe != len(frames[i]):
|
||||||
|
raise Exception('there are not equal number of frames to process, please check your directory of each date')
|
||||||
|
|
||||||
|
|
||||||
|
#4. set starting and ending swaths
|
||||||
|
if modeReference in spotlightModes:
|
||||||
|
if startingSwath is None:
|
||||||
|
startingSwath = 1
|
||||||
|
if endingSwath is None:
|
||||||
|
endingSwath = 1
|
||||||
|
if modeReference in stripmapModes:
|
||||||
|
if startingSwath is None:
|
||||||
|
startingSwath = 1
|
||||||
|
if endingSwath is None:
|
||||||
|
endingSwath = 1
|
||||||
|
if modeReference in scansarNominalModes:
|
||||||
|
if startingSwath is None:
|
||||||
|
startingSwath = 1
|
||||||
|
if endingSwath is None:
|
||||||
|
endingSwath = 5
|
||||||
|
if modeReference in scansarWideModes:
|
||||||
|
if startingSwath is None:
|
||||||
|
startingSwath = 1
|
||||||
|
if endingSwath is None:
|
||||||
|
endingSwath = 7
|
||||||
|
|
||||||
|
#print result
|
||||||
|
print('\nlist of dates:')
|
||||||
|
print(' index date frames')
|
||||||
|
print('=======================================================')
|
||||||
|
for i in range(ndate):
|
||||||
|
if dates[i] == dateReference:
|
||||||
|
print(' %03d %s'%(i, dates[i])+' {}'.format(frames[i])+' reference')
|
||||||
|
else:
|
||||||
|
print(' %03d %s'%(i, dates[i])+' {}'.format(frames[i]))
|
||||||
|
print('\n')
|
||||||
|
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
#1. create directories and read data
|
||||||
|
##################################################
|
||||||
|
if not os.path.isdir(odir):
|
||||||
|
print('output directory {} does not exist, create'.format(odir))
|
||||||
|
os.makedirs(odir, exist_ok=True)
|
||||||
|
|
||||||
|
os.chdir(odir)
|
||||||
|
for i in range(ndate):
|
||||||
|
ledFiles = sorted(glob.glob(os.path.join(dateDirs[i], 'LED-ALOS2*-*-*')))
|
||||||
|
date = os.path.basename(ledFiles[0]).split('-')[-2]
|
||||||
|
dateDir = date
|
||||||
|
|
||||||
|
if dateSecondary != []:
|
||||||
|
if date not in dateSecondary:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if os.path.isdir(dateDir):
|
||||||
|
print('{} already exists, do not create'.format(dateDir))
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
os.makedirs(dateDir, exist_ok=True)
|
||||||
|
os.chdir(dateDir)
|
||||||
|
|
||||||
|
sensor = MultiMode.createSensor(sensor='ALOS2', name=None)
|
||||||
|
sensor.configure()
|
||||||
|
sensor.track.configure()
|
||||||
|
|
||||||
|
for j in range(nframe):
|
||||||
|
#frame number starts with 1
|
||||||
|
frameDir = 'f{}_{}'.format(j+1, framesReference[j])
|
||||||
|
os.makedirs(frameDir, exist_ok=True)
|
||||||
|
os.chdir(frameDir)
|
||||||
|
|
||||||
|
#attach a frame to reference and secondary
|
||||||
|
frameObj = MultiMode.createFrame()
|
||||||
|
frameObj.configure()
|
||||||
|
sensor.track.frames.append(frameObj)
|
||||||
|
|
||||||
|
#swath number starts with 1
|
||||||
|
for k in range(startingSwath, endingSwath+1):
|
||||||
|
print('processing date {} frame {} swath {}'.format(date, framesReference[j], k))
|
||||||
|
|
||||||
|
swathDir = 's{}'.format(k)
|
||||||
|
os.makedirs(swathDir, exist_ok=True)
|
||||||
|
os.chdir(swathDir)
|
||||||
|
|
||||||
|
#attach a swath to sensor
|
||||||
|
swathObj = MultiMode.createSwath()
|
||||||
|
swathObj.configure()
|
||||||
|
sensor.track.frames[-1].swaths.append(swathObj)
|
||||||
|
|
||||||
|
#setup sensor
|
||||||
|
#sensor.leaderFile = sorted(glob.glob(os.path.join(dateDirs[i], 'LED-ALOS2*{}-*-*'.format(framesReference[j]))))[0]
|
||||||
|
sensor.leaderFile = sorted(glob.glob(os.path.join(dateDirs[i], 'LED-ALOS2*{}-*-*'.format(frames[i][j]))))[0]
|
||||||
|
if modeReference in scansarModes:
|
||||||
|
#sensor.imageFile = sorted(glob.glob(os.path.join(dateDirs[i], 'IMG-{}-ALOS2*{}-*-*-F{}'.format(pol.upper(), framesReference[j], k))))[0]
|
||||||
|
sensor.imageFile = sorted(glob.glob(os.path.join(dateDirs[i], 'IMG-{}-ALOS2*{}-*-*-F{}'.format(pol.upper(), frames[i][j], k))))[0]
|
||||||
|
else:
|
||||||
|
#sensor.imageFile = sorted(glob.glob(os.path.join(dateDirs[i], 'IMG-{}-ALOS2*{}-*-*'.format(pol.upper(), framesReference[j]))))[0]
|
||||||
|
sensor.imageFile = sorted(glob.glob(os.path.join(dateDirs[i], 'IMG-{}-ALOS2*{}-*-*'.format(pol.upper(), frames[i][j]))))[0]
|
||||||
|
sensor.outputFile = date + '.slc'
|
||||||
|
sensor.useVirtualFile = useVirtualFile
|
||||||
|
#read sensor
|
||||||
|
(imageFDR, imageData)=sensor.readImage()
|
||||||
|
(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord)=sensor.readLeader()
|
||||||
|
sensor.setSwath(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
|
||||||
|
sensor.setFrame(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
|
||||||
|
sensor.setTrack(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
|
||||||
|
os.chdir('../')
|
||||||
|
#!!!frame numbers of all dates are reset to those of reference date
|
||||||
|
sensor.track.frames[j].frameNumber = framesReference[j]
|
||||||
|
saveProduct(sensor.track.frames[-1], date + '.frame.xml')
|
||||||
|
os.chdir('../')
|
||||||
|
saveProduct(sensor.track, date + '.track.xml')
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from contrib.alos2proc_f.alos2proc_f import rect_with_looks
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
|
||||||
|
from StackPulic import createObject
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='rectify range offset')
|
||||||
|
parser.add_argument('-aff', dest='aff', type=str, required=True,
|
||||||
|
help = 'affine transform paramter file')
|
||||||
|
parser.add_argument('-input', dest='input', type=str, default='./',
|
||||||
|
help = 'input file')
|
||||||
|
parser.add_argument('-output', dest='output', type=str, required=True,
|
||||||
|
help = 'output file')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1 . default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
aff = inps.aff
|
||||||
|
rangeOffset = inps.input
|
||||||
|
rectRangeOffset = inps.output
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
DEBUG=False
|
||||||
|
|
||||||
|
self = createObject()
|
||||||
|
self._insar = createObject()
|
||||||
|
|
||||||
|
self._insar.rangeOffset = rangeOffset
|
||||||
|
self._insar.rectRangeOffset = rectRangeOffset
|
||||||
|
self._insar.numberRangeLooks1 = numberRangeLooks1
|
||||||
|
self._insar.numberAzimuthLooks1 = numberAzimuthLooks1
|
||||||
|
|
||||||
|
#read affine transform parameters
|
||||||
|
with open(aff, 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
self._insar.numberRangeLooksSim = int(lines[0].split()[0])
|
||||||
|
self._insar.numberAzimuthLooksSim = int(lines[0].split()[1])
|
||||||
|
self._insar.radarDemAffineTransform = [float(x) for x in lines[1].strip('[').strip(']').split(',')]
|
||||||
|
if DEBUG:
|
||||||
|
print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
|
||||||
|
print('{} {}\n{}'.format(self._insar.numberRangeLooksSim, self._insar.numberAzimuthLooksSim, self._insar.radarDemAffineTransform))
|
||||||
|
print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
|
||||||
|
|
||||||
|
#rectify
|
||||||
|
rgoff = isceobj.createImage()
|
||||||
|
rgoff.load(self._insar.rangeOffset+'.xml')
|
||||||
|
|
||||||
|
if self._insar.radarDemAffineTransform == [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]:
|
||||||
|
if not os.path.isfile(self._insar.rectRangeOffset):
|
||||||
|
os.symlink(self._insar.rangeOffset, self._insar.rectRangeOffset)
|
||||||
|
create_xml(self._insar.rectRangeOffset, rgoff.width, rgoff.length, 'float')
|
||||||
|
else:
|
||||||
|
rect_with_looks(self._insar.rangeOffset,
|
||||||
|
self._insar.rectRangeOffset,
|
||||||
|
rgoff.width, rgoff.length,
|
||||||
|
rgoff.width, rgoff.length,
|
||||||
|
self._insar.radarDemAffineTransform[0], self._insar.radarDemAffineTransform[1],
|
||||||
|
self._insar.radarDemAffineTransform[2], self._insar.radarDemAffineTransform[3],
|
||||||
|
self._insar.radarDemAffineTransform[4], self._insar.radarDemAffineTransform[5],
|
||||||
|
self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1,
|
||||||
|
self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1,
|
||||||
|
'REAL',
|
||||||
|
'Bilinear')
|
||||||
|
create_xml(self._insar.rectRangeOffset, rgoff.width, rgoff.length, 'float')
|
||||||
|
|
||||||
|
|
@ -0,0 +1,500 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import isce, isceobj, stdproc
|
||||||
|
from isceobj.Util.Poly2D import Poly2D
|
||||||
|
from isceobj.Location.Offset import OffsetField, Offset
|
||||||
|
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import readOffset
|
||||||
|
from isceobj.Alos2Proc.runSwathOffset import swathOffset
|
||||||
|
|
||||||
|
from contrib.alos2proc.alos2proc import rg_filter
|
||||||
|
|
||||||
|
from StackPulic import loadTrack
|
||||||
|
from StackPulic import saveTrack
|
||||||
|
from StackPulic import subbandParameters
|
||||||
|
from StackPulic import stackDateStatistics
|
||||||
|
from StackPulic import acquisitionModesAlos2
|
||||||
|
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='resample data to a common grid')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-odir', dest='odir', type=str, required=True,
|
||||||
|
help = 'output directory where resampled version of each date is output')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, nargs='+', default=[],
|
||||||
|
help = 'a number of secondary dates seperated by blanks, can also include ref_date. format: YYMMDD YYMMDD YYMMDD. If provided, only resample these dates')
|
||||||
|
parser.add_argument('-ref_frame', dest='ref_frame', type=str, default=None,
|
||||||
|
help = 'frame number of the swath whose grid is used as reference. e.g. 2800. default: first frame')
|
||||||
|
parser.add_argument('-ref_swath', dest='ref_swath', type=int, default=None,
|
||||||
|
help = 'swath number of the swath whose grid is used as reference. e.g. 1. default: first swath')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'range offsets between swaths/frames should be integer multiples of -nrlks1. default: 1 ')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=14,
|
||||||
|
help = 'azimuth offsets between swaths/frames should be integer multiples of -nalks1. default: 14')
|
||||||
|
parser.add_argument('-subband', dest='subband', action='store_true', default=False,
|
||||||
|
help='create and resample subband SLCs')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
odir = inps.odir
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
frameReference = inps.ref_frame
|
||||||
|
swathReference = inps.ref_swath
|
||||||
|
nRange = inps.nrlks1
|
||||||
|
nAzimuth = inps.nalks1
|
||||||
|
subbandFlag = inps.subband
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
DEBUG=False
|
||||||
|
|
||||||
|
spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = acquisitionModesAlos2()
|
||||||
|
|
||||||
|
#get date statistics
|
||||||
|
dateDirs, dates, frames, swaths, dateIndexReference = stackDateStatistics(idir, dateReference)
|
||||||
|
ndate = len(dates)
|
||||||
|
nframe = len(frames)
|
||||||
|
nswath = len(swaths)
|
||||||
|
|
||||||
|
if frameReference is None:
|
||||||
|
frameReference = frames[0]
|
||||||
|
else:
|
||||||
|
if frameReference not in frames:
|
||||||
|
raise Exception('specified -ref_frame {} not in frame list {}'.format(frameReference, frames))
|
||||||
|
if swathReference is None:
|
||||||
|
swathReference = swaths[0]
|
||||||
|
else:
|
||||||
|
if swathReference not in swaths:
|
||||||
|
raise Exception('specified -ref_swath {} not in swath list {}'.format(swathReference, swaths))
|
||||||
|
|
||||||
|
#find frame and swath indexes of reference swath
|
||||||
|
frameReferenceIndex = frames.index(frameReference)
|
||||||
|
swathReferenceIndex = swaths.index(swathReference)
|
||||||
|
|
||||||
|
print('resampling all frames and swaths to frame: {} (index: {}) swath: {} (index {})'.format(
|
||||||
|
frameReference, frameReferenceIndex, swathReference, swathReferenceIndex))
|
||||||
|
|
||||||
|
|
||||||
|
#read swath offsets and save in 2-d lists
|
||||||
|
swathRangeOffsetGeometrical = []
|
||||||
|
swathAzimuthOffsetGeometrical = []
|
||||||
|
swathRangeOffsetMatching = []
|
||||||
|
swathAzimuthOffsetMatching = []
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
|
||||||
|
swathRangeOffsetGeometrical0 = []
|
||||||
|
swathAzimuthOffsetGeometrical0 = []
|
||||||
|
swathRangeOffsetMatching0 = []
|
||||||
|
swathAzimuthOffsetMatching0 = []
|
||||||
|
|
||||||
|
if nswath >= 2:
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
with open(os.path.join(idir, dateReference, frameDir, 'mosaic/swath_offset.txt'), 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
for linex in lines:
|
||||||
|
if 'range offset' in linex:
|
||||||
|
swathRangeOffsetGeometrical0.append(float(linex.split()[3]))
|
||||||
|
swathRangeOffsetMatching0.append(float(linex.split()[4]))
|
||||||
|
if 'azimuth offset' in linex:
|
||||||
|
swathAzimuthOffsetGeometrical0.append(float(linex.split()[3]))
|
||||||
|
swathAzimuthOffsetMatching0.append(float(linex.split()[4]))
|
||||||
|
else:
|
||||||
|
swathRangeOffsetGeometrical0.append(0.0)
|
||||||
|
swathRangeOffsetMatching0.append(0.0)
|
||||||
|
swathAzimuthOffsetGeometrical0.append(0.0)
|
||||||
|
swathAzimuthOffsetMatching0.append(0.0)
|
||||||
|
|
||||||
|
swathRangeOffsetGeometrical.append(swathRangeOffsetGeometrical0)
|
||||||
|
swathAzimuthOffsetGeometrical.append(swathAzimuthOffsetGeometrical0)
|
||||||
|
swathRangeOffsetMatching.append(swathRangeOffsetMatching0)
|
||||||
|
swathAzimuthOffsetMatching.append(swathAzimuthOffsetMatching0)
|
||||||
|
|
||||||
|
|
||||||
|
#read frame offsets and save in 1-d list
|
||||||
|
frameRangeOffsetGeometrical = []
|
||||||
|
frameAzimuthOffsetGeometrical = []
|
||||||
|
frameRangeOffsetMatching = []
|
||||||
|
frameAzimuthOffsetMatching = []
|
||||||
|
|
||||||
|
if nframe >= 2:
|
||||||
|
with open(os.path.join(idir, dateReference, 'insar/frame_offset.txt'), 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
for linex in lines:
|
||||||
|
if 'range offset' in linex:
|
||||||
|
frameRangeOffsetGeometrical.append(float(linex.split()[3]))
|
||||||
|
frameRangeOffsetMatching.append(float(linex.split()[4]))
|
||||||
|
if 'azimuth offset' in linex:
|
||||||
|
frameAzimuthOffsetGeometrical.append(float(linex.split()[3]))
|
||||||
|
frameAzimuthOffsetMatching.append(float(linex.split()[4]))
|
||||||
|
else:
|
||||||
|
frameRangeOffsetGeometrical.append(0.0)
|
||||||
|
frameRangeOffsetMatching.append(0.0)
|
||||||
|
frameAzimuthOffsetGeometrical.append(0.0)
|
||||||
|
frameAzimuthOffsetMatching.append(0.0)
|
||||||
|
|
||||||
|
|
||||||
|
#compute accurate starting range and sensing start using offset file for reference date
|
||||||
|
#swath offset is computed between adjacent swaths within a frame, offset unit: first swath sample size
|
||||||
|
#frame offset is computed between first swaths of adjacent frames, offset unit: first swath sample size
|
||||||
|
startingRangeAll = [[None for j in range(nswath)] for i in range(nframe)]
|
||||||
|
sensingStartAll = [[None for j in range(nswath)] for i in range(nframe)]
|
||||||
|
|
||||||
|
trackReference = loadTrack(dateDirs[dateIndexReference], dates[dateIndexReference])
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
#startingRange and sensingStart of first swath of current frame
|
||||||
|
# for i1 in range(i+1):
|
||||||
|
# startingRangeFirst = trackReference.frames[0].swaths[0].startingRange - \
|
||||||
|
# frameRangeOffsetMatching[i1] * trackReference.frames[0].swaths[0].rangePixelSize
|
||||||
|
# sensingStartFirst = trackReference.frames[0].swaths[0].sensingStart - \
|
||||||
|
# datetime.timedelta(seconds = frameAzimuthOffsetMatching[i1] * trackReference.frames[0].swaths[0].azimuthLineInterval)
|
||||||
|
|
||||||
|
startingRangeFirst = trackReference.frames[0].swaths[0].startingRange - \
|
||||||
|
sum(frameRangeOffsetMatching[0:i+1]) * trackReference.frames[0].swaths[0].rangePixelSize
|
||||||
|
sensingStartFirst = trackReference.frames[0].swaths[0].sensingStart - \
|
||||||
|
datetime.timedelta(seconds = sum(frameAzimuthOffsetMatching[0:i+1]) * trackReference.frames[0].swaths[0].azimuthLineInterval)
|
||||||
|
|
||||||
|
#startingRange and sensingStart of each swath of current frame
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
# for j1 in range(j+1):
|
||||||
|
# startingRangeAll[i][j] = startingRangeFirst - \
|
||||||
|
# swathRangeOffsetMatching[i][j1] * trackReference.frames[i].swaths[0].rangePixelSize
|
||||||
|
# sensingStartAll[i][j] = sensingStartFirst - \
|
||||||
|
# datetime.timedelta(seconds = swathAzimuthOffsetMatching[i][j1] * trackReference.frames[i].swaths[0].azimuthLineInterval)
|
||||||
|
|
||||||
|
startingRangeAll[i][j] = startingRangeFirst - \
|
||||||
|
sum(swathRangeOffsetMatching[i][0:j+1]) * trackReference.frames[i].swaths[0].rangePixelSize
|
||||||
|
sensingStartAll[i][j] = sensingStartFirst - \
|
||||||
|
datetime.timedelta(seconds = sum(swathAzimuthOffsetMatching[i][0:j+1]) * trackReference.frames[i].swaths[0].azimuthLineInterval)
|
||||||
|
|
||||||
|
#check computation result
|
||||||
|
if DEBUG:
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
print(i, j, (trackReference.frames[i].swaths[j].startingRange-startingRangeAll[i][j])/trackReference.frames[0].swaths[0].rangePixelSize,
|
||||||
|
(trackReference.frames[i].swaths[j].sensingStart-sensingStartAll[i][j]).total_seconds()/trackReference.frames[0].swaths[0].azimuthLineInterval)
|
||||||
|
|
||||||
|
#update startingRange and sensingStart of reference track
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
trackReference.frames[i].swaths[j].startingRange = startingRangeAll[i][j]
|
||||||
|
trackReference.frames[i].swaths[j].sensingStart = sensingStartAll[i][j]
|
||||||
|
|
||||||
|
|
||||||
|
##find minimum startingRange and sensingStart
|
||||||
|
startingRangeMinimum = trackReference.frames[0].swaths[0].startingRange
|
||||||
|
sensingStartMinimum = trackReference.frames[0].swaths[0].sensingStart
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
if trackReference.frames[i].swaths[j].startingRange < startingRangeMinimum:
|
||||||
|
startingRangeMinimum = trackReference.frames[i].swaths[j].startingRange
|
||||||
|
if trackReference.frames[i].swaths[j].sensingStart < sensingStartMinimum:
|
||||||
|
sensingStartMinimum = trackReference.frames[i].swaths[j].sensingStart
|
||||||
|
print('startingRangeMinimum (m): {}'.format(startingRangeMinimum))
|
||||||
|
print('sensingStartMinimum: {}'.format(sensingStartMinimum))
|
||||||
|
|
||||||
|
|
||||||
|
#adjust each swath of each frame to minimum startingRange and sensingStart
|
||||||
|
#load reference track again for saving track parameters of resampled
|
||||||
|
trackReferenceResampled = loadTrack(dateDirs[dateIndexReference], dates[dateIndexReference])
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
#current swath
|
||||||
|
swathReference = trackReference.frames[i].swaths[j]
|
||||||
|
#swath of reference sample size
|
||||||
|
swathReferenceReference = trackReference.frames[frameReferenceIndex].swaths[swathReferenceIndex]
|
||||||
|
#current swath resampled
|
||||||
|
swathReferenceResampled = trackReferenceResampled.frames[i].swaths[j]
|
||||||
|
|
||||||
|
#update startingRange and sensingStart
|
||||||
|
offsetRange = (swathReference.startingRange - startingRangeMinimum) / (swathReferenceReference.rangePixelSize*nRange)
|
||||||
|
offsetAzimuth = (swathReference.sensingStart - sensingStartMinimum).total_seconds() / (swathReferenceReference.azimuthLineInterval*nAzimuth)
|
||||||
|
|
||||||
|
swathReferenceResampled.startingRange = startingRangeMinimum + round(offsetRange) * (swathReferenceReference.rangePixelSize*nRange)
|
||||||
|
swathReferenceResampled.sensingStart = sensingStartMinimum + datetime.timedelta(seconds = round(offsetAzimuth) *
|
||||||
|
(swathReferenceReference.azimuthLineInterval*nAzimuth))
|
||||||
|
|
||||||
|
#update other parameters
|
||||||
|
swathReferenceResampled.numberOfSamples = round(swathReference.numberOfSamples * swathReference.rangePixelSize / swathReferenceReference.rangePixelSize)
|
||||||
|
swathReferenceResampled.numberOfLines = round(swathReference.numberOfLines * swathReference.azimuthLineInterval / swathReferenceReference.azimuthLineInterval)
|
||||||
|
swathReferenceResampled.rangeSamplingRate = swathReferenceReference.rangeSamplingRate
|
||||||
|
swathReferenceResampled.rangePixelSize = swathReferenceReference.rangePixelSize
|
||||||
|
swathReferenceResampled.prf = swathReferenceReference.prf
|
||||||
|
swathReferenceResampled.azimuthPixelSize = swathReferenceReference.azimuthPixelSize
|
||||||
|
swathReferenceResampled.azimuthLineInterval = swathReferenceReference.azimuthLineInterval
|
||||||
|
#should also update dopplerVsPixel, azimuthFmrateVsPixel?
|
||||||
|
#if hasattr(swathReference, 'burstLength'):
|
||||||
|
if swathReference.burstLength is not None:
|
||||||
|
swathReferenceResampled.burstLength *= (swathReference.burstLength * swathReference.azimuthLineInterval / swathReferenceReference.azimuthLineInterval)
|
||||||
|
#if hasattr(swathReference, 'burstCycleLength'):
|
||||||
|
if swathReference.burstCycleLength is not None:
|
||||||
|
swathReferenceResampled.burstCycleLength *= (swathReference.burstCycleLength * swathReference.azimuthLineInterval / swathReferenceReference.azimuthLineInterval)
|
||||||
|
#no need to update parameters for ScanSAR burst-by-burst processing, since we are not doing such burst-by-burst processing.
|
||||||
|
|
||||||
|
|
||||||
|
#resample each date
|
||||||
|
os.makedirs(odir, exist_ok=True)
|
||||||
|
os.chdir(odir)
|
||||||
|
for idate in range(ndate):
|
||||||
|
if dateSecondary != []:
|
||||||
|
if dates[idate] not in dateSecondary:
|
||||||
|
continue
|
||||||
|
|
||||||
|
os.makedirs(dates[idate], exist_ok=True)
|
||||||
|
os.chdir(dates[idate])
|
||||||
|
|
||||||
|
trackSecondary = loadTrack(dateDirs[idate], dates[idate])
|
||||||
|
for i, frameNumber in enumerate(frames):
|
||||||
|
frameDir = 'f{}_{}'.format(i+1, frameNumber)
|
||||||
|
os.makedirs(frameDir, exist_ok=True)
|
||||||
|
os.chdir(frameDir)
|
||||||
|
for j, swathNumber in enumerate(range(swaths[0], swaths[-1] + 1)):
|
||||||
|
swathDir = 's{}'.format(swathNumber)
|
||||||
|
os.makedirs(swathDir, exist_ok=True)
|
||||||
|
os.chdir(swathDir)
|
||||||
|
|
||||||
|
#current swath
|
||||||
|
swathReference = trackReference.frames[i].swaths[j]
|
||||||
|
#swath of reference sample size
|
||||||
|
swathReferenceReference = trackReference.frames[frameReferenceIndex].swaths[swathReferenceIndex]
|
||||||
|
#current swath resampled
|
||||||
|
swathReferenceResampled = trackReferenceResampled.frames[i].swaths[j]
|
||||||
|
|
||||||
|
#current swath to be resampled
|
||||||
|
swathSecondary = trackSecondary.frames[i].swaths[j]
|
||||||
|
|
||||||
|
|
||||||
|
#current slc to be processed
|
||||||
|
slc = os.path.join(dateDirs[idate], frameDir, swathDir, dates[idate]+'.slc')
|
||||||
|
|
||||||
|
|
||||||
|
#0. create subband SLCs
|
||||||
|
if subbandFlag:
|
||||||
|
subbandRadarWavelength, subbandBandWidth, subbandFrequencyCenter, subbandPrefix = subbandParameters(trackReference)
|
||||||
|
|
||||||
|
slcLower = dates[idate]+'_{}_tmp.slc'.format(subbandPrefix[0])
|
||||||
|
slcUpper = dates[idate]+'_{}_tmp.slc'.format(subbandPrefix[1])
|
||||||
|
rg_filter(slc, 2,
|
||||||
|
[slcLower, slcUpper],
|
||||||
|
subbandBandWidth,
|
||||||
|
subbandFrequencyCenter,
|
||||||
|
257, 2048, 0.1, 0, 0.0)
|
||||||
|
slcList = [slc, slcLower, slcUpper]
|
||||||
|
slcListResampled = [dates[idate]+'.slc', dates[idate]+'_{}.slc'.format(subbandPrefix[0]), dates[idate]+'_{}.slc'.format(subbandPrefix[1])]
|
||||||
|
slcListRemoved = [slcLower, slcUpper]
|
||||||
|
else:
|
||||||
|
slcList = [slc]
|
||||||
|
slcListResampled = [dates[idate]+'.slc']
|
||||||
|
slcListRemoved = []
|
||||||
|
|
||||||
|
|
||||||
|
#1. compute offset polynomial
|
||||||
|
if idate == dateIndexReference:
|
||||||
|
rangePoly = Poly2D()
|
||||||
|
rangePoly.initPoly(rangeOrder=1,azimuthOrder=0,coeffs=[[
|
||||||
|
(swathReferenceResampled.startingRange - swathReference.startingRange) / swathReference.rangePixelSize,
|
||||||
|
swathReferenceResampled.rangePixelSize / swathReference.rangePixelSize - 1.0]])
|
||||||
|
|
||||||
|
azimuthPoly = Poly2D()
|
||||||
|
azimuthPoly.initPoly(rangeOrder=0,azimuthOrder=1,coeffs=[
|
||||||
|
[(swathReferenceResampled.sensingStart - swathReference.sensingStart).total_seconds() / swathReference.azimuthLineInterval],
|
||||||
|
[swathReferenceResampled.azimuthLineInterval / swathReference.azimuthLineInterval - 1.0]])
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
print()
|
||||||
|
print('rangePoly.getCoeffs(): {}'.format(rangePoly.getCoeffs()))
|
||||||
|
print('azimuthPoly.getCoeffs(): {}'.format(azimuthPoly.getCoeffs()))
|
||||||
|
print('rangePoly._meanRange: {}'.format(rangePoly._meanRange))
|
||||||
|
print('rangePoly._normRange: {}'.format(rangePoly._normRange))
|
||||||
|
print('rangePoly._meanAzimuth: {}'.format(rangePoly._meanAzimuth))
|
||||||
|
print('rangePoly._normAzimuth: {}'.format(rangePoly._normAzimuth))
|
||||||
|
print('azimuthPoly._meanRange: {}'.format(azimuthPoly._meanRange))
|
||||||
|
print('azimuthPoly._normRange: {}'.format(azimuthPoly._normRange))
|
||||||
|
print('azimuthPoly._meanAzimuth: {}'.format(azimuthPoly._meanAzimuth))
|
||||||
|
print('azimuthPoly._normAzimuth: {}'.format(azimuthPoly._normAzimuth))
|
||||||
|
print()
|
||||||
|
|
||||||
|
else:
|
||||||
|
offsets = readOffset(os.path.join(dateDirs[idate], frameDir, swathDir, 'cull.off'))
|
||||||
|
# x1 x2 x3
|
||||||
|
# y1 y2 y3
|
||||||
|
#create new offset field to save offsets: swathReferenceResampled --> swathReference --> swathSecondary
|
||||||
|
offsetsUpdated = OffsetField()
|
||||||
|
|
||||||
|
for offset in offsets:
|
||||||
|
offsetUpdate = Offset()
|
||||||
|
|
||||||
|
x1 = offset.x * swathReference.rangePixelSize / swathReferenceResampled.rangePixelSize + \
|
||||||
|
(swathReference.startingRange - swathReferenceResampled.startingRange) / swathReferenceResampled.rangePixelSize
|
||||||
|
y1 = offset.y * swathReference.azimuthLineInterval / swathReferenceResampled.azimuthLineInterval + \
|
||||||
|
(swathReference.sensingStart - swathReferenceResampled.sensingStart).total_seconds() / swathReferenceResampled.azimuthLineInterval
|
||||||
|
|
||||||
|
x3 = offset.x + offset.dx
|
||||||
|
y3 = offset.y + offset.dy
|
||||||
|
|
||||||
|
dx = x3 - x1
|
||||||
|
dy = y3 - y1
|
||||||
|
|
||||||
|
offsetUpdate.setCoordinate(x1, y1)
|
||||||
|
offsetUpdate.setOffset(dx, dy)
|
||||||
|
offsetUpdate.setSignalToNoise(offset.snr)
|
||||||
|
offsetUpdate.setCovariance(offset.sigmax, offset.sigmay, offset.sigmaxy)
|
||||||
|
offsetsUpdated.addOffset(offsetUpdate)
|
||||||
|
|
||||||
|
azimuthPoly, rangePoly = offsetsUpdated.getFitPolynomials(rangeOrder=2,azimuthOrder=2,maxOrder=True, usenumpy=False)
|
||||||
|
|
||||||
|
#check polynomial accuracy
|
||||||
|
if DEBUG:
|
||||||
|
print()
|
||||||
|
print(' x y dx dy dx(poly) dy(poly) dx - dx(poly) dy - dy(poly)')
|
||||||
|
print('==============================================================================================================')
|
||||||
|
for offset in offsetsUpdated:
|
||||||
|
print('%11.3f %11.3f %11.3f %11.3f %11.3f %11.3f %11.3f %11.3f'%(offset.x, offset.y,
|
||||||
|
offset.dx, offset.dy,
|
||||||
|
rangePoly(offset.y, offset.x), azimuthPoly(offset.y, offset.x),
|
||||||
|
offset.dx - rangePoly(offset.y, offset.x), offset.dy - azimuthPoly(offset.y, offset.x)))
|
||||||
|
print()
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
print()
|
||||||
|
print('rangePoly.getCoeffs(): {}'.format(rangePoly.getCoeffs()))
|
||||||
|
print('azimuthPoly.getCoeffs(): {}'.format(azimuthPoly.getCoeffs()))
|
||||||
|
print('rangePoly._meanRange: {}'.format(rangePoly._meanRange))
|
||||||
|
print('rangePoly._normRange: {}'.format(rangePoly._normRange))
|
||||||
|
print('rangePoly._meanAzimuth: {}'.format(rangePoly._meanAzimuth))
|
||||||
|
print('rangePoly._normAzimuth: {}'.format(rangePoly._normAzimuth))
|
||||||
|
print('azimuthPoly._meanRange: {}'.format(azimuthPoly._meanRange))
|
||||||
|
print('azimuthPoly._normRange: {}'.format(azimuthPoly._normRange))
|
||||||
|
print('azimuthPoly._meanAzimuth: {}'.format(azimuthPoly._meanAzimuth))
|
||||||
|
print('azimuthPoly._normAzimuth: {}'.format(azimuthPoly._normAzimuth))
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
#2. carrier phase
|
||||||
|
dpoly = Poly2D()
|
||||||
|
order = len(swathSecondary.dopplerVsPixel) - 1
|
||||||
|
coeffs = [2*np.pi*val*swathSecondary.azimuthLineInterval for val in swathSecondary.dopplerVsPixel]
|
||||||
|
dpoly.initPoly(rangeOrder=order, azimuthOrder=0)
|
||||||
|
dpoly.setCoeffs([coeffs])
|
||||||
|
|
||||||
|
#azCarrPoly = Poly2D()
|
||||||
|
#azCarrPoly.initPoly(rangeOrder=0,azimuthOrder=0,coeffs=[[0.]])
|
||||||
|
|
||||||
|
|
||||||
|
#3. resample images
|
||||||
|
#checked: offset computation results using azimuthPoly/rangePoly and in resamp_slc.f90
|
||||||
|
#checked: no flattenning
|
||||||
|
#checked: no reading of range and azimuth images
|
||||||
|
#checked: range/azimuth carrier values: 0, 0
|
||||||
|
#checked: doppler no problem
|
||||||
|
# but doppler is computed using reference's coordinate in:
|
||||||
|
# isce/components/stdproc/stdproc/resamp_slc/src/resamp_slc.f90
|
||||||
|
# I have fixed it.
|
||||||
|
|
||||||
|
|
||||||
|
for slcInput, slcOutput in zip(slcList, slcListResampled):
|
||||||
|
inimg = isceobj.createSlcImage()
|
||||||
|
inimg.load(slcInput + '.xml')
|
||||||
|
inimg.filename = slcInput
|
||||||
|
inimg.extraFilename = slcInput+'.vrt'
|
||||||
|
inimg.setAccessMode('READ')
|
||||||
|
|
||||||
|
rObj = stdproc.createResamp_slc()
|
||||||
|
#the following two items are actually not used, since we are not flattenning?
|
||||||
|
#but need to set these otherwise the program complains
|
||||||
|
rObj.slantRangePixelSpacing = swathSecondary.rangePixelSize
|
||||||
|
rObj.radarWavelength = trackSecondary.radarWavelength
|
||||||
|
#rObj.azimuthCarrierPoly = azCarrPoly
|
||||||
|
rObj.dopplerPoly = dpoly
|
||||||
|
|
||||||
|
rObj.azimuthOffsetsPoly = azimuthPoly
|
||||||
|
rObj.rangeOffsetsPoly = rangePoly
|
||||||
|
rObj.imageIn = inimg
|
||||||
|
|
||||||
|
####Setting reference values
|
||||||
|
#the following four items are actually not used, since we are not flattenning?
|
||||||
|
#but need to set these otherwise the program complains
|
||||||
|
rObj.startingRange = swathSecondary.startingRange
|
||||||
|
rObj.referenceSlantRangePixelSpacing = swathReferenceResampled.rangePixelSize
|
||||||
|
rObj.referenceStartingRange = swathReferenceResampled.startingRange
|
||||||
|
rObj.referenceWavelength = trackReferenceResampled.radarWavelength
|
||||||
|
|
||||||
|
|
||||||
|
width = swathReferenceResampled.numberOfSamples
|
||||||
|
length = swathReferenceResampled.numberOfLines
|
||||||
|
imgOut = isceobj.createSlcImage()
|
||||||
|
imgOut.setWidth(width)
|
||||||
|
imgOut.filename = slcOutput
|
||||||
|
imgOut.setAccessMode('write')
|
||||||
|
|
||||||
|
rObj.outputWidth = width
|
||||||
|
rObj.outputLines = length
|
||||||
|
#rObj.residualRangeImage = rngImg
|
||||||
|
#rObj.residualAzimuthImage = aziImg
|
||||||
|
|
||||||
|
rObj.resamp_slc(imageOut=imgOut)
|
||||||
|
|
||||||
|
imgOut.renderHdr()
|
||||||
|
|
||||||
|
for x in slcListRemoved:
|
||||||
|
os.remove(x)
|
||||||
|
os.remove(x + '.vrt')
|
||||||
|
os.remove(x + '.xml')
|
||||||
|
|
||||||
|
os.chdir('../')
|
||||||
|
os.chdir('../')
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
|
||||||
|
#dump resampled reference paramter files, only do this when reference is resampled
|
||||||
|
dumpFlag = True
|
||||||
|
if dateSecondary != []:
|
||||||
|
if dates[dateIndexReference] not in dateSecondary:
|
||||||
|
dumpFlag = False
|
||||||
|
if dumpFlag:
|
||||||
|
#we are still in directory 'odir'
|
||||||
|
os.chdir(dates[dateIndexReference])
|
||||||
|
saveTrack(trackReferenceResampled, dates[dateIndexReference])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Author: Cunren Liang
|
||||||
|
# Copyright 2015-present, NASA-JPL/Caltech
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import datetime
|
||||||
|
import numpy as np
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import isce, isceobj
|
||||||
|
from isceobj.Alos2Proc.runUnwrapSnaphu import unwrapSnaphu
|
||||||
|
|
||||||
|
from StackPulic import createObject
|
||||||
|
from StackPulic import loadProduct
|
||||||
|
|
||||||
|
def cmdLineParse():
|
||||||
|
'''
|
||||||
|
command line parser.
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='take more looks and compute coherence')
|
||||||
|
parser.add_argument('-idir', dest='idir', type=str, required=True,
|
||||||
|
help = 'input directory where resampled data of each date (YYMMDD) is located. only folders are recognized')
|
||||||
|
parser.add_argument('-ref_date_stack', dest='ref_date_stack', type=str, required=True,
|
||||||
|
help = 'reference date of stack. format: YYMMDD')
|
||||||
|
parser.add_argument('-ref_date', dest='ref_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-sec_date', dest='sec_date', type=str, required=True,
|
||||||
|
help = 'reference date of this pair. format: YYMMDD')
|
||||||
|
parser.add_argument('-nrlks1', dest='nrlks1', type=int, default=1,
|
||||||
|
help = 'number of range looks 1. default: 1')
|
||||||
|
parser.add_argument('-nalks1', dest='nalks1', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 1. default: 1')
|
||||||
|
parser.add_argument('-nrlks2', dest='nrlks2', type=int, default=1,
|
||||||
|
help = 'number of range looks 2. default: 1')
|
||||||
|
parser.add_argument('-nalks2', dest='nalks2', type=int, default=1,
|
||||||
|
help = 'number of azimuth looks 2. default: 1')
|
||||||
|
parser.add_argument('-wbd_msk', dest='wbd_msk', action='store_true', default=False,
|
||||||
|
help='mask unwrapped interferogram with water body')
|
||||||
|
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print('')
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
inps = cmdLineParse()
|
||||||
|
|
||||||
|
|
||||||
|
#get user parameters from input
|
||||||
|
idir = inps.idir
|
||||||
|
dateReferenceStack = inps.ref_date_stack
|
||||||
|
dateReference = inps.ref_date
|
||||||
|
dateSecondary = inps.sec_date
|
||||||
|
numberRangeLooks1 = inps.nrlks1
|
||||||
|
numberAzimuthLooks1 = inps.nalks1
|
||||||
|
numberRangeLooks2 = inps.nrlks2
|
||||||
|
numberAzimuthLooks2 = inps.nalks2
|
||||||
|
waterBodyMaskStartingStep = inps.wbd_msk
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
pair = '{}-{}'.format(dateReference, dateSecondary)
|
||||||
|
ms = pair
|
||||||
|
ml2 = '_{}rlks_{}alks'.format(numberRangeLooks1*numberRangeLooks2, numberAzimuthLooks1*numberAzimuthLooks2)
|
||||||
|
|
||||||
|
self = createObject()
|
||||||
|
self._insar = createObject()
|
||||||
|
|
||||||
|
self._insar.filteredInterferogram = 'filt_' + ms + ml2 + '.int'
|
||||||
|
self._insar.multilookAmplitude = ms + ml2 + '.amp'
|
||||||
|
self._insar.multilookPhsig = ms + ml2 + '.phsig'
|
||||||
|
self._insar.unwrappedInterferogram = 'filt_' + ms + ml2 + '.unw'
|
||||||
|
self._insar.unwrappedMaskedInterferogram = 'filt_' + ms + ml2 + '_msk.unw'
|
||||||
|
self._insar.multilookWbdOut = os.path.join('../', idir, dateReferenceStack, 'insar', dateReferenceStack + ml2 + '.wbd')
|
||||||
|
|
||||||
|
self._insar.numberRangeLooks1 = numberRangeLooks1
|
||||||
|
self._insar.numberAzimuthLooks1 = numberAzimuthLooks1
|
||||||
|
self._insar.numberRangeLooks2 = numberRangeLooks2
|
||||||
|
self._insar.numberAzimuthLooks2 = numberAzimuthLooks2
|
||||||
|
|
||||||
|
if waterBodyMaskStartingStep:
|
||||||
|
self.waterBodyMaskStartingStep='unwrap'
|
||||||
|
else:
|
||||||
|
self.waterBodyMaskStartingStep=None
|
||||||
|
|
||||||
|
trackReference = loadProduct('{}.track.xml'.format(dateReference))
|
||||||
|
unwrapSnaphu(self, trackReference)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,7 +30,12 @@
|
||||||
<property name="water body">/net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd</property>
|
<property name="water body">/net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd</property>
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
See also comments of parameters "number of range looks ion" and "number of azimuth looks ion"
|
||||||
|
below to set a smaller number of looks to avoid phase aliasing in some areas (such as edges of
|
||||||
|
Tibetan Plateau, where there might be strong tropospheric variations due to large height
|
||||||
|
differences).
|
||||||
|
==========================================================================================-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -133,6 +138,10 @@ IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-450
|
||||||
<!--<property name="water body">None</property>-->
|
<!--<property name="water body">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
if only dense offset is needed, do InSAR can be set to False to skip InSAR steps.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="do InSAR">True</property>-->
|
||||||
<!--<property name="use virtual file">True</property>-->
|
<!--<property name="use virtual file">True</property>-->
|
||||||
<!--<property name="use GPU">False</property>-->
|
<!--<property name="use GPU">False</property>-->
|
||||||
|
|
||||||
|
|
@ -169,6 +178,45 @@ IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-450
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--============================================================================================================================================
|
||||||
|
Instructions on number of looks used by the software
|
||||||
|
The software first takes number of range/azimuth looks 1, and then take any other number of range/azimuth looks (2, sim and ion).
|
||||||
|
|
||||||
|
Here are the purposes of these number of looks. Usually there is no need to set number of range/azimuth looks sim (automatically set), so it is
|
||||||
|
not explained here.
|
||||||
|
|
||||||
|
number of range/azimuth looks 1: save space, remove speckle noise, equalize sample size, match original resolution (full-aperture)
|
||||||
|
number of range/azimuth looks 2: make interferogram not too small or large
|
||||||
|
number of range/azimuth looks ion: make interferogram for ionosphere estimation not too small or large, facilitate ionosphere filtering
|
||||||
|
|
||||||
|
total number of looks of InSAR processing is: number of range/azimuth looks 1 * number of range/azimuth looks 2
|
||||||
|
total number of looks in ionosphere estimation is: number of range/azimuth looks 1 * number of range/azimuth looks ion
|
||||||
|
total number of looks in radar/DEM matching is: number of range/azimuth looks 1 * number of range/azimuth looks sim
|
||||||
|
|
||||||
|
Below is the default number of looks used by the software. REMEMBER, NORMALLY YOU ONLY NEED TO CHANGE number of range/azimuth looks 2!!!
|
||||||
|
|
||||||
|
============================================================================================================================================
|
||||||
|
Operation Mode | Mode (AUIG2) | Mode (in file name) | look1 (r*a) | look2 (r*a) | total insar (r*a) | look_ion (r*a) | total ion (r*a)
|
||||||
|
============================================================================================================================================
|
||||||
|
spotlight | SPT | SBS | 2*4 | 4*4 | 8*16 | 16*16 | 32*64
|
||||||
|
============================================================================================================================================
|
||||||
|
stripmap | SM1 | UBS, UBD | 2*3 | 4*4 | 8*12 | 32*32 | 64*96
|
||||||
|
| SM2 | HBS, HBD, HBQ | 2*4 | 4*4 | 8*16 | 16*16 | 32*64
|
||||||
|
| SM3 | FBS, FBD, FBQ | 2*4 | 4*4 | 8*16 | 16*16 | 32*64
|
||||||
|
============================================================================================================================================
|
||||||
|
ScanSAR | WD1 | WBS, WBD | 1*14 | 5*2 | 5*28 | 80*32 | 80*448
|
||||||
|
| WD1 | WWS, WWD | 2*14 | 5*2 | 10*28 | 80*32 | 160*448
|
||||||
|
| WD2 | VBS, VBD | 1*14 | 5*2 | 5*28 | 80*32 | 80*448
|
||||||
|
============================================================================================================================================
|
||||||
|
|
||||||
|
To find the acquisition mode code, check the unpacked ALOS-2 product. For example, in the following
|
||||||
|
file name
|
||||||
|
|
||||||
|
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
||||||
|
^^^
|
||||||
|
FBD (indicated by ^) is the acquisition mode code.
|
||||||
|
=============================================================================================================================================-->
|
||||||
|
|
||||||
<!--=========================================================================================
|
<!--=========================================================================================
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
These are the numbers of looks to be taken when forming the interferogram
|
||||||
==========================================================================================-->
|
==========================================================================================-->
|
||||||
|
|
@ -234,7 +282,15 @@ IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-450
|
||||||
|
|
||||||
<!--=========================================================================================
|
<!--=========================================================================================
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
||||||
This is for ionospheric correction
|
This is for ionospheric correction.
|
||||||
|
Use a larger number of looks results in smaller image size, which saves time in filtering in
|
||||||
|
ionosphere estimation. However, a larger number of looks may also lead to phase aliasing in
|
||||||
|
the resulting inteferograms and therefore lead to phase unwrapping errors, which causes
|
||||||
|
significant errors in ionosphere estimation.
|
||||||
|
If the area has strong troposhere or phase variations (normally in areas with large height
|
||||||
|
differences such as edges of Tibetan Plateau), a smaller number of looks should be used to
|
||||||
|
avoid phase aliasing after taking looks. E.g. 1/2 of the default number of range/azimuth looks
|
||||||
|
ion that can be found in the annotation of parameter 'number of range looks 1'.
|
||||||
==========================================================================================-->
|
==========================================================================================-->
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
<!--<property name="number of range looks ion">None</property>-->
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
<!--<property name="number of azimuth looks ion">None</property>-->
|
||||||
|
|
@ -260,11 +316,28 @@ IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-450
|
||||||
==========================================================================================-->
|
==========================================================================================-->
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you want
|
||||||
|
to use a phase difference value 0.21 (rad) for swath 1 and 2 in frame 2, the parameter can be
|
||||||
|
specified as:
|
||||||
|
[[None, None, None, None], [0.21, None, None, None]]
|
||||||
|
This parameter has highest priority in determing phase difference between swaths.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="swath phase difference of lower band">None</property>-->
|
||||||
|
<!--<property name="swath phase difference of upper band">None</property>-->
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
||||||
|
<!--<property name="whether do secondary filtering of ionosphere phase">True</property>-->
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
||||||
|
<!--<property name="window size of secondary filtering of ionosphere phase">5</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
Normally no need to set this parameter, it will be automatically determined.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="standard deviation of ionosphere phase after filtering">None</property>-->
|
||||||
|
|
||||||
<!--=========================================================================================
|
<!--=========================================================================================
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
parameters for filtering subband interferograms used for ionospheric phase estimation
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,33 @@ IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-450
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--============================================================================================================================================
|
||||||
|
Instructions on number of looks used by the software
|
||||||
|
In alos2burstApp.py, number of range/azimuth looks 1 is always 1. Usually there is no need to set number of range/azimuth looks sim
|
||||||
|
(automatically set).
|
||||||
|
|
||||||
|
total number of looks of InSAR processing is: number of range/azimuth looks 1 * number of range/azimuth looks 2
|
||||||
|
total number of looks in ionosphere estimation is: number of range/azimuth looks 1 * number of range/azimuth looks ion
|
||||||
|
total number of looks in radar/DEM matching is: number of range/azimuth looks 1 * number of range/azimuth looks sim
|
||||||
|
total number of looks of SD processing is: number of range/azimuth looks 1 * number of range/azimuth looks sd
|
||||||
|
|
||||||
|
Below is the default number of looks used by the software. REMEMBER, NORMALLY YOU ONLY NEED TO CHANGE number of range/azimuth looks 2
|
||||||
|
AND number of range/azimuth looks sd!!!
|
||||||
|
|
||||||
|
==================================================================================================================
|
||||||
|
Operation Mode | Mode (AUIG2) | Mode (in file name) | look1 (r*a) | look2 (r*a) | look_ion (r*a) | look_sd (r*a)
|
||||||
|
==================================================================================================================
|
||||||
|
ScanSAR | WD1 | WBS, WBD, WWS, WWD | 1*1 | 7*2 | 42*12 | 14*4
|
||||||
|
==================================================================================================================
|
||||||
|
|
||||||
|
To find the acquisition mode code, check the unpacked ALOS-2 product. For example, in the following
|
||||||
|
file name
|
||||||
|
|
||||||
|
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
||||||
|
^^^
|
||||||
|
FBD (indicated by ^) is the acquisition mode code.
|
||||||
|
=============================================================================================================================================-->
|
||||||
|
|
||||||
<!--=========================================================================================
|
<!--=========================================================================================
|
||||||
These are the numbers of looks to be taken when forming the interferogram.
|
These are the numbers of looks to be taken when forming the interferogram.
|
||||||
these two parameters are always 1, not to be set by users
|
these two parameters are always 1, not to be set by users
|
||||||
|
|
@ -227,7 +254,17 @@ IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-450
|
||||||
|
|
||||||
<!--=========================================================================================
|
<!--=========================================================================================
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
||||||
This is for ionospheric correction
|
This is for ionospheric correction.
|
||||||
|
Use a larger number of looks results in smaller image size, which saves time in filtering in
|
||||||
|
ionosphere estimation. However, a larger number of looks may also lead to phase aliasing in
|
||||||
|
the resulting inteferograms and therefore lead to phase unwrapping errors, which causes
|
||||||
|
significant errors in ionosphere estimation.
|
||||||
|
Below are the default number of looks used by the software
|
||||||
|
number of range looks ion, spotlightModes: 16, stripmapModes: 16, scansarModes: 40
|
||||||
|
number of azimuth looks ion, spotlightModes: 16, stripmapModes: 16, scansarModes: 16
|
||||||
|
If the area does not have strong troposhere or phase variations (normally in areas with large
|
||||||
|
height differences such as edges of Tibetan Plateau), a larger number of looks can be used,
|
||||||
|
e.g. double the default numbers of range/azimuth looks.
|
||||||
==========================================================================================-->
|
==========================================================================================-->
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
<!--<property name="number of range looks ion">None</property>-->
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
<!--<property name="number of azimuth looks ion">None</property>-->
|
||||||
|
|
@ -253,11 +290,28 @@ IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-450
|
||||||
==========================================================================================-->
|
==========================================================================================-->
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you want
|
||||||
|
to use a phase difference value 0.21 (rad) for swath 1 and 2 in frame 2, the parameter can be
|
||||||
|
specified as:
|
||||||
|
[[None, None, None, None], [0.21, None, None, None]]
|
||||||
|
This parameter has highest priority in determing phase difference between swaths.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="swath phase difference of lower band">None</property>-->
|
||||||
|
<!--<property name="swath phase difference of upper band">None</property>-->
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
||||||
|
<!--<property name="whether do secondary filtering of ionosphere phase">True</property>-->
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
||||||
|
<!--<property name="window size of secondary filtering of ionosphere phase">5</property>-->
|
||||||
|
|
||||||
|
<!--=========================================================================================
|
||||||
|
Normally no need to set this parameter, it will be automatically determined.
|
||||||
|
==========================================================================================-->
|
||||||
|
<!--<property name="standard deviation of ionosphere phase after filtering">None</property>-->
|
||||||
|
|
||||||
<!--=========================================================================================
|
<!--=========================================================================================
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
parameters for filtering subband interferograms used for ionospheric phase estimation
|
||||||
|
|
|
||||||
|
|
@ -15,298 +15,5 @@
|
||||||
|
|
||||||
<property name="use GPU">True</property>
|
<property name="use GPU">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -15,298 +15,5 @@
|
||||||
|
|
||||||
<property name="use GPU">True</property>
|
<property name="use GPU">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -15,298 +15,5 @@
|
||||||
|
|
||||||
<property name="use GPU">True</property>
|
<property name="use GPU">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -15,298 +15,5 @@
|
||||||
|
|
||||||
<property name="use GPU">True</property>
|
<property name="use GPU">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -15,298 +15,5 @@
|
||||||
|
|
||||||
<property name="use GPU">True</property>
|
<property name="use GPU">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -15,284 +15,5 @@
|
||||||
|
|
||||||
<property name="use GPU">False</property>
|
<property name="use GPU">False</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="referenceFrames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created four times in runRdr2Geo.py, runLook.py, runIonUwrap.py
|
|
||||||
and runLookSd.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) masking filtered interferogram or unwrapped interferogram in sd processing
|
|
||||||
(4) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
always remove unsynchronized signal, since no extra computation required, and it does
|
|
||||||
improve coherence (example: indonesia_sep_2018/d25r/180927-181011_burst_3subswaths)
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">100.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram.
|
|
||||||
these two parameters are always 1, not to be set by users
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="filterWinsize">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for spectral diversity
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sd">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sd">None</property>-->
|
|
||||||
<!--<property name="interferogram filter strength SD">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size SD">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size SD">4</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step SD">unwrap</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
union or intersection when combining sd interferograms
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="union when combining sd interferograms">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list SD">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method for SD: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method SD">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2burstApp>
|
</alos2burstApp>
|
||||||
|
|
|
||||||
|
|
@ -15,284 +15,5 @@
|
||||||
|
|
||||||
<property name="use GPU">False</property>
|
<property name="use GPU">False</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="referenceFrames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created four times in runRdr2Geo.py, runLook.py, runIonUwrap.py
|
|
||||||
and runLookSd.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) masking filtered interferogram or unwrapped interferogram in sd processing
|
|
||||||
(4) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
always remove unsynchronized signal, since no extra computation required, and it does
|
|
||||||
improve coherence (example: indonesia_sep_2018/d25r/180927-181011_burst_3subswaths)
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">100.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram.
|
|
||||||
these two parameters are always 1, not to be set by users
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="filterWinsize">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for spectral diversity
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sd">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sd">None</property>-->
|
|
||||||
<!--<property name="interferogram filter strength SD">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size SD">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size SD">4</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step SD">unwrap</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
union or intersection when combining sd interferograms
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="union when combining sd interferograms">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list SD">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method for SD: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method SD">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2burstApp>
|
</alos2burstApp>
|
||||||
|
|
|
||||||
|
|
@ -15,284 +15,5 @@
|
||||||
|
|
||||||
<property name="use GPU">False</property>
|
<property name="use GPU">False</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="referenceFrames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created four times in runRdr2Geo.py, runLook.py, runIonUwrap.py
|
|
||||||
and runLookSd.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) masking filtered interferogram or unwrapped interferogram in sd processing
|
|
||||||
(4) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
always remove unsynchronized signal, since no extra computation required, and it does
|
|
||||||
improve coherence (example: indonesia_sep_2018/d25r/180927-181011_burst_3subswaths)
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">100.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram.
|
|
||||||
these two parameters are always 1, not to be set by users
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="filterWinsize">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for spectral diversity
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sd">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sd">None</property>-->
|
|
||||||
<!--<property name="interferogram filter strength SD">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size SD">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size SD">4</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step SD">unwrap</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
union or intersection when combining sd interferograms
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="union when combining sd interferograms">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list SD">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method for SD: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method SD">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2burstApp>
|
</alos2burstApp>
|
||||||
|
|
|
||||||
|
|
@ -15,284 +15,5 @@
|
||||||
|
|
||||||
<property name="use GPU">False</property>
|
<property name="use GPU">False</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="referenceFrames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created four times in runRdr2Geo.py, runLook.py, runIonUwrap.py
|
|
||||||
and runLookSd.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) masking filtered interferogram or unwrapped interferogram in sd processing
|
|
||||||
(4) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
always remove unsynchronized signal, since no extra computation required, and it does
|
|
||||||
improve coherence (example: indonesia_sep_2018/d25r/180927-181011_burst_3subswaths)
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">100.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram.
|
|
||||||
these two parameters are always 1, not to be set by users
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="filterWinsize">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for spectral diversity
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sd">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sd">None</property>-->
|
|
||||||
<!--<property name="interferogram filter strength SD">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size SD">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size SD">4</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step SD">unwrap</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
union or intersection when combining sd interferograms
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="union when combining sd interferograms">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list SD">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method for SD: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method SD">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2burstApp>
|
</alos2burstApp>
|
||||||
|
|
|
||||||
|
|
@ -13,298 +13,5 @@
|
||||||
|
|
||||||
<property name="use GPU">True</property>
|
<property name="use GPU">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -13,298 +13,5 @@
|
||||||
|
|
||||||
<property name="use GPU">True</property>
|
<property name="use GPU">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -13,298 +13,5 @@
|
||||||
|
|
||||||
<property name="use GPU">True</property>
|
<property name="use GPU">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -15,298 +15,5 @@
|
||||||
|
|
||||||
<property name="do dense offset">True</property>
|
<property name="do dense offset">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -13,298 +13,5 @@
|
||||||
|
|
||||||
<property name="use GPU">True</property>
|
<property name="use GPU">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -13,298 +13,5 @@
|
||||||
|
|
||||||
<property name="use GPU">True</property>
|
<property name="use GPU">True</property>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--=====================================================================================================
|
|
||||||
instructions for alos2App.py/alos2burstApp.py
|
|
||||||
|
|
||||||
This is the input file of alos2App.py/alos2burstApp.py. Below are all parameters users can set.
|
|
||||||
Instructions on how to set these parameters are also provided. Parameter default values are shown in the
|
|
||||||
brackets. Remove the first four characters and the last three characters in a parameter line to set a
|
|
||||||
parameter value.
|
|
||||||
|
|
||||||
For the techinques and algorithms implemented in the software, refer to:
|
|
||||||
|
|
||||||
1. ScanSAR or multi-mode InSAR processing
|
|
||||||
C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017.
|
|
||||||
|
|
||||||
2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or
|
|
||||||
multi-aperture InSAR (MAI) processing
|
|
||||||
C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017.
|
|
||||||
|
|
||||||
3. Ionospheric correction
|
|
||||||
C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR
|
|
||||||
data acquired by ALOS-2,"
|
|
||||||
IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018.
|
|
||||||
======================================================================================================-->
|
|
||||||
|
|
||||||
<!--Note that, in ScanSAR-stripmap interferometry, ScanSAR must be reference!-->
|
|
||||||
<!--<property name="reference directory">None</property>-->
|
|
||||||
<!--<property name="secondary directory">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of frames, e.g., [0680, 0690]. Here is how you can find frame number. Below
|
|
||||||
is a JAXA SLC product
|
|
||||||
0000168233_001001_ALOS2183010690-171012.zip
|
|
||||||
After you unpack the JAXA SLC product, you will find an image file like:
|
|
||||||
IMG-HH-ALOS2183010685-171012-FBDR1.1__A
|
|
||||||
^^^^
|
|
||||||
The number 0685 (indicated by ^) is the frame number. DON'T use the frame number in the zip
|
|
||||||
file name, as it may be incorrect (like the above example).
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="reference frames">None</property>-->
|
|
||||||
<!--<property name="secondary frames">None</property>-->
|
|
||||||
<!--<property name="reference polarization">HH</property>-->
|
|
||||||
<!--<property name="secondary polarization">HH</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
for ScanSAR-stripmap, always process all swaths, user's settings are overwritten
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="starting swath">None</property>-->
|
|
||||||
<!--<property name="ending swath">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
DEM and water body will be automatically downloaded if not specified. If you want to process
|
|
||||||
multiple pairs over one area, we recommend downloading your own dem using to avoid download
|
|
||||||
it multiple times. Here is how you can download a DEM and water body.
|
|
||||||
#3 arcsec for geocoding
|
|
||||||
mkdir dem_3_arcsec
|
|
||||||
cd dem_3_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 3 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#1 arcsec for creating differential interferogram
|
|
||||||
mkdir dem_1_arcsec
|
|
||||||
cd dem_1_arcsec
|
|
||||||
dem.py -a stitch -b 29 37 125 133 -k -s 1 -c -f -u http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11
|
|
||||||
fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f
|
|
||||||
rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml
|
|
||||||
cd ../
|
|
||||||
|
|
||||||
#water body
|
|
||||||
#do correct missing water body tiles problem here!!! check usage of wbd.py for more details,
|
|
||||||
#or simply follow the commands below
|
|
||||||
mkdir wbd_1_arcsec
|
|
||||||
cd wbd_1_arcsec
|
|
||||||
wbd.py 29 37 125 133
|
|
||||||
fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f
|
|
||||||
cd ../
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dem for coregistration">None</property>-->
|
|
||||||
<!--<property name="dem for geocoding">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
this water body is used to create water body in radar coordinate used in processing.
|
|
||||||
radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and
|
|
||||||
runIonUwrap.py, respectively. radar-coordinate water body is used in:
|
|
||||||
(1) determining the number of offsets in slc offset estimation, and radar/dem offset
|
|
||||||
estimation
|
|
||||||
(2) masking filtered interferogram or unwrapped interferogram
|
|
||||||
(3) determining the number of offsets in slc residual offset estimation after geometric
|
|
||||||
offset computation in coregistering slcs in dense offset.
|
|
||||||
(4) masking dense offset field
|
|
||||||
(5) mask coherence in ionosphere fitting and filtering
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="use virtual file">True</property>-->
|
|
||||||
<!--<property name="use GPU">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
if ScanSAR burst synchronization is lower than this threshold, an MBF filter is applied to
|
|
||||||
the reference/secondary images to remove non-overlap azimuth burst spectrum to improve coherence.
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="burst synchronization threshold">75.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
crop slcs to the reference/secondary overlap area. Cropping is always done for ScanSAR-stripmap
|
|
||||||
interferometry
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="crop slc">False</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is for determining the number of offsets to be estimated between reference and secondary SLCs.
|
|
||||||
for areas where no water body data available, turn this off, otherwise the program will use
|
|
||||||
geometrical offset, which is not accuate enough. If it still does not work, set
|
|
||||||
"number of range offsets for slc matching" and "number of azimuth offsets for slc matching"
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="use water body to dertermine number of matching offsets">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are 2-D lists, with frame as the first dimension and swath as the second dimension.
|
|
||||||
For example, if you want to process two frames and three swaths, you can specify one of
|
|
||||||
these parameters as:
|
|
||||||
[[20, 30, 20],[15, 20, 20]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range offsets for slc matching">None</property>-->
|
|
||||||
<!--<property name="number of azimuth offsets for slc matching">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken when forming the interferogram
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 1">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 1">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks 2">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks 2">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for matching the radar image and DEM
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks sim">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks sim">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--<property name="do matching when computing adjacent swath offset">True</property>-->
|
|
||||||
<!--<property name="do matching when computing adjacent frame offset">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are interferogram filtering parameters
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
water body mask starting step: None, filt, unwrap
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="water body mask starting step">unwrap</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a list of files to be geocoded
|
|
||||||
Wild card such as * is accepted, e.g. filt_*-*_5rlks_28alks.unw.conncomp
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode file list">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
This is a four-element list [s, n, w, e], e.g. [26.24, 30.04, 33.45, 37.79].
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode bounding box">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
geocode interpolation method: sinc, bilinear, bicubic, nearest
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="geocode interpolation method">None</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for ionospheric corrections
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do ionospheric phase estimation">True</property>-->
|
|
||||||
<!--<property name="apply ionospheric phase correction">True</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These are the numbers of looks to be taken after taking the numbers of range/azimuth looks 1.
|
|
||||||
This is for ionospheric correction
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="number of range looks ion">None</property>-->
|
|
||||||
<!--<property name="number of azimuth looks ion">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
seperated islands or areas usually affect ionosphere estimation and it's better to mask them
|
|
||||||
out. check ion/ion_cal/lower_40rlks_224alks.int (here number of looks 40 and 224 depends on
|
|
||||||
your particular case) for areas to be masked out.
|
|
||||||
The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
|
|
||||||
lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
|
|
||||||
four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
|
|
||||||
lastColumn instead. For exmple, if you want to mask the following two areas out, you can
|
|
||||||
specify a 2-D list like:
|
|
||||||
[[100, 200, 100, 200],[1000, 1200, 500, 600]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="areas masked out in ionospheric phase estimation">None</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
a 2-D list. e.g. if you are processing two ScanSAR frames, each with five swaths, and you do
|
|
||||||
not want phase difference of swath 1 and 2 in frame 2 snap to fixed values, the parameter can be specified
|
|
||||||
as:
|
|
||||||
[[True, True, True, True], [False, True, True, True]]
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="swath phase difference snap to fixed values">None</property>-->
|
|
||||||
|
|
||||||
<!--<property name="apply polynomial fit before filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="whether filtering ionosphere phase">True</property>-->
|
|
||||||
<!--<property name="apply polynomial fit in adaptive filtering window">True</property>-->
|
|
||||||
<!--<property name="maximum window size for filtering ionosphere phase">301</property>-->
|
|
||||||
<!--<property name="minimum window size for filtering ionosphere phase">11</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
parameters for filtering subband interferograms used for ionospheric phase estimation
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="filter subband interferogram">False</property>-->
|
|
||||||
<!--<property name="subband interferogram filter strength">0.3</property>-->
|
|
||||||
<!--<property name="subband interferogram filter window size">32</property>-->
|
|
||||||
<!--<property name="subband interferogram filter step size">4</property>-->
|
|
||||||
<!--<property name="remove magnitude before filtering subband interferogram">True</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
These parameters are for dense offset
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="do dense offset">False</property>-->
|
|
||||||
<!--<property name="estimate residual offset after geometrical coregistration">True</property>-->
|
|
||||||
<!--<property name="delete geometry files used for dense offset estimation">False</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
#For the following set of matching parameters
|
|
||||||
from: dense offset estimation window width
|
|
||||||
to: dense offset covariance surface oversample window size
|
|
||||||
Normally we only have to set the following parameters. A good set of parameters other than default is:
|
|
||||||
<property name="dense offset estimation window width">128</property>
|
|
||||||
<property name="dense offset estimation window hight">128</property>
|
|
||||||
<property name="dense offset skip width">64</property>
|
|
||||||
<property name="dense offset skip hight">64</property>
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset estimation window width">64</property>-->
|
|
||||||
<!--<property name="dense offset estimation window hight">64</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window width">8</property>-->
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="dense offset search window hight">8</property>-->
|
|
||||||
<!--<property name="dense offset skip width">32</property>-->
|
|
||||||
<!--<property name="dense offset skip hight">32</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample factor">64</property>-->
|
|
||||||
<!--<property name="dense offset covariance surface oversample window size">16</property>-->
|
|
||||||
<!--<property name="mask dense offset with water body">True</property>-->
|
|
||||||
<!--<property name="do offset filtering">False</property>-->
|
|
||||||
<!--<property name="offset filter window size">3</property>-->
|
|
||||||
<!--<property name="offset filter snr threshold">0.0</property>-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--=========================================================================================
|
|
||||||
system parameters, better not set these
|
|
||||||
==========================================================================================-->
|
|
||||||
<!--<property name="pickle dump directory">PICKLE</property>-->
|
|
||||||
<!--<property name="pickle load directory">PICKLE</property>-->
|
|
||||||
<!--<property name="renderer">xml</property>-->
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
</alos2App>
|
</alos2App>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
export OMP_NUM_THREADS=4
|
||||||
|
export CUDA_VISIBLE_DEVICES=7
|
||||||
|
|
||||||
#scansar-scansar
|
#scansar-scansar
|
||||||
##########################
|
##########################
|
||||||
cd scansar-scansar/1
|
cd scansar-scansar/1
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
export OMP_NUM_THREADS=4
|
||||||
|
export CUDA_VISIBLE_DEVICES=6
|
||||||
|
|
||||||
#scansar-scansar_burst
|
#scansar-scansar_burst
|
||||||
cd scansar-scansar_burst/1
|
cd scansar-scansar_burst/1
|
||||||
alos2burstApp.py --steps
|
alos2burstApp.py --steps
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue