Project
Loading...
Searching...
No Matches
TimeFrameMixin.h
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.
15
16#ifndef ALICEO2_ALICE3GLOBALRECONSTRUCTION_TIMEFRAMEMIXIN_H
17#define ALICEO2_ALICE3GLOBALRECONSTRUCTION_TIMEFRAMEMIXIN_H
18
30#include "TRKSimulation/Hit.h"
33#include "Framework/Logger.h"
34
35#include <Rtypes.h>
36#include <TTree.h>
37#include <TRandom3.h>
38#include <gsl/span>
39
40#include <algorithm>
41#include <array>
42#include <cmath>
43#include <limits>
44#include <ranges>
45#include <vector>
46
47#include <nlohmann/json.hpp>
48
49namespace o2::trk
50{
51
52template <int nLayers, class Base>
53class TimeFrameMixin : public Base
54{
55 public:
56 TimeFrameMixin() = default;
57 ~TimeFrameMixin() override = default;
58
59 int loadROFsFromHitTree(TTree* hitsTree, GeometryTGeo* gman, const nlohmann::json& config);
60
61 int loadROFrameData(const std::array<gsl::span<const o2::trk::ROFRecord>, nLayers>& layerROFs,
62 const std::array<gsl::span<const o2::trk::Cluster>, nLayers>& layerClusters,
63 const std::array<gsl::span<const unsigned char>, nLayers>& layerPatterns,
64 const std::array<const dataformats::MCTruthContainer<MCCompLabel>*, nLayers>* mcLabels = nullptr,
65 float yPlaneMLOT = 0.f);
66
67 void getPrimaryVerticesFromMC(TTree* mcHeaderTree, int nRofs, Long64_t nEvents, int inROFpileup);
68
70
71 void deriveAndInitTiming(const std::array<gsl::span<const o2::trk::ROFRecord>, nLayers>& layerROFs);
72
73 const o2::InteractionRecord& getTFAnchorIR() const noexcept { return mTFAnchorIR; }
74
75 protected:
76 void initTimingTables(const std::array<o2::its::LayerTiming, nLayers>& timings);
78
81};
82
83template <int nLayers, class Base>
85{
86 static_cast<o2::its::TimeFrame<nLayers>*>(this)->updateROFVertexLookupTable();
87}
88
89template <int nLayers, class Base>
90void TimeFrameMixin<nLayers, Base>::initTimingTables(const std::array<o2::its::LayerTiming, nLayers>& timings)
91{
92 if (mTimingTablesInitialised) {
93 return;
94 }
95 typename o2::its::TimeFrame<nLayers>::ROFOverlapTableN rofOverlapTable;
96 typename o2::its::TimeFrame<nLayers>::ROFVertexLookupTableN rofVertexLookupTable;
98 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
99 rofOverlapTable.defineLayer(iLayer, timings[iLayer]);
100 rofVertexLookupTable.defineLayer(iLayer, timings[iLayer]);
101 rofMaskTable.defineLayer(iLayer, timings[iLayer]);
102 }
103 rofOverlapTable.init();
104 rofVertexLookupTable.init();
105 rofMaskTable.init();
106 rofMaskTable.resetMask(1u);
107 this->setROFOverlapTable(std::move(rofOverlapTable));
108 this->setROFVertexLookupTable(std::move(rofVertexLookupTable));
109 this->setMultiplicityCutMask(std::move(rofMaskTable));
110 this->useMultiplictyMask();
111 mTimingTablesInitialised = true;
112
113 const auto maskView = this->getROFMaskView();
114 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
115 LOGP(info, "TRK timing initialised: layer {}: {}", iLayer, timings[iLayer].asString());
116 LOGP(info, "TRK ROF mask: {}", maskView.asString(iLayer));
117 }
118}
119
120template <int nLayers, class Base>
121void TimeFrameMixin<nLayers, Base>::deriveAndInitTiming(const std::array<gsl::span<const o2::trk::ROFRecord>, nLayers>& layerROFs)
122{
123 if (mTimingTablesInitialised) {
124 return;
125 }
126
127 o2::InteractionRecord anchor{0, 0};
128 bool haveAnchor = false;
129 for (const auto& span : layerROFs) {
130 if (span.empty()) {
131 continue;
132 }
133 const auto& first = span.front().getBCData();
134 if (!haveAnchor || first.toLong() < anchor.toLong()) {
135 anchor = first;
136 haveAnchor = true;
137 }
138 }
139 mTFAnchorIR = anchor;
140 const int64_t anchorBC = anchor.toLong();
141
142 std::array<o2::its::LayerTiming, nLayers> timings{};
143 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
144 const auto& span = layerROFs[iLayer];
145 auto& t = timings[iLayer];
146 t.mNROFsTF = static_cast<o2::its::LayerTiming::BCType>(span.size());
147
148 if (span.size() >= 2) {
149 const int64_t delta = span[1].getBCData().toLong() - span[0].getBCData().toLong();
150 if (delta > 0) {
151 t.mROFLength = static_cast<o2::its::LayerTiming::BCType>(delta);
152 } else {
153 LOGP(warning, "TRK layer {}: non-positive BC delta between rofs[0] and rofs[1] ({}); falling back to mROFLength=1", iLayer, delta);
154 t.mROFLength = 1;
155 }
156 } else {
157 if (span.size() == 1) {
158 LOGP(warning, "TRK layer {}: only one input ROF — cannot derive mROFLength; falling back to mROFLength=1", iLayer);
159 }
160 t.mROFLength = 1;
161 }
162
163 if (!span.empty()) {
164 const int64_t bias = span.front().getBCData().toLong() - anchorBC;
165 t.mROFBias = static_cast<o2::its::LayerTiming::BCType>(bias);
166 }
167 t.mROFDelay = 0;
168 t.mROFAddTimeErr = 0;
169 }
170
171 initTimingTables(timings);
172}
173
174template <int nLayers, class Base>
175int TimeFrameMixin<nLayers, Base>::loadROFsFromHitTree(TTree* hitsTree, GeometryTGeo* gman, const nlohmann::json& config)
176{
177 constexpr std::array<int, 2> startLayer{0, 3};
178 const Long64_t nEvents = hitsTree->GetEntries();
179 this->setIsStaggered(true);
180
181 gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L) | o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G));
182
183 std::vector<o2::trk::Hit>* trkHit = nullptr;
184 hitsTree->SetBranchAddress("TRKHit", &trkHit);
185
186 const int inROFpileup{config.contains("inROFpileup") ? config["inROFpileup"].get<int>() : 1};
187
188 const int nRofs = (nEvents + inROFpileup - 1) / inROFpileup;
189 std::array<o2::its::LayerTiming, nLayers> timings{};
190 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
191 timings[iLayer].mNROFsTF = static_cast<o2::its::LayerTiming::BCType>(nRofs);
192 timings[iLayer].mROFLength = 1;
193 }
194 this->initTimingTables(timings);
195 const auto& timing = this->getROFOverlapTableView().getLayer(0);
196 if (timing.mNROFsTF != static_cast<o2::its::LayerTiming::BCType>(nRofs)) {
197 LOGP(fatal, "TRK: inconsistent number of ROFs across TFs: timing has {}, hit-tree path produced {}", timing.mNROFsTF, nRofs);
198 }
199
200 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
201 this->mMinR[iLayer] = std::numeric_limits<float>::max();
202 this->mMaxR[iLayer] = std::numeric_limits<float>::lowest();
203 this->mROFramesClusters[iLayer].clear();
204 this->mROFramesClusters[iLayer].resize(nRofs + 1, 0);
205 this->mUnsortedClusters[iLayer].clear();
206 this->mTrackingFrameInfo[iLayer].clear();
207 this->mClusterExternalIndices[iLayer].clear();
208 this->mClusterSize[iLayer].clear();
209 }
210
211 std::array<int, nLayers> clusterCountPerLayer{};
212 for (Long64_t iEvent = 0; iEvent < nEvents; ++iEvent) {
213 hitsTree->GetEntry(iEvent);
214 for (const auto& hit : *trkHit) {
215 if (gman->getDisk(hit.GetDetectorID()) != -1) {
216 continue;
217 }
218 int subDetID = gman->getSubDetID(hit.GetDetectorID());
219 const int layer = startLayer[subDetID] + gman->getLayer(hit.GetDetectorID());
220 if (layer >= nLayers) {
221 continue;
222 }
223 ++clusterCountPerLayer[layer];
224 }
225 }
226
227 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
228 this->mUnsortedClusters[iLayer].reserve(clusterCountPerLayer[iLayer]);
229 this->mTrackingFrameInfo[iLayer].reserve(clusterCountPerLayer[iLayer]);
230 this->mClusterExternalIndices[iLayer].reserve(clusterCountPerLayer[iLayer]);
231 this->mClusterSize[iLayer].reserve(clusterCountPerLayer[iLayer]);
232 }
233
234 std::array<float, 11> resolution{0.001, 0.001, 0.001, 0.001, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004};
235 if (config["geometry"]["pitch"].size() == nLayers) {
236 for (int iLayer{0}; iLayer < config["geometry"]["pitch"].size(); ++iLayer) {
237 LOGP(info, "Setting resolution for layer {} from config", iLayer);
238 LOGP(info, "Layer {} pitch {} cm", iLayer, config["geometry"]["pitch"][iLayer].get<float>());
239 resolution[iLayer] = config["geometry"]["pitch"][iLayer].get<float>() / std::sqrt(12.f);
240 }
241 }
242 LOGP(info, "Number of active parts in VD: {}", gman->getNumberOfActivePartsVD());
243
244 std::array<int, nLayers> hitCounterPerLayer{};
245 std::array<dataformats::MCTruthContainer<MCCompLabel>*, nLayers> labels{};
246 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
248 this->mClusterLabels[iLayer] = labels[iLayer];
249 }
250
251 int iRof{0};
252 for (Long64_t iEvent = 0; iEvent < nEvents; ++iEvent) {
253 hitsTree->GetEntry(iEvent);
254
255 for (auto& hit : *trkHit) {
256 if (gman->getDisk(hit.GetDetectorID()) != -1) {
257 continue;
258 }
259 int subDetID = gman->getSubDetID(hit.GetDetectorID());
260 const int layer = startLayer[subDetID] + gman->getLayer(hit.GetDetectorID());
261
262 float alpha{0.f};
265 float r{0.f};
266 if (layer >= nLayers) {
267 continue;
268 }
269 if (layer >= 3) {
270 int chipID = hit.GetDetectorID();
271 alpha = gman->getSensorRefAlphaMLOT(chipID);
272 const o2::math_utils::Transform3D& l2g = gman->getMatrixL2G(chipID);
273 auto locXYZ = l2g ^ (hit.GetPos());
274 locXYZ.SetX(locXYZ.X() + gRandom->Gaus(0.0, resolution[layer]));
275 locXYZ.SetZ(locXYZ.Z() + gRandom->Gaus(0.0, resolution[layer]));
276 gloXYZ = gman->getMatrixL2G(chipID) * locXYZ;
277 trkXYZ = gman->getMatrixT2L(chipID - gman->getNumberOfActivePartsVD()) ^ locXYZ;
278 r = std::hypot(gloXYZ.X(), gloXYZ.Y());
279 } else {
280 const auto& hitPos = hit.GetPos();
281 r = std::hypot(hitPos.X(), hitPos.Y());
282 alpha = std::atan2(hitPos.Y(), hitPos.X()) + gRandom->Gaus(0.0, resolution[layer] / r);
283 o2::math_utils::bringTo02Pi(alpha);
284 gloXYZ.SetX(r * std::cos(alpha));
285 gloXYZ.SetY(r * std::sin(alpha));
286 gloXYZ.SetZ(hitPos.Z() + gRandom->Gaus(0.0, resolution[layer]));
287 trkXYZ.SetX(r);
288 trkXYZ.SetY(0.f);
289 trkXYZ.SetZ(gloXYZ.Z());
290 }
291 this->mMinR[layer] = std::min(this->mMinR[layer], r);
292 this->mMaxR[layer] = std::max(this->mMaxR[layer], r);
293 this->addTrackingFrameInfoToLayer(layer, gloXYZ.x(), gloXYZ.y(), gloXYZ.z(), trkXYZ.x(), alpha,
294 std::array<float, 2>{trkXYZ.y(), trkXYZ.z()},
295 std::array<float, 3>{resolution[layer] * resolution[layer], 0., resolution[layer] * resolution[layer]});
296 this->addClusterToLayer(layer, gloXYZ.x(), gloXYZ.y(), gloXYZ.z(), this->mUnsortedClusters[layer].size());
297 const int layerHitCounter = hitCounterPerLayer[layer]++;
298 this->addClusterExternalIndexToLayer(layer, layerHitCounter);
299 this->mClusterSize[layer].push_back(1);
300 MCCompLabel label{hit.GetTrackID(), static_cast<int>(iEvent), 0};
301 labels[layer]->addElement(layerHitCounter, label);
302 }
303 trkHit->clear();
304
305 if ((iEvent + 1) % inROFpileup == 0 || iEvent == nEvents - 1) {
306 iRof++;
307 for (unsigned int iLayer{0}; iLayer < this->mUnsortedClusters.size(); ++iLayer) {
308 this->mROFramesClusters[iLayer][iRof] = this->mUnsortedClusters[iLayer].size();
309 }
310 }
311 }
312 return nRofs;
313}
314
315template <int nLayers, class Base>
316int TimeFrameMixin<nLayers, Base>::loadROFrameData(const std::array<gsl::span<const o2::trk::ROFRecord>, nLayers>& layerROFs,
317 const std::array<gsl::span<const o2::trk::Cluster>, nLayers>& layerClusters,
318 const std::array<gsl::span<const unsigned char>, nLayers>& layerPatterns,
319 const std::array<const dataformats::MCTruthContainer<MCCompLabel>*, nLayers>* mcLabels,
320 float yPlaneMLOT)
321{
322 constexpr std::array<int, 2> startLayer{0, 3};
323 this->setIsStaggered(true);
325 geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L) | o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G));
326
327 if (!mTimingTablesInitialised) {
328 LOGP(fatal, "TRK::loadROFrameData: timing tables not initialised — call deriveAndInitTiming() first");
329 }
330 int nRofs{0};
331 for (const auto& rofs : layerROFs) {
332 nRofs = std::max(nRofs, static_cast<int>(rofs.size()));
333 }
334
335 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
336 const auto& timing = this->getROFOverlapTableView().getLayer(iLayer);
337 if (timing.mNROFsTF != static_cast<o2::its::LayerTiming::BCType>(layerROFs[iLayer].size())) {
338 LOGP(fatal, "TRK: inconsistent number of ROFs on layer {}: timing has {}, cluster path received {}", iLayer, timing.mNROFsTF, layerROFs[iLayer].size());
339 }
340 this->mMinR[iLayer] = std::numeric_limits<float>::max();
341 this->mMaxR[iLayer] = std::numeric_limits<float>::lowest();
342 this->mROFramesClusters[iLayer].clear();
343 this->mROFramesClusters[iLayer].resize(layerROFs[iLayer].size() + 1, 0);
344 this->mUnsortedClusters[iLayer].clear();
345 this->mTrackingFrameInfo[iLayer].clear();
346 this->mClusterExternalIndices[iLayer].clear();
347 this->mClusterSize[iLayer].clear();
348 this->mUnsortedClusters[iLayer].reserve(layerClusters[iLayer].size());
349 this->mTrackingFrameInfo[iLayer].reserve(layerClusters[iLayer].size());
350 this->mClusterExternalIndices[iLayer].reserve(layerClusters[iLayer].size());
351 this->mClusterSize[iLayer].reserve(layerClusters[iLayer].size());
352 }
353
354 std::array<std::vector<size_t>, nLayers> patternOffsetsPerLayer;
355 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
356 auto& offsets = patternOffsetsPerLayer[iLayer];
357 offsets.resize(layerClusters[iLayer].size(), std::numeric_limits<size_t>::max());
358 size_t pattPos = 0;
359 bool validPatterns = true;
360 for (size_t clusterId{0}; clusterId < layerClusters[iLayer].size(); ++clusterId) {
361 if (pattPos + 2 > layerPatterns[iLayer].size()) {
362 validPatterns = false;
363 break;
364 }
365 offsets[clusterId] = pattPos;
366 const uint8_t rowSpan = layerPatterns[iLayer][pattPos];
367 const uint8_t colSpan = layerPatterns[iLayer][pattPos + 1];
368 const size_t nBytes = (size_t(rowSpan) * colSpan + 7) / 8;
369 if (pattPos + 2 + nBytes > layerPatterns[iLayer].size()) {
370 validPatterns = false;
371 break;
372 }
373 pattPos += 2 + nBytes;
374 }
375 if (!validPatterns || pattPos != layerPatterns[iLayer].size()) {
376 LOGP(fatal, "Malformed TRK pattern stream for layer {}: {} bytes for {} clusters",
377 iLayer, layerPatterns[iLayer].size(), layerClusters[iLayer].size());
378 }
379 }
380
381 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
382 for (size_t iRof{0}; iRof < layerROFs[iLayer].size(); ++iRof) {
383 const auto& rof = layerROFs[iLayer][iRof];
384 const int first = rof.getFirstEntry();
385 const int last = first + rof.getNEntries();
386
387 for (int clusterId{first}; clusterId < last; ++clusterId) {
388 if (clusterId < 0 || clusterId >= static_cast<int>(layerClusters[iLayer].size())) {
389 LOGP(warning, "Skipping out-of-range TRK cluster {} on layer {}", clusterId, iLayer);
390 continue;
391 }
392
393 const auto& c = layerClusters[iLayer][clusterId];
394 if (c.subDetID < 0 || c.subDetID > 1 || c.disk != -1) {
395 continue;
396 }
397
398 const int clusterLayer = startLayer[c.subDetID] + c.layer;
399 if (clusterLayer != iLayer) {
400 LOGP(error, "Skipping cluster from layer {} found in TRK layer stream {}", clusterLayer, iLayer);
401 continue;
402 }
403
404 const auto pattOffset = patternOffsetsPerLayer[iLayer][clusterId];
405 const uint8_t* pattForCluster = layerPatterns[iLayer].data() + pattOffset;
406 auto locXYZ = Clusterer::getClusterLocalCoordinates(c, pattForCluster, yPlaneMLOT);
407
408 const auto gloXYZ = geom->getMatrixL2G(c.chipID) * locXYZ;
409
410 float alpha{0.f};
412 if (c.subDetID == 1) {
413 alpha = geom->getSensorRefAlphaMLOT(c.chipID);
414 trkXYZ = geom->getMatrixT2L(c.chipID - geom->getNumberOfActivePartsVD()) ^ locXYZ;
415 } else {
416 const float r = std::hypot(gloXYZ.X(), gloXYZ.Y());
417 alpha = std::atan2(gloXYZ.Y(), gloXYZ.X());
418 o2::math_utils::bringTo02Pi(alpha);
419 trkXYZ.SetX(r);
420 trkXYZ.SetY(0.f);
421 trkXYZ.SetZ(gloXYZ.Z());
422 }
423
424 const float r = std::hypot(gloXYZ.X(), gloXYZ.Y());
425 this->mMinR[iLayer] = std::min(this->mMinR[iLayer], r);
426 this->mMaxR[iLayer] = std::max(this->mMaxR[iLayer], r);
427
428 const float sigmaY2 = (c.subDetID == 0)
431 const float sigmaZ2 = (c.subDetID == 0)
434
435 this->addTrackingFrameInfoToLayer(iLayer, gloXYZ.x(), gloXYZ.y(), gloXYZ.z(), trkXYZ.x(), alpha,
436 std::array<float, 2>{trkXYZ.y(), trkXYZ.z()},
437 std::array<float, 3>{sigmaY2, 0.f, sigmaZ2});
438 this->addClusterToLayer(iLayer, gloXYZ.x(), gloXYZ.y(), gloXYZ.z(), this->mUnsortedClusters[iLayer].size());
439 this->addClusterExternalIndexToLayer(iLayer, clusterId);
440 this->mClusterSize[iLayer].push_back(std::clamp(static_cast<unsigned int>(c.size), 0u, 255u));
441 }
442
443 this->mROFramesClusters[iLayer][iRof + 1] = this->mUnsortedClusters[iLayer].size();
444 }
445 }
446
447 for (auto i = 0; i < this->mNTrackletsPerCluster.size(); ++i) {
448 this->mNTrackletsPerCluster[i].resize(this->mUnsortedClusters[1].size());
449 this->mNTrackletsPerClusterSum[i].resize(this->mUnsortedClusters[1].size() + 1);
450 }
451
452 if (mcLabels != nullptr) {
453 for (int iLayer{0}; iLayer < nLayers; ++iLayer) {
454 this->mClusterLabels[iLayer] = (*mcLabels)[iLayer];
455 }
456 }
457
458 return nRofs;
459}
460
461template <int nLayers, class Base>
462void TimeFrameMixin<nLayers, Base>::getPrimaryVerticesFromMC(TTree* mcHeaderTree, int nRofs, Long64_t nEvents, int inROFpileup)
463{
464 auto mcheader = new o2::dataformats::MCEventHeader;
465 mcHeaderTree->SetBranchAddress("MCEventHeader.", &mcheader);
466
467 this->mPrimaryVertices.clear();
468 this->mPrimaryVerticesLabels.clear();
469
470 const auto& clockLayer = this->getROFOverlapTableView().getClockLayer();
471 const auto rofLength = clockLayer.mROFLength;
472
473 int iRof{0};
474 for (Long64_t iEvent = 0; iEvent < nEvents; ++iEvent) {
475 mcHeaderTree->GetEntry(iEvent);
477 vertex.setTimeStamp(o2::its::TimeEstBC{
478 clockLayer.getROFStartInBC(iRof),
479 static_cast<o2::its::TimeStampErrorType>(rofLength)});
480 vertex.setXYZ(mcheader->GetX(), mcheader->GetY(), mcheader->GetZ());
481 vertex.setNContributors(30);
482 vertex.setChi2(0.f);
483 LOGP(debug, "ROF {}: Added primary vertex at ({}, {}, {})", iRof, mcheader->GetX(), mcheader->GetY(), mcheader->GetZ());
484 this->addPrimaryVertex(vertex);
485 this->addPrimaryVertexLabel({o2::MCCompLabel{o2::MCCompLabel::maxTrackID(), static_cast<int>(iEvent), 0, false}, 1.f});
486 if ((iEvent + 1) % inROFpileup == 0 || iEvent == nEvents - 1) {
487 iRof++;
488 }
489 }
490 updateHostROFVertexLookupTable();
491}
492
493template <int nLayers, class Base>
495{
496 LOGP(info, "TRK: using truth seeds as vertices from DigitizationContext");
497 this->mPrimaryVertices.clear();
498 this->mPrimaryVerticesLabels.clear();
499
500 const auto dc = o2::steer::DigitizationContext::loadFromFile("collisioncontext.root");
501 const auto irs = dc->getEventRecords();
503
504 const int64_t anchorBC = mTFAnchorIR.toLong();
505 const auto& clockLayer = this->getROFOverlapTableView().getClockLayer();
506 const auto rofLength = clockLayer.mROFLength;
507
508 using Vertex = o2::its::Vertex;
509 struct VertEntry {
510 int64_t bc;
512 int event;
513 };
514 std::vector<VertEntry> entries;
515
516 const int iSrc = 0;
517 auto eveId2colId = dc->getCollisionIndicesForSource(iSrc);
518 for (int iEve{0}; iEve < mcReader.getNEvents(iSrc); ++iEve) {
519 const auto& ir = irs[eveId2colId[iEve]];
520 if (!ir.isDummy()) {
521 const auto& eve = mcReader.getMCEventHeader(iSrc, iEve);
522 const int64_t evBC = ir.toLong() - anchorBC;
523 if (evBC >= 0) {
524 Vertex vert;
525 vert.setTimeStamp(o2::its::TimeEstBC{
526 static_cast<o2::its::TimeStampType>(evBC),
527 static_cast<o2::its::TimeStampErrorType>(rofLength)});
528 vert.setNContributors(std::max(1L, std::ranges::count_if(
529 mcReader.getTracks(iSrc, iEve),
530 [](const auto& trk) {
531 return trk.isPrimary() && trk.GetPt() > 0.05 && std::abs(trk.GetEta()) < 1.1;
532 })));
533 vert.setXYZ((float)eve.GetX(), (float)eve.GetY(), (float)eve.GetZ());
534 vert.setChi2(1);
535 constexpr float cov = 50e-9f;
536 vert.setCov(cov, cov, cov, cov, cov, cov);
537 entries.push_back({evBC, vert, iEve});
538 }
539 }
540 mcReader.releaseTracksForSourceAndEvent(iSrc, iEve);
541 }
542
543 // Sort by BC so the lookup table binary search works correctly
544 std::ranges::sort(entries, {}, &VertEntry::bc);
545
546 for (const auto& e : entries) {
547 this->addPrimaryVertex(e.vertex);
548 o2::MCCompLabel lbl(o2::MCCompLabel::maxTrackID(), e.event, iSrc, false);
549 this->addPrimaryVertexLabel({lbl, 1.f});
550 }
551 updateHostROFVertexLookupTable();
552 LOGP(info, "TRK truth seeding: added {} vertices", entries.size());
553}
554
555} // namespace o2::trk
556
557#endif // ALICEO2_ALICE3GLOBALRECONSTRUCTION_TIMEFRAMEMIXIN_H
std::vector< std::string > labels
std::string asString(TDataMember const &dm, char *pointer)
Definition of the TRK Hit class.
std::ostringstream debug
uint64_t vertex
Definition RawEventData.h:9
uint64_t bc
Definition RawEventData.h:5
int32_t i
Definition of a container to keep Monte Carlo truth external to simulation objects.
uint32_t c
Definition RawData.h:2
Definition of the SegmentationChipclass.
Definition of the TRK cluster finder.
static constexpr int maxTrackID()
A container to hold and manage MC truth information/labels.
const Mat3D & getMatrixT2L(int sensID) const
const Mat3D & getMatrixL2G(int sensID) const
static DigitizationContext * loadFromFile(std::string_view filename="")
size_t getNEvents(int source) const
Get number of events.
o2::dataformats::MCEventHeader const & getMCEventHeader(int source, int event) const
retrieves the MCEventHeader for a given eventID and sourceID
void releaseTracksForSourceAndEvent(int source, int event)
API to ask releasing tracks (freeing memory) for source + event.
std::vector< MCTrack > const & getTracks(int source, int event) const
variant returning all tracks for source and event at once
static o2::math_utils::Point3D< float > getClusterLocalCoordinates(const Cluster &cluster, const uint8_t *patt, float yPlaneMLOT=0.f) noexcept
Definition Clusterer.cxx:26
int getSubDetID(int index) const
float getSensorRefAlphaMLOT(int chipId) const
int getLayer(int index) const
local layer index within the sub-detector (0-based per VD/MLOT)
void fillMatrixCache(int mask)
int getNumberOfActivePartsVD() const
int getDisk(int index) const
static GeometryTGeo * Instance()
static constexpr float PitchColVD
static constexpr float PitchColMLOT
static constexpr float PitchRowMLOT
static constexpr float PitchRowVD
int loadROFsFromHitTree(TTree *hitsTree, GeometryTGeo *gman, const nlohmann::json &config)
const o2::InteractionRecord & getTFAnchorIR() const noexcept
int loadROFrameData(const std::array< gsl::span< const o2::trk::ROFRecord >, nLayers > &layerROFs, const std::array< gsl::span< const o2::trk::Cluster >, nLayers > &layerClusters, const std::array< gsl::span< const unsigned char >, nLayers > &layerPatterns, const std::array< const dataformats::MCTruthContainer< MCCompLabel > *, nLayers > *mcLabels=nullptr, float yPlaneMLOT=0.f)
void initTimingTables(const std::array< o2::its::LayerTiming, nLayers > &timings)
void getPrimaryVerticesFromMC(TTree *mcHeaderTree, int nRofs, Long64_t nEvents, int inROFpileup)
~TimeFrameMixin() override=default
void deriveAndInitTiming(const std::array< gsl::span< const o2::trk::ROFRecord >, nLayers > &layerROFs)
o2::InteractionRecord mTFAnchorIR
struct _cl_event * event
Definition glcorearb.h:2982
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLsizei const GLuint const GLintptr * offsets
Definition glcorearb.h:2595
GLint first
Definition glcorearb.h:399
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLboolean r
Definition glcorearb.h:1233
uint32_t TimeStampType
Definition TimeEstBC.h:26
o2::dataformats::Vertex< o2::its::TimeEstBC > Vertex
Definition Vertex.h:26
uint16_t TimeStampErrorType
Definition TimeEstBC.h:27
ROFVertexLookupTable< NLayers > ROFVertexLookupTableN
Definition TimeFrame.h:68
ROFOverlapTable< NLayers > ROFOverlapTableN
Definition TimeFrame.h:67
ROFMaskTable< NLayers > ROFMaskTableN
Definition TimeFrame.h:69
static constexpr int L2G
Definition Cartesian.h:54
static constexpr int T2L
Definition Cartesian.h:55
const int nEvents
Definition test_Fifo.cxx:27
o2::InteractionRecord ir(0, 0)