CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TriggerHelper.cc
Go to the documentation of this file.
1 //
2 //
3 
4 
6 
8 
12 #include <string>
13 #include <vector>
14 
15 
16 
19  : watchDB_( 0 )
20  , gtDBKey_( "" )
21  , l1DBKey_( "" )
22  , hltDBKey_( "" )
23  , on_( true )
24  , onDcs_( true )
25  , onGt_( true )
26  , onL1_( true )
27  , onHlt_( true )
28  , configError_( "CONFIG_ERROR" )
29 {
30 
31  // General switch(es)
32  if ( config.exists( "andOr" ) ) {
33  andOr_ = config.getParameter< bool >( "andOr" );
34  } else {
35  on_ = false;
36  onDcs_ = false;
37  onGt_ = false;
38  onL1_ = false;
39  onHlt_ = false;
40  }
41 
42  if ( on_ ) {
43  if ( config.exists( "andOrDcs" ) ) {
44  andOrDcs_ = config.getParameter< bool >( "andOrDcs" );
45  dcsInputTag_ = config.getParameter< edm::InputTag >( "dcsInputTag" );
46  dcsPartitions_ = config.getParameter< std::vector< int > >( "dcsPartitions" );
47  errorReplyDcs_ = config.getParameter< bool >( "errorReplyDcs" );
48  } else {
49  onDcs_ = false;
50  }
51  if ( config.exists( "andOrGt" ) ) {
52  andOrGt_ = config.getParameter< bool >( "andOrGt" );
53  gtInputTag_ = config.getParameter< edm::InputTag >( "gtInputTag" );
54  gtLogicalExpressions_ = config.getParameter< std::vector< std::string > >( "gtStatusBits" );
55  errorReplyGt_ = config.getParameter< bool >( "errorReplyGt" );
56  if ( config.exists( "gtDBKey" ) ) gtDBKey_ = config.getParameter< std::string >( "gtDBKey" );
57  } else {
58  onGt_ = false;
59  }
60  if ( config.exists( "andOrL1" ) ) {
61  andOrL1_ = config.getParameter< bool >( "andOrL1" );
62  l1LogicalExpressions_ = config.getParameter< std::vector< std::string > >( "l1Algorithms" );
63  errorReplyL1_ = config.getParameter< bool >( "errorReplyL1" );
64  if ( config.exists( "l1DBKey" ) ) l1DBKey_ = config.getParameter< std::string >( "l1DBKey" );
65  } else {
66  onL1_ = false;
67  }
68  if ( config.exists( "andOrHlt" ) ) {
69  andOrHlt_ = config.getParameter< bool >( "andOrHlt" );
70  hltInputTag_ = config.getParameter< edm::InputTag >( "hltInputTag" );
71  hltLogicalExpressions_ = config.getParameter< std::vector< std::string > >( "hltPaths" );
72  errorReplyHlt_ = config.getParameter< bool >( "errorReplyHlt" );
73  if ( config.exists( "hltDBKey" ) ) hltDBKey_ = config.getParameter< std::string >( "hltDBKey" );
74  } else {
75  onHlt_ = false;
76  }
77  if ( ! onDcs_ && ! onGt_ && ! onL1_ && ! onHlt_ ) on_ = false;
79  }
80 
81 }
82 
83 
86 {
87 
88  if ( on_ ) delete watchDB_;
89 
90 }
91 
92 
95 {
96 
97  // FIXME Can this stay safely in the run loop, or does it need to go to the event loop?
98  // Means: Are the event setups identical?
99  if ( watchDB_->check( setup ) ) {
100  if ( onGt_ && gtDBKey_.size() > 0 ) {
101  const std::vector< std::string > exprs( expressionsFromDB( gtDBKey_, setup ) );
102  if ( exprs.empty() || exprs.at( 0 ) != configError_ ) gtLogicalExpressions_ = exprs;
103  }
104  if ( onL1_ && l1DBKey_.size() > 0 ) {
105  const std::vector< std::string > exprs( expressionsFromDB( l1DBKey_, setup ) );
106  if ( exprs.empty() || exprs.at( 0 ) != configError_ ) l1LogicalExpressions_ = exprs;
107  }
108  if ( onHlt_ && hltDBKey_.size() > 0 ) {
109  const std::vector< std::string > exprs( expressionsFromDB( hltDBKey_, setup ) );
110  if ( exprs.empty() || exprs.at( 0 ) != configError_ ) hltLogicalExpressions_ = exprs;
111  }
112  }
113 
114  hltConfigInit_ = false;
115  if ( onHlt_ ) {
116  if ( hltInputTag_.process().size() == 0 ) {
117  edm::LogError( "TriggerHelper" ) << "HLT TriggerResults InputTag \"" << hltInputTag_.encode() << "\" specifies no process";
118  } else {
119  bool hltChanged( false );
120  if ( ! hltConfig_.init( run, setup, hltInputTag_.process(), hltChanged ) ) {
121  edm::LogError( "TriggerHelper" ) << "HLT config initialization error with process name \"" << hltInputTag_.process() << "\"";
122  } else if ( hltConfig_.size() <= 0 ) {
123  edm::LogError( "TriggerHelper" ) << "HLT config size error";
124  } else hltConfigInit_ = true;
125  }
126  }
127 
128 }
129 
130 
133 {
134 
135  if ( ! on_ ) return true;
136 
137  // Determine decision
138  if ( andOr_ ) return ( acceptDcs( event ) || acceptGt( event ) || acceptL1( event, setup ) || acceptHlt( event ) );
139  return ( acceptDcs( event ) && acceptGt( event ) && acceptL1( event, setup ) && acceptHlt( event ) );
140 
141 }
142 
143 
145 {
146 
147  // An empty DCS partitions list acts as switch.
148  if ( ! onDcs_ || dcsPartitions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
149 
150  // Accessing the DcsStatusCollection
152  event.getByLabel( dcsInputTag_, dcsStatus );
153  if ( ! dcsStatus.isValid() ) {
154  edm::LogError( "TriggerHelper" ) << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode() << "\" not in event ==> decision: " << errorReplyDcs_;
155  return errorReplyDcs_;
156  }
157 
158  // Determine decision of DCS partition combination and return
159  if ( andOrDcs_ ) { // OR combination
160  for ( std::vector< int >::const_iterator partitionNumber = dcsPartitions_.begin(); partitionNumber != dcsPartitions_.end(); ++partitionNumber ) {
161  if ( acceptDcsPartition( dcsStatus, *partitionNumber ) ) return true;
162  }
163  return false;
164  }
165  for ( std::vector< int >::const_iterator partitionNumber = dcsPartitions_.begin(); partitionNumber != dcsPartitions_.end(); ++partitionNumber ) {
166  if ( ! acceptDcsPartition( dcsStatus, *partitionNumber ) ) return false;
167  }
168  return true;
169 
170 }
171 
172 
173 bool TriggerHelper::acceptDcsPartition( const edm::Handle< DcsStatusCollection > & dcsStatus, int dcsPartition ) const
174 {
175 
176  // Error checks
177  switch( dcsPartition ) {
178  case DcsStatus::EBp :
179  case DcsStatus::EBm :
180  case DcsStatus::EEp :
181  case DcsStatus::EEm :
182  case DcsStatus::HBHEa :
183  case DcsStatus::HBHEb :
184  case DcsStatus::HBHEc :
185  case DcsStatus::HF :
186  case DcsStatus::HO :
187  case DcsStatus::RPC :
188  case DcsStatus::DT0 :
189  case DcsStatus::DTp :
190  case DcsStatus::DTm :
191  case DcsStatus::CSCp :
192  case DcsStatus::CSCm :
193  case DcsStatus::CASTOR:
194  case DcsStatus::TIBTID:
195  case DcsStatus::TOB :
196  case DcsStatus::TECp :
197  case DcsStatus::TECm :
198  case DcsStatus::BPIX :
199  case DcsStatus::FPIX :
200  case DcsStatus::ESp :
201  case DcsStatus::ESm :
202  break;
203  default:
204  edm::LogError( "TriggerHelper" ) << "DCS partition number \"" << dcsPartition << "\" does not exist ==> decision: " << errorReplyDcs_;
205  return errorReplyDcs_;
206  }
207 
208  // Determine decision
209  return dcsStatus->at( 0 ).ready( dcsPartition );
210 
211 }
212 
213 
216 {
217 
218  // An empty GT status bits logical expressions list acts as switch.
219  if ( ! onGt_ || gtLogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
220 
221  // Accessing the L1GlobalTriggerReadoutRecord
223  event.getByLabel( gtInputTag_, gtReadoutRecord );
224  if ( ! gtReadoutRecord.isValid() ) {
225  edm::LogError( "TriggerHelper" ) << "L1GlobalTriggerReadoutRecord product with InputTag \"" << gtInputTag_.encode() << "\" not in event ==> decision: " << errorReplyGt_;
226  return errorReplyGt_;
227  }
228 
229  // Determine decision of GT status bits logical expression combination and return
230  if ( andOrGt_ ) { // OR combination
231  for ( std::vector< std::string >::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin(); gtLogicalExpression != gtLogicalExpressions_.end(); ++gtLogicalExpression ) {
232  if ( acceptGtLogicalExpression( gtReadoutRecord, *gtLogicalExpression ) ) return true;
233  }
234  return false;
235  }
236  for ( std::vector< std::string >::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin(); gtLogicalExpression != gtLogicalExpressions_.end(); ++gtLogicalExpression ) {
237  if ( ! acceptGtLogicalExpression( gtReadoutRecord, *gtLogicalExpression ) ) return false;
238  }
239  return true;
240 
241 }
242 
243 
246 {
247 
248  // Check empty std::strings
249  if ( gtLogicalExpression.empty() ) {
250  edm::LogError( "TriggerHelper" ) << "Empty logical expression ==> decision: " << errorReplyGt_;
251  return errorReplyGt_;
252  }
253 
254  // Negated paths
255  bool negExpr( negate( gtLogicalExpression ) );
256  if ( negExpr && gtLogicalExpression.empty() ) {
257  edm::LogError( "TriggerHelper" ) << "Empty (negated) logical expression ==> decision: " << errorReplyGt_;
258  return errorReplyGt_;
259  }
260 
261  // Parse logical expression and determine GT status bit decision
262  L1GtLogicParser gtAlgoLogicParser( gtLogicalExpression );
263  // Loop over status bits
264  for ( size_t iStatusBit = 0; iStatusBit < gtAlgoLogicParser.operandTokenVector().size(); ++iStatusBit ) {
265  const std::string gtStatusBit( gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenName );
266  // Manipulate status bit decision as stored in the parser
267  bool decision;
268  // Hard-coded status bits!!!
269  if ( gtStatusBit == "PhysDecl" || gtStatusBit == "PhysicsDeclared" ) {
270  decision = ( gtReadoutRecord->gtFdlWord().physicsDeclared() == 1 );
271  } else {
272  edm::LogError( "TriggerHelper" ) << "GT status bit \"" << gtStatusBit << "\" is not defined ==> decision: " << errorReplyGt_;
273  decision = errorReplyDcs_;
274  }
275  gtAlgoLogicParser.operandTokenVector().at( iStatusBit ).tokenResult = decision;
276  }
277 
278  // Determine decision
279  const bool gtDecision( gtAlgoLogicParser.expressionResult() );
280  return negExpr ? ( ! gtDecision ) : gtDecision;
281 
282 }
283 
284 
287 {
288 
289  // An empty L1 logical expressions list acts as switch.
290  if ( ! onL1_ || l1LogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
291 
292  // Getting the L1 event setup
293  l1Gt_->retrieveL1EventSetup( setup ); // FIXME This can possibly go to initRun()
294 
295  // Determine decision of L1 logical expression combination and return
296  if ( andOrL1_ ) { // OR combination
297  for ( std::vector< std::string >::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin(); l1LogicalExpression != l1LogicalExpressions_.end(); ++l1LogicalExpression ) {
298  if ( acceptL1LogicalExpression( event, *l1LogicalExpression ) ) return true;
299  }
300  return false;
301  }
302  for ( std::vector< std::string >::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin(); l1LogicalExpression != l1LogicalExpressions_.end(); ++l1LogicalExpression ) {
303  if ( ! acceptL1LogicalExpression( event, *l1LogicalExpression ) ) return false;
304  }
305  return true;
306 
307 }
308 
309 
312 {
313 
314  // Check empty std::strings
315  if ( l1LogicalExpression.empty() ) {
316  edm::LogError( "TriggerHelper" ) << "Empty logical expression ==> decision: " << errorReplyL1_;
317  return errorReplyL1_;
318  }
319 
320  // Negated logical expression
321  bool negExpr( negate( l1LogicalExpression ) );
322  if ( negExpr && l1LogicalExpression.empty() ) {
323  edm::LogError( "TriggerHelper" ) << "Empty (negated) logical expression ==> decision: " << errorReplyL1_;
324  return errorReplyL1_;
325  }
326 
327  // Parse logical expression and determine L1 decision
328  L1GtLogicParser l1AlgoLogicParser( l1LogicalExpression );
329  // Loop over algorithms
330  for ( size_t iAlgorithm = 0; iAlgorithm < l1AlgoLogicParser.operandTokenVector().size(); ++iAlgorithm ) {
331  const std::string l1AlgoName( l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenName );
332  int error( -1 );
333  const bool decision( l1Gt_->decision( event, l1AlgoName, error ) );
334  // Error checks
335  if ( error != 0 ) {
336  if ( error == 1 ) edm::LogError( "TriggerHelper" ) << "L1 algorithm \"" << l1AlgoName << "\" does not exist in the L1 menu ==> decision: " << errorReplyL1_;
337  else edm::LogError( "TriggerHelper" ) << "L1 algorithm \"" << l1AlgoName << "\" received error code " << error << " from L1GtUtils::decisionBeforeMask ==> decision: " << errorReplyL1_;
338  l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenResult = errorReplyL1_;
339  continue;
340  }
341  // Manipulate algo decision as stored in the parser
342  l1AlgoLogicParser.operandTokenVector().at( iAlgorithm ).tokenResult = decision;
343  }
344 
345  // Return decision
346  const bool l1Decision( l1AlgoLogicParser.expressionResult() );
347  return negExpr ? ( ! l1Decision ) : l1Decision;
348 
349 }
350 
351 
354 {
355 
356  // An empty HLT logical expressions list acts as switch.
357  if ( ! onHlt_ || hltLogicalExpressions_.empty() ) return ( ! andOr_ ); // logically neutral, depending on base logical connective
358 
359  // Checking the HLT configuration,
360  if ( ! hltConfigInit_ ) {
361  edm::LogError( "TriggerHelper" ) << "HLT config error ==> decision: " << errorReplyHlt_;
362  return errorReplyHlt_;
363  }
364 
365  // Accessing the TriggerResults
366  edm::Handle< edm::TriggerResults > hltTriggerResults;
367  event.getByLabel( hltInputTag_, hltTriggerResults );
368  if ( ! hltTriggerResults.isValid() ) {
369  edm::LogError( "TriggerHelper" ) << "TriggerResults product with InputTag \"" << hltInputTag_.encode() << "\" not in event ==> decision: " << errorReplyHlt_;
370  return errorReplyHlt_;
371  }
372 
373  // Determine decision of HLT logical expression combination and return
374  if ( andOrHlt_ ) { // OR combination
375  for ( std::vector< std::string >::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin(); hltLogicalExpression != hltLogicalExpressions_.end(); ++hltLogicalExpression ) {
376  if ( acceptHltLogicalExpression( hltTriggerResults, *hltLogicalExpression ) ) return true;
377  }
378  return false;
379  }
380  for ( std::vector< std::string >::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin(); hltLogicalExpression != hltLogicalExpressions_.end(); ++hltLogicalExpression ) {
381  if ( ! acceptHltLogicalExpression( hltTriggerResults, *hltLogicalExpression ) ) return false;
382  }
383  return true;
384 
385 }
386 
387 
389 bool TriggerHelper::acceptHltLogicalExpression( const edm::Handle< edm::TriggerResults > & hltTriggerResults, std::string hltLogicalExpression ) const
390 {
391 
392  // Check empty std::strings
393  if ( hltLogicalExpression.empty() ) {
394  edm::LogError( "TriggerHelper" ) << "Empty logical expression ==> decision: " << errorReplyHlt_;
395  return errorReplyHlt_;
396  }
397 
398  // Negated paths
399  bool negExpr( negate( hltLogicalExpression ) );
400  if ( negExpr && hltLogicalExpression.empty() ) {
401  edm::LogError( "TriggerHelper" ) << "Empty (negated) logical expression ==> decision: " << errorReplyHlt_;
402  return errorReplyHlt_;
403  }
404 
405  // Parse logical expression and determine HLT decision
406  L1GtLogicParser hltAlgoLogicParser( hltLogicalExpression );
407  // Loop over paths
408  for ( size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath ) {
409  const std::string hltPathName( hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenName );
410  const unsigned indexPath( hltConfig_.triggerIndex( hltPathName ) );
411  // Further error checks
412  if ( indexPath == hltConfig_.size() ) {
413  edm::LogError( "TriggerHelper" ) << "HLT path \"" << hltPathName << "\" is not found in process " << hltInputTag_.process() << " ==> decision: " << errorReplyHlt_;
414  hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = errorReplyHlt_;
415  continue;
416  }
417  if ( hltTriggerResults->error( indexPath ) ) {
418  edm::LogError( "TriggerHelper" ) << "HLT path \"" << hltPathName << "\" in error ==> decision: " << errorReplyHlt_;
419  hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = errorReplyHlt_;
420  continue;
421  }
422  // Manipulate algo decision as stored in the parser
423  const bool decision( hltTriggerResults->accept( indexPath ) );
424  hltAlgoLogicParser.operandTokenVector().at( iPath ).tokenResult = decision;
425  }
426 
427  // Determine decision
428  const bool hltDecision( hltAlgoLogicParser.expressionResult() );
429  return negExpr ? ( ! hltDecision ) : hltDecision;
430 
431 }
432 
433 
434 
436 std::vector< std::string > TriggerHelper::expressionsFromDB( const std::string & key, const edm::EventSetup & setup )
437 {
438 
439  edm::ESHandle< AlCaRecoTriggerBits > logicalExpressions;
440  setup.get< AlCaRecoTriggerBitsRcd >().get( logicalExpressions );
441  const std::map< std::string, std::string > & expressionMap = logicalExpressions->m_alcarecoToTrig;
442  std::map< std::string, std::string >::const_iterator listIter = expressionMap.find( key );
443  if ( listIter == expressionMap.end() ) {
444  edm::LogError( "TriggerHelper" ) << "No logical expressions found under key " << key << " in 'AlCaRecoTriggerBitsRcd'";
445  return std::vector< std::string >( 1, configError_ );
446  }
447  return logicalExpressions->decompose( listIter->second );
448 
449 }
450 
451 
452 
454 bool TriggerHelper::negate( std::string & word ) const
455 {
456 
457  bool negate( false );
458  if ( word.at( 0 ) == '~' ) {
459  negate = true;
460  word.erase( 0, 1 );
461  }
462  return negate;
463 
464 }
unsigned int size() const
number of trigger paths in trigger table
T getParameter(std::string const &) const
std::unique_ptr< L1GtUtils > l1Gt_
Definition: TriggerHelper.h:44
bool acceptGtLogicalExpression(const edm::Handle< L1GlobalTriggerReadoutRecord > &gtReadoutRecord, std::string gtLogicalExpression)
Does this event fulfill this particular GT status bits&#39; logical expression?
bool acceptHltLogicalExpression(const edm::Handle< edm::TriggerResults > &hltTriggerResults, std::string hltLogicalExpression) const
Was this event accepted by this particular HLT paths&#39; logical expression?
bool negate(std::string &word) const
Checks for negated words.
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::string l1DBKey_
Definition: TriggerHelper.h:59
std::vector< int > dcsPartitions_
Definition: TriggerHelper.h:51
const std::string configError_
Definition: TriggerHelper.h:74
std::string encode() const
Definition: InputTag.cc:164
std::vector< std::string > gtLogicalExpressions_
Definition: TriggerHelper.h:56
TriggerHelper(const edm::ParameterSet &config, edm::ConsumesCollector &&iC, T &module)
~TriggerHelper()
To be called from d&#39;tors by &#39;delete&#39;.
unsigned int triggerIndex(const std::string &triggerName) const
slot position of trigger path in trigger table (0 to size-1)
std::string gtDBKey_
Definition: TriggerHelper.h:55
std::vector< OperandToken > & operandTokenVector()
return the vector of operand tokens
bool acceptHlt(const edm::Event &event)
Was this event accepted by the configured HLT logical expression combination?
edm::InputTag hltInputTag_
Definition: TriggerHelper.h:63
std::vector< std::string > l1LogicalExpressions_
Definition: TriggerHelper.h:60
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool isValid() const
Definition: HandleBase.h:75
string key
FastSim: produces sample of signal events, overlayed with premixed minbias events.
bool acceptL1(const edm::Event &event, const edm::EventSetup &setup)
Was this event accepted by the configured L1 logical expression combination?
bool acceptL1LogicalExpression(const edm::Event &event, std::string l1LogicalExpression)
Was this event accepted by this particular L1 algorithms&#39; logical expression?
bool init(const edm::Run &iRun, const edm::EventSetup &iSetup, const std::string &processName, bool &changed)
d&#39;tor
const T & get() const
Definition: EventSetup.h:56
HLTConfigProvider hltConfig_
Definition: TriggerHelper.h:45
edm::InputTag gtInputTag_
Definition: TriggerHelper.h:54
bool acceptDcsPartition(const edm::Handle< DcsStatusCollection > &dcsStatus, int dcsPartition) const
edm::InputTag dcsInputTag_
Definition: TriggerHelper.h:50
bool acceptDcs(const edm::Event &event)
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
std::string const & process() const
Definition: InputTag.h:47
bool acceptGt(const edm::Event &event)
Does this event fulfill the configured GT status logical expression combination?
std::vector< std::string > expressionsFromDB(const std::string &key, const edm::EventSetup &setup)
Reads and returns logical expressions from DB.
void initRun(const edm::Run &run, const edm::EventSetup &setup)
To be called from beginedm::Run() methods.
edm::ESWatcher< AlCaRecoTriggerBitsRcd > * watchDB_
Definition: TriggerHelper.h:43
std::vector< std::string > hltLogicalExpressions_
Definition: TriggerHelper.h:65
std::string hltDBKey_
Definition: TriggerHelper.h:64
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
Definition: Run.h:43
virtual const bool expressionResult() const
bool accept(const edm::Event &event, const edm::EventSetup &setup)
To be called from analyze/filter() methods.