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