CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/CommonTools/RecoUtils/src/GenericTriggerEventFlag.cc

Go to the documentation of this file.
00001 //
00002 // $Id: GenericTriggerEventFlag.cc,v 1.4 2010/05/12 14:12:17 vadler Exp $
00003 //
00004 
00005 
00006 #include "CommonTools/RecoUtils/interface/GenericTriggerEventFlag.h"
00007 
00008 #include "CondFormats/HLTObjects/interface/AlCaRecoTriggerBits.h"
00009 #include "DataFormats/L1GlobalTrigger/interface/L1GtLogicParser.h"
00010 #include "FWCore/Framework/interface/ESHandle.h"
00011 
00012 #include <string>
00013 #include <vector>
00014 
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 
00017 
00019 GenericTriggerEventFlag::GenericTriggerEventFlag( const edm::ParameterSet & config )
00020   : watchDB_( 0 )
00021   , verbose_( 0 )
00022   , gtDBKey_( "" )
00023   , l1DBKey_( "" )
00024   , hltDBKey_( "" )
00025   , on_( true )
00026   , onDcs_( true )
00027   , onGt_( true )
00028   , onL1_( true )
00029   , onHlt_( true )
00030   , configError_( "CONFIG_ERROR" )
00031 {
00032 
00033   // General switch(es)
00034   if ( config.exists( "andOr" ) ) {
00035     andOr_ = config.getParameter< bool >( "andOr" );
00036     if ( config.exists( "verbosityLevel" ) ) verbose_ = config.getParameter< unsigned >( "verbosityLevel" );
00037   } else {
00038     on_    = false;
00039     onDcs_ = false;
00040     onGt_  = false;
00041     onL1_  = false;
00042     onHlt_ = false;
00043   }
00044 
00045   if ( on_ ) {
00046     if ( config.exists( "andOrDcs" ) ) {
00047       andOrDcs_      = config.getParameter< bool >( "andOrDcs" );
00048       dcsInputTag_   = config.getParameter< edm::InputTag >( "dcsInputTag" );
00049       dcsPartitions_ = config.getParameter< std::vector< int > >( "dcsPartitions" );
00050       errorReplyDcs_ = config.getParameter< bool >( "errorReplyDcs" );
00051     } else {
00052       onDcs_ = false;
00053     }
00054     if ( config.exists( "andOrGt" ) ) {
00055       andOrGt_              = config.getParameter< bool >( "andOrGt" );
00056       gtInputTag_           = config.getParameter< edm::InputTag >( "gtInputTag" );
00057       gtLogicalExpressions_ = config.getParameter< std::vector< std::string > >( "gtStatusBits" );
00058       errorReplyGt_         = config.getParameter< bool >( "errorReplyGt" );
00059       if ( config.exists( "gtDBKey" ) ) gtDBKey_ = config.getParameter< std::string >( "gtDBKey" );
00060     } else {
00061       onGt_ = false;
00062     }
00063     if ( config.exists( "andOrL1" ) ) {
00064       andOrL1_              = config.getParameter< bool >( "andOrL1" );
00065       l1LogicalExpressions_ = config.getParameter< std::vector< std::string > >( "l1Algorithms" );
00066       errorReplyL1_         = config.getParameter< bool >( "errorReplyL1" );
00067       if ( config.exists( "l1DBKey" ) ) l1DBKey_ = config.getParameter< std::string >( "l1DBKey" );
00068     } else {
00069       onL1_ = false;
00070     }
00071     if ( config.exists( "andOrHlt" ) ) {
00072       andOrHlt_              = config.getParameter< bool >( "andOrHlt" );
00073       hltInputTag_           = config.getParameter< edm::InputTag >( "hltInputTag" );
00074       hltLogicalExpressions_ = config.getParameter< std::vector< std::string > >( "hltPaths" );
00075       errorReplyHlt_         = config.getParameter< bool >( "errorReplyHlt" );
00076       if ( config.exists( "hltDBKey" ) ) hltDBKey_ = config.getParameter< std::string >( "hltDBKey" );
00077     } else {
00078       onHlt_ = false;
00079     }
00080     if ( ! onDcs_ && ! onGt_ && ! onL1_ && ! onHlt_ ) on_      = false;
00081     else                                              watchDB_ = new edm::ESWatcher< AlCaRecoTriggerBitsRcd> ;
00082   }
00083 
00084 }
00085 
00086 
00088 GenericTriggerEventFlag::~GenericTriggerEventFlag()
00089 {
00090 
00091   if ( on_ ) delete watchDB_;
00092 
00093 }
00094 
00095 
00097 void GenericTriggerEventFlag::initRun( const edm::Run & run, const edm::EventSetup & setup )
00098 {
00099 
00100   // FIXME Can this stay safely in the run loop, or does it need to go to the event loop?
00101   // Means: Are the event setups identical?
00102   if ( watchDB_->check( setup ) ) {
00103     if ( onGt_ && gtDBKey_.size() > 0 ) {
00104       const std::vector< std::string > exprs( expressionsFromDB( gtDBKey_, setup ) );
00105       if ( exprs.empty() || exprs.at( 0 ) != configError_ ) gtLogicalExpressions_ = exprs;
00106     }
00107     if ( onL1_ && l1DBKey_.size() > 0 ) {
00108       const std::vector< std::string > exprs( expressionsFromDB( l1DBKey_, setup ) );
00109       if ( exprs.empty() || exprs.at( 0 ) != configError_ ) l1LogicalExpressions_ = exprs;
00110     }
00111     if ( onHlt_ && hltDBKey_.size() > 0 ) {
00112       const std::vector< std::string > exprs( expressionsFromDB( hltDBKey_, setup ) );
00113       if ( exprs.empty() || exprs.at( 0 ) != configError_ ) hltLogicalExpressions_ = exprs;
00114     }
00115   }
00116 
00117   hltConfigInit_ = false;
00118   if ( onHlt_ ) {
00119     if ( hltInputTag_.process().size() == 0 ) {
00120       if ( verbose_ > 0 ) edm::LogError( "GenericTriggerEventFlag" ) << "HLT TriggerResults InputTag \"" << hltInputTag_.encode() << "\" specifies no process";
00121     } else {
00122       bool hltChanged( false );
00123       if ( ! hltConfig_.init( run, setup, hltInputTag_.process(), hltChanged ) ) {
00124         if ( verbose_ > 0 ) edm::LogError( "GenericTriggerEventFlag" ) << "HLT config initialization error with process name \"" << hltInputTag_.process() << "\"";
00125       } else if ( hltConfig_.size() <= 0 ) {
00126         if ( verbose_ > 0 ) edm::LogError( "GenericTriggerEventFlag" ) << "HLT config size error";
00127       } else hltConfigInit_ = true;
00128     }
00129   }
00130 
00131 }
00132 
00133 
00135 bool GenericTriggerEventFlag::accept( const edm::Event & event, const edm::EventSetup & setup )
00136 {
00137 
00138   if ( ! on_ ) return true;
00139 
00140   // Determine decision
00141   if ( andOr_ ) return ( acceptDcs( event ) || acceptGt( event ) || acceptL1( event, setup ) || acceptHlt( event ) );
00142   return ( acceptDcs( event ) && acceptGt( event ) && acceptL1( event, setup ) && acceptHlt( event ) );
00143 
00144 }
00145 
00146 
00147 bool GenericTriggerEventFlag::acceptDcs( const edm::Event & event )
00148 {
00149 
00150   // An empty DCS partitions list acts as switch.
00151   if ( ! onDcs_ || dcsPartitions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
00152 
00153   // Accessing the DcsStatusCollection
00154   edm::Handle< DcsStatusCollection > dcsStatus;
00155   event.getByLabel( dcsInputTag_, dcsStatus );
00156   if ( ! dcsStatus.isValid() ) {
00157     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode() << "\" not in event ==> decision: " << errorReplyDcs_;
00158     return errorReplyDcs_;
00159   }
00160   if ( ( *dcsStatus ).size() == 0 ) {
00161     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode() << "\" empty ==> decision: " << errorReplyDcs_;
00162     return errorReplyDcs_;
00163   }
00164 
00165   // Determine decision of DCS partition combination and return
00166   if ( andOrDcs_ ) { // OR combination
00167     for ( std::vector< int >::const_iterator partitionNumber = dcsPartitions_.begin(); partitionNumber != dcsPartitions_.end(); ++partitionNumber ) {
00168       if ( acceptDcsPartition( dcsStatus, *partitionNumber ) ) return true;
00169     }
00170     return false;
00171   }
00172   for ( std::vector< int >::const_iterator partitionNumber = dcsPartitions_.begin(); partitionNumber != dcsPartitions_.end(); ++partitionNumber ) {
00173     if ( ! acceptDcsPartition( dcsStatus, *partitionNumber ) ) return false;
00174   }
00175   return true;
00176 
00177 }
00178 
00179 
00180 bool GenericTriggerEventFlag::acceptDcsPartition( const edm::Handle< DcsStatusCollection > & dcsStatus, int dcsPartition ) const
00181 {
00182 
00183   // Error checks
00184   switch( dcsPartition ) {
00185     case DcsStatus::EBp   :
00186     case DcsStatus::EBm   :
00187     case DcsStatus::EEp   :
00188     case DcsStatus::EEm   :
00189     case DcsStatus::HBHEa :
00190     case DcsStatus::HBHEb :
00191     case DcsStatus::HBHEc :
00192     case DcsStatus::HF    :
00193     case DcsStatus::HO    :
00194     case DcsStatus::RPC   :
00195     case DcsStatus::DT0   :
00196     case DcsStatus::DTp   :
00197     case DcsStatus::DTm   :
00198     case DcsStatus::CSCp  :
00199     case DcsStatus::CSCm  :
00200     case DcsStatus::CASTOR:
00201     case DcsStatus::TIBTID:
00202     case DcsStatus::TOB   :
00203     case DcsStatus::TECp  :
00204     case DcsStatus::TECm  :
00205     case DcsStatus::BPIX  :
00206     case DcsStatus::FPIX  :
00207     case DcsStatus::ESp   :
00208     case DcsStatus::ESm   :
00209       break;
00210     default:
00211       if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "DCS partition number \"" << dcsPartition << "\" does not exist ==> decision: " << errorReplyDcs_;
00212       return errorReplyDcs_;
00213   }
00214 
00215   // Determine decision
00216   return dcsStatus->at( 0 ).ready( dcsPartition );
00217 
00218 }
00219 
00220 
00222 bool GenericTriggerEventFlag::acceptGt( const edm::Event & event )
00223 {
00224 
00225   // An empty GT status bits logical expressions list acts as switch.
00226   if ( ! onGt_ || gtLogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
00227 
00228   // Accessing the L1GlobalTriggerReadoutRecord
00229   edm::Handle< L1GlobalTriggerReadoutRecord > gtReadoutRecord;
00230   event.getByLabel( gtInputTag_, gtReadoutRecord );
00231   if ( ! gtReadoutRecord.isValid() ) {
00232     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "L1GlobalTriggerReadoutRecord product with InputTag \"" << gtInputTag_.encode() << "\" not in event ==> decision: " << errorReplyGt_;
00233     return errorReplyGt_;
00234   }
00235 
00236   // Determine decision of GT status bits logical expression combination and return
00237   if ( andOrGt_ ) { // OR combination
00238     for ( std::vector< std::string >::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin(); gtLogicalExpression != gtLogicalExpressions_.end(); ++gtLogicalExpression ) {
00239       if ( acceptGtLogicalExpression( gtReadoutRecord, *gtLogicalExpression ) ) return true;
00240     }
00241     return false;
00242   }
00243   for ( std::vector< std::string >::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin(); gtLogicalExpression != gtLogicalExpressions_.end(); ++gtLogicalExpression ) {
00244     if ( ! acceptGtLogicalExpression( gtReadoutRecord, *gtLogicalExpression ) ) return false;
00245   }
00246   return true;
00247 
00248 }
00249 
00250 
00252 bool GenericTriggerEventFlag::acceptGtLogicalExpression( const edm::Handle< L1GlobalTriggerReadoutRecord > & gtReadoutRecord, std::string gtLogicalExpression )
00253 {
00254 
00255   // Check empty std::strings
00256   if ( gtLogicalExpression.empty() ) {
00257     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty logical expression ==> decision: " << errorReplyGt_;
00258     return errorReplyGt_;
00259   }
00260 
00261   // Negated paths
00262   bool negExpr( negate( gtLogicalExpression ) );
00263   if ( negExpr && gtLogicalExpression.empty() ) {
00264     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty (negated) logical expression ==> decision: " << errorReplyGt_;
00265     return errorReplyGt_;
00266   }
00267 
00268   // Parse logical expression and determine GT status bit decision
00269   L1GtLogicParser gtAlgoLogicParser( gtLogicalExpression );
00270   // Loop over status bits
00271   for ( size_t iStatusBit = 0; iStatusBit < gtAlgoLogicParser.operandTokenVector().size(); ++iStatusBit ) {
00272     const std::string gtStatusBit( gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenName );
00273     // Manipulate status bit decision as stored in the parser
00274     bool decision;
00275     // Hard-coded status bits!!!
00276     if ( gtStatusBit == "PhysDecl" || gtStatusBit == "PhysicsDeclared" ) {
00277       decision = ( gtReadoutRecord->gtFdlWord().physicsDeclared() == 1 );
00278     } else {
00279       if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "GT status bit \"" << gtStatusBit << "\" is not defined ==> decision: " << errorReplyGt_;
00280       decision = errorReplyDcs_;
00281     }
00282     gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenResult = decision;
00283   }
00284 
00285   // Determine decision
00286   const bool gtDecision( gtAlgoLogicParser.expressionResult() );
00287   return negExpr ? ( ! gtDecision ) : gtDecision;
00288 
00289 }
00290 
00291 
00293 bool GenericTriggerEventFlag::acceptL1( const edm::Event & event, const edm::EventSetup & setup )
00294 {
00295 
00296   // An empty L1 logical expressions list acts as switch.
00297   if ( ! onL1_ || l1LogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
00298 
00299   // Getting the L1 event setup
00300   l1Gt_.retrieveL1EventSetup( setup ); // FIXME This can possibly go to initRun()
00301 
00302   // Determine decision of L1 logical expression combination and return
00303   if ( andOrL1_ ) { // OR combination
00304     for ( std::vector< std::string >::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin(); l1LogicalExpression != l1LogicalExpressions_.end(); ++l1LogicalExpression ) {
00305       if ( acceptL1LogicalExpression( event, *l1LogicalExpression ) ) return true;
00306     }
00307     return false;
00308   }
00309   for ( std::vector< std::string >::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin(); l1LogicalExpression != l1LogicalExpressions_.end(); ++l1LogicalExpression ) {
00310     if ( ! acceptL1LogicalExpression( event, *l1LogicalExpression ) ) return false;
00311   }
00312   return true;
00313 
00314 }
00315 
00316 
00318 bool GenericTriggerEventFlag::acceptL1LogicalExpression( const edm::Event & event, std::string l1LogicalExpression )
00319 {
00320 
00321   // Check empty std::strings
00322   if ( l1LogicalExpression.empty() ) {
00323     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty logical expression ==> decision: " << errorReplyL1_;
00324     return errorReplyL1_;
00325   }
00326 
00327   // Negated logical expression
00328   bool negExpr( negate( l1LogicalExpression ) );
00329   if ( negExpr && l1LogicalExpression.empty() ) {
00330     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty (negated) logical expression ==> decision: " << errorReplyL1_;
00331     return errorReplyL1_;
00332   }
00333 
00334   // Parse logical expression and determine L1 decision
00335   L1GtLogicParser l1AlgoLogicParser( l1LogicalExpression );
00336   // Loop over algorithms
00337   for ( size_t iAlgorithm = 0; iAlgorithm < l1AlgoLogicParser.operandTokenVector().size(); ++iAlgorithm ) {
00338     const std::string l1AlgoName( l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenName );
00339     int error( -1 );
00340     const bool decision( l1Gt_.decision( event, l1AlgoName, error ) );
00341     // Error checks
00342     if ( error != 0 ) {
00343       if ( verbose_ > 2 ) {
00344         if ( error == 1 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "L1 algorithm \"" << l1AlgoName << "\" does not exist in the L1 menu ==> decision: "                                          << errorReplyL1_;
00345         else              edm::LogWarning( "GenericTriggerEventFlag" ) << "L1 algorithm \"" << l1AlgoName << "\" received error code " << error << " from L1GtUtils::decisionBeforeMask ==> decision: " << errorReplyL1_;
00346       }
00347       l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenResult = errorReplyL1_;
00348       continue;
00349     }
00350     // Manipulate algo decision as stored in the parser
00351     l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenResult = decision;
00352   }
00353 
00354   // Return decision
00355   const bool l1Decision( l1AlgoLogicParser.expressionResult() );
00356   return negExpr ? ( ! l1Decision ) : l1Decision;
00357 
00358 }
00359 
00360 
00362 bool GenericTriggerEventFlag::acceptHlt( const edm::Event & event )
00363 {
00364 
00365   // An empty HLT logical expressions list acts as switch.
00366   if ( ! onHlt_ || hltLogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
00367 
00368   // Checking the HLT configuration,
00369   if ( ! hltConfigInit_ ) {
00370     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "HLT config error ==> decision: " << errorReplyHlt_;
00371     return errorReplyHlt_;
00372   }
00373 
00374   // Accessing the TriggerResults
00375   edm::Handle< edm::TriggerResults > hltTriggerResults;
00376   event.getByLabel( hltInputTag_, hltTriggerResults );
00377   if ( ! hltTriggerResults.isValid() ) {
00378     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "TriggerResults product with InputTag \"" << hltInputTag_.encode() << "\" not in event ==> decision: " << errorReplyHlt_;
00379     return errorReplyHlt_;
00380   }
00381   if ( ( *hltTriggerResults ).size() == 0 ) {
00382     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "TriggerResults product with InputTag \"" << hltInputTag_.encode() << "\" empty ==> decision: " << errorReplyHlt_;
00383     return errorReplyDcs_;
00384   }
00385 
00386   // Determine decision of HLT logical expression combination and return
00387   if ( andOrHlt_ ) { // OR combination
00388     for ( std::vector< std::string >::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin(); hltLogicalExpression != hltLogicalExpressions_.end(); ++hltLogicalExpression ) {
00389       if ( acceptHltLogicalExpression( hltTriggerResults, *hltLogicalExpression ) ) return true;
00390     }
00391     return false;
00392   }
00393   for ( std::vector< std::string >::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin(); hltLogicalExpression != hltLogicalExpressions_.end(); ++hltLogicalExpression ) {
00394     if ( ! acceptHltLogicalExpression( hltTriggerResults, *hltLogicalExpression ) ) return false;
00395   }
00396   return true;
00397 
00398 }
00399 
00400 
00402 bool GenericTriggerEventFlag::acceptHltLogicalExpression( const edm::Handle< edm::TriggerResults > & hltTriggerResults, std::string hltLogicalExpression ) const
00403 {
00404 
00405   // Check empty std::strings
00406   if ( hltLogicalExpression.empty() ) {
00407     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty logical expression ==> decision: " << errorReplyHlt_;
00408     return errorReplyHlt_;
00409   }
00410 
00411   // Negated paths
00412   bool negExpr( negate( hltLogicalExpression ) );
00413   if ( negExpr && hltLogicalExpression.empty() ) {
00414     if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "Empty (negated) logical expression ==> decision: " << errorReplyHlt_;
00415     return errorReplyHlt_;
00416   }
00417 
00418   // Parse logical expression and determine HLT decision
00419   L1GtLogicParser hltAlgoLogicParser( hltLogicalExpression );
00420   // Loop over paths
00421   for ( size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath ) {
00422     const std::string hltPathName( hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenName );
00423     const unsigned indexPath( hltConfig_.triggerIndex( hltPathName ) );
00424     // Further error checks
00425     if ( indexPath == hltConfig_.size() ) {
00426       if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "HLT path \"" << hltPathName << "\" is not found in process " << hltInputTag_.process() << " ==> decision: " << errorReplyHlt_;
00427       hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = errorReplyHlt_;
00428       continue;
00429     }
00430     if ( hltTriggerResults->error( indexPath ) ) {
00431       if ( verbose_ > 2 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "HLT path \"" << hltPathName << "\" in error ==> decision: " << errorReplyHlt_;
00432       hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = errorReplyHlt_;
00433       continue;
00434     }
00435     // Manipulate algo decision as stored in the parser
00436     const bool decision( hltTriggerResults->accept( indexPath ) );
00437     hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = decision;
00438   }
00439 
00440   // Determine decision
00441   const bool hltDecision( hltAlgoLogicParser.expressionResult() );
00442   return negExpr ? ( ! hltDecision ) : hltDecision;
00443 
00444 }
00445 
00446 
00447 
00449 std::vector< std::string > GenericTriggerEventFlag::expressionsFromDB( const std::string & key, const edm::EventSetup & setup )
00450 {
00451 
00452   edm::ESHandle< AlCaRecoTriggerBits > logicalExpressions;
00453   setup.get< AlCaRecoTriggerBitsRcd >().get( logicalExpressions );
00454   const std::map< std::string, std::string > & expressionMap = logicalExpressions->m_alcarecoToTrig;
00455   std::map< std::string, std::string >::const_iterator listIter = expressionMap.find( key );
00456   if ( listIter == expressionMap.end() ) {
00457     if ( verbose_ > 0 ) edm::LogWarning( "GenericTriggerEventFlag" ) << "No logical expressions found under key " << key << " in 'AlCaRecoTriggerBitsRcd'";
00458     return std::vector< std::string >( 1, configError_ );
00459   }
00460   return logicalExpressions->decompose( listIter->second );
00461 
00462 }
00463 
00464 
00465 
00467 bool GenericTriggerEventFlag::negate( std::string & word ) const
00468 {
00469 
00470   bool negate( false );
00471   if ( word.at( 0 ) == '~' ) {
00472     negate = true;
00473     word.erase( 0, 1 );
00474   }
00475   return negate;
00476 
00477 }