177 lines
6.1 KiB
Python
177 lines
6.1 KiB
Python
#
|
|
# Author: Piyush Agram
|
|
# Copyright 2016
|
|
#
|
|
import logging
|
|
from zerodop.geozero import createGeozero
|
|
from stdproc.rectify.geocode.Geocodable import Geocodable
|
|
import isceobj
|
|
import iscesys
|
|
from iscesys.ImageUtil.ImageUtil import ImageUtil as IU
|
|
from isceobj.Planet.Planet import Planet
|
|
from isceobj.Orbit.Orbit import Orbit
|
|
from isceobj.Constants import SPEED_OF_LIGHT
|
|
import os
|
|
import datetime
|
|
import numpy as np
|
|
|
|
logger = logging.getLogger('isce.topsinsar.runGeocode')
|
|
posIndx = 1
|
|
|
|
def runGeocode(self, prodlist, bbox, is_offset_mode=False):
|
|
'''Generalized geocoding of all the files listed above.'''
|
|
from isceobj.Catalog import recordInputsAndOutputs
|
|
logger.info("Geocoding Image")
|
|
insar = self._insar
|
|
|
|
if (not self.doDenseOffsets) and (is_offset_mode):
|
|
print('Skipping geocoding as Dense Offsets has not been requested ....')
|
|
return
|
|
|
|
|
|
if isinstance(prodlist,str):
|
|
from isceobj.Util.StringUtils import StringUtils as SU
|
|
tobeGeocoded = SU.listify(prodlist)
|
|
else:
|
|
tobeGeocoded = prodlist
|
|
|
|
|
|
#remove files that have not been processed
|
|
newlist=[]
|
|
for toGeo in tobeGeocoded:
|
|
if os.path.exists(toGeo):
|
|
newlist.append(toGeo)
|
|
|
|
|
|
tobeGeocoded = newlist
|
|
print('Number of products to geocode: ', len(tobeGeocoded))
|
|
|
|
if len(tobeGeocoded) == 0:
|
|
print('No products found to geocode')
|
|
return
|
|
|
|
|
|
###Read in the product
|
|
burst = self._insar.loadProduct( self._insar.referenceSlcCropProduct)
|
|
|
|
####Get required values from product
|
|
t0 = burst.sensingStart
|
|
prf = burst.PRF
|
|
r0 = burst.startingRange
|
|
dr = 0.5* SPEED_OF_LIGHT/ burst.rangeSamplingRate
|
|
wvl = burst.radarWavelegth
|
|
side= burst.getInstrument().getPlatform().pointingDirection
|
|
orb = burst.orbit
|
|
planet = Planet(pname='Earth')
|
|
|
|
if (bbox is None):
|
|
snwe = self._insar.estimatedBbox
|
|
else:
|
|
snwe = bbox
|
|
if len(snwe) != 4 :
|
|
raise Exception('Bbox must be 4 floats in SNWE order.')
|
|
|
|
if is_offset_mode: ### If using topsOffsetApp, image has been "pre-looked" by the
|
|
numberRangeLooks = self.denseSkipWidth ### skips in runDenseOffsets
|
|
numberAzimuthLooks = self.denseSkipHeight
|
|
rangeFirstSample = r0 + (self._insar.offset_left-1) * dr
|
|
sensingStart = t0 + datetime.timedelta(seconds=((self._insar.offset_top-1)/prf))
|
|
else:
|
|
###Resolve number of looks
|
|
azLooks, rgLooks = self.insar.numberOfLooks(burst, self.posting, self.numberAzimuthLooks, self.numberRangeLooks)
|
|
|
|
numberRangeLooks = rgLooks
|
|
numberAzimuthLooks = azLooks
|
|
rangeFirstSample = r0 + ((numberRangeLooks-1)/2.0) * dr
|
|
sensingStart = t0 + datetime.timedelta(seconds=(((numberAzimuthLooks-1)/2.0)/prf))
|
|
|
|
|
|
###Ughhh!! Doppler handling
|
|
if self._insar.referenceGeometrySystem.lower().startswith('native'):
|
|
###Need to fit polynomials
|
|
###Geozero fortran assumes that starting range for radar image and polynomial are same
|
|
###Also assumes that the polynomial spacing is original spacing at full looks
|
|
###This is not true for multilooked data. Need to fix this with good datastruct in ISCEv3
|
|
###Alternate method is to modify the mean and norm of a Poly1D structure such that the
|
|
###translation is accounted for correctly.
|
|
poly = burst._dopplerVsPixel
|
|
|
|
if len(poly) != 1:
|
|
slcPix = np.linspace(0., burst.numberOfSamples, len(poly)+1)
|
|
dopplers = np.polyval(poly[::-1], slcPix)
|
|
|
|
newPix = slcPix - (rangeFirstSample - r0)/dr
|
|
nppoly = np.polyfit(newPix, dopplers, len(poly)-1)
|
|
|
|
dopplercoeff = list(nppoly[::-1])
|
|
else:
|
|
dopplercoeff = poly
|
|
|
|
else:
|
|
dopplercoeff = [0.]
|
|
|
|
##Scale by PRF since the module needs it
|
|
dopplercoeff = [x/prf for x in dopplercoeff]
|
|
|
|
###Setup DEM
|
|
demfilename = self.verifyDEM()
|
|
demImage = isceobj.createDemImage()
|
|
demImage.load(demfilename + '.xml')
|
|
|
|
###Catalog for tracking
|
|
catalog = isceobj.Catalog.createCatalog(insar.procDoc.name)
|
|
catalog.addItem('Dem Used', demfilename, 'geocode')
|
|
|
|
#####Geocode one by one
|
|
first = False
|
|
ge = Geocodable()
|
|
for prod in tobeGeocoded:
|
|
objGeo = createGeozero()
|
|
objGeo.configure()
|
|
|
|
####IF statements to check for user configuration
|
|
objGeo.snwe = snwe
|
|
objGeo.demCropFilename = insar.demCropFilename
|
|
|
|
|
|
objGeo.dopplerCentroidCoeffs = dopplercoeff
|
|
objGeo.lookSide = side
|
|
|
|
#create the instance of the input image and the appropriate
|
|
#geocode method
|
|
inImage,method = ge.create(prod)
|
|
objGeo.method = method
|
|
|
|
objGeo.slantRangePixelSpacing = dr
|
|
objGeo.prf = prf
|
|
objGeo.orbit = orb
|
|
objGeo.width = inImage.getWidth()
|
|
objGeo.length = inImage.getLength()
|
|
objGeo.dopplerCentroidCoeffs = dopplercoeff
|
|
objGeo.radarWavelength = wvl
|
|
objGeo.rangeFirstSample = rangeFirstSample
|
|
objGeo.setSensingStart(sensingStart)
|
|
objGeo.numberRangeLooks = numberRangeLooks
|
|
objGeo.numberAzimuthLooks = numberAzimuthLooks
|
|
|
|
|
|
objGeo.wireInputPort(name='dem', object=demImage)
|
|
objGeo.wireInputPort(name='planet', object=planet)
|
|
objGeo.wireInputPort(name='tobegeocoded', object=inImage)
|
|
|
|
objGeo.geocode()
|
|
|
|
catalog.addItem('Geocoding: ', inImage.filename, 'geocode')
|
|
catalog.addItem('Output file: ', inImage.filename + '.geo', 'geocode')
|
|
catalog.addItem('Width', inImage.width, 'geocode')
|
|
catalog.addItem('Length', inImage.length, 'geocode')
|
|
catalog.addItem('Range looks', objGeo.numberRangeLooks, 'geocode')
|
|
catalog.addItem('Azimuth looks', objGeo.numberAzimuthLooks, 'geocode')
|
|
catalog.addItem('South' , objGeo.minimumGeoLatitude, 'geocode')
|
|
catalog.addItem('North', objGeo.maximumGeoLatitude, 'geocode')
|
|
catalog.addItem('West', objGeo.minimumGeoLongitude, 'geocode')
|
|
catalog.addItem('East', objGeo.maximumGeoLongitude, 'geocode')
|
|
|
|
catalog.printToLog(logger, "runGeocode")
|
|
self._insar.procDoc.addAllFromCatalog(catalog)
|