Skip to content

Refactor Event ownership, event level processing and add LoLXTTreeWriter

Jolie Roiseux requested to merge feature/customizable-writer-class into develop

Description

Event Ownership

Each processor now takes an Event in the constructor instead of passing the Event to the processEvent() method. The Event is a shared_ptr in order to properly manage shared ownership and deleting of the Event to avoid memory leaks. Each processor (derived from IEventProcessor or for readers, DataFile) stores the shared_ptr as mEvent. The base class (IEventProcessor) does not contain the mEvent variable in order to allow different event types to be stored based on the specific requirements for the each case.

Event Types

Specialized Event types such as LoLXEvent can be created by inheriting from the Event class. The reader that uses this event type must take it as a parameter. Initialize event to the correct type such as event = std::make_shared<LoLXEvent>(); in RunManager::createReader and cast the event to the desired type before creating the DataFile using std::dynamic_pointer_cast such as in V1740Factory.cxx.

Event Level Processing

Event level processing can take place on any type of Event. If the processing requires specific variables, it should take the correct event type that contains these variables such as LoLXEventProcessor takes a LoLXEvent. In RunManager::createEventLevelProcessor, cast event to the desired type using std::dynamic_pointer_cast and check that the cast was successful (if not successful, the result will be nullptr/0). If a user selects LOLX for the event processor strategy in the config file, but has not used V1740 as the device/reader, it will fail because the event was not created as a LoLXEvent. Pass the result of the cast to the processor constructor if it was successful.

TTreeWriter

When using an Event Level Processor or an event type that has more variables than the base Event class, create a new TTreeWriter derived class. For example, the LoLXTTreeWriter. Add a branch for each variable in the constructor and set the branch variables in pushEventVariables(). The specific writer should be constructed with a shared pointer of the correct event type as a parameter and store it as mEvent to be used in pushEventVariables(). In the PulseWriteProcessor constructor, specify the correct TTreeWriter to use based on the EventLevelProcessor selected. For the LoLXTTreeWriter example, if channelCfg.eventStrategy == "LOLX", then the writing strategy should be forced to be LoLXTTreeWriter. Since this writers takes std::shared_ptr<LoLXEvent>, the event must be cast to the correct type before creating the writer.

Testing

Testing LoLX specific functionality:

  • Use a config file that uses the V1740 reader(Device)
  • Make sure "EventProcessor": "LOLX", is in the ChannelConfigs and it is using TTreeWriter
  • Run ./bin/vanwftk <path to config file>
  • It should run without errors
  • The outputted TTree should contain multiplicity and firstPulseTime (if run without "EventProcessor": "LOLX", the TTree should not contain these variables)

Testing dynamic casting fails correctly:

  • Use a config file that uses a reader(Device) other than V1740 (e.g. experiments/example.json)
  • Add "EventProcessor": "LOLX", to the ChannelConfigs
  • Run ./bin/vanwftk <path to config file>
  • It should fail and output Cannot use LOLX event processor for this Event. Must use LoLXEvent (V1740).
Edited by Jolie Roiseux

Merge request reports