ISCE_INSAR/contrib/stack/stripmapStack/refineSlaveTiming.py

250 lines
7.3 KiB
Python
Raw Normal View History

2019-01-16 19:40:08 +00:00
#!/usr/bin/env python3
import numpy as np
import argparse
import os
import isce
import isceobj
import shelve
import datetime
from isceobj.Location.Offset import OffsetField
from iscesys.StdOEL.StdOELPy import create_writer
from mroipac.ampcor.Ampcor import Ampcor
import pickle
def createParser():
'''
Command line parser.
'''
parser = argparse.ArgumentParser( description='Generate offset field between two Sentinel swaths')
parser.add_argument('-m','--master', type=str, dest='master', required=True,
help='Master image')
parser.add_argument('--mm', type=str, dest='metamaster', default=None,
help='Master meta data dir')
parser.add_argument('-s', '--slave', type=str, dest='slave', required=True,
help='Slave image')
parser.add_argument('--ss', type=str, dest='metaslave', default=None,
help='Slave meta data dir')
parser.add_argument('-o', '--outfile',type=str, required=True, dest='outfile',
help='Misregistration in subpixels')
parser.add_argument('--aa', dest='azazorder', type=int, default=0,
help = 'Azimuth order of azimuth offsets')
parser.add_argument('--ar', dest='azrgorder', type=int, default=0,
help = 'Range order of azimuth offsets')
parser.add_argument('--ra', dest='rgazorder', type=int, default=0,
help = 'Azimuth order of range offsets')
parser.add_argument('--rr', dest='rgrgorder', type=int, default=0,
help = 'Range order of range offsets')
parser.add_argument('--ao', dest='azoff', type=int, default=0,
help='Azimuth gross offset')
parser.add_argument('--ro', dest='rgoff', type=int, default=0,
help='Range gross offset')
parser.add_argument('-t', '--thresh', dest='snrthresh', type=float, default=5.0,
help='SNR threshold')
return parser
def cmdLineParse(iargs = None):
parser = createParser()
return parser.parse_args(args=iargs)
def estimateOffsetField(master, slave, azoffset=0, rgoffset=0):
'''
Estimate offset field between burst and simamp.
'''
sim = isceobj.createSlcImage()
sim.load(slave+'.xml')
sim.setAccessMode('READ')
sim.createImage()
sar = isceobj.createSlcImage()
sar.load(master + '.xml')
sar.setAccessMode('READ')
sar.createImage()
width = sar.getWidth()
length = sar.getLength()
objOffset = Ampcor(name='master_offset1')
objOffset.configure()
objOffset.setAcrossGrossOffset(rgoffset)
objOffset.setDownGrossOffset(azoffset)
objOffset.setWindowSizeWidth(128)
objOffset.setWindowSizeHeight(128)
objOffset.setSearchWindowSizeWidth(40)
objOffset.setSearchWindowSizeHeight(40)
margin = 2*objOffset.searchWindowSizeWidth + objOffset.windowSizeWidth
nAcross = 60
nDown = 60
offAc = max(101,-rgoffset)+margin
offDn = max(101,-azoffset)+margin
lastAc = int( min(width, sim.getWidth() - offAc) - margin)
lastDn = int( min(length, sim.getLength() - offDn) - margin)
# print('Across: ', offAc, lastAc, width, sim.getWidth(), margin)
# print('Down: ', offDn, lastDn, length, sim.getLength(), margin)
if not objOffset.firstSampleAcross:
objOffset.setFirstSampleAcross(offAc)
if not objOffset.lastSampleAcross:
objOffset.setLastSampleAcross(lastAc)
if not objOffset.firstSampleDown:
objOffset.setFirstSampleDown(offDn)
if not objOffset.lastSampleDown:
objOffset.setLastSampleDown(lastDn)
if not objOffset.numberLocationAcross:
objOffset.setNumberLocationAcross(nAcross)
if not objOffset.numberLocationDown:
objOffset.setNumberLocationDown(nDown)
objOffset.setFirstPRF(1.0)
objOffset.setSecondPRF(1.0)
objOffset.setImageDataType1('complex')
objOffset.setImageDataType2('complex')
objOffset.ampcor(sar, sim)
sar.finalizeImage()
sim.finalizeImage()
result = objOffset.getOffsetField()
return result
def fitOffsets(field,azrgOrder=0,azazOrder=0,
rgrgOrder=0,rgazOrder=0,snr=5.0):
'''
Estimate constant range and azimith shifs.
'''
stdWriter = create_writer("log","",True,filename='off.log')
for distance in [10,5,3,1]:
inpts = len(field._offsets)
objOff = isceobj.createOffoutliers()
objOff.wireInputPort(name='offsets', object=field)
objOff.setSNRThreshold(snr)
objOff.setDistance(distance)
objOff.setStdWriter(stdWriter)
objOff.offoutliers()
field = objOff.getRefinedOffsetField()
outputs = len(field._offsets)
print('%d points left'%(len(field._offsets)))
aa, dummy = field.getFitPolynomials(azimuthOrder=azazOrder, rangeOrder=azrgOrder, usenumpy=True)
dummy, rr = field.getFitPolynomials(azimuthOrder=rgazOrder, rangeOrder=rgrgOrder, usenumpy=True)
azshift = aa._coeffs[0][0]
rgshift = rr._coeffs[0][0]
print('Estimated az shift: ', azshift)
print('Estimated rg shift: ', rgshift)
return (aa, rr), field
def main(iargs=None):
'''
Generate offset fields burst by burst.
'''
inps = cmdLineParse(iargs)
field = estimateOffsetField(inps.master, inps.slave,
azoffset=inps.azoff, rgoffset=inps.rgoff)
if os.path.exists(inps.outfile):
os.remove(inps.outfile)
outDir = os.path.dirname(inps.outfile)
if not os.path.exists(outDir):
os.makedirs(outDir)
if inps.metamaster is not None:
masterShelveDir = os.path.join(outDir, 'masterShelve')
if not os.path.exists(masterShelveDir):
os.makedirs(masterShelveDir)
cmd = 'cp ' + inps.metamaster + '/data* ' + masterShelveDir
os.system(cmd)
if inps.metaslave is not None:
slaveShelveDir = os.path.join(outDir, 'slaveShelve')
if not os.path.exists(slaveShelveDir):
os.makedirs(slaveShelveDir)
cmd = 'cp ' + inps.metaslave + '/data* ' + slaveShelveDir
os.system(cmd)
rgratio = 1.0
azratio = 1.0
if (inps.metamaster is not None) and (inps.metaslave is not None):
# with shelve.open( os.path.join(inps.metamaster, 'data'), 'r') as db:
with shelve.open( os.path.join(masterShelveDir, 'data'), 'r') as db:
mframe = db['frame']
# with shelve.open( os.path.join(inps.metaslave, 'data'), 'r') as db:
with shelve.open( os.path.join(slaveShelveDir, 'data'), 'r') as db:
sframe = db['frame']
rgratio = mframe.instrument.getRangePixelSize()/sframe.instrument.getRangePixelSize()
azratio = sframe.PRF / mframe.PRF
print ('*************************************')
print ('rgratio, azratio: ', rgratio, azratio)
print ('*************************************')
odb = shelve.open(inps.outfile)
odb['raw_field'] = field
shifts, cull = fitOffsets(field,azazOrder=inps.azazorder,
azrgOrder=inps.azrgorder,
rgazOrder=inps.rgazorder,
rgrgOrder=inps.rgrgorder,
snr=inps.snrthresh)
odb['cull_field'] = cull
####Scale by ratio
for row in shifts[0]._coeffs:
for ind, val in enumerate(row):
row[ind] = val * azratio
for row in shifts[1]._coeffs:
for ind, val in enumerate(row):
row[ind] = val * rgratio
odb['azpoly'] = shifts[0]
odb['rgpoly'] = shifts[1]
odb.close()
if __name__ == '__main__':
main()