#include "GaudiKernel/Algorithm.h"
#include "GaudiKernel/SmartDataPtr.h"
#include "Event/Recon/CalRecon/CalCluster.h"
#include "Event/Recon/CalRecon/CalEventEnergy.h"
#include "Event/TopLevel/EventModel.h"
#include "IEnergyCorr.h"
/**
* @class CalEnergyAlg
*
* @brief An algorithm for controlling and applying the various energy correction tools
* used to determine the final event energy for GLAST
*
* $Header: /nfs/slac/g/glast/ground/cvs/CalRecon/src/CalEnergyAlg.h,v 0.1 2005/04/11 13:28:50 chamont Exp $
*/
class CalEnergyAlg : public Algorithm
{
public:
//! constructor
CalEnergyAlg( const std::string & name, ISvcLocator * pSvcLocator );
//! destructor
virtual ~CalEnergyAlg()
{
m_corrTools.clear();
};
virtual StatusCode initialize();
StatusCode execute();
StatusCode finalize() ;
private:
//! correction tool names
StringArrayProperty m_corrToolNames ;
//! correction tools
std::vector<IEnergyCorr*> m_corrTools ;
//! Type of correction for primary corrected parameters
unsigned int m_corrType;
//! Set status bits depending on which iteration of algorithm
unsigned int m_passBits;
} ;
#include "GaudiKernel/DeclareFactoryEntries.h"
DECLARE_ALGORITHM_FACTORY(CalEnergyAlg) ;
CalEnergyAlg::CalEnergyAlg( const std::string & name, ISvcLocator * pSvcLocator )
: Algorithm(name,pSvcLocator)
{
std::vector<std::string> corrToolVec;
unsigned int corrType;
// Initial/default parameters depend on whether this would be the first pass
// through CalRecon or the second. The first pass through should have the
// algorithm name "RawEnergy" assigned to it, the second (or subsequent) name
// doesn't matter for initialization.
// This branch if first pass
if (name == "RawEnergy")
{
corrToolVec.push_back("CalRawEnergyTool");
corrType = Event::CalCorToolResult::RAWENERGY;
m_passBits = Event::CalEventEnergy::PASS_ONE;
}
// This the default for the second iteration of CalRecon
else
{
corrToolVec.push_back("LastLayerCorrTool");
corrToolVec.push_back("ProfileTool");
corrToolVec.push_back("CalValsCorrTool");
corrToolVec.push_back("CalTkrLikelihoodTool");
corrToolVec.push_back("CalTransvOffsetTool");
corrType = Event::CalCorToolResult::CALVALS;
m_passBits = Event::CalEventEnergy::PASS_TWO;
}
// Declare the properties with these defaults
declareProperty("corrToolNames", m_corrToolNames = corrToolVec);
declareProperty("finalCorrType", m_corrType = corrType);
}
StatusCode CalEnergyAlg::initialize()
{
// Purpose and Method: Initialize the algorithm:
// - Initializes the vector of pointers to the various
// energy correction tools to all for this particular
// iteration of reconstruction
MsgStream log(msgSvc(), name());
StatusCode sc = StatusCode::SUCCESS;
// Basic initialization first
log << MSG::INFO << "CalEnergyAlg Initialization";
if( (sc = setProperties()).isFailure())
{
log << " didn't work!" << endreq;
return sc;
}
log << endreq;
// Now build the list of correction tools to apply during execution
const std::vector< std::string >& corrToolNames = m_corrToolNames ;
std::vector< std::string >::const_iterator toolName ;
IEnergyCorr* tool ;
for (toolName = corrToolNames.begin(); toolName != corrToolNames.end(); toolName++)
{
// Attempt to retrieve the tool
sc = toolSvc()->retrieveTool(*toolName,tool);
// Did we fail to find the tool?
if (sc.isFailure() )
{
log << MSG::ERROR << " Unable to create " << *toolName << endreq ;
return sc ;
}
// Otherwise add to our list
else
{
m_corrTools.push_back(tool) ;
}
}
return sc;
}
StatusCode CalEnergyAlg::execute()
{
//Purpose and method: Primary driver for running the various energy correction tools
// Also creates and registers the output TDS object for the Event Energy
// and retrieves the "best" energy as the one to use this event.
//
// TDS input: CalClusterCol
// TDS output: CalEventEnergy (with a vector of CalCorToolResult objects for each tool run)
//
MsgStream log(msgSvc(), name());
StatusCode sc = StatusCode::SUCCESS;
log<<MSG::DEBUG<<"Begin"<<endreq ;
// Retrieve our TDS objects, we use Clusters to output corrected energy in CalEventEnergy
Event::CalClusterCol* calClusters = SmartDataPtr<Event::CalClusterCol>(eventSvc(),EventModel::CalRecon::CalClusterCol);
Event::CalEventEnergy* calEnergy = SmartDataPtr<Event::CalEventEnergy>(eventSvc(),EventModel::CalRecon::CalEventEnergy);
// If no CalEnergy object (yet) then create one and register in TDS
if (calEnergy == 0)
{
calEnergy = new Event::CalEventEnergy();
if ((eventSvc()->registerObject(EventModel::CalRecon::CalEventEnergy, calEnergy)).isFailure())
{
log<<MSG::ERROR<<"Cannot register CalEventEnergy"<<endreq ;
return StatusCode::FAILURE ;
}
}
// No clusters no work
if (calClusters != 0)
{
// apply corrections according to vector of tools
int itool = 0 ;
std::vector<IEnergyCorr *>::const_iterator tool ;
for ( tool = m_corrTools.begin(); tool != m_corrTools.end(); ++tool, ++itool )
{
log<<MSG::DEBUG<<"Correction "<<itool<<endreq ;
(*tool)->doEnergyCorr(calClusters->front());
}
// Set the pass number bits
calEnergy->setStatusBit(m_passBits);
// Go through and pick the "best" energy
// For now this consists of choosing the value from CalValsCorrTool
// It is envisaged that this will be replaced by a call to a tool/method which examines all
// possibilites and chooses the best for the given event
for(Event::CalCorToolResultCol::iterator corIter = calEnergy->begin(); corIter != calEnergy->end(); corIter++)
{
Event::CalCorToolResult* corResult = *corIter;
if ((corResult->getStatusBits() & m_corrType) == m_corrType)
{
// Set the main energy parameters to the selected correction tool values
// Should also be setting a bit in CalEventEnergy to describe this?
calEnergy->setParams(corResult->getParams());
break;
}
}
}
log<<MSG::DEBUG<<"End"<<endreq ;
return sc;
}
StatusCode CalEnergyAlg::finalize()
{
return StatusCode::SUCCESS ;
}
|