Beispiel #1
0
def snaphuUnwrapOriginal(wrapName,
                         corName,
                         ampName,
                         unwrapName,
                         costMode='s',
                         initMethod='mcf'):
    '''
    unwrap interferogram using original snaphu program
    '''
    import numpy as np
    import isceobj

    corImg = isceobj.createImage()
    corImg.load(corName + '.xml')
    width = corImg.width
    length = corImg.length

    #specify coherence file format in configure file
    snaphuConfFile = 'snaphu.conf'
    if corImg.bands == 1:
        snaphuConf = '''CORRFILEFORMAT        FLOAT_DATA
CONNCOMPFILE        {}
MAXNCOMPS       20'''.format(unwrapName + '.conncomp')

    else:
        snaphuConf = '''CORRFILEFORMAT        FLOAT_DATA
CONNCOMPFILE        {}
MAXNCOMPS       20'''.format(unwrapName + '.conncomp')
    with open(snaphuConfFile, 'w') as f:
        f.write(snaphuConf)
    cmd = 'snaphu {} {} -f {} -{} -o {} -a {} -c {} -v --{}'.format(
        wrapName, width, snaphuConfFile, costMode, unwrapName, ampName,
        corName, initMethod)
    runCmd(cmd)
    create_xml(unwrapName, width, length, 'unw')

    connImage = isceobj.Image.createImage()
    connImage.setFilename(unwrapName + '.conncomp')
    connImage.setWidth(width)
    connImage.setAccessMode('read')
    connImage.setDataType('BYTE')
    connImage.renderVRT()
    connImage.createImage()
    connImage.finalizeImage()
    connImage.renderHdr()
    del connImage

    #remove wired things in no-data area
    amp = np.memmap(unwrapName,
                    dtype='float32',
                    mode='r+',
                    shape=(length * 2, width))
    wrap = np.fromfile(wrapName, dtype=np.complex64).reshape(length, width)
    (amp[0:length * 2:2, :])[np.nonzero(wrap == 0)] = 0
    (amp[1:length * 2:2, :])[np.nonzero(wrap == 0)] = 0
    del amp
    del wrap

    return
Beispiel #2
0
def runLook(self):
    '''take looks
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    #masterTrack = self._insar.loadTrack(master=True)
    #slaveTrack = self._insar.loadTrack(master=False)
    wbdFile = os.path.abspath(self._insar.wbd)

    insarDir = 'insar'
    if not os.path.exists(insarDir):
        os.makedirs(insarDir)
    os.chdir(insarDir)


    amp = isceobj.createImage()
    amp.load(self._insar.amplitude+'.xml')
    width = amp.width
    length = amp.length
    width2 = int(width / self._insar.numberRangeLooks2)
    length2 = int(length / self._insar.numberAzimuthLooks2)

    if not ((self._insar.numberRangeLooks2 == 1) and (self._insar.numberAzimuthLooks2 == 1)):
        #take looks
        look(self._insar.differentialInterferogram, self._insar.multilookDifferentialInterferogram, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 4, 0, 1)
        look(self._insar.amplitude, self._insar.multilookAmplitude, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 4, 1, 1)
        look(self._insar.latitude, self._insar.multilookLatitude, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 3, 0, 1)
        look(self._insar.longitude, self._insar.multilookLongitude, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 3, 0, 1)
        look(self._insar.height, self._insar.multilookHeight, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 3, 0, 1)
        #creat xml
        create_xml(self._insar.multilookDifferentialInterferogram, width2, length2, 'int')
        create_xml(self._insar.multilookAmplitude, width2, length2, 'amp')
        create_xml(self._insar.multilookLatitude, width2, length2, 'double')
        create_xml(self._insar.multilookLongitude, width2, length2, 'double')
        create_xml(self._insar.multilookHeight, width2, length2, 'double')
        #los has two bands, use look program in isce instead
        cmd = "looks.py -i {} -o {} -r {} -a {}".format(self._insar.los, self._insar.multilookLos, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2)
        runCmd(cmd)

        #water body
        #this looking operation has no problems where there is only water and land, but there is also possible no-data area
        #look(self._insar.wbdOut, self._insar.multilookWbdOut, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 0, 0, 1)
        #create_xml(self._insar.multilookWbdOut, width2, length2, 'byte')
        #use waterBodyRadar instead to avoid the problems of no-data pixels in water body
        waterBodyRadar(self._insar.multilookLatitude, self._insar.multilookLongitude, wbdFile, self._insar.multilookWbdOut)


    os.chdir('../')

    catalog.printToLog(logger, "runLook")
    self._insar.procDoc.addAllFromCatalog(catalog)
def simulateRadar(hgtfile, simfile, scale=3.0, offset=100.0):
    '''
    simulate a radar image by computing gradient of a dem image.
    '''
    import numpy as np
    import isceobj
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml

    #set chunk length here for efficient processing
    ###############################################
    chunk_length = 1000
    ###############################################

    hgt = isceobj.createImage()
    hgt.load(hgtfile + '.xml')

    chunk_width = hgt.width
    num_chunk = int(hgt.length / chunk_length)
    chunk_length_last = hgt.length - num_chunk * chunk_length

    simData = np.zeros((chunk_length, chunk_width), dtype=np.float32)

    hgtfp = open(hgtfile, 'rb')
    simfp = open(simfile, 'wb')

    print("simulating a radar image using topography")
    for i in range(num_chunk):
        print("processing chunk %6d of %6d" % (i + 1, num_chunk),
              end='\r',
              flush=True)
        hgtData = np.fromfile(hgtfp,
                              dtype=np.float64,
                              count=chunk_length * chunk_width).reshape(
                                  chunk_length, chunk_width)
        simData[:,
                0:chunk_width - 1] = scale * np.diff(hgtData, axis=1) + offset
        simData.astype(np.float32).tofile(simfp)

    print("processing chunk %6d of %6d" % (num_chunk, num_chunk))
    if chunk_length_last != 0:
        hgtData = np.fromfile(hgtfp,
                              dtype=np.float64,
                              count=chunk_length_last * chunk_width).reshape(
                                  chunk_length_last, chunk_width)
        simData[0:chunk_length_last,
                0:chunk_width - 1] = scale * np.diff(hgtData, axis=1) + offset
        (simData[0:chunk_length_last, :]).astype(np.float32).tofile(simfp)

    hgtfp.close()
    simfp.close()
    create_xml(simfile, hgt.width, hgt.length, 'float')
Beispiel #4
0
def formInterferogram(slcReference, slcSecondary, interferogram, amplitude,
                      numberRangeLooks, numberAzimuthLooks):
    import numpy as np
    import isce, isceobj
    from isceobj.Alos2Proc.Alos2ProcPublic import multilook
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml

    img = isceobj.createImage()
    img.load(slcReference + '.xml')
    width = img.width
    length = img.length

    width2 = int(width / numberRangeLooks)
    length2 = int(length / numberAzimuthLooks)

    fpRef = open(slcReference, 'rb')
    fpSec = open(slcSecondary, 'rb')
    fpInf = open(interferogram, 'wb')
    fpAmp = open(amplitude, 'wb')

    for k in range(length2):
        if (((k + 1) % 200) == 0):
            print("processing line %6d of %6d" % (k + 1, length2),
                  end='\r',
                  flush=True)
        ref = np.fromfile(fpRef,
                          dtype=np.complex64,
                          count=numberAzimuthLooks * width).reshape(
                              numberAzimuthLooks, width)
        sec = np.fromfile(fpSec,
                          dtype=np.complex64,
                          count=numberAzimuthLooks * width).reshape(
                              numberAzimuthLooks, width)
        inf = multilook(ref * np.conjugate(sec),
                        numberAzimuthLooks,
                        numberRangeLooks,
                        mean=False)
        amp = np.sqrt(multilook(ref.real*ref.real+ref.imag*ref.imag, numberAzimuthLooks, numberRangeLooks, mean=False)) + 1j * \
              np.sqrt(multilook(sec.real*sec.real+sec.imag*sec.imag, numberAzimuthLooks, numberRangeLooks, mean=False))
        index = np.nonzero((np.real(amp) == 0) + (np.imag(amp) == 0))
        amp[index] = 0
        inf.tofile(fpInf)
        amp.tofile(fpAmp)
    print("processing line %6d of %6d" % (length2, length2))
    fpRef.close()
    fpSec.close()
    fpInf.close()
    fpAmp.close()

    create_xml(interferogram, width2, length2, 'int')
    create_xml(amplitude, width2, length2, 'amp')
Beispiel #5
0
def mosaicBurstInterferogram(swath,
                             burstPrefix,
                             outputFile,
                             numberOfLooksThreshold=1):
    '''
    take a burst sequence and output mosaicked file
    '''
    import numpy as np

    interferogram = np.zeros((swath.numberOfLines, swath.numberOfSamples),
                             dtype=np.complex64)
    cnt = np.zeros((swath.numberOfLines, swath.numberOfSamples), dtype=np.int8)
    for i in range(swath.numberOfBursts):
        burstFile = burstPrefix + '_%02d.int' % (i + 1)
        burstInterferogram = np.fromfile(burstFile,
                                         dtype=np.complex64).reshape(
                                             swath.burstSlcNumberOfLines,
                                             swath.burstSlcNumberOfSamples)
        interferogram[
            0 + swath.burstSlcFirstLineOffsets[i]:swath.burstSlcNumberOfLines +
            swath.burstSlcFirstLineOffsets[i], :] += burstInterferogram
        cnt[0 + swath.burstSlcFirstLineOffsets[i]:swath.burstSlcNumberOfLines +
            swath.burstSlcFirstLineOffsets[i], :] += (burstInterferogram != 0)

    #trim upper and lower edges with less number of looks
    #############################################################################
    firstLine = 0
    for i in range(swath.numberOfLines):
        if np.sum(cnt[i, :] >= numberOfLooksThreshold
                  ) > swath.numberOfSamples / 2:
            firstLine = i
            break
    lastLine = swath.numberOfLines - 1
    for i in range(swath.numberOfLines):
        if np.sum(cnt[swath.numberOfLines - 1 - i, :] >= numberOfLooksThreshold
                  ) > swath.numberOfSamples / 2:
            lastLine = swath.numberOfLines - 1 - i
            break

    interferogram[:firstLine, :] = 0
    interferogram[lastLine + 1:, :] = 0

    # if numberOfLooksThreshold!= None:
    #     interferogram[np.nonzero(cnt<numberOfLooksThreshold)] = 0
    #############################################################################

    interferogram.astype(np.complex64).tofile(outputFile)
    create_xml(outputFile, swath.numberOfSamples, swath.numberOfLines, 'int')
Beispiel #6
0
def mosaicBurstAmplitude(swath,
                         burstPrefix,
                         outputFile,
                         numberOfLooksThreshold=1):
    '''
    take a burst sequence and output the magnitude
    '''
    import numpy as np

    amp = np.zeros((swath.numberOfLines, swath.numberOfSamples),
                   dtype=np.float32)
    cnt = np.zeros((swath.numberOfLines, swath.numberOfSamples), dtype=np.int8)
    for i in range(swath.numberOfBursts):
        burstFile = burstPrefix + '_%02d.slc' % (i + 1)
        #azLineOffset = round((swath.burstSlcStartTimes[i] - swath.burstSlcStartTimes[0]).total_seconds() / swath.azimuthLineInterval)
        burstMag = np.absolute(
            np.fromfile(burstFile, dtype=np.complex64).reshape(
                swath.burstSlcNumberOfLines, swath.burstSlcNumberOfSamples))
        burstPwr = burstMag * burstMag
        amp[0 + swath.burstSlcFirstLineOffsets[i]:swath.burstSlcNumberOfLines +
            swath.burstSlcFirstLineOffsets[i], :] += burstPwr
        cnt[0 + swath.burstSlcFirstLineOffsets[i]:swath.burstSlcNumberOfLines +
            swath.burstSlcFirstLineOffsets[i], :] += (burstPwr != 0)

    #trim upper and lower edges with less number of looks
    #############################################################################
    firstLine = 0
    for i in range(swath.numberOfLines):
        if np.sum(cnt[i, :] >= numberOfLooksThreshold
                  ) > swath.numberOfSamples / 2:
            firstLine = i
            break
    lastLine = swath.numberOfLines - 1
    for i in range(swath.numberOfLines):
        if np.sum(cnt[swath.numberOfLines - 1 - i, :] >= numberOfLooksThreshold
                  ) > swath.numberOfSamples / 2:
            lastLine = swath.numberOfLines - 1 - i
            break

    amp[:firstLine, :] = 0
    amp[lastLine + 1:, :] = 0

    # if numberOfLooksThreshold!= None:
    #     amp[np.nonzero(cnt<numberOfLooksThreshold)] = 0
    #############################################################################

    np.sqrt(amp).astype(np.float32).tofile(outputFile)
    create_xml(outputFile, swath.numberOfSamples, swath.numberOfLines, 'float')
Beispiel #7
0
def runRectRangeOffset(self):
    '''rectify range offset
    '''
    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)

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


    #rectify
    rgoff = isceobj.createImage()
    rgoff.load(self._insar.rangeOffset+'.xml')

    if self._insar.radarDemAffineTransform == [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]:
        if not os.path.isfile(self._insar.rectRangeOffset):
            os.symlink(self._insar.rangeOffset, self._insar.rectRangeOffset)
            create_xml(self._insar.rectRangeOffset, rgoff.width, rgoff.length, 'float')
    else:
        rect_with_looks(self._insar.rangeOffset,
                        self._insar.rectRangeOffset,
                        rgoff.width, rgoff.length,
                        rgoff.width, rgoff.length,
                        self._insar.radarDemAffineTransform[0], self._insar.radarDemAffineTransform[1],
                        self._insar.radarDemAffineTransform[2], self._insar.radarDemAffineTransform[3],
                        self._insar.radarDemAffineTransform[4], self._insar.radarDemAffineTransform[5],
                        self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1,
                        self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1,
                        'REAL',
                        'Bilinear')
        create_xml(self._insar.rectRangeOffset, rgoff.width, rgoff.length, 'float')

    os.chdir('../')

    catalog.printToLog(logger, "runRectRangeOffset")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #8
0
def runLookSd(self):
    '''take looks
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    #masterTrack = self._insar.loadTrack(master=True)
    #slaveTrack = self._insar.loadTrack(master=False)
    wbdFile = os.path.abspath(self._insar.wbd)

    sdDir = 'sd'
    if not os.path.exists(sdDir):
        os.makedirs(sdDir)
    os.chdir(sdDir)

    sd = isceobj.createImage()
    sd.load(self._insar.interferogramSd[0] + '.xml')
    width = sd.width
    length = sd.length
    width2 = int(width / self._insar.numberRangeLooksSd)
    length2 = int(length / self._insar.numberAzimuthLooksSd)

    if not ((self._insar.numberRangeLooksSd == 1) and
            (self._insar.numberAzimuthLooksSd == 1)):
        #take looks
        for sd, sdMultilook in zip(self._insar.interferogramSd,
                                   self._insar.multilookInterferogramSd):
            look(sd, sdMultilook, width, self._insar.numberRangeLooksSd,
                 self._insar.numberAzimuthLooksSd, 4, 0, 1)
            create_xml(sdMultilook, width2, length2, 'int')
        look(os.path.join('../insar', self._insar.latitude),
             self._insar.multilookLatitudeSd, width,
             self._insar.numberRangeLooksSd, self._insar.numberAzimuthLooksSd,
             3, 0, 1)
        look(os.path.join('../insar', self._insar.longitude),
             self._insar.multilookLongitudeSd, width,
             self._insar.numberRangeLooksSd, self._insar.numberAzimuthLooksSd,
             3, 0, 1)
        create_xml(self._insar.multilookLatitudeSd, width2, length2, 'double')
        create_xml(self._insar.multilookLongitudeSd, width2, length2, 'double')
        #water body
        waterBodyRadar(self._insar.multilookLatitudeSd,
                       self._insar.multilookLongitudeSd, wbdFile,
                       self._insar.multilookWbdOutSd)

    os.chdir('../')

    catalog.printToLog(logger, "runLookSd")
    self._insar.procDoc.addAllFromCatalog(catalog)
def runExtractBurst(self):
    '''extract bursts.
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

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

    #demFile = os.path.abspath(self._insar.dem)
    #wbdFile = os.path.abspath(self._insar.wbd)
    ###############################################################################
    for i, frameNumber in enumerate(self._insar.masterFrames):
        frameDir = 'f{}_{}'.format(i + 1, frameNumber)
        os.chdir(frameDir)
        for j, swathNumber in enumerate(
                range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            swathDir = 's{}'.format(swathNumber)
            os.chdir(swathDir)

            print('extracting bursts frame {}, swath {}'.format(
                frameNumber, swathNumber))

            az_ratio1 = 20.0
            for k in range(2):
                if k == 0:
                    #master
                    swath = masterTrack.frames[i].swaths[j]
                    unsynLines = self._insar.burstUnsynchronizedTime * swath.prf
                    extractDir = self._insar.masterBurstPrefix
                    burstPrefix = self._insar.masterBurstPrefix
                    fullApertureSlc = self._insar.masterSlc
                    magnitude = self._insar.masterMagnitude
                else:
                    #slave
                    swath = slaveTrack.frames[i].swaths[j]
                    unsynLines = -self._insar.burstUnsynchronizedTime * swath.prf
                    extractDir = self._insar.slaveBurstPrefix
                    burstPrefix = self._insar.slaveBurstPrefix
                    fullApertureSlc = self._insar.slaveSlc
                    magnitude = self._insar.slaveMagnitude

                #UPDATE SWATH PARAMETERS 1
                #########################################################################################
                if self._insar.burstSynchronization <= self.burstSynchronizationThreshold:
                    swath.burstLength -= abs(unsynLines)
                    if unsynLines < 0:
                        swath.burstStartTime += datetime.timedelta(
                            seconds=abs(unsynLines) / swath.prf)
                #########################################################################################

                #extract burst
                os.makedirs(extractDir, exist_ok=True)
                os.chdir(extractDir)
                if os.path.isfile(os.path.join('../', fullApertureSlc)):
                    os.rename(os.path.join('../', fullApertureSlc),
                              fullApertureSlc)
                os.rename(os.path.join('../', fullApertureSlc + '.vrt'),
                          fullApertureSlc + '.vrt')
                os.rename(os.path.join('../', fullApertureSlc + '.xml'),
                          fullApertureSlc + '.xml')

                extract_burst(fullApertureSlc, burstPrefix, swath.prf, swath.prfFraction, swath.burstLength, swath.burstCycleLength-swath.burstLength, \
                (swath.burstStartTime - swath.sensingStart).total_seconds() * swath.prf, swath.azimuthFmrateVsPixel, swath.dopplerVsPixel, az_ratio1, 0.0)

                #read output parameters
                with open('extract_burst.txt', 'r') as f:
                    lines = f.readlines()
                offsetFromFirstBurst = []
                for linex in lines:
                    if 'total number of bursts extracted' in linex:
                        numberOfBursts = int(linex.split(':')[1])
                    if 'output burst length' in linex:
                        burstSlcNumberOfLines = int(linex.split(':')[1])
                    if 'line number of first line of first output burst in original SLC (1.0/prf)' in linex:
                        fb_ln = float(linex.split(':')[1])
                    if 'bsl of first output burst' in linex:
                        bsl_firstburst = float(linex.split(':')[1])
                    if 'offset from first burst' in linex:
                        offsetFromFirstBurst.append(
                            int(linex.split(',')[0].split(':')[1]))

                #time of first line of first burst raw
                firstBurstRawStartTime = swath.sensingStart + datetime.timedelta(
                    seconds=bsl_firstburst / swath.prf)

                #time of first line of first burst slc
                #original time is at the upper edge of first line, we change it to center of first line.
                sensingStart = swath.sensingStart + datetime.timedelta(
                    seconds=fb_ln / swath.prf +
                    (az_ratio1 - 1.0) / 2.0 / swath.prf)
                numberOfLines = offsetFromFirstBurst[numberOfBursts -
                                                     1] + burstSlcNumberOfLines

                for ii in range(numberOfBursts):
                    burstFile = burstPrefix + '_%02d.slc' % (ii + 1)
                    create_xml(burstFile, swath.numberOfSamples,
                               burstSlcNumberOfLines, 'slc')

                #UPDATE SWATH PARAMETERS 2
                #########################################################################################
                swath.numberOfLines = numberOfLines
                #this is also the time of the first line of the first burst slc
                swath.sensingStart = sensingStart
                swath.azimuthPixelSize = az_ratio1 * swath.azimuthPixelSize
                swath.azimuthLineInterval = az_ratio1 * swath.azimuthLineInterval

                swath.numberOfBursts = numberOfBursts
                swath.firstBurstRawStartTime = firstBurstRawStartTime
                swath.firstBurstSlcStartTime = sensingStart
                swath.burstSlcFirstLineOffsets = offsetFromFirstBurst
                swath.burstSlcNumberOfSamples = swath.numberOfSamples
                swath.burstSlcNumberOfLines = burstSlcNumberOfLines
                #########################################################################################

                #create a magnitude image
                mosaicBurstAmplitude(swath,
                                     burstPrefix,
                                     magnitude,
                                     numberOfLooksThreshold=4)

                os.chdir('../')
            os.chdir('../')
        self._insar.saveProduct(masterTrack.frames[i],
                                self._insar.masterFrameParameter)
        self._insar.saveProduct(slaveTrack.frames[i],
                                self._insar.slaveFrameParameter)
        os.chdir('../')

###############################################################################
    catalog.printToLog(logger, "runExtractBurst")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #10
0
def runFilt(self):
    '''filter interferogram
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

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

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

    ############################################################
    # STEP 1. filter interferogram
    ############################################################
    print('\nfilter interferogram: {}'.format(
        self._insar.multilookDifferentialInterferogram))

    toBeFiltered = self._insar.multilookDifferentialInterferogram
    if self.removeMagnitudeBeforeFiltering:
        toBeFiltered = 'tmp.int'
        cmd = "imageMath.py -e='a/(abs(a)+(a==0))' --a={} -o {} -t cfloat -s BSQ".format(
            self._insar.multilookDifferentialInterferogram, toBeFiltered)
        runCmd(cmd)

    #if shutil.which('psfilt1') != None:
    if True:
        intImage = isceobj.createIntImage()
        intImage.load(toBeFiltered + '.xml')
        width = intImage.width
        length = intImage.length
        # cmd = "psfilt1 {int} {filtint} {width} {filterstrength} 64 16".format(
        #        int = toBeFiltered,
        #        filtint = self._insar.filteredInterferogram,
        #        width = width,
        #        filterstrength = self.filterStrength
        #        )
        # runCmd(cmd)
        windowSize = self.filterWinsize
        stepSize = self.filterStepsize
        psfilt1(toBeFiltered, self._insar.filteredInterferogram, width,
                self.filterStrength, windowSize, stepSize)
        create_xml(self._insar.filteredInterferogram, width, length, 'int')
    else:
        #original
        intImage = isceobj.createIntImage()
        intImage.load(toBeFiltered + '.xml')
        intImage.setAccessMode('read')
        intImage.createImage()
        width = intImage.width
        length = intImage.length

        #filtered
        filtImage = isceobj.createIntImage()
        filtImage.setFilename(self._insar.filteredInterferogram)
        filtImage.setWidth(width)
        filtImage.setAccessMode('write')
        filtImage.createImage()

        #looks like the ps filtering program keep the original interferogram magnitude, which is bad for phase unwrapping?
        filters = Filter()
        filters.wireInputPort(name='interferogram', object=intImage)
        filters.wireOutputPort(name='filtered interferogram', object=filtImage)
        filters.goldsteinWerner(alpha=self.filterStrength)
        intImage.finalizeImage()
        filtImage.finalizeImage()
        del intImage, filtImage, filters

    if self.removeMagnitudeBeforeFiltering:
        os.remove(toBeFiltered)
        os.remove(toBeFiltered + '.vrt')
        os.remove(toBeFiltered + '.xml')

    #restore original magnitude
    tmpFile = 'tmp.int'
    renameFile(self._insar.filteredInterferogram, tmpFile)
    cmd = "imageMath.py -e='a*abs(b)' --a={} --b={} -o {} -t cfloat -s BSQ".format(
        tmpFile, self._insar.multilookDifferentialInterferogram,
        self._insar.filteredInterferogram)
    runCmd(cmd)
    os.remove(tmpFile)
    os.remove(tmpFile + '.vrt')
    os.remove(tmpFile + '.xml')

    ############################################################
    # STEP 2. create phase sigma using filtered interferogram
    ############################################################
    print('\ncreate phase sigma using: {}'.format(
        self._insar.filteredInterferogram))

    #recreate filtered image
    filtImage = isceobj.createIntImage()
    filtImage.load(self._insar.filteredInterferogram + '.xml')
    filtImage.setAccessMode('read')
    filtImage.createImage()

    #amplitude image
    ampImage = isceobj.createAmpImage()
    ampImage.load(self._insar.multilookAmplitude + '.xml')
    ampImage.setAccessMode('read')
    ampImage.createImage()

    #phase sigma correlation image
    phsigImage = isceobj.createImage()
    phsigImage.setFilename(self._insar.multilookPhsig)
    phsigImage.setWidth(width)
    phsigImage.dataType = 'FLOAT'
    phsigImage.bands = 1
    phsigImage.setImageType('cor')
    phsigImage.setAccessMode('write')
    phsigImage.createImage()

    icu = Icu(name='insarapp_filter_icu')
    icu.configure()
    icu.unwrappingFlag = False
    icu.icu(intImage=filtImage, ampImage=ampImage, phsigImage=phsigImage)

    phsigImage.renderHdr()

    filtImage.finalizeImage()
    ampImage.finalizeImage()
    phsigImage.finalizeImage()

    del filtImage
    del ampImage
    del phsigImage
    del icu

    ############################################################
    # STEP 3. mask filtered interferogram using water body
    ############################################################
    print('\nmask filtered interferogram using: {}'.format(
        self._insar.multilookWbdOut))

    if self.waterBodyMaskStartingStep == 'filt':
        if not os.path.exists(self._insar.multilookWbdOut):
            catalog.addItem(
                'warning message',
                'requested masking interferogram with water body, but water body does not exist',
                'runFilt')
        else:
            wbd = np.fromfile(self._insar.multilookWbdOut,
                              dtype=np.int8).reshape(length, width)
            phsig = np.memmap(self._insar.multilookPhsig,
                              dtype='float32',
                              mode='r+',
                              shape=(length, width))
            phsig[np.nonzero(wbd == -1)] = 0
            del phsig
            filt = np.memmap(self._insar.filteredInterferogram,
                             dtype='complex64',
                             mode='r+',
                             shape=(length, width))
            filt[np.nonzero(wbd == -1)] = 0
            del filt
            del wbd

    os.chdir('../')

    catalog.printToLog(logger, "runFilt")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #11
0
                dates[dateIndexReference], dates[i], Bpar, Bperp)

        if dateSecondary != []:
            if dates[i] not in dateSecondary:
                continue

        #compute baseline grid
        if baselineGrid:
            baselineFile = '{}-{}.rmg'.format(dates[dateIndexReference],
                                              dates[i])
            if os.path.isfile(baselineFile):
                print('baseline grid file {} already exists, do not create'.
                      format(baselineFile))
            else:
                for j in range(lengthBaseline):
                    for k in range(widthBaseline):
                        (baseline[j * 2, k],
                         baseline[j * 2 + 1, k]) = computeBaseline(
                             trackReference, trackSecondary, azimuthTimeMin +
                             datetime.timedelta(seconds=azimuthDelta * j),
                             rangeMin + rangeDelta * k)
                baseline.astype(np.float32).tofile(baselineFile)
                create_xml(baselineFile, widthBaseline, lengthBaseline, 'rmg')

    #dump baseline at image center
    if baselineCenterFile is not None:
        print('\nbaselines at image centers')
        print(baselineCenter)
        with open(baselineCenterFile, 'w') as f:
            f.write(baselineCenter)
Beispiel #12
0
    img.load(latitude + '.xml')
    width = img.width
    length = img.length
    width2 = int(width / numberRangeLooks2)
    length2 = int(length / numberAzimuthLooks2)

    if not ((numberRangeLooks2 == 1) and (numberAzimuthLooks2 == 1)):
        #take looks
        look(latitude, multilookLatitude, width, numberRangeLooks2,
             numberAzimuthLooks2, 3, 0, 1)
        look(longitude, multilookLongitude, width, numberRangeLooks2,
             numberAzimuthLooks2, 3, 0, 1)
        look(height, multilookHeight, width, numberRangeLooks2,
             numberAzimuthLooks2, 3, 0, 1)
        #creat xml
        create_xml(multilookLatitude, width2, length2, 'double')
        create_xml(multilookLongitude, width2, length2, 'double')
        create_xml(multilookHeight, width2, length2, 'double')
        #los has two bands, use look program in isce instead
        #cmd = "looks.py -i {} -o {} -r {} -a {}".format(self._insar.los, self._insar.multilookLos, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2)
        #runCmd(cmd)

        #replace the above system call with function call
        from mroipac.looks.Looks import Looks
        from isceobj.Image import createImage
        inImage = createImage()
        inImage.load(los + '.xml')

        lkObj = Looks()
        lkObj.setDownLooks(numberAzimuthLooks2)
        lkObj.setAcrossLooks(numberRangeLooks2)
Beispiel #13
0
            index2 = np.linspace(0, width2-1, num=width2, endpoint=True)
            index3 = np.linspace(0, width3-1, num=width3, endpoint=True) * nrlo/nrli + (nrlo-nrli)/(2.0*nrli)
            ionrect = np.zeros((length3, width3), dtype=np.float32)
            for i in range(length2):
                f = interp1d(index2, ionfilt[i,:], kind='cubic', fill_value="extrapolate")
                ionrect[i, :] = f(index3)
            
            index2 = np.linspace(0, length2-1, num=length2, endpoint=True)
            index3 = np.linspace(0, length3-1, num=length3, endpoint=True) * nalo/nali + (nalo-nali)/(2.0*nali)
            for j in range(width3):
                f = interp1d(index2, ionrect[0:length2, j], kind='cubic', fill_value="extrapolate")
                ionrect[:, j] = f(index3)
            
            ionrectfile = 'filt_ion_'+dates2[idate]+ml3+'.ion'
            ionrect.astype(np.float32).tofile(ionrectfile)
            create_xml(ionrectfile, width3, length3, 'float')
        else:
            ionrectfile = 'filt_ion_'+dates2[idate]+ml2+'.ion'
            ts[idate, :, :].astype(np.float32).tofile(ionrectfile)
            create_xml(ionrectfile, width, length, 'float')

    if interp and ((numberRangeLooks2 != numberRangeLooksIon) or (numberAzimuthLooks2 != numberAzimuthLooksIon)):
        ionrectfile = 'filt_ion_'+dateZero+ml3+'.ion'
        (np.zeros((length3, width3), dtype=np.float32)).astype(np.float32).tofile(ionrectfile)
        create_xml(ionrectfile, width3, length3, 'float')
    else:
        ionrectfile = 'filt_ion_'+dateZero+ml2+'.ion'
        (np.zeros((length, width), dtype=np.float32)).astype(np.float32).tofile(ionrectfile)
        create_xml(ionrectfile, width, length, 'float')

    os.chdir(cdir)
Beispiel #14
0
def runSlcMosaic(self):
    '''mosaic SLCs
    '''
    if not self.doDenseOffset:
        print(
            '\ndense offset not requested, skip this and the remaining steps...'
        )
        return
    if not ((self._insar.modeCombination == 0) or
            (self._insar.modeCombination == 1)):
        print(
            'dense offset only support spotligh-spotlight and stripmap-stripmap pairs'
        )
        return

    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()
    referenceTrack = self._insar.loadTrack(reference=True)
    secondaryTrack = self._insar.loadTrack(reference=False)

    denseOffsetDir = 'dense_offset'
    os.makedirs(denseOffsetDir, exist_ok=True)
    os.chdir(denseOffsetDir)

    ##################################################
    # estimate reference and secondary frame offsets
    ##################################################
    if len(referenceTrack.frames) > 1:
        matchingMode = 1

        #if reference offsets from matching are not already computed
        if self.frameOffsetMatching == False:
            offsetReference = frameOffset(referenceTrack,
                                          self._insar.referenceSlc,
                                          self._insar.referenceFrameOffset,
                                          crossCorrelation=True,
                                          matchingMode=matchingMode)
        offsetSecondary = frameOffset(secondaryTrack,
                                      self._insar.secondarySlc,
                                      self._insar.secondaryFrameOffset,
                                      crossCorrelation=True,
                                      matchingMode=matchingMode)
        if self.frameOffsetMatching == False:
            self._insar.frameRangeOffsetMatchingReference = offsetReference[2]
            self._insar.frameAzimuthOffsetMatchingReference = offsetReference[
                3]
        self._insar.frameRangeOffsetMatchingSecondary = offsetSecondary[2]
        self._insar.frameAzimuthOffsetMatchingSecondary = offsetSecondary[3]

    ##################################################
    # mosaic slc
    ##################################################
    numberOfFrames = len(referenceTrack.frames)
    if numberOfFrames == 1:
        import shutil
        #frameDir = os.path.join('f1_{}/mosaic'.format(self._insar.referenceFrames[0]))
        frameDir = os.path.join('f1_{}/s{}'.format(
            self._insar.referenceFrames[0], self._insar.startingSwath))
        if not os.path.isfile(self._insar.referenceSlc):
            if os.path.isfile(
                    os.path.join('../', frameDir, self._insar.referenceSlc)):
                os.symlink(
                    os.path.join('../', frameDir, self._insar.referenceSlc),
                    self._insar.referenceSlc)
        #shutil.copy2() can overwrite
        shutil.copy2(
            os.path.join('../', frameDir, self._insar.referenceSlc + '.vrt'),
            self._insar.referenceSlc + '.vrt')
        shutil.copy2(
            os.path.join('../', frameDir, self._insar.referenceSlc + '.xml'),
            self._insar.referenceSlc + '.xml')
        if not os.path.isfile(self._insar.secondarySlc):
            if os.path.isfile(
                    os.path.join('../', frameDir, self._insar.secondarySlc)):
                os.symlink(
                    os.path.join('../', frameDir, self._insar.secondarySlc),
                    self._insar.secondarySlc)
        shutil.copy2(
            os.path.join('../', frameDir, self._insar.secondarySlc + '.vrt'),
            self._insar.secondarySlc + '.vrt')
        shutil.copy2(
            os.path.join('../', frameDir, self._insar.secondarySlc + '.xml'),
            self._insar.secondarySlc + '.xml')

        #update track parameters
        #########################################################
        #mosaic size
        referenceTrack.numberOfSamples = referenceTrack.frames[0].swaths[
            0].numberOfSamples
        referenceTrack.numberOfLines = referenceTrack.frames[0].swaths[
            0].numberOfLines
        #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
        #range parameters
        referenceTrack.startingRange = referenceTrack.frames[0].swaths[
            0].startingRange
        referenceTrack.rangeSamplingRate = referenceTrack.frames[0].swaths[
            0].rangeSamplingRate
        referenceTrack.rangePixelSize = referenceTrack.frames[0].swaths[
            0].rangePixelSize
        #azimuth parameters
        referenceTrack.sensingStart = referenceTrack.frames[0].swaths[
            0].sensingStart
        referenceTrack.prf = referenceTrack.frames[0].swaths[0].prf
        referenceTrack.azimuthPixelSize = referenceTrack.frames[0].swaths[
            0].azimuthPixelSize
        referenceTrack.azimuthLineInterval = referenceTrack.frames[0].swaths[
            0].azimuthLineInterval

        referenceTrack.dopplerVsPixel = referenceTrack.frames[0].swaths[
            0].dopplerVsPixel

        #update track parameters, secondary
        #########################################################
        #mosaic size
        secondaryTrack.numberOfSamples = secondaryTrack.frames[0].swaths[
            0].numberOfSamples
        secondaryTrack.numberOfLines = secondaryTrack.frames[0].swaths[
            0].numberOfLines
        #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
        #range parameters
        secondaryTrack.startingRange = secondaryTrack.frames[0].swaths[
            0].startingRange
        secondaryTrack.rangeSamplingRate = secondaryTrack.frames[0].swaths[
            0].rangeSamplingRate
        secondaryTrack.rangePixelSize = secondaryTrack.frames[0].swaths[
            0].rangePixelSize
        #azimuth parameters
        secondaryTrack.sensingStart = secondaryTrack.frames[0].swaths[
            0].sensingStart
        secondaryTrack.prf = secondaryTrack.frames[0].swaths[0].prf
        secondaryTrack.azimuthPixelSize = secondaryTrack.frames[0].swaths[
            0].azimuthPixelSize
        secondaryTrack.azimuthLineInterval = secondaryTrack.frames[0].swaths[
            0].azimuthLineInterval

        secondaryTrack.dopplerVsPixel = secondaryTrack.frames[0].swaths[
            0].dopplerVsPixel

    else:
        #mosaic reference slc
        #########################################################
        #choose offsets
        rangeOffsets = self._insar.frameRangeOffsetMatchingReference
        azimuthOffsets = self._insar.frameAzimuthOffsetMatchingReference

        #list of input files
        slcs = []
        for i, frameNumber in enumerate(self._insar.referenceFrames):
            frameDir = 'f{}_{}'.format(i + 1, frameNumber)
            swathDir = 's{}'.format(self._insar.startingSwath)
            slcs.append(
                os.path.join('../', frameDir, swathDir,
                             self._insar.referenceSlc))

        #note that track parameters are updated after mosaicking
        #parameters update is checked, it is OK.
        frameMosaic(referenceTrack,
                    slcs,
                    self._insar.referenceSlc,
                    rangeOffsets,
                    azimuthOffsets,
                    1,
                    1,
                    updateTrack=True,
                    phaseCompensation=True,
                    resamplingMethod=2)
        create_xml(self._insar.referenceSlc, referenceTrack.numberOfSamples,
                   referenceTrack.numberOfLines, 'slc')
        referenceTrack.dopplerVsPixel = computeTrackDoppler(referenceTrack)

        #mosaic secondary slc
        #########################################################
        #choose offsets
        rangeOffsets = self._insar.frameRangeOffsetMatchingSecondary
        azimuthOffsets = self._insar.frameAzimuthOffsetMatchingSecondary

        #list of input files
        slcs = []
        for i, frameNumber in enumerate(self._insar.referenceFrames):
            frameDir = 'f{}_{}'.format(i + 1, frameNumber)
            swathDir = 's{}'.format(self._insar.startingSwath)
            slcs.append(
                os.path.join('../', frameDir, swathDir,
                             self._insar.secondarySlc))

        #note that track parameters are updated after mosaicking
        #parameters update is checked, it is OK.
        frameMosaic(secondaryTrack,
                    slcs,
                    self._insar.secondarySlc,
                    rangeOffsets,
                    azimuthOffsets,
                    1,
                    1,
                    updateTrack=True,
                    phaseCompensation=True,
                    resamplingMethod=2)
        create_xml(self._insar.secondarySlc, secondaryTrack.numberOfSamples,
                   secondaryTrack.numberOfLines, 'slc')
        secondaryTrack.dopplerVsPixel = computeTrackDoppler(secondaryTrack)

    #save parameter file inside denseoffset directory
    self._insar.saveProduct(referenceTrack,
                            self._insar.referenceTrackParameter)
    self._insar.saveProduct(secondaryTrack,
                            self._insar.secondaryTrackParameter)

    os.chdir('../')
    catalog.printToLog(logger, "runSlcMosaic")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #15
0
def cropSlc(orbit, swath, slc, orbit2, swath2, edge=0, useVirtualFile=True):
    from isceobj.Alos2Proc.Alos2ProcPublic import find_vrt_keyword
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
    '''
    orbit:  orbit of the image to be cropped
    swath:  swath of the image to be cropped
    slc:    image to be cropped
    orbit2: orbit of the other image
    swath2: swath of the other image
    '''

    #find topleft and lowerright corners
    #all indices start with 0
    corner = []
    for x in [[0, 0], [swath2.numberOfLines - 1, swath2.numberOfSamples - 1]]:
        line2 = x[0]
        sample2 = x[1]
        rg2 = swath2.startingRange + swath2.rangePixelSize * sample2
        az2 = swath2.sensingStart + datetime.timedelta(seconds=line2 /
                                                       swath2.prf)
        llh2 = orbit2.rdr2geo(az2, rg2)
        az, rg = orbit.geo2rdr(llh2)
        line = (az - swath.sensingStart).total_seconds() * swath.prf
        sample = (rg - swath.startingRange) / swath.rangePixelSize
        corner.append([line, sample])

    #image (to be cropped) bounds
    firstLine = 0
    lastLine = swath.numberOfLines - 1
    firstSample = 0
    lastSample = swath.numberOfSamples - 1

    #the othe image bounds in image (to be cropped)
    #add edge
    #edge = 9
    firstLine2 = int(corner[0][0] - edge)
    lastLine2 = int(corner[1][0] + edge)
    firstSample2 = int(corner[0][1] - edge)
    lastSample2 = int(corner[1][1] + edge)

    #image (to be cropped) output bounds
    firstLine3 = max(firstLine, firstLine2)
    lastLine3 = min(lastLine, lastLine2)
    firstSample3 = max(firstSample, firstSample2)
    lastSample3 = min(lastSample, lastSample2)
    numberOfSamples3 = lastSample3 - firstSample3 + 1
    numberOfLines3 = lastLine3 - firstLine3 + 1

    #check if there is overlap
    if lastLine3 - firstLine3 + 1 < 1000:
        raise Exception(
            'azimuth overlap < 1000 lines, not enough area for InSAR\n')
    if lastSample3 - firstSample3 + 1 < 1000:
        raise Exception(
            'range overlap < 1000 samples, not enough area for InSAR\n')

    #check if there is a need to crop image
    if abs(firstLine3-firstLine) < 100 and abs(lastLine3-lastLine) < 100 and \
       abs(firstSample3-firstSample) < 100 and abs(lastSample3-lastSample) < 100:
        print('no need to crop {}. nothing is done by crop.'.format(slc))
        return

    #crop image
    if useVirtualFile:
        #vrt
        SourceFilename = find_vrt_keyword(slc + '.vrt', 'SourceFilename')
        ImageOffset = int(find_vrt_keyword(slc + '.vrt', 'ImageOffset'))
        PixelOffset = int(find_vrt_keyword(slc + '.vrt', 'PixelOffset'))
        LineOffset = int(find_vrt_keyword(slc + '.vrt', 'LineOffset'))

        #overwrite vrt and xml
        img = isceobj.createImage()
        img.load(slc + '.xml')
        img.width = numberOfSamples3
        img.length = numberOfLines3
        img.renderHdr()

        #overrite vrt
        with open(slc + '.vrt', 'w') as fid:
            fid.write('''<VRTDataset rasterXSize="{0}" rasterYSize="{1}">
    <VRTRasterBand band="1" dataType="CFloat32" subClass="VRTRawRasterBand">
        <SourceFilename relativeToVRT="0">{2}</SourceFilename>
        <ByteOrder>MSB</ByteOrder>
        <ImageOffset>{3}</ImageOffset>
        <PixelOffset>8</PixelOffset>
        <LineOffset>{4}</LineOffset>
    </VRTRasterBand>
</VRTDataset>'''.format(
                numberOfSamples3, numberOfLines3, SourceFilename,
                ImageOffset + firstLine3 * LineOffset + firstSample3 * 8,
                LineOffset))
    else:
        #read and crop data
        with open(slc, 'rb') as f:
            f.seek(
                firstLine3 * swath.numberOfSamples *
                np.dtype(np.complex64).itemsize, 0)
            data = np.fromfile(f, dtype=np.complex64, count=numberOfLines3 * swath.numberOfSamples)\
                               .reshape(numberOfLines3,swath.numberOfSamples)
            data2 = data[:, firstSample3:lastSample3 + 1]
        #overwrite original
        data2.astype(np.complex64).tofile(slc)

        #creat new vrt and xml
        os.remove(slc + '.xml')
        os.remove(slc + '.vrt')
        create_xml(slc, numberOfSamples3, numberOfLines3, 'slc')

    #update parameters
    #update doppler and azfmrate first
    dop = np.polyval(swath.dopplerVsPixel[::-1],
                     np.arange(swath.numberOfSamples))
    dop3 = dop[firstSample3:lastSample3 + 1]
    p = np.polyfit(np.arange(numberOfSamples3), dop3, 3)
    swath.dopplerVsPixel = [p[3], p[2], p[1], p[0]]

    azfmrate = np.polyval(swath.azimuthFmrateVsPixel[::-1],
                          np.arange(swath.numberOfSamples))
    azfmrate3 = azfmrate[firstSample3:lastSample3 + 1]
    p = np.polyfit(np.arange(numberOfSamples3), azfmrate3, 3)
    swath.azimuthFmrateVsPixel = [p[3], p[2], p[1], p[0]]

    swath.numberOfSamples = numberOfSamples3
    swath.numberOfLines = numberOfLines3

    swath.startingRange += firstSample3 * swath.rangePixelSize
    swath.sensingStart += datetime.timedelta(seconds=firstLine3 / swath.prf)
Beispiel #16
0
def runIonFilt(self):
    '''compute and filter ionospheric phase
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    if not self.doIon:
        catalog.printToLog(logger, "runIonFilt")
        self._insar.procDoc.addAllFromCatalog(catalog)
        return

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

    from isceobj.Alos2Proc.runIonSubband import defineIonDir
    ionDir = defineIonDir()
    subbandPrefix = ['lower', 'upper']

    ionCalDir = os.path.join(ionDir['ion'], ionDir['ionCal'])
    if not os.path.exists(ionCalDir):
        os.makedirs(ionCalDir)
    os.chdir(ionCalDir)


    ############################################################
    # STEP 1. compute ionospheric phase
    ############################################################
    from isceobj.Constants import SPEED_OF_LIGHT
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml

    ###################################
    #SET PARAMETERS HERE
    #THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self)
    corThresholdAdj = 0.85
    ###################################

    print('\ncomputing ionosphere')
    #get files
    ml2 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon, 
                              self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon)

    lowerUnwfile = subbandPrefix[0]+ml2+'.unw'
    upperUnwfile = subbandPrefix[1]+ml2+'.unw'
    corfile = 'diff'+ml2+'.cor'

    #use image size from lower unwrapped interferogram
    img = isceobj.createImage()
    img.load(lowerUnwfile + '.xml')
    width = img.width
    length = img.length

    lowerUnw = (np.fromfile(lowerUnwfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :]
    upperUnw = (np.fromfile(upperUnwfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :]
    cor = (np.fromfile(corfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :]
    #amp = (np.fromfile(corfile, dtype=np.float32).reshape(length*2, width))[0:length*2:2, :]

    #masked out user-specified areas
    if self.maskedAreasIon != None:
        maskedAreas = reformatMaskedAreas(self.maskedAreasIon, length, width)
        for area in maskedAreas:
            lowerUnw[area[0]:area[1], area[2]:area[3]] = 0
            upperUnw[area[0]:area[1], area[2]:area[3]] = 0
            cor[area[0]:area[1], area[2]:area[3]] = 0

    #compute ionosphere
    fl = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[0]
    fu = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[1]
    adjFlag = 1
    ionos = computeIonosphere(lowerUnw, upperUnw, cor, fl, fu, adjFlag, corThresholdAdj, 0)

    #dump ionosphere
    ionfile = 'ion'+ml2+'.ion'
    # ion = np.zeros((length*2, width), dtype=np.float32)
    # ion[0:length*2:2, :] = amp
    # ion[1:length*2:2, :] = ionos
    # ion.astype(np.float32).tofile(ionfile)
    # img.filename = ionfile
    # img.extraFilename = ionfile + '.vrt'
    # img.renderHdr()

    ionos.astype(np.float32).tofile(ionfile)
    create_xml(ionfile, width, length, 'float')


    ############################################################
    # STEP 2. filter ionospheric phase
    ############################################################

    #################################################
    #SET PARAMETERS HERE
    #if applying polynomial fitting
    #False: no fitting, True: with fitting
    fit = self.fitIon
    #gaussian filtering window size
    size_max = self.filteringWinsizeMaxIon
    size_min = self.filteringWinsizeMinIon

    #THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self)
    corThresholdIon = 0.85
    #################################################

    print('\nfiltering ionosphere')
    ionfile = 'ion'+ml2+'.ion'
    corfile = 'diff'+ml2+'.cor'
    ionfiltfile = 'filt_ion'+ml2+'.ion'

    img = isceobj.createImage()
    img.load(ionfile + '.xml')
    width = img.width
    length = img.length
    #ion = (np.fromfile(ionfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :]
    ion = np.fromfile(ionfile, dtype=np.float32).reshape(length, width)
    cor = (np.fromfile(corfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :]
    #amp = (np.fromfile(ionfile, dtype=np.float32).reshape(length*2, width))[0:length*2:2, :]

    #masked out user-specified areas
    if self.maskedAreasIon != None:
        maskedAreas = reformatMaskedAreas(self.maskedAreasIon, length, width)
        for area in maskedAreas:
            ion[area[0]:area[1], area[2]:area[3]] = 0
            cor[area[0]:area[1], area[2]:area[3]] = 0

    #remove possible wired values in coherence
    cor[np.nonzero(cor<0)] = 0.0
    cor[np.nonzero(cor>1)] = 0.0

    # #applying water body mask here
    # waterBodyFile = 'wbd'+ml2+'.wbd'
    # if os.path.isfile(waterBodyFile):
    #     print('applying water body mask to coherence used to compute ionospheric phase')
    #     wbd = np.fromfile(waterBodyFile, dtype=np.int8).reshape(length, width)
    #     cor[np.nonzero(wbd!=0)] = 0.00001

    if fit:
        ion_fit = weight_fitting(ion, cor, width, length, 1, 1, 1, 1, 2, corThresholdIon)
        ion -= ion_fit * (ion!=0)

    #minimize the effect of low coherence pixels
    #cor[np.nonzero( (cor<0.85)*(cor!=0) )] = 0.00001
    #filt = adaptive_gaussian(ion, cor, size_max, size_min)
    #cor**14 should be a good weight to use. 22-APR-2018
    filt = adaptive_gaussian(ion, cor**14, size_max, size_min)

    if fit:
        filt += ion_fit * (filt!=0)

    # ion = np.zeros((length*2, width), dtype=np.float32)
    # ion[0:length*2:2, :] = amp
    # ion[1:length*2:2, :] = filt
    # ion.astype(np.float32).tofile(ionfiltfile)
    # img.filename = ionfiltfile
    # img.extraFilename = ionfiltfile + '.vrt'
    # img.renderHdr()

    filt.astype(np.float32).tofile(ionfiltfile)
    create_xml(ionfiltfile, width, length, 'float')


    ############################################################
    # STEP 3. resample ionospheric phase
    ############################################################
    from contrib.alos2proc_f.alos2proc_f import rect
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
    from scipy.interpolate import interp1d
    import shutil

    #################################################
    #SET PARAMETERS HERE
    #interpolation method
    interpolationMethod = 1
    #################################################

    print('\ninterpolate ionosphere')

    ml3 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooks2, 
                              self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooks2)

    ionfiltfile = 'filt_ion'+ml2+'.ion'
    #ionrectfile = 'filt_ion'+ml3+'.ion'
    ionrectfile = self._insar.multilookIon

    img = isceobj.createImage()
    img.load(ionfiltfile + '.xml')
    width2 = img.width
    length2 = img.length

    img = isceobj.createImage()
    img.load(os.path.join('../../', ionDir['insar'], self._insar.multilookDifferentialInterferogram) + '.xml')
    width3 = img.width
    length3 = img.length

    #number of range looks output
    nrlo = self._insar.numberRangeLooks1*self._insar.numberRangeLooks2
    #number of range looks input
    nrli = self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon
    #number of azimuth looks output
    nalo = self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooks2
    #number of azimuth looks input
    nali = self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon

    if (self._insar.numberRangeLooks2 != self._insar.numberRangeLooksIon) or \
       (self._insar.numberAzimuthLooks2 != self._insar.numberAzimuthLooksIon):
        #this should be faster using fortran
        if interpolationMethod == 0:
            rect(ionfiltfile, ionrectfile,
                width2,length2,
                width3,length3,
                nrlo/nrli, 0.0,
                0.0, nalo/nali,
                (nrlo-nrli)/(2.0*nrli),
                (nalo-nali)/(2.0*nali),
                'REAL','Bilinear')
        #finer, but slower method
        else:
            ionfilt = np.fromfile(ionfiltfile, dtype=np.float32).reshape(length2, width2)
            index2 = np.linspace(0, width2-1, num=width2, endpoint=True)
            index3 = np.linspace(0, width3-1, num=width3, endpoint=True) * nrlo/nrli + (nrlo-nrli)/(2.0*nrli)
            ionrect = np.zeros((length3, width3), dtype=np.float32)
            for i in range(length2):
                f = interp1d(index2, ionfilt[i,:], kind='cubic', fill_value="extrapolate")
                ionrect[i, :] = f(index3)
            
            index2 = np.linspace(0, length2-1, num=length2, endpoint=True)
            index3 = np.linspace(0, length3-1, num=length3, endpoint=True) * nalo/nali + (nalo-nali)/(2.0*nali)
            for j in range(width3):
                f = interp1d(index2, ionrect[0:length2, j], kind='cubic', fill_value="extrapolate")
                ionrect[:, j] = f(index3)
            ionrect.astype(np.float32).tofile(ionrectfile)
            del ionrect
        create_xml(ionrectfile, width3, length3, 'float')

        os.rename(ionrectfile, os.path.join('../../insar', ionrectfile))
        os.rename(ionrectfile+'.vrt', os.path.join('../../insar', ionrectfile)+'.vrt')
        os.rename(ionrectfile+'.xml', os.path.join('../../insar', ionrectfile)+'.xml')
        os.chdir('../../insar')
    else:
        shutil.copyfile(ionfiltfile, os.path.join('../../insar', ionrectfile))
        os.chdir('../../insar')
        create_xml(ionrectfile, width3, length3, 'float')
    #now we are in 'insar'


    ############################################################
    # STEP 4. correct interferogram
    ############################################################
    from isceobj.Alos2Proc.Alos2ProcPublic import renameFile
    from isceobj.Alos2Proc.Alos2ProcPublic import runCmd

    if self.applyIon:
        print('\ncorrect interferogram')
        if os.path.isfile(self._insar.multilookDifferentialInterferogramOriginal):
            print('original interferogram: {} is already here, do not rename: {}'.format(self._insar.multilookDifferentialInterferogramOriginal, self._insar.multilookDifferentialInterferogram))
        else:
            print('renaming {} to {}'.format(self._insar.multilookDifferentialInterferogram, self._insar.multilookDifferentialInterferogramOriginal))
            renameFile(self._insar.multilookDifferentialInterferogram, self._insar.multilookDifferentialInterferogramOriginal)

        cmd = "imageMath.py -e='a*exp(-1.0*J*b)' --a={} --b={} -s BIP -t cfloat -o {}".format(
            self._insar.multilookDifferentialInterferogramOriginal,
            self._insar.multilookIon,
            self._insar.multilookDifferentialInterferogram)
        runCmd(cmd)
    else:
        print('\nionospheric phase estimation finished, but correction of interfeorgram not requested')

    os.chdir('../')

    catalog.printToLog(logger, "runIonFilt")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #17
0
def runSwathMosaic(self):
    '''mosaic subswaths
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

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


    for i, frameNumber in enumerate(self._insar.referenceFrames):
        frameDir = 'f{}_{}'.format(i+1, frameNumber)
        os.chdir(frameDir)

        mosaicDir = 'mosaic'
        os.makedirs(mosaicDir, exist_ok=True)
        os.chdir(mosaicDir)

        if self._insar.endingSwath-self._insar.startingSwath+1 == 1:
            import shutil
            swathDir = 's{}'.format(referenceTrack.frames[i].swaths[0].swathNumber)
            
            if not os.path.isfile(self._insar.interferogram):
                os.symlink(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram)
            shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
            shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
            if not os.path.isfile(self._insar.amplitude):
                os.symlink(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude)
            shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
            shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')

            # os.rename(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram)
            # os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
            # os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
            # os.rename(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude)
            # os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
            # os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')

            #update frame parameters
            #########################################################
            frame = referenceTrack.frames[i]
            infImg = isceobj.createImage()
            infImg.load(self._insar.interferogram+'.xml')
            #mosaic size
            frame.numberOfSamples = infImg.width
            frame.numberOfLines = infImg.length
            #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
            #range parameters
            frame.startingRange = frame.swaths[0].startingRange
            frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate
            frame.rangePixelSize = frame.swaths[0].rangePixelSize
            #azimuth parameters
            frame.sensingStart = frame.swaths[0].sensingStart
            frame.prf = frame.swaths[0].prf
            frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize
            frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval

            #update frame parameters, secondary
            #########################################################
            frame = secondaryTrack.frames[i]
            #mosaic size
            frame.numberOfSamples = int(frame.swaths[0].numberOfSamples/self._insar.numberRangeLooks1)
            frame.numberOfLines = int(frame.swaths[0].numberOfLines/self._insar.numberAzimuthLooks1)
            #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
            #range parameters
            frame.startingRange = frame.swaths[0].startingRange
            frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate
            frame.rangePixelSize = frame.swaths[0].rangePixelSize
            #azimuth parameters
            frame.sensingStart = frame.swaths[0].sensingStart
            frame.prf = frame.swaths[0].prf
            frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize
            frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval

            os.chdir('../')

            #save parameter file
            self._insar.saveProduct(referenceTrack.frames[i], self._insar.referenceFrameParameter)
            self._insar.saveProduct(secondaryTrack.frames[i], self._insar.secondaryFrameParameter)

            os.chdir('../')

            continue

        #choose offsets
        numberOfFrames = len(referenceTrack.frames)
        numberOfSwaths = len(referenceTrack.frames[i].swaths)
        if self.swathOffsetMatching:
            #no need to do this as the API support 2-d list
            #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingReference)).reshape(numberOfFrames, numberOfSwaths)
            #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingReference)).reshape(numberOfFrames, numberOfSwaths)
            rangeOffsets = self._insar.swathRangeOffsetMatchingReference
            azimuthOffsets = self._insar.swathAzimuthOffsetMatchingReference

        else:
            #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalReference)).reshape(numberOfFrames, numberOfSwaths)
            #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalReference)).reshape(numberOfFrames, numberOfSwaths)
            rangeOffsets = self._insar.swathRangeOffsetGeometricalReference
            azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalReference

        rangeOffsets = rangeOffsets[i]
        azimuthOffsets = azimuthOffsets[i]

        #list of input files
        inputInterferograms = []
        inputAmplitudes = []
        for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            swathDir = 's{}'.format(swathNumber)
            inputInterferograms.append(os.path.join('../', swathDir, self._insar.interferogram))
            inputAmplitudes.append(os.path.join('../', swathDir, self._insar.amplitude))

        #note that frame parameters are updated after mosaicking
        #mosaic amplitudes
        swathMosaic(referenceTrack.frames[i], inputAmplitudes, self._insar.amplitude, 
            rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, resamplingMethod=0)
        #mosaic interferograms
        swathMosaic(referenceTrack.frames[i], inputInterferograms, self._insar.interferogram, 
            rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, updateFrame=True, resamplingMethod=1)

        create_xml(self._insar.amplitude, referenceTrack.frames[i].numberOfSamples, referenceTrack.frames[i].numberOfLines, 'amp')
        create_xml(self._insar.interferogram, referenceTrack.frames[i].numberOfSamples, referenceTrack.frames[i].numberOfLines, 'int')

        #update secondary frame parameters here
        #no matching for secondary, always use geometry
        rangeOffsets = self._insar.swathRangeOffsetGeometricalSecondary
        azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalSecondary
        rangeOffsets = rangeOffsets[i]
        azimuthOffsets = azimuthOffsets[i]
        swathMosaicParameters(secondaryTrack.frames[i], rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1)

        os.chdir('../')

        #save parameter file
        self._insar.saveProduct(referenceTrack.frames[i], self._insar.referenceFrameParameter)
        self._insar.saveProduct(secondaryTrack.frames[i], self._insar.secondaryFrameParameter)

        os.chdir('../')


    #mosaic spectral diversity interferograms
    for i, frameNumber in enumerate(self._insar.referenceFrames):
        frameDir = 'f{}_{}'.format(i+1, frameNumber)
        os.chdir(frameDir)

        mosaicDir = 'mosaic'
        os.makedirs(mosaicDir, exist_ok=True)
        os.chdir(mosaicDir)

        if self._insar.endingSwath-self._insar.startingSwath+1 == 1:
            import shutil
            swathDir = 's{}'.format(referenceTrack.frames[i].swaths[0].swathNumber)
            
            for sdFile in self._insar.interferogramSd:
                if not os.path.isfile(sdFile):
                    os.symlink(os.path.join('../', swathDir, 'spectral_diversity', sdFile), sdFile)
                shutil.copy2(os.path.join('../', swathDir, 'spectral_diversity', sdFile+'.vrt'), sdFile+'.vrt')
                shutil.copy2(os.path.join('../', swathDir, 'spectral_diversity', sdFile+'.xml'), sdFile+'.xml')

            os.chdir('../')
            os.chdir('../')
            continue

        #choose offsets
        numberOfFrames = len(referenceTrack.frames)
        numberOfSwaths = len(referenceTrack.frames[i].swaths)
        if self.swathOffsetMatching:
            #no need to do this as the API support 2-d list
            #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingReference)).reshape(numberOfFrames, numberOfSwaths)
            #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingReference)).reshape(numberOfFrames, numberOfSwaths)
            rangeOffsets = self._insar.swathRangeOffsetMatchingReference
            azimuthOffsets = self._insar.swathAzimuthOffsetMatchingReference

        else:
            #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalReference)).reshape(numberOfFrames, numberOfSwaths)
            #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalReference)).reshape(numberOfFrames, numberOfSwaths)
            rangeOffsets = self._insar.swathRangeOffsetGeometricalReference
            azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalReference

        rangeOffsets = rangeOffsets[i]
        azimuthOffsets = azimuthOffsets[i]

        #list of input files
        inputSd = [[], [], []]
        for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            swathDir = 's{}'.format(swathNumber)
            for k, sdFile in enumerate(self._insar.interferogramSd):
                inputSd[k].append(os.path.join('../', swathDir, 'spectral_diversity', sdFile))

        #mosaic spectral diversity interferograms
        for inputSdList, outputSdFile in zip(inputSd, self._insar.interferogramSd):
            swathMosaic(referenceTrack.frames[i], inputSdList, outputSdFile, 
                rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, updateFrame=False, phaseCompensation=True, pcRangeLooks=5, pcAzimuthLooks=5, filt=True, resamplingMethod=1)

        for sdFile in self._insar.interferogramSd:
            create_xml(sdFile, referenceTrack.frames[i].numberOfSamples, referenceTrack.frames[i].numberOfLines, 'int')

        os.chdir('../')
        os.chdir('../')


    catalog.printToLog(logger, "runSwathMosaic")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #18
0
def resampleBursts(masterSwath,
                   slaveSwath,
                   masterBurstDir,
                   slaveBurstDir,
                   slaveBurstResampledDir,
                   interferogramDir,
                   masterBurstPrefix,
                   slaveBurstPrefix,
                   slaveBurstResampledPrefix,
                   interferogramPrefix,
                   rangeOffset,
                   azimuthOffset,
                   rangeOffsetResidual=0,
                   azimuthOffsetResidual=0):

    import os
    import datetime
    import numpy as np
    import numpy.matlib
    from contrib.alos2proc.alos2proc import resamp

    if not os.path.exists(slaveBurstResampledDir):
        os.makedirs(slaveBurstResampledDir)
    if not os.path.exists(interferogramDir):
        os.makedirs(interferogramDir)

    #get burst file names
    masterBurstSlc = [
        masterBurstPrefix + '_%02d.slc' % (i + 1)
        for i in range(masterSwath.numberOfBursts)
    ]
    slaveBurstSlc = [
        slaveBurstPrefix + '_%02d.slc' % (i + 1)
        for i in range(slaveSwath.numberOfBursts)
    ]
    slaveBurstSlcResampled = [
        slaveBurstPrefix + '_%02d.slc' % (i + 1)
        for i in range(masterSwath.numberOfBursts)
    ]
    interferogram = [
        interferogramPrefix + '_%02d.int' % (i + 1)
        for i in range(masterSwath.numberOfBursts)
    ]

    length = masterSwath.burstSlcNumberOfLines
    width = masterSwath.burstSlcNumberOfSamples
    lengthSlave = slaveSwath.burstSlcNumberOfLines
    widthSlave = slaveSwath.burstSlcNumberOfSamples

    #slave burst slc start times
    slaveBurstStartTimesSlc = [slaveSwath.firstBurstSlcStartTime + \
                               datetime.timedelta(seconds=slaveSwath.burstSlcFirstLineOffsets[i]*slaveSwath.azimuthLineInterval) \
                               for i in range(slaveSwath.numberOfBursts)]
    #slave burst raw start times
    slaveBurstStartTimesRaw = [slaveSwath.firstBurstRawStartTime + \
                               datetime.timedelta(seconds=i*slaveSwath.burstCycleLength/slaveSwath.prf) \
                               for i in range(slaveSwath.numberOfBursts)]

    for i in range(masterSwath.numberOfBursts):

        ##########################################################################
        # 1. get offsets and corresponding slave burst
        ##########################################################################
        #range offset
        with open(rangeOffset, 'rb') as f:
            f.seek(
                masterSwath.burstSlcFirstLineOffsets[i] * width *
                np.dtype(np.float32).itemsize, 0)
            rgoffBurst = np.fromfile(f, dtype=np.float32,
                                     count=length * width).reshape(
                                         length, width)
            if type(rangeOffsetResidual) == np.ndarray:
                residual = rangeOffsetResidual[
                    0 + masterSwath.burstSlcFirstLineOffsets[i]:length +
                    masterSwath.burstSlcFirstLineOffsets[i], :]
                rgoffBurst[np.nonzero(
                    rgoffBurst != -999999.0)] += residual[np.nonzero(
                        rgoffBurst != -999999.0)]
            else:
                rgoffBurst[np.nonzero(
                    rgoffBurst != -999999.0)] += rangeOffsetResidual
        #azimuth offset
        with open(azimuthOffset, 'rb') as f:
            f.seek(
                masterSwath.burstSlcFirstLineOffsets[i] * width *
                np.dtype(np.float32).itemsize, 0)
            azoffBurst = np.fromfile(f, dtype=np.float32,
                                     count=length * width).reshape(
                                         length, width)
            if type(azimuthOffsetResidual) == np.ndarray:
                residual = azimuthOffsetResidual[
                    0 + masterSwath.burstSlcFirstLineOffsets[i]:length +
                    masterSwath.burstSlcFirstLineOffsets[i], :]
                azoffBurst[np.nonzero(
                    azoffBurst != -999999.0)] += residual[np.nonzero(
                        azoffBurst != -999999.0)]
            else:
                azoffBurst[np.nonzero(
                    azoffBurst != -999999.0)] += azimuthOffsetResidual

        #find the corresponding slave burst
        #get mean offset to use
        #remove BAD_VALUE = -999999.0 as defined in geo2rdr.f90
        #single precision is not accurate enough to compute mean
        azoffBurstMean = np.mean(
            azoffBurst[np.nonzero(azoffBurst != -999999.0)], dtype=np.float64)
        iSlave = -1
        for j in range(slaveSwath.numberOfBursts):
            if abs(masterSwath.burstSlcFirstLineOffsets[i] + azoffBurstMean -
                   slaveSwath.burstSlcFirstLineOffsets[j]) < (
                       masterSwath.burstLength / masterSwath.prf *
                       2.0) / masterSwath.azimuthLineInterval:
                iSlave = j
                break

        #output zero resampled burst/interferogram if no slave burst found
        if iSlave == -1:
            print('\nburst pair, master: %2d, slave:  no' % (i + 1))
            #output an interferogram with all pixels set to zero
            os.chdir(interferogramDir)
            np.zeros((length, width), dtype=np.complex64).astype(
                np.complex64).tofile(interferogram[i])
            create_xml(interferogram[i], width, length, 'int')
            os.chdir('../')
            #output a resampled slave image with all pixels set to zero
            os.chdir(slaveBurstResampledDir)
            np.zeros((length, width), dtype=np.complex64).astype(
                np.complex64).tofile(slaveBurstSlcResampled[i])
            create_xml(slaveBurstSlcResampled[i], width, length, 'slc')
            os.chdir('../')
            continue
        else:
            print('\nburst pair, master: %2d, slave: %3d' %
                  (i + 1, iSlave + 1))

        #adjust azimuth offset accordingly, since original azimuth offset assumes master and slave start with sensingStart
        azoffBurst -= (slaveSwath.burstSlcFirstLineOffsets[iSlave] -
                       masterSwath.burstSlcFirstLineOffsets[i])

        ##########################################################################
        # 2. compute deramp and reramp signals
        ##########################################################################
        cj = np.complex64(1j)
        tbase = (slaveBurstStartTimesSlc[iSlave] - (slaveBurstStartTimesRaw[iSlave] + \
                 datetime.timedelta(seconds=(slaveSwath.burstLength - 1.0) / 2.0 / slaveSwath.prf))).total_seconds()

        #compute deramp signal
        index1 = np.matlib.repmat(np.arange(widthSlave), lengthSlave, 1)
        index2 = np.matlib.repmat(
            np.arange(lengthSlave).reshape(lengthSlave, 1), 1, widthSlave)
        ka = slaveSwath.azimuthFmrateVsPixel[3] * index1**3 + slaveSwath.azimuthFmrateVsPixel[2] * index1**2 + \
             slaveSwath.azimuthFmrateVsPixel[1] * index1    + slaveSwath.azimuthFmrateVsPixel[0]
        #use the convention that ka > 0
        ka = -ka
        t = tbase + index2 * slaveSwath.azimuthLineInterval
        deramp = np.exp(cj * np.pi * (-ka) * t**2)

        #compute reramp signal
        index1 = np.matlib.repmat(np.arange(width), length, 1) + rgoffBurst
        index2 = np.matlib.repmat(
            np.arange(length).reshape(length, 1), 1, width) + azoffBurst
        ka = slaveSwath.azimuthFmrateVsPixel[3] * index1**3 + slaveSwath.azimuthFmrateVsPixel[2] * index1**2 + \
             slaveSwath.azimuthFmrateVsPixel[1] * index1    + slaveSwath.azimuthFmrateVsPixel[0]
        #use the convention that ka > 0
        ka = -ka
        t = tbase + index2 * slaveSwath.azimuthLineInterval
        reramp = np.exp(cj * np.pi * (ka) * t**2)

        ##########################################################################
        # 3. resample slave burst
        ##########################################################################
        #go to slave directory to do resampling
        os.chdir(slaveBurstDir)

        #output offsets
        rgoffBurstFile = "burst_rg.off"
        azoffBurstFile = "burst_az.off"
        rgoffBurst.astype(np.float32).tofile(rgoffBurstFile)
        azoffBurst.astype(np.float32).tofile(azoffBurstFile)

        #deramp slave burst
        slaveBurstDerampedFile = "slave.slc"
        sburst = np.fromfile(slaveBurstSlc[iSlave],
                             dtype=np.complex64).reshape(
                                 lengthSlave, widthSlave)
        (deramp * sburst).astype(np.complex64).tofile(slaveBurstDerampedFile)
        create_xml(slaveBurstDerampedFile, widthSlave, lengthSlave, 'slc')

        #resampled slave burst
        slaveBurstResampFile = 'slave_resamp.slc'

        #resample slave burst
        #now doppler has bigger impact now, as it's value is about 35 Hz (azimuth resampling frequency is now only 1/20 * PRF)
        #we don't know if this doppler value is accurate or not, so we set it to zero, which seems to give best resampling result
        #otherwise if it is not accurate and we still use it, it will significantly affect resampling result
        dopplerVsPixel = slaveSwath.dopplerVsPixel
        dopplerVsPixel = [0.0, 0.0, 0.0, 0.0]

        resamp(slaveBurstDerampedFile,
               slaveBurstResampFile,
               rgoffBurstFile,
               azoffBurstFile,
               width,
               length,
               1.0 / slaveSwath.azimuthLineInterval,
               dopplerVsPixel,
               rgcoef=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
               azcoef=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
               azpos_off=0.0)

        #read resampled slave burst and reramp
        sburstResamp = reramp * (np.fromfile(
            slaveBurstResampFile, dtype=np.complex64).reshape(length, width))

        #clear up
        os.remove(rgoffBurstFile)
        os.remove(azoffBurstFile)
        os.remove(slaveBurstDerampedFile)
        os.remove(slaveBurstDerampedFile + '.vrt')
        os.remove(slaveBurstDerampedFile + '.xml')
        os.remove(slaveBurstResampFile)
        os.remove(slaveBurstResampFile + '.vrt')
        os.remove(slaveBurstResampFile + '.xml')

        os.chdir('../')

        ##########################################################################
        # 4. dump results
        ##########################################################################
        #dump resampled slave burst
        os.chdir(slaveBurstResampledDir)
        sburstResamp.astype(np.complex64).tofile(slaveBurstSlcResampled[i])
        create_xml(slaveBurstSlcResampled[i], width, length, 'slc')
        os.chdir('../')

        #dump burst interferogram
        mburst = np.fromfile(os.path.join(masterBurstDir, masterBurstSlc[i]),
                             dtype=np.complex64).reshape(length, width)
        os.chdir(interferogramDir)
        (mburst * np.conj(sburstResamp)).astype(np.complex64).tofile(
            interferogram[i])
        create_xml(interferogram[i], width, length, 'int')
        os.chdir('../')
def runFrameMosaic(self):
    '''mosaic frames
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

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

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

    numberOfFrames = len(masterTrack.frames)
    if numberOfFrames == 1:
        import shutil
        frameDir = os.path.join('f1_{}/mosaic'.format(
            self._insar.masterFrames[0]))
        if not os.path.isfile(self._insar.interferogram):
            os.symlink(
                os.path.join('../', frameDir, self._insar.interferogram),
                self._insar.interferogram)
        #shutil.copy2() can overwrite
        shutil.copy2(
            os.path.join('../', frameDir, self._insar.interferogram + '.vrt'),
            self._insar.interferogram + '.vrt')
        shutil.copy2(
            os.path.join('../', frameDir, self._insar.interferogram + '.xml'),
            self._insar.interferogram + '.xml')
        if not os.path.isfile(self._insar.amplitude):
            os.symlink(os.path.join('../', frameDir, self._insar.amplitude),
                       self._insar.amplitude)
        shutil.copy2(
            os.path.join('../', frameDir, self._insar.amplitude + '.vrt'),
            self._insar.amplitude + '.vrt')
        shutil.copy2(
            os.path.join('../', frameDir, self._insar.amplitude + '.xml'),
            self._insar.amplitude + '.xml')

        # os.rename(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram)
        # os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
        # os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
        # os.rename(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude)
        # os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
        # os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')

        #update track parameters
        #########################################################
        #mosaic size
        masterTrack.numberOfSamples = masterTrack.frames[0].numberOfSamples
        masterTrack.numberOfLines = masterTrack.frames[0].numberOfLines
        #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
        #range parameters
        masterTrack.startingRange = masterTrack.frames[0].startingRange
        masterTrack.rangeSamplingRate = masterTrack.frames[0].rangeSamplingRate
        masterTrack.rangePixelSize = masterTrack.frames[0].rangePixelSize
        #azimuth parameters
        masterTrack.sensingStart = masterTrack.frames[0].sensingStart
        masterTrack.prf = masterTrack.frames[0].prf
        masterTrack.azimuthPixelSize = masterTrack.frames[0].azimuthPixelSize
        masterTrack.azimuthLineInterval = masterTrack.frames[
            0].azimuthLineInterval

        #update track parameters, slave
        #########################################################
        #mosaic size
        slaveTrack.numberOfSamples = slaveTrack.frames[0].numberOfSamples
        slaveTrack.numberOfLines = slaveTrack.frames[0].numberOfLines
        #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
        #range parameters
        slaveTrack.startingRange = slaveTrack.frames[0].startingRange
        slaveTrack.rangeSamplingRate = slaveTrack.frames[0].rangeSamplingRate
        slaveTrack.rangePixelSize = slaveTrack.frames[0].rangePixelSize
        #azimuth parameters
        slaveTrack.sensingStart = slaveTrack.frames[0].sensingStart
        slaveTrack.prf = slaveTrack.frames[0].prf
        slaveTrack.azimuthPixelSize = slaveTrack.frames[0].azimuthPixelSize
        slaveTrack.azimuthLineInterval = slaveTrack.frames[
            0].azimuthLineInterval

    else:
        #choose offsets
        if self.frameOffsetMatching:
            rangeOffsets = self._insar.frameRangeOffsetMatchingMaster
            azimuthOffsets = self._insar.frameAzimuthOffsetMatchingMaster
        else:
            rangeOffsets = self._insar.frameRangeOffsetGeometricalMaster
            azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalMaster

        #list of input files
        inputInterferograms = []
        inputAmplitudes = []
        for i, frameNumber in enumerate(self._insar.masterFrames):
            frameDir = 'f{}_{}'.format(i + 1, frameNumber)
            inputInterferograms.append(
                os.path.join('../', frameDir, 'mosaic',
                             self._insar.interferogram))
            inputAmplitudes.append(
                os.path.join('../', frameDir, 'mosaic', self._insar.amplitude))

        #note that track parameters are updated after mosaicking
        #mosaic amplitudes
        frameMosaic(masterTrack,
                    inputAmplitudes,
                    self._insar.amplitude,
                    rangeOffsets,
                    azimuthOffsets,
                    self._insar.numberRangeLooks1,
                    self._insar.numberAzimuthLooks1,
                    updateTrack=False,
                    phaseCompensation=False,
                    resamplingMethod=0)
        #mosaic interferograms
        frameMosaic(masterTrack,
                    inputInterferograms,
                    self._insar.interferogram,
                    rangeOffsets,
                    azimuthOffsets,
                    self._insar.numberRangeLooks1,
                    self._insar.numberAzimuthLooks1,
                    updateTrack=True,
                    phaseCompensation=True,
                    resamplingMethod=1)

        create_xml(self._insar.amplitude, masterTrack.numberOfSamples,
                   masterTrack.numberOfLines, 'amp')
        create_xml(self._insar.interferogram, masterTrack.numberOfSamples,
                   masterTrack.numberOfLines, 'int')

        #update slave parameters here
        #do not match for slave, always use geometrical
        rangeOffsets = self._insar.frameRangeOffsetGeometricalSlave
        azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalSlave
        frameMosaicParameters(slaveTrack, rangeOffsets, azimuthOffsets,
                              self._insar.numberRangeLooks1,
                              self._insar.numberAzimuthLooks1)

    os.chdir('../')
    #save parameter file
    self._insar.saveProduct(masterTrack, self._insar.masterTrackParameter)
    self._insar.saveProduct(slaveTrack, self._insar.slaveTrackParameter)

    #mosaic spectral diversity inteferograms
    mosaicDir = 'sd'
    os.makedirs(mosaicDir, exist_ok=True)
    os.chdir(mosaicDir)

    numberOfFrames = len(masterTrack.frames)
    if numberOfFrames == 1:
        import shutil
        frameDir = os.path.join('f1_{}/mosaic'.format(
            self._insar.masterFrames[0]))
        for sdFile in self._insar.interferogramSd:
            if not os.path.isfile(sdFile):
                os.symlink(os.path.join('../', frameDir, sdFile), sdFile)
            shutil.copy2(os.path.join('../', frameDir, sdFile + '.vrt'),
                         sdFile + '.vrt')
            shutil.copy2(os.path.join('../', frameDir, sdFile + '.xml'),
                         sdFile + '.xml')
    else:
        #choose offsets
        if self.frameOffsetMatching:
            rangeOffsets = self._insar.frameRangeOffsetMatchingMaster
            azimuthOffsets = self._insar.frameAzimuthOffsetMatchingMaster
        else:
            rangeOffsets = self._insar.frameRangeOffsetGeometricalMaster
            azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalMaster

        #list of input files
        inputSd = [[], [], []]
        for i, frameNumber in enumerate(self._insar.masterFrames):
            frameDir = 'f{}_{}'.format(i + 1, frameNumber)
            for k, sdFile in enumerate(self._insar.interferogramSd):
                inputSd[k].append(
                    os.path.join('../', frameDir, 'mosaic', sdFile))

        #mosaic spectral diversity interferograms
        for inputSdList, outputSdFile in zip(inputSd,
                                             self._insar.interferogramSd):
            frameMosaic(masterTrack,
                        inputSdList,
                        outputSdFile,
                        rangeOffsets,
                        azimuthOffsets,
                        self._insar.numberRangeLooks1,
                        self._insar.numberAzimuthLooks1,
                        updateTrack=False,
                        phaseCompensation=True,
                        resamplingMethod=1)

        for sdFile in self._insar.interferogramSd:
            create_xml(sdFile, masterTrack.numberOfSamples,
                       masterTrack.numberOfLines, 'int')

    os.chdir('../')

    catalog.printToLog(logger, "runFrameMosaic")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #20
0
def swathMosaic(frame,
                inputFiles,
                outputfile,
                rangeOffsets,
                azimuthOffsets,
                numberOfRangeLooks,
                numberOfAzimuthLooks,
                updateFrame=False,
                phaseCompensation=False,
                phaseDiff=None,
                phaseDiffFixed=None,
                snapThreshold=None,
                snapSwath=None,
                pcRangeLooks=1,
                pcAzimuthLooks=4,
                filt=False,
                resamplingMethod=0):
    '''
    mosaic swaths
    
    #PART 1. REGULAR INPUT PARAMTERS
    frame:                 frame
    inputFiles:            input file list
    outputfile:            output mosaic file
    rangeOffsets:          range offsets
    azimuthOffsets:        azimuth offsets
    numberOfRangeLooks:    number of range looks of the input files
    numberOfAzimuthLooks:  number of azimuth looks of the input files
    updateFrame:           whether update frame parameters

    #PART 2. PARAMETERS FOR COMPUTING PHASE DIFFERENCE BETWEEN SUBSWATHS
    phaseCompensation:     whether do phase compensation for each swath
    phaseDiff:             pre-computed compensation phase for each swath
    phaseDiffFixed:        if provided, the estimated value will snap to one of these values, which is nearest to the estimated one.
    snapThreshold:         this is used with phaseDiffFixed
    snapSwath:             indicate whether snap to fixed values for each swath phase diff, must be specified if phaseDiffFixed!=None
    pcRangeLooks:          number of range looks to take when compute swath phase difference
    pcAzimuthLooks:        number of azimuth looks to take when compute swath phase difference
    filt:                  whether do filtering when compute swath phase difference

    #PART 3. RESAMPLING METHOD
    resamplingMethod:      0: amp resampling. 1: int resampling.
    '''
    from contrib.alos2proc_f.alos2proc_f import rect_with_looks
    from contrib.alos2proc.alos2proc import mosaicsubswath
    from isceobj.Alos2Proc.Alos2ProcPublic import multilook
    from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence_1
    from isceobj.Alos2Proc.Alos2ProcPublic import filterInterferogram
    from isceobj.Alos2Proc.Alos2ProcPublic import computePhaseDiff
    from isceobj.Alos2Proc.Alos2ProcPublic import snap

    numberOfSwaths = len(frame.swaths)
    swaths = frame.swaths

    rangeScale = []
    azimuthScale = []
    rectWidth = []
    rectLength = []
    for i in range(numberOfSwaths):
        rangeScale.append(swaths[0].rangePixelSize / swaths[i].rangePixelSize)
        azimuthScale.append(swaths[0].azimuthLineInterval /
                            swaths[i].azimuthLineInterval)
        if i == 0:
            rectWidth.append(
                int(swaths[i].numberOfSamples / numberOfRangeLooks))
            rectLength.append(
                int(swaths[i].numberOfLines / numberOfAzimuthLooks))
        else:
            rectWidth.append(
                round(1.0 / rangeScale[i] *
                      int(swaths[i].numberOfSamples / numberOfRangeLooks)))
            rectLength.append(
                round(1.0 / azimuthScale[i] *
                      int(swaths[i].numberOfLines / numberOfAzimuthLooks)))
            #rectWidth.append( int(1.0 / rangeScale[i] * int(swaths[i].numberOfSamples / numberOfRangeLooks)) )
            #rectLength.append( int(1.0 / azimuthScale[i] * int(swaths[i].numberOfLines / numberOfAzimuthLooks)) )

    #convert original offset to offset for images with looks
    #use list instead of np.array to make it consistent with the rest of the code
    rangeOffsets1 = [i / numberOfRangeLooks for i in rangeOffsets]
    azimuthOffsets1 = [i / numberOfAzimuthLooks for i in azimuthOffsets]

    #get offset relative to the first frame
    rangeOffsets2 = [0.0]
    azimuthOffsets2 = [0.0]
    for i in range(1, numberOfSwaths):
        rangeOffsets2.append(0.0)
        azimuthOffsets2.append(0.0)
        for j in range(1, i + 1):
            rangeOffsets2[i] += rangeOffsets1[j]
            azimuthOffsets2[i] += azimuthOffsets1[j]

    #resample each swath
    rinfs = []
    for i, inf in enumerate(inputFiles):
        rinfs.append("{}_{}{}".format(
            os.path.splitext(os.path.basename(inf))[0], i,
            os.path.splitext(os.path.basename(inf))[1]))
        #do not resample first swath
        if i == 0:
            if os.path.isfile(rinfs[i]):
                os.remove(rinfs[i])
            os.symlink(inf, rinfs[i])
        else:
            #no need to resample
            if (abs(rangeOffsets2[i] - round(rangeOffsets2[i])) < 0.0001) and (
                    abs(azimuthOffsets2[i] - round(azimuthOffsets2[i])) <
                    0.0001):
                if os.path.isfile(rinfs[i]):
                    os.remove(rinfs[i])
                os.symlink(inf, rinfs[i])
                #all of the following use of rangeOffsets2/azimuthOffsets2 is inside int(), we do the following in case it is like
                #4.99999999999...
                rangeOffsets2[i] = round(rangeOffsets2[i])
                azimuthOffsets2[i] = round(azimuthOffsets2[i])
            else:
                infImg = isceobj.createImage()
                infImg.load(inf + '.xml')
                rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
                azimuthOffsets2Frac = azimuthOffsets2[i] - int(
                    azimuthOffsets2[i])

                if resamplingMethod == 0:
                    rect_with_looks(inf, rinfs[i], infImg.width, infImg.length,
                                    rectWidth[i], rectLength[i], rangeScale[i],
                                    0.0, 0.0, azimuthScale[i],
                                    rangeOffsets2Frac * rangeScale[i],
                                    azimuthOffsets2Frac * azimuthScale[i], 1,
                                    1, 1, 1, 'COMPLEX', 'Bilinear')
                elif resamplingMethod == 1:
                    #decompose amplitude and phase
                    phaseFile = 'phase'
                    amplitudeFile = 'amplitude'
                    data = np.fromfile(inf, dtype=np.complex64).reshape(
                        infImg.length, infImg.width)
                    phase = np.exp(np.complex64(1j) * np.angle(data))
                    phase[np.nonzero(data == 0)] = 0
                    phase.astype(np.complex64).tofile(phaseFile)
                    amplitude = np.absolute(data)
                    amplitude.astype(np.float32).tofile(amplitudeFile)

                    #resampling
                    phaseRectFile = 'phaseRect'
                    amplitudeRectFile = 'amplitudeRect'
                    rect_with_looks(phaseFile, phaseRectFile, infImg.width,
                                    infImg.length, rectWidth[i], rectLength[i],
                                    rangeScale[i], 0.0, 0.0, azimuthScale[i],
                                    rangeOffsets2Frac * rangeScale[i],
                                    azimuthOffsets2Frac * azimuthScale[i], 1,
                                    1, 1, 1, 'COMPLEX', 'Sinc')
                    rect_with_looks(amplitudeFile, amplitudeRectFile,
                                    infImg.width, infImg.length, rectWidth[i],
                                    rectLength[i], rangeScale[i], 0.0, 0.0,
                                    azimuthScale[i],
                                    rangeOffsets2Frac * rangeScale[i],
                                    azimuthOffsets2Frac * azimuthScale[i], 1,
                                    1, 1, 1, 'REAL', 'Bilinear')

                    #recombine amplitude and phase
                    phase = np.fromfile(phaseRectFile,
                                        dtype=np.complex64).reshape(
                                            rectLength[i], rectWidth[i])
                    amplitude = np.fromfile(amplitudeRectFile,
                                            dtype=np.float32).reshape(
                                                rectLength[i], rectWidth[i])
                    (phase * amplitude).astype(np.complex64).tofile(rinfs[i])

                    #tidy up
                    os.remove(phaseFile)
                    os.remove(amplitudeFile)
                    os.remove(phaseRectFile)
                    os.remove(amplitudeRectFile)

    #determine output width and length
    #actually no need to calculate in range direction
    xs = []
    xe = []
    ys = []
    ye = []
    for i in range(numberOfSwaths):
        if i == 0:
            xs.append(0)
            xe.append(rectWidth[i] - 1)
            ys.append(0)
            ye.append(rectLength[i] - 1)
        else:
            xs.append(0 - int(rangeOffsets2[i]))
            xe.append(rectWidth[i] - 1 - int(rangeOffsets2[i]))
            ys.append(0 - int(azimuthOffsets2[i]))
            ye.append(rectLength[i] - 1 - int(azimuthOffsets2[i]))

    (xmin, xminIndex) = min((v, i) for i, v in enumerate(xs))
    (xmax, xmaxIndex) = max((v, i) for i, v in enumerate(xe))
    (ymin, yminIndex) = min((v, i) for i, v in enumerate(ys))
    (ymax, ymaxIndex) = max((v, i) for i, v in enumerate(ye))

    outWidth = xmax - xmin + 1
    outLength = ymax - ymin + 1

    #prepare offset for mosaicing
    rangeOffsets3 = []
    azimuthOffsets3 = []
    for i in range(numberOfSwaths):
        azimuthOffsets3.append(
            int(azimuthOffsets2[i]) - int(azimuthOffsets2[yminIndex]))
        if i != 0:
            rangeOffsets3.append(
                int(rangeOffsets2[i]) - int(rangeOffsets2[i - 1]))
        else:
            rangeOffsets3.append(0)

    delta = int(30 / numberOfRangeLooks)

    #compute compensation phase for each swath
    diffMean2 = [0.0 for i in range(numberOfSwaths)]
    phaseDiffEst = [None for i in range(numberOfSwaths)]
    #True if:
    #  (1) used diff phase from input
    #  (2) used estimated diff phase after snapping to a fixed diff phase provided
    #False if:
    #  (1) used purely estimated diff phase
    phaseDiffSource = ['estimated' for i in range(numberOfSwaths)]
    # 1. 'estimated': estimated from subswath overlap
    # 2. 'estimated+snap': estimated from subswath overlap and snap to a fixed value
    # 3. 'input': pre-computed
    # confidence level: 3 > 2 > 1
    numberOfValidSamples = [None for i in range(numberOfSwaths)]
    # only record when (filt == False) and (index[0].size >= 4000)
    if phaseCompensation:
        #compute swath phase offset
        diffMean = [0.0]
        for i in range(1, numberOfSwaths):

            #no need to estimate diff phase if provided from input
            #####################################################################
            if phaseDiff != None:
                if phaseDiff[i] != None:
                    diffMean.append(phaseDiff[i])
                    phaseDiffSource[i] = 'input'
                    print('using pre-computed phase offset given from input')
                    print('phase offset: subswath{} - subswath{}: {}'.format(
                        frame.swaths[i - 1].swathNumber,
                        frame.swaths[i].swathNumber, phaseDiff[i]))
                    continue
            #####################################################################

            #all indexes start with zero, all the computed start/end sample/line indexes are included.

            #no need to add edge here, as we are going to find first/last nonzero sample/lines later
            #edge = delta
            edge = 0

            #image i-1
            startSample1 = edge + 0 - int(rangeOffsets2[i]) + int(
                rangeOffsets2[i - 1])
            endSample1 = -edge + rectWidth[i - 1] - 1
            startLine1 = edge + max(
                0 - int(azimuthOffsets2[i]) + int(azimuthOffsets2[i - 1]), 0)
            endLine1 = -edge + min(
                rectLength[i] - 1 - int(azimuthOffsets2[i]) +
                int(azimuthOffsets2[i - 1]), rectLength[i - 1] - 1)
            data1 = readImage(rinfs[i - 1], rectWidth[i - 1],
                              rectLength[i - 1], startSample1, endSample1,
                              startLine1, endLine1)

            #image i
            startSample2 = edge + 0
            endSample2 = -edge + rectWidth[i - 1] - 1 - int(
                rangeOffsets2[i - 1]) + int(rangeOffsets2[i])
            startLine2 = edge + max(
                0 - int(azimuthOffsets2[i - 1]) + int(azimuthOffsets2[i]), 0)
            endLine2 = -edge + min(
                rectLength[i - 1] - 1 - int(azimuthOffsets2[i - 1]) +
                int(azimuthOffsets2[i]), rectLength[i] - 1)
            data2 = readImage(rinfs[i], rectWidth[i], rectLength[i],
                              startSample2, endSample2, startLine2, endLine2)

            #remove edge due to incomplete covolution in resampling
            edge = 9
            (startLine0, endLine0, startSample0, endSample0) = findNonzero(
                np.logical_and((data1 != 0), (data2 != 0)))
            data1 = data1[startLine0 + edge:endLine0 + 1 - edge,
                          startSample0 + edge:endSample0 + 1 - edge]
            data2 = data2[startLine0 + edge:endLine0 + 1 - edge,
                          startSample0 + edge:endSample0 + 1 - edge]

            #take looks
            data1 = multilook(data1, pcAzimuthLooks, pcRangeLooks)
            data2 = multilook(data2, pcAzimuthLooks, pcRangeLooks)

            #filter
            if filt:
                data1 /= (np.absolute(data1) + (data1 == 0))
                data2 /= (np.absolute(data2) + (data2 == 0))
                data1 = filterInterferogram(data1, 3.0, 64, 1)
                data2 = filterInterferogram(data2, 3.0, 64, 1)

            #get difference
            dataDiff = data1 * np.conj(data2)
            cor = cal_coherence_1(dataDiff, win=5)
            index = np.nonzero(np.logical_and(cor > 0.85, dataDiff != 0))

            DEBUG = False
            if DEBUG:
                from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
                (length7, width7) = dataDiff.shape
                filename = 'diff_ori_s{}-s{}.int'.format(
                    frame.swaths[i - 1].swathNumber,
                    frame.swaths[i].swathNumber)
                dataDiff.astype(np.complex64).tofile(filename)
                create_xml(filename, width7, length7, 'int')
                filename = 'cor_ori_s{}-s{}.cor'.format(
                    frame.swaths[i - 1].swathNumber,
                    frame.swaths[i].swathNumber)
                cor.astype(np.float32).tofile(filename)
                create_xml(filename, width7, length7, 'float')

            print('\ncompute phase difference between subswaths {} and {}'.
                  format(frame.swaths[i - 1].swathNumber,
                         frame.swaths[i].swathNumber))
            print('number of pixels with coherence > 0.85: {}'.format(
                index[0].size))

            #if already filtered the subswath overlap interferograms (MAI), do not filtered differential interferograms
            if (filt == False) and (index[0].size < 4000):
                #coherence too low, filter subswath overlap differential interferogram
                diffMean0 = 0.0
                breakFlag = False
                for (filterStrength, filterWinSize) in zip([3.0, 9.0],
                                                           [64, 128]):
                    dataDiff = data1 * np.conj(data2)
                    dataDiff /= (np.absolute(dataDiff) + (dataDiff == 0))
                    dataDiff = filterInterferogram(dataDiff, filterStrength,
                                                   filterWinSize, 1)
                    cor = cal_coherence_1(dataDiff, win=7)

                    DEBUG = False
                    if DEBUG:
                        from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
                        (length7, width7) = dataDiff.shape
                        filename = 'diff_filt_s{}-s{}_strength_{}_winsize_{}.int'.format(
                            frame.swaths[i - 1].swathNumber,
                            frame.swaths[i].swathNumber, filterStrength,
                            filterWinSize)
                        dataDiff.astype(np.complex64).tofile(filename)
                        create_xml(filename, width7, length7, 'int')
                        filename = 'cor_filt_s{}-s{}_strength_{}_winsize_{}.cor'.format(
                            frame.swaths[i - 1].swathNumber,
                            frame.swaths[i].swathNumber, filterStrength,
                            filterWinSize)
                        cor.astype(np.float32).tofile(filename)
                        create_xml(filename, width7, length7, 'float')

                    for corth in [0.99999, 0.9999]:
                        index = np.nonzero(
                            np.logical_and(cor > corth, dataDiff != 0))
                        if index[0].size > 30000:
                            breakFlag = True
                            break
                    if breakFlag:
                        break

                if index[0].size < 100:
                    diffMean0 = 0.0
                    print(
                        '\n\nWARNING: too few high coherence pixels for swath phase difference estimation'
                    )
                    print('         number of high coherence pixels: {}\n\n'.
                          format(index[0].size))
                else:
                    print(
                        'filtered coherence threshold used: {}, number of pixels used: {}'
                        .format(corth, index[0].size))
                    angle = np.mean(np.angle(dataDiff[index]),
                                    dtype=np.float64)
                    diffMean0 += angle
                    data2 *= np.exp(np.complex64(1j) * angle)
                    print(
                        'phase offset: %15.12f rad with filter strength: %f, window size: %3d'
                        % (diffMean0, filterStrength, filterWinSize))
            else:
                if filt:
                    (diffMean0, numberOfValidSamples[i]) = computePhaseDiff(
                        data1,
                        data2,
                        coherenceWindowSize=5,
                        coherenceThreshold=0.95)
                else:
                    (diffMean0, numberOfValidSamples[i]) = computePhaseDiff(
                        data1,
                        data2,
                        coherenceWindowSize=5,
                        coherenceThreshold=0.85)
                if numberOfValidSamples[i] < 100:
                    diffMean0 = 0.0
                    print(
                        '\n\nWARNING: too few high coherence pixels for swath phase difference estimation'
                    )
                    print('         number of high coherence pixels: {}\n\n'.
                          format(numberOfValidSamples[i]))

                #do not record when filt
                if filt:
                    numberOfValidSamples[i] = None

            #save purely estimated diff phase
            phaseDiffEst[i] = diffMean0

            #if fixed diff phase provided and the estimated diff phase is close enough to a fixed value, snap to it
            if phaseDiffFixed != None:
                if snapSwath[i - 1] == True:
                    (outputValue, snapped) = snap(diffMean0, phaseDiffFixed,
                                                  snapThreshold)
                    if snapped == True:
                        diffMean0 = outputValue
                        phaseDiffSource[i] = 'estimated+snap'

            diffMean.append(diffMean0)
            print('phase offset: subswath{} - subswath{}: {}'.format(
                frame.swaths[i - 1].swathNumber, frame.swaths[i].swathNumber,
                diffMean0))

        for i in range(1, numberOfSwaths):
            for j in range(1, i + 1):
                diffMean2[i] += diffMean[j]

    #mosaic swaths
    diffflag = 1
    oflag = [0 for i in range(numberOfSwaths)]
    mosaicsubswath(outputfile, outWidth, outLength, delta, diffflag,
                   numberOfSwaths, rinfs, rectWidth, rangeOffsets3,
                   azimuthOffsets3, diffMean2, oflag)
    #remove tmp files
    for x in rinfs:
        os.remove(x)

    #update frame parameters
    if updateFrame:
        #mosaic size
        frame.numberOfSamples = outWidth
        frame.numberOfLines = outLength
        #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
        #range parameters
        frame.startingRange = frame.swaths[0].startingRange
        frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate
        frame.rangePixelSize = frame.swaths[0].rangePixelSize
        #azimuth parameters
        azimuthTimeOffset = -max([
            int(x) for x in azimuthOffsets2
        ]) * numberOfAzimuthLooks * frame.swaths[0].azimuthLineInterval
        frame.sensingStart = frame.swaths[0].sensingStart + datetime.timedelta(
            seconds=azimuthTimeOffset)
        frame.prf = frame.swaths[0].prf
        frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize
        frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval

    if phaseCompensation:
        # estimated phase diff, used phase diff, used phase diff source
        return (phaseDiffEst, diffMean, phaseDiffSource, numberOfValidSamples)
Beispiel #21
0
def estimateSwathOffset(swath1,
                        swath2,
                        image1,
                        image2,
                        rangeScale1=1,
                        azimuthScale1=1,
                        rangeScale2=1,
                        azimuthScale2=1,
                        numberOfAzimuthLooks=10):
    '''
    estimate offset of two adjacent swaths using matching
    '''
    from osgeo import gdal
    import isceobj
    from contrib.alos2proc_f.alos2proc_f import rect_with_looks
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
    from isceobj.Alos2Proc.Alos2ProcPublic import cullOffsets
    from isceobj.Alos2Proc.Alos2ProcPublic import meanOffset
    from mroipac.ampcor.Ampcor import Ampcor

    #processing image 1
    rangeOff1 = int(
        (swath2.startingRange - swath1.startingRange) / swath1.rangePixelSize)
    if rangeOff1 < 0:
        rangeOff1 = 0
    numberOfSamples1 = swath1.numberOfSamples - rangeOff1

    numberOfSamplesRect1 = int(numberOfSamples1 / rangeScale1)
    numberOfLinesRect1 = int(swath1.numberOfLines / azimuthScale1)

    numberOfSamplesLook1 = int(numberOfSamplesRect1 / 1)
    numberOfLinesLook1 = int(numberOfLinesRect1 / numberOfAzimuthLooks)

    #get magnitude image whether complex or not
    #ReadAsArray: https://pcjericks.github.io/py-gdalogr-cookbook/raster_layers.html
    ds = gdal.Open(image1 + '.vrt', gdal.GA_ReadOnly)
    data = ds.ReadAsArray(rangeOff1, 0, numberOfSamples1, swath1.numberOfLines)
    ds = None
    (np.absolute(data)).astype(np.float32).tofile('image1.float')

    #rectify
    if rangeScale1 == 1 and azimuthScale1 == 1:
        os.rename('image1.float', 'image1_rect.float')
    else:
        rect_with_looks('image1.float', 'image1_rect.float', numberOfSamples1,
                        swath1.numberOfLines, numberOfSamplesRect1,
                        numberOfLinesRect1, rangeScale1, 0.0, 0.0,
                        azimuthScale1, 0.0, 0.0, 1, 1, 1, 1, 'REAL',
                        'Bilinear')
        os.remove('image1.float')

    #take looks
    if numberOfAzimuthLooks == 1:
        os.rename('image1_rect.float', 'image1_look.float')
    else:
        data1 = np.fromfile('image1_rect.float',
                            dtype=np.float32).reshape(numberOfLinesRect1,
                                                      numberOfSamplesRect1)
        data1 = np.sqrt(multilook(data1**2, numberOfAzimuthLooks, 1))
        data1.astype(np.float32).tofile('image1_look.float')
        os.remove('image1_rect.float')
    create_xml('image1_look.float', numberOfSamplesLook1, numberOfLinesLook1,
               'float')

    #processing image 2
    rangeOff2 = 0
    numberOfSamples2 = int(
        (swath1.startingRange + swath1.rangePixelSize *
         (swath1.numberOfSamples - 1) - swath2.startingRange) /
        swath2.rangePixelSize) + 1
    if numberOfSamples2 > swath2.numberOfSamples:
        numberOfSamples2 = swath2.numberOfSamples

    numberOfSamplesRect2 = int(numberOfSamples2 / rangeScale2)
    numberOfLinesRect2 = int(swath2.numberOfLines / azimuthScale2)

    numberOfSamplesLook2 = int(numberOfSamplesRect2 / 1)
    numberOfLinesLook2 = int(numberOfLinesRect2 / numberOfAzimuthLooks)

    #get magnitude image whether complex or not
    ds = gdal.Open(image2 + '.vrt', gdal.GA_ReadOnly)
    data = ds.ReadAsArray(rangeOff2, 0, numberOfSamples2, swath2.numberOfLines)
    ds = None
    (np.absolute(data)).astype(np.float32).tofile('image2.float')

    #rectify
    if rangeScale2 == 1 and azimuthScale2 == 1:
        os.rename('image2.float', 'image2_rect.float')
    else:
        rect_with_looks('image2.float', 'image2_rect.float', numberOfSamples2,
                        swath2.numberOfLines, numberOfSamplesRect2,
                        numberOfLinesRect2, rangeScale2, 0.0, 0.0,
                        azimuthScale2, 0.0, 0.0, 1, 1, 1, 1, 'REAL',
                        'Bilinear')
        os.remove('image2.float')

    #take looks
    if numberOfAzimuthLooks == 1:
        os.rename('image2_rect.float', 'image2_look.float')
    else:
        data2 = np.fromfile('image2_rect.float',
                            dtype=np.float32).reshape(numberOfLinesRect2,
                                                      numberOfSamplesRect2)
        data2 = np.sqrt(multilook(data2**2, numberOfAzimuthLooks, 1))
        data2.astype(np.float32).tofile('image2_look.float')
        os.remove('image2_rect.float')
    create_xml('image2_look.float', numberOfSamplesLook2, numberOfLinesLook2,
               'float')

    #matching
    ampcor = Ampcor(name='insarapp_slcs_ampcor')
    ampcor.configure()

    mMag = isceobj.createImage()
    mMag.load('image1_look.float.xml')
    mMag.setAccessMode('read')
    mMag.createImage()

    sMag = isceobj.createImage()
    sMag.load('image2_look.float.xml')
    sMag.setAccessMode('read')
    sMag.createImage()

    ampcor.setImageDataType1('real')
    ampcor.setImageDataType2('real')

    ampcor.setReferenceSlcImage(mMag)
    ampcor.setSecondarySlcImage(sMag)

    #MATCH REGION
    rgoff = 0
    azoff = int(
        (swath1.sensingStart - swath2.sensingStart).total_seconds() /
        swath1.azimuthLineInterval / azimuthScale1 / numberOfAzimuthLooks)
    #it seems that we cannot use 0, haven't look into the problem
    if rgoff == 0:
        rgoff = 1
    if azoff == 0:
        azoff = 1
    firstSample = 1
    if rgoff < 0:
        firstSample = int(35 - rgoff)
    firstLine = 1
    if azoff < 0:
        firstLine = int(35 - azoff)
    ampcor.setAcrossGrossOffset(rgoff)
    ampcor.setDownGrossOffset(azoff)
    ampcor.setFirstSampleAcross(firstSample)
    ampcor.setLastSampleAcross(numberOfSamplesLook1)
    ampcor.setNumberLocationAcross(20)
    ampcor.setFirstSampleDown(firstLine)
    ampcor.setLastSampleDown(numberOfLinesLook1)
    ampcor.setNumberLocationDown(100)

    #MATCH PARAMETERS
    ampcor.setWindowSizeWidth(32)
    ampcor.setWindowSizeHeight(32)
    #note this is the half width/length of search area, so number of resulting correlation samples: 8*2+1
    ampcor.setSearchWindowSizeWidth(8)
    ampcor.setSearchWindowSizeHeight(8)

    #REST OF THE STUFF
    ampcor.setAcrossLooks(1)
    ampcor.setDownLooks(1)
    ampcor.setOversamplingFactor(64)
    ampcor.setZoomWindowSize(16)
    #1. The following not set
    #Matching Scale for Sample/Line Directions                       (-)    = 1. 1.
    #should add the following in Ampcor.py?
    #if not set, in this case, Ampcor.py'value is also 1. 1.
    #ampcor.setScaleFactorX(1.)
    #ampcor.setScaleFactorY(1.)

    #MATCH THRESHOLDS AND DEBUG DATA
    #2. The following not set
    #in roi_pac the value is set to 0 1
    #in isce the value is set to 0.001 1000.0
    #SNR and Covariance Thresholds                                   (-)    =  {s1} {s2}
    #should add the following in Ampcor?
    #THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC
    #ampcor.setThresholdSNR(0)
    #ampcor.setThresholdCov(1)
    ampcor.setDebugFlag(False)
    ampcor.setDisplayFlag(False)

    #in summary, only two things not set which are indicated by 'The following not set' above.

    #run ampcor
    ampcor.ampcor()
    offsets = ampcor.getOffsetField()
    refinedOffsets = cullOffsets(offsets)

    #finalize image, and re-create it
    #otherwise the file pointer is still at the end of the image
    mMag.finalizeImage()
    sMag.finalizeImage()

    os.remove('image1_look.float')
    os.remove('image1_look.float.vrt')
    os.remove('image1_look.float.xml')
    os.remove('image2_look.float')
    os.remove('image2_look.float.vrt')
    os.remove('image2_look.float.xml')

    if refinedOffsets != None:
        rangeOffset, azimuthOffset = meanOffset(refinedOffsets)
        rangeOffset -= rangeOff1 / rangeScale1
        azimuthOffset *= numberOfAzimuthLooks
        return (rangeOffset, azimuthOffset)
    else:
        return None
Beispiel #22
0
def ionFilt(self, referenceTrack, catalog=None):

    from isceobj.Alos2Proc.runIonSubband import defineIonDir
    ionDir = defineIonDir()
    subbandPrefix = ['lower', 'upper']

    ionCalDir = os.path.join(ionDir['ion'], ionDir['ionCal'])
    os.makedirs(ionCalDir, exist_ok=True)
    os.chdir(ionCalDir)

    log = ''

    ############################################################
    # STEP 1. compute ionospheric phase
    ############################################################
    from isceobj.Constants import SPEED_OF_LIGHT
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml

    ###################################
    #SET PARAMETERS HERE
    #THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self)
    corThresholdAdj = 0.97
    corOrderAdj = 20
    ###################################

    print('\ncomputing ionosphere')
    #get files
    ml2 = '_{}rlks_{}alks'.format(
        self._insar.numberRangeLooks1 * self._insar.numberRangeLooksIon,
        self._insar.numberAzimuthLooks1 * self._insar.numberAzimuthLooksIon)

    lowerUnwfile = subbandPrefix[0] + ml2 + '.unw'
    upperUnwfile = subbandPrefix[1] + ml2 + '.unw'
    corfile = 'diff' + ml2 + '.cor'

    #use image size from lower unwrapped interferogram
    img = isceobj.createImage()
    img.load(lowerUnwfile + '.xml')
    width = img.width
    length = img.length

    lowerUnw = (np.fromfile(lowerUnwfile, dtype=np.float32).reshape(
        length * 2, width))[1:length * 2:2, :]
    upperUnw = (np.fromfile(upperUnwfile, dtype=np.float32).reshape(
        length * 2, width))[1:length * 2:2, :]
    cor = (np.fromfile(corfile,
                       dtype=np.float32).reshape(length * 2,
                                                 width))[1:length * 2:2, :]
    #amp = (np.fromfile(corfile, dtype=np.float32).reshape(length*2, width))[0:length*2:2, :]

    #masked out user-specified areas
    if self.maskedAreasIon != None:
        maskedAreas = reformatMaskedAreas(self.maskedAreasIon, length, width)
        for area in maskedAreas:
            lowerUnw[area[0]:area[1], area[2]:area[3]] = 0
            upperUnw[area[0]:area[1], area[2]:area[3]] = 0
            cor[area[0]:area[1], area[2]:area[3]] = 0

    #remove possible wired values in coherence
    cor[np.nonzero(cor < 0)] = 0.0
    cor[np.nonzero(cor > 1)] = 0.0

    #remove water body
    wbd = np.fromfile('wbd' + ml2 + '.wbd',
                      dtype=np.int8).reshape(length, width)
    cor[np.nonzero(wbd == -1)] = 0.0

    #remove small values
    cor[np.nonzero(cor < corThresholdAdj)] = 0.0

    #compute ionosphere
    fl = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[0]
    fu = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[1]
    adjFlag = 1
    ionos = computeIonosphere(lowerUnw, upperUnw, cor**corOrderAdj, fl, fu,
                              adjFlag, 0)

    #dump ionosphere
    ionfile = 'ion' + ml2 + '.ion'
    # ion = np.zeros((length*2, width), dtype=np.float32)
    # ion[0:length*2:2, :] = amp
    # ion[1:length*2:2, :] = ionos
    # ion.astype(np.float32).tofile(ionfile)
    # img.filename = ionfile
    # img.extraFilename = ionfile + '.vrt'
    # img.renderHdr()

    ionos.astype(np.float32).tofile(ionfile)
    create_xml(ionfile, width, length, 'float')

    ############################################################
    # STEP 2. filter ionospheric phase
    ############################################################
    import scipy.signal as ss

    #################################################
    #SET PARAMETERS HERE
    #fit and filter ionosphere
    fit = self.fitIon
    filt = self.filtIon
    fitAdaptive = self.fitAdaptiveIon
    filtSecondary = self.filtSecondaryIon
    if (fit == False) and (filt == False):
        raise Exception(
            'either fit ionosphere or filt ionosphere should be True when doing ionospheric correction\n'
        )

    #filtering window size
    size_max = self.filteringWinsizeMaxIon
    size_min = self.filteringWinsizeMinIon
    size_secondary = self.filteringWinsizeSecondaryIon
    if size_min > size_max:
        print(
            '\n\nWARNING: minimum window size for filtering ionosphere phase {} > maximum window size {}'
            .format(size_min, size_max))
        print('         re-setting maximum window size to {}\n\n'.format(
            size_min))
        size_max = size_min
    if size_secondary % 2 != 1:
        size_secondary += 1
        print(
            'window size of secondary filtering of ionosphere phase should be odd, window size changed to {}'
            .format(size_secondary))

    #coherence threshold for fitting a polynomial
    corThresholdFit = 0.25

    #ionospheric phase standard deviation after filtering
    std_out0 = self.filterStdIon
    #std_out0 = 0.1
    #################################################

    print('\nfiltering ionosphere')

    #input files
    ionfile = 'ion' + ml2 + '.ion'
    #corfile = 'diff'+ml2+'.cor'
    corLowerfile = subbandPrefix[0] + ml2 + '.cor'
    corUpperfile = subbandPrefix[1] + ml2 + '.cor'
    #output files
    ionfiltfile = 'filt_ion' + ml2 + '.ion'
    stdfiltfile = 'filt_ion' + ml2 + '.std'
    windowsizefiltfile = 'filt_ion' + ml2 + '.win'

    #read data
    img = isceobj.createImage()
    img.load(ionfile + '.xml')
    width = img.width
    length = img.length

    ion = np.fromfile(ionfile, dtype=np.float32).reshape(length, width)
    corLower = (np.fromfile(corLowerfile, dtype=np.float32).reshape(
        length * 2, width))[1:length * 2:2, :]
    corUpper = (np.fromfile(corUpperfile, dtype=np.float32).reshape(
        length * 2, width))[1:length * 2:2, :]
    cor = (corLower + corUpper) / 2.0
    index = np.nonzero(np.logical_or(corLower == 0, corUpper == 0))
    cor[index] = 0
    del corLower, corUpper

    #masked out user-specified areas
    if self.maskedAreasIon != None:
        maskedAreas = reformatMaskedAreas(self.maskedAreasIon, length, width)
        for area in maskedAreas:
            ion[area[0]:area[1], area[2]:area[3]] = 0
            cor[area[0]:area[1], area[2]:area[3]] = 0

    #remove possible wired values in coherence
    cor[np.nonzero(cor < 0)] = 0.0
    cor[np.nonzero(cor > 1)] = 0.0

    #remove water body. Not helpful, just leave it here
    wbd = np.fromfile('wbd' + ml2 + '.wbd',
                      dtype=np.int8).reshape(length, width)
    cor[np.nonzero(wbd == -1)] = 0.0

    # #applying water body mask here
    # waterBodyFile = 'wbd'+ml2+'.wbd'
    # if os.path.isfile(waterBodyFile):
    #     print('applying water body mask to coherence used to compute ionospheric phase')
    #     wbd = np.fromfile(waterBodyFile, dtype=np.int8).reshape(length, width)
    #     cor[np.nonzero(wbd!=0)] = 0.00001

    #minimize the effect of low coherence pixels
    #cor[np.nonzero( (cor<0.85)*(cor!=0) )] = 0.00001
    #filt = adaptive_gaussian(ion, cor, size_max, size_min)
    #cor**14 should be a good weight to use. 22-APR-2018
    #filt = adaptive_gaussian_v0(ion, cor**corOrderFilt, size_max, size_min)

    #1. compute number of looks
    azimuthBandwidth = 0
    for i, frameNumber in enumerate(self._insar.referenceFrames):
        for j, swathNumber in enumerate(
                range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            #azimuthBandwidth += 2270.575 * 0.85
            azimuthBandwidth += referenceTrack.frames[i].swaths[
                j].azimuthBandwidth
    azimuthBandwidth = azimuthBandwidth / (
        len(self._insar.referenceFrames) *
        (self._insar.endingSwath - self._insar.startingSwath + 1))

    #azimuth number of looks should also apply to burst mode
    #assume range bandwidth of subband image is 1/3 of orginal range bandwidth, as in runIonSubband.py!!!
    numberOfLooks = referenceTrack.azimuthLineInterval * self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon / (1.0/azimuthBandwidth) *\
                    referenceTrack.frames[0].swaths[0].rangeBandwidth / 3.0 / referenceTrack.rangeSamplingRate * self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon

    #consider also burst characteristics. In ScanSAR-stripmap interferometry, azimuthBandwidth is from referenceTrack (ScanSAR)
    if self._insar.modeCombination in [21, 31]:
        numberOfLooks /= 5.0
    if self._insar.modeCombination in [22, 32]:
        numberOfLooks /= 7.0
    if self._insar.modeCombination in [21]:
        numberOfLooks *= (self._insar.burstSynchronization / 100.0)

    #numberOfLooks checked
    print(
        'number of looks to be used for computing subband interferogram standard deviation: {}'
        .format(numberOfLooks))
    if catalog is not None:
        catalog.addItem('number of looks of subband interferograms',
                        numberOfLooks, 'runIonFilt')
    log += 'number of looks of subband interferograms: {}\n'.format(
        numberOfLooks)

    #2. compute standard deviation of the raw ionospheric phase
    #f0 same as in runIonSubband.py!!!
    def ion_std(fl, fu, numberOfLooks, cor):
        '''
        compute standard deviation of ionospheric phase
        fl:  lower band center frequency
        fu:  upper band center frequency
        cor: coherence, must be numpy array
        '''
        f0 = (fl + fu) / 2.0
        interferogramVar = (1.0 - cor**2) / (2.0 * numberOfLooks * cor**2 +
                                             (cor == 0))
        std = fl * fu / f0 / (fu**2 -
                              fl**2) * np.sqrt(fu**2 * interferogramVar +
                                               fl**2 * interferogramVar)
        std[np.nonzero(cor == 0)] = 0
        return std

    std = ion_std(fl, fu, numberOfLooks, cor)

    #3. compute minimum filter window size for given coherence and standard deviation of filtered ionospheric phase
    cor2 = np.linspace(0.1, 0.9, num=9, endpoint=True)
    std2 = ion_std(fl, fu, numberOfLooks, cor2)
    std_out2 = np.zeros(cor2.size)
    win2 = np.zeros(cor2.size, dtype=np.int32)
    for i in range(cor2.size):
        for size in range(9, 10001, 2):
            #this window must be the same as those used in adaptive_gaussian!!!
            gw = gaussian(size, size / 2.0, scale=1.0)
            scale = 1.0 / np.sum(gw / std2[i]**2)
            std_out2[i] = scale * np.sqrt(np.sum(gw**2 / std2[i]**2))
            win2[i] = size
            if std_out2[i] <= std_out0:
                break
    print(
        'if ionospheric phase standard deviation <= {} rad, minimum filtering window size required:'
        .format(std_out0))
    print('coherence   window size')
    print('************************')
    for x, y in zip(cor2, win2):
        print('  %5.2f       %5d' % (x, y))
    print()
    if catalog is not None:
        catalog.addItem('coherence value', cor2, 'runIonFilt')
        catalog.addItem('minimum filter window size', win2, 'runIonFilt')
    log += 'coherence value: {}\n'.format(cor2)
    log += 'minimum filter window size: {}\n'.format(win2)

    #4. filter interferogram
    #fit ionosphere
    if fit:
        #prepare weight
        wgt = std**2
        wgt[np.nonzero(cor < corThresholdFit)] = 0
        index = np.nonzero(wgt != 0)
        wgt[index] = 1.0 / (wgt[index])
        #fit
        ion_fit, coeff = polyfit_2d(ion, wgt, 2)
        ion -= ion_fit * (ion != 0)
    #filter the rest of the ionosphere
    if filt:
        (ion_filt, std_out,
         window_size_out) = adaptive_gaussian(ion,
                                              std,
                                              size_min,
                                              size_max,
                                              std_out0,
                                              fit=fitAdaptive)
        if filtSecondary:
            g2d = gaussian(size_secondary, size_secondary / 2.0, scale=1.0)
            scale = ss.fftconvolve((ion_filt != 0), g2d, mode='same')
            ion_filt = (ion_filt != 0) * ss.fftconvolve(
                ion_filt, g2d, mode='same') / (scale + (scale == 0))

    if catalog is not None:
        catalog.addItem('standard deviation of filtered ionospheric phase',
                        std_out0, 'runIonFilt')
    log += 'standard deviation of filtered ionospheric phase: {}\n'.format(
        std_out0)

    #get final results
    if (fit == True) and (filt == True):
        ion_final = ion_filt + ion_fit * (ion_filt != 0)
    elif (fit == True) and (filt == False):
        ion_final = ion_fit
    elif (fit == False) and (filt == True):
        ion_final = ion_filt
    else:
        ion_final = ion

    #output results
    ion_final.astype(np.float32).tofile(ionfiltfile)
    create_xml(ionfiltfile, width, length, 'float')
    if filt == True:
        std_out.astype(np.float32).tofile(stdfiltfile)
        create_xml(stdfiltfile, width, length, 'float')
        window_size_out.astype(np.float32).tofile(windowsizefiltfile)
        create_xml(windowsizefiltfile, width, length, 'float')

    os.chdir('../../')

    return log
Beispiel #23
0
def spectralDiversity(referenceSwath,
                      interferogramDir,
                      interferogramPrefix,
                      outputList,
                      numberLooksScanSAR=None,
                      numberRangeLooks=20,
                      numberAzimuthLooks=10,
                      coherenceThreshold=0.85,
                      keep=False,
                      filt=False,
                      filtWinSizeRange=5,
                      filtWinSizeAzimuth=5):
    '''
    numberLooksScanSAR: number of looks of the ScanSAR system
    numberRangeLooks:   number of range looks to take
    numberAzimuthLooks: number of azimuth looks to take
    keep:               whether keep intermediate files
    '''
    import os
    import numpy as np
    from isceobj.Alos2Proc.Alos2ProcPublic import create_multi_index
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
    from isceobj.Alos2Proc.Alos2ProcPublic import multilook
    from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence_1

    width = referenceSwath.numberOfSamples
    length = referenceSwath.numberOfLines
    lengthBurst = referenceSwath.burstSlcNumberOfLines
    nBurst = referenceSwath.numberOfBursts
    azsi = referenceSwath.azimuthLineInterval
    tc = referenceSwath.burstCycleLength / referenceSwath.prf

    bursts = [
        os.path.join(interferogramDir,
                     interferogramPrefix + '_%02d.int' % (i + 1))
        for i in range(referenceSwath.numberOfBursts)
    ]

    ####################################################
    #input parameters
    rgl = numberRangeLooks
    azl = numberAzimuthLooks
    cor_th = coherenceThreshold
    nls0 = lengthBurst / (referenceSwath.burstSlcFirstLineOffsets[nBurst - 1] /
                          (nBurst - 1.0))
    print('number of looks of the ScanSAR system: {}'.format(nls0))
    if numberLooksScanSAR != None:
        nls = numberLooksScanSAR
    else:
        nls = int(nls0)
    print('number of looks to be used: {}'.format(nls))
    ####################################################

    #read burst interferograms
    inf = np.zeros((length, width, nls), dtype=np.complex64)
    cnt = np.zeros((length, width), dtype=np.int8)
    for i in range(nBurst):
        if (i + 1) % 5 == 0 or (i + 1) == nBurst:
            print('reading burst %02d' % (i + 1))

        burst = np.fromfile(bursts[i],
                            dtype=np.complex64).reshape(lengthBurst, width)

        #subset for the burst
        cntBurst = cnt[0 +
                       referenceSwath.burstSlcFirstLineOffsets[i]:lengthBurst +
                       referenceSwath.burstSlcFirstLineOffsets[i], :]
        infBurst = inf[0 +
                       referenceSwath.burstSlcFirstLineOffsets[i]:lengthBurst +
                       referenceSwath.burstSlcFirstLineOffsets[i], :, :]

        #set number of non-zero pixels
        cntBurst[np.nonzero(burst)] += 1

        #get index
        index1 = np.nonzero(np.logical_and(burst != 0, cntBurst <= nls))
        index2 = index1 + (cntBurst[index1] - 1, )

        #set values
        infBurst[index2] = burst[index1]

    #number of looks for each sample
    if keep:
        nlFile = 'number_of_looks.nl'
        cnt.astype(np.int8).tofile(nlFile)
        create_xml(nlFile, width, length, 'byte')

    if filt:
        import scipy.signal as ss
        filterKernel = np.ones((filtWinSizeAzimuth, filtWinSizeRange),
                               dtype=np.float64)
        for i in range(nls):
            print('filtering look {}'.format(i + 1))
            flag = (inf[:, :, i] != 0)
            #scale = ss.fftconvolve(flag, filterKernel, mode='same')
            #inf[:,:,i] = flag*ss.fftconvolve(inf[:,:,i], filterKernel, mode='same') / (scale + (scale==0))
            #this should be faster?
            scale = ss.convolve2d(flag, filterKernel, mode='same')
            inf[:, :, i] = flag * ss.convolve2d(
                inf[:, :, i], filterKernel, mode='same') / (scale +
                                                            (scale == 0))

    #width and length after multilooking
    widthm = int(width / rgl)
    lengthm = int(length / azl)
    #use the convention that ka > 0
    ka = -np.polyval(referenceSwath.azimuthFmrateVsPixel[::-1],
                     create_multi_index(width, rgl))

    #get spectral diversity inteferogram
    offset_sd = []
    for i in range(1, nls):
        print('ouput spectral diversity inteferogram %d' % i)
        #original spectral diversity inteferogram
        sd = inf[:, :, 0] * np.conj(inf[:, :, i])

        #replace original amplitude with its square root
        index = np.nonzero(sd != 0)
        sd[index] /= np.sqrt(np.absolute(sd[index]))

        sdFile = outputList[i - 1]
        sd.astype(np.complex64).tofile(sdFile)
        create_xml(sdFile, width, length, 'int')

        #multi look
        sdm = multilook(sd, azl, rgl)
        cor = cal_coherence_1(sdm)

        #convert phase to offset
        offset = np.angle(sdm) / (2.0 * np.pi * ka * tc * i)[None, :] / azsi

        #compute offset using good samples
        point_index = np.nonzero(
            np.logical_and(cor >= cor_th,
                           np.angle(sdm) != 0))
        npoint = round(np.size(point_index) / 2)
        if npoint < 20:
            print(
                'WARNING: too few good samples for spectral diversity at look {}: {}'
                .format(i, npoint))
            offset_sd.append(0)
        else:
            offset_sd.append(
                np.sum(offset[point_index] * cor[point_index]) /
                np.sum(cor[point_index]))

        if keep:
            sdmFile = 'sd_%d_%drlks_%dalks.int' % (i, rgl, azl)
            sdm.astype(np.complex64).tofile(sdmFile)
            create_xml(sdmFile, widthm, lengthm, 'int')
            corFile = 'sd_%d_%drlks_%dalks.cor' % (i, rgl, azl)
            cor.astype(np.float32).tofile(corFile)
            create_xml(corFile, widthm, lengthm, 'float')
            offsetFile = 'sd_%d_%drlks_%dalks.off' % (i, rgl, azl)
            offset.astype(np.float32).tofile(offsetFile)
            create_xml(offsetFile, widthm, lengthm, 'float')

    offset_mean = np.sum(np.array(offset_sd) * np.arange(1, nls)) / np.sum(
        np.arange(1, nls))

    return offset_mean
Beispiel #24
0
def runIonSubband(self):
    '''create subband interferograms
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    if not self.doIon:
        catalog.printToLog(logger, "runIonSubband")
        self._insar.procDoc.addAllFromCatalog(catalog)
        return

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

    #using 1/3, 1/3, 1/3 band split
    radarWavelength = masterTrack.radarWavelength
    rangeBandwidth = masterTrack.frames[0].swaths[0].rangeBandwidth
    rangeSamplingRate = masterTrack.frames[0].swaths[0].rangeSamplingRate
    radarWavelengthLower = SPEED_OF_LIGHT / (SPEED_OF_LIGHT / radarWavelength -
                                             rangeBandwidth / 3.0)
    radarWavelengthUpper = SPEED_OF_LIGHT / (SPEED_OF_LIGHT / radarWavelength +
                                             rangeBandwidth / 3.0)
    subbandRadarWavelength = [radarWavelengthLower, radarWavelengthUpper]
    subbandBandWidth = [
        rangeBandwidth / 3.0 / rangeSamplingRate,
        rangeBandwidth / 3.0 / rangeSamplingRate
    ]
    subbandFrequencyCenter = [
        -rangeBandwidth / 3.0 / rangeSamplingRate,
        rangeBandwidth / 3.0 / rangeSamplingRate
    ]

    subbandPrefix = ['lower', 'upper']
    '''
    ionDir = {
        ionDir['swathMosaic'] : 'mosaic',
        ionDir['insar'] : 'insar',
        ionDir['ion'] : 'ion',
        ionDir['subband'] : ['lower', 'upper'],
        ionDir['ionCal'] : 'ion_cal'
        }
    '''
    #define upper level directory names
    ionDir = defineIonDir()

    self._insar.subbandRadarWavelength = subbandRadarWavelength

    ############################################################
    # STEP 1. create directories
    ############################################################
    #create and enter 'ion' directory
    #after finishing each step, we are in this directory
    if not os.path.exists(ionDir['ion']):
        os.makedirs(ionDir['ion'])
    os.chdir(ionDir['ion'])

    #create insar processing directories
    for k in range(2):
        subbandDir = ionDir['subband'][k]
        for i, frameNumber in enumerate(self._insar.masterFrames):
            frameDir = 'f{}_{}'.format(i + 1, frameNumber)
            for j, swathNumber in enumerate(
                    range(self._insar.startingSwath,
                          self._insar.endingSwath + 1)):
                swathDir = 's{}'.format(swathNumber)
                fullDir = os.path.join(subbandDir, frameDir, swathDir)
                if not os.path.exists(fullDir):
                    os.makedirs(fullDir)

    #create ionospheric phase directory
    if not os.path.exists(ionDir['ionCal']):
        os.makedirs(ionDir['ionCal'])

    ############################################################
    # STEP 2. create subband interferograms
    ############################################################
    import numpy as np
    import stdproc
    from iscesys.StdOEL.StdOELPy import create_writer
    from isceobj.Alos2Proc.Alos2ProcPublic import readOffset
    from contrib.alos2proc.alos2proc import rg_filter

    for i, frameNumber in enumerate(self._insar.masterFrames):
        frameDir = 'f{}_{}'.format(i + 1, frameNumber)
        for j, swathNumber in enumerate(
                range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            swathDir = 's{}'.format(swathNumber)
            #filter master and slave images
            for slcx in [self._insar.masterSlc, self._insar.slaveSlc]:
                slc = os.path.join('../', frameDir, swathDir, slcx)
                slcLower = os.path.join(ionDir['subband'][0], frameDir,
                                        swathDir, slcx)
                slcUpper = os.path.join(ionDir['subband'][1], frameDir,
                                        swathDir, slcx)
                rg_filter(slc, 2, [slcLower, slcUpper], subbandBandWidth,
                          subbandFrequencyCenter, 257, 2048, 0.1, 0, 0.0)
            #resample
            for k in range(2):
                os.chdir(os.path.join(ionDir['subband'][k], frameDir,
                                      swathDir))
                #recreate xml file to remove the file path
                #can also use fixImageXml.py?
                for x in [self._insar.masterSlc, self._insar.slaveSlc]:
                    img = isceobj.createSlcImage()
                    img.load(x + '.xml')
                    img.setFilename(x)
                    img.extraFilename = x + '.vrt'
                    img.setAccessMode('READ')
                    img.renderHdr()

                #############################################
                #1. form interferogram
                #############################################
                masterSwath = masterTrack.frames[i].swaths[j]
                slaveSwath = slaveTrack.frames[i].swaths[j]

                refinedOffsets = readOffset(
                    os.path.join('../../../../', frameDir, swathDir,
                                 'cull.off'))
                intWidth = int(masterSwath.numberOfSamples /
                               self._insar.numberRangeLooks1)
                intLength = int(masterSwath.numberOfLines /
                                self._insar.numberAzimuthLooks1)
                dopplerVsPixel = [
                    i / slaveSwath.prf for i in slaveSwath.dopplerVsPixel
                ]

                #master slc
                mSLC = isceobj.createSlcImage()
                mSLC.load(self._insar.masterSlc + '.xml')
                mSLC.setAccessMode('read')
                mSLC.createImage()

                #slave slc
                sSLC = isceobj.createSlcImage()
                sSLC.load(self._insar.slaveSlc + '.xml')
                sSLC.setAccessMode('read')
                sSLC.createImage()

                #interferogram
                interf = isceobj.createIntImage()
                interf.setFilename(self._insar.interferogram)
                interf.setWidth(intWidth)
                interf.setAccessMode('write')
                interf.createImage()

                #amplitdue
                amplitude = isceobj.createAmpImage()
                amplitude.setFilename(self._insar.amplitude)
                amplitude.setWidth(intWidth)
                amplitude.setAccessMode('write')
                amplitude.createImage()

                #create a writer for resamp
                stdWriter = create_writer("log",
                                          "",
                                          True,
                                          filename="resamp.log")
                stdWriter.setFileTag("resamp", "log")
                stdWriter.setFileTag("resamp", "err")
                stdWriter.setFileTag("resamp", "out")

                #set up resampling program now
                #The setting has been compared with resamp_roi's setting in ROI_pac item by item.
                #The two kinds of setting are exactly the same. The number of setting items are
                #exactly the same
                objResamp = stdproc.createResamp()
                objResamp.wireInputPort(name='offsets', object=refinedOffsets)
                objResamp.stdWriter = stdWriter
                objResamp.setNumberFitCoefficients(6)
                objResamp.setNumberRangeBin1(masterSwath.numberOfSamples)
                objResamp.setNumberRangeBin2(slaveSwath.numberOfSamples)
                objResamp.setStartLine(1)
                objResamp.setNumberLines(masterSwath.numberOfLines)
                objResamp.setFirstLineOffset(1)
                objResamp.setDopplerCentroidCoefficients(dopplerVsPixel)
                objResamp.setRadarWavelength(subbandRadarWavelength[k])
                objResamp.setSlantRangePixelSpacing(slaveSwath.rangePixelSize)
                objResamp.setNumberRangeLooks(self._insar.numberRangeLooks1)
                objResamp.setNumberAzimuthLooks(
                    self._insar.numberAzimuthLooks1)
                objResamp.setFlattenWithOffsetFitFlag(0)
                objResamp.resamp(mSLC, sSLC, interf, amplitude)

                #finialize images
                mSLC.finalizeImage()
                sSLC.finalizeImage()
                interf.finalizeImage()
                amplitude.finalizeImage()
                stdWriter.finalize()

                #############################################
                #2. trim amplitude
                #############################################
                #using memmap instead, which should be faster, since we only have a few pixels to change
                amp = np.memmap(self._insar.amplitude,
                                dtype='complex64',
                                mode='r+',
                                shape=(intLength, intWidth))
                index = np.nonzero((np.real(amp) == 0) + (np.imag(amp) == 0))
                amp[index] = 0

                #Deletion flushes memory changes to disk before removing the object:
                del amp

                #############################################
                #3. delete subband slcs
                #############################################
                os.remove(self._insar.masterSlc)
                os.remove(self._insar.masterSlc + '.vrt')
                os.remove(self._insar.masterSlc + '.xml')
                os.remove(self._insar.slaveSlc)
                os.remove(self._insar.slaveSlc + '.vrt')
                os.remove(self._insar.slaveSlc + '.xml')

                os.chdir('../../../')

    ############################################################
    # STEP 3. mosaic swaths
    ############################################################
    from isceobj.Alos2Proc.runSwathMosaic import swathMosaic
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml

    for k in range(2):
        os.chdir(ionDir['subband'][k])
        for i, frameNumber in enumerate(self._insar.masterFrames):
            frameDir = 'f{}_{}'.format(i + 1, frameNumber)
            os.chdir(frameDir)

            mosaicDir = ionDir['swathMosaic']
            if not os.path.exists(mosaicDir):
                os.makedirs(mosaicDir)
            os.chdir(mosaicDir)

            if not (
                   ((self._insar.modeCombination == 21) or \
                    (self._insar.modeCombination == 22) or \
                    (self._insar.modeCombination == 31) or \
                    (self._insar.modeCombination == 32))
                   and
                   (self._insar.endingSwath-self._insar.startingSwath+1 > 1)
                   ):
                import shutil
                swathDir = 's{}'.format(
                    masterTrack.frames[i].swaths[0].swathNumber)

                # if not os.path.isfile(self._insar.interferogram):
                #     os.symlink(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram)
                # shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
                # shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
                # if not os.path.isfile(self._insar.amplitude):
                #     os.symlink(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude)
                # shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
                # shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')

                os.rename(
                    os.path.join('../', swathDir, self._insar.interferogram),
                    self._insar.interferogram)
                os.rename(
                    os.path.join('../', swathDir,
                                 self._insar.interferogram + '.vrt'),
                    self._insar.interferogram + '.vrt')
                os.rename(
                    os.path.join('../', swathDir,
                                 self._insar.interferogram + '.xml'),
                    self._insar.interferogram + '.xml')
                os.rename(os.path.join('../', swathDir, self._insar.amplitude),
                          self._insar.amplitude)
                os.rename(
                    os.path.join('../', swathDir,
                                 self._insar.amplitude + '.vrt'),
                    self._insar.amplitude + '.vrt')
                os.rename(
                    os.path.join('../', swathDir,
                                 self._insar.amplitude + '.xml'),
                    self._insar.amplitude + '.xml')

                #no need to update frame parameters here
                os.chdir('../')
                #no need to save parameter file here
                os.chdir('../')

                continue

            #choose offsets
            numberOfFrames = len(masterTrack.frames)
            numberOfSwaths = len(masterTrack.frames[i].swaths)
            if self.swathOffsetMatching:
                #no need to do this as the API support 2-d list
                #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths)
                #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths)
                rangeOffsets = self._insar.swathRangeOffsetMatchingMaster
                azimuthOffsets = self._insar.swathAzimuthOffsetMatchingMaster

            else:
                #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths)
                #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths)
                rangeOffsets = self._insar.swathRangeOffsetGeometricalMaster
                azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalMaster

            rangeOffsets = rangeOffsets[i]
            azimuthOffsets = azimuthOffsets[i]

            #list of input files
            inputInterferograms = []
            inputAmplitudes = []
            for j, swathNumber in enumerate(
                    range(self._insar.startingSwath,
                          self._insar.endingSwath + 1)):
                swathDir = 's{}'.format(swathNumber)
                inputInterferograms.append(
                    os.path.join('../', swathDir, self._insar.interferogram))
                inputAmplitudes.append(
                    os.path.join('../', swathDir, self._insar.amplitude))

            #note that frame parameters are updated after mosaicking, here no need to update parameters
            #mosaic amplitudes
            swathMosaic(masterTrack.frames[i],
                        inputAmplitudes,
                        self._insar.amplitude,
                        rangeOffsets,
                        azimuthOffsets,
                        self._insar.numberRangeLooks1,
                        self._insar.numberAzimuthLooks1,
                        resamplingMethod=0)
            #mosaic interferograms
            swathMosaic(masterTrack.frames[i],
                        inputInterferograms,
                        self._insar.interferogram,
                        rangeOffsets,
                        azimuthOffsets,
                        self._insar.numberRangeLooks1,
                        self._insar.numberAzimuthLooks1,
                        updateFrame=False,
                        phaseCompensation=True,
                        resamplingMethod=1)

            create_xml(self._insar.amplitude,
                       masterTrack.frames[i].numberOfSamples,
                       masterTrack.frames[i].numberOfLines, 'amp')
            create_xml(self._insar.interferogram,
                       masterTrack.frames[i].numberOfSamples,
                       masterTrack.frames[i].numberOfLines, 'int')

            #update slave frame parameters here, here no need to update parameters
            os.chdir('../')
            #save parameter file, here no need to save parameter file
            os.chdir('../')
        os.chdir('../')

    ############################################################
    # STEP 4. mosaic frames
    ############################################################
    from isceobj.Alos2Proc.runFrameMosaic import frameMosaic
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml

    for k in range(2):
        os.chdir(ionDir['subband'][k])

        mosaicDir = ionDir['insar']
        if not os.path.exists(mosaicDir):
            os.makedirs(mosaicDir)
        os.chdir(mosaicDir)

        numberOfFrames = len(masterTrack.frames)
        if numberOfFrames == 1:
            import shutil
            frameDir = os.path.join('f1_{}/mosaic'.format(
                self._insar.masterFrames[0]))
            # if not os.path.isfile(self._insar.interferogram):
            #     os.symlink(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram)
            # #shutil.copy2() can overwrite
            # shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
            # shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
            # if not os.path.isfile(self._insar.amplitude):
            #     os.symlink(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude)
            # shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
            # shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')

            os.rename(os.path.join('../', frameDir, self._insar.interferogram),
                      self._insar.interferogram)
            os.rename(
                os.path.join('../', frameDir,
                             self._insar.interferogram + '.vrt'),
                self._insar.interferogram + '.vrt')
            os.rename(
                os.path.join('../', frameDir,
                             self._insar.interferogram + '.xml'),
                self._insar.interferogram + '.xml')
            os.rename(os.path.join('../', frameDir, self._insar.amplitude),
                      self._insar.amplitude)
            os.rename(
                os.path.join('../', frameDir, self._insar.amplitude + '.vrt'),
                self._insar.amplitude + '.vrt')
            os.rename(
                os.path.join('../', frameDir, self._insar.amplitude + '.xml'),
                self._insar.amplitude + '.xml')

            #update track parameters, no need to update track parameters here

        else:
            #choose offsets
            if self.frameOffsetMatching:
                rangeOffsets = self._insar.frameRangeOffsetMatchingMaster
                azimuthOffsets = self._insar.frameAzimuthOffsetMatchingMaster
            else:
                rangeOffsets = self._insar.frameRangeOffsetGeometricalMaster
                azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalMaster

            #list of input files
            inputInterferograms = []
            inputAmplitudes = []
            for i, frameNumber in enumerate(self._insar.masterFrames):
                frameDir = 'f{}_{}'.format(i + 1, frameNumber)
                inputInterferograms.append(
                    os.path.join('../', frameDir, 'mosaic',
                                 self._insar.interferogram))
                inputAmplitudes.append(
                    os.path.join('../', frameDir, 'mosaic',
                                 self._insar.amplitude))

            #note that track parameters are updated after mosaicking
            #mosaic amplitudes
            frameMosaic(masterTrack,
                        inputAmplitudes,
                        self._insar.amplitude,
                        rangeOffsets,
                        azimuthOffsets,
                        self._insar.numberRangeLooks1,
                        self._insar.numberAzimuthLooks1,
                        updateTrack=False,
                        phaseCompensation=False,
                        resamplingMethod=0)
            #mosaic interferograms
            frameMosaic(masterTrack,
                        inputInterferograms,
                        self._insar.interferogram,
                        rangeOffsets,
                        azimuthOffsets,
                        self._insar.numberRangeLooks1,
                        self._insar.numberAzimuthLooks1,
                        updateTrack=False,
                        phaseCompensation=True,
                        resamplingMethod=1)

            create_xml(self._insar.amplitude, masterTrack.numberOfSamples,
                       masterTrack.numberOfLines, 'amp')
            create_xml(self._insar.interferogram, masterTrack.numberOfSamples,
                       masterTrack.numberOfLines, 'int')

            #update slave parameters here, no need to update slave parameters here

        os.chdir('../')
        #save parameter file, no need to save parameter file here
        os.chdir('../')

    ############################################################
    # STEP 5. clear frame processing files
    ############################################################
    import shutil
    from isceobj.Alos2Proc.Alos2ProcPublic import runCmd

    for k in range(2):
        os.chdir(ionDir['subband'][k])
        for i, frameNumber in enumerate(self._insar.masterFrames):
            frameDir = 'f{}_{}'.format(i + 1, frameNumber)
            shutil.rmtree(frameDir)
            #cmd = 'rm -rf {}'.format(frameDir)
            #runCmd(cmd)
        os.chdir('../')

    ############################################################
    # STEP 6. create differential interferograms
    ############################################################
    import numpy as np
    from isceobj.Alos2Proc.Alos2ProcPublic import runCmd

    for k in range(2):
        os.chdir(ionDir['subband'][k])

        insarDir = ionDir['insar']
        if not os.path.exists(insarDir):
            os.makedirs(insarDir)
        os.chdir(insarDir)

        rangePixelSize = self._insar.numberRangeLooks1 * masterTrack.rangePixelSize
        radarWavelength = subbandRadarWavelength[k]
        rectRangeOffset = os.path.join('../../../', insarDir,
                                       self._insar.rectRangeOffset)

        cmd = "imageMath.py -e='a*exp(-1.0*J*b*4.0*{}*{}/{}) * (b!=0)' --a={} --b={} -o {} -t cfloat".format(
            np.pi, rangePixelSize, radarWavelength, self._insar.interferogram,
            rectRangeOffset, self._insar.differentialInterferogram)
        runCmd(cmd)

        os.chdir('../../')

    os.chdir('../')
    catalog.printToLog(logger, "runIonSubband")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #25
0
def runIonSubband(self):
    '''create subband interferograms
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    if not self.doIon:
        catalog.printToLog(logger, "runIonSubband")
        self._insar.procDoc.addAllFromCatalog(catalog)
        return

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

    #using 1/3, 1/3, 1/3 band split
    radarWavelength = referenceTrack.radarWavelength
    rangeBandwidth = referenceTrack.frames[0].swaths[0].rangeBandwidth
    rangeSamplingRate = referenceTrack.frames[0].swaths[0].rangeSamplingRate
    radarWavelengthLower = SPEED_OF_LIGHT / (SPEED_OF_LIGHT / radarWavelength -
                                             rangeBandwidth / 3.0)
    radarWavelengthUpper = SPEED_OF_LIGHT / (SPEED_OF_LIGHT / radarWavelength +
                                             rangeBandwidth / 3.0)
    subbandRadarWavelength = [radarWavelengthLower, radarWavelengthUpper]
    subbandBandWidth = [
        rangeBandwidth / 3.0 / rangeSamplingRate,
        rangeBandwidth / 3.0 / rangeSamplingRate
    ]
    subbandFrequencyCenter = [
        -rangeBandwidth / 3.0 / rangeSamplingRate,
        rangeBandwidth / 3.0 / rangeSamplingRate
    ]

    subbandPrefix = ['lower', 'upper']
    '''
    ionDir = {
        ionDir['swathMosaic'] : 'mosaic',
        ionDir['insar'] : 'insar',
        ionDir['ion'] : 'ion',
        ionDir['subband'] : ['lower', 'upper'],
        ionDir['ionCal'] : 'ion_cal'
        }
    '''
    #define upper level directory names
    ionDir = defineIonDir()

    self._insar.subbandRadarWavelength = subbandRadarWavelength

    ############################################################
    # STEP 1. create directories
    ############################################################
    #create and enter 'ion' directory
    #after finishing each step, we are in this directory
    os.makedirs(ionDir['ion'], exist_ok=True)
    os.chdir(ionDir['ion'])

    #create insar processing directories
    for k in range(2):
        subbandDir = ionDir['subband'][k]
        for i, frameNumber in enumerate(self._insar.referenceFrames):
            frameDir = 'f{}_{}'.format(i + 1, frameNumber)
            for j, swathNumber in enumerate(
                    range(self._insar.startingSwath,
                          self._insar.endingSwath + 1)):
                swathDir = 's{}'.format(swathNumber)
                fullDir = os.path.join(subbandDir, frameDir, swathDir)
                os.makedirs(fullDir, exist_ok=True)

    #create ionospheric phase directory
    os.makedirs(ionDir['ionCal'])

    ############################################################
    # STEP 2. create subband interferograms
    ############################################################
    import shutil
    import numpy as np
    from contrib.alos2proc.alos2proc import rg_filter
    from isceobj.Alos2Proc.Alos2ProcPublic import resampleBursts
    from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstAmplitude
    from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstInterferogram
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml

    for i, frameNumber in enumerate(self._insar.referenceFrames):
        frameDir = 'f{}_{}'.format(i + 1, frameNumber)
        for j, swathNumber in enumerate(
                range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            swathDir = 's{}'.format(swathNumber)
            #filter reference and secondary images
            for burstPrefix, swath in zip([
                    self._insar.referenceBurstPrefix,
                    self._insar.secondaryBurstPrefix
            ], [
                    referenceTrack.frames[i].swaths[j],
                    secondaryTrack.frames[i].swaths[j]
            ]):
                slcDir = os.path.join('../', frameDir, swathDir, burstPrefix)
                slcLowerDir = os.path.join(ionDir['subband'][0], frameDir,
                                           swathDir, burstPrefix)
                slcUpperDir = os.path.join(ionDir['subband'][1], frameDir,
                                           swathDir, burstPrefix)
                os.makedirs(slcLowerDir, exist_ok=True)
                os.makedirs(slcUpperDir, exist_ok=True)
                for k in range(swath.numberOfBursts):
                    print('processing burst: %02d' % (k + 1))
                    slc = os.path.join(slcDir,
                                       burstPrefix + '_%02d.slc' % (k + 1))
                    slcLower = os.path.join(
                        slcLowerDir, burstPrefix + '_%02d.slc' % (k + 1))
                    slcUpper = os.path.join(
                        slcUpperDir, burstPrefix + '_%02d.slc' % (k + 1))
                    rg_filter(slc, 2, [slcLower, slcUpper], subbandBandWidth,
                              subbandFrequencyCenter, 257, 2048, 0.1, 0, 0.0)
            #resample
            for l in range(2):
                os.chdir(os.path.join(ionDir['subband'][l], frameDir,
                                      swathDir))
                #recreate xml file to remove the file path
                #can also use fixImageXml.py?
                for burstPrefix, swath in zip([
                        self._insar.referenceBurstPrefix,
                        self._insar.secondaryBurstPrefix
                ], [
                        referenceTrack.frames[i].swaths[j],
                        secondaryTrack.frames[i].swaths[j]
                ]):
                    os.chdir(burstPrefix)
                    for k in range(swath.numberOfBursts):
                        slc = burstPrefix + '_%02d.slc' % (k + 1)
                        img = isceobj.createSlcImage()
                        img.load(slc + '.xml')
                        img.setFilename(slc)
                        img.extraFilename = slc + '.vrt'
                        img.setAccessMode('READ')
                        img.renderHdr()
                    os.chdir('../')

                #############################################
                #1. form interferogram
                #############################################
                referenceSwath = referenceTrack.frames[i].swaths[j]
                secondarySwath = secondaryTrack.frames[i].swaths[j]

                #set up resampling parameters
                width = referenceSwath.numberOfSamples
                length = referenceSwath.numberOfLines
                polyCoeff = self._insar.rangeResidualOffsetCc[i][j]
                rgIndex = (np.arange(width) -
                           polyCoeff[-1][0]) / polyCoeff[-1][1]
                azIndex = (np.arange(length) -
                           polyCoeff[-1][2]) / polyCoeff[-1][3]
                rangeOffset =  polyCoeff[0][0] + polyCoeff[0][1]*rgIndex[None,:] + polyCoeff[0][2]*rgIndex[None,:]**2 + \
                              (polyCoeff[1][0] + polyCoeff[1][1]*rgIndex[None,:]) * azIndex[:, None] + \
                               polyCoeff[2][0] * azIndex[:, None]**2
                azimuthOffset = self._insar.azimuthResidualOffsetCc[i][j]

                secondaryBurstResampledDir = self._insar.secondaryBurstPrefix + '_2_coreg_cc'
                interferogramDir = 'burst_interf_2_coreg_cc'
                interferogramPrefix = self._insar.referenceBurstPrefix + '-' + self._insar.secondaryBurstPrefix
                resampleBursts(
                    referenceSwath,
                    secondarySwath,
                    self._insar.referenceBurstPrefix,
                    self._insar.secondaryBurstPrefix,
                    secondaryBurstResampledDir,
                    interferogramDir,
                    self._insar.referenceBurstPrefix,
                    self._insar.secondaryBurstPrefix,
                    self._insar.secondaryBurstPrefix,
                    interferogramPrefix,
                    os.path.join(
                        '../../../../{}/{}'.format(frameDir, swathDir),
                        self._insar.rangeOffset),
                    os.path.join(
                        '../../../../{}/{}'.format(frameDir, swathDir),
                        self._insar.azimuthOffset),
                    rangeOffsetResidual=rangeOffset,
                    azimuthOffsetResidual=azimuthOffset)

                os.chdir(self._insar.referenceBurstPrefix)
                mosaicBurstAmplitude(referenceSwath,
                                     self._insar.referenceBurstPrefix,
                                     self._insar.referenceMagnitude,
                                     numberOfLooksThreshold=4)
                os.chdir('../')

                os.chdir(secondaryBurstResampledDir)
                mosaicBurstAmplitude(referenceSwath,
                                     self._insar.secondaryBurstPrefix,
                                     self._insar.secondaryMagnitude,
                                     numberOfLooksThreshold=4)
                os.chdir('../')

                os.chdir(interferogramDir)
                mosaicBurstInterferogram(referenceSwath,
                                         interferogramPrefix,
                                         self._insar.interferogram,
                                         numberOfLooksThreshold=4)
                os.chdir('../')

                amp = np.zeros((referenceSwath.numberOfLines,
                                2 * referenceSwath.numberOfSamples),
                               dtype=np.float32)
                amp[0:, 1:referenceSwath.numberOfSamples*2:2] = np.fromfile(os.path.join(secondaryBurstResampledDir, self._insar.secondaryMagnitude), \
                    dtype=np.float32).reshape(referenceSwath.numberOfLines, referenceSwath.numberOfSamples)
                amp[0:, 0:referenceSwath.numberOfSamples*2:2] = np.fromfile(os.path.join(self._insar.referenceBurstPrefix, self._insar.referenceMagnitude), \
                    dtype=np.float32).reshape(referenceSwath.numberOfLines, referenceSwath.numberOfSamples)
                amp.astype(np.float32).tofile(self._insar.amplitude)
                create_xml(self._insar.amplitude,
                           referenceSwath.numberOfSamples,
                           referenceSwath.numberOfLines, 'amp')

                os.rename(
                    os.path.join(interferogramDir, self._insar.interferogram),
                    self._insar.interferogram)
                os.rename(
                    os.path.join(interferogramDir,
                                 self._insar.interferogram + '.vrt'),
                    self._insar.interferogram + '.vrt')
                os.rename(
                    os.path.join(interferogramDir,
                                 self._insar.interferogram + '.xml'),
                    self._insar.interferogram + '.xml')

                #############################################
                #2. delete subband slcs
                #############################################
                shutil.rmtree(self._insar.referenceBurstPrefix)
                shutil.rmtree(self._insar.secondaryBurstPrefix)
                shutil.rmtree(secondaryBurstResampledDir)
                shutil.rmtree(interferogramDir)

                os.chdir('../../../')

    ############################################################
    # STEP 3. mosaic swaths
    ############################################################
    from isceobj.Alos2Proc.runSwathMosaic import swathMosaic
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml

    for k in range(2):
        os.chdir(ionDir['subband'][k])
        for i, frameNumber in enumerate(self._insar.referenceFrames):
            frameDir = 'f{}_{}'.format(i + 1, frameNumber)
            os.chdir(frameDir)

            mosaicDir = 'mosaic'
            os.makedirs(mosaicDir, exist_ok=True)
            os.chdir(mosaicDir)

            if self._insar.endingSwath - self._insar.startingSwath + 1 == 1:
                import shutil
                swathDir = 's{}'.format(
                    referenceTrack.frames[i].swaths[0].swathNumber)

                # if not os.path.isfile(self._insar.interferogram):
                #     os.symlink(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram)
                # shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
                # shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
                # if not os.path.isfile(self._insar.amplitude):
                #     os.symlink(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude)
                # shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
                # shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')

                os.rename(
                    os.path.join('../', swathDir, self._insar.interferogram),
                    self._insar.interferogram)
                os.rename(
                    os.path.join('../', swathDir,
                                 self._insar.interferogram + '.vrt'),
                    self._insar.interferogram + '.vrt')
                os.rename(
                    os.path.join('../', swathDir,
                                 self._insar.interferogram + '.xml'),
                    self._insar.interferogram + '.xml')
                os.rename(os.path.join('../', swathDir, self._insar.amplitude),
                          self._insar.amplitude)
                os.rename(
                    os.path.join('../', swathDir,
                                 self._insar.amplitude + '.vrt'),
                    self._insar.amplitude + '.vrt')
                os.rename(
                    os.path.join('../', swathDir,
                                 self._insar.amplitude + '.xml'),
                    self._insar.amplitude + '.xml')

                os.chdir('../')
                os.chdir('../')
                continue

            #choose offsets
            numberOfFrames = len(referenceTrack.frames)
            numberOfSwaths = len(referenceTrack.frames[i].swaths)
            if self.swathOffsetMatching:
                #no need to do this as the API support 2-d list
                #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingReference)).reshape(numberOfFrames, numberOfSwaths)
                #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingReference)).reshape(numberOfFrames, numberOfSwaths)
                rangeOffsets = self._insar.swathRangeOffsetMatchingReference
                azimuthOffsets = self._insar.swathAzimuthOffsetMatchingReference

            else:
                #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalReference)).reshape(numberOfFrames, numberOfSwaths)
                #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalReference)).reshape(numberOfFrames, numberOfSwaths)
                rangeOffsets = self._insar.swathRangeOffsetGeometricalReference
                azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalReference

            rangeOffsets = rangeOffsets[i]
            azimuthOffsets = azimuthOffsets[i]

            #list of input files
            inputInterferograms = []
            inputAmplitudes = []
            phaseDiff = [None]
            for j, swathNumber in enumerate(
                    range(self._insar.startingSwath,
                          self._insar.endingSwath + 1)):
                swathDir = 's{}'.format(swathNumber)
                inputInterferograms.append(
                    os.path.join('../', swathDir, self._insar.interferogram))
                inputAmplitudes.append(
                    os.path.join('../', swathDir, self._insar.amplitude))

                #compute phase needed to be compensated using startingRange
                if j >= 1:
                    #phaseDiffSwath1 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange)/subbandRadarWavelength[k]
                    #phaseDiffSwath2 = -4.0 * np.pi * (referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange)/subbandRadarWavelength[k]
                    phaseDiffSwath1 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
                                      -4.0 * np.pi * secondaryTrack.frames[i].swaths[j-1].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
                    phaseDiffSwath2 = +4.0 * np.pi * referenceTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k]) \
                                      -4.0 * np.pi * secondaryTrack.frames[i].swaths[j].startingRange * (1.0/radarWavelength - 1.0/subbandRadarWavelength[k])
                    if referenceTrack.frames[i].swaths[j-1].startingRange - secondaryTrack.frames[i].swaths[j-1].startingRange == \
                       referenceTrack.frames[i].swaths[j].startingRange - secondaryTrack.frames[i].swaths[j].startingRange:
                        #phaseDiff.append(phaseDiffSwath2 - phaseDiffSwath1)
                        #if reference and secondary versions are all before or after version 2.025 (starting range error < 0.5 m),
                        #it should be OK to do the above.
                        #see results in neom where it meets the above requirement, but there is still phase diff
                        #to be less risky, we do not input values here
                        phaseDiff.append(None)
                    else:
                        phaseDiff.append(None)

            #note that frame parameters are updated after mosaicking
            #mosaic amplitudes
            swathMosaic(referenceTrack.frames[i],
                        inputAmplitudes,
                        self._insar.amplitude,
                        rangeOffsets,
                        azimuthOffsets,
                        self._insar.numberRangeLooks1,
                        self._insar.numberAzimuthLooks1,
                        resamplingMethod=0)
            #mosaic interferograms
            #These are for ALOS-2, may need to change for ALOS-4!
            phaseDiffFixed = [
                0.0, 0.4754024578084084, 0.9509913179406437,
                1.4261648478671614, 2.179664007520499, 2.6766909968024932,
                3.130810857
            ]

            snapThreshold = 0.2

            #the above preparetions only applies to 'self._insar.modeCombination == 21'
            #looks like it also works for 31 (scansarNominalModes-stripmapModes)
            if self._insar.modeCombination != 21:
                phaseDiff = None
                phaseDiffFixed = None
                snapThreshold = None

            (phaseDiffEst, phaseDiffUsed,
             phaseDiffSource) = swathMosaic(referenceTrack.frames[i],
                                            inputInterferograms,
                                            self._insar.interferogram,
                                            rangeOffsets,
                                            azimuthOffsets,
                                            self._insar.numberRangeLooks1,
                                            self._insar.numberAzimuthLooks1,
                                            updateFrame=False,
                                            phaseCompensation=True,
                                            phaseDiff=phaseDiff,
                                            phaseDiffFixed=phaseDiffFixed,
                                            snapThreshold=snapThreshold,
                                            pcRangeLooks=1,
                                            pcAzimuthLooks=3,
                                            filt=False,
                                            resamplingMethod=1)

            #the first item is meaningless for all the following list, so only record the following items
            if phaseDiff == None:
                phaseDiff = [
                    None for iii in range(self._insar.startingSwath,
                                          self._insar.endingSwath + 1)
                ]
            catalog.addItem(
                '{} subswath phase difference input'.format(
                    ionDir['subband'][k]), phaseDiff[1:], 'runIonSubband')
            catalog.addItem(
                '{} subswath phase difference estimated'.format(
                    ionDir['subband'][k]), phaseDiffEst[1:], 'runIonSubband')
            catalog.addItem(
                '{} subswath phase difference used'.format(
                    ionDir['subband'][k]), phaseDiffUsed[1:], 'runIonSubband')
            catalog.addItem(
                '{} subswath phase difference used source'.format(
                    ionDir['subband'][k]), phaseDiffSource[1:],
                'runIonSubband')
            #check if there is value around 3.130810857, which may not be stable
            phaseDiffUnstableExist = False
            for xxx in phaseDiffUsed:
                if abs(abs(xxx) - 3.130810857) < 0.2:
                    phaseDiffUnstableExist = True
            catalog.addItem(
                '{} subswath phase difference unstable exists'.format(
                    ionDir['subband'][k]), phaseDiffUnstableExist,
                'runIonSubband')

            create_xml(self._insar.amplitude,
                       referenceTrack.frames[i].numberOfSamples,
                       referenceTrack.frames[i].numberOfLines, 'amp')
            create_xml(self._insar.interferogram,
                       referenceTrack.frames[i].numberOfSamples,
                       referenceTrack.frames[i].numberOfLines, 'int')

            os.chdir('../')
            os.chdir('../')
        os.chdir('../')

    ############################################################
    # STEP 4. mosaic frames
    ############################################################
    from isceobj.Alos2Proc.runFrameMosaic import frameMosaic
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml

    for k in range(2):
        os.chdir(ionDir['subband'][k])

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

        numberOfFrames = len(referenceTrack.frames)
        if numberOfFrames == 1:
            import shutil
            frameDir = os.path.join('f1_{}/mosaic'.format(
                self._insar.referenceFrames[0]))
            # if not os.path.isfile(self._insar.interferogram):
            #     os.symlink(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram)
            # #shutil.copy2() can overwrite
            # shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
            # shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
            # if not os.path.isfile(self._insar.amplitude):
            #     os.symlink(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude)
            # shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
            # shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')

            os.rename(os.path.join('../', frameDir, self._insar.interferogram),
                      self._insar.interferogram)
            os.rename(
                os.path.join('../', frameDir,
                             self._insar.interferogram + '.vrt'),
                self._insar.interferogram + '.vrt')
            os.rename(
                os.path.join('../', frameDir,
                             self._insar.interferogram + '.xml'),
                self._insar.interferogram + '.xml')
            os.rename(os.path.join('../', frameDir, self._insar.amplitude),
                      self._insar.amplitude)
            os.rename(
                os.path.join('../', frameDir, self._insar.amplitude + '.vrt'),
                self._insar.amplitude + '.vrt')
            os.rename(
                os.path.join('../', frameDir, self._insar.amplitude + '.xml'),
                self._insar.amplitude + '.xml')

        else:
            #choose offsets
            if self.frameOffsetMatching:
                rangeOffsets = self._insar.frameRangeOffsetMatchingReference
                azimuthOffsets = self._insar.frameAzimuthOffsetMatchingReference
            else:
                rangeOffsets = self._insar.frameRangeOffsetGeometricalReference
                azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalReference

            #list of input files
            inputInterferograms = []
            inputAmplitudes = []
            for i, frameNumber in enumerate(self._insar.referenceFrames):
                frameDir = 'f{}_{}'.format(i + 1, frameNumber)
                inputInterferograms.append(
                    os.path.join('../', frameDir, 'mosaic',
                                 self._insar.interferogram))
                inputAmplitudes.append(
                    os.path.join('../', frameDir, 'mosaic',
                                 self._insar.amplitude))

            #note that track parameters are updated after mosaicking
            #mosaic amplitudes
            frameMosaic(referenceTrack,
                        inputAmplitudes,
                        self._insar.amplitude,
                        rangeOffsets,
                        azimuthOffsets,
                        self._insar.numberRangeLooks1,
                        self._insar.numberAzimuthLooks1,
                        updateTrack=False,
                        phaseCompensation=False,
                        resamplingMethod=0)
            #mosaic interferograms
            frameMosaic(referenceTrack,
                        inputInterferograms,
                        self._insar.interferogram,
                        rangeOffsets,
                        azimuthOffsets,
                        self._insar.numberRangeLooks1,
                        self._insar.numberAzimuthLooks1,
                        updateTrack=False,
                        phaseCompensation=True,
                        resamplingMethod=1)

            create_xml(self._insar.amplitude, referenceTrack.numberOfSamples,
                       referenceTrack.numberOfLines, 'amp')
            create_xml(self._insar.interferogram,
                       referenceTrack.numberOfSamples,
                       referenceTrack.numberOfLines, 'int')

        os.chdir('../')
        os.chdir('../')

    ############################################################
    # STEP 5. clear frame processing files
    ############################################################
    import shutil
    from isceobj.Alos2Proc.Alos2ProcPublic import runCmd

    for k in range(2):
        os.chdir(ionDir['subband'][k])
        for i, frameNumber in enumerate(self._insar.referenceFrames):
            frameDir = 'f{}_{}'.format(i + 1, frameNumber)
            shutil.rmtree(frameDir)
            #cmd = 'rm -rf {}'.format(frameDir)
            #runCmd(cmd)
        os.chdir('../')

    ############################################################
    # STEP 6. create differential interferograms
    ############################################################
    import numpy as np
    from isceobj.Alos2Proc.Alos2ProcPublic import runCmd

    for k in range(2):
        os.chdir(ionDir['subband'][k])

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

        rangePixelSize = self._insar.numberRangeLooks1 * referenceTrack.rangePixelSize
        radarWavelength = subbandRadarWavelength[k]
        rectRangeOffset = os.path.join('../../../', insarDir,
                                       self._insar.rectRangeOffset)

        cmd = "imageMath.py -e='a*exp(-1.0*J*b*4.0*{}*{}/{}) * (b!=0)' --a={} --b={} -o {} -t cfloat".format(
            np.pi, rangePixelSize, radarWavelength, self._insar.interferogram,
            rectRangeOffset, self._insar.differentialInterferogram)
        runCmd(cmd)

        os.chdir('../../')

    os.chdir('../')
    catalog.printToLog(logger, "runIonSubband")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #26
0
def swathMosaic(frame,
                inputFiles,
                outputfile,
                rangeOffsets,
                azimuthOffsets,
                numberOfRangeLooks,
                numberOfAzimuthLooks,
                updateFrame=False,
                phaseCompensation=False,
                pcRangeLooks=1,
                pcAzimuthLooks=4,
                filt=False,
                resamplingMethod=0):
    '''
    mosaic swaths
    
    frame:                 frame
    inputFiles:            input file list
    output file:           output mosaic file
    rangeOffsets:          range offsets
    azimuthOffsets:        azimuth offsets
    numberOfRangeLooks:    number of range looks of the input files
    numberOfAzimuthLooks:  number of azimuth looks of the input files
    phaseCompensation:     whether do phase compensation for each swath
    pcRangeLooks:          number of range looks to take when compute swath phase difference
    pcAzimuthLooks:        number of azimuth looks to take when compute swath phase difference
    filt:                  whether do filtering when compute swath phase difference
    resamplingMethod:      0: amp resampling. 1: int resampling.
    '''
    from contrib.alos2proc_f.alos2proc_f import rect_with_looks
    from contrib.alos2proc.alos2proc import mosaicsubswath
    from isceobj.Alos2Proc.Alos2ProcPublic import multilook
    from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence_1
    from isceobj.Alos2Proc.Alos2ProcPublic import filterInterferogram

    numberOfSwaths = len(frame.swaths)
    swaths = frame.swaths

    rangeScale = []
    azimuthScale = []
    rectWidth = []
    rectLength = []
    for i in range(numberOfSwaths):
        rangeScale.append(swaths[0].rangePixelSize / swaths[i].rangePixelSize)
        azimuthScale.append(swaths[0].azimuthLineInterval /
                            swaths[i].azimuthLineInterval)
        if i == 0:
            rectWidth.append(
                int(swaths[i].numberOfSamples / numberOfRangeLooks))
            rectLength.append(
                int(swaths[i].numberOfLines / numberOfAzimuthLooks))
        else:
            rectWidth.append(
                int(1.0 / rangeScale[i] *
                    int(swaths[i].numberOfSamples / numberOfRangeLooks)))
            rectLength.append(
                int(1.0 / azimuthScale[i] *
                    int(swaths[i].numberOfLines / numberOfAzimuthLooks)))

    #convert original offset to offset for images with looks
    #use list instead of np.array to make it consistent with the rest of the code
    rangeOffsets1 = [i / numberOfRangeLooks for i in rangeOffsets]
    azimuthOffsets1 = [i / numberOfAzimuthLooks for i in azimuthOffsets]

    #get offset relative to the first frame
    rangeOffsets2 = [0.0]
    azimuthOffsets2 = [0.0]
    for i in range(1, numberOfSwaths):
        rangeOffsets2.append(0.0)
        azimuthOffsets2.append(0.0)
        for j in range(1, i + 1):
            rangeOffsets2[i] += rangeOffsets1[j]
            azimuthOffsets2[i] += azimuthOffsets1[j]

    #resample each swath
    rinfs = []
    for i, inf in enumerate(inputFiles):
        rinfs.append("{}_{}{}".format(
            os.path.splitext(os.path.basename(inf))[0], i,
            os.path.splitext(os.path.basename(inf))[1]))
        #do not resample first swath
        if i == 0:
            if os.path.isfile(rinfs[i]):
                os.remove(rinfs[i])
            os.symlink(inf, rinfs[i])
        else:
            infImg = isceobj.createImage()
            infImg.load(inf + '.xml')
            rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
            azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i])

            if resamplingMethod == 0:
                rect_with_looks(inf, rinfs[i], infImg.width, infImg.length,
                                rectWidth[i], rectLength[i], rangeScale[i],
                                0.0, 0.0, azimuthScale[i],
                                rangeOffsets2Frac * rangeScale[i],
                                azimuthOffsets2Frac * azimuthScale[i], 1, 1, 1,
                                1, 'COMPLEX', 'Bilinear')
            elif resamplingMethod == 1:
                #decompose amplitude and phase
                phaseFile = 'phase'
                amplitudeFile = 'amplitude'
                data = np.fromfile(inf, dtype=np.complex64).reshape(
                    infImg.length, infImg.width)
                phase = np.exp(np.complex64(1j) * np.angle(data))
                phase[np.nonzero(data == 0)] = 0
                phase.astype(np.complex64).tofile(phaseFile)
                amplitude = np.absolute(data)
                amplitude.astype(np.float32).tofile(amplitudeFile)

                #resampling
                phaseRectFile = 'phaseRect'
                amplitudeRectFile = 'amplitudeRect'
                rect_with_looks(phaseFile, phaseRectFile, infImg.width,
                                infImg.length, rectWidth[i], rectLength[i],
                                rangeScale[i], 0.0, 0.0, azimuthScale[i],
                                rangeOffsets2Frac * rangeScale[i],
                                azimuthOffsets2Frac * azimuthScale[i], 1, 1, 1,
                                1, 'COMPLEX', 'Sinc')
                rect_with_looks(amplitudeFile, amplitudeRectFile, infImg.width,
                                infImg.length, rectWidth[i], rectLength[i],
                                rangeScale[i], 0.0, 0.0, azimuthScale[i],
                                rangeOffsets2Frac * rangeScale[i],
                                azimuthOffsets2Frac * azimuthScale[i], 1, 1, 1,
                                1, 'REAL', 'Bilinear')

                #recombine amplitude and phase
                phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(
                    rectLength[i], rectWidth[i])
                amplitude = np.fromfile(amplitudeRectFile,
                                        dtype=np.float32).reshape(
                                            rectLength[i], rectWidth[i])
                (phase * amplitude).astype(np.complex64).tofile(rinfs[i])

                #tidy up
                os.remove(phaseFile)
                os.remove(amplitudeFile)
                os.remove(phaseRectFile)
                os.remove(amplitudeRectFile)

    #determine output width and length
    #actually no need to calculate in range direction
    xs = []
    xe = []
    ys = []
    ye = []
    for i in range(numberOfSwaths):
        if i == 0:
            xs.append(0)
            xe.append(rectWidth[i] - 1)
            ys.append(0)
            ye.append(rectLength[i] - 1)
        else:
            xs.append(0 - int(rangeOffsets2[i]))
            xe.append(rectWidth[i] - 1 - int(rangeOffsets2[i]))
            ys.append(0 - int(azimuthOffsets2[i]))
            ye.append(rectLength[i] - 1 - int(azimuthOffsets2[i]))

    (xmin, xminIndex) = min((v, i) for i, v in enumerate(xs))
    (xmax, xmaxIndex) = max((v, i) for i, v in enumerate(xe))
    (ymin, yminIndex) = min((v, i) for i, v in enumerate(ys))
    (ymax, ymaxIndex) = max((v, i) for i, v in enumerate(ye))

    outWidth = xmax - xmin + 1
    outLength = ymax - ymin + 1

    #prepare offset for mosaicing
    rangeOffsets3 = []
    azimuthOffsets3 = []
    for i in range(numberOfSwaths):
        azimuthOffsets3.append(
            int(azimuthOffsets2[i]) - int(azimuthOffsets2[yminIndex]))
        if i != 0:
            rangeOffsets3.append(
                int(rangeOffsets2[i]) - int(rangeOffsets2[i - 1]))
        else:
            rangeOffsets3.append(0)

    delta = int(30 / numberOfRangeLooks)

    #compute compensation phase for each swath
    diffMean2 = [0.0 for i in range(numberOfSwaths)]
    if phaseCompensation:
        #compute swath phase offset
        diffMean = [0.0]
        for i in range(1, numberOfSwaths):
            #all indexes start with zero, all the computed start/end sample/line indexes are included.

            #no need to add edge here, as we are going to find first/last nonzero sample/lines later
            #edge = delta
            edge = 0

            #image i-1
            startSample1 = edge + 0 - int(rangeOffsets2[i]) + int(
                rangeOffsets2[i - 1])
            endSample1 = -edge + rectWidth[i - 1] - 1
            startLine1 = edge + max(
                0 - int(azimuthOffsets2[i]) + int(azimuthOffsets2[i - 1]), 0)
            endLine1 = -edge + min(
                rectLength[i] - 1 - int(azimuthOffsets2[i]) +
                int(azimuthOffsets2[i - 1]), rectLength[i - 1] - 1)
            data1 = readImage(rinfs[i - 1], rectWidth[i - 1],
                              rectLength[i - 1], startSample1, endSample1,
                              startLine1, endLine1)

            #image i
            startSample2 = edge + 0
            endSample2 = -edge + rectWidth[i - 1] - 1 - int(
                rangeOffsets2[i - 1]) + int(rangeOffsets2[i])
            startLine2 = edge + max(
                0 - int(azimuthOffsets2[i - 1]) + int(azimuthOffsets2[i]), 0)
            endLine2 = -edge + min(
                rectLength[i - 1] - 1 - int(azimuthOffsets2[i - 1]) +
                int(azimuthOffsets2[i]), rectLength[i] - 1)
            data2 = readImage(rinfs[i], rectWidth[i], rectLength[i],
                              startSample2, endSample2, startLine2, endLine2)

            #remove edge due to incomplete covolution in resampling
            edge = 9
            (startLine0, endLine0, startSample0, endSample0) = findNonzero(
                np.logical_and((data1 != 0), (data2 != 0)))
            data1 = data1[startLine0 + edge:endLine0 + 1 - edge,
                          startSample0 + edge:endSample0 + 1 - edge]
            data2 = data2[startLine0 + edge:endLine0 + 1 - edge,
                          startSample0 + edge:endSample0 + 1 - edge]

            #take looks
            data1 = multilook(data1, pcAzimuthLooks, pcRangeLooks)
            data2 = multilook(data2, pcAzimuthLooks, pcRangeLooks)

            #filter
            if filt:
                data1 /= (np.absolute(data1) + (data1 == 0))
                data2 /= (np.absolute(data2) + (data2 == 0))
                data1 = filterInterferogram(data1, 3.0, 64, 1)
                data2 = filterInterferogram(data2, 3.0, 64, 1)

            #get difference
            corth = 0.87
            if filt:
                corth = 0.90
            diffMean0 = 0.0
            for k in range(5):
                dataDiff = data1 * np.conj(data2)
                cor = cal_coherence_1(dataDiff, win=3)
                index = np.nonzero(np.logical_and(cor > corth, dataDiff != 0))
                if index[0].size < 100:
                    diffMean0 = 0.0
                    print(
                        '\n\nWARNING: too few high coherence pixels for swath phase difference estimation between swath {} and {}'
                        .format(i - 1, i))
                    print('       : first swath swath number: 0\n\n')
                    break
                angle = np.mean(np.angle(dataDiff[index]), dtype=np.float64)
                diffMean0 += angle
                data2 *= np.exp(np.complex64(1j) * angle)
                print('phase offset: %15.12f rad after loop: %3d' %
                      (diffMean0, k))

                DEBUG = False
                if DEBUG and (k == 0):
                    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
                    (lengthxx, widthxx) = dataDiff.shape
                    filtnamePrefix = 'subswath{}_subswath{}_loop{}'.format(
                        frame.swaths[i - 1].swathNumber,
                        frame.swaths[i].swathNumber, k)
                    cor.astype(np.float32).tofile(filtnamePrefix + '.cor')
                    create_xml(filtnamePrefix + '.cor', widthxx, lengthxx,
                               'float')
                    dataDiff.astype(np.complex64).tofile(filtnamePrefix +
                                                         '.int')
                    create_xml(filtnamePrefix + '.int', widthxx, lengthxx,
                               'int')

            diffMean.append(diffMean0)
            print('phase offset: subswath{} - subswath{}: {}'.format(
                frame.swaths[i - 1].swathNumber, frame.swaths[i].swathNumber,
                diffMean0))

        for i in range(1, numberOfSwaths):
            for j in range(1, i + 1):
                diffMean2[i] += diffMean[j]

    #mosaic swaths
    diffflag = 1
    oflag = [0 for i in range(numberOfSwaths)]
    mosaicsubswath(outputfile, outWidth, outLength, delta, diffflag,
                   numberOfSwaths, rinfs, rectWidth, rangeOffsets3,
                   azimuthOffsets3, diffMean2, oflag)
    #remove tmp files
    for x in rinfs:
        os.remove(x)

    #update frame parameters
    if updateFrame:
        #mosaic size
        frame.numberOfSamples = outWidth
        frame.numberOfLines = outLength
        #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
        #range parameters
        frame.startingRange = frame.swaths[0].startingRange
        frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate
        frame.rangePixelSize = frame.swaths[0].rangePixelSize
        #azimuth parameters
        azimuthTimeOffset = -max([
            int(x) for x in azimuthOffsets2
        ]) * numberOfAzimuthLooks * frame.swaths[0].azimuthLineInterval
        frame.sensingStart = frame.swaths[0].sensingStart + datetime.timedelta(
            seconds=azimuthTimeOffset)
        frame.prf = frame.swaths[0].prf
        frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize
        frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval
Beispiel #27
0
def runSwathMosaic(self):
    '''mosaic subswaths
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

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

    for i, frameNumber in enumerate(self._insar.masterFrames):
        frameDir = 'f{}_{}'.format(i + 1, frameNumber)
        os.chdir(frameDir)

        mosaicDir = 'mosaic'
        os.makedirs(mosaicDir, exist_ok=True)
        os.chdir(mosaicDir)

        if not (
               ((self._insar.modeCombination == 21) or \
                (self._insar.modeCombination == 22) or \
                (self._insar.modeCombination == 31) or \
                (self._insar.modeCombination == 32))
               and
               (self._insar.endingSwath-self._insar.startingSwath+1 > 1)
               ):
            import shutil
            swathDir = 's{}'.format(
                masterTrack.frames[i].swaths[0].swathNumber)

            if not os.path.isfile(self._insar.interferogram):
                os.symlink(
                    os.path.join('../', swathDir, self._insar.interferogram),
                    self._insar.interferogram)
            shutil.copy2(
                os.path.join('../', swathDir,
                             self._insar.interferogram + '.vrt'),
                self._insar.interferogram + '.vrt')
            shutil.copy2(
                os.path.join('../', swathDir,
                             self._insar.interferogram + '.xml'),
                self._insar.interferogram + '.xml')
            if not os.path.isfile(self._insar.amplitude):
                os.symlink(
                    os.path.join('../', swathDir, self._insar.amplitude),
                    self._insar.amplitude)
            shutil.copy2(
                os.path.join('../', swathDir, self._insar.amplitude + '.vrt'),
                self._insar.amplitude + '.vrt')
            shutil.copy2(
                os.path.join('../', swathDir, self._insar.amplitude + '.xml'),
                self._insar.amplitude + '.xml')

            # os.rename(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram)
            # os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt')
            # os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml')
            # os.rename(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude)
            # os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt')
            # os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml')

            #update frame parameters
            #########################################################
            frame = masterTrack.frames[i]
            infImg = isceobj.createImage()
            infImg.load(self._insar.interferogram + '.xml')
            #mosaic size
            frame.numberOfSamples = infImg.width
            frame.numberOfLines = infImg.length
            #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
            #range parameters
            frame.startingRange = frame.swaths[0].startingRange
            frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate
            frame.rangePixelSize = frame.swaths[0].rangePixelSize
            #azimuth parameters
            frame.sensingStart = frame.swaths[0].sensingStart
            frame.prf = frame.swaths[0].prf
            frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize
            frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval

            #update frame parameters, slave
            #########################################################
            frame = slaveTrack.frames[i]
            #mosaic size
            frame.numberOfSamples = int(frame.swaths[0].numberOfSamples /
                                        self._insar.numberRangeLooks1)
            frame.numberOfLines = int(frame.swaths[0].numberOfLines /
                                      self._insar.numberAzimuthLooks1)
            #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
            #range parameters
            frame.startingRange = frame.swaths[0].startingRange
            frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate
            frame.rangePixelSize = frame.swaths[0].rangePixelSize
            #azimuth parameters
            frame.sensingStart = frame.swaths[0].sensingStart
            frame.prf = frame.swaths[0].prf
            frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize
            frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval

            os.chdir('../')

            #save parameter file
            self._insar.saveProduct(masterTrack.frames[i],
                                    self._insar.masterFrameParameter)
            self._insar.saveProduct(slaveTrack.frames[i],
                                    self._insar.slaveFrameParameter)

            os.chdir('../')

            continue

        #choose offsets
        numberOfFrames = len(masterTrack.frames)
        numberOfSwaths = len(masterTrack.frames[i].swaths)
        if self.swathOffsetMatching:
            #no need to do this as the API support 2-d list
            #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths)
            #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths)
            rangeOffsets = self._insar.swathRangeOffsetMatchingMaster
            azimuthOffsets = self._insar.swathAzimuthOffsetMatchingMaster

        else:
            #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths)
            #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths)
            rangeOffsets = self._insar.swathRangeOffsetGeometricalMaster
            azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalMaster

        rangeOffsets = rangeOffsets[i]
        azimuthOffsets = azimuthOffsets[i]

        #list of input files
        inputInterferograms = []
        inputAmplitudes = []
        for j, swathNumber in enumerate(
                range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            swathDir = 's{}'.format(swathNumber)
            inputInterferograms.append(
                os.path.join('../', swathDir, self._insar.interferogram))
            inputAmplitudes.append(
                os.path.join('../', swathDir, self._insar.amplitude))

        #note that frame parameters are updated after mosaicking
        #mosaic amplitudes
        swathMosaic(masterTrack.frames[i],
                    inputAmplitudes,
                    self._insar.amplitude,
                    rangeOffsets,
                    azimuthOffsets,
                    self._insar.numberRangeLooks1,
                    self._insar.numberAzimuthLooks1,
                    resamplingMethod=0)
        #mosaic interferograms
        swathMosaic(masterTrack.frames[i],
                    inputInterferograms,
                    self._insar.interferogram,
                    rangeOffsets,
                    azimuthOffsets,
                    self._insar.numberRangeLooks1,
                    self._insar.numberAzimuthLooks1,
                    updateFrame=True,
                    resamplingMethod=1)

        create_xml(self._insar.amplitude,
                   masterTrack.frames[i].numberOfSamples,
                   masterTrack.frames[i].numberOfLines, 'amp')
        create_xml(self._insar.interferogram,
                   masterTrack.frames[i].numberOfSamples,
                   masterTrack.frames[i].numberOfLines, 'int')

        #update slave frame parameters here
        #no matching for slave, always use geometry
        rangeOffsets = self._insar.swathRangeOffsetGeometricalSlave
        azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalSlave
        rangeOffsets = rangeOffsets[i]
        azimuthOffsets = azimuthOffsets[i]
        swathMosaicParameters(slaveTrack.frames[i], rangeOffsets,
                              azimuthOffsets, self._insar.numberRangeLooks1,
                              self._insar.numberAzimuthLooks1)

        os.chdir('../')

        #save parameter file
        self._insar.saveProduct(masterTrack.frames[i],
                                self._insar.masterFrameParameter)
        self._insar.saveProduct(slaveTrack.frames[i],
                                self._insar.slaveFrameParameter)

        os.chdir('../')

    catalog.printToLog(logger, "runSwathMosaic")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #28
0
def runRdrDemOffset(self):
    '''estimate between radar image and dem
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    referenceTrack = self._insar.loadTrack(reference=True)
    demFile = os.path.abspath(self._insar.dem)

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

    rdrDemDir = 'rdr_dem_offset'
    os.makedirs(rdrDemDir, exist_ok=True)
    os.chdir(rdrDemDir)

    ##################################################################################################
    #compute dem pixel size
    demImage = isceobj.createDemImage()
    demImage.load(demFile + '.xml')
    #DEM pixel size in meters (appoximate value)
    demDeltaLon = abs(demImage.getDeltaLongitude()) / 0.0002777777777777778 * 30.0
    demDeltaLat = abs(demImage.getDeltaLatitude())  / 0.0002777777777777778 * 30.0

    #number of looks to take in range
    if self._insar.numberRangeLooksSim == None:
        if self._insar.numberRangeLooks1 * referenceTrack.rangePixelSize > demDeltaLon:
            self._insar.numberRangeLooksSim = 1
        else:
            self._insar.numberRangeLooksSim = int(demDeltaLon / (self._insar.numberRangeLooks1 * referenceTrack.rangePixelSize) + 0.5)
    #number of looks to take in azimuth
    if self._insar.numberAzimuthLooksSim == None:
        if self._insar.numberAzimuthLooks1 * referenceTrack.azimuthPixelSize > demDeltaLat:
            self._insar.numberAzimuthLooksSim = 1
        else:
            self._insar.numberAzimuthLooksSim = int(demDeltaLat / (self._insar.numberAzimuthLooks1 * referenceTrack.azimuthPixelSize) + 0.5)

    #simulate a radar image using dem
    simulateRadar(os.path.join('../', self._insar.height), self._insar.sim, scale=3.0, offset=100.0)
    sim = isceobj.createImage()
    sim.load(self._insar.sim+'.xml')

    #take looks
    if (self._insar.numberRangeLooksSim == 1) and (self._insar.numberAzimuthLooksSim == 1):
        simLookFile = self._insar.sim
        ampLookFile = 'amp_{}rlks_{}alks.float'.format(self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, 
                                                       self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1)
        cmd = "imageMath.py -e='sqrt(a_0*a_0+a_1*a_1)' --a={} -o {} -t float".format(os.path.join('../', self._insar.amplitude), ampLookFile)
        runCmd(cmd)
    else:
        simLookFile = 'sim_{}rlks_{}alks.float'.format(self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, 
                                                       self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1)
        ampLookFile = 'amp_{}rlks_{}alks.float'.format(self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, 
                                                       self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1)
        ampTmpFile = 'amp_tmp.float'
        look(self._insar.sim, simLookFile, sim.width, self._insar.numberRangeLooksSim, self._insar.numberAzimuthLooksSim, 2, 0, 1)
        look(os.path.join('../', self._insar.amplitude), ampTmpFile, sim.width, self._insar.numberRangeLooksSim, self._insar.numberAzimuthLooksSim, 4, 1, 1)
 
        width = int(sim.width/self._insar.numberRangeLooksSim)
        length = int(sim.length/self._insar.numberAzimuthLooksSim)
        create_xml(simLookFile, width, length, 'float')
        create_xml(ampTmpFile, width, length, 'amp')

        cmd = "imageMath.py -e='sqrt(a_0*a_0+a_1*a_1)' --a={} -o {} -t float".format(ampTmpFile, ampLookFile)
        runCmd(cmd)
        os.remove(ampTmpFile)
        os.remove(ampTmpFile+'.vrt')
        os.remove(ampTmpFile+'.xml')

    #initial number of offsets to use
    numberOfOffsets = 800
    #compute land ratio to further determine the number of offsets to use
    wbd=np.memmap(os.path.join('../', self._insar.wbdOut), dtype='byte', mode='r', shape=(sim.length, sim.width))
    landRatio = np.sum(wbd[0:sim.length:10, 0:sim.width:10]!=-1) / int(sim.length/10) / int(sim.width/10)
    del wbd
    if (landRatio <= 0.00125):
        print('\n\nWARNING: land area too small for estimating offsets between radar and dem')
        print('do not estimate offsets between radar and dem\n\n')
        self._insar.radarDemAffineTransform = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
        catalog.addItem('warning message', 'land area too small for estimating offsets between radar and dem', 'runRdrDemOffset')

        os.chdir('../../')

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

        return

    #total number of offsets to use
    numberOfOffsets /= landRatio
    #allocate number of offsets in range/azimuth according to image width/length
    width = int(sim.width/self._insar.numberRangeLooksSim)
    length = int(sim.length/self._insar.numberAzimuthLooksSim)
    #number of offsets to use in range/azimuth
    numberOfOffsetsRange = int(np.sqrt(numberOfOffsets * width / length))
    numberOfOffsetsAzimuth = int(length / width * np.sqrt(numberOfOffsets * width / length))

    #this should be better?
    numberOfOffsetsRange = int(np.sqrt(numberOfOffsets))
    numberOfOffsetsAzimuth = int(np.sqrt(numberOfOffsets))


    if numberOfOffsetsRange > int(width/2):
        numberOfOffsetsRange = int(width/2)
    if numberOfOffsetsAzimuth > int(length/2):
        numberOfOffsetsAzimuth = int(length/2)

    if numberOfOffsetsRange < 10:
        numberOfOffsetsRange = 10
    if numberOfOffsetsAzimuth < 10:
        numberOfOffsetsAzimuth = 10

    catalog.addItem('number of range offsets', '{}'.format(numberOfOffsetsRange), 'runRdrDemOffset')
    catalog.addItem('number of azimuth offsets', '{}'.format(numberOfOffsetsAzimuth), 'runRdrDemOffset')

    #matching
    ampcor = Ampcor(name='insarapp_slcs_ampcor')
    ampcor.configure()

    mMag = isceobj.createImage()
    mMag.load(ampLookFile+'.xml')
    mMag.setAccessMode('read')
    mMag.createImage()

    sMag = isceobj.createImage()
    sMag.load(simLookFile+'.xml')
    sMag.setAccessMode('read')
    sMag.createImage()

    ampcor.setImageDataType1('real')
    ampcor.setImageDataType2('real')

    ampcor.setReferenceSlcImage(mMag)
    ampcor.setSecondarySlcImage(sMag)

    #MATCH REGION
    rgoff = 0
    azoff = 0
    #it seems that we cannot use 0, haven't look into the problem
    if rgoff == 0:
        rgoff = 1
    if azoff == 0:
        azoff = 1
    firstSample = 1
    if rgoff < 0:
        firstSample = int(35 - rgoff)
    firstLine = 1
    if azoff < 0:
        firstLine = int(35 - azoff)
    ampcor.setAcrossGrossOffset(rgoff)
    ampcor.setDownGrossOffset(azoff)
    ampcor.setFirstSampleAcross(firstSample)
    ampcor.setLastSampleAcross(width)
    ampcor.setNumberLocationAcross(numberOfOffsetsRange)
    ampcor.setFirstSampleDown(firstLine)
    ampcor.setLastSampleDown(length)
    ampcor.setNumberLocationDown(numberOfOffsetsAzimuth)

    #MATCH PARAMETERS
    ampcor.setWindowSizeWidth(64)
    ampcor.setWindowSizeHeight(64)
    #note this is the half width/length of search area, so number of resulting correlation samples: 8*2+1
    ampcor.setSearchWindowSizeWidth(16)
    ampcor.setSearchWindowSizeHeight(16)

    #REST OF THE STUFF
    ampcor.setAcrossLooks(1)
    ampcor.setDownLooks(1)
    ampcor.setOversamplingFactor(64)
    ampcor.setZoomWindowSize(16)
    #1. The following not set
    #Matching Scale for Sample/Line Directions                       (-)    = 1. 1.
    #should add the following in Ampcor.py?
    #if not set, in this case, Ampcor.py'value is also 1. 1.
    #ampcor.setScaleFactorX(1.)
    #ampcor.setScaleFactorY(1.)

    #MATCH THRESHOLDS AND DEBUG DATA
    #2. The following not set
    #in roi_pac the value is set to 0 1
    #in isce the value is set to 0.001 1000.0
    #SNR and Covariance Thresholds                                   (-)    =  {s1} {s2}
    #should add the following in Ampcor?
    #THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC
    #ampcor.setThresholdSNR(0)
    #ampcor.setThresholdCov(1)
    ampcor.setDebugFlag(False)
    ampcor.setDisplayFlag(False)

    #in summary, only two things not set which are indicated by 'The following not set' above.

    #run ampcor
    ampcor.ampcor()
    offsets = ampcor.getOffsetField()
    ampcorOffsetFile = 'ampcor.off'
    cullOffsetFile = 'cull.off'
    affineTransformFile = 'affine_transform.txt'
    writeOffset(offsets, ampcorOffsetFile)

    #finalize image, and re-create it
    #otherwise the file pointer is still at the end of the image
    mMag.finalizeImage()
    sMag.finalizeImage()

    # #cull offsets
    # import io
    # from contextlib import redirect_stdout
    # f = io.StringIO()
    # with redirect_stdout(f):
    #     fitoff(ampcorOffsetFile, cullOffsetFile, 1.5, .5, 50)
    # s = f.getvalue()
    # #print(s)
    # with open(affineTransformFile, 'w') as f:
    #     f.write(s)

    #cull offsets
    import subprocess
    proc = subprocess.Popen(["python3", "-c", "import isce; from contrib.alos2proc_f.alos2proc_f import fitoff; fitoff('ampcor.off', 'cull.off', 1.5, .5, 50)"], stdout=subprocess.PIPE)
    out = proc.communicate()[0]
    with open(affineTransformFile, 'w') as f:
        f.write(out.decode('utf-8'))

    #check number of offsets left
    with open(cullOffsetFile, 'r') as f:
        numCullOffsets = sum(1 for linex in f)
    if numCullOffsets < 50:
        print('\n\nWARNING: too few points left after culling, {} left'.format(numCullOffsets))
        print('do not estimate offsets between radar and dem\n\n')
        self._insar.radarDemAffineTransform = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
        catalog.addItem('warning message', 'too few points left after culling, {} left'.format(numCullOffsets), 'runRdrDemOffset')

        os.chdir('../../')

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

        return

    #read affine transform parameters
    with open(affineTransformFile) as f:
        lines = f.readlines()
    i = 0
    for linex in lines:
        if 'Affine Matrix ' in linex:
            m11 = float(lines[i + 2].split()[0])
            m12 = float(lines[i + 2].split()[1])
            m21 = float(lines[i + 3].split()[0])
            m22 = float(lines[i + 3].split()[1])
            t1  = float(lines[i + 7].split()[0])
            t2  = float(lines[i + 7].split()[1])
            break
        i += 1    

    self._insar.radarDemAffineTransform = [m11, m12, m21, m22, t1, t2]
    ##################################################################################################

    os.chdir('../../')


    catalog.printToLog(logger, "runRdrDemOffset")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #29
0
def runIonUwrap(self):
    '''unwrap subband interferograms
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    if not self.doIon:
        catalog.printToLog(logger, "runIonUwrap")
        self._insar.procDoc.addAllFromCatalog(catalog)
        return

    referenceTrack = self._insar.loadTrack(reference=True)
    secondaryTrack = self._insar.loadTrack(reference=False)
    wbdFile = os.path.abspath(self._insar.wbd)

    from isceobj.Alos2Proc.runIonSubband import defineIonDir
    ionDir = defineIonDir()
    subbandPrefix = ['lower', 'upper']

    ionCalDir = os.path.join(ionDir['ion'], ionDir['ionCal'])
    os.makedirs(ionCalDir, exist_ok=True)
    os.chdir(ionCalDir)


    ############################################################
    # STEP 1. take looks
    ############################################################
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
    from contrib.alos2proc.alos2proc import look
    from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar

    ml2 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon, 
                              self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon)

    for k in range(2):
        fullbandDir = os.path.join('../../', ionDir['insar'])
        subbandDir = os.path.join('../', ionDir['subband'][k], ionDir['insar'])
        prefix = subbandPrefix[k]

        amp = isceobj.createImage()
        amp.load(os.path.join(subbandDir, self._insar.amplitude)+'.xml')
        width = amp.width
        length = amp.length
        width2 = int(width / self._insar.numberRangeLooksIon)
        length2 = int(length / self._insar.numberAzimuthLooksIon)

        #take looks
        look(os.path.join(subbandDir, self._insar.differentialInterferogram), prefix+ml2+'.int', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 4, 0, 1)
        create_xml(prefix+ml2+'.int', width2, length2, 'int')
        look(os.path.join(subbandDir, self._insar.amplitude), prefix+ml2+'.amp', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 4, 1, 1)
        create_xml(prefix+ml2+'.amp', width2, length2, 'amp')

        # #water body
        # if k == 0:
        #     wbdOutFile = os.path.join(fullbandDir, self._insar.wbdOut)
        #     if os.path.isfile(wbdOutFile):
        #         look(wbdOutFile, 'wbd'+ml2+'.wbd', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 0, 0, 1)
        #         create_xml('wbd'+ml2+'.wbd', width2, length2, 'byte')

        #water body
        if k == 0:
            look(os.path.join(fullbandDir, self._insar.latitude), 'lat'+ml2+'.lat', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 3, 0, 1)
            look(os.path.join(fullbandDir, self._insar.longitude), 'lon'+ml2+'.lon', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 3, 0, 1)
            create_xml('lat'+ml2+'.lat', width2, length2, 'double')
            create_xml('lon'+ml2+'.lon', width2, length2, 'double')
            waterBodyRadar('lat'+ml2+'.lat', 'lon'+ml2+'.lon', wbdFile, 'wbd'+ml2+'.wbd')


    ############################################################
    # STEP 2. compute coherence
    ############################################################
    from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence

    lowerbandInterferogramFile = subbandPrefix[0]+ml2+'.int'
    upperbandInterferogramFile = subbandPrefix[1]+ml2+'.int'
    lowerbandAmplitudeFile = subbandPrefix[0]+ml2+'.amp'
    upperbandAmplitudeFile = subbandPrefix[1]+ml2+'.amp'
    lowerbandCoherenceFile = subbandPrefix[0]+ml2+'.cor'
    upperbandCoherenceFile = subbandPrefix[1]+ml2+'.cor'
    coherenceFile = 'diff'+ml2+'.cor'

    lowerint = np.fromfile(lowerbandInterferogramFile, dtype=np.complex64).reshape(length2, width2)
    upperint = np.fromfile(upperbandInterferogramFile, dtype=np.complex64).reshape(length2, width2)
    loweramp = np.fromfile(lowerbandAmplitudeFile, dtype=np.float32).reshape(length2, width2*2)
    upperamp = np.fromfile(upperbandAmplitudeFile, dtype=np.float32).reshape(length2, width2*2)

    #compute coherence only using interferogram
    #here I use differential interferogram of lower and upper band interferograms
    #so that coherence is not affected by fringes
    cord = cal_coherence(lowerint*np.conjugate(upperint), win=3, edge=4)
    cor = np.zeros((length2*2, width2), dtype=np.float32)
    cor[0:length2*2:2, :] = np.sqrt( (np.absolute(lowerint)+np.absolute(upperint))/2.0 )
    cor[1:length2*2:2, :] = cord
    cor.astype(np.float32).tofile(coherenceFile)
    create_xml(coherenceFile, width2, length2, 'cor')

    #create lower and upper band coherence files
    #lower
    amp1 = loweramp[:, 0:width2*2:2]
    amp2 = loweramp[:, 1:width2*2:2]
    cor[1:length2*2:2, :] = np.absolute(lowerint)/(amp1+(amp1==0))/(amp2+(amp2==0))*(amp1!=0)*(amp2!=0)
    cor.astype(np.float32).tofile(lowerbandCoherenceFile)
    create_xml(lowerbandCoherenceFile, width2, length2, 'cor')

    #upper
    amp1 = upperamp[:, 0:width2*2:2]
    amp2 = upperamp[:, 1:width2*2:2]
    cor[1:length2*2:2, :] = np.absolute(upperint)/(amp1+(amp1==0))/(amp2+(amp2==0))*(amp1!=0)*(amp2!=0)
    cor.astype(np.float32).tofile(upperbandCoherenceFile)
    create_xml(upperbandCoherenceFile, width2, length2, 'cor')


    ############################################################
    # STEP 3. filtering subband interferograms
    ############################################################
    from contrib.alos2filter.alos2filter import psfilt1
    from isceobj.Alos2Proc.Alos2ProcPublic import runCmd
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
    from mroipac.icu.Icu import Icu

    if self.filterSubbandInt:
        for k in range(2):
            toBeFiltered = 'tmp.int'
            if self.removeMagnitudeBeforeFilteringSubbandInt:
                cmd = "imageMath.py -e='a/(abs(a)+(a==0))' --a={} -o {} -t cfloat -s BSQ".format(subbandPrefix[k]+ml2+'.int', toBeFiltered)
            else:
                #scale the inteferogram, otherwise its magnitude is too large for filtering
                cmd = "imageMath.py -e='a/100000.0' --a={} -o {} -t cfloat -s BSQ".format(subbandPrefix[k]+ml2+'.int', toBeFiltered)
            runCmd(cmd)

            intImage = isceobj.createIntImage()
            intImage.load(toBeFiltered + '.xml')
            width = intImage.width
            length = intImage.length

            windowSize = self.filterWinsizeSubbandInt
            stepSize = self.filterStepsizeSubbandInt
            psfilt1(toBeFiltered, 'filt_'+subbandPrefix[k]+ml2+'.int', width, self.filterStrengthSubbandInt, windowSize, stepSize)
            create_xml('filt_'+subbandPrefix[k]+ml2+'.int', width, length, 'int')

            os.remove(toBeFiltered)
            os.remove(toBeFiltered + '.vrt')
            os.remove(toBeFiltered + '.xml')

            #create phase sigma for phase unwrapping
            #recreate filtered image
            filtImage = isceobj.createIntImage()
            filtImage.load('filt_'+subbandPrefix[k]+ml2+'.int' + '.xml')
            filtImage.setAccessMode('read')
            filtImage.createImage()

            #amplitude image
            ampImage = isceobj.createAmpImage()
            ampImage.load(subbandPrefix[k]+ml2+'.amp' + '.xml')
            ampImage.setAccessMode('read')
            ampImage.createImage()

            #phase sigma correlation image
            phsigImage = isceobj.createImage()
            phsigImage.setFilename(subbandPrefix[k]+ml2+'.phsig')
            phsigImage.setWidth(width)
            phsigImage.dataType='FLOAT'
            phsigImage.bands = 1
            phsigImage.setImageType('cor')
            phsigImage.setAccessMode('write')
            phsigImage.createImage()

            icu = Icu(name='insarapp_filter_icu')
            icu.configure()
            icu.unwrappingFlag = False
            icu.icu(intImage = filtImage, ampImage=ampImage, phsigImage=phsigImage)

            phsigImage.renderHdr()

            filtImage.finalizeImage()
            ampImage.finalizeImage()
            phsigImage.finalizeImage()


    ############################################################
    # STEP 4. phase unwrapping
    ############################################################
    from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrap

    for k in range(2):
        tmid = referenceTrack.sensingStart + datetime.timedelta(seconds=(self._insar.numberAzimuthLooks1-1.0)/2.0*referenceTrack.azimuthLineInterval+
               referenceTrack.numberOfLines/2.0*self._insar.numberAzimuthLooks1*referenceTrack.azimuthLineInterval)

        if self.filterSubbandInt:
            toBeUnwrapped = 'filt_'+subbandPrefix[k]+ml2+'.int'
            coherenceFile = subbandPrefix[k]+ml2+'.phsig'
        else:
            toBeUnwrapped = subbandPrefix[k]+ml2+'.int'
            coherenceFile = 'diff'+ml2+'.cor'

        snaphuUnwrap(referenceTrack, tmid, 
            toBeUnwrapped, 
            coherenceFile, 
            subbandPrefix[k]+ml2+'.unw', 
            self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon, 
            self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon, 
            costMode = 'SMOOTH',initMethod = 'MCF', defomax = 2, initOnly = True)


    os.chdir('../../')
    catalog.printToLog(logger, "runIonUwrap")
    self._insar.procDoc.addAllFromCatalog(catalog)
Beispiel #30
0
def runCoregCc(self):
    '''coregister bursts by cross correlation
    '''
    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

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

    #demFile = os.path.abspath(self._insar.dem)
    #wbdFile = os.path.abspath(self._insar.wbd)
    ###############################################################################
    self._insar.rangeResidualOffsetCc = [
        [] for i in range(len(masterTrack.frames))
    ]
    self._insar.azimuthResidualOffsetCc = [
        [] for i in range(len(masterTrack.frames))
    ]
    for i, frameNumber in enumerate(self._insar.masterFrames):
        frameDir = 'f{}_{}'.format(i + 1, frameNumber)
        os.chdir(frameDir)
        for j, swathNumber in enumerate(
                range(self._insar.startingSwath, self._insar.endingSwath + 1)):
            swathDir = 's{}'.format(swathNumber)
            os.chdir(swathDir)

            print('processing frame {}, swath {}'.format(
                frameNumber, swathNumber))

            masterSwath = masterTrack.frames[i].swaths[j]
            slaveSwath = slaveTrack.frames[i].swaths[j]

            ##################################################
            # estimate cross-correlation offsets
            ##################################################
            #compute number of offsets to use
            wbdImg = isceobj.createImage()
            wbdImg.load(self._insar.wbdOut + '.xml')
            width = wbdImg.width
            length = wbdImg.length

            #initial number of offsets to use
            numberOfOffsets = 800

            #compute land ratio to further determine the number of offsets to use
            if self.useWbdForNumberOffsets:
                wbd = np.memmap(self._insar.wbdOut,
                                dtype='byte',
                                mode='r',
                                shape=(length, width))
                landRatio = np.sum(wbd == 0) / length / width
                del wbd
                if (landRatio <= 0.00125):
                    print(
                        '\n\nWARNING: land area too small for estimating offsets between master and slave magnitudes at frame {}, swath {}'
                        .format(frameNumber, swathNumber))
                    print('set offsets to zero\n\n')
                    self._insar.rangeResidualOffsetCc[i].append(0.0)
                    self._insar.azimuthResidualOffsetCc[i].append(0.0)
                    catalog.addItem(
                        'warning message',
                        'land area too small for estimating offsets between master and slave magnitudes at frame {}, swath {}'
                        .format(frameNumber, swathNumber), 'runCoregCc')
                    continue
                #total number of offsets to use
                numberOfOffsets /= landRatio

            #allocate number of offsets in range/azimuth according to image width/length
            #number of offsets to use in range/azimuth
            numberOfOffsetsRange = int(
                np.sqrt(numberOfOffsets * width / length))
            numberOfOffsetsAzimuth = int(
                length / width * np.sqrt(numberOfOffsets * width / length))

            #this should be better?
            numberOfOffsetsRange = int(np.sqrt(numberOfOffsets))
            numberOfOffsetsAzimuth = int(np.sqrt(numberOfOffsets))

            if numberOfOffsetsRange > int(width / 2):
                numberOfOffsetsRange = int(width / 2)
            if numberOfOffsetsAzimuth > int(length / 2):
                numberOfOffsetsAzimuth = int(length / 2)

            if numberOfOffsetsRange < 10:
                numberOfOffsetsRange = 10
            if numberOfOffsetsAzimuth < 10:
                numberOfOffsetsAzimuth = 10

            #user's settings
            if self.numberRangeOffsets != None:
                numberOfOffsetsRange = self.numberRangeOffsets[i][j]
            if self.numberAzimuthOffsets != None:
                numberOfOffsetsAzimuth = self.numberAzimuthOffsets[i][j]

            catalog.addItem(
                'number of range offsets at frame {}, swath {}'.format(
                    frameNumber, swathNumber),
                '{}'.format(numberOfOffsetsRange), 'runCoregCc')
            catalog.addItem(
                'number of azimuth offsets at frame {}, swath {}'.format(
                    frameNumber, swathNumber),
                '{}'.format(numberOfOffsetsAzimuth), 'runCoregCc')

            #need to cp to current directory to make it (gdal) work
            if not os.path.isfile(self._insar.masterMagnitude):
                os.symlink(
                    os.path.join(self._insar.masterBurstPrefix,
                                 self._insar.masterMagnitude),
                    self._insar.masterMagnitude)
            #shutil.copy2() can overwrite
            shutil.copy2(
                os.path.join(self._insar.masterBurstPrefix,
                             self._insar.masterMagnitude + '.vrt'),
                self._insar.masterMagnitude + '.vrt')
            shutil.copy2(
                os.path.join(self._insar.masterBurstPrefix,
                             self._insar.masterMagnitude + '.xml'),
                self._insar.masterMagnitude + '.xml')

            if not os.path.isfile(self._insar.slaveMagnitude):
                os.symlink(
                    os.path.join(
                        self._insar.slaveBurstPrefix + '_1_coreg_geom',
                        self._insar.slaveMagnitude),
                    self._insar.slaveMagnitude)
            #shutil.copy2() can overwrite
            shutil.copy2(
                os.path.join(self._insar.slaveBurstPrefix + '_1_coreg_geom',
                             self._insar.slaveMagnitude + '.vrt'),
                self._insar.slaveMagnitude + '.vrt')
            shutil.copy2(
                os.path.join(self._insar.slaveBurstPrefix + '_1_coreg_geom',
                             self._insar.slaveMagnitude + '.xml'),
                self._insar.slaveMagnitude + '.xml')

            #matching
            ampcor = Ampcor(name='insarapp_slcs_ampcor')
            ampcor.configure()

            mMag = isceobj.createImage()
            mMag.load(self._insar.masterMagnitude + '.xml')
            mMag.setAccessMode('read')
            mMag.createImage()

            sMag = isceobj.createImage()
            sMag.load(self._insar.slaveMagnitude + '.xml')
            sMag.setAccessMode('read')
            sMag.createImage()

            ampcor.setImageDataType1('real')
            ampcor.setImageDataType2('real')

            ampcor.setMasterSlcImage(mMag)
            ampcor.setSlaveSlcImage(sMag)

            #MATCH REGION
            rgoff = 0
            azoff = 0
            #it seems that we cannot use 0, haven't look into the problem
            if rgoff == 0:
                rgoff = 1
            if azoff == 0:
                azoff = 1
            firstSample = 1
            if rgoff < 0:
                firstSample = int(35 - rgoff)
            firstLine = 1
            if azoff < 0:
                firstLine = int(35 - azoff)
            ampcor.setAcrossGrossOffset(rgoff)
            ampcor.setDownGrossOffset(azoff)
            ampcor.setFirstSampleAcross(firstSample)
            ampcor.setLastSampleAcross(mMag.width)
            ampcor.setNumberLocationAcross(numberOfOffsetsRange)
            ampcor.setFirstSampleDown(firstLine)
            ampcor.setLastSampleDown(mMag.length)
            ampcor.setNumberLocationDown(numberOfOffsetsAzimuth)

            #MATCH PARAMETERS
            ampcor.setWindowSizeWidth(64)
            ampcor.setWindowSizeHeight(64)
            #note this is the half width/length of search area, so number of resulting correlation samples: 8*2+1
            ampcor.setSearchWindowSizeWidth(8)
            ampcor.setSearchWindowSizeHeight(8)

            #REST OF THE STUFF
            ampcor.setAcrossLooks(1)
            ampcor.setDownLooks(1)
            ampcor.setOversamplingFactor(64)
            ampcor.setZoomWindowSize(16)
            #1. The following not set
            #Matching Scale for Sample/Line Directions                       (-)    = 1. 1.
            #should add the following in Ampcor.py?
            #if not set, in this case, Ampcor.py'value is also 1. 1.
            #ampcor.setScaleFactorX(1.)
            #ampcor.setScaleFactorY(1.)

            #MATCH THRESHOLDS AND DEBUG DATA
            #2. The following not set
            #in roi_pac the value is set to 0 1
            #in isce the value is set to 0.001 1000.0
            #SNR and Covariance Thresholds                                   (-)    =  {s1} {s2}
            #should add the following in Ampcor?
            #THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC
            #ampcor.setThresholdSNR(0)
            #ampcor.setThresholdCov(1)
            ampcor.setDebugFlag(False)
            ampcor.setDisplayFlag(False)

            #in summary, only two things not set which are indicated by 'The following not set' above.

            #run ampcor
            ampcor.ampcor()
            offsets = ampcor.getOffsetField()
            refinedOffsets = cullOffsetsRoipac(offsets, numThreshold=50)

            #finalize image, and re-create it
            #otherwise the file pointer is still at the end of the image
            mMag.finalizeImage()
            sMag.finalizeImage()

            #clear up
            os.remove(self._insar.masterMagnitude)
            os.remove(self._insar.masterMagnitude + '.vrt')
            os.remove(self._insar.masterMagnitude + '.xml')
            os.remove(self._insar.slaveMagnitude)
            os.remove(self._insar.slaveMagnitude + '.vrt')
            os.remove(self._insar.slaveMagnitude + '.xml')

            #compute average offsets to use in resampling
            if refinedOffsets == None:
                rangeOffset = 0
                azimuthOffset = 0
                self._insar.rangeResidualOffsetCc[i].append(rangeOffset)
                self._insar.azimuthResidualOffsetCc[i].append(azimuthOffset)
                print(
                    '\n\nWARNING: too few offsets left in matching master and slave magnitudes at frame {}, swath {}'
                    .format(frameNumber, swathNumber))
                print('set offsets to zero\n\n')
                catalog.addItem(
                    'warning message',
                    'too few offsets left in matching master and slave magnitudes at frame {}, swath {}'
                    .format(frameNumber, swathNumber), 'runCoregCc')
            else:
                rangeOffset, azimuthOffset = meanOffset(refinedOffsets)
                #for range offset, need to compute from a polynomial
                #see components/isceobj/Location/Offset.py and components/isceobj/Util/Library/python/Poly2D.py for definations
                (azimuthPoly,
                 rangePoly) = refinedOffsets.getFitPolynomials(rangeOrder=2,
                                                               azimuthOrder=2)
                #make a deep copy, otherwise it also changes original coefficient list of rangePoly, which affects following rangePoly(*, *) computation
                polyCoeff = copy.deepcopy(rangePoly.getCoeffs())
                rgIndex = (np.arange(width) - rangePoly.getMeanRange()
                           ) / rangePoly.getNormRange()
                azIndex = (np.arange(length) - rangePoly.getMeanAzimuth()
                           ) / rangePoly.getNormAzimuth()
                rangeOffset =  polyCoeff[0][0] + polyCoeff[0][1]*rgIndex[None,:] + polyCoeff[0][2]*rgIndex[None,:]**2 + \
                              (polyCoeff[1][0] + polyCoeff[1][1]*rgIndex[None,:]) * azIndex[:, None] + \
                               polyCoeff[2][0] * azIndex[:, None]**2
                polyCoeff.append([
                    rangePoly.getMeanRange(),
                    rangePoly.getNormRange(),
                    rangePoly.getMeanAzimuth(),
                    rangePoly.getNormAzimuth()
                ])
                self._insar.rangeResidualOffsetCc[i].append(polyCoeff)
                self._insar.azimuthResidualOffsetCc[i].append(azimuthOffset)

                catalog.addItem(
                    'range residual offset at {} {} at frame {}, swath {}'.
                    format(0, 0, frameNumber, swathNumber),
                    '{}'.format(rangePoly(0, 0)), 'runCoregCc')
                catalog.addItem(
                    'range residual offset at {} {} at frame {}, swath {}'.
                    format(0, width - 1, frameNumber, swathNumber),
                    '{}'.format(rangePoly(0, width - 1)), 'runCoregCc')
                catalog.addItem(
                    'range residual offset at {} {} at frame {}, swath {}'.
                    format(length - 1, 0, frameNumber, swathNumber),
                    '{}'.format(rangePoly(length - 1, 0)), 'runCoregCc')
                catalog.addItem(
                    'range residual offset at {} {} at frame {}, swath {}'.
                    format(length - 1, width - 1, frameNumber, swathNumber),
                    '{}'.format(rangePoly(length - 1,
                                          width - 1)), 'runCoregCc')
                catalog.addItem(
                    'azimuth residual offset at frame {}, swath {}'.format(
                        frameNumber, swathNumber), '{}'.format(azimuthOffset),
                    'runCoregCc')

                DEBUG = False
                if DEBUG:
                    print('+++++++++++++++++++++++++++++')
                    print(rangeOffset[0, 0], rangePoly(0, 0))
                    print(rangeOffset[0, width - 1], rangePoly(0, width - 1))
                    print(rangeOffset[length - 1, 0], rangePoly(length - 1, 0))
                    print(rangeOffset[length - 1, width - 1],
                          rangePoly(length - 1, width - 1))
                    print(
                        rangeOffset[int((length - 1) / 2),
                                    int((width - 1) / 2)],
                        rangePoly(int((length - 1) / 2), int((width - 1) / 2)))
                    print('+++++++++++++++++++++++++++++')

            ##################################################
            # resample bursts
            ##################################################
            slaveBurstResampledDir = self._insar.slaveBurstPrefix + '_2_coreg_cc'
            #interferogramDir = self._insar.masterBurstPrefix + '-' + self._insar.slaveBurstPrefix + '_coreg_geom'
            interferogramDir = 'burst_interf_2_coreg_cc'
            interferogramPrefix = self._insar.masterBurstPrefix + '-' + self._insar.slaveBurstPrefix
            resampleBursts(masterSwath,
                           slaveSwath,
                           self._insar.masterBurstPrefix,
                           self._insar.slaveBurstPrefix,
                           slaveBurstResampledDir,
                           interferogramDir,
                           self._insar.masterBurstPrefix,
                           self._insar.slaveBurstPrefix,
                           self._insar.slaveBurstPrefix,
                           interferogramPrefix,
                           self._insar.rangeOffset,
                           self._insar.azimuthOffset,
                           rangeOffsetResidual=rangeOffset,
                           azimuthOffsetResidual=azimuthOffset)

            ##################################################
            # mosaic burst amplitudes and interferograms
            ##################################################
            os.chdir(slaveBurstResampledDir)
            mosaicBurstAmplitude(masterSwath,
                                 self._insar.slaveBurstPrefix,
                                 self._insar.slaveMagnitude,
                                 numberOfLooksThreshold=4)
            os.chdir('../')

            os.chdir(interferogramDir)
            mosaicBurstInterferogram(masterSwath,
                                     interferogramPrefix,
                                     self._insar.interferogram,
                                     numberOfLooksThreshold=4)
            os.chdir('../')

            ##################################################
            # final amplitude and interferogram
            ##################################################
            amp = np.zeros(
                (masterSwath.numberOfLines, 2 * masterSwath.numberOfSamples),
                dtype=np.float32)
            amp[0:, 1:masterSwath.numberOfSamples*2:2] = np.fromfile(os.path.join(slaveBurstResampledDir, self._insar.slaveMagnitude), \
                dtype=np.float32).reshape(masterSwath.numberOfLines, masterSwath.numberOfSamples)
            amp[0:, 0:masterSwath.numberOfSamples*2:2] = np.fromfile(os.path.join(self._insar.masterBurstPrefix, self._insar.masterMagnitude), \
                dtype=np.float32).reshape(masterSwath.numberOfLines, masterSwath.numberOfSamples)
            amp.astype(np.float32).tofile(self._insar.amplitude)
            create_xml(self._insar.amplitude, masterSwath.numberOfSamples,
                       masterSwath.numberOfLines, 'amp')

            os.rename(
                os.path.join(interferogramDir, self._insar.interferogram),
                self._insar.interferogram)
            os.rename(
                os.path.join(interferogramDir,
                             self._insar.interferogram + '.vrt'),
                self._insar.interferogram + '.vrt')
            os.rename(
                os.path.join(interferogramDir,
                             self._insar.interferogram + '.xml'),
                self._insar.interferogram + '.xml')

            os.chdir('../')
        os.chdir('../')

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