Project
Loading...
Searching...
No Matches
ResidualAggregator.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
20
21#include <filesystem>
22#include <numeric>
23#include <algorithm>
24#include <chrono>
25#include <random>
26#include <fmt/format.h>
27
28using namespace o2::tpc;
29
31{
32 // trees must be deleted before the file is closed, otherwise segfaults
33 LOGP(debug, "Deleting ResidualsContainer with {} entries. File name is {}", getNEntries(), fileName);
35 treeOutTrackData.reset();
36 treeOutResiduals.reset();
37 treeOutStats.reset();
38 treeOutRecords.reset();
39 if (fileOut) {
40 LOG(debug) << "Removing output file of discarded slot";
41 // this slot was not finalized, need to close and remove the file
42 fileOut->Close();
43 fileOut.reset();
44 std::string fileToRemove = fileName + ".part";
45 if (!std::filesystem::remove(fileToRemove)) {
46 LOG(warning) << "Tried to delete, but could not find file named " << fileToRemove;
47 }
48 }
49}
50
52{
53 LOG(error) << "Must not call copy constructor of ResidualsContainer";
54 // the copy constructor is needed because of ROOT's ClassDef
55 // but should never actually be called
56}
57
59{
60 LOGP(debug, "Move operator called for rhs with {} entries", rhs.nResidualsTotal);
61 trackResiduals = rhs.trackResiduals;
62 fileOut = std::move(rhs.fileOut);
63 fileName = std::move(rhs.fileName);
64 treeOutResidualsUnbinned = std::move(rhs.treeOutResidualsUnbinned);
65 treeOutTrackData = std::move(rhs.treeOutTrackData);
66 treeOutResiduals = std::move(rhs.treeOutResiduals);
67 treeOutStats = std::move(rhs.treeOutStats);
68 treeOutRecords = std::move(rhs.treeOutRecords);
69 for (int iSec = 0; iSec < SECTORSPERSIDE * SIDES; ++iSec) {
70 residuals[iSec] = std::move(rhs.residuals[iSec]);
71 stats[iSec] = std::move(rhs.stats[iSec]);
72 }
73 tfOrbits = std::move(rhs.tfOrbits);
74 sumBinnedResid = std::move(rhs.sumBinnedResid);
75 sumUnbinnedResid = std::move(rhs.sumUnbinnedResid);
76 lumi = std::move(rhs.lumi);
77 unbinnedRes = std::move(rhs.unbinnedRes);
78 trackInfo = std::move(rhs.trackInfo);
79 trkData = std::move(rhs.trkData);
80 trkDataMC = std::move(rhs.trkDataMC);
81 orbitReset = rhs.orbitReset;
82 firstTForbit = rhs.firstTForbit;
83 firstSeenTF = rhs.firstSeenTF;
84 lastSeenTF = rhs.lastSeenTF;
85 nResidualsTotal = rhs.nResidualsTotal;
86}
87
88void ResidualsContainer::init(const TrackResiduals* residualsEngine, std::string outputDir, bool wFile, bool wBinnedResid, bool wUnbinnedResid, bool wTrackData, bool wTrackDataMC, int autosave, int compression, long orbitResetTime)
89{
90 trackResiduals = residualsEngine;
91 writeToRootFile = wFile;
92 writeBinnedResid = wBinnedResid;
93 writeUnbinnedResiduals = wUnbinnedResid;
94 writeTrackData = wTrackData;
95 writeTrackDataMC = wTrackData && wTrackDataMC;
96 autosaveInterval = autosave;
97 orbitReset = orbitResetTime;
98 if (writeToRootFile) {
99 bool outFileCreated = false;
100 int nTries = 0;
101 fileName += std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
102 while (!outFileCreated && nTries < 100) {
103 std::random_device rd;
104 std::mt19937 g(rd());
105 std::uniform_int_distribution<> distr(0, 99);
106 fileName += fmt::format("_{:03}", distr(g)); // add some random number in case multiple slots are opened in an offline job simultaneously
107 fileName += ".root";
108 std::string fileNameTmp = outputDir + fileName;
109 fileNameTmp += ".part"; // to prevent premature external usage of the file use temporary name
110 if (std::filesystem::exists(fileNameTmp)) {
111 fileName.erase(fileName.length() - 9); // remove the _XXX.root from fileName, try with other XXX
112 ++nTries;
113 continue;
114 }
115 fileOut = std::make_unique<TFile>(fileNameTmp.c_str(), "recreate", "", compression);
116 outFileCreated = true;
117 }
118 if (!outFileCreated) {
119 LOG(error) << "Could not create output file for this slot after 100 tries. Disable file writing for this slot";
120 writeToRootFile = false;
121 }
122 }
124 treeOutResidualsUnbinned = std::make_unique<TTree>("unbinnedResid", "TPC unbinned residuals");
126 treeOutResidualsUnbinned->Branch("trackInfo", &trackInfoPtr);
127 treeOutResidualsUnbinned->Branch("CTPLumi", &lumiTF);
128 treeOutResidualsUnbinned->Branch("timeMS", &timeMS);
129 treeOutResidualsUnbinned->Branch("detInfo", &detInfoUnbResPtr);
130 }
131 if (writeTrackData) {
132 treeOutTrackData = std::make_unique<TTree>("trackData", "Track information incl cluster range ref");
133 treeOutTrackData->Branch("trk", &trkDataPtr);
134 if (writeTrackDataMC) {
135 treeOutTrackData->Branch("trkMC", &trkDataMCPtr);
136 }
137 }
138 if (writeBinnedResid) {
139 treeOutResiduals = std::make_unique<TTree>("resid", "TPC binned residuals");
140 treeOutStats = std::make_unique<TTree>("stats", "Voxel statistics mean position and nEntries");
141 for (int iSec = 0; iSec < SECTORSPERSIDE * SIDES; ++iSec) {
142 residualsPtr[iSec] = &residuals[iSec];
143 statsPtr[iSec] = &stats[iSec];
145 for (int ix = 0; ix < trackResiduals->getNXBins(); ++ix) {
146 for (int ip = 0; ip < trackResiduals->getNY2XBins(); ++ip) {
147 for (int iz = 0; iz < trackResiduals->getNZ2XBins(); ++iz) {
148 auto& statsVoxel = stats[iSec][trackResiduals->getGlbVoxBin(ix, ip, iz)];
149 // COG estimates are set to the bin center by default
150 trackResiduals->getVoxelCoordinates(iSec, ix, ip, iz, statsVoxel.meanPos[TrackResiduals::VoxX], statsVoxel.meanPos[TrackResiduals::VoxF], statsVoxel.meanPos[TrackResiduals::VoxZ]);
151 }
152 }
153 }
154 treeOutResiduals->Branch(Form("sec%d", iSec), &residualsPtr[iSec]);
155 treeOutStats->Branch(Form("sec%d", iSec), &statsPtr[iSec]);
156 }
157 }
158 treeOutRecords = std::make_unique<TTree>("records", "Statistics per TF slot");
159 treeOutRecords->Branch("firstTForbit", &tfOrbitsPtr);
160 treeOutRecords->Branch("sumOfBinnedResiduals", &sumBinnedResidPtr);
161 treeOutRecords->Branch("sumOfUnbinnedResiduals", &sumUnbinnedResidPtr);
162 treeOutRecords->Branch("CTPLumi", &lumiPtr);
163 treeOutRecords->Branch("TPCVDriftRef", &TPCVDriftRef);
164 treeOutRecords->Branch("TPCDriftTimeOffsetRef", &TPCDriftTimeOffsetRef);
165 LOG(debug) << "Done initializing residuals container for file named " << fileName;
166}
167
169{
170 // only called when the slot is finalized, otherwise treeOutStats
171 // remains empty and we keep the statistics in memory in the vectors
172 // (since their size anyway does not change)
173 treeOutRecords->Fill();
174 if (writeBinnedResid) {
175 treeOutStats->Fill();
176 }
177}
178
179void ResidualsContainer::fill(const o2::dataformats::TFIDInfo& ti, const gsl::span<const UnbinnedResid> resid, const gsl::span<const DetInfoResid> detInfoRes, const gsl::span<const o2::tpc::TrackDataCompact> trkRefsIn, const gsl::span<const o2::tpc::TrackData>* trkDataIn, const gsl::span<const o2::tpc::TrackDataMC>* trkDataMCIn, const o2::ctp::LumiInfo* lumiInput)
180{
181 // receives large vector of unbinned residuals and fills the sector-wise vectors
182 // with binned residuals and statistics
183 LOG(debug) << "Filling ResidualsContainer with vector of size " << resid.size();
184 uint32_t nUnbinnedResidualsInTF = 0;
185 uint32_t nBinnedResidualsInTF = 0;
186 if (ti.tfCounter > lastSeenTF) {
188 }
189 if (ti.tfCounter < firstSeenTF) {
192 }
193 for (const auto& residIn : resid) {
194 bool counterIncremented = false;
196 unbinnedRes.push_back(residIn);
197 detInfoUnbRes.push_back(detInfoRes.size() ? detInfoRes[nUnbinnedResidualsInTF] : DetInfoResid{});
199 counterIncremented = true;
200 }
201 ++nUnbinnedResidualsInTF;
202 if (!writeBinnedResid) {
203 continue;
204 }
205 if (residIn.isTgSlpClamped() || residIn.isPositionOnly()) {
206 // scdcalib.clampTgSlp: kept in the unbinned output, but its tgSlp is saturated and the voxel fit uses tgSlp (dX from
207 // dY vs tan(phi)), so it must not enter the binned residuals; scdcalib.keepClustersOnPropFail: no reference, dy = dz = 0
208 continue;
209 }
210 int sec = residIn.sec;
211 auto& residVecOut = residuals[sec];
212 auto& statVecOut = stats[sec];
213 std::array<unsigned char, TrackResiduals::VoxDim> bvox;
214 float xPos = param::RowX[residIn.row];
215 float yPos = residIn.y * param::MaxY / 0x7fff + residIn.dy * param::MaxResid / 0x7fff;
216 float zPos = residIn.z * param::MaxZ / 0x7fff + residIn.dz * param::MaxResid / 0x7fff;
217 if (!trackResiduals->findVoxelBin(sec, xPos, yPos, zPos, bvox)) {
218 // we are not inside any voxel
219 LOGF(debug, "Dropping residual in sec(%i), x(%f), y(%f), z(%f)", sec, xPos, yPos, zPos);
220 continue;
221 }
222 residVecOut.emplace_back(residIn.dy, residIn.dz, residIn.tgSlp, bvox);
223 auto& stat = statVecOut[trackResiduals->getGlbVoxBin(bvox)];
224 float& binEntries = stat.nEntries;
225 float oldEntries = binEntries++;
226 float norm = 1.f / binEntries;
227 // update COG for voxel bvox (update for X only needed in case binning is not per pad row)
228 float xPosInv = 1.f / xPos;
229 stat.meanPos[TrackResiduals::VoxX] = (stat.meanPos[TrackResiduals::VoxX] * oldEntries + xPos) * norm;
230 stat.meanPos[TrackResiduals::VoxF] = (stat.meanPos[TrackResiduals::VoxF] * oldEntries + yPos * xPosInv) * norm;
231 stat.meanPos[TrackResiduals::VoxZ] = (stat.meanPos[TrackResiduals::VoxZ] * oldEntries + zPos * xPosInv) * norm;
232 if (!counterIncremented) {
234 }
235 ++nBinnedResidualsInTF;
236 }
237 for (const auto& trkRef : trkRefsIn) {
238 trackInfo.push_back(trkRef);
239 }
240 sumBinnedResid.push_back(nBinnedResidualsInTF);
241 sumUnbinnedResid.push_back(nUnbinnedResidualsInTF);
242 if (writeBinnedResid) {
243 treeOutResiduals->Fill();
244 }
245 for (auto& residVecOut : residuals) {
246 residVecOut.clear();
247 }
248 if (writeTrackData) {
249 for (const auto& trkIn : *trkDataIn) {
250 trkData.push_back(trkIn);
251 }
252 if (writeTrackDataMC && trkDataMCIn) {
253 trkDataMC.assign(trkDataMCIn->begin(), trkDataMCIn->end());
254 }
255 treeOutTrackData->Fill();
256 trkData.clear();
257 trkDataMC.clear();
258 }
260 if (lumiInput) {
261 lumiTF = *lumiInput;
262 }
263 timeMS = orbitReset + ti.tfCounter * o2::constants::lhc::LHCOrbitMUS * 1.e-3;
265 unbinnedRes.clear();
266 detInfoUnbRes.clear();
267 trackInfo.clear();
268 }
269 tfOrbits.push_back(ti.firstTForbit);
270 if (lumiInput) {
271 lumi.push_back(*lumiInput);
272 }
273
274 if (autosaveInterval > 0 && (tfOrbits.size() % autosaveInterval) == 0 && writeToRootFile) {
275 writeToFile(false);
276 }
277}
278
279void ResidualsContainer::writeToFile(bool closeFileAfterwards)
280{
281 LOG(info) << "Writing results to file. Closing afterwards? " << closeFileAfterwards;
282 fillStatisticsBranches(); // these would need to be filled only once, so only the last entry is important
283 fileOut->cd();
284 treeOutRecords->Write();
285 if (writeBinnedResid) {
286 treeOutResiduals->Write();
287 treeOutStats->Write();
288 }
291 }
292 if (writeTrackData) {
293 treeOutTrackData->Write();
294 }
295
296 if (closeFileAfterwards) {
297 treeOutRecords.reset();
298 if (writeBinnedResid) {
299 treeOutResiduals.reset();
300 treeOutStats.reset();
301 }
304 }
305 if (writeTrackData) {
306 treeOutTrackData.reset();
307 }
308 fileOut->Close();
309 fileOut.reset();
310 }
311}
312
314{
315 // the previous slot is merged to this one and afterwards
316 // the previous one will be deleted
317 LOGP(debug, "Merging previous slot with {} entries into current one with {} entries", prev->getNEntries(), getNEntries());
318 if (writeBinnedResid) {
319 for (int iSec = 0; iSec < SECTORSPERSIDE * SIDES; ++iSec) {
320 // merge statistics
321 const auto& statVecPrev = prev->stats[iSec];
322 auto& statVec = stats[iSec];
323 for (int iVox = 0; iVox < trackResiduals->getNVoxelsPerSector(); ++iVox) {
324 const auto& statPrev = statVecPrev[iVox];
325 auto& stat = statVec[iVox];
326 float norm = 1.f;
327 if (statPrev.nEntries + stat.nEntries > 0.1) {
328 // if there is at least a single entry in either of the containers we need the proper norm
329 norm /= (statPrev.nEntries + stat.nEntries);
330 }
331 stat.meanPos[TrackResiduals::VoxX] = (stat.meanPos[TrackResiduals::VoxX] * stat.nEntries + statPrev.meanPos[TrackResiduals::VoxX] * statPrev.nEntries) * norm;
332 stat.meanPos[TrackResiduals::VoxF] = (stat.meanPos[TrackResiduals::VoxF] * stat.nEntries + statPrev.meanPos[TrackResiduals::VoxF] * statPrev.nEntries) * norm;
333 stat.meanPos[TrackResiduals::VoxZ] = (stat.meanPos[TrackResiduals::VoxZ] * stat.nEntries + statPrev.meanPos[TrackResiduals::VoxZ] * statPrev.nEntries) * norm;
334 stat.nEntries += statPrev.nEntries;
335 }
336 // prepare merging of residuals
337 prev->treeOutResiduals->SetBranchAddress(Form("sec%d", iSec), &residualsPtr[iSec]);
338 }
339 // We append the entries of the tree of the following slot to the
340 // previous slot and afterwards move the merged tree to this slot.
341 // This way the order of the entries is preserved
342 for (int i = 0; i < treeOutResiduals->GetEntries(); ++i) {
343 treeOutResiduals->GetEntry(i);
344 prev->treeOutResiduals->Fill();
345 }
346 }
347
348 if (writeTrackData) {
349 prev->treeOutTrackData->SetBranchAddress("trk", &trkDataPtr);
350 if (writeTrackDataMC) {
351 prev->treeOutTrackData->SetBranchAddress("trkMC", &trkDataMCPtr);
352 }
353 for (int i = 0; i < treeOutTrackData->GetEntries(); ++i) {
354 treeOutTrackData->GetEntry(i);
355 prev->treeOutTrackData->Fill();
356 }
357 }
359 prev->treeOutResidualsUnbinned->SetBranchAddress("res", &unbinnedResPtr);
360 prev->treeOutResidualsUnbinned->SetBranchAddress("trackInfo", &trackInfoPtr);
361 prev->treeOutResidualsUnbinned->SetBranchAddress("CTPLumi", &lumiTF);
362 prev->treeOutResidualsUnbinned->SetBranchAddress("timeMS", &timeMS);
363 prev->treeOutResidualsUnbinned->SetBranchAddress("detInfo", &detInfoUnbResPtr);
364 for (int i = 0; i < treeOutResidualsUnbinned->GetEntries(); ++i) {
365 treeOutResidualsUnbinned->GetEntry(i);
366 prev->treeOutResidualsUnbinned->Fill();
367 }
368 }
369
370 treeOutResiduals = std::move(prev->treeOutResiduals);
371 treeOutTrackData = std::move(prev->treeOutTrackData);
373
374 // since we want to continue using the TTrees of the previous slot, we must
375 // avoid that ROOT deletes them when the TFile of the previous slot is erased
376 treeOutResiduals->SetDirectory(fileOut.get());
377 treeOutTrackData->SetDirectory(fileOut.get());
378 treeOutResidualsUnbinned->SetDirectory(fileOut.get());
379
381
382 // append the current vector to the vector of the previous container and afterwards swap them,
383 // since the vector of the previous container will be deleted
384 prev->tfOrbits.insert(prev->tfOrbits.end(), tfOrbits.begin(), tfOrbits.end());
385 std::swap(prev->tfOrbits, tfOrbits);
386 prev->sumBinnedResid.insert(prev->sumBinnedResid.end(), sumBinnedResid.begin(), sumBinnedResid.end());
387 std::swap(prev->sumBinnedResid, sumBinnedResid);
388 prev->sumUnbinnedResid.insert(prev->sumUnbinnedResid.end(), sumUnbinnedResid.begin(), sumUnbinnedResid.end());
389 std::swap(prev->sumUnbinnedResid, sumUnbinnedResid);
390 prev->lumi.insert(prev->lumi.end(), lumi.begin(), lumi.end());
391 std::swap(prev->lumi, lumi);
392
393 firstSeenTF = prev->firstSeenTF;
394 LOGP(debug, "Done with the merge. Current slot has {} entries", getNEntries());
395}
396
398{
399 LOG(info) << "There are in total " << nResidualsTotal << " residuals stored in the container";
400}
401
403
405{
406 auto& slots = getSlots();
407 slots.clear();
408}
409
411{
412 LOG(debug) << "There are " << slot.getContainer()->getNEntries() << " entries currently. Min entries per voxel: " << mMinEntries;
413 auto entriesPerVoxel = slot.getContainer()->getNEntries() / (mTrackResiduals.getNVoxelsPerSector() * SECTORSPERSIDE * SIDES);
414 LOGP(debug, "Slot has {} entries per voxel, at least {} are required", entriesPerVoxel, mMinEntries);
415 return entriesPerVoxel >= mMinEntries;
416}
417
419{
420 // nothing to be done here, but method needs to be overwritten
421}
422
424{
425 LOG(info) << "Finalizing slot";
426 auto finalizeStartTime = std::chrono::high_resolution_clock::now();
427 auto cont = slot.getContainer();
428 cont->print();
429 if (!mWriteOutput || cont->getNEntries() == 0 || !cont->writeToRootFile) {
430 LOGP(info, "Skip writing output with {} entries, since file output is disabled or slot is empty", cont->getNEntries());
431 return;
432 }
433 cont->TPCVDriftRef = mTPCVDriftRef;
434 cont->TPCDriftTimeOffsetRef = mTPCDriftTimeOffsetRef;
435 cont->writeToFile(true);
436
437 long orbitOffsetStart = (cont->firstSeenTF - slot.getTFStart()) * o2::base::GRPGeomHelper::getNHBFPerTF();
438 long orbitOffsetEnd = (slot.getTFEnd() - cont->firstSeenTF) * o2::base::GRPGeomHelper::getNHBFPerTF();
439 long timeStartMS = mOrbitResetTime + (cont->firstTForbit - orbitOffsetStart) * o2::constants::lhc::LHCOrbitMUS * 1.e-3;
440 long timeEndMS = mOrbitResetTime + (cont->firstTForbit + orbitOffsetEnd) * o2::constants::lhc::LHCOrbitMUS * 1.e-3;
441 auto fileName = fmt::format("o2tpc_residuals_{}_{}_{}_{}.root", timeStartMS, timeEndMS, slot.getTFStart(), slot.getTFEnd());
442 auto fileNameWithPath = mOutputDir + fileName;
443 std::filesystem::rename(o2::utils::Str::concat_string(mOutputDir, cont->fileName, ".part"), fileNameWithPath);
444 if (mStoreMetaData) {
445 o2::dataformats::FileMetaData fileMetaData; // object with information for meta data file
446 fileMetaData.fillFileData(fileNameWithPath);
447 fileMetaData.setDataTakingContext(mDataTakingContext);
448 fileMetaData.type = "calib";
449 fileMetaData.priority = "high";
450 auto metaFileNameTmp = fmt::format("{}{}.tmp", mMetaOutputDir, fileName);
451 auto metaFileName = fmt::format("{}{}.done", mMetaOutputDir, fileName);
452 try {
453 std::ofstream metaFileOut(metaFileNameTmp);
454 metaFileOut << fileMetaData;
455 metaFileOut.close();
456 std::filesystem::rename(metaFileNameTmp, metaFileName);
457 } catch (std::exception const& e) {
458 LOG(error) << "Failed to store residuals meta data file " << metaFileName << ", reason: " << e.what();
459 }
460 }
461 std::chrono::duration<double, std::milli> finalizeDuration = std::chrono::high_resolution_clock::now() - finalizeStartTime;
462 LOGP(info, "Finalizing calibration slot took: {} ms", std::chrono::duration_cast<std::chrono::milliseconds>(finalizeDuration).count());
463}
464
466{
467 auto emplaceStartTime = std::chrono::high_resolution_clock::now();
468 auto& cont = getSlots();
469 auto& slot = front ? cont.emplace_front(tStart, tEnd) : cont.emplace_back(tStart, tEnd);
470 slot.setContainer(std::make_unique<ResidualsContainer>());
471 slot.getContainer()->init(&mTrackResiduals, mOutputDir, mWriteOutput, mWriteBinnedResiduals, mWriteUnbinnedResiduals, mWriteTrackData, mWriteTrackDataMC, mAutosaveInterval, mCompressionSetting, mOrbitResetTime);
472 std::chrono::duration<double, std::milli> emplaceDuration = std::chrono::high_resolution_clock::now() - emplaceStartTime;
473 LOGP(info, "Emplacing new calibration slot took: {} ms", std::chrono::duration_cast<std::chrono::milliseconds>(emplaceDuration).count());
474 return slot;
475}
476
478{
479 // for the residual extraction we are using the reference vDrift and time offset values only
480 if (v.refVDrift != mTPCVDriftRef) {
481 mTPCVDriftRef = v.refVDrift;
482 mTPCDriftTimeOffsetRef = v.refTimeOffset;
483 LOGP(info, "Imposing reference VDrift={}/TDrift={} for TPC residuals extraction", mTPCVDriftRef, mTPCDriftTimeOffsetRef);
484 }
485}
std::ostringstream debug
int32_t i
Collects local TPC cluster residuals from EPNs.
Parameters used for TPC space point calibration.
calibration data from laser track calibration
TFType getTFEnd() const
Definition TimeSlot.h:47
const Container * getContainer() const
Definition TimeSlot.h:53
TFType getTFStart() const
Definition TimeSlot.h:46
Slot & emplaceNewSlot(bool front, TFType tStart, TFType tEnd) final
bool hasEnoughData(const Slot &slot) const final
void setTPCVDrift(const o2::tpc::VDriftCorrFact &v)
void finalizeSlot(Slot &slot) final
size_t getGlbVoxBin(int ix, int ip, int iz) const
int getNVoxelsPerSector() const
Get the total number of voxels per TPC sector (mNXBins * mNY2XBins * mNZ2XBins)
void getVoxelCoordinates(int isec, int ix, int ip, int iz, float &x, float &p, float &z) const
bool findVoxelBin(int secID, float x, float y, float z, std::array< unsigned char, VoxDim > &bvox) const
Calculates the bin indices for given x, y, z in sector coordinates.
GLint GLsizei count
Definition glcorearb.h:399
const GLdouble * v
Definition glcorearb.h:832
GLboolean GLboolean g
Definition glcorearb.h:1233
Global TPC definitions and constants.
Definition SimTraits.h:172
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
bool fillFileData(const std::string &fname, bool fillmd5=false, const std::string &tmpEnding="")
void setDataTakingContext(const o2::framework::DataTakingContext &dtc)
std::unique_ptr< TTree > treeOutResidualsUnbinned
std::vector< TrackDataCompact > * trackInfoPtr
allows to obtain track type for each unbinned residual downstream
long orbitReset
current orbit reset time in ms
std::array< std::vector< TrackResiduals::VoxStats > *, SECTORSPERSIDE *SIDES > statsPtr
std::vector< TrackData > * trkDataPtr
track data and cluster ranges
std::unique_ptr< TTree > treeOutRecords
float TPCVDriftRef
TPC nominal drift speed in cm/microseconds.
std::vector< TrackDataMC > * trkDataMCPtr
MC truth for the track data (MC only)
std::vector< uint32_t > sumBinnedResid
TFType lastSeenTF
the last TF which was added to this container
uint64_t timeMS
for each processed TF we store its absolute time in ms in the tree of unbinned residuals
bool writeTrackDataMC
flag, whether the MC truth of the seeding tracks should be written out
std::vector< DetInfoResid > * detInfoUnbResPtr
detector info associated to unbinned residuals which are sent to the aggregator
void fill(const o2::dataformats::TFIDInfo &ti, const gsl::span< const UnbinnedResid > resid, const gsl::span< const DetInfoResid > detInfoRes, const gsl::span< const o2::tpc::TrackDataCompact > trkRefsIn, const gsl::span< const o2::tpc::TrackData > *trkDataIn, const gsl::span< const o2::tpc::TrackDataMC > *trkDataMCIn, const o2::ctp::LumiInfo *lumiInput)
std::vector< UnbinnedResid > * unbinnedResPtr
unbinned residuals which are sent to the aggregator
std::vector< uint32_t > tfOrbits
std::vector< uint32_t > * sumBinnedResidPtr
sum of binned residuals for each TF
std::vector< TrackDataMC > trkDataMC
uint32_t firstTForbit
stored for the first seen TF to allow conversion to time stamp
std::vector< o2::ctp::LumiInfo > * lumiPtr
luminosity information from CTP per TF
void init(const TrackResiduals *residualsEngine, std::string outputDir, bool wFile, bool wBinnedResid, bool wUnbinnedResid, bool wTrackData, bool wTrackDataMC, int autosave, int compression, long orbitResetTime)
std::array< std::vector< TrackResiduals::LocalResid > *, SECTORSPERSIDE *SIDES > residualsPtr
bool writeBinnedResid
flag, whether binned residuals should be written out
std::vector< o2::ctp::LumiInfo > lumi
bool writeTrackData
flag, whether full seeding track information should be written out
std::vector< TrackDataCompact > trackInfo
std::vector< uint32_t > * tfOrbitsPtr
first TF orbit
bool writeUnbinnedResiduals
flag, whether unbinned residuals should be written out
void writeToFile(bool closeFileAfterwards)
o2::ctp::LumiInfo lumiTF
for each processed TF we store the lumi information in the tree of unbinned residuals
std::array< std::vector< TrackResiduals::LocalResid >, SECTORSPERSIDE *SIDES > residuals
local (binned) residuals per sector
void merge(ResidualsContainer *prev)
std::vector< UnbinnedResid > unbinnedRes
float TPCDriftTimeOffsetRef
TPC nominal (e.g. at the start of run) drift time bias in cm/mus.
std::unique_ptr< TFile > fileOut
std::vector< uint32_t > sumUnbinnedResid
std::array< std::vector< TrackResiduals::VoxStats >, SECTORSPERSIDE *SIDES > stats
voxel statistics per sector
std::unique_ptr< TTree > treeOutStats
const TrackResiduals * trackResiduals
TFType firstSeenTF
the first TF which was added to this container
uint64_t nResidualsTotal
the total number of residuals for this container
std::vector< uint32_t > * sumUnbinnedResidPtr
sum of unbinned residuals for each TF
std::unique_ptr< TTree > treeOutResiduals
int autosaveInterval
if > 0, then the output written to file for every n-th TF
std::vector< DetInfoResid > detInfoUnbRes
std::unique_ptr< TTree > treeOutTrackData
std::vector< TrackData > trkData
bool writeToRootFile
set to false to avoid that any output file is produced
static std::string concat_string(Ts const &... ts)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::uniform_int_distribution< unsigned long long > distr
std::random_device rd