CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/CommonTools/TriggerUtils/src/GenericTriggerEventFlag.cc

Go to the documentation of this file.
00001 //
00002 // $Id: GenericTriggerEventFlag.cc,v 1.14 2012/10/04 20:26:10 vadler Exp $
00003 //
00004 
00005 
00006 #include "CommonTools/TriggerUtils/interface/GenericTriggerEventFlag.h"
00007 
00008 #include "FWCore/Framework/interface/ESHandle.h"
00009 #include "CondFormats/L1TObjects/interface/L1GtTriggerMenu.h"
00010 #include "CondFormats/DataRecord/interface/L1GtTriggerMenuRcd.h"
00011 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
00012 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerEvmReadoutRecord.h"
00013 #include "CondFormats/HLTObjects/interface/AlCaRecoTriggerBits.h"
00014 #include "DataFormats/L1GlobalTrigger/interface/L1GtLogicParser.h"
00015 
00016 #include <vector>
00017 
00018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00019 
00020 
00021 // Constants' definitions
00022 static const bool useL1EventSetup( true );
00023 static const bool useL1GtTriggerMenuLite( false );
00024 
00025 
00027 GenericTriggerEventFlag::GenericTriggerEventFlag( const edm::ParameterSet & config )
00028   : watchDB_( 0 )
00029   , hltConfigInit_( false )
00030   , andOr_( false )
00031   , dbLabel_( "" )
00032   , verbose_( 0 )
00033   , andOrDcs_( false )
00034   , errorReplyDcs_( false )
00035   , andOrGt_( false )
00036   , gtInputTag_( "" )
00037   , gtEvmInputTag_( "" )
00038   , gtDBKey_( "" )
00039   , errorReplyGt_( false )
00040   , andOrL1_( false )
00041   , l1BeforeMask_( true )
00042   , l1DBKey_( "" )
00043   , errorReplyL1_( false )
00044   , andOrHlt_( false )
00045   , hltDBKey_( "" )
00046   , errorReplyHlt_( false )
00047   , on_( true )
00048   , onDcs_( true )
00049   , onGt_( true )
00050   , onL1_( true )
00051   , onHlt_( true )
00052   , configError_( "CONFIG_ERROR" )
00053   , emptyKeyError_( "EMPTY_KEY_ERROR" )
00054 {
00055 
00056   // General switch(es)
00057   if ( config.exists( "andOr" ) ) {
00058     andOr_ = config.getParameter< bool >( "andOr" );
00059     if ( config.exists( "verbosityLevel" ) ) verbose_ = config.getParameter< unsigned >( "verbosityLevel" );
00060   } else {
00061     on_    = false;
00062     onDcs_ = false;
00063     onGt_  = false;
00064     onL1_  = false;
00065     onHlt_ = false;
00066   }
00067 
00068   if ( on_ ) {
00069     if ( config.exists( "andOrDcs" ) ) {
00070       andOrDcs_      = config.getParameter< bool >( "andOrDcs" );
00071       dcsInputTag_   = config.getParameter< edm::InputTag >( "dcsInputTag" );
00072       dcsPartitions_ = config.getParameter< std::vector< int > >( "dcsPartitions" );
00073       errorReplyDcs_ = config.getParameter< bool >( "errorReplyDcs" );
00074     } else {
00075       onDcs_ = false;
00076     }
00077     if ( config.exists( "andOrGt" ) ) {
00078       andOrGt_              = config.getParameter< bool >( "andOrGt" );
00079       gtInputTag_           = config.getParameter< edm::InputTag >( "gtInputTag" );
00080       gtLogicalExpressions_ = config.getParameter< std::vector< std::string > >( "gtStatusBits" );
00081       errorReplyGt_         = config.getParameter< bool >( "errorReplyGt" );
00082       if ( config.exists( "gtEvmInputTag" ) ) gtEvmInputTag_ = config.getParameter< edm::InputTag >( "gtEvmInputTag" );
00083       if ( config.exists( "gtDBKey" ) )       gtDBKey_       = config.getParameter< std::string >( "gtDBKey" );
00084     } else {
00085       onGt_ = false;
00086     }
00087     if ( config.exists( "andOrL1" ) ) {
00088       andOrL1_                   = config.getParameter< bool >( "andOrL1" );
00089       l1LogicalExpressionsCache_ = config.getParameter< std::vector< std::string > >( "l1Algorithms" );
00090       errorReplyL1_              = config.getParameter< bool >( "errorReplyL1" );
00091       if ( config.exists( "l1DBKey" ) )      l1DBKey_      = config.getParameter< std::string >( "l1DBKey" );
00092       if ( config.exists( "l1BeforeMask" ) ) l1BeforeMask_ = config.getParameter< bool >( "l1BeforeMask" );
00093     } else {
00094       onL1_ = false;
00095     }
00096     if ( config.exists( "andOrHlt" ) ) {
00097       andOrHlt_                   = config.getParameter< bool >( "andOrHlt" );
00098       hltInputTag_                = config.getParameter< edm::InputTag >( "hltInputTag" );
00099       hltLogicalExpressionsCache_ = config.getParameter< std::vector< std::string > >( "hltPaths" );
00100       errorReplyHlt_              = config.getParameter< bool >( "errorReplyHlt" );
00101       if ( config.exists( "hltDBKey" ) ) hltDBKey_ = config.getParameter< std::string >( "hltDBKey" );
00102     } else {
00103       onHlt_ = false;
00104     }
00105     if ( ! onDcs_ && ! onGt_ && ! onL1_ && ! onHlt_ ) on_ = false;
00106     else {
00107       if ( config.exists( "dbLabel" ) ) dbLabel_ = config.getParameter< std::string >( "dbLabel" );
00108       watchDB_ = new edm::ESWatcher< AlCaRecoTriggerBitsRcd >;
00109     }
00110   }
00111 
00112 }
00113 
00114 
00116 GenericTriggerEventFlag::~GenericTriggerEventFlag()
00117 {
00118 
00119   if ( on_ ) delete watchDB_;
00120 
00121 }
00122 
00123 
00125 void GenericTriggerEventFlag::initRun( const edm::Run & run, const edm::EventSetup & setup )
00126 {
00127 
00128   if ( watchDB_->check( setup ) ) {
00129     if ( onGt_ && gtDBKey_.size() > 0 ) {
00130       const std::vector< std::string > exprs( expressionsFromDB( gtDBKey_, setup ) );
00131       if ( exprs.empty() || exprs.at( 0 ) != configError_ ) gtLogicalExpressions_ = exprs;
00132     }
00133     if ( onL1_ && l1DBKey_.size() > 0 ) {
00134       const std::vector< std::string > exprs( expressionsFromDB( l1DBKey_, setup ) );
00135       if ( exprs.empty() || exprs.at( 0 ) != configError_ ) l1LogicalExpressionsCache_ = exprs;
00136     }
00137     if ( onHlt_ && hltDBKey_.size() > 0 ) {
00138       const std::vector< std::string > exprs( expressionsFromDB( hltDBKey_, setup ) );
00139       if ( exprs.empty() || exprs.at( 0 ) != configError_ ) hltLogicalExpressionsCache_ = exprs;
00140     }
00141   }
00142 
00143   // Re-initialise starting valuse before wild-card expansion
00144   l1LogicalExpressions_  = l1LogicalExpressionsCache_;
00145   hltLogicalExpressions_ = hltLogicalExpressionsCache_;
00146 
00147   hltConfigInit_ = false;
00148   if ( onHlt_ ) {
00149     if ( hltInputTag_.process().size() == 0 ) {
00150       if ( verbose_ > 0 ) edm::LogError( "GenericTriggerEventFlag" ) << "HLT TriggerResults InputTag \"" << hltInputTag_.encode() << "\" specifies no process";
00151     } else {
00152       bool hltChanged( false );
00153       if ( ! hltConfig_.init( run, setup, hltInputTag_.process(), hltChanged ) ) {
00154         if ( verbose_ > 0 ) edm::LogError( "GenericTriggerEventFlag" ) << "HLT config initialization error with process name \"" << hltInputTag_.process() << "\"";
00155       } else if ( hltConfig_.size() <= 0 ) {
00156         if ( verbose_ > 0 ) edm::LogError( "GenericTriggerEventFlag" ) << "HLT config size error";
00157       } else hltConfigInit_ = true;
00158     }
00159   }
00160 
00161   // Expand version wild-cards in HLT logical expressions
00162   // L1
00163   if ( onL1_ ) {
00164     // build vector of algo names
00165     l1Gt_.getL1GtRunCache( run, setup, true, false );
00166     edm::ESHandle< L1GtTriggerMenu > handleL1GtTriggerMenu;
00167     setup.get< L1GtTriggerMenuRcd >().get( handleL1GtTriggerMenu );
00168 //     L1GtTriggerMenu l1GtTriggerMenu( *handleL1GtTriggerMenu );
00169     std::vector< std::string > algoNames;
00170 //     const AlgorithmMap l1GtPhys( l1GtTriggerMenu.gtAlgorithmMap() );
00171     const AlgorithmMap l1GtPhys( handleL1GtTriggerMenu->gtAlgorithmMap() );
00172     for ( CItAlgo iAlgo = l1GtPhys.begin(); iAlgo != l1GtPhys.end(); ++iAlgo ) {
00173       algoNames.push_back( iAlgo->second.algoName() );
00174     }
00175 //     const AlgorithmMap l1GtTech( l1GtTriggerMenu.gtTechnicalTriggerMap() );
00176     const AlgorithmMap l1GtTech( handleL1GtTriggerMenu->gtTechnicalTriggerMap() );
00177     for ( CItAlgo iAlgo = l1GtTech.begin(); iAlgo != l1GtTech.end(); ++iAlgo ) {
00178       algoNames.push_back( iAlgo->second.algoName() );
00179     }
00180     for ( unsigned iExpr = 0; iExpr < l1LogicalExpressions_.size(); ++iExpr ) {
00181       std::string l1LogicalExpression( l1LogicalExpressions_.at( iExpr ) );
00182       L1GtLogicParser l1AlgoLogicParser( l1LogicalExpression );
00183       // Loop over algorithms
00184       for ( size_t iAlgo = 0; iAlgo < l1AlgoLogicParser.operandTokenVector().size(); ++iAlgo ) {
00185         const std::string l1AlgoName( l1AlgoLogicParser.operandTokenVector().at( iAlgo ).tokenName );
00186         if ( l1AlgoName.find( '*' ) != std::string::npos ) {
00187           l1LogicalExpression.replace( l1LogicalExpression.find( l1AlgoName ), l1AlgoName.size(), expandLogicalExpression( algoNames, l1AlgoName ) );
00188         }
00189       }
00190       l1LogicalExpressions_[ iExpr ] = l1LogicalExpression;
00191     }
00192   }
00193   // HLT
00194   if ( hltConfigInit_ ) {
00195     for ( unsigned iExpr = 0; iExpr < hltLogicalExpressions_.size(); ++iExpr ) {
00196       std::string hltLogicalExpression( hltLogicalExpressions_.at( iExpr ) );
00197       L1GtLogicParser hltAlgoLogicParser( hltLogicalExpression );
00198       // Loop over paths
00199       for ( size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath ) {
00200         const std::string hltPathName( hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenName );
00201         if ( hltPathName.find( '*' ) != std::string::npos ) {
00202           hltLogicalExpression.replace( hltLogicalExpression.find( hltPathName ), hltPathName.size(), expandLogicalExpression( hltConfig_.triggerNames(), hltPathName ) );
00203         }
00204       }
00205       hltLogicalExpressions_[ iExpr ] = hltLogicalExpression;
00206     }
00207   }
00208 
00209 }
00210 
00211 
00213 bool GenericTriggerEventFlag::accept( const edm::Event & event, const edm::EventSetup & setup )
00214 {
00215 
00216   if ( ! on_ ) return true;
00217 
00218   // Determine decision
00219   if ( andOr_ ) return ( acceptDcs( event ) || acceptGt( event ) || acceptL1( event, setup ) || acceptHlt( event ) );
00220   return ( acceptDcs( event ) && acceptGt( event ) && acceptL1( event, setup ) && acceptHlt( event ) );
00221 
00222 }
00223 
00224 
00225 bool GenericTriggerEventFlag::acceptDcs( const edm::Event & event )
00226 {
00227 
00228   // An empty DCS partitions list acts as switch.
00229   if ( ! onDcs_ || dcsPartitions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
00230 
00231   // Accessing the DcsStatusCollection
00232   edm::Handle< DcsStatusCollection > dcsStatus;
00233   event.getByLabel( dcsInputTag_, dcsStatus );
00234   if ( ! dcsStatus.isValid() ) {
00235     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode() << "\" not in event ==> decision: " << errorReplyDcs_;
00236     return errorReplyDcs_;
00237   }
00238   if ( ( *dcsStatus ).size() == 0 ) {
00239     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode() << "\" empty ==> decision: " << errorReplyDcs_;
00240     return errorReplyDcs_;
00241   }
00242 
00243   // Determine decision of DCS partition combination and return
00244   if ( andOrDcs_ ) { // OR combination
00245     for ( std::vector< int >::const_iterator partitionNumber = dcsPartitions_.begin(); partitionNumber != dcsPartitions_.end(); ++partitionNumber ) {
00246       if ( acceptDcsPartition( dcsStatus, *partitionNumber ) ) return true;
00247     }
00248     return false;
00249   }
00250   for ( std::vector< int >::const_iterator partitionNumber = dcsPartitions_.begin(); partitionNumber != dcsPartitions_.end(); ++partitionNumber ) {
00251     if ( ! acceptDcsPartition( dcsStatus, *partitionNumber ) ) return false;
00252   }
00253   return true;
00254 
00255 }
00256 
00257 
00258 bool GenericTriggerEventFlag::acceptDcsPartition( const edm::Handle< DcsStatusCollection > & dcsStatus, int dcsPartition ) const
00259 {
00260 
00261   // Error checks
00262   switch( dcsPartition ) {
00263     case DcsStatus::EBp   :
00264     case DcsStatus::EBm   :
00265     case DcsStatus::EEp   :
00266     case DcsStatus::EEm   :
00267     case DcsStatus::HBHEa :
00268     case DcsStatus::HBHEb :
00269     case DcsStatus::HBHEc :
00270     case DcsStatus::HF    :
00271     case DcsStatus::HO    :
00272     case DcsStatus::RPC   :
00273     case DcsStatus::DT0   :
00274     case DcsStatus::DTp   :
00275     case DcsStatus::DTm   :
00276     case DcsStatus::CSCp  :
00277     case DcsStatus::CSCm  :
00278     case DcsStatus::CASTOR:
00279     case DcsStatus::TIBTID:
00280     case DcsStatus::TOB   :
00281     case DcsStatus::TECp  :
00282     case DcsStatus::TECm  :
00283     case DcsStatus::BPIX  :
00284     case DcsStatus::FPIX  :
00285     case DcsStatus::ESp   :
00286     case DcsStatus::ESm   :
00287       break;
00288     default:
00289       if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "DCS partition number \"" << dcsPartition << "\" does not exist ==> decision: " << errorReplyDcs_;
00290       return errorReplyDcs_;
00291   }
00292 
00293   // Determine decision
00294   return dcsStatus->at( 0 ).ready( dcsPartition );
00295 
00296 }
00297 
00298 
00300 bool GenericTriggerEventFlag::acceptGt( const edm::Event & event )
00301 {
00302 
00303   // An empty GT status bits logical expressions list acts as switch.
00304   if ( ! onGt_ || gtLogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
00305 
00306   // Determine decision of GT status bits logical expression combination and return
00307   if ( andOrGt_ ) { // OR combination
00308     for ( std::vector< std::string >::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin(); gtLogicalExpression != gtLogicalExpressions_.end(); ++gtLogicalExpression ) {
00309       if ( acceptGtLogicalExpression( event, *gtLogicalExpression ) ) return true;
00310     }
00311     return false;
00312   }
00313   for ( std::vector< std::string >::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin(); gtLogicalExpression != gtLogicalExpressions_.end(); ++gtLogicalExpression ) {
00314     if ( ! acceptGtLogicalExpression( event, *gtLogicalExpression ) ) return false;
00315   }
00316   return true;
00317 
00318 }
00319 
00320 
00322 bool GenericTriggerEventFlag::acceptGtLogicalExpression( const edm::Event & event, std::string gtLogicalExpression )
00323 {
00324 
00325   // Check empty std::strings
00326   if ( gtLogicalExpression.empty() ) {
00327     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty logical expression ==> decision: " << errorReplyGt_;
00328     return errorReplyGt_;
00329   }
00330 
00331   // Negated paths
00332   bool negExpr( negate( gtLogicalExpression ) );
00333   if ( negExpr && gtLogicalExpression.empty() ) {
00334     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty (negated) logical expression ==> decision: " << errorReplyGt_;
00335     return errorReplyGt_;
00336   }
00337 
00338   // Parse logical expression and determine GT status bit decision
00339   L1GtLogicParser gtAlgoLogicParser( gtLogicalExpression );
00340   // Loop over status bits
00341   for ( size_t iStatusBit = 0; iStatusBit < gtAlgoLogicParser.operandTokenVector().size(); ++iStatusBit ) {
00342     const std::string gtStatusBit( gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenName );
00343     // Manipulate status bit decision as stored in the parser
00344     bool decision( errorReplyDcs_ );
00345     // Hard-coded status bits!!!
00346     if ( gtStatusBit == "PhysDecl" || gtStatusBit == "PhysicsDeclared" ) {
00347       edm::Handle< L1GlobalTriggerReadoutRecord > gtReadoutRecord;
00348       event.getByLabel( gtInputTag_, gtReadoutRecord );
00349       if ( ! gtReadoutRecord.isValid() ) {
00350         if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "L1GlobalTriggerReadoutRecord product with InputTag \"" << gtInputTag_.encode() << "\" not in event ==> decision: " << errorReplyGt_;
00351         gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenResult = errorReplyDcs_;
00352         continue;
00353       }
00354       decision = ( gtReadoutRecord->gtFdlWord().physicsDeclared() == 1 );
00355     } else if ( gtStatusBit == "Stable" || gtStatusBit == "StableBeam" || gtStatusBit == "Adjust" || gtStatusBit == "Sqeeze" || gtStatusBit == "Flat" || gtStatusBit == "FlatTop" ||
00356                 gtStatusBit == "7TeV" || gtStatusBit == "8TeV" || gtStatusBit == "2360GeV" || gtStatusBit == "900GeV" ) {
00357       edm::Handle< L1GlobalTriggerEvmReadoutRecord > gtEvmReadoutRecord;
00358       event.getByLabel( gtEvmInputTag_, gtEvmReadoutRecord );
00359       if ( ! gtEvmReadoutRecord.isValid() ) {
00360         if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "L1GlobalTriggerEvmReadoutRecord product with InputTag \"" << gtEvmInputTag_.encode() << "\" not in event ==> decision: " << errorReplyGt_;
00361         gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenResult = errorReplyDcs_;
00362         continue;
00363       }
00364       if ( gtStatusBit == "Stable" || gtStatusBit == "StableBeam" ) {
00365         decision = ( gtEvmReadoutRecord->gtfeWord().beamMode() == 11 );
00366       } else if ( gtStatusBit == "Adjust" ) {
00367         decision = ( 10 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11 );
00368       } else if ( gtStatusBit == "Sqeeze" ) {
00369         decision = ( 9 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11 );
00370       } else if ( gtStatusBit == "Flat" || gtStatusBit == "FlatTop" ) {
00371         decision = ( 8 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11 );
00372       } else if ( gtStatusBit == "7TeV" ) {
00373         decision = ( gtEvmReadoutRecord->gtfeWord().beamMomentum() == 3500 );
00374       } else if ( gtStatusBit == "8TeV" ) {
00375         decision = ( gtEvmReadoutRecord->gtfeWord().beamMomentum() == 4000 );
00376       } else if ( gtStatusBit == "2360GeV" ) {
00377         decision = ( gtEvmReadoutRecord->gtfeWord().beamMomentum() == 1180 );
00378       } else if ( gtStatusBit == "900GeV" ) {
00379         decision = ( gtEvmReadoutRecord->gtfeWord().beamMomentum() == 450 );
00380       }
00381     } else {
00382       if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "GT status bit \"" << gtStatusBit << "\" is not defined ==> decision: " << errorReplyGt_;
00383     }
00384     gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenResult = decision;
00385   }
00386 
00387   // Determine decision
00388   const bool gtDecision( gtAlgoLogicParser.expressionResult() );
00389   return negExpr ? ( ! gtDecision ) : gtDecision;
00390 
00391 }
00392 
00393 
00395 bool GenericTriggerEventFlag::acceptL1( const edm::Event & event, const edm::EventSetup & setup )
00396 {
00397 
00398   // An empty L1 logical expressions list acts as switch.
00399   if ( ! onL1_ || l1LogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
00400 
00401   // Getting the L1 event setup
00402   l1Gt_.getL1GtRunCache( event, setup, useL1EventSetup, useL1GtTriggerMenuLite ); // FIXME This can possibly go to initRun()
00403 
00404   // Determine decision of L1 logical expression combination and return
00405   if ( andOrL1_ ) { // OR combination
00406     for ( std::vector< std::string >::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin(); l1LogicalExpression != l1LogicalExpressions_.end(); ++l1LogicalExpression ) {
00407       if ( acceptL1LogicalExpression( event, *l1LogicalExpression ) ) return true;
00408     }
00409     return false;
00410   }
00411   for ( std::vector< std::string >::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin(); l1LogicalExpression != l1LogicalExpressions_.end(); ++l1LogicalExpression ) {
00412     if ( ! acceptL1LogicalExpression( event, *l1LogicalExpression ) ) return false;
00413   }
00414   return true;
00415 
00416 }
00417 
00418 
00420 bool GenericTriggerEventFlag::acceptL1LogicalExpression( const edm::Event & event, std::string l1LogicalExpression )
00421 {
00422 
00423   // Check empty std::strings
00424   if ( l1LogicalExpression.empty() ) {
00425     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty logical expression ==> decision: " << errorReplyL1_;
00426     return errorReplyL1_;
00427   }
00428 
00429   // Negated logical expression
00430   bool negExpr( negate( l1LogicalExpression ) );
00431   if ( negExpr && l1LogicalExpression.empty() ) {
00432     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty (negated) logical expression ==> decision: " << errorReplyL1_;
00433     return errorReplyL1_;
00434   }
00435 
00436   // Parse logical expression and determine L1 decision
00437   L1GtLogicParser l1AlgoLogicParser( l1LogicalExpression );
00438   // Loop over algorithms
00439   for ( size_t iAlgorithm = 0; iAlgorithm < l1AlgoLogicParser.operandTokenVector().size(); ++iAlgorithm ) {
00440     const std::string l1AlgoName( l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenName );
00441     int error( -1 );
00442     const bool decision( l1BeforeMask_ ? l1Gt_.decisionBeforeMask( event, l1AlgoName, error ) : l1Gt_.decisionAfterMask( event, l1AlgoName, error ) );
00443     // Error checks
00444     if ( error != 0 ) {
00445       if ( verbose_ > 1 ) {
00446         if ( error == 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "L1 algorithm \"" << l1AlgoName << "\" does not exist in the L1 menu ==> decision: "                                          << errorReplyL1_;
00447         else              edm::LogWarning( "GenericTriggerEventFlag" ) << "L1 algorithm \"" << l1AlgoName << "\" received error code " << error << " from L1GtUtils::decisionBeforeMask ==> decision: " << errorReplyL1_;
00448       }
00449       l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenResult = errorReplyL1_;
00450       continue;
00451     }
00452     // Manipulate algo decision as stored in the parser
00453     l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenResult = decision;
00454   }
00455 
00456   // Return decision
00457   const bool l1Decision( l1AlgoLogicParser.expressionResult() );
00458   return negExpr ? ( ! l1Decision ) : l1Decision;
00459 
00460 }
00461 
00462 
00464 bool GenericTriggerEventFlag::acceptHlt( const edm::Event & event )
00465 {
00466 
00467   // An empty HLT logical expressions list acts as switch.
00468   if ( ! onHlt_ || hltLogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
00469 
00470   // Checking the HLT configuration,
00471   if ( ! hltConfigInit_ ) {
00472     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "HLT config error ==> decision: " << errorReplyHlt_;
00473     return errorReplyHlt_;
00474   }
00475 
00476   // Accessing the TriggerResults
00477   edm::Handle< edm::TriggerResults > hltTriggerResults;
00478   event.getByLabel( hltInputTag_, hltTriggerResults );
00479   if ( ! hltTriggerResults.isValid() ) {
00480     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "TriggerResults product with InputTag \"" << hltInputTag_.encode() << "\" not in event ==> decision: " << errorReplyHlt_;
00481     return errorReplyHlt_;
00482   }
00483   if ( ( *hltTriggerResults ).size() == 0 ) {
00484     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "TriggerResults product with InputTag \"" << hltInputTag_.encode() << "\" empty ==> decision: " << errorReplyHlt_;
00485     return errorReplyDcs_;
00486   }
00487 
00488   // Determine decision of HLT logical expression combination and return
00489   if ( andOrHlt_ ) { // OR combination
00490     for ( std::vector< std::string >::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin(); hltLogicalExpression != hltLogicalExpressions_.end(); ++hltLogicalExpression ) {
00491       if ( acceptHltLogicalExpression( hltTriggerResults, *hltLogicalExpression ) ) return true;
00492     }
00493     return false;
00494   }
00495   for ( std::vector< std::string >::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin(); hltLogicalExpression != hltLogicalExpressions_.end(); ++hltLogicalExpression ) {
00496     if ( ! acceptHltLogicalExpression( hltTriggerResults, *hltLogicalExpression ) ) return false;
00497   }
00498   return true;
00499 
00500 }
00501 
00502 
00504 bool GenericTriggerEventFlag::acceptHltLogicalExpression( const edm::Handle< edm::TriggerResults > & hltTriggerResults, std::string hltLogicalExpression ) const
00505 {
00506 
00507   // Check empty std::strings
00508   if ( hltLogicalExpression.empty() ) {
00509     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty logical expression ==> decision: " << errorReplyHlt_;
00510     return errorReplyHlt_;
00511   }
00512 
00513   // Negated paths
00514   bool negExpr( negate( hltLogicalExpression ) );
00515   if ( negExpr && hltLogicalExpression.empty() ) {
00516     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty (negated) logical expression ==> decision: " << errorReplyHlt_;
00517     return errorReplyHlt_;
00518   }
00519 
00520   // Parse logical expression and determine HLT decision
00521   L1GtLogicParser hltAlgoLogicParser( hltLogicalExpression );
00522   // Loop over paths
00523   for ( size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath ) {
00524     const std::string hltPathName( hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenName );
00525     const unsigned indexPath( hltConfig_.triggerIndex( hltPathName ) );
00526     // Further error checks
00527     if ( indexPath == hltConfig_.size() ) {
00528       if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "HLT path \"" << hltPathName << "\" is not found in process " << hltInputTag_.process() << " ==> decision: " << errorReplyHlt_;
00529       hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = errorReplyHlt_;
00530       continue;
00531     }
00532     if ( hltTriggerResults->error( indexPath ) ) {
00533       if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "HLT path \"" << hltPathName << "\" in error ==> decision: " << errorReplyHlt_;
00534       hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = errorReplyHlt_;
00535       continue;
00536     }
00537     // Manipulate algo decision as stored in the parser
00538     const bool decision( hltTriggerResults->accept( indexPath ) );
00539     hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = decision;
00540   }
00541 
00542   // Determine decision
00543   const bool hltDecision( hltAlgoLogicParser.expressionResult() );
00544   return negExpr ? ( ! hltDecision ) : hltDecision;
00545 
00546 }
00547 
00548 
00549 
00551 std::string GenericTriggerEventFlag::expandLogicalExpression( const std::vector< std::string > & targets, const std::string & expr, bool useAnd ) const
00552 {
00553 
00554   // Find matching entries in the menu
00555   std::vector< std::string > matched;
00556   const std::string versionWildcard( "_v*" );
00557   if ( expr.substr( expr.size() - versionWildcard.size() ) == versionWildcard ) {
00558     const std::string exprBase( expr.substr( 0, expr.size() - versionWildcard.size() ) );
00559     matched = hltConfig_.restoreVersion( targets, exprBase );
00560   } else {
00561     matched = hltConfig_.matched( targets, expr );
00562   }
00563 
00564   // Return input, if no match is found
00565   if ( matched.empty() ) {
00566     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Logical expression: \"" << expr << "\" could not be resolved";
00567     return expr;
00568   }
00569 
00570   // Compose logical expression
00571   std::string expanded( "(" );
00572   for ( unsigned iVers = 0; iVers < matched.size(); ++iVers ) {
00573     if ( iVers > 0 ) expanded.append( useAnd ? " AND " : " OR " );
00574     expanded.append( matched.at( iVers ) );
00575   }
00576   expanded.append( ")" );
00577   if ( verbose_ > 1 ) edm::LogInfo( "GenericTriggerEventFlag" ) << "Logical expression: \"" << expr     << "\"\n"
00578                                                                 << "   --> expanded to  \"" << expanded << "\"";
00579 
00580   return expanded;
00581 
00582 }
00583 
00584 
00585 
00587 bool GenericTriggerEventFlag::negate( std::string & word ) const
00588 {
00589 
00590   bool negate( false );
00591   if ( word.at( 0 ) == '~' ) {
00592     negate = true;
00593     word.erase( 0, 1 );
00594   }
00595   return negate;
00596 
00597 }
00598 
00599 
00600 
00602 std::vector< std::string > GenericTriggerEventFlag::expressionsFromDB( const std::string & key, const edm::EventSetup & setup )
00603 {
00604 
00605   if ( key.size() == 0 ) return std::vector< std::string >( 1, emptyKeyError_ );
00606   edm::ESHandle< AlCaRecoTriggerBits > logicalExpressions;
00607   std::vector< edm::eventsetup::DataKey > labels;
00608   setup.get< AlCaRecoTriggerBitsRcd >().fillRegisteredDataKeys( labels );
00609   std::vector< edm::eventsetup::DataKey >::const_iterator iKey = labels.begin();
00610   while ( iKey != labels.end() && iKey->name().value() != dbLabel_ ) ++iKey;
00611   if ( iKey == labels.end() ) {
00612     if ( verbose_ > 0 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Label " << dbLabel_ << " not found in DB for 'AlCaRecoTriggerBitsRcd'";
00613     return std::vector< std::string >( 1, configError_ );
00614   }
00615   setup.get< AlCaRecoTriggerBitsRcd >().get( dbLabel_, logicalExpressions );
00616   const std::map< std::string, std::string > & expressionMap = logicalExpressions->m_alcarecoToTrig;
00617   std::map< std::string, std::string >::const_iterator listIter = expressionMap.find( key );
00618   if ( listIter == expressionMap.end() ) {
00619     if ( verbose_ > 0 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "No logical expressions found under key " << key << " in 'AlCaRecoTriggerBitsRcd'";
00620     return std::vector< std::string >( 1, configError_ );
00621   }
00622   return logicalExpressions->decompose( listIter->second );
00623 
00624 }