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.
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.
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:
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. 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
.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. unpack
unpack
sends the complete structure ParsedEVB to the CSweeperUnpacker function Unpack
.Unpack
gives SweeperEvent back to unpack
, which then returns this structure to the user. 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):
/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. unpack
function and the structure SweeperEvent, the analysis code must include the header files Sweeper.h and SweeperEvent.h.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:
This substructure contains information about the focal-plane ion chamber
This substructure contains information about the energy from each crystal in the hodoscope.
This substructure contains information about the energy from the segmented target.
This structure contains information from the multi-hit Mesytech MTDC-32. This module was included in 2015 to replace the old Phillips TDC.
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 |
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.
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:
This is an obsolete substructure containing time information from the Phillips TDC (currently discontinued)