Example #1
0
    def readOrbit(self, platformPositionRecord):
        '''
        reformat orbit from platformPositionRecord
        '''
        orb=Orbit()
        orb.setOrbitSource('leaderfile')
        orb.setOrbitQuality(self.orbitElementsDesignator[platformPositionRecord.metadata['Orbital elements designator']])

        t0 = datetime.datetime(year=platformPositionRecord.metadata['Year of data point'],
                               month=platformPositionRecord.metadata['Month of data point'],
                               day=platformPositionRecord.metadata['Day of data point'])
        t0 = t0 + datetime.timedelta(seconds=platformPositionRecord.metadata['Seconds of day'])

        #####Read in orbit in inertial coordinates
        deltaT = platformPositionRecord.metadata['Time interval between data points']
        numPts = platformPositionRecord.metadata['Number of data points']
        for i in range(numPts):
            vec = StateVector()
            t = t0 + datetime.timedelta(seconds=i*deltaT)
            vec.setTime(t)

            dataPoints = platformPositionRecord.metadata['Positional Data Points'][i]
            pos = [dataPoints['Position vector X'], dataPoints['Position vector Y'], dataPoints['Position vector Z']]
            vel = [dataPoints['Velocity vector X'], dataPoints['Velocity vector Y'], dataPoints['Velocity vector Z']]
            vec.setPosition(pos)
            vec.setVelocity(vel)
            orb.addStateVector(vec)

        return orb
Example #2
0
    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
Example #3
0
class DOR(BaseEnvisatFile):
    """A class for parsing Envisat DORIS orbit files"""

    def __init__(self,fileName=None):
        BaseEnvisatFile.__init__(self)
        self.fileName = fileName
        self.fp = None
        self.orbit = Orbit()
        self.orbit.setOrbitSource('DORIS')
        self.orbit.setReferenceFrame('ECR')

    def parse(self):

        orbitDict = {}
        try:
            self.fp = open(self.fileName, 'rb')
        except IOError as errs:
            errno,strerr = errs
            print("IOError: %s" % strerr)
            return

        self.readMPH()
        self.readSPH()
        self.readStateVectors()

        self.fp.close()

        if (self.sph['dataSets'][0]['DS_NAME'] == 'DORIS PRELIMINARY ORBIT'):
            self.orbit.setOrbitQuality('Preliminary')
        elif (self.sph['dataSets'][0]['DS_NAME'] == 'DORIS PRECISE ORBIT'):
            self.orbit.setOrbitQuality('Precise')

        orbitDict.update(self.mph)
        orbitDict.update(self.sph)

        return orbitDict

    def readStateVectors(self):
        headerLength = self.mphLength + self.sphLength
        self.fp.seek(headerLength)

        for line in self.fp.readlines():
            vals = line.decode('utf8').split()
            dateTime = self._parseDateTime(vals[0] + ' ' + vals[1])
            position = list(map(float,vals[4:7]))
            velocity = list(map(float,vals[7:10]))
            sv = StateVector()
            sv.setTime(dateTime)
            sv.setPosition(position)
            sv.setVelocity(velocity)
            self.orbit.addStateVector(sv)

    def _parseDateTime(self,dtString):
        dateTime = datetime.datetime.strptime(dtString,'%d-%b-%Y %H:%M:%S.%f')
        return dateTime
Example #4
0
    def trimOrbit(self, startTime, stopTime):
        """Trim the list of state vectors to encompass the time span [startTime:stopTime]"""

        newOrbit = Orbit()
        newOrbit.setOrbitSource('ODR')
        newOrbit.setReferenceFrame('ECR')
        for sv in self._ephemeris:
            if ((sv.getTime() > startTime) and (sv.getTime() < stopTime)):
                newOrbit.addStateVector(sv)

        return newOrbit
Example #5
0
    def convert(self):
        '''
        Convert ECI orbit to ECEF orbit.
        '''

        ECROrbit = Orbit()
        ECROrbit.configure()

        for sv in self.orbit:
            svtime = sv.getTime()
            position = sv.getPosition()
            velocity = sv.getVelocity()

            ####Compute GMST from GAST - Eq 5.13
            dtiff = (svtime - self.referenceEpoch).total_seconds()
            theta = self.referenceGAST + self.Omega * dtiff

            costh = np.cos(theta)
            sinth = np.sin(theta)

            ###Position transformation
            A = np.zeros((3, 3))
            A[0, 0] = costh
            A[0, 1] = sinth
            A[1, 0] = -sinth
            A[1, 1] = costh
            A[2, 2] = 1

            ###Velocity transformation
            Adot = np.zeros((3, 3))
            Adot[0, 0] = -self.Omega * sinth
            Adot[0, 1] = self.Omega * costh
            Adot[1, 0] = -self.Omega * costh
            Adot[1, 1] = -self.Omega * sinth

            ###Compute ECR state vector
            newPos = np.dot(A, position)
            newVel = np.dot(Adot, position) + np.dot(A, velocity)

            ####Create state vector object
            newsv = StateVector()
            newsv.setTime(svtime)
            newsv.setPosition(newPos.tolist())
            newsv.setVelocity(newVel.tolist())

            ###Append to orbit
            ECROrbit.addStateVector(newsv)

        ECROrbit.setOrbitSource('Sidereal angle conversion')
        ECROrbit.setOrbitQuality(self.orbit.getOrbitQuality())
        return ECROrbit
Example #6
0
    def convert(self):
        '''Convert ECI orbit to ECEF orbit.'''

        date = self.orbit._stateVectors[0].getTime().date()
        bspName = 'inertial_orbit_' + date.strftime('%Y%m%d') + '.bsp'

        ####Convert ISCE orbit to SPICE orbit file
        sorb = ISCEOrbit(self.orbit)
        sorb.exportToSPK(bspName, frame=self.eci)

        ####Convert coordinates with corrections
        spk = SpiceOrbit(bspName)
        spk.initSpice()

        wgsOrbit = Orbit()
        wgsOrbit.setOrbitSource(self.orbit.getOrbitSource())
        wgsOrbit.setOrbitQuality(self.orbit.getOrbitQuality())
        for sv in self.orbit:
            tim = sv.getTime()
            spksv = spk.interpolateOrbit(tim, frame=self.ecef)
            wgsOrbit.addStateVector(spksv)

        return wgsOrbit
Example #7
0
class ODR(object):
    """A class to parse Orbital Data Records (ODR) generated by Delft"""

    logging_name = 'isceobj.Orbit.ODR'

    @logged
    def __init__(self, file=None):
        self._file = file
        self._format = None
        self._satellite = None
        self._arcNumber = None
        self._cycleLength = None
        self._numberOfRecords = None
        self._version = None
        self._ephemeris = Orbit()
        self._ephemeris.setOrbitSource('ODR')
        self._ephemeris.setReferenceFrame('ECR')
        self.grs80 = Ellipsoid.Ellipsoid(
            *AstronomicalHandbook.PlanetsData.ellipsoid['Earth']['GRS-80'])

        return None

    #jng added the start and stop time. The computation of the velocities seems pretty time comsuming, so limit the orbit data extraction only to startTime nad stopTime
    def parseHeader(self, startTime=None, stopTime=None):
        fp = None
        try:
            fp = open(self._file, 'rb')
        except IOError as strerr:
            self.logger.error(strerr)
        buffer = fp.read(16)
        # Header 1
        (format, satellite,
         dataStartTimeSeconds) = struct.unpack('>4s8si', buffer)
        buffer = fp.read(16)
        # Header 2
        (cycleLength, number, numberOfRecords,
         version) = struct.unpack('>4i', buffer)

        self._format = format.decode('utf-8')
        self._satellite = satellite.decode('utf-8')
        self._arcNumber = number
        self._cycleLength = cycleLength * 1e3  # In cycle length in days
        self._numberOfRecords = numberOfRecords
        self._version = version

        positions = []
        for i in range(numberOfRecords):
            buffer = fp.read(16)
            if not startTime == None:
                position = self.parseDataRecords(buffer)
                if position['time'] < startTime:
                    continue

            if not stopTime == None:
                position = self.parseDataRecords(buffer)
                if position['time'] > stopTime:
                    continue

            positions.append(self.parseDataRecords(buffer))

        self.createStateVectors(positions)
        fp.close()

    def parseDataRecords(self, buffer):
        """Parse the individual data records for this ODR file"""
        (timeSeconds, latitude, longitude,
         height) = struct.unpack('>4i', buffer)
        time = self._utcSecondsToDatetime(timeSeconds)
        if (self._format == '@ODR'):
            latitude = latitude * 1e-6
            longitude = longitude * 1e-6
        elif (self._format == 'xODR'):
            latitude = latitude * 1e-7
            longitude = longitude * 1e-7
        height = height * 1e-3

        xyz = self._convertToXYZ(latitude, longitude, height)
        return ({'time': time, 'x': xyz[0], 'y': xyz[1], 'z': xyz[2]})

    def createStateVectors(self, positions):
        """Calculate the satellite velocity from the position data and create StateVector objects"""

        for i in range(len(positions)):
            t0 = positions[i]['time']
            x0 = positions[i]['x']
            y0 = positions[i]['y']
            z0 = positions[i]['z']

            sv = StateVector()
            sv.setTime(t0)
            sv.setPosition([x0, y0, z0])
            sv.setVelocity([0.0, 0.0, 0.0])
            self._ephemeris.addStateVector(sv)
        self._calculateVelocities()

    def _calculateVelocities(self):
        for sv in self._ephemeris:
            t0 = sv.getTime()
            t1 = t0 + datetime.timedelta(seconds=-0.5)
            t2 = t0 + datetime.timedelta(seconds=0.5)
            try:
                sv1 = self._ephemeris.interpolateOrbit(t1, method='legendre')
                sv2 = self._ephemeris.interpolateOrbit(t2, method='legendre')
            except ValueError:
                continue
            if (not sv1) or (not sv2):
                continue
            v1 = sv1.getPosition()
            v2 = sv2.getPosition()
            vx = (v2[0] - v1[0])
            vy = (v2[1] - v1[1])
            vz = (v2[2] - v1[2])
            sv.setVelocity([vx, vy, vz])

    def trimOrbit(self, startTime, stopTime):
        """Trim the list of state vectors to encompass the time span [startTime:stopTime]"""

        newOrbit = Orbit()
        newOrbit.setOrbitSource('ODR')
        newOrbit.setReferenceFrame('ECR')
        for sv in self._ephemeris:
            if ((sv.getTime() > startTime) and (sv.getTime() < stopTime)):
                newOrbit.addStateVector(sv)

        return newOrbit

    def getEphemeris(self):
        return self._ephemeris

    def _convertToXYZ(self, latitude, longitude, height):
        # The latitude, longitude and height are referenced to the center of mass of the satellite above the GRS80 ellipsoid
        xyz = self.grs80.llh_to_xyz([latitude, longitude, height])
        return xyz

    def _utcSecondsToDatetime(self, seconds):
        """All of the ODR records are in UTC seconds from 1 Jan. 1985"""
        dataTime = datetime.datetime(year=1985, month=1, day=1)
        dataTime = dataTime + datetime.timedelta(seconds=seconds)
        return dataTime
    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
Example #9
0
class PDS(object):
    def __init__(self, file=None):
        self.filename = file
        self.firstEpoch = 0
        self.lastEpoch = 0
        self.orbit = Orbit()
        self.orbit.configure()
        self.orbit.setOrbitSource('PDS')

    def getOrbit(self):
        return self.orbit

    def parse(self):
        fp = open(self.filename, 'r')
        for line in fp.readlines():
            if (line[0].isdigit()):
                self.__parseStateVectorLine(line)
            else:
                self.__parseRecordLine(line)
        fp.close()

    def __parseRecordLine(self, line):
        line = line.strip()
        if (line.startswith('START_TIME')):
            values = line.split('=')
            values[1] = values[1].strip('"')
            dateTime = values[1].split()
            self.firstEpoch = self.__parseDateTimeString(
                dateTime[0], dateTime[1])
        elif (line.startswith('STOP_TIME')):
            values = line.split('=')
            values[1] = values[1].strip('"')
            dateTime = values[1].split()
            self.lastEpoch = self.__parseDateTimeString(
                dateTime[0], dateTime[1])
        elif (line.startswith('LEAP_UTC')):
            pass
        elif (line.startswith('LEAP_SIGN')):
            pass
        elif (line.startswith('RECORD_SIZE')):
            pass
        elif (line.startswith('NUM_REC')):
            pass

    def __parseStateVectorLine(self, line):
        date = line[0:11]
        time = line[12:27]
        x = float(line[44:56])
        y = float(line[57:69])
        z = float(line[70:82])
        vx = float(line[83:95])
        vy = float(line[96:108])
        vz = float(line[109:121])

        dt = self.__parseDateTimeString(date, time)

        sv = StateVector()
        sv.configure()
        sv.setTime(dt)
        sv.setPosition([x, y, z])
        sv.setVelocity([vx, vy, vz])
        self.orbit.addStateVector(sv)

    def __parseDateTimeString(self, date, time):
        """
        Fix idiosyncrasies in the date and time strings
        """
        time = time.replace(
            '-', '0'
        )  # For some reason, there are occasionally - signs where there should be zeros
        dt = datetime.datetime.strptime(date + ' ' + time,
                                        '%d-%b-%Y %H:%M:%S.%f')
        return dt
Example #10
0
class PRC(object):
    """A class to parse orbit data from D-PAF"""

    logging_name = "isce.orbit.PRC.PRC"

    @logged
    def __init__(self, file=None):
        self.filename = file
        self.firstEpoch = 0
        self.lastEpoch = 0
        self.tdtOffset = 0
        self.orbit = Orbit()
        self.orbit.configure()
        self.orbit.setOrbitQuality('Precise')
        self.orbit.setOrbitSource('PRC')
        return None

    def getOrbit(self):
        return self.orbit

    def parse(self):
        #People still seem to be using the old .Z format
        #Adding support for it - PSA
        if os.path.splitext(self.filename)[1] == '.Z':
            from subprocess import Popen, PIPE
            fp = Popen(["zcat", self.filename], stdout=PIPE).stdout
        else:
            fp = open(self.filename, 'r')
        data = fp.read()
        fp.close()

        numLines = int(len(data) / 130)
        for i in range(numLines):
            line = data[i * 130:(i + 1) * 130]
            self.__parseLine(line)

    def __parseLine(self, line):
        """Parse a line from a PRC orbit file"""
        referenceFrame = line[0:6].decode('utf-8')
        if (referenceFrame == 'STATE '):
            self.__parseStateLine(line)
        if (referenceFrame == 'STTERR'):
            self.__parseTerrestrialLine(line)

    def __parseTerrestrialLine(self, line):
        j2000Day = float(line[14:20]) / 10.0 + 0.5
        tdt = float(line[20:31]) / 1e6
        x = float(line[31:43]) / 1e3
        y = float(line[43:55]) / 1e3
        z = float(line[55:67]) / 1e3
        vx = float(line[67:78]) / 1e6
        vy = float(line[78:89]) / 1e6
        vz = float(line[89:100]) / 1e6
        quality = line[127]

        tdt = tdt - self.tdtOffset
        dt = self.__j2000ToDatetime(j2000Day, tdt)

        sv = StateVector()
        sv.configure()
        sv.setTime(dt)
        sv.setPosition([x, y, z])
        sv.setVelocity([vx, vy, vz])
        self.orbit.addStateVector(sv)

    def __parseStateLine(self, line):
        self.firstEpoch = self.__j2000ToDatetime(float(line[6:12]) / 10.0, 0.0)
        self.lastEpoch = self.__j2000ToDatetime(float(line[12:18]) / 10.0, 0.0)
        self.tdtOffset = float(line[47:52])
        self.tdtOffset = self.tdtOffset / 1e3

    def __j2000ToDatetime(self, j2000Day, tdt):
        """Convert the number of days since 1 Jan. 2000 to a datetime object"""
        j2000 = datetime.datetime(year=2000, month=1, day=1)
        dt = j2000 + datetime.timedelta(days=j2000Day, seconds=tdt)
        return dt

    pass