test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Member Functions | Public Attributes
HltDiff Class Reference

Public Member Functions

void compare () const
 
 HltDiff ()
 
void usage (std::ostream &out) const
 

Public Attributes

bool debug
 
bool file_check
 
bool ignore_prescales
 
bool json_out
 
unsigned int max_events
 
std::vector< std::string > new_files
 
std::string new_process
 
std::vector< std::string > old_files
 
std::string old_process
 
std::string output_file
 
bool root_out
 
unsigned int verbose
 

Detailed Description

Definition at line 1177 of file hltDiff.cc.

Constructor & Destructor Documentation

HltDiff::HltDiff ( )
inline

Definition at line 1194 of file hltDiff.cc.

1194  :
1195  old_files(0),
1196  old_process(""),
1197  new_files(0),
1198  new_process(""),
1199  max_events(1e9),
1200  ignore_prescales(true),
1201  json_out(false),
1202  root_out(false),
1203  output_file(""),
1204  file_check(false),
1205  debug(false),
1206  verbose(0) {}
bool debug
Definition: hltDiff.cc:1191
bool root_out
Definition: hltDiff.cc:1188
bool file_check
Definition: hltDiff.cc:1190
unsigned int verbose
Definition: hltDiff.cc:1192
std::vector< std::string > old_files
Definition: hltDiff.cc:1181
std::string output_file
Definition: hltDiff.cc:1189
std::vector< std::string > new_files
Definition: hltDiff.cc:1183
bool ignore_prescales
Definition: hltDiff.cc:1186
bool json_out
Definition: hltDiff.cc:1187
unsigned int max_events
Definition: hltDiff.cc:1185
std::string new_process
Definition: hltDiff.cc:1184
std::string old_process
Definition: hltDiff.cc:1182

Member Function Documentation

void HltDiff::compare ( ) const
inline

Definition at line 1208 of file hltDiff.cc.

References edm::HLTGlobalStatus::accept(), ecal_dqm_sourceclient-live_cfg::cerr, check_files(), runEdmFileComparison::collection, trigger::TriggerEvent::collectionTags(), JsonOutputProducer::configuration, counter, gather_cfg::cout, debug, event(), event_state(), JsonOutputProducer::JsonConfiguration::events, JsonOutputProducer::eventState(), JsonOutputProducer::JsonConfigurationBlock::extractFileBase(), JsonOutputProducer::JsonConfigurationBlock::files, spr::find(), HLTCommonConfig::First, fwlite::Handle< T >::getByLabel(), getHLTConfigData(), HLTCommonConfig::HLTCommonConfig(), i, edm::HLTGlobalStatus::index(), Invalid, fwlite::Handle< T >::isValid(), L1Trigger_dataformats::json, min(), HLTConfigInterface::moduleLabel(), HLTConfigInterface::moduleType(), JsonOutputProducer::JsonConfiguration::n, JsonOutputProducer::JsonTriggerEventState::n, nEvents, JsonOutputProducer::JsonConfiguration::o, JsonOutputProducer::JsonTriggerEventState::o, or, electronStore::output_file, AlCaHLTBitMon_ParallelJobs::p, Pass, path_state(), Prescaled, prescaled_state(), JsonOutputProducer::JsonConfiguration::prescales, print_detailed_path_state(), print_trigger_candidates(), print_trigger_collection(), JsonOutputProducer::JsonConfigurationBlock::process, HLTConfigInterface::processName(), fwlite::Handle< T >::product(), JsonOutputProducer::pushEvent(), Ready, DTTTrigCorrFirst::run, HLTCommonConfig::Second, HLTConfigInterface::size(), JsonOutputProducer::JsonConfigurationBlock::skipped_triggers, edm::HLTGlobalStatus::state(), JsonOutputProducer::JsonVars::state, AlCaHLTBitMon_QueryRunRegistry::string, strip_process_name(), edmLumisInFiles::summary, JsonOutputProducer::JsonVars::trigger, JsonOutputProducer::JsonVars::trigger_passed_count, HLTConfigInterface::triggerIndex(), HLTConfigInterface::triggerName(), JsonOutputProducer::vars, JsonOutputProducer::write(), and SummaryOutputProducer::write().

Referenced by main().

1208  {
1209  std::shared_ptr<fwlite::ChainEvent> old_events;
1210  std::shared_ptr<fwlite::ChainEvent> new_events;
1211 
1213  old_events = std::make_shared<fwlite::ChainEvent>(old_files);
1214  else
1215  return;
1216 
1217  if (new_files.size() == 1 and new_files[0] == "-")
1218  new_events = old_events;
1219  else if (not file_check or check_files(new_files))
1220  new_events = std::make_shared<fwlite::ChainEvent>(new_files);
1221  else
1222  return;
1223 
1224  // creating the structure holding data for JSON and ROOT output
1226 
1227  json.configuration.prescales = ignore_prescales;
1228  // setting the old configuration
1229  json.configuration.o.process = old_process;
1230  json.configuration.o.files = old_files;
1231  json.configuration.o.extractFileBase();
1232  // setting the new configuration
1233  json.configuration.n.process = new_process;
1234  json.configuration.n.files = new_files;
1235  json.configuration.n.extractFileBase();
1236 
1237  // initialising configurations to be compared
1238  std::unique_ptr<HLTConfigDataEx> old_config_data;
1239  std::unique_ptr<HLTConfigDataEx> new_config_data;
1240  std::unique_ptr<HLTCommonConfig> common_config;
1241  HLTConfigInterface const * old_config = nullptr;
1242  HLTConfigInterface const * new_config = nullptr;
1243 
1244  unsigned int counter = 0;
1245  unsigned int skipped = 0;
1246  unsigned int affected = 0;
1247  bool new_run = true;
1248  std::vector<TriggerDiff> differences;
1249 
1250  // loop over the reference events
1251  const unsigned int nEvents = std::min((int)old_events->size(), (int)max_events);
1252  for (old_events->toBegin(); not old_events->atEnd(); ++(*old_events)) {
1253  // printing progress on every 10%
1254  if (counter%(nEvents/10) == 0) {
1255  printf("Processed events: %d out of %d (%d%%)\n", (int)counter, (int)nEvents, 10*counter/(nEvents/10));
1256  }
1257 
1258  // seek the same event in the "new" files
1259  edm::EventID const& id = old_events->id();
1260  if (new_events != old_events and not new_events->to(id)) {
1261  if (debug)
1262  std::cerr << "run " << id.run() << ", lumi " << id.luminosityBlock() << ", event " << id.event() << ": not found in the 'new' files, skipping." << std::endl;
1263  ++skipped;
1264  continue;
1265  }
1266 
1267  // read the TriggerResults and TriggerEvent
1269  edm::TriggerResults const * old_results = nullptr;
1270  old_results_h.getByLabel<fwlite::Event>(* old_events->event(), "TriggerResults", "", old_process.c_str());
1271  if (old_results_h.isValid())
1272  old_results = old_results_h.product();
1273  else {
1274  if (debug)
1275  std::cerr << "run " << id.run() << ", lumi " << id.luminosityBlock() << ", event " << id.event() << ": 'old' TriggerResults not found, skipping." << std::endl;
1276  continue;
1277  }
1278 
1280  trigger::TriggerEvent const * old_summary = nullptr;
1281  old_summary_h.getByLabel<fwlite::Event>(* old_events->event(), "hltTriggerSummaryAOD", "", old_process.c_str());
1282  if (old_summary_h.isValid())
1283  old_summary = old_summary_h.product();
1284 
1286  edm::TriggerResults const * new_results = nullptr;
1287  new_results_h.getByLabel<fwlite::Event>(* new_events->event(), "TriggerResults", "", new_process.c_str());
1288  if (new_results_h.isValid())
1289  new_results = new_results_h.product();
1290  else {
1291  if (debug)
1292  std::cerr << "run " << id.run() << ", lumi " << id.luminosityBlock() << ", event " << id.event() << ": 'new' TriggerResults not found, skipping." << std::endl;
1293  continue;
1294  }
1295 
1297  trigger::TriggerEvent const * new_summary = nullptr;
1298  new_summary_h.getByLabel<fwlite::Event>(* new_events->event(), "hltTriggerSummaryAOD", "", new_process.c_str());
1299  if (new_summary_h.isValid())
1300  new_summary = new_summary_h.product();
1301 
1302  // initialise the trigger configuration
1303  if (new_run) {
1304  new_run = false;
1305  old_events->fillParameterSetRegistry();
1306  new_events->fillParameterSetRegistry();
1307 
1308  old_config_data = getHLTConfigData(* old_events->event(), old_process);
1309  new_config_data = getHLTConfigData(* new_events->event(), new_process);
1310  if (new_config_data->triggerNames() == old_config_data->triggerNames()) {
1311  old_config = old_config_data.get();
1312  new_config = new_config_data.get();
1313  } else {
1314  common_config = std::unique_ptr<HLTCommonConfig>(new HLTCommonConfig(*old_config_data, *new_config_data));
1315  old_config = & common_config->getView(HLTCommonConfig::Index::First);
1316  new_config = & common_config->getView(HLTCommonConfig::Index::Second);
1317  std::cout << "Warning: old and new TriggerResults come from different HLT menus. Only the common " << old_config->size() << " triggers are compared.\n" << std::endl;
1318  }
1319 
1320  differences.clear();
1321  differences.resize(old_config->size());
1322 
1323  // adding the list of selected triggers to JSON output
1324  std::vector<std::string> states_str;
1325  for (int i = State::Ready; i != State::Invalid; i++)
1326  states_str.push_back(std::string(path_state(static_cast<State>(i))));
1327  json.vars.state = states_str;
1328  for (size_t triggerId = 0; triggerId < old_config->size(); ++triggerId) {
1329  json.vars.trigger.push_back(old_config->triggerName(triggerId));
1330  json.vars.trigger_passed_count.push_back(std::pair<int, int>(0,0));
1331  }
1332  // getting names of triggers existing only in the old configuration
1333  for (std::vector<std::string>::const_iterator it = old_config_data->triggerNames().begin(); it != old_config_data->triggerNames().end(); ++it) {
1334  if (std::find(json.vars.trigger.begin(), json.vars.trigger.end(), *it) != json.vars.trigger.end()) continue;
1335  json.configuration.o.skipped_triggers.push_back(*it);
1336  }
1337  // getting names of triggers existing only in the new configuration
1338  for (std::vector<std::string>::const_iterator it = new_config_data->triggerNames().begin(); it != new_config_data->triggerNames().end(); ++it) {
1339  if (std::find(json.vars.trigger.begin(), json.vars.trigger.end(), *it) != json.vars.trigger.end()) continue;
1340  json.configuration.n.skipped_triggers.push_back(*it);
1341  }
1342  }
1343 
1344  // compare the TriggerResults
1345  bool needs_header = true;
1346  bool event_affected = false;
1347  for (unsigned int p = 0; p < old_config->size(); ++p) {
1348  // FIXME explicitly converting the indices is a hack, it should be properly encapsulated instead
1349  unsigned int old_index = old_config->triggerIndex(p);
1350  unsigned int new_index = new_config->triggerIndex(p);
1351  State old_state = prescaled_state(old_results->state(old_index), p, old_results->index(old_index), * old_config);
1352  State new_state = prescaled_state(new_results->state(new_index), p, new_results->index(new_index), * new_config);
1353 
1354  if (old_state == Pass) {
1355  ++differences[p].count;
1356  }
1357  if (old_state == Pass)
1358  ++json.vars.trigger_passed_count.at(p).first;
1359  if (new_state == Pass)
1360  ++json.vars.trigger_passed_count.at(p).second;
1361 
1362  bool trigger_affected = false;
1363  if (not ignore_prescales or (old_state != Prescaled and new_state != Prescaled)) {
1364  if (old_state == Pass and new_state != Pass) {
1365  ++differences[p].lost;
1366  trigger_affected = true;
1367  } else if (old_state != Pass and new_state == Pass) {
1368  ++differences[p].gained;
1369  trigger_affected = true;
1370  } else if (old_results->index(old_index) != new_results->index(new_index)) {
1371  ++differences[p].internal;
1372  trigger_affected = true;
1373  }
1374  }
1375 
1376  if (not trigger_affected) continue;
1377 
1378  event_affected = true;
1379  const unsigned int old_moduleIndex = old_results->index(old_index);
1380  const unsigned int new_moduleIndex = new_results->index(new_index);
1381  // storing the event to JSON, without any trigger results for the moment
1382  JsonOutputProducer::JsonEvent& event = json.pushEvent(id.run(), id.luminosityBlock(), id.event());
1383  JsonOutputProducer::JsonTriggerEventState& state = event.pushTrigger(p);
1384  state.o = json.eventState(old_state, old_moduleIndex, old_config->moduleLabel(p, old_moduleIndex), old_config->moduleType(p, old_moduleIndex));
1385  state.n = json.eventState(new_state, new_moduleIndex, new_config->moduleLabel(p, new_moduleIndex), new_config->moduleType(p, new_moduleIndex));
1386 
1387  if (verbose > 0) {
1388  if (needs_header) {
1389  needs_header = false;
1390  std::cout << "run " << id.run() << ", lumi " << id.luminosityBlock() << ", event " << id.event() << ": "
1391  << "old result is '" << event_state(old_results->accept()) << "', "
1392  << "new result is '" << event_state(new_results->accept()) << "'"
1393  << std::endl;
1394  }
1395  // print the Trigger path and filter responsible for the discrepancy
1396  std::cout << " Path " << old_config->triggerName(p) << ":\n"
1397  << " old state is ";
1398  print_detailed_path_state(std::cout, old_state, p, old_moduleIndex, * old_config);
1399  std::cout << ",\n"
1400  << " new state is ";
1401  print_detailed_path_state(std::cout, new_state, p, new_moduleIndex, * new_config);
1402  std::cout << std::endl;
1403  }
1404  if (verbose > 1 and old_summary and new_summary) {
1405  // print TriggerObjects for the filter responsible for the discrepancy
1406  unsigned int module = std::min(old_moduleIndex, new_moduleIndex);
1407  std::cout << " Filter " << old_config->moduleLabel(p, module) << ":\n";
1408  std::cout << " old trigger candidates:\n";
1409  print_trigger_candidates(std::cout, * old_summary, edm::InputTag(old_config->moduleLabel(p, module), "", old_config->processName()));
1410  std::cout << " new trigger candidates:\n";
1411  print_trigger_candidates(std::cout, * new_summary, edm::InputTag(new_config->moduleLabel(p, module), "", new_config->processName()));
1412  }
1413  if (verbose > 0)
1414  std::cout << std::endl;
1415  }
1416  if (event_affected)
1417  ++affected;
1418 
1419  // compare the TriggerEvent
1420  if (event_affected and verbose > 2 and old_summary and new_summary) {
1421  std::map<std::string, std::pair<std::string, std::string>> collections;
1422  for (auto const & old_collection: old_summary->collectionTags())
1423  collections[strip_process_name(old_collection)].first = old_collection;
1424  for (auto const & new_collection: new_summary->collectionTags())
1425  collections[strip_process_name(new_collection)].second = new_collection;
1426 
1427  for (auto const & collection: collections) {
1428  std::cout << " Collection " << collection.first << ":\n";
1429  std::cout << " old trigger candidates:\n";
1430  print_trigger_collection(std::cout, * old_summary, collection.second.first);
1431  std::cout << " new trigger candidates:\n";
1432  print_trigger_collection(std::cout, * new_summary, collection.second.second);
1433  std::cout << std::endl;
1434  }
1435  }
1436 
1437  ++counter;
1438  if (nEvents and counter >= nEvents)
1439  break;
1440  }
1441 
1442  json.configuration.events = counter;
1443 
1444  if (not counter) {
1445  std::cout << "There are no common events between the old and new files";
1446  if (skipped)
1447  std::cout << ", " << skipped << " events were skipped";
1448  std::cout << "." << std::endl;
1449  } else {
1450  std::cout << "Found " << counter << " matching events, out of which " << affected << " have different HLT results";
1451  if (skipped)
1452  std::cout << ", " << skipped << " events were skipped";
1453  std::cout << "\nSee more in the files listed below...\n" << std::endl;
1454  }
1455 
1456  // writing all the required output
1457  json.write(); // to JSON file for interactive visualisation
1459  summary.write(); // to ROOT file for fast validation with static plots
1460  }
virtual std::string const & moduleLabel(unsigned int trigger, unsigned int module) const =0
int i
Definition: DBlmapReader.cc:9
bool check_files(std::vector< std::string > const &files)
Definition: hltDiff.cc:1167
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
bool debug
Definition: hltDiff.cc:1191
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
Definition: Activities.doc:12
bool root_out
Definition: hltDiff.cc:1188
Definition: hltDiff.cc:288
void print_trigger_candidates(std::ostream &out, trigger::TriggerEvent const &summary, edm::InputTag const &filter)
Definition: hltDiff.cc:344
bool isValid() const
Definition: Handle.h:61
bool file_check
Definition: hltDiff.cc:1190
bool accept() const
Has at least one path accepted the event?
void print_detailed_path_state(std::ostream &out, State state, int path, int module, HLTConfigInterface const &config)
Definition: hltDiff.cc:333
const char * event_state(bool state)
Definition: hltDiff.cc:134
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
void getByLabel(const P &iP, const char *iModuleLabel, const char *iProductInstanceLabel=0, const char *iProcessLabel=0)
Definition: Handle.h:91
std::vector< std::string > old_files
Definition: hltDiff.cc:1181
State prescaled_state(int state, int path, int module, HLTConfigInterface const &config)
Definition: hltDiff.cc:305
std::string output_file
Definition: hltDiff.cc:1189
std::unique_ptr< HLTConfigDataEx > getHLTConfigData(fwlite::EventBase const &event, std::string process)
Definition: hltDiff.cc:410
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:1183
virtual std::string const & moduleType(unsigned int trigger, unsigned int module) const =0
bool ignore_prescales
Definition: hltDiff.cc:1186
bool json_out
Definition: hltDiff.cc:1187
std::string strip_process_name(std::string const &s)
Definition: hltDiff.cc:318
T min(T a, T b)
Definition: MathUtil.h:58
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
void print_trigger_collection(std::ostream &out, trigger::TriggerEvent const &summary, std::string const &tag)
Definition: hltDiff.cc:374
virtual std::string const & processName() const =0
const char * path_state(State state)
Definition: hltDiff.cc:295
unsigned int max_events
Definition: hltDiff.cc:1185
static std::atomic< unsigned int > counter
State
Definition: hltDiff.cc:286
tuple cout
Definition: gather_cfg.py:145
T const * product() const
Definition: Handle.h:66
UInt_t nEvents
Definition: hcalCalib.cc:42
Definition: vlib.h:208
std::string new_process
Definition: hltDiff.cc:1184
hlt::HLTState state(const unsigned int i) const
Get status of ith path.
std::string old_process
Definition: hltDiff.cc:1182
void HltDiff::usage ( std::ostream &  out) const
inline

Definition at line 1462 of file hltDiff.cc.

Referenced by main().

1462  {
1463  out << "\
1464 usage: hltDiff -o|--old-files FILE1.ROOT [FILE2.ROOT ...] [-O|--old-process LABEL[:INSTANCE[:PROCESS]]]\n\
1465  -n|--new-files FILE1.ROOT [FILE2.ROOT ...] [-N|--new-process LABEL[:INSTANCE[:PROCESS]]]\n\
1466  [-m|--max-events MAXEVENTS] [-p|--prescales] [-j|--json-output] OUTPUT_FILE.JSON\n\
1467  [-r|--root-output] OUTPUT_FILE.ROOT [-f|--file-check] [-d|--debug] [-v|--verbose] [-h|--help]\n\
1468 \n\
1469  -o|--old-files FILE1.ROOT [FILE2.ROOT ...]\n\
1470  input file(s) with the old (reference) trigger results\n\
1471 \n\
1472  -O|--old-process PROCESS\n\
1473  process name of the collection with the old (reference) trigger results\n\
1474  default: take the 'TriggerResults' from the last process\n\
1475 \n\
1476  -n|--new-files FILE1.ROOT [FILE2.ROOT ...]\n\
1477  input file(s) with the new trigger results to be compared with the reference\n\
1478  to read these from a different collection in the same files as\n\
1479  the reference, use '-n -' and specify the collection with -N (see below)\n\
1480 \n\
1481  -N|--new-process PROCESS\n\
1482  process name of the collection with the new (reference) trigger results\n\
1483  default: take the 'TriggerResults' from the last process\n\
1484 \n\
1485  -m|--max-events MAXEVENTS\n\
1486  compare only the first MAXEVENTS events\n\
1487  default: compare all the events in the original (reference) files\n\
1488 \n\
1489  -p|--prescales\n\
1490  do not ignore differences caused by HLTPrescaler modules\n\
1491 \n\
1492  -j|--json-output\n\
1493  produce comparison results in a JSON format\n\
1494 \n\
1495  -r|--root-output\n\
1496  produce comparison results as histograms in a ROOT file\n\
1497 \n\
1498  -F|--output-file FILE_NAME\n\
1499  combine all RUNs to files with the specified custom name: FILE_NAME.json, FILE_NAME.root\n\
1500  default: a separate output file will be produced for each RUN with names suitable for the DQM GUI\n\
1501 \n\
1502  -f|--file-check\n\
1503  check existence of every old and new file before running the comparison\n\
1504  safer if files are run for the first time, but can cause a substantial delay\n\
1505 \n\
1506  -d|--debug\n\
1507  display messages about missing events and collectiions\n\
1508 \n\
1509  -v|--verbose LEVEL\n\
1510  set verbosity level:\n\
1511  1: event-by-event comparison results\n\
1512  2: + print the trigger candidates of the affected filters\n\
1513  3: + print all the trigger candidates for the affected events\n\
1514  default: 1\n\
1515 \n\
1516  -h|--help\n\
1517  print this help message, and exit" << std::endl;
1518  }

Member Data Documentation

bool HltDiff::debug

Definition at line 1191 of file hltDiff.cc.

Referenced by rrapi.RRApi::dprint(), rrapi.RRApi::get(), and main().

bool HltDiff::file_check

Definition at line 1190 of file hltDiff.cc.

Referenced by main().

bool HltDiff::ignore_prescales

Definition at line 1186 of file hltDiff.cc.

Referenced by main().

bool HltDiff::json_out

Definition at line 1187 of file hltDiff.cc.

Referenced by main().

unsigned int HltDiff::max_events

Definition at line 1185 of file hltDiff.cc.

Referenced by main().

std::vector<std::string> HltDiff::new_files

Definition at line 1183 of file hltDiff.cc.

Referenced by main().

std::string HltDiff::new_process

Definition at line 1184 of file hltDiff.cc.

Referenced by main().

std::vector<std::string> HltDiff::old_files

Definition at line 1181 of file hltDiff.cc.

Referenced by main().

std::string HltDiff::old_process

Definition at line 1182 of file hltDiff.cc.

Referenced by main().

std::string HltDiff::output_file

Definition at line 1189 of file hltDiff.cc.

Referenced by main().

bool HltDiff::root_out

Definition at line 1188 of file hltDiff.cc.

Referenced by main().

unsigned int HltDiff::verbose