124 lines
5.4 KiB
Python
124 lines
5.4 KiB
Python
#
|
|
# 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)
|