37 mCosmicsProcessing =
false;
38 std::vector<VertexingParameters> vertParams;
39 std::vector<TrackingParameters> trackParams;
43 float bFactorTracklets = bFactor < 0.01 ? 1. : bFactor;
46 LOGP(info,
"Tracking mode not set, trying to fetch it from configurable params to: {}",
asString(mMode));
49 trackParams.resize(trackConf.doUPCIteration ? 4 : 3);
51 trackParams[1].TrackletMinPt = 0.2f;
52 trackParams[1].CellDeltaTanLambdaSigma *= 2.;
53 trackParams[2].TrackletMinPt = 0.1f;
54 trackParams[2].CellDeltaTanLambdaSigma *= 4.;
56 trackParams[0].MinPt[0] = 1.f / 12;
58 trackParams[1].MinPt[0] = 1.f / 12;
60 trackParams[2].MinTrackLength = 4;
61 trackParams[2].MinPt[0] = 1.f / 12;
62 trackParams[2].MinPt[1] = 1.f / 5;
63 trackParams[2].MinPt[2] = 1.f / 1;
64 trackParams[2].MinPt[3] = 1.f / 6;
66 trackParams[2].StartLayerMask = (1 << 6) + (1 << 3);
68 trackParams[3].MinTrackLength = 4;
69 trackParams[3].TrackletMinPt = 0.1f;
70 trackParams[3].CellDeltaTanLambdaSigma *= 4.;
71 trackParams[3].DeltaROF = 0;
73 for (
size_t ip = 0; ip < trackParams.size(); ip++) {
74 auto&
param = trackParams[ip];
77 param.CellsPerClusterLimit = 1.e3f;
78 param.TrackletsPerClusterLimit = 1.e3f;
80 if (ip < trackConf.MaxIter) {
81 if (trackConf.startLayerMask[ip] > 0) {
82 trackParams[2].StartLayerMask = trackConf.startLayerMask[ip];
84 if (trackConf.minTrackLgtIter[ip] > 0) {
85 param.MinTrackLength = trackConf.minTrackLgtIter[ip];
87 for (
int ilg = trackConf.MaxTrackLength; ilg >= trackConf.MinTrackLength; ilg--) {
88 int lslot0 = (trackConf.MaxTrackLength - ilg), lslot = lslot0 + ip * (trackConf.MaxTrackLength - trackConf.MinTrackLength + 1);
89 if (trackConf.minPtIterLgt[lslot] > 0.) {
90 param.MinPt[lslot0] = trackConf.minPtIterLgt[lslot];
96 vertParams[1].phiCut = 0.015f;
97 vertParams[1].tanLambdaCut = 0.015f;
98 vertParams[1].vertPerRofThreshold = 0;
99 vertParams[1].deltaRof = 0;
101 trackParams.resize(1);
102 trackParams[0].ZBins = 64;
103 trackParams[0].PhiBins = 32;
104 trackParams[0].MinTrackLength = 4;
105 LOGP(info,
"Initializing tracker in sync. phase reconstruction with {} passes", trackParams.size());
106 vertParams.resize(1);
108 mCosmicsProcessing =
true;
109 mRunVertexer =
false;
110 trackParams.resize(1);
111 trackParams[0].MinTrackLength = 4;
112 trackParams[0].CellDeltaTanLambdaSigma *= 10;
113 trackParams[0].PhiBins = 4;
114 trackParams[0].ZBins = 16;
115 trackParams[0].PVres = 1.e5f;
116 trackParams[0].MaxChi2ClusterAttachment = 60.;
117 trackParams[0].MaxChi2NDF = 40.;
118 trackParams[0].TrackletsPerClusterLimit = 100.;
119 trackParams[0].CellsPerClusterLimit = 100.;
120 LOGP(info,
"Initializing tracker in reconstruction for cosmics with {} passes", trackParams.size());
123 throw std::runtime_error(fmt::format(
"Unsupported ITS tracking mode {:s} ",
asString(mMode)));
127 for (
auto& p : vertParams) {
128 p.PrintMemory = vertConf.printMemory;
129 p.MaxMemory = vertConf.maxMemory;
130 p.DropTFUponFailure = vertConf.dropTFUponFailure;
132 for (
auto& p : trackParams) {
133 p.PrintMemory = trackConf.printMemory;
134 p.MaxMemory = trackConf.maxMemory;
135 p.DropTFUponFailure = trackConf.dropTFUponFailure;
138 for (
auto&
params : trackParams) {
142 for (
size_t ip = 0; ip < trackParams.size(); ip++) {
143 auto&
param = trackParams[ip];
144 param.TrackletMinPt *= bFactorTracklets;
145 for (
int ilg = trackConf.MaxTrackLength; ilg >= trackConf.MinTrackLength; ilg--) {
146 int lslot = trackConf.MaxTrackLength - ilg;
147 param.MinPt[lslot] *= bFactor;
150 mTracker->setParameters(trackParams);
151 mVertexer->setParameters(vertParams);
152 if (trackConf.nThreads == vertConf.nThreads) {
154 int nThreads = trackConf.nThreads;
156 const int hw = std::thread::hardware_concurrency();
157 const int maxThreads = (hw == 0 ? 1 : hw);
158 nThreads = std::clamp(nThreads, 1, maxThreads);
159 clamped = trackConf.nThreads > maxThreads;
161 LOGP(info,
"Tracker and Vertexer will share the task arena with {} thread(s){}", nThreads, (clamped) ?
" (clamped)" :
"");
162 mTaskArena = std::make_shared<tbb::task_arena>(std::abs(nThreads));
164 mVertexer->setNThreads(vertConf.nThreads, mTaskArena);
165 mTracker->setNThreads(trackConf.nThreads, mTaskArena);
170 auto compClusters = pc.
inputs().
get<gsl::span<o2::itsmft::CompClusterExt>>(
"compClusters");
171 gsl::span<const unsigned char> patterns = pc.
inputs().
get<gsl::span<unsigned char>>(
"patterns");
172 gsl::span<const o2::itsmft::PhysTrigger> physTriggers;
173 std::vector<o2::itsmft::PhysTrigger> fromTRD;
174 if (mUseTriggers == 2) {
176 auto trdTriggers = pc.
inputs().
get<gsl::span<o2::trd::TriggerRecord>>(
"phystrig");
177 for (
const auto& trig : trdTriggers) {
178 if (trig.getBCData() >=
ir && trig.getNumberOfTracklets()) {
179 ir = trig.getBCData();
183 physTriggers = gsl::span<const o2::itsmft::PhysTrigger>(fromTRD.data(), fromTRD.size());
184 }
else if (mUseTriggers == 1) {
185 physTriggers = pc.
inputs().
get<gsl::span<o2::itsmft::PhysTrigger>>(
"phystrig");
188 auto rofsinput = pc.
inputs().
get<gsl::span<o2::itsmft::ROFRecord>>(
"ROframes");
189 auto& trackROFvec = pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"ITS",
"ITSTrackROF", 0}, rofsinput.begin(), rofsinput.end());
190 auto& irFrames = pc.
outputs().
make<std::vector<o2::dataformats::IRFrame>>(
Output{
"ITS",
"IRFRAMES", 0});
193 irFrames.reserve(trackROFvec.size());
194 int nBCPerTF = alpParams.roFrameLengthInBC;
196 LOGP(info,
"ITSTracker pulled {} clusters, {} RO frames", compClusters.size(), trackROFvec.size());
198 gsl::span<itsmft::MC2ROFRecord const> mc2rofs;
203 LOG(info) << labels->
getIndexedSize() <<
" MC label objects , in " << mc2rofs.size() <<
" MC events";
206 auto& allClusIdx = pc.
outputs().
make<std::vector<int>>(
Output{
"ITS",
"TRACKCLSID", 0});
207 auto& allTracks = pc.
outputs().
make<std::vector<o2::its::TrackITS>>(
Output{
"ITS",
"TRACKS", 0});
208 auto& vertROFvec = pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"ITS",
"VERTICESROF", 0});
209 auto& vertices = pc.
outputs().
make<std::vector<Vertex>>(
Output{
"ITS",
"VERTICES", 0});
214 auto& allTrackLabels = mIsMC ? pc.
outputs().
make<std::vector<o2::MCCompLabel>>(
Output{
"ITS",
"TRACKSMCTR", 0}) : dummyMCLabTracks;
215 auto& allVerticesLabels = mIsMC ? pc.
outputs().
make<std::vector<o2::MCCompLabel>>(
Output{
"ITS",
"VERTICESMCTR", 0}) : dummyMCLabVerts;
216 auto& allVerticesPurities = mIsMC ? pc.
outputs().
make<std::vector<float>>(
Output{
"ITS",
"VERTICESMCPUR", 0}) : dummyMCPurVerts;
218 std::uint32_t roFrame = 0;
221 LOG(info) <<
"ITSTracker RO: continuous=" << continuous;
223 if (mOverrideBeamEstimation) {
226 mMeanVertex->getSigmaY2(),
227 mTracker->getParameters()[0].LayerResolution[0],
228 mTracker->getParameters()[0].SystErrorY2[0]);
233 gsl::span<const unsigned char>::iterator pattIt = patterns.begin();
235 gsl::span<itsmft::ROFRecord> trackROFspan(trackROFvec);
236 loadROF(trackROFspan, compClusters, pattIt, labels);
237 pattIt = patterns.begin();
238 std::vector<int> savedROF;
239 auto logger = [&](
const std::string& s) {
LOG(info) << s; };
240 auto fatalLogger = [&](
const std::string& s) {
LOG(fatal) << s; };
241 auto errorLogger = [&](
const std::string& s) {
LOG(error) << s; };
244 std::vector<uint8_t> processingMask, processUPCMask;
245 int cutVertexMult{0}, cutUPCVertex{0}, cutRandomMult =
int(trackROFvec.size()) - multEst.
selectROFs(trackROFvec, compClusters, physTriggers, processingMask);
246 processUPCMask.resize(processingMask.size(),
false);
248 float vertexerElapsedTime{0.f};
250 vertROFvec.reserve(trackROFvec.size());
252 vertexerElapsedTime = mVertexer->clustersToVertices(logger);
257 gsl::span<const std::pair<MCCompLabel, float>> vMCRecInfo;
258 for (
auto iRof{0}; iRof < trackROFspan.size(); ++iRof) {
259 std::vector<Vertex> vtxVecLoc;
260 auto& vtxROF = vertROFvec.emplace_back(trackROFspan[iRof]);
261 vtxROF.setFirstEntry(vertices.size());
268 if (!vtxSpan.empty()) {
270 LOGP(
debug,
"ROF {} rejected as vertices are from the UPC iteration", iRof);
271 processUPCMask[iRof] =
true;
273 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxUPCMode);
275 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxStdMode);
278 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxUPCMode);
281 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxStdMode);
283 vtxROF.setNEntries(vtxSpan.size());
284 bool selROF = vtxSpan.empty();
285 for (
auto iV{0}; iV < vtxSpan.size(); ++iV) {
286 auto&
v = vtxSpan[iV];
287 if (multEstConf.isVtxMultCutRequested() && !multEstConf.isPassingVtxMultCut(
v.getNContributors())) {
291 vertices.push_back(
v);
293 allVerticesLabels.push_back(vMCRecInfo[iV].
first);
294 allVerticesPurities.push_back(vMCRecInfo[iV].second);
297 if (processingMask[iRof] && !selROF) {
298 LOGP(info,
"ROF {} rejected by the vertex multiplicity selection [{},{}]", iRof, multEstConf.cutMultVtxLow, multEstConf.cutMultVtxHigh);
299 processingMask[iRof] = selROF;
303 vtxVecLoc.emplace_back();
304 vtxVecLoc.back().setNContributors(1);
305 vtxROF.setNEntries(vtxVecLoc.size());
306 for (
auto&
v : vtxVecLoc) {
307 vertices.push_back(
v);
313 LOG(info) << fmt::format(
" - Vertex seeding total elapsed time: {} ms for {} ({} + {}) vertices found in {}/{} ROFs",
319 trackROFspan.size());
320 LOG(info) << fmt::format(
" - FastMultEst: rejected {}/{} ROFs: random/mult.sel:{} (seed {}), vtx.sel:{}", cutRandomMult + cutVertexMult, trackROFspan.size(), cutRandomMult, multEst.
lastRandomSeed, cutVertexMult);
322 if (mOverrideBeamEstimation) {
327 if (mCosmicsProcessing && compClusters.size() > 1500 * trackROFspan.size()) {
328 LOG(error) <<
"Cosmics processing was requested with an average detector occupancy exceeding 1.e-7, skipping TF processing.";
335 mTracker->clustersToTracks(logger, fatalLogger);
337 mTracker->clustersToTracks(logger, errorLogger);
341 allTracks.reserve(totTracks);
342 allClusIdx.reserve(totClusIDs);
345 LOG(warning) << fmt::format(
" - The processed timeframe had {} clusters with wild z coordinates, check the dictionaries",
mTimeFrame->
hasBogusClusters());
348 for (
unsigned int iROF{0}; iROF < trackROFvec.size(); ++iROF) {
349 auto& tracksROF{trackROFvec[iROF]};
350 auto& vtxROF = vertROFvec[iROF];
352 auto number{tracks.size()};
353 auto first{allTracks.size()};
354 int offset = -tracksROF.getFirstEntry();
355 tracksROF.setFirstEntry(
first);
356 tracksROF.setNEntries(number);
357 tracksROF.setFlags(vtxROF.getFlags());
358 if (processingMask[iROF]) {
359 irFrames.emplace_back(tracksROF.getBCData(), tracksROF.getBCData() + nBCPerTF - 1).info = tracks.size();
364 for (
unsigned int iTrk{0}; iTrk < tracks.size(); ++iTrk) {
365 auto& trc{tracks[iTrk]};
366 trc.setFirstClusterEntry(allClusIdx.size());
367 int ncl = trc.getNumberOfClusters(), nclf = 0;
369 auto clid = trc.getClusterIndex(ic);
372 allClusIdx.push_back(clid);
377 allTracks.emplace_back(trc);
381 LOGP(info,
"ITSTracker pushed {} tracks and {} vertices", allTracks.size(), vertices.size());
383 LOGP(info,
"ITSTracker pushed {} track labels", allTrackLabels.size());
384 LOGP(info,
"ITSTracker pushed {} vertex labels", allVerticesLabels.size());
385 LOGP(info,
"ITSTracker pushed {} vertex purities", allVerticesPurities.size());