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 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 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 runIonFilt(self): '''compute and filter ionospheric phase ''' catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) self.updateParamemetersFromUser() if not self.doIon: catalog.printToLog(logger, "runIonFilt") self._insar.procDoc.addAllFromCatalog(catalog) return masterTrack = self._insar.loadTrack(master=True) slaveTrack = self._insar.loadTrack(master=False) from isceobj.Alos2Proc.runIonSubband import defineIonDir ionDir = defineIonDir() subbandPrefix = ['lower', 'upper'] ionCalDir = os.path.join(ionDir['ion'], ionDir['ionCal']) if not os.path.exists(ionCalDir): os.makedirs(ionCalDir) os.chdir(ionCalDir) ############################################################ # 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.85 ################################### 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 #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, fl, fu, adjFlag, corThresholdAdj, 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 ############################################################ ################################################# #SET PARAMETERS HERE #if applying polynomial fitting #False: no fitting, True: with fitting fit = self.fitIon #gaussian filtering window size size_max = self.filteringWinsizeMaxIon size_min = self.filteringWinsizeMinIon #THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self) corThresholdIon = 0.85 ################################################# print('\nfiltering ionosphere') ionfile = 'ion'+ml2+'.ion' corfile = 'diff'+ml2+'.cor' ionfiltfile = 'filt_ion'+ml2+'.ion' img = isceobj.createImage() img.load(ionfile + '.xml') width = img.width length = img.length #ion = (np.fromfile(ionfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :] ion = np.fromfile(ionfile, dtype=np.float32).reshape(length, width) cor = (np.fromfile(corfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :] #amp = (np.fromfile(ionfile, 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: 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 # #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 if fit: ion_fit = weight_fitting(ion, cor, width, length, 1, 1, 1, 1, 2, corThresholdIon) ion -= ion_fit * (ion!=0) #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(ion, cor**14, size_max, size_min) if fit: filt += ion_fit * (filt!=0) # ion = np.zeros((length*2, width), dtype=np.float32) # ion[0:length*2:2, :] = amp # ion[1:length*2:2, :] = filt # ion.astype(np.float32).tofile(ionfiltfile) # img.filename = ionfiltfile # img.extraFilename = ionfiltfile + '.vrt' # img.renderHdr() filt.astype(np.float32).tofile(ionfiltfile) create_xml(ionfiltfile, 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('../') catalog.printToLog(logger, "runIonFilt") self._insar.procDoc.addAllFromCatalog(catalog)
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)