Adding Your Own Handler
Creating The Handler
Before adding your own handler to the code you must know where does your handler will be placed in the chain, is it before silicon clustering? maybe after the main strip hit calculation? understanding the place will help you know which data you'll be filtering or processing.
Here is a quick recipe for adding your own handler to the process:
- The code will be added to the project TBCommon
- The handler is a class implementing EventHandler virtual functions:
- void HandleEvent(Event *event,quint16 nFile = 0): This method will be called on every new event extracted from the file, for now lets ignore the nFile parameter.
- void FinalizeHandling() : This method will be called after we finished reading the data file.
- By knowing the difference between this two method one can design his\hers handler in 2 operating ways:
- Event-By-Event processing: this type of handler will have it's main algorithm in the HandleEvent method, for each event come through him he will calculate something. For example: Main strip hit, this handler is calculating the main hit by fitting a gaus through the strip hits, this calculation will be made for every event.
- Full Data processing: this type of handler will only store the data given him by HandleEvent method but will do his actual calculation at FinalizeHandling due to his need in the full data provided from the run
Now lets add a handler that will correct the code according to the alignment data, hence a
CalibrationHandler
class CalibrationHandler: public EventHandler
{
public:
CalibrationHandler();
virtual void HandleEvent(Event *event,quint16 nFile = 0);
virtual void FinalizeHandling();
private:
TH1F* m_CalibHist;
};
The
Event class is just a prototype for an event data, the data we'll be working with will be in the form of
AnalogEvent so once receiving the data in
HandleEvent we have to convert it:
void CalibrationHandler::HandleEvent(Event* event, quint16 nFile)
{
AnalogEvnet* aEvent = (AnalogEvent*)event;
...
Lets say we want to go all over the sTGC data and shift the y coord of the hit in 1
CalibrationHandler::CalibrationHandler() : EventHandler("CalibrationHandler")
{
}
void CalibrationHandler::HandleEvent(Event* event, quint16 nFile)
{
AnalogEvent* aEvent = (AnalogEvent*)event;
QList<quint8> stgcKeys = aEvent->STGCData()->keys();
foreach(quint8 ID,stgcKeys)
{
aEvent->STGCData()->value(ID)->MainHit.y += 1;
}
}
Maybe once we finished processing the data we want to display a hist with some data about the file. We know that the
FinalizeHandling method will be called at the end so
void CalibrationHandler::FinalizeHandling()
{
TQtWidget* wid = new TQtWidget(0,"Calibration");
wid->resize(700,500);
wid->show();
wid->GetCanvas()->cd();
m_CalibHist->Draw();
}
Configuring The Handler
The handler can read a parameter from the XML file, for example the handler the filters out event with not enough strip hit will read it's threshold from the file by calling:
SufficientStripHit::SufficientStripHit() : EventHandler("SufficientStripHit")
{
m_nPoints = MetaDataManager::Instance().GetHandlerValue("SufficientStripHit");
}
Of course this will work only if we add the following line to
config.xml file in TBCommon dir
<Handlers>
<Handler name="SufficientStripHit" value="3" active="true"/>
</Handlers>
The
active value will determine if the handler will be activated during the run (gives us some freedom while running)
If we want to filter the event we simply do:
aEvent->SetValid(false);
This will guarantee us the event will not continue after this handler.
Adding The Handler To The Flow
After building our handler we just need to add him to the flow. We do that by adding him in the
InitHandlers method found at the
OfflineManager, project
TestBeamOffline
MainHitAnalysis* mainHit = new MainHitAnalysis();
CalibrationHandler* calibHandler = new CalibrationHandler();
//Organization of the data flow to the handlers (analyzers & data modification)
EventDataManager::Instance().AddHandler(mainHit);
EventDataManager::Instance().AddHandler(calibHandler);
In this example we have only two handlers, the
MainHit &
CalibrationHandler so the event will go to
MainHit first, then to the
CalibHandler second. We need to pay attention since we have certain handlers for the alignment process (aka Calibration at the code) and handlers for the calibrated data. We noticed this in the initialization of the handlers:
void OfflineManager::InitHandlers()
{
EventDataManager::Instance().DeleteHandlers();
if ( true == m_ShouldCalibrate )
{
//Here will be handlers the will calculate the alignment parameters that will be used by the "CalibrationHandler" while the actual run
}
else
{
MainHitAnalysis* mainHit = new MainHitAnalysis();
CalibrationHandler* calibHandler = new CalibrationHandler();
//Organization of the data flow to the handlers (analyzers & data modification)
EventDataManager::Instance().AddHandler(mainHit);
EventDataManager::Instance().AddHandler(calibHandler);
}
}
--
HadarCohen - 13 Apr 2014