Exemplo n.º 1
0
class ERS(Component):

    #Parsers.CEOS.CEOSFormat.ceosTypes['text'] =
    #    {'typeCode': 63, 'subtypeCode': [18,18,18]}
    #Parsers.CEOS.CEOSFormat.ceosTypes['leaderFile'] =
    #    {'typeCode': 192, 'subtypeCode': [63,18,18]}
    #Parsers.CEOS.CEOSFormat.ceosTypes['dataSetSummary'] =
    #    {'typeCode': 10, 'subtypeCode': [10,31,20]}
    #Parsers.CEOS.CEOSFormat.ceosTypes['platformPositionData'] =
    #    {'typeCode': 30, 'subtypeCode': [10,31,20]}
    #Parsers.CEOS.CEOSFormat.ceosTypes['facilityData'] =
    #    {'typeCode': 200, 'subtypeCode': [10,31,50]}
    #Parsers.CEOS.CEOSFormat.ceosTypes['datafileDescriptor'] =
    #    {'typeCode': 192, 'subtypeCode':[63,18,18]}
    #Parsers.CEOS.CEOSFormat.ceosTypes['signalData'] =
    #    {'typeCode': 10, 'subtypeCode': [50,31,20]}
    #Parsers.CEOS.CEOSFormat.ceosTypes['nullFileDescriptor'] =
    #    {'typeCode': 192, 'subtypeCode': [192,63,18]}

    logging_name = 'isce.sensor.ers'

    def __init__(self):
        Component.__init__(self)
        self._leaderFile = None
        self._imageFileList = ''
        self._leaderFileList = ''
        self._imageFile = None
        self._orbitDir = None # Use this for Delft Orbit files
        self._orbitFile = None # Use this for PDS Orbit files for now
        self._orbitType = None
        self.frameList = []
        self.output = None

        self.descriptionOfVariables = {}
        self.dictionaryOfVariables = {
            'ORBIT_TYPE': ['self._orbitType','str','mandatory'],
            'ORBIT_DIRECTORY': ['self._orbitDir','str','optional'],
            'ORBIT_FILE': ['self._orbitFile','str','optional'],
            'LEADERFILE': ['self._leaderFileList','str','mandatory'],
            'IMAGEFILE': ['self._imageFileList','str','mandatory'],
            'OUTPUT': ['self.output','str','optional']}


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

        # 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}
        return None

    def getFrame(self):
        return self.frame

    def parse(self):
        self.leaderFile = LeaderFile(file=self._leaderFile)
        self.leaderFile.parse()

        self.imageFile = ImageFile(self)
        self.imageFile.parse()

        self.populateMetadata()

    def populateMetadata(self):
        """
        Create the appropriate metadata objects from our CEOSFormat metadata
        """

        self._populatePlatform()
        self._populateInstrument()
        self._populateFrame()
        if (self._orbitType == 'ODR'):
            self._populateDelftOrbits()
        elif (self._orbitType == 'PRC'):
            self._populatePRCOrbits()
        elif (self._orbitType == 'PDS'):
            self._populatePDSOrbits()
        else:
            self._populateHeaderOrbit()

    def _populatePlatform(self):
        """
        Populate the platform object with metadata
        """

        platform = self.frame.getInstrument().getPlatform()

        platform.setMission(self.leaderFile.sceneHeaderRecord.metadata[
            'Sensor platform mission identifier'])
        platform.setAntennaLength(self.constants['antennaLength'])
        platform.setPointingDirection(-1)
        platform.setPlanet(Planet('Earth'))

    def _populateInstrument(self):
        """Populate the instrument object with metadata"""
        instrument = self.frame.getInstrument()
        pri = self.imageFile.firstPri
        rangeSamplingRate = self.constants['rangeSamplingRate']
        #rangeSamplingRate = self.leaderFile.sceneHeaderRecord.metadata[
        #    'Range sampling rate']*1e6
        rangePixelSize = Const.c/(2.0*rangeSamplingRate)
        pulseInterval = 4.0/rangeSamplingRate*(pri+2.0)
        prf = 1.0/pulseInterval

        instrument.setRadarWavelength(
            self.leaderFile.sceneHeaderRecord.metadata['Radar wavelength'])
        instrument.setIncidenceAngle(
            self.leaderFile.sceneHeaderRecord.metadata[
            'Incidence angle at scene centre'])
        instrument.setPulseRepetitionFrequency(prf)
        instrument.setRangeSamplingRate(rangeSamplingRate)
        instrument.setRangePixelSize(rangePixelSize)
        instrument.setPulseLength(self.leaderFile.sceneHeaderRecord.metadata[
            'Range pulse length']*1e-6)
        instrument.setChirpSlope(self.constants['chirpPulseBandwidth']/
            (self.leaderFile.sceneHeaderRecord.metadata['Range pulse length']*
             1e-6))
        instrument.setInPhaseValue(self.constants['iBias'])
        instrument.setQuadratureValue(self.constants['qBias'])

    def _populateFrame(self):
        """Populate the scene object with metadata"""
        rangeSamplingRate = self.constants['rangeSamplingRate']
        #rangeSamplingRate = self.leaderFile.sceneHeaderRecord.metadata[
        #    'Range sampling rate']*1e6
        rangePixelSize = Const.c/(2.0*rangeSamplingRate)
        pulseInterval = 1.0/self.frame.getInstrument().getPulseRepetitionFrequency()
        frame = self._decodeSceneReferenceNumber(
            self.leaderFile.sceneHeaderRecord.metadata[
            'Scene reference number'])
        startingRange = (9*pulseInterval + self.imageFile.minSwst*4/rangeSamplingRate-self.constants['delayTime'])*Const.c/2.0
        farRange = startingRange + self.imageFile.width*rangePixelSize
        # Use the Scene center time to get the date, then use the ICU on board time from the image for the rest
        centerLineTime = datetime.datetime.strptime(self.leaderFile.sceneHeaderRecord.metadata['Scene centre time'],"%Y%m%d%H%M%S%f")
        first_line_utc = datetime.datetime(year=centerLineTime.year, month=centerLineTime.month, day=centerLineTime.day)
        if(self.leaderFile.sceneHeaderRecord.metadata['Processing facility identifier'] in ('CRDC_SARDPF','GTS - ERS')):
            first_line_utc = first_line_utc + datetime.timedelta(milliseconds=self.imageFile.startTime)
        else:
            deltaSeconds = (self.imageFile.startTime - self.leaderFile.sceneHeaderRecord.metadata['Satellite encoded binary time code'])* 1/256.0
            # Sometimes, the ICU on board clock is corrupt, if the time suggested by the on board clock is more than
            # 5 days from the satellite clock time, assume its bogus and use the low-precision scene centre time
            if (math.fabs(deltaSeconds) > 5*86400):
                        self.logger.warn("ICU on board time appears to be corrupt, resorting to low precision clock")
                        first_line_utc = centerLineTime - datetime.timedelta(microseconds=pulseInterval*(self.imageFile.length/2.0)*1e6)
            else:
                satelliteClockTime = datetime.datetime.strptime(self.leaderFile.sceneHeaderRecord.metadata['Satellite clock time'],"%Y%m%d%H%M%S%f")
                first_line_utc = satelliteClockTime + datetime.timedelta(microseconds=int(deltaSeconds*1e6))
        mid_line_utc = first_line_utc + datetime.timedelta(microseconds=pulseInterval*(self.imageFile.length/2.0)*1e6)
        last_line_utc = first_line_utc + datetime.timedelta(microseconds=pulseInterval*self.imageFile.length*1e6)
        self.logger.debug("Frame UTC start, mid, end times:  %s %s %s" % (first_line_utc,mid_line_utc,last_line_utc))

        self.frame.setFrameNumber(frame)
        self.frame.setOrbitNumber(self.leaderFile.sceneHeaderRecord.metadata['Orbit number'])
        self.frame.setStartingRange(startingRange)
        self.frame.setFarRange(farRange)
        self.frame.setProcessingFacility(self.leaderFile.sceneHeaderRecord.metadata['Processing facility identifier'])
        self.frame.setProcessingSystem(self.leaderFile.sceneHeaderRecord.metadata['Processing system identifier'])
        self.frame.setProcessingSoftwareVersion(self.leaderFile.sceneHeaderRecord.metadata['Processing version identifier'])
        self.frame.setPolarization(self.constants['polarization'])
        self.frame.setNumberOfLines(self.imageFile.length)
        self.frame.setNumberOfSamples(self.imageFile.width)
        self.frame.setSensingStart(first_line_utc)
        self.frame.setSensingMid(mid_line_utc)
        self.frame.setSensingStop(last_line_utc)

    def _populateHeaderOrbit(self):
        """Populate an orbit object with the header orbits"""
        self.logger.info("Using Header Orbits")
        orbit = self.frame.getOrbit()

        orbit.setOrbitSource('Header')
        orbit.setOrbitQuality('Unknown')
        t0 = datetime.datetime(year=self.leaderFile.platformPositionRecord.metadata['Year of data point'],
                               month=self.leaderFile.platformPositionRecord.metadata['Month of data point'],
                               day=self.leaderFile.platformPositionRecord.metadata['Day of data point'])
        t0 = t0 + datetime.timedelta(microseconds=self.leaderFile.platformPositionRecord.metadata['Seconds of day']*1e6)
        for i in range(self.leaderFile.platformPositionRecord.metadata['Number of data points']):
            vec = StateVector()
            deltaT = self.leaderFile.platformPositionRecord.metadata['Time interval between DATA points']
            t = t0 + datetime.timedelta(microseconds=i*deltaT*1e6)
            vec.setTime(t)
            dataPoints = self.leaderFile.platformPositionRecord.metadata['Positional Data Points'][i]
            vec.setPosition([dataPoints['Position vector X'], dataPoints['Position vector Y'], dataPoints['Position vector Z']])
            vec.setVelocity([dataPoints['Velocity vector X'], dataPoints['Velocity vector Y'], dataPoints['Velocity vector Z']])
            orbit.addStateVector(vec)

    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()
        orbitFile = arclist.getOrbitFile(self.frame.getSensingStart())
        odr = ODR(file=os.path.join(self._orbitDir,orbitFile))
        #jng it seem that for this tipe of orbit points are separated by 60 sec. In ODR at least 9 state vectors are needed to compute the velocities. add
        # extra time before and after to allow interpolation, but do not do it for all data points. too slow
        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 extractImage(self):
        import array
        import math
        # just in case there was only one image and it was passed as a str instead of a list with only one element
        if(isinstance(self._imageFileList,str)):
            self._imageFileList = [self._imageFileList]
            self._leaderFileList = [self._leaderFileList]
        if(len(self._imageFileList) != len(self._leaderFileList)):
            self.logger.error("Number of leader files different from number of image files.")
            raise Exception

        self.frameList = []

        for i in range(len(self._imageFileList)):
            appendStr = "_" + str(i)
            #if only one file don't change the name
            if(len(self._imageFileList) == 1):
                appendStr = ''

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

            self._leaderFile = self._leaderFileList[i]
            self._imageFile = self._imageFileList[i]
            self.leaderFile = LeaderFile(file=self._leaderFile)
            self.leaderFile.parse()

            self.imageFile = ImageFile(self)

            try:
                outputNow = self.output + appendStr
                out = open(outputNow,'wb')
            except IOError as strerr:
                self.logger.error("IOError: %s" % strerr)
                return

            self.imageFile.extractImage(output=out)
            out.close()

            rawImage = isceobj.createRawImage()
            rawImage.setByteOrder('l')
            rawImage.setAccessMode('read')
            rawImage.setFilename(outputNow)
            rawImage.setWidth(self.imageFile.width)
            rawImage.setXmin(0)
            rawImage.setXmax(self.imageFile.width)
            self.frame.setImage(rawImage)
            self.populateMetadata()
            self.frameList.append(self.frame)
            #jng Howard Z at this point adjusts the sampling starting time for imagery generated from CRDC_SARDPF facility.
            # for now create the orbit aux file based in starting time and prf
            prf = self.frame.getInstrument().getPulseRepetitionFrequency()
            senStart = self.frame.getSensingStart()
            numPulses = int(math.ceil(DTU.timeDeltaToSeconds(self.frame.getSensingStop()-senStart)*prf))
            # the aux files has two entries per line. day of the year and microseconds in the day
            musec0 = (senStart.hour*3600 + senStart.minute*60 + senStart.second)*10**6 + senStart.microsecond
            maxMusec = (24*3600)*10**6#use it to check if we went across  a day. very rare
            day0 = (datetime.datetime(senStart.year,senStart.month,senStart.day) - datetime.datetime(senStart.year,1,1)).days + 1
            outputArray  = array.array('d',[0]*2*numPulses)
            self.frame.auxFile = outputNow + '.aux'
            fp = open(self.frame.auxFile,'wb')
            j = -1
            for i1 in range(numPulses):
                j += 1
                musec = round((j/prf)*10**6) + musec0
                if musec >= maxMusec:
                    day0 += 1
                    musec0 = musec%maxMusec
                    musec = musec0
                    j = 0
                outputArray[2*i1] = day0
                outputArray[2*i1+1] = musec

            outputArray.tofile(fp)
            fp.close()

        tk = Track()
        if(len(self._imageFileList) > 1):
            self.frame = tk.combineFrames(self.output,self.frameList)

            for i in range(len(self._imageFileList)):
                try:
                    os.remove(self.output + "_" + str(i))
                except OSError:
                    print("Error. Cannot remove temporary file",self.output + "_" + str(i))
                    raise OSError



    def _decodeSceneReferenceNumber(self,referenceNumber):
        frameNumber = referenceNumber.split('=')
        if (len(frameNumber) > 2):
            frameNumber = frameNumber[2].strip()
        else:
            frameNumber = frameNumber[0]

        return frameNumber
class UAVSAR_Polsar(Sensor):
    """
    A class representing a UAVSAR Polsar SLC.
    """

    family = 'uavsar_polsar'
    logging_name = 'isce.Sensor.UAVSAR_Polsar'
    lookMap = {'RIGHT': -1, 'LEFT': 1}

    parameter_list = (METADATAFILE, ) + Sensor.parameter_list

    def __init__(self, name=''):
        super().__init__(family=self.family, name=name)
        self.frame = Frame()
        self.frame.configure()
        self._elp = None
        self._peg = None

    def _populatePlatform(self, **kwargs):
        platform = self.frame.getInstrument().getPlatform()
        platform.setMission('UAVSAR')
        platform.setPointingDirection(
            self.lookMap[self.metadata['Look Direction'].upper()])
        platform.setPlanet(Planet(pname="Earth"))
        platform.setAntennaLength(1.5)

    def _populateInstrument(self, **kwargs):
        fudgefactor = 1.0  # 1.0/1.0735059946800756
        instrument = self.frame.getInstrument()
        instrument.setRadarWavelength(self.metadata['Center Wavelength'])
        instrument.setPulseRepetitionFrequency(
            fudgefactor * 1.0 /
            self.metadata['Average Pulse Repetition Interval'])
        instrument.setRangePixelSize(self.metadata['slc_mag.col_mult'])
        instrument.setAzimuthPixelSize(self.metadata['slc_mag.row_mult'])
        instrument.setPulseLength(self.metadata['Pulse Length'])
        instrument.setChirpSlope(-self.metadata['Bandwidth'] /
                                 self.metadata['Pulse Length'])
        instrument.setRangeSamplingRate(SPEED_OF_LIGHT / 2.0 /
                                        instrument.getRangePixelSize())

    def _populateFrame(self, **kwargs):
        tStart = datetime.datetime.strptime(
            self.metadata['Start Time of Acquisition'], "%d-%b-%Y %H:%M:%S %Z")
        tStop = datetime.datetime.strptime(
            self.metadata['Stop Time of Acquisition'], "%d-%b-%Y %H:%M:%S %Z")
        dtMid = DTU.timeDeltaToSeconds(tStop - tStart) / 2.
        tMid = tStart + datetime.timedelta(microseconds=int(dtMid * 1e6))

        frame = self.frame
        frame.setSensingStart(tStart)
        frame.setSensingStop(tStop)
        frame.setSensingMid(tMid)
        frame.setNumberOfLines(int(self.metadata['slc_mag.set_rows']))
        frame.setNumberOfSamples(int(self.metadata['slc_mag.set_cols']))

        frame.C0 = self.metadata['slc_mag.col_addr']
        frame.S0 = self.metadata['slc_mag.row_addr']

        self.extractDoppler()
        frame.setStartingRange(self.startingRange)
        frame.platformHeight = self.platformHeight

        width = frame.getNumberOfSamples()
        deltaRange = frame.instrument.getRangePixelSize()
        nearRange = frame.getStartingRange()

        frame.setFarRange(nearRange + width * deltaRange)

        frame._ellipsoid = self.elp
        frame.peg = self.peg
        frame.procVelocity = self.velocity

        frame.terrainHeight = self.terrainHeight
        frame.upperLeftCorner = Coordinate()
        frame.upperLeftCorner.setLatitude(
            math.degrees(self.metadata['Approximate Upper Left Latitude']))
        frame.upperLeftCorner.setLongitude(
            math.degrees(self.metadata['Approximate Upper Left Longitude']))
        frame.upperLeftCorner.setHeight(self.terrainHeight)
        frame.upperRightCorner = Coordinate()
        frame.upperRightCorner.setLatitude(
            math.degrees(self.metadata['Approximate Upper Right Latitude']))
        frame.upperRightCorner.setLongitude(
            math.degrees(self.metadata['Approximate Upper Right Longitude']))
        frame.upperRightCorner.setHeight(self.terrainHeight)
        frame.lowerRightCorner = Coordinate()
        frame.lowerRightCorner.setLatitude(
            math.degrees(self.metadata['Approximate Lower Right Latitude']))
        frame.lowerRightCorner.setLongitude(
            math.degrees(self.metadata['Approximate Lower Right Longitude']))
        frame.lowerRightCorner.setHeight(self.terrainHeight)
        frame.lowerLeftCorner = Coordinate()
        frame.lowerLeftCorner.setLatitude(
            math.degrees(self.metadata['Approximate Lower Left Latitude']))
        frame.lowerLeftCorner.setLongitude(
            math.degrees(self.metadata['Approximate Lower Left Longitude']))
        frame.lowerLeftCorner.setHeight(self.terrainHeight)

    def _populateFrameSolo(self):
        self.logger.info("UAVSAR_Polsar._populateFrameSolo")

    def _populateExtras(self):
        pass

    def _populateOrbit(self, **kwargs):
        """
        Create the orbit as the reference orbit defined by the peg
        """

        numgroup = 1000
        prf = self.frame.instrument.getPulseRepetitionFrequency()
        daz = self.frame.instrument.getAzimuthPixelSize()
        vel = daz * prf
        t0 = self.frame.getSensingStart()

        nlines = int((self.frame.getSensingStop() - t0).total_seconds() * prf)

        # make sure the elp property has been called
        elp = self.elp
        orbit = self.frame.getOrbit()
        orbit.setOrbitSource('Header')

        for i in range(-5 * numgroup,
                       int(nlines / numgroup) * numgroup + 5 * numgroup,
                       numgroup):
            delt = int(i * 1.0e6 / prf)
            torb = self.frame.getSensingStart() + datetime.timedelta(
                microseconds=delt)
            ds = delt * 1.0e-6 * vel

            vec = OrbitStateVector()

            posSCH = [self.frame.S0 + ds, 0.0, self.platformHeight]
            velSCH = [self.velocity, 0., 0.]
            posXYZ, velXYZ = elp.schdot_to_xyzdot(posSCH, velSCH)

            vec.setTime(torb)
            vec.setPosition(posXYZ)
            vec.setVelocity(velXYZ)
            orbit.addStateVector(vec)

    def populateMetadata(self):
        self._populatePlatform()
        self._populateInstrument()
        self._populateFrame()
        self._populateOrbit()

    def extractImage(self):
        from iscesys.Parsers import rdf
        self.metadata = rdf.parse(self.metadataFile)
        self.populateMetadata()
        slcImage = isceobj.createSlcImage()
        self.slcname = os.path.join(
            os.path.dirname(os.path.abspath(self.metadataFile)),
            self.metadata['slc' + self.polarization.upper()])
        slcImage.setFilename(self.slcname)
        slcImage.setXmin(0)
        slcImage.setXmax(self.frame.getNumberOfSamples())
        slcImage.setWidth(self.frame.getNumberOfSamples())
        slcImage.setAccessMode('r')
        slcImage.renderHdr()
        self.frame.setImage(slcImage)

    def extractDoppler(self):
        # Recast the Near, Mid, and Far Reskew Doppler values
        # into three RDF records because they were not parsed
        # correctly by the RDF parser; it was parsed as a string.
        # Use the RDF parser on the individual Doppler values to
        # do the unit conversion properly.

        # The units, and values parsed from the metadataFile
        key = 'Reskew Doppler Near Mid Far'
        u = self.metadata.data[key].units.split(',')
        v = map(float, self.metadata.data[key].value.split())
        k = ["Reskew Doppler " + x for x in ("Near", "Mid", "Far")]

        # Use the interactive RDF accumulator to create an RDF object
        # for the near, mid, and far Doppler values
        from iscesys.Parsers.rdf import iRDF
        dop = iRDF.RDFAccumulator()
        for z in zip(k, u, v):
            dop("%s (%s) = %f" % z)
        self.dopplerVals = {}
        for r in dop.record_list:
            self.dopplerVals[r.key.split()[-1]] = r.field.value

        # Quadratic model using Near, Mid, Far range doppler values
        # UAVSAR has a subroutine to compute doppler values at each pixel
        # that should be used instead.
        frame = self.frame
        instrument = frame.getInstrument()
        width = frame.getNumberOfSamples()
        nearRangeBin = 0.
        midRangeBin = float(int((width - 1.0) / 2.0))
        farRangeBin = width - 1.0

        A = numpy.matrix([[1.0, nearRangeBin, nearRangeBin**2],
                          [1.0, midRangeBin, midRangeBin**2],
                          [1.0, farRangeBin, farRangeBin**2]])
        d = numpy.matrix([
            self.dopplerVals['Near'], self.dopplerVals['Mid'],
            self.dopplerVals['Far']
        ]).transpose()
        coefs = (numpy.linalg.inv(A) * d).transpose().tolist()[0]
        prf = instrument.getPulseRepetitionFrequency()
        coefs_norm = {
            'a': coefs[0] / prf,
            'b': coefs[1] / prf,
            'c': coefs[2] / prf
        }

        self.doppler_coeff = coefs
        return coefs_norm

    @property
    def terrainHeight(self):
        # The peg point incorporates the actual terrainHeight
        # return self.metadata['Global Average Terrain Height']
        return 0.0

    @property
    def platformHeight(self):
        # Reduce the platform height by the terrain height because the
        # peg radius of curvature includes the terrain height
        h = (self.metadata['Global Average Altitude'] -
             self.metadata['Global Average Terrain Height'])
        return h

    @property
    def platformStartingAzimuth(self):
        azimuth = self.frame.S0
        return azimuth

    @property
    def startingRange(self):
        return self.metadata['Image Starting Range']

    @property
    def squintAngle(self):
        """
        Update this to use the sphere rather than planar approximation.
        """
        startingRange = self.startingRange
        h = self.platformHeight
        v = self.velocity
        wavelength = self.frame.getInstrument().getRadarWavelength()

        if h > startingRange:
            raise ValueError("Spacecraft Height too large (%s>%s)" %
                             (h, startingRange))

        sinTheta = math.sqrt(1 - (h / startingRange)**2)
        fd = self.dopplerVals['Near']
        sinSquint = fd / (2.0 * v * sinTheta) * wavelength

        if sinSquint**2 > 1:
            raise ValueError(
                "Error in One or More of the Squint Calculation Values\n" +
                "Doppler Centroid: %s\nVelocity: %s\nWavelength: %s\n" %
                (fd, v, wavelength))
        self.squint = math.degrees(
            math.atan2(sinSquint, math.sqrt(1 - sinSquint**2)))
        # jng squint is also used later on from the frame, just add it here
        self.frame.squintAngle = math.radians(self.squint)

        return self.squint

    @property
    def heightDt(self):
        """
        Delta(height)/Delta(Time) from frame start-time to mid-time
        """
        return 0.0

    @property
    def velocity(self):
        platform = self.frame.getInstrument().getPlatform()
        elp = platform.getPlanet().get_elp()
        peg = self.peg
        elp.setSCH(peg.latitude, peg.longitude, peg.heading)
        scale = (elp.pegRadCur + self.platformHeight) / elp.pegRadCur
        ds_ground = self.frame.instrument.getAzimuthPixelSize()
        dt = 1.0 / self.frame.instrument.getPulseRepetitionFrequency()
        v = scale * ds_ground / dt
        return v

    @property
    def elp(self):
        if not self._elp:
            planet = Planet(pname="Earth")
            self._elp = planet.get_elp()
        return self._elp

    @property
    def peg(self):
        if not self._peg:
            peg = [
                math.degrees(self.metadata['Peg Latitude']),
                math.degrees(self.metadata['Peg Longitude']),
                math.degrees(self.metadata['Peg Heading'])
            ]
            th = self.metadata['Global Average Terrain Height']

            if self.metadata['Mocomp II Applied'] is 'Y':
                self.elp.setSCH(peg[0], peg[1], peg[2], th)
            else:
                self.elp.setSCH(peg[0], peg[1], peg[2], 0)

            rc = self.elp.pegRadCur

            from isceobj.Location.Peg import Peg
            self._peg = Peg(latitude=peg[0],
                            longitude=peg[1],
                            heading=peg[2],
                            radiusOfCurvature=rc)

            self.logger.info(
                "UAVSAR_Polsar: peg radius of curvature = {}".format(
                    self.elp.pegRadCur))
            self.logger.info("UAVSAR_Polsar: terrain height = {}".format(th))
            self.logger.info("UAVSAR_Polsar: mocomp II applied = {}".format(
                self.metadata['Mocomp II Applied']))

        return self._peg
Exemplo n.º 3
0
class Sentinel1A(Component):
    """
        A Class representing RadarSAT 2 data
    """
    def __init__(self):
        Component.__init__(self)
        self.xml = None
        self.tiff = None
        self.orbitfile = None
        self.output = None
        self.frame = Frame()
        self.frame.configure()

        self._xml_root = None
        self.descriptionOfVariables = {}
        self.dictionaryOfVariables = {
            'XML': ['self.xml', 'str', 'mandatory'],
            'TIFF': ['self.tiff', 'str', 'mandatory'],
            'ORBITFILE': ['self.orbitfile', 'str', 'optional'],
            'OUTPUT': ['self.output', 'str', 'optional']
        }

    def getFrame(self):
        return self.frame

    def parse(self):
        try:
            fp = open(self.xml, 'r')
        except IOError as strerr:
            print("IOError: %s" % strerr)
            return
        self._xml_root = ElementTree(file=fp).getroot()
        #        self.product.set_from_etnode(self._xml_root)
        self.populateMetadata()

        fp.close()

    def grab_from_xml(self, path):
        try:
            res = self._xml_root.find(path).text
        except:
            raise Exception('Tag= %s not found' % (path))

        if res is None:
            raise Exception('Tag = %s not found' % (path))

        return res

    def convertToDateTime(self, string):
        dt = datetime.datetime.strptime(string, "%Y-%m-%dT%H:%M:%S.%f")
        return dt

    def populateMetadata(self):
        """
            Create metadata objects from the metadata files
        """
        ####Set each parameter one - by - one
        mission = self.grab_from_xml('adsHeader/missionId')
        swath = self.grab_from_xml('adsHeader/swath')
        polarization = self.grab_from_xml('adsHeader/polarisation')

        frequency = float(
            self.grab_from_xml(
                'generalAnnotation/productInformation/radarFrequency'))
        passDirection = self.grab_from_xml(
            'generalAnnotation/productInformation/pass')

        rangePixelSize = float(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/rangePixelSpacing'))
        azimuthPixelSize = float(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/azimuthPixelSpacing'))
        rangeSamplingRate = Const.c / (2.0 * rangePixelSize)
        prf = 1.0 / float(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/azimuthTimeInterval'))

        lines = int(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/numberOfLines'))
        samples = int(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/numberOfSamples'))

        startingRange = float(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/slantRangeTime')
        ) * Const.c / 2.0
        incidenceAngle = float(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/incidenceAngleMidSwath'))
        dataStartTime = self.convertToDateTime(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/productFirstLineUtcTime'))
        dataStopTime = self.convertToDateTime(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/productLastLineUtcTime'))

        pulseLength = float(
            self.grab_from_xml(
                'generalAnnotation/downlinkInformationList/downlinkInformation/downlinkValues/txPulseLength'
            ))
        chirpSlope = float(
            self.grab_from_xml(
                'generalAnnotation/downlinkInformationList/downlinkInformation/downlinkValues/txPulseRampRate'
            ))
        pulseBandwidth = pulseLength * chirpSlope

        ####Sentinel is always right looking
        lookSide = -1
        facility = 'EU'
        version = '1.0'

        #        height = self.product.imageGenerationParameters.sarProcessingInformation._satelliteHeight

        ####Populate platform
        platform = self.frame.getInstrument().getPlatform()
        platform.setPlanet(Planet(pname="Earth"))
        platform.setMission(mission)
        platform.setPointingDirection(lookSide)
        platform.setAntennaLength(2 * azimuthPixelSize)

        ####Populate instrument
        instrument = self.frame.getInstrument()
        instrument.setRadarFrequency(frequency)
        instrument.setPulseRepetitionFrequency(prf)
        instrument.setPulseLength(pulseLength)
        instrument.setChirpSlope(pulseBandwidth / pulseLength)
        instrument.setIncidenceAngle(incidenceAngle)
        #self.frame.getInstrument().setRangeBias(0)
        instrument.setRangePixelSize(rangePixelSize)
        instrument.setRangeSamplingRate(rangeSamplingRate)
        instrument.setBeamNumber(swath)
        instrument.setPulseLength(pulseLength)

        #Populate Frame
        #self.frame.setSatelliteHeight(height)
        self.frame.setSensingStart(dataStartTime)
        self.frame.setSensingStop(dataStopTime)
        diffTime = DTUtil.timeDeltaToSeconds(dataStopTime -
                                             dataStartTime) / 2.0
        sensingMid = dataStartTime + datetime.timedelta(
            microseconds=int(diffTime * 1e6))
        self.frame.setSensingMid(sensingMid)
        self.frame.setPassDirection(passDirection)
        self.frame.setPolarization(polarization)
        self.frame.setStartingRange(startingRange)
        self.frame.setFarRange(startingRange + (samples - 1) * rangePixelSize)
        self.frame.setNumberOfLines(lines)
        self.frame.setNumberOfSamples(samples)
        self.frame.setProcessingFacility(facility)
        self.frame.setProcessingSoftwareVersion(version)

        self.frame.setPassDirection(passDirection)

        ResOrbFlag = self.extractResOrbit()
        if ResOrbFlag == 0:
            print(
                "cannot find POD Restituted Orbit, using orbit coming along with SLC"
            )
            self.extractOrbit()

######################################################################################

    def extractResOrbit(self):
        #read ESA's POD Restituted Orbit by Cunren Liang, APR. 2, 2015.
        import pathlib

        useResOrbFlag = 0

        ResOrbDir = os.environ.get('RESORB')
        if ResOrbDir != None:
            print("Trying to find POD Restituted Orbit...")
            #get start time and stop time of the SLC data from data xml file
            dataStartTime = self.convertToDateTime(
                self.grab_from_xml(
                    'imageAnnotation/imageInformation/productFirstLineUtcTime')
            )
            dataStopTime = self.convertToDateTime(
                self.grab_from_xml(
                    'imageAnnotation/imageInformation/productLastLineUtcTime'))

            #RESORB has an orbit every 10 sec, extend the start and stop time by 50 sec.
            dataStartTimeExt = dataStartTime - datetime.timedelta(0, 50)
            dataStopTimeExt = dataStopTime + datetime.timedelta(0, 50)

            ###########################
            #deal with orbit directory
            ###########################

            orbList = pathlib.Path(ResOrbDir).glob('**/*.EOF')
            for orb in orbList:
                #save full path
                orb = str(orb)
                orbx = orb

                #get orbit file name
                orb = os.path.basename(os.path.normpath(orb))
                #print("{0}".format(orb))

                #get start and stop time of the orbit file
                orbStartTime = datetime.datetime.strptime(
                    orb[42:57], "%Y%m%dT%H%M%S")
                orbStopTime = datetime.datetime.strptime(
                    orb[58:73], "%Y%m%dT%H%M%S")
                #print("{0}, {1}".format(orbStartTime, orbStopTime))

                if dataStartTimeExt >= orbStartTime and dataStopTimeExt <= orbStopTime:
                    try:
                        orbfp = open(orbx, 'r')
                    except IOError as strerr:
                        print("IOError: %s" % strerr)
                        return useResOrbFlag
                    orbxml = ElementTree(file=orbfp).getroot()
                    print('using orbit file: {0}'.format(orbx))

                    frameOrbit = Orbit()
                    frameOrbit.setOrbitSource('Restituted')

                    #find the orbit data from the file, and use them
                    node = orbxml.find('Data_Block/List_of_OSVs'
                                       )  #note upper case and lower case
                    for child in node.getchildren():
                        timestamp = self.convertToDateTime(
                            child.find('UTC').text[4:])
                        if timestamp < dataStartTimeExt:
                            continue
                        if timestamp > dataStopTimeExt:
                            break

                        pos = []
                        vel = []
                        for tag in ['X', 'Y', 'Z']:
                            pos.append(float(child.find(tag).text))
                            vel.append(float(child.find('V' + tag).text))

                        vec = StateVector()
                        vec.setTime(timestamp)
                        vec.setPosition(pos)
                        vec.setVelocity(vel)
                        frameOrbit.addStateVector(vec)

                    #there is no need to extend the orbit any longer
                    #planet = self.frame.instrument.platform.planet
                    #orbExt = OrbitExtender(planet=planet)
                    #orbExt.configure()
                    #newOrb = orbExt.extendOrbit(frameOrbit)

                    self.frame.getOrbit().setOrbitSource('Restituted')
                    for sv in frameOrbit:
                        self.frame.getOrbit().addStateVector(sv)

                    orbfp.close()
                    useResOrbFlag = 1
                    break
        return useResOrbFlag
######################################################################################

    def extractOrbit(self):
        '''
        Extract orbit information from xml node.
        '''

        node = self._xml_root.find('generalAnnotation/orbitList')
        frameOrbit = Orbit()
        frameOrbit.setOrbitSource('Header')

        for child in node.getchildren():
            timestamp = self.convertToDateTime(child.find('time').text)
            pos = []
            vel = []
            posnode = child.find('position')
            velnode = child.find('velocity')
            for tag in ['x', 'y', 'z']:
                pos.append(float(posnode.find(tag).text))

            for tag in ['x', 'y', 'z']:
                vel.append(float(velnode.find(tag).text))

            vec = StateVector()
            vec.setTime(timestamp)
            vec.setPosition(pos)
            vec.setVelocity(vel)
            frameOrbit.addStateVector(vec)

        planet = self.frame.instrument.platform.planet
        orbExt = OrbitExtender(planet=planet)
        orbExt.configure()
        newOrb = orbExt.extendOrbit(frameOrbit)

        self.frame.getOrbit().setOrbitSource('Header')
        for sv in newOrb:
            self.frame.getOrbit().addStateVector(sv)

        return

    def extractPreciseOrbit(self):
        '''
        Extract precise orbit from given Orbit file.
        '''
        try:
            fp = open(self.orbitfile, 'r')
        except IOError as strerr:
            print("IOError: %s" % strerr)
            return

        _xml_root = ElementTree(file=fp).getroot()

        node = _xml_root.find('Data_Block/List_of_OSVs')

        orb = Orbit()
        orb.configure()

        margin = datetime.timedelta(seconds=40.0)
        tstart = self.frame.getSensingStart() - margin
        tend = self.frame.getSensingStop() + margin

        for child in node.getchildren():
            timestamp = self.convertToDateTime(child.find('UTC').text[4:])

            if (timestamp >= tstart) and (timestamp < tend):

                pos = []
                vel = []

                for tag in ['VX', 'VY', 'VZ']:
                    vel.append(float(child.find(tag).text))

                for tag in ['X', 'Y', 'Z']:
                    pos.append(float(child.find(tag).text))

                vec = StateVector()
                vec.setTime(timestamp)
                vec.setPosition(pos)
                vec.setVelocity(vel)
                orb.addStateVector(vec)

        fp.close()

        self.frame.getOrbit().setOrbitSource('Header')
        for sv in orb:
            self.frame.getOrbit().addStateVector(sv)

        return

    def extractImage(self):
        """
           Use gdal python bindings to extract image
        """
        try:
            from osgeo import gdal
        except ImportError:
            raise Exception(
                'GDAL python bindings not found. Need this for RSAT2/ TandemX / Sentinel1A.'
            )

        self.parse()
        width = self.frame.getNumberOfSamples()
        lgth = self.frame.getNumberOfLines()

        src = gdal.Open(self.tiff.strip(), gdal.GA_ReadOnly)
        band = src.GetRasterBand(1)
        fid = open(self.output, 'wb')
        for ii in range(lgth):
            data = band.ReadAsArray(0, ii, width, 1)
            data.tofile(fid)

        fid.close()
        src = None
        band = None

        ####
        slcImage = isceobj.createSlcImage()
        slcImage.setByteOrder('l')
        slcImage.setFilename(self.output)
        slcImage.setAccessMode('read')
        slcImage.setWidth(self.frame.getNumberOfSamples())
        slcImage.setLength(self.frame.getNumberOfLines())
        slcImage.setXmin(0)
        slcImage.setXmax(self.frame.getNumberOfSamples())
        self.frame.setImage(slcImage)

    def extractDoppler(self):
        '''
        self.parse()
        Extract doppler information as needed by mocomp
        '''
        #        ins = self.frame.getInstrument()
        #        dc = self.product.imageGenerationParameters.dopplerCentroid
        quadratic = {}

        #        r0 = self.frame.startingRange
        #        fs = ins.getRangeSamplingRate()
        #        tNear = 2*r0/Const.c

        #        tMid = tNear + 0.5*self.frame.getNumberOfSamples()/fs
        #        t0 = dc.dopplerCentroidReferenceTime
        #        poly = dc.dopplerCentroidCoefficients

        #        fd_mid = 0.0
        #        for kk in range(len(poly)):
        #            fd_mid += poly[kk] * (tMid - t0)**kk

        #        quadratic['a'] = fd_mid / ins.getPulseRepetitionFrequency()
        quadratic['a'] = 0.
        quadratic['b'] = 0.
        quadratic['c'] = 0.
        return quadratic
Exemplo n.º 4
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
Exemplo n.º 5
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
Exemplo n.º 6
0
class ERS_EnviSAT(Sensor):

    parameter_list = (IMAGEFILE, ORBIT_TYPE, ORBIT_DIRECTORY,
                      ORBIT_FILE) + Sensor.parameter_list
    """
        A Class for parsing ERS_EnviSAT_format image files
        There is no LEADERFILE file, which was required for old ERS [disk image] raw
        data, i.e. [ERS.py] sensor. There is also no INSTRUMENT file. All required
        default headers/parameters are stored in the image data file itself
    """

    family = 'ers_envisat'

    def __init__(self, family='', name=''):
        super(ERS_EnviSAT,
              self).__init__(family if family else self.__class__.family,
                             name=name)
        self.imageFile = None
        self._imageFileData = None
        self.logger = logging.getLogger("isce.sensor.ERA_EnviSAT")

        self.frame = None
        self.frameList = []

        # Constants are from the paper below:
        # J. J. Mohr and Soren. 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,
            'chirp': 0.419137466e12,
            'waveLength': 0.0565646,
            'pulseLength': 37.10e-06,
            'SEC_PER_PRI_COUNT': 210.943006e-9,
            'numberOfSamples': 11232
        }
        return None

    def getFrame(self):
        return self.frame

    def populateMetadata(self):
        """Create the appropriate metadata objects from ERS Envisat-type metadata"""
        print("Debug Flag: start populate Metadata")
        self._populatePlatform()
        self._populateInstrument()
        self._populateFrame()
        if (self._orbitType == 'ODR'):
            self._populateDelftOrbits()
        elif (self._orbitType == 'PRC'):
            self._populatePRCOrbits()
        else:
            self.logger.error("ERROR: no orbit type (ODR or PRC")

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

        platform.setMission("ERS" + str(self._imageFileData['PRODUCT'][61]))
        platform.setAntennaLength(self.constants['antennaLength'])
        platform.setPointingDirection(-1)
        platform.setPlanet(Planet(pname='Earth'))

    def _populateInstrument(self):
        """Populate the instrument object with metadata"""
        instrument = self.frame.getInstrument()
        pri = (self._imageFileData['pri_counter'] +
               2.0) * self.constants['SEC_PER_PRI_COUNT']
        print("Debug: pri = ", pri)
        rangeSamplingRate = self.constants['rangeSamplingRate']
        rangePixelSize = Const.c / (2.0 * rangeSamplingRate)
        prf = 1.0 / pri
        self._imageFileData['prf'] = prf

        instrument.setRadarWavelength(self.constants['waveLength'])
        # instrument.setIncidenceAngle(self.leaderFile.sceneHeaderRecord.metadata['Incidence angle at scene centre']) # comment out +HB, need to check
        instrument.setPulseRepetitionFrequency(prf)
        instrument.setRangeSamplingRate(rangeSamplingRate)
        instrument.setRangePixelSize(rangePixelSize)
        instrument.setPulseLength(self.constants['pulseLength'])
        instrument.setChirpSlope(self.constants['chirp'])
        instrument.setInPhaseValue(self.constants['iBias'])
        instrument.setQuadratureValue(self.constants['qBias'])
        print("Debug Flag Populate Instrument Done")

    def _populateFrame(self):
        """Populate the scene object with metadata"""
        numberOfLines = self._imageFileData[
            'length']  # updated the value after findSwst and extractIQ
        numberOfSamples = self._imageFileData[
            'width']  # updated value after findSwst and extractIQ
        frame = 0  # ERS in Envisat format header does not contain frame number!
        pulseInterval = (self._imageFileData['pri_counter'] +
                         2.0) * self.constants['SEC_PER_PRI_COUNT']
        rangeSamplingRate = self.constants['rangeSamplingRate']
        rangePixelSize = Const.c / (2.0 * rangeSamplingRate)
        startingRange = (9 * pulseInterval +
                         self._imageFileData['minSwst'] * 4 / rangeSamplingRate
                         - self.constants['delayTime']) * Const.c / 2.0
        farRange = startingRange + self._imageFileData['width'] * rangePixelSize

        first_line_utc = datetime.datetime.strptime(
            self._imageFileData['SENSING_START'], '%d-%b-%Y %H:%M:%S.%f')
        mid_line_utc = datetime.datetime.strptime(
            self._imageFileData['SENSING_START'], '%d-%b-%Y %H:%M:%S.%f')
        last_line_utc = datetime.datetime.strptime(
            self._imageFileData['SENSING_STOP'], '%d-%b-%Y %H:%M:%S.%f')
        centerTime = DTU.timeDeltaToSeconds(last_line_utc -
                                            first_line_utc) / 2.0
        mid_line_utc = mid_line_utc + datetime.timedelta(
            microseconds=int(centerTime * 1e6))

        print("Debug Print: Frame UTC start, mid, end times:  %s %s %s" %
              (first_line_utc, mid_line_utc, last_line_utc))

        self.frame.setFrameNumber(frame)
        self.frame.setProcessingFacility(self._imageFileData['PROC_CENTER'])
        self.frame.setProcessingSystem(self._imageFileData['SOFTWARE_VER'])
        self.frame.setTrackNumber(int(self._imageFileData['REL_ORBIT']))
        self.frame.setOrbitNumber(int(self._imageFileData['ABS_ORBIT']))
        self.frame.setPolarization(self.constants['polarization'])
        self.frame.setNumberOfSamples(numberOfSamples)
        self.frame.setNumberOfLines(numberOfLines)
        self.frame.setStartingRange(startingRange)
        self.frame.setFarRange(farRange)
        self.frame.setSensingStart(first_line_utc)
        self.frame.setSensingMid(mid_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()
        orbitFile = arclist.getOrbitFile(self.frame.getSensingStart())
        self.logger.info('Using ODR file: ' + orbitFile)

        odr = ODR(file=os.path.join(self._orbitDir, orbitFile))
        # It seem that for this tipe of orbit points are separated by 60 sec. In ODR at
        # least 9 state vectors are needed to compute the velocities. add extra time before
        # and after to allow interpolation, but do not do it for all data points. too slow
        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)
        print("Debug populate Delft Orbits Done")
        print(startTime, stopTime)

    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 _populateImage(self, outname):
        width = self._imageFileData['width']

        # Create a RawImage object
        rawImage = isceobj.createRawImage()
        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):
        import array
        import math

        self.frameList = []

        for i in range(len(self._imageFileList)):
            appendStr = "_" + str(i)  #intermediate raw files suffix
            if (len(self._imageFileList) == 1):
                appendStr = ''  #if only one file don't change the name

            outputNow = self.output + appendStr
            auxImage = isceobj.createImage()  # unused
            widthAux = 2  # unused
            auxName = outputNow + '.aux'

            self.imageFile = self._imageFileList[i]
            self.frame = Frame()
            self.frame.configure()

            self.frame.auxFile = auxName  #add the auxFile as part of the frame and diring the stitching create also a combined aux file # HB: added from Envisat.py
            imageFileParser = ImageFile(fileName=self.imageFile)
            self._imageFileData = imageFileParser.parse(
            )  # parse image and get swst values and new width

            try:
                outputNow = self.output + appendStr
                out = open(outputNow, 'wb')
            except IOError as strerr:
                self.logger.error("IOError: %s" % strerr)
                return

            imageFileParser.extractIQ(
                output=out)  # IMPORTANT for ERS Envisat-type data
            out.close()

            self.populateMetadata(
            )  # populate Platform, Instrument, Frame, and Orbit
            self._populateImage(outputNow)
            self.frameList.append(self.frame)

            ### Below: create a aux file
            # for now create the orbit aux file based in starting time and prf
            prf = self.frame.getInstrument().getPulseRepetitionFrequency()
            senStart = self.frame.getSensingStart()
            numPulses = int(
                math.ceil(
                    DTU.timeDeltaToSeconds(self.frame.getSensingStop() -
                                           senStart) * prf))
            # the aux files has two entries per line. day of the year and microseconds in the day
            musec0 = (senStart.hour * 3600 + senStart.minute * 60 +
                      senStart.second) * 10**6 + senStart.microsecond
            maxMusec = (
                24 * 3600
            ) * 10**6  # use it to check if we went across a day. very rare
            day0 = (datetime.datetime(senStart.year, senStart.month,
                                      senStart.day) -
                    datetime.datetime(senStart.year, 1, 1)).days + 1
            outputArray = array.array('d', [0] * 2 * numPulses)
            self.frame.auxFile = outputNow + '.aux'
            fp = open(self.frame.auxFile, 'wb')
            j = -1
            for i1 in range(numPulses):
                j += 1
                musec = round((j / prf) * 10**6) + musec0
                if musec >= maxMusec:
                    day0 += 1
                    musec0 = musec % maxMusec
                    musec = musec0
                    j = 0
                outputArray[2 * i1] = day0
                outputArray[2 * i1 + 1] = musec

            outputArray.tofile(fp)
            fp.close()

        ## refactor this with __init__.tkfunc
        tk = Track()
        if (len(self._imageFileList) > 1):
            self.frame = tk.combineFrames(self.output, self.frameList)

            for i in range(len(self._imageFileList)):
                try:
                    os.remove(self.output + "_" + str(i))
                except OSError:
                    print("Error. Cannot remove temporary file",
                          self.output + "_" + str(i))
                    raise OSError
Exemplo n.º 7
0
class Generic(Component):
    """
    A class to parse generic SAR data stored in the HDF5 format
    """

    logging_name = 'isce.sensor.Generic'

    def __init__(self):
        super(Generic, self).__init__()
        self._hdf5File = None
        self.output = None
        self.frame = Frame()
        self.frame.configure()

        self.logger = logging.getLogger('isce.sensor.Generic')

        self.descriptionOfVariables = {}
        self.dictionaryOfVariables = {
            'HDF5': ['self._hdf5File', 'str', 'mandatory'],
            'OUTPUT': ['self.output', 'str', 'optional']
        }
        return None

    def getFrame(self):
        return self.frame

    def parse(self):
        try:
            fp = h5py.File(self._hdf5File, 'r')
        except Exception as strerror:
            self.logger.error("IOError: %s" % strerror)
            return

        self.populateMetadata(fp)
        fp.close()

    def populateMetadata(self, file):
        """
        Create the appropriate metadata objects from our HDF5 file
        """
        self._populatePlatform(file)
        self._populateInstrument(file)
        self._populateFrame(file)
        self._populateOrbit(file)

    def _populatePlatform(self, file):
        platform = self.frame.getInstrument().getPlatform()

        platform.setMission(file['Platform'].attrs['Mission'])
        platform.setPlanet(Planet(pname='Earth'))
        platform.setAntennaLength(file['Platform'].attrs['Antenna Length'])

    def _populateInstrument(self, file):
        instrument = self.frame.getInstrument()

        instrument.setRadarWavelength(file['Instrument'].attrs['Wavelength'])
        instrument.setPulseRepetitionFrequency(
            file['Instrument'].attrs['Pulse Repetition Frequency'])
        instrument.setRangePixelSize(
            file['Instrument'].attrs['Range Pixel Size'])
        instrument.setPulseLength(file['Instrument'].attrs['Pulse Length'])
        instrument.setChirpSlope(file['Instrument'].attrs['Chirp Slope'])
        instrument.setRangeSamplingRate(
            file['Instrument'].attrs['Range Sampling Frequency'])
        instrument.setInPhaseValue(file['Frame'].attrs['In Phase Bias'])
        instrument.setQuadratureValue(file['Frame'].attrs['Quadrature Bias'])

    def _populateFrame(self, file):
        size = file['Frame'].shape
        start = DTU.parseIsoDateTime(file['Frame'].attrs['Sensing Start'])
        stop = DTU.parseIsoDateTime(file['Frame'].attrs['Sensing Stop'])
        deltaT = DTU.timeDeltaToSeconds(stop - start)
        mid = start + datetime.timedelta(microseconds=int(deltaT / 2.0 * 1e6))
        startingRange = file['Frame'].attrs['Starting Range']
        rangePixelSize = file['Instrument'].attrs['Range Pixel Size']
        farRange = startingRange + size[1] * rangePixelSize

        self.frame.setStartingRange(file['Frame'].attrs['Starting Range'])
        self.frame.setFarRange(farRange)
        self.frame.setNumberOfLines(size[0])
        self.frame.setNumberOfSamples(2 * size[1])
        self.frame.setSensingStart(start)
        self.frame.setSensingMid(mid)
        self.frame.setSensingStop(stop)

    def _populateOrbit(self, file):
        orbit = self.frame.getOrbit()

        orbit.setReferenceFrame('ECR')
        orbit.setOrbitSource(file['Orbit'].attrs['Source'])

        for i in range(len(file['Orbit']['Time'])):
            vec = StateVector()
            time = DTU.parseIsoDateTime(file['Orbit']['Time'][i])
            vec.setTime(time)
            vec.setPosition(list(file['Orbit']['Position'][i]))
            vec.setVelocity(list(file['Orbit']['Velocity'][i]))
            orbit.addStateVector(vec)

    def extractImage(self):
        try:
            file = h5py.File(self._hdf5File, 'r')
        except Exception as strerror:
            self.logger.error("IOError: %s" % strerror)
            return
        size = file['Frame'].shape
        dtype = self._translateDataType(file['Frame'].attrs['Image Type'])
        length = size[0]
        width = size[1]
        data = numpy.memmap(self.output,
                            dtype=dtype,
                            mode='w+',
                            shape=(length, width, 2))
        data[:, :, :] = file['Frame'][:, :, :]
        del data

        rawImage = isceobj.createRawImage()
        rawImage.setByteOrder('l')
        rawImage.setAccessMode('r')
        rawImage.setFilename(self.output)
        rawImage.setWidth(2 * width)
        rawImage.setXmin(0)
        rawImage.setXmax(2 * width)
        self.frame.setImage(rawImage)
        self.populateMetadata(file)

        file.close()

    def write(self, output, compression=None):
        """
        Given a frame object (appropriately populated) and an image, create
        an HDF5 from those objects.
        """
        if (not self.frame):
            self.logger.error("Frame not set")
            raise AttributeError("Frame not set")

        h5file = h5py.File(output, 'w')
        self._writeMetadata(h5file, compression)

    def _writeMetadata(self, h5file, compression=None):
        self._writePlatform(h5file)
        self._writeInstrument(h5file)
        self._writeFrame(h5file, compression)
        self._writeOrbit(h5file)

    def _writePlatform(self, h5file):
        platform = self.frame.getInstrument().getPlatform()
        if (not platform):
            self.logger.error("Platform not set")
            raise AttributeError("Platform not set")

        group = h5file.create_group('Platform')
        group.attrs['Mission'] = platform.getMission()
        group.attrs['Planet'] = platform.getPlanet().name
        group.attrs['Antenna Length'] = platform.getAntennaLength()

    def _writeInstrument(self, h5file):
        instrument = self.frame.getInstrument()
        if (not instrument):
            self.logger.error("Instrument not set")
            raise AttributeError("Instrument not set")

        group = h5file.create_group('Instrument')
        group.attrs['Wavelength'] = instrument.getRadarWavelength()
        group.attrs[
            'Pulse Repetition Frequency'] = instrument.getPulseRepetitionFrequency(
            )
        group.attrs['Range Pixel Size'] = instrument.getRangePixelSize()
        group.attrs['Pulse Length'] = instrument.getPulseLength()
        group.attrs['Chirp Slope'] = instrument.getChirpSlope()
        group.attrs[
            'Range Sampling Frequency'] = instrument.getRangeSamplingRate()
        group.attrs['In Phase Bias'] = instrument.getInPhaseValue()
        group.attrs['Quadrature Bias'] = instrument.getQuadratureValue()

    def _writeFrame(self, h5file, compression=None):
        group = self._writeImage(h5file, compression)
        group.attrs['Starting Range'] = self.frame.getStartingRange()
        group.attrs['Sensing Start'] = self.frame.getSensingStart().isoformat()
        group.attrs['Sensing Stop'] = self.frame.getSensingStop().isoformat()

    def _writeImage(self, h5file, compression=None):
        image = self.frame.getImage()
        if (not image):
            self.logger.error("Image not set")
            raise AttributeError("Image not set")
        filename = image.getFilename()
        length = image.getLength()
        width = image.getWidth()

        dtype = self._translateDataType(image.dataType)
        if (image.dataType == 'BYTE'):
            width = int(width / 2)

        self.logger.debug("Width: %s" % (width))
        self.logger.debug("Length: %s" % (length))
        data = numpy.memmap(filename,
                            dtype=dtype,
                            mode='r',
                            shape=(length, 2 * width))
        dset = h5file.create_dataset("Frame", (length, width, 2),
                                     dtype=dtype,
                                     compression=compression)
        dset.attrs['Image Type'] = image.dataType
        dset[:, :, 0] = data[:, ::2]
        dset[:, :, 1] = data[:, 1::2]
        del data

        return dset

    def _writeOrbit(self, h5file):
        # Add orbit information
        (time, position, velocity) = self._orbitToArray()
        group = h5file.create_group("Orbit")
        group.attrs['Source'] = self.frame.getOrbit().getOrbitSource()
        group.attrs['Reference Frame'] = self.frame.getOrbit(
        ).getReferenceFrame()
        timedset = h5file.create_dataset("Orbit/Time",
                                         time.shape,
                                         dtype=time.dtype)
        posdset = h5file.create_dataset("Orbit/Position",
                                        position.shape,
                                        dtype=numpy.float64)
        veldset = h5file.create_dataset("Orbit/Velocity",
                                        velocity.shape,
                                        dtype=numpy.float64)
        timedset[...] = time
        posdset[...] = position
        veldset[...] = velocity

    def _orbitToArray(self):
        orbit = self.frame.getOrbit()
        if (not orbit):
            self.logger.error("Orbit not set")
            raise AttributeError("Orbit not set")

        time = []
        position = []
        velocity = []
        for sv in orbit:
            timeString = sv.getTime().isoformat()
            time.append(timeString)
            position.append(sv.getPosition())
            velocity.append(sv.getVelocity())

        return numpy.array(time), numpy.array(position), numpy.array(velocity)

    def _translateDataType(self, imageType):
        dtype = ''
        if (imageType == 'BYTE'):
            dtype = 'int8'
        elif (imageType == 'CFLOAT'):
            dtype = 'float32'
        elif (imageType == 'SHORT'):
            dtype = 'int16'
        else:
            self.logger.error("Unknown data type %s" % (imageType))
            raise ValueError("Unknown data type %s" % (imageType))

        return dtype
Exemplo n.º 8
0
class UAVSAR_Stack(Component):
    """
    A class representing a UAVSAR SLC.
    """

    family = 'uavsar_stack'
    logging_name = 'isce.Sensor.UAVSAR_Stack'
    lookMap = {'RIGHT': -1, 'LEFT': 1}

    parameter_list = (METADATAFILE, SEGMENT_INDEX)

    @logged
    def __init__(self, name=''):
        super().__init__(family=self.family, name=name)
        self.frame = Frame()
        self.frame.configure()
        self._elp = None
        self._peg = None
        elp = self.elp
        return

    def _populatePlatform(self, **kwargs):
        platform = self.frame.getInstrument().getPlatform()
        platform.setMission('UAVSAR')
        platform.setPointingDirection(
            self.lookMap[self.metadata['Look Direction'].upper()])
        platform.setPlanet(Planet(pname="Earth"))
        platform.setAntennaLength(self.metadata['Antenna Length'])
        return

    def _populateInstrument(self, **kwargs):
        instrument = self.frame.getInstrument()
        instrument.setRadarWavelength(self.metadata['Center Wavelength'])
        instrument.setPulseRepetitionFrequency(
            1.0 / self.metadata['Average Pulse Repetition Interval'])
        instrument.setRangePixelSize(
            self.metadata['1x1 SLC Range Pixel Spacing'])
        instrument.setAzimuthPixelSize(
            self.metadata['1x1 SLC Azimuth Pixel Spacing'])
        instrument.setPulseLength(self.metadata['Pulse Length'])
        instrument.setChirpSlope(-self.metadata['Bandwidth'] /
                                 self.metadata['Pulse Length'])
        from isceobj.Constants.Constants import SPEED_OF_LIGHT
        instrument.setRangeSamplingRate(SPEED_OF_LIGHT / 2.0 /
                                        instrument.getRangePixelSize())
        instrument.setIncidenceAngle(0.5 *
                                     (self.metadata['Minimum Look Angle'] +
                                      self.metadata['Maximum Look Angle']))

        return

    def _populateFrame(self):
        #Get the Start, Mid, and Stop times
        import datetime
        tStart = datetime.datetime.strptime(
            self.metadata['Start Time of Acquisition'], "%d-%b-%Y %H:%M:%S %Z")
        tStop = datetime.datetime.strptime(
            self.metadata['Stop Time of Acquisition'], "%d-%b-%Y %H:%M:%S %Z")
        dtMid = DTU.timeDeltaToSeconds(tStop - tStart) / 2.
        tMid = tStart + datetime.timedelta(microseconds=int(dtMid * 1e6))

        frame = self.frame
        frame._frameNumber = 1
        frame._trackNumber = 1
        frame.setSensingStart(tStart)
        frame.setSensingStop(tStop)
        frame.setSensingMid(tMid)
        frame.setNumberOfLines(int(self.metadata['slc_1_1x1_mag.set_rows']))
        frame.setNumberOfSamples(int(self.metadata['slc_1_1x1_mag.set_cols']))
        frame.setPolarization(self.metadata['Polarization'])
        frame.C0 = self.metadata['slc_1_1x1_mag.col_addr']
        frame.S0 = self.metadata['Segment {} Data Starting Azimuth'.format(
            self.segment_index)]
        frame.nearLookAngle = self.metadata['Minimum Look Angle']
        frame.farLookAngle = self.metadata['Maximum Look Angle']
        frame.setStartingRange(self.startingRange)
        frame.platformHeight = self.platformHeight
        width = frame.getNumberOfSamples()
        deltaRange = frame.instrument.getRangePixelSize()
        nearRange = frame.getStartingRange()
        midRange = nearRange + (width / 2.) * deltaRange
        frame.setFarRange(nearRange + width * deltaRange)
        self.extractDoppler()
        frame._ellipsoid = self.elp
        frame.peg = self.peg
        frame.procVelocity = self.velocity

        from isceobj.Location.Coordinate import Coordinate
        frame.upperLeftCorner = Coordinate()

        #The corner latitude, longitudes are given as a pair
        #of values in degrees at each corner (without rdf unit specified)
        llC = []
        for ic in range(1, 5):
            key = 'Segment {0} Data Approximate Corner {1}'.format(
                self.segment_index, ic)
            self.logger.info("key = {}".format(key))
            self.logger.info("metadata[key] = {}".format(
                self.metadata[key], type(self.metadata[key])))
            llC.append(list(map(float, self.metadata[key].split(','))))

        frame.terrainHeight = self.terrainHeight
        frame.upperLeftCorner.setLatitude(llC[0][0])
        frame.upperLeftCorner.setLongitude(llC[0][1])
        frame.upperLeftCorner.setHeight(self.terrainHeight)

        frame.upperRightCorner = Coordinate()
        frame.upperRightCorner.setLatitude(llC[1][0])
        frame.upperRightCorner.setLongitude(llC[1][1])
        frame.upperRightCorner.setHeight(self.terrainHeight)

        frame.lowerRightCorner = Coordinate()
        frame.lowerRightCorner.setLatitude(llC[2][0])
        frame.lowerRightCorner.setLongitude(llC[2][1])
        frame.lowerRightCorner.setHeight(self.terrainHeight)

        frame.lowerLeftCorner = Coordinate()
        frame.lowerLeftCorner.setLatitude(llC[3][0])
        frame.lowerLeftCorner.setLongitude(llC[3][1])
        frame.lowerLeftCorner.setHeight(self.terrainHeight)

        frame.nearLookAngle = math.degrees(self.metadata['Minimum Look Angle'])
        frame.farLookAngle = math.degrees(self.metadata['Maximum Look Angle'])

        return

    def _populateFrameSolo(self):
        self.logger.info("UAVSAR_Stack._populateFrameSolo")

    def _populateExtras(self):
        pass

    def _populateOrbit(self, **kwargs):
        """
        Create the orbit as the reference orbit defined by the peg
        """
        numgroup = 1000
        prf = self.frame.instrument.getPulseRepetitionFrequency()
        daz = self.frame.instrument.getAzimuthPixelSize()
        vel = daz * prf
        t0 = self.frame.getSensingStart()

        nlines = int((self.frame.getSensingStop() - t0).total_seconds() * prf)

        #make sure the elp property has been called
        elp = self.elp
        orbit = self.frame.getOrbit()
        orbit.setOrbitSource('Header')

        for i in range(-5 * numgroup,
                       int(nlines / numgroup) * numgroup + 5 * numgroup,
                       numgroup):
            delt = int(i * 1.0e6 / prf)
            torb = self.frame.getSensingStart() + datetime.timedelta(
                microseconds=delt)
            ###Need to compute offset
            ###While taking into account, rounding off in time
            ds = delt * 1.0e-6 * vel

            vec = OrbitStateVector()
            vec.setTime(torb)

            posSCH = [self.frame.S0 + ds, 0.0, self.platformHeight]
            velSCH = [self.velocity, 0., 0.]
            posXYZ, velXYZ = elp.schdot_to_xyzdot(posSCH, velSCH)
            vec.setPosition(posXYZ)
            vec.setVelocity(velXYZ)
            orbit.addStateVector(vec)

        return
        #t0 = (self.frame.getSensingStart() -
        #datetime.timedelta(microseconds=delta))
        #ds = deltaFactor*self.frame.instrument.getAzimuthPixelSize()
        #s0 = self.platformStartingAzimuth - numExtra*ds
        #self.logger.info("populateOrbit: frame.sensingStart, frame.sensingStop  = ", self.frame.getSensingStart(),
        #self.frame.getSensingStop())
        #self.logger.info("populateOrbit: deltaFactor, numExtra, dt = ", deltaFactor, numExtra, dt)
        #self.logger.info("populateOrbit: t0, startingAzimuth, platformStartingAzimuth, s0, ds = ",
        #t0, self.frame.S0, self.platformStartingAzimuth, s0, ds)
        #h = self.platformHeight
        #v = [self.velocity, 0., 0.]
        #self.logger.info("t0, dt = ", t0, dt)
        #self.logger.info("s0, ds, h = ", s0, ds, h)
        #self.logger.info("elp.pegRadCur = ", self.elp.pegRadCur)
        #self.logger.info("v = ", v[0])
        #platform = self.frame.getInstrument().getPlatform()
        #elp = self.elp   #make sure the elp property has been called
        #orbit = self.frame.getOrbit()
        #orbit.setOrbitSource('Header')

        #for i in range(int(self.frame.getNumberOfLines()/deltaFactor)+1000*numExtra+1):
        #vec = OrbitStateVector()
        #t = t0 + datetime.timedelta(microseconds=int(i*dt*1e6))
        #vec.setTime(t)
        #posSCH = [s0 + i*ds , 0., h]
        #velSCH = v
        #posXYZ, velXYZ = self.elp.schdot_to_xyzdot(posSCH, velSCH)
        #sch_pos, sch_vel = elp.xyzdot_to_schdot(posXYZ, velXYZ)

        #vec.setPosition(posXYZ)
        #vec.setVelocity(velXYZ)
        #orbit.addStateVector(vec)
        #return

    def populateMetadata(self):
        self._populatePlatform()
        self._populateInstrument()
        self._populateFrame()
        #self.extractDoppler()
        self._populateOrbit()

    def parse(self):
        from iscesys.Parsers import rdf
        self.metadata = rdf.parse(self.metadataFile)
        self.populateMetadata()

    def extractImage(self):
        self.parse()
        slcImage = isceobj.createSlcImage()
        self.slcname = self.metadata['slc_{}_1x1'.format(self.segment_index)]
        slcImage.setFilename(self.slcname)
        slcImage.setXmin(0)
        slcImage.setXmax(self.frame.getNumberOfSamples())
        slcImage.setWidth(self.frame.getNumberOfSamples())
        slcImage.setAccessMode('r')
        self.frame.setImage(slcImage)
        return

    def extractDoppler(self):
        """
        Read doppler values from the doppler file and fit a polynomial
        """
        frame = self.frame
        instrument = frame.getInstrument()
        rho0 = frame.getStartingRange()
        drho = instrument.getRangePixelSize(
        )  #full res value, not spacing in the dop file
        prf = instrument.getPulseRepetitionFrequency()
        self.logger.info("extractDoppler: rho0, drho, prf = {}, {}, {}".format(
            rho0, drho, prf))
        dopfile = self.metadata['dop']
        f = open(dopfile, 'r')
        x = f.readlines()  #first line is a header

        import numpy
        z = numpy.array(
            [list(map(float, e)) for e in list(map(str.split, x[1:]))])
        rho = z[:, 0]
        dop = z[:, 1]
        #rho0 = rho[0]
        #drho = (rho[1] - rho[0])/2.0
        rhoi = [(r - rho0) / drho for r in rho]
        polydeg = 6  #2  #Quadratic is built in for now
        fit = numpy.polynomial.polynomial.polyfit(rhoi,
                                                  dop,
                                                  polydeg,
                                                  rcond=1.e-9,
                                                  full=True)

        coefs = fit[0]
        res2 = fit[1][0]  #sum of squared residuals
        self.logger.info("coeffs = {}".format(coefs))
        self.logger.info("rms residual = {}".format(numpy.sqrt(res2 /
                                                               len(dop))))
        o = open("dop.txt", 'w')
        for i, d in zip(rhoi, dop):
            val = polyval(coefs, i)
            res = d - val
            o.write("{0} {1} {2} {3}\n".format(i, d, val, res))
            dopfile = self.metadata['dop']

        self.dopplerVals = {
            'Near': polyval(coefs, 0)
        }  #need this temporarily in this module

        self.logger.info(
            "UAVSAR_Stack.extractDoppler: self.dopplerVals = {}".format(
                self.dopplerVals))
        self.logger.info("UAVSAR_Stack.extractDoppler: prf = {}".format(prf))

        #The doppler file values are in units rad/m.  divide by 2*pi rad/cycle to convert
        #to cycle/m.  Then multiply by velocity to get Hz and divide by prf for dimensionless
        #doppler coefficients
        dop_scale = self.velocity / 2.0 / math.pi
        coefs = [x * dop_scale for x in coefs]
        #Set the coefs in frame._dopplerVsPixel because that is where DefaultDopp looks for them
        self.frame._dopplerVsPixel = coefs

        return coefs

    @property
    def terrainHeight(self):
        #The peg point incorporates the actual terrainHeight
        return 0.0

    @property
    def platformHeight(self):
        h = self.metadata['Global Average Altitude']
        #Reduce the platform height by the terrain height because the
        #peg radius of curvature includes the terrain height
        h -= self.metadata['Global Average Terrain Height']
        return h

    @property
    def platformStartingAzimuth(self):
        azimuth = self.frame.S0
        return azimuth

    @property
    def startingRange(self):
        return self.metadata['Image Starting Slant Range']

    @property
    def squintAngle(self):
        """
        Update this to use the sphere rather than planar approximation.
        """
        startingRange = self.startingRange
        h = self.platformHeight
        v = self.velocity
        prf = self.frame.getInstrument().getPulseRepetitionFrequency()
        wavelength = self.frame.getInstrument().getRadarWavelength()

        if h > startingRange:
            raise ValueError("Spacecraft Height too large (%s>%s)" %
                             (h, startingRange))

        sinTheta = math.sqrt(1 - (h / startingRange)**2)
        fd = self.dopplerVals['Near']
        sinSquint = fd / (2.0 * v * sinTheta) * wavelength

        if sinSquint**2 > 1:
            raise ValueError(
                "Error in One or More of the Squint Calculation Values\n" +
                "Doppler Centroid: %s\nVelocity: %s\nWavelength: %s\n" %
                (fd, v, wavelength))
        self.squint = math.degrees(
            math.atan2(sinSquint, math.sqrt(1 - sinSquint**2)))
        #squint is also required in the frame.
        self.frame.squintAngle = math.radians(self.squint)
        return self.squint

    @property
    def heightDt(self):
        """
        Delta(height)/Delta(Time) from frame start-time to mid-time
        """
        return 0.0

    @property
    def velocity(self):
        v = self.metadata['Average Along Track Velocity']
        platform = self.frame.getInstrument().getPlatform()
        elp = self.elp
        peg = self.peg
        scale = (elp.pegRadCur + self.platformHeight) / elp.pegRadCur
        ds_ground = self.frame.instrument.getAzimuthPixelSize()
        dt = 1.0 / self.frame.instrument.getPulseRepetitionFrequency()
        v1 = scale * ds_ground / dt
        return v1

    @property
    def elp(self):
        if not self._elp:
            planet = Planet(pname="Earth")
            self._elp = planet.get_elp()
        return self._elp

    @property
    def peg(self):
        if not self._peg:
            peg = [
                math.degrees(self.metadata['Peg Latitude']),
                math.degrees(self.metadata['Peg Longitude']),
                math.degrees(self.metadata['Peg Heading'])
            ]
            th = self.metadata['Global Average Terrain Height']
            platform = self.frame.getInstrument().getPlatform()
            self.elp.setSCH(peg[0], peg[1], peg[2], th)
            rc = self.elp.pegRadCur

            from isceobj.Location.Peg import Peg
            self._peg = Peg(latitude=peg[0],
                            longitude=peg[1],
                            heading=peg[2],
                            radiusOfCurvature=rc)
            self.logger.info(
                "UAVSAR_Stack: peg radius of curvature = {}".format(
                    self.elp.pegRadCur))
            self.logger.info("UAVSAR_Stack: terrain height = {}".format(th))

        return self._peg
Exemplo n.º 9
0
class ERS_SLC(Sensor):

    family = 'ers_slc'
    logging_name = 'isce.sensor.ers_slc'

    parameter_list = (IMAGEFILE,
                      LEADERFILE,
                      ORBIT_TYPE,
                      ORBIT_DIRECTORY,
                      ORBIT_FILE)      + Sensor.parameter_list

    @logged
    def __init__(self, name=''):
        super().__init__(family=self.__class__.family, name=name)

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

        # 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}
        return None

    def getFrame(self):
        return self.frame

    def parse(self):
        self.leaderFile = LeaderFile(file=self._leaderFile)
        self.leaderFile.parse()

        self.imageFile = ImageFile(self)
        self.imageFile.parse()

        self.populateMetadata()

    def populateMetadata(self):
        """
        Create the appropriate metadata objects from our CEOSFormat metadata
        """

        self._populatePlatform()
        self._populateInstrument()
        self._populateFrame()
        if (self._orbitType == 'ODR'):
            self._populateDelftOrbits()
        elif (self._orbitType == 'PRC'):
            self._populatePRCOrbits()
        elif (self._orbitType == 'PDS'):
            self._populatePDSOrbits()
        else:
            self._populateHeaderOrbit()

        self._populateDoppler()

    def _populatePlatform(self):
        """
        Populate the platform object with metadata
        """

        platform = self.frame.getInstrument().getPlatform()

        platform.setMission(self.leaderFile.sceneHeaderRecord.metadata[
            'Sensor platform mission identifier'])
        platform.setAntennaLength(self.constants['antennaLength'])
        platform.setPointingDirection(-1)
        platform.setPlanet(Planet(pname='Earth'))

    def _populateInstrument(self):
        """Populate the instrument object with metadata"""
        instrument = self.frame.getInstrument()
        prf = self.leaderFile.sceneHeaderRecord.metadata['Pulse Repetition Frequency']
        rangeSamplingRate = self.leaderFile.sceneHeaderRecord.metadata['Range sampling rate']*1.0e6
        rangePixelSize = Const.c/(2.0*rangeSamplingRate)

        instrument.setRadarWavelength(
            self.leaderFile.sceneHeaderRecord.metadata['Radar wavelength'])
        instrument.setIncidenceAngle(
            self.leaderFile.sceneHeaderRecord.metadata[
            'Incidence angle at scene centre'])
        instrument.setPulseRepetitionFrequency(prf)
        instrument.setRangeSamplingRate(rangeSamplingRate)
        instrument.setRangePixelSize(rangePixelSize)
        instrument.setPulseLength(self.leaderFile.sceneHeaderRecord.metadata[
            'Range pulse length']*1e-6)
        instrument.setChirpSlope(self.constants['chirpPulseBandwidth']/
            (self.leaderFile.sceneHeaderRecord.metadata['Range pulse length']*
             1e-6))
        instrument.setInPhaseValue(self.constants['iBias'])
        instrument.setQuadratureValue(self.constants['qBias'])

    def _populateFrame(self):
        """Populate the scene object with metadata"""
        rangeSamplingRate = self.constants['rangeSamplingRate']
        rangePixelSize = Const.c/(2.0*rangeSamplingRate)
        pulseInterval = 1.0/self.frame.getInstrument().getPulseRepetitionFrequency()
        frame = self._decodeSceneReferenceNumber(
            self.leaderFile.sceneHeaderRecord.metadata[
            'Scene reference number'])

        prf = self.frame.instrument.getPulseRepetitionFrequency()
        tau0 = self.leaderFile.sceneHeaderRecord.metadata['Zero-doppler range time of first range pixel']*1.0e-3
        startingRange = tau0*Const.c/2.0
        farRange = startingRange + self.imageFile.width*rangePixelSize


        first_line_utc = datetime.datetime.strptime(self.leaderFile.sceneHeaderRecord.metadata['Zero-doppler azimuth time of first azimuth pixel'], "%d-%b-%Y %H:%M:%S.%f")
        mid_line_utc = first_line_utc + datetime.timedelta(seconds = (self.imageFile.length-1) * 0.5 / prf)

        last_line_utc = first_line_utc + datetime.timedelta(seconds = (self.imageFile.length-1)/prf)

        self.logger.debug("Frame UTC start, mid, end times:  %s %s %s" % (first_line_utc,mid_line_utc,last_line_utc))

        self.frame.setFrameNumber(frame)
        self.frame.setOrbitNumber(self.leaderFile.sceneHeaderRecord.metadata['Orbit number'])
        self.frame.setStartingRange(startingRange)
        self.frame.setFarRange(farRange)
        self.frame.setProcessingFacility(self.leaderFile.sceneHeaderRecord.metadata['Processing facility identifier'])
        self.frame.setProcessingSystem(self.leaderFile.sceneHeaderRecord.metadata['Processing system identifier'])
        self.frame.setProcessingSoftwareVersion(self.leaderFile.sceneHeaderRecord.metadata['Processing version identifier'])
        self.frame.setPolarization(self.constants['polarization'])
        self.frame.setNumberOfLines(self.imageFile.length)
        self.frame.setNumberOfSamples(self.imageFile.width)
        self.frame.setSensingStart(first_line_utc)
        self.frame.setSensingMid(mid_line_utc)
        self.frame.setSensingStop(last_line_utc)

    def _populateHeaderOrbit(self):
        """Populate an orbit object with the header orbits"""
        self.logger.info("Using Header Orbits")
        orbit = self.frame.getOrbit()

        orbit.setOrbitSource('Header')
        orbit.setOrbitQuality('Unknown')
        t0 = datetime.datetime(year=self.leaderFile.platformPositionRecord.metadata['Year of data point'],
                               month=self.leaderFile.platformPositionRecord.metadata['Month of data point'],
                               day=self.leaderFile.platformPositionRecord.metadata['Day of data point'])
        t0 = t0 + datetime.timedelta(microseconds=self.leaderFile.platformPositionRecord.metadata['Seconds of day']*1e6)
        for i in range(self.leaderFile.platformPositionRecord.metadata['Number of data points']):
            vec = StateVector()
            deltaT = self.leaderFile.platformPositionRecord.metadata['Time interval between DATA points']
            t = t0 + datetime.timedelta(microseconds=i*deltaT*1e6)
            vec.setTime(t)
            dataPoints = self.leaderFile.platformPositionRecord.metadata['Positional Data Points'][i]
            vec.setPosition([dataPoints['Position vector X'], dataPoints['Position vector Y'], dataPoints['Position vector Z']])
            vec.setVelocity([dataPoints['Velocity vector X'], dataPoints['Velocity vector Y'], dataPoints['Velocity vector Z']])
            orbit.addStateVector(vec)

    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()
        orbitFile = arclist.getOrbitFile(self.frame.getSensingStart())
        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 _populateDoppler(self):
        '''
        Extract doppler from the CEOS file.
        '''

        prf = self.frame.instrument.getPulseRepetitionFrequency()

        #####ERS provides doppler as a function of slant range time in seconds
        d0 = self.leaderFile.sceneHeaderRecord.metadata['Cross track Doppler frequency centroid constant term']

        d1 = self.leaderFile.sceneHeaderRecord.metadata['Cross track Doppler frequency centroid linear term']

        d2 = self.leaderFile.sceneHeaderRecord.metadata['Cross track Doppler frequency centroid quadratic term']

        self.dopplerRangeTime = [d0, d1, d2]

        return

    def extractDoppler(self):

        width = self.frame.getNumberOfSamples()
        prf = self.frame.instrument.getPulseRepetitionFrequency()

        midtime = 0.5*width/self.frame.instrument.getRangeSamplingRate() 

        fd_mid = 0.0
        x = 1.0
        for ind, coeff in enumerate(self.dopplerRangeTime):
            fd_mid += coeff * x
            x *= midtime

        ####For insarApp
        quadratic = {}
        quadratic['a'] = fd_mid / prf
        quadratic['b'] = 0.0
        quadratic['c'] = 0.0


        ###For roiApp more accurate
        ####Convert stuff to pixel wise coefficients
        dr = self.frame.getInstrument().getRangePixelSize()
        norm = 0.5*Const.c/dr

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


        self.frame._dopplerVsPixel = dcoeffs
        print('Doppler Fit: ', fit[::-1])

        return quadratic



    def extractImage(self):
        import array
        import math

        self.parse()
        try:
            out = open(self.output, 'wb')
        except:
            raise Exception('Cannot open output file: %s'%(self.output))

        self.imageFile.extractImage(output=out)
        out.close()

        rawImage = isceobj.createSlcImage()
        rawImage.setByteOrder('l')
        rawImage.setAccessMode('read')
        rawImage.setFilename(self.output)
        rawImage.setWidth(self.imageFile.width)
        rawImage.setXmin(0)
        rawImage.setXmax(self.imageFile.width)
        self.frame.setImage(rawImage)

        prf = self.frame.getInstrument().getPulseRepetitionFrequency()
        senStart = self.frame.getSensingStart()
        numPulses = int(math.ceil(DTU.timeDeltaToSeconds(self.frame.getSensingStop()-senStart)*prf))
        musec0 = (senStart.hour*3600 + senStart.minute*60 + senStart.second)*10**6 + senStart.microsecond
        maxMusec = (24*3600)*10**6#use it to check if we went across  a day. very rare
        day0 = (datetime.datetime(senStart.year,senStart.month,senStart.day) - datetime.datetime(senStart.year,1,1)).days + 1
        outputArray  = array.array('d',[0]*2*numPulses)
        self.frame.auxFile = self.output + '.aux'
        fp = open(self.frame.auxFile,'wb')
        j = -1
        for i1 in range(numPulses):
            j += 1
            musec = round((j/prf)*10**6) + musec0
            if musec >= maxMusec:
                day0 += 1
                musec0 = musec%maxMusec
                musec = musec0
                j = 0
            outputArray[2*i1] = day0
            outputArray[2*i1+1] = musec

        outputArray.tofile(fp)
        fp.close()


    def _decodeSceneReferenceNumber(self,referenceNumber):
        frameNumber = referenceNumber.split('=')
        if (len(frameNumber) > 2):
            frameNumber = frameNumber[2].strip()
        else:
            frameNumber = frameNumber[0]

        return frameNumber
Exemplo n.º 10
0
class Sentinel1(Sensor):
    """
        A Class representing Sentinel1 StripMap data
    """

    family = 's1sm'
    logging = 'isce.sensor.S1_SM'

    parameter_list = (
        XML,
        TIFF,
        MANIFEST,
        SAFE,
        ORBIT_FILE,
        ORBIT_DIR,
        POLARIZATION,
    ) + Sensor.parameter_list

    def __init__(self, family='', name=''):

        super(Sentinel1,
              self).__init__(family if family else self.__class__.family,
                             name=name)

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

        self._xml_root = None

    def validateUserInputs(self):
        '''
        Validate inputs from user.
        Populate tiff and xml from SAFE folder name.
        '''

        import fnmatch
        import zipfile

        if not self.xml:
            if not self.safe:
                raise Exception('SAFE directory is not provided')

        ####First find annotation file
        ####Dont need swath number when driving with xml and tiff file
        if not self.xml:
            swathid = 's1?-s?-slc-{}'.format(self.polarization)

        dirname = self.safe
        if not self.xml:
            match = None

            if dirname.endswith('.zip'):
                pattern = os.path.join('*SAFE', 'annotation',
                                       swathid) + '*.xml'
                zf = zipfile.ZipFile(dirname, 'r')
                match = fnmatch.filter(zf.namelist(), pattern)
                zf.close()

                if (len(match) == 0):
                    raise Exception(
                        'No annotation xml file found in zip file: {0}'.format(
                            dirname))

                ####Add /vsizip at the start to make it a zip file
                self.xml = '/vsizip/' + os.path.join(dirname, match[0])

            else:
                pattern = os.path.join('annotation', swathid) + '*.xml'
                match = glob.glob(os.path.join(dirname, pattern))

                if (len(match) == 0):
                    raise Exception(
                        'No annotation xml file found in {0}'.format(dirname))

                self.xml = match[0]

        if not self.xml:
            raise Exception('No annotation files found')

        print('Input XML file: ', self.xml)

        ####Find TIFF file
        if (not self.tiff) and (self.safe):
            match = None

            if dirname.endswith('.zip'):
                pattern = os.path.join('*SAFE', 'measurement',
                                       swathid) + '*.tiff'
                zf = zipfile.ZipFile(dirname, 'r')
                match = fnmatch.filter(zf.namelist(), pattern)
                zf.close()

                if (len(match) == 0):
                    raise Exception(
                        'No tiff file found in zip file: {0}'.format(dirname))

                ####Add /vsizip at the start to make it a zip file
                self.tiff = '/vsizip/' + os.path.join(dirname, match[0])

            else:
                pattern = os.path.join('measurement', swathid) + '*.tiff'
                match = glob.glob(os.path.join(dirname, pattern))

                if len(match) == 0:
                    raise Exception(
                        'No tiff file found in directory: {0}'.format(dirname))

                self.tiff = match[0]

            print('Input TIFF files: ', self.tiff)

        ####Find manifest files
        if self.safe:
            if dirname.endswith('.zip'):
                pattern = '*SAFE/manifest.safe'
                zf = zipfile.ZipFile(dirname, 'r')
                match = fnmatch.filter(zf.namelist(), pattern)
                zf.close()
                self.manifest = '/vsizip/' + os.path.join(dirname, match[0])
            else:
                self.manifest = os.path.join(dirname, 'manifest.safe')

            print('Manifest files: ', self.manifest)

        return

    def getFrame(self):
        return self.frame

    def parse(self):
        '''
        Actual parsing of the metadata for the product.
        '''
        from isceobj.Sensor.TOPS.Sentinel1 import s1_findOrbitFile
        ###Check user inputs
        self.validateUserInputs()

        if self.xml.startswith('/vsizip'):
            import zipfile
            parts = self.xml.split(os.path.sep)

            if parts[2] == '':
                parts[2] = os.path.sep

            zipname = os.path.join(*(parts[2:-3]))
            fname = os.path.join(*(parts[-3:]))

            zf = zipfile.ZipFile(zipname, 'r')
            xmlstr = zf.read(fname)
            zf.close()
        else:
            with open(self.xml, 'r') as fid:
                xmlstr = fid.read()

        self._xml_root = ET.fromstring(xmlstr)
        self.populateMetadata()

        if self.manifest:
            self.populateIPFVersion()
        else:
            self.frame.setProcessingFacility('ESA')
            self.frame.setProcessingSoftwareVersion('IPFx.xx')

        if not self.orbitFile:
            if self.orbitDir:
                self.orbitFile = s1_findOrbitFile(
                    self.orbitDir,
                    self.frame.sensingStart,
                    self.frame.sensingStop,
                    mission=self.frame.getInstrument().getPlatform(
                    ).getMission())

        if self.orbitFile:
            orb = self.extractPreciseOrbit()
            self.frame.orbit.setOrbitSource(os.path.basename(self.orbitFile))
        else:
            orb = self.extractOrbitFromAnnotation()
            self.frame.orbit.setOrbitSource('Annotation')

        for sv in orb:
            self.frame.orbit.addStateVector(sv)

    def grab_from_xml(self, path):
        try:
            res = self._xml_root.find(path).text
        except:
            raise Exception('Tag= %s not found' % (path))

        if res is None:
            raise Exception('Tag = %s not found' % (path))

        return res

    def convertToDateTime(self, string):
        dt = datetime.datetime.strptime(string, "%Y-%m-%dT%H:%M:%S.%f")
        return dt

    def populateMetadata(self):
        """
            Create metadata objects from the metadata files
        """
        ####Set each parameter one - by - one
        mission = self.grab_from_xml('adsHeader/missionId')
        swath = self.grab_from_xml('adsHeader/swath')
        polarization = self.grab_from_xml('adsHeader/polarisation')

        frequency = float(
            self.grab_from_xml(
                'generalAnnotation/productInformation/radarFrequency'))
        passDirection = self.grab_from_xml(
            'generalAnnotation/productInformation/pass')

        rangePixelSize = float(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/rangePixelSpacing'))
        azimuthPixelSize = float(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/azimuthPixelSpacing'))
        rangeSamplingRate = Const.c / (2.0 * rangePixelSize)
        prf = 1.0 / float(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/azimuthTimeInterval'))

        lines = int(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/numberOfLines'))
        samples = int(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/numberOfSamples'))

        startingRange = float(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/slantRangeTime')
        ) * Const.c / 2.0
        incidenceAngle = float(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/incidenceAngleMidSwath'))
        dataStartTime = self.convertToDateTime(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/productFirstLineUtcTime'))
        dataStopTime = self.convertToDateTime(
            self.grab_from_xml(
                'imageAnnotation/imageInformation/productLastLineUtcTime'))

        pulseLength = float(
            self.grab_from_xml(
                'generalAnnotation/downlinkInformationList/downlinkInformation/downlinkValues/txPulseLength'
            ))
        chirpSlope = float(
            self.grab_from_xml(
                'generalAnnotation/downlinkInformationList/downlinkInformation/downlinkValues/txPulseRampRate'
            ))
        pulseBandwidth = pulseLength * chirpSlope

        ####Sentinel is always right looking
        lookSide = -1

        #        height = self.product.imageGenerationParameters.sarProcessingInformation._satelliteHeight

        ####Populate platform
        platform = self.frame.getInstrument().getPlatform()
        platform.setPlanet(Planet(pname="Earth"))
        platform.setMission(mission)
        platform.setPointingDirection(lookSide)
        platform.setAntennaLength(2 * azimuthPixelSize)

        ####Populate instrument
        instrument = self.frame.getInstrument()
        instrument.setRadarFrequency(frequency)
        instrument.setPulseRepetitionFrequency(prf)
        instrument.setPulseLength(pulseLength)
        instrument.setChirpSlope(pulseBandwidth / pulseLength)
        instrument.setIncidenceAngle(incidenceAngle)
        #self.frame.getInstrument().setRangeBias(0)
        instrument.setRangePixelSize(rangePixelSize)
        instrument.setRangeSamplingRate(rangeSamplingRate)
        instrument.setBeamNumber(swath)
        instrument.setPulseLength(pulseLength)

        #Populate Frame
        #self.frame.setSatelliteHeight(height)
        self.frame.setSensingStart(dataStartTime)
        self.frame.setSensingStop(dataStopTime)
        diffTime = DTUtil.timeDeltaToSeconds(dataStopTime -
                                             dataStartTime) / 2.0
        sensingMid = dataStartTime + datetime.timedelta(
            microseconds=int(diffTime * 1e6))
        self.frame.setSensingMid(sensingMid)
        self.frame.setPassDirection(passDirection)
        self.frame.setPolarization(polarization)
        self.frame.setStartingRange(startingRange)
        self.frame.setFarRange(startingRange + (samples - 1) * rangePixelSize)
        self.frame.setNumberOfLines(lines)
        self.frame.setNumberOfSamples(samples)

        self.frame.setPassDirection(passDirection)

    def extractOrbitFromAnnotation(self):
        '''
        Extract orbit information from xml node.
        '''

        node = self._xml_root.find('generalAnnotation/orbitList')
        frameOrbit = Orbit()
        frameOrbit.setOrbitSource('Header')

        for child in node:
            timestamp = self.convertToDateTime(child.find('time').text)
            pos = []
            vel = []
            posnode = child.find('position')
            velnode = child.find('velocity')
            for tag in ['x', 'y', 'z']:
                pos.append(float(posnode.find(tag).text))

            for tag in ['x', 'y', 'z']:
                vel.append(float(velnode.find(tag).text))

            vec = StateVector()
            vec.setTime(timestamp)
            vec.setPosition(pos)
            vec.setVelocity(vel)
            frameOrbit.addStateVector(vec)

        planet = self.frame.instrument.platform.planet
        orbExt = OrbitExtender(planet=planet)
        orbExt.configure()
        newOrb = orbExt.extendOrbit(frameOrbit)

        return newOrb

    def extractPreciseOrbit(self):
        '''
        Extract precise orbit from given Orbit file.
        '''
        try:
            fp = open(self.orbitFile, 'r')
        except IOError as strerr:
            print("IOError: %s" % strerr)
            return

        _xml_root = ET.ElementTree(file=fp).getroot()

        node = _xml_root.find('Data_Block/List_of_OSVs')

        orb = Orbit()
        orb.configure()

        margin = datetime.timedelta(seconds=40.0)
        tstart = self.frame.getSensingStart() - margin
        tend = self.frame.getSensingStop() + margin

        for child in node:
            timestamp = self.convertToDateTime(child.find('UTC').text[4:])

            if (timestamp >= tstart) and (timestamp < tend):

                pos = []
                vel = []

                for tag in ['VX', 'VY', 'VZ']:
                    vel.append(float(child.find(tag).text))

                for tag in ['X', 'Y', 'Z']:
                    pos.append(float(child.find(tag).text))

                vec = StateVector()
                vec.setTime(timestamp)
                vec.setPosition(pos)
                vec.setVelocity(vel)
                orb.addStateVector(vec)

        fp.close()

        return orb

    def extractImage(self):
        """
           Use gdal python bindings to extract image
        """
        try:
            from osgeo import gdal
        except ImportError:
            raise Exception(
                'GDAL python bindings not found. Need this for RSAT2/ TandemX / Sentinel1A.'
            )

        self.parse()
        width = self.frame.getNumberOfSamples()
        lgth = self.frame.getNumberOfLines()

        src = gdal.Open(self.tiff.strip(), gdal.GA_ReadOnly)
        band = src.GetRasterBand(1)
        fid = open(self.output, 'wb')
        for ii in range(lgth):
            data = band.ReadAsArray(0, ii, width, 1)
            data.tofile(fid)

        fid.close()
        src = None
        band = None

        ####
        slcImage = isceobj.createSlcImage()
        slcImage.setByteOrder('l')
        slcImage.setFilename(self.output)
        slcImage.setAccessMode('read')
        slcImage.setWidth(self.frame.getNumberOfSamples())
        slcImage.setLength(self.frame.getNumberOfLines())
        slcImage.setXmin(0)
        slcImage.setXmax(self.frame.getNumberOfSamples())
        self.frame.setImage(slcImage)

    def extractDoppler(self):
        '''
        self.parse()
        Extract doppler information as needed by mocomp
        '''
        from isceobj.Util import Poly1D

        node = self._xml_root.find('dopplerCentroid/dcEstimateList')

        tdiff = 1.0e9
        dpoly = None

        for index, burst in enumerate(node):
            refTime = self.convertToDateTime(burst.find('azimuthTime').text)

            delta = abs((refTime - self.frame.sensingMid).total_seconds())
            if delta < tdiff:
                tdiff = delta
                r0 = 0.5 * Const.c * float(burst.find('t0').text)
                coeffs = [
                    float(val)
                    for val in burst.find('dataDcPolynomial').text.split()
                ]

                poly = Poly1D.Poly1D()
                poly.initPoly(order=len(coeffs) - 1)
                poly.setMean(r0)
                poly.setNorm(0.5 * Const.c)
                poly.setCoeffs(coeffs)

                dpoly = poly

        if dpoly is None:
            raise Exception(
                'Could not extract Doppler information for S1 scene')

        ###Part for insarApp
        ###Should be removed in the future
        rmid = self.frame.startingRange + 0.5 * self.frame.getNumberOfSamples(
        ) * self.frame.getInstrument().getRangePixelSize()

        quadratic = {}
        quadratic['a'] = dpoly(
            rmid) / self.frame.getInstrument().getPulseRepetitionFrequency()
        quadratic['b'] = 0.
        quadratic['c'] = 0.

        ###Actual Doppler Polynomial for accurate processing
        ###Will be used in roiApp
        pix = np.linspace(0,
                          self.frame.getNumberOfSamples(),
                          num=dpoly._order + 2)
        rngs = self.frame.startingRange + pix * self.frame.getInstrument(
        ).getRangePixelSize()
        evals = dpoly(rngs)
        fit = np.polyfit(pix, evals, dpoly._order)
        self.frame._dopplerVsPixel = list(fit[::-1])
        print('Doppler Fit : ', fit[::-1])

        return quadratic

    def populateIPFVersion(self):
        '''
        Get IPF version from the manifest file.
        '''

        try:
            if self.manifest.startswith('/vsizip'):
                import zipfile
                parts = self.manifest.split(os.path.sep)
                if parts[2] == '':
                    parts[2] = os.path.sep
                zipname = os.path.join(*(parts[2:-2]))
                fname = os.path.join(*(parts[-2:]))
                print('MANS: ', zipname, fname)

                zf = zipfile.ZipFile(zipname, 'r')
                xmlstr = zf.read(fname)

            else:
                with open(self.manifest, 'r') as fid:
                    xmlstr = fid.read()

            ####Setup namespace
            nsp = "{http://www.esa.int/safe/sentinel-1.0}"

            root = ET.fromstring(xmlstr)

            elem = root.find('.//metadataObject[@ID="processing"]')

            rdict = elem.find('.//xmlData/' + nsp + 'processing/' + nsp +
                              'facility').attrib
            self.frame.setProcessingFacility(rdict['site'] + ', ' +
                                             rdict['country'])

            rdict = elem.find('.//xmlData/' + nsp + 'processing/' + nsp +
                              'facility/' + nsp + 'software').attrib

            self.frame.setProcessingSoftwareVersion(rdict['name'] + ' ' +
                                                    rdict['version'])

        except:  ###Not a critical error ... continuing
            print(
                'Could not read version number successfully from manifest file: ',
                self.manifest)
            pass

        return