test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
hltDiff.cc
Go to the documentation of this file.
1 /* hltDiff: compare TriggerResults event by event
2  *
3  * Compare two TriggerResults collections event by event.
4  * These can come from two collections in the same file(s), or from two different sets of files.
5  */
6 
7 #include <vector>
8 #include <set>
9 #include <string>
10 #include <iostream>
11 #include <sstream>
12 #include <fstream>
13 #include <stdio.h>
14 #include <iomanip>
15 #include <memory>
16 
17 #include <cstring>
18 #include <unistd.h>
19 #include <getopt.h>
20 #include <stdio.h>
21 #include <math.h>
22 
23 #include <boost/algorithm/string.hpp>
24 #include <boost/filesystem.hpp>
25 
26 #include <TFile.h>
27 #include <TCanvas.h>
28 #include <TH1F.h>
29 #include <TH2F.h>
30 #include <TGraphAsymmErrors.h>
31 
42 
43 
44 void error(std::ostream & out) {
45  out << "Try 'hltDiff --help' for more information" << std::endl;
46 }
47 
48 void error(std::ostream & out, const char * message) {
49  out << message << std::endl;
50  error(out);
51 }
52 
53 void error(std::ostream & out, const std::string & message) {
54  out << message << std::endl;
55  error(out);
56 }
57 
58 
60 public:
61  virtual std::string const & processName() const = 0;
62  virtual unsigned int size() const = 0;
63  virtual unsigned int size(unsigned int trigger) const = 0;
64  virtual std::string const & triggerName(unsigned int trigger) const = 0;
65  virtual unsigned int triggerIndex(unsigned int trigger) const = 0;
66  virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const = 0;
67  virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const = 0;
68  virtual bool prescaler(unsigned int trigger, unsigned int module) const = 0;
69 };
70 
71 
73 public:
75  data_(data),
76  moduleTypes_(size()),
77  prescalers_(size())
78  {
79  for (unsigned int t = 0; t < data_.size(); ++t) {
80  prescalers_[t].resize(size(t));
81  moduleTypes_[t].resize(size(t));
82  for (unsigned int m = 0; m < data_.size(t); ++m) {
84  prescalers_[t][m] = (type == "HLTPrescaler");
85  moduleTypes_[t][m] = &* moduleTypeSet_.insert(std::move(type)).first;
86  }
87  }
88  }
89 
90  virtual std::string const & processName() const override {
91  return data_.processName();
92  }
93 
94  virtual unsigned int size() const override {
95  return data_.size();
96  }
97 
98  virtual unsigned int size(unsigned int trigger) const override {
99  return data_.size(trigger);
100  }
101 
102  virtual std::vector<std::string> const & triggerNames() const {
103  return data_.triggerNames();
104  }
105 
106  virtual std::string const & triggerName(unsigned int trigger) const override {
107  return data_.triggerName(trigger);
108  }
109 
110  virtual unsigned int triggerIndex(unsigned int trigger) const override {
111  return trigger;
112  }
113 
114  virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const override {
115  return data_.moduleLabel(trigger, module);
116  }
117 
118  virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const override {
119  return * moduleTypes_.at(trigger).at(module);
120  }
121 
122  virtual bool prescaler(unsigned int trigger, unsigned int module) const override {
123  return prescalers_.at(trigger).at(module);
124  }
125 
126 private:
128  std::set<std::string> moduleTypeSet_;
129  std::vector<std::vector<std::string const*>> moduleTypes_;
130  std::vector<std::vector<bool>> prescalers_;
131 };
132 
133 
134 const char * event_state(bool state) {
135  return state ? "accepted" : "rejected";
136 }
137 
138 
140 public:
141  enum class Index {
142  First = 0,
143  Second = 1
144  };
145 
146  class View : public HLTConfigInterface {
147  public:
149  config_(config),
150  index_(index)
151  { }
152 
153  virtual std::string const & processName() const override;
154  virtual unsigned int size() const override;
155  virtual unsigned int size(unsigned int trigger) const override;
156  virtual std::string const & triggerName(unsigned int trigger) const override;
157  virtual unsigned int triggerIndex(unsigned int trigger) const override;
158  virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const override;
159  virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const override;
160  virtual bool prescaler(unsigned int trigger, unsigned int module) const override;
161 
162  private:
165  };
166 
167 
169  first_(first),
170  second_(second),
171  firstView_(*this, Index::First),
172  secondView_(*this, Index::Second)
173  {
174  for (unsigned int f = 0; f < first.size(); ++f)
175  for (unsigned int s = 0; s < second.size(); ++s)
176  if (first.triggerName(f) == second.triggerName(s)) {
177  triggerIndices_.push_back(std::make_pair(f, s));
178  break;
179  }
180  }
181 
182  View const & getView(Index index) const {
183  if (index == Index::First)
184  return firstView_;
185  else
186  return secondView_;
187  }
188 
190  if (index == Index::First)
191  return first_.processName();
192  else
193  return second_.processName();
194  }
195 
196  unsigned int size(Index index) const {
197  return triggerIndices_.size();
198  }
199 
200  unsigned int size(Index index, unsigned int trigger) const {
201  if (index == Index::First)
202  return first_.size(trigger);
203  else
204  return second_.size(trigger);
205  }
206 
207  std::string const & triggerName(Index index, unsigned int trigger) const {
208  if (index == Index::First)
209  return first_.triggerName(triggerIndices_.at(trigger).first);
210  else
211  return second_.triggerName(triggerIndices_.at(trigger).second);
212  }
213 
214  unsigned int triggerIndex(Index index, unsigned int trigger) const {
215  if (index == Index::First)
216  return triggerIndices_.at(trigger).first;
217  else
218  return triggerIndices_.at(trigger).second;
219  }
220 
221  std::string const & moduleLabel(Index index, unsigned int trigger, unsigned int module) const {
222  if (index == Index::First)
223  return first_.moduleLabel(triggerIndices_.at(trigger).first, module);
224  else
225  return second_.moduleLabel(triggerIndices_.at(trigger).second, module);
226  }
227 
228  std::string const & moduleType(Index index, unsigned int trigger, unsigned int module) const {
229  if (index == Index::First)
230  return first_.moduleType(triggerIndices_.at(trigger).first, module);
231  else
232  return second_.moduleType(triggerIndices_.at(trigger).second, module);
233  }
234 
235  bool prescaler(Index index, unsigned int trigger, unsigned int module) const {
236  if (index == Index::First)
237  return first_.prescaler(triggerIndices_.at(trigger).first, module);
238  else
239  return second_.prescaler(triggerIndices_.at(trigger).second, module);
240  }
241 
242 private:
245 
248 
249  std::vector<std::pair<unsigned int, unsigned int>> triggerIndices_;
250 };
251 
252 
254  return config_.processName(index_);
255 }
256 
257 unsigned int HLTCommonConfig::View::size() const {
258  return config_.size(index_);
259 }
260 
261 unsigned int HLTCommonConfig::View::size(unsigned int trigger) const {
262  return config_.size(index_, trigger);
263 }
264 
265 std::string const & HLTCommonConfig::View::triggerName(unsigned int trigger) const {
266  return config_.triggerName(index_, trigger);
267 }
268 
269 unsigned int HLTCommonConfig::View::triggerIndex(unsigned int trigger) const {
270  return config_.triggerIndex(index_, trigger);
271 }
272 
273 std::string const & HLTCommonConfig::View::moduleLabel(unsigned int trigger, unsigned int module) const {
274  return config_.moduleLabel(index_, trigger, module);
275 }
276 
277 std::string const & HLTCommonConfig::View::moduleType(unsigned int trigger, unsigned int module) const {
278  return config_.moduleType(index_, trigger, module);
279 }
280 
281 bool HLTCommonConfig::View::prescaler(unsigned int trigger, unsigned int module) const {
282  return config_.prescaler(index_, trigger, module);
283 }
284 
285 
286 enum State {
293 };
294 
295 const char * path_state(State state) {
296  static const char * message[] = { "not run", "accepted", "rejected", "exception", "prescaled", "invalid" };
297 
298  if (state > 0 and state < Invalid)
299  return message[state];
300  else
301  return message[Invalid];
302 }
303 
304 inline
305 State prescaled_state(int state, int path, int module, HLTConfigInterface const & config) {
306  if (state == Fail and config.prescaler(path, module))
307  return Prescaled;
308  return (State) state;
309 }
310 
311 // return a copy of a string denoting an InputTag without the process name
312 // i.e.
313 // "module" --> "module"
314 // "module:instance" --> "module:instance"
315 // "module::process" --> "module"
316 // "module:instance:process" --> "module:instance"
317 //
319  if (std::count(s.begin(), s.end(), ':') == 2) {
320  // remove the process name and the second ':' separator
321  size_t end = s.find_last_of(':');
322  if (end > 0 and s.at(end-1) == ':')
323  // no instance name, remove also the first ':' separator
324  --end;
325  return s.substr(0, end);
326  } else {
327  // no process name, return the string unchanged
328  return s;
329  }
330 }
331 
332 
333 void print_detailed_path_state(std::ostream & out, State state, int path, int module, HLTConfigInterface const & config) {
334  auto const & label = config.moduleLabel(path, module);
335  auto const & type = config.moduleType(path, module);
336 
337  out << "'" << path_state(state) << "'";
338  if (state == Fail)
339  out << " by module " << module << " '" << label << "' [" << type << "]";
340  else if (state == Exception)
341  out << " at module " << module << " '" << label << "' [" << type << "]";
342 }
343 
345  // find the index of the collection of trigger candidates corresponding to the filter
346  unsigned int index = summary.filterIndex(filter);
347 
348  if (index >= summary.sizeFilters()) {
349  // the collection of trigger candidates corresponding to the filter could not be found
350  out << " not found\n";
351  return;
352  }
353 
354  if (summary.filterKeys(index).empty()) {
355  // the collection of trigger candidates corresponding to the filter is empty
356  out << " none\n";
357  return;
358  }
359 
360  for (unsigned int i = 0; i < summary.filterKeys(index).size(); ++i) {
361  auto key = summary.filterKeys(index)[i];
362  auto id = summary.filterIds(index)[i];
363  trigger::TriggerObject const & candidate = summary.getObjects().at(key);
364  out << " "
365  << "filter id: " << id << ", "
366  << "object id: " << candidate.id() << ", "
367  << "pT: " << candidate.pt() << ", "
368  << "eta: " << candidate.eta() << ", "
369  << "phi: " << candidate.phi() << ", "
370  << "mass: " << candidate.mass() << "\n";
371  }
372 }
373 
375  auto iterator = std::find(summary.collectionTags().begin(), summary.collectionTags().end(), tag);
376  if (iterator == summary.collectionTags().end()) {
377  // the collection of trigger candidates could not be found
378  out << " not found\n";
379  return;
380  }
381 
382  unsigned int index = iterator - summary.collectionTags().begin();
383  unsigned int begin = (index == 0) ? 0 : summary.collectionKey(index - 1);
384  unsigned int end = summary.collectionKey(index);
385 
386  if (end == begin) {
387  // the collection of trigger candidates is empty
388  out << " none\n";
389  return;
390  }
391 
392  for (unsigned int key = begin; key < end; ++key) {
393  trigger::TriggerObject const & candidate = summary.getObjects().at(key);
394  out << " "
395  << "object id: " << candidate.id() << ", "
396  << "pT: " << candidate.pt() << ", "
397  << "eta: " << candidate.eta() << ", "
398  << "phi: " << candidate.phi() << ", "
399  << "mass: " << candidate.mass() << "\n";
400  }
401 }
402 
403 
405  std::vector<boost::iterator_range<std::string::const_iterator>> tokens;
406  boost::split(tokens, branch, boost::is_any_of("_."), boost::token_compress_off);
407  return boost::copy_range<std::string>(tokens[3]);
408 }
409 
410 std::unique_ptr<HLTConfigDataEx> getHLTConfigData(fwlite::EventBase const & event, std::string process) {
411  auto const & history = event.processHistory();
412  if (process.empty()) {
413  // determine the process name from the most recent "TriggerResults" object
414  auto const & branch = event.getBranchNameFor( edm::Wrapper<edm::TriggerResults>::typeInfo(), "TriggerResults", "", process.c_str() );
415  process = getProcessNameFromBranch( branch );
416  }
417 
419  if (not history.getConfigurationForProcess(process, config)) {
420  std::cerr << "error: the process " << process << " is not in the Process History" << std::endl;
421  exit(1);
422  }
424  if (pset == nullptr) {
425  std::cerr << "error: the configuration for the process " << process << " is not available in the Provenance" << std::endl;
426  exit(1);
427  }
428  return std::unique_ptr<HLTConfigDataEx>(new HLTConfigDataEx(HLTConfigData(pset)));
429 }
430 
431 
432 struct TriggerDiff {
433  TriggerDiff() : count(0), gained(0), lost(0), internal(0) { }
434 
435  unsigned int count;
436  unsigned int gained;
437  unsigned int lost;
438  unsigned int internal;
439 
440  static
441  std::string format(unsigned int value, char sign = '+') {
442  if (value == 0)
443  return std::string("-");
444 
445  char buffer[12]; // sign, 10 digits, null
446  memset(buffer, 0, 12);
447 
448  unsigned int digit = 10;
449  while (value > 0) {
450  buffer[digit] = value % 10 + 48;
451  value /= 10;
452  --digit;
453  }
454  buffer[digit] = sign;
455 
456  return std::string(buffer + digit);
457  }
458 };
459 
460 std::ostream & operator<<(std::ostream & out, TriggerDiff diff) {
461  out << std::setw(12) << diff.count
462  << std::setw(12) << TriggerDiff::format(diff.gained, '+')
463  << std::setw(12) << TriggerDiff::format(diff.lost, '-')
464  << std::setw(12) << TriggerDiff::format(diff.internal, '~');
465  return out;
466 }
467 
468 
470 {
471 private:
472  static size_t tab_spaces;
473 
474  // static variables and methods for printing specific JSON elements
475  static std::string indent(size_t _nTabs) {
476  std::string str = "\n";
477  while (_nTabs){
478  int nSpaces = tab_spaces;
479  while (nSpaces) {
480  str.push_back(' ');
481  nSpaces--;
482  }
483  _nTabs--;
484  }
485 
486  return str;
487  }
488 
489  static std::string key(const std::string& _key, const std::string& _delim="") {
490  std::string str = "\"\":";
491  str.insert(1, _key);
492  str.append(_delim);
493 
494  return str;
495  }
496 
497  static std::string key_string(const std::string& _key, const std::string& _string, const std::string& _delim="") {
498  std::string str = key(_key, _delim);
499  str.push_back('"');
500  str.append(_string);
501  str.push_back('"');
502  return str;
503  }
504 
505  static std::string key_int(const std::string& _key, int _int, const std::string& _delim="") {
506  std::string str = key(_key, _delim);
507  str.append(std::to_string(_int));
508 
509  return str;
510  }
511 
512  static std::string string(const std::string& _string, const std::string& _delim="") {
513  std::string str = "\"\"";
514  str.insert(1, _string);
515  str.append(_delim);
516 
517  return str;
518  }
519 
520  static std::string list_string(const std::vector<std::string>& _values, const std::string& _delim="") {
521  std::string str = "[";
522  for (std::vector<std::string>::const_iterator it = _values.begin(); it != _values.end(); ++it) {
523  str.append(_delim);
524  str.push_back('"');
525  str.append(*it);
526  str.push_back('"');
527  if (it != --_values.end()) str.push_back(',');
528  }
529  str.append(_delim);
530  str.push_back(']');
531 
532  return str;
533  }
534 
535 public:
536  bool writeJson;
539  // structs holding particular JSON objects
541  std::string file_base; // common part at the beginning of all files
542  std::vector<std::string> files;
544  std::vector<std::string> skipped_triggers;
545 
546  std::string serialise(size_t _indent=0) const {
547  std::ostringstream json;
548  json << indent(_indent); // line
549  json << key_string("file_base", file_base) << ',';
550  json << indent(_indent); // line
551  json << key("files") << list_string(files) << ',';
552  json << indent(_indent); // line
553  json << key_string("process", process) << ',';
554  json << indent(_indent); // line
555  json << key("skipped_triggers") << list_string(skipped_triggers);
556 
557  return json.str();
558  }
559 
561  std::string file0 = files.at(0);
562  // determining the last position at which all filenames have the same character
563  for (size_t i = 0; i < file0.length(); ++i) {
564  bool identicalInAll = true;
565  char character = file0.at(i);
566  for (std::string file : files) {
567  if (file.at(i) == character) continue;
568  identicalInAll = false;
569  break;
570  }
571  if (!identicalInAll) break;
572  file_base.push_back(character);
573  }
574  const unsigned int file_base_len = file_base.length();
575  if (file_base_len < 1) return;
576  // removing the file_base from each filename
577  for (std::string &file : files) {
578  file.erase(0, file_base_len);
579  }
580  }
581 
582  JsonConfigurationBlock() : file_base(""), files(0), process(""), skipped_triggers(0) {}
583  };
584 
588  bool prescales;
589  int events;
590 
591  std::string serialise(size_t _indent=0) const {
592  std::ostringstream json;
593  json << indent(_indent) << key("configuration") << '{'; // line open
594  json << indent(_indent+1) << key("o") << '{'; // line open
595  json << o.serialise(_indent+2); // block
596  json << indent(_indent+1) << "},"; // line close
597  json << indent(_indent+1) << key("n") << '{'; // line open
598  json << n.serialise(_indent+2); // line block
599  json << indent(_indent+1) << "},"; // line close
600  std::string prescales_str = prescales ? "true" : "false";
601  json << indent(_indent+1) << key("prescales") << prescales_str << ','; // line
602  json << indent(_indent+1) << key("events") << events; // line
603  json << indent(_indent) << "}"; // line close
604 
605  return json.str();
606  }
607 
608  JsonConfiguration() : o(), n() {}
609  };
610 
611  struct JsonVars {
612  std::vector<std::string> state;
613  std::vector<std::string> trigger;
614  std::vector<std::pair<int, int> > trigger_passed_count; // <old, new>
615  std::vector<std::string> label;
616  std::vector<std::string> type;
617 
618  std::string serialise(size_t _indent=0) const {
619  std::ostringstream json;
620  json << indent(_indent) << key("vars") << '{'; // line open
621  json << indent(_indent+1) << key("state") << list_string(state) << ','; // line
622  json << indent(_indent+1) << key("trigger") << list_string(trigger) << ','; // line
623  json << indent(_indent+1) << key("trigger_passed_count") << '['; // line
624  for (std::vector<std::pair<int, int> >::const_iterator it = trigger_passed_count.begin(); it != trigger_passed_count.end(); ++it) {
625  json << '{' << key("o") << (*it).first << ',' << key("n") << (*it).second << '}';
626  if (it != trigger_passed_count.end()-1)
627  json << ',';
628  }
629  json << "],";
630  json << indent(_indent+1) << key("label") << list_string(label) << ','; // line
631  json << indent(_indent+1) << key("type") << list_string(type); // line
632  json << indent(_indent) << '}'; // line close
633 
634  return json.str();
635  }
636 
637  JsonVars() : state(0), trigger(0), trigger_passed_count(0), label(0), type(0) {}
638  };
639 
640  // class members
643 
644 private:
645  unsigned int labelId(std::string labelName) {
646  unsigned int id = std::find(vars.label.begin(), vars.label.end(), labelName) - vars.label.begin();
647  if (id < vars.label.size())
648  return id;
649  vars.label.push_back(labelName);
650  return vars.label.size()-1;
651  }
652 
653  unsigned int typeId(std::string typeName) {
654  unsigned int id = std::find(vars.type.begin(), vars.type.end(), typeName) - vars.type.begin();
655  if (id < vars.type.size())
656  return id;
657  vars.type.push_back(typeName);
658  return vars.type.size()-1;
659  }
660 
661 public:
662  struct JsonEventState {
663  State s; // state
664  int m; // module id
665  int l; // label id
666  int t; // type id
667 
668  std::string serialise(size_t _indent=0) const {
669  std::ostringstream json;
670  json << key_int("s", int(s)); // line
671  // No more information needed if the state is 'accepted'
672  if (s == State::Pass) return json.str();
673  json << ',';
674  json << key_int("m", m) << ',';
675  json << key_int("l", l) << ',';
676  json << key_int("t", t);
677 
678  return json.str();
679  }
680 
681  JsonEventState() : s(State::Ready), m(-1), l(-1), t(-1) {}
682  JsonEventState(State _s, int _m, int _l, int _t): s(_s), m(_m), l(_l), t(_t) { }
683  };
684 
686  int tr; // trigger id
689 
690  std::string serialise(size_t _indent=0) const {
691  std::ostringstream json;
692  json << indent(_indent) << key_int("t", tr) << ','; // line
693  json << indent(_indent) << key("o") << '{' << o.serialise() << "},"; // line
694  json << indent(_indent) << key("n") << '{' << n.serialise() << "}"; // line
695 
696  return json.str();
697  }
698 
699  JsonTriggerEventState() : tr(-1), o(), n() {}
700  JsonTriggerEventState(int _tr) : tr(_tr), o(), n() {}
701  };
702 
703  struct JsonEvent {
704  int run;
705  int lumi;
706  int event;
707  std::vector<JsonTriggerEventState> triggerStates;
708 
709  std::string serialise(size_t _indent=0) const {
710  std::ostringstream json;
711  json << indent(_indent) << '{' << "\"r\"" << ':' << run << ",\"l\":" << lumi << ",\"e\":" << event << ",\"t\":["; // line open
712  for (std::vector<JsonTriggerEventState>::const_iterator it = triggerStates.begin(); it != triggerStates.end(); ++it) {
713  json << '{'; // line open
714  json << (*it).serialise(_indent+2); // block
715  json << indent(_indent+1) << '}'; // line close
716  if (it != --triggerStates.end()) json << ',';
717  }
718  json << indent(_indent) << ']' << '}'; // line close
719 
720  return json.str();
721  }
722 
723  JsonEvent(int _run, int _lumi, int _event) :
724  run(_run), lumi(_lumi), event(_event), triggerStates(0) { }
725 
727  // check whether the last trigger is the one
728  if (triggerStates.size() > 0) {
729  JsonTriggerEventState& lastTrigger = triggerStates.back();
730  if (lastTrigger.tr == _tr)
731  return lastTrigger;
732  }
733  triggerStates.push_back(JsonTriggerEventState(_tr));
734  return triggerStates.back();
735  }
736 
737  };
738 
739  // class members
740  std::map<int, std::vector<JsonEvent> > m_run_events;
741 
742  // methods
743  JsonOutputProducer(bool _writeJson, std::string _file_name) :
744  writeJson(_writeJson),
745  out_filename_base(_file_name) {
746  useSingleOutFile = out_filename_base.length() > 0;
747  }
748 
749  JsonEvent& pushEvent(int _run, int _lumi, int _event) {
750  // ensuring that this RUN is present in the producer
751  if ( (m_run_events.count(_run) == 0 && !useSingleOutFile) || m_run_events.size() == 0 )
752  m_run_events.emplace(_run, std::vector<JsonEvent>());
753  std::vector<JsonEvent>& v_events = useSingleOutFile ? m_run_events.begin()->second : m_run_events.at(_run);
754  // check whether the last event is the one
755  if (v_events.size() > 0) {
756  JsonEvent& lastEvent = v_events.back();
757  if (lastEvent.run == _run && lastEvent.lumi == _lumi && lastEvent.event == _event)
758  return lastEvent;
759  }
760  v_events.push_back(JsonEvent(_run, _lumi, _event));
761  return v_events.back();
762  }
763 
764  JsonEventState eventState(State _s, int _m, const std::string& _l, const std::string& _t) {
765  return JsonEventState(_s, _m, this->labelId(_l), this->typeId(_t));
766  }
767 
769  if (useSingleOutFile)
770  return out_filename_base;
771 
772  char name[1000];
773  sprintf(name, "DQM_V0001_R%.9d__OLD_%s__NEW_%s_DQM", _run, configuration.o.process.c_str(), configuration.n.process.c_str());
774 
775  return std::string(name);
776  }
777 
778  void write() {
779  std::set<std::string> filesCreated;
780  for (const auto& runEvents : m_run_events) {
781  const int run = runEvents.first;
782  const std::vector<JsonEvent>& v_events = runEvents.second;
783  // Writing the output to a JSON file
784  std::ofstream out_file;
785  std::string output_name = output_filename_base(run)+=".json";
786  out_file.open(output_name, std::ofstream::out);
787  out_file << '{'; // line open
788  out_file << configuration.serialise(1) << ',';
789  out_file << vars.serialise(1) << ',';
790  // writing block for each event
791  out_file << indent(1) << key("events") << '['; // line open
792  for (std::vector<JsonEvent>::const_iterator it = v_events.begin(); it != v_events.end(); ++it) {
793  out_file << (*it).serialise(2);
794  if (it != --v_events.end()) out_file << ',';
795  }
796  out_file << indent(1) << ']'; // line close
797  out_file << indent(0) << "}"; // line close
798  out_file.close();
799  // Adding file name to the list of created files
800  filesCreated.insert(output_name);
801  }
802 
803  printf("Created the following JSON files:\n");
804  for (const std::string& filename : filesCreated)
805  printf(" %s\n", filename.c_str());
806  }
807 };
809 
810 
812 {
813 private:
815  int run;
816 
817  struct Pair {
818  double v;
819  double e;
820 
821  Pair(double _v, double _e) : v(_v), e(_e) {};
822  Pair(int _v, int _e) : v(_v), e(_e) {};
823  };
824 
825  struct Event {
826  int run;
827  int lumi;
828  int event;
829 
830  Event(int _run, int _lumi, int _event) : run(_run), lumi(_lumi), event(_event) {};
831  bool operator < (const Event& b) const {
832  return std::tie(run, lumi, event) < std::tie(b.run, b.lumi, b.event);
833  }
834  };
835 
836  struct GenericSummary {
838  int id;
840  std::set<Event> v_gained;
841  std::set<Event> v_lost;
842  std::set<Event> v_changed;
843 
844  GenericSummary(int _id, const JsonOutputProducer& _json, const std::vector<std::string>& _names) :
845  json(_json),
846  id(_id) {
847  name = _names.at(id);
848  }
849 
850  int addEntry(const JsonOutputProducer::JsonEvent& _event, const int _triggerIndex) {
851  const JsonOutputProducer::JsonTriggerEventState& state = _event.triggerStates.at(_triggerIndex);
852  const Event event = Event(_event.run, _event.lumi, _event.event);
853  int moduleId = state.o.l;
854  if (state.o.s == State::Pass && state.n.s == State::Fail) {
855  moduleId = state.n.l;
856  v_lost.insert(event);
857  } else
858  if (state.o.s == State::Fail && state.n.s == State::Pass) {
859  v_gained.insert(event);
860  } else
861  if (state.o.s == State::Fail && state.n.s == State::Fail) {
862  v_changed.insert(event);
863  }
864 
865  return moduleId;
866  }
867 
868  Pair gained() const {
869  return Pair( double(v_gained.size()), sqrt( double(v_gained.size()) ) );
870  }
871 
872  Pair lost() const {
873  return Pair( double(v_lost.size()), sqrt( double(v_lost.size()) ) );
874  }
875 
876  Pair changed() const {
877  return Pair( double(v_changed.size()), sqrt( double(v_changed.size()) ) );
878  }
879 
880  bool keepForC() const {
881  return v_changed.size() > 0;
882  }
883 
884  bool keepForGL() const {
885  return v_gained.size() > 0 || v_lost.size() > 0;
886  }
887  };
888 
892  std::map<int, GenericSummary> m_modules;
893 
894  TriggerSummary(int _id, const JsonOutputProducer& _json) :
895  GenericSummary(_id, _json, _json.vars.trigger),
896  accepted_o(_json.vars.trigger_passed_count.at(id).first),
897  accepted_n(_json.vars.trigger_passed_count.at(id).second) {}
898 
899  void addEntry(const JsonOutputProducer::JsonEvent& _event, const int _triggerIndex, const std::vector<std::string>& _moduleNames) {
900  int moduleLabelId = GenericSummary::addEntry(_event, _triggerIndex);
901  // Updating number of events affected by the particular module
902  if (m_modules.count(moduleLabelId) == 0)
903  m_modules.emplace(moduleLabelId, GenericSummary(moduleLabelId, json, _moduleNames));
904  m_modules.at(moduleLabelId).addEntry(_event, _triggerIndex);
905  }
906 
907  Pair gained(int type =0) const {
908  Pair gained( GenericSummary::gained() );
909  if (type == 0) return gained; // Absolute number of affected events
910  double all( accepted_n );
911  Pair fraction = Pair( gained.v / (all+1e-10), sqrt(all) / (all+1e-10) );
912  if (type == 1) return fraction; // Relative number of affected events with respect to all accepted
913  if (type == 2) return Pair(std::max(0.0, fraction.v - fraction.e), 0.0); // Smallest value given the uncertainty
914  return Pair( fraction.v / (fraction.e + 1e-10), 0.0 ); // Significance of the effect as N std. deviations
915  }
916 
917  Pair lost(int type =0) const {
918  Pair lost( GenericSummary::lost() );
919  if (type == 0) return lost;
920  double all( accepted_o );
921  Pair fraction = Pair( lost.v / (all+1e-10), sqrt(all) / (all+1e-10) );
922  if (type == 1) return fraction;
923  if (type == 2) return Pair(std::max(0.0, fraction.v - fraction.e), 0.0); // Smallest value given the uncertainty
924  return Pair( fraction.v / (fraction.e + 1e-10), 0.0 );
925  }
926 
927  Pair changed(int type =0) const {
928  Pair changed( GenericSummary::changed() );
929  if (type == 0) return changed;
930  double all( json.configuration.events - accepted_o );
931  Pair fraction = Pair( changed.v / (all+1e-10), sqrt(all) / (all+1e-10) );
932  if (type == 1) return fraction;
933  if (type == 2) return Pair(std::max(0.0, fraction.v - fraction.e), 0.0); // Smallest value given the uncertainty
934  return Pair( fraction.v / (fraction.e + 1e-10), 0.0 );
935  }
936  };
937 
938 private:
939  std::map<int, TriggerSummary> m_triggerSummary;
940  std::map<int, GenericSummary> m_moduleSummary;
941 
942  void prepareSummaries(const int _run, const std::vector<JsonOutputProducer::JsonEvent>& _events) {
943  this->run = _run;
944  // Initialising the summary objects for trigger/module
945  m_triggerSummary.clear();
946  m_moduleSummary.clear();
947  const size_t nTriggers( json.vars.trigger.size() );
948  const size_t nModules( json.vars.label.size() );
949  for (size_t i=0; i<nTriggers; ++i)
950  m_triggerSummary.emplace(i, TriggerSummary(i, json) );
951  for (size_t i=0; i<nModules; ++i)
952  m_moduleSummary.emplace(i, GenericSummary(i, json, json.vars.label) );
953 
954  // Add each affected trigger in each event to the trigger/module summary objects
955  for (const JsonOutputProducer::JsonEvent& event : _events) {
956  for (size_t iTrigger = 0; iTrigger < event.triggerStates.size(); ++iTrigger) {
957  const JsonOutputProducer::JsonTriggerEventState& state = event.triggerStates.at(iTrigger);
958  m_triggerSummary.at(state.tr).addEntry(event, iTrigger, json.vars.label);
959  const int moduleId = state.o.s == State::Fail ? state.o.l : state.n.l;
960  m_moduleSummary.at(moduleId).addEntry(event, iTrigger);
961  }
962  }
963  }
964 
966  std::map<std::string, TH1*> m_histo;
967  // Counting the numbers of bins for different types of histograms
968  // *_c - changed; *_gl - gained or lost
969  int nTriggers(0), nTriggers_c(0), nTriggers_gl(0), nModules_c(0), nModules_gl(0);
970 
971  for (const auto& idSummary : m_triggerSummary) {
972  if (idSummary.second.accepted_o > 0) ++nTriggers;
973  if (idSummary.second.keepForGL()) ++nTriggers_gl;
974  if (idSummary.second.keepForC()) ++nTriggers_c;
975  }
976  for (const auto& idSummary : m_moduleSummary) {
977  if (idSummary.second.keepForGL()) ++nModules_gl;
978  if (idSummary.second.keepForC()) ++nModules_c;
979  }
980 
981  // Initialising overview histograms
982  std::string name = "trigger_accepted";
983  m_histo.emplace(name, new TH1F(name.c_str(), ";;Events accepted^{OLD}", nTriggers, 0, nTriggers));
984  name = "trigger_gained";
985  m_histo.emplace(name, new TH1F(name.c_str(), ";;Events gained", nTriggers_gl, 0, nTriggers_gl));
986  name = "trigger_lost";
987  m_histo.emplace(name, new TH1F(name.c_str(), ";;Events lost", nTriggers_gl, 0, nTriggers_gl));
988  name = "trigger_changed";
989  m_histo.emplace(name, new TH1F(name.c_str(), ";;Events changed", nTriggers_c, 0, nTriggers_c));
990  name = "trigger_gained_frac";
991  m_histo.emplace(name, new TH1F(name.c_str(), ";;#frac{gained}{accepted}", nTriggers_gl, 0, nTriggers_gl));
992  name = "trigger_lost_frac";
993  m_histo.emplace(name, new TH1F(name.c_str(), ";;#frac{lost}{accepted}", nTriggers_gl, 0, nTriggers_gl));
994  name = "trigger_changed_frac";
995  m_histo.emplace(name, new TH1F(name.c_str(), ";;#frac{changed}{all - accepted}", nTriggers_c, 0, nTriggers_c));
996  name = "module_changed";
997  m_histo.emplace(name, new TH1F(name.c_str(), ";;Events changed", nModules_c, 0, nModules_c));
998  name = "module_gained";
999  m_histo.emplace(name, new TH1F(name.c_str(), ";;Events gained", nModules_gl, 0, nModules_gl));
1000  name = "module_lost";
1001  m_histo.emplace(name, new TH1F(name.c_str(), ";;Events lost", nModules_gl, 0, nModules_gl));
1002 
1003  // Filling the per-trigger bins in the summary histograms
1004  size_t bin(0), bin_c(0), bin_gl(0);
1005  for (const auto& idSummary : m_triggerSummary) {
1006  const TriggerSummary& summary = idSummary.second;
1007  if (summary.accepted_o > 0) {
1008  ++bin;
1009  // Setting bin contents
1010  m_histo.at("trigger_accepted")->SetBinContent(bin, summary.accepted_o);
1011  // Setting bin labels
1012  m_histo.at("trigger_accepted")->GetXaxis()->SetBinLabel(bin, summary.name.c_str());
1013  }
1014  if (summary.keepForGL()) {
1015  ++bin_gl;
1016  // Setting bin contents
1017  m_histo.at("trigger_gained")->SetBinContent(bin_gl, summary.gained().v);
1018  m_histo.at("trigger_lost")->SetBinContent(bin_gl, -summary.lost().v);
1019  m_histo.at("trigger_gained_frac")->SetBinContent(bin_gl, summary.gained(1).v);
1020  m_histo.at("trigger_lost_frac")->SetBinContent(bin_gl, -summary.lost(1).v);
1021  // Setting bin errors
1022  m_histo.at("trigger_gained_frac")->SetBinError(bin_gl, summary.gained(1).e);
1023  m_histo.at("trigger_lost_frac")->SetBinError(bin_gl, -summary.lost(1).e);
1024  // Setting bin labels
1025  m_histo.at("trigger_gained")->GetXaxis()->SetBinLabel(bin_gl, summary.name.c_str());
1026  m_histo.at("trigger_lost")->GetXaxis()->SetBinLabel(bin_gl, summary.name.c_str());
1027  m_histo.at("trigger_gained_frac")->GetXaxis()->SetBinLabel(bin_gl, summary.name.c_str());
1028  m_histo.at("trigger_lost_frac")->GetXaxis()->SetBinLabel(bin_gl, summary.name.c_str());
1029  }
1030  if (summary.keepForC()) {
1031  ++bin_c;
1032  // Setting bin contents
1033  m_histo.at("trigger_changed")->SetBinContent(bin_c, summary.changed().v);
1034  m_histo.at("trigger_changed_frac")->SetBinContent(bin_c, summary.changed(1).v);
1035  // Setting bin errors
1036  m_histo.at("trigger_changed_frac")->SetBinError(bin_c, summary.changed(1).e);
1037  // Setting bin labels
1038  m_histo.at("trigger_changed")->GetXaxis()->SetBinLabel(bin_c, summary.name.c_str());
1039  m_histo.at("trigger_changed_frac")->GetXaxis()->SetBinLabel(bin_c, summary.name.c_str());
1040  }
1041  }
1042 
1043  // Filling the per-module bins in the summary histograms
1044  bin = 0;
1045  bin_c = 0;
1046  bin_gl = 0;
1047  for (const auto& idSummary : m_moduleSummary) {
1048  ++bin;
1049  const GenericSummary& summary = idSummary.second;
1050  if (summary.keepForGL()) {
1051  ++bin_gl;
1052  // Setting bin contents
1053  m_histo.at("module_gained")->SetBinContent(bin_gl, summary.gained().v);
1054  m_histo.at("module_lost")->SetBinContent(bin_gl, -summary.lost().v);
1055  // Setting bin labels
1056  m_histo.at("module_gained")->GetXaxis()->SetBinLabel(bin_gl, summary.name.c_str());
1057  m_histo.at("module_lost")->GetXaxis()->SetBinLabel(bin_gl, summary.name.c_str());
1058  }
1059  if (summary.keepForC()) {
1060  ++bin_c;
1061  // Setting bin contents
1062  m_histo.at("module_changed")->SetBinContent(bin_c, summary.changed().v);
1063  // Setting bin labels
1064  m_histo.at("module_changed")->GetXaxis()->SetBinLabel(bin_c, summary.name.c_str());
1065  }
1066  }
1067 
1068  // Styling the histograms
1069  for (const auto& nameHisto : m_histo) {
1070  const std::string name = nameHisto.first;
1071  TH1* histo = nameHisto.second;
1072  if (name.find("gained") != std::string::npos || name.find("changed") != std::string::npos) {
1073  if (name.find("frac") != std::string::npos)
1074  histo->GetYaxis()->SetRangeUser(0.0, 1.0);
1075  }
1076  if (name.find("lost") != std::string::npos) {
1077  if (name.find("frac") != std::string::npos)
1078  histo->GetYaxis()->SetRangeUser(-1.0, 0.0);
1079  }
1080  }
1081 
1082  // Storing histograms to a ROOT file
1083  std::string file_name = json.output_filename_base(this->run)+=".root";
1084  TFile* out_file = new TFile(file_name.c_str(), "RECREATE");
1085  // Storing the histograms is a proper folder according to the DQM convention
1086  char savePath[1000];
1087  sprintf(savePath, "DQMData/Run %d/HLT/Run summary/EventByEvent/", this->run);
1088  out_file->mkdir(savePath);
1089  gDirectory->cd(savePath);
1090  gDirectory->Write();
1091  for (const auto& nameHisto : m_histo)
1092  nameHisto.second->Write(nameHisto.first.c_str());
1093  out_file->Close();
1094 
1095  return file_name;
1096  }
1097 
1099  std::string file_name = json.output_filename_base(this->run)+="_trigger.csv";
1100  FILE* out_file = fopen((file_name).c_str(), "w");
1101 
1102  fprintf(out_file,"Total,Accepted OLD,Accepted NEW,Gained,Lost,|G|/A_N + |L|/AO,sigma(AN)+sigma(AO),Changed,C/(T-AO),sigma(T-AO),trigger\n");
1103  for (const auto& idSummary : m_triggerSummary) {
1104  const SummaryOutputProducer::TriggerSummary& S = idSummary.second;
1105  fprintf(out_file, "%d,%d,%d,%+.f,%+.f,%.2f%%,%.2f%%,~%.f,~%.2f%%,%.2f%%,%s\n",
1106  this->json.configuration.events, S.accepted_o, S.accepted_n, S.gained().v, -1.0*S.lost().v, (S.gained(1).v+S.lost(1).v)*100.0, (S.gained(1).e+S.lost(1).e)*100.0, S.changed().v, S.changed(1).v*100.0, S.changed(1).e*100.0, S.name.c_str());
1107  }
1108 
1109  fclose(out_file);
1110 
1111  return file_name;
1112  }
1113 
1115  std::string file_name = json.output_filename_base(this->run)+="_module.csv";
1116  FILE* out_file = fopen((file_name).c_str(), "w");
1117 
1118  fprintf(out_file,"Total,Gained,Lost,Changed,module\n");
1119  for (const auto& idSummary : m_moduleSummary) {
1120  const SummaryOutputProducer::GenericSummary& S = idSummary.second;
1121  fprintf(out_file, "%d,+%.f,-%.f,~%.f,%s\n",
1122  this->json.configuration.events, S.gained().v, S.lost().v, S.changed().v, S.name.c_str());
1123  }
1124 
1125  fclose(out_file);
1126 
1127  return file_name;
1128  }
1129 
1130 public:
1132  bool storeCSV;
1133 
1134  SummaryOutputProducer(const JsonOutputProducer& _json, bool _storeROOT, bool _storeCSV=true):
1135  json(_json),
1136  run(-1),
1137  storeROOT(_storeROOT),
1138  storeCSV(_storeCSV) {}
1139 
1140  void write() {
1141  std::vector<std::string> filesCreated;
1142  // Processing every run from the JSON producer
1143  for (const auto& runEvents : json.m_run_events) {
1144  prepareSummaries(runEvents.first, runEvents.second);
1145  if (storeROOT)
1146  filesCreated.push_back(writeHistograms());
1147  if (storeCSV) {
1148  filesCreated.push_back(writeCSV_trigger());
1149  filesCreated.push_back(writeCSV_module());
1150  }
1151  }
1152 
1153  printf("Created the following summary files:\n");
1154  for (const std::string& filename : filesCreated)
1155  printf(" %s\n", filename.c_str());
1156  }
1157 
1158 };
1159 
1160 
1161 bool check_file(std::string const & file) {
1162  std::unique_ptr<TFile> f(TFile::Open(file.c_str()));
1163  return (f and not f->IsZombie());
1164 }
1165 
1166 
1167 bool check_files(std::vector<std::string> const & files) {
1168  bool flag = true;
1169  for (auto const & file: files)
1170  if (not check_file(file)) {
1171  flag = false;
1172  std::cerr << "hltDiff: error: file " << file << " does not exist, or is not a regular file." << std::endl;
1173  }
1174  return flag;
1175 }
1176 
1177 class HltDiff
1178 {
1179 
1180 public:
1181  std::vector<std::string> old_files;
1183  std::vector<std::string> new_files;
1185  unsigned int max_events;
1187  bool json_out;
1188  bool root_out;
1191  bool debug;
1192  unsigned int verbose;
1193 
1195  old_files(0),
1196  old_process(""),
1197  new_files(0),
1198  new_process(""),
1199  max_events(1e9),
1200  ignore_prescales(true),
1201  json_out(false),
1202  root_out(false),
1203  output_file(""),
1204  file_check(false),
1205  debug(false),
1206  verbose(0) {}
1207 
1208  void compare() const {
1209  std::shared_ptr<fwlite::ChainEvent> old_events;
1210  std::shared_ptr<fwlite::ChainEvent> new_events;
1211 
1212  if (not file_check or check_files(old_files))
1213  old_events = std::make_shared<fwlite::ChainEvent>(old_files);
1214  else
1215  return;
1216 
1217  if (new_files.size() == 1 and new_files[0] == "-")
1218  new_events = old_events;
1219  else if (not file_check or check_files(new_files))
1220  new_events = std::make_shared<fwlite::ChainEvent>(new_files);
1221  else
1222  return;
1223 
1224  // creating the structure holding data for JSON and ROOT output
1225  JsonOutputProducer json(json_out, output_file);
1226 
1227  json.configuration.prescales = ignore_prescales;
1228  // setting the old configuration
1229  json.configuration.o.process = old_process;
1230  json.configuration.o.files = old_files;
1232  // setting the new configuration
1233  json.configuration.n.process = new_process;
1234  json.configuration.n.files = new_files;
1236 
1237  // initialising configurations to be compared
1238  std::unique_ptr<HLTConfigDataEx> old_config_data;
1239  std::unique_ptr<HLTConfigDataEx> new_config_data;
1240  std::unique_ptr<HLTCommonConfig> common_config;
1241  HLTConfigInterface const * old_config = nullptr;
1242  HLTConfigInterface const * new_config = nullptr;
1243 
1244  unsigned int counter = 0;
1245  unsigned int skipped = 0;
1246  unsigned int affected = 0;
1247  bool new_run = true;
1248  std::vector<TriggerDiff> differences;
1249 
1250  // loop over the reference events
1251  const unsigned int nEvents = std::min((int)old_events->size(), (int)max_events);
1252  for (old_events->toBegin(); not old_events->atEnd(); ++(*old_events)) {
1253  // printing progress on every 10%
1254  if (counter%(nEvents/10) == 0) {
1255  printf("Processed events: %d out of %d (%d%%)\n", (int)counter, (int)nEvents, 10*counter/(nEvents/10));
1256  }
1257 
1258  // seek the same event in the "new" files
1259  edm::EventID const& id = old_events->id();
1260  if (new_events != old_events and not new_events->to(id)) {
1261  if (debug)
1262  std::cerr << "run " << id.run() << ", lumi " << id.luminosityBlock() << ", event " << id.event() << ": not found in the 'new' files, skipping." << std::endl;
1263  ++skipped;
1264  continue;
1265  }
1266 
1267  // read the TriggerResults and TriggerEvent
1269  edm::TriggerResults const * old_results = nullptr;
1270  old_results_h.getByLabel<fwlite::Event>(* old_events->event(), "TriggerResults", "", old_process.c_str());
1271  if (old_results_h.isValid())
1272  old_results = old_results_h.product();
1273  else {
1274  if (debug)
1275  std::cerr << "run " << id.run() << ", lumi " << id.luminosityBlock() << ", event " << id.event() << ": 'old' TriggerResults not found, skipping." << std::endl;
1276  continue;
1277  }
1278 
1280  trigger::TriggerEvent const * old_summary = nullptr;
1281  old_summary_h.getByLabel<fwlite::Event>(* old_events->event(), "hltTriggerSummaryAOD", "", old_process.c_str());
1282  if (old_summary_h.isValid())
1283  old_summary = old_summary_h.product();
1284 
1286  edm::TriggerResults const * new_results = nullptr;
1287  new_results_h.getByLabel<fwlite::Event>(* new_events->event(), "TriggerResults", "", new_process.c_str());
1288  if (new_results_h.isValid())
1289  new_results = new_results_h.product();
1290  else {
1291  if (debug)
1292  std::cerr << "run " << id.run() << ", lumi " << id.luminosityBlock() << ", event " << id.event() << ": 'new' TriggerResults not found, skipping." << std::endl;
1293  continue;
1294  }
1295 
1297  trigger::TriggerEvent const * new_summary = nullptr;
1298  new_summary_h.getByLabel<fwlite::Event>(* new_events->event(), "hltTriggerSummaryAOD", "", new_process.c_str());
1299  if (new_summary_h.isValid())
1300  new_summary = new_summary_h.product();
1301 
1302  // initialise the trigger configuration
1303  if (new_run) {
1304  new_run = false;
1305  old_events->fillParameterSetRegistry();
1306  new_events->fillParameterSetRegistry();
1307 
1308  old_config_data = getHLTConfigData(* old_events->event(), old_process);
1309  new_config_data = getHLTConfigData(* new_events->event(), new_process);
1310  if (new_config_data->triggerNames() == old_config_data->triggerNames()) {
1311  old_config = old_config_data.get();
1312  new_config = new_config_data.get();
1313  } else {
1314  common_config = std::unique_ptr<HLTCommonConfig>(new HLTCommonConfig(*old_config_data, *new_config_data));
1315  old_config = & common_config->getView(HLTCommonConfig::Index::First);
1316  new_config = & common_config->getView(HLTCommonConfig::Index::Second);
1317  std::cout << "Warning: old and new TriggerResults come from different HLT menus. Only the common " << old_config->size() << " triggers are compared.\n" << std::endl;
1318  }
1319 
1320  differences.clear();
1321  differences.resize(old_config->size());
1322 
1323  // adding the list of selected triggers to JSON output
1324  std::vector<std::string> states_str;
1325  for (int i = State::Ready; i != State::Invalid; i++)
1326  states_str.push_back(std::string(path_state(static_cast<State>(i))));
1327  json.vars.state = states_str;
1328  for (size_t triggerId = 0; triggerId < old_config->size(); ++triggerId) {
1329  json.vars.trigger.push_back(old_config->triggerName(triggerId));
1330  json.vars.trigger_passed_count.push_back(std::pair<int, int>(0,0));
1331  }
1332  // getting names of triggers existing only in the old configuration
1333  for (std::vector<std::string>::const_iterator it = old_config_data->triggerNames().begin(); it != old_config_data->triggerNames().end(); ++it) {
1334  if (std::find(json.vars.trigger.begin(), json.vars.trigger.end(), *it) != json.vars.trigger.end()) continue;
1335  json.configuration.o.skipped_triggers.push_back(*it);
1336  }
1337  // getting names of triggers existing only in the new configuration
1338  for (std::vector<std::string>::const_iterator it = new_config_data->triggerNames().begin(); it != new_config_data->triggerNames().end(); ++it) {
1339  if (std::find(json.vars.trigger.begin(), json.vars.trigger.end(), *it) != json.vars.trigger.end()) continue;
1340  json.configuration.n.skipped_triggers.push_back(*it);
1341  }
1342  }
1343 
1344  // compare the TriggerResults
1345  bool needs_header = true;
1346  bool event_affected = false;
1347  for (unsigned int p = 0; p < old_config->size(); ++p) {
1348  // FIXME explicitly converting the indices is a hack, it should be properly encapsulated instead
1349  unsigned int old_index = old_config->triggerIndex(p);
1350  unsigned int new_index = new_config->triggerIndex(p);
1351  State old_state = prescaled_state(old_results->state(old_index), p, old_results->index(old_index), * old_config);
1352  State new_state = prescaled_state(new_results->state(new_index), p, new_results->index(new_index), * new_config);
1353 
1354  if (old_state == Pass) {
1355  ++differences[p].count;
1356  }
1357  if (old_state == Pass)
1358  ++json.vars.trigger_passed_count.at(p).first;
1359  if (new_state == Pass)
1360  ++json.vars.trigger_passed_count.at(p).second;
1361 
1362  bool trigger_affected = false;
1363  if (not ignore_prescales or (old_state != Prescaled and new_state != Prescaled)) {
1364  if (old_state == Pass and new_state != Pass) {
1365  ++differences[p].lost;
1366  trigger_affected = true;
1367  } else if (old_state != Pass and new_state == Pass) {
1368  ++differences[p].gained;
1369  trigger_affected = true;
1370  } else if (old_results->index(old_index) != new_results->index(new_index)) {
1371  ++differences[p].internal;
1372  trigger_affected = true;
1373  }
1374  }
1375 
1376  if (not trigger_affected) continue;
1377 
1378  event_affected = true;
1379  const unsigned int old_moduleIndex = old_results->index(old_index);
1380  const unsigned int new_moduleIndex = new_results->index(new_index);
1381  // storing the event to JSON, without any trigger results for the moment
1382  JsonOutputProducer::JsonEvent& event = json.pushEvent(id.run(), id.luminosityBlock(), id.event());
1383  JsonOutputProducer::JsonTriggerEventState& state = event.pushTrigger(p);
1384  state.o = json.eventState(old_state, old_moduleIndex, old_config->moduleLabel(p, old_moduleIndex), old_config->moduleType(p, old_moduleIndex));
1385  state.n = json.eventState(new_state, new_moduleIndex, new_config->moduleLabel(p, new_moduleIndex), new_config->moduleType(p, new_moduleIndex));
1386 
1387  if (verbose > 0) {
1388  if (needs_header) {
1389  needs_header = false;
1390  std::cout << "run " << id.run() << ", lumi " << id.luminosityBlock() << ", event " << id.event() << ": "
1391  << "old result is '" << event_state(old_results->accept()) << "', "
1392  << "new result is '" << event_state(new_results->accept()) << "'"
1393  << std::endl;
1394  }
1395  // print the Trigger path and filter responsible for the discrepancy
1396  std::cout << " Path " << old_config->triggerName(p) << ":\n"
1397  << " old state is ";
1398  print_detailed_path_state(std::cout, old_state, p, old_moduleIndex, * old_config);
1399  std::cout << ",\n"
1400  << " new state is ";
1401  print_detailed_path_state(std::cout, new_state, p, new_moduleIndex, * new_config);
1402  std::cout << std::endl;
1403  }
1404  if (verbose > 1 and old_summary and new_summary) {
1405  // print TriggerObjects for the filter responsible for the discrepancy
1406  unsigned int module = std::min(old_moduleIndex, new_moduleIndex);
1407  std::cout << " Filter " << old_config->moduleLabel(p, module) << ":\n";
1408  std::cout << " old trigger candidates:\n";
1409  print_trigger_candidates(std::cout, * old_summary, edm::InputTag(old_config->moduleLabel(p, module), "", old_config->processName()));
1410  std::cout << " new trigger candidates:\n";
1411  print_trigger_candidates(std::cout, * new_summary, edm::InputTag(new_config->moduleLabel(p, module), "", new_config->processName()));
1412  }
1413  if (verbose > 0)
1414  std::cout << std::endl;
1415  }
1416  if (event_affected)
1417  ++affected;
1418 
1419  // compare the TriggerEvent
1420  if (event_affected and verbose > 2 and old_summary and new_summary) {
1421  std::map<std::string, std::pair<std::string, std::string>> collections;
1422  for (auto const & old_collection: old_summary->collectionTags())
1423  collections[strip_process_name(old_collection)].first = old_collection;
1424  for (auto const & new_collection: new_summary->collectionTags())
1425  collections[strip_process_name(new_collection)].second = new_collection;
1426 
1427  for (auto const & collection: collections) {
1428  std::cout << " Collection " << collection.first << ":\n";
1429  std::cout << " old trigger candidates:\n";
1430  print_trigger_collection(std::cout, * old_summary, collection.second.first);
1431  std::cout << " new trigger candidates:\n";
1432  print_trigger_collection(std::cout, * new_summary, collection.second.second);
1433  std::cout << std::endl;
1434  }
1435  }
1436 
1437  ++counter;
1438  if (nEvents and counter >= nEvents)
1439  break;
1440  }
1441 
1442  json.configuration.events = counter;
1443 
1444  if (not counter) {
1445  std::cout << "There are no common events between the old and new files";
1446  if (skipped)
1447  std::cout << ", " << skipped << " events were skipped";
1448  std::cout << "." << std::endl;
1449  } else {
1450  std::cout << "Found " << counter << " matching events, out of which " << affected << " have different HLT results";
1451  if (skipped)
1452  std::cout << ", " << skipped << " events were skipped";
1453  std::cout << "\nSee more in the files listed below...\n" << std::endl;
1454  }
1455 
1456  // writing all the required output
1457  json.write(); // to JSON file for interactive visualisation
1458  SummaryOutputProducer summary(json, this->root_out, true);
1459  summary.write(); // to ROOT file for fast validation with static plots
1460  }
1461 
1462  void usage(std::ostream & out) const {
1463  out << "\
1464 usage: hltDiff -o|--old-files FILE1.ROOT [FILE2.ROOT ...] [-O|--old-process LABEL[:INSTANCE[:PROCESS]]]\n\
1465  -n|--new-files FILE1.ROOT [FILE2.ROOT ...] [-N|--new-process LABEL[:INSTANCE[:PROCESS]]]\n\
1466  [-m|--max-events MAXEVENTS] [-p|--prescales] [-j|--json-output] OUTPUT_FILE.JSON\n\
1467  [-r|--root-output] OUTPUT_FILE.ROOT [-f|--file-check] [-d|--debug] [-v|--verbose] [-h|--help]\n\
1468 \n\
1469  -o|--old-files FILE1.ROOT [FILE2.ROOT ...]\n\
1470  input file(s) with the old (reference) trigger results\n\
1471 \n\
1472  -O|--old-process PROCESS\n\
1473  process name of the collection with the old (reference) trigger results\n\
1474  default: take the 'TriggerResults' from the last process\n\
1475 \n\
1476  -n|--new-files FILE1.ROOT [FILE2.ROOT ...]\n\
1477  input file(s) with the new trigger results to be compared with the reference\n\
1478  to read these from a different collection in the same files as\n\
1479  the reference, use '-n -' and specify the collection with -N (see below)\n\
1480 \n\
1481  -N|--new-process PROCESS\n\
1482  process name of the collection with the new (reference) trigger results\n\
1483  default: take the 'TriggerResults' from the last process\n\
1484 \n\
1485  -m|--max-events MAXEVENTS\n\
1486  compare only the first MAXEVENTS events\n\
1487  default: compare all the events in the original (reference) files\n\
1488 \n\
1489  -p|--prescales\n\
1490  do not ignore differences caused by HLTPrescaler modules\n\
1491 \n\
1492  -j|--json-output\n\
1493  produce comparison results in a JSON format\n\
1494 \n\
1495  -r|--root-output\n\
1496  produce comparison results as histograms in a ROOT file\n\
1497 \n\
1498  -F|--output-file FILE_NAME\n\
1499  combine all RUNs to files with the specified custom name: FILE_NAME.json, FILE_NAME.root\n\
1500  default: a separate output file will be produced for each RUN with names suitable for the DQM GUI\n\
1501 \n\
1502  -f|--file-check\n\
1503  check existence of every old and new file before running the comparison\n\
1504  safer if files are run for the first time, but can cause a substantial delay\n\
1505 \n\
1506  -d|--debug\n\
1507  display messages about missing events and collectiions\n\
1508 \n\
1509  -v|--verbose LEVEL\n\
1510  set verbosity level:\n\
1511  1: event-by-event comparison results\n\
1512  2: + print the trigger candidates of the affected filters\n\
1513  3: + print all the trigger candidates for the affected events\n\
1514  default: 1\n\
1515 \n\
1516  -h|--help\n\
1517  print this help message, and exit" << std::endl;
1518  }
1519 
1520 };
1521 
1522 
1523 int main(int argc, char ** argv) {
1524  // options
1525  const char optstring[] = "dfo:O:n:N:m:pjrF:v::h";
1526  const option longopts[] = {
1527  option{ "debug", no_argument, nullptr, 'd' },
1528  option{ "file-check", no_argument, nullptr, 'f' },
1529  option{ "old-files", required_argument, nullptr, 'o' },
1530  option{ "old-process", required_argument, nullptr, 'O' },
1531  option{ "new-files", required_argument, nullptr, 'n' },
1532  option{ "new-process", required_argument, nullptr, 'N' },
1533  option{ "max-events", required_argument, nullptr, 'm' },
1534  option{ "prescales", no_argument, nullptr, 'p' },
1535  option{ "json-output", optional_argument, nullptr, 'j' },
1536  option{ "root-output", optional_argument, nullptr, 'r' },
1537  option{ "output-file", optional_argument, nullptr, 'F' },
1538  option{ "verbose", optional_argument, nullptr, 'v' },
1539  option{ "help", no_argument, nullptr, 'h' },
1540  };
1541 
1542  // Creating an HltDiff object with the default configuration
1543  HltDiff* hlt = new HltDiff();
1544 
1545  // parse the command line options
1546  int c = -1;
1547  while ((c = getopt_long(argc, argv, optstring, longopts, nullptr)) != -1) {
1548  switch (c) {
1549  case 'd':
1550  hlt->debug = true;
1551  break;
1552 
1553  case 'f':
1554  hlt->file_check = true;
1555  break;
1556 
1557  case 'o':
1558  hlt->old_files.emplace_back(optarg);
1559  while (optind < argc) {
1560  if (argv[optind][0] == '-')
1561  break;
1562  hlt->old_files.emplace_back(argv[optind]);
1563  ++optind;
1564  }
1565  break;
1566 
1567  case 'O':
1568  hlt->old_process = optarg;
1569  break;
1570 
1571  case 'n':
1572  hlt->new_files.emplace_back(optarg);
1573  while (optind < argc) {
1574  if (argv[optind][0] == '-')
1575  break;
1576  hlt->new_files.emplace_back(argv[optind]);
1577  ++optind;
1578  }
1579  break;
1580 
1581  case 'N':
1582  hlt->new_process = optarg;
1583  break;
1584 
1585  case 'm':
1586  hlt->max_events = atoi(optarg);
1587  break;
1588 
1589  case 'p':
1590  hlt->ignore_prescales = false;
1591  break;
1592 
1593  case 'j':
1594  hlt->json_out = true;
1595  break;
1596 
1597  case 'r':
1598  hlt->root_out = true;
1599  break;
1600 
1601  case 'F':
1602  hlt->output_file = optarg;
1603  break;
1604 
1605  case 'v':
1606  hlt->verbose = 1;
1607  if (optarg) {
1608  hlt->verbose = std::max(1, atoi(optarg));
1609  } else if (!optarg && NULL != argv[optind] && '-' != argv[optind][0]) {
1610  // workaround for a bug in getopt which doesn't allow space before optional arguments
1611  const char *tmp_optarg = argv[optind++];
1612  hlt->verbose = std::max(1, atoi(tmp_optarg));
1613  }
1614  break;
1615 
1616  case 'h':
1617  hlt->usage(std::cerr);
1618  exit(0);
1619  break;
1620 
1621  default:
1622  error(std::cerr);
1623  exit(1);
1624  break;
1625  }
1626  }
1627 
1628  if (hlt->old_files.empty()) {
1629  error(std::cerr, "hltDiff: please specify the 'old' file(s)");
1630  exit(1);
1631  }
1632  if (hlt->new_files.empty()) {
1633  error(std::cerr, "hltDiff: please specify the 'new' file(s)");
1634  exit(1);
1635  }
1636 
1637  hlt->compare();
1638 
1639  return 0;
1640 }
unsigned int typeId(std::string typeName)
Definition: hltDiff.cc:653
JsonEvent & pushEvent(int _run, int _lumi, int _event)
Definition: hltDiff.cc:749
virtual unsigned int triggerIndex(unsigned int trigger) const override
Definition: hltDiff.cc:110
virtual std::string const & triggerName(unsigned int trigger) const override
Definition: hltDiff.cc:265
virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const =0
type
Definition: HCALResponse.h:21
static std::string indent(size_t _nTabs)
Definition: hltDiff.cc:475
unsigned int count
Definition: hltDiff.cc:435
int i
Definition: DBlmapReader.cc:9
std::set< std::string > moduleTypeSet_
Definition: hltDiff.cc:128
virtual bool prescaler(unsigned int trigger, unsigned int module) const override
Definition: hltDiff.cc:122
std::vector< std::pair< unsigned int, unsigned int > > triggerIndices_
Definition: hltDiff.cc:249
virtual bool prescaler(unsigned int trigger, unsigned int module) const override
Definition: hltDiff.cc:281
std::string const & moduleLabel(Index index, unsigned int trigger, unsigned int module) const
Definition: hltDiff.cc:221
virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const override
Definition: hltDiff.cc:277
virtual unsigned int size(unsigned int trigger) const override
Definition: hltDiff.cc:98
unsigned int internal
Definition: hltDiff.cc:438
not [yet] run
Definition: HLTenums.h:18
std::map< int, GenericSummary > m_modules
Definition: hltDiff.cc:892
std::map< int, std::vector< JsonEvent > > m_run_events
Definition: hltDiff.cc:740
unsigned int labelId(std::string labelName)
Definition: hltDiff.cc:645
bool check_files(std::vector< std::string > const &files)
Definition: hltDiff.cc:1167
int id() const
getters
Definition: TriggerObject.h:55
const std::vector< std::string > & collectionTags() const
Definition: TriggerEvent.h:96
The single EDProduct to be saved for each event (AOD case)
Definition: TriggerEvent.h:25
trigger::size_type sizeFilters() const
Definition: TriggerEvent.h:135
bool debug
Definition: hltDiff.cc:1191
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
bool root_out
Definition: hltDiff.cc:1188
Definition: hltDiff.cc:288
void print_trigger_candidates(std::ostream &out, trigger::TriggerEvent const &summary, edm::InputTag const &filter)
Definition: hltDiff.cc:344
bool isValid() const
Definition: Handle.h:61
unsigned int size(Index index, unsigned int trigger) const
Definition: hltDiff.cc:200
trigger::size_type collectionKey(trigger::size_type index) const
Definition: TriggerEvent.h:102
static size_t tab_spaces
Definition: hltDiff.cc:472
float phi() const
Definition: TriggerObject.h:58
bool file_check
Definition: hltDiff.cc:1190
unsigned int lost
Definition: hltDiff.cc:437
std::vector< std::string > skipped_triggers
Definition: hltDiff.cc:544
std::string serialise(size_t _indent=0) const
Definition: hltDiff.cc:709
tuple lumi
Definition: fjr2json.py:35
std::vector< std::vector< std::string const * > > moduleTypes_
Definition: hltDiff.cc:129
Pair gained(int type=0) const
Definition: hltDiff.cc:907
const JsonOutputProducer & json
Definition: hltDiff.cc:814
unsigned int verbose
Definition: hltDiff.cc:1192
double sign(double x)
bool accept() const
Has at least one path accepted the event?
std::string writeCSV_module() const
Definition: hltDiff.cc:1114
const Keys & filterKeys(trigger::size_type index) const
Definition: TriggerEvent.h:111
View(HLTCommonConfig const &config, HLTCommonConfig::Index index)
Definition: hltDiff.cc:148
const std::vector< std::string > & triggerNames() const
names of trigger paths
trigger::size_type filterIndex(const edm::InputTag &filterTag) const
find index of filter in data-member vector from filter tag
Definition: TriggerEvent.h:123
reject
Definition: HLTenums.h:20
Pair changed(int type=0) const
Definition: hltDiff.cc:927
virtual bool prescaler(unsigned int trigger, unsigned int module) const =0
#define NULL
Definition: scimark2.h:8
virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const override
Definition: hltDiff.cc:273
unsigned int size() const
number of trigger paths in trigger table
JsonOutputProducer(bool _writeJson, std::string _file_name)
Definition: hltDiff.cc:743
HLTConfigData data_
Definition: hltDiff.cc:127
TriggerSummary(int _id, const JsonOutputProducer &_json)
Definition: hltDiff.cc:894
void print_detailed_path_state(std::ostream &out, State state, int path, int module, HLTConfigInterface const &config)
Definition: hltDiff.cc:333
virtual std::string const & processName() const override
Definition: hltDiff.cc:90
std::vector< std::pair< int, int > > trigger_passed_count
Definition: hltDiff.cc:614
std::string serialise(size_t _indent=0) const
Definition: hltDiff.cc:668
GenericSummary(int _id, const JsonOutputProducer &_json, const std::vector< std::string > &_names)
Definition: hltDiff.cc:844
float eta() const
Definition: TriggerObject.h:57
const char * event_state(bool state)
Definition: hltDiff.cc:134
void prepareSummaries(const int _run, const std::vector< JsonOutputProducer::JsonEvent > &_events)
Definition: hltDiff.cc:942
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:188
Pair(int _v, int _e)
Definition: hltDiff.cc:822
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
virtual std::string const & triggerName(unsigned int trigger) const override
Definition: hltDiff.cc:106
JsonTriggerEventState & pushTrigger(int _tr)
Definition: hltDiff.cc:726
list diff
Definition: mps_update.py:85
std::vector< JsonTriggerEventState > triggerStates
Definition: hltDiff.cc:707
std::vector< std::string > label
Definition: hltDiff.cc:615
View secondView_
Definition: hltDiff.cc:247
HLTCommonConfig(HLTConfigDataEx const &first, HLTConfigDataEx const &second)
Definition: hltDiff.cc:168
SummaryOutputProducer(const JsonOutputProducer &_json, bool _storeROOT, bool _storeCSV=true)
Definition: hltDiff.cc:1134
virtual std::vector< std::string > const & triggerNames() const
Definition: hltDiff.cc:102
Single trigger physics object (e.g., an isolated muon)
Definition: TriggerObject.h:22
U second(std::pair< T, U > const &p)
static std::string format(unsigned int value, char sign= '+')
Definition: hltDiff.cc:441
void getByLabel(const P &iP, const char *iModuleLabel, const char *iProductInstanceLabel=0, const char *iProcessLabel=0)
Definition: Handle.h:91
std::map< int, GenericSummary > m_moduleSummary
Definition: hltDiff.cc:940
std::vector< std::string > old_files
Definition: hltDiff.cc:1181
static std::string string(const std::string &_string, const std::string &_delim="")
Definition: hltDiff.cc:512
unsigned int gained
Definition: hltDiff.cc:436
virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const override
Definition: hltDiff.cc:114
JsonEventState eventState(State _s, int _m, const std::string &_l, const std::string &_t)
Definition: hltDiff.cc:764
State prescaled_state(int state, int path, int module, HLTConfigInterface const &config)
Definition: hltDiff.cc:305
virtual std::string const & triggerName(unsigned int trigger) const =0
const JsonOutputProducer & json
Definition: hltDiff.cc:837
const Vids & filterIds(trigger::size_type index) const
Definition: TriggerEvent.h:110
std::string output_file
Definition: hltDiff.cc:1189
ParameterSetID const & parameterSetID() const
bool operator<(const FedChannelConnection &, const FedChannelConnection &)
std::string output_filename_base(int _run) const
Definition: hltDiff.cc:768
Pair(double _v, double _e)
Definition: hltDiff.cc:821
virtual std::string const & processName() const override
Definition: hltDiff.cc:253
int addEntry(const JsonOutputProducer::JsonEvent &_event, const int _triggerIndex)
Definition: hltDiff.cc:850
accept
Definition: HLTenums.h:19
HLTConfigDataEx const & second_
Definition: hltDiff.cc:244
std::unique_ptr< HLTConfigDataEx > getHLTConfigData(fwlite::EventBase const &event, std::string process)
Definition: hltDiff.cc:410
const TriggerObjectCollection & getObjects() const
Definition: TriggerEvent.h:98
HltDiff()
Definition: hltDiff.cc:1194
JsonEvent(int _run, int _lumi, int _event)
Definition: hltDiff.cc:723
T sqrt(T t)
Definition: SSEVec.h:18
Event(int _run, int _lumi, int _event)
Definition: hltDiff.cc:830
unsigned int index(const unsigned int i) const
Get index (slot position) of module giving the decision of the ith path.
std::vector< std::string > new_files
Definition: hltDiff.cc:1183
std::string serialise(size_t _indent=0) const
Definition: hltDiff.cc:618
def move
Definition: eostools.py:510
static std::string key_int(const std::string &_key, int _int, const std::string &_delim="")
Definition: hltDiff.cc:505
std::map< int, TriggerSummary > m_triggerSummary
Definition: hltDiff.cc:939
std::string getProcessNameFromBranch(std::string const &branch)
Definition: hltDiff.cc:404
HLTCommonConfig const & config_
Definition: hltDiff.cc:163
JsonConfigurationBlock o
Definition: hltDiff.cc:586
std::vector< std::string > trigger
Definition: hltDiff.cc:613
virtual unsigned int size() const override
Definition: hltDiff.cc:94
bool getMapped(key_type const &k, value_type &result) const
Definition: Registry.cc:18
virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const =0
const std::string moduleType(const std::string &module) const
C++ class name of module.
bool ignore_prescales
Definition: hltDiff.cc:1186
double f[11][100]
bool json_out
Definition: hltDiff.cc:1187
std::string out_filename_base
Definition: hltDiff.cc:537
std::string strip_process_name(std::string const &s)
Definition: hltDiff.cc:318
std::string serialise(size_t _indent=0) const
Definition: hltDiff.cc:546
unsigned int size(Index index) const
Definition: hltDiff.cc:196
#define end
Definition: vmac.h:37
T min(T a, T b)
Definition: MathUtil.h:58
static std::string list_string(const std::vector< std::string > &_values, const std::string &_delim="")
Definition: hltDiff.cc:520
void addEntry(const JsonOutputProducer::JsonEvent &_event, const int _triggerIndex, const std::vector< std::string > &_moduleNames)
Definition: hltDiff.cc:899
JsonConfigurationBlock n
Definition: hltDiff.cc:587
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
virtual unsigned int triggerIndex(unsigned int trigger) const =0
string key
FastSim: produces sample of signal events, overlayed with premixed minbias events.
void print_trigger_collection(std::ostream &out, trigger::TriggerEvent const &summary, std::string const &tag)
Definition: hltDiff.cc:374
HLTConfigDataEx(HLTConfigData data)
Definition: hltDiff.cc:74
const std::string & processName() const
Accessors (const methods)
unsigned int triggerIndex(Index index, unsigned int trigger) const
Definition: hltDiff.cc:214
string output_file
std::vector< std::string > state
Definition: hltDiff.cc:612
void compare() const
Definition: hltDiff.cc:1208
#define debug
Definition: HDRShower.cc:19
std::vector< std::string > files
Definition: hltDiff.cc:542
virtual std::string const & processName() const =0
std::string serialise(size_t _indent=0) const
Definition: hltDiff.cc:591
tuple argc
Definition: dir2webdir.py:38
double b
Definition: hdecay.h:120
std::string writeHistograms() const
Definition: hltDiff.cc:965
double S(const TLorentzVector &, const TLorentzVector &)
Definition: Particle.cc:99
Definition: hltDiff.cc:289
const char * path_state(State state)
Definition: hltDiff.cc:295
HLTConfigDataEx const & first_
Definition: hltDiff.cc:243
bool check_file(std::string const &file)
Definition: hltDiff.cc:1161
#define begin
Definition: vmac.h:30
unsigned int max_events
Definition: hltDiff.cc:1185
tuple events
Definition: patZpeak.py:19
virtual unsigned int size() const =0
std::string serialise(size_t _indent=0) const
Definition: hltDiff.cc:690
static std::atomic< unsigned int > counter
tuple filename
Definition: lut2db_cfg.py:20
std::vector< std::string > type
Definition: hltDiff.cc:616
std::string const & moduleType(Index index, unsigned int trigger, unsigned int module) const
Definition: hltDiff.cc:228
bool prescaler(Index index, unsigned int trigger, unsigned int module) const
Definition: hltDiff.cc:235
std::string const & processName(Index index) const
Definition: hltDiff.cc:189
State
Definition: hltDiff.cc:286
const std::string & moduleLabel(unsigned int trigger, unsigned int module) const
tuple cout
Definition: gather_cfg.py:145
virtual unsigned int size() const override
Definition: hltDiff.cc:257
T const * product() const
Definition: Handle.h:66
View const & getView(Index index) const
Definition: hltDiff.cc:182
volatile std::atomic< bool > shutdown_flag false
std::vector< std::vector< bool > > prescalers_
Definition: hltDiff.cc:130
std::string const & triggerName(Index index, unsigned int trigger) const
Definition: hltDiff.cc:207
const std::string & triggerName(unsigned int triggerIndex) const
virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const override
Definition: hltDiff.cc:118
float mass() const
Definition: TriggerObject.h:59
UInt_t nEvents
Definition: hcalCalib.cc:42
tuple process
Definition: LaserDQM_cfg.py:3
Pair lost(int type=0) const
Definition: hltDiff.cc:917
JsonConfiguration configuration
Definition: hltDiff.cc:641
Definition: vlib.h:208
std::string new_process
Definition: hltDiff.cc:1184
double split
Definition: MVATrainer.cc:139
virtual unsigned int triggerIndex(unsigned int trigger) const override
Definition: hltDiff.cc:269
JsonEventState(State _s, int _m, int _l, int _t)
Definition: hltDiff.cc:682
static Registry * instance()
Definition: Registry.cc:12
hlt::HLTState state(const unsigned int i) const
Get status of ith path.
static std::string key(const std::string &_key, const std::string &_delim="")
Definition: hltDiff.cc:489
std::string writeCSV_trigger() const
Definition: hltDiff.cc:1098
static std::string key_string(const std::string &_key, const std::string &_string, const std::string &_delim="")
Definition: hltDiff.cc:497
std::string old_process
Definition: hltDiff.cc:1182
void usage(std::ostream &out) const
Definition: hltDiff.cc:1462