![]() | ![]() | ![]() | Editing the Readout Skeleton | ![]() |
In this section we are only going to look at the most basic use of the Readout Skeleton. For more complete documentation of the readout program, see:
http://docs.nscl.msu.edu/daq/ProductionReadout/ManualThe minimal modifications you need to make to the readout skeleton is:
In addition if your application requires that scalers be read out during the run, you will have to:
Take a moment to examine Skeleton.cpp. While it contains a sample class definition of an event segment:
class MySegment : public CEventSegment { public: virtual void Initialize() {} virtual void Clear() {} virtual unsigned int MaxSize() { return 10; } virtual DAQWordBufferPtr& Read(DAQWordBufferPtr& rBuf) { for(int i =0; i < 10; i++) { *rBuf = i; ++rBuf; } return rBuf; } };
and while this segment is later registered as an event segment as shown below:
void CMyExperiment::SetupReadout(CExperiment& rExperiment) { CReadoutMain::SetupReadout(rExperiment); // Insert your code below this comment. /* >>>DELETE THIS LINE<<<< */ rExperiment.AddEventSegment(new MySegment); }
Please do not extend this but treat it as a self contained example and remove the line indicated in Example 3 above.
You will have a much better structured program if you create a separate pair of files, a header and an implementation, of your event segment class. Create a file called MyEventSegment.h and edit it to contain the text shown below:
#ifndef __MYEVENTSEGMENT_H #define __MYEVENTSEGMENT_H #include <spectrodaq.h> #include <CEventSegment.h> #include <CDocumentedPacket.h> /*! You should put a comment here that describes what this event segment does. Make this as descriptive as possible.. no fair using the text: "This call defines my event segment" Nobody will know what that means. */ class MyEventSegment : public CEventSegment { private: // Put any member data you need here. CDocumentedPacket m_MyPacket; //!< Put data in a documented packet. public: MyEventSegment(unsigned short id); virtual void Initialize(); virtual void Clear(); virtual unsigned int MaxSize(); virtual DAQWordBufferPtr& Read(DAQWordBufferPtr& rBuf); }; #endif // __MYEVENTSEGMENT_H
This file defines a class named MyEventSegment. MyEventSegment inherits all of the properties of a CEventSegment. That inheritance makes it eligible to be registered to be called by the readout software in response to triggers. Instances of this class that are registered with the readout program will be called at the member functions declared in example.
The m_MyPacket data member will be used to put our data into a documented packet. A documented packet is a well structured piece of event data. Documentation buffers in the event stream also list the set of documented buffers that may have been put into the event stream.
The table below describes the resposibilities of each entry point in an event segment.
Function | When/Why called |
Initialize | When runs start before the first event. |
Clear | After an event to clear hardware. |
Read | After an event trigger to read out an event. |
In order to provide concrete code, we will assume that you are creating an event segment that will read out an experiment into a top level tagged packet. We'll assume further that the experiment must readout a Phillips TDC (7186)and a Phillips peak sensing ADC (7164). We assume that the time channels are read in zero suppressed mode and the unsupressed time channels select which corresponding channels of the peak sensing ADC will be read. We will produce events with the following internal format (the skeleton will prepend our event with an all encompassing word count:
The top level packet will have a packet size word, the id of the packet, and sub packets for each TDC channel that had a valid conversion. Each sub packet will have the same basic structure: A word count that is self inclusive, an id, which in this case is the channel number of the tdc, and the TDC, and ADC conversion values read from the hardware. While for this small example, there's quite a bit of overhead, for larger systems, this sort of self-describing data structure can be very useful.
We start implementing our event segment by creating a file named MyEventSegment.cpp with the contents shown below:
/* Your code should have a comment here describing what the file is for. It's also a good idea to add comments indicating who wrote this thing and when....an even better idea to have a change log that indicates the major revisions the file has undergone in its lifetime. */ #include "MyEventSegment.h" // include your class header.
We now must implement each of the member functions in the class:
![]() | ![]() | ![]() | Editing the Readout Skeleton | ![]() |