24 #include <boost/algorithm/string.hpp> 25 #include <boost/filesystem.hpp> 31 #include <TGraphAsymmErrors.h> 46 out <<
"Try 'hltDiff --help' for more information" << std::endl;
49 void error(std::ostream &
out,
const char * message) {
50 out << message << std::endl;
55 out << message << std::endl;
64 virtual unsigned int size()
const = 0;
65 virtual unsigned int size(
unsigned int trigger)
const = 0;
67 virtual unsigned int triggerIndex(
unsigned int trigger)
const = 0;
70 virtual bool prescaler(
unsigned int trigger,
unsigned int module)
const = 0;
81 for (
unsigned int t = 0;
t < data_.size(); ++
t) {
82 prescalers_[
t].resize(
size(
t));
83 moduleTypes_[
t].resize(
size(
t));
84 for (
unsigned int m = 0;
m < data_.size(
t); ++
m) {
86 prescalers_[
t][
m] = (type ==
"HLTPrescaler");
87 moduleTypes_[
t][
m] = &* moduleTypeSet_.insert(
std::move(type)).first;
93 return data_.processName();
96 unsigned int size()
const override {
101 return data_.size(trigger);
105 return data_.triggerNames();
109 return data_.triggerName(trigger);
117 return data_.moduleLabel(trigger, module);
121 return * moduleTypes_.at(trigger).at(module);
125 return prescalers_.at(trigger).at(module);
137 return state ?
"accepted" :
"rejected";
154 ~
View()
override =
default;
156 unsigned int size()
const override;
157 unsigned int size(
unsigned int trigger)
const override;
159 unsigned int triggerIndex(
unsigned int trigger)
const override;
162 bool prescaler(
unsigned int trigger,
unsigned int module)
const override;
173 firstView_(*this,
Index::First),
174 secondView_(*this,
Index::Second)
176 for (
unsigned int f = 0;
f < first.
size(); ++
f)
177 for (
unsigned int s = 0;
s < second.
size(); ++
s)
179 triggerIndices_.push_back(std::make_pair(
f,
s));
185 if (index == Index::First)
192 if (index == Index::First)
193 return first_.processName();
195 return second_.processName();
199 return triggerIndices_.size();
203 if (index == Index::First)
204 return first_.size(trigger);
206 return second_.size(trigger);
210 if (index == Index::First)
211 return first_.triggerName(triggerIndices_.at(trigger).first);
213 return second_.triggerName(triggerIndices_.at(trigger).second);
217 if (index == Index::First)
218 return triggerIndices_.at(trigger).first;
220 return triggerIndices_.at(trigger).second;
224 if (index == Index::First)
225 return first_.moduleLabel(triggerIndices_.at(trigger).first, module);
227 return second_.moduleLabel(triggerIndices_.at(trigger).second, module);
231 if (index == Index::First)
232 return first_.moduleType(triggerIndices_.at(trigger).first, module);
234 return second_.moduleType(triggerIndices_.at(trigger).second, module);
238 if (index == Index::First)
239 return first_.prescaler(triggerIndices_.at(trigger).first, module);
241 return second_.prescaler(triggerIndices_.at(trigger).second, module);
256 return config_.processName(index_);
260 return config_.size(index_);
264 return config_.size(index_, trigger);
268 return config_.triggerName(index_, trigger);
272 return config_.triggerIndex(index_, trigger);
276 return config_.moduleLabel(index_, trigger, module);
280 return config_.moduleType(index_, trigger, module);
284 return config_.prescaler(index_, trigger, module);
298 static const char * message[] = {
"not run",
"accepted",
"rejected",
"exception",
"prescaled",
"invalid" };
300 if (state > 0 and state <
Invalid)
301 return message[state];
310 return (
State) state;
321 if (
std::count(s.begin(), s.end(),
':') == 2) {
323 size_t end = s.find_last_of(
':');
324 if (end > 0 and s.at(end-1) ==
':')
327 return s.substr(0, end);
341 out <<
" by module " << module <<
" '" <<
label <<
"' [" <<
type <<
"]";
343 out <<
" at module " << module <<
" '" <<
label <<
"' [" << type <<
"]";
352 out <<
" not found\n";
362 for (
unsigned int i = 0;
i < summary.
filterKeys(index).size(); ++
i) {
367 <<
"filter id: " <<
id <<
", " 368 <<
"object id: " << candidate.
id() <<
", " 369 <<
"pT: " << candidate.
pt() <<
", " 370 <<
"eta: " << candidate.
eta() <<
", " 371 <<
"phi: " << candidate.
phi() <<
", " 372 <<
"mass: " << candidate.
mass() <<
"\n";
380 out <<
" not found\n";
397 <<
"object id: " << candidate.
id() <<
", " 398 <<
"pT: " << candidate.
pt() <<
", " 399 <<
"eta: " << candidate.
eta() <<
", " 400 <<
"phi: " << candidate.
phi() <<
", " 401 <<
"mass: " << candidate.
mass() <<
"\n";
407 std::vector<boost::iterator_range<std::string::const_iterator>> tokens;
408 boost::split(tokens, branch, boost::is_any_of(
"_."), boost::token_compress_off);
409 return boost::copy_range<std::string>(tokens[3]);
413 auto const & history =
event.processHistory();
414 if (process.empty()) {
421 if (not history.getConfigurationForProcess(process, config)) {
422 std::cerr <<
"error: the process " << process <<
" is not in the Process History" << std::endl;
426 if (pset ==
nullptr) {
427 std::cerr <<
"error: the configuration for the process " << process <<
" is not available in the Provenance" << std::endl;
430 return std::make_unique<HLTConfigDataEx>(
HLTConfigData(pset));
440 unsigned int internal;
448 memset(buffer, 0, 12);
450 unsigned int digit = 10;
452 buffer[digit] = value % 10 + 48;
456 buffer[digit] =
sign;
462 return this->gained + this->lost + this->
internal;
467 out << std::setw(12) << diff.
count 484 int nSpaces = tab_spaces;
513 str.append(std::to_string(_int));
520 str.insert(1, _string);
528 for (
auto it = _values.begin(); it != _values.end(); ++it) {
533 if (it != --_values.end()) str.push_back(
',');
553 std::ostringstream
json;
555 json << key_string(
"file_base", file_base) <<
',';
557 json <<
key(
"files") << list_string(files) <<
',';
559 json << key_string(
"process", process) <<
',';
561 json <<
key(
"skipped_triggers") << list_string(skipped_triggers);
569 for (
size_t i = 0;
i < file0.length(); ++
i) {
570 bool identicalInAll =
true;
571 char character = file0.at(
i);
573 if (
file.at(
i) == character)
continue;
574 identicalInAll =
false;
577 if (!identicalInAll)
break;
578 file_base.push_back(character);
580 const unsigned int file_base_len = file_base.length();
581 if (file_base_len < 1)
return;
584 file.erase(0, file_base_len);
598 std::ostringstream
json;
599 json <<
indent(_indent) <<
key(
"configuration") <<
'{';
600 json <<
indent(_indent+1) <<
key(
"o") <<
'{';
602 json <<
indent(_indent+1) <<
"},";
603 json <<
indent(_indent+1) <<
key(
"n") <<
'{';
605 json <<
indent(_indent+1) <<
"},";
606 std::string prescales_str = prescales ?
"true" :
"false";
607 json <<
indent(_indent+1) <<
key(
"prescales") << prescales_str <<
',';
609 json <<
indent(_indent) <<
"}";
625 std::ostringstream
json;
626 json <<
indent(_indent) <<
key(
"vars") <<
'{';
627 json <<
indent(_indent+1) <<
key(
"state") << list_string(state) <<
',';
628 json <<
indent(_indent+1) <<
key(
"trigger") << list_string(trigger) <<
',';
629 json <<
indent(_indent+1) <<
key(
"trigger_passed_count") <<
'[';
630 for (
auto it = trigger_passed_count.begin(); it != trigger_passed_count.end(); ++it) {
631 json <<
'{' <<
key(
"o") << (*it).first <<
',' <<
key(
"n") << (*it).second <<
'}';
632 if (it != trigger_passed_count.end()-1)
636 json <<
indent(_indent+1) <<
key(
"label") << list_string(label) <<
',';
637 json <<
indent(_indent+1) <<
key(
"type") << list_string(type);
638 json <<
indent(_indent) <<
'}';
643 JsonVars() : state(0), trigger(0), trigger_passed_count(0), label(0), type(0) {}
653 if (
id < vars.
label.size())
655 vars.
label.push_back(labelName);
656 return vars.
label.size()-1;
661 if (
id < vars.
type.size())
663 vars.
type.push_back(typeName);
664 return vars.
type.size()-1;
675 std::ostringstream
json;
676 json << key_int(
"s",
int(s));
680 json << key_int(
"m", m) <<
',';
681 json << key_int(
"l", l) <<
',';
682 json << key_int(
"t", t);
697 std::ostringstream
json;
698 json <<
indent(_indent) << key_int(
"t", tr) <<
',';
716 std::ostringstream
json;
717 json <<
indent(_indent) <<
'{' <<
"\"r\"" <<
':' << run <<
",\"l\":" << lumi <<
",\"e\":" <<
event <<
",\"t\":[";
718 for (
auto it = triggerStates.begin(); it != triggerStates.end(); ++it) {
720 json << (*it).serialise(_indent+2);
721 json <<
indent(_indent+1) <<
'}';
722 if (it != --triggerStates.end()) json <<
',';
724 json <<
indent(_indent) <<
']' <<
'}';
730 run(_run), lumi(_lumi), event(_event), triggerStates(0) { }
734 if (!triggerStates.empty()) {
736 if (lastTrigger.
tr == _tr)
740 return triggerStates.back();
750 writeJson(_writeJson),
751 out_filename_base(
std::
move(_file_name)) {
752 useSingleOutFile = out_filename_base.length() > 0;
757 if ( (m_run_events.count(_run) == 0 && !useSingleOutFile) || m_run_events.empty() )
758 m_run_events.emplace(_run, std::vector<JsonEvent>());
759 std::vector<JsonEvent>& v_events = useSingleOutFile ? m_run_events.begin()->second : m_run_events.at(_run);
761 if (!v_events.empty()) {
763 if (lastEvent.
run == _run && lastEvent.
lumi == _lumi && lastEvent.
event == _event)
766 v_events.push_back(
JsonEvent(_run, _lumi, _event));
767 return v_events.back();
771 return JsonEventState(_s, _m, this->labelId(_l), this->typeId(_t));
775 if (useSingleOutFile)
776 return out_filename_base;
779 sprintf(name,
"DQM_V0001_R%.9d__OLD_%s__NEW_%s_DQM", _run, configuration.
o.
process.c_str(), configuration.
n.
process.c_str());
785 if (!writeJson)
return;
786 std::set<std::string> filesCreated;
787 std::ofstream out_file;
788 if (!m_run_events.empty()) {
790 for (
const auto& runEvents : m_run_events) {
791 const int run = runEvents.first;
792 const std::vector<JsonEvent>& v_events = runEvents.second;
794 std::string output_name = output_filename_base(run)+=
".json";
797 out_file << configuration.
serialise(1) <<
',';
800 out_file <<
indent(1) <<
key(
"events") <<
'[';
801 for (
auto it = v_events.begin(); it != v_events.end(); ++it) {
802 out_file << (*it).serialise(2);
803 if (it != --v_events.end()) out_file <<
',';
805 out_file <<
indent(1) <<
']';
806 out_file <<
indent(0) <<
"}";
809 filesCreated.insert(output_name);
813 std::string output_name = output_filename_base(0)+=
".json";
816 out_file << configuration.
serialise(1) <<
',';
819 out_file <<
indent(1) <<
key(
"events") <<
'[';
824 out_file <<
indent(1) <<
']';
825 out_file <<
indent(0) <<
"}";
828 filesCreated.insert(output_name);
831 if (!filesCreated.empty()) {
832 std::cout <<
"Created the following JSON files:" << std::endl;
851 Pair(
double _v,
double _e) : v(_v), e(_e) {};
852 Pair(
int _v,
int _e) : v(_v), e(_e) {};
860 Event(
int _run,
int _lumi,
int _event) : run(_run), lumi(_lumi), event(_event) {};
862 return std::tie(run, lumi, event) < std::tie(b.
run, b.
lumi, b.
event);
877 name = _names.at(
id);
883 int moduleId = state.
o.
l;
885 moduleId = state.
n.
l;
886 v_lost.insert(
event);
889 v_gained.insert(
event);
892 v_changed.insert(
event);
899 return Pair(
double(v_gained.size()),
sqrt(
double(v_gained.size()) ) );
903 return Pair(
double(v_lost.size()),
sqrt(
double(v_lost.size()) ) );
907 return Pair(
double(v_changed.size()),
sqrt(
double(v_changed.size()) ) );
911 return !v_changed.empty();
915 return !v_gained.empty() || !v_lost.empty();
926 accepted_o(_json.
vars.trigger_passed_count.at(
id).
first),
927 accepted_n(_json.
vars.trigger_passed_count.at(
id).
second) {}
932 if (m_modules.count(moduleLabelId) == 0)
933 m_modules.emplace(moduleLabelId,
GenericSummary(moduleLabelId, json, _moduleNames));
934 m_modules.at(moduleLabelId).addEntry(_event, _triggerIndex);
938 Pair gained( GenericSummary::gained() );
939 if (
type == 0)
return gained;
940 double all( accepted_n );
944 return Pair( fraction.
v / (fraction.
e + 1
e-10), 0.0 );
948 Pair lost( GenericSummary::lost() );
949 if (
type == 0)
return lost;
950 double all( accepted_o );
954 return Pair( fraction.
v / (fraction.
e + 1
e-10), 0.0 );
958 Pair changed( GenericSummary::changed() );
959 if (
type == 0)
return changed;
964 return Pair( fraction.
v / (fraction.
e + 1
e-10), 0.0 );
972 void prepareSummaries(
const int _run,
const std::vector<JsonOutputProducer::JsonEvent>& _events) {
975 m_triggerSummary.clear();
976 m_moduleSummary.clear();
977 const size_t nTriggers( json.
vars.
trigger.size() );
978 const size_t nModules( json.
vars.
label.size() );
979 for (
size_t i=0;
i<nTriggers; ++
i)
981 for (
size_t i=0;
i<nModules; ++
i)
986 for (
size_t iTrigger = 0; iTrigger <
event.triggerStates.size(); ++iTrigger) {
990 m_moduleSummary.at(moduleId).addEntry(
event, iTrigger);
996 std::map<std::string, TH1*> m_histo;
999 int nTriggers(0), nTriggers_c(0), nTriggers_gl(0), nModules_c(0), nModules_gl(0);
1001 for (
const auto& idSummary : m_triggerSummary) {
1002 if (idSummary.second.accepted_o > 0) ++nTriggers;
1003 if (idSummary.second.keepForGL()) ++nTriggers_gl;
1004 if (idSummary.second.keepForC()) ++nTriggers_c;
1006 for (
const auto& idSummary : m_moduleSummary) {
1007 if (idSummary.second.keepForGL()) ++nModules_gl;
1008 if (idSummary.second.keepForC()) ++nModules_c;
1011 nTriggers =
std::max(1, nTriggers);
1012 nTriggers_gl =
std::max(1, nTriggers_gl);
1013 nTriggers_c =
std::max(1, nTriggers_c);
1014 nModules_c =
std::max(1, nModules_c);
1015 nModules_gl =
std::max(1, nModules_gl);
1019 m_histo.emplace(name,
new TH1F(name.c_str(),
";;Events accepted^{OLD}", nTriggers, 0, nTriggers));
1020 name =
"trigger_gained";
1021 m_histo.emplace(name,
new TH1F(name.c_str(),
";;Events gained", nTriggers_gl, 0, nTriggers_gl));
1022 name =
"trigger_lost";
1023 m_histo.emplace(name,
new TH1F(name.c_str(),
";;Events lost", nTriggers_gl, 0, nTriggers_gl));
1024 name =
"trigger_changed";
1025 m_histo.emplace(name,
new TH1F(name.c_str(),
";;Events changed", nTriggers_c, 0, nTriggers_c));
1026 name =
"trigger_gained_frac";
1027 m_histo.emplace(name,
new TH1F(name.c_str(),
";;#frac{gained}{accepted}", nTriggers_gl, 0, nTriggers_gl));
1028 name =
"trigger_lost_frac";
1029 m_histo.emplace(name,
new TH1F(name.c_str(),
";;#frac{lost}{accepted}", nTriggers_gl, 0, nTriggers_gl));
1030 name =
"trigger_changed_frac";
1031 m_histo.emplace(name,
new TH1F(name.c_str(),
";;#frac{changed}{all - accepted}", nTriggers_c, 0, nTriggers_c));
1032 name =
"module_changed";
1033 m_histo.emplace(name,
new TH1F(name.c_str(),
";;Events changed", nModules_c, 0, nModules_c));
1034 name =
"module_gained";
1035 m_histo.emplace(name,
new TH1F(name.c_str(),
";;Events gained", nModules_gl, 0, nModules_gl));
1036 name =
"module_lost";
1037 m_histo.emplace(name,
new TH1F(name.c_str(),
";;Events lost", nModules_gl, 0, nModules_gl));
1040 size_t bin(0), bin_c(0), bin_gl(0);
1041 for (
const auto& idSummary : m_triggerSummary) {
1046 m_histo.at(
"trigger_accepted")->SetBinContent(
bin, summary.
accepted_o);
1048 m_histo.at(
"trigger_accepted")->GetXaxis()->SetBinLabel(
bin, summary.
name.c_str());
1053 m_histo.at(
"trigger_gained")->SetBinContent(bin_gl, summary.
gained().
v);
1054 m_histo.at(
"trigger_lost")->SetBinContent(bin_gl, -summary.
lost().
v);
1055 m_histo.at(
"trigger_gained_frac")->SetBinContent(bin_gl, summary.
gained(1).
v);
1056 m_histo.at(
"trigger_lost_frac")->SetBinContent(bin_gl, -summary.
lost(1).
v);
1058 m_histo.at(
"trigger_gained_frac")->SetBinError(bin_gl, summary.
gained(1).
e);
1059 m_histo.at(
"trigger_lost_frac")->SetBinError(bin_gl, -summary.
lost(1).
e);
1061 m_histo.at(
"trigger_gained")->GetXaxis()->SetBinLabel(bin_gl, summary.
name.c_str());
1062 m_histo.at(
"trigger_lost")->GetXaxis()->SetBinLabel(bin_gl, summary.
name.c_str());
1063 m_histo.at(
"trigger_gained_frac")->GetXaxis()->SetBinLabel(bin_gl, summary.
name.c_str());
1064 m_histo.at(
"trigger_lost_frac")->GetXaxis()->SetBinLabel(bin_gl, summary.
name.c_str());
1069 m_histo.at(
"trigger_changed")->SetBinContent(bin_c, summary.
changed().
v);
1070 m_histo.at(
"trigger_changed_frac")->SetBinContent(bin_c, summary.
changed(1).
v);
1072 m_histo.at(
"trigger_changed_frac")->SetBinError(bin_c, summary.
changed(1).
e);
1074 m_histo.at(
"trigger_changed")->GetXaxis()->SetBinLabel(bin_c, summary.
name.c_str());
1075 m_histo.at(
"trigger_changed_frac")->GetXaxis()->SetBinLabel(bin_c, summary.
name.c_str());
1083 for (
const auto& idSummary : m_moduleSummary) {
1089 m_histo.at(
"module_gained")->SetBinContent(bin_gl, summary.
gained().
v);
1090 m_histo.at(
"module_lost")->SetBinContent(bin_gl, -summary.
lost().
v);
1092 m_histo.at(
"module_gained")->GetXaxis()->SetBinLabel(bin_gl, summary.
name.c_str());
1093 m_histo.at(
"module_lost")->GetXaxis()->SetBinLabel(bin_gl, summary.
name.c_str());
1098 m_histo.at(
"module_changed")->SetBinContent(bin_c, summary.
changed().
v);
1100 m_histo.at(
"module_changed")->GetXaxis()->SetBinLabel(bin_c, summary.
name.c_str());
1105 for (
const auto& nameHisto : m_histo) {
1107 TH1*
histo = nameHisto.second;
1108 if (name.find(
"gained") != std::string::npos || name.find(
"changed") != std::string::npos) {
1109 if (name.find(
"frac") != std::string::npos)
1110 histo->GetYaxis()->SetRangeUser(0.0, 1.0);
1112 if (name.find(
"lost") != std::string::npos) {
1113 if (name.find(
"frac") != std::string::npos)
1114 histo->GetYaxis()->SetRangeUser(-1.0, 0.0);
1120 auto out_file =
new TFile(file_name.c_str(),
"RECREATE");
1122 char savePath[1000];
1123 sprintf(savePath,
"DQMData/Run %d/HLT/Run summary/EventByEvent/", this->run);
1124 out_file->mkdir(savePath);
1125 gDirectory->cd(savePath);
1126 gDirectory->Write();
1127 for (
const auto& nameHisto : m_histo)
1128 nameHisto.second->Write(nameHisto.first.c_str());
1136 FILE* out_file = fopen((file_name).c_str(),
"w");
1138 fprintf(out_file,
"Total,Accepted OLD,Accepted NEW,Gained,Lost,|G|/A_N + |L|/AO,sigma(AN)+sigma(AO),Changed,C/(T-AO),sigma(T-AO),trigger\n");
1139 for (
const auto& idSummary : m_triggerSummary) {
1141 fprintf(out_file,
"%d,%d,%d,%+.f,%+.f,%.2f%%,%.2f%%,~%.f,~%.2f%%,%.2f%%,%s\n",
1142 this->json.
configuration.
events, S.
accepted_o, S.
accepted_n, S.
gained().
v, -1.0*S.
lost().
v, (S.
gained(1).
v+S.
lost(1).
v)*100.0, (S.
gained(1).
e+S.
lost(1).
e)*100.0, S.
changed().
v, S.
changed(1).
v*100.0, S.
changed(1).
e*100.0, S.
name.c_str());
1152 FILE* out_file = fopen((file_name).c_str(),
"w");
1154 fprintf(out_file,
"Total,Gained,Lost,Changed,module\n");
1155 for (
const auto& idSummary : m_moduleSummary) {
1157 fprintf(out_file,
"%d,+%.f,-%.f,~%.f,%s\n",
1173 storeROOT(_storeROOT),
1174 storeCSV(_storeCSV) {}
1177 std::vector<std::string> filesCreated;
1181 prepareSummaries(runEvents.first, runEvents.second);
1183 filesCreated.push_back(writeHistograms());
1186 filesCreated.push_back(writeCSV_trigger());
1187 filesCreated.push_back(writeCSV_module());
1192 filesCreated.push_back(writeHistograms());
1195 filesCreated.push_back(writeCSV_trigger());
1196 filesCreated.push_back(writeCSV_module());
1200 if (!filesCreated.empty()) {
1201 std::cout <<
"Created the following summary files:" << std::endl;
1211 std::unique_ptr<TFile>
f(TFile::Open(file.c_str()));
1212 return (f and not f->IsZombie());
1218 for (
auto const &
file: files)
1221 std::cerr <<
"hltDiff: error: file " <<
file <<
" does not exist, or is not a regular file." << std::endl;
1251 ignore_prescales(
true),
1262 std::shared_ptr<fwlite::ChainEvent> old_events;
1263 std::shared_ptr<fwlite::ChainEvent> new_events;
1266 old_events = std::make_shared<fwlite::ChainEvent>(old_files);
1270 if (new_files.size() == 1 and new_files[0] ==
"-")
1271 new_events = old_events;
1273 new_events = std::make_shared<fwlite::ChainEvent>(new_files);
1291 std::unique_ptr<HLTConfigDataEx> old_config_data;
1292 std::unique_ptr<HLTConfigDataEx> new_config_data;
1293 std::unique_ptr<HLTCommonConfig> common_config;
1299 unsigned int affected = 0;
1300 bool new_run =
true;
1301 std::vector<TriggerDiff> differences;
1305 const unsigned int counter_denominator =
std::max(1,
int(nEvents/10));
1306 for (old_events->toBegin(); not old_events->atEnd(); ++(*old_events)) {
1308 if (counter%(counter_denominator) == 0) {
1309 std::cout <<
"Processed events: " << counter <<
" out of " << nEvents
1310 <<
" (" << 10*counter/(counter_denominator) <<
"%)" << std::endl;
1315 if (new_events != old_events and not new_events->to(
id)) {
1317 std::cerr <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event() <<
": not found in the 'new' files, skipping." << std::endl;
1327 old_results = old_results_h.
product();
1330 std::cerr <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event() <<
": 'old' TriggerResults not found, skipping." << std::endl;
1336 old_summary_h.
getByLabel<
fwlite::Event>(* old_events->event(),
"hltTriggerSummaryAOD",
"", old_process.c_str());
1338 old_summary = old_summary_h.
product();
1344 new_results = new_results_h.
product();
1347 std::cerr <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event() <<
": 'new' TriggerResults not found, skipping." << std::endl;
1353 new_summary_h.
getByLabel<
fwlite::Event>(* new_events->event(),
"hltTriggerSummaryAOD",
"", new_process.c_str());
1355 new_summary = new_summary_h.
product();
1360 old_events->fillParameterSetRegistry();
1361 new_events->fillParameterSetRegistry();
1365 if (new_config_data->triggerNames() == old_config_data->triggerNames()) {
1366 old_config = old_config_data.get();
1367 new_config = new_config_data.get();
1369 common_config = std::make_unique<HLTCommonConfig>(*old_config_data, *new_config_data);
1372 std::cout <<
"Warning: old and new TriggerResults come from different HLT menus. Only the common " << old_config->size() <<
" triggers are compared.\n" << std::endl;
1375 differences.clear();
1376 differences.resize(old_config->
size());
1379 std::vector<std::string> states_str;
1383 for (
size_t triggerId = 0; triggerId < old_config->
size(); ++triggerId) {
1388 for (
auto const & it : old_config_data->triggerNames()) {
1393 for (
auto const & it : new_config_data->triggerNames()) {
1400 bool needs_header =
true;
1401 bool event_affected =
false;
1402 for (
unsigned int p = 0;
p < old_config->
size(); ++
p) {
1409 if (old_state ==
Pass) {
1410 ++differences.at(
p).count;
1412 if (old_state ==
Pass)
1414 if (new_state ==
Pass)
1417 bool trigger_affected =
false;
1419 if (old_state ==
Pass and new_state !=
Pass) {
1420 ++differences.at(
p).lost;
1421 trigger_affected =
true;
1422 }
else if (old_state !=
Pass and new_state ==
Pass) {
1423 ++differences.at(
p).gained;
1424 trigger_affected =
true;
1425 }
else if (old_results->
index(old_index) != new_results->
index(new_index)) {
1426 ++differences.at(
p).internal;
1427 trigger_affected =
true;
1431 if (not trigger_affected)
continue;
1433 event_affected =
true;
1434 const unsigned int old_moduleIndex = old_results->
index(old_index);
1435 const unsigned int new_moduleIndex = new_results->
index(new_index);
1444 needs_header =
false;
1445 std::cout <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event() <<
": " 1452 <<
" old state is ";
1455 <<
" new state is ";
1459 if (verbose > 1 and old_summary and new_summary) {
1461 unsigned int module =
std::min(old_moduleIndex, new_moduleIndex);
1463 std::cout <<
" old trigger candidates:\n";
1465 std::cout <<
" new trigger candidates:\n";
1475 if (event_affected and verbose > 2 and old_summary and new_summary) {
1476 std::map<std::string, std::pair<std::string, std::string>> collections;
1479 for (
auto const & new_collection: new_summary->collectionTags())
1484 std::cout <<
" old trigger candidates:\n";
1486 std::cout <<
" new trigger candidates:\n";
1493 if (nEvents and counter >= nEvents)
1500 std::cout <<
"There are no common events between the old and new files";
1502 std::cout <<
", " << skipped <<
" events were skipped";
1505 std::cout <<
"Found " << counter <<
" matching events, out of which " << affected <<
" have different HLT results";
1507 std::cout <<
", " << skipped <<
" events were skipped";
1512 bool summaryHeaderPrinted =
false;
1513 for (
size_t p = 0;
p < old_config->
size(); ++
p) {
1514 if (differences.at(
p).total() < 1)
continue;
1515 if (!summaryHeaderPrinted)
1516 std::cout << std::setw(12) <<
"Events" << std::setw(12) <<
"Accepted" << std::setw(12) <<
"Gained" << std::setw(12) <<
"Lost" << std::setw(12) <<
"Other" <<
" " <<
"Trigger" << std::endl;
1517 std::cout << std::setw(12) << counter << differences.at(
p) <<
" " << old_config->
triggerName(
p) << std::endl;
1518 summaryHeaderPrinted =
true;
1530 usage: hltDiff -o|--old-files FILE1.ROOT [FILE2.ROOT ...] [-O|--old-process LABEL[:INSTANCE[:PROCESS]]]\n\ 1531 -n|--new-files FILE1.ROOT [FILE2.ROOT ...] [-N|--new-process LABEL[:INSTANCE[:PROCESS]]]\n\ 1532 [-m|--max-events MAXEVENTS] [-p|--prescales] [-c|--csv-output] [-j|--json-output]\n\ 1533 [-r|--root-output] [-f|--file-check] [-d|--debug] [-q|--quiet] [-v|--verbose]\n\ 1534 [-h|--help] [-F|--output-file] FILE_NAME\n\ 1536 -o|--old-files FILE1.ROOT [FILE2.ROOT ...]\n\ 1537 input file(s) with the old (reference) trigger results\n\ 1539 -O|--old-process PROCESS\n\ 1540 process name of the collection with the old (reference) trigger results\n\ 1541 default: take the 'TriggerResults' from the last process\n\ 1543 -n|--new-files FILE1.ROOT [FILE2.ROOT ...]\n\ 1544 input file(s) with the new trigger results to be compared with the reference\n\ 1545 to read these from a different collection in the same files as\n\ 1546 the reference, use '-n -' and specify the collection with -N (see below)\n\ 1548 -N|--new-process PROCESS\n\ 1549 process name of the collection with the new (reference) trigger results\n\ 1550 default: take the 'TriggerResults' from the last process\n\ 1552 -m|--max-events MAXEVENTS\n\ 1553 compare only the first MAXEVENTS events\n\ 1554 default: compare all the events in the original (reference) files\n\ 1557 do not ignore differences caused by HLTPrescaler modules\n\ 1560 produce comparison results in a CSV format\n\ 1563 produce comparison results in a JSON format\n\ 1566 produce comparison results as histograms in a ROOT file\n\ 1568 -F|--output-file FILE_NAME\n\ 1569 combine all RUNs to files with the specified custom name: FILE_NAME.json, FILE_NAME.root\n\ 1570 default: a separate output file will be produced for each RUN with names suitable for the DQM GUI\n\ 1573 check existence of every old and new file before running the comparison\n\ 1574 safer if files are run for the first time, but can cause a substantial delay\n\ 1577 display messages about missing events and collectiions\n\ 1580 don't display summary printout with the list of affected trigger paths\n\ 1582 -v|--verbose LEVEL\n\ 1583 set verbosity level:\n\ 1584 1: event-by-event comparison results\n\ 1585 2: + print the trigger candidates of the affected filters\n\ 1586 3: + print all the trigger candidates for the affected events\n\ 1590 print this help message, and exit" << std::endl;
1598 const char optstring[] =
"dfo:O:n:N:m:pcjrF:v::hq";
1599 const option longopts[] = {
1600 option{
"debug", no_argument,
nullptr,
'd' },
1601 option{
"file-check", no_argument,
nullptr,
'f' },
1602 option{
"old-files", required_argument,
nullptr,
'o' },
1603 option{
"old-process", required_argument,
nullptr,
'O' },
1604 option{
"new-files", required_argument,
nullptr,
'n' },
1605 option{
"new-process", required_argument,
nullptr,
'N' },
1606 option{
"max-events", required_argument,
nullptr,
'm' },
1607 option{
"prescales", no_argument,
nullptr,
'p' },
1608 option{
"csv-output", optional_argument,
nullptr,
'c' },
1609 option{
"json-output", optional_argument,
nullptr,
'j' },
1610 option{
"root-output", optional_argument,
nullptr,
'r' },
1611 option{
"output-file", optional_argument,
nullptr,
'F' },
1612 option{
"verbose", optional_argument,
nullptr,
'v' },
1613 option{
"help", no_argument,
nullptr,
'h' },
1614 option{
"quiet", no_argument,
nullptr,
'q' },
1622 while ((c = getopt_long(argc, argv, optstring, longopts,
nullptr)) != -1) {
1629 hlt->file_check =
true;
1633 hlt->old_files.emplace_back(optarg);
1634 while (optind < argc) {
1635 if (argv[optind][0] ==
'-')
1637 hlt->old_files.emplace_back(argv[optind]);
1643 hlt->old_process = optarg;
1647 hlt->new_files.emplace_back(optarg);
1648 while (optind < argc) {
1649 if (argv[optind][0] ==
'-')
1651 hlt->new_files.emplace_back(argv[optind]);
1657 hlt->new_process = optarg;
1661 hlt->max_events = atoi(optarg);
1665 hlt->ignore_prescales =
false;
1669 hlt->csv_out =
true;
1673 hlt->json_out =
true;
1677 hlt->root_out =
true;
1681 hlt->output_file = optarg;
1688 }
else if (!optarg &&
nullptr != argv[optind] &&
'-' != argv[optind][0]) {
1690 const char *tmp_optarg = argv[optind++];
1711 if (
hlt->old_files.empty()) {
1715 if (
hlt->new_files.empty()) {
unsigned int typeId(std::string typeName)
std::string const & processName() const override
unsigned int total() const
JsonEvent & pushEvent(int _run, int _lumi, int _event)
std::string const & processName() const override
static std::string indent(size_t _nTabs)
virtual unsigned int triggerIndex(unsigned int trigger) const =0
std::set< std::string > moduleTypeSet_
std::vector< std::pair< unsigned int, unsigned int > > triggerIndices_
std::string const & moduleLabel(Index index, unsigned int trigger, unsigned int module) const
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
std::string const & moduleLabel(unsigned int trigger, unsigned int module) const override
virtual std::string const & processName() const =0
void print_trigger_candidates(std::ostream &out, trigger::TriggerEvent const &summary, edm::InputTag const &filter)
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
unsigned int size(Index index, unsigned int trigger) const
trigger::size_type collectionKey(trigger::size_type index) const
std::string const & triggerName(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?
std::string writeCSV_module() const
const Keys & filterKeys(trigger::size_type index) const
View(HLTCommonConfig const &config, HLTCommonConfig::Index index)
std::string const & moduleLabel(unsigned int trigger, unsigned int module) const override
trigger::size_type filterIndex(const edm::InputTag &filterTag) const
find index of filter in data-member vector from filter tag
Pair changed(int type=0) const
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)
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)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
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= '+')
void getByLabel(const P &iP, const char *iModuleLabel, const char *iProductInstanceLabel=0, const char *iProcessLabel=0)
std::map< int, GenericSummary > m_moduleSummary
std::vector< std::string > old_files
static std::string string(const std::string &_string, const std::string &_delim="")
bool prescaler(unsigned int trigger, unsigned int module) 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)
const JsonOutputProducer & json
const Vids & filterIds(trigger::size_type index) const
def addEntry(schema, datatableName, entryinfo, branchinfo)
ParameterSetID const & parameterSetID() const
std::string output_filename_base(int _run) const
Pair(double _v, double _e)
int addEntry(const JsonOutputProducer::JsonEvent &_event, const int _triggerIndex)
HLTConfigDataEx const & second_
std::unique_ptr< HLTConfigDataEx > getHLTConfigData(fwlite::EventBase const &event, std::string process)
std::string const & moduleType(unsigned int trigger, unsigned int module) const override
const TriggerObjectCollection & getObjects() const
JsonEvent(int _run, int _lumi, int _event)
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
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
virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const =0
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_
std::set< Event > v_changed
std::vector< std::string > trigger
bool getMapped(key_type const &k, value_type &result) const
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)
unsigned int size() const override
std::string const & triggerName(unsigned int trigger) const override
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)
void print_trigger_collection(std::ostream &out, trigger::TriggerEvent const &summary, std::string const &tag)
bool prescaler(unsigned int trigger, unsigned int module) const override
unsigned int triggerIndex(unsigned int trigger) const override
HLTConfigDataEx(HLTConfigData data)
int main(int argc, char **argv)
bin
set the eta bin as selection string.
unsigned int triggerIndex(Index index, unsigned int trigger) const
unsigned int triggerIndex(unsigned int trigger) const override
std::vector< std::string > state
std::vector< std::string > files
std::ostream & operator<<(std::ostream &out, TriggerDiff diff)
std::string serialise(size_t _indent=0) const
std::string writeHistograms() const
SummaryOutputProducer(const JsonOutputProducer &_json, bool _storeROOT, bool _storeCSV)
std::set< Event > v_gained
const char * path_state(State state)
unsigned int size(unsigned int trigger) const override
HLTConfigDataEx const & first_
bool operator<(DTCELinkId const &lhs, DTCELinkId const &rhs)
bool check_file(std::string const &file)
virtual unsigned int size() const =0
char data[epos_bytes_allocation]
std::string serialise(size_t _indent=0) const
static std::atomic< unsigned int > counter
virtual std::string const & triggerName(unsigned int trigger) const =0
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
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
virtual bool prescaler(unsigned int trigger, unsigned int module) const =0
Pair lost(int type=0) const
JsonConfiguration configuration
unsigned int size() const override
JsonTriggerEventState(int _tr)
JsonEventState(State _s, int _m, int _l, int _t)
static Registry * instance()
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 writeCSV_trigger() const
static std::string key_string(const std::string &_key, const std::string &_string, const std::string &_delim="")
void usage(std::ostream &out) const