Classes | Modules
Event User Interface
Collaboration diagram for Event User Interface:

Classes

class  evt::ComponentGroup< Component >
 Common class for groups of components of the Event hierarchy. More...
 
class  evt::Event
 
class  evt::Header
 Global event header. More...
 

Modules

 Shower
 
 Surface Event
 
 Fluorescence Event
 
 User Data
 

Detailed Description

Introduction

The Event interface provides the machinery for storing and retrieving event information, including simulated, reconstructed and raw data acquisition quantities. As such, the event interface constitutes the mechanism for communicating information from one physics module to the next.The interface comprises a collection of classes organized with the hierarchy one normally associates with the detector instruments, together with parallel stuctures for holding :

The figure below provides a non-exhaustive illustration of this hierarcy.
eventDescription.jpg
As a simple example, one could retrieve a reference to PMT 1 of station 157 as follows:

// assume theEvent is a reference to the
// top of the evt::Event hierarchy
PMT& pmt1 = theEvent.GetSEvent().GetStation(157).GetPMT(1);

Using the Event: objects vs. references

Proper use of functions in the Event interface requires understanding the difference between returning an object and returning a reference to an object. Briefly, return by reference provides handles into existing Event data structures, while returning objects themselves provides a separate copy, detached from the Event data structures. Here is an example, using the sevt::PMT::GetFADCTrace function, which returns a container of FADC data for an SD phototube:

// pmt1 is reference to an sevt::PMT
utl::TraceI t = pmt1.GetFADCTrace(); // returns the Trace object
cout << pmt.GetFADCTrace()[300]; // suppose it prints 50
t[300] = 60; // this assigns a value to local copy of the TraceI
cout << pmt.GetFADCTrace()[300]; // therefore, this still prints 50 (not 60)

In the example above, a copy of a utl::TraceI object is returned from the event, so making the assignment t[300]=60 does not alter the evt::Event contents. In contrast, consider this code:

TraceI& t = pmt.GetFADCTrace(); // returns a reference to the Trace object
cout << pmt.GetFADCTrace()[300]; // suppose this prints fifty
t[300] = 60; // this assigns a value to local copy of the TraceI
cout << pmt.GetFADCTrace()[300]; // now this prints 60.

In this case, the return-by-reference in the first line provides a handle into the utl::TraceI object, allowing us to alter the trace in the evt::Event. In short, if you are attempting to change the values stored within data structures in the event, you must use return-by-reference semantics.Most Event functions also provide an option to return a const reference. For example, the sevt::PMT interface contains a function const utl::TraceI& GetFADCTrace(..arguments..). This provides access to the FADC information (by reference), but disallows changing it. Using reference semantics is more efficient than returning an object since no copying is required, and should therefore be used in cases where you only want to read pre-existing data.Iterators over evt::Event components are also provided in both const and non-const versions. If you need to change the value of an object being iterated over, you must use the non-const form. If you are just reading information, the const form is safer.

Component types and protocols

The subcomponents of evt::Event can be categorized in four types:

As the name suggests, Always-existing components always exist, without the need for any physics module to create them. Always-existing include the Event headers. Such components have access method, but no methods to create them or check for their existence (since they are created automatically). For example:

evt::Header& h = theEvent.GetHeader();
Optional components are only present if they are explicitly created by a physics module. Such objects are accompanied by three methods, one to check their existence, one to create them, and one to retrieve them, according to the following pattern:

// retrieve the object
// Object& GetObject( ) throw (NonExistentObjectException)
// make the object
// void MakeObject()
// check whether the object exists
// bool HasObject()

We'll refer to this as the Get/Make/Has protocol. As a specific example of an optional component, consider the Monte Carlo truth belonging to an sevt::PMT.

// myPMT is a reference to some PMT
sevt::PMT& pmtSim = myPMT.GetSimData(); // fails with an exception since SimData not yet created
if (!myPMT.HasSimData()) { // check for existing sim data
myPMT.MakeSimData(); // create sim data if it doesn't already exist
}
sevt::PMT& pmtSim = myPMT.GetSimData(); // success

This Get/Make/Has protocol is used by physics modules to check for the presence or absence of components, determine if the required processing has been done at various stages of computation, and create components when appropriate.Enumerated components are Event components which exist in multiple instances, such as components representing Stations, Telescopes, PMTs, pixels and so forth. The Get/Make/Has protocol described above is used with enumerated components by specifying a component index as an argument to the Get/Make/Has method:

// theSEvent is a reference to an sevt::SEvent
int id = 799;
if (!theSEvent.HasStation(id))
theSEvent.MakeStation(id);
processStation(theSEvent.GetStation(id)); // processStation takes Station& argument

Existing enumerated components can also be accessed by iterators. For example:

for (sevt::SEvent::StationIterator sIt = theSEvent.StationsBegin() ;
sIt != theSEvent.StationsEnd(); ++sIt) {
processStation(*sit);
}

Use of iterators is the preferred method for accessing existing enumerated components. The reason is that use of the iterators helps to avoid failures due to inadvertent requests for non-existing components.Finally, MultiTrace components are used to hold collections of traces each of which is labeled by the source generating the trace. For instance, in a Monte Carlo simulation of the SD, one can store separate FADC traces for the electron, muon and photon components of a total trace. Such components can be accessed by explicitly specifying an enumeration representing the trace source, or by using iterators to step through all available sources:

// access to a trace explicitly by source name
utl::TraceD vt = theStation.GetVEMTrace(); // empty argument returns total trace
utl::TraceD vtPh = theStation.GetVEMTrace(Station::ePhoton); // trace coming from photons alone
// access all sources in the MultiTrace using an iterator
for (sevt::Station::VEMTraceIterator vIt = theStation.VEMTracesBegin() ;
vIt != theStation.VEMTracesEnd(); ++vIt) {
utl::TraceD t = vIt->GetTrace(); // returns the trace itself
int component = vIt->GetLabel(); // identifies the source of the trace (electron, muon, photon, etc.)
}

Access to the raw DAS events

write me

, generated on Tue Sep 26 2023.