CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 //
00002 // $Id: GenericTriggerEventFlag.cc,v 1.13 2012/04/22 15:09:29 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";
00351         event.getByType( gtReadoutRecord );
00352         if ( ! gtReadoutRecord.isValid() ) {
00353           if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "L1GlobalTriggerReadoutRecord product not in event at all ==> decision: " << errorReplyGt_;
00354           gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenResult = errorReplyDcs_;
00355           continue;
00356         }
00357       }
00358       decision = ( gtReadoutRecord->gtFdlWord().physicsDeclared() == 1 );
00359     } else if ( gtStatusBit == "Stable" || gtStatusBit == "StableBeam" || gtStatusBit == "Adjust" || gtStatusBit == "Sqeeze" || gtStatusBit == "Flat" || gtStatusBit == "FlatTop" ||
00360                 gtStatusBit == "7TeV" || gtStatusBit == "900GeV" ) {
00361       edm::Handle< L1GlobalTriggerEvmReadoutRecord > gtEvmReadoutRecord;
00362       event.getByLabel( gtEvmInputTag_, gtEvmReadoutRecord );
00363       if ( ! gtEvmReadoutRecord.isValid() ) {
00364         if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "L1GlobalTriggerEvmReadoutRecord product with InputTag \"" << gtEvmInputTag_.encode() << "\" not in event";
00365         event.getByType( gtEvmReadoutRecord );
00366         if ( ! gtEvmReadoutRecord.isValid() ) {
00367           if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "L1GlobalTriggerEvmReadoutRecord product not in event at all ==> decision: " << errorReplyGt_;
00368           gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenResult = errorReplyDcs_;
00369           continue;
00370         }
00371       }
00372       if ( gtStatusBit == "Stable" || gtStatusBit == "StableBeam" ) {
00373         decision = ( gtEvmReadoutRecord->gtfeWord().beamMode() == 11 );
00374       } else if ( gtStatusBit == "Adjust" ) {
00375         decision = ( 10 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11 );
00376       } else if ( gtStatusBit == "Sqeeze" ) {
00377         decision = ( 9 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11 );
00378       } else if ( gtStatusBit == "Flat" || gtStatusBit == "FlatTop" ) {
00379         decision = ( 8 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11 );
00380       } else if ( gtStatusBit == "7TeV" ) {
00381         decision = ( gtEvmReadoutRecord->gtfeWord().beamMomentum() == 3500 );
00382       } else if ( gtStatusBit == "900GeV" ) {
00383         decision = ( gtEvmReadoutRecord->gtfeWord().beamMomentum() == 450 );
00384       }
00385     } else {
00386       if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "GT status bit \"" << gtStatusBit << "\" is not defined ==> decision: " << errorReplyGt_;
00387     }
00388     gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenResult = decision;
00389   }
00390 
00391   // Determine decision
00392   const bool gtDecision( gtAlgoLogicParser.expressionResult() );
00393   return negExpr ? ( ! gtDecision ) : gtDecision;
00394 
00395 }
00396 
00397 
00399 bool GenericTriggerEventFlag::acceptL1( const edm::Event & event, const edm::EventSetup & setup )
00400 {
00401 
00402   // An empty L1 logical expressions list acts as switch.
00403   if ( ! onL1_ || l1LogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
00404 
00405   // Getting the L1 event setup
00406   l1Gt_.getL1GtRunCache( event, setup, useL1EventSetup, useL1GtTriggerMenuLite ); // FIXME This can possibly go to initRun()
00407 
00408   // Determine decision of L1 logical expression combination and return
00409   if ( andOrL1_ ) { // OR combination
00410     for ( std::vector< std::string >::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin(); l1LogicalExpression != l1LogicalExpressions_.end(); ++l1LogicalExpression ) {
00411       if ( acceptL1LogicalExpression( event, *l1LogicalExpression ) ) return true;
00412     }
00413     return false;
00414   }
00415   for ( std::vector< std::string >::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin(); l1LogicalExpression != l1LogicalExpressions_.end(); ++l1LogicalExpression ) {
00416     if ( ! acceptL1LogicalExpression( event, *l1LogicalExpression ) ) return false;
00417   }
00418   return true;
00419 
00420 }
00421 
00422 
00424 bool GenericTriggerEventFlag::acceptL1LogicalExpression( const edm::Event & event, std::string l1LogicalExpression )
00425 {
00426 
00427   // Check empty std::strings
00428   if ( l1LogicalExpression.empty() ) {
00429     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty logical expression ==> decision: " << errorReplyL1_;
00430     return errorReplyL1_;
00431   }
00432 
00433   // Negated logical expression
00434   bool negExpr( negate( l1LogicalExpression ) );
00435   if ( negExpr && l1LogicalExpression.empty() ) {
00436     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty (negated) logical expression ==> decision: " << errorReplyL1_;
00437     return errorReplyL1_;
00438   }
00439 
00440   // Parse logical expression and determine L1 decision
00441   L1GtLogicParser l1AlgoLogicParser( l1LogicalExpression );
00442   // Loop over algorithms
00443   for ( size_t iAlgorithm = 0; iAlgorithm < l1AlgoLogicParser.operandTokenVector().size(); ++iAlgorithm ) {
00444     const std::string l1AlgoName( l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenName );
00445     int error( -1 );
00446     const bool decision( l1BeforeMask_ ? l1Gt_.decisionBeforeMask( event, l1AlgoName, error ) : l1Gt_.decisionAfterMask( event, l1AlgoName, error ) );
00447     // Error checks
00448     if ( error != 0 ) {
00449       if ( verbose_ > 1 ) {
00450         if ( error == 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "L1 algorithm \"" << l1AlgoName << "\" does not exist in the L1 menu ==> decision: "                                          << errorReplyL1_;
00451         else              edm::LogWarning( "GenericTriggerEventFlag" ) << "L1 algorithm \"" << l1AlgoName << "\" received error code " << error << " from L1GtUtils::decisionBeforeMask ==> decision: " << errorReplyL1_;
00452       }
00453       l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenResult = errorReplyL1_;
00454       continue;
00455     }
00456     // Manipulate algo decision as stored in the parser
00457     l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenResult = decision;
00458   }
00459 
00460   // Return decision
00461   const bool l1Decision( l1AlgoLogicParser.expressionResult() );
00462   return negExpr ? ( ! l1Decision ) : l1Decision;
00463 
00464 }
00465 
00466 
00468 bool GenericTriggerEventFlag::acceptHlt( const edm::Event & event )
00469 {
00470 
00471   // An empty HLT logical expressions list acts as switch.
00472   if ( ! onHlt_ || hltLogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
00473 
00474   // Checking the HLT configuration,
00475   if ( ! hltConfigInit_ ) {
00476     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "HLT config error ==> decision: " << errorReplyHlt_;
00477     return errorReplyHlt_;
00478   }
00479 
00480   // Accessing the TriggerResults
00481   edm::Handle< edm::TriggerResults > hltTriggerResults;
00482   event.getByLabel( hltInputTag_, hltTriggerResults );
00483   if ( ! hltTriggerResults.isValid() ) {
00484     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "TriggerResults product with InputTag \"" << hltInputTag_.encode() << "\" not in event ==> decision: " << errorReplyHlt_;
00485     return errorReplyHlt_;
00486   }
00487   if ( ( *hltTriggerResults ).size() == 0 ) {
00488     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "TriggerResults product with InputTag \"" << hltInputTag_.encode() << "\" empty ==> decision: " << errorReplyHlt_;
00489     return errorReplyDcs_;
00490   }
00491 
00492   // Determine decision of HLT logical expression combination and return
00493   if ( andOrHlt_ ) { // OR combination
00494     for ( std::vector< std::string >::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin(); hltLogicalExpression != hltLogicalExpressions_.end(); ++hltLogicalExpression ) {
00495       if ( acceptHltLogicalExpression( hltTriggerResults, *hltLogicalExpression ) ) return true;
00496     }
00497     return false;
00498   }
00499   for ( std::vector< std::string >::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin(); hltLogicalExpression != hltLogicalExpressions_.end(); ++hltLogicalExpression ) {
00500     if ( ! acceptHltLogicalExpression( hltTriggerResults, *hltLogicalExpression ) ) return false;
00501   }
00502   return true;
00503 
00504 }
00505 
00506 
00508 bool GenericTriggerEventFlag::acceptHltLogicalExpression( const edm::Handle< edm::TriggerResults > & hltTriggerResults, std::string hltLogicalExpression ) const
00509 {
00510 
00511   // Check empty std::strings
00512   if ( hltLogicalExpression.empty() ) {
00513     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty logical expression ==> decision: " << errorReplyHlt_;
00514     return errorReplyHlt_;
00515   }
00516 
00517   // Negated paths
00518   bool negExpr( negate( hltLogicalExpression ) );
00519   if ( negExpr && hltLogicalExpression.empty() ) {
00520     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty (negated) logical expression ==> decision: " << errorReplyHlt_;
00521     return errorReplyHlt_;
00522   }
00523 
00524   // Parse logical expression and determine HLT decision
00525   L1GtLogicParser hltAlgoLogicParser( hltLogicalExpression );
00526   // Loop over paths
00527   for ( size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath ) {
00528     const std::string hltPathName( hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenName );
00529     const unsigned indexPath( hltConfig_.triggerIndex( hltPathName ) );
00530     // Further error checks
00531     if ( indexPath == hltConfig_.size() ) {
00532       if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "HLT path \"" << hltPathName << "\" is not found in process " << hltInputTag_.process() << " ==> decision: " << errorReplyHlt_;
00533       hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = errorReplyHlt_;
00534       continue;
00535     }
00536     if ( hltTriggerResults->error( indexPath ) ) {
00537       if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "HLT path \"" << hltPathName << "\" in error ==> decision: " << errorReplyHlt_;
00538       hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = errorReplyHlt_;
00539       continue;
00540     }
00541     // Manipulate algo decision as stored in the parser
00542     const bool decision( hltTriggerResults->accept( indexPath ) );
00543     hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = decision;
00544   }
00545 
00546   // Determine decision
00547   const bool hltDecision( hltAlgoLogicParser.expressionResult() );
00548   return negExpr ? ( ! hltDecision ) : hltDecision;
00549 
00550 }
00551 
00552 
00553 
00555 std::string GenericTriggerEventFlag::expandLogicalExpression( const std::vector< std::string > & targets, const std::string & expr, bool useAnd ) const
00556 {
00557 
00558   // Find matching entries in the menu
00559   std::vector< std::string > matched;
00560   const std::string versionWildcard( "_v*" );
00561   if ( expr.substr( expr.size() - versionWildcard.size() ) == versionWildcard ) {
00562     const std::string exprBase( expr.substr( 0, expr.size() - versionWildcard.size() ) );
00563     matched = hltConfig_.restoreVersion( targets, exprBase );
00564   } else {
00565     matched = hltConfig_.matched( targets, expr );
00566   }
00567 
00568   // Return input, if no match is found
00569   if ( matched.empty() ) {
00570     if ( verbose_ > 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Logical expression: \"" << expr << "\" could not be resolved";
00571     return expr;
00572   }
00573 
00574   // Compose logical expression
00575   std::string expanded( "(" );
00576   for ( unsigned iVers = 0; iVers < matched.size(); ++iVers ) {
00577     if ( iVers > 0 ) expanded.append( useAnd ? " AND " : " OR " );
00578     expanded.append( matched.at( iVers ) );
00579   }
00580   expanded.append( ")" );
00581   if ( verbose_ > 1 ) edm::LogInfo( "GenericTriggerEventFlag" ) << "Logical expression: \"" << expr     << "\"\n"
00582                                                                 << "   --> expanded to  \"" << expanded << "\"";
00583 
00584   return expanded;
00585 
00586 }
00587 
00588 
00589 
00591 bool GenericTriggerEventFlag::negate( std::string & word ) const
00592 {
00593 
00594   bool negate( false );
00595   if ( word.at( 0 ) == '~' ) {
00596     negate = true;
00597     word.erase( 0, 1 );
00598   }
00599   return negate;
00600 
00601 }
00602 
00603 
00604 
00606 std::vector< std::string > GenericTriggerEventFlag::expressionsFromDB( const std::string & key, const edm::EventSetup & setup )
00607 {
00608 
00609   if ( key.size() == 0 ) return std::vector< std::string >( 1, emptyKeyError_ );
00610   edm::ESHandle< AlCaRecoTriggerBits > logicalExpressions;
00611   std::vector< edm::eventsetup::DataKey > labels;
00612   setup.get< AlCaRecoTriggerBitsRcd >().fillRegisteredDataKeys( labels );
00613   std::vector< edm::eventsetup::DataKey >::const_iterator iKey = labels.begin();
00614   while ( iKey != labels.end() && iKey->name().value() != dbLabel_ ) ++iKey;
00615   if ( iKey == labels.end() ) {
00616     if ( verbose_ > 0 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Label " << dbLabel_ << " not found in DB for 'AlCaRecoTriggerBitsRcd'";
00617     return std::vector< std::string >( 1, configError_ );
00618   }
00619   setup.get< AlCaRecoTriggerBitsRcd >().get( dbLabel_, logicalExpressions );
00620   const std::map< std::string, std::string > & expressionMap = logicalExpressions->m_alcarecoToTrig;
00621   std::map< std::string, std::string >::const_iterator listIter = expressionMap.find( key );
00622   if ( listIter == expressionMap.end() ) {
00623     if ( verbose_ > 0 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "No logical expressions found under key " << key << " in 'AlCaRecoTriggerBitsRcd'";
00624     return std::vector< std::string >( 1, configError_ );
00625   }
00626   return logicalExpressions->decompose( listIter->second );
00627 
00628 }