All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DuplicateEventTracker_service.cc
Go to the documentation of this file.
1 /**
2  * @file sbncode/Utilities/DuplicateEventTracker_service.cc
3  * @brief Service keeping track of _art_ event IDs.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date January 22, 2021
6  * @see sbncode/Utilities/DuplicateEventTracker.h
7  */
8 
9 
10 // library header
12 
13 // framework libraries
14 #include "art/Framework/Services/Registry/ActivityRegistry.h"
15 #include "art/Framework/Principal/Event.h"
16 #include "art/Framework/Services/Registry/ServiceDefinitionMacros.h"
17 #include "canvas/Persistency/Provenance/EventID.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
19 
20 // C/C++ standard libraries
21 #include <set>
22 #include <cassert>
23 
24 
25 // -----------------------------------------------------------------------------
27  (Parameters const& config, art::ActivityRegistry& reg)
28  // configuration parameters
29  : fWarningOnly(config().WarningOnly())
30  , fSkipSummary(config().SkipSummary())
31  , fExceptionAtEnd(config().ExceptionAtEnd())
32  , fLogCategory(config().LogCategory())
33 {
34 
35  reg.sPostOpenFile.watch(this, &DuplicateEventTracker::postOpenFile);
36 
37  reg.sPostSourceEvent.watch(this, &DuplicateEventTracker::postEventReading);
38 
39  reg.sPostEndJob.watch(this, &DuplicateEventTracker::postEndJob);
40 
41 } // sbn::DuplicateEventTracker::DuplicateEventTracker()
42 
43 
44 // -----------------------------------------------------------------------------
46 
47  mf::LogInfo log(fLogCategory);
48  log << "Summary of duplicate events encountered:";
49 
50  std::set<sbn::EventRegistry::FileID_t> duplicateFileIDs;
51  unsigned int nDuplicateEvents = 0U;
52  auto eventRecords = fEventRegistry.records();
53  std::sort(eventRecords.begin(), eventRecords.end(),
54  [](auto const& A, auto const& B){ return A.first < B.first; });
55  for (auto const& [ eventID, record ]: eventRecords) {
56  if (record.sourceFiles.size() <= 1U) continue;
57  ++nDuplicateEvents;
58 
59  log << "\n " << eventID << " from " << record.sourceFiles.size()
60  << " sources:";
61  for (auto const fileID: record.sourceFiles) {
62  log << " [" << fileID << "]";
63  duplicateFileIDs.insert(fileID);
64  }
65  } // for
66 
67  if (!duplicateFileIDs.empty()) {
68  log << "\nDuplicate events from " << duplicateFileIDs.size() << " files:";
69  for (auto const fileID: duplicateFileIDs) {
70  // a bit cheating multithreading: we assume that between the copy of the
71  // event records and the source file list no source has been moved or
72  // removed; with the current interface, this is assured
73  auto const sourceName = fEventRegistry.sourceName(fileID);
74  log << "\n [" << fileID << "]";
75  if (sourceName) log << " '" << *sourceName << "'";
76  else log << " N/A"; // should not happen though
77  } // for sources
78  } // if duplicates
79 
80  if (nDuplicateEvents > 0U) {
81  log << "\nCounted " << nDuplicateEvents << " duplicate events from "
82  << duplicateFileIDs.size() << " source files.";
83  }
84  else log << "\nNo duplicate events found.";
85 
86 } // sbn::DuplicateEventTracker::printSummary()
87 
88 
89 // -----------------------------------------------------------------------------
91 
92  // register the current input file; if it exists already,
93  // we just get its ID again (but that's troublesome anyway)
94  fCurrentInputFileID = fEventRegistry.recordSource(fileName);
95 
96 } // sbn::DuplicateEventTracker::postOpenFile()
97 
98 
99 // -----------------------------------------------------------------------------
101  (art::Event const& event, art::ScheduleContext)
102 {
103 
104  sbn::EventRegistry::EventRecord_t const eventInfo
105  = fEventRegistry.recordEvent(event.id(), fCurrentInputFileID);
106  assert(eventInfo.sourceFiles.size() > 0U);
107  if (eventInfo.sourceFiles.size() == 1U) return; // all done, no new duplicates
108 
109  ++fNDuplicateEvents;
110 
111  if (fWarningOnly) {
112  mf::LogWarning(fLogCategory)
113  << "WARNING: event " << event.id() << " encountered "
114  << eventInfo.sourceFiles.size() << " times,"
115  << "\n now from '"
116  << fEventRegistry.sourceNameOr(eventInfo.sourceFiles.back(), "<?>")
117  << "',"
118  << "\n first time from '"
119  << fEventRegistry.sourceNameOr(eventInfo.sourceFiles.front(), "<?>")
120  << "'"
121  ;
122  return;
123  }
124 
125  if (fExceptionAtEnd) return;
126 
127  assert(eventInfo.sourceFiles.size() == 2U);
128  throw cet::exception(fLogCategory)
129  << "Duplicate event " << event.id() << " encountered"
130  << "\n first in '"
131  << fEventRegistry.sourceNameOr(eventInfo.sourceFiles.front(), "<?>") << "'"
132  << "\n and now in '"
133  << fEventRegistry.sourceNameOr(eventInfo.sourceFiles.back(), "<?>") << "'\n"
134  ;
135 
136 } // sbn::DuplicateEventTracker::postEventReading()
137 
138 
139 // -----------------------------------------------------------------------------
141 
142  if (!fSkipSummary) printSummary();
143 
144  if (fExceptionAtEnd && (fNDuplicateEvents > 0U)) {
145  throw cet::exception(fLogCategory)
146  << "Found " << fNDuplicateEvents << " duplicate events in the job.\n";
147  }
148 
149 } // sbn::DuplicateEventTracker::postEndJob()
150 
151 
152 // -----------------------------------------------------------------------------
153 DEFINE_ART_SERVICE(sbn::DuplicateEventTracker)
154 
155 // -----------------------------------------------------------------------------
156 
void postEndJob()
Prints the summary and throws an exception depending on the configuration.
std::string const fLogCategory
Message service category tag.
std::vector< FileID_t > sourceFiles
List of ID of source files.
Definition: EventRegistry.h:88
Service keeping track of art event IDs.
void postEventReading(art::Event const &event, art::ScheduleContext)
Records the event and throws an exception depending on the configuration.
void printSummary() const
Prints a summary of the current duplicates.
art::ServiceTable< Config > Parameters
std::optional< std::string > sourceName(FileID_t const &fileID) const
fDetProps &fDetProps fDetProps &fDetProps fLogCategory
DuplicateEventTracker(Parameters const &config, art::ActivityRegistry &reg)
Constructor: reads the configuration.
std::vector< EventIDandRecord_t > records() const
Returns a copy of all event records.
sbn::EventRegistry fEventRegistry
Record of all events and their source.
Keeps track of duplicate events in the job.
float A
Definition: dedx.py:137
Element of the registry for an event.
Definition: EventRegistry.h:86
void postOpenFile(std::string const &fileName)
Records the current file name.