ISCE_INSAR/components/isceobj/Alos2Proc/runSlcMatch.py

273 lines
11 KiB
Python

#
# Author: Cunren Liang
# Copyright 2015-present, NASA-JPL/Caltech
#
import os
import logging
import numpy as np
import isceobj
from isceobj.Alos2Proc.runRdr2Geo import topoCPU
from isceobj.Alos2Proc.runRdr2Geo import topoGPU
from isceobj.Alos2Proc.runGeo2Rdr import geo2RdrCPU
from isceobj.Alos2Proc.runGeo2Rdr import geo2RdrGPU
from contrib.alos2proc.alos2proc import resamp
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
from isceobj.Alos2Proc.Alos2ProcPublic import renameFile
from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar
from mroipac.ampcor.Ampcor import Ampcor
from isceobj.Alos2Proc.Alos2ProcPublic import meanOffset
from isceobj.Alos2Proc.Alos2ProcPublic import cullOffsetsRoipac
logger = logging.getLogger('isce.alos2insar.runSlcMatch')
def runSlcMatch(self):
'''match a pair of SLCs
'''
if not self.doDenseOffset:
return
if not ((self._insar.modeCombination == 0) or (self._insar.modeCombination == 1)):
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
self.updateParamemetersFromUser()
demFile = os.path.abspath(self._insar.dem)
wbdFile = os.path.abspath(self._insar.wbd)
denseOffsetDir = 'dense_offset'
os.makedirs(denseOffsetDir, exist_ok=True)
os.chdir(denseOffsetDir)
masterTrack = self._insar.loadProduct(self._insar.masterTrackParameter)
slaveTrack = self._insar.loadProduct(self._insar.slaveTrackParameter)
#########################################################################################
##################################################
# compute geometric offsets
##################################################
if self.useGPU and self._insar.hasGPU():
topoGPU(masterTrack, 1, 1, demFile,
'lat.rdr', 'lon.rdr', 'hgt.rdr', 'los.rdr')
geo2RdrGPU(slaveTrack, 1, 1,
'lat.rdr', 'lon.rdr', 'hgt.rdr', 'rg.off', 'az.off')
else:
topoCPU(masterTrack, 1, 1, demFile,
'lat.rdr', 'lon.rdr', 'hgt.rdr', 'los.rdr')
geo2RdrCPU(slaveTrack, 1, 1,
'lat.rdr', 'lon.rdr', 'hgt.rdr', 'rg.off', 'az.off')
##################################################
# resample SLC
##################################################
#SlaveSlcResampled = os.path.splitext(self._insar.slaveSlc)[0]+'_resamp'+os.path.splitext(self._insar.slaveSlc)[1]
SlaveSlcResampled = self._insar.slaveSlcCoregistered
rangeOffsets2Frac = 0.0
azimuthOffsets2Frac = 0.0
resamp(self._insar.slaveSlc,
SlaveSlcResampled,
'rg.off',
'az.off',
masterTrack.numberOfSamples, masterTrack.numberOfLines,
slaveTrack.prf,
slaveTrack.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(SlaveSlcResampled, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'slc')
if self.estimateResidualOffset:
numberOfOffsets = 800
rangeStep = 50
length = masterTrack.numberOfLines
width = masterTrack.numberOfSamples
waterBodyRadar('lat.rdr', 'lon.rdr', wbdFile, 'wbd.rdr')
wbd=np.memmap('wbd.rdr', dtype=np.int8, mode='r', shape=(length, width))
azimuthStep = int(length/width*rangeStep+0.5)
landRatio = np.sum(wbd[0:length:azimuthStep,0:width:rangeStep]!=-1)/(int(length/azimuthStep)*int(width/rangeStep))
del wbd
if (landRatio <= 0.00125):
print('\n\nWARNING: land area too small for estimating residual slc offsets')
print('do not estimate residual offsets\n\n')
catalog.addItem('warning message', 'land area too small for estimating residual slc offsets', 'runSlcMatch')
else:
numberOfOffsets /= landRatio
#we use equal number of offsets in range and azimuth here
numberOfOffsetsRange = int(np.sqrt(numberOfOffsets)+0.5)
numberOfOffsetsAzimuth = int(np.sqrt(numberOfOffsets)+0.5)
if numberOfOffsetsRange > int(width/2):
numberOfOffsetsRange = int(width/2)
if numberOfOffsetsAzimuth > int(length/2):
numberOfOffsetsAzimuth = int(length/2)
if numberOfOffsetsRange < 10:
numberOfOffsetsRange = 10
if numberOfOffsetsAzimuth < 10:
numberOfOffsetsAzimuth = 10
##########################################
#2. match using ampcor
##########################################
ampcor = Ampcor(name='insarapp_slcs_ampcor')
ampcor.configure()
mSLC = isceobj.createSlcImage()
mSLC.load(self._insar.masterSlc+'.xml')
mSLC.setAccessMode('read')
mSLC.createImage()
sSLC = isceobj.createSlcImage()
sSLC.load(SlaveSlcResampled+'.xml')
sSLC.setAccessMode('read')
sSLC.createImage()
ampcor.setImageDataType1('complex')
ampcor.setImageDataType2('complex')
ampcor.setMasterSlcImage(mSLC)
ampcor.setSlaveSlcImage(sSLC)
#MATCH REGION
#compute an offset at image center to use
rgoff = 0.0
azoff = 0.0
#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(numberOfOffsetsRange)
ampcor.setFirstSampleDown(firstLine)
ampcor.setLastSampleDown(mSLC.length)
ampcor.setNumberLocationDown(numberOfOffsetsAzimuth)
#MATCH PARAMETERS
#full-aperture mode
if (self._insar.modeCombination == 21) or \
(self._insar.modeCombination == 22) or \
(self._insar.modeCombination == 31) or \
(self._insar.modeCombination == 32):
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(16)
ampcor.setSearchWindowSizeHeight(16)
#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()
mSLC.finalizeImage()
sSLC.finalizeImage()
#3. cull offsets
refinedOffsets = cullOffsetsRoipac(offsets, numThreshold=50)
if refinedOffsets == None:
print('\n\nWARNING: too few offsets left for slc residual offset estimation')
print('do not estimate residual offsets\n\n')
catalog.addItem('warning message', 'too few offsets left for slc residual offset estimation', 'runSlcMatch')
else:
rangeOffset, azimuthOffset = meanOffset(refinedOffsets)
os.remove(SlaveSlcResampled)
os.remove(SlaveSlcResampled+'.vrt')
os.remove(SlaveSlcResampled+'.xml')
rangeOffsets2Frac = rangeOffset
azimuthOffsets2Frac = azimuthOffset
resamp(self._insar.slaveSlc,
SlaveSlcResampled,
'rg.off',
'az.off',
masterTrack.numberOfSamples, masterTrack.numberOfLines,
slaveTrack.prf,
slaveTrack.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(SlaveSlcResampled, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'slc')
catalog.addItem('number of offsets range', numberOfOffsetsRange, 'runSlcMatch')
catalog.addItem('number of offsets azimuth', numberOfOffsetsAzimuth, 'runSlcMatch')
catalog.addItem('range residual offset after geometric coregistration', rangeOffset, 'runSlcMatch')
catalog.addItem('azimuth residual offset after geometric coregistration', azimuthOffset, 'runSlcMatch')
if self.deleteGeometryFiles:
os.remove('lat.rdr')
os.remove('lat.rdr.vrt')
os.remove('lat.rdr.xml')
os.remove('lon.rdr')
os.remove('lon.rdr.vrt')
os.remove('lon.rdr.xml')
os.remove('hgt.rdr')
os.remove('hgt.rdr.vrt')
os.remove('hgt.rdr.xml')
os.remove('los.rdr')
os.remove('los.rdr.vrt')
os.remove('los.rdr.xml')
# if os.path.isfile('wbd.rdr'):
# os.remove('wbd.rdr')
# os.remove('wbd.rdr.vrt')
# os.remove('wbd.rdr.xml')
#########################################################################################
os.chdir('../')
catalog.printToLog(logger, "runSlcMatch")
self._insar.procDoc.addAllFromCatalog(catalog)