Project
Loading...
Searching...
No Matches
TrackerSpecImpl.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.
11
12#ifndef O2_TRK_TRACKERSPECIMPL_H
13#define O2_TRK_TRACKERSPECIMPL_H
14
16
21#include "Field/MagFieldParam.h"
22#include "Field/MagneticField.h"
24#include "ITStracking/Tracker.h"
29#include "TRKSimulation/Hit.h"
30
31#include <TFile.h>
32#include <TGeoGlobalMagField.h>
33#include <TTree.h>
34
35#include <algorithm>
36#include <array>
37#include <chrono>
38#include <format>
39#include <numeric>
40#include <vector>
41
42namespace o2::trk
43{
44
45template <typename TimeFrameT, typename TrackerTraitsT>
46void TrackerDPL::runTracking(framework::ProcessingContext& pc, TimeFrameT& timeFrame, TrackerTraitsT& trackerTraits)
47{
48 o2::its::Tracker<11> itsTracker(&trackerTraits);
49 timeFrame.setMemoryPool(mMemoryPool);
50 trackerTraits.setMemoryPool(mMemoryPool);
51 trackerTraits.setNThreads(mTaskArena->max_concurrency(), mTaskArena);
52 trackerTraits.adoptTimeFrame(static_cast<o2::its::TimeFrame<11>*>(&timeFrame));
53 itsTracker.adoptTimeFrame(timeFrame);
54 trackerTraits.updateTrackingParameters(mTrackingParams);
55 timeFrame.initTrackerTopologies(mTrackingParams, 11);
56
57 int nRofs{0};
58 if (!mHitRecoConfig.empty()) {
59 TFile hitsFile(mHitRecoConfig["inputfiles"]["hits"].get<std::string>().c_str(), "READ");
60 TFile mcHeaderFile(mHitRecoConfig["inputfiles"]["mcHeader"].get<std::string>().c_str(), "READ");
61 TTree* hitsTree = hitsFile.Get<TTree>("o2sim");
62 std::vector<o2::trk::Hit>* trkHit = nullptr;
63 hitsTree->SetBranchAddress("TRKHit", &trkHit);
64
65 TTree* mcHeaderTree = mcHeaderFile.Get<TTree>("o2sim");
66 auto mcheader = new o2::dataformats::MCEventHeader;
67 mcHeaderTree->SetBranchAddress("MCEventHeader.", &mcheader);
68
69 o2::base::GeometryManager::loadGeometry(mHitRecoConfig["inputfiles"]["geometry"].get<std::string>().c_str(), false, true);
71
72 const Long64_t nEvents{hitsTree->GetEntries()};
73 LOGP(info, "Starting {} reconstruction from hits for {} events", trackerTraits.getName(), nEvents);
74
75 trackerTraits.setBz(mHitRecoConfig["geometry"]["bz"].get<float>());
76 auto field = new field::MagneticField("ALICE3Mag", "ALICE 3 Magnetic Field", mHitRecoConfig["geometry"]["bz"].get<float>() / 5.f, 0.0, o2::field::MagFieldParam::k5kGUniform);
77 TGeoGlobalMagField::Instance()->SetField(field);
78 TGeoGlobalMagField::Instance()->Lock();
79
80 nRofs = timeFrame.loadROFsFromHitTree(hitsTree, gman, mHitRecoConfig);
81 const int inROFpileup{mHitRecoConfig.contains("inROFpileup") ? mHitRecoConfig["inROFpileup"].get<int>() : 1};
82 timeFrame.getPrimaryVerticesFromMC(mcHeaderTree, nRofs, nEvents, inROFpileup);
83 } else if (!mClusterRecoConfig.empty()) {
84 LOGP(info, "Starting {} reconstruction from clusters", trackerTraits.getName());
85
86 o2::base::GeometryManager::loadGeometry(mClusterRecoConfig["inputfiles"]["geometry"].get<std::string>().c_str(), false, true);
88
89 trackerTraits.setBz(mClusterRecoConfig["geometry"]["bz"].get<float>());
90 auto field = new field::MagneticField("ALICE3Mag", "ALICE 3 Magnetic Field", mClusterRecoConfig["geometry"]["bz"].get<float>() / 5.f, 0.0, o2::field::MagFieldParam::k5kGUniform);
91 TGeoGlobalMagField::Instance()->SetField(field);
92 TGeoGlobalMagField::Instance()->Lock();
93
94 constexpr int nLayers{11};
95 std::array<gsl::span<const o2::trk::Cluster>, nLayers> layerClusters;
96 std::array<gsl::span<const unsigned char>, nLayers> layerPatterns;
97 std::array<gsl::span<const o2::trk::ROFRecord>, nLayers> layerROFs;
98 std::array<const dataformats::MCTruthContainer<MCCompLabel>*, nLayers> layerLabels{};
99
100 size_t nInputRofs{0};
101 for (int iLayer = 0; iLayer < nLayers; ++iLayer) {
102 layerClusters[iLayer] = pc.inputs().get<gsl::span<o2::trk::Cluster>>(std::format("compClusters_{}", iLayer));
103 layerPatterns[iLayer] = pc.inputs().get<gsl::span<unsigned char>>(std::format("patterns_{}", iLayer));
104 layerROFs[iLayer] = pc.inputs().get<gsl::span<o2::trk::ROFRecord>>(std::format("ROframes_{}", iLayer));
105 nInputRofs = std::max(nInputRofs, layerROFs[iLayer].size());
106 if (mIsMC) {
107 layerLabels[iLayer] = pc.inputs().get<const dataformats::MCTruthContainer<MCCompLabel>*>(std::format("trkmclabels_{}", iLayer)).release();
108 }
109 }
110
111 timeFrame.deriveAndInitTiming(layerROFs);
112
113 const float yPlaneMLOT = 0.0010f;
114 nRofs = timeFrame.loadROFrameData(layerROFs, layerClusters, layerPatterns, mIsMC ? &layerLabels : nullptr, yPlaneMLOT);
115 timeFrame.addTruthSeedingVertices();
116 }
117
118 const auto trackingLoopStart = std::chrono::steady_clock::now();
119 for (size_t iter{0}; iter < mTrackingParams.size(); ++iter) {
120 LOGP(info, "{}", mTrackingParams[iter].asString());
121 trackerTraits.initialiseTimeFrame(iter);
122 trackerTraits.computeLayerTracklets(iter, -1);
123 LOGP(info, "Number of tracklets in iteration {}: {}", iter, timeFrame.getNumberOfTracklets());
124 trackerTraits.computeLayerCells(iter);
125 LOGP(info, "Number of cells in iteration {}: {}", iter, timeFrame.getNumberOfCells());
126 trackerTraits.findCellsNeighbours(iter);
127 LOGP(info, "Number of cell neighbours in iteration {}: {}", iter, timeFrame.getNumberOfNeighbours());
128 trackerTraits.findRoads(iter);
129 LOGP(info, "Number of roads in iteration {}: {}", iter, timeFrame.getNumberOfTracks());
130 }
131 const auto trackingLoopElapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - trackingLoopStart).count();
132 LOGP(info, "Tracking iterations block took {} ms", trackingLoopElapsedMs);
133
134 if (mIsMC) {
135 itsTracker.computeTracksMClabels();
136 }
137
138 const auto& tracks = timeFrame.getTracks();
139 const auto& labels = timeFrame.getTracksLabel();
140 std::vector<o2::its::TrackITS> allTracks(tracks.begin(), tracks.end());
141 std::vector<o2::MCCompLabel> allLabels;
142
143 int totalTracks = allTracks.size();
144 int goodTracks = 0;
145 int fakeTracks = 0;
146
147 if (mIsMC) {
148 allLabels.assign(labels.begin(), labels.end());
149 for (const auto& label : allLabels) {
150 if (label.isFake()) {
151 ++fakeTracks;
152 } else {
153 ++goodTracks;
154 }
155 }
156 }
157
158 LOGP(info, "=== Tracking Summary ===");
159 LOGP(info, "Total tracks reconstructed: {}", totalTracks);
160 LOGP(info, "Good tracks: {} ({:.1f}%)", goodTracks, totalTracks > 0 ? 100.0 * goodTracks / totalTracks : 0);
161 LOGP(info, "Fake tracks: {} ({:.1f}%)", fakeTracks, totalTracks > 0 ? 100.0 * fakeTracks / totalTracks : 0);
162
163 const auto& rofView = timeFrame.getROFOverlapTableView();
164 const auto& clockLayer = rofView.getClockLayer();
165 const int clockLayerId = rofView.getClock();
166 const int64_t anchorBC = timeFrame.getTFAnchorIR().toLong();
167
168 int highestROF = static_cast<int>(clockLayer.mNROFsTF);
169 for (const auto& trc : allTracks) {
170 highestROF = std::max(highestROF, static_cast<int>(clockLayer.getROF(trc.getTimeStamp())));
171 }
172 for (const auto& vtx : timeFrame.getPrimaryVertices()) {
173 highestROF = std::max(highestROF, static_cast<int>(clockLayer.getROF(vtx.getTimeStamp().lower())));
174 }
175
176 std::vector<o2::trk::ROFRecord> allTrackROFs(highestROF);
177 for (size_t iROF = 0; iROF < allTrackROFs.size(); ++iROF) {
178 auto& rof = allTrackROFs[iROF];
180 ir.setFromLong(anchorBC + static_cast<int64_t>(clockLayer.getROFStartInBC(iROF)));
181 rof.setBCData(ir);
182 rof.setROFrame(iROF);
183 rof.setFirstEntry(0);
184 rof.setNEntries(0);
185 }
186
187 std::vector<int> rofEntries(highestROF + 1, 0);
188 for (const auto& trc : allTracks) {
189 const int rof = static_cast<int>(clockLayer.getROF(trc.getTimeStamp()));
190 if (rof >= 0 && rof < highestROF) {
191 ++rofEntries[rof];
192 }
193 }
194 std::exclusive_scan(rofEntries.begin(), rofEntries.end(), rofEntries.begin(), 0);
195
196 std::vector<o2::dataformats::IRFrame> irFrames;
197 irFrames.reserve(allTrackROFs.size());
198 const auto& maskView = timeFrame.getROFMaskView();
199 const auto rofLenMinus1 = clockLayer.mROFLength > 0 ? clockLayer.mROFLength - 1 : 0;
200 for (size_t iROF = 0; iROF < allTrackROFs.size(); ++iROF) {
201 allTrackROFs[iROF].setFirstEntry(rofEntries[iROF]);
202 allTrackROFs[iROF].setNEntries(rofEntries[iROF + 1] - rofEntries[iROF]);
203 if (maskView.isROFEnabled(clockLayerId, static_cast<int>(iROF))) {
204 const auto& bcStart = allTrackROFs[iROF].getBCData();
205 auto& irFrame = irFrames.emplace_back(bcStart, bcStart + rofLenMinus1);
206 irFrame.info = allTrackROFs[iROF].getNEntries();
207 }
208 }
209
210 pc.outputs().snapshot(o2::framework::Output{"TRK", "TRACKS", 0}, allTracks);
211 pc.outputs().snapshot(o2::framework::Output{"TRK", "TRACKSROF", 0}, allTrackROFs);
212 pc.outputs().snapshot(o2::framework::Output{"TRK", "IRFRAMES", 0}, irFrames);
213 if (mIsMC) {
214 pc.outputs().snapshot(o2::framework::Output{"TRK", "TRACKSMCTR", 0}, allLabels);
215 }
216
217 LOGP(info, "TRK pushed {} tracks in {} ROFs and {} IR frames{}",
218 allTracks.size(), allTrackROFs.size(), irFrames.size(),
219 mIsMC ? " (with MC labels)" : "");
220
221 timeFrame.wipe();
222}
223
224} // namespace o2::trk
225
226#endif // O2_TRK_TRACKERSPECIMPL_H
std::vector< std::string > labels
std::string asString(TDataMember const &dm, char *pointer)
Definition of the GeometryManager class.
Definition of the TRK Hit class.
Class to delimit start and end IR of certain time period.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Definition of the MagFieldParam: container for ALICE mag. field parameters.
Definition of the MagF class.
static void loadGeometry(std::string_view geomFilePath="", bool applyMisalignment=false, bool preferAlignedFile=true)
A container to hold and manage MC truth information/labels.
void snapshot(const Output &spec, T const &object)
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
void adoptTimeFrame(TimeFrame< NLayers > &tf)
Definition Tracker.cxx:226
void computeTracksMClabels()
Definition Tracker.cxx:122
static GeometryTGeo * Instance()
void runTracking(framework::ProcessingContext &pc, TimeFrameT &timeFrame, TrackerTraitsT &trackerTraits)
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
template std::string ConfigParamRegistry::get< std::string >(const char *key) const
void setFromLong(int64_t l)
const int nEvents
Definition test_Fifo.cxx:27
o2::InteractionRecord ir(0, 0)