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