ISCE_INSAR/components/isceobj/ScansarProc/runEstimateBurstSync.py

124 lines
5.4 KiB
Python
Raw Normal View History

2019-01-16 19:40:08 +00:00
#
# Author: Piyush Agram
# Copyright 2016
#
import logging
import isceobj
import os
import numpy as np
import datetime
logger = logging.getLogger('isce.scansarinsar.runEstimateBurstSync')
def runEstimateBurstSync(self):
'''Estimate burst sync between acquisitions.
'''
swathList = self._insar.getValidSwathList(self.swaths)
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
print('Common swaths: ', swathList)
if not os.path.isdir(self._insar.burstSyncDirectory):
os.makedirs(self._insar.burstSyncDirectory)
for ind, swath in enumerate(swathList):
##Load master swath
master = self._insar.loadProduct( os.path.join(self._insar.equalizedMasterSlcProduct,
's{0}.xml'.format(swath)))
##Load slave swath
slave = self._insar.loadProduct( os.path.join(self._insar.equalizedSlaveSlcProduct,
's{0}.xml'.format(swath)))
##Replacing Cunren's original high fidelity implementation with simpler more efficient one
##To estimate burst sync, we dont really need the DEM. Hardly changes with topography
##Topo impacts range offset but hardly affects azimuth offsets. Hence using a single estimate
##At mid range and start of middle burst of the master.
##In the original implementation - topo and geo2rdr were performed to the mid 100 lines of
##master image. Eventually, offset estimates were averaged to a single number.
##Our single estimate gets us to that number in a simpler manner.
###Get mid range for middle burst of master
midRange = master.startingRange + 0.5 * master.numberOfSamples * master.instrument.rangePixelSize
midLine = master.burstStartLines[len(master.burstStartLines)//2]
tmaster = master.sensingStart + datetime.timedelta(seconds = midLine / master.PRF)
llh = master.orbit.rdr2geo(tmaster, midRange)
slvaz, slvrng = slave.orbit.geo2rdr(llh)
###Translate to offsets
rgoff = ((slvrng - slave.startingRange) / slave.instrument.rangePixelSize) - 0.5 * master.numberOfSamples
azoff = ((slvaz - slave.sensingStart).total_seconds() * slave.PRF) - midLine
##Jumping back to Cunren's original code
scburstStartLine = master.burstStartLines[0] + azoff
nb = slave.nbraw
nc = slave.ncraw
#Slave burst start times corresponding to master burst start times implies 100% synchronization
scburstStartLines = scburstStartLine + np.arange(-100000, 100000)*nc
dscburstStartLines = -(slave.burstStartLines[0] - scburstStartLines)
unsynLines = dscburstStartLines[ np.argmin( np.abs(dscburstStartLines))]
if np.abs(unsynLines) >= nb:
synLines = 0
if unsynLines > 0:
unsynLines = nb
else:
unsynLines = -nb
else:
synLines = nb - np.abs(unsynLines)
##Copy of illustration from Cunren's code
############################################################# ###############################
#illustration of the sign of the number of unsynchronized lin es (unsynLines)
#The convention is the same as ampcor offset, that is,
# slaveLineNumber = masterLineNumber + unsynLine s
#
# |-----------------------| ------------
# | | ^
# | | |
# | | | unsynLines < 0
# | | |
# | | \ /
# | | |-----------------------|
# | | | |
# | | | |
# |-----------------------| | |
# Master Burst | |
# | |
# | |
# | |
# | |
# |-----------------------|
# Slave Burst
#
#
############################################################# ###############################
##For now keeping Cunren's text file format.
##Could be streamlined
outfile = os.path.join(self._insar.burstSyncDirectory, 's{0}.txt'.format(swath))
self._insar.writeBurstSyncFile(outfile, rgoff, azoff,
nb, nc,
unsynLines, synLines)
synPerc = (synLines/nb)*100.0
if synPerc < self.burstOverlapThreshold:
print('Sync overlap {0} < {1}. Will trigger common azimuth spectra filter for swath {2}'.format(synPerc, self.burstOverlapThreshold, swath))
else:
print('Sync overlap {0} >= {1}. No common azimuth spectra filter applied for swath {2}'.format(synPerc, self.burstOverlapThreshold, swath))
catalog.printToLog(logger, "runEstimateBurstSync")
self._insar.procDoc.addAllFromCatalog(catalog)