next up previous contents
Next: Calibrator Up: The MINOS Off-line Software Previous: Registry   Contents


Raw Data and Rotorooter

Last significant change: 2002/10/14

General Principles

The RawData package primarily provides containers (classes derived from RawDataBlock) that encapsulate the raw data from the DAQ (data acquisition), DCS (detector control system) and beam monitoring systems. The basic unit is a block which consists of three required 32-bit words and a variable number of data words. A copy of the packed data, including the header words, is held by the base class. The RawDataBlock supplies some methods common to all blocks. In particular one can retrieve the size of the block and read-only access to the packed data. This encapsulation supports the principle that once a block is generated from the constructor it should not be modified. Based on the block id the data may be wrapped in a class deriving from RawDataBlock that specializes the access methods. These access methods encapsulate the knowledge neccessary for unpacking specific blocks. Additionally the package provides a block identification class, a electronics channel identifier class, a specialized record class and record headers, and support classes for elements unpacked out of specific blocks.

The Rotorooter package provides the interface for DAQ, DCS and beam monitoring systems which generate raw blocks in a C (or C-like) non-Object-Oriented environment to convert them into objects and write them out in the offline framework format. To minimize the coupling between the offline and online components the information is transmitted from the online to the rotorooter via sockets. The online code interfaces to a series of C functions; the rotorooter turns the collections of blocks, sent to it as a group, into objects and creates a offline record to hold them. The record can be persisted (Chapter 13). There are also C functions for the online code to call to open and close files and configure parameters of the rotorooter.

Details of the RawDataBlock

Figure 11.1: Basic RawDataBlock layout

The basic RawDataBlock provides basic read-only access to the unadulterated data. The reported size is a self inclusive count of 32-bit words; the raw data is treated as a array of 32-bit integers when moved between platforms of different architectures. All RawDataBlocks support the methods:

   const Int_t* GetData() const; // as array of 32bit words 
         Int_t  GetSize() const; 
         Int_t  GetChecksum() const; 
         Bool_t TestChecksum() const; 
     RawBlockId GetBlockId() const;

Specialized blocks derive from RawDataBlock and supply the specific methods for unpacking a particular block. A block is primarily designated by the major id as decribed in Section 11.3 on RawBlockId.

The details of the block layout may evolve over time and thus the upacking may have to handle (generally minor) differences. Which version of the unpacking to use is encoded into each instance of a block by the minor id portion of the block id.

Details of the RawBlockId

The RawBlockId has fields that identify the minor version number, the major block number, online source, detector, and a compacted simulation flag.

Figure 11.2: RawBlockId layout
\includegraphics[scale=0.60]{rawblockid.eps} Compact simulation flag csf: (0=Data, 1=DaqFake, 2=MC, 3=Reroot)
Detector bits: CalDet, Far, Near
Data source S: 0=DAQ, 1=DCS

The major id numbers for DAQ and DCS (which includes beam monitoring in a logical sense) are independent. Major id values must be less than $2^{16}$ or in the range [0$\dots$65535]; minor version numbers can range from 0 to 255. Minor version numbers should be changed every time the layout of a block is modified or interpretation of any word or field in the block is changed. This is critical if the specialized RawDataBlock is to reliably be able to handle unpacking in all cases.

The connection between class type and major block id is made by a two lines of code in the derived class implementation file:

#include "RawData/RawBlockRegistry.h"

This second line is a cpp macro that expands into some helper code. There are no quotes around the ClassName in the cpp macro. The MajorId must be an integer value that fits in 16 bits and IsDCS is a boolean value (0 or 1). When the class is compiled and the code put into the shared library, then loading the library automatically generates a static object that registers the connection between the ClassName and the major id and DCS flag. This connection is necessary in order for the rotorooter to convert flat memory space into the correct RawDataBlock object.

The following code will generate a list of all known blocks and their ids:

#include "RawData/RawBlockRegistry.h" 
RawBlockRegistry& rbr = RawBlockRegistry::Instance();
cout << rbr;

Details of the RawChannelId

Operation of the rotorooter

Online code interface to the rotorooter

The interface code that online sources should use in communicating with the rotorooter is built into a static library (libRotorooterRotoTalk.a) as part of the offline code build procedure and can be found in lib/$SRT_SUBDIR/ relative to the release found at $SRT_PUBLIC_CONTEXT. The header file of prototypes rototalk.h is found in Rotorooter/RotoTalk/.

Connections to the rotorooter can be openned and closed using:

int  roto_open_DCP_connection(const char* host);
int  roto_open_DCS_connection(const char* host);
int  roto_close_connection();
Note: There may be a need for an additional function, i.e. roto_open_BM_connection(const char* host), if the DCS and beam monitoring are going to have their individual receivers on the same host. Currently DCP is assigned port 9011 and DCS to port 9012.

The DAQ (DCP) can have multiple files open simultaneously as the rotorooter knows how to route individual records to the appropriate file based on the run & subrun numbers. The DCS runs in a mode that is independent of the start and stopping of runs by the DAQ; DCS files are tagged by the time passed to the rotorooter and only one file can be open at any one time.

int  roto_open_daqfile(int detector, int run, int subrun);
int  roto_close_daqfile(int detector, int run, int subrun);
int  roto_open_dcsfile(int detector, int sec, int nanosec);
int  roto_close_dcsfile();
The detector value is all cases one of: Near=1, Far=2, CalDet=4.

Data is send to the rotorooter as a flat buffer and a byte count.

int  roto_send_record(const void* buffer, int nbytes);
The sent buffer can contain any number of contiguous packed blocks in the form described in Section 11.2. These will be collected into a single RawRecord and output to a TTree in the root file.

Figure 11.3: Record buffer layout
\includegraphics[scale=0.75]{rawrecord.eps} Example record of three blocks; each block leads with a 32-bit word of the inclusive word count.

Each sent buffer must contain one block that is used to create the record header: one of RawDaqHeaderBlock (0x200) RawSnarlHeaderBlock (0x101) for the DAQ, or RawDcsHeaderBlock (0x001) for DCS.

Finally, the rotorooter can be configured using:

int  roto_send_autosave_config(const char* stream, unsigned int nrec, unsigned int nsec);
int  roto_send_compress_config(const char* stream, int level);
int  roto_send_basketsize_config(const char* stream, int basketsize);

int  roto_request_shutdown(int priority);

next up previous contents
Next: Calibrator Up: The MINOS Off-line Software Previous: Registry   Contents
MINOS Software 2017-10-29