def runUnwrapSnaphu(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) insarDir = 'insar' os.makedirs(insarDir, exist_ok=True) os.chdir(insarDir) ############################################################ # STEP 1. unwrap interferogram ############################################################ if shutil.which('snaphu') != None: print('\noriginal snaphu program found') print( 'unwrap {} using original snaphu, rather than that in ISCE'.format( self._insar.filteredInterferogram)) snaphuUnwrapOriginal(self._insar.filteredInterferogram, self._insar.multilookPhsig, self._insar.multilookAmplitude, self._insar.unwrappedInterferogram, costMode='s', initMethod='mcf') 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, self._insar.filteredInterferogram, self._insar.multilookPhsig, self._insar.unwrappedInterferogram, self._insar.numberRangeLooks1 * self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks1 * self._insar.numberAzimuthLooks2, costMode='SMOOTH', initMethod='MCF', defomax=2, initOnly=True) ############################################################ # STEP 2. mask using connected components ############################################################ cmd = "imageMath.py -e='a_0*(b>0);a_1*(b>0)' --a={} --b={} -s BIL -t float -o={}".format( self._insar.unwrappedInterferogram, self._insar.unwrappedInterferogram + '.conncomp', self._insar.unwrappedMaskedInterferogram) runCmd(cmd) ############################################################ # STEP 3. mask using water body ############################################################ if self.waterBodyMaskStartingStep == 'unwrap': wbdImage = isceobj.createImage() 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 os.chdir('../') catalog.printToLog(logger, "runUnwrapSnaphu") self._insar.procDoc.addAllFromCatalog(catalog)
def runIonUwrap(self): '''unwrap subband interferograms ''' catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) self.updateParamemetersFromUser() if not self.doIon: catalog.printToLog(logger, "runIonUwrap") self._insar.procDoc.addAllFromCatalog(catalog) return referenceTrack = self._insar.loadTrack(reference=True) secondaryTrack = self._insar.loadTrack(reference=False) wbdFile = os.path.abspath(self._insar.wbd) 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 1. take looks ############################################################ from isceobj.Alos2Proc.Alos2ProcPublic import create_xml from contrib.alos2proc.alos2proc import look from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar ml2 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon) for k in range(2): fullbandDir = os.path.join('../../', ionDir['insar']) subbandDir = os.path.join('../', ionDir['subband'][k], ionDir['insar']) prefix = subbandPrefix[k] amp = isceobj.createImage() amp.load(os.path.join(subbandDir, self._insar.amplitude)+'.xml') width = amp.width length = amp.length width2 = int(width / self._insar.numberRangeLooksIon) length2 = int(length / self._insar.numberAzimuthLooksIon) #take looks look(os.path.join(subbandDir, self._insar.differentialInterferogram), prefix+ml2+'.int', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 4, 0, 1) create_xml(prefix+ml2+'.int', width2, length2, 'int') look(os.path.join(subbandDir, self._insar.amplitude), prefix+ml2+'.amp', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 4, 1, 1) create_xml(prefix+ml2+'.amp', width2, length2, 'amp') # #water body # if k == 0: # wbdOutFile = os.path.join(fullbandDir, self._insar.wbdOut) # if os.path.isfile(wbdOutFile): # look(wbdOutFile, 'wbd'+ml2+'.wbd', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 0, 0, 1) # create_xml('wbd'+ml2+'.wbd', width2, length2, 'byte') #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) 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') ############################################################ # STEP 2. compute coherence ############################################################ from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence lowerbandInterferogramFile = subbandPrefix[0]+ml2+'.int' upperbandInterferogramFile = subbandPrefix[1]+ml2+'.int' lowerbandAmplitudeFile = subbandPrefix[0]+ml2+'.amp' upperbandAmplitudeFile = subbandPrefix[1]+ml2+'.amp' lowerbandCoherenceFile = subbandPrefix[0]+ml2+'.cor' upperbandCoherenceFile = subbandPrefix[1]+ml2+'.cor' coherenceFile = 'diff'+ml2+'.cor' lowerint = np.fromfile(lowerbandInterferogramFile, dtype=np.complex64).reshape(length2, width2) upperint = np.fromfile(upperbandInterferogramFile, dtype=np.complex64).reshape(length2, width2) loweramp = np.fromfile(lowerbandAmplitudeFile, dtype=np.float32).reshape(length2, width2*2) upperamp = np.fromfile(upperbandAmplitudeFile, dtype=np.float32).reshape(length2, width2*2) #compute coherence only using interferogram #here I use differential interferogram of lower and upper band interferograms #so that coherence is not affected by fringes cord = cal_coherence(lowerint*np.conjugate(upperint), win=3, edge=4) cor = np.zeros((length2*2, width2), dtype=np.float32) cor[0:length2*2:2, :] = np.sqrt( (np.absolute(lowerint)+np.absolute(upperint))/2.0 ) cor[1:length2*2:2, :] = cord cor.astype(np.float32).tofile(coherenceFile) create_xml(coherenceFile, width2, length2, 'cor') #create lower and upper band coherence files #lower amp1 = loweramp[:, 0:width2*2:2] amp2 = loweramp[:, 1:width2*2:2] cor[1:length2*2:2, :] = np.absolute(lowerint)/(amp1+(amp1==0))/(amp2+(amp2==0))*(amp1!=0)*(amp2!=0) cor.astype(np.float32).tofile(lowerbandCoherenceFile) create_xml(lowerbandCoherenceFile, width2, length2, 'cor') #upper amp1 = upperamp[:, 0:width2*2:2] amp2 = upperamp[:, 1:width2*2:2] cor[1:length2*2:2, :] = np.absolute(upperint)/(amp1+(amp1==0))/(amp2+(amp2==0))*(amp1!=0)*(amp2!=0) cor.astype(np.float32).tofile(upperbandCoherenceFile) create_xml(upperbandCoherenceFile, width2, length2, 'cor') ############################################################ # STEP 3. filtering subband interferograms ############################################################ from contrib.alos2filter.alos2filter import psfilt1 from isceobj.Alos2Proc.Alos2ProcPublic import runCmd from isceobj.Alos2Proc.Alos2ProcPublic import create_xml from mroipac.icu.Icu import Icu if self.filterSubbandInt: for k in range(2): 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) else: #scale the inteferogram, otherwise its magnitude is too large for filtering cmd = "imageMath.py -e='a/100000.0' --a={} -o {} -t cfloat -s BSQ".format(subbandPrefix[k]+ml2+'.int', toBeFiltered) runCmd(cmd) intImage = isceobj.createIntImage() intImage.load(toBeFiltered + '.xml') width = intImage.width length = intImage.length windowSize = self.filterWinsizeSubbandInt stepSize = self.filterStepsizeSubbandInt psfilt1(toBeFiltered, 'filt_'+subbandPrefix[k]+ml2+'.int', width, self.filterStrengthSubbandInt, windowSize, stepSize) create_xml('filt_'+subbandPrefix[k]+ml2+'.int', width, length, 'int') os.remove(toBeFiltered) 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() #amplitude image ampImage = isceobj.createAmpImage() ampImage.load(subbandPrefix[k]+ml2+'.amp' + '.xml') ampImage.setAccessMode('read') ampImage.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() icu = Icu(name='insarapp_filter_icu') icu.configure() icu.unwrappingFlag = False icu.icu(intImage = filtImage, ampImage=ampImage, phsigImage=phsigImage) phsigImage.renderHdr() filtImage.finalizeImage() ampImage.finalizeImage() phsigImage.finalizeImage() ############################################################ # STEP 4. phase unwrapping ############################################################ from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrap for k in range(2): tmid = referenceTrack.sensingStart + datetime.timedelta(seconds=(self._insar.numberAzimuthLooks1-1.0)/2.0*referenceTrack.azimuthLineInterval+ referenceTrack.numberOfLines/2.0*self._insar.numberAzimuthLooks1*referenceTrack.azimuthLineInterval) if self.filterSubbandInt: toBeUnwrapped = 'filt_'+subbandPrefix[k]+ml2+'.int' coherenceFile = subbandPrefix[k]+ml2+'.phsig' else: 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)
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' if not os.path.exists(sdDir): os.makedirs(sdDir) 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)