ATLAS Offline Software
Loading...
Searching...
No Matches
DuplicateChecker.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7
8//
9// includes
10//
11
14
16#include <EventLoop/Job.h>
17#include <EventLoop/IWorker.h>
22#include <TChain.h>
23#include <TTree.h>
24#include <fstream>
25#include <stdexcept>
28
29//
30// method implementations
31//
32
34
35namespace EL
36{
37 void DuplicateChecker ::
38 testInvariant () const
39 {}
40
41
42
43 DuplicateChecker ::
44 DuplicateChecker ()
45 : m_eventInfoName ("EventInfo")
46 {
47 RCU_NEW_INVARIANT (this);
48 }
49
50
51
52 const std::string& DuplicateChecker ::
53 eventInfoName () const
54 {
55 RCU_READ_INVARIANT (this);
56 return m_eventInfoName;
57 }
58
59
60
61 void DuplicateChecker ::
62 setEventInfoName (const std::string& val_eventInfoName)
63 {
65 m_eventInfoName = val_eventInfoName;
66 }
67
68
69
70 const std::string& DuplicateChecker ::
71 outputTreeName () const
72 {
73 RCU_READ_INVARIANT (this);
74 return m_outputTreeName;
75 }
76
77
78
79 void DuplicateChecker ::
80 setOutputTreeName (const std::string& val_outputTreeName)
81 {
83 m_outputTreeName = val_outputTreeName;
84 }
85
86
87
88 void DuplicateChecker ::
89 addKnownDuplicate (const std::string& sampleName,
90 const std::string& fileName,
91 Long64_t entry, number_type runNumber,
92 number_type eventNumber)
93 {
95 m_duplicates[std::make_pair (sampleName, fileName)].insert
96 (std::make_pair (entry, std::make_pair (runNumber, eventNumber)));
97 }
98
99
100
101 void DuplicateChecker ::
102 addKnownDuplicatesFile (const std::string& duplicatesFile)
103 {
104 std::ifstream file (duplicatesFile);
105 std::string line;
106 while (std::getline (file, line))
107 {
108 if (!line.empty() && line[0] != '#')
109 {
110 std::string sampleName, fileName;
111 Long64_t entry;
112 number_type runNumber, eventNumber;
113 std::istringstream str (line);
114 if (!(str >> sampleName >> fileName >> entry >> runNumber >> eventNumber))
115 throw std::runtime_error ("failed to parse line: " + line);
116 addKnownDuplicate (sampleName, fileName, entry, runNumber, eventNumber);
117 }
118 }
119 }
120
121
122
123 bool DuplicateChecker ::
124 processSummary (const std::string& submitdir, const std::string& treeName)
125 {
127 sh.load (submitdir + "/hist");
128 sh.setMetaString (SH::MetaFields::treeName, treeName);
129 return processSummary (sh, submitdir + "/duplicates");
130 }
131
132
133
134 bool DuplicateChecker ::
135 processSummary (const SH::SampleHandler& sh, const std::string& outputFile)
136 {
137 std::ofstream file (outputFile.c_str());
138 bool success = true;
139 for (SH::Sample *sample : sh)
140 {
141 std::set<std::pair<number_type,number_type>> known_list;
142 std::set<std::pair<number_type,number_type>> processed_list;
143
144 std::unique_ptr<TChain> tree (sample->makeTChain());
145 std::string *inputFileName = nullptr;
146 tree->SetBranchAddress ("fileName", &inputFileName);
147 Long64_t inputFileIndex;
148 tree->SetBranchAddress ("fileIndex", &inputFileIndex);
149 number_type runNumber;
150 tree->SetBranchAddress ("runNumber", &runNumber);
151 number_type eventNumber;
152 tree->SetBranchAddress ("eventNumber", &eventNumber);
153 Bool_t processed;
154 tree->SetBranchAddress ("processed", &processed);
155 for (Long64_t entry = 0, entries = tree->GetEntries();
156 entry < entries; ++ entry)
157 {
158 if (tree->GetEntry (entry) < 0)
159 throw std::runtime_error ("failed to read tree entry");
160 std::pair<number_type,number_type> id (runNumber, eventNumber);
161
162 if (known_list.find (id) == known_list.end())
163 known_list.insert (id);
164 else
165 {
166 file << sample->name() << " " << *inputFileName << " "
167 << inputFileIndex << " " << runNumber << " "
168 << eventNumber << std::endl;
169 }
170
171 if (processed)
172 {
173 if (processed_list.find (id) == processed_list.end())
174 processed_list.insert (id);
175 else
176 {
177 success = false;
178 std::cout << "ERROR: duplicate event processed: "
179 << sample->name() << " "
180 << runNumber << " " << eventNumber << std::endl;
181 }
182 }
183 }
184 if (known_list.size() != processed_list.size())
185 {
186 RCU_ASSERT (processed_list.size() < known_list.size());
187 success = false;
188 for (auto& id : known_list)
189 {
190 if (processed_list.find (id) == processed_list.end())
191 {
192 std::cout << "ERROR: event never processed: "
193 << sample->name() << " "
194 << runNumber << " " << eventNumber << std::endl;
195 }
196 }
197 }
198 }
199 return success;
200 }
201
202
203
204 StatusCode DuplicateChecker ::
205 setupJob (Job& job)
206 {
208 job.useXAOD ();
209 return StatusCode::SUCCESS;
210 }
211
212
213
214 StatusCode DuplicateChecker ::
215 changeInput (bool /*firstFile*/)
216 {
218 m_inputFileName = wk()->inputFileName();
219
220 auto iter = m_duplicates.find
221 (std::make_pair (wk()->metaData()->castString (SH::MetaNames::sampleName()), m_inputFileName));
222 if (iter != m_duplicates.end())
223 m_currentDuplicates = &iter->second;
224 else
225 m_currentDuplicates = nullptr;
226 return StatusCode::SUCCESS;
227 }
228
229
230
231 StatusCode DuplicateChecker ::
232 initialize ()
233 {
235
236 m_event = wk()->xaodEvent();
237
238 if (!m_outputTreeName.empty())
239 {
240 m_outputTree = new TTree (m_outputTreeName.c_str(), "DuplicateChecker tree");
241 wk()->addOutput (m_outputTree);
242 m_outputTree->Branch ("fileName", &m_inputFileName);
243 m_outputTree->Branch ("fileIndex", &m_inputFileIndex, "inputFileIndex/L");
244 m_outputTree->Branch ("runNumber", &m_runNumber, "runNumber/i");
245 m_outputTree->Branch ("eventNumber", &m_eventNumber, "eventNumber/i");
246 m_outputTree->Branch ("processed", &m_processEvent, "processed/O");
247 }
248
249 return StatusCode::SUCCESS;
250 }
251
252
253
254 StatusCode DuplicateChecker ::
255 execute ()
256 {
258
259 read_run_event_number ();
260 m_processEvent = true;
261
262 const std::pair<number_type,number_type> id (m_runNumber, m_eventNumber);
263
264 if (m_currentDuplicates != nullptr)
265 {
266 auto iter = m_currentDuplicates->find (wk()->treeEntry());
267 if (iter != m_currentDuplicates->end())
268 {
269 if (id != iter->second)
270 {
271 ATH_MSG_FATAL ("expected duplicate event at entry " << iter->first
272 << " to be run=" << iter->second.first << ",event="
273 << iter->second.second << " but found run="
274 << id.first << ",event=" << id.second);
275 return StatusCode::FAILURE;
276 }
277 m_processEvent = false;
278 }
279 }
280
281 // implicitly skip duplicates in same file
282 if (m_processEvent)
283 {
284 if (m_processed.find (id) != m_processed.end())
285 {
286 ATH_MSG_WARNING ("skipping duplicate event run=" << id.first
287 << " event=" << id.second << " in file "
288 << wk()->inputFileName() << " at event "
289 << wk()->treeEntry());
290 m_processEvent = false;
291 } else
292 m_processed.insert (id);
293 }
294 if (m_processEvent == false)
295 wk()->skipEvent ();
296 if (m_outputTree)
297 {
298 m_inputFileIndex = wk()->treeEntry ();
299 m_outputTree->Fill ();
300 // m_inputFileName.clear ();
301 }
302
303 return StatusCode::SUCCESS;
304 }
305
306
307
308 void DuplicateChecker ::
309 read_run_event_number ()
310 {
311 const xAOD::EventInfo *info = nullptr;
312 if (m_event->retrieve (info, m_eventInfoName).isFailure())
313 throw std::runtime_error ("didn't find event info \"" + m_eventInfoName + "\"");
314
315 m_runNumber = info->runNumber();
316 m_eventNumber = info->eventNumber();
317 }
318}
#define RCU_ASSERT(x)
Definition Assert.h:210
#define RCU_CHANGE_INVARIANT(x)
Definition Assert.h:219
#define RCU_NEW_INVARIANT(x)
Definition Assert.h:221
#define RCU_READ_INVARIANT(x)
Definition Assert.h:217
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_FATAL(x,...)
ClassImp(EL::DuplicateChecker) namespace EL
A class that manages a list of Sample objects.
a base class that manages a set of files belonging to a particular data set and the associated meta-d...
Definition Sample.h:49
double entries
Definition listroot.cxx:49
This module defines the arguments passed from the BATCH driver to the BATCH worker.
::StatusCode StatusCode
StatusCode definition for legacy code.
EventInfo_v1 EventInfo
Definition of the latest event info version.
static const std::string treeName
the name of the tree in the sample
Definition MetaFields.h:44
static const std::string & sampleName()
the name of the sample being processed
Definition MetaNames.cxx:57
TChain * tree
TFile * file