ATLAS Offline Software
Loading...
Searching...
No Matches
TreeAccessor.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
14
15#include "TObjString.h"
16#include "TFile.h"
17#include "TTree.h"
18#include "TSystem.h"
19#include "TString.h"
20#include <iostream>
21#include <fstream>
22#include <iomanip>
23
24using std::cout;
25using std::endl;
26
27using namespace LArSamples;
28
29
30std::unique_ptr<TreeAccessor> TreeAccessor::open(const TString& fileName)
31{
32 std::unique_ptr<TFile> file (TFile::Open(fileName));
33 if (!file) return nullptr;
34 if (!file->IsOpen()) { return nullptr; }
35 TTree* cellTree = (TTree*)file->Get("cells");
36 if (!cellTree) return nullptr;
37 TTree* scTree = (TTree*)file->Get("SC");
38 if (!scTree) return nullptr;
39 TTree* eventTree = (TTree*)file->Get("events");
40 if (!eventTree) return nullptr;
41 TTree* runTree = (TTree*)file->Get("runs");
42 return std::make_unique<TreeAccessor>(*cellTree, *scTree, *eventTree, runTree, file.release());
43}
44
45
46const CellInfo* TreeAccessor::getCellInfo(unsigned int i) const
47{
48 const HistoryContainer* cont = historyContainer(i);
49 if (!cont || !cont->cellInfo()) return nullptr;
50 return new CellInfo(*cont->cellInfo());
51}
52
53const CellInfo* TreeAccessor::getSCInfo(unsigned int i) const
54{
55 const HistoryContainer* cont = historyContainerSC(i);
56 if (!cont || !cont->cellInfo()) return nullptr;
57 return new CellInfo(*cont->cellInfo());
58}
59
60
61const History* TreeAccessor::getCellHistory(unsigned int i) const
62{
63 if (i >= cellTree().GetEntries()) return nullptr;
64 getCellEntry(i);
65
66 std::vector<const EventData*> eventDatas;
67
68 for (unsigned int k = 0; k < currentContainer()->nDataContainers(); k++) {
69 const EventData* evtData = eventData(currentContainer()->dataContainer(k)->eventIndex());
70 EventData* newEvtData = (evtData ? new EventData(*evtData) : nullptr);
71 eventDatas.push_back(newEvtData);
72 }
73 return (currentContainer()->cellInfo() ? new History(*currentContainer(), eventDatas, i) : nullptr);
74}
75
76const History* TreeAccessor::getSCHistory(unsigned int i) const
77{
78 if (i >= SCTree().GetEntries()) return nullptr;
79 getSCEntry(i);
80
81 std::vector<const EventData*> eventDatas;
82
83 for (unsigned int k = 0; k < currentContainerSC()->nDataContainers(); k++) {
84 const EventData* evtData = eventData(currentContainerSC()->dataContainer(k)->eventIndex());
85 EventData* newEvtData = (evtData ? new EventData(*evtData) : nullptr);
86 eventDatas.push_back(newEvtData);
87 }
88 return (currentContainerSC()->cellInfo() ? new History(*currentContainerSC(), eventDatas, i) : nullptr);
89}
90
91std::unique_ptr<TreeAccessor> TreeAccessor::merge(const std::vector<const Accessor*>& accessors,
92 const TString& fileName)
93{
94 cout << "Merging to " << fileName << endl;
95 auto newAcc = std::make_unique<TreeAccessor>(fileName);
96 unsigned int size = 0;
97
98 int evtIndex = 0, runIndex = 0;
99 std::map<std::pair<int, int>, int> evtMap;
100 std::map<int, int> runMap;
101
102 cout << "Merging runs" << endl;
103 for (const Accessor* accessor : accessors) {
104 if (!accessor) {
105 cout << "Cannot merge: one of the inputs is null!" << endl;
106 return nullptr;
107 }
108 for (unsigned int i = 0; i < accessor->nRuns(); i++) {
109 int run = accessor->runData(i)->run();
110 if (runMap.find(run) != runMap.end()) continue;
111 runMap[run] = runIndex;
112 RunData newRun(*accessor->runData(i));
113 newAcc->addRun(&newRun);
114 runIndex++;
115 }
116 }
117
118 cout << "Merging events" << endl;
119 unsigned int nEventsTotal = 0, iEvt = 0;
120 for (const Accessor* accessor : accessors)
121 nEventsTotal += accessor->nEvents();
122 for (const Accessor* accessor : accessors) {
123 for (unsigned int i = 0; i < accessor->nEvents(); i++) {
124 iEvt++;
125 if (iEvt % 100000 == 0) cout << "Merging event " << iEvt << "/" << nEventsTotal << endl;
126 std::pair<int, int> evtId(accessor->eventData(i)->run(), accessor->eventData(i)->event());
127 if (evtMap.find(evtId) != evtMap.end()) continue;
128 evtMap[evtId] = evtIndex;
129 std::map<int, int>::const_iterator idx = runMap.find(accessor->eventData(i)->run());
130 int newRunIndex = (idx == runMap.end() ? -999 : idx->second);
131 //cout << "Storing eventData for run " << accessor->eventData(i)->run() << " at index " << newRunIndex << " instead of " << accessor->eventData(i)->runIndex() << endl;
132 EventData newEvent(*accessor->eventData(i), newRunIndex);
133 newAcc->addEvent(&newEvent);
134 evtIndex++;
135 }
136 }
137
138 for (unsigned int i = 0; i < newAcc->nChannels(); i++) {
139 if (i % 10000 == 0) {
140 cout << "Merging channel " << i << "/" << newAcc->nChannels() << " (current size = " << size << ")" << endl;
141 //ClassCounts::printCountsTable();
142 }
143 std::optional<HistoryContainer> historyContainer;
144 CellInfo* info = nullptr;
145 for (const Accessor* accessor : accessors) {
146 const History* history = accessor->cellHistory(i);
147 if (!history || !history->isValid()) continue;
148 if (!historyContainer) {
149 info = new CellInfo(*history->cellInfo());
150 historyContainer.emplace (info);
151 }
152 for (unsigned int j = 0; j < history->nData(); j++) {
153 auto newDC = std::make_unique<DataContainer>(history->data(j)->container());
154 std::map<std::pair<int, int>, int>::const_iterator newIndex
155 = evtMap.find(std::make_pair(history->data(j)->run(), history->data(j)->event()));
156 if (newIndex == evtMap.end()) std::cout << "Event not found for cell " << i << ", data " << j << ".\n";
157 newDC->setEventIndex(newIndex != evtMap.end() ? newIndex->second : -1);
158 historyContainer->add(newDC.release());
159 if (not info) continue;
160 if (!info->shape(history->data(j)->gain())) {
161 const ShapeInfo* shape = history->cellInfo()->shape(history->data(j)->gain());
162 if (!shape) {
163 cout << "Shape not filled for hash = " << i << ", index = " << j << ", gain = " << Data::gainStr(history->data(j)->gain()) << endl;
164 }
165 info->setShape(history->data(j)->gain(), (shape ? new ShapeInfo(*shape) : nullptr));
166 }
167 }
168 }
169 if (historyContainer) size += historyContainer->nDataContainers();
170 newAcc->add(&historyContainer.value());
171 }
172
173 cout << "Merging done, final size = " << size << endl;
174 newAcc->save();
175 return newAcc;
176}
177
178
179std::unique_ptr<TreeAccessor> TreeAccessor::merge(const std::vector<const Accessor*>& accessors,const TString& fileName,const TString& LBFile)
180{
181 // O.Simard - 01.07.2011
182 // Alternative version with LB cleaning.
183
184 bool kBadLB=false;
185 std::vector<unsigned int> LBList;
186 std::ifstream infile(LBFile.Data());
187 std::string line;
188 // assume single-line format with coma-separated LBs (from python)
189 std::getline(infile,line,'\n');
190 TString filter(line.c_str());
191 std::unique_ptr<TObjArray> list (filter.Tokenize(", ")); // coma\space delimiters
192 if(list->GetEntries() == 0){
193 printf("No LB filtering specified, or bad format. Exiting.\n");
194 return nullptr;
195 }
196
197 for(int k = 0; k < list->GetEntries(); k++){
198 TObjString* tobs = (TObjString*)(list->At(k));
199 LBList.push_back((unsigned int)(tobs->String()).Atoi());
200 }
201 printf("LB List: %d\n",(int)LBList.size());
202
203
204 // from here it is similar to other functions of this class
205 auto newAcc = std::make_unique<TreeAccessor>(fileName);
206 unsigned int size = 0;
207
208 int evtIndex = 0, runIndex = 0;
209 std::map<std::pair<int, int>, int> evtMap;
210 std::map<int, int> runMap;
211
212 cout << "Merging runs" << endl;
213 for (const Accessor* accessor : accessors) {
214 if (!accessor) {
215 cout << "Cannot merge: one of the inputs is null!" << endl;
216 return nullptr;
217 }
218 for (unsigned int i = 0; i < accessor->nRuns(); i++) {
219 int run = accessor->runData(i)->run();
220 if (runMap.find(run) != runMap.end()) continue;
221 runMap[run] = runIndex;
222 RunData newRun(*accessor->runData(i));
223 newAcc->addRun(&newRun);
224 runIndex++;
225 }
226 }
227
228 cout << "Merging events" << endl;
229 unsigned int nEventsTotal = 0, iEvt = 0;
230 for (const Accessor* accessor : accessors)
231 nEventsTotal += accessor->nEvents();
232 for (const Accessor* accessor : accessors) {
233 for (unsigned int i = 0; i < accessor->nEvents(); i++) {
234 iEvt++;
235 if (iEvt % 100000 == 0) cout << "Merging event " << iEvt << "/" << nEventsTotal << endl;
236
237 // ----
238 // skip LBs which are found in the list
239 kBadLB=false;
240 for(unsigned int ilb = 0 ; ilb < LBList.size() ; ilb++){
241 if(LBList.at(ilb)==accessor->eventData(i)->lumiBlock()){
242 kBadLB=true;
243 //printf(" == Rejecting Event in LB %4d\n",accessor->eventData(i)->lumiBlock());
244 break;
245 }
246 }
247 if(kBadLB) continue;
248 // ----
249
250 std::pair<int, int> evtId(accessor->eventData(i)->run(), accessor->eventData(i)->event());
251 if (evtMap.find(evtId) != evtMap.end()) continue;
252 evtMap[evtId] = evtIndex;
253 std::map<int, int>::const_iterator idx = runMap.find(accessor->eventData(i)->run());
254 int newRunIndex = (idx == runMap.end() ? -999 : idx->second);
255 EventData newEvent(*accessor->eventData(i), newRunIndex);
256 newAcc->addEvent(&newEvent);
257 evtIndex++;
258 }
259 }
260
261 cout << "Merging cells" << endl;
262 for (unsigned int i = 0; i < newAcc->nChannels(); i++) {
263 if (i % 10000 == 0) {
264 cout << "Merging channel " << i << "/" << newAcc->nChannels() << " (current size = " << size << ")" << endl;
265 //ClassCounts::printCountsTable();
266 }
267 std::optional<HistoryContainer> historyContainer;
268 CellInfo* info = nullptr;
269 for (const Accessor* accessor : accessors) {
270 const History* history = accessor->cellHistory(i);
271 if (!history || !history->isValid()) continue;
272 if (!historyContainer) {
273 info = new CellInfo(*history->cellInfo());
274 historyContainer.emplace (info);
275 }
276 for (unsigned int j = 0; j < history->nData(); j++) {
277 auto newDC = std::make_unique<DataContainer>(history->data(j)->container());
278 std::map<std::pair<int, int>, int>::const_iterator newIndex
279 = evtMap.find(std::make_pair(history->data(j)->run(), history->data(j)->event()));
280 //if (newIndex == evtMap.end()) cout << "Event not found for cell " << i << ", data " << j << "." << endl;
281 newDC->setEventIndex(newIndex != evtMap.end() ? newIndex->second : -1);
282 historyContainer->add(newDC.release());
283 if (not info) continue;
284 if (!info->shape(history->data(j)->gain())) {
285 const ShapeInfo* shape = history->cellInfo()->shape(history->data(j)->gain());
286 if (!shape)
287 cout << "Shape not filled for hash = " << i << ", index = " << j << ", gain = " << Data::gainStr(history->data(j)->gain()) << endl;
288 info->setShape(history->data(j)->gain(), (shape ? new ShapeInfo(*shape) : nullptr));
289 }
290 }
291 }
293 size += historyContainer->nDataContainers();
294 }
295 newAcc->add(&historyContainer.value());
296 //}
297 }
298
299 cout << "Merging SC" << endl;
300 for (unsigned int i = 0; i < newAcc->nChannelsSC(); i++) {
301 if (i % 10000 == 0) {
302 cout << "Merging channel " << i << "/" << newAcc->nChannelsSC() << " (current size = " << size << ")" << endl;
303 }
304 std::optional<HistoryContainer> historyContainer;
305 CellInfo* info = nullptr;
306 for (const Accessor* accessor : accessors) {
307 const History* history = accessor->getSCHistory(i);
308 if (!history || !history->isValid()) continue;
309 if (!historyContainer) {
310 info = new CellInfo(*history->cellInfo());
311 historyContainer.emplace (info);
312 }
313 for (unsigned int j = 0; j < history->nData(); j++) {
314 auto newDC = std::make_unique<DataContainer>(history->data(j)->container());
315 std::map<std::pair<int, int>, int>::const_iterator newIndex
316 = evtMap.find(std::make_pair(history->data(j)->run(), history->data(j)->event()));
317 //if (newIndex == evtMap.end()) cout << "Event not found for cell " << i << ", data " << j << "." << endl;
318 newDC->setEventIndex(newIndex != evtMap.end() ? newIndex->second : -1);
319 historyContainer->add(newDC.release());
320 if (not info) continue;
321 if (!info->shape(history->data(j)->gain())) {
322 const ShapeInfo* shape = history->cellInfo()->shape(history->data(j)->gain());
323 if (!shape)
324 cout << "Shape not filled for hash = " << i << ", index = " << j << ", gain = " << Data::gainStr(history->data(j)->gain()) << endl;
325 info->setShape(history->data(j)->gain(), (shape ? new ShapeInfo(*shape) : nullptr));
326 }
327 }
328 }
330 size += historyContainer->nDataContainers();
331 }
332 newAcc->addSC(&historyContainer.value());
333 //}
334 }
335
336 cout << "Merging done, final size = " << size << endl;
337 newAcc->save();
338 return newAcc;
339}
340
341
342std::unique_ptr<TreeAccessor> TreeAccessor::filter(const Accessor& accessor,
343 const FilterParams& filterParams,
344 const TString& fileName,
345 const DataTweaker& tweaker)
346{
347 FilterList filterList; filterList.add(filterParams, fileName);
348 std::vector<std::unique_ptr<TreeAccessor> > result = filter(accessor, filterList, tweaker);
349 return (!result.empty() ? std::move(result[0]) : nullptr);
350}
351
352std::vector<std::unique_ptr<TreeAccessor> >
354 const FilterList& filterList,
355 const DataTweaker& tweaker)
356{
357 std::vector<std::unique_ptr<TreeAccessor> > newAccessors;
358
359 if (filterList.size() == 0) {
360 cout << "No filter categories specified, done! (?)" << endl;
361 return newAccessors;
362 }
363
364 for (unsigned int f = 0; f < filterList.size(); f++) {
365 cout << "Skimming to " << filterList.fileName(f) << endl;
366 if (!gSystem->AccessPathName(filterList.fileName(f))) {
367 cout << "File already exists, exiting." << endl;
368 return newAccessors;
369 }
370 }
371
372 for (unsigned int f = 0; f < filterList.size(); f++)
373 newAccessors.push_back(std::make_unique<TreeAccessor>(filterList.fileName(f)));
374 std::map<std::pair<unsigned int, unsigned int>, unsigned int> eventIndices;
375 std::vector< std::map<unsigned int, unsigned int> > eventsToKeep(filterList.size());
376 std::vector< std::map<unsigned int, unsigned int> > runsToKeep(filterList.size());
377
378 double nTot = 0, nPass = 0;
379
380 for (unsigned int i = 0; i < accessor.nEvents(); i++) {
381 const EventData* eventData = accessor.eventData(i);
382 eventIndices[std::pair<unsigned int, unsigned int>(eventData->run(), eventData->event())] = i;
383 }
384
385 for (unsigned int i = 0; i < accessor.nChannels(); i++) {
386 if (i % 25000 == 0) {
387 cout << "Filtering " << i << "/" << accessor.nChannels()
388 << " (passing so far = " << nPass << ", total seen = " << nTot << ")" << endl;
389 //ClassCounts::printCountsTable();
390 }
391 bool first = true;
392
393 const History* history = nullptr;
394 for (unsigned int f = 0; f < filterList.size(); f++) {
395 history = accessor.pass(i, filterList.filterParams(f));
396 if (history) break;
397 }
398 for (unsigned int f = 0; f < filterList.size(); f++) {
399 if (!history || !history->cellInfo() || !filterList.filterParams(f).passCell(*history->cellInfo())) {
400 HistoryContainer newHist;
401 newAccessors[f]->add(&newHist);
402 continue;
403 }
404 if (first) { nTot += history->nData(); first = false; }
405 HistoryContainer newHist(new CellInfo(*history->cellInfo()));
406 for (unsigned int k = 0; k < history->nData(); k++) {
407 if (!filterList.filterParams(f).passEvent(*history->data(k))) continue;
408 const EventData* eventData = history->data(k)->eventData();
409 std::map<std::pair<unsigned int, unsigned int>, unsigned int>::const_iterator findIndex =
410 eventIndices.find(std::pair<unsigned int, unsigned int>(eventData->run(), eventData->event()));
411 if (findIndex == eventIndices.end()) {
412 cout << "Inconsistent event numbering!!!" << endl;
413 return std::vector<std::unique_ptr<TreeAccessor> >();
414 }
415 int oldEvtIndex = findIndex->second;
416 bool isNewEvt = (eventsToKeep[f].find(oldEvtIndex) == eventsToKeep[f].end());
417 unsigned int newEvtIndex = (isNewEvt ? eventsToKeep[f].size() : eventsToKeep[f][oldEvtIndex]);
418 if (isNewEvt) eventsToKeep[f][oldEvtIndex] = newEvtIndex;
419
420 int oldRunIndex = history->data(k)->eventData()->runIndex();
421 bool isNewRun = (runsToKeep[f].find(oldRunIndex) == runsToKeep[f].end());
422 unsigned int newRunIndex = (isNewRun ? runsToKeep[f].size() : runsToKeep[f][oldRunIndex]);
423 if (isNewRun) runsToKeep[f][oldRunIndex] = newRunIndex;
424
425 Data* newData = tweaker.tweak(*history->data(k), newEvtIndex);
426 if (!newData) {
427 cout << "Filtering failed on data " << k << " of cell " << i << ", aborting" << endl;
428 return std::vector<std::unique_ptr<TreeAccessor> >();
429 }
430 nPass++;
431 newHist.add(newData->dissolve());
432 }
433 newAccessors[f]->add(&newHist);
434 }
435 }
436
437 for (unsigned int f = 0; f < filterList.size(); f++) {
438 cout << "Adding runs..." << endl;
439 std::vector<unsigned int> runsToKeep_ordered(runsToKeep[f].size());
440 for (const auto& runIndex : runsToKeep[f])
441 runsToKeep_ordered[runIndex.second] = runIndex.first;
442
443 for (unsigned int runIndex : runsToKeep_ordered) {
444 RunData newRun(*accessor.runData(runIndex));
445 newAccessors[f]->addRun(&newRun);
446 }
447 cout << "Adding events..." << endl;
448 std::vector<unsigned int> eventsToKeep_ordered(eventsToKeep[f].size());
449 for (const auto& eventIndex : eventsToKeep[f])
450 eventsToKeep_ordered[eventIndex.second] = eventIndex.first;
451
452 for (unsigned int eventIndex : eventsToKeep_ordered) {
453 std::map<unsigned int, unsigned int>::const_iterator idx = runsToKeep[f].find(accessor.eventData(eventIndex)->runIndex());
454 int newRunIndex = (idx == runsToKeep[f].end() ? 0 : idx->second);
455 std::unique_ptr<EventData> newEvent (tweaker.tweak(*accessor.eventData(eventIndex), newRunIndex));
456 newAccessors[f]->addEvent(newEvent.get());
457 }
458 }
459 cout << "Filtering done! final size = " << nPass << endl;
460 //ClassCounts::printCountsTable();
461 for (unsigned int f = 0; f < filterList.size(); f++) {
462 cout << "Saving " << newAccessors[f]->fileName() << endl;
463 newAccessors[f]->save();
464 }
465 return newAccessors;
466}
467
468
469std::unique_ptr<TreeAccessor> TreeAccessor::makeTemplate(const Accessor& accessor, const TString& fileName)
470{
471 auto newAccessor = std::make_unique<TreeAccessor>(fileName);
472
473 std::vector<short> samples(5, 0);
474 std::vector<float> autoCorrs(4, 0);
475
476 RunData dummyRun(0);
477 newAccessor->addRun(&dummyRun);
478
479 EventData dummyEvent(0, 0, 0, 0);
480 newAccessor->addEvent(&dummyEvent);
481
482 for (unsigned int i = 0; i < accessor.nChannels(); i++) {
483 if (i % 25000 == 0)
484 cout << "Templating " << i << "/" << accessor.nChannels() << endl;
485 const History* history = accessor.cellHistory(i);
486 if (!history || !history->cellInfo()) {
487 HistoryContainer newHist;
488 newAccessor->add(&newHist);
489 continue;
490 }
491 HistoryContainer newHist(new CellInfo(*history->cellInfo()));
492 auto dataContainer = std::make_unique<DataContainer>(CaloGain::LARHIGHGAIN, samples, 0, 0, 0, 0, autoCorrs);
493 newHist.add(dataContainer.release());
494 newAccessor->add(&newHist);
495 }
496
497 newAccessor->save();
498 return newAccessor;
499}
500
501bool TreeAccessor::writeToFile(const TString& fileName) const
502{
503 TFile newFile(fileName, "RECREATE");
504 if (!newFile.IsOpen()) return false;
505
506 cellTree().Write();
507 eventTree().Write();
508
509 return true;
510}
TGraphErrors * GetEntries(TH2F *histo)
virtual const CellInfo * cellInfo(unsigned int i) const
const ShapeInfo * shape(CaloGain::CaloGain gain) const
Definition CellInfo.cxx:78
Data * tweak(const Data &data, int evtIndex=-1) const
const EventData * eventData() const
Definition Data.h:95
CaloGain::CaloGain gain() const
Definition Data.h:85
static TString gainStr(CaloGain::CaloGain gain)
Definition Data.cxx:505
const DataContainer & container() const
Definition Data.h:156
const DataContainer * dissolve()
Definition Data.cxx:56
int event() const
Definition Data.cxx:28
int run() const
Definition Data.cxx:27
void add(const FilterParams &params, const TString &fileName)
Definition FilterList.h:27
unsigned int size() const
Definition FilterList.h:29
const FilterParams & filterParams(unsigned int i) const
Definition FilterList.h:30
const TString & fileName(unsigned int i) const
Definition FilterList.h:31
bool passCell(const CellInfo &info) const
bool passEvent(const Data &data) const
const CellInfo * cellInfo() const
unsigned int nDataContainers() const
bool isValid() const
Definition History.cxx:152
const CellInfo * cellInfo() const
Definition History.h:57
const Data * data(unsigned int i) const
Definition History.cxx:91
unsigned int nData() const
Definition History.h:52
HistoryContainer * currentContainer() const
const HistoryContainer * historyContainer(unsigned int i) const
const HistoryContainer * historyContainerSC(unsigned int i) const
HistoryContainer * currentContainerSC() const
int getCellEntry(unsigned int i) const
int getSCEntry(unsigned int i) const
const EventData * eventData(unsigned int i) const
const History * getCellHistory(unsigned int i) const
static std::unique_ptr< TreeAccessor > merge(const std::vector< const Accessor * > &accessors, const TString &fileName="")
const CellInfo * getCellInfo(unsigned int i) const
bool writeToFile(const TString &fileName) const
static std::unique_ptr< TreeAccessor > open(const TString &fileName)
const History * getSCHistory(unsigned int i) const
const CellInfo * getSCInfo(unsigned int i) const
static std::unique_ptr< TreeAccessor > makeTemplate(const Accessor &accessor, const TString &fileName)
static std::unique_ptr< TreeAccessor > filter(const Accessor &accessor, const FilterParams &filterParams, const TString &fileName, const DataTweaker &tweaker)
@ LARHIGHGAIN
Definition CaloGain.h:18
int run(int argc, char *argv[])