コード例 #1
0
class UAVSAR_HDF5_SLC(Sensor):
    """
    A class representing a Level1Product meta data.
    Level1Product(hdf5=h5filename) will parse the hdf5
    file and produce an object with attributes for metadata.
    """
    parameter_list = (HDF5, FREQUENCY, POLARIZATION) + Sensor.parameter_list

    logging_name = 'isce.Sensor.UAVSAR_HDF5_SLC'
    family = 'uavsar_hdf5_slc'

    def __init__(self,
                 family='',
                 name=''):  # , frequency='frequencyA', polarization='HH'):
        super(UAVSAR_HDF5_SLC,
              self).__init__(family if family else self.__class__.family,
                             name=name)
        self.frame = Frame()
        self.frame.configure()
        # Some extra processing parameters unique to UAVSAR HDF5 SLC (currently)
        self.dopplerRangeTime = []
        self.dopplerAzimuthTime = []
        self.azimuthRefTime = None
        self.rangeRefTime = None
        self.rangeFirstTime = None
        self.rangeLastTime = None
        #self.frequency = frequency
        #self.polarization = polarization

        self.lookMap = {'right': -1, 'left': 1}
        return

    def __getstate__(self):
        d = dict(self.__dict__)
        del d['logger']
        return d

    def __setstate__(self, d):
        self.__dict__.update(d)
        self.logger = logging.getLogger('isce.Sensor.UAVSAR_HDF5_SLC')
        return

    def getFrame(self):
        return self.frame

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

        self.populateMetadata(fp)
        fp.close()

    def populateMetadata(self, file):
        """
            Populate our Metadata objects
        """

        self._populatePlatform(file)
        self._populateInstrument(file)
        self._populateFrame(file)
        self._populateOrbit(file)

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

        platform.setMission(
            file['/science/LSAR/identification'].get('missionId')[(
            )].decode('utf-8'))
        platform.setPointingDirection(
            self.lookMap[file['/science/LSAR/identification'].get(
                'lookDirection')[()].decode('utf-8')])
        platform.setPlanet(Planet(pname="Earth"))

        # We are not using this value anywhere. Let's fix it for now.
        platform.setAntennaLength(12.0)

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

        rangePixelSize = file['/science/LSAR/SLC/swaths/' + self.frequency +
                              '/slantRangeSpacing'][()]
        wvl = SPEED_OF_LIGHT / file['/science/LSAR/SLC/swaths/' +
                                    self.frequency +
                                    '/processedCenterFrequency'][()]
        instrument.setRadarWavelength(wvl)
        instrument.setPulseRepetitionFrequency(
            1.0 / file['/science/LSAR/SLC/swaths/zeroDopplerTimeSpacing'][()])
        rangePixelSize = file['/science/LSAR/SLC/swaths/' + self.frequency +
                              '/slantRangeSpacing'][()]
        instrument.setRangePixelSize(rangePixelSize)

        # Chrip slope and length only are used in the split spectrum workflow to compute the bandwidth.
        # Therefore fixing it to 1.0 won't breack anything
        Chirp_slope = 1.0
        rangeBandwidth = file['/science/LSAR/SLC/swaths/' + self.frequency +
                              '/processedRangeBandwidth'][()]
        Chirp_length = rangeBandwidth / Chirp_slope
        instrument.setPulseLength(Chirp_length)
        instrument.setChirpSlope(Chirp_slope)
        rangeSamplingFrequency = SPEED_OF_LIGHT / 2. / rangePixelSize
        instrument.setRangeSamplingRate(rangeSamplingFrequency)

        incangle = 0.0
        instrument.setIncidenceAngle(incangle)

    def _populateFrame(self, file):

        slantRange = file['/science/LSAR/SLC/swaths/' + self.frequency +
                          '/slantRange'][0]
        self.frame.setStartingRange(slantRange)

        referenceUTC = file['/science/LSAR/SLC/swaths/zeroDopplerTime'].attrs[
            'units'].decode('utf-8')
        referenceUTC = referenceUTC.replace('seconds since ', '')
        referenceUTC = datetime.datetime.strptime(referenceUTC,
                                                  '%Y-%m-%d %H:%M:%S')

        relStart = file['/science/LSAR/SLC/swaths/zeroDopplerTime'][0]
        relEnd = file['/science/LSAR/SLC/swaths/zeroDopplerTime'][-1]
        relMid = 0.5 * (relStart + relEnd)

        sensingStart = self._combineDateTime(referenceUTC, relStart)
        sensingStop = self._combineDateTime(referenceUTC, relEnd)
        sensingMid = self._combineDateTime(referenceUTC, relMid)

        self.frame.setPassDirection(
            file['/science/LSAR/identification'].get('orbitPassDirection')[(
            )].decode('utf-8'))
        self.frame.setOrbitNumber(
            file['/science/LSAR/identification'].get('trackNumber')[()])
        self.frame.setProcessingFacility('JPL')
        self.frame.setProcessingSoftwareVersion(
            file['/science/LSAR/SLC/metadata/processingInformation/algorithms']
            .get('ISCEVersion')[()].decode('utf-8'))
        self.frame.setPolarization(self.polarization)
        self.frame.setNumberOfLines(
            file['/science/LSAR/SLC/swaths/' + self.frequency + '/' +
                 self.polarization].shape[0])
        self.frame.setNumberOfSamples(
            file['/science/LSAR/SLC/swaths/' + self.frequency + '/' +
                 self.polarization].shape[1])
        self.frame.setSensingStart(sensingStart)
        self.frame.setSensingMid(sensingMid)
        self.frame.setSensingStop(sensingStop)

        rangePixelSize = self.frame.instrument.rangePixelSize
        farRange = slantRange + (self.frame.getNumberOfSamples() -
                                 1) * rangePixelSize
        self.frame.setFarRange(farRange)

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

        orbit.setReferenceFrame('ECR')
        orbit.setOrbitSource('Header')

        referenceUTC = file['/science/LSAR/SLC/swaths/zeroDopplerTime'].attrs[
            'units'].decode('utf-8')
        referenceUTC = referenceUTC.replace('seconds since ', '')
        t0 = datetime.datetime.strptime(referenceUTC, '%Y-%m-%d %H:%M:%S')
        t = file['/science/LSAR/SLC/metadata/orbit/time']
        position = file['/science/LSAR/SLC/metadata/orbit/position']
        velocity = file['/science/LSAR/SLC/metadata/orbit/velocity']

        for i in range(len(position)):
            vec = StateVector()
            dt = t0 + datetime.timedelta(seconds=t[i])
            vec.setTime(dt)
            vec.setPosition([position[i, 0], position[i, 1], position[i, 2]])
            vec.setVelocity([velocity[i, 0], velocity[i, 1], velocity[i, 2]])
            orbit.addStateVector(vec)

    def extractImage(self):

        import numpy as np
        import h5py

        self.parse()

        fid = h5py.File(self.hdf5, 'r')
        ds = fid['/science/LSAR/SLC/swaths/' + self.frequency + '/' +
                 self.polarization]
        nLines = ds.shape[0]

        with open(self.output, 'wb') as fout:
            for ii in range(nLines):
                ds[ii, :].astype(np.complex64).tofile(fout)

        fid.close()

        slcImage = isceobj.createSlcImage()
        slcImage.setFilename(self.output)
        slcImage.setXmin(0)
        slcImage.setXmax(self.frame.getNumberOfSamples())
        slcImage.setWidth(self.frame.getNumberOfSamples())
        slcImage.setAccessMode('r')
        slcImage.renderHdr()
        self.frame.setImage(slcImage)

    def _parseNanoSecondTimeStamp(self, timestamp):
        """
            Parse a date-time string with nanosecond precision and return a datetime object
        """
        dateTime, nanoSeconds = timestamp.decode('utf-8').split('.')
        microsec = float(nanoSeconds) * 1e-3
        dt = datetime.datetime.strptime(dateTime, '%Y-%m-%d %H:%M:%S')
        dt = dt + datetime.timedelta(microseconds=microsec)
        return dt

    def _combineDateTime(self, dobj, secsstr):
        '''Takes the date from dobj and time from secs to spit out a date time object.
        '''
        sec = float(secsstr)
        dt = datetime.timedelta(seconds=sec)
        return dobj + dt

    def extractDoppler(self):
        """
        Return the doppler centroid as defined in the HDF5 file.
        """

        import h5py
        from scipy.interpolate import UnivariateSpline
        import numpy as np

        h5 = h5py.File(self.hdf5, 'r')

        # extract the 2D LUT of Doppler and choose only one range line as the data duplicates for other range lines
        dop = h5['/science/LSAR/SLC/metadata/processingInformation/parameters/'
                 + self.frequency + '/dopplerCentroid'][0, :]
        rng = h5[
            '/science/LSAR/SLC/metadata/processingInformation/parameters/slantRange']

        # extract the slant range of the image grid
        imgRng = h5['/science/LSAR/SLC/swaths/' + self.frequency +
                    '/slantRange']

        # use only part of the slant range that closely covers image ranges and ignore the rest
        ind0 = np.argmin(np.abs(rng - imgRng[0])) - 1
        ind0 = np.max([0, ind0])
        ind1 = np.argmin(np.abs(rng - imgRng[-1])) + 1
        ind1 = np.min([ind1, rng.shape[0]])

        dop = dop[ind0:ind1]
        rng = rng[ind0:ind1]

        f = UnivariateSpline(rng, dop)
        imgDop = f(imgRng)

        dr = imgRng[1] - imgRng[0]
        pix = (imgRng - imgRng[0]) / dr
        fit = np.polyfit(pix, imgDop, 41)

        self.frame._dopplerVsPixel = list(fit[::-1])

        ####insarApp style (doesn't get used for stripmapApp). A fixed Doppler at the middle of the scene
        quadratic = {}
        quadratic['a'] = imgDop[int(
            imgDop.shape[0] /
            2)] / self.frame.getInstrument().getPulseRepetitionFrequency()
        quadratic['b'] = 0.
        quadratic['c'] = 0.

        return quadratic
コード例 #2
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
コード例 #3
0
class Radarsat2(Sensor):
    """
        A Class representing RADARSAT 2 data
    """

    family = 'radarsat2'
    parameter_list = (XML, TIFF) + Sensor.parameter_list

    def __init__(self, family='', name=''):
        super().__init__(family if family else self.__class__.family,
                         name=name)
        self.product = _Product()
        self.frame = Frame()
        self.frame.configure()

    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 populateMetadata(self):
        """
            Create metadata objects from the metadata files
        """
        mission = self.product.sourceAttributes.satellite
        swath = self.product.sourceAttributes.radarParameters.beams
        frequency = self.product.sourceAttributes.radarParameters.radarCenterFrequency
        orig_prf = self.product.sourceAttributes.radarParameters.prf  # original PRF not necessarily effective PRF
        rangePixelSize = self.product.imageAttributes.rasterAttributes.sampledPixelSpacing
        rangeSamplingRate = Const.c / (2 * rangePixelSize)
        pulseLength = self.product.sourceAttributes.radarParameters.pulseLengths[
            0]
        pulseBandwidth = self.product.sourceAttributes.radarParameters.pulseBandwidths[
            0]
        polarization = self.product.sourceAttributes.radarParameters.polarizations
        lookSide = lookMap[self.product.sourceAttributes.radarParameters.
                           antennaPointing.upper()]
        facility = self.product.imageGenerationParameters.generalProcessingInformation._processingFacility
        version = self.product.imageGenerationParameters.generalProcessingInformation.softwareVersion
        lines = self.product.imageAttributes.rasterAttributes.numberOfLines
        samples = self.product.imageAttributes.rasterAttributes.numberOfSamplesPerLine
        startingRange = self.product.imageGenerationParameters.slantRangeToGroundRange.slantRangeTimeToFirstRangeSample * (
            Const.c / 2)
        incidenceAngle = (self.product.imageGenerationParameters.
                          sarProcessingInformation.incidenceAngleNearRange +
                          self.product.imageGenerationParameters.
                          sarProcessingInformation.incidenceAngleFarRange) / 2
        # some RS2 scenes have oversampled SLC images because processed azimuth bandwidth larger than PRF EJF 2015/08/15
        azimuthPixelSize = self.product.imageAttributes.rasterAttributes.sampledLineSpacing  # ground spacing in meters
        totalProcessedAzimuthBandwidth = self.product.imageGenerationParameters.sarProcessingInformation.totalProcessedAzimuthBandwidth
        prf = orig_prf * np.ceil(
            totalProcessedAzimuthBandwidth / orig_prf
        )  # effective PRF can be double original, suggested by Piyush
        print("effective PRF %f, original PRF %f" % (prf, orig_prf))

        lineFlip = (self.product.imageAttributes.rasterAttributes.
                    lineTimeOrdering.upper() == 'DECREASING')

        if lineFlip:
            dataStopTime = self.product.imageGenerationParameters.sarProcessingInformation.zeroDopplerTimeFirstLine
            dataStartTime = self.product.imageGenerationParameters.sarProcessingInformation.zeroDopplerTimeLastLine
        else:
            dataStartTime = self.product.imageGenerationParameters.sarProcessingInformation.zeroDopplerTimeFirstLine
            dataStopTime = self.product.imageGenerationParameters.sarProcessingInformation.zeroDopplerTimeLastLine

        passDirection = self.product.sourceAttributes.orbitAndAttitude.orbitInformation.passDirection
        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(15.0)

        ####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)

        # Initialize orbit objects
        # Read into temp orbit first.
        # Radarsat 2 needs orbit extensions.
        tempOrbit = Orbit()

        self.frame.getOrbit().setOrbitSource(
            'Header: ' + self.product.sourceAttributes.orbitAndAttitude.
            orbitInformation.orbitDataFile)
        self.frame.setPassDirection(passDirection)
        stateVectors = self.product.sourceAttributes.orbitAndAttitude.orbitInformation.stateVectors
        for i in range(len(stateVectors)):
            position = [
                stateVectors[i].xPosition, stateVectors[i].yPosition,
                stateVectors[i].zPosition
            ]
            velocity = [
                stateVectors[i].xVelocity, stateVectors[i].yVelocity,
                stateVectors[i].zVelocity
            ]
            vec = StateVector()
            vec.setTime(stateVectors[i].timeStamp)
            vec.setPosition(position)
            vec.setVelocity(velocity)
            tempOrbit.addStateVector(vec)

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

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

# save the Doppler centroid coefficients, converting units from product.xml file
# units in the file are quadratic coefficients in Hz, Hz/sec, and Hz/(sec^2)
# ISCE expects Hz, Hz/(range sample), Hz((range sample)^2
# note that RS2 Doppler values are estimated at time dc.dopplerCentroidReferenceTime,
# so the values might need to be adjusted for ISCE usage
# added EJF 2015/08/17
        dc = self.product.imageGenerationParameters.dopplerCentroid
        poly = dc.dopplerCentroidCoefficients
        # need to convert units
        poly[1] = poly[1] / rangeSamplingRate
        poly[2] = poly[2] / rangeSamplingRate**2
        self.doppler_coeff = poly

        # similarly save Doppler azimuth fm rate values, converting units
        # units in the file are quadratic coefficients in Hz, Hz/sec, and Hz/(sec^2)
        # Guessing that ISCE expects Hz, Hz/(range sample), Hz((range sample)^2
        # note that RS2 Doppler values are estimated at time dc.dopplerRateReferenceTime,
        # so the values might need to be adjusted for ISCE usage
        # added EJF 2015/08/17
        dr = self.product.imageGenerationParameters.dopplerRateValues
        fmpoly = dr.dopplerRateValuesCoefficients
        # need to convert units
        fmpoly[1] = fmpoly[1] / rangeSamplingRate
        fmpoly[2] = fmpoly[2] / rangeSamplingRate**2
        self.azfmrate_coeff = fmpoly

        # now calculate effective PRF from the azimuth line spacing after we have the orbit info EJF 2015/08/15
        # this does not work because azimuth spacing is on ground. Instead use bandwidth ratio calculated above  EJF


#        SCHvelocity = self.frame.getSchVelocity()
#        SCHvelocity = 7550.75  # hard code orbit velocity for now m/s
#        prf = SCHvelocity/azimuthPixelSize
#        instrument.setPulseRepetitionFrequency(prf)

    def extractImage(self, verbose=True):
        '''
        Use gdal to extract the slc.
        '''

        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()
        lineFlip = (self.product.imageAttributes.rasterAttributes.
                    lineTimeOrdering.upper() == 'DECREASING')
        pixFlip = (self.product.imageAttributes.rasterAttributes.
                   pixelTimeOrdering.upper() == 'DECREASING')

        src = gdal.Open(self.tiff.strip(), gdal.GA_ReadOnly)
        cJ = np.complex64(1.0j)

        ####Images are small enough that we can do it all in one go - Piyush
        real = src.GetRasterBand(1).ReadAsArray(0, 0, width, lgth)
        imag = src.GetRasterBand(2).ReadAsArray(0, 0, width, lgth)

        if (real is None) or (imag is None):
            raise Exception(
                'Input Radarsat2 SLC seems to not be a 2 band Int16 image.')

        data = real + cJ * imag

        real = None
        imag = None
        src = None

        if lineFlip:
            if verbose:
                print('Vertically Flipping data')
            data = np.flipud(data)

        if pixFlip:
            if verbose:
                print('Horizontally Flipping data')
            data = np.fliplr(data)

        data.tofile(self.output)

        ####
        slcImage = isceobj.createSlcImage()
        slcImage.setByteOrder('l')
        slcImage.setFilename(self.output)
        slcImage.setAccessMode('read')
        slcImage.setWidth(width)
        slcImage.setLength(lgth)
        slcImage.setXmin(0)
        slcImage.setXmax(width)
        #        slcImage.renderHdr()
        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

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

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

        coeffs = poly
        dr = self.frame.getInstrument().getRangePixelSize()
        rref = 0.5 * Const.c * t0
        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
コード例 #4
0
class KOMPSAT5(Component):
    """
    A class representing a Level1Product meta data.
    Level1Product(hdf5=h5filename) will parse the hdf5
    file and produce an object with attributes for metadata.
    """

    logging_name = 'isce.Sensor.KOMPSAT5'

    def __init__(self):
        super(KOMPSAT5,self).__init__()
        self.hdf5 = None
        self.output = None
        self.frame = Frame()
        self.frame.configure()
        # Some extra processing parameters unique to CSK SLC (currently)
        self.dopplerCoeffs = []
        self.rangeFirstTime = None
        self.rangeLastTime = None
        self.rangeRefTime = None
        self.refUTC = None
        
        self.descriptionOfVariables = {}
        self.dictionaryOfVariables = {'HDF5': ['self.hdf5','str','mandatory'],
                                      'OUTPUT': ['self.output','str','optional']}
        
        self.lookMap = {'RIGHT': -1,
                        'LEFT': 1}                            
        return

    def __getstate__(self):
        d = dict(self.__dict__)
        del d['logger']
        return d

    def __setstate__(self,d):
        self.__dict__.update(d)
        self.logger = logging.getLogger('isce.Sensor.COSMO_SkyMed_SLC')
        return

    
    def getFrame(self):
        return self.frame
    
    def parse(self):
        try:
            fp = h5py.File(self.hdf5,'r')
        except Exception as strerr:
            self.logger.error("IOError: %s" % strerr)
            return None

        self.populateMetadata(fp)
        fp.close()

    def populateMetadata(self, file):
        """
            Populate our Metadata objects
        """
        
        self._populatePlatform(file)
        self._populateInstrument(file)
        self._populateFrame(file)
        self._populateOrbit(file)
        self._populateExtras(file)
    
    def _populatePlatform(self, file):
        platform = self.frame.getInstrument().getPlatform()

        platform.setMission(file.attrs['Satellite ID'])
        platform.setPointingDirection(self.lookMap[file.attrs['Look Side'].decode('utf-8')])
        platform.setPlanet(Planet("Earth"))                            

        ####This is an approximation for spotlight mode
        ####In spotlight mode, antenna length changes with azimuth position
        platform.setAntennaLength(file.attrs['Antenna Length'])
        try:
            if file.attrs['Multi-Beam ID'].startswith('ES'):
                platform.setAntennaLength(16000.0/file['S01/SBI'].attrs['Line Time Interval'])
        except:
            pass
    
    def _populateInstrument(self, file):
        instrument = self.frame.getInstrument()

#        rangePixelSize = Const.c/(2*file['S01'].attrs['Sampling Rate'])  
        rangePixelSize = file['S01/SBI'].attrs['Column Spacing']
        instrument.setRadarWavelength(file.attrs['Radar Wavelength'])
#        instrument.setPulseRepetitionFrequency(file['S01'].attrs['PRF'])
        instrument.setPulseRepetitionFrequency(1.0/file['S01/SBI'].attrs['Line Time Interval'])
        instrument.setRangePixelSize(rangePixelSize)
        instrument.setPulseLength(file['S01'].attrs['Range Chirp Length'])        
        instrument.setChirpSlope(file['S01'].attrs['Range Chirp Rate'])                
#        instrument.setRangeSamplingRate(file['S01'].attrs['Sampling Rate'])
        instrument.setRangeSamplingRate(1.0/file['S01/SBI'].attrs['Column Time Interval'])

        incangle = 0.5*(file['S01/SBI'].attrs['Far Incidence Angle'] +
                 file['S01/SBI'].attrs['Near Incidence Angle'])
        instrument.setIncidenceAngle(incangle) 


    def _populateFrame(self, file):

        rft = file['S01/SBI'].attrs['Zero Doppler Range First Time']
        slantRange = rft*Const.c/2.0
        self.frame.setStartingRange(slantRange)
        
        referenceUTC = self._parseNanoSecondTimeStamp(file.attrs['Reference UTC'])
        relStart = file['S01/SBI'].attrs['Zero Doppler Azimuth First Time']
        relEnd = file['S01/SBI'].attrs['Zero Doppler Azimuth Last Time']
        relMid = 0.5*(relStart + relEnd)
        
        sensingStart = self._combineDateTime(referenceUTC, relStart) 
        sensingStop = self._combineDateTime(referenceUTC, relEnd)        
        sensingMid = self._combineDateTime(referenceUTC, relMid)           
        
        
        self.frame.setPassDirection(file.attrs['Orbit Direction'])
        self.frame.setOrbitNumber(file.attrs['Orbit Number'])              
        self.frame.setProcessingFacility(file.attrs['Processing Centre'])        
        self.frame.setProcessingSoftwareVersion(file.attrs['L0 Software Version'])
        self.frame.setPolarization(file['S01'].attrs['Polarisation'])
        self.frame.setNumberOfLines(file['S01/SBI'].shape[0])
        self.frame.setNumberOfSamples(file['S01/SBI'].shape[1])
        self.frame.setSensingStart(sensingStart)
        self.frame.setSensingMid(sensingMid)
        self.frame.setSensingStop(sensingStop)

        rangePixelSize = self.frame.getInstrument().getRangePixelSize()
        farRange = slantRange +  (self.frame.getNumberOfSamples()-1)*rangePixelSize
        self.frame.setFarRange(farRange)

    def _populateOrbit(self,file):
        orbit = self.frame.getOrbit()
        
        orbit.setReferenceFrame('ECR')
        orbit.setOrbitSource('Header')
        t0 = datetime.datetime.strptime(file.attrs['Reference UTC'].decode('utf-8'),'%Y-%m-%d %H:%M:%S.%f000')
        t = file.attrs['State Vectors Times']
        position = file.attrs['ECEF Satellite Position']
        velocity = file.attrs['ECEF Satellite Velocity']
                
        for i in range(len(position)):
            vec = StateVector()
            dt = t0 + datetime.timedelta(seconds=t[i])          
            vec.setTime(dt)            
            vec.setPosition([position[i,0],position[i,1],position[i,2]])
            vec.setVelocity([velocity[i,0],velocity[i,1],velocity[i,2]])
            orbit.addStateVector(vec)


    def _populateExtras(self, file):
        """
        Populate some of the extra fields unique to processing TSX data.
        In the future, other sensors may need this information as well, 
        and a re-organization may be necessary.
        """
        from isceobj.Doppler.Doppler import Doppler

        scale = file['S01'].attrs['PRF'] * file['S01/SBI'].attrs['Line Time Interval']
        self.dopplerCoeffs = file.attrs['Centroid vs Range Time Polynomial']*scale
        self.rangeRefTime = file.attrs['Range Polynomial Reference Time']
        self.rangeFirstTime = file['S01/SBI'].attrs['Zero Doppler Range First Time']
        self.rangeLastTime = file['S01/SBI'].attrs['Zero Doppler Range Last Time']

    def extractImage(self):
        import os
        from ctypes import cdll, c_char_p
        extract_csk = cdll.LoadLibrary(os.path.dirname(__file__)+'/csk.so')
        inFile_c = c_char_p(bytes(self.hdf5, 'utf-8'))
        outFile_c = c_char_p(bytes(self.output, 'utf-8'))

        extract_csk.extract_csk_slc(inFile_c, outFile_c)

        self.parse()
        slcImage = isceobj.createSlcImage()
        slcImage.setFilename(self.output)
        slcImage.setXmin(0)
        slcImage.setXmax(self.frame.getNumberOfSamples())
        slcImage.setWidth(self.frame.getNumberOfSamples())
        slcImage.setAccessMode('r')
        self.frame.setImage(slcImage)
       

    def _parseNanoSecondTimeStamp(self,timestamp):
        """
            Parse a date-time string with nanosecond precision and return a datetime object
        """
        dateTime,nanoSeconds = timestamp.decode('utf-8').split('.')
        microsec = float(nanoSeconds)*1e-3
        dt = datetime.datetime.strptime(dateTime,'%Y-%m-%d %H:%M:%S')
        dt = dt + datetime.timedelta(microseconds=microsec)
        return dt

    def _combineDateTime(self,dobj, secsstr):
        '''Takes the date from dobj and time from secs to spit out a date time object.
        '''
        sec = float(secsstr)
        dt = datetime.timedelta(seconds = sec)
        return dobj + dt
       

    def extractDoppler(self):
        """
        Return the doppler centroid as defined in the HDF5 file.
        """
        quadratic = {}
        midtime = (self.rangeLastTime + self.rangeFirstTime)*0.5 - self.rangeRefTime
        fd_mid = self.dopplerCoeffs[0] + self.dopplerCoeffs[1]*midtime + self.dopplerCoeffs[2]*midtime*midtime

        quadratic['a'] = fd_mid/self.frame.getInstrument().getPulseRepetitionFrequency()
        quadratic['b'] = 0.
        quadratic['c'] = 0.
        return quadratic
コード例 #5
0
ファイル: Sentinel1A.py プロジェクト: HBaldwin3/isce_v2.0.0
class Sentinel1A(Component):
    """
        A Class representing RadarSAT 2 data
    """
    def __init__(self):
        Component.__init__(self)
        self.xml = None
        self.tiff = None
        self.output = None
        self.gdal_translate = 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'],
            'OUTPUT': ['self.output', 'str', 'optional'],
            'GDAL_TRANSLATE': ['self.gdal_translate', '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("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)
        self.extractOrbit()

    def extractOrbit(self):
        '''
        Extract orbit information from xml node.
        '''
        node = self._xml_root.find('generalAnnotation/orbitList')
        frameOrbit = self.frame.getOrbit()
        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)

    def extractImage(self):
        """
           Use gdal_translate to extract the slc
        """
        import tempfile
        import subprocess

        if (not self.gdal_translate):
            raise TypeError(
                "The path to executable gdal_translate was not specified")
        if (not os.path.exists(self.gdal_translate)):
            raise OSError("Could not find gdal_translate in directory %s" %
                          os.path.dirname(self.gdal_translate))

        self.parse()
        # Use GDAL to convert the geoTIFF file to an raster image
        # There should be a way to do this using the GDAL python api
        curdir = os.getcwd()
        tempdir = tempfile.mkdtemp(dir=curdir)
        #        os.rmdir(tempdir) # Wasteful, but if the directory exists, gdal_translate freaks out
        #instring = 'RADARSAT_2_CALIB:UNCALIB:%s' % self.xml
        #process = subprocess.Popen([self.gdal_translate,'-of','MFF2','-ot','CFloat32',instring,tempdir])
        if (self.tiff is None) or (not os.path.exists(self.tiff)):
            raise Exception(
                'Path to input tiff file: %s is wrong or file doesnt exist.' %
                (self.tiff))

        process = subprocess.Popen([
            self.gdal_translate,
            self.tiff.strip(), '-of', 'ENVI', '-ot', 'CFloat32', '-co',
            'INTERLEAVE=BIP',
            os.path.join(tempdir, 'image_data')
        ])
        process.wait()

        # Move the output of the gdal_translate call to a reasonable file name

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

        os.rename(os.path.join(tempdir, 'image_data'), self.output)

        #       os.unlink(os.path.join(tempdir,'attrib'))
        os.unlink(os.path.join(tempdir, 'image_data.hdr'))
        os.rmdir(tempdir)

        ####
        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
コード例 #6
0
class SAOCOM_SLC(Sensor):

    parameter_list = (IMAGEFILE,
                      XEMTFILE,
                      XMLFILE)           + Sensor.parameter_list

    """
        A Class for parsing SAOCOM instrument and imagery files
    """

    family = 'saocom_slc'

    def __init__(self,family='',name=''):
        super(SAOCOM_SLC, self).__init__(family if family else  self.__class__.family, name=name)
        self._imageFile = None
        self._xemtFileParser = None
        self._xmlFileParser = None
        self._instrumentFileData = None
        self._imageryFileData = None
        self.dopplerRangeTime = None
        self.rangeRefTime = None
        self.azimuthRefTime = None
        self.rangeFirstTime = None
        self.rangeLastTime = None
        self.logger = logging.getLogger("isce.sensor.SAOCOM_SLC")
        self.frame = None
        self.frameList = []
        
        self.lookMap = {'RIGHT': -1,
                        'LEFT': 1}
        self.nearIncidenceAngle = {'S1DP': 20.7, 
        'S2DP': 24.9, 
        'S3DP': 29.1, 
        'S4DP': 33.7, 
        'S5DP': 38.2, 
        'S6DP': 41.3, 
        'S7DP': 44.6, 
        'S8DP': 47.2, 
        'S9DP': 48.8, 
        'S1QP': 17.6, 
        'S2QP': 19.5, 
        'S3QP': 21.4, 
        'S4QP': 23.2, 
        'S5QP': 25.3, 
        'S6QP': 27.2, 
        'S7QP': 29.6, 
        'S8QP': 31.2, 
        'S9QP': 33.0, 
        'S10QP': 34.6}
        self.farIncidenceAngle = {'S1DP': 25.0, 
        'S2DP': 29.2, 
        'S3DP': 33.8, 
        'S4DP': 38.3, 
        'S5DP': 41.3, 
        'S6DP': 44.5, 
        'S7DP': 47.1, 
        'S8DP': 48.7, 
        'S9DP': 50.2, 
        'S1QP': 19.6, 
        'S2QP': 21.5, 
        'S3QP': 23.3, 
        'S4QP': 25.4, 
        'S5QP': 27.3, 
        'S6QP': 29.6, 
        'S7QP': 31.2, 
        'S8QP': 33.0, 
        'S9QP': 34.6, 
        'S10QP': 35.5}
        
    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._xemtFileParser = XEMTFile(fileName=self.xemtFile)
        self._xemtFileParser.parse()
        self._xmlFileParser = XMLFile(fileName=self.xmlFile)
        self._xmlFileParser.parse()
        self.populateMetadata()

    def populateMetadata(self):
        self._populatePlatform()
        self._populateInstrument()
        self._populateFrame()
        self._populateOrbit()
        self._populateExtras()
        
    def _populatePlatform(self):
        """Populate the platform object with metadata"""
        platform = self.frame.getInstrument().getPlatform()
        
        # Populate the Platform and Scene objects
        platform.setMission(self._xmlFileParser.sensorName)
        platform.setPointingDirection(self.lookMap[self._xmlFileParser.sideLooking])
        platform.setAntennaLength(9.968)
        platform.setPlanet(Planet(pname="Earth"))
        
    def _populateInstrument(self):
        """Populate the instrument object with metadata"""
        instrument = self.frame.getInstrument()
        
        rangePixelSize = self._xmlFileParser.PSRng
        azimuthPixelSize = self._xmlFileParser.PSAz
        radarWavelength = Const.c/float(self._xmlFileParser.fc_hz)
        instrument.setRadarWavelength(radarWavelength)
        instrument.setPulseRepetitionFrequency(self._xmlFileParser.prf)
        instrument.setRangePixelSize(rangePixelSize)
        instrument.setAzimuthPixelSize(azimuthPixelSize)
        instrument.setPulseLength(self._xmlFileParser.pulseLength)
        instrument.setChirpSlope(float(self._xmlFileParser.pulseBandwidth)/float(self._xmlFileParser.pulseLength))

        instrument.setRangeSamplingRate(self._xmlFileParser.frg)

        incAngle = 0.5*(self.nearIncidenceAngle[self._xemtFileParser.beamID] + self.farIncidenceAngle[self._xemtFileParser.beamID])
        instrument.setIncidenceAngle(incAngle)
        
    def _populateFrame(self):
        """Populate the scene object with metadata"""
        
        rft = self._xmlFileParser.rangeStartTime
        slantRange = float(rft)*Const.c/2.0
        self.frame.setStartingRange(slantRange)

        sensingStart = self._parseNanoSecondTimeStamp(self._xmlFileParser.azimuthStartTime)
        sensingTime = self._xmlFileParser.lines/self._xmlFileParser.prf
        sensingStop = sensingStart + datetime.timedelta(seconds=sensingTime)
        sensingMid = sensingStart + datetime.timedelta(seconds=0.5*sensingTime)

        self.frame.setPassDirection(self._xmlFileParser.orbitDirection)
        self.frame.setProcessingFacility(self._xemtFileParser.facilityID)
        self.frame.setProcessingSoftwareVersion(self._xemtFileParser.softVersion)
        self.frame.setPolarization(self._xmlFileParser.polarization)
        self.frame.setNumberOfLines(self._xmlFileParser.lines)
        self.frame.setNumberOfSamples(self._xmlFileParser.samples)
        self.frame.setSensingStart(sensingStart)
        self.frame.setSensingMid(sensingMid)
        self.frame.setSensingStop(sensingStop)

        rangePixelSize = self.frame.getInstrument().getRangePixelSize()
        farRange = slantRange +  (self.frame.getNumberOfSamples()-1)*rangePixelSize
        self.frame.setFarRange(farRange)
        
    def _populateOrbit(self):
        orbit = self.frame.getOrbit()
        orbit.setReferenceFrame('ECR')
        orbit.setOrbitSource('Header')
        t0 = self._parseNanoSecondTimeStamp(self._xmlFileParser.orbitStartTime)
        t = np.arange(self._xmlFileParser.numberSV)*self._xmlFileParser.deltaTimeSV
        position = self._xmlFileParser.orbitPositionXYZ
        velocity = self._xmlFileParser.orbitVelocityXYZ

        for i in range(0,self._xmlFileParser.numberSV):
            vec = StateVector()
            dt = t0 + datetime.timedelta(seconds=t[i])
            vec.setTime(dt)
            vec.setPosition([position[i*3],position[i*3+1],position[i*3+2]])
            vec.setVelocity([velocity[i*3],velocity[i*3+1],velocity[i*3+2]])
            orbit.addStateVector(vec)
            print("valor "+str(i)+": "+str(dt))
        
    def _populateExtras(self):
        from isceobj.Doppler.Doppler import Doppler
        
        self.dopplerRangeTime = self._xmlFileParser.dopRngTime
        self.rangeRefTime = self._xmlFileParser.trg
        self.rangeFirstTime = self._xmlFileParser.rangeStartTime
        
    def extractImage(self):
        """
        Exports GeoTiff to ISCE format.
        """
        from osgeo import gdal
        
        ds = gdal.Open(self._imageFileName)
        metadata = ds.GetMetadata()
        geoTs = ds.GetGeoTransform() #GeoTransform
        prj = ds.GetProjection() #Projection
        dataType = ds.GetRasterBand(1).DataType
        gcps = ds.GetGCPs()
        
        sds = ds.ReadAsArray()
        
        # Output raster array to ISCE file
        driver = gdal.GetDriverByName('ISCE')  
        export = driver.Create(self.output, ds.RasterXSize, ds.RasterYSize, 1, dataType)
        band = export.GetRasterBand(1)
        band.WriteArray(sds)
        export.SetGeoTransform(geoTs)
        export.SetMetadata(metadata)
        export.SetProjection(prj)
        export.SetGCPs(gcps,prj)
        band.FlushCache()
        export.FlushCache()        
        
        self.parse()
        slcImage = isceobj.createSlcImage()
        slcImage.setFilename(self.output)
        slcImage.setXmin(0)
        slcImage.setXmax(self.frame.getNumberOfSamples())
        slcImage.setWidth(self.frame.getNumberOfSamples())
        slcImage.setAccessMode('r')
        self.frame.setImage(slcImage)
        
    def _parseNanoSecondTimeStamp(self,timestamp):
        """
            Parse a date-time string with microsecond precision and return a datetime object
        """
        dateTime,decSeconds = timestamp.split('.')
        microsec = float("0."+decSeconds)*1e6
        dt = datetime.datetime.strptime(dateTime,'%d-%b-%Y %H:%M:%S')
        dt = dt + datetime.timedelta(microseconds=microsec)
        return dt

    def extractDoppler(self):
        """
        Return the doppler centroid.
        """
        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
コード例 #7
0
class COSMO_SkyMed_SLC(Sensor):
    """
    A class representing a Level1Product meta data.
    Level1Product(hdf5=h5filename) will parse the hdf5
    file and produce an object with attributes for metadata.
    """
    parameter_list = (HDF5, ) + Sensor.parameter_list
    logging_name = 'isce.Sensor.COSMO_SkyMed_SLC'
    family = 'cosmo_skymed_slc'

    def __init__(self, family='', name=''):
        super(COSMO_SkyMed_SLC,
              self).__init__(family if family else self.__class__.family,
                             name=name)
        self.frame = Frame()
        self.frame.configure()
        # Some extra processing parameters unique to CSK SLC (currently)
        self.dopplerRangeTime = []
        self.dopplerAzimuthTime = []
        self.azimuthRefTime = None
        self.rangeRefTime = None
        self.rangeFirstTime = None
        self.rangeLastTime = None

        self.lookMap = {'RIGHT': -1, 'LEFT': 1}
        return

    def __getstate__(self):
        d = dict(self.__dict__)
        del d['logger']
        return d

    def __setstate__(self, d):
        self.__dict__.update(d)
        self.logger = logging.getLogger('isce.Sensor.COSMO_SkyMed_SLC')
        return

    def getFrame(self):
        return self.frame

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

        self.populateMetadata(fp)
        fp.close()

    def populateMetadata(self, file):
        """
            Populate our Metadata objects
        """

        self._populatePlatform(file)
        self._populateInstrument(file)
        self._populateFrame(file)
        self._populateOrbit(file)
        self._populateExtras(file)

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

        platform.setMission(file.attrs['Satellite ID'])
        platform.setPointingDirection(
            self.lookMap[file.attrs['Look Side'].decode('utf-8')])
        platform.setPlanet(Planet(pname="Earth"))

        ####This is an approximation for spotlight mode
        ####In spotlight mode, antenna length changes with azimuth position
        platform.setAntennaLength(file.attrs['Antenna Length'])
        try:
            if file.attrs['Multi-Beam ID'].startswith('ES'):
                platform.setAntennaLength(
                    16000.0 / file['S01/SBI'].attrs['Line Time Interval'])
        except:
            pass

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

        #        rangePixelSize = Const.c/(2*file['S01'].attrs['Sampling Rate'])
        rangePixelSize = file['S01/SBI'].attrs['Column Spacing']
        instrument.setRadarWavelength(file.attrs['Radar Wavelength'])
        #        instrument.setPulseRepetitionFrequency(file['S01'].attrs['PRF'])
        instrument.setPulseRepetitionFrequency(
            1.0 / file['S01/SBI'].attrs['Line Time Interval'])
        instrument.setRangePixelSize(rangePixelSize)
        instrument.setPulseLength(file['S01'].attrs['Range Chirp Length'])
        instrument.setChirpSlope(file['S01'].attrs['Range Chirp Rate'])
        #        instrument.setRangeSamplingRate(file['S01'].attrs['Sampling Rate'])
        instrument.setRangeSamplingRate(
            1.0 / file['S01/SBI'].attrs['Column Time Interval'])

        incangle = 0.5 * (file['S01/SBI'].attrs['Far Incidence Angle'] +
                          file['S01/SBI'].attrs['Near Incidence Angle'])
        instrument.setIncidenceAngle(incangle)

    def _populateFrame(self, file):

        rft = file['S01/SBI'].attrs['Zero Doppler Range First Time']
        slantRange = rft * Const.c / 2.0
        self.frame.setStartingRange(slantRange)

        referenceUTC = self._parseNanoSecondTimeStamp(
            file.attrs['Reference UTC'])
        relStart = file['S01/SBI'].attrs['Zero Doppler Azimuth First Time']
        relEnd = file['S01/SBI'].attrs['Zero Doppler Azimuth Last Time']
        relMid = 0.5 * (relStart + relEnd)

        sensingStart = self._combineDateTime(referenceUTC, relStart)
        sensingStop = self._combineDateTime(referenceUTC, relEnd)
        sensingMid = self._combineDateTime(referenceUTC, relMid)

        self.frame.setPassDirection(file.attrs['Orbit Direction'])
        self.frame.setOrbitNumber(file.attrs['Orbit Number'])
        self.frame.setProcessingFacility(file.attrs['Processing Centre'])
        self.frame.setProcessingSoftwareVersion(
            file.attrs['L0 Software Version'])
        self.frame.setPolarization(file['S01'].attrs['Polarisation'])
        self.frame.setNumberOfLines(file['S01/SBI'].shape[0])
        self.frame.setNumberOfSamples(file['S01/SBI'].shape[1])
        self.frame.setSensingStart(sensingStart)
        self.frame.setSensingMid(sensingMid)
        self.frame.setSensingStop(sensingStop)

        rangePixelSize = self.frame.getInstrument().getRangePixelSize()
        farRange = slantRange + (self.frame.getNumberOfSamples() -
                                 1) * rangePixelSize
        self.frame.setFarRange(farRange)

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

        orbit.setReferenceFrame('ECR')
        orbit.setOrbitSource('Header')
        t0 = datetime.datetime.strptime(
            file.attrs['Reference UTC'].decode('utf-8'),
            '%Y-%m-%d %H:%M:%S.%f000')
        t = file.attrs['State Vectors Times']
        position = file.attrs['ECEF Satellite Position']
        velocity = file.attrs['ECEF Satellite Velocity']

        for i in range(len(position)):
            vec = StateVector()
            dt = t0 + datetime.timedelta(seconds=t[i])
            vec.setTime(dt)
            vec.setPosition([position[i, 0], position[i, 1], position[i, 2]])
            vec.setVelocity([velocity[i, 0], velocity[i, 1], velocity[i, 2]])
            orbit.addStateVector(vec)

    def _populateExtras(self, file):
        """
        Populate some of the extra fields unique to processing TSX data.
        In the future, other sensors may need this information as well,
        and a re-organization may be necessary.
        """
        from isceobj.Doppler.Doppler import Doppler

        self.dopplerRangeTime = file.attrs['Centroid vs Range Time Polynomial']
        self.dopplerAzimuthTime = file.attrs[
            'Centroid vs Azimuth Time Polynomial']
        self.rangeRefTime = file.attrs['Range Polynomial Reference Time']
        self.azimuthRefTime = file.attrs['Azimuth Polynomial Reference Time']
        self.rangeFirstTime = file['S01/SBI'].attrs[
            'Zero Doppler Range First Time']
        self.rangeLastTime = file['S01/SBI'].attrs[
            'Zero Doppler Range Last Time']

        # get Doppler rate information, vs. azimuth first EJF 2015/00/05
        # guessing that same scale applies as for Doppler centroid
        self.dopplerRateCoeffs = file.attrs[
            'Doppler Rate vs Azimuth Time Polynomial']

    def extractImage(self):
        import os
        from ctypes import cdll, c_char_p
        extract_csk = cdll.LoadLibrary(os.path.dirname(__file__) + '/csk.so')
        inFile_c = c_char_p(bytes(self.hdf5, 'utf-8'))
        outFile_c = c_char_p(bytes(self.output, 'utf-8'))

        extract_csk.extract_csk_slc(inFile_c, outFile_c)

        self.parse()
        slcImage = isceobj.createSlcImage()
        slcImage.setFilename(self.output)
        slcImage.setXmin(0)
        slcImage.setXmax(self.frame.getNumberOfSamples())
        slcImage.setWidth(self.frame.getNumberOfSamples())
        slcImage.setAccessMode('r')
        self.frame.setImage(slcImage)

    def _parseNanoSecondTimeStamp(self, timestamp):
        """
            Parse a date-time string with nanosecond precision and return a datetime object
        """
        dateTime, nanoSeconds = timestamp.decode('utf-8').split('.')
        microsec = float(nanoSeconds) * 1e-3
        dt = datetime.datetime.strptime(dateTime, '%Y-%m-%d %H:%M:%S')
        dt = dt + datetime.timedelta(microseconds=microsec)
        return dt

    def _combineDateTime(self, dobj, secsstr):
        '''Takes the date from dobj and time from secs to spit out a date time object.
        '''
        sec = float(secsstr)
        dt = datetime.timedelta(seconds=sec)
        return datetime.datetime.combine(dobj.date(), datetime.time(0, 0)) + dt

    def extractDoppler(self):
        """
        Return the doppler centroid as defined in the HDF5 file.
        """
        import numpy as np

        quadratic = {}
        midtime = (self.rangeLastTime +
                   self.rangeFirstTime) * 0.5 - self.rangeRefTime

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

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

        ####For roiApp more accurate
        ####Convert stuff to pixel wise coefficients
        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])

        #EMG - 20160420 This section was introduced in the populateMetadata method by EJF in r2022
        #Its pupose seems to be to set self.doppler_coeff and self.azfmrate_coeff, which don't seem
        #to be used anywhere in ISCE. Need to take time to understand the need for this and consult
        #with EJF.
        #
        ## save the Doppler centroid coefficients, converting units from .h5 file
        ## units in the file are quadratic coefficients in Hz, Hz/sec, and Hz/(sec^2)
        ## ISCE expects Hz, Hz/(range sample), Hz/(range sample)^2
        ## note that RS2 Doppler values are estimated at time dc.dopplerCentroidReferenceTime,
        ## so the values might need to be adjusted for ISCE usage
        ## adapted from RS2 version EJF 2015/09/05
        #        poly = self.frame._dopplerVsPixel
        #        rangeSamplingRate = self.frame.getInstrument().getPulseRepetitionFrequency()
        #        # need to convert units
        #        poly[1] = poly[1]/rangeSamplingRate
        #        poly[2] = poly[2]/rangeSamplingRate**2
        #        self.doppler_coeff = poly
        #
        ## similarly save Doppler azimuth fm rate values, converting units
        ## units in the file are quadratic coefficients in Hz, Hz/sec, and Hz/(sec^2)
        ## units are already converted below
        ## Guessing that ISCE expects Hz, Hz/(azimuth line), Hz/(azimuth line)^2
        ## note that RS2 Doppler values are estimated at time dc.dopplerRateReferenceTime,
        ## so the values might need to be adjusted for ISCE usage
        ## modified from RS2 version EJF 2015/09/05
        ## CSK Doppler azimuth FM rate not yet implemented in reading section, set to zero for now
        #
        #        fmpoly = self.dopplerRateCoeffs
        #        # don't need to convert units
        ##        fmpoly[1] = fmpoly[1]/rangeSamplingRate
        ##        fmpoly[2] = fmpoly[2]/rangeSamplingRate**2
        #        self.azfmrate_coeff = fmpoly
        #EMG - 20160420

        return quadratic
コード例 #8
0
ファイル: Radarsat2.py プロジェクト: HBaldwin3/isce_v2.0.0
class Radarsat2(Component):
    """
        A Class representing RadarSAT 2 data
    """
    def __init__(self):
        Component.__init__(self)        
        self.xml = None
        self.tiff = None
        self.output = None
        self.product = _Product()                                
        self.frame = Frame()
        self.frame.configure()
        
        self.descriptionOfVariables = {}
        self.dictionaryOfVariables = {'XML': ['self.xml','str','mandatory'],
                                      'TIFF': ['self.tiff','str','mandatory'],
                                      '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 populateMetadata(self):
        """
            Create metadata objects from the metadata files
        """
        mission = self.product.sourceAttributes.satellite
        swath = self.product.sourceAttributes.radarParameters.beams
        frequency = self.product.sourceAttributes.radarParameters.radarCenterFrequency
        prf = self.product.sourceAttributes.radarParameters.prf        
        rangePixelSize = self.product.imageAttributes.rasterAttributes.sampledPixelSpacing
        rangeSamplingRate = Const.c/(2*rangePixelSize)        
        pulseLength = self.product.sourceAttributes.radarParameters.pulseLengths[0]
        pulseBandwidth = self.product.sourceAttributes.radarParameters.pulseBandwidths[0]
        polarization = self.product.sourceAttributes.radarParameters.polarizations
        lookSide = lookMap[self.product.sourceAttributes.radarParameters.antennaPointing.upper()]
        facility = self.product.imageGenerationParameters.generalProcessingInformation._processingFacility
        version = self.product.imageGenerationParameters.generalProcessingInformation.softwareVersion
        lines = self.product.imageAttributes.rasterAttributes.numberOfLines
        samples = self.product.imageAttributes.rasterAttributes.numberOfSamplesPerLine
        startingRange = self.product.imageGenerationParameters.slantRangeToGroundRange.slantRangeTimeToFirstRangeSample * (Const.c/2)
        incidenceAngle = (self.product.imageGenerationParameters.sarProcessingInformation.incidenceAngleNearRange + self.product.imageGenerationParameters.sarProcessingInformation.incidenceAngleFarRange)/2

        lineFlip =  (self.product.imageAttributes.rasterAttributes.lineTimeOrdering.upper() == 'DECREASING')

        if lineFlip:
            dataStopTime = self.product.imageGenerationParameters.sarProcessingInformation.zeroDopplerTimeFirstLine
            dataStartTime = self.product.imageGenerationParameters.sarProcessingInformation.zeroDopplerTimeLastLine
        else:
            dataStartTime = self.product.imageGenerationParameters.sarProcessingInformation.zeroDopplerTimeFirstLine
            dataStopTime = self.product.imageGenerationParameters.sarProcessingInformation.zeroDopplerTimeLastLine

        passDirection = self.product.sourceAttributes.orbitAndAttitude.orbitInformation.passDirection
        height = self.product.imageGenerationParameters.sarProcessingInformation._satelliteHeight

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

        ####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)
        
        # Initialize orbit objects
        # Read into temp orbit first. 
        # Radarsat 2 needs orbit extensions.
        tempOrbit = Orbit()

        self.frame.getOrbit().setOrbitSource('Header: ' + self.product.sourceAttributes.orbitAndAttitude.orbitInformation.orbitDataFile)
        self.frame.setPassDirection(passDirection)
        stateVectors = self.product.sourceAttributes.orbitAndAttitude.orbitInformation.stateVectors
        for i in range(len(stateVectors)):
            position = [stateVectors[i].xPosition, stateVectors[i].yPosition, stateVectors[i].zPosition]
            velocity = [stateVectors[i].xVelocity, stateVectors[i].yVelocity, stateVectors[i].zVelocity]
            vec = StateVector()            
            vec.setTime(stateVectors[i].timeStamp)
            vec.setPosition(position)
            vec.setVelocity(velocity)
            tempOrbit.addStateVector(vec)

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

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


    def extractImage(self, verbose=True):
        '''
        Use gdal to extract the slc.
        '''

        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()
        lineFlip = (self.product.imageAttributes.rasterAttributes.lineTimeOrdering.upper() == 'DECREASING')
        pixFlip = (self.product.imageAttributes.rasterAttributes.pixelTimeOrdering.upper() == 'DECREASING')

        src = gdal.Open(self.tiff.strip(), gdal.GA_ReadOnly)
        cJ = np.complex64(1.0j)

        ####Images are small enough that we can do it all in one go - Piyush
        real = src.GetRasterBand(1).ReadAsArray(0,0,width,lgth)
        imag = src.GetRasterBand(2).ReadAsArray(0,0,width,lgth)

        if (real is None) or (imag is None):
            raise Exception('Input Radarsat2 SLC seems to not be a 2 band Int16 image.')

        data = real+cJ*imag

        real = None
        imag = None
        src = None

        if lineFlip:
            if verbose:
                print('Vertically Flipping data')
            data = np.flipud(data)

        if pixFlip:
            if verbose:
                print('Horizontally Flipping data')
            data = np.fliplr(data)

        data.tofile(self.output)

        ####
        slcImage = isceobj.createSlcImage()
        slcImage.setByteOrder('l')
        slcImage.setFilename(self.output)
        slcImage.setAccessMode('read')
        slcImage.setWidth(width)
        slcImage.setLength(lgth)
        slcImage.setXmin(0)
        slcImage.setXmax(width)
#        slcImage.renderHdr()
        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['b'] = 0.
        quadratic['c'] = 0.
        return quadratic
コード例 #9
0
ファイル: Sentinel1.py プロジェクト: scottstanie/isce2
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
コード例 #10
0
class ICEYE_SLC(Sensor):
    """
    A class representing a Level1Product meta data.
    Level1Product(hdf5=h5filename) will parse the hdf5
    file and produce an object with attributes for metadata.
    """
    parameter_list = (HDF5, APPLY_SLANT_RANGE_PHASE) + Sensor.parameter_list
    logging_name = 'isce.Sensor.ICEYE_SLC'
    family = 'iceye_slc'

    def __init__(self, family='', name=''):
        super(ICEYE_SLC,
              self).__init__(family if family else self.__class__.family,
                             name=name)
        self.frame = Frame()
        self.frame.configure()
        # Some extra processing parameters unique to CSK SLC (currently)
        self.dopplerRangeTime = []
        self.dopplerAzimuthTime = []
        self.azimuthRefTime = None
        self.rangeRefTime = None
        self.rangeFirstTime = None
        self.rangeLastTime = None

        self.lookMap = {'RIGHT': -1, 'LEFT': 1}
        return

    def __getstate__(self):
        d = dict(self.__dict__)
        del d['logger']
        return d

    def __setstate__(self, d):
        self.__dict__.update(d)
        self.logger = logging.getLogger('isce.Sensor.ICEYE_SLC')
        return

    def getFrame(self):
        return self.frame

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

        self.populateMetadata(fp)
        fp.close()

    def populateMetadata(self, file):
        """
            Populate our Metadata objects
        """

        self._populatePlatform(file)
        self._populateInstrument(file)
        self._populateFrame(file)
        self._populateOrbit(file)
        self._populateExtras(file)

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

        platform.setMission(file['satellite_name'][()])
        platform.setPointingDirection(
            self.lookMap[file['look_side'][()].upper()])
        platform.setPlanet(Planet(pname="Earth"))

        ####This is an approximation for spotlight mode
        ####In spotlight mode, antenna length changes with azimuth position
        platform.setAntennaLength(2 * file['azimuth_ground_spacing'][()])

        assert (file['range_looks'][()] == 1)
        assert (file['azimuth_looks'][()] == 1)

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

        rangePixelSize = file['slant_range_spacing'][()]
        instrument.setRadarWavelength(Const.c / file['carrier_frequency'][()])
        instrument.setPulseRepetitionFrequency(file['processing_prf'][()])
        instrument.setRangePixelSize(rangePixelSize)
        instrument.setPulseLength(file['chirp_duration'][()])
        instrument.setChirpSlope(file['chirp_bandwidth'][()] /
                                 file['chirp_duration'][()])
        instrument.setRangeSamplingRate(file['range_sampling_rate'][()])

        incangle = file['local_incidence_angle']
        instrument.setIncidenceAngle(incangle[incangle.size // 2])

    def _populateFrame(self, file):

        rft = file['first_pixel_time'][()]
        slantRange = rft * Const.c / 2.0
        self.frame.setStartingRange(slantRange)

        sensingStart = datetime.datetime.strptime(
            file['zerodoppler_start_utc'][()].decode('utf-8'),
            '%Y-%m-%dT%H:%M:%S.%f')
        sensingStop = datetime.datetime.strptime(
            file['zerodoppler_end_utc'][()].decode('utf-8'),
            '%Y-%m-%dT%H:%M:%S.%f')
        sensingMid = sensingStart + 0.5 * (sensingStop - sensingStart)

        self.frame.setPassDirection(file['orbit_direction'][()])
        self.frame.setOrbitNumber(file['orbit_absolute_number'][()])
        self.frame.setProcessingFacility('ICEYE')
        self.frame.setProcessingSoftwareVersion(
            str(file['processor_version'][()]))
        self.frame.setPolarization(file['polarization'][()])
        self.frame.setNumberOfLines(file['number_of_azimuth_samples'][()])
        self.frame.setNumberOfSamples(file['number_of_range_samples'][()])
        self.frame.setSensingStart(sensingStart)
        self.frame.setSensingMid(sensingMid)
        self.frame.setSensingStop(sensingStop)

        rangePixelSize = self.frame.getInstrument().getRangePixelSize()
        farRange = slantRange + (self.frame.getNumberOfSamples() -
                                 1) * rangePixelSize
        self.frame.setFarRange(farRange)

    def _populateOrbit(self, file):
        import numpy as np
        orbit = self.frame.getOrbit()

        orbit.setReferenceFrame('ECR')
        orbit.setOrbitSource('Header')
        t = file['state_vector_time_utc'][:]
        position = np.zeros((t.size, 3))
        position[:, 0] = file['posX'][:]
        position[:, 1] = file['posY'][:]
        position[:, 2] = file['posZ'][:]

        velocity = np.zeros((t.size, 3))
        velocity[:, 0] = file['velX'][:]
        velocity[:, 1] = file['velY'][:]
        velocity[:, 2] = file['velZ'][:]

        for ii in range(t.size):
            vec = StateVector()
            vec.setTime(
                datetime.datetime.strptime(t[ii][0].decode('utf-8'),
                                           '%Y-%m-%dT%H:%M:%S.%f'))
            vec.setPosition(
                [position[ii, 0], position[ii, 1], position[ii, 2]])
            vec.setVelocity(
                [velocity[ii, 0], velocity[ii, 1], velocity[ii, 2]])
            orbit.addStateVector(vec)

    def _populateExtras(self, file):
        """
        Populate some of the extra fields unique to processing TSX data.
        In the future, other sensors may need this information as well,
        and a re-organization may be necessary.
        """
        import numpy as np
        self.dcpoly = np.mean(file['dc_estimate_coeffs'][:], axis=0)

    def extractImage(self):
        import numpy as np
        import h5py

        self.parse()

        fid = h5py.File(self.hdf5, 'r')

        si = fid['s_i']
        sq = fid['s_q']

        nLines = si.shape[0]
        spectralShift = 2 * self.frame.getInstrument().getRangePixelSize(
        ) / self.frame.getInstrument().getRadarWavelength()
        spectralShift -= np.floor(spectralShift)
        phsShift = np.exp(-1j * 2 * np.pi * spectralShift *
                          np.arange(si.shape[1]))
        with open(self.output, 'wb') as fout:
            for ii in range(nLines):
                line = (si[ii, :] + 1j * sq[ii, :])
                if self.applySlantRangePhase:
                    line *= phsShift
                line.astype(np.complex64).tofile(fout)

        fid.close()

        slcImage = isceobj.createSlcImage()
        slcImage.setFilename(self.output)
        slcImage.setXmin(0)
        slcImage.setXmax(self.frame.getNumberOfSamples())
        slcImage.setWidth(self.frame.getNumberOfSamples())
        slcImage.setAccessMode('r')
        self.frame.setImage(slcImage)

    def extractDoppler(self):
        """
        Return the doppler centroid as defined in the HDF5 file.
        """
        import numpy as np

        quadratic = {}

        rangePixelSize = self.frame.getInstrument().getRangePixelSize()
        rt0 = self.frame.getStartingRange() / (2 * Const.c)
        rt1 = rt0 + ((self.frame.getNumberOfSamples() - 1) *
                     rangePixelSize) / (2 * Const.c)

        ####insarApp style
        quadratic['a'] = np.polyval(self.dcpoly, 0.5 *
                                    (rt0 + rt1)) / self.frame.PRF
        quadratic['b'] = 0.
        quadratic['c'] = 0.

        ####For roiApp more accurate
        ####Convert stuff to pixel wise coefficients
        x = np.linspace(rt0, rt1, num=len(self.dcpoly) + 1)
        pix = np.linspace(0,
                          self.frame.getNumberOfSamples(),
                          num=len(self.dcpoly) + 1)
        evals = np.polyval(self.dcpoly, x)
        fit = np.polyfit(pix, evals, len(self.dcpoly) - 1)
        self.frame._dopplerVsPixel = list(fit[::-1])
        print('Doppler Fit: ', self.frame._dopplerVsPixel)

        return quadratic