24 #include <boost/algorithm/string.hpp>
30 #include <TGraphAsymmErrors.h>
43 void error(std::ostream&
out) { out <<
"Try 'hltDiff --help' for more information" << std::endl; }
45 void error(std::ostream&
out,
const char* message) {
46 out << message << std::endl;
51 out << message << std::endl;
59 virtual unsigned int size()
const = 0;
60 virtual unsigned int size(
unsigned int trigger)
const = 0;
62 virtual unsigned int triggerIndex(
unsigned int trigger)
const = 0;
65 virtual bool prescaler(
unsigned int trigger,
unsigned int module)
const = 0;
86 unsigned int size(
unsigned int trigger)
const override {
return data_.
size(trigger); }
92 unsigned int triggerIndex(
unsigned int trigger)
const override {
return trigger; }
122 ~View()
override =
default;
124 unsigned int size()
const override;
125 unsigned int size(
unsigned int trigger)
const override;
127 unsigned int triggerIndex(
unsigned int trigger)
const override;
130 bool prescaler(
unsigned int trigger,
unsigned int module)
const override;
139 for (
unsigned int f = 0;
f < first.
size(); ++
f)
140 for (
unsigned int s = 0;
s < second.
size(); ++
s)
222 return config_.triggerName(index_, trigger);
226 return config_.triggerIndex(index_, trigger);
230 return config_.moduleLabel(index_, trigger, module);
234 return config_.moduleType(index_, trigger, module);
238 return config_.prescaler(index_, trigger, module);
251 static const char* message[] = {
"not run",
"accepted",
"rejected",
"exception",
"prescaled",
"invalid"};
253 if (state > 0 and state <
Invalid)
254 return message[
state];
273 if (
std::count(s.begin(), s.end(),
':') == 2) {
275 size_t end = s.find_last_of(
':');
276 if (end > 0 and s.at(end - 1) ==
':')
279 return s.substr(0, end);
292 out <<
" by module " << module <<
" '" <<
label <<
"' [" <<
type <<
"]";
294 out <<
" at module " << module <<
" '" <<
label <<
"' [" << type <<
"]";
303 out <<
" not found\n";
313 for (
unsigned int i = 0;
i < summary.
filterKeys(index).size(); ++
i) {
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";
331 out <<
" not found\n";
348 <<
"object id: " << candidate.
id() <<
", "
349 <<
"pT: " << candidate.
pt() <<
", "
350 <<
"eta: " << candidate.
eta() <<
", "
351 <<
"phi: " << candidate.
phi() <<
", "
352 <<
"mass: " << candidate.
mass() <<
"\n";
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]);
363 auto const&
history =
event.processHistory();
364 if (process.empty()) {
372 if (not
history.getConfigurationForProcess(process, config)) {
373 std::cerr <<
"error: the process " << process <<
" is not in the Process History" << std::endl;
377 if (pset ==
nullptr) {
378 std::cerr <<
"error: the configuration for the process " << process <<
" is not available in the Provenance"
382 return std::make_unique<HLTConfigDataEx>(
HLTConfigData(pset));
391 unsigned int internal;
398 memset(buffer, 0, 12);
400 unsigned int digit = 10;
402 buffer[digit] = value % 10 + 48;
406 buffer[digit] =
sign;
411 unsigned int total()
const {
return this->gained + this->lost + this->
internal; }
428 int nSpaces = tab_spaces;
457 str.append(std::to_string(_int));
464 str.insert(1, _string);
472 for (
auto it = _values.begin(); it != _values.end(); ++it) {
477 if (it != --_values.end())
498 std::ostringstream
json;
500 json << key_string(
"file_base", file_base) <<
',';
502 json <<
key(
"files") << list_string(
files) <<
',';
504 json << key_string(
"process",
process) <<
',';
506 json <<
key(
"skipped_triggers") << list_string(skipped_triggers);
514 for (
size_t i = 0;
i < file0.length(); ++
i) {
515 bool identicalInAll =
true;
516 char character = file0.at(
i);
518 if (
file.at(
i) == character)
520 identicalInAll =
false;
525 file_base.push_back(character);
527 const unsigned int file_base_len = file_base.length();
528 if (file_base_len < 1)
532 file.erase(0, file_base_len);
546 std::ostringstream
json;
547 json <<
indent(_indent) <<
key(
"configuration") <<
'{';
548 json <<
indent(_indent + 1) <<
key(
"o") <<
'{';
549 json <<
o.serialise(_indent + 2);
550 json <<
indent(_indent + 1) <<
"},";
551 json <<
indent(_indent + 1) <<
key(
"n") <<
'{';
552 json <<
n.serialise(_indent + 2);
553 json <<
indent(_indent + 1) <<
"},";
555 json <<
indent(_indent + 1) <<
key(
"prescales") << prescales_str <<
',';
557 json <<
indent(_indent) <<
"}";
573 std::ostringstream
json;
574 json <<
indent(_indent) <<
key(
"vars") <<
'{';
575 json <<
indent(_indent + 1) <<
key(
"state") << list_string(
state) <<
',';
576 json <<
indent(_indent + 1) <<
key(
"trigger") << list_string(trigger) <<
',';
577 json <<
indent(_indent + 1) <<
key(
"trigger_passed_count") <<
'[';
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)
584 json <<
indent(_indent + 1) <<
key(
"label") << list_string(
label) <<
',';
585 json <<
indent(_indent + 1) <<
key(
"type") << list_string(
type);
586 json <<
indent(_indent) <<
'}';
601 if (
id <
vars.label.size())
603 vars.label.push_back(labelName);
604 return vars.label.size() - 1;
609 if (
id <
vars.type.size())
611 vars.type.push_back(typeName);
612 return vars.type.size() - 1;
623 std::ostringstream
json;
624 json << key_int(
"s",
int(
s));
629 json << key_int(
"m",
m) <<
',';
630 json << key_int(
"l",
l) <<
',';
631 json << key_int(
"t",
t);
646 std::ostringstream
json;
647 json <<
indent(_indent) << key_int(
"t", tr) <<
',';
648 json <<
indent(_indent) <<
key(
"o") <<
'{' <<
o.serialise() <<
"},";
649 json <<
indent(_indent) <<
key(
"n") <<
'{' <<
n.serialise() <<
"}";
665 std::ostringstream
json;
666 json <<
indent(_indent) <<
'{' <<
"\"r\"" <<
':' <<
run <<
",\"l\":" <<
lumi <<
",\"e\":" <<
event
668 for (
auto it = triggerStates.begin(); it != triggerStates.end(); ++it) {
670 json << (*it).serialise(_indent + 2);
671 json <<
indent(_indent + 1) <<
'}';
672 if (it != --triggerStates.end())
675 json <<
indent(_indent) <<
']' <<
'}';
684 if (!triggerStates.empty()) {
686 if (lastTrigger.
tr == _tr)
690 return triggerStates.back();
699 : writeJson(_writeJson), out_filename_base(std::
move(_file_name)) {
700 useSingleOutFile = out_filename_base.length() > 0;
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);
709 if (!v_events.empty()) {
711 if (lastEvent.
run == _run && lastEvent.
lumi == _lumi && lastEvent.
event == _event)
714 v_events.push_back(
JsonEvent(_run, _lumi, _event));
715 return v_events.back();
719 return JsonEventState(_s, _m, this->labelId(_l), this->typeId(_t));
723 if (useSingleOutFile)
724 return out_filename_base;
728 "DQM_V0001_R%.9d__OLD_%s__NEW_%s_DQM",
739 std::set<std::string> filesCreated, filesNotCreated;
741 if (!m_run_events.empty()) {
743 for (
const auto& runEvents : m_run_events) {
744 const int run = runEvents.first;
745 const std::vector<JsonEvent>& v_events = runEvents.second;
747 std::string output_name = output_filename_base(run) +=
".json";
749 if (out_file.good()) {
752 out_file <<
vars.serialise(1) <<
',';
754 out_file <<
indent(1) <<
key(
"events") <<
'[';
755 for (
auto it = v_events.begin(); it != v_events.end(); ++it) {
756 out_file << (*it).serialise(2);
757 if (it != --v_events.end())
760 out_file <<
indent(1) <<
']';
761 out_file <<
indent(0) <<
"}";
764 filesCreated.insert(output_name);
766 filesNotCreated.insert(output_name);
770 std::string output_name = output_filename_base(0) +=
".json";
772 if (out_file.good()) {
775 out_file <<
vars.serialise(1) <<
',';
777 out_file <<
indent(1) <<
key(
"events") <<
'[';
782 out_file <<
indent(1) <<
']';
783 out_file <<
indent(0) <<
"}";
786 filesCreated.insert(output_name);
788 filesNotCreated.insert(output_name);
791 if (!filesCreated.empty()) {
792 std::cout <<
"Created the following JSON files:" << std::endl;
797 if (!filesNotCreated.empty()) {
798 std::cout <<
"Failed to create the following JSON files (check output directory and its permissions):"
817 Pair(
double _v,
double _e) :
v(_v),
e(_e){};
840 name = _names.at(
id);
848 moduleId = state.
n.
l;
849 v_lost.insert(
event);
851 v_gained.insert(
event);
853 v_changed.insert(
event);
865 bool keepForC()
const {
return !v_changed.empty(); }
867 bool keepForGL()
const {
return !v_gained.empty() || !v_lost.empty(); }
877 accepted_o(_json.
vars.trigger_passed_count.at(
id).
first),
878 accepted_n(_json.
vars.trigger_passed_count.at(
id).
second) {}
881 const int _triggerIndex,
882 const std::vector<std::string>& _moduleNames) {
883 int moduleLabelId = GenericSummary::addEntry(_event, _triggerIndex);
885 if (m_modules.count(moduleLabelId) == 0)
887 m_modules.at(moduleLabelId).addEntry(_event, _triggerIndex);
891 Pair gained(GenericSummary::gained());
894 double all(accepted_n);
900 return Pair(fraction.
v / (fraction.
e + 1
e-10), 0.0);
904 Pair lost(GenericSummary::lost());
907 double all(accepted_o);
913 return Pair(fraction.
v / (fraction.
e + 1
e-10), 0.0);
917 Pair changed(GenericSummary::changed());
920 double all(
json.configuration.events - accepted_o);
926 return Pair(fraction.
v / (fraction.
e + 1
e-10), 0.0);
934 void prepareSummaries(
const int _run,
const std::vector<JsonOutputProducer::JsonEvent>& _events) {
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)
943 for (
size_t i = 0;
i < nModules; ++
i)
948 for (
size_t iTrigger = 0; iTrigger <
event.triggerStates.size(); ++iTrigger) {
950 m_triggerSummary.at(state.
tr).addEntry(
event, iTrigger,
json.vars.label);
952 m_moduleSummary.at(moduleId).addEntry(
event, iTrigger);
959 file_name =
json.output_filename_base(this->
run) +=
".root";
960 auto out_file =
new TFile(file_name.c_str(),
"RECREATE");
966 std::map<std::string, TH1*> m_histo;
969 int nTriggers(0), nTriggers_c(0), nTriggers_gl(0), nModules_c(0), nModules_gl(0);
971 for (
const auto& idSummary : m_triggerSummary) {
972 if (idSummary.second.accepted_o > 0)
974 if (idSummary.second.keepForGL())
976 if (idSummary.second.keepForC())
979 for (
const auto& idSummary : m_moduleSummary) {
980 if (idSummary.second.keepForGL())
982 if (idSummary.second.keepForC())
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);
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));
1015 size_t bin(0), bin_c(0), bin_gl(0);
1016 for (
const auto& idSummary : m_triggerSummary) {
1021 m_histo.at(
"trigger_accepted")->SetBinContent(
bin, summary.
accepted_o);
1023 m_histo.at(
"trigger_accepted")->GetXaxis()->SetBinLabel(
bin, summary.
name.c_str());
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);
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);
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());
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);
1047 m_histo.at(
"trigger_changed_frac")->SetBinError(bin_c, summary.
changed(1).
e);
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());
1058 for (
const auto& idSummary : m_moduleSummary) {
1064 m_histo.at(
"module_gained")->SetBinContent(bin_gl, summary.
gained().
v);
1065 m_histo.at(
"module_lost")->SetBinContent(bin_gl, -summary.
lost().
v);
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());
1073 m_histo.at(
"module_changed")->SetBinContent(bin_c, summary.
changed().
v);
1075 m_histo.at(
"module_changed")->GetXaxis()->SetBinLabel(bin_c, summary.
name.c_str());
1080 for (
const auto& nameHisto : m_histo) {
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);
1087 if (name.find(
"lost") != std::string::npos) {
1088 if (name.find(
"frac") != std::string::npos)
1089 histo->GetYaxis()->SetRangeUser(-1.0, 0.0);
1094 char savePath[1000];
1095 sprintf(savePath,
"DQMData/Run %d/HLT/Run summary/EventByEvent/", this->
run);
1097 gDirectory->cd(savePath);
1098 gDirectory->Write();
1099 for (
const auto& nameHisto : m_histo)
1100 nameHisto.second->Write(nameHisto.first.c_str());
1109 file_name =
json.output_filename_base(this->
run) +=
"_trigger.csv";
1110 FILE*
out_file = fopen(file_name.c_str(),
"w");
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) {
1119 "%d,%d,%d,%+.f,%+.f,%.2f%%,%.2f%%,~%.f,~%.2f%%,%.2f%%,%s\n",
1120 this->
json.configuration.events,
1142 file_name =
json.output_filename_base(this->
run) +=
"_module.csv";
1143 FILE*
out_file = fopen(file_name.c_str(),
"w");
1146 fprintf(out_file,
"Total,Gained,Lost,Changed,module\n");
1147 for (
const auto& idSummary : m_moduleSummary) {
1150 "%d,+%.f,-%.f,~%.f,%s\n",
1151 this->
json.configuration.events,
1169 :
json(_json),
run(0), storeROOT(_storeROOT), storeCSV(_storeCSV) {}
1172 std::vector<std::string> filesCreated, filesNotCreated;
1174 if (!
json.m_run_events.empty()) {
1175 for (
const auto& runEvents :
json.m_run_events) {
1176 prepareSummaries(runEvents.first, runEvents.second);
1179 auto& fNameVec = writeHistograms(fName) ? filesCreated : filesNotCreated;
1180 fNameVec.push_back(fName);
1184 auto& fNameTriggerVec = writeCSV_trigger(fNameTrigger) ? filesCreated : filesNotCreated;
1185 fNameTriggerVec.push_back(fNameTrigger);
1188 auto& fNameModuleVec = writeCSV_module(fNameModule) ? filesCreated : filesNotCreated;
1189 fNameModuleVec.push_back(fNameModule);
1195 auto& fNameVec = writeHistograms(fName) ? filesCreated : filesNotCreated;
1196 fNameVec.push_back(fName);
1200 auto& fNameTriggerVec = writeCSV_trigger(fNameTrigger) ? filesCreated : filesNotCreated;
1201 fNameTriggerVec.push_back(fNameTrigger);
1204 auto& fNameModuleVec = writeCSV_module(fNameModule) ? filesCreated : filesNotCreated;
1205 fNameModuleVec.push_back(fNameModule);
1209 if (!filesCreated.empty()) {
1210 std::cout <<
"Created the following summary files:" << std::endl;
1215 if (!filesNotCreated.empty()) {
1216 std::cout <<
"Failed to create the following summary files (check output directory and its permissions):"
1225 std::unique_ptr<TFile>
f(TFile::Open(file.c_str()));
1226 return (f and not f->IsZombie());
1231 for (
auto const&
file : files)
1234 std::cerr <<
"hltDiff: error: file " <<
file <<
" does not exist, or is not a regular file." << std::endl;
1262 ignore_prescales(
true),
1273 std::shared_ptr<fwlite::ChainEvent> old_events;
1274 std::shared_ptr<fwlite::ChainEvent> new_events;
1277 old_events = std::make_shared<fwlite::ChainEvent>(old_files);
1281 if (new_files.size() == 1 and new_files[0] ==
"-")
1282 new_events = old_events;
1284 new_events = std::make_shared<fwlite::ChainEvent>(new_files);
1302 std::unique_ptr<HLTConfigDataEx> old_config_data;
1303 std::unique_ptr<HLTConfigDataEx> new_config_data;
1304 std::unique_ptr<HLTCommonConfig> common_config;
1309 unsigned int skipped = 0;
1310 unsigned int affected = 0;
1311 bool new_run =
true;
1312 std::vector<TriggerDiff> differences;
1316 const unsigned int counter_denominator =
std::max(1,
int(nEvents / 10));
1317 for (old_events->toBegin(); not old_events->atEnd(); ++(*old_events)) {
1319 if (counter % (counter_denominator) == 0) {
1320 std::cout <<
"Processed events: " << counter <<
" out of " << nEvents <<
" ("
1321 << 10 * counter / (counter_denominator) <<
"%)" << std::endl;
1326 if (new_events != old_events and not new_events->to(
id)) {
1328 std::cerr <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event()
1329 <<
": not found in the 'new' files, skipping." << std::endl;
1339 old_results = old_results_h.
product();
1342 std::cerr <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event()
1343 <<
": 'old' TriggerResults not found, skipping." << std::endl;
1349 old_summary_h.
getByLabel<
fwlite::Event>(*old_events->event(),
"hltTriggerSummaryAOD",
"", old_process.c_str());
1351 old_summary = old_summary_h.
product();
1357 new_results = new_results_h.
product();
1360 std::cerr <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event()
1361 <<
": 'new' TriggerResults not found, skipping." << std::endl;
1367 new_summary_h.
getByLabel<
fwlite::Event>(*new_events->event(),
"hltTriggerSummaryAOD",
"", new_process.c_str());
1369 new_summary = new_summary_h.
product();
1374 old_events->fillParameterSetRegistry();
1375 new_events->fillParameterSetRegistry();
1379 if (new_config_data->triggerNames() == old_config_data->triggerNames()) {
1380 old_config = old_config_data.get();
1381 new_config = new_config_data.get();
1383 common_config = std::make_unique<HLTCommonConfig>(*old_config_data, *new_config_data);
1386 std::cout <<
"Warning: old and new TriggerResults come from different HLT menus. Only the common "
1387 << old_config->size() <<
" triggers are compared.\n"
1391 differences.clear();
1392 differences.resize(old_config->
size());
1395 std::vector<std::string> states_str;
1399 for (
size_t triggerId = 0; triggerId < old_config->
size(); ++triggerId) {
1404 for (
auto const& it : old_config_data->triggerNames()) {
1410 for (
auto const& it : new_config_data->triggerNames()) {
1418 bool needs_header =
true;
1419 bool event_affected =
false;
1420 for (
unsigned int p = 0;
p < old_config->
size(); ++
p) {
1427 if (old_state ==
Pass) {
1428 ++differences.at(
p).count;
1430 if (old_state ==
Pass)
1432 if (new_state ==
Pass)
1435 bool trigger_affected =
false;
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;
1449 if (not trigger_affected)
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);
1469 needs_header =
false;
1470 std::cout <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event() <<
": "
1476 <<
" old state is ";
1479 <<
" new state is ";
1483 if (
verbose > 1 and old_summary and new_summary) {
1485 unsigned int module =
std::min(old_moduleIndex, new_moduleIndex);
1487 std::cout <<
" old trigger candidates:\n";
1491 std::cout <<
" new trigger candidates:\n";
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;
1507 for (
auto const& new_collection : new_summary->collectionTags())
1512 std::cout <<
" old trigger candidates:\n";
1514 std::cout <<
" new trigger candidates:\n";
1521 if (nEvents and counter >= nEvents)
1528 std::cout <<
"There are no common events between the old and new files";
1530 std::cout <<
", " << skipped <<
" events were skipped";
1533 std::cout <<
"Found " << counter <<
" matching events, out of which " << affected
1534 <<
" have different HLT results";
1536 std::cout <<
", " << skipped <<
" events were skipped";
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)
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"
1549 <<
"Trigger" << std::endl;
1550 std::cout << std::setw(12) << counter << differences.at(
p) <<
" " << old_config->triggerName(
p) << std::endl;
1551 summaryHeaderPrinted =
true;
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\
1569 -o|--old-files FILE1.ROOT [FILE2.ROOT ...]\n\
1570 input file(s) with the old (reference) trigger results\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\
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\
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\
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\
1590 do not ignore differences caused by HLTPrescaler modules\n\
1593 produce comparison results in a CSV format\n\
1596 produce comparison results in a JSON format\n\
1599 produce comparison results as histograms in a ROOT file\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\
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\
1610 display messages about missing events and collections\n\
1613 don't display summary printout with the list of affected trigger paths\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\
1623 print this help message, and exit"
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'},
1654 while ((c = getopt_long(argc, argv, optstring, longopts,
nullptr)) != -1) {
1661 hlt->file_check =
true;
1665 hlt->old_files.emplace_back(optarg);
1666 while (optind < argc) {
1667 if (argv[optind][0] ==
'-')
1669 hlt->old_files.emplace_back(argv[optind]);
1675 hlt->old_process = optarg;
1679 hlt->new_files.emplace_back(optarg);
1680 while (optind < argc) {
1681 if (argv[optind][0] ==
'-')
1683 hlt->new_files.emplace_back(argv[optind]);
1689 hlt->new_process = optarg;
1693 hlt->max_events = atoi(optarg);
1697 hlt->ignore_prescales =
false;
1701 hlt->csv_out =
true;
1705 hlt->json_out =
true;
1709 hlt->root_out =
true;
1713 hlt->output_file = optarg;
1720 }
else if (!optarg &&
nullptr != argv[optind] &&
'-' != argv[optind][0]) {
1722 const char* tmp_optarg = argv[optind++];
1743 if (
hlt->old_files.empty()) {
1747 if (
hlt->new_files.empty()) {
unsigned int typeId(std::string typeName)
unsigned int total() const
JsonEvent & pushEvent(int _run, int _lumi, int _event)
std::string const & triggerName(unsigned int trigger) const override
virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const =0
static std::string indent(size_t _nTabs)
std::set< std::string > moduleTypeSet_
tuple ret
prodAgent to be discontinued
std::vector< std::pair< unsigned int, unsigned int > > triggerIndices_
const edm::EventSetup & c
bool prescaler(unsigned int trigger, unsigned int module) const override
std::string const & moduleLabel(Index index, unsigned int trigger, unsigned int module) const
std::string const & moduleType(unsigned int trigger, unsigned int module) const override
std::map< int, GenericSummary > m_modules
std::map< int, std::vector< JsonEvent > > m_run_events
unsigned int labelId(std::string labelName)
virtual ~HLTConfigInterface()=default
bool check_files(std::vector< std::string > const &files)
const std::vector< std::string > & collectionTags() const
The single EDProduct to be saved for each event (AOD case)
trigger::size_type sizeFilters() const
bool operator<(const Event &b) const
uint16_t *__restrict__ id
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
void print_trigger_candidates(std::ostream &out, trigger::TriggerEvent const &summary, edm::InputTag const &filter)
unsigned int size(Index index, unsigned int trigger) const
trigger::size_type collectionKey(trigger::size_type index) const
unsigned int size(unsigned int trigger) const override
std::vector< std::string > skipped_triggers
std::string serialise(size_t _indent=0) const
std::vector< std::vector< std::string const * > > moduleTypes_
Pair gained(int type=0) const
const JsonOutputProducer & json
bool accept() const
Has at least one path accepted the event?
const Keys & filterKeys(trigger::size_type index) const
View(HLTCommonConfig const &config, HLTCommonConfig::Index index)
const std::vector< std::string > & triggerNames() const
names of trigger paths
trigger::size_type filterIndex(const edm::InputTag &filterTag) const
find index of filter in data-member vector from filter tag
std::string const & processName() const override
Pair changed(int type=0) const
virtual bool prescaler(unsigned int trigger, unsigned int module) const =0
std::string const & moduleLabel(unsigned int trigger, unsigned int module) const override
unsigned int size() const
number of trigger paths in trigger table
JsonOutputProducer(bool _writeJson, std::string _file_name)
TriggerSummary(int _id, const JsonOutputProducer &_json)
void print_detailed_path_state(std::ostream &out, State state, int path, int module, HLTConfigInterface const &config)
bool prescaler(unsigned int trigger, unsigned int module) const override
std::vector< std::pair< int, int > > trigger_passed_count
std::string serialise(size_t _indent=0) const
GenericSummary(int _id, const JsonOutputProducer &_json, const std::vector< std::string > &_names)
const char * event_state(bool state)
void prepareSummaries(const int _run, const std::vector< JsonOutputProducer::JsonEvent > &_events)
std::ostream & operator<<(std::ostream &out, const ALILine &li)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
~HLTConfigDataEx() override=default
JsonTriggerEventState & pushTrigger(int _tr)
std::vector< JsonTriggerEventState > triggerStates
std::vector< std::string > label
HLTCommonConfig(HLTConfigDataEx const &first, HLTConfigDataEx const &second)
virtual std::vector< std::string > const & triggerNames() const
Single trigger physics object (e.g., an isolated muon)
U second(std::pair< T, U > const &p)
static std::string format(unsigned int value, char sign= '+')
std::map< int, GenericSummary > m_moduleSummary
std::vector< std::string > old_files
static std::string string(const std::string &_string, const std::string &_delim="")
unsigned int triggerIndex(unsigned int trigger) const override
JsonEventState eventState(State _s, int _m, const std::string &_l, const std::string &_t)
State prescaled_state(int state, int path, int module, HLTConfigInterface const &config)
virtual std::string const & triggerName(unsigned int trigger) const =0
const JsonOutputProducer & json
const Vids & filterIds(trigger::size_type index) const
ParameterSetID const & parameterSetID() const
std::string output_filename_base(int _run) const
Pair(double _v, double _e)
static constexpr int verbose
std::string const & processName() const override
int addEntry(const JsonOutputProducer::JsonEvent &_event, const int _triggerIndex)
HLTConfigDataEx const & second_
std::unique_ptr< HLTConfigDataEx > getHLTConfigData(fwlite::EventBase const &event, std::string process)
const TriggerObjectCollection & getObjects() const
JsonEvent(int _run, int _lumi, int _event)
Event(int _run, int _lumi, int _event)
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
std::string serialise(size_t _indent=0) const
static std::string key_int(const std::string &_key, int _int, const std::string &_delim="")
std::map< int, TriggerSummary > m_triggerSummary
std::string getProcessNameFromBranch(std::string const &branch)
HLTCommonConfig const & config_
tuple key
prepare the HTCondor submission files and eventually submit them
std::set< Event > v_changed
std::vector< std::string > trigger
bool getMapped(key_type const &k, value_type &result) const
virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const =0
const std::string moduleType(const std::string &module) const
C++ class name of module.
std::string out_filename_base
std::string strip_process_name(std::string const &s)
std::string serialise(size_t _indent=0) const
unsigned int size(Index index) const
static std::string list_string(const std::vector< std::string > &_values, const std::string &_delim="")
void addEntry(const JsonOutputProducer::JsonEvent &_event, const int _triggerIndex, const std::vector< std::string > &_moduleNames)
bool writeCSV_module(std::string &file_name) const
virtual unsigned int triggerIndex(unsigned int trigger) const =0
void print_trigger_collection(std::ostream &out, trigger::TriggerEvent const &summary, std::string const &tag)
HLTConfigDataEx(HLTConfigData data)
const std::string & processName() const
Accessors (const methods)
unsigned int triggerIndex(Index index, unsigned int trigger) const
uint16_t *__restrict__ uint16_t const *__restrict__ uint32_t const *__restrict__ uint32_t *__restrict__ uint32_t const *__restrict__ moduleId
std::vector< std::string > state
std::vector< std::string > files
virtual std::string const & processName() const =0
bool writeHistograms(std::string &file_name) const
unsigned int size() const override
std::string const & moduleLabel(unsigned int trigger, unsigned int module) const override
std::string serialise(size_t _indent=0) const
SummaryOutputProducer(const JsonOutputProducer &_json, bool _storeROOT, bool _storeCSV)
std::set< Event > v_gained
void getByLabel(const P &iP, const char *iModuleLabel, const char *iProductInstanceLabel=nullptr, const char *iProcessLabel=nullptr)
const char * path_state(State state)
bool writeCSV_trigger(std::string &file_name) const
HLTConfigDataEx const & first_
tuple config
parse the configuration file
bool check_file(std::string const &file)
char data[epos_bytes_allocation]
virtual unsigned int size() const =0
std::string serialise(size_t _indent=0) const
static std::atomic< unsigned int > counter
std::vector< std::string > type
std::string const & moduleType(Index index, unsigned int trigger, unsigned int module) const
bool prescaler(Index index, unsigned int trigger, unsigned int module) const
std::string const & processName(Index index) const
const std::string & moduleLabel(unsigned int trigger, unsigned int module) const
unsigned int size() const override
T const * product() const
View const & getView(Index index) const
std::vector< std::vector< bool > > prescalers_
std::string const & triggerName(Index index, unsigned int trigger) const
const std::string & triggerName(unsigned int triggerIndex) const
Pair lost(int type=0) const
JsonConfiguration configuration
JsonTriggerEventState(int _tr)
unsigned int triggerIndex(unsigned int trigger) const override
JsonEventState(State _s, int _m, int _l, int _t)
static Registry * instance()
std::string const & triggerName(unsigned int trigger) const override
hlt::HLTState state(const unsigned int i) const
Get status of ith path.
static std::string key(const std::string &_key, const std::string &_delim="")
std::string const & moduleType(unsigned int trigger, unsigned int module) const override
static std::string key_string(const std::string &_key, const std::string &_string, const std::string &_delim="")
void usage(std::ostream &out) const