-
Notifications
You must be signed in to change notification settings - Fork 7
Add A New Detector Processor
This page will describe the process for adding a new Processor to the analysis. In principle, you can add a Processor to handle specific detector types, or to handle those that already exist.
To add a new detector first a class must be constructed which defines its behavior by creating a .hpp and .cpp file. For example, the following section defines a new detector class called "Template". We will break down the header and source separately.
##Header ####Doxygen Documentation We use doxygen to document the software. This four line comment gives the name of the file, a brief description, the author and the date that it was originally written.
/** \file TemplateProcessor.hpp
* \brief A Template class to be used to build others.
* \author S. V. Paulauskas
* \date October 26, 2014
*/
####Include Guards The include guards should have the form displayed here. It's the name of the file/class with two underscores framing it.
#ifndef __TEMPLATEPROCESSOR_HPP__
#define __TEMPLATEPROCESSOR_HPP__
####Local Includes Since the template processor is derived from EventProcessor we will need to include the parent class header. We get away from having to include the vector header since the EventProcessor already includes it.
#include "EventProcessor.hpp"
####More Doxygen comments This provides a little bit more targeted description of the class.
//! A generic processor to be used as a template for others
This is the beginning of the class definition. The colon (:) tells us that this processor is derived from the EventProcessor
.
class TemplateProcessor : public EventProcessor {
####Public methods Public methods should always be listed first since they are what people will need to know about when using the class.
public:
####Default Constructor The default constructor is called when instancing the class.
/** Default Constructor */
TemplateProcessor();
####Constructor w/ argument This constructor can be used to set private variables to user defined values.
/** Constructor Accepting an argument */
TemplateProcessor(const double & a);
####Default Destructor Here is where you put things that need to be cleaned up when the processor is destroyed.
/** Default Destructor */
~TemplateProcessor(){};
####Declare Plots This method will be used to declare all of the plots necessary for the processor
/** Declares the plots for the processor */
virtual void DeclarePlots(void);
####PreProcess This method handles any processing of the signals from this detector that does not depend on any other detector class. For example, with a DSSD this method would calculate the pixel that was activated.
/** Performs the preprocessing, which cannot depend on other processors
* \param [in] event : the event to process
* \return true if preprocessing was successful
*/
virtual bool PreProcess(RawEvent &event);
####Process This method handles any processing of the signals that may depend on other detectors but has no thresholds, cuts or other restrictions put on the histograms. For example, histogramming of the ToF with VANDLE bars.
/** Performs the main processsing, which may depend on other processors
* \param [in] event : the event to process
* \return true if processing was successful
*/
virtual bool Process(RawEvent &event);
####Get Methods The get methods are used by the experiment processors to obtain information calculated in the preprocess stage. In our simple example we'll not do anything too fancy. For other detectors this may actually be useful (e.x. VandleProcessor).
/** \return The processed Template events */
const std::vector<ChanEvent*> * GetTemplateEvents(void) const {
return(&evts_);
}
####Private methods and variables The private methods and variables always come last, they are things that people generally will not be needing to use.
private:
std::vector<ChanEvent*> evts_;
####Close of the class declaration. };
####Close of the include guard
The comment is included to remind us what the #endif
is associated with.
#endif // __TEMPLATEPROCESSOR_HPP__
##Source File Here is the associated source file for the TemplateProcessor. Let's look at this a little more in depth. ####Doxygen Headed This is similar to the one that we had in the header file just with the file name changed.
/** \file TemplateProcessor.cpp
*\brief A Template processor class that can be used to build your own.
*\author S. V. Paulauskas
*\date October 26, 2014
*/
####System Includes The system includes are those that are included with angle brackets. They should be listed in alphabetical order, and come before the local includes.
#include <iostream>
####Local Includes We have the local includes here that were not necessary in the main header file. They should be listed in alphabetical order.
#include "DammPlotIds.hpp"
#include "Globals.hpp"
#include "RawEvent.hpp"
#include "TemplateProcessor.hpp"
####Namespace declaration We declare the namespace that will be used for the
namespace dammIds {
namespace experiment {
const int D_ENERGY = 0; //!< ID for the energy of the template detector
const int DD_TEMPLATE_VS_PULSER = 1; //!< Energy Template vs. Energy Pulser
}
}//namespace dammIds
using namespace std;
using namespace dammIds::experiment;
TemplateProcessor::TemplateProcessor():
EventProcessor(OFFSET, RANGE, "TemplateProcessor") {
associatedTypes.insert("template");
}
TemplateProcessor::TemplateProcessor(const double &a):
EventProcessor(OFFSET, RANGE, "TemplateProcessor") {
associatedTypes.insert("template");
a_ = a;
}
void TemplateProcessor::DeclarePlots(void) {
DeclareHistogram1D(D_ENERGY, SA, "Energy");
DeclareHistogram2D(DD_TEMPLATE_VS_PULSER, SA, SA,
"Template Energy vs. Pulser Energy");
}
bool TemplateProcessor::PreProcess(RawEvent &event) {
if (!EventProcessor::PreProcess(event))
return(false);
static const vector<ChanEvent*> & evts_ =
event.GetSummary("template")->GetList();
for(vector<ChanEvent*>::const_iterator it = evts_.begin();
it != evts_.end(); it++) {
unsigned int location = (*it)->GetChanID().GetLocation();
if(location == 0)
plot(D_ENERGY, (*it)->GetEnergy()*a);
}
return(true);
}
bool TemplateProcessor::Process(RawEvent &event) {
if (!EventProcessor::Process(event))
return(false);
static const vector<ChanEvent*> & pulserEvents =
event.GetSummary("pulser")->GetList();
for(vector<ChanEvent*>::const_iterator it = evts_.begin();
it != evts_.end(); it++) {
unsigned int loc = (*it)->GetChanID().GetLocation();
for(vector<ChanEvent*>::const_iterator itA = pulserEvents.begin();
itA != pulserEvents.end(); itA++) {
if(loc == 0)
plot(DD_TEMPLATE_VS_PULSER, (*it)->GetEnergy(),
(*itA)->GetEnergy());
}
}
return(true);
}
Pixie Acquisition and Analysis Software Suite