Пример #1
0
def runGeocodeOffset(self):
    '''geocode 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()

    #use original track object to determine bbox
    if self.bbox == None:
        masterTrack = self._insar.loadTrack(master=True)
        bbox = getBboxGeo(masterTrack)
    else:
        bbox = self.bbox
    catalog.addItem('geocode bounding box', bbox, 'runGeocodeOffset')

    demFile = os.path.abspath(self._insar.demGeo)

    denseOffsetDir = 'dense_offset'
    if not os.path.exists(denseOffsetDir):
        os.makedirs(denseOffsetDir)
    os.chdir(denseOffsetDir)

    masterTrack = self._insar.loadProduct(self._insar.masterTrackParameter)
    #slaveTrack = self._insar.loadProduct(self._insar.slaveTrackParameter)

    #########################################################################################
    #compute bounding box for geocoding
    #if self.bbox == None:
    #    bbox = getBboxGeo(masterTrack)
    #else:
    #    bbox = self.bbox
    #catalog.addItem('geocode bounding box', bbox, 'runGeocodeOffset')

    geocodeList = [self._insar.denseOffset, self._insar.denseOffsetSnr]
    if self.doOffsetFiltering:
        geocodeList.append(self._insar.denseOffsetFilt)

    for inputFile in geocodeList:
        interpMethod = 'nearest'
        geocode(masterTrack,
                demFile,
                inputFile,
                bbox,
                self.offsetSkipWidth,
                self.offsetSkipHeight,
                interpMethod,
                self._insar.offsetImageTopoffset,
                self._insar.offsetImageLeftoffset,
                addMultilookOffset=False)
#########################################################################################

    os.chdir('../')
    catalog.printToLog(logger, "runGeocodeOffset")
    self._insar.procDoc.addAllFromCatalog(catalog)
Пример #2
0
def runGeocode(self):
    '''geocode final products
    '''
    if hasattr(self, 'doInSAR'):
        if not self.doInSAR:
            return

    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    referenceTrack = self._insar.loadTrack(reference=True)
    #secondaryTrack = self._insar.loadTrack(reference=False)

    demFile = os.path.abspath(self._insar.demGeo)

    insarDir = 'insar'
    os.makedirs(insarDir, exist_ok=True)
    os.chdir(insarDir)

    #compute bounding box for geocoding
    if self.bbox == None:
        bbox = getBboxGeo(referenceTrack)
    else:
        bbox = self.bbox
    catalog.addItem('geocode bounding box', bbox, 'runGeocode')

    if self.geocodeList == None:
        geocodeList = [self._insar.unwrappedInterferogram,
        self._insar.unwrappedMaskedInterferogram,
        self._insar.multilookCoherence,
        self._insar.multilookLos]
        if self.doIon:
            geocodeList.append(self._insar.multilookIon)
    else:
        geocodeList = []
        for xxx in self.geocodeList:
            geocodeList += glob.glob(xxx)

    numberRangeLooks = self._insar.numberRangeLooks1 * self._insar.numberRangeLooks2
    numberAzimuthLooks = self._insar.numberAzimuthLooks1 * self._insar.numberAzimuthLooks2

    for inputFile in geocodeList:
        if self.geocodeInterpMethod == None:
            img = isceobj.createImage()
            img.load(inputFile + '.xml')
            if img.dataType.upper() == 'CFLOAT':
                interpMethod = 'sinc'
            else:
                interpMethod = 'bilinear'
        else:
            interpMethod = self.geocodeInterpMethod.lower()

        geocode(referenceTrack, demFile, inputFile, bbox, numberRangeLooks, numberAzimuthLooks, interpMethod, 0, 0)


    os.chdir('../')

    catalog.printToLog(logger, "runGeocode")
    self._insar.procDoc.addAllFromCatalog(catalog)
Пример #3
0
def runGeocodeSd(self):
    '''geocode final products
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    referenceTrack = self._insar.loadTrack(reference=True)
    #secondaryTrack = self._insar.loadTrack(reference=False)

    demFile = os.path.abspath(self._insar.demGeo)

    sdDir = 'sd'
    os.makedirs(sdDir, exist_ok=True)
    os.chdir(sdDir)

    if self.geocodeListSd == None:
        geocodeList = self._insar.multilookCoherenceSd + self._insar.azimuthDeformationSd + self._insar.maskedAzimuthDeformationSd
    else:
        geocodeList = []
        for xxx in self.geocodeListSd:
            geocodeList += glob.glob(xxx)

    if self.bbox == None:
        bbox = getBboxGeo(referenceTrack)
    else:
        bbox = self.bbox
    catalog.addItem('geocode bounding box', bbox, 'runGeocodeSd')

    numberRangeLooks = self._insar.numberRangeLooks1 * self._insar.numberRangeLooksSd
    numberAzimuthLooks = self._insar.numberAzimuthLooks1 * self._insar.numberAzimuthLooksSd

    for inputFile in geocodeList:
        if self.geocodeInterpMethodSd == None:
            img = isceobj.createImage()
            img.load(inputFile + '.xml')
            if img.dataType.upper() == 'CFLOAT':
                interpMethod = 'sinc'
            else:
                interpMethod = 'bilinear'
        else:
            interpMethod = self.geocodeInterpMethodSd.lower()

        geocode(referenceTrack, demFile, inputFile, bbox, numberRangeLooks, numberAzimuthLooks, interpMethod, 0, 0)


    os.chdir('../')

    catalog.printToLog(logger, "runGeocodeSd")
    self._insar.procDoc.addAllFromCatalog(catalog)
Пример #4
0
def runPreprocessor(self):
    '''Extract images.
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)


    #find files
    #actually no need to use absolute path any longer, since we are able to find file from vrt now. 27-JAN-2020, CRL.
    #denseoffset may still need absolute path when making links
    self.masterDir = os.path.abspath(self.masterDir)
    self.slaveDir = os.path.abspath(self.slaveDir)

    ledFilesMaster = sorted(glob.glob(os.path.join(self.masterDir, 'LED-ALOS2*-*-*')))
    imgFilesMaster = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*-*-*'.format(self.masterPolarization.upper()))))

    ledFilesSlave = sorted(glob.glob(os.path.join(self.slaveDir, 'LED-ALOS2*-*-*')))
    imgFilesSlave = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*-*-*'.format(self.slavePolarization.upper()))))

    firstFrameMaster = ledFilesMaster[0].split('-')[-3][-4:]
    firstFrameSlave = ledFilesSlave[0].split('-')[-3][-4:]
    firstFrameImagesMaster = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.masterPolarization.upper(), firstFrameMaster))))
    firstFrameImagesSlave = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.slavePolarization.upper(), firstFrameSlave))))


    #determin operation mode
    masterMode = os.path.basename(ledFilesMaster[0]).split('-')[-1][0:3]
    slaveMode = os.path.basename(ledFilesSlave[0]).split('-')[-1][0:3]
    spotlightModes = ['SBS']
    stripmapModes = ['UBS', 'UBD', 'HBS', 'HBD', 'HBQ', 'FBS', 'FBD', 'FBQ']
    scansarNominalModes = ['WBS', 'WBD', 'WWS', 'WWD']
    scansarWideModes = ['VBS', 'VBD']
    scansarModes = ['WBS', 'WBD', 'WWS', 'WWD', 'VBS', 'VBD']

    #usable combinations
    if (masterMode in spotlightModes) and (slaveMode in spotlightModes):
        self._insar.modeCombination = 0
    elif (masterMode in stripmapModes) and (slaveMode in stripmapModes):
        self._insar.modeCombination = 1
    elif (masterMode in scansarNominalModes) and (slaveMode in scansarNominalModes):
        self._insar.modeCombination = 21
    elif (masterMode in scansarWideModes) and (slaveMode in scansarWideModes):
        self._insar.modeCombination = 22
    elif (masterMode in scansarNominalModes) and (slaveMode in stripmapModes):
        self._insar.modeCombination = 31
    elif (masterMode in scansarWideModes) and (slaveMode in stripmapModes):
        self._insar.modeCombination = 32
    else:
        print('\n\nthis mode combination is not possible')
        print('note that for ScanSAR-stripmap, ScanSAR must be master\n\n')
        raise Exception('mode combination not supported')


    if self._insar.modeCombination != 21:
        print('\n\nburst processing only support {}\n\n'.format(scansarNominalModes))
        raise Exception('mode combination not supported')


    #determine default number of looks:
    self._insar.numberRangeLooks1 = self.numberRangeLooks1
    self._insar.numberAzimuthLooks1 = self.numberAzimuthLooks1
    self._insar.numberRangeLooks2 = self.numberRangeLooks2
    self._insar.numberAzimuthLooks2 = self.numberAzimuthLooks2
    #the following two will be automatically determined by runRdrDemOffset.py
    self._insar.numberRangeLooksSim = self.numberRangeLooksSim
    self._insar.numberAzimuthLooksSim = self.numberAzimuthLooksSim
    self._insar.numberRangeLooksIon = self.numberRangeLooksIon
    self._insar.numberAzimuthLooksIon = self.numberAzimuthLooksIon
    self._insar.numberRangeLooksSd = self.numberRangeLooksSd
    self._insar.numberAzimuthLooksSd = self.numberAzimuthLooksSd

    #force number of looks 1 to 1
    self.numberRangeLooks1 = 1
    self.numberAzimuthLooks1 = 1
    self._insar.numberRangeLooks1 = 1
    self._insar.numberAzimuthLooks1 = 1
    if self._insar.numberRangeLooks2 == None:
        self._insar.numberRangeLooks2 = 7
    if self._insar.numberAzimuthLooks2 == None:
        self._insar.numberAzimuthLooks2 = 2
    if self._insar.numberRangeLooksIon == None:
        self._insar.numberRangeLooksIon = 42
    if self._insar.numberAzimuthLooksIon == None:
        self._insar.numberAzimuthLooksIon = 12
    if self._insar.numberRangeLooksSd == None:
        self._insar.numberRangeLooksSd = 14
    if self._insar.numberAzimuthLooksSd == None:
        self._insar.numberAzimuthLooksSd = 4

    #define processing file names
    self._insar.masterDate = os.path.basename(ledFilesMaster[0]).split('-')[2]
    self._insar.slaveDate = os.path.basename(ledFilesSlave[0]).split('-')[2]
    self._insar.setFilename(masterDate=self._insar.masterDate, slaveDate=self._insar.slaveDate, 
        nrlks1=self._insar.numberRangeLooks1, nalks1=self._insar.numberAzimuthLooks1, 
        nrlks2=self._insar.numberRangeLooks2, nalks2=self._insar.numberAzimuthLooks2)
    self._insar.setFilenameSd(masterDate=self._insar.masterDate, slaveDate=self._insar.slaveDate, 
        nrlks1=self._insar.numberRangeLooks1, nalks1=self._insar.numberAzimuthLooks1, 
        nrlks_sd=self._insar.numberRangeLooksSd, nalks_sd=self._insar.numberAzimuthLooksSd, nsd=3)

    #find frame numbers
    if (self._insar.modeCombination == 31) or (self._insar.modeCombination == 32):
        if (self.masterFrames == None) or (self.slaveFrames == None):
            raise Exception('for ScanSAR-stripmap inteferometry, you must set master and slave frame numbers')
    #if not set, find frames automatically
    if self.masterFrames == None:
        self.masterFrames = []
        for led in ledFilesMaster:
            frameNumber = os.path.basename(led).split('-')[1][-4:]
            if frameNumber not in self.masterFrames:
                self.masterFrames.append(frameNumber)
    if self.slaveFrames == None:
        self.slaveFrames = []
        for led in ledFilesSlave:
            frameNumber = os.path.basename(led).split('-')[1][-4:]
            if frameNumber not in self.slaveFrames:
                self.slaveFrames.append(frameNumber)
    #sort frames
    self.masterFrames = sorted(self.masterFrames)
    self.slaveFrames = sorted(self.slaveFrames)
    #check number of frames
    if len(self.masterFrames) != len(self.slaveFrames):
        raise Exception('number of frames in master dir is not equal to number of frames \
            in slave dir. please set frame number manually')


    #find swath numbers (if not ScanSAR-ScanSAR, compute valid swaths)
    if (self._insar.modeCombination == 0) or (self._insar.modeCombination == 1):
        self.startingSwath = 1
        self.endingSwath = 1

    if self._insar.modeCombination == 21:
        if self.startingSwath == None:
            self.startingSwath = 1
        if self.endingSwath == None:
            self.endingSwath = 5

    if self._insar.modeCombination == 22:
        if self.startingSwath == None:
            self.startingSwath = 1
        if self.endingSwath == None:
            self.endingSwath = 7

    #determine starting and ending swaths for ScanSAR-stripmap, user's settings are overwritten
    #use first frame to check overlap
    if (self._insar.modeCombination == 31) or (self._insar.modeCombination == 32):
        if self._insar.modeCombination == 31:
            numberOfSwaths = 5
        else:
            numberOfSwaths = 7
        overlapSubswaths = []
        for i in range(numberOfSwaths):
            overlapRatio = check_overlap(ledFilesMaster[0], firstFrameImagesMaster[i], ledFilesSlave[0], firstFrameImagesSlave[0])
            if overlapRatio > 1.0 / 4.0:
                overlapSubswaths.append(i+1)
        if overlapSubswaths == []:
            raise Exception('There is no overlap area between the ScanSAR-stripmap pair')
        self.startingSwath = int(overlapSubswaths[0])
        self.endingSwath = int(overlapSubswaths[-1])

    #save the valid frames and swaths for future processing
    self._insar.masterFrames = self.masterFrames
    self._insar.slaveFrames = self.slaveFrames
    self._insar.startingSwath = self.startingSwath
    self._insar.endingSwath = self.endingSwath


    ##################################################
    #1. create directories and read data
    ##################################################
    self.master.configure()
    self.slave.configure()
    self.master.track.configure()
    self.slave.track.configure()
    for i, (masterFrame, slaveFrame) in enumerate(zip(self._insar.masterFrames, self._insar.slaveFrames)):
        #frame number starts with 1
        frameDir = 'f{}_{}'.format(i+1, masterFrame)
        if not os.path.exists(frameDir):
            os.makedirs(frameDir)
        os.chdir(frameDir)

        #attach a frame to master and slave
        frameObjMaster = MultiMode.createFrame()
        frameObjSlave = MultiMode.createFrame()
        frameObjMaster.configure()
        frameObjSlave.configure()
        self.master.track.frames.append(frameObjMaster)
        self.slave.track.frames.append(frameObjSlave)

        #swath number starts with 1
        for j in range(self._insar.startingSwath, self._insar.endingSwath+1):
            print('processing frame {} swath {}'.format(masterFrame, j))

            swathDir = 's{}'.format(j)
            if not os.path.exists(swathDir):
                os.makedirs(swathDir)
            os.chdir(swathDir)

            #attach a swath to master and slave
            swathObjMaster = MultiMode.createSwath()
            swathObjSlave = MultiMode.createSwath()
            swathObjMaster.configure()
            swathObjSlave.configure()
            self.master.track.frames[-1].swaths.append(swathObjMaster)
            self.slave.track.frames[-1].swaths.append(swathObjSlave)

            #setup master
            self.master.leaderFile = sorted(glob.glob(os.path.join(self.masterDir, 'LED-ALOS2*{}-*-*'.format(masterFrame))))[0]
            if masterMode in scansarModes:
                self.master.imageFile = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*{}-*-*-F{}'.format(self.masterPolarization.upper(), masterFrame, j))))[0]
            else:
                self.master.imageFile = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.masterPolarization.upper(), masterFrame))))[0]
            self.master.outputFile = self._insar.masterSlc
            self.master.useVirtualFile = self.useVirtualFile
            #read master
            (imageFDR, imageData)=self.master.readImage()
            (leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord)=self.master.readLeader()
            self.master.setSwath(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
            self.master.setFrame(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
            self.master.setTrack(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)

            #setup slave
            self.slave.leaderFile = sorted(glob.glob(os.path.join(self.slaveDir, 'LED-ALOS2*{}-*-*'.format(slaveFrame))))[0]
            if slaveMode in scansarModes:
                self.slave.imageFile = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*{}-*-*-F{}'.format(self.slavePolarization.upper(), slaveFrame, j))))[0]
            else:
                self.slave.imageFile = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.slavePolarization.upper(), slaveFrame))))[0]
            self.slave.outputFile = self._insar.slaveSlc
            self.slave.useVirtualFile = self.useVirtualFile
            #read slave
            (imageFDR, imageData)=self.slave.readImage()
            (leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord)=self.slave.readLeader()
            self.slave.setSwath(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
            self.slave.setFrame(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
            self.slave.setTrack(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)

            os.chdir('../')
        self._insar.saveProduct(self.master.track.frames[-1], self._insar.masterFrameParameter)
        self._insar.saveProduct(self.slave.track.frames[-1], self._insar.slaveFrameParameter)
        os.chdir('../')
    self._insar.saveProduct(self.master.track, self._insar.masterTrackParameter)
    self._insar.saveProduct(self.slave.track, self._insar.slaveTrackParameter)


    ##################################################
    #2. compute burst synchronization
    ##################################################
    #burst synchronization may slowly change along a track as a result of the changing relative speed of the two flights
    #in one frame, real unsynchronized time is the same for all swaths
    unsynTime = 0
    #real synchronized time/percentage depends on the swath burst length (synTime = burstlength - abs(unsynTime))
    #synTime = 0
    synPercentage = 0

    numberOfFrames = len(self._insar.masterFrames)
    numberOfSwaths = self._insar.endingSwath - self._insar.startingSwath + 1
    
    for i, frameNumber in enumerate(self._insar.masterFrames):
        for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            masterSwath = self.master.track.frames[i].swaths[j]
            slaveSwath = self.slave.track.frames[i].swaths[j]
            #using Piyush's code for computing range and azimuth offsets
            midRange = masterSwath.startingRange + masterSwath.rangePixelSize * masterSwath.numberOfSamples * 0.5
            midSensingStart = masterSwath.sensingStart + datetime.timedelta(seconds = masterSwath.numberOfLines * 0.5 / masterSwath.prf)
            llh = self.master.track.orbit.rdr2geo(midSensingStart, midRange)
            slvaz, slvrng = self.slave.track.orbit.geo2rdr(llh)
            ###Translate to offsets
            #note that slave range pixel size and prf might be different from master, here we assume there is a virtual slave with same
            #range pixel size and prf
            rgoff = ((slvrng - slaveSwath.startingRange) / masterSwath.rangePixelSize) - masterSwath.numberOfSamples * 0.5
            azoff = ((slvaz - slaveSwath.sensingStart).total_seconds() * masterSwath.prf) - masterSwath.numberOfLines * 0.5

            #compute burst synchronization
            #burst parameters for ScanSAR wide mode not estimed yet
            if self._insar.modeCombination == 21:
                scburstStartLine = (masterSwath.burstStartTime - masterSwath.sensingStart).total_seconds() * masterSwath.prf + azoff
                #slave burst start times corresponding to master burst start times (100% synchronization)
                scburstStartLines = np.arange(scburstStartLine - 100000*masterSwath.burstCycleLength, \
                                              scburstStartLine + 100000*masterSwath.burstCycleLength, \
                                              masterSwath.burstCycleLength)
                dscburstStartLines = -((slaveSwath.burstStartTime - slaveSwath.sensingStart).total_seconds() * slaveSwath.prf - scburstStartLines)
                #find the difference with minimum absolute value
                unsynLines = dscburstStartLines[np.argmin(np.absolute(dscburstStartLines))]
                if np.absolute(unsynLines) >= slaveSwath.burstLength:
                    synLines = 0
                    if unsynLines > 0:
                        unsynLines = slaveSwath.burstLength
                    else:
                        unsynLines = -slaveSwath.burstLength
                else:
                    synLines = slaveSwath.burstLength - np.absolute(unsynLines)

                unsynTime += unsynLines / masterSwath.prf
                synPercentage += synLines / masterSwath.burstLength * 100.0

                catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(synLines / masterSwath.burstLength * 100.0), 'runPreprocessor')

            ############################################################################################
            #illustration of the sign of the number of unsynchronized lines (unsynLines)     
            #The convention is the same as ampcor offset, that is,
            #              slaveLineNumber = masterLineNumber + unsynLines
            #
            # |-----------------------|     ------------
            # |                       |        ^
            # |                       |        |
            # |                       |        |   unsynLines < 0
            # |                       |        |
            # |                       |       \ /
            # |                       |    |-----------------------|
            # |                       |    |                       |
            # |                       |    |                       |
            # |-----------------------|    |                       |
            #        Master Burst          |                       |
            #                              |                       |
            #                              |                       |
            #                              |                       |
            #                              |                       |
            #                              |-----------------------|
            #                                     Slave Burst
            #
            #
            ############################################################################################
 
            ##burst parameters for ScanSAR wide mode not estimed yet
            elif self._insar.modeCombination == 31:
                #scansar is master
                scburstStartLine = (masterSwath.burstStartTime - masterSwath.sensingStart).total_seconds() * masterSwath.prf + azoff
                #slave burst start times corresponding to master burst start times (100% synchronization)
                for k in range(-100000, 100000):
                    saz_burstx = scburstStartLine + masterSwath.burstCycleLength * k
                    st_burstx = slaveSwath.sensingStart + datetime.timedelta(seconds=saz_burstx / masterSwath.prf)
                    if saz_burstx >= 0.0 and saz_burstx <= slaveSwath.numberOfLines -1:
                        slaveSwath.burstStartTime = st_burstx
                        slaveSwath.burstLength = masterSwath.burstLength
                        slaveSwath.burstCycleLength = masterSwath.burstCycleLength
                        slaveSwath.swathNumber = masterSwath.swathNumber
                        break
                #unsynLines = 0
                #synLines = masterSwath.burstLength
                #unsynTime += unsynLines / masterSwath.prf
                #synPercentage += synLines / masterSwath.burstLength * 100.0
                catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(100.0), 'runPreprocessor')
            else:
                pass

        #overwrite original frame parameter file
        if self._insar.modeCombination == 31:
            frameDir = 'f{}_{}'.format(i+1, frameNumber)
            self._insar.saveProduct(self.slave.track.frames[i], os.path.join(frameDir, self._insar.slaveFrameParameter))

    #getting average
    if self._insar.modeCombination == 21:
        unsynTime /= numberOfFrames*numberOfSwaths
        synPercentage /= numberOfFrames*numberOfSwaths
    elif self._insar.modeCombination == 31:
        unsynTime = 0.
        synPercentage = 100.
    else:
        pass

    #record results
    if (self._insar.modeCombination == 21) or (self._insar.modeCombination == 31):
        self._insar.burstUnsynchronizedTime = unsynTime
        self._insar.burstSynchronization = synPercentage
        catalog.addItem('burst synchronization averaged', '%.1f%%'%(synPercentage), 'runPreprocessor')


    ##################################################
    #3. compute baseline
    ##################################################
    #only compute baseline at four corners and center of the master track
    bboxRdr = getBboxRdr(self.master.track)

    rangeMin = bboxRdr[0]
    rangeMax = bboxRdr[1]
    azimuthTimeMin = bboxRdr[2]
    azimuthTimeMax = bboxRdr[3]

    azimuthTimeMid = azimuthTimeMin+datetime.timedelta(seconds=(azimuthTimeMax-azimuthTimeMin).total_seconds()/2.0)
    rangeMid = (rangeMin + rangeMax) / 2.0

    points = [[azimuthTimeMin, rangeMin],
              [azimuthTimeMin, rangeMax],
              [azimuthTimeMax, rangeMin],
              [azimuthTimeMax, rangeMax],
              [azimuthTimeMid, rangeMid]]

    Bpar = []
    Bperp = []
    #modify Piyush's code for computing baslines
    refElp = Planet(pname='Earth').ellipsoid
    for x in points:
        masterSV = self.master.track.orbit.interpolate(x[0], method='hermite')
        target = self.master.track.orbit.rdr2geo(x[0], x[1])

        slvTime, slvrng = self.slave.track.orbit.geo2rdr(target)
        slaveSV = self.slave.track.orbit.interpolateOrbit(slvTime, method='hermite')

        targxyz = np.array(refElp.LLH(target[0], target[1], target[2]).ecef().tolist())
        mxyz = np.array(masterSV.getPosition())
        mvel = np.array(masterSV.getVelocity())
        sxyz = np.array(slaveSV.getPosition())

        aa = np.linalg.norm(sxyz-mxyz)
        costheta = (x[1]*x[1] + aa*aa - slvrng*slvrng)/(2.*x[1]*aa)

        Bpar.append(aa*costheta)

        perp = aa * np.sqrt(1 - costheta*costheta)
        direction = np.sign(np.dot( np.cross(targxyz-mxyz, sxyz-mxyz), mvel))
        Bperp.append(direction*perp)    

    catalog.addItem('parallel baseline at upperleft of master track', Bpar[0], 'runPreprocessor')
    catalog.addItem('parallel baseline at upperright of master track', Bpar[1], 'runPreprocessor')
    catalog.addItem('parallel baseline at lowerleft of master track', Bpar[2], 'runPreprocessor')
    catalog.addItem('parallel baseline at lowerright of master track', Bpar[3], 'runPreprocessor')
    catalog.addItem('parallel baseline at center of master track', Bpar[4], 'runPreprocessor')

    catalog.addItem('perpendicular baseline at upperleft of master track', Bperp[0], 'runPreprocessor')
    catalog.addItem('perpendicular baseline at upperright of master track', Bperp[1], 'runPreprocessor')
    catalog.addItem('perpendicular baseline at lowerleft of master track', Bperp[2], 'runPreprocessor')
    catalog.addItem('perpendicular baseline at lowerright of master track', Bperp[3], 'runPreprocessor')
    catalog.addItem('perpendicular baseline at center of master track', Bperp[4], 'runPreprocessor')


    ##################################################
    #4. compute bounding box
    ##################################################
    masterBbox = getBboxGeo(self.master.track)
    slaveBbox = getBboxGeo(self.slave.track)

    catalog.addItem('master bounding box', masterBbox, 'runPreprocessor')
    catalog.addItem('slave bounding box', slaveBbox, 'runPreprocessor')


    catalog.printToLog(logger, "runPreprocessor")
    self._insar.procDoc.addAllFromCatalog(catalog)
Пример #5
0
def runDownloadDem(self):
    '''download DEM and water body
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    referenceTrack = self._insar.loadTrack(reference=True)
    secondaryTrack = self._insar.loadTrack(reference=False)

    bboxGeo = getBboxGeo(referenceTrack)
    bbox = np.array(bboxGeo)
    bboxStr = '{} {} {} {}'.format(np.int(np.floor(bbox[0])),
                                   np.int(np.ceil(bbox[1])),
                                   np.int(np.floor(bbox[2])),
                                   np.int(np.ceil(bbox[3])))

    #get 1 arcsecond dem for coregistration
    if self.dem == None:
        demDir = 'dem_1_arcsec'
        os.makedirs(demDir, exist_ok=True)
        os.chdir(demDir)

        # downloadUrl = 'http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11'
        # cmd = 'dem.py -a stitch -b {} -k -s 1 -c -f -u {}'.format(
        #        bboxStr,
        #        downloadUrl
        #        )
        # runCmd(cmd)
        # cmd = 'fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f'
        # runCmd(cmd)
        # cmd = 'rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml'
        # runCmd(cmd)

        #replace the above system calls with function calls
        downloadDem(list(bbox),
                    demType='version3',
                    resolution=1,
                    fillingValue=-32768,
                    outputFile=None,
                    userName=None,
                    passWord=None)
        imagePathXml((glob.glob('demLat_*_*_Lon_*_*.dem.wgs84'))[0],
                     fullPath=True)
        filesRemoved = glob.glob('*.hgt*') + glob.glob('*.log') + glob.glob(
            'demLat_*_*_Lon_*_*.dem') + glob.glob(
                'demLat_*_*_Lon_*_*.dem.vrt') + glob.glob(
                    'demLat_*_*_Lon_*_*.dem.xml')
        for filex in filesRemoved:
            os.remove(filex)

        os.chdir('../')

        self.dem = glob.glob(
            os.path.join(demDir, 'demLat_*_*_Lon_*_*.dem.wgs84'))[0]

    #get 3 arcsecond dem for geocoding
    if self.demGeo == None:
        demGeoDir = 'dem_3_arcsec'
        os.makedirs(demGeoDir, exist_ok=True)
        os.chdir(demGeoDir)

        # downloadUrl = 'http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11'
        # cmd = 'dem.py -a stitch -b {} -k -s 3 -c -f -u {}'.format(
        #        bboxStr,
        #        downloadUrl
        #        )
        # runCmd(cmd)
        # cmd = 'fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f'
        # runCmd(cmd)
        # cmd = 'rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml'
        # runCmd(cmd)

        #replace the above system calls with function calls
        downloadDem(list(bbox),
                    demType='version3',
                    resolution=3,
                    fillingValue=-32768,
                    outputFile=None,
                    userName=None,
                    passWord=None)
        imagePathXml((glob.glob('demLat_*_*_Lon_*_*.dem.wgs84'))[0],
                     fullPath=True)
        filesRemoved = glob.glob('*.hgt*') + glob.glob('*.log') + glob.glob(
            'demLat_*_*_Lon_*_*.dem') + glob.glob(
                'demLat_*_*_Lon_*_*.dem.vrt') + glob.glob(
                    'demLat_*_*_Lon_*_*.dem.xml')
        for filex in filesRemoved:
            os.remove(filex)

        os.chdir('../')

        self.demGeo = glob.glob(
            os.path.join(demGeoDir, 'demLat_*_*_Lon_*_*.dem.wgs84'))[0]

    #get water body for masking interferogram
    if self.wbd == None:
        wbdDir = 'wbd_1_arcsec'
        os.makedirs(wbdDir, exist_ok=True)
        os.chdir(wbdDir)

        #cmd = 'wbd.py {}'.format(bboxStr)
        #runCmd(cmd)
        download_wbd(np.int(np.floor(bbox[0])), np.int(np.ceil(bbox[1])),
                     np.int(np.floor(bbox[2])), np.int(np.ceil(bbox[3])))
        #cmd = 'fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f'
        #runCmd(cmd)
        #cmd = 'rm *.log'
        #runCmd(cmd)

        #replace the above system calls with function calls
        imagePathXml((glob.glob('swbdLat_*_*_Lon_*_*.wbd'))[0], fullPath=True)
        filesRemoved = glob.glob('*.log')
        for filex in filesRemoved:
            os.remove(filex)

        os.chdir('../')

        self.wbd = glob.glob(os.path.join(wbdDir,
                                          'swbdLat_*_*_Lon_*_*.wbd'))[0]

    self._insar.dem = self.dem
    self._insar.demGeo = self.demGeo
    self._insar.wbd = self.wbd

    catalog.printToLog(logger, "runDownloadDem")
    self._insar.procDoc.addAllFromCatalog(catalog)
Пример #6
0
    #######################################################

    demFile = os.path.abspath(demGeo)
    trackReferenceStack = loadProduct(ref_date_stack_track)

    #compute bounding box for geocoding
    if bbox is not None:
        bbox = [float(x) for x in bbox.split('/')]
        if len(bbox) != 4:
            raise Exception('user input bbox must have four elements')
    else:
        img = isceobj.createImage()
        img.load(inputFile + '.xml')
        bbox = getBboxGeo(trackReferenceStack,
                          useTrackOnly=True,
                          numberOfSamples=img.width,
                          numberOfLines=img.length,
                          numberRangeLooks=numberRangeLooks,
                          numberAzimuthLooks=numberAzimuthLooks)
    print(
        '====================================================================================================='
    )
    print('geocode bounding box: {}'.format(bbox))
    print(
        '====================================================================================================='
    )

    interpMethod = geocodeInterpMethod
    geocode(trackReferenceStack, demFile, inputFile, bbox, numberRangeLooks,
            numberAzimuthLooks, interpMethod, 0, 0)
Пример #7
0
def runBaseline(self):
    '''compute baseline
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    referenceTrack = self._insar.loadTrack(reference=True)
    secondaryTrack = self._insar.loadTrack(reference=False)


    ##################################################
    #2. compute burst synchronization
    ##################################################
    #burst synchronization may slowly change along a track as a result of the changing relative speed of the two flights
    #in one frame, real unsynchronized time is the same for all swaths
    unsynTime = 0
    #real synchronized time/percentage depends on the swath burst length (synTime = burstlength - abs(unsynTime))
    #synTime = 0
    synPercentage = 0

    numberOfFrames = len(self._insar.referenceFrames)
    numberOfSwaths = self._insar.endingSwath - self._insar.startingSwath + 1
    
    for i, frameNumber in enumerate(self._insar.referenceFrames):
        for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            referenceSwath = referenceTrack.frames[i].swaths[j]
            secondarySwath = secondaryTrack.frames[i].swaths[j]
            #using Piyush's code for computing range and azimuth offsets
            midRange = referenceSwath.startingRange + referenceSwath.rangePixelSize * referenceSwath.numberOfSamples * 0.5
            midSensingStart = referenceSwath.sensingStart + datetime.timedelta(seconds = referenceSwath.numberOfLines * 0.5 / referenceSwath.prf)
            llh = referenceTrack.orbit.rdr2geo(midSensingStart, midRange)
            slvaz, slvrng = secondaryTrack.orbit.geo2rdr(llh)
            ###Translate to offsets
            #note that secondary range pixel size and prf might be different from reference, here we assume there is a virtual secondary with same
            #range pixel size and prf
            rgoff = ((slvrng - secondarySwath.startingRange) / referenceSwath.rangePixelSize) - referenceSwath.numberOfSamples * 0.5
            azoff = ((slvaz - secondarySwath.sensingStart).total_seconds() * referenceSwath.prf) - referenceSwath.numberOfLines * 0.5

            #compute burst synchronization
            #burst parameters for ScanSAR wide mode not estimed yet
            if self._insar.modeCombination == 21:
                scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
                #secondary burst start times corresponding to reference burst start times (100% synchronization)
                scburstStartLines = np.arange(scburstStartLine - 100000*referenceSwath.burstCycleLength, \
                                              scburstStartLine + 100000*referenceSwath.burstCycleLength, \
                                              referenceSwath.burstCycleLength)
                dscburstStartLines = -((secondarySwath.burstStartTime - secondarySwath.sensingStart).total_seconds() * secondarySwath.prf - scburstStartLines)
                #find the difference with minimum absolute value
                unsynLines = dscburstStartLines[np.argmin(np.absolute(dscburstStartLines))]
                if np.absolute(unsynLines) >= secondarySwath.burstLength:
                    synLines = 0
                    if unsynLines > 0:
                        unsynLines = secondarySwath.burstLength
                    else:
                        unsynLines = -secondarySwath.burstLength
                else:
                    synLines = secondarySwath.burstLength - np.absolute(unsynLines)

                unsynTime += unsynLines / referenceSwath.prf
                synPercentage += synLines / referenceSwath.burstLength * 100.0

                catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(synLines / referenceSwath.burstLength * 100.0), 'runBaseline')

            ############################################################################################
            #illustration of the sign of the number of unsynchronized lines (unsynLines)     
            #The convention is the same as ampcor offset, that is,
            #              secondaryLineNumber = referenceLineNumber + unsynLines
            #
            # |-----------------------|     ------------
            # |                       |        ^
            # |                       |        |
            # |                       |        |   unsynLines < 0
            # |                       |        |
            # |                       |       \ /
            # |                       |    |-----------------------|
            # |                       |    |                       |
            # |                       |    |                       |
            # |-----------------------|    |                       |
            #        Reference Burst          |                       |
            #                              |                       |
            #                              |                       |
            #                              |                       |
            #                              |                       |
            #                              |-----------------------|
            #                                     Secondary Burst
            #
            #
            ############################################################################################
 
            ##burst parameters for ScanSAR wide mode not estimed yet
            elif self._insar.modeCombination == 31:
                #scansar is reference
                scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
                #secondary burst start times corresponding to reference burst start times (100% synchronization)
                for k in range(-100000, 100000):
                    saz_burstx = scburstStartLine + referenceSwath.burstCycleLength * k
                    st_burstx = secondarySwath.sensingStart + datetime.timedelta(seconds=saz_burstx / referenceSwath.prf)
                    if saz_burstx >= 0.0 and saz_burstx <= secondarySwath.numberOfLines -1:
                        secondarySwath.burstStartTime = st_burstx
                        secondarySwath.burstLength = referenceSwath.burstLength
                        secondarySwath.burstCycleLength = referenceSwath.burstCycleLength
                        secondarySwath.swathNumber = referenceSwath.swathNumber
                        break
                #unsynLines = 0
                #synLines = referenceSwath.burstLength
                #unsynTime += unsynLines / referenceSwath.prf
                #synPercentage += synLines / referenceSwath.burstLength * 100.0
                catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(100.0), 'runBaseline')
            else:
                pass

        #overwrite original frame parameter file
        if self._insar.modeCombination == 31:
            frameDir = 'f{}_{}'.format(i+1, frameNumber)
            self._insar.saveProduct(secondaryTrack.frames[i], os.path.join(frameDir, self._insar.secondaryFrameParameter))

    #getting average
    if self._insar.modeCombination == 21:
        unsynTime /= numberOfFrames*numberOfSwaths
        synPercentage /= numberOfFrames*numberOfSwaths
    elif self._insar.modeCombination == 31:
        unsynTime = 0.
        synPercentage = 100.
    else:
        pass

    #record results
    if (self._insar.modeCombination == 21) or (self._insar.modeCombination == 31):
        self._insar.burstUnsynchronizedTime = unsynTime
        self._insar.burstSynchronization = synPercentage
        catalog.addItem('burst synchronization averaged', '%.1f%%'%(synPercentage), 'runBaseline')


    ##################################################
    #3. compute baseline
    ##################################################
    #only compute baseline at four corners and center of the reference track
    bboxRdr = getBboxRdr(referenceTrack)

    rangeMin = bboxRdr[0]
    rangeMax = bboxRdr[1]
    azimuthTimeMin = bboxRdr[2]
    azimuthTimeMax = bboxRdr[3]

    azimuthTimeMid = azimuthTimeMin+datetime.timedelta(seconds=(azimuthTimeMax-azimuthTimeMin).total_seconds()/2.0)
    rangeMid = (rangeMin + rangeMax) / 2.0

    points = [[azimuthTimeMin, rangeMin],
              [azimuthTimeMin, rangeMax],
              [azimuthTimeMax, rangeMin],
              [azimuthTimeMax, rangeMax],
              [azimuthTimeMid, rangeMid]]

    Bpar = []
    Bperp = []
    #modify Piyush's code for computing baslines
    refElp = Planet(pname='Earth').ellipsoid
    for x in points:
        referenceSV = referenceTrack.orbit.interpolate(x[0], method='hermite')
        target = referenceTrack.orbit.rdr2geo(x[0], x[1])

        slvTime, slvrng = secondaryTrack.orbit.geo2rdr(target)
        secondarySV = secondaryTrack.orbit.interpolateOrbit(slvTime, method='hermite')

        targxyz = np.array(refElp.LLH(target[0], target[1], target[2]).ecef().tolist())
        mxyz = np.array(referenceSV.getPosition())
        mvel = np.array(referenceSV.getVelocity())
        sxyz = np.array(secondarySV.getPosition())

        #to fix abrupt change near zero in baseline grid. JUN-05-2020
        mvelunit = mvel / np.linalg.norm(mvel)
        sxyz = sxyz - np.dot ( sxyz-mxyz, mvelunit) * mvelunit

        aa = np.linalg.norm(sxyz-mxyz)
        costheta = (x[1]*x[1] + aa*aa - slvrng*slvrng)/(2.*x[1]*aa)

        Bpar.append(aa*costheta)

        perp = aa * np.sqrt(1 - costheta*costheta)
        direction = np.sign(np.dot( np.cross(targxyz-mxyz, sxyz-mxyz), mvel))
        Bperp.append(direction*perp)    

    catalog.addItem('parallel baseline at upperleft of reference track', Bpar[0], 'runBaseline')
    catalog.addItem('parallel baseline at upperright of reference track', Bpar[1], 'runBaseline')
    catalog.addItem('parallel baseline at lowerleft of reference track', Bpar[2], 'runBaseline')
    catalog.addItem('parallel baseline at lowerright of reference track', Bpar[3], 'runBaseline')
    catalog.addItem('parallel baseline at center of reference track', Bpar[4], 'runBaseline')

    catalog.addItem('perpendicular baseline at upperleft of reference track', Bperp[0], 'runBaseline')
    catalog.addItem('perpendicular baseline at upperright of reference track', Bperp[1], 'runBaseline')
    catalog.addItem('perpendicular baseline at lowerleft of reference track', Bperp[2], 'runBaseline')
    catalog.addItem('perpendicular baseline at lowerright of reference track', Bperp[3], 'runBaseline')
    catalog.addItem('perpendicular baseline at center of reference track', Bperp[4], 'runBaseline')


    ##################################################
    #4. compute bounding box
    ##################################################
    referenceBbox = getBboxGeo(referenceTrack)
    secondaryBbox = getBboxGeo(secondaryTrack)

    catalog.addItem('reference bounding box', referenceBbox, 'runBaseline')
    catalog.addItem('secondary bounding box', secondaryBbox, 'runBaseline')


    catalog.printToLog(logger, "runBaseline")
    self._insar.procDoc.addAllFromCatalog(catalog)
Пример #8
0
def runDownloadDem(self):
    '''download DEM and water body
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    masterTrack = self._insar.loadTrack(master=True)
    slaveTrack = self._insar.loadTrack(master=False)

    bboxGeo = getBboxGeo(masterTrack)
    bbox = np.array(bboxGeo)
    bboxStr = '{} {} {} {}'.format(np.int(np.floor(bbox[0])),
                                   np.int(np.ceil(bbox[1])),
                                   np.int(np.floor(bbox[2])),
                                   np.int(np.ceil(bbox[3])))

    #get 1 arcsecond dem for coregistration
    if self.dem == None:
        demDir = 'dem_1_arcsec'
        if not os.path.exists(demDir):
            os.makedirs(demDir)
        os.chdir(demDir)

        downloadUrl = 'http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11'
        cmd = 'dem.py -a stitch -b {} -k -s 1 -c -f -u {}'.format(
            bboxStr, downloadUrl)
        runCmd(cmd)
        cmd = 'fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f'
        runCmd(cmd)
        cmd = 'rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml'
        runCmd(cmd)
        os.chdir('../')

        self.dem = glob.glob(
            os.path.join(demDir, 'demLat_*_*_Lon_*_*.dem.wgs84'))[0]

    #get 3 arcsecond dem for geocoding
    if self.demGeo == None:
        demGeoDir = 'dem_3_arcsec'
        if not os.path.exists(demGeoDir):
            os.makedirs(demGeoDir)
        os.chdir(demGeoDir)

        downloadUrl = 'http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11'
        cmd = 'dem.py -a stitch -b {} -k -s 3 -c -f -u {}'.format(
            bboxStr, downloadUrl)
        runCmd(cmd)
        cmd = 'fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f'
        runCmd(cmd)
        cmd = 'rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml'
        runCmd(cmd)
        os.chdir('../')

        self.demGeo = glob.glob(
            os.path.join(demGeoDir, 'demLat_*_*_Lon_*_*.dem.wgs84'))[0]

    #get water body for masking interferogram
    if self.wbd == None:
        wbdDir = 'wbd_1_arcsec'
        if not os.path.exists(wbdDir):
            os.makedirs(wbdDir)
        os.chdir(wbdDir)

        #cmd = 'wbd.py {}'.format(bboxStr)
        #runCmd(cmd)
        download_wbd(np.int(np.floor(bbox[0])), np.int(np.ceil(bbox[1])),
                     np.int(np.floor(bbox[2])), np.int(np.ceil(bbox[3])))
        cmd = 'fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f'
        runCmd(cmd)
        cmd = 'rm *.log'
        runCmd(cmd)
        os.chdir('../')

        self.wbd = glob.glob(os.path.join(wbdDir,
                                          'swbdLat_*_*_Lon_*_*.wbd'))[0]

    self._insar.dem = self.dem
    self._insar.demGeo = self.demGeo
    self._insar.wbd = self.wbd

    catalog.printToLog(logger, "runDownloadDem")
    self._insar.procDoc.addAllFromCatalog(catalog)
Пример #9
0
def runPreprocessor(self):
    '''Extract images.
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)


    #find files
    #actually no need to use absolute path any longer, since we are able to find file from vrt now. 27-JAN-2020, CRL.
    #denseoffset may still need absolute path when making links
    self.referenceDir = os.path.abspath(self.referenceDir)
    self.secondaryDir = os.path.abspath(self.secondaryDir)

    ledFilesReference = sorted(glob.glob(os.path.join(self.referenceDir, 'LED-ALOS2*-*-*')))
    imgFilesReference = sorted(glob.glob(os.path.join(self.referenceDir, 'IMG-{}-ALOS2*-*-*'.format(self.referencePolarization.upper()))))

    ledFilesSecondary = sorted(glob.glob(os.path.join(self.secondaryDir, 'LED-ALOS2*-*-*')))
    imgFilesSecondary = sorted(glob.glob(os.path.join(self.secondaryDir, 'IMG-{}-ALOS2*-*-*'.format(self.secondaryPolarization.upper()))))

    firstFrameReference = ledFilesReference[0].split('-')[-3][-4:]
    firstFrameSecondary = ledFilesSecondary[0].split('-')[-3][-4:]
    firstFrameImagesReference = sorted(glob.glob(os.path.join(self.referenceDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.referencePolarization.upper(), firstFrameReference))))
    firstFrameImagesSecondary = sorted(glob.glob(os.path.join(self.secondaryDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.secondaryPolarization.upper(), firstFrameSecondary))))


    #determin operation mode
    referenceMode = os.path.basename(ledFilesReference[0]).split('-')[-1][0:3]
    secondaryMode = os.path.basename(ledFilesSecondary[0]).split('-')[-1][0:3]
    spotlightModes = ['SBS']
    stripmapModes = ['UBS', 'UBD', 'HBS', 'HBD', 'HBQ', 'FBS', 'FBD', 'FBQ']
    scansarNominalModes = ['WBS', 'WBD', 'WWS', 'WWD']
    scansarWideModes = ['VBS', 'VBD']
    scansarModes = ['WBS', 'WBD', 'WWS', 'WWD', 'VBS', 'VBD']

    #usable combinations
    if (referenceMode in spotlightModes) and (secondaryMode in spotlightModes):
        self._insar.modeCombination = 0
    elif (referenceMode in stripmapModes) and (secondaryMode in stripmapModes):
        self._insar.modeCombination = 1
    elif (referenceMode in scansarNominalModes) and (secondaryMode in scansarNominalModes):
        self._insar.modeCombination = 21
    elif (referenceMode in scansarWideModes) and (secondaryMode in scansarWideModes):
        self._insar.modeCombination = 22
    elif (referenceMode in scansarNominalModes) and (secondaryMode in stripmapModes):
        self._insar.modeCombination = 31
    elif (referenceMode in scansarWideModes) and (secondaryMode in stripmapModes):
        self._insar.modeCombination = 32
    else:
        print('\n\nthis mode combination is not possible')
        print('note that for ScanSAR-stripmap, ScanSAR must be reference\n\n')
        raise Exception('mode combination not supported')

# pixel size from real data processing. azimuth pixel size may change a bit as
# the antenna points to a different swath and therefore uses a different PRF.

#   MODE  RANGE PIXEL SIZE (LOOKS)       AZIMUTH PIXEL SIZE (LOOKS)
# -------------------------------------------------------------------
#   SPT    [SBS]
#          1.4304222392897463 (2)         0.9351804642158579 (4)
#   SM1    [UBS,UBD]
#          1.4304222392897463 (2)         1.8291988125114438 (2)
#   SM2    [HBS,HBD,HBQ]
#          2.8608444785794984 (2)         3.0672373839847196 (2)
#   SM3    [FBS,FBD,FBQ]
#          4.291266717869248  (2)         3.2462615913656667 (4)

#   WD1    [WBS,WBD] [WWS,WWD]
#          8.582533435738496  (1)         2.6053935830031887 (14)
#          8.582533435738496  (1)         2.092362043327227  (14)
#          8.582533435738496  (1)         2.8817632034495717 (14)
#          8.582533435738496  (1)         3.054362492601842  (14)
#          8.582533435738496  (1)         2.4582084463356977 (14)

#   WD2    [VBS,VBD]
#          8.582533435738496  (1)         2.9215796012950728 (14)
#          8.582533435738496  (1)         3.088859074497863  (14)
#          8.582533435738496  (1)         2.8792293071133073 (14)
#          8.582533435738496  (1)         3.0592146044234854 (14)
#          8.582533435738496  (1)         2.8818767752199137 (14)
#          8.582533435738496  (1)         3.047038521027477  (14)
#          8.582533435738496  (1)         2.898816222039108  (14)

    #determine default number of looks:
    self._insar.numberRangeLooks1 = self.numberRangeLooks1
    self._insar.numberAzimuthLooks1 = self.numberAzimuthLooks1
    self._insar.numberRangeLooks2 = self.numberRangeLooks2
    self._insar.numberAzimuthLooks2 = self.numberAzimuthLooks2
    #the following two will be automatically determined by runRdrDemOffset.py
    self._insar.numberRangeLooksSim = self.numberRangeLooksSim
    self._insar.numberAzimuthLooksSim = self.numberAzimuthLooksSim
    self._insar.numberRangeLooksIon = self.numberRangeLooksIon
    self._insar.numberAzimuthLooksIon = self.numberAzimuthLooksIon

    if self._insar.numberRangeLooks1 == None:
        if referenceMode in ['SBS']:
            self._insar.numberRangeLooks1 = 2
        elif referenceMode in ['UBS', 'UBD']:
            self._insar.numberRangeLooks1 = 2
        elif referenceMode in ['HBS', 'HBD', 'HBQ']:
            self._insar.numberRangeLooks1 = 2
        elif referenceMode in ['FBS', 'FBD', 'FBQ']:
            self._insar.numberRangeLooks1 = 2
        elif referenceMode in ['WBS', 'WBD']:
            self._insar.numberRangeLooks1 = 1
        elif referenceMode in ['WWS', 'WWD']:
            self._insar.numberRangeLooks1 = 2
        elif referenceMode in ['VBS', 'VBD']:
            self._insar.numberRangeLooks1 = 1
        else:
            raise Exception('unknow acquisition mode')

    if self._insar.numberAzimuthLooks1 == None:
        if referenceMode in ['SBS']:
            self._insar.numberAzimuthLooks1 = 4
        elif referenceMode in ['UBS', 'UBD']:
            self._insar.numberAzimuthLooks1 = 2
        elif referenceMode in ['HBS', 'HBD', 'HBQ']:
            self._insar.numberAzimuthLooks1 = 2
        elif referenceMode in ['FBS', 'FBD', 'FBQ']:
            self._insar.numberAzimuthLooks1 = 4
        elif referenceMode in ['WBS', 'WBD']:
            self._insar.numberAzimuthLooks1 = 14
        elif referenceMode in ['WWS', 'WWD']:
            self._insar.numberAzimuthLooks1 = 14
        elif referenceMode in ['VBS', 'VBD']:
            self._insar.numberAzimuthLooks1 = 14
        else:
            raise Exception('unknow acquisition mode')

    if self._insar.numberRangeLooks2 == None:
        if referenceMode in spotlightModes:
            self._insar.numberRangeLooks2 = 4
        elif referenceMode in stripmapModes:
            self._insar.numberRangeLooks2 = 4
        elif referenceMode in scansarModes:
            self._insar.numberRangeLooks2 = 5
        else:
            raise Exception('unknow acquisition mode')

    if self._insar.numberAzimuthLooks2 == None:
        if referenceMode in spotlightModes:
            self._insar.numberAzimuthLooks2 = 4
        elif referenceMode in stripmapModes:
            self._insar.numberAzimuthLooks2 = 4
        elif referenceMode in scansarModes:
            self._insar.numberAzimuthLooks2 = 2
        else:
            raise Exception('unknow acquisition mode')

    if self._insar.numberRangeLooksIon == None:
        if referenceMode in spotlightModes:
            self._insar.numberRangeLooksIon = 16
        elif referenceMode in stripmapModes:
            self._insar.numberRangeLooksIon = 16
        elif referenceMode in scansarModes:
            self._insar.numberRangeLooksIon = 40
        else:
            raise Exception('unknow acquisition mode')

    if self._insar.numberAzimuthLooksIon == None:
        if referenceMode in spotlightModes:
            self._insar.numberAzimuthLooksIon = 16
        elif referenceMode in stripmapModes:
            self._insar.numberAzimuthLooksIon = 16
        elif referenceMode in scansarModes:
            self._insar.numberAzimuthLooksIon = 16
        else:
            raise Exception('unknow acquisition mode')


    #define processing file names
    self._insar.referenceDate = os.path.basename(ledFilesReference[0]).split('-')[2]
    self._insar.secondaryDate = os.path.basename(ledFilesSecondary[0]).split('-')[2]
    self._insar.setFilename(referenceDate=self._insar.referenceDate, secondaryDate=self._insar.secondaryDate, nrlks1=self._insar.numberRangeLooks1, nalks1=self._insar.numberAzimuthLooks1, nrlks2=self._insar.numberRangeLooks2, nalks2=self._insar.numberAzimuthLooks2)


    #find frame numbers
    if (self._insar.modeCombination == 31) or (self._insar.modeCombination == 32):
        if (self.referenceFrames == None) or (self.secondaryFrames == None):
            raise Exception('for ScanSAR-stripmap inteferometry, you must set reference and secondary frame numbers')
    #if not set, find frames automatically
    if self.referenceFrames == None:
        self.referenceFrames = []
        for led in ledFilesReference:
            frameNumber = os.path.basename(led).split('-')[1][-4:]
            if frameNumber not in self.referenceFrames:
                self.referenceFrames.append(frameNumber)
    if self.secondaryFrames == None:
        self.secondaryFrames = []
        for led in ledFilesSecondary:
            frameNumber = os.path.basename(led).split('-')[1][-4:]
            if frameNumber not in self.secondaryFrames:
                self.secondaryFrames.append(frameNumber)
    #sort frames
    self.referenceFrames = sorted(self.referenceFrames)
    self.secondaryFrames = sorted(self.secondaryFrames)
    #check number of frames
    if len(self.referenceFrames) != len(self.secondaryFrames):
        raise Exception('number of frames in reference dir is not equal to number of frames \
            in secondary dir. please set frame number manually')


    #find swath numbers (if not ScanSAR-ScanSAR, compute valid swaths)
    if (self._insar.modeCombination == 0) or (self._insar.modeCombination == 1):
        self.startingSwath = 1
        self.endingSwath = 1

    if self._insar.modeCombination == 21:
        if self.startingSwath == None:
            self.startingSwath = 1
        if self.endingSwath == None:
            self.endingSwath = 5

    if self._insar.modeCombination == 22:
        if self.startingSwath == None:
            self.startingSwath = 1
        if self.endingSwath == None:
            self.endingSwath = 7

    #determine starting and ending swaths for ScanSAR-stripmap, user's settings are overwritten
    #use first frame to check overlap
    if (self._insar.modeCombination == 31) or (self._insar.modeCombination == 32):
        if self._insar.modeCombination == 31:
            numberOfSwaths = 5
        else:
            numberOfSwaths = 7
        overlapSubswaths = []
        for i in range(numberOfSwaths):
            overlapRatio = check_overlap(ledFilesReference[0], firstFrameImagesReference[i], ledFilesSecondary[0], firstFrameImagesSecondary[0])
            if overlapRatio > 1.0 / 4.0:
                overlapSubswaths.append(i+1)
        if overlapSubswaths == []:
            raise Exception('There is no overlap area between the ScanSAR-stripmap pair')
        self.startingSwath = int(overlapSubswaths[0])
        self.endingSwath = int(overlapSubswaths[-1])

    #save the valid frames and swaths for future processing
    self._insar.referenceFrames = self.referenceFrames
    self._insar.secondaryFrames = self.secondaryFrames
    self._insar.startingSwath = self.startingSwath
    self._insar.endingSwath = self.endingSwath


    ##################################################
    #1. create directories and read data
    ##################################################
    self.reference.configure()
    self.secondary.configure()
    self.reference.track.configure()
    self.secondary.track.configure()
    for i, (referenceFrame, secondaryFrame) in enumerate(zip(self._insar.referenceFrames, self._insar.secondaryFrames)):
        #frame number starts with 1
        frameDir = 'f{}_{}'.format(i+1, referenceFrame)
        os.makedirs(frameDir, exist_ok=True)
        os.chdir(frameDir)

        #attach a frame to reference and secondary
        frameObjReference = MultiMode.createFrame()
        frameObjSecondary = MultiMode.createFrame()
        frameObjReference.configure()
        frameObjSecondary.configure()
        self.reference.track.frames.append(frameObjReference)
        self.secondary.track.frames.append(frameObjSecondary)

        #swath number starts with 1
        for j in range(self._insar.startingSwath, self._insar.endingSwath+1):
            print('processing frame {} swath {}'.format(referenceFrame, j))

            swathDir = 's{}'.format(j)
            os.makedirs(swathDir, exist_ok=True)
            os.chdir(swathDir)

            #attach a swath to reference and secondary
            swathObjReference = MultiMode.createSwath()
            swathObjSecondary = MultiMode.createSwath()
            swathObjReference.configure()
            swathObjSecondary.configure()
            self.reference.track.frames[-1].swaths.append(swathObjReference)
            self.secondary.track.frames[-1].swaths.append(swathObjSecondary)

            #setup reference
            self.reference.leaderFile = sorted(glob.glob(os.path.join(self.referenceDir, 'LED-ALOS2*{}-*-*'.format(referenceFrame))))[0]
            if referenceMode in scansarModes:
                self.reference.imageFile = sorted(glob.glob(os.path.join(self.referenceDir, 'IMG-{}-ALOS2*{}-*-*-F{}'.format(self.referencePolarization.upper(), referenceFrame, j))))[0]
            else:
                self.reference.imageFile = sorted(glob.glob(os.path.join(self.referenceDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.referencePolarization.upper(), referenceFrame))))[0]
            self.reference.outputFile = self._insar.referenceSlc
            self.reference.useVirtualFile = self.useVirtualFile
            #read reference
            (imageFDR, imageData)=self.reference.readImage()
            (leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord)=self.reference.readLeader()
            self.reference.setSwath(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
            self.reference.setFrame(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
            self.reference.setTrack(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)

            #setup secondary
            self.secondary.leaderFile = sorted(glob.glob(os.path.join(self.secondaryDir, 'LED-ALOS2*{}-*-*'.format(secondaryFrame))))[0]
            if secondaryMode in scansarModes:
                self.secondary.imageFile = sorted(glob.glob(os.path.join(self.secondaryDir, 'IMG-{}-ALOS2*{}-*-*-F{}'.format(self.secondaryPolarization.upper(), secondaryFrame, j))))[0]
            else:
                self.secondary.imageFile = sorted(glob.glob(os.path.join(self.secondaryDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.secondaryPolarization.upper(), secondaryFrame))))[0]
            self.secondary.outputFile = self._insar.secondarySlc
            self.secondary.useVirtualFile = self.useVirtualFile
            #read secondary
            (imageFDR, imageData)=self.secondary.readImage()
            (leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord)=self.secondary.readLeader()
            self.secondary.setSwath(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
            self.secondary.setFrame(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)
            self.secondary.setTrack(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData)

            os.chdir('../')
        self._insar.saveProduct(self.reference.track.frames[-1], self._insar.referenceFrameParameter)
        self._insar.saveProduct(self.secondary.track.frames[-1], self._insar.secondaryFrameParameter)
        os.chdir('../')
    self._insar.saveProduct(self.reference.track, self._insar.referenceTrackParameter)
    self._insar.saveProduct(self.secondary.track, self._insar.secondaryTrackParameter)


    ##################################################
    #2. compute burst synchronization
    ##################################################
    #burst synchronization may slowly change along a track as a result of the changing relative speed of the two flights
    #in one frame, real unsynchronized time is the same for all swaths
    unsynTime = 0
    #real synchronized time/percentage depends on the swath burst length (synTime = burstlength - abs(unsynTime))
    #synTime = 0
    synPercentage = 0

    numberOfFrames = len(self._insar.referenceFrames)
    numberOfSwaths = self._insar.endingSwath - self._insar.startingSwath + 1
    
    for i, frameNumber in enumerate(self._insar.referenceFrames):
        for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            referenceSwath = self.reference.track.frames[i].swaths[j]
            secondarySwath = self.secondary.track.frames[i].swaths[j]
            #using Piyush's code for computing range and azimuth offsets
            midRange = referenceSwath.startingRange + referenceSwath.rangePixelSize * referenceSwath.numberOfSamples * 0.5
            midSensingStart = referenceSwath.sensingStart + datetime.timedelta(seconds = referenceSwath.numberOfLines * 0.5 / referenceSwath.prf)
            llh = self.reference.track.orbit.rdr2geo(midSensingStart, midRange)
            slvaz, slvrng = self.secondary.track.orbit.geo2rdr(llh)
            ###Translate to offsets
            #note that secondary range pixel size and prf might be different from reference, here we assume there is a virtual secondary with same
            #range pixel size and prf
            rgoff = ((slvrng - secondarySwath.startingRange) / referenceSwath.rangePixelSize) - referenceSwath.numberOfSamples * 0.5
            azoff = ((slvaz - secondarySwath.sensingStart).total_seconds() * referenceSwath.prf) - referenceSwath.numberOfLines * 0.5

            #compute burst synchronization
            #burst parameters for ScanSAR wide mode not estimed yet
            if self._insar.modeCombination == 21:
                scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
                #secondary burst start times corresponding to reference burst start times (100% synchronization)
                scburstStartLines = np.arange(scburstStartLine - 100000*referenceSwath.burstCycleLength, \
                                              scburstStartLine + 100000*referenceSwath.burstCycleLength, \
                                              referenceSwath.burstCycleLength)
                dscburstStartLines = -((secondarySwath.burstStartTime - secondarySwath.sensingStart).total_seconds() * secondarySwath.prf - scburstStartLines)
                #find the difference with minimum absolute value
                unsynLines = dscburstStartLines[np.argmin(np.absolute(dscburstStartLines))]
                if np.absolute(unsynLines) >= secondarySwath.burstLength:
                    synLines = 0
                    if unsynLines > 0:
                        unsynLines = secondarySwath.burstLength
                    else:
                        unsynLines = -secondarySwath.burstLength
                else:
                    synLines = secondarySwath.burstLength - np.absolute(unsynLines)

                unsynTime += unsynLines / referenceSwath.prf
                synPercentage += synLines / referenceSwath.burstLength * 100.0

                catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(synLines / referenceSwath.burstLength * 100.0), 'runPreprocessor')

            ############################################################################################
            #illustration of the sign of the number of unsynchronized lines (unsynLines)     
            #The convention is the same as ampcor offset, that is,
            #              secondaryLineNumber = referenceLineNumber + unsynLines
            #
            # |-----------------------|     ------------
            # |                       |        ^
            # |                       |        |
            # |                       |        |   unsynLines < 0
            # |                       |        |
            # |                       |       \ /
            # |                       |    |-----------------------|
            # |                       |    |                       |
            # |                       |    |                       |
            # |-----------------------|    |                       |
            #        Reference Burst          |                       |
            #                              |                       |
            #                              |                       |
            #                              |                       |
            #                              |                       |
            #                              |-----------------------|
            #                                     Secondary Burst
            #
            #
            ############################################################################################
 
            ##burst parameters for ScanSAR wide mode not estimed yet
            elif self._insar.modeCombination == 31:
                #scansar is reference
                scburstStartLine = (referenceSwath.burstStartTime - referenceSwath.sensingStart).total_seconds() * referenceSwath.prf + azoff
                #secondary burst start times corresponding to reference burst start times (100% synchronization)
                for k in range(-100000, 100000):
                    saz_burstx = scburstStartLine + referenceSwath.burstCycleLength * k
                    st_burstx = secondarySwath.sensingStart + datetime.timedelta(seconds=saz_burstx / referenceSwath.prf)
                    if saz_burstx >= 0.0 and saz_burstx <= secondarySwath.numberOfLines -1:
                        secondarySwath.burstStartTime = st_burstx
                        secondarySwath.burstLength = referenceSwath.burstLength
                        secondarySwath.burstCycleLength = referenceSwath.burstCycleLength
                        secondarySwath.swathNumber = referenceSwath.swathNumber
                        break
                #unsynLines = 0
                #synLines = referenceSwath.burstLength
                #unsynTime += unsynLines / referenceSwath.prf
                #synPercentage += synLines / referenceSwath.burstLength * 100.0
                catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(100.0), 'runPreprocessor')
            else:
                pass

        #overwrite original frame parameter file
        if self._insar.modeCombination == 31:
            frameDir = 'f{}_{}'.format(i+1, frameNumber)
            self._insar.saveProduct(self.secondary.track.frames[i], os.path.join(frameDir, self._insar.secondaryFrameParameter))

    #getting average
    if self._insar.modeCombination == 21:
        unsynTime /= numberOfFrames*numberOfSwaths
        synPercentage /= numberOfFrames*numberOfSwaths
    elif self._insar.modeCombination == 31:
        unsynTime = 0.
        synPercentage = 100.
    else:
        pass

    #record results
    if (self._insar.modeCombination == 21) or (self._insar.modeCombination == 31):
        self._insar.burstUnsynchronizedTime = unsynTime
        self._insar.burstSynchronization = synPercentage
        catalog.addItem('burst synchronization averaged', '%.1f%%'%(synPercentage), 'runPreprocessor')


    ##################################################
    #3. compute baseline
    ##################################################
    #only compute baseline at four corners and center of the reference track
    bboxRdr = getBboxRdr(self.reference.track)

    rangeMin = bboxRdr[0]
    rangeMax = bboxRdr[1]
    azimuthTimeMin = bboxRdr[2]
    azimuthTimeMax = bboxRdr[3]

    azimuthTimeMid = azimuthTimeMin+datetime.timedelta(seconds=(azimuthTimeMax-azimuthTimeMin).total_seconds()/2.0)
    rangeMid = (rangeMin + rangeMax) / 2.0

    points = [[azimuthTimeMin, rangeMin],
              [azimuthTimeMin, rangeMax],
              [azimuthTimeMax, rangeMin],
              [azimuthTimeMax, rangeMax],
              [azimuthTimeMid, rangeMid]]

    Bpar = []
    Bperp = []
    #modify Piyush's code for computing baslines
    refElp = Planet(pname='Earth').ellipsoid
    for x in points:
        referenceSV = self.reference.track.orbit.interpolate(x[0], method='hermite')
        target = self.reference.track.orbit.rdr2geo(x[0], x[1])

        slvTime, slvrng = self.secondary.track.orbit.geo2rdr(target)
        secondarySV = self.secondary.track.orbit.interpolateOrbit(slvTime, method='hermite')

        targxyz = np.array(refElp.LLH(target[0], target[1], target[2]).ecef().tolist())
        mxyz = np.array(referenceSV.getPosition())
        mvel = np.array(referenceSV.getVelocity())
        sxyz = np.array(secondarySV.getPosition())

        #to fix abrupt change near zero in baseline grid. JUN-05-2020
        mvelunit = mvel / np.linalg.norm(mvel)
        sxyz = sxyz - np.dot ( sxyz-mxyz, mvelunit) * mvelunit

        aa = np.linalg.norm(sxyz-mxyz)
        costheta = (x[1]*x[1] + aa*aa - slvrng*slvrng)/(2.*x[1]*aa)

        Bpar.append(aa*costheta)

        perp = aa * np.sqrt(1 - costheta*costheta)
        direction = np.sign(np.dot( np.cross(targxyz-mxyz, sxyz-mxyz), mvel))
        Bperp.append(direction*perp)    

    catalog.addItem('parallel baseline at upperleft of reference track', Bpar[0], 'runPreprocessor')
    catalog.addItem('parallel baseline at upperright of reference track', Bpar[1], 'runPreprocessor')
    catalog.addItem('parallel baseline at lowerleft of reference track', Bpar[2], 'runPreprocessor')
    catalog.addItem('parallel baseline at lowerright of reference track', Bpar[3], 'runPreprocessor')
    catalog.addItem('parallel baseline at center of reference track', Bpar[4], 'runPreprocessor')

    catalog.addItem('perpendicular baseline at upperleft of reference track', Bperp[0], 'runPreprocessor')
    catalog.addItem('perpendicular baseline at upperright of reference track', Bperp[1], 'runPreprocessor')
    catalog.addItem('perpendicular baseline at lowerleft of reference track', Bperp[2], 'runPreprocessor')
    catalog.addItem('perpendicular baseline at lowerright of reference track', Bperp[3], 'runPreprocessor')
    catalog.addItem('perpendicular baseline at center of reference track', Bperp[4], 'runPreprocessor')


    ##################################################
    #4. compute bounding box
    ##################################################
    referenceBbox = getBboxGeo(self.reference.track)
    secondaryBbox = getBboxGeo(self.secondary.track)

    catalog.addItem('reference bounding box', referenceBbox, 'runPreprocessor')
    catalog.addItem('secondary bounding box', secondaryBbox, 'runPreprocessor')


    catalog.printToLog(logger, "runPreprocessor")
    self._insar.procDoc.addAllFromCatalog(catalog)