Ejemplo n.º 1
0
def fitOffsets(field, azrgOrder=0, azazOrder=0, rgrgOrder=0, rgazOrder=0, snr=5.0):
    '''
    Estimate constant range and azimuth shifts.
    '''

    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
Ejemplo n.º 2
0
def run(rgOffsets, distance, stdWriter, catalog=None, sceneid='NO_ID'):
    #offoutliers returns a list of modified locations
    #the list of lists is
    #list[0] = location across
    #list[1] = location  across offset
    #list[2] = location down
    #list[3] = location  down offset
    #list[4] = snr
    #list[5] = sig

    logger.info("Culling offset field outliers: %s" % sceneid)
    objOff = isceobj.createOffoutliers()
    objOff.wireInputPort(name='offsets', object=rgOffsets)
    objOff.setSNRThreshold(2.0)
    objOff.setDistance(distance)
    #set the tag used in the outfile. each message is precided by this tag
    #is the writer is not of "file" type the call has no effect
    stdWriter.setFileTag("offoutliers", "log")
    stdWriter.setFileTag("offoutliers", "err")
    stdWriter.setFileTag("offoutliers", "out")
    objOff.stdWriter = stdWriter.set_file_tags("offoutliers", "log", "err",
                                               "out")

    objOff.offoutliers()

    if catalog is not None:
        # Record the inputs and outputs
        isceobj.Catalog.recordInputsAndOutputs(catalog, objOff,
                                               "runOffoutliers.%s" % sceneid,
                                               logger,
                                               "runOffoutliers.%s" % sceneid)

    return objOff.getRefinedOffsetField()
Ejemplo n.º 3
0
def cullOffset(offsets, distances, numCullOffsetsLimits):
    import os
    import isce
    import isceobj
    from iscesys.StdOEL.StdOELPy import create_writer
    #offsets: offsets from ampcor
    #distances: tuple
    #numCullOffsetsLimits: tuple

    refinedOffsets = offsets
    for i, (distance, numCullOffsetsLimit) in enumerate(
            zip(distances, numCullOffsetsLimits)):

        cullOff = isceobj.createOffoutliers()
        cullOff.wireInputPort(name='offsets', object=refinedOffsets)
        cullOff.setSNRThreshold(2.0)
        cullOff.setDistance(distance)

        #set the tag used in the outfile. each message is precided by this tag
        #is the writer is not of "file" type the call has no effect
        logfile = "offoutliers.log"
        stdWriter = create_writer("log", "", True, filename=logfile)
        stdWriter.setFileTag("offoutliers", "log")
        stdWriter.setFileTag("offoutliers", "err")
        stdWriter.setFileTag("offoutliers", "out")
        cullOff.setStdWriter(stdWriter)

        try:
            cullOff.offoutliers()
            refinedOffsets = cullOff.getRefinedOffsetField()
            numLeft = len(refinedOffsets._offsets)
            print('Number of offsets left after %2dth culling: %5d' %
                  (i, numLeft))
            if numLeft < numCullOffsetsLimit:
                print(
                    '*******************************************************')
                print('WARNING: Too few points left after culling: {} left'.
                      format(numLeft))
                print(
                    '*******************************************************')
                return None
        except:
            print('*******************************************************')
            print('WARNING: unsuccessful offset culling')
            print('*******************************************************')
            return None

        os.remove(logfile)

    return refinedOffsets
Ejemplo n.º 4
0
def runOffoutliers(self, distance, errorLimit=100):
    #offoutliers returns a list of modified locations
    #the list of lists is
    #list[0] = location across
    #list[1] = location  across offset
    #list[2] = location down
    #list[3] = location  down offset
    #list[4] = snr
    #list[5] = sig
    logger.info('Error limit = %d' % (errorLimit))
    warnLimit = errorLimit * 3
    logger.info("Culling offset field outliers")
    rgOffsets = self._insar.getRefinedOffsetField()
    logger.info('Number of input offsets: %d' % (len(rgOffsets._offsets)))
    logger.info('Distance: %f' % (distance))
    objOff = isceobj.createOffoutliers()
    objOff.wireInputPort(name='offsets', object=rgOffsets)
    objOff.setSNRThreshold(2.0)
    objOff.setDistance(distance)
    #set the tag used in the outfile. each message is precided by this tag
    #is the writer is not of "file" type the call has no effect
    self._stdWriter.setFileTag("offoutliers", "log")
    self._stdWriter.setFileTag("offoutliers", "err")
    self._stdWriter.setFileTag("offoutliers", "out")
    objOff.setStdWriter(self._stdWriter)

    objOff.offoutliers()

    # Record the inputs and outputs
    from isceobj.Catalog import recordInputsAndOutputs
    recordInputsAndOutputs(self._insar.procDoc, objOff, "runOffoutliers",
                           logger, "runOffoutliers")

    refinedOffsets = objOff.getRefinedOffsetField()
    lenOut = len(refinedOffsets._offsets)
    logger.info('Number of offsets left after culling: %d' % (lenOut))
    if lenOut < errorLimit:
        logger.error(
            'Small number of output Offsets after culling: %d .\n Increase number of windows (or) window sizes (or) provide gross offset manually.'
            % (lenOut))
        raise Exception('Offset estimation Failed.')
    elif lenOut < warnLimit:
        logger.warn(
            'Number of output offsets after culling are low: %d. Might be ok to continue.'
            % (lenOut))

    self._insar.setRefinedOffsetField(refinedOffsets)
Ejemplo n.º 5
0
def cullOffsets(offsets):
    import isceobj
    from iscesys.StdOEL.StdOELPy import create_writer

    distances = (10, 5, 3, 3, 3, 3, 3, 3)
    #numCullOffsetsLimits = (100, 75, 50, 50, 50, 50, 50, 50)
    numCullOffsetsLimits = (50, 40, 30, 30, 30, 30, 30, 30)

    refinedOffsets = offsets
    for i, (distance, numCullOffsetsLimit) in enumerate(
            zip(distances, numCullOffsetsLimits)):

        cullOff = isceobj.createOffoutliers()
        cullOff.wireInputPort(name='offsets', object=refinedOffsets)
        cullOff.setSNRThreshold(2.0)
        cullOff.setDistance(distance)

        #set the tag used in the outfile. each message is precided by this tag
        #is the writer is not of "file" type the call has no effect
        stdWriter = create_writer("log", "", True, filename="offoutliers.log")
        stdWriter.setFileTag("offoutliers", "log")
        stdWriter.setFileTag("offoutliers", "err")
        stdWriter.setFileTag("offoutliers", "out")
        cullOff.setStdWriter(stdWriter)

        #run it
        cullOff.offoutliers()

        refinedOffsets = cullOff.getRefinedOffsetField()
        numLeft = len(refinedOffsets._offsets)
        print('Number of offsets left after %2dth culling: %5d' % (i, numLeft))
        if numLeft < numCullOffsetsLimit:
            refinedOffsets = None

        stdWriter.finalize()

    return refinedOffsets
Ejemplo n.º 6
0
def fitOffsets(field):
    '''
    Estimate constant range and azimith shifs.
    '''


    stdWriter = create_writer("log","",True,filename='off.log')

    for distance in [10,5,3]:
        inpts = len(field._offsets)

        objOff = isceobj.createOffoutliers()
        objOff.wireInputPort(name='offsets', object=field)
        objOff.setSNRThreshold(2.0)
        objOff.setDistance(distance)
        objOff.setStdWriter(stdWriter)

        objOff.offoutliers()

        field = objOff.getRefinedOffsetField()
        outputs = len(field._offsets)

        print('%d points left'%(len(field._offsets)))

            
        wt = np.array([x.snr for x in field])
        dx = np.array([x.dx for x in field])
        dy = np.array([y.dy for y in field])

        azshift = np.dot(wt,dy) / np.sum(wt)
        rgshift = np.dot(wt,dx) / np.sum(wt)

        print('Estimated az shift: ', azshift)
        print('Estimated rg shift: ', rgshift)

    return (azshift, rgshift), field
Ejemplo n.º 7
0
#   STEP 2. cull offsets
#####################################################################

        #first cull by mean
        threshold = 3.5
        meanOffsets = meanOffset(offsets)
        offsets = cullOffsetbyMean(offsets, meanOffsets[1], threshold)


        distances = (10,5,3,3,3,3,3,3)
        numCullOffsetsLimits = (100, 75, 50, 50, 50, 50, 50, 50)
    
        refinedOffsets = offsets
        for i, (distance, numCullOffsetsLimit) in enumerate(zip(distances, numCullOffsetsLimits)):

            cullOff = isceobj.createOffoutliers()
            cullOff.wireInputPort(name='offsets', object=refinedOffsets)
            cullOff.setSNRThreshold(2.0)
            cullOff.setDistance(distance)
        
            #set the tag used in the outfile. each message is precided by this tag
            #is the writer is not of "file" type the call has no effect
            stdWriter = create_writer("log", "", True, filename="offoutliers.log")
            stdWriter.setFileTag("offoutliers", "log")
            stdWriter.setFileTag("offoutliers", "err")
            stdWriter.setFileTag("offoutliers", "out")
            cullOff.setStdWriter(stdWriter)


            #run it
            cullOff.offoutliers()
Ejemplo n.º 8
0
def run(imageAmp, imageSim, numBand, infos, nstages, scale, stdWriter, catalog=None, sceneid='NO_ID'):
    logger.info("Running Rgoffset: %s" % sceneid)

    coarseAcross = 0
    coarseDown = 0
    firstAc =  infos['firstSampleAcross']
    firstDown =  infos['firstSampleDown']
    numLocationAcross =  infos['numberLocationAcross']
    numLocationDown =  infos['numberLocationDown']

    slaveWidth = imageAmp.getWidth()
    slaveLength = imageAmp.getLength()
    objAmp = isceobj.createSlcImage()
    objAmp.dataType = 'CFLOAT'
    objAmp.bands = 1
    objAmp.setFilename(imageAmp.getFilename())
    objAmp.setAccessMode('read')
    objAmp.setWidth(slaveWidth)
    objAmp.createImage()

    masterWidth = imageSim.getWidth()
    objSim = isceobj.createImage()
    objSim.setFilename(imageSim.getFilename())
    objSim.dataType = 'FLOAT'
    objSim.setWidth(masterWidth)
    objSim.setAccessMode('read')
    objSim.createImage()
    masterLength = imageSim.getLength()

    finalIteration = False
    for iterNum in xrange(nstages-1,-1,-1):
        ####Rewind the images
        try:
            objAmp.rewind()
            objSim.rewind()
        except:
            print('Issues when rewinding images.') #KK sys.exit?

        ######
        logger.debug('Starting Iteration Stage : %d'%(iterNum))
        logger.debug("Gross Across: %s" % (coarseAcross))
        logger.debug("Gross Down: %s" % (coarseDown))

        ####Clear objs
        objAmpcor = None
        objOff = None
        offField = None

        objAmpcor = Ampcor()
        objAmpcor.setImageDataType1('real')
        objAmpcor.setImageDataType2('complex')

        ####Dummy values as there is no scale difference at this step
        objAmpcor.setFirstPRF(1.0)
        objAmpcor.setSecondPRF(1.0)
        objAmpcor.setFirstRangeSpacing(1.0)
        objAmpcor.setSecondRangeSpacing(1.0)

        #####Scale all the reference and search windows
        scaleFactor = scale**iterNum
        objAmpcor.windowSizeWidth *= scaleFactor
        objAmpcor.windowSizeHeight *= scaleFactor
        objAmpcor.searchWindowSizeWidth *= scaleFactor
        objAmpcor.searchWindowSizeHeight *= scaleFactor
        xMargin = 2*objAmpcor.searchWindowSizeWidth + objAmpcor.windowSizeWidth
        yMargin = 2*objAmpcor.searchWindowSizeHeight + objAmpcor.windowSizeHeight


        #####Set image limits for search
        offAc = max(firstAc,-coarseAcross)+xMargin
        offDn = max(firstDn,-coarseDown)+yMargin

        offAcmax = int(coarseAcross)
        logger.debug("Gross Max Across: %s" % (offAcmax))
        lastAc = int(min(masterWidth, slaveWidth-offAcmax) - xMargin)

        offDnmax = int(coarseDown)
        logger.debug("Gross Max Down: %s" % (offDnmax))

        lastDn = int(min(masterLength, slaveLength-offDnmax)  - yMargin)
        logger.debug("Last Down: %s" %(lastDn))
        objAmpcor.setFirstSampleAcross(offAc)
        objAmpcor.setLastSampleAcross(lastAc)
        objAmpcor.setFirstSampleDown(offDn)
        objAmpcor.setLastSampleDown(lastDn)
        objAmpcor.setAcrossGrossOffset(coarseAcross)
        objAmpcor.setDownGrossOffset(coarseDown)

        if (offAc > lastAc) or (offDn > lastDn):
            print('Search window scale is too large.')
            print('Skipping Scale: %d'%(iterNum+1))
            continue

        if ((lastAc - offAc) <=  (2*xMargin)) or ((lastDn - offDn) <= (2*yMargin)):
            print('Image not large enough accounting for margins.')
            print('Skipping Scale: %d'%(iterNum+1))
            continue

        logger.debug('Looks = %d'%scaleFactor)
        logger.debug('Correlation window sizes: %d  %d'%(objAmpcor.windowSizeWidth, objAmpcor.windowSizeHeight))
        logger.debug('Search window sizes: %d %d'%(objAmpcor.searchWindowSizeWidth, objAmpcor.searchWindowSizeHeight))
        logger.debug(' Across pos: %d %d out of (%d,%d)'%(objAmpcor.firstSampleAcross, objAmpcor.lastSampleAcross, masterWidth, slaveWidth))
        logger.debug(' Down pos: %d %d out of (%d,%d)'%(objAmpcor.firstSampleDown, objAmpcor.lastSampleDown, masterLength, slaveLength))
        if (iterNum == 0) or finalIteration:
            if catalog is not None:
                # Record the inputs
            isceobj.Catalog.recordInputs(catalog, objAmpcor,
                                         "runRgoffset.%s" % sceneid,
                                         logger,
                                         "runRgoffset.%s" % sceneid)
            objAmpcor.setNumberLocationAcross(numLocationAcross)
            objAmpcor.setNumberLocationDown(numLocationDown)
        else:
            objAmpcor.setNumberLocationAcross(20)
            objAmpcor.setNumberLocationDown(20)
            objAmpcor.setAcrossLooks(scaleFactor)
            objAmpcor.setDownLooks(scaleFactor)
            objAmpcor.setZoomWindowSize(scale*objAmpcor.zoomWindowSize)
            objAmpcor.setOversamplingFactor(2)


        objAmpcor.ampcor(objSim,objAmp)
        offField = objAmpcor.getOffsetField()

        if (iterNum == 0) or finalIteration:
            if catalog is not None:
                # Record the outputs
                isceobj.Catalog.recordOutputs(catalog, objAmpcor,
                                              "runRgoffset.%s" % sceneid,
                                              logger,
                                              "runRgoffset.%s" % sceneid)
        else:
            objOff = isceobj.createOffoutliers()
            objOff.wireInputPort(name='offsets', object=offField)
            objOff.setSNRThreshold(2.0)
            objOff.setDistance(10)
            objOff.setStdWriter = stdWriter.set_file_tags("nstage_offoutliers"+str(iterNum),
                                                          "log",
                                                          "err",
                                                          "out")
            objOff.offoutliers()
            coarseAcross = int(objOff.averageOffsetAcross)
            coarseDown = int(objOff.averageOffsetDown)

    objSim.finalizeImage()
    objAmp.finalizeImage()
    objOff = None
    objAmpcor = None

    return offField
Ejemplo n.º 9
0
    def nstage(self, slcImage1=None, slcImage2=None):
        if not (slcImage1 == None):
            self.slcImage1 = slcImage1
        if (self.slcImage1 == None):
            logger.error("Error. master slc image not set.")
            raise Exception
        if not (slcImage2 == None):
            self.slcImage2 = slcImage2
        if (self.slcImage2 == None):
            logger.error("Error. slave slc image not set.")
            raise Exception

        self.fileLength1 = self.slcImage1.getLength()
        self.lineLength1 = self.slcImage1.getWidth()
        self.fileLength2 = self.slcImage2.getLength()
        self.lineLength2 = self.slcImage2.getWidth()

        ####Run checks
        self.checkTypes()
        self.checkWindows()

        ####Actual processing
        mSlc = self.slcImage1
        sSlc = self.slcImage2
        coarseAcross = self.acrossGrossOffset
        coarseDown = self.downGrossOffset
        nStageName = self.name
        logger.info('NSTAGE NAME = %s' % (self.name))
        for iterNum in range(self.nStages - 1, -1, -1):
            ####Rewind the images
            try:
                mSlc.rewind()
                sSlc.rewind()
            except:
                logger.error('Issues when rewinding images.')
                raise Exception

            objOff = None
            objAmpcor = None

            logger.debug('Starting Iteration Stage: %d' % (iterNum))
            logger.debug('Gross Across: %s' % (coarseAcross))
            logger.debug('Gross Down  : %s' % (coarseDown))

            objAmpcor = Ampcor(name='%s_%d' % (nStageName, iterNum))
            objAmpcor.configure()
            objAmpcor.setImageDataType1(self.imageDataType1)
            objAmpcor.setImageDataType2(self.imageDataType2)
            objAmpcor.setFirstPRF(self.prf1)
            objAmpcor.setSecondPRF(self.prf2)
            objAmpcor.setFirstRangeSpacing(self.rangeSpacing1)
            objAmpcor.setSecondRangeSpacing(self.rangeSpacing2)

            ######Scale all the reference and search windows
            scaleFactor = self.scale**iterNum
            logger.debug('Scale Factor: %d' % (int(scaleFactor)))
            objAmpcor.windowSizeWidth = scaleFactor * self.windowSizeWidth
            objAmpcor.windowSizeHeight = scaleFactor * self.windowSizeHeight
            objAmpcor.searchWindowSizeWidth = scaleFactor * self.searchWindowSizeWidth
            objAmpcor.searchWindowSizeHeight = scaleFactor * self.searchWindowSizeHeight

            xMargin = 2 * objAmpcor.searchWindowSizeWidth + objAmpcor.windowSizeWidth
            yMargin = 2 * objAmpcor.searchWindowSizeHeight + objAmpcor.windowSizeHeight

            #####Set image limits for search
            offAc = max(objAmpcor.margin, -coarseAcross) + xMargin
            offDn = max(objAmpcor.margin, -coarseDown) + yMargin

            offAcmax = int(coarseAcross +
                           ((self.rangeSpacing1 / self.rangeSpacing2) - 1) *
                           self.lineLength1)
            logger.debug("Gross Max Across: %s" % (offAcmax))
            lastAc = int(
                min(self.lineLength1, self.lineLength2 - offAcmax) - xMargin)

            offDnmax = int(coarseDown +
                           ((self.prf2 / self.prf1) - 1) * self.lineLength1)
            logger.debug("Gross Max Down: %s" % (offDnmax))

            lastDn = int(
                min(self.fileLength1, self.fileLength2 - offDnmax) - yMargin)

            objAmpcor.setFirstSampleAcross(offAc)
            objAmpcor.setLastSampleAcross(lastAc)
            objAmpcor.setFirstSampleDown(offDn)
            objAmpcor.setLastSampleDown(lastDn)

            objAmpcor.setAcrossGrossOffset(coarseAcross)
            objAmpcor.setDownGrossOffset(coarseDown)

            if (offAc > lastAc) or (offDn > lastDn):
                logger.info('Search window scale is too large.')
                logger.info('Skipping scale: %d' % (iterNum + 1))
                continue

            logger.debug('First Sample Across = %d' % (offAc))
            logger.debug('Last Sampe Across = %d' % (lastAc))
            logger.debug('First Sample Down = %d' % (offDn))
            logger.debug('Last Sample Down = %d' % (lastDn))
            logger.debug('Looks = %d' % (scaleFactor))
            logger.debug(
                'Correlation window sizes: %d %d' %
                (objAmpcor.windowSizeWidth, objAmpcor.windowSizeHeight))
            logger.debug('Search window sizes: %d %d' %
                         (objAmpcor.searchWindowSizeWidth,
                          objAmpcor.searchWindowSizeHeight))

            objAmpcor.band1 = self.band1
            objAmpcor.band2 = self.band2
            if (iterNum == 0):
                objAmpcor.setNumberLocationAcross(self.numberLocationAcross)
                objAmpcor.setNumberLocationDown(self.numberLocationDown)
                objAmpcor.setAcrossLooks(self.acrossLooks)
                objAmpcor.setDownLooks(self.downLooks)
                objAmpcor.setZoomWindowSize(self.zoomWindowSize)
                objAmpcor.setOversamplingFactor(self.oversamplingFactor)
            else:
                objAmpcor.setNumberLocationAcross(self.coarseNumWinAcross)
                objAmpcor.setNumberLocationDown(self.coarseNumWinDown)
                objAmpcor.setAcrossLooks(scaleFactor * self.acrossLooks)
                objAmpcor.setDownLooks(scaleFactor * self.downLooks)
                objAmpcor.setZoomWindowSize(self.coarseZoomWindowSize)
                objAmpcor.setOversamplingFactor(self.coarseOversamplingFactor)

            objAmpcor.ampcor(mSlc, sSlc)

            offField = objAmpcor.getOffsetField()

            if (iterNum != 0):
                objOff = isceobj.createOffoutliers()
                objOff.wireInputPort(name='offsets', object=offField)
                objOff.setSNRThreshold(self.coarseSNRThreshold)
                objOff.setDistance(self.coarseDistance)
                self._stdWriter.setFileTag("nstage_offoutliers" + str(iterNum),
                                           "log")
                self._stdWriter.setFileTag("nstage_offoutliers" + str(iterNum),
                                           "err")
                self._stdWriter.setFileTag("nstage_offoutliers" + str(iterNum),
                                           "out")
                objOff.setStdWriter(self._stdWriter)
                objOff.offoutliers()

                fracLeft = len(
                    objOff.indexArray) / (1.0 * len(offField._offsets))

                print('FracLEft = ', fracLeft)
                if (fracLeft < 0.1):
                    logger.error(
                        'NStage - Iteration: %d, Fraction Windows left: %d. Increase number of windows or improve gross offset estimate manually.'
                        % (iterNum, int(100 * fracLeft)))
                    raise Exception(
                        'NStage matching failed at iteration : %d' % (iterNum))
                elif (fracLeft < 0.2):
                    logger.error(
                        'NStage - Iteration: %d, Fraction Windows left: %d. Increase number of windows or improve gross offset estimate manually.'
                        % (iterNum, int(100 * fracLeft)))

                coarseAcross = int(objOff.averageOffsetAcross)
                coarseDown = int(objOff.averageOffsetDown)

        mSlc.finalizeImage()
        sSlc.finalizeImage()

        self.getState(offField)
        objOff = None
        objAmpcor = None
        return
Ejemplo n.º 10
0
def run(frame1,
        frame2,
        formSlc1,
        formSlc2,
        imSlc1,
        imSlc2,
        nstages,
        scale,
        infos,
        stdWriter,
        catalog=None,
        sceneid='NO_ID'):
    logger.info(
        "Calculate offset between slcs using %d stages of ampcor: %s " %
        (nstages, sceneid))

    prf1 = frame1.getInstrument().getPulseRepetitionFrequency()
    prf2 = frame2.getInstrument().getPulseRepetitionFrequency()
    nearRange1 = formSlc1.startingRange
    nearRange2 = formSlc2.startingRange
    fs1 = frame1.getInstrument().getRangeSamplingRate()
    fs2 = frame2.getInstrument().getRangeSamplingRate()

    ###There seems to be no other way of determining image length - Piyush
    patchSize = infos['patchSize']
    numPatches = infos['numberPatches']
    valid_az_samples = infos['numberValidPulses']
    firstAc = infos['firstSampleAcrossPrf']
    firstDown = infos['firstSampleDownPrf']
    numLocationAcross = infos['numberLocationAcrossPrf']
    numLocationDown = infos['numberLocationDownPrf']

    delRg1 = CN.SPEED_OF_LIGHT / (2 * fs1)
    delRg2 = CN.SPEED_OF_LIGHT / (2 * fs2)

    grossRg = infos['grossRg']
    if grossRg is not None:
        coarseAcross = grossRg
    else:
        coarseRange = (nearRange1 - nearRange2) / delRg2
        coarseAcross = int(coarseRange + 0.5)
        if (coarseRange <= 0):
            coarseAcross = int(coarseRange - 0.5)

    grossAz = infos['grossAz']
    if grossAz is not None:
        coarseDown = grossAz
    else:
        s1 = formSlc1.mocompPosition[1][0]
        s1_2 = formSlc1.mocompPosition[1][1]
        s2 = formSlc2.mocompPosition[1][0]
        s2_2 = formSlc2.mocompPosition[1][1]

        coarseAz = int((s1 - s2) / (s2_2 - s2) + prf2 * (1 / prf1 - 1 / prf2) *
                       (patchSize - valid_az_samples) / 2)
        coarseDown = int(coarseAz + 0.5)
        if (coarseAz <= 0):
            coarseDown = int(coarseAz - 0.5)

    coarseAcross = 0 + coarseAcross
    coarseDown = 0 + coarseDown

    mSlc = isceobj.createSlcImage()
    IU.copyAttributes(imSlc1, mSlc)
    accessMode = 'read'
    mSlc.setAccessMode(accessMode)
    mSlc.createImage()
    masterWidth = mSlc.getWidth()
    masterLength = mSlc.getLength()

    sSlc = isceobj.createSlcImage()
    IU.copyAttributes(imSlc2, sSlc)
    accessMode = 'read'
    sSlc.setAccessMode(accessMode)
    sSlc.createImage()
    slaveWidth = sSlc.getWidth()
    slaveLength = sSlc.getLength()

    finalIteration = False
    for iterNum in xrange(nstages - 1, -1, -1):
        ####Rewind the images
        try:
            mSlc.rewind()
            sSlc.rewind()
        except:
            print('Issues when rewinding images.'
                  )  #KK shouldn't it be an error? sys.exit

        ######
        logger.debug('Starting Iteration Stage : %d' % (iterNum))
        logger.debug("Gross Across: %s" % (coarseAcross))
        logger.debug("Gross Down: %s" % (coarseDown))

        ####Clear objs
        objAmpcor = None
        objOff = None
        offField = None

        objAmpcor = Ampcor()
        objAmpcor.setImageDataType1('complex')
        objAmpcor.setImageDataType2('complex')
        objAmpcor.setFirstPRF(prf1)
        objAmpcor.setSecondPRF(prf2)
        objAmpcor.setFirstRangeSpacing(delRg1)
        objAmpcor.setSecondRangeSpacing(delRg2)

        #####Scale all the reference and search windows
        scaleFactor = scale**iterNum
        objAmpcor.windowSizeWidth *= scaleFactor
        objAmpcor.windowSizeHeight *= scaleFactor
        objAmpcor.searchWindowSizeWidth *= scaleFactor
        objAmpcor.searchWindowSizeHeight *= scaleFactor
        xMargin = 2 * objAmpcor.searchWindowSizeWidth + objAmpcor.windowSizeWidth
        yMargin = 2 * objAmpcor.searchWindowSizeHeight + objAmpcor.windowSizeHeight

        #####Set image limits for search
        offAc = max(firstAc, -coarseAcross) + xMargin
        offDn = max(firstDown, -coarseDown) + yMargin

        offAcmax = int(coarseAcross + ((fs2 / fs1) - 1) * masterWidth)
        logger.debug("Gross Max Across: %s" % (offAcmax))
        lastAc = int(min(masterWidth, slaveWidth - offAcmax) - xMargin)

        offDnmax = int(coarseDown + ((prf2 / prf1) - 1) * masterLength)
        logger.debug("Gross Max Down: %s" % (offDnmax))

        lastDn = int(min(masterLength, slaveLength - offDnmax) - yMargin)

        objAmpcor.setFirstSampleAcross(offAc)
        objAmpcor.setLastSampleAcross(lastAc)
        objAmpcor.setFirstSampleDown(offDn)
        objAmpcor.setLastSampleDown(lastDn)
        objAmpcor.setAcrossGrossOffset(coarseAcross)
        objAmpcor.setDownGrossOffset(coarseDown)

        if (offAc > lastAc) or (offDn > lastDn):
            print('Search window scale is too large.')
            print('Skipping Scale: %d' % (iterNum + 1))
            continue

        logger.debug('Looks = %d' % scaleFactor)
        logger.debug('Correlation window sizes: %d  %d' %
                     (objAmpcor.windowSizeWidth, objAmpcor.windowSizeHeight))
        logger.debug('Search window sizes: %d %d' %
                     (objAmpcor.searchWindowSizeWidth,
                      objAmpcor.searchWindowSizeHeight))
        logger.debug(' Across pos: %d %d out of (%d,%d)' %
                     (objAmpcor.firstSampleAcross, objAmpcor.lastSampleAcross,
                      masterWidth, slaveWidth))
        logger.debug(' Down pos: %d %d out of (%d,%d)' %
                     (objAmpcor.firstSampleDown, objAmpcor.lastSampleDown,
                      masterLength, slaveLength))
        if (iterNum == 0) or finalIteration:
            if catalog is not None:
                # Record the inputs
                isceobj.Catalog.recordInputs(catalog, objAmpcor,
                                             "runOffsetprf.%s" % sceneid,
                                             logger,
                                             "runOffsetprf.%s" % sceneid)
            objAmpcor.setNumberLocationAcross(numLocationAcross)
            objAmpcor.setNumberLocationDown(numLocationDown)
        else:
            objAmpcor.setNumberLocationAcross(10)
            objAmpcor.setNumberLocationDown(10)
            objAmpcor.setAcrossLooks(scaleFactor)
            objAmpcor.setDownLooks(scaleFactor)
            objAmpcor.setZoomWindowSize(scale * objAmpcor.zoomWindowSize)
            objAmpcor.setOversamplingFactor(2)

        objAmpcor.ampcor(mSlc, sSlc)
        offField = objAmpcor.getOffsetField()

        if (iterNum == 0) or finalIteration:
            if catalog is not None:
                # Record the outputs
                isceobj.Catalog.recordOutputs(catalog, objAmpcor,
                                              "runOffsetprf.%s" % sceneid,
                                              logger,
                                              "runOffsetprf.%s" % sceneid)
        else:
            objOff = isceobj.createOffoutliers()
            objOff.wireInputPort(name='offsets', object=offField)
            objOff.setSNRThreshold(2.0)
            objOff.setDistance(10)
            objOff.setStdWriter = stdWriter.set_file_tags(
                "nstage_offoutliers" + str(iterNum), "log", "err", "out")
            objOff.offoutliers()
            coarseAcross = int(objOff.averageOffsetAcross)
            coarseDown = int(objOff.averageOffsetDown)

    mSlc.finalizeImage()
    sSlc.finalizeImage()
    objOff = None
    objAmpcor = None

    return offField