199 lines
9.5 KiB
Python
199 lines
9.5 KiB
Python
#
|
|
# Author: Cunren Liang
|
|
# Copyright 2015-present, NASA-JPL/Caltech
|
|
#
|
|
|
|
import os
|
|
import shutil
|
|
import logging
|
|
import datetime
|
|
import numpy as np
|
|
|
|
import isceobj
|
|
from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrap
|
|
from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrapOriginal
|
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
|
from contrib.alos2proc.alos2proc import look
|
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
|
|
|
logger = logging.getLogger('isce.alos2burstinsar.runUnwrapSnaphuSd')
|
|
|
|
def runUnwrapSnaphuSd(self):
|
|
'''unwrap filtered interferogram
|
|
'''
|
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
|
self.updateParamemetersFromUser()
|
|
|
|
masterTrack = self._insar.loadTrack(master=True)
|
|
#slaveTrack = self._insar.loadTrack(master=False)
|
|
|
|
sdDir = 'sd'
|
|
os.makedirs(sdDir, exist_ok=True)
|
|
os.chdir(sdDir)
|
|
|
|
|
|
############################################################
|
|
# STEP 1. unwrap interferogram
|
|
############################################################
|
|
nsd = len(self._insar.filteredInterferogramSd)
|
|
img = isceobj.createImage()
|
|
img.load(self._insar.filteredInterferogramSd[0]+'.xml')
|
|
width = img.width
|
|
length = img.length
|
|
|
|
if shutil.which('snaphu') != None:
|
|
print('\noriginal snaphu program found, use it for unwrapping interferograms')
|
|
useOriginalSnaphu = True
|
|
#create an amplitude for use
|
|
# amplitude = os.path.join('../insar', self._insar.amplitude)
|
|
# amplitudeMultilook = 'tmp.amp'
|
|
# img = isceobj.createImage()
|
|
# img.load(amplitude+'.xml')
|
|
# look(amplitude, amplitudeMultilook, img.width, self._insar.numberRangeLooksSd, self._insar.numberAzimuthLooksSd, 4, 1, 1)
|
|
else:
|
|
useOriginalSnaphu = False
|
|
|
|
for sdCoherence, sdInterferogramFilt, sdInterferogramUnwrap in zip(self._insar.multilookCoherenceSd, self._insar.filteredInterferogramSd, self._insar.unwrappedInterferogramSd):
|
|
if useOriginalSnaphu:
|
|
amplitudeMultilook = 'tmp.amp'
|
|
cmd = "imageMath.py -e='sqrt(abs(a));sqrt(abs(a))' --a={} -o {} -t float -s BSQ".format(sdInterferogramFilt, amplitudeMultilook)
|
|
runCmd(cmd)
|
|
snaphuUnwrapOriginal(sdInterferogramFilt,
|
|
sdCoherence,
|
|
amplitudeMultilook,
|
|
sdInterferogramUnwrap,
|
|
costMode = 's',
|
|
initMethod = 'mcf')
|
|
os.remove(amplitudeMultilook)
|
|
os.remove(amplitudeMultilook+'.vrt')
|
|
os.remove(amplitudeMultilook+'.xml')
|
|
else:
|
|
tmid = masterTrack.sensingStart + datetime.timedelta(seconds=(self._insar.numberAzimuthLooks1-1.0)/2.0*masterTrack.azimuthLineInterval+
|
|
masterTrack.numberOfLines/2.0*self._insar.numberAzimuthLooks1*masterTrack.azimuthLineInterval)
|
|
snaphuUnwrap(masterTrack, tmid,
|
|
sdInterferogramFilt,
|
|
sdCoherence,
|
|
sdInterferogramUnwrap,
|
|
self._insar.numberRangeLooks1*self._insar.numberRangeLooksSd,
|
|
self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksSd,
|
|
costMode = 'SMOOTH',initMethod = 'MCF', defomax = 2, initOnly = True)
|
|
|
|
#if useOriginalSnaphu:
|
|
# os.remove(amplitudeMultilook)
|
|
|
|
|
|
############################################################
|
|
# STEP 2. mask using connected components
|
|
############################################################
|
|
for sdInterferogramUnwrap, sdInterferogramUnwrapMasked in zip(self._insar.unwrappedInterferogramSd, self._insar.unwrappedMaskedInterferogramSd):
|
|
cmd = "imageMath.py -e='a_0*(b>0);a_1*(b>0)' --a={} --b={} -s BIL -t float -o={}".format(sdInterferogramUnwrap, sdInterferogramUnwrap+'.conncomp', sdInterferogramUnwrapMasked)
|
|
runCmd(cmd)
|
|
|
|
|
|
############################################################
|
|
# STEP 3. mask using water body
|
|
############################################################
|
|
if self.waterBodyMaskStartingStepSd=='unwrap':
|
|
wbd = np.fromfile(self._insar.multilookWbdOutSd, dtype=np.int8).reshape(length, width)
|
|
|
|
for sdInterferogramUnwrap, sdInterferogramUnwrapMasked in zip(self._insar.unwrappedInterferogramSd, self._insar.unwrappedMaskedInterferogramSd):
|
|
unw=np.memmap(sdInterferogramUnwrap, 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
|
|
unw=np.memmap(sdInterferogramUnwrapMasked, 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
|
|
|
|
|
|
############################################################
|
|
# STEP 4. convert to azimuth deformation
|
|
############################################################
|
|
#burst cycle in s
|
|
burstCycleLength = masterTrack.frames[0].swaths[0].burstCycleLength / masterTrack.frames[0].swaths[0].prf
|
|
|
|
#compute azimuth fmrate
|
|
#stack all azimuth fmrates
|
|
index = np.array([], dtype=np.float64)
|
|
ka = np.array([], dtype=np.float64)
|
|
for frame in masterTrack.frames:
|
|
for swath in frame.swaths:
|
|
startingRangeMultilook = masterTrack.frames[0].swaths[0].startingRange + \
|
|
(self._insar.numberRangeLooks1*self._insar.numberRangeLooksSd-1.0)/2.0*masterTrack.frames[0].swaths[0].rangePixelSize
|
|
rangePixelSizeMultilook = self._insar.numberRangeLooks1 * self._insar.numberRangeLooksSd * masterTrack.frames[0].swaths[0].rangePixelSize
|
|
index0 = (swath.startingRange + np.arange(swath.numberOfSamples) * swath.rangePixelSize - startingRangeMultilook) / rangePixelSizeMultilook
|
|
ka0 = np.polyval(swath.azimuthFmrateVsPixel[::-1], np.arange(swath.numberOfSamples))
|
|
index = np.concatenate((index, index0))
|
|
ka = np.concatenate((ka, ka0))
|
|
p = np.polyfit(index, ka, 3)
|
|
#new ka
|
|
ka = np.polyval(p, np.arange(width))
|
|
|
|
#compute radar beam footprint velocity at middle track
|
|
tmid = masterTrack.sensingStart + datetime.timedelta(seconds=(self._insar.numberAzimuthLooks1-1.0)/2.0*masterTrack.azimuthLineInterval+
|
|
masterTrack.numberOfLines/2.0*self._insar.numberAzimuthLooks1*masterTrack.azimuthLineInterval)
|
|
svmid = masterTrack.orbit.interpolateOrbit(tmid, method='hermite')
|
|
#earth radius in meters
|
|
r = 6371 * 1000.0
|
|
#radar footprint velocity
|
|
veln = np.linalg.norm(svmid.getVelocity()) * r / np.linalg.norm(svmid.getPosition())
|
|
print('radar beam footprint velocity at middle track: %8.2f m/s'%veln)
|
|
|
|
#phase to defo factor
|
|
factor = -1.0* veln / (2.0 * np.pi * ka * burstCycleLength)
|
|
|
|
#process unwrapped without mask
|
|
sdunw_out = np.zeros((length*2, width))
|
|
flag = np.zeros((length, width))
|
|
wgt = np.zeros((length, width))
|
|
for i in range(nsd):
|
|
sdunw = np.fromfile(self._insar.unwrappedInterferogramSd[i], dtype=np.float32).reshape(length*2, width)
|
|
sdunw[1:length*2:2, :] *= factor[None, :] / (i+1.0)
|
|
sdunw.astype(np.float32).tofile(self._insar.azimuthDeformationSd[i])
|
|
create_xml(self._insar.azimuthDeformationSd[i], width, length, 'rmg')
|
|
flag += (sdunw[1:length*2:2, :]!=0)
|
|
#since the interferogram is filtered, we only use this light weight
|
|
wgt0 = (i+1)**2
|
|
wgt += wgt0 * (sdunw[1:length*2:2, :]!=0)
|
|
sdunw_out[0:length*2:2, :] += (sdunw[0:length*2:2, :])**2
|
|
sdunw_out[1:length*2:2, :] += wgt0 * sdunw[1:length*2:2, :]
|
|
#output weighting average
|
|
index = np.nonzero(flag!=0)
|
|
(sdunw_out[0:length*2:2, :])[index] = np.sqrt((sdunw_out[0:length*2:2, :])[index] / flag[index])
|
|
(sdunw_out[1:length*2:2, :])[index] = (sdunw_out[1:length*2:2, :])[index] / wgt[index]
|
|
if not self.unionSd:
|
|
(sdunw_out[0:length*2:2, :])[np.nonzero(flag<nsd)] = 0
|
|
(sdunw_out[1:length*2:2, :])[np.nonzero(flag<nsd)] = 0
|
|
sdunw_out.astype(np.float32).tofile(self._insar.azimuthDeformationSd[-1])
|
|
create_xml(self._insar.azimuthDeformationSd[-1], width, length, 'rmg')
|
|
|
|
#process unwrapped with mask
|
|
sdunw_out = np.zeros((length*2, width))
|
|
flag = np.zeros((length, width))
|
|
wgt = np.zeros((length, width))
|
|
for i in range(nsd):
|
|
sdunw = np.fromfile(self._insar.unwrappedMaskedInterferogramSd[i], dtype=np.float32).reshape(length*2, width)
|
|
sdunw[1:length*2:2, :] *= factor[None, :] / (i+1.0)
|
|
sdunw.astype(np.float32).tofile(self._insar.maskedAzimuthDeformationSd[i])
|
|
create_xml(self._insar.maskedAzimuthDeformationSd[i], width, length, 'rmg')
|
|
flag += (sdunw[1:length*2:2, :]!=0)
|
|
#since the interferogram is filtered, we only use this light weight
|
|
wgt0 = (i+1)**2
|
|
wgt += wgt0 * (sdunw[1:length*2:2, :]!=0)
|
|
sdunw_out[0:length*2:2, :] += (sdunw[0:length*2:2, :])**2
|
|
sdunw_out[1:length*2:2, :] += wgt0 * sdunw[1:length*2:2, :]
|
|
#output weighting average
|
|
index = np.nonzero(flag!=0)
|
|
(sdunw_out[0:length*2:2, :])[index] = np.sqrt((sdunw_out[0:length*2:2, :])[index] / flag[index])
|
|
(sdunw_out[1:length*2:2, :])[index] = (sdunw_out[1:length*2:2, :])[index] / wgt[index]
|
|
if not self.unionSd:
|
|
(sdunw_out[0:length*2:2, :])[np.nonzero(flag<nsd)] = 0
|
|
(sdunw_out[1:length*2:2, :])[np.nonzero(flag<nsd)] = 0
|
|
sdunw_out.astype(np.float32).tofile(self._insar.maskedAzimuthDeformationSd[-1])
|
|
create_xml(self._insar.maskedAzimuthDeformationSd[-1], width, length, 'rmg')
|
|
|
|
os.chdir('../')
|
|
|
|
catalog.printToLog(logger, "runUnwrapSnaphuSd")
|
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
|
|