Project
Loading...
Searching...
No Matches
TimeFrame.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.
15
17#include "TRKSimulation/Hit.h"
19#include "Framework/Logger.h"
21#include <TTree.h>
22#include <TRandom3.h>
23#include <vector>
24#include <array>
25
27
28namespace o2::trk
29{
30
31template <int NLayers>
32int TimeFrame<NLayers>::loadROFsFromHitTree(TTree* hitsTree, GeometryTGeo* gman, const nlohmann::json& config)
33{
34 constexpr std::array<int, 2> startLayer{0, 3};
35 const Long64_t nEvents = hitsTree->GetEntries();
36
37 gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L) | o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G));
38
39 std::vector<o2::trk::Hit>* trkHit = nullptr;
40 hitsTree->SetBranchAddress("TRKHit", &trkHit);
41
42 const int inROFpileup{config.contains("inROFpileup") ? config["inROFpileup"].get<int>() : 1};
43
44 // Calculate number of ROFs
45 const int nRofs = (nEvents + inROFpileup - 1) / inROFpileup;
46
47 // Set up ROF timing for all layers (no staggering in TRK simulation, all layers read out together)
48 constexpr uint32_t rofLength = 198; // ROF length in BC
50 for (int iLayer = 0; iLayer < NLayers; ++iLayer) {
51 overlapTable.defineLayer(iLayer, nRofs, rofLength, 0, 0, 0);
52 }
53 overlapTable.init();
54 this->setROFOverlapTable(overlapTable);
55
56 // Set up the vertex lookup table timing (pre-allocate, vertices will be filled later)
58 for (int iLayer = 0; iLayer < NLayers; ++iLayer) {
59 vtxLookupTable.defineLayer(iLayer, nRofs, rofLength, 0, 0, 0);
60 }
61 vtxLookupTable.init(); // pre-allocate without vertices
62 this->setROFVertexLookupTable(vtxLookupTable);
63
64 // Reset and prepare ROF data structures
65 for (int iLayer{0}; iLayer < NLayers; ++iLayer) {
66 this->mMinR[iLayer] = std::numeric_limits<float>::max();
67 this->mMaxR[iLayer] = std::numeric_limits<float>::lowest();
68 this->mROFramesClusters[iLayer].clear();
69 this->mROFramesClusters[iLayer].resize(nRofs + 1, 0);
70 this->mUnsortedClusters[iLayer].clear();
71 this->mTrackingFrameInfo[iLayer].clear();
72 this->mClusterExternalIndices[iLayer].clear();
73 }
74
75 // Pre-count hits to reserve memory efficiently
76 std::array<int, NLayers> clusterCountPerLayer{};
77 for (Long64_t iEvent = 0; iEvent < nEvents; ++iEvent) {
78 hitsTree->GetEntry(iEvent);
79 for (const auto& hit : *trkHit) {
80 if (gman->getDisk(hit.GetDetectorID()) != -1) {
81 continue; // skip non-barrel hits
82 }
83 int subDetID = gman->getSubDetID(hit.GetDetectorID());
84 const int layer = startLayer[subDetID] + gman->getLayer(hit.GetDetectorID());
85 if (layer >= NLayers) {
86 continue;
87 }
88 ++clusterCountPerLayer[layer];
89 }
90 }
91
92 // Reserve memory for all layers (mClusterSize is now per-layer)
93 for (int iLayer{0}; iLayer < NLayers; ++iLayer) {
94 this->mUnsortedClusters[iLayer].reserve(clusterCountPerLayer[iLayer]);
95 this->mTrackingFrameInfo[iLayer].reserve(clusterCountPerLayer[iLayer]);
96 this->mClusterExternalIndices[iLayer].reserve(clusterCountPerLayer[iLayer]);
97 clearResizeBoundedVector(this->mClusterSize[iLayer], clusterCountPerLayer[iLayer], this->mMemoryPool.get());
98 }
99
100 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};
101 if (config["geometry"]["pitch"].size() == static_cast<size_t>(NLayers)) {
102 for (size_t iLayer{0}; iLayer < config["geometry"]["pitch"].size(); ++iLayer) {
103 LOGP(info, "Setting resolution for layer {} from config", iLayer);
104 LOGP(info, "Layer {} pitch {} cm", iLayer, config["geometry"]["pitch"][iLayer].get<float>());
105 resolution[iLayer] = config["geometry"]["pitch"][iLayer].get<float>() / std::sqrt(12.f);
106 }
107 }
108 LOGP(info, "Number of active parts in VD: {}", gman->getNumberOfActivePartsVD());
109
110 // One shared MC label container for all layers
112
113 int hitCounter{0};
114 int iRof{0}; // Current ROF index
115 for (Long64_t iEvent = 0; iEvent < nEvents; ++iEvent) {
116 hitsTree->GetEntry(iEvent);
117
118 for (auto& hit : *trkHit) {
119 if (gman->getDisk(hit.GetDetectorID()) != -1) {
120 continue; // skip non-barrel hits for this test
121 }
122 int subDetID = gman->getSubDetID(hit.GetDetectorID());
123 const int layer = startLayer[subDetID] + gman->getLayer(hit.GetDetectorID());
124
125 float alpha{0.f};
128 float r{0.f};
129 if (layer >= NLayers) {
130 continue;
131 }
132 if (layer >= 3) {
133 int chipID = hit.GetDetectorID();
134 alpha = gman->getSensorRefAlphaMLOT(chipID);
135 const o2::math_utils::Transform3D& l2g = gman->getMatrixL2G(chipID);
136 auto locXYZ = l2g ^ (hit.GetPos());
137 locXYZ.SetX(locXYZ.X() + gRandom->Gaus(0.0, resolution[layer]));
138 locXYZ.SetZ(locXYZ.Z() + gRandom->Gaus(0.0, resolution[layer]));
139 gloXYZ = gman->getMatrixL2G(chipID) * locXYZ;
140 trkXYZ = gman->getMatrixT2L(chipID - gman->getNumberOfActivePartsVD()) ^ locXYZ;
141 r = std::hypot(gloXYZ.X(), gloXYZ.Y());
142 } else {
143 const auto& hitPos = hit.GetPos();
144 r = std::hypot(hitPos.X(), hitPos.Y());
145 alpha = std::atan2(hitPos.Y(), hitPos.X()) + gRandom->Gaus(0.0, resolution[layer] / r);
146 o2::math_utils::bringTo02Pi(alpha);
147 gloXYZ.SetX(r * std::cos(alpha));
148 gloXYZ.SetY(r * std::sin(alpha));
149 gloXYZ.SetZ(hitPos.Z() + gRandom->Gaus(0.0, resolution[layer]));
150 trkXYZ.SetX(r);
151 trkXYZ.SetY(0.f);
152 trkXYZ.SetZ(gloXYZ.Z());
153 }
154 this->mMinR[layer] = std::min(this->mMinR[layer], r);
155 this->mMaxR[layer] = std::max(this->mMaxR[layer], r);
156 this->addTrackingFrameInfoToLayer(layer, gloXYZ.x(), gloXYZ.y(), gloXYZ.z(), trkXYZ.x(), alpha,
157 std::array<float, 2>{trkXYZ.y(), trkXYZ.z()},
158 std::array<float, 3>{resolution[layer] * resolution[layer], 0., resolution[layer] * resolution[layer]});
160 const int clusterIdxInLayer = this->mUnsortedClusters[layer].size();
161 this->addClusterToLayer(layer, gloXYZ.x(), gloXYZ.y(), gloXYZ.z(), clusterIdxInLayer);
162 this->addClusterExternalIndexToLayer(layer, hitCounter);
163 MCCompLabel label{hit.GetTrackID(), static_cast<int>(iEvent), 0};
164 labels->addElement(hitCounter, label);
165 this->mClusterSize[layer][clusterIdxInLayer] = 1;
166 hitCounter++;
167 }
168 trkHit->clear();
169
170 // Update ROF structure when we complete an ROF or reach the last event
171 if ((iEvent + 1) % inROFpileup == 0 || iEvent == nEvents - 1) {
172 iRof++;
173 for (unsigned int iLayer{0}; iLayer < this->mUnsortedClusters.size(); ++iLayer) {
174 this->mROFramesClusters[iLayer][iRof] = this->mUnsortedClusters[iLayer].size(); // effectively calculating an exclusive sum
175 }
176 }
177 }
178
179 // Set the shared labels container for all layers
180 for (int iLayer = 0; iLayer < NLayers; ++iLayer) {
181 this->mClusterLabels[iLayer] = labels;
182 }
183
184 return nRofs;
185}
186
187template <int NLayers>
188void TimeFrame<NLayers>::getPrimaryVerticesFromMC(TTree* mcHeaderTree, int nRofs, Long64_t nEvents, int inROFpileup, uint32_t rofLength)
189{
190 auto mcheader = new o2::dataformats::MCEventHeader;
191 mcHeaderTree->SetBranchAddress("MCEventHeader.", &mcheader);
192
193 this->mPrimaryVertices.clear();
194
195 int iRof{0};
196 for (Long64_t iEvent = 0; iEvent < nEvents; ++iEvent) {
197 mcHeaderTree->GetEntry(iEvent);
199 vertex.setXYZ(mcheader->GetX(), mcheader->GetY(), mcheader->GetZ());
200 vertex.setNContributors(30);
201 vertex.setChi2(0.f);
202
203 // Set proper BC timestamp for vertex-ROF compatibility
204 // The vertex timestamp is set to the center of its ROF with half-ROF as error
205 const uint32_t rofCenter = static_cast<uint32_t>(rofLength * iRof + rofLength / 2);
206 const uint16_t rofHalf = static_cast<uint16_t>(rofLength / 2);
207 vertex.setTimeStamp({rofCenter, rofHalf});
208
209 LOGP(debug, "ROF {}: Added primary vertex at ({}, {}, {}) with BC timestamp [{}, +/-{}]",
210 iRof, mcheader->GetX(), mcheader->GetY(), mcheader->GetZ(), rofCenter, rofHalf);
211 this->addPrimaryVertex(vertex);
212 if ((iEvent + 1) % inROFpileup == 0 || iEvent == nEvents - 1) {
213 iRof++;
214 }
215 }
216 this->mMultiplicityCutMask.resetMask(1u);
217
218 // Update the vertex lookup table with the newly added vertices
219 this->updateROFVertexLookupTable();
220}
221
222// Explicit template instantiation for TRK with 11 layers
223template class TimeFrame<11>;
224
225} // namespace o2::trk
std::vector< std::string > labels
TRK TimeFrame class derived from ITS TimeFrame.
Definition of the TRK Hit class.
std::ostringstream debug
uint64_t vertex
Definition RawEventData.h:9
A container to hold and manage MC truth information/labels.
const Mat3D & getMatrixT2L(int sensID) const
const Mat3D & getMatrixL2G(int sensID) const
int getSubDetID(int index) const
float getSensorRefAlphaMLOT(int chipId) const
int getLayer(int index) const
void fillMatrixCache(int mask)
int getNumberOfActivePartsVD() const
int getDisk(int index) const
void getPrimaryVerticesFromMC(TTree *mcHeaderTree, int nRofs, Long64_t nEvents, int inROFpileup, uint32_t rofLength=198)
int loadROFsFromHitTree(TTree *hitsTree, GeometryTGeo *gman, const nlohmann::json &config)
Definition TimeFrame.cxx:32
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLboolean r
Definition glcorearb.h:1233
void clearResizeBoundedVector(bounded_vector< T > &vec, size_t sz, std::pmr::memory_resource *mr=nullptr, T def=T())
static constexpr int L2G
Definition Cartesian.h:54
static constexpr int T2L
Definition Cartesian.h:55
const int nEvents
Definition test_Fifo.cxx:27