Variable Length Decoder
Previous  Top  Next

Oftentimes the data is not formatted at fixed boundaries but 'variable length'. The following decoder gives an example of how to deal with this kind of data. Here we get a block called Event that contains 8 spins with time-of-flight data. The spins variable length and 'packed' in the Events TOFData item. The length of the following spin is indicated in the word preceding the spin data. Our job is to 'walk' the linked list of spin data fields, and copy the data from the source block into the TOFSpin destination block. Below are the definitions of the Event source block and the TOFSpin destination block. If you plan to install this example please load the Dec2.blk block definition file by entering it in the gseos.ini file in the Config/BlkFiles section. Run the dec2.py sample decoder to install the decoder.


*       =======================================================================
*       Event Data Blocks
*       =======================================================================
Event {
        (Data[6008]    ,,, 8;)
         Met           ,,,32;
         SpinVern      ,,, 8;
         TOFData[3000] ,,,16;
         Cksum         ,,, 8;
      }


TOFSpin {
          Cnt[8]       ,,,16;
          DataSp0[260] ,,,16;
          DataSp1[260] ,,,16;
          DataSp2[260] ,,,16;
          DataSp3[260] ,,,16;
          DataSp4[260] ,,,16;
          DataSp5[260] ,,,16;
          DataSp6[260] ,,,16;
          DataSp7[260] ,,,16;
        }

The following decoder script gets a local copy of the destination data items for quicker access during decoder runtime. It takes advantage of the naming of the items in the TOFSpin block and loops over the dictionary extracting the items by name. It then defines the decoder function fDecEvent and registers it for the Event block. As you can see it is not necessary to create a temporary decoder object which you then append to the decoder list of the Event block. Instead you can simply pass the result of the constructor into the append function directly.


#
# Decode Event Data
# The Event Data consists of 8 spins with variable length data. Each spins
# data is prepended with a count indicating the length of the following data
# field. Walk the list of spins and extract the event count and event data
# for every spin and assign it to the appropriate items of the TOFSpin Block.
#
from __main__ import Event, TOFSpin
import GseosDecoder

#
#
# Get the SpinData items from the TOFSpin block. Instead of assigning
# one array item at a time we loop over the items accessing the
# dictionary directly.
#
SpinData = []
for wSpin in range(8):
  SpinData.append(TOFSpin.__dict__['DataSp'+str(wSpin)])


def fDecEvent(Event):
  "TOF Event Decoder"
  wLengthPos = 0

  #
  #  Loop over all spins, extract the length of the following spin, and
  #  copy the spin data. The advance to the next spin.
  #
  for wSpin in range(8):
    wSpinLen = Event.TOFData[wLengthPos]
    TOFSpin.Cnt[wSpin] = wSpinLen

    #
    #  Get the spin data
    #
    wPos = wLengthPos+1
    SpinData[wSpin][:wSpinLen] = Event.TOFData[wPos:wPos+wSpinLen]

    wLengthPos = wPos + wSpinLen
  #
  #  Now we have filled in all our spins, ship the block to the system.
  #
  TOFSpin.SendBlock()

#
# Hook the decoder on arrivals of Event blocks.
# Don't bother creating a temporary decoder object.
#
Event.Decoders.append(GseosDecoder.TDecoder('TOF Event Decoder', fDecEvent, [TOFSpin]))