CMS 3D CMS Logo

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