Project
Loading...
Searching...
No Matches
Tracker.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.
14
15#include "MFTTracking/Tracker.h"
16#include "MFTTracking/Cluster.h"
17#include "MFTTracking/Cell.h"
18#include "MFTTracking/TrackCA.h"
21#include "Framework/Logger.h"
22
23namespace o2
24{
25namespace mft
26{
27
29
30//_________________________________________________________________________________________________
31template <typename T>
32Tracker<T>::Tracker(bool useMC) : mUseMC{useMC}
33{
34 mTrackFitter = std::make_unique<o2::mft::TrackFitter<T>>();
35}
36
37//_________________________________________________________________________________________________
38template <typename T>
40{
42 mBz = bz;
43 mTrackFitter->setBz(bz);
44}
45
46//_________________________________________________________________________________________________
47template <typename T>
48void Tracker<T>::configure(const MFTTrackingParam& trkParam, int trackerID)
49{
51 bool firstTracker = trackerID == 0;
52 mTrackerID = trackerID;
53 initialize(trkParam);
54
55 mTrackFitter->setMFTRadLength(trkParam.MFTRadLength);
56 mTrackFitter->setVerbosity(trkParam.verbose);
57 mTrackFitter->setAlignResiduals(trkParam.alignResidual);
58 if (trkParam.forceZeroField || (std::abs(mBz) < o2::constants::math::Almost0)) {
59 mTrackFitter->setTrackModel(o2::mft::MFTTrackModel::Linear);
60 } else {
61 mTrackFitter->setTrackModel(trkParam.trackmodel);
62 }
63
64 if (firstTracker) {
65 LOG(info) << "Configurable tracker parameters:";
66 switch (mTrackFitter->getTrackModel()) {
68 LOG(info) << "Fwd track model = Helix";
69 break;
71 LOG(info) << "Fwd track model = Quadratic";
72 break;
74 LOG(info) << "Fwd track model = Linear";
75 break;
77 LOG(info) << "Fwd track model = Optimized";
78 break;
79 }
80 LOG(info) << "alignResidual = " << trkParam.alignResidual;
81 LOG(info) << "MinTrackPointsLTF = " << mMinTrackPointsLTF;
82 LOG(info) << "MinTrackPointsCA = " << mMinTrackPointsCA;
83 LOG(info) << "MinTrackStationsLTF = " << mMinTrackStationsLTF;
84 LOG(info) << "MinTrackStationsCA = " << mMinTrackStationsCA;
85 LOG(info) << "LTFConeRadius = " << (trkParam.LTFConeRadius ? "true" : "false");
86 LOG(info) << "CAConeRadius = " << (trkParam.CAConeRadius ? "true" : "false");
87 LOG(info) << "LTFclsRCut = " << mLTFclsRCut;
88 LOG(info) << "ROADclsRCut = " << mROADclsRCut;
89 LOG(info) << "RBins = " << mRBins;
90 LOG(info) << "PhiBins = " << mPhiBins;
91 LOG(info) << "ZVtxMin = " << mZVtxMin;
92 LOG(info) << "ZVtxMax = " << mZVtxMax;
93 LOG(info) << "RCutAtZmin = " << mRCutAtZmin;
94 if (mUseMC) {
95 LOG(info) << "TrueTrackMCThreshold = " << mTrueTrackMCThreshold;
96 }
97 LOG(info) << "FullClusterScan = " << (trkParam.FullClusterScan ? "true" : "false");
98 LOG(info) << "forceZeroField = " << (trkParam.forceZeroField ? "true" : "false");
99 LOG(info) << "MFTRadLength = " << trkParam.MFTRadLength;
100 LOG(info) << "irFramesOnly = " << (trkParam.irFramesOnly ? "true" : "false");
101 LOG(info) << "isMultCutRequested = " << (trkParam.isMultCutRequested() ? "true" : "false");
102 if (trkParam.isMultCutRequested()) {
103 LOG(info) << "cutMultClusLow = " << trkParam.cutMultClusLow;
104 LOG(info) << "cutMultClusHigh = " << trkParam.cutMultClusHigh;
105 }
106 initializeFinder();
107 }
108 mRoad.initialize();
109}
110
111//_________________________________________________________________________________________________
112template <typename T>
114{
115 static bool staticInitDone = false;
116
117 // The lock will prevent executing the code below at the same time for different tracker copes (one will wait for other)
118 std::lock_guard<std::mutex> guard(TrackerConfig::sTCMutex);
119
120 if (staticInitDone) {
121 return;
122 }
123 staticInitDone = true;
124
128 for (auto layer = 0; layer < constants::mft::LayersNumber; layer++) {
129 // Conical track-finder binning.
130 // Needs to be executed only once since it is filling static data members used by all tracker threads
132 mInversePhiBinSize = 1.0 / mPhiBinSize;
134 mInverseRBinSize[layer] = 1.0 / mRBinSize[layer];
135 auto ZL0 = LayerZCoordinate()[0];
136 auto deltaZ = (abs(LayerZCoordinate()[layer]) - abs(ZL0));
137 auto binArcLenght = constants::index_table::RMin[layer] * o2::constants::math::TwoPI / mPhiBins;
138 Float_t NconicalBins = 2.0 * deltaZ * mRCutAtZmin / (abs(ZL0) + mZVtxMin) / binArcLenght;
139 mPhiBinWin[layer] = std::max(3, int(ceil(NconicalBins)));
140 LOG(debug) << "mPhiBinWin[" << layer << "] = " << mPhiBinWin[layer] << std::endl;
141 }
142
143 if (mFullClusterScan) { // bin containers are needed only for the fullClusterScan
144 return;
145 }
146
148
149 Float_t dz, x, y, r, phi, x_proj, y_proj, r_proj, phi_proj, zLayer1, zLayer2;
150 Int_t binIndex1, binIndex2, binIndex2S, binR_proj, binPhi_proj;
151
152 for (Int_t layer1 = 0; layer1 < (constants::mft::LayersNumber - 1); ++layer1) {
153 zLayer1 = constants::mft::LayerZCoordinate()[layer1];
154
155 for (Int_t iRBin = 0; iRBin < mRBins; ++iRBin) {
156 bool isFirstPhiBin = true;
157
158 r = (iRBin + 0.5) * mRBinSize[layer1] + constants::index_table::RMin[layer1];
159
160 for (Int_t iPhiBin = 0; iPhiBin < mPhiBins; ++iPhiBin) {
161 isFirstPhiBin = !iPhiBin;
162
163 phi = (iPhiBin + 0.5) * mPhiBinSize + constants::index_table::PhiMin;
164
165 binIndex1 = getBinIndex(iRBin, iPhiBin);
166
167 x = r * TMath::Cos(phi);
168 y = r * TMath::Sin(phi);
169
170 for (Int_t layer2 = (layer1 + 1); layer2 < constants::mft::LayersNumber; ++layer2) {
171 zLayer2 = constants::mft::LayerZCoordinate()[layer2];
172
173 dz = zLayer2 - zLayer1;
174 x_proj = x + dz * x * constants::mft::InverseLayerZCoordinate()[layer1];
175 y_proj = y + dz * y * constants::mft::InverseLayerZCoordinate()[layer1];
176 auto clsPoint2D = math_utils::Point2D<Float_t>(x_proj, y_proj);
177 r_proj = clsPoint2D.R();
178 phi_proj = clsPoint2D.Phi();
180
181 binR_proj = getRBinIndex(r_proj, layer2);
182 binPhi_proj = getPhiBinIndex(phi_proj);
183
184 int binwPhiS = mPhiBinWin[layer2];
185 int binhwPhiS = binwPhiS / 2;
186
187 float rMin = r * (mZVtxMax + abs(zLayer2)) / (mZVtxMax + abs(zLayer1));
188 float rMax = r * (abs(zLayer2) + mZVtxMin) / (abs(zLayer1) + mZVtxMin);
189
190 int rBinMin = getRBinIndex(rMin, layer2);
191 int rBinMax = getRBinIndex(rMax, layer2);
192 if (rBinMin == binR_proj) {
193 rBinMin--;
194 }
195 if (rBinMax == binR_proj) {
196 rBinMax++;
197 }
198 rBinMin = TMath::Range(0, mRBins - 1, rBinMin);
199 rBinMax = TMath::Range(0, mRBins - 1, rBinMax);
200 if (isFirstPhiBin) {
201 LOG(debug) << "Layer1 = " << layer1 << " Layer2 = " << layer2 << " iRBin = " << iRBin << " r = " << r << " r_proj = " << r_proj << " rBinMin = " << rBinMin << " rBinMax = " << rBinMax;
202 }
203 for (Int_t binR = rBinMin; binR <= rBinMax; ++binR) {
204
205 for (Int_t iPhi = 0; iPhi < binwPhiS; ++iPhi) {
206 int binPhiS = binPhi_proj + (iPhi - binhwPhiS);
207 if (binPhiS < 0) {
208 continue;
209 }
210
211 binIndex2S = getBinIndex(binR, binPhiS);
212 (*mBinsS.get())[layer1][layer2 - 1][binIndex1].emplace_back(binIndex2S);
213 }
214 }
215
216 int binwPhi = mPhiBinWin[layer2];
217 int binhwPhi = binwPhi / 2;
218
219 for (Int_t binR = rBinMin; binR <= rBinMax; ++binR) {
220
221 for (Int_t iPhi = 0; iPhi < binwPhi; ++iPhi) {
222 int binPhi = binPhi_proj + (iPhi - binhwPhi);
223 if (binPhi < 0) {
224 continue;
225 }
226
227 binIndex2 = getBinIndex(binR, binPhi);
228 (*mBins.get())[layer1][layer2 - 1][binIndex1].emplace_back(binIndex2);
229 }
230 }
231
232 } // end loop layer2
233 } // end loop PhiBinIndex
234 } // end loop RBinIndex
235 } // end loop layer1
236}
237
238//_________________________________________________________________________________________________
239template <typename T>
241{
242 if (!mFullClusterScan) {
243 findTracksLTF(event);
244 } else {
245 findTracksLTFfcs(event);
246 }
247}
248
249//_________________________________________________________________________________________________
250template <typename T>
252{
253 if (!mFullClusterScan) {
254 findTracksCA(event);
255 } else {
256 findTracksCAfcs(event);
257 }
258}
259
260//_________________________________________________________________________________________________
261template <typename T>
263{
264 // find (high momentum) tracks by the Linear Track Finder (LTF) method
265
266 MCCompLabel mcCompLabel;
267 Int_t layer1, layer2, nPointDisks;
268 Int_t binR_proj, binPhi_proj, bin;
269 Int_t binIndex, clsMinIndex, clsMaxIndex, clsMinIndexS, clsMaxIndexS;
270 Int_t extClsIndex;
271 Int_t clsSize;
272 Float_t dz = 0., dRCone = 1.;
273 Float_t dR2, dR2min, dR2cut = mLTFclsR2Cut;
274 Bool_t hasDisk[constants::mft::DisksNumber], newPoint;
275
276 Int_t clsInLayer1, clsInLayer2, clsInLayer;
277
278 Int_t nPoints;
279 TrackElement trackPoints[constants::mft::LayersNumber];
280
281 Int_t step = 0;
282 layer1 = 0;
283
284 while (true) {
285
286 layer2 = (step == 0) ? (constants::mft::LayersNumber - 1) : (layer2 - 1);
287 step++;
288
289 if (layer2 < layer1 + (mMinTrackPointsLTF - 1)) {
290 ++layer1;
291 if (layer1 > (constants::mft::LayersNumber - (mMinTrackPointsLTF - 1))) {
292 break;
293 }
294 step = 0;
295 continue;
296 }
297
298 for (std::vector<Cluster>::iterator it1 = event.getClustersInLayer(layer1).begin(); it1 != event.getClustersInLayer(layer1).end(); ++it1) {
299 Cluster& cluster1 = *it1;
300 if (cluster1.getUsed()) {
301 continue;
302 }
303 clsInLayer1 = it1 - event.getClustersInLayer(layer1).begin();
304
305 // loop over the bins in the search window
306 for (const auto& binS : (*mBinsS.get())[layer1][layer2 - 1][cluster1.indexTableBin]) {
307
308 getBinClusterRange(event, layer2, binS, clsMinIndexS, clsMaxIndexS);
309
310 for (std::vector<Cluster>::iterator it2 = (event.getClustersInLayer(layer2).begin() + clsMinIndexS); it2 != (event.getClustersInLayer(layer2).begin() + clsMaxIndexS + 1); ++it2) {
311 Cluster& cluster2 = *it2;
312 if (cluster2.getUsed()) {
313 continue;
314 }
315 clsInLayer2 = it2 - event.getClustersInLayer(layer2).begin();
316
317 // start a Track type T
318 nPoints = 0;
319
320 // add the first seed point
321 trackPoints[nPoints].layer = layer1;
322 trackPoints[nPoints].idInLayer = clsInLayer1;
323 nPoints++;
324
325 // intermediate layers
326 for (Int_t layer = (layer1 + 1); layer <= (layer2 - 1); ++layer) {
327
328 newPoint = kTRUE;
329
330 // check if road is a cylinder or a cone
332 dRCone = 1 + dz * constants::mft::InverseLayerZCoordinate()[layer1];
333
334 // loop over the bins in the search window
335 dR2min = mLTFConeRadius ? dR2cut * dRCone * dRCone : dR2cut;
336 for (const auto& bin : (*mBins.get())[layer1][layer - 1][cluster1.indexTableBin]) {
337
338 getBinClusterRange(event, layer, bin, clsMinIndex, clsMaxIndex);
339
340 for (std::vector<Cluster>::iterator it = (event.getClustersInLayer(layer).begin() + clsMinIndex); it != (event.getClustersInLayer(layer).begin() + clsMaxIndex + 1); ++it) {
341 Cluster& cluster = *it;
342 if (cluster.getUsed()) {
343 continue;
344 }
345 clsInLayer = it - event.getClustersInLayer(layer).begin();
346
347 dR2 = getDistanceToSeed(cluster1, cluster2, cluster);
348 // retain the closest point within a radius dR2cut
349 if (dR2 >= dR2min) {
350 continue;
351 }
352 dR2min = dR2;
353
354 if (newPoint) {
355 trackPoints[nPoints].layer = layer;
356 trackPoints[nPoints].idInLayer = clsInLayer;
357 nPoints++;
358 }
359 // retain only the closest point in DistanceToSeed
360 newPoint = false;
361 } // end clusters bin intermediate layer
362 } // end intermediate layers
363 } // end binRPhi
364
365 // add the second seed point
366 trackPoints[nPoints].layer = layer2;
367 trackPoints[nPoints].idInLayer = clsInLayer2;
368 nPoints++;
369
370 // keep only tracks fulfilling the minimum length condition
371 if (nPoints < mMinTrackPointsLTF) {
372 continue;
373 }
374 for (Int_t i = 0; i < (constants::mft::DisksNumber); i++) {
375 hasDisk[i] = kFALSE;
376 }
377 for (Int_t point = 0; point < nPoints; ++point) {
378 auto layer = trackPoints[point].layer;
379 hasDisk[layer / 2] = kTRUE;
380 }
381 nPointDisks = 0;
382 for (Int_t disk = 0; disk < (constants::mft::DisksNumber); ++disk) {
383 if (hasDisk[disk]) {
384 ++nPointDisks;
385 }
386 }
387 if (nPointDisks < mMinTrackStationsLTF) {
388 continue;
389 }
390
391 // add a new Track
392 event.addTrack();
393 for (Int_t point = 0; point < nPoints; ++point) {
394 auto layer = trackPoints[point].layer;
395 auto clsInLayer = trackPoints[point].idInLayer;
396 Cluster& cluster = event.getClustersInLayer(layer)[clsInLayer];
397 mcCompLabel = mUseMC ? event.getClusterLabels(layer, cluster.clusterId) : MCCompLabel();
398 extClsIndex = event.getClusterExternalIndex(layer, cluster.clusterId);
399 clsSize = event.getClusterSize(layer, cluster.clusterId);
400 event.getCurrentTrack().setPoint(cluster, layer, clsInLayer, mcCompLabel, extClsIndex, clsSize);
401 // mark the used clusters
402 cluster.setUsed(true);
403 }
404 } // end seed clusters bin layer2
405 } // end binRPhi
406 } // end clusters layer1
407
408 } // end seeding
409}
410
411//_________________________________________________________________________________________________
412template <typename T>
413void Tracker<T>::findTracksLTFfcs(ROframe<T>& event)
414{
415 // find (high momentum) tracks by the Linear Track Finder (LTF) method
416 // with full scan of the clusters in the target plane
417
418 MCCompLabel mcCompLabel;
419 Int_t layer1, layer2, nPointDisks;
420 Int_t binR_proj, binPhi_proj, bin;
421 Int_t binIndex, clsMinIndex, clsMaxIndex, clsMinIndexS, clsMaxIndexS;
422 Int_t extClsIndex;
423 Int_t clsSize;
424 Float_t dR2, dR2min, dR2cut = mLTFclsR2Cut;
425 Bool_t hasDisk[constants::mft::DisksNumber], newPoint;
426
427 Int_t clsInLayer1, clsInLayer2, clsInLayer;
428
429 Int_t nPoints;
430 TrackElement trackPoints[constants::mft::LayersNumber];
431
432 Int_t step = 0;
433 layer1 = 0;
434
435 while (true) {
436
437 layer2 = (step == 0) ? (constants::mft::LayersNumber - 1) : (layer2 - 1);
438 step++;
439
440 if (layer2 < layer1 + (mMinTrackPointsLTF - 1)) {
441 ++layer1;
442 if (layer1 > (constants::mft::LayersNumber - (mMinTrackPointsLTF - 1))) {
443 break;
444 }
445 step = 0;
446 continue;
447 }
448
449 for (std::vector<Cluster>::iterator it1 = event.getClustersInLayer(layer1).begin(); it1 != event.getClustersInLayer(layer1).end(); ++it1) {
450 Cluster& cluster1 = *it1;
451 if (cluster1.getUsed()) {
452 continue;
453 }
454 clsInLayer1 = it1 - event.getClustersInLayer(layer1).begin();
455
456 for (std::vector<Cluster>::iterator it2 = event.getClustersInLayer(layer2).begin(); it2 != event.getClustersInLayer(layer2).end(); ++it2) {
457 Cluster& cluster2 = *it2;
458 if (cluster2.getUsed()) {
459 continue;
460 }
461 clsInLayer2 = it2 - event.getClustersInLayer(layer2).begin();
462
463 // start a track type T
464 nPoints = 0;
465
466 // add the first seed point
467 trackPoints[nPoints].layer = layer1;
468 trackPoints[nPoints].idInLayer = clsInLayer1;
469 nPoints++;
470
471 // intermediate layers
472 for (Int_t layer = (layer1 + 1); layer <= (layer2 - 1); ++layer) {
473
474 newPoint = kTRUE;
475
476 // loop over the bins in the search window
477 dR2min = dR2cut;
478 for (std::vector<Cluster>::iterator it = event.getClustersInLayer(layer).begin(); it != event.getClustersInLayer(layer).end(); ++it) {
479 Cluster& cluster = *it;
480 if (cluster.getUsed()) {
481 continue;
482 }
483 clsInLayer = it - event.getClustersInLayer(layer).begin();
484
485 dR2 = getDistanceToSeed(cluster1, cluster2, cluster);
486 // retain the closest point within a radius dR2cut
487 if (dR2 >= dR2min) {
488 continue;
489 }
490 dR2min = dR2;
491
492 if (newPoint) {
493 trackPoints[nPoints].layer = layer;
494 trackPoints[nPoints].idInLayer = clsInLayer;
495 nPoints++;
496 }
497 // retain only the closest point in DistanceToSeed
498 newPoint = false;
499 } // end clusters bin intermediate layer
500 } // end intermediate layers
501
502 // add the second seed point
503 trackPoints[nPoints].layer = layer2;
504 trackPoints[nPoints].idInLayer = clsInLayer2;
505 nPoints++;
506
507 // keep only tracks fulfilling the minimum length condition
508 if (nPoints < mMinTrackPointsLTF) {
509 continue;
510 }
511 for (Int_t i = 0; i < (constants::mft::DisksNumber); i++) {
512 hasDisk[i] = kFALSE;
513 }
514 for (Int_t point = 0; point < nPoints; ++point) {
515 auto layer = trackPoints[point].layer;
516 hasDisk[layer / 2] = kTRUE;
517 }
518 nPointDisks = 0;
519 for (Int_t disk = 0; disk < (constants::mft::DisksNumber); ++disk) {
520 if (hasDisk[disk]) {
521 ++nPointDisks;
522 }
523 }
524 if (nPointDisks < mMinTrackStationsLTF) {
525 continue;
526 }
527
528 // add a new Track
529 event.addTrack();
530 for (Int_t point = 0; point < nPoints; ++point) {
531 auto layer = trackPoints[point].layer;
532 auto clsInLayer = trackPoints[point].idInLayer;
533 Cluster& cluster = event.getClustersInLayer(layer)[clsInLayer];
534 mcCompLabel = mUseMC ? event.getClusterLabels(layer, cluster.clusterId) : MCCompLabel();
535 extClsIndex = event.getClusterExternalIndex(layer, cluster.clusterId);
536 clsSize = event.getClusterSize(layer, cluster.clusterId);
537 event.getCurrentTrack().setPoint(cluster, layer, clsInLayer, mcCompLabel, extClsIndex, clsSize);
538 // mark the used clusters
539 cluster.setUsed(true);
540 }
541 } // end seed clusters bin layer2
542 } // end clusters layer1
543
544 } // end seeding
545}
546
547//_________________________________________________________________________________________________
548template <typename T>
549void Tracker<T>::findTracksCA(ROframe<T>& event)
550{
551 // layers: 0, 1, 2, ..., 9
552 // rules for combining first/last plane in a road:
553 // 0 with 6, 7, 8, 9
554 // 1 with 6, 7, 8, 9
555 // 2 with 8, 9
556 // 3 with 8, 9
557 Int_t layer1Min = 0, layer1Max = 3;
558 Int_t layer2Min[4] = {6, 6, 8, 8};
559 constexpr Int_t layer2Max = constants::mft::LayersNumber - 1;
560
561 MCCompLabel mcCompLabel;
562 Int_t roadId, nPointDisks;
563 Int_t binR_proj, binPhi_proj, bin;
564 Int_t binIndex, clsMinIndex, clsMaxIndex, clsMinIndexS, clsMaxIndexS;
565 Float_t dz = 0., dRCone = 1.;
566 Float_t dR2, dR2min, dR2cut = mROADclsR2Cut;
567 Bool_t hasDisk[constants::mft::DisksNumber];
568
569 Int_t clsInLayer1, clsInLayer2, clsInLayer;
570
571 Int_t nPoints;
572 std::vector<TrackElement> roadPoints;
573
574 roadId = 0;
575
576 for (Int_t layer1 = layer1Min; layer1 <= layer1Max; ++layer1) {
577
578 for (Int_t layer2 = layer2Max; layer2 >= layer2Min[layer1]; --layer2) {
579
580 for (std::vector<Cluster>::iterator it1 = event.getClustersInLayer(layer1).begin(); it1 != event.getClustersInLayer(layer1).end(); ++it1) {
581 Cluster& cluster1 = *it1;
582 if (cluster1.getUsed()) {
583 continue;
584 }
585 clsInLayer1 = it1 - event.getClustersInLayer(layer1).begin();
586
587 // loop over the bins in the search window
588 for (const auto& binS : (*mBinsS.get())[layer1][layer2 - 1][cluster1.indexTableBin]) {
589
590 getBinClusterRange(event, layer2, binS, clsMinIndexS, clsMaxIndexS);
591
592 for (std::vector<Cluster>::iterator it2 = (event.getClustersInLayer(layer2).begin() + clsMinIndexS); it2 != (event.getClustersInLayer(layer2).begin() + clsMaxIndexS + 1); ++it2) {
593 Cluster& cluster2 = *it2;
594 if (cluster2.getUsed()) {
595 continue;
596 }
597 clsInLayer2 = it2 - event.getClustersInLayer(layer2).begin();
598
599 // start a road
600 roadPoints.clear();
601
602 // add the first seed point
603 roadPoints.emplace_back(layer1, clsInLayer1);
604
605 for (Int_t layer = (layer1 + 1); layer <= (layer2 - 1); ++layer) {
606
607 // check if road is a cylinder or a cone
609 dRCone = 1 + dz * constants::mft::InverseLayerZCoordinate()[layer1];
610
611 dR2min = mLTFConeRadius ? dR2cut * dRCone * dRCone : dR2cut;
612
613 // loop over the bins in the search window
614 for (const auto& bin : (*mBins.get())[layer1][layer - 1][cluster1.indexTableBin]) {
615
616 getBinClusterRange(event, layer, bin, clsMinIndex, clsMaxIndex);
617
618 for (std::vector<Cluster>::iterator it = (event.getClustersInLayer(layer).begin() + clsMinIndex); it != (event.getClustersInLayer(layer).begin() + clsMaxIndex + 1); ++it) {
619 Cluster& cluster = *it;
620 if (cluster.getUsed()) {
621 continue;
622 }
623 clsInLayer = it - event.getClustersInLayer(layer).begin();
624
625 dR2 = getDistanceToSeed(cluster1, cluster2, cluster);
626 // add all points within a radius dR2cut
627 if (dR2 >= dR2min) {
628 continue;
629 }
630
631 roadPoints.emplace_back(layer, clsInLayer);
632
633 } // end clusters bin intermediate layer
634 } // end intermediate layers
635 } // end binR
636
637 // add the second seed point
638 roadPoints.emplace_back(layer2, clsInLayer2);
639 nPoints = roadPoints.size();
640
641 // keep only roads fulfilling the minimum length condition
642 if (nPoints < mMinTrackPointsCA) {
643 continue;
644 }
645 for (Int_t i = 0; i < (constants::mft::DisksNumber); i++) {
646 hasDisk[i] = kFALSE;
647 }
648 for (Int_t point = 0; point < nPoints; ++point) {
649 auto layer = roadPoints[point].layer;
650 hasDisk[layer / 2] = kTRUE;
651 }
652 nPointDisks = 0;
653 for (Int_t disk = 0; disk < (constants::mft::DisksNumber); ++disk) {
654 if (hasDisk[disk]) {
655 ++nPointDisks;
656 }
657 }
658 if (nPointDisks < mMinTrackStationsCA) {
659 continue;
660 }
661
662 mRoad.reset();
663 for (Int_t point = 0; point < nPoints; ++point) {
664 auto layer = roadPoints[point].layer;
665 auto clsInLayer = roadPoints[point].idInLayer;
666 mRoad.setPoint(layer, clsInLayer);
667 }
668 mRoad.setRoadId(roadId);
669 ++roadId;
670
671 computeCellsInRoad(event);
672 runForwardInRoad();
673 runBackwardInRoad(event);
674
675 } // end clusters in layer2
676 } // end binRPhi
677 } // end clusters in layer1
678 } // end layer2
679 } // end layer1
680}
681
682//_________________________________________________________________________________________________
683template <typename T>
684void Tracker<T>::findTracksCAfcs(ROframe<T>& event)
685{
686 // layers: 0, 1, 2, ..., 9
687 // rules for combining first/last plane in a road:
688 // 0 with 6, 7, 8, 9
689 // 1 with 6, 7, 8, 9
690 // 2 with 8, 9
691 // 3 with 8, 9
692 Int_t layer1Min = 0, layer1Max = 3;
693 Int_t layer2Min[4] = {6, 6, 8, 8};
694 constexpr Int_t layer2Max = constants::mft::LayersNumber - 1;
695
696 MCCompLabel mcCompLabel;
697 Int_t roadId, nPointDisks;
698 Int_t binR_proj, binPhi_proj, bin;
699 Int_t binIndex, clsMinIndex, clsMaxIndex, clsMinIndexS, clsMaxIndexS;
700 Float_t dR2, dR2cut = mROADclsR2Cut;
701 Bool_t hasDisk[constants::mft::DisksNumber];
702
703 Int_t clsInLayer1, clsInLayer2, clsInLayer;
704
705 Int_t nPoints;
706 std::vector<TrackElement> roadPoints;
707
708 roadId = 0;
709
710 for (Int_t layer1 = layer1Min; layer1 <= layer1Max; ++layer1) {
711
712 for (Int_t layer2 = layer2Max; layer2 >= layer2Min[layer1]; --layer2) {
713
714 for (std::vector<Cluster>::iterator it1 = event.getClustersInLayer(layer1).begin(); it1 != event.getClustersInLayer(layer1).end(); ++it1) {
715 Cluster& cluster1 = *it1;
716 if (cluster1.getUsed()) {
717 continue;
718 }
719 clsInLayer1 = it1 - event.getClustersInLayer(layer1).begin();
720
721 for (std::vector<Cluster>::iterator it2 = event.getClustersInLayer(layer2).begin(); it2 != event.getClustersInLayer(layer2).end(); ++it2) {
722 Cluster& cluster2 = *it2;
723 if (cluster2.getUsed()) {
724 continue;
725 }
726 clsInLayer2 = it2 - event.getClustersInLayer(layer2).begin();
727
728 // start a road
729 roadPoints.clear();
730
731 // add the first seed point
732 roadPoints.emplace_back(layer1, clsInLayer1);
733
734 for (Int_t layer = (layer1 + 1); layer <= (layer2 - 1); ++layer) {
735
736 for (std::vector<Cluster>::iterator it = event.getClustersInLayer(layer).begin(); it != event.getClustersInLayer(layer).end(); ++it) {
737 Cluster& cluster = *it;
738 if (cluster.getUsed()) {
739 continue;
740 }
741 clsInLayer = it - event.getClustersInLayer(layer).begin();
742
743 dR2 = getDistanceToSeed(cluster1, cluster2, cluster);
744 // add all points within a radius dR2cut
745 if (dR2 >= dR2cut) {
746 continue;
747 }
748
749 roadPoints.emplace_back(layer, clsInLayer);
750
751 } // end clusters bin intermediate layer
752 } // end intermediate layers
753
754 // add the second seed point
755 roadPoints.emplace_back(layer2, clsInLayer2);
756 nPoints = roadPoints.size();
757
758 // keep only roads fulfilling the minimum length condition
759 if (nPoints < mMinTrackPointsCA) {
760 continue;
761 }
762 for (Int_t i = 0; i < (constants::mft::DisksNumber); i++) {
763 hasDisk[i] = kFALSE;
764 }
765 for (Int_t point = 0; point < nPoints; ++point) {
766 auto layer = roadPoints[point].layer;
767 hasDisk[layer / 2] = kTRUE;
768 }
769 nPointDisks = 0;
770 for (Int_t disk = 0; disk < (constants::mft::DisksNumber); ++disk) {
771 if (hasDisk[disk]) {
772 ++nPointDisks;
773 }
774 }
775 if (nPointDisks < mMinTrackStationsCA) {
776 continue;
777 }
778
779 mRoad.reset();
780 for (Int_t point = 0; point < nPoints; ++point) {
781 auto layer = roadPoints[point].layer;
782 auto clsInLayer = roadPoints[point].idInLayer;
783 mRoad.setPoint(layer, clsInLayer);
784 }
785 mRoad.setRoadId(roadId);
786 ++roadId;
787
788 computeCellsInRoad(event);
789 runForwardInRoad();
790 runBackwardInRoad(event);
791
792 } // end clusters in layer2
793 } // end clusters in layer1
794 } // end layer2
795 } // end layer1
796}
797
798//_________________________________________________________________________________________________
799template <typename T>
800void Tracker<T>::computeCellsInRoad(ROframe<T>& event)
801{
802 Int_t layer1, layer1min, layer1max, layer2, layer2min, layer2max;
803 Int_t nPtsInLayer1, nPtsInLayer2;
804 Int_t clsInLayer1, clsInLayer2;
805 Int_t cellId;
806 Bool_t noCell;
807
808 mRoad.getLength(layer1min, layer1max);
809 --layer1max;
810
811 for (layer1 = layer1min; layer1 <= layer1max; ++layer1) {
812
813 cellId = 0;
814
815 layer2min = layer1 + 1;
816 layer2max = std::min(layer1 + (constants::mft::DisksNumber - isDiskFace(layer1)), constants::mft::LayersNumber - 1);
817
818 nPtsInLayer1 = mRoad.getNPointsInLayer(layer1);
819
820 for (Int_t point1 = 0; point1 < nPtsInLayer1; ++point1) {
821
822 clsInLayer1 = mRoad.getClustersIdInLayer(layer1)[point1];
823
824 layer2 = layer2min;
825
826 noCell = kTRUE;
827 while (noCell && (layer2 <= layer2max)) {
828
829 nPtsInLayer2 = mRoad.getNPointsInLayer(layer2);
830 /*
831 if (nPtsInLayer2 > 1) {
832 LOG(info) << "BV===== more than one point in road " << mRoad.getRoadId() << " in layer " << layer2 << " : " << nPtsInLayer2 << "\n";
833 }
834 */
835 for (Int_t point2 = 0; point2 < nPtsInLayer2; ++point2) {
836
837 clsInLayer2 = mRoad.getClustersIdInLayer(layer2)[point2];
838
839 noCell = kFALSE;
840 // create a cell
841 addCellToCurrentRoad(event, layer1, layer2, clsInLayer1, clsInLayer2, cellId);
842 } // end points in layer2
843 ++layer2;
844
845 } // end while(noCell && (layer2 <= layer2max))
846 } // end points in layer1
847 } // end layer1
848}
849
850//_________________________________________________________________________________________________
851template <typename T>
852void Tracker<T>::runForwardInRoad()
853{
854 Int_t layerR, layerL, icellR, icellL;
855 Int_t iter = 0;
856 Bool_t levelChange = kTRUE;
857
858 while (levelChange) {
859
860 levelChange = kFALSE;
861 ++iter;
862
863 // R = right, L = left
864 for (layerL = 0; layerL < (constants::mft::LayersNumber - 2); ++layerL) {
865
866 for (icellL = 0; icellL < mRoad.getCellsInLayer(layerL).size(); ++icellL) {
867
868 Cell& cellL = mRoad.getCellsInLayer(layerL)[icellL];
869
870 layerR = cellL.getSecondLayerId();
871
872 if (layerR == (constants::mft::LayersNumber - 1)) {
873 continue;
874 }
875
876 for (icellR = 0; icellR < mRoad.getCellsInLayer(layerR).size(); ++icellR) {
877
878 Cell& cellR = mRoad.getCellsInLayer(layerR)[icellR];
879
880 if ((cellL.getLevel() == cellR.getLevel()) && getCellsConnect(cellL, cellR)) {
881 if (iter == 1) {
882 mRoad.addRightNeighbourToCell(layerL, icellL, layerR, icellR);
883 mRoad.addLeftNeighbourToCell(layerR, icellR, layerL, icellL);
884 }
885 mRoad.incrementCellLevel(layerR, icellR);
886 levelChange = kTRUE;
887
888 } // end matching cells
889 } // end loop cellR
890 } // end loop cellL
891 } // end loop layer
892
893 updateCellStatusInRoad();
894
895 } // end while (levelChange)
896}
897
898//_________________________________________________________________________________________________
899template <typename T>
900void Tracker<T>::runBackwardInRoad(ROframe<T>& event)
901{
902 if (mMaxCellLevel == 1) {
903 return; // we have only isolated cells
904 }
905
906 Bool_t addCellToNewTrack, hasDisk[constants::mft::DisksNumber];
907
908 Int_t lastCellLayer, lastCellId, icell;
909 Int_t cellId, layerC, cellIdC, layerRC, cellIdRC, layerL, cellIdL;
910 Int_t nPointDisks;
911 Float_t deviationPrev, deviation;
912
913 Int_t minLayer = 6;
914 Int_t maxLayer = 8;
915
916 Int_t nCells;
917 TrackElement trackCells[constants::mft::LayersNumber - 1];
918
919 for (Int_t layer = maxLayer; layer >= minLayer; --layer) {
920
921 for (cellId = 0; cellId < mRoad.getCellsInLayer(layer).size(); ++cellId) {
922
923 if (mRoad.isCellUsed(layer, cellId) || (mRoad.getCellLevel(layer, cellId) < (mMinTrackPointsCA - 1))) {
924 continue;
925 }
926
927 // start a TrackCA
928 nCells = 0;
929
930 trackCells[nCells].layer = layer;
931 trackCells[nCells].idInLayer = cellId;
932 nCells++;
933
934 // add cells to the new track
935 addCellToNewTrack = kTRUE;
936 while (addCellToNewTrack) {
937
938 layerRC = trackCells[nCells - 1].layer;
939 cellIdRC = trackCells[nCells - 1].idInLayer;
940
941 const Cell& cellRC = mRoad.getCellsInLayer(layerRC)[cellIdRC];
942
943 addCellToNewTrack = kFALSE;
944
945 // loop over left neighbours
946 deviationPrev = o2::constants::math::TwoPI;
947
948 for (Int_t iLN = 0; iLN < cellRC.getNLeftNeighbours(); ++iLN) {
949
950 const auto& leftNeighbour = cellRC.getLeftNeighbours()[iLN];
951 layerL = leftNeighbour.first;
952 cellIdL = leftNeighbour.second;
953
954 const Cell& cellL = mRoad.getCellsInLayer(layerL)[cellIdL];
955
956 if (mRoad.isCellUsed(layerL, cellIdL) || (mRoad.getCellLevel(layerL, cellIdL) != (mRoad.getCellLevel(layerRC, cellIdRC) - 1))) {
957 continue;
958 }
959
960 deviation = getCellDeviation(cellL, cellRC);
961
962 if (deviation < deviationPrev) {
963
964 deviationPrev = deviation;
965
966 if (iLN > 0) {
967 // delete the last added cell
968 nCells--;
969 }
970
971 trackCells[nCells].layer = layerL;
972 trackCells[nCells].idInLayer = cellIdL;
973 nCells++;
974
975 addCellToNewTrack = kTRUE;
976 }
977
978 } // end loop left neighbour
979 } // end while(addCellToNewTrack)
980
981 // check the track length
982 for (Int_t i = 0; i < (constants::mft::DisksNumber); ++i) {
983 hasDisk[i] = kFALSE;
984 }
985
986 layerC = trackCells[0].layer;
987 cellIdC = trackCells[0].idInLayer;
988 const Cell& cellC = mRoad.getCellsInLayer(layerC)[cellIdC];
989 hasDisk[cellC.getSecondLayerId() / 2] = kTRUE;
990 for (icell = 0; icell < nCells; ++icell) {
991 layerC = trackCells[icell].layer;
992 cellIdC = trackCells[icell].idInLayer;
993 hasDisk[layerC / 2] = kTRUE;
994 }
995
996 nPointDisks = 0;
997 for (Int_t disk = 0; disk < (constants::mft::DisksNumber); ++disk) {
998 if (hasDisk[disk]) {
999 ++nPointDisks;
1000 }
1001 }
1002
1003 if (nPointDisks < mMinTrackStationsCA) {
1004 continue;
1005 }
1006
1007 // add a new Track setting isCA = true
1008 event.addTrack(true);
1009 for (icell = 0; icell < nCells; ++icell) {
1010 layerC = trackCells[icell].layer;
1011 cellIdC = trackCells[icell].idInLayer;
1012 addCellToCurrentTrackCA(layerC, cellIdC, event);
1013 mRoad.setCellUsed(layerC, cellIdC, kTRUE);
1014 // marked the used clusters
1015 const Cell& cellC = mRoad.getCellsInLayer(layerC)[cellIdC];
1016 event.getClustersInLayer(cellC.getFirstLayerId())[cellC.getFirstClusterIndex()].setUsed(true);
1017 event.getClustersInLayer(cellC.getSecondLayerId())[cellC.getSecondClusterIndex()].setUsed(true);
1018 }
1019 event.getCurrentTrack().sort();
1020 } // end loop cells
1021 } // end loop start layer
1022}
1023
1024//_________________________________________________________________________________________________
1025template <typename T>
1026void Tracker<T>::updateCellStatusInRoad()
1027{
1028 Int_t layerMin, layerMax;
1029 mRoad.getLength(layerMin, layerMax);
1030 for (Int_t layer = layerMin; layer < layerMax; ++layer) {
1031 for (Int_t icell = 0; icell < mRoad.getCellsInLayer(layer).size(); ++icell) {
1032 mRoad.updateCellLevel(layer, icell);
1033 mMaxCellLevel = std::max(mMaxCellLevel, mRoad.getCellLevel(layer, icell));
1034 }
1035 }
1036}
1037
1038//_________________________________________________________________________________________________
1039template <typename T>
1040void Tracker<T>::addCellToCurrentRoad(ROframe<T>& event, const Int_t layer1, const Int_t layer2, const Int_t clsInLayer1, const Int_t clsInLayer2, Int_t& cellId)
1041{
1042 Cell& cell = mRoad.addCellInLayer(layer1, layer2, clsInLayer1, clsInLayer2, cellId);
1043
1044 Cluster& cluster1 = event.getClustersInLayer(layer1)[clsInLayer1];
1045 Cluster& cluster2 = event.getClustersInLayer(layer2)[clsInLayer2];
1046
1047 Float_t coord[6];
1048 coord[0] = cluster1.getX();
1049 coord[1] = cluster1.getY();
1050 coord[2] = cluster1.getZ();
1051 coord[3] = cluster2.getX();
1052 coord[4] = cluster2.getY();
1053 coord[5] = cluster2.getZ();
1054
1055 cell.setCoordinates(coord);
1056 cellId++;
1057}
1058
1059//_________________________________________________________________________________________________
1060template <typename T>
1061void Tracker<T>::addCellToCurrentTrackCA(const Int_t layer1, const Int_t cellId, ROframe<T>& event)
1062{
1063 auto& trackCA = event.getCurrentTrack();
1064 const Cell& cell = mRoad.getCellsInLayer(layer1)[cellId];
1065 const Int_t layer2 = cell.getSecondLayerId();
1066 const Int_t clsInLayer1 = cell.getFirstClusterIndex();
1067 const Int_t clsInLayer2 = cell.getSecondClusterIndex();
1068
1069 Cluster& cluster1 = event.getClustersInLayer(layer1)[clsInLayer1];
1070 Cluster& cluster2 = event.getClustersInLayer(layer2)[clsInLayer2];
1071
1072 MCCompLabel mcCompLabel1 = mUseMC ? event.getClusterLabels(layer1, cluster1.clusterId) : MCCompLabel();
1073 MCCompLabel mcCompLabel2 = mUseMC ? event.getClusterLabels(layer2, cluster2.clusterId) : MCCompLabel();
1074
1075 Int_t extClsIndex;
1076 Int_t clsSize;
1077
1078 if (trackCA.getNumberOfPoints() == 0) {
1079 extClsIndex = event.getClusterExternalIndex(layer2, cluster2.clusterId);
1080 clsSize = event.getClusterSize(layer2, cluster2.clusterId);
1081 trackCA.setPoint(cluster2, layer2, clsInLayer2, mcCompLabel2, extClsIndex, clsSize);
1082 }
1083
1084 extClsIndex = event.getClusterExternalIndex(layer1, cluster1.clusterId);
1085 clsSize = event.getClusterSize(layer2, cluster2.clusterId);
1086 trackCA.setPoint(cluster1, layer1, clsInLayer1, mcCompLabel1, extClsIndex, clsSize);
1087}
1088
1089//_________________________________________________________________________________________________
1090template <typename T>
1092{
1093 for (auto& track : event.getTracks()) {
1094 T outParam = track;
1095 mTrackFitter->initTrack(track);
1096 mTrackFitter->fit(track);
1097 mTrackFitter->initTrack(outParam, true);
1098 mTrackFitter->fit(outParam, true);
1099 track.setOutParam(outParam);
1100 }
1101 return true;
1102}
1103
1104//_________________________________________________________________________________________________
1105template <typename T>
1107{
1108 // Mutex used here to avoid race condition
1109 std::lock_guard<std::mutex> guard(TrackerConfig::sTCMutex);
1110 // Deallocate the memory that was previously reserved for these arrays
1111 TrackerConfig::mBins.reset();
1112 TrackerConfig::mBinsS.reset();
1113}
1114
1115template class Tracker<o2::mft::TrackLTF>;
1116template class Tracker<o2::mft::TrackLTFL>;
1117
1118} // namespace mft
1119} // namespace o2
Base track model for the Barrel, params only, w/o covariance.
A segment connecting two clusters from two planes.
A simple structure for the MFT cluster, used by the standalone track finder.
int32_t i
Class for the standalone track finding.
Standalone classes for the track found by the Linear-Track-Finder (LTF) and by the Cellular-Automaton...
std::ostringstream debug
HMPID cluster implementation.
Definition Cluster.h:27
static std::unique_ptr< BinContainer > mBins
static std::unique_ptr< BinContainer > mBinsS
static void initBinContainers()
static std::mutex sTCMutex
void findLTFTracks(ROframe< T > &)
Definition Tracker.cxx:240
void setBz(Float_t bz)
Definition Tracker.cxx:39
Tracker(bool useMC)
Definition Tracker.cxx:32
void findCATracks(ROframe< T > &)
Definition Tracker.cxx:251
void initializeFinder()
Definition Tracker.cxx:113
void configure(const MFTTrackingParam &trkParam, int trackerID)
Definition Tracker.cxx:48
bool fitTracks(ROframe< T > &)
Definition Tracker.cxx:1091
struct _cl_event * event
Definition glcorearb.h:2982
GLint GLenum GLint x
Definition glcorearb.h:403
GLsizeiptr size
Definition glcorearb.h:659
GLenum coord
Definition glcorearb.h:4109
GLint y
Definition glcorearb.h:270
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLboolean r
Definition glcorearb.h:1233
constexpr float Almost0
constexpr float TwoPI
auto get(const std::byte *buffer, size_t=0)
Definition DataHeader.h:454
void bringTo02PiGen(float &phi)
Definition Utils.h:80
constexpr std::array< Float_t, o2::mft::constants::mft::LayersNumber > RMin
Definition Constants.h:58
constexpr std::array< Float_t, o2::mft::constants::mft::LayersNumber > RMax
Definition Constants.h:59
constexpr std::array< Float_t, LayersNumber > InverseLayerZCoordinate()
Definition Constants.h:48
constexpr Int_t LayersNumber
Definition Constants.h:37
constexpr std::array< Float_t, LayersNumber > LayerZCoordinate()
Definition Constants.h:44
constexpr Int_t DisksNumber
Definition Constants.h:38
value_T step
Definition TrackUtils.h:42
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
bool FullClusterScan
Special version for TED shots and cosmics, with full scan of the clusters.
float cutMultClusHigh
reject ROF with estimated cluster mult. below this value (no cut if <0)
Bool_t CAConeRadius
road for CA algo : cylinder or cone (default)
Bool_t LTFConeRadius
road for LTF algo : cylinder or cone (default)
bool irFramesOnly
reject ROF with estimated cluster mult. above this value (no cut if <0)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"