ISCE_INSAR/components/isceobj/TopsProc/runRangeCoreg.py

192 lines
5.6 KiB
Python

#
# Author: Piyush Agram
# Copyright 2016
#
import numpy as np
import os
import isceobj
import logging
import datetime
from isceobj.Location.Offset import OffsetField, Offset
logger = logging.getLogger('isce.topsinsar.rangecoreg')
def runAmpcor(reference, secondary):
'''
Run one ampcor process.
'''
import isceobj
from mroipac.ampcor.Ampcor import Ampcor
mImg = isceobj.createSlcImage()
mImg.load(reference + '.xml')
mImg.setAccessMode('READ')
mImg.createImage()
sImg = isceobj.createSlcImage()
sImg.load(secondary + '.xml')
sImg.setAccessMode('READ')
sImg.createImage()
objAmpcor = Ampcor('ampcor_burst')
objAmpcor.configure()
objAmpcor.setImageDataType1('mag')
objAmpcor.setImageDataType2('mag')
if objAmpcor.acrossGrossOffset is None:
coarseAcross = 0
if objAmpcor.downGrossOffset is None:
coarseDown = 0
objAmpcor.windowSizeWidth = 64
objAmpcor.windowSizeHeight = 32
objAmpcor.searchWindowSizeWidth = 16
objAmpcor.searchWindowSizeHeight = 16
objAmpcor.oversamplingFactor = 32
xMargin = 2*objAmpcor.searchWindowSizeWidth + objAmpcor.windowSizeWidth
yMargin = 2*objAmpcor.searchWindowSizeHeight + objAmpcor.windowSizeHeight
firstAc = 1000
#####Compute image positions
offDn = objAmpcor.windowSizeHeight//2 + 1
offAc = firstAc+xMargin
offDnmax = mImg.getLength() - objAmpcor.windowSizeHeight//2 - 1
lastAc = int(mImg.width - 1000 - xMargin)
if not objAmpcor.firstSampleAcross:
objAmpcor.setFirstSampleAcross(offAc)
if not objAmpcor.lastSampleAcross:
objAmpcor.setLastSampleAcross(lastAc)
if not objAmpcor.numberLocationAcross:
objAmpcor.setNumberLocationAcross(40)
if not objAmpcor.firstSampleDown:
objAmpcor.setFirstSampleDown(offDn)
if not objAmpcor.lastSampleDown:
objAmpcor.setLastSampleDown(offDnmax)
###Since we are only dealing with overlaps
objAmpcor.setNumberLocationDown(20)
#####Override gross offsets if not provided
if not objAmpcor.acrossGrossOffset:
objAmpcor.setAcrossGrossOffset(coarseAcross)
if not objAmpcor.downGrossOffset:
objAmpcor.setDownGrossOffset(coarseDown)
objAmpcor.setImageDataType1('mag')
objAmpcor.setImageDataType2('mag')
objAmpcor.setFirstPRF(1.0)
objAmpcor.setSecondPRF(1.0)
objAmpcor.setFirstRangeSpacing(1.0)
objAmpcor.setSecondRangeSpacing(1.0)
objAmpcor(mImg, sImg)
mImg.finalizeImage()
sImg.finalizeImage()
return objAmpcor.getOffsetField()
def runRangeCoreg(self, debugPlot=True):
'''
Estimate constant offset in range.
'''
if not self.doESD:
return
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
swathList = self._insar.getValidSwathList(self.swaths)
rangeOffsets = []
snr = []
for swath in swathList:
if self._insar.numberOfCommonBursts[swath-1] < 2:
print('Skipping range coreg for swath IW{0}'.format(swath))
continue
minBurst, maxBurst = self._insar.commonReferenceBurstLimits(swath-1)
maxBurst = maxBurst - 1 ###For overlaps
referenceTop = self._insar.loadProduct( os.path.join(self._insar.referenceSlcOverlapProduct, 'top_IW{0}.xml'.format(swath)))
referenceBottom = self._insar.loadProduct( os.path.join(self._insar.referenceSlcOverlapProduct , 'bottom_IW{0}.xml'.format(swath)))
secondaryTop = self._insar.loadProduct( os.path.join(self._insar.coregOverlapProduct , 'top_IW{0}.xml'.format(swath)))
secondaryBottom = self._insar.loadProduct( os.path.join(self._insar.coregOverlapProduct, 'bottom_IW{0}.xml'.format(swath)))
for pair in [(referenceTop,secondaryTop), (referenceBottom,secondaryBottom)]:
for ii in range(minBurst,maxBurst):
mFile = pair[0].bursts[ii-minBurst].image.filename
sFile = pair[1].bursts[ii-minBurst].image.filename
field = runAmpcor(mFile, sFile)
for offset in field:
rangeOffsets.append(offset.dx)
snr.append(offset.snr)
###Cull
mask = np.logical_and(np.array(snr) > self.offsetSNRThreshold, np.abs(rangeOffsets) < 1.2)
val = np.array(rangeOffsets)[mask]
medianval = np.median(val)
meanval = np.mean(val)
stdval = np.std(val)
hist, bins = np.histogram(val, 50, density=True)
center = 0.5*(bins[:-1] + bins[1:])
try:
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
except:
print('Matplotlib could not be imported. Skipping debug plot ...')
debugPlot = False
if debugPlot:
try:
####Plotting
plt.figure()
plt.bar(center, hist, align='center', width = 0.7*(bins[1] - bins[0]))
plt.xlabel('Range shift in pixels')
plt.savefig( os.path.join(self._insar.esdDirname, 'rangeMisregistration.jpg'))
plt.close()
except:
print('Looks like matplotlib could not save image to JPEG, continuing .....')
print('Install Pillow to ensure debug plots for Residual range offsets are generated.')
pass
catalog.addItem('Median', medianval, 'esd')
catalog.addItem('Mean', meanval, 'esd')
catalog.addItem('Std', stdval, 'esd')
catalog.addItem('snr threshold', self.offsetSNRThreshold, 'esd')
catalog.addItem('number of coherent points', val.size, 'esd')
catalog.printToLog(logger, "runRangeCoreg")
self._insar.procDoc.addAllFromCatalog(catalog)
self._insar.secondaryRangeCorrection = meanval * referenceTop.bursts[0].rangePixelSize