new alosStack application

LT1AB
CunrenLiang 2020-10-19 19:42:07 -07:00 committed by CunrenLiang
parent 3aa234c515
commit e9bd7edeb3
89 changed files with 9627 additions and 5214 deletions

View File

@ -117,6 +117,13 @@ WBD = Application.Parameter('wbd',
mandatory=False,
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',
public_name = 'use virtual file',
default=True,
@ -331,6 +338,22 @@ SWATH_PHASE_DIFF_SNAP_ION = Application.Parameter('swathPhaseDiffSnapIon',
container = list,
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',
public_name = 'apply polynomial fit before filtering ionosphere phase',
default = True,
@ -352,6 +375,13 @@ FIT_ADAPTIVE_ION = Application.Parameter('fitAdaptiveIon',
mandatory = False,
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',
public_name='maximum window size for filtering ionosphere phase',
default=301,
@ -366,6 +396,20 @@ FILTERING_WINSIZE_MIN_ION = Application.Parameter('filteringWinsizeMinIon',
mandatory=False,
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',
public_name = 'filter subband interferogram',
default = False,
@ -601,6 +645,7 @@ class Alos2InSAR(Application):
DEM,
DEM_GEO,
WBD,
DO_INSAR,
USE_VIRTUAL_FILE,
USE_GPU,
BURST_SYNCHRONIZATION_THRESHOLD,
@ -631,11 +676,16 @@ class Alos2InSAR(Application):
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,
@ -775,6 +825,7 @@ class Alos2InSAR(Application):
## Add instance attribute RunWrapper functions, which emulate methods.
def _add_methods(self):
self.runPreprocessor = Alos2Proc.createPreprocessor(self)
self.runBaseline = Alos2Proc.createBaseline(self)
self.runDownloadDem = Alos2Proc.createDownloadDem(self)
self.runPrepareSlc = Alos2Proc.createPrepareSlc(self)
self.runSlcOffset = Alos2Proc.createSlcOffset(self)
@ -793,6 +844,7 @@ class Alos2InSAR(Application):
self.runIonSubband = Alos2Proc.createIonSubband(self)
self.runIonUwrap = Alos2Proc.createIonUwrap(self)
self.runIonFilt = Alos2Proc.createIonFilt(self)
self.runIonCorrect = Alos2Proc.createIonCorrect(self)
self.runFilt = Alos2Proc.createFilt(self)
self.runUnwrapSnaphu = Alos2Proc.createUnwrapSnaphu(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',
func=self.runDownloadDem,
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,
doc=(
"""filter interferogram"""
@ -995,6 +1060,8 @@ class Alos2InSAR(Application):
# Run a preprocessor for the two sets of frames
self.runPreprocessor()
self.runBaseline()
self.runDownloadDem()
self.runPrepareSlc()
@ -1031,6 +1098,8 @@ class Alos2InSAR(Application):
self.runIonFilt()
self.runIonCorrect()
self.runFilt()
self.runUnwrapSnaphu()

View File

@ -321,6 +321,22 @@ SWATH_PHASE_DIFF_SNAP_ION = Application.Parameter('swathPhaseDiffSnapIon',
container = list,
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',
public_name = 'apply polynomial fit before filtering ionosphere phase',
default = True,
@ -342,6 +358,13 @@ FIT_ADAPTIVE_ION = Application.Parameter('fitAdaptiveIon',
mandatory = False,
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',
public_name='maximum window size for filtering ionosphere phase',
default=301,
@ -356,6 +379,20 @@ FILTERING_WINSIZE_MIN_ION = Application.Parameter('filteringWinsizeMinIon',
mandatory=False,
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',
public_name = 'filter subband interferogram',
default = False,
@ -566,11 +603,16 @@ class Alos2burstInSAR(Application):
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,
@ -704,6 +746,7 @@ class Alos2burstInSAR(Application):
## Add instance attribute RunWrapper functions, which emulate methods.
def _add_methods(self):
self.runPreprocessor = Alos2burstProc.createPreprocessor(self)
self.runBaseline = Alos2burstProc.createBaseline(self)
self.runExtractBurst = Alos2burstProc.createExtractBurst(self)
self.runDownloadDem = Alos2burstProc.createDownloadDem(self)
self.runCoregGeom = Alos2burstProc.createCoregGeom(self)
@ -723,6 +766,7 @@ class Alos2burstInSAR(Application):
self.runIonSubband = Alos2burstProc.createIonSubband(self)
self.runIonUwrap = Alos2burstProc.createIonUwrap(self)
self.runIonFilt = Alos2burstProc.createIonFilt(self)
self.runIonCorrect = Alos2burstProc.createIonCorrect(self)
self.runFilt = Alos2burstProc.createFilt(self)
self.runUnwrapSnaphu = Alos2burstProc.createUnwrapSnaphu(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,
doc=(
"""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,
doc=(
"""filter interferogram"""
@ -916,6 +972,8 @@ class Alos2burstInSAR(Application):
# Run a preprocessor for the two sets of frames
self.runPreprocessor()
self.runBaseline()
self.runExtractBurst()
self.runDownloadDem()
@ -954,6 +1012,8 @@ class Alos2burstInSAR(Application):
self.runIonFilt()
self.runIonCorrect()
self.runFilt()
self.runUnwrapSnaphu()

View File

@ -91,7 +91,7 @@ def create_xml(fileName, width, length, fileType):
#image.finalizeImage()
def multilook_v1(data, nalks, nrlks):
def multilook_v1(data, nalks, nrlks, mean=True):
'''
doing multiple looking
ATTENSION: original array changed after running this function
@ -106,10 +106,13 @@ def multilook_v1(data, nalks, 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]
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
'''
@ -125,7 +128,10 @@ def multilook(data, nalks, nrlks):
for i in range(1, 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):
@ -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(
int(j*rangeStep+1),
float(rgoff[i][j]),
float(rgoff[i][j])*rangeStep,
int(i*azimuthStep+1),
float(azoff[i][j]),
float(azoff[i][j])*azimuthStep,
float(22.00015),
float(0.000273),
float(0.002126),
@ -749,7 +755,7 @@ def snaphuUnwrap(track, t, wrapName, corName, unwrapName, nrlks, nalks, costMode
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
'''
@ -762,7 +768,7 @@ def snaphuUnwrapOriginal(wrapName, corName, ampName, unwrapName, costMode = 's',
length = corImg.length
#specify coherence file format in configure file
snaphuConfFile = 'snaphu.conf'
#snaphuConfFile = 'snaphu.conf'
if corImg.bands == 1:
snaphuConf = '''CORRFILEFORMAT FLOAT_DATA
CONNCOMPFILE {}
@ -809,7 +815,7 @@ MAXNCOMPS 20'''.format(unwrapName+'.conncomp')
return
def getBboxGeo(track):
def getBboxGeo(track, useTrackOnly=False, numberOfSamples=1, numberOfLines=1, numberRangeLooks=1, numberAzimuthLooks=1):
'''
get bounding box in geo-coordinate
'''
@ -817,7 +823,15 @@ def getBboxGeo(track):
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]
rangeMax = bboxRdr[1]
@ -1254,8 +1268,199 @@ def snap(inputValue, fixedValues, snapThreshold):
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])

View File

@ -4,6 +4,7 @@ InstallSameDir(
Alos2ProcPublic.py
Factories.py
denseOffsetNote.txt
runBaseline.py
runCoherence.py
runDenseOffset.py
runDiffInterferogram.py
@ -16,6 +17,7 @@ InstallSameDir(
runGeo2Rdr.py
runGeocode.py
runGeocodeOffset.py
runIonCorrect.py
runIonFilt.py
runIonSubband.py
runIonUwrap.py

View File

@ -74,6 +74,7 @@ def createUnwrap2Stage(other, do_unwrap_2stage = None, unwrapperName = None):
createPreprocessor = _factory("runPreprocessor")
createBaseline = _factory("runBaseline")
createDownloadDem = _factory("runDownloadDem")
createPrepareSlc = _factory("runPrepareSlc")
createSlcOffset = _factory("runSlcOffset")
@ -92,6 +93,7 @@ createCoherence = _factory("runCoherence")
createIonSubband = _factory("runIonSubband")
createIonUwrap = _factory("runIonUwrap")
createIonFilt = _factory("runIonFilt")
createIonCorrect = _factory("runIonCorrect")
createFilt = _factory("runFilt")
createUnwrapSnaphu = _factory("runUnwrapSnaphu")
createGeocode = _factory("runGeocode")

View File

@ -40,6 +40,6 @@ project = 'Alos2Proc'
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.Alias('install',install)

View File

@ -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)

View File

@ -13,8 +13,12 @@ from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
logger = logging.getLogger('isce.alos2insar.runCoherence')
def runCoherence(self):
'''Extract images.
'''estimate coherence
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()

View File

@ -15,6 +15,10 @@ logger = logging.getLogger('isce.alos2insar.runDiffInterferogram')
def runDiffInterferogram(self):
'''Extract images.
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()

View File

@ -21,12 +21,24 @@ logger = logging.getLogger('isce.alos2insar.runFilt')
def runFilt(self):
'''filter interferogram
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()
#referenceTrack = self._insar.loadTrack(reference=True)
#secondaryTrack = self._insar.loadTrack(reference=False)
filt(self)
catalog.printToLog(logger, "runFilt")
self._insar.procDoc.addAllFromCatalog(catalog)
def filt(self):
insarDir = 'insar'
os.makedirs(insarDir, exist_ok=True)
os.chdir(insarDir)
@ -150,21 +162,17 @@ def runFilt(self):
print('\nmask filtered interferogram using: {}'.format(self._insar.multilookWbdOut))
if self.waterBodyMaskStartingStep=='filt':
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')
else:
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.nonzero(wbd==-1)]=0
del phsig
filt=np.memmap(self._insar.filteredInterferogram, dtype='complex64', mode='r+', shape=(length, width))
filt[np.nonzero(wbd==-1)]=0
del filt
del wbd
#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')
#else:
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.nonzero(wbd==-1)]=0
del phsig
filt=np.memmap(self._insar.filteredInterferogram, dtype='complex64', mode='r+', shape=(length, width))
filt[np.nonzero(wbd==-1)]=0
del filt
del wbd
os.chdir('../')
catalog.printToLog(logger, "runFilt")
self._insar.procDoc.addAllFromCatalog(catalog)

View File

@ -18,6 +18,10 @@ logger = logging.getLogger('isce.alos2insar.runFormInterferogram')
def runFormInterferogram(self):
'''form interferograms.
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()

View File

@ -17,6 +17,10 @@ logger = logging.getLogger('isce.alos2insar.runFrameMosaic')
def runFrameMosaic(self):
'''mosaic frames
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()
@ -193,90 +197,107 @@ def frameMosaic(track, inputFiles, outputfile, rangeOffsets, azimuthOffsets, num
if i == 0:
rinfs[i] = inf
else:
infImg = isceobj.createImage()
infImg.load(inf+'.xml')
rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i])
#no need to resample
if (abs(rangeOffsets2[i] - round(rangeOffsets2[i])) < 0.0001) and (abs(azimuthOffsets2[i] - round(azimuthOffsets2[i])) < 0.0001):
if os.path.isfile(rinfs[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:
rect_with_looks(inf,
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)
infImg = isceobj.createImage()
infImg.load(inf+'.xml')
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')
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,
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
#actually no need to calculate in azimuth direction

View File

@ -13,6 +13,10 @@ logger = logging.getLogger('isce.alos2insar.runFrameOffset')
def runFrameOffset(self):
'''estimate frame offsets.
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()

View File

@ -13,6 +13,10 @@ logger = logging.getLogger('isce.alos2insar.runGeo2Rdr')
def runGeo2Rdr(self):
'''compute range and azimuth offsets
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()

View File

@ -16,6 +16,10 @@ logger = logging.getLogger('isce.alos2insar.runGeocode')
def runGeocode(self):
'''geocode final products
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()

View File

@ -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)

View File

@ -15,6 +15,10 @@ logger = logging.getLogger('isce.alos2insar.runIonFilt')
def runIonFilt(self):
'''compute and filter ionospheric phase
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()
@ -110,6 +114,7 @@ def runIonFilt(self):
############################################################
# STEP 2. filter ionospheric phase
############################################################
import scipy.signal as ss
#################################################
#SET PARAMETERS HERE
@ -117,22 +122,36 @@ def runIonFilt(self):
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 = 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')
@ -271,6 +290,12 @@ def runIonFilt(self):
#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:
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
if (fit == True) and (filt == True):
@ -291,114 +316,7 @@ def runIonFilt(self):
window_size_out.astype(np.float32).tofile(windowsizefiltfile)
create_xml(windowsizefiltfile, width, length, 'float')
############################################################
# 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('../')
os.chdir('../../')
catalog.printToLog(logger, "runIonFilt")
self._insar.procDoc.addAllFromCatalog(catalog)

View File

@ -14,6 +14,10 @@ logger = logging.getLogger('isce.alos2insar.runIonSubband')
def runIonSubband(self):
'''create subband interferograms
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()
@ -296,30 +300,38 @@ def runIonSubband(self):
#list of input files
inputInterferograms = []
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)):
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)
# #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

View File

@ -4,6 +4,7 @@
#
import os
import shutil
import logging
import datetime
import numpy as np
@ -15,6 +16,10 @@ logger = logging.getLogger('isce.alos2insar.runIonUwrap')
def runIonUwrap(self):
'''unwrap subband interferograms
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()
@ -24,7 +29,17 @@ def runIonUwrap(self):
return
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)
from isceobj.Alos2Proc.runIonSubband import defineIonDir
@ -73,8 +88,14 @@ def runIonUwrap(self):
#water body
if k == 0:
look(os.path.join(fullbandDir, self._insar.latitude), 'lat'+ml2+'.lat', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 3, 0, 1)
look(os.path.join(fullbandDir, self._insar.longitude), 'lon'+ml2+'.lon', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 3, 0, 1)
if latLonDir is None:
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('lon'+ml2+'.lon', width2, length2, 'double')
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 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'
if self.removeMagnitudeBeforeFilteringSubbandInt:
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 + '.xml')
#create phase sigma for phase unwrapping
#recreate filtered image
filtImage = isceobj.createIntImage()
filtImage.load('filt_'+subbandPrefix[k]+ml2+'.int' + '.xml')
filtImage.setAccessMode('read')
filtImage.createImage()
toBeUsedInPhsig = 'filt_'+subbandPrefix[k]+ml2+'.int'
else:
toBeUsedInPhsig = subbandPrefix[k]+ml2+'.int'
#amplitude image
ampImage = isceobj.createAmpImage()
ampImage.load(subbandPrefix[k]+ml2+'.amp' + '.xml')
ampImage.setAccessMode('read')
ampImage.createImage()
#2. create phase sigma for phase unwrapping
#recreate filtered image
filtImage = isceobj.createIntImage()
filtImage.load(toBeUsedInPhsig + '.xml')
filtImage.setAccessMode('read')
filtImage.createImage()
#phase sigma correlation image
phsigImage = isceobj.createImage()
phsigImage.setFilename(subbandPrefix[k]+ml2+'.phsig')
phsigImage.setWidth(width)
phsigImage.dataType='FLOAT'
phsigImage.bands = 1
phsigImage.setImageType('cor')
phsigImage.setAccessMode('write')
phsigImage.createImage()
#amplitude image
ampImage = isceobj.createAmpImage()
ampImage.load(subbandPrefix[k]+ml2+'.amp' + '.xml')
ampImage.setAccessMode('read')
ampImage.createImage()
icu = Icu(name='insarapp_filter_icu')
icu.configure()
icu.unwrappingFlag = False
icu.icu(intImage = filtImage, ampImage=ampImage, phsigImage=phsigImage)
#phase sigma correlation image
phsigImage = isceobj.createImage()
phsigImage.setFilename(subbandPrefix[k]+ml2+'.phsig')
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()
ampImage.finalizeImage()
phsigImage.finalizeImage()
phsigImage.renderHdr()
filtImage.finalizeImage()
ampImage.finalizeImage()
phsigImage.finalizeImage()
############################################################
# STEP 4. phase unwrapping
############################################################
from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrap
from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrapOriginal
for k in range(2):
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'
coherenceFile = 'diff'+ml2+'.cor'
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)
os.chdir('../../')
catalog.printToLog(logger, "runIonUwrap")
self._insar.procDoc.addAllFromCatalog(catalog)
#if shutil.which('snaphu') != None:
#do not use original snaphu now
if False:
print('\noriginal snaphu program found')
print('unwrap {} using original snaphu, rather than that in ISCE'.format(toBeUnwrapped))
snaphuUnwrapOriginal(toBeUnwrapped,
subbandPrefix[k]+ml2+'.phsig',
subbandPrefix[k]+ml2+'.amp',
subbandPrefix[k]+ml2+'.unw',
costMode = 's',
initMethod = 'mcf',
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)

View File

@ -17,6 +17,10 @@ logger = logging.getLogger('isce.alos2insar.runLook')
def runLook(self):
'''take looks
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()

View File

@ -15,6 +15,7 @@ from isceobj.Planet.Planet import Planet
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
from isceobj.Alos2Proc.Alos2ProcPublic import getBboxRdr
from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo
from isceobj.Alos2Proc.Alos2ProcPublic import modeProcParDict
logger = logging.getLogger('isce.alos2insar.runPreprocessor')
@ -110,81 +111,20 @@ def runPreprocessor(self):
self._insar.numberRangeLooksIon = self.numberRangeLooksIon
self._insar.numberAzimuthLooksIon = self.numberAzimuthLooksIon
if self._insar.numberRangeLooks1 == None:
if referenceMode in ['SBS']:
self._insar.numberRangeLooks1 = 2
elif referenceMode in ['UBS', 'UBD']:
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.numberRangeLooks1 is None:
self._insar.numberRangeLooks1 = modeProcParDict['ALOS-2'][referenceMode]['numberRangeLooks1']
if self._insar.numberAzimuthLooks1 is None:
self._insar.numberAzimuthLooks1 = modeProcParDict['ALOS-2'][referenceMode]['numberAzimuthLooks1']
if self._insar.numberAzimuthLooks1 == None:
if referenceMode in ['SBS']:
self._insar.numberAzimuthLooks1 = 4
elif referenceMode in ['UBS', 'UBD']:
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 is None:
self._insar.numberRangeLooks2 = modeProcParDict['ALOS-2'][referenceMode]['numberRangeLooks2']
if self._insar.numberAzimuthLooks2 is None:
self._insar.numberAzimuthLooks2 = modeProcParDict['ALOS-2'][referenceMode]['numberAzimuthLooks2']
if self._insar.numberRangeLooks2 == None:
if referenceMode in spotlightModes:
self._insar.numberRangeLooks2 = 4
elif referenceMode in stripmapModes:
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')
if self._insar.numberRangeLooksIon is None:
self._insar.numberRangeLooksIon = modeProcParDict['ALOS-2'][referenceMode]['numberRangeLooksIon']
if self._insar.numberAzimuthLooksIon is None:
self._insar.numberAzimuthLooksIon = modeProcParDict['ALOS-2'][referenceMode]['numberAzimuthLooksIon']
#define processing file names
@ -335,201 +275,6 @@ def runPreprocessor(self):
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")
self._insar.procDoc.addAllFromCatalog(catalog)

View File

@ -14,6 +14,10 @@ logger = logging.getLogger('isce.alos2insar.runRdr2Geo')
def runRdr2Geo(self):
'''compute lat/lon/hgt
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()

View File

@ -20,10 +20,20 @@ logger = logging.getLogger('isce.alos2insar.runRdrDemOffset')
def runRdrDemOffset(self):
'''estimate between radar image and dem
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()
referenceTrack = self._insar.loadTrack(reference=True)
rdrDemOffset(self, referenceTrack, catalog=catalog)
def rdrDemOffset(self, referenceTrack, catalog=None):
demFile = os.path.abspath(self._insar.dem)
insarDir = 'insar'
@ -96,13 +106,15 @@ def runRdrDemOffset(self):
if (landRatio <= 0.00125):
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')
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')
if catalog is not None:
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('../../')
catalog.printToLog(logger, "runRdrDemOffset")
self._insar.procDoc.addAllFromCatalog(catalog)
if catalog is not None:
catalog.printToLog(logger, "runRdrDemOffset")
self._insar.procDoc.addAllFromCatalog(catalog)
return
@ -130,8 +142,9 @@ def runRdrDemOffset(self):
if numberOfOffsetsAzimuth < 10:
numberOfOffsetsAzimuth = 10
catalog.addItem('number of range offsets', '{}'.format(numberOfOffsetsRange), 'runRdrDemOffset')
catalog.addItem('number of azimuth offsets', '{}'.format(numberOfOffsetsAzimuth), 'runRdrDemOffset')
if catalog is not None:
catalog.addItem('number of range offsets', '{}'.format(numberOfOffsetsRange), 'runRdrDemOffset')
catalog.addItem('number of azimuth offsets', '{}'.format(numberOfOffsetsAzimuth), 'runRdrDemOffset')
#matching
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('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]
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('../../')
catalog.printToLog(logger, "runRdrDemOffset")
self._insar.procDoc.addAllFromCatalog(catalog)
if catalog is not None:
catalog.printToLog(logger, "runRdrDemOffset")
self._insar.procDoc.addAllFromCatalog(catalog)
return
@ -277,8 +292,9 @@ def runRdrDemOffset(self):
os.chdir('../../')
catalog.printToLog(logger, "runRdrDemOffset")
self._insar.procDoc.addAllFromCatalog(catalog)
if catalog is not None:
catalog.printToLog(logger, "runRdrDemOffset")
self._insar.procDoc.addAllFromCatalog(catalog)
def simulateRadar(hgtfile, simfile, scale=3.0, offset=100.0):

View File

@ -15,6 +15,10 @@ logger = logging.getLogger('isce.alos2insar.runRectRangeOffset')
def runRectRangeOffset(self):
'''rectify range offset
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()

View File

@ -40,13 +40,30 @@ def runSlcMosaic(self):
if len(referenceTrack.frames) > 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 self.frameOffsetMatching == False:
#if self.frameOffsetMatching == False:
if referenceEstimated == False:
offsetReference = frameOffset(referenceTrack, self._insar.referenceSlc, self._insar.referenceFrameOffset,
crossCorrelation=True, matchingMode=matchingMode)
offsetSecondary = frameOffset(secondaryTrack, self._insar.secondarySlc, self._insar.secondaryFrameOffset,
crossCorrelation=True, matchingMode=matchingMode)
if self.frameOffsetMatching == False:
#if self.frameOffsetMatching == False:
if referenceEstimated == False:
self._insar.frameRangeOffsetMatchingReference = offsetReference[2]
self._insar.frameAzimuthOffsetMatchingReference = offsetReference[3]
self._insar.frameRangeOffsetMatchingSecondary = offsetSecondary[2]
@ -110,6 +127,43 @@ def runSlcMosaic(self):
secondaryTrack.dopplerVsPixel = secondaryTrack.frames[0].swaths[0].dopplerVsPixel
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
#########################################################
#choose offsets

View File

@ -25,6 +25,11 @@ logger = logging.getLogger('isce.alos2insar.runSlcOffset')
def runSlcOffset(self):
'''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)
self.updateParamemetersFromUser()

View File

@ -17,6 +17,10 @@ logger = logging.getLogger('isce.alos2insar.runSwathMosaic')
def runSwathMosaic(self):
'''mosaic subswaths
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()
@ -211,8 +215,10 @@ def swathMosaic(frame, inputFiles, outputfile, rangeOffsets, azimuthOffsets, num
rectWidth.append( int(swaths[i].numberOfSamples / numberOfRangeLooks) )
rectLength.append( int(swaths[i].numberOfLines / numberOfAzimuthLooks) )
else:
rectWidth.append( int(1.0 / rangeScale[i] * int(swaths[i].numberOfSamples / numberOfRangeLooks)) )
rectLength.append( int(1.0 / azimuthScale[i] * int(swaths[i].numberOfLines / numberOfAzimuthLooks)) )
rectWidth.append( round(1.0 / rangeScale[i] * int(swaths[i].numberOfSamples / numberOfRangeLooks)) )
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
#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.symlink(inf, rinfs[i])
else:
infImg = isceobj.createImage()
infImg.load(inf+'.xml')
rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i])
#no need to resample
if (abs(rangeOffsets2[i] - round(rangeOffsets2[i])) < 0.0001) and (abs(azimuthOffsets2[i] - round(azimuthOffsets2[i])) < 0.0001):
if os.path.isfile(rinfs[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:
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)
#resampling
phaseRectFile = 'phaseRect'
amplitudeRectFile = 'amplitudeRect'
rect_with_looks(phaseFile,
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')
#resampling
phaseRectFile = 'phaseRect'
amplitudeRectFile = 'amplitudeRect'
rect_with_looks(phaseFile,
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
phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(rectLength[i], rectWidth[i])
amplitude = np.fromfile(amplitudeRectFile, dtype=np.float32).reshape(rectLength[i], rectWidth[i])
(phase*amplitude).astype(np.complex64).tofile(rinfs[i])
#recombine amplitude and phase
phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(rectLength[i], rectWidth[i])
amplitude = np.fromfile(amplitudeRectFile, dtype=np.float32).reshape(rectLength[i], rectWidth[i])
(phase*amplitude).astype(np.complex64).tofile(rinfs[i])
#tidy up
os.remove(phaseFile)
os.remove(amplitudeFile)
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

View File

@ -18,6 +18,10 @@ logger = logging.getLogger('isce.alos2insar.runSwathOffset')
def runSwathOffset(self):
'''estimate swath offsets.
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()

View File

@ -19,12 +19,23 @@ logger = logging.getLogger('isce.alos2insar.runUnwrapSnaphu')
def runUnwrapSnaphu(self):
'''unwrap filtered interferogram
'''
if hasattr(self, 'doInSAR'):
if not self.doInSAR:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()
referenceTrack = self._insar.loadTrack(reference=True)
#secondaryTrack = self._insar.loadTrack(reference=False)
unwrapSnaphu(self, referenceTrack)
catalog.printToLog(logger, "runUnwrapSnaphu")
self._insar.procDoc.addAllFromCatalog(catalog)
def unwrapSnaphu(self, referenceTrack):
insarDir = 'insar'
os.makedirs(insarDir, exist_ok=True)
os.chdir(insarDir)
@ -70,21 +81,20 @@ def runUnwrapSnaphu(self):
wbdImage.load(self._insar.multilookWbdOut+'.xml')
width = wbdImage.width
length = wbdImage.length
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')
else:
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[0:length*2:2, :])[np.nonzero(wbd==-1)]=0
(unw[1:length*2:2, :])[np.nonzero(wbd==-1)]=0
del unw
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[1:length*2:2, :])[np.nonzero(wbd==-1)]=0
del unw, wbd
#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')
#else:
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[0:length*2:2, :])[np.nonzero(wbd==-1)]=0
(unw[1:length*2:2, :])[np.nonzero(wbd==-1)]=0
del unw
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[1:length*2:2, :])[np.nonzero(wbd==-1)]=0
del unw, wbd
os.chdir('../')
catalog.printToLog(logger, "runUnwrapSnaphu")
self._insar.procDoc.addAllFromCatalog(catalog)

View File

@ -74,6 +74,7 @@ def createUnwrap2Stage(other, do_unwrap_2stage = None, unwrapperName = None):
createPreprocessor = _factory("runPreprocessor")
createBaseline = _factory("runBaseline", path = "isceobj.Alos2Proc.")
createExtractBurst = _factory("runExtractBurst")
createDownloadDem = _factory("runDownloadDem", path = "isceobj.Alos2Proc.")
createCoregGeom = _factory("runCoregGeom")
@ -93,6 +94,7 @@ createCoherence = _factory("runCoherence", path = "isceobj.Alos2Proc.")
createIonSubband = _factory("runIonSubband")
createIonUwrap = _factory("runIonUwrap", path = "isceobj.Alos2Proc.")
createIonFilt = _factory("runIonFilt", path = "isceobj.Alos2Proc.")
createIonCorrect = _factory("runIonCorrect", path = "isceobj.Alos2Proc.")
createFilt = _factory("runFilt", path = "isceobj.Alos2Proc.")
createUnwrapSnaphu = _factory("runUnwrapSnaphu", path = "isceobj.Alos2Proc.")
createGeocode = _factory("runGeocode", path = "isceobj.Alos2Proc.")

View File

@ -252,30 +252,38 @@ def runIonSubband(self):
#list of input files
inputInterferograms = []
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)):
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)
# #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
#mosaic amplitudes

View File

@ -258,201 +258,6 @@ def runPreprocessor(self):
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")
self._insar.procDoc.addAllFromCatalog(catalog)

View File

@ -136,6 +136,17 @@ class TerraSARX(Sensor):
self.populateMetadata()
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):
"""
Populate our Metadata objects

View File

@ -213,7 +213,9 @@
cycle
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
do jj=1,sincone

View File

@ -55,6 +55,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <assert.h>
@ -1755,6 +1756,8 @@ void SolveCS2(signed char **residue, short **mstcosts, long nrow, long ncol,
double cost, c_max;
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 **rowflow, **colflow;
@ -1808,19 +1811,10 @@ void SolveCS2(signed char **residue, short **mstcosts, long nrow, long ncol,
exit(ABNORMAL_EXIT);
}
if(from==(to+1)){
num=from+(int )((from-1)/nNrow);
colflow[(num-1) % (nNrow+1)][(int )(num-1)/(nNrow+1)]-=flow;
}else if(from==(to-1)){
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)){
/* node indices are indexed from 1, not 0 */
/* node indices are in column major order, not row major */
/* handle flow to/from ground first */
if((from==ground) || (to==ground)){
if(to==ground){
num=to;
to=from;
@ -1828,17 +1822,69 @@ void SolveCS2(signed char **residue, short **mstcosts, long nrow, long ncol,
flow=-flow;
}
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){
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)){
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)){
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{
fprintf(sp0,"Unassigned ground arc parsing cs2 solution\nAbort\n");
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{
fprintf(sp0,"Non-grid arc parsing cs2 solution\nAbort\n");
exit(ABNORMAL_EXIT);

View File

@ -4,16 +4,18 @@ Read the document for each stack processor for details.
+ [stripmapStack](./stripmapStack/README.md)
+ [topsStack](./topsStack/README.md)
+ [alosStack](./alosStack/alosStack_tutorial.txt)
### 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
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/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.
@ -32,3 +34,4 @@ For StripMap stack processor and ionospheric phase estimation:
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. 777786, Feb. 2017. (https://ieeexplore.ieee.org/abstract/document/7637021/)

View File

@ -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

View File

@ -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')

View File

@ -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')

View File

@ -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>

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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('../')

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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)

View File

@ -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('../')

View File

@ -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')

View File

@ -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)

View File

@ -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')))

View File

@ -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('../')

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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'))

View File

@ -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('../')

View File

@ -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('../')

View File

@ -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)

View File

@ -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('../')

View File

@ -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()

View File

@ -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')

View File

@ -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('../')

View File

@ -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)

View File

@ -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('../')

View File

@ -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')

View File

@ -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])

View File

@ -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)

View File

@ -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>
<!--=========================================================================================
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>-->
<!--=========================================================================================
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 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>-->
<!--============================================================================================================================================
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
==========================================================================================-->
@ -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.
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 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>-->
<!--=========================================================================================
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

View File

@ -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>-->
<!--============================================================================================================================================
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 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.
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 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>-->
<!--=========================================================================================
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

View File

@ -15,298 +15,5 @@
<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>
</alos2App>

View File

@ -15,298 +15,5 @@
<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>
</alos2App>

View File

@ -15,298 +15,5 @@
<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>
</alos2App>

View File

@ -15,298 +15,5 @@
<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>
</alos2App>

View File

@ -15,298 +15,5 @@
<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>
</alos2App>

View File

@ -15,284 +15,5 @@
<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>
</alos2burstApp>

View File

@ -15,284 +15,5 @@
<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>
</alos2burstApp>

View File

@ -15,284 +15,5 @@
<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>
</alos2burstApp>

View File

@ -15,284 +15,5 @@
<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>
</alos2burstApp>

View File

@ -13,298 +13,5 @@
<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>
</alos2App>

View File

@ -13,298 +13,5 @@
<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>
</alos2App>

View File

@ -13,298 +13,5 @@
<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>
</alos2App>

View File

@ -15,298 +15,5 @@
<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>
</alos2App>

View File

@ -13,298 +13,5 @@
<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>
</alos2App>

View File

@ -13,298 +13,5 @@
<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>
</alos2App>

View File

@ -1,3 +1,6 @@
export OMP_NUM_THREADS=4
export CUDA_VISIBLE_DEVICES=7
#scansar-scansar
##########################
cd scansar-scansar/1

View File

@ -1,3 +1,6 @@
export OMP_NUM_THREADS=4
export CUDA_VISIBLE_DEVICES=6
#scansar-scansar_burst
cd scansar-scansar_burst/1
alos2burstApp.py --steps