User Tools

Site Tools


pre-unpacker

The Sweeper Pre-unpacker

The purpose of the Sweeper Pre-unpacker is to “translate” the data format from the Sweeper EVB into a more intuitive format reflecting the physical variables measured in a experiment. In simple terms, the Pre-unpacker “receives” a pointer pointing to the fragment payload (fragment body) of the first fragment processed by the Sweeper EVB; reads and parses the data stream; and returns a C++ structure (SweeperEvent) which contains the physical (uncalibrated) variables to be analyzed. The beauty of this approach is that the user doesn't have to know the details about the data format from the Sweeper DAQ electronics (CCUSB and VMUSB controllers). Instead, all she/he has to do is reading the variables contained in the Pre-unpacker structure SweeperEvent (e.g. time, energy,…), calibrate them, and use them to calculate the physical quantities relevant for the analysis.

How the Sweeper Pre-unpacker works

In this section, we describe the Sweeper Pre-unpacker in some detail. The casual user can skip this part and go directly to the next section describing how to use the Pre-Unpacker.

The complete code described in this section is encoded in the library libSweeperUnpacker.so which can be used by the user to unpack data from the Sweeper. In this way, the whole unpacking sequence is a black-box for the user. The Sweeper Pre-unpacker functions are enclosed under the namespace Sweeper. The pre-unpacking is done in two steps: (1) data from the Sweeper EVB are parsed and re-organized in the C++ structure ParsedEVB containing substructures encoding data from different electronic modules (e.g. Phillips 71xx ADC, Mesytec MTDC-32, etc.); (2) data from the structure ParsedEVB are re-organized into detector-related sub-structures contained in the structure SweeperEvent. Thus, the back-bone of the Pre-unpacker are the structures ParsedEVB and SweeperEvent. Note that the later is the only part of the whole Pre-unpacker that is relevant for the user.

The functionality of the Pre-unpacker is schematically illustrated in the figure below.

Schematic representation of libSweeperUnpacker

The whole Pre-unpacker package is coded in three main files: Sweeper.cpp; CSweeperParser.cpp; and CSweeperUnpacker.cpp. The data parsing/unpacking sequence is described below:

  • The function unpack, establishes the communication between the parsing and unpacking stages described above. This function receives two pointers, pBegin and pEnd. As illustrated in the data diagram, the former points to the fragment body of the first fragment, whereas the later points to the end of fragment.
  • The function unpack passes the pointers pBegin and pEnd to the CSweeperParser function parse. This function uses the NSCLDAQ class FragmentIndex to iterate through the two fragments from the Sweeper EVB. For each fragment, a pointer pBody pointing to the body of the ring item encoded in the fragment is created and sent to the CSweeperParser function parseData.
  • The function parseData goes through the body data and searches for tags identifying the data from each module (see data diagram). Whenever a tag is found, parseData sends the pointer pBody to a specific function designed to decode data from a given module. As an example, when parseData finds the tag 0x0DDC, it will call the function DecodeMTDC to parse the data from the Mesytec MTDC module containing time information. Once parsed, the time values from different detectors will be contained in a substructure (mtdc) of the structure ParsedEVB.
  • This sequence will be repeated for each fragment (one from CCUSB and the other from VMUSB). At the end, the structure ParsedEVB will contain all the information from the different electronic modules of the Sweeper Magnet. This structure is then sent back to the function unpack
  • The function unpack sends the complete structure ParsedEVB to the CSweeperUnpacker function Unpack.
  • This function calls specific functions to pack the data from ParsedEVB into the detector substructures contained in the structure SweeperEvent. After filling all these substructures, Unpack gives SweeperEvent back to unpack, which then returns this structure to the user.

Using the Sweeper Pre-unpacker

In order to include the Sweeper Pre-unpacker, the user needs to follow a series of steps (for more details, please contact the Sweeper Device Physicist Jorge Pereira (pereira@nscl.msu.edu) or DAQ expert Ron Fox (fox@nscl.msu.edu):

  • The analysis-software compiler must include the library libSweeperUnpacker.so along with some header files. Their current location (June 2017) is /user/sweeper/develop/unpacker/library/src, for libSweeperUnpacker.so, and /user/sweeper/develop/unpacker/library/inc and /user/sweeper/develop/unpacker/library/inc/Sweeper, for the header files.
  • In order to use the Sweeper unpack function and the structure SweeperEvent, the analysis code must include the header files Sweeper.h and SweeperEvent.h.
  • As described above, the user needs to provide two pointers (pBegin and pEnd) to the function unpack. pBegin points to the fragment body of the first fragment, and pEnd points to the end of the fragment. The function unpack will return a SweeperEvent structure containing all the unpacked information needed for the analysis. The example below shows how to use the Sweeper Pre-unpacker in SpecTcl. The processor CSweeperMapper was created to call the Pre-unpacker function Sweeper::unpack. This function returns the SweeperEvent-type structure event which contains all the detector-related substructures needed by the user.
#include <Sweeper.h>
#include <SweeperEvent.h>
 
#include <Event.h>
#include <EventProcessor.h>
#include <TCLAnalyzer.h>
#include <Globals.h>
 
Bool_t
CSweeperMapper::operator()(const Address_t pEvent, 
                                       CEvent&  rEvent, 
                                       CAnalyzer& rAnalyzer,	
                                       CBufferDecoder& rDecoder)
{
	CTclAnalyzer&      rAna((CTclAnalyzer&)rAnalyzer);	
        TranslatorPointer<UShort_t> p(*(rDecoder.getBufferTranslator()), pEvent);	
 
 
        // Here I define the pointers pBegin and pEnd needed by the unpack function
        UShort_t  *pBegin = (UShort_t*)pEvent;  //pBegin points to the fragment payload (fragment body) of the first fragment
        UShort_t  tWords = *p++; // Here I take the (self-inclusive) payload size
        UShort_t  *pEnd = pBegin + tWords; // pEnd points to the end of the fragment
 
        // At least one member of the pipeline must tell the analyzer how	
        // many bytes were in the raw event so it knows where to find the	
        // next event.	
        rAna.SetEventSize(tWords*sizeof(UShort_t));  // Set event size.	
 
 
        // Function Sweeper::unpack is called here. The function returns the SweeperEvent-type structure event
        Sweeper::SweeperEvent event = Sweeper::unpack(pBegin, pEnd);
}

In the above example, all the unpacked data are encoded in the structure event (type SweeperEvent). Thus, all that the user needs to do is to handle the variables (organized in sub-structures) provided in the event structure. The list of SweeperEvent sub-structures and corresponding variables are described below:

Substructure fpic

This substructure contains information about the focal-plane ion chamber

  • fpic.hasdata (bool): logic variable which is TRUE when the structure contains valid data
  • fpic.raw[0-15] (uint16_t): energy array (Phillips 7164 ADC module) from each of the 16 detector pads

Substructure hodo

This substructure contains information about the energy from each crystal in the hodoscope.

  • hodo.hasdata (bool): logic variable which is TRUE when the structure contains valid data
  • hodo.raw[0-24] (uint16_t): energy array (Mesytec MADC-32) from each of the 25 crystals

Substructure segta

This substructure contains information about the energy from the segmented target.

  • segta.hasdata (bool): logic variable which is TRUE when the structure contains valid data
  • segta.data[0-31] (uint16_t): energy array (Mesytec MADC-32) from each of the channels in the segmented-target

Substructure mtdc

This structure contains information from the multi-hit Mesytech MTDC-32. This module was included in 2015 to replace the old Phillips TDC.

  • mtdc.hasdata (bool): logic variable which is TRUE when the structure contains valid data
  • hits[0-31] (uint16_t): array with number of “hits” for each channel
  • raw[0-31] (uint16_t): array with time of first hit of each channel
  • data[0-31][maximum number-of-hits=31] (uint16_t): array with times for each hit and channel

In the current configuration (May 2017) the channel assignment is given by:

Channel Source
0 FP Thin SCI Left, Up (Sweeper trigger)
1 FP Thin SCI Left, Down
2 FP Thin SCI Right, Up
3 FP Thin SCI Right, Down
4 Free
5 RF
6 Pot SCI
7 XF SCI
8 FP Thin SCI Left, Up (Sweeper trigger)
9-10 Free
11 Time stamp from L3 module
12-14 Free
15 FP Thin SCI Left, Up (Sweeper trigger)
16-31 Free

Substructure crdc1 and crdc2

  • crdc1(2).hasdata (bool): logic variable which is TRUE when the structure for crdc1 (or 2) contains valid data
  • crdc1(2).anode (uint16_t): energy (Phillips 7164 ADC) from the detector anode
  • crdc1(2).tac (uint16_t): time (Ortec 456 TAC + Phillips 7164 ADC) from the detector anode
  • crdc1(2).m_sampleBegin (uint16_t): First sample number from last read pad
  • crdc1(2).m_sampleWidth (uint16_t): Sample width from last read pad
  • crdc1(2).m_data[number-of-pads=112][number-of-samples] (uint16_t): energy array for each pad and sample number

Substructure fpsci

This substructure contains energy and time information about the scintillators included in the Sweeper setup: Pot, XF, FP Thin, and FP Thick. Note that since the Phillips TDC was removed from the sweeper electronics (and replaced by the MTDC), the time information in this substructure is no longer available.

  • fpsci.hasdatathin (bool): logic variable which is TRUE when the structure contains valid data for the Thin scintillator
  • fpsci.thin_de_lu (uint16_t): energy (FERA module) from the FP thin left-up PMT
  • fpsci.thin_de_ld (uint16_t): energy (FERA module) from the FP thin left-down PMT
  • fpsci.thin_de_ru (uint16_t): energy (FERA module) from the FP thin right-up PMT
  • fpsci.thin_de_rd (uint16_t): energy (FERA module) from the FP thin right-down PMT
  • fpsci.thin_t_lu (uint16_t): time (Phillips TDC module) from the FP thin left-up PMT
  • fpsci.thin_t_ld (uint16_t): time (Phillips TDC module) from the FP thin left-down PMT
  • fpsci.thin_t_ru (uint16_t): time (Phillips TDC module) from the FP thin right-up PMT
  • fpsci.thin_t_rd (uint16_t): time (Phillips TDC module) from the FP thin right-down PMT
  • fpsci.hasdatathick (bool): logic variable which is TRUE when the structure contains valid data for the Thick scintillator. Note that this detector is currently not included
  • fpsci.thick_de_lu (uint16_t): energy (FERA module) from the FP thick left-up PMT
  • fpsci.thick_de_ld (uint16_t): energy (FERA module) from the FP thick left-down PMT
  • fpsci.thick_de_ru (uint16_t): energy (FERA module) from the FP thick right-up PMT
  • fpsci.thick_de_rd (uint16_t): energy (FERA module) from the FP thick right-down PMT
  • fpsci.thick_t_lu (uint16_t): time (Phillips TDC module) from the FP thick left-up PMT
  • fpsci.thick_t_ld (uint16_t): time (Phillips TDC module) from the FP thick left-down PMT
  • fpsci.thick_t_ru (uint16_t): time (Phillips TDC module) from the FP thick right-up PMT
  • fpsci.thick_t_rd (uint16_t): time (Phillips TDC module) from the FP thick right-down PMT
  • fpsci.pote (uint16_t): energy (FERA module) from the Pot scintillator

Substructure trigger (obsolete)

We could consider that this is an obsolete structure containing the bit pattern from the ULM module, and times for each trigger signal. Note that in general, these times are not included in the electronics, since the only trigger signal relevant for the Sweeper Magnet is “ext 2”. The variables included in this structure are:

  • trigger.hasdata (bool): logic variable which is TRUE when the structure contains valid data
  • trigger.registr (uint16_t): a 16-bit work with the bit pattern from the ULM
  • trigger.sweeper (uint16_t): the time (from the Phillips TDC) for the trigger source from sweeper (not connected)
  • trigger.external1 (uint16_t): the time (the Phillips TDC) from the trigger source from external 1 (not connected)
  • trigger.external2 (uint16_t): the time (the Phillips TDC) from the trigger source from external 2 (from L3 trigger)
  • trigger.secondary (uint16_t): the time (the Phillips TDC) from the trigger source from secondary (not connected)

Substructure tof (obsolete)

This is an obsolete substructure containing time information from the Phillips TDC (currently discontinued)

  • tof.hasdata (bool): logic variable which is TRUE when the structure contains valid data
  • tof.xfp (uint16_t): time (Phillips TDC) from A1900 XF scintillator
  • tof.rf (uint16_t): time (Phillips TDC)from RF signal
  • tof.pot (uint16_t): time (Phillips TDC) from Pot scintillator
pre-unpacker.txt · Last modified: 2017/06/26 13:24 by pereira