Last significant change: 2002/10/14
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.
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.
The RawBlockId has fields that identify the minor version number, the major block number, online source, detector, and a compacted simulation flag.
|
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
or
in the range [0
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"
REGISTERRAWBLOCK(ClassName,MajorId,IsDCS);
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;
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.
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);