You are here: Home Software sfdu2tmpacket

sfdu2tmpacket

by Leif Kalla last modified Sep 08, 2004 12:31 PM

Convert SFDU format to EGSE tlm.

— Python Source, 7Kb

File contents

#! /usr/bin/env python

import struct
import getopt
import exceptions
import sys
import time
import string
import array
import os.path
import zipfile


class EndOfInput(exceptions.Exception):
    def __init__(self,args=None):
        self.args = args

class ZippedSfdu(str):
        def __init__(self, *argsl, **argsd):
                str.__init__(self,  *argsl, **argsd)
                self.position=0

        def read(self, n=1):
                ret= self[self.position:self.position+n]
                self.position += n

                return ret

        def close(self):
                pass


class TmPacket(object):
    """ An ESA Telemetry packet with DDS header
    """

    DDS_HEADER_FMT = "!IIIHHBB"

    def __init__(self,bin):
        "The DDS header should be in the argument."

        #print "FMT SIZE : %d " % \
        #      (struct.calcsize(TmPacket.DDS_HEADER_FMT))

        self.lst = struct.unpack(TmPacket.DDS_HEADER_FMT,bin)

        gmt = time.gmtime(self.lst[0])
        subsec = self.lst[1]/10e5
        subStr = "%.6f" % subsec
        subStr = subStr.lstrip("0.")
        self.SCET_Str = "%04d-%02d-%02d %02d:%02d:%02d.%s" % (gmt[0],gmt[1], \
                                                              gmt[2],gmt[3],\
                                                              gmt[4],gmt[5],subStr)
        self.year = gmt[0]
        self.month = gmt[1]
        self.day = gmt[2]
        self.hour = gmt[3]
        self.min = gmt[4]
        self.sec = gmt[5]
        self.subsec = self.lst[1]/10e5

        self.len = self.lst[2]
            
        #print self.SCET_Str

    def write(self,file):
        self.data.tofile(file)
        
    
class LVO(object):
    """
    """
    LABELSIZE=20  #20 octets
    FORMAT="!4s4c4s8s"
    FORMATB="!4s4c4s2i"
    
    def __init__(self,bin):
        self.data=0
        self.amount=0
        
        #print "FMT SIZE 1: %d 2: %d" % \
        #      (struct.calcsize(LVO.FORMAT),struct.calcsize(LVO.FORMATB))
        
        self.lst = struct.unpack(LVO.FORMAT,bin)
        
        if self.lst[3] == 'B':
            self.lst = struct.unpack(LVO.FORMATB,bin)
            self.size = long(self.lst[6])<<32 | self.lst[7]
        else:
            self.size = 1

    def hasMore(self):
        """When we have read structure object VALUE size from input
        return 0
        """
        if self.amount < self.size:
            return 1
        else:
            return 0

    def addToAmount(self,size):
        self.amount = self.amount + size
        

    def decodeData(self,byteSwap=1):
        """Decode the TM packets from the LVO.
        Return a list of TM packets.
        """


        dtaSize = len(self.data)
        if dtaSize<18:
            print "input data size too small"
            sys.exit(-2)

        #print "String size:" + str(dtaSize)

        ret = []
        ptr = 0
        while ptr < dtaSize:
            packet = TmPacket(self.data[ptr:ptr+18])
            ptr = ptr + 18
            packet.data = array.array('H',self.data[ptr:ptr+(packet.len)])

            if byteSwap:
                packet.data.byteswap()
            
            #print "packet data:%d" % len(packet.data)
            ptr = ptr + packet.len
            ret.append(packet)
        return ret
            

    def decodeAndWrite(self,out,verbose,byteSwap=1):
        """Decode the TM packets from the LVO.
        write them to file
        """


        dtaSize = len(self.data)
        if dtaSize<18:
            print "input data size too small"
            sys.exit(-2)

        #print "String size:" + str(dtaSize)

        ptr = 0
        while ptr < dtaSize:
            packet = TmPacket(self.data[ptr:ptr+18])
            ptr = ptr + 18
            packet.data = array.array('H',self.data[ptr:ptr+(packet.len)])

            if byteSwap:
                packet.data.byteswap()
            
            #print "packet data:%d" % len(packet.data)
            ptr = ptr + packet.len
            if verbose:
                print packet.SCET_Str
            packet.write(out)
            

        
    def isStructure(self):
        if self.lst[2] in ('Z','F','U'):
            return 1
        else:
            return 0

    def isData(self):
        if self.lst[2] in ('I','S','D','K','V'):
            return 1
        else:
            return 0

    def isApplicationData(self):
        if self.lst[2] == 'I': return 1
        else: return 0



class LVOReader(object):
    """
    """

    def __init__(self,file,dir,byteSwap=1):
        self.dir=dir
        self.file = file

        if file[-1]=="Z":
                #self.f = open(file,"rb")
                zipobj = zipfile.ZipFile(file,"r")
                self.f = ZippedSfdu( zipobj.read( zipobj.namelist()[0] ))
                #self.f = zipfile.ZipFile(file,"r")
        else:
                self.f = open(file,"rb")

        self.base = os.path.basename(file)
        self.outFile = os.path.join(self.dir,self.base.rstrip('.sfduZ')+".tlm")
        self.out = open(self.outFile,"wb")
        self.verbose=0

    def __del__(self):
        self.f.close()
        self.out.close()


    def readLABEL(self):
        bin=self.f.read(LVO.LABELSIZE)

        if len(bin) != LVO.LABELSIZE:
            raise EndOfInput, "EOF"
        return bin

    def readLVO(self,Stru=None):
        wrdSize = 2 #two bytes

        #self.f.seek(-2,2)

        bin=self.readLABEL()
        obj = LVO(bin)

        if obj.isStructure():
            while obj.hasMore():
                self.readLVO(obj)

            if Stru != None: Stru.addToAmount(LVO.LABELSIZE+obj.size)


        if obj.isData():
            if obj.size != 1:
                #print obj.lst
                obj.data = self.f.read(obj.size)

                if len(obj.data) != obj.size:
                    raise EndOfInput, "Not enough data in file, cal.size:%d , is:%d)" % (obj.size,len(obj.data))

                Stru.addToAmount(LVO.LABELSIZE+obj.size)
            else:
                obj.data = self.f.read()
                Stru.addToAmount(LVO.LABELSIZE+len(obj.data))
                #It's larger than 1 (the size of LVO is 1 if 'read to EOF' info)

            if obj.isApplicationData():
                #packets = obj.decodeData(byteSwap)
                #for item in packets:
                #    item.write(self.out)
                obj.decodeAndWrite(self.out,self.verbose,byteSwap)
                

        #print "What to do next ? " + str(obj.lst)

    def summary(self):
        print "wrote "+self.outFile

    def setVerbose(self,verbose):
        self.verbose=verbose
        
        
def usage(name):
    print name+" [-d <dir>] [-N] [-v] <SFDU FILE>"
    print """
    -d <dir> write file to this directory
    -N Don't byteswap the output data
    -v be verbose

    The output files will be named with a .tlm extension.

    Copyright (C) 2003 Swedish Institute of Space Physics
    Leif Kalla (Leif.Kalla@irf.se)

    Zipfile extension by Tuukka Sales/Finnish Meteorological Insititute
    (Tuukka.Sales@fmi.fi) (2004)

    This is free software
    """



if __name__ == "__main__":

    try:

        args = sys.argv[1:]
        #Default is to byteswap packet data, since our EGSE handles
        #little ENDIAN byteordered packet data
        byteSwap=1
        verbose=0
        outDir=""

        opt, par = getopt.getopt(args,'Nd:hsv')

        ##Get options
        for mopt in opt:
            if mopt[0] == '-N':
                byteSwap=0
            elif mopt[0] == '-h':
                usage(sys.argv[0])
                sys.exit(0)
            elif mopt[0] == '-d':
                outDir = mopt[1]
            elif mopt[0] == '-v':
                verbose=1


        for item in par:
            lvor = LVOReader(item,outDir,byteSwap)
            lvor.setVerbose(verbose)
            lvor.readLVO()
            lvor.summary()

    except getopt.GetoptError, e:
        # print help information and exit:
        print e.args
        usage(sys.argv[0])
        sys.exit(2)

    except EndOfInput, e:
        print e.args

    except EOFError, e:
        print e.args
    except Exception, e:
        print e.args
Document Actions