18 #include <boost/algorithm/string.hpp>
19 #include <boost/filesystem.hpp>
37 usage: hltDiff -o|--old-files FILE1.ROOT [FILE2.ROOT ...] [-O|--old-process LABEL[:INSTANCE[:PROCESS]]]\n\
38 -n|--new-files FILE1.ROOT [FILE2.ROOT ...] [-N|--new-process LABEL[:INSTANCE[:PROCESS]]]\n\
39 [-m|--max-events MAXEVENTS] [-p|--prescales] [-q|--quiet] [-v|--verbose] [-h|--help]\n\
41 -o|--old-files FILE1.ROOT [FILE2.ROOT ...]\n\
42 input file(s) with the old (reference) trigger results.\n\
44 -O|--old-process PROCESS\n\
45 process name of the collection with the old (reference) trigger results;\n\
46 the default is to take the 'TriggerResults' from the last process.\n\
48 -n|--new-files FILE1.ROOT [FILE2.ROOT ...]\n\
49 input file(s) with the new trigger results to be compared with the reference;\n\
50 to read these from a different collection in the same files as\n\
51 the reference, use '-n -' and specify the collection with -N (see below).\n\
53 -N|--new-process PROCESS\n\
54 process name of the collection with the new (reference) trigger results;\n\
55 the default is to take the 'TriggerResults' from the last process.\n\
57 -m|--max-events MAXEVENTS\n\
58 compare only the first MAXEVENTS events;\n\
59 the default is to compare all the events in the original (reference) files.\n\
62 do not ignore differences caused by HLTPrescaler modules.\n\
65 suppress messages about missing events and collectiions.\n\
69 use once to print event-by-event comparison results;\n\
70 use twice to print the trigger candidates of the affected filters;\n\
71 use three times to print all the trigger candidates for the affected events.\n\
74 print this help message, and exit." << std::endl;
78 out <<
"Try 'hltDiff --help' for more information." << std::endl;
82 out << message << std::endl;
87 out << message << std::endl;
95 virtual unsigned int size()
const = 0;
96 virtual unsigned int size(
unsigned int trigger)
const = 0;
98 virtual unsigned int triggerIndex(
unsigned int trigger)
const = 0;
101 virtual bool prescaler(
unsigned int trigger,
unsigned int module)
const = 0;
127 virtual unsigned int size()
const override {
131 virtual unsigned int size(
unsigned int trigger)
const override {
143 virtual unsigned int triggerIndex(
unsigned int trigger)
const override {
168 return state ?
"accepted" :
"rejected";
187 virtual unsigned int size()
const override;
188 virtual unsigned int size(
unsigned int trigger)
const override;
190 virtual unsigned int triggerIndex(
unsigned int trigger)
const override;
193 virtual bool prescaler(
unsigned int trigger,
unsigned int module)
const override;
207 for (
unsigned int f = 0;
f < first.
size(); ++
f)
208 for (
unsigned int s = 0;
s < second.
size(); ++
s)
291 return config_.size(index_);
295 return config_.size(index_, trigger);
299 return config_.triggerName(index_, trigger);
303 return config_.triggerIndex(index_, trigger);
307 return config_.moduleLabel(index_, trigger, module);
311 return config_.moduleType(index_, trigger, module);
315 return config_.prescaler(index_, trigger, module);
329 static const char *
message[] = {
"not run",
"accepted",
"rejected",
"exception",
"prescaled",
"invalid" };
331 if (state > 0 and state <
Invalid)
332 return message[state];
341 return (
State) state;
350 out <<
" by module " << module <<
" '" <<
label <<
"' [" <<
type <<
"]";
352 out <<
" at module " << module <<
" '" <<
label <<
"' [" << type <<
"]";
361 out <<
" not found\n";
371 for (
unsigned int i = 0;
i < summary.
filterKeys(index).size(); ++
i) {
376 <<
"filter id: " <<
id <<
", "
377 <<
"object id: " << candidate.
id() <<
", "
378 <<
"pT: " << candidate.
pt() <<
", "
379 <<
"eta: " << candidate.
eta() <<
", "
380 <<
"phi: " << candidate.
phi() <<
", "
381 <<
"mass: " << candidate.
mass() <<
"\n";
389 out <<
" not found\n";
406 <<
"object id: " << candidate.
id() <<
", "
407 <<
"pT: " << candidate.
pt() <<
", "
408 <<
"eta: " << candidate.
eta() <<
", "
409 <<
"phi: " << candidate.
phi() <<
", "
410 <<
"mass: " << candidate.
mass() <<
"\n";
416 std::vector<boost::iterator_range<std::string::const_iterator>> tokens;
417 boost::split(tokens, branch, boost::is_any_of(
"_."), boost::token_compress_off);
418 return boost::copy_range<std::string>(tokens[3]);
422 auto const & history =
event.processHistory();
423 if (process.empty()) {
430 if (not history.getConfigurationForProcess(process, config)) {
431 std::cerr <<
"error: the process " << process <<
" is not in the Process History" << std::endl;
435 if (pset ==
nullptr) {
436 std::cerr <<
"error: the configuration for the process " << process <<
" is not available in the Provenance" << std::endl;
449 unsigned int internal;
457 memset(buffer, 0, 12);
459 unsigned int digit = 10;
461 buffer[digit] = value % 10 + 48;
465 buffer[digit] =
sign;
472 out << std::setw(12) << diff.
count
481 std::unique_ptr<TFile>
f(TFile::Open(file.c_str()));
482 return (f and not f->IsZombie());
488 for (
auto const &
file: files)
491 std::cerr <<
"hltDiff: error: file " <<
file <<
" does not exist, or is not a regular file." << std::endl;
498 std::vector<std::string>
const & new_files,
std::string const & new_process,
499 unsigned int max_events,
bool ignore_prescales,
int verbose,
int quiet) {
501 std::shared_ptr<fwlite::ChainEvent> old_events;
502 std::shared_ptr<fwlite::ChainEvent> new_events;
505 old_events = std::make_shared<fwlite::ChainEvent>(old_files);
509 if (new_files.size() == 1 and new_files[0] ==
"-")
510 new_events = old_events;
512 new_events = std::make_shared<fwlite::ChainEvent>(new_files);
516 std::unique_ptr<HLTConfigDataEx> old_config_data;
517 std::unique_ptr<HLTConfigDataEx> new_config_data;
518 std::unique_ptr<HLTCommonConfig> common_config;
523 unsigned int skipped = 0;
524 unsigned int affected = 0;
526 std::vector<TriggerDiff> differences;
529 for (old_events->toBegin(); not old_events->atEnd(); ++(*old_events)) {
533 if (new_events != old_events and not new_events->to(
id)) {
535 std::cerr <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event() <<
": not found in the 'new' files, skipping." << std::endl;
545 old_results = old_results_h.
product();
548 std::cerr <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event() <<
": 'old' TriggerResults not found, skipping." << std::endl;
554 old_summary_h.
getByLabel<
fwlite::Event>(* old_events->event(),
"hltTriggerSummaryAOD",
"", old_process.c_str());
556 old_summary = old_summary_h.
product();
562 new_results = new_results_h.
product();
565 std::cerr <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event() <<
": 'new' TriggerResults not found, skipping." << std::endl;
571 new_summary_h.
getByLabel<
fwlite::Event>(* new_events->event(),
"hltTriggerSummaryAOD",
"", new_process.c_str());
573 new_summary = new_summary_h.
product();
578 old_events->fillParameterSetRegistry();
579 new_events->fillParameterSetRegistry();
583 if (new_config_data->triggerNames() == old_config_data->triggerNames()) {
584 old_config = old_config_data.get();
585 new_config = new_config_data.get();
587 common_config = std::unique_ptr<HLTCommonConfig>(
new HLTCommonConfig(*old_config_data, *new_config_data));
590 std::cerr <<
"Warning: old and new TriggerResults come from different HLT menus. Only the common triggers will be compared:" << std::endl;
591 for (
unsigned int i = 0;
i < old_config->size(); ++
i)
592 std::cerr <<
" " << old_config->triggerName(
i) << std::endl;
597 differences.resize(old_config->
size());
601 bool needs_header =
true;
602 bool affected_event =
false;
603 for (
unsigned int p = 0;
p < old_config->
size(); ++
p) {
610 if (old_state ==
Pass)
611 ++differences[
p].count;
615 if (old_state ==
Pass and new_state !=
Pass) {
616 ++differences[
p].lost;
618 }
else if (old_state !=
Pass and new_state ==
Pass) {
619 ++differences[
p].gained;
621 }
else if (old_results->
index(old_index) != new_results->
index(new_index)) {
622 ++differences[
p].internal;
628 affected_event =
true;
632 needs_header =
false;
633 std::cout <<
"run " <<
id.run() <<
", lumi " <<
id.luminosityBlock() <<
", event " <<
id.event() <<
": "
645 std::cout << std::endl;
647 if (verbose > 1 and old_summary and new_summary) {
651 std::cout <<
" old trigger candidates:\n";
653 std::cout <<
" new trigger candidates:\n";
664 if (affected_event and verbose > 2 and old_summary and new_summary) {
665 std::set<std::string>
names;
667 names.insert(new_summary->collectionTags().begin(), new_summary->collectionTags().end());
670 std::cout <<
" old trigger candidates:\n";
672 std::cout <<
" new trigger candidates:\n";
679 if (max_events and counter >= max_events)
684 std::cout <<
"There are no common events between the old and new files";
686 std::cout <<
", " << skipped <<
" events were skipped";
689 std::cout <<
"Found " << affected <<
" events out of " << counter <<
" with differences";
691 std::cout <<
", " << skipped <<
" events were skipped";
693 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;
694 for (
unsigned int p = 0;
p < old_config->
size(); ++
p)
695 std::cout << std::setw(12) << counter << differences[
p] <<
" " << old_config->
triggerName(
p) << std::endl;
702 const char optstring[] =
"o:O:n:N:m:pqvh";
703 const option longopts[] = {
704 option{
"old-files", required_argument,
nullptr,
'o' },
705 option{
"old-process", required_argument,
nullptr,
'O' },
706 option{
"new-files", required_argument,
nullptr,
'n' },
707 option{
"new-process", required_argument,
nullptr,
'N' },
708 option{
"max-events", required_argument,
nullptr,
'm' },
709 option{
"prescales", no_argument,
nullptr,
'p' },
710 option{
"quet", no_argument,
nullptr,
'q' },
711 option{
"verbose", no_argument,
nullptr,
'v' },
712 option{
"help", no_argument,
nullptr,
'h' },
716 std::vector<std::string> old_files;
718 std::vector<std::string> new_files;
720 unsigned int max_events = 0;
721 bool ignore_prescales =
true;
727 while ((c = getopt_long(argc, argv, optstring, longopts,
nullptr)) != -1) {
730 old_files.emplace_back(optarg);
731 while (optind < argc) {
732 if (argv[optind][0] ==
'-')
734 old_files.emplace_back(argv[optind]);
740 old_process = optarg;
744 new_files.emplace_back(optarg);
745 while (optind < argc) {
746 if (argv[optind][0] ==
'-')
748 new_files.emplace_back(argv[optind]);
754 new_process = optarg;
758 max_events = atoi(optarg);
762 ignore_prescales =
false;
785 if (old_files.empty()) {
789 if (new_files.empty()) {
794 compare(old_files, old_process, new_files, new_process, max_events, ignore_prescales, verbose, quiet);
virtual unsigned int triggerIndex(unsigned int trigger) const override
virtual std::string const & triggerName(unsigned int trigger) const override
virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const =0
std::set< std::string > moduleTypeSet_
virtual bool prescaler(unsigned int trigger, unsigned int module) const override
std::vector< std::pair< unsigned int, unsigned int > > triggerIndices_
virtual bool prescaler(unsigned int trigger, unsigned int module) const override
std::string const & moduleLabel(Index index, unsigned int trigger, unsigned int module) const
virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const override
virtual unsigned int size(unsigned int trigger) const override
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
static const HistoName names[]
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
std::vector< std::vector< std::string const * > > moduleTypes_
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
virtual bool prescaler(unsigned int trigger, unsigned int module) const =0
virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const override
unsigned int size() const
number of trigger paths in trigger table
void print_detailed_path_state(std::ostream &out, State state, int path, int module, HLTConfigInterface const &config)
virtual std::string const & processName() const override
const char * event_state(bool state)
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)
virtual std::string const & triggerName(unsigned int trigger) const override
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)
virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const override
State prescaled_state(int state, int path, int module, HLTConfigInterface const &config)
virtual std::string const & triggerName(unsigned int trigger) const =0
const Vids & filterIds(trigger::size_type index) const
ParameterSetID const & parameterSetID() const
virtual std::string const & processName() const override
HLTConfigDataEx const & second_
std::unique_ptr< HLTConfigDataEx > getHLTConfigData(fwlite::EventBase const &event, std::string process)
const TriggerObjectCollection & getObjects() const
unsigned int index(const unsigned int i) const
Get index (slot position) of module giving the decision of the ith path.
std::string getProcessNameFromBranch(std::string const &branch)
HLTCommonConfig const & config_
virtual unsigned int size() const override
void compare(std::vector< std::string > const &old_files, std::string const &old_process, std::vector< std::string > const &new_files, std::string const &new_process, unsigned int max_events, bool ignore_prescales, int verbose, int quiet)
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.
unsigned int size(Index index) const
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
virtual unsigned int triggerIndex(unsigned int trigger) const =0
string key
FastSim: produces sample of signal events, overlayed with premixed minbias events.
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
virtual std::string const & processName() const =0
const char * path_state(State state)
HLTConfigDataEx const & first_
bool check_file(std::string const &file)
char data[epos_bytes_allocation]
virtual unsigned int size() const =0
static std::atomic< unsigned int > counter
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
virtual 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
virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const override
virtual unsigned int triggerIndex(unsigned int trigger) const override
static Registry * instance()
hlt::HLTState state(const unsigned int i) const
Get status of ith path.