Ejemplo n.º 1
0
class EnviSAT_SLC(Sensor):

    parameter_list = (ORBIT_DIRECTORY, ORBITFILE, INSTRUMENTFILE,
                      INSTRUMENT_DIRECTORY, IMAGEFILE) + Sensor.parameter_list
    """
        A Class for parsing EnviSAT instrument and imagery files
    """

    family = 'envisat'

    def __init__(self, family='', name=''):
        super(EnviSAT_SLC,
              self).__init__(family if family else self.__class__.family,
                             name=name)
        self._imageFile = None
        self._instrumentFileData = None
        self._imageryFileData = None
        self.dopplerRangeTime = None
        self.rangeRefTime = None
        self.logger = logging.getLogger("isce.sensor.EnviSAT_SLC")
        self.frame = None
        self.frameList = []

        self.constants = {'antennaLength': 10.0, 'iBias': 128, 'qBias': 128}

    def getFrame(self):
        return self.frame

    def parse(self):
        """
            Parse both imagery and instrument files and create
            objects representing the platform, instrument and scene
        """

        self.frame = Frame()
        self.frame.configure()

        self._imageFile = ImageryFile(fileName=self._imageFileName)
        self._imageryFileData = self._imageFile.parse()

        if self.instrumentFile in [None, '']:
            self.findInstrumentFile()

        instrumentFileParser = InstrumentFile(fileName=self.instrumentFile)
        self._instrumentFileData = instrumentFileParser.parse()

        self.populateMetadata()

    def populateMetadata(self):

        self._populatePlatform()
        self._populateInstrument()
        self._populateFrame()
        self._populateOrbit()
        self.dopplerRangeTime = self._imageryFileData['doppler']
        self.rangeRefTime = self._imageryFileData['dopplerOrigin'][0] * 1.0e-9


#        print('Doppler confidence: ', 100.0 * self._imageryFileData['dopplerConfidence'][0])

    def _populatePlatform(self):
        """Populate the platform object with metadata"""
        platform = self.frame.getInstrument().getPlatform()

        # Populate the Platform and Scene objects
        platform.setMission("Envisat")
        platform.setPointingDirection(-1)
        platform.setAntennaLength(self.constants['antennaLength'])
        platform.setPlanet(Planet(pname="Earth"))

    def _populateInstrument(self):
        """Populate the instrument object with metadata"""
        instrument = self.frame.getInstrument()

        rangeSampleSpacing = Const.c / (
            2 * self._imageryFileData['rangeSamplingRate'])
        pri = self._imageryFileData['pri']

        ####These shouldnt matter for SLC data since data is already focused.
        txPulseLength = 512 / 19207680.000000
        chirpPulseBandwidth = 16.0e6
        chirpSlope = chirpPulseBandwidth / txPulseLength

        instrument.setRangePixelSize(rangeSampleSpacing)
        instrument.setPulseLength(txPulseLength)
        #instrument.setSwath(imageryFileData['SWATH'])
        instrument.setRadarFrequency(self._instrumentFileData['frequency'])
        instrument.setChirpSlope(chirpSlope)
        instrument.setRangeSamplingRate(
            self._imageryFileData['rangeSamplingRate'])
        instrument.setPulseRepetitionFrequency(1.0 / pri)
        #instrument.setRangeBias(rangeBias)
        instrument.setInPhaseValue(self.constants['iBias'])
        instrument.setQuadratureValue(self.constants['qBias'])

    def _populateFrame(self):
        """Populate the scene object with metadata"""
        numberOfLines = self._imageryFileData['numLines']
        numberOfSamples = self._imageryFileData['numSamples']
        pri = self._imageryFileData['pri']
        startingRange = Const.c * float(
            self._imageryFileData['timeToFirstSample']) * 1.0e-9 / 2.0
        rangeSampleSpacing = Const.c / (
            2 * self._imageryFileData['rangeSamplingRate'])
        farRange = startingRange + numberOfSamples * rangeSampleSpacing
        first_line_utc = datetime.datetime.strptime(
            self._imageryFileData['FIRST_LINE_TIME'], '%d-%b-%Y %H:%M:%S.%f')
        center_line_utc = datetime.datetime.strptime(
            self._imageryFileData['FIRST_LINE_TIME'], '%d-%b-%Y %H:%M:%S.%f')
        last_line_utc = datetime.datetime.strptime(
            self._imageryFileData['LAST_LINE_TIME'], '%d-%b-%Y %H:%M:%S.%f')
        centerTime = DTUtil.timeDeltaToSeconds(last_line_utc -
                                               first_line_utc) / 2.0
        center_line_utc = center_line_utc + datetime.timedelta(
            microseconds=int(centerTime * 1e6))

        self.frame.setStartingRange(startingRange)
        self.frame.setFarRange(farRange)
        self.frame.setProcessingFacility(self._imageryFileData['PROC_CENTER'])
        self.frame.setProcessingSystem(self._imageryFileData['SOFTWARE_VER'])
        self.frame.setTrackNumber(int(self._imageryFileData['REL_ORBIT']))
        self.frame.setOrbitNumber(int(self._imageryFileData['ABS_ORBIT']))
        self.frame.setPolarization(self._imageryFileData['MDS1_TX_RX_POLAR'])
        self.frame.setNumberOfSamples(numberOfSamples)
        self.frame.setNumberOfLines(numberOfLines)
        self.frame.setSensingStart(first_line_utc)
        self.frame.setSensingMid(center_line_utc)
        self.frame.setSensingStop(last_line_utc)

    def _populateOrbit(self):
        if self.orbitFile in [None, '']:
            self.findOrbitFile()

        dorParser = DOR(fileName=self.orbitFile)
        dorParser.parse()
        startTime = self.frame.getSensingStart() - datetime.timedelta(
            minutes=5)
        stopTime = self.frame.getSensingStop() + datetime.timedelta(minutes=5)
        self.frame.setOrbit(dorParser.orbit.trimOrbit(startTime, stopTime))

    def _populateImage(self, outname, width, length):

        #farRange = self.frame.getStartingRange() + width*self.frame.getInstrument().getRangeSamplingRate()
        # Update the NumberOfSamples and NumberOfLines in the Frame object
        self.frame.setNumberOfSamples(width)
        self.frame.setNumberOfLines(length)
        #self.frame.setFarRange(farRange)
        # Create a RawImage object
        rawImage = createSlcImage()
        rawImage.setFilename(outname)
        rawImage.setAccessMode('read')
        rawImage.setByteOrder('l')
        rawImage.setXmin(0)
        rawImage.setXmax(width)
        rawImage.setWidth(width)
        self.frame.setImage(rawImage)

    def extractImage(self):
        from datetime import datetime as dt
        import tempfile as tf

        self.parse()
        width = self._imageryFileData['numSamples']
        length = self._imageryFileData['numLines']
        self._imageFile.extractImage(self.output, width, length)
        self._populateImage(self.output, width, length)

        pass

    def findOrbitFile(self):

        datefmt = '%Y%m%d%H%M%S'
        #        sensingStart = self.frame.getSensingStart()
        sensingStart = datetime.datetime.strptime(
            self._imageryFileData['FIRST_LINE_TIME'], '%d-%b-%Y %H:%M:%S.%f')
        outFile = None

        if self.orbitDir in [None, '']:
            raise Exception(
                'No Envisat Orbit File or Orbit Directory specified')

        try:
            for fname in os.listdir(self.orbitDir):
                if not os.path.isfile(os.path.join(self.orbitDir, fname)):
                    continue

                if not fname.startswith('DOR'):
                    continue

                fields = fname.split('_')
                procdate = datetime.datetime.strptime(
                    fields[-6][-8:] + fields[-5], datefmt)
                startdate = datetime.datetime.strptime(fields[-4] + fields[-3],
                                                       datefmt)
                enddate = datetime.datetime.strptime(fields[-2] + fields[-1],
                                                     datefmt)

                if (sensingStart > startdate) and (sensingStart < enddate):
                    outFile = os.path.join(self.orbitDir, fname)
                    break

        except:
            raise Exception(
                'Error occured when trying to find orbit file in %s' %
                (self.orbitDir))

        if not outFile:
            raise Exception('Envisat orbit file could not be found in %s' %
                            (self.orbitDir))

        self.orbitFile = outFile
        return

    def findInstrumentFile(self):

        datefmt = '%Y%m%d%H%M%S'

        sensingStart = datetime.datetime.strptime(
            self._imageryFileData['FIRST_LINE_TIME'], '%d-%b-%Y %H:%M:%S.%f')
        print('sens: ', sensingStart)
        outFile = None

        if self.instrumentDir in [None, '']:
            raise Exception(
                'No Envisat Instrument File or Instrument Directory specified')

        try:
            for fname in os.listdir(self.instrumentDir):
                if not os.path.isfile(os.path.join(self.instrumentDir, fname)):
                    continue

                if not fname.startswith('ASA_INS'):
                    continue

                fields = fname.split('_')
                procdate = datetime.datetime.strptime(
                    fields[-6][-8:] + fields[-5], datefmt)
                startdate = datetime.datetime.strptime(fields[-4] + fields[-3],
                                                       datefmt)
                enddate = datetime.datetime.strptime(fields[-2] + fields[-1],
                                                     datefmt)

                if (sensingStart > startdate) and (sensingStart < enddate):
                    outFile = os.path.join(self.instrumentDir, fname)
                    break

        except:
            raise Exception(
                'Error occured when trying to find instrument file in %s' %
                (self.instrumentDir))

        if not outFile:
            raise Exception(
                'Envisat instrument file could not be found in %s' %
                (self.instrumentDir))

        self.instrumentFile = outFile
        return

    def extractDoppler(self):
        """
        Return the doppler centroid as defined in the ASAR file.
        """
        quadratic = {}

        r0 = self.frame.getStartingRange()
        dr = self.frame.instrument.getRangePixelSize()
        width = self.frame.getNumberOfSamples()

        midr = r0 + (width / 2.0) * dr
        midtime = 2 * midr / Const.c - self.rangeRefTime

        fd_mid = 0.0
        tpow = midtime
        for kk in self.dopplerRangeTime:
            fd_mid += kk * tpow
            tpow *= midtime

        ####For insarApp
        quadratic['a'] = fd_mid / self.frame.getInstrument(
        ).getPulseRepetitionFrequency()
        quadratic['b'] = 0.
        quadratic['c'] = 0.

        ####For roiApp
        ####More accurate
        from isceobj.Util import Poly1D

        coeffs = self.dopplerRangeTime
        dr = self.frame.getInstrument().getRangePixelSize()
        rref = 0.5 * Const.c * self.rangeRefTime
        r0 = self.frame.getStartingRange()
        norm = 0.5 * Const.c / dr

        dcoeffs = []
        for ind, val in enumerate(coeffs):
            dcoeffs.append(val / (norm**ind))

        poly = Poly1D.Poly1D()
        poly.initPoly(order=len(coeffs) - 1)
        poly.setMean((rref - r0) / dr - 1.0)
        poly.setCoeffs(dcoeffs)

        pix = np.linspace(0,
                          self.frame.getNumberOfSamples(),
                          num=len(coeffs) + 1)
        evals = poly(pix)
        fit = np.polyfit(pix, evals, len(coeffs) - 1)
        self.frame._dopplerVsPixel = list(fit[::-1])
        print('Doppler Fit: ', fit[::-1])

        return quadratic
Ejemplo n.º 2
0
class ERS_EnviSAT_SLC(Sensor):

    parameter_list = (ORBIT_TYPE,
                      ORBIT_DIRECTORY,
                      ORBITFILE,
                      IMAGEFILE)           + Sensor.parameter_list

    """
        A Class for parsing ERS instrument and imagery files (Envisat format)
    """

    family = 'ers'
    logging_name = 'isce.sensor.ers_envisat_slc'

    def __init__(self,family='',name=''):
        super(ERS_EnviSAT_SLC, self).__init__(family if family else  self.__class__.family, name=name)
        self._imageFile = None
        #self._instrumentFileData = None #none for ERS
        self._imageryFileData = None
        self.dopplerRangeTime = None
        self.rangeRefTime = None
        self.logger = logging.getLogger("isce.sensor.ERS_EnviSAT_SLC")
        self.frame = None
        self.frameList = []

        #NOTE: copied from ERS_SLC.py... only antennaLength used? -SH
        # Constants are from
        # J. J. Mohr and S. N. Madsen. Geometric calibration of ERS satellite
        # SAR images. IEEE T. Geosci. Remote, 39(4):842-850, Apr. 2001.
        self.constants = {'polarization': 'VV',
                          'antennaLength': 10,
                          'lookDirection': 'RIGHT',
                          'chirpPulseBandwidth': 15.50829e6,
                          'rangeSamplingRate': 18.962468e6,
                          'delayTime':6.622e-6,
                          'iBias': 15.5,
                          'qBias': 15.5}


    def getFrame(self):
        return self.frame

    def parse(self):
        """
            Parse both imagery and create
            objects representing the platform, instrument and scene
        """

        self.frame = Frame()
        self.frame.configure()

        self._imageFile = ImageryFile(fileName=self._imageFileName)
        self._imageryFileData = self._imageFile.parse()

        self.populateMetadata()

    def populateMetadata(self):

        self._populatePlatform()
        self._populateInstrument()
        self._populateFrame()
        #self._populateOrbit()
        if (self._orbitType == 'ODR'):
            self._populateDelftOrbits()
        elif (self._orbitType == 'PRC'):
            self._populatePRCOrbits()
        elif (self._orbitType == 'PDS'):
            self._populatePDSOrbits()
        #else:
        #    self._populateHeaderOrbit() #NOTE: No leader file
        #NOTE: remove?
        self.dopplerRangeTime = self._imageryFileData['doppler']
        self.rangeRefTime = self._imageryFileData['dopplerOrigin'][0] * 1.0e-9
#        print('Doppler confidence: ', 100.0 * self._imageryFileData['dopplerConfidence'][0])

    def _populatePlatform(self):
        """Populate the platform object with metadata"""
        platform = self.frame.getInstrument().getPlatform()

        # Populate the Platform and Scene objects
        platform.setMission("ERS")
        platform.setPointingDirection(-1)
        platform.setAntennaLength(self.constants['antennaLength'])
        platform.setPlanet(Planet(pname="Earth"))

    def _populateInstrument(self):
        """Populate the instrument object with metadata"""
        instrument = self.frame.getInstrument()

        rangeSampleSpacing = Const.c/(2*self._imageryFileData['rangeSamplingRate'])
        pri = self._imageryFileData['pri']


        ####These shouldnt matter for SLC data since data is already focused.
        txPulseLength = 512 / 19207680.000000
        chirpPulseBandwidth = 16.0e6
        chirpSlope = chirpPulseBandwidth/txPulseLength

        instrument.setRangePixelSize(rangeSampleSpacing)
        instrument.setPulseLength(txPulseLength)
        #instrument.setSwath(imageryFileData['SWATH'])
        instrument.setRadarFrequency(self._imageryFileData['radarFrequency'])
        instrument.setChirpSlope(chirpSlope)
        instrument.setRangeSamplingRate(self._imageryFileData['rangeSamplingRate'])
        instrument.setPulseRepetitionFrequency(1.0/pri)
        #instrument.setRangeBias(rangeBias)
        instrument.setInPhaseValue(self.constants['iBias'])
        instrument.setQuadratureValue(self.constants['qBias'])

    def _populateFrame(self):
        """Populate the scene object with metadata"""
        numberOfLines = self._imageryFileData['numLines']
        numberOfSamples = self._imageryFileData['numSamples']
        pri = self._imageryFileData['pri']
        startingRange = Const.c * float(self._imageryFileData['timeToFirstSample']) * 1.0e-9 / 2.0
        rangeSampleSpacing = Const.c/(2*self._imageryFileData['rangeSamplingRate'])
        farRange = startingRange + numberOfSamples*rangeSampleSpacing
        first_line_utc = datetime.datetime.strptime(self._imageryFileData['FIRST_LINE_TIME'], '%d-%b-%Y %H:%M:%S.%f')
        center_line_utc = datetime.datetime.strptime(self._imageryFileData['FIRST_LINE_TIME'], '%d-%b-%Y %H:%M:%S.%f')
        last_line_utc = datetime.datetime.strptime(self._imageryFileData['LAST_LINE_TIME'], '%d-%b-%Y %H:%M:%S.%f')
        centerTime = DTUtil.timeDeltaToSeconds(last_line_utc-first_line_utc)/2.0
        center_line_utc = center_line_utc + datetime.timedelta(microseconds=int(centerTime*1e6))

        self.frame.setStartingRange(startingRange)
        self.frame.setFarRange(farRange)
        self.frame.setProcessingFacility(self._imageryFileData['PROC_CENTER'])
        self.frame.setProcessingSystem(self._imageryFileData['SOFTWARE_VER'])
        self.frame.setTrackNumber(int(self._imageryFileData['REL_ORBIT']))
        self.frame.setOrbitNumber(int(self._imageryFileData['ABS_ORBIT']))
        self.frame.setPolarization(self._imageryFileData['MDS1_TX_RX_POLAR'])
        self.frame.setNumberOfSamples(numberOfSamples)
        self.frame.setNumberOfLines(numberOfLines)
        self.frame.setSensingStart(first_line_utc)
        self.frame.setSensingMid(center_line_utc)
        self.frame.setSensingStop(last_line_utc)

    def _populateDelftOrbits(self):
        """Populate an orbit object with the Delft orbits"""
        from isceobj.Orbit.ODR import ODR, Arclist
        self.logger.info("Using Delft Orbits")
        arclist = Arclist(os.path.join(self._orbitDir,'arclist'))
        arclist.parse()
        print(self.frame.getSensingStart())
        print(arclist)
        orbitFile = arclist.getOrbitFile(self.frame.getSensingStart())
        #print(orbitFile)
        odr = ODR(file=os.path.join(self._orbitDir,orbitFile))


        startTimePreInterp = self.frame.getSensingStart() - datetime.timedelta(minutes=60)
        stopTimePreInterp = self.frame.getSensingStop() + datetime.timedelta(minutes=60)
        odr.parseHeader(startTimePreInterp,stopTimePreInterp)
        startTime = self.frame.getSensingStart() - datetime.timedelta(minutes=5)
        stopTime = self.frame.getSensingStop() + datetime.timedelta(minutes=5)
        self.logger.debug("Extracting orbits between %s and %s" % (startTime,stopTime))
        orbit = odr.trimOrbit(startTime,stopTime)
        self.frame.setOrbit(orbit)

    def _populatePRCOrbits(self):
        """Populate an orbit object the D-PAF PRC orbits"""
        from isceobj.Orbit.PRC import PRC, Arclist
        self.logger.info("Using PRC Orbits")
        arclist = Arclist(os.path.join(self._orbitDir,'arclist'))
        arclist.parse()
        orbitFile = arclist.getOrbitFile(self.frame.getSensingStart())
        self.logger.debug("Using file %s" % (orbitFile))
        prc = PRC(file=os.path.join(self._orbitDir,orbitFile))
        prc.parse()
        startTime = self.frame.getSensingStart() - datetime.timedelta(minutes=5)
        stopTime = self.frame.getSensingStop() + datetime.timedelta(minutes=5)
        self.logger.debug("Extracting orbits between %s and %s" % (startTime,stopTime))
        fullOrbit = prc.getOrbit()
        orbit = fullOrbit.trimOrbit(startTime,stopTime)
        self.frame.setOrbit(orbit)

    def _populatePDSOrbits(self):
        """
        Populate an orbit object using the ERS-2 PDS format
        """
        from isceobj.Orbit.PDS import PDS
        self.logger.info("Using PDS Orbits")
        pds = PDS(file=self._orbitFile)
        pds.parse()
        startTime = self.frame.getSensingStart() - datetime.timedelta(minutes=5)
        stopTime = self.frame.getSensingStop() + datetime.timedelta(minutes=5)
        self.logger.debug("Extracting orbits between %s and %s" % (startTime,stopTime))
        fullOrbit = pds.getOrbit()
        orbit = fullOrbit.trimOrbit(startTime,stopTime)
        self.frame.setOrbit(orbit)


    def _populateImage(self,outname,width,length):

        #farRange = self.frame.getStartingRange() + width*self.frame.getInstrument().getRangeSamplingRate()
        # Update the NumberOfSamples and NumberOfLines in the Frame object
        self.frame.setNumberOfSamples(width)
        self.frame.setNumberOfLines(length)
        #self.frame.setFarRange(farRange)
        # Create a RawImage object
        rawImage = createSlcImage()
        rawImage.setFilename(outname)
        rawImage.setAccessMode('read')
        rawImage.setByteOrder('l')
        rawImage.setXmin(0)
        rawImage.setXmax(width)
        rawImage.setWidth(width)
        self.frame.setImage(rawImage)

    def extractImage(self):
        from datetime import datetime as dt
        import tempfile as tf

        self.parse()
        width = self._imageryFileData['numSamples']
        length = self._imageryFileData['numLines']
        self._imageFile.extractImage(self.output, width, length)
        self._populateImage(self.output, width, length)

        pass



    def extractDoppler(self):
        """
        Return the doppler centroid as defined in the ASAR file.
        """
        quadratic = {}

        r0 = self.frame.getStartingRange()
        dr = self.frame.instrument.getRangePixelSize()
        width = self.frame.getNumberOfSamples()

        midr = r0 + (width/2.0) * dr
        midtime = 2 * midr/ Const.c - self.rangeRefTime

        fd_mid = 0.0
        tpow = midtime
        for kk in self.dopplerRangeTime:
            fd_mid += kk * tpow
            tpow *= midtime


        ####For insarApp
        quadratic['a'] = fd_mid/self.frame.getInstrument().getPulseRepetitionFrequency()
        quadratic['b'] = 0.
        quadratic['c'] = 0.

        
        ####For roiApp
        ####More accurate
        from isceobj.Util import Poly1D
        
        coeffs = self.dopplerRangeTime
        dr = self.frame.getInstrument().getRangePixelSize()
        rref = 0.5 * Const.c * self.rangeRefTime 
        r0 = self.frame.getStartingRange()
        norm = 0.5*Const.c/dr

        dcoeffs = []
        for ind, val in enumerate(coeffs):
            dcoeffs.append( val / (norm**ind))


        poly = Poly1D.Poly1D()
        poly.initPoly(order=len(coeffs)-1)
        poly.setMean( (rref - r0)/dr - 1.0)
        poly.setCoeffs(dcoeffs)


        pix = np.linspace(0, self.frame.getNumberOfSamples(), num=len(coeffs)+1)
        evals = poly(pix)
        fit = np.polyfit(pix,evals, len(coeffs)-1)
        self.frame._dopplerVsPixel = list(fit[::-1])
        print('Doppler Fit: ', fit[::-1])


        return quadratic