Let's now make this into a full program which reads from a data file. In order to get written out to a data file, some more structure gets added to the event data. These additional structures are generally invisible to us (unless we debug the DAQ).The key to getting Event objects (and event data) is through the Eventiterators, which are objects themselves, and return to you either the next Event object or 0 if the stream of events is exhausted (for example, when you reach the end of a data file).
There are different kinds of Eventiterators, but they all have an extremely simple interface to get you the next Event object:
Eventiterator *it; // a pointer to the event iterator // ... some code to get the actual iterator object ... Event *evt = it->getNextEvent();Once you have the iterator, the only thing you can do (other than delete the the iterator object) is to ask for the next Event object. All decisions and configurations are done at the time when you create the object.
Since the Eventiterator will return 0 when no events are left, you will see this construct very often:
while ( evt = it->getNextEvent() ) { // ... do something with the Event object ... delete evt; // done, delete the object again. }for example with our "channel57" function from above:while ( evt = it->getNextEvent() ) { int i = channel57(evt); delete evt; // done, delete the object again. }Note, however, that not all types of Eventiterators will "become empty". There is a "testEventiterator" which makes up Event objects from scratch for testing purposes and will continue forever and never get empty, and another type, the "ddEventiterator" which reads online data from a "data distributor pool", will block and wait for more events to be injected into the pool. You should provide another exit from the while loop if you don't know what type of iterator you are reading from.
Here is now a full program which calls our "channel57" function. It can be found in the example directory.
#include <stdlib.h> #include <fileEventiterator.h> int main(int argc, char *argv[]) { if (argc < 2) { cout << "Usage: " << argv[0] << " filename" << endl; exit (1); } int status; Eventiterator * it = new fileEventiterator (argv[1], status); if (status) { cout << "Couldn't open input file " << argv[1] << endl; delete it; exit(1); } Event *evt; while ( evt = it->getNextEvent() ) { channel57(evt); delete evt; } }So we will create an object of class "fileEventiterator" with the filename which we pass to the main program on the command line, and read through all the events in that file. Note that there are several different constructors for a fileEventiterator; the one shown herefileEventiterator(const char *filename, int &status);which takes a file name and returns the status of the operation (0 means all ok) in the second parameter is the most commonly used one.So we run that application with a file that contains packets from the Emcal detector, and we get
>> ./channel57 /export/data1/dcm_data/emc/run_03006.dat | more Channel 57 is 3538 Channel 57 is 3532 Channel 57 is 3530 Channel 57 is 3538 Channel 57 is 3536 Channel 57 is 3534 Channel 57 is 3532 Channel 57 is 3537 Channel 57 is 3528 Channel 57 is 3544We just show a few lines of output here. It may be difficult to run this example, because you typically don't find that data file on your system. We will show a few more features and then switch to the "testEventiterator", which makes up Event data (and the objects) from scratch and will not need any particular data file.
Alphabetic index Hierarchy of classes