Commit dd802685 authored by Marco Clemencic's avatar Marco Clemencic
Browse files

v10r2

parent 4f163aab
// $Id: SelectionLine.h,v 1.2 2010-01-18 15:44:53 graven Exp $
#ifndef SELECTION_LINE_H
#define SELECTION_LINE_H 1
// Include files
// from Gaudi
#include "Kernel/IANNSvc.h"
#include "GaudiKernel/IIncidentListener.h"
#include "GaudiAlg/GaudiHistoAlg.h"
#include "boost/array.hpp"
// Forward declarations
class StatEntity;
class ISequencerTimerTool;
class Algorithm;
class IJobOptionsSvc;
class IAlgManager;
/** @class Line Line.h
* Sequencer for (Hlt) processing, adapted from GaudiSequencer,
* but more specific...
*
* @author Gerhard Raven
* @date 2008-09-13
*/
namespace Selection {
class Line : public GaudiHistoAlg
, virtual public IIncidentListener
{
public:
/// Standard constructor
Line( const std::string& name, ISvcLocator* pSvcLocator );
virtual ~Line( ); ///< Destructor
virtual StatusCode initialize(); ///< Algorithm initialization
virtual StatusCode execute (); ///< Algorithm execution
void handle(const Incident&);
void resetExecuted(); ///< Called before an event processing
// id for this line -- return 0 if error
virtual std::pair<std::string,unsigned int> id() const = 0;
// @TODO/FIXME: for now, just use inheritance to force _some_
// implementation -- should be done smarter
// retrieve numberOfCandidates from subalgo
virtual unsigned int numberOfCandidates(const Algorithm*) const = 0;
// retrieve numberOfCandidates from decision algo
virtual unsigned int numberOfCandidates() const = 0;
class Stage {
public:
Stage(Line& parent, const std::string& name)
: m_parent(parent)
, m_timerTool(0)
, m_algorithm(0)
, m_property(name, std::string())
, m_reverse(false)
, m_dirty(true)
, m_initialized(false)
{ m_property.declareUpdateHandler(&Stage::updateHandler,this); }
Stage( Stage& rhs )
: m_parent(rhs.m_parent)
, m_timerTool(rhs.m_timerTool)
, m_algorithm(0)
, m_property( rhs.m_property )
, m_reverse(false)
, m_dirty(true)
, m_initialized(false)
{ m_property.declareUpdateHandler(&Stage::updateHandler,this); }
~Stage() { if (m_algorithm) m_algorithm->release();}; ///< Destructor
bool passed() const { return algorithm()?algorithm()->filterPassed():true; }
StatusCode execute(ISequencerTimerTool* = 0);
StatusCode initialize(ISequencerTimerTool* = 0);
std::string toString() const { return name(); }
StatusCode fromString(const std::string& name);
const std::string& name() const { return m_property.value(); }
void resetExecuted() const { if (algorithm()) algorithm()->resetExecuted(); }
StringProperty& property() { return m_property; }
private:
void setTimer( int nb ) { m_timer = nb; }
Algorithm* algorithm() const { return m_algorithm; }
bool reverse() const { return m_reverse; }
int timer() const { return m_timer; }
void updateHandler(Property& prop);
Line& m_parent;
ISequencerTimerTool* m_timerTool; ///< Pointer to the timer tool
Algorithm* m_algorithm; ///< Algorithm pointer
StringProperty m_property;
bool m_reverse; ///< Indicates that the flag has to be inverted
bool m_dirty;
bool m_initialized;
int m_timer; ///< Timer number fo rthis algorithm
};
protected:
// utilities for derived classes to use...
const std::string& decisionName() { return m_decision; }
// retrieve (recursive!) list of sub algorithms
std::vector< const Algorithm* > algorithms() const ;
IANNSvc& annSvc() const;
private:
//TODO: move into DecReport...
enum stage { initial= 0, // i.e. did not pass 'prescale
prescaled = 1, // i.e. did not pass 'seed'
odin = 2, // i.e. did not pass 'filter0'
l0du = 3, // i.e. did not pass 'filter1'
hlt = 4, // i.e. did not pass 'filter2'
filter1ed = 5, // i.e. did not pass 'filter3'
filter2ed = 6, // i.e. did not pass 'postscale'
postscaled = 7 ,
nStages = postscaled };
const std::string& transition( const stage &s) const {
static std::vector<std::string> s_map;
if (s_map.empty()) {
s_map.push_back("Prescale");
s_map.push_back("ODIN");
s_map.push_back("L0DU");
s_map.push_back("HLT");
s_map.push_back("Filter0");
s_map.push_back("Filter1");
s_map.push_back("Postscale");
}
return s_map[s];
};
typedef std::vector<std::pair<const Algorithm*,unsigned> > SubAlgos;
SubAlgos retrieveSubAlgorithms() const;
/** Decode a vector of string. */
StatusCode decodeNames( );
Algorithm* getSubAlgorithm(const std::string& name);
/** Private copy, assignment operator. This is not allowed **/
Line( const Line& a );
Line& operator=( const Line& a );
boost::array<Stage*,nStages> m_stages; ///< List of algorithms to process.
SubAlgos m_subAlgo; ///< list of subalgorithms and their sub-count
ISequencerTimerTool* m_timerTool; ///< Pointer to the timer tool
IJobOptionsSvc* m_jos; ///< Pointer to job options service
IAlgManager* m_algMgr; ///< Pointer to algorithm manager
AIDA::IHistogram1D* m_errorHisto;
AIDA::IHistogram1D *m_timeHisto;
AIDA::IHistogram1D *m_stepHisto;
AIDA::IProfile1D *m_candHisto;
mutable IANNSvc *m_hltANNSvc;
StatEntity *m_acceptCounter;
StatEntity *m_errorCounter;
StatEntity *m_slowCounter;
std::string m_outputContainerName;
std::string m_decision;
std::string s_ANNSvc;
std::vector<std::string> m_incidents; ///< Incidents to be flagged in HltDecReport if they occurs during processing
bool m_ignoreFilter; ///< True if one continues always.
bool m_measureTime; ///< Flag to measure time
bool m_returnOK; ///< Forces the sequencer to return a good status
bool m_acceptOnError; ///< Forces accept if error
bool m_acceptOnIncident; ///< Forces accept if incident
bool m_acceptIfSlow; ///< Forces accept if event is slow
bool m_caughtIncident;
int m_timer; ///< Timer number for the sequencer
int m_maxAcceptOnError; ///< quota to avoid runaway accepts in case of persistent errors..
int m_nAcceptOnError;
unsigned m_slowThreshold;
};
}
#endif // Line_H
#$Id: requirements,v 1.5 2010-02-27 09:08:43 graven Exp $
#============================================================================
# Created : 2010-01-18
# Maintainer : Gerhard Raven
#============================================================================
package SelectionLine
version v1r0p1
# Structure
#============================================================================
branches cmt doc src Kernel
include_path none
# Used packages
#============================================================================
use Boost v* LCG_Interfaces
use Python v* LCG_Interfaces
use AIDA v* LCG_Interfaces
use HltInterfaces v* Kernel
use HltEvent v* Event
use GaudiKernel v*
use GaudiAlg v*
use GaudiUtils v*
#============================================================================
# Component library building rule
#============================================================================
library SelectionLine ../src/*.cpp
#============================================================================
# define component library link options
#============================================================================
apply_pattern linker_library library=SelectionLine
# =============================================================================
# ======= the patterns ========================================================
apply_pattern install_more_includes more=Kernel
#macro HltLineUserModules "HltConf.HltLinesConfigurableUser"
#apply_pattern install_python_modules
## needed because of the use of Aida2Root
private
macro_append ROOT_linkopts " -lHist " WIN32 " libHist.lib"
! $Id: release.notes,v 1.4 2010-02-27 09:08:24 graven Exp $
! -----------------------------------------------------------------------------
! Package : Phys/SelectionLine
! Responsible : Gerhard Raven
! Purpose : Infrastructure for HLT and stripping 'lines'
! -----------------------------------------------------------------------------
!======================= SelectionLine v1r0p1 2010-02-27 =====================
! 2010-02-27 - Gerhard Raven
- shorten histogram names
!======================= SelectionLine v1r0 2010-01-29 =====================
! 2010-01-18 - Gerhard Raven
- initial import of code adapted from Hlt/HltLine, together with
HltBase/HltHistogramUtilities (the latter is here for dependency reasons
only, and should be moved 'further' down in the dependency stack)
- reshuffle a bit.. (Line.{h,cpp} -> SelectionLine.{h,cpp}, move SelectionLine.h
into Kernel)
#include "HistogramUtilities.h"
#include "GaudiUtils/Aida2ROOT.h"
// ============================================================================
// ROOT
// ============================================================================
#include "TH1D.h"
#include "TH2D.h"
#include "TProfile.h"
namespace {
template <typename R, typename A>
bool setAxisLabels_( A* aida, const std::string& xAxis, const std::string& yAxis ) {
if (aida==0) return false;
R *root = Gaudi::Utils::Aida2ROOT::aida2root( aida );
if (root==0) return false;
root->SetXTitle(xAxis.c_str());
root->SetYTitle(yAxis.c_str());
return true;
}
bool setBinLabels_( TAxis* axis, const std::vector<std::pair<unsigned,std::string> >& labels ) {
if (axis==0) return false;
unsigned nbins = axis->GetNbins();
for (std::vector<std::pair<unsigned,std::string> >::const_iterator i = labels.begin();i!=labels.end();++i ) {
//TODO: check bin exists...
if (1+i->first <= 0 || 1+i->first > nbins ) return false;
// Argh... ROOT bins start counting at '1' instead of '0'
axis -> SetBinLabel(1 + i->first ,i->second.c_str() );
}
return true;
}
template <typename R, typename A>
bool setBinLabels_( A* aida, const std::vector<std::pair<unsigned,std::string> >& labels ) {
if (aida==0) return false;
R *root = Gaudi::Utils::Aida2ROOT::aida2root( aida );
if (root==0) return false;
return setBinLabels_( root->GetXaxis(), labels );
}
template <typename Histogram>
bool setBinLabels_( Histogram* hist, const std::vector<std::string>& labels ) {
std::vector<std::pair<unsigned,std::string> > l;
for (unsigned i = 0;i<labels.size();++i) l.push_back(std::make_pair( i , labels[i] ) );
return HistogramUtilities::setBinLabels(hist,l);
}
};
namespace HistogramUtilities {
bool setBinLabels( AIDA::IHistogram1D* hist, const std::vector<std::pair<unsigned,std::string> >& labels ) {
return setBinLabels_<TH1D>(hist,labels);
}
bool setBinLabels( AIDA::IProfile1D* hist, const std::vector<std::pair<unsigned,std::string> >& labels ) {
return setBinLabels_<TProfile>(hist, labels);
}
bool setBinLabels( AIDA::IHistogram1D* hist, const std::vector<std::string>& labels ) {
return setBinLabels_(hist,labels);
}
bool setBinLabels( AIDA::IProfile1D* hist, const std::vector<std::string>& labels ) {
return setBinLabels_(hist,labels);
}
bool setBinLabels( AIDA::IHistogram2D* hist, const std::vector<std::string>& xlabels,
const std::vector<std::string>& ylabels) {
if (hist==0) return false;
std::vector<std::pair<unsigned,std::string> > lx;
for (unsigned i = 0;i<xlabels.size();++i) {
lx.push_back(std::make_pair( i , xlabels[i] ) );
}
std::vector<std::pair<unsigned,std::string> > ly;
for (unsigned i = 0;i<ylabels.size();++i) {
ly.push_back(std::make_pair( i , ylabels[i] ) );
}
TH2D *h2d = Gaudi::Utils::Aida2ROOT::aida2root( hist );
if (h2d==0) return false;
return setBinLabels_( h2d->GetXaxis(), lx) && setBinLabels_( h2d->GetYaxis(), ly );
}
bool setAxisLabels( AIDA::IHistogram1D* hist, const std::string & xAxis,const std::string & yAxis ) {
return setAxisLabels_<TH1D>( hist, xAxis, yAxis );
}
bool setAxisLabels( AIDA::IProfile1D* hist, const std::string & xAxis,const std::string & yAxis ) {
return setAxisLabels_<TProfile>( hist, xAxis, yAxis );
}
#if 0
bool shiftBinsLeft( AIDA::IProfile1D* profile ) {
if (profile==0) return false;
TProfile *prof = Gaudi::Utils::Aida2ROOT::aida2root( profile );
if (prof==0) return false;
}
#endif
};
#include <vector>
#include <string>
#include <utility>
namespace AIDA {
class IHistogram1D;
class IHistogram2D;
class IProfile1D;
};
namespace HistogramUtilities {
bool setBinLabels( AIDA::IHistogram1D* hist, const std::vector<std::string>& labels ) ;
bool setBinLabels( AIDA::IProfile1D* hist, const std::vector<std::string>& labels ) ;
bool setBinLabels( AIDA::IHistogram1D* hist, const std::vector<std::pair<unsigned,std::string> >& labels ) ;
bool setBinLabels( AIDA::IProfile1D* hist, const std::vector<std::pair<unsigned,std::string> >& labels ) ;
bool setBinLabels( AIDA::IHistogram2D* hist, const std::vector<std::string>& xlabels,
const std::vector<std::string>& ylabels) ;
bool setAxisLabels( AIDA::IHistogram1D* hist, const std::string & xAxis,const std::string & yAxis ) ;
bool setAxisLabels( AIDA::IProfile1D* prof, const std::string & xAxis,const std::string & yAxis ) ;
};
// $Id: SelectionLine.cpp,v 1.3 2010-02-27 09:08:24 graven Exp $
// ============================================================================
// Include files
// ============================================================================
#include <cmath>
#include <vector>
#include <iterator>
// ============================================================================
// Boost
// ============================================================================
#include "boost/foreach.hpp"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/construct.hpp"
// ============================================================================
// AIDA
// ============================================================================
#include "AIDA/IHistogram1D.h"
#include "AIDA/IProfile1D.h"
#include "AIDA/IHistogram.h"
#include "AIDA/IAxis.h"
// ============================================================================
// GaudiKernel
// ============================================================================
#include "GaudiKernel/StatusCode.h"
#include "GaudiKernel/StringKey.h"
#include "GaudiKernel/AlgFactory.h"
#include "GaudiKernel/IAlgManager.h"
#include "GaudiKernel/ListItem.h"
#include "GaudiKernel/IJobOptionsSvc.h"
#include "GaudiKernel/IAlgContextSvc.h"
#include "GaudiKernel/IIncidentSvc.h"
// ============================================================================
// GaudiAlg
// ============================================================================
#include "GaudiAlg/ISequencerTimerTool.h"
// ============================================================================
// HLT
// ============================================================================
#include "HistogramUtilities.h"
using namespace HistogramUtilities;
// ============================================================================
// HltEvent
// ============================================================================
#include "Event/HltDecReports.h"
// ============================================================================
// Local
// ============================================================================
#include "Kernel/SelectionLine.h"
// ============================================================================
//-----------------------------------------------------------------------------
// Implementation file for class : HltLine
//
// 2008-09-13 : Gerhard Raven
//-----------------------------------------------------------------------------
void
Selection::Line::Stage::updateHandler(Property&) {
if (!m_initialized) {
m_dirty=true;
return;
}
if (m_algorithm!=0) m_algorithm->release();
if (!m_property.value().empty()) {
m_algorithm = m_parent.getSubAlgorithm(m_property.value());
if (!m_algorithm) throw GaudiException( "could not obtain algorithm for " , m_property.value(), StatusCode::FAILURE);
m_algorithm->addRef();
}
m_dirty = false;
}
StatusCode
Selection::Line::Stage::initialize(ISequencerTimerTool* timer) {
m_initialized=true;
if ( m_dirty ) updateHandler(m_property);
// TODO: bind timer call...
if ( timer!=0 && algorithm()!=0 ) setTimer( timer->addTimer( algorithm()->name() ) );
// empty transition is allowed...
return algorithm()!=0 ? algorithm()->sysInitialize() : StatusCode::SUCCESS;
}
StatusCode
Selection::Line::Stage::execute(ISequencerTimerTool* timertool) {
assert(!m_dirty);
if (!algorithm() ) return StatusCode::SUCCESS;
if (!algorithm()->isEnabled() ) return StatusCode::SUCCESS;
if ( algorithm()->isExecuted()) return StatusCode::SUCCESS;
// TODO: bind timer at init time
if ( timertool ) timertool->start( timer() );
StatusCode result = StatusCode::FAILURE;
try {
result = algorithm()->sysExecute();
algorithm()->setExecuted( true );
} catch (...) { }
if ( timertool ) timertool->stop( timer() );
return result;
}
Selection::Line::SubAlgos
Selection::Line::retrieveSubAlgorithms() const {
typedef std::list<std::pair<const Algorithm*,unsigned> > SubAlgoList;
SubAlgoList subAlgo;
subAlgo.push_back( std::make_pair(this,0));
SubAlgoList::iterator i = subAlgo.begin();
while ( i != subAlgo.end() ) {
std::vector<Algorithm*> *subs = i->first->subAlgorithms();
if (!subs->empty()) {
unsigned depth = i->second+1;
SubAlgoList::iterator j = i;
++j;
for (std::vector<Algorithm*>::const_iterator k = subs->begin();k!=subs->end();++k)
subAlgo.insert(j, std::make_pair( *k, depth ) );
}
++i;
}
subAlgo.pop_front(); // remove ourselves...
debug() << " dumping sub algorithms: " << endmsg;
for (SubAlgoList::const_iterator i = subAlgo.begin(); i!= subAlgo.end();++i) {
debug() << std::string(3+3*i->second,' ') << i->first->name() << endmsg;
}
// transform map such that it has algo, # of sub(sub(sub()))algorightms
SubAlgos table;
for (SubAlgoList::const_iterator i = subAlgo.begin(); i!= subAlgo.end();++i) {
SubAlgoList::const_iterator j = i; ++j;
while ( j!=subAlgo.end() && j->second > i->second ) ++j;
table.push_back(std::make_pair( i->first, std::distance(i,j) ) );
}
return table;
}
IANNSvc& Selection::Line::annSvc() const {
if (m_hltANNSvc == 0) {
StatusCode sc = serviceLocator()->service(s_ANNSvc, m_hltANNSvc);
Assert( sc.isSuccess() && m_hltANNSvc != 0, " no ANNSvc??");
}
return *m_hltANNSvc;
}
//=============================================================================
// Standard constructor, initializes variables
//=============================================================================
Selection::Line::Line( const std::string& name,
ISvcLocator* pSvcLocator)
: GaudiHistoAlg ( name , pSvcLocator )
, m_timerTool( 0 )
, m_jos(0)
, m_algMgr(0)
, m_errorHisto(0)
, m_timeHisto(0)
, m_stepHisto(0)
, m_candHisto(0)
, m_hltANNSvc(0)
, m_acceptCounter(0)
, m_errorCounter(0)
, m_slowCounter(0)
, m_timer(0)
, m_nAcceptOnError(0)
{
for (unsigned i=0; i<m_stages.size(); ++i) {
m_stages[i] = new Stage(*this, transition(stage(i)));
declareProperty( m_stages[i]->property().name() , m_stages[i]->property() );
}
declareProperty( "HltDecReportsLocation", m_outputContainerName = LHCb::HltDecReportsLocation::Default );
//TODO: install updateHandler, refuse changes after initialize...
declareProperty( "DecisionName" , m_decision = name+"Decision");
declareProperty( "ANNSvc" , s_ANNSvc = "HltANNSvc");
declareProperty( "IgnoreFilterPassed" , m_ignoreFilter = false );
declareProperty( "MeasureTime" , m_measureTime = false );
declareProperty( "ReturnOK" , m_returnOK = false );
declareProperty( "AcceptOnError" , m_acceptOnError = true );
declareProperty( "AcceptOnIncident" , m_acceptOnIncident = true );
declareProperty( "AcceptIfSlow" , m_acceptIfSlow = false );
declareProperty( "MaxAcceptOnError" , m_maxAcceptOnError = -1 ); // -1: no quota # TODO: make this a throttelable rate...
declareProperty( "FlagAsSlowThreshold" , m_slowThreshold = 500000, "microseconds" );
declareProperty( "IncidentsToBeFlagged" , m_incidents);
}
//=============================================================================
// Destructor
//=============================================================================
Selection::Line::~Line() { };
//=============================================================================
// Initialisation. Check parameters
//=============================================================================
StatusCode Selection::Line::initialize() {
/// initialize the base:
StatusCode status = GaudiHistoAlg::initialize();
if ( !status.isSuccess() ) return status;
/// lock the context
Gaudi::Utils::AlgContext lock1 ( this , contextSvc() ) ;
debug() << "==> Initialize" << endreq;
m_jos = svc<IJobOptionsSvc>( "JobOptionsSvc" );
m_algMgr = svc<IAlgManager> ( "ApplicationMgr" );
// register for incidents...