2020-03-29 02:19:21 +00:00
|
|
|
#
|
|
|
|
# Author: Cunren Liang
|
|
|
|
# Copyright 2015-present, NASA-JPL/Caltech
|
|
|
|
#
|
|
|
|
|
|
|
|
import os
|
|
|
|
import logging
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
import isceobj
|
|
|
|
from isceobj.Util.decorators import use_api
|
|
|
|
|
|
|
|
logger = logging.getLogger('isce.alos2insar.runDenseOffset')
|
|
|
|
|
|
|
|
def runDenseOffset(self):
|
|
|
|
'''estimate offset fied
|
|
|
|
'''
|
|
|
|
if not self.doDenseOffset:
|
|
|
|
return
|
|
|
|
if not ((self._insar.modeCombination == 0) or (self._insar.modeCombination == 1)):
|
|
|
|
return
|
|
|
|
|
|
|
|
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
|
|
|
|
self.updateParamemetersFromUser()
|
|
|
|
|
|
|
|
denseOffsetDir = 'dense_offset'
|
2020-04-13 19:40:32 +00:00
|
|
|
os.makedirs(denseOffsetDir, exist_ok=True)
|
2020-03-29 02:19:21 +00:00
|
|
|
os.chdir(denseOffsetDir)
|
|
|
|
|
2020-07-02 19:40:49 +00:00
|
|
|
#referenceTrack = self._insar.loadProduct(self._insar.referenceTrackParameter)
|
|
|
|
#secondaryTrack = self._insar.loadProduct(self._insar.secondaryTrackParameter)
|
2020-03-29 02:19:21 +00:00
|
|
|
|
|
|
|
#########################################################################################
|
|
|
|
|
|
|
|
if self.useGPU and self._insar.hasGPU():
|
|
|
|
runDenseOffsetGPU(self)
|
|
|
|
#define null value. Lijun said there is actually no such null value in GPU ampcor.
|
|
|
|
nullValue = -10000.0
|
|
|
|
else:
|
|
|
|
runDenseOffsetCPU(self)
|
|
|
|
#define null value
|
|
|
|
nullValue = -10000.0
|
|
|
|
|
|
|
|
#null value set to zero
|
|
|
|
img = isceobj.createImage()
|
|
|
|
img.load(self._insar.denseOffset+'.xml')
|
|
|
|
width = img.width
|
|
|
|
length = img.length
|
|
|
|
offset=np.memmap(self._insar.denseOffset, dtype='float32', mode='r+', shape=(length*2, width))
|
|
|
|
snr=np.memmap(self._insar.denseOffsetSnr, dtype='float32', mode='r+', shape=(length, width))
|
|
|
|
offsetband1 = offset[0:length*2:2, :]
|
|
|
|
offsetband2 = offset[1:length*2:2, :]
|
|
|
|
index = np.nonzero(np.logical_or(offsetband1==nullValue, offsetband2==nullValue))
|
|
|
|
offsetband1[index] = 0
|
|
|
|
offsetband2[index] = 0
|
|
|
|
snr[index] = 0
|
|
|
|
del offset, offsetband1, offsetband2, snr
|
|
|
|
|
|
|
|
#areas covered by water body set to zero
|
|
|
|
if self.maskOffsetWithWbd:
|
|
|
|
img = isceobj.createImage()
|
|
|
|
img.load('wbd.rdr.xml')
|
|
|
|
width0 = img.width
|
|
|
|
length0 = img.length
|
|
|
|
|
|
|
|
img = isceobj.createImage()
|
|
|
|
img.load(self._insar.denseOffset+'.xml')
|
|
|
|
width = img.width
|
|
|
|
length = img.length
|
|
|
|
|
|
|
|
#get water body mask
|
|
|
|
wbd0=np.memmap('wbd.rdr', dtype=np.int8, mode='r', shape=(length0, width0))
|
2021-02-13 20:56:58 +00:00
|
|
|
wbd0=wbd0[0+self._insar.offsetImageTopoffset:length0:self.offsetSkipHeight,
|
2020-03-29 02:19:21 +00:00
|
|
|
0+self._insar.offsetImageLeftoffset:width0:self.offsetSkipWidth]
|
|
|
|
wbd = np.zeros((length+100, width+100), dtype=np.int8)
|
|
|
|
wbd[0:wbd0.shape[0], 0:wbd0.shape[1]]=wbd0
|
|
|
|
|
|
|
|
#mask offset and snr
|
|
|
|
offset=np.memmap(self._insar.denseOffset, dtype='float32', mode='r+', shape=(length*2, width))
|
|
|
|
snr=np.memmap(self._insar.denseOffsetSnr, dtype='float32', mode='r+', shape=(length, width))
|
|
|
|
(offset[0:length*2:2, :])[np.nonzero(wbd[0:length, 0:width]==-1)]=0
|
|
|
|
(offset[1:length*2:2, :])[np.nonzero(wbd[0:length, 0:width]==-1)]=0
|
|
|
|
snr[np.nonzero(wbd[0:length, 0:width]==-1)]=0
|
|
|
|
|
|
|
|
del wbd0, wbd, offset, snr
|
|
|
|
|
|
|
|
|
|
|
|
#########################################################################################
|
|
|
|
|
|
|
|
os.chdir('../')
|
|
|
|
catalog.printToLog(logger, "runDenseOffset")
|
|
|
|
self._insar.procDoc.addAllFromCatalog(catalog)
|
|
|
|
|
|
|
|
|
|
|
|
#@use_api
|
|
|
|
def runDenseOffsetCPU(self):
|
|
|
|
'''
|
|
|
|
Estimate dense offset field between a pair of SLCs.
|
|
|
|
'''
|
|
|
|
from mroipac.ampcor.DenseAmpcor import DenseAmpcor
|
|
|
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
|
|
|
|
|
|
|
####For this module currently, we need to create an actual file on disk
|
2020-07-02 19:40:49 +00:00
|
|
|
for infile in [self._insar.referenceSlc, self._insar.secondarySlcCoregistered]:
|
2020-03-29 02:19:21 +00:00
|
|
|
if os.path.isfile(infile):
|
|
|
|
continue
|
|
|
|
cmd = 'gdal_translate -of ENVI {0}.vrt {0}'.format(infile)
|
|
|
|
runCmd(cmd)
|
|
|
|
|
|
|
|
m = isceobj.createSlcImage()
|
2020-07-02 19:40:49 +00:00
|
|
|
m.load(self._insar.referenceSlc + '.xml')
|
2020-03-29 02:19:21 +00:00
|
|
|
m.setAccessMode('READ')
|
|
|
|
|
|
|
|
s = isceobj.createSlcImage()
|
2020-07-02 19:40:49 +00:00
|
|
|
s.load(self._insar.secondarySlcCoregistered + '.xml')
|
2020-03-29 02:19:21 +00:00
|
|
|
s.setAccessMode('READ')
|
|
|
|
|
|
|
|
#objOffset.numberThreads = 1
|
|
|
|
print('\n************* dense offset estimation parameters *************')
|
2020-07-02 19:40:49 +00:00
|
|
|
print('reference SLC: %s' % (self._insar.referenceSlc))
|
|
|
|
print('secondary SLC: %s' % (self._insar.secondarySlcCoregistered))
|
2020-03-29 02:19:21 +00:00
|
|
|
print('dense offset estimation window width: %d' % (self.offsetWindowWidth))
|
|
|
|
print('dense offset estimation window hight: %d' % (self.offsetWindowHeight))
|
|
|
|
print('dense offset search window width: %d' % (self.offsetSearchWindowWidth))
|
|
|
|
print('dense offset search window hight: %d' % (self.offsetSearchWindowHeight))
|
|
|
|
print('dense offset skip width: %d' % (self.offsetSkipWidth))
|
|
|
|
print('dense offset skip hight: %d' % (self.offsetSkipHeight))
|
|
|
|
print('dense offset covariance surface oversample factor: %d' % (self.offsetCovarianceOversamplingFactor))
|
|
|
|
print('dense offset covariance surface oversample window size: %d\n' % (self.offsetCovarianceOversamplingWindowsize))
|
|
|
|
|
|
|
|
|
|
|
|
objOffset = DenseAmpcor(name='dense')
|
|
|
|
objOffset.configure()
|
|
|
|
|
|
|
|
if m.dataType.startswith('C'):
|
|
|
|
objOffset.setImageDataType1('complex')
|
|
|
|
else:
|
|
|
|
objOffset.setImageDataType1('real')
|
|
|
|
if s.dataType.startswith('C'):
|
|
|
|
objOffset.setImageDataType2('complex')
|
|
|
|
else:
|
|
|
|
objOffset.setImageDataType2('real')
|
|
|
|
|
|
|
|
objOffset.offsetImageName = self._insar.denseOffset
|
|
|
|
objOffset.snrImageName = self._insar.denseOffsetSnr
|
|
|
|
objOffset.covImageName = self._insar.denseOffsetCov
|
|
|
|
|
|
|
|
objOffset.setWindowSizeWidth(self.offsetWindowWidth)
|
|
|
|
objOffset.setWindowSizeHeight(self.offsetWindowHeight)
|
|
|
|
#NOTE: actual number of resulting correlation pixels: self.offsetSearchWindowWidth*2+1
|
|
|
|
objOffset.setSearchWindowSizeWidth(self.offsetSearchWindowWidth)
|
|
|
|
objOffset.setSearchWindowSizeHeight(self.offsetSearchWindowHeight)
|
|
|
|
objOffset.setSkipSampleAcross(self.offsetSkipWidth)
|
|
|
|
objOffset.setSkipSampleDown(self.offsetSkipHeight)
|
|
|
|
objOffset.setOversamplingFactor(self.offsetCovarianceOversamplingFactor)
|
|
|
|
objOffset.setZoomWindowSize(self.offsetCovarianceOversamplingWindowsize)
|
|
|
|
objOffset.setAcrossGrossOffset(0)
|
|
|
|
objOffset.setDownGrossOffset(0)
|
|
|
|
#these are azimuth scaling factor
|
|
|
|
#Matching Scale for Sample/Line Directions (-) = 1.000000551500 1.000002373200
|
|
|
|
objOffset.setFirstPRF(1.0)
|
|
|
|
objOffset.setSecondPRF(1.0)
|
|
|
|
|
|
|
|
objOffset.denseampcor(m, s)
|
|
|
|
|
|
|
|
### Store params for later
|
|
|
|
self._insar.offsetImageTopoffset = objOffset.locationDown[0][0]
|
|
|
|
self._insar.offsetImageLeftoffset = objOffset.locationAcross[0][0]
|
|
|
|
|
|
|
|
#change band order
|
|
|
|
width=objOffset.offsetCols
|
|
|
|
length=objOffset.offsetLines
|
|
|
|
|
|
|
|
offset1 = np.fromfile(self._insar.denseOffset, dtype=np.float32).reshape(length*2, width)
|
|
|
|
offset2 = np.zeros((length*2, width), dtype=np.float32)
|
|
|
|
offset2[0:length*2:2, :] = offset1[1:length*2:2, :]
|
|
|
|
offset2[1:length*2:2, :] = offset1[0:length*2:2, :]
|
|
|
|
|
|
|
|
os.remove(self._insar.denseOffset)
|
|
|
|
os.remove(self._insar.denseOffset+'.vrt')
|
|
|
|
os.remove(self._insar.denseOffset+'.xml')
|
|
|
|
|
|
|
|
offset2.astype(np.float32).tofile(self._insar.denseOffset)
|
|
|
|
outImg = isceobj.createImage()
|
|
|
|
outImg.setDataType('FLOAT')
|
|
|
|
outImg.setFilename(self._insar.denseOffset)
|
|
|
|
outImg.setBands(2)
|
|
|
|
outImg.scheme = 'BIL'
|
|
|
|
outImg.setWidth(width)
|
|
|
|
outImg.setLength(length)
|
|
|
|
outImg.addDescription('two-band pixel offset file. 1st band: range offset, 2nd band: azimuth offset')
|
|
|
|
outImg.setAccessMode('read')
|
|
|
|
outImg.renderHdr()
|
|
|
|
|
|
|
|
return (objOffset.offsetCols, objOffset.offsetLines)
|
|
|
|
|
|
|
|
|
|
|
|
def runDenseOffsetGPU(self):
|
|
|
|
'''
|
|
|
|
Estimate dense offset field between a pair of SLCs.
|
|
|
|
'''
|
|
|
|
from contrib.PyCuAmpcor import PyCuAmpcor
|
|
|
|
from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
|
|
|
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
|
|
|
|
|
|
|
############################################################################################
|
|
|
|
# #different from minyan's script: cuDenseOffsets.py: deramp method (0: mag, 1: complex)
|
|
|
|
# objOffset.derampMethod = 2 #
|
|
|
|
# #varying-gross-offset parameters not set
|
|
|
|
|
|
|
|
# #not set in minyan's script: cuDenseOffsets.py
|
|
|
|
# objOffset.corrSurfaceZoomInWindow
|
|
|
|
# objOffset.grossOffsetAcrossStatic = 0
|
|
|
|
# objOffset.grossOffsetDownStatic = 0
|
|
|
|
############################################################################################
|
|
|
|
|
|
|
|
|
|
|
|
####For this module currently, we need to create an actual file on disk
|
2020-07-02 19:40:49 +00:00
|
|
|
for infile in [self._insar.referenceSlc, self._insar.secondarySlcCoregistered]:
|
2020-03-29 02:19:21 +00:00
|
|
|
if os.path.isfile(infile):
|
|
|
|
continue
|
|
|
|
cmd = 'gdal_translate -of ENVI {0}.vrt {0}'.format(infile)
|
|
|
|
runCmd(cmd)
|
|
|
|
|
|
|
|
m = isceobj.createSlcImage()
|
2020-07-02 19:40:49 +00:00
|
|
|
m.load(self._insar.referenceSlc + '.xml')
|
2020-03-29 02:19:21 +00:00
|
|
|
m.setAccessMode('READ')
|
|
|
|
|
|
|
|
s = isceobj.createSlcImage()
|
2020-07-02 19:40:49 +00:00
|
|
|
s.load(self._insar.secondarySlcCoregistered + '.xml')
|
2020-03-29 02:19:21 +00:00
|
|
|
s.setAccessMode('READ')
|
|
|
|
|
|
|
|
print('\n************* dense offset estimation parameters *************')
|
2020-07-02 19:40:49 +00:00
|
|
|
print('reference SLC: %s' % (self._insar.referenceSlc))
|
|
|
|
print('secondary SLC: %s' % (self._insar.secondarySlcCoregistered))
|
2020-03-29 02:19:21 +00:00
|
|
|
print('dense offset estimation window width: %d' % (self.offsetWindowWidth))
|
|
|
|
print('dense offset estimation window hight: %d' % (self.offsetWindowHeight))
|
|
|
|
print('dense offset search window width: %d' % (self.offsetSearchWindowWidth))
|
|
|
|
print('dense offset search window hight: %d' % (self.offsetSearchWindowHeight))
|
|
|
|
print('dense offset skip width: %d' % (self.offsetSkipWidth))
|
|
|
|
print('dense offset skip hight: %d' % (self.offsetSkipHeight))
|
|
|
|
print('dense offset covariance surface oversample factor: %d' % (self.offsetCovarianceOversamplingFactor))
|
|
|
|
|
|
|
|
|
|
|
|
objOffset = PyCuAmpcor.PyCuAmpcor()
|
|
|
|
objOffset.algorithm = 0
|
2021-02-13 20:56:58 +00:00
|
|
|
objOffset.derampMethod = 1 # 1=linear phase ramp, 0=take mag, 2=skip
|
2020-07-02 19:40:49 +00:00
|
|
|
objOffset.referenceImageName = self._insar.referenceSlc
|
|
|
|
objOffset.referenceImageHeight = m.length
|
|
|
|
objOffset.referenceImageWidth = m.width
|
|
|
|
objOffset.secondaryImageName = self._insar.secondarySlcCoregistered
|
|
|
|
objOffset.secondaryImageHeight = s.length
|
|
|
|
objOffset.secondaryImageWidth = s.width
|
2020-03-29 02:19:21 +00:00
|
|
|
objOffset.offsetImageName = self._insar.denseOffset
|
2021-02-13 20:56:58 +00:00
|
|
|
objOffset.grossOffsetImageName = self._insar.denseOffset + ".gross"
|
2020-03-29 02:19:21 +00:00
|
|
|
objOffset.snrImageName = self._insar.denseOffsetSnr
|
2021-02-13 20:56:58 +00:00
|
|
|
objOffset.covImageName = self._insar.denseOffsetCov
|
2020-03-29 02:19:21 +00:00
|
|
|
|
|
|
|
objOffset.windowSizeWidth = self.offsetWindowWidth
|
|
|
|
objOffset.windowSizeHeight = self.offsetWindowHeight
|
2021-02-13 20:56:58 +00:00
|
|
|
|
2020-03-29 02:19:21 +00:00
|
|
|
objOffset.halfSearchRangeAcross = self.offsetSearchWindowWidth
|
|
|
|
objOffset.halfSearchRangeDown = self.offsetSearchWindowHeight
|
2021-02-13 20:56:58 +00:00
|
|
|
|
2020-03-29 02:19:21 +00:00
|
|
|
objOffset.skipSampleDown = self.offsetSkipHeight
|
|
|
|
objOffset.skipSampleAcross = self.offsetSkipWidth
|
2021-02-13 20:56:58 +00:00
|
|
|
|
2020-03-29 02:19:21 +00:00
|
|
|
#Oversampling method for correlation surface(0=fft,1=sinc)
|
2021-02-13 20:56:58 +00:00
|
|
|
objOffset.corrSurfaceOverSamplingMethod = 0
|
2020-03-29 02:19:21 +00:00
|
|
|
objOffset.corrSurfaceOverSamplingFactor = self.offsetCovarianceOversamplingFactor
|
2021-02-13 20:56:58 +00:00
|
|
|
|
|
|
|
# set gross offset
|
2020-03-29 02:19:21 +00:00
|
|
|
objOffset.grossOffsetAcrossStatic = 0
|
|
|
|
objOffset.grossOffsetDownStatic = 0
|
2021-02-13 20:56:58 +00:00
|
|
|
# set the margin
|
|
|
|
margin = 0
|
2020-03-29 02:19:21 +00:00
|
|
|
|
2021-02-13 20:56:58 +00:00
|
|
|
# adjust the margin
|
|
|
|
margin = max(margin, abs(objOffset.grossOffsetAcrossStatic), abs(objOffset.grossOffsetDownStatic))
|
2020-03-29 02:19:21 +00:00
|
|
|
|
2021-02-13 20:56:58 +00:00
|
|
|
# set the starting pixel of the first reference window
|
|
|
|
objOffset.referenceStartPixelDownStatic = margin + self.offsetSearchWindowHeight
|
|
|
|
objOffset.referenceStartPixelAcrossStatic = margin + self.offsetSearchWindowWidth
|
2020-03-29 02:19:21 +00:00
|
|
|
|
2021-02-13 20:56:58 +00:00
|
|
|
# find out the total number of windows
|
|
|
|
objOffset.numberWindowDown = (m.length - 2*margin - 2*self.offsetSearchWindowHeight - self.offsetWindowHeight) // self.offsetSkipHeight
|
|
|
|
objOffset.numberWindowAcross = (m.width - 2*margin - 2*self.offsetSearchWindowWidth - self.offsetWindowWidth) // self.offsetSkipWidth
|
|
|
|
|
|
|
|
# gpu job control
|
|
|
|
objOffset.deviceID = 0
|
|
|
|
objOffset.nStreams = 2
|
|
|
|
objOffset.numberWindowDownInChunk = 1
|
|
|
|
objOffset.numberWindowAcrossInChunk = 64
|
2020-03-29 02:19:21 +00:00
|
|
|
objOffset.mmapSize = 16
|
|
|
|
|
2021-02-13 20:56:58 +00:00
|
|
|
# pass/adjust the parameters
|
2020-03-29 02:19:21 +00:00
|
|
|
objOffset.setupParams()
|
2021-02-13 20:56:58 +00:00
|
|
|
# set up the starting pixels for each window, based on the gross offset
|
|
|
|
objOffset.setConstantGrossOffset(objOffset.grossOffsetAcrossStatic, objOffset.grossOffsetDownStatic)
|
|
|
|
# check whether all pixels are in image range (optional)
|
2020-03-29 02:19:21 +00:00
|
|
|
objOffset.checkPixelInImageRange()
|
2021-02-13 20:56:58 +00:00
|
|
|
print('\n======================================')
|
|
|
|
print('Running PyCuAmpcor...')
|
|
|
|
print('======================================\n')
|
2020-03-29 02:19:21 +00:00
|
|
|
objOffset.runAmpcor()
|
|
|
|
|
|
|
|
### Store params for later
|
2021-02-13 20:56:58 +00:00
|
|
|
# location of the center of the first reference window
|
|
|
|
self._insar.offsetImageTopoffset = objOffset.referenceStartPixelDownStatic + (objOffset.windowSizeHeight-1)//2
|
|
|
|
self._insar.offsetImageLeftoffset = objOffset.referenceStartPixelAcrossStatic +(objOffset.windowSizeWidth-1)//2
|
2020-03-29 02:19:21 +00:00
|
|
|
|
2021-02-13 20:56:58 +00:00
|
|
|
# offset image dimension, the number of windows
|
2020-03-29 02:19:21 +00:00
|
|
|
width = objOffset.numberWindowAcross
|
|
|
|
length = objOffset.numberWindowDown
|
2021-02-13 20:56:58 +00:00
|
|
|
|
|
|
|
# convert the offset image from BIP to BIL
|
|
|
|
offsetBIP = np.fromfile(objOffset.offsetImageName, dtype=np.float32).reshape(length, width*2)
|
2020-03-29 02:19:21 +00:00
|
|
|
offsetBIL = np.zeros((length*2, width), dtype=np.float32)
|
|
|
|
offsetBIL[0:length*2:2, :] = offsetBIP[:, 1:width*2:2]
|
|
|
|
offsetBIL[1:length*2:2, :] = offsetBIP[:, 0:width*2:2]
|
2021-02-13 20:56:58 +00:00
|
|
|
os.remove(objOffset.offsetImageName)
|
|
|
|
offsetBIL.astype(np.float32).tofile(objOffset.offsetImageName)
|
2020-03-29 02:19:21 +00:00
|
|
|
|
2021-02-13 20:56:58 +00:00
|
|
|
# generate offset image description files
|
2020-03-29 02:19:21 +00:00
|
|
|
outImg = isceobj.createImage()
|
|
|
|
outImg.setDataType('FLOAT')
|
2021-02-13 20:56:58 +00:00
|
|
|
outImg.setFilename(objOffset.offsetImageName)
|
2020-03-29 02:19:21 +00:00
|
|
|
outImg.setBands(2)
|
|
|
|
outImg.scheme = 'BIL'
|
|
|
|
outImg.setWidth(objOffset.numberWindowAcross)
|
|
|
|
outImg.setLength(objOffset.numberWindowDown)
|
|
|
|
outImg.addDescription('two-band pixel offset file. 1st band: range offset, 2nd band: azimuth offset')
|
|
|
|
outImg.setAccessMode('read')
|
|
|
|
outImg.renderHdr()
|
|
|
|
|
2021-02-13 20:56:58 +00:00
|
|
|
# gross offset image is not needed, since all zeros
|
|
|
|
|
|
|
|
# generate snr image description files
|
2020-03-29 02:19:21 +00:00
|
|
|
snrImg = isceobj.createImage()
|
2021-02-13 20:56:58 +00:00
|
|
|
snrImg.setFilename( objOffset.snrImageName)
|
2020-03-29 02:19:21 +00:00
|
|
|
snrImg.setDataType('FLOAT')
|
|
|
|
snrImg.setBands(1)
|
|
|
|
snrImg.setWidth(objOffset.numberWindowAcross)
|
|
|
|
snrImg.setLength(objOffset.numberWindowDown)
|
|
|
|
snrImg.setAccessMode('read')
|
|
|
|
snrImg.renderHdr()
|
|
|
|
|
2021-02-13 20:56:58 +00:00
|
|
|
# generate cov image description files
|
|
|
|
# covariance of azimuth/range offsets.
|
|
|
|
# 1st band: cov(az, az), 2nd band: cov(rg, rg), 3rd band: cov(az, rg)
|
|
|
|
covImg = isceobj.createImage()
|
|
|
|
covImg.setFilename(objOffset.covImageName)
|
|
|
|
covImg.setDataType('FLOAT')
|
|
|
|
covImg.setBands(3)
|
|
|
|
covImg.scheme = 'BIP'
|
|
|
|
covImg.setWidth(objOffset.numberWindowAcross)
|
|
|
|
covImg.setLength(objOffset.numberWindowDown)
|
|
|
|
outImg.addDescription('covariance of azimuth/range offsets')
|
|
|
|
covImg.setAccessMode('read')
|
|
|
|
covImg.renderHdr()
|
|
|
|
|
2020-03-29 02:19:21 +00:00
|
|
|
return (objOffset.numberWindowAcross, objOffset.numberWindowDown)
|
2021-02-13 20:56:58 +00:00
|
|
|
|
|
|
|
# end of file
|