예제 #1
0
def computeBaseline(trackReference, trackSecondary, azimuthTime,
                    rangeDistance):
    import numpy as np

    from isceobj.Planet.Planet import Planet

    #modify Piyush's code for computing baslines
    refElp = Planet(pname='Earth').ellipsoid
    #for x in points:
    referenceSV = trackReference.orbit.interpolate(azimuthTime,
                                                   method='hermite')
    target = trackReference.orbit.rdr2geo(azimuthTime, rangeDistance)

    slvTime, slvrng = trackSecondary.orbit.geo2rdr(target)
    secondarySV = trackSecondary.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 = (rangeDistance * rangeDistance + aa * aa -
                slvrng * slvrng) / (2. * rangeDistance * aa)

    Bpar = aa * costheta

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

    return (Bpar, Bperp)
예제 #2
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)
예제 #3
0
def main(iargs=None):
    '''Compute baseline.
    '''
    inps = cmdLineParse(iargs)
    from isceobj.Planet.Planet import Planet
    import numpy as np

    referenceSwathList = ut.getSwathList(inps.reference)
    secondarySwathList = ut.getSwathList(inps.secondary)
    swathList = list(sorted(set(referenceSwathList + secondarySwathList)))

    #catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    baselineDir = os.path.dirname(inps.baselineFile)
    if baselineDir != '':
        os.makedirs(baselineDir, exist_ok=True)

    referenceswaths = []
    secondaryswaths = []
    for swath in swathList:
        referencexml = os.path.join(inps.reference, 'IW{0}.xml'.format(swath))
        secondaryxml = os.path.join(inps.secondary, 'IW{0}.xml'.format(swath))

        if os.path.exists(referencexml) and os.path.exists(secondaryxml):

            reference = ut.loadProduct(
                os.path.join(inps.reference, 'IW{0}.xml'.format(swath)))
            secondary = ut.loadProduct(
                os.path.join(inps.secondary, 'IW{0}.xml'.format(swath)))

            referenceswaths.append(reference)
            secondaryswaths.append(secondary)

    refElp = Planet(pname='Earth').ellipsoid
    mStartingRange = min([x.startingRange for x in referenceswaths])
    mFarRange = max([x.farRange for x in referenceswaths])
    mSensingStart = min([x.sensingStart for x in referenceswaths])
    mSensingStop = max([x.sensingStop for x in referenceswaths])
    mOrb = getMergedOrbit(referenceswaths)

    dr = referenceswaths[0].bursts[0].rangePixelSize
    dt = referenceswaths[0].bursts[0].azimuthTimeInterval

    nPixels = int(np.round((mFarRange - mStartingRange) / dr)) + 1
    nLines = int(np.round(
        (mSensingStop - mSensingStart).total_seconds() / dt)) + 1

    sOrb = getMergedOrbit(secondaryswaths)

    rangeLimits = mFarRange - mStartingRange
    nRange = int(np.ceil(rangeLimits / 7000.))
    slantRange = mStartingRange + np.arange(nRange) * rangeLimits / (nRange -
                                                                     1.0)

    azimuthLimits = (mSensingStop - mSensingStart).total_seconds()
    nAzimuth = int(np.ceil(azimuthLimits))
    azimuthTime = [
        mSensingStart + datetime.timedelta(seconds=x * azimuthLimits /
                                           (nAzimuth - 1.0))
        for x in range(nAzimuth)
    ]

    Bpar = np.zeros(nRange, dtype=np.float32)
    Bperp = np.zeros(nRange, dtype=np.float32)

    fid = open(inps.baselineFile, 'wb')
    print('Baseline file {0} dims: {1}L x {2}P'.format(inps.baselineFile,
                                                       nAzimuth, nRange))

    if inps.reference == inps.secondary:
        Bperp = np.zeros((nAzimuth, nRange), dtype=np.float32)
        Bperp.tofile(fid)
    else:
        for ii, taz in enumerate(azimuthTime):

            referenceSV = mOrb.interpolate(taz, method='hermite')
            mxyz = np.array(referenceSV.getPosition())
            mvel = np.array(referenceSV.getVelocity())

            for jj, rng in enumerate(slantRange):

                target = mOrb.rdr2geo(taz, rng)

                targxyz = np.array(
                    refElp.LLH(target[0], target[1],
                               target[2]).ecef().tolist())
                slvTime, slvrng = sOrb.geo2rdr(target)

                secondarySV = sOrb.interpolateOrbit(slvTime, method='hermite')

                sxyz = np.array(secondarySV.getPosition())

                aa = np.linalg.norm(sxyz - mxyz)
                costheta = (rng * rng + aa * aa - slvrng * slvrng) / (2. *
                                                                      rng * aa)

                Bpar[jj] = aa * costheta

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

            Bperp.tofile(fid)

    fid.close()

    ####Write XML
    img = isceobj.createImage()
    img.setFilename(inps.baselineFile)
    img.bands = 1
    img.scheme = 'BIP'
    img.dataType = 'FLOAT'
    img.setWidth(nRange)
    img.setAccessMode('READ')
    img.setLength(nAzimuth)
    img.renderHdr()
    img.renderVRT()

    ###Create oversampled VRT file
    cmd = 'gdal_translate -of VRT -ot Float32 -r bilinear -outsize {xsize} {ysize} {infile}.vrt {infile}.full.vrt'.format(
        xsize=nPixels, ysize=nLines, infile=inps.baselineFile)

    status = os.system(cmd)
    if status:
        raise Exception('cmd: {0} Failed'.format(cmd))
예제 #4
0
def main(iargs=None):
    '''Compute baseline.
    '''
    inps = cmdLineParse(iargs)
    from isceobj.Planet.Planet import Planet
    import numpy as np
    import shelve

    baselineDir = os.path.dirname(inps.baselineFile)
    if baselineDir != '':
        os.makedirs(baselineDir, exist_ok=True)

    with shelve.open(os.path.join(inps.reference, 'data'), flag='r') as mdb:
        reference = mdb['frame']

    with shelve.open(os.path.join(inps.secondary, 'data'), flag='r') as mdb:
        secondary = mdb['frame']

    # check if the reference and secondary shelf are the same, i.e. it is baseline grid for the reference
    reference_SensingStart = reference.getSensingStart()
    secondary_SensingStart = secondary.getSensingStart()
    if reference_SensingStart == secondary_SensingStart:
        referenceBaseline = True
    else:
        referenceBaseline = False

    refElp = Planet(pname='Earth').ellipsoid

    dr = reference.instrument.rangePixelSize
    dt = 1. / reference.PRF  #reference.azimuthTimeInterval

    mStartingRange = reference.startingRange  #min([x.startingRange for x in referenceswaths])
    mFarRange = reference.startingRange + dr * (
        reference.numberOfSamples - 1
    )  #max([x.farRange for x in referenceswaths])
    mSensingStart = reference.sensingStart  #  min([x.sensingStart for x in referenceswaths])
    mSensingStop = reference.sensingStop  #max([x.sensingStop for x in referenceswaths])
    mOrb = getMergedOrbit(reference)

    nPixels = int(np.round((mFarRange - mStartingRange) / dr)) + 1
    nLines = int(np.round(
        (mSensingStop - mSensingStart).total_seconds() / dt)) + 1

    sOrb = getMergedOrbit(secondary)

    rangeLimits = mFarRange - mStartingRange

    # To make sure that we have at least 30 points
    nRange = int(np.max([30, int(np.ceil(rangeLimits / 7000.))]))

    slantRange = mStartingRange + np.arange(nRange) * rangeLimits / (nRange -
                                                                     1.0)

    azimuthLimits = (mSensingStop - mSensingStart).total_seconds()
    nAzimuth = int(np.max([30, int(np.ceil(azimuthLimits))]))
    azimuthTime = [
        mSensingStart + datetime.timedelta(seconds=x * azimuthLimits /
                                           (nAzimuth - 1.0))
        for x in range(nAzimuth)
    ]

    Bperp = np.zeros((nAzimuth, nRange), dtype=np.float32)
    Bpar = np.zeros((nAzimuth, nRange), dtype=np.float32)

    fid = open(inps.baselineFile, 'wb')
    print('Baseline file {0} dims: {1}L x {2}P'.format(inps.baselineFile,
                                                       nAzimuth, nRange))

    if referenceBaseline:
        Bperp = np.zeros((nAzimuth, nRange), dtype=np.float32)
        Bperp.tofile(fid)
    else:
        for ii, taz in enumerate(azimuthTime):

            referenceSV = mOrb.interpolate(taz, method='hermite')
            mxyz = np.array(referenceSV.getPosition())
            mvel = np.array(referenceSV.getVelocity())

            for jj, rng in enumerate(slantRange):

                target = mOrb.rdr2geo(taz, rng)

                targxyz = np.array(
                    refElp.LLH(target[0], target[1],
                               target[2]).ecef().tolist())
                slvTime, slvrng = sOrb.geo2rdr(target)

                secondarySV = sOrb.interpolateOrbit(slvTime, method='hermite')

                sxyz = np.array(secondarySV.getPosition())

                aa = np.linalg.norm(sxyz - mxyz)
                costheta = (rng * rng + aa * aa - slvrng * slvrng) / (2. *
                                                                      rng * aa)

                Bpar[ii, jj] = aa * costheta

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

        Bperp.tofile(fid)
    fid.close()

    ####Write XML
    img = isceobj.createImage()
    img.setFilename(inps.baselineFile)
    img.bands = 1
    img.scheme = 'BIP'
    img.dataType = 'FLOAT'
    img.setWidth(nRange)
    img.setAccessMode('READ')
    img.setLength(nAzimuth)
    img.renderHdr()
    img.renderVRT()

    ###Create oversampled VRT file
    cmd = 'gdal_translate -of VRT -ot Float32 -r bilinear -outsize {xsize} {ysize} {infile}.vrt {infile}.full.vrt'.format(
        xsize=nPixels, ysize=nLines, infile=inps.baselineFile)

    status = os.system(cmd)
    if status:
        raise Exception('cmd: {0} Failed'.format(cmd))
예제 #5
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)
예제 #6
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)
예제 #7
0
def runComputeBaseline(self):

    from isceobj.Planet.Planet import Planet
    import numpy as np

    swathList = self._insar.getInputSwathList(self.swaths)
    commonBurstStartMasterIndex = [-1] * self._insar.numberOfSwaths
    commonBurstStartSlaveIndex = [-1] * self._insar.numberOfSwaths
    numberOfCommonBursts = [0] * self._insar.numberOfSwaths

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

    for swath in swathList:

        masterxml = os.path.join(self._insar.masterSlcProduct,
                                 'IW{0}.xml'.format(swath))
        slavexml = os.path.join(self._insar.slaveSlcProduct,
                                'IW{0}.xml'.format(swath))

        if os.path.exists(masterxml) and os.path.exists(slavexml):
            master = self._insar.loadProduct(masterxml)
            slave = self._insar.loadProduct(slavexml)

            burstOffset, minBurst, maxBurst = master.getCommonBurstLimits(
                slave)
            commonSlaveIndex = minBurst + burstOffset
            numberCommon = maxBurst - minBurst

            if numberCommon == 0:
                print('No common bursts found for swath {0}'.format(swath))

            else:
                ###Bookkeeping
                commonBurstStartMasterIndex[swath - 1] = minBurst
                commonBurstStartSlaveIndex[swath - 1] = commonSlaveIndex
                numberOfCommonBursts[swath - 1] = numberCommon

                catalog.addItem(
                    'IW-{0} Number of bursts in master'.format(swath),
                    master.numberOfBursts, 'baseline')
                catalog.addItem(
                    'IW-{0} First common burst in master'.format(swath),
                    minBurst, 'baseline')
                catalog.addItem(
                    'IW-{0} Last common burst in master'.format(swath),
                    maxBurst, 'baseline')
                catalog.addItem(
                    'IW-{0} Number of bursts in slave'.format(swath),
                    slave.numberOfBursts, 'baseline')
                catalog.addItem(
                    'IW-{0} First common burst in slave'.format(swath),
                    minBurst + burstOffset, 'baseline')
                catalog.addItem(
                    'IW-{0} Last common burst in slave'.format(swath),
                    maxBurst + burstOffset, 'baseline')
                catalog.addItem('IW-{0} Number of common bursts'.format(swath),
                                numberCommon, 'baseline')

                refElp = Planet(pname='Earth').ellipsoid
                Bpar = []
                Bperp = []

                for boff in [0, numberCommon - 1]:
                    ###Baselines at top of common bursts
                    mBurst = master.bursts[minBurst + boff]
                    sBurst = slave.bursts[commonSlaveIndex + boff]

                    ###Target at mid range
                    tmid = mBurst.sensingMid
                    rng = mBurst.midRange
                    masterSV = mBurst.orbit.interpolate(tmid, method='hermite')
                    target = mBurst.orbit.rdr2geo(tmid, rng)

                    slvTime, slvrng = sBurst.orbit.geo2rdr(target)
                    slaveSV = sBurst.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())
                    mvelunit = mvel / np.linalg.norm(mvel)
                    sxyz = sxyz - np.dot(sxyz - mxyz, mvelunit) * mvelunit

                    aa = np.linalg.norm(sxyz - mxyz)
                    costheta = (rng * rng + aa * aa -
                                slvrng * slvrng) / (2. * rng * 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(
                    'IW-{0} Bpar at midrange for first common burst'.format(
                        swath), Bpar[0], 'baseline')
                catalog.addItem(
                    'IW-{0} Bperp at midrange for first common burst'.format(
                        swath), Bperp[0], 'baseline')
                catalog.addItem(
                    'IW-{0} Bpar at midrange for last common burst'.format(
                        swath), Bpar[1], 'baseline')
                catalog.addItem(
                    'IW-{0} Bperp at midrange for last common burst'.format(
                        swath), Bperp[1], 'baseline')

        else:
            print('Skipping processing for swath number IW-{0}'.format(swath))

    self._insar.commonBurstStartMasterIndex = commonBurstStartMasterIndex
    self._insar.commonBurstStartSlaveIndex = commonBurstStartSlaveIndex
    self._insar.numberOfCommonBursts = numberOfCommonBursts

    if not any([x >= 2 for x in self._insar.numberOfCommonBursts]):
        print(
            'No swaths contain any burst overlaps ... cannot continue for interferometry applications'
        )

    catalog.printToLog(logger, "runComputeBaseline")
    self._insar.procDoc.addAllFromCatalog(catalog)
예제 #8
0
def main(iargs=None):
    '''Compute baseline.
    '''
    inps = cmdLineParse(iargs)
    from isceobj.Planet.Planet import Planet
    import numpy as np

    #swathList = self._insar.getInputSwathList(self.swaths)
    #commonBurstStartMasterIndex = [-1] * self._insar.numberOfSwaths
    #commonBurstStartSlaveIndex = [-1] * self._insar.numberOfSwaths
    #numberOfCommonBursts = [0] * self._insar.numberOfSwaths

    masterSwathList = ut.getSwathList(inps.master)
    slaveSwathList = ut.getSwathList(inps.slave)
    swathList = list(sorted(set(masterSwathList + slaveSwathList)))

    #catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    baselineDir = os.path.dirname(inps.baselineFile)
    if not os.path.exists(baselineDir):
        os.makedirs(baselineDir)

    f = open(inps.baselineFile, 'w')

    for swath in swathList:

        masterxml = os.path.join(inps.master, 'IW{0}.xml'.format(swath))
        slavexml = os.path.join(inps.slave, 'IW{0}.xml'.format(swath))

        if os.path.exists(masterxml) and os.path.exists(slavexml):

            master = ut.loadProduct(
                os.path.join(inps.master, 'IW{0}.xml'.format(swath)))
            slave = ut.loadProduct(
                os.path.join(inps.slave, 'IW{0}.xml'.format(swath)))

            minMaster = master.bursts[0].burstNumber
            maxMaster = master.bursts[-1].burstNumber

            minSlave = slave.bursts[0].burstNumber
            maxSlave = slave.bursts[-1].burstNumber

            minBurst = max(minSlave, minMaster)
            maxBurst = min(maxSlave, maxMaster)
            print('minSlave,maxSlave', minSlave, maxSlave)
            print('minMaster,maxMaster', minMaster, maxMaster)
            print('minBurst, maxBurst: ', minBurst, maxBurst)
            refElp = Planet(pname='Earth').ellipsoid
            Bpar = []
            Bperp = []

            for ii in range(minBurst, maxBurst + 1):

                ###Bookkeeping
                #commonBurstStartMasterIndex[swath-1] = minBurst
                #commonBurstStartSlaveIndex[swath-1]  = commonSlaveIndex
                #numberOfCommonBursts[swath-1] = numberCommon

                #catalog.addItem('IW-{0} Number of bursts in master'.format(swath), master.numberOfBursts, 'baseline')
                #catalog.addItem('IW-{0} First common burst in master'.format(swath), minBurst, 'baseline')
                #catalog.addItem('IW-{0} Last common burst in master'.format(swath), maxBurst, 'baseline')
                #catalog.addItem('IW-{0} Number of bursts in slave'.format(swath), slave.numberOfBursts, 'baseline')
                #catalog.addItem('IW-{0} First common burst in slave'.format(swath), minBurst + burstOffset, 'baseline')
                #catalog.addItem('IW-{0} Last common burst in slave'.format(swath), maxBurst + burstOffset, 'baseline')
                #catalog.addItem('IW-{0} Number of common bursts'.format(swath), numberCommon, 'baseline')

                #refElp = Planet(pname='Earth').ellipsoid
                #Bpar = []
                #Bperp = []

                #for boff in [0, numberCommon-1]:
                ###Baselines at top of common bursts
                mBurst = master.bursts[ii - minMaster]
                sBurst = slave.bursts[ii - minSlave]

                ###Target at mid range
                tmid = mBurst.sensingMid
                rng = mBurst.midRange
                masterSV = mBurst.orbit.interpolate(tmid, method='hermite')
                target = mBurst.orbit.rdr2geo(tmid, rng)

                slvTime, slvrng = sBurst.orbit.geo2rdr(target)
                slaveSV = sBurst.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 = (rng * rng + aa * aa - slvrng * slvrng) / (2. *
                                                                      rng * 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('IW-{0} Bpar at midrange for first common burst'.format(swath), Bpar[0], 'baseline')
                #catalog.addItem('IW-{0} Bperp at midrange for first common burst'.format(swath), Bperp[0], 'baseline')
                #catalog.addItem('IW-{0} Bpar at midrange for last common burst'.format(swath), Bpar[1], 'baseline')
                #catalog.addItem('IW-{0} Bperp at midrange for last common burst'.format(swath), Bperp[1], 'baseline')

            print('Bprep: ', Bperp)
            print('Bpar: ', Bpar)
            f.write('swath: IW{0}'.format(swath) + '\n')
            f.write('Bperp (average): ' + str(np.mean(Bperp)) + '\n')
            f.write('Bpar (average): ' + str(np.mean(Bpar)) + '\n')

    f.close()