Skip to content

Commit 5e3822f

Browse files
njacazioalibuild
andauthored
[ALICE3] Update FastTracker (#11570)
Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent bbd15bf commit 5e3822f

File tree

2 files changed

+139
-146
lines changed

2 files changed

+139
-146
lines changed

ALICE3/Core/FastTracker.cxx

Lines changed: 90 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12-
#include <vector>
13-
#include <string>
12+
#include "FastTracker.h"
13+
14+
#include "ReconstructionDataFormats/TrackParametrization.h"
15+
1416
#include "TMath.h"
1517
#include "TMatrixD.h"
16-
#include "TRandom.h"
1718
#include "TMatrixDSymEigen.h"
18-
#include "FastTracker.h"
19+
#include "TRandom.h"
20+
21+
#include <string>
22+
#include <vector>
1923

2024
namespace o2
2125
{
@@ -24,43 +28,24 @@ namespace fastsim
2428

2529
// +-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+
2630

27-
FastTracker::FastTracker()
28-
{
29-
// base constructor
30-
magneticField = 20; // in kiloGauss
31-
applyZacceptance = false;
32-
applyMSCorrection = true;
33-
applyElossCorrection = true;
34-
applyEffCorrection = true;
35-
covMatFactor = 0.99f;
36-
verboseLevel = 0;
37-
38-
// last fast-tracked track properties
39-
covMatOK = 0;
40-
covMatNotOK = 0;
41-
nIntercepts = 0;
42-
nSiliconPoints = 0;
43-
nGasPoints = 0;
44-
45-
maxRadiusSlowDet = 10;
46-
integrationTime = 0.02; // ms
47-
crossSectionMinB = 8;
48-
dNdEtaCent = 2200;
49-
dNdEtaMinB = 1;
50-
avgRapidity = 0.45;
51-
sigmaD = 6.0;
52-
luminosity = 1.e27;
53-
otherBackground = 0.0; // [0, 1]
54-
upcBackgroundMultiplier = 1.0;
55-
}
56-
5731
void FastTracker::AddLayer(TString name, float r, float z, float x0, float xrho, float resRPhi, float resZ, float eff, int type)
5832
{
5933
DetLayer newLayer(name, r, z, x0, xrho, resRPhi, resZ, eff, type);
6034
// Check that efficient layers are not inert layers
6135
if (newLayer.getEfficiency() > 0.0f && newLayer.isInert()) {
6236
LOG(error) << "Layer " << name << " with efficiency > 0.0 should not be inert";
6337
}
38+
// Layers should be ordered by increasing radius, check this
39+
if (!layers.empty() && newLayer.getRadius() < layers.back().getRadius()) {
40+
LOG(fatal) << "Layer " << newLayer << " is not ordered correctly, it should be after layer " << layers.back();
41+
}
42+
// Layers should all have different names
43+
for (const auto& layer : layers) {
44+
if (layer.getName() == newLayer.getName()) {
45+
LOG(fatal) << "Layer with name " << newLayer.getName() << " already exists in FastTracker layers";
46+
}
47+
}
48+
// Add the new layer to the layers vector
6449
layers.push_back(newLayer);
6550
}
6651

@@ -78,7 +63,7 @@ DetLayer FastTracker::GetLayer(int layer, bool ignoreBarrelLayers) const
7863
return layers[layerIdx];
7964
}
8065

81-
int FastTracker::GetLayerIndex(std::string name) const
66+
int FastTracker::GetLayerIndex(const std::string& name) const
8267
{
8368
int i = 0;
8469
for (const auto& layer : layers) {
@@ -211,9 +196,9 @@ float FastTracker::Dist(float z, float r)
211196
// https://github.com/AliceO2Group/DelphesO2/blob/master/src/DetectorK/DetectorK.cxx#L743
212197
int index = 1;
213198
int nSteps = 301;
214-
double dist = 0.0;
215-
double dz0 = (4 * sigmaD - (-4) * sigmaD / (nSteps = 1));
216-
double z0 = 0.0;
199+
float dist = 0.0;
200+
float dz0 = (4 * sigmaD - (-4) * sigmaD / (nSteps = 1));
201+
float z0 = 0.0;
217202
for (int i = 0; i < nSteps; i++) {
218203
if (i == nSteps - 1)
219204
index = 1;
@@ -243,7 +228,7 @@ float FastTracker::IntegratedHitDensity(float multiplicity, float radius)
243228
// porting of DetektorK::IntegratedHitDensity
244229
// see here:
245230
// https://github.com/AliceO2Group/DelphesO2/blob/master/src/DetectorK/DetectorK.cxx#L712
246-
float zdcHz = luminosity * 1.e24 * crossSectionMinB;
231+
float zdcHz = luminosity * 1.e24 * mCrossSectionMinB;
247232
float den = zdcHz * integrationTime / 1000. * multiplicity * Dist(0., radius) / (o2::constants::math::TwoPI * radius);
248233
if (den < OneEventHitDensity(multiplicity, radius))
249234
den = OneEventHitDensity(multiplicity, radius);
@@ -301,6 +286,7 @@ float FastTracker::ProbGoodChiSqHit(float radius, float searchRadiusRPhi, float
301286
// returns number of intercepts (generic for now)
302287
int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackParCov& outputTrack, const float nch)
303288
{
289+
dNdEtaCent = nch; // set the number of charged particles per unit rapidity
304290
hits.clear();
305291
nIntercepts = 0;
306292
nSiliconPoints = 0;
@@ -310,38 +296,54 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
310296
const float initialRadius = std::hypot(posIni[0], posIni[1]);
311297
const float kTrackingMargin = 0.1;
312298
const int kMaxNumberOfDetectors = 20;
299+
if (kMaxNumberOfDetectors < layers.size()) {
300+
LOG(fatal) << "Too many layers in FastTracker, increase kMaxNumberOfDetectors";
301+
return -1; // too many layers
302+
}
303+
int firstActiveLayer = -1; // first layer that is not inert
304+
for (size_t i = 0; i < layers.size(); ++i) {
305+
if (!layers[i].isInert()) {
306+
firstActiveLayer = i;
307+
break;
308+
}
309+
}
310+
if (firstActiveLayer <= 0) {
311+
LOG(fatal) << "No active layers found in FastTracker, check layer setup";
312+
return -2; // no active layers
313+
}
313314
const int xrhosteps = 100;
314315
const bool applyAngularCorrection = true;
315316

316317
goodHitProbability.clear();
317-
for (int i = 0; i < kMaxNumberOfDetectors; ++i)
318+
for (int i = 0; i < kMaxNumberOfDetectors; ++i) {
318319
goodHitProbability.push_back(-1.);
319-
goodHitProbability[0] = 1.;
320+
}
321+
goodHitProbability[0] = 1.; // we use layer zero to accumulate
320322

321323
// +-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+
322324
// Outward pass to find intercepts
323325
int firstLayerReached = -1;
324326
int lastLayerReached = -1;
325327
new (&outputTrack)(o2::track::TrackParCov)(inputTrack);
326-
for (uint32_t il = 0; il < layers.size(); il++) {
328+
for (size_t il = 0; il < layers.size(); il++) {
327329
// check if layer is doable
328-
if (layers[il].getRadius() < initialRadius)
330+
if (layers[il].getRadius() < initialRadius) {
329331
continue; // this layer should not be attempted, but go ahead
332+
}
330333

331334
// check if layer is reached
332335
float targetX = 1e+3;
333-
bool ok = true;
334336
inputTrack.getXatLabR(layers[il].getRadius(), targetX, magneticField);
335337
if (targetX > 999.f) {
336338
LOGF(debug, "Failed to find intercept for layer %d at radius %.2f cm", il, layers[il].getRadius());
337339
break; // failed to find intercept
338340
}
339341

340-
ok = inputTrack.propagateTo(targetX, magneticField);
341-
if (ok && applyMSCorrection && layers[il].getRadiationLength() > 0) {
342+
bool ok = inputTrack.propagateTo(targetX, magneticField);
343+
if (ok && mApplyMSCorrection && layers[il].getRadiationLength() > 0) {
342344
ok = inputTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection);
343345
}
344-
if (ok && applyElossCorrection && layers[il].getDensity() > 0) { // correct in small steps
346+
if (ok && mApplyElossCorrection && layers[il].getDensity() > 0) { // correct in small steps
345347
for (int ise = xrhosteps; ise--;) {
346348
ok = inputTrack.correctForMaterial(0, -layers[il].getDensity() / xrhosteps, applyAngularCorrection);
347349
if (!ok)
@@ -361,7 +363,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
361363
break;
362364
}
363365
}
364-
if (std::abs(inputTrack.getZ()) > layers[il].getZ() && applyZacceptance) {
366+
if (std::abs(inputTrack.getZ()) > layers[il].getZ() && mApplyZacceptance) {
365367
break; // out of acceptance bounds
366368
}
367369

@@ -384,39 +386,19 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
384386
o2::track::TrackParCov inwardTrack(inputTrack);
385387

386388
// Enlarge covariance matrix
387-
std::array<float, 5> trPars = {0.};
388-
for (int ip = 0; ip < 5; ip++) {
389+
std::array<float, o2::track::kNParams> trPars = {0.};
390+
for (int ip = 0; ip < o2::track::kNParams; ip++) {
389391
trPars[ip] = outputTrack.getParam(ip);
390392
}
391-
std::array<float, 15> largeCov = {0.};
392-
enum { kY,
393-
kZ,
394-
kSnp,
395-
kTgl,
396-
kPtI }; // track parameter aliases
397-
enum { kY2,
398-
kYZ,
399-
kZ2,
400-
kYSnp,
401-
kZSnp,
402-
kSnp2,
403-
kYTgl,
404-
kZTgl,
405-
kSnpTgl,
406-
kTgl2,
407-
kYPtI,
408-
kZPtI,
409-
kSnpPtI,
410-
kTglPtI,
411-
kPtI2 }; // cov.matrix aliases
412-
const double kLargeErr2Coord = 5 * 5;
413-
const double kLargeErr2Dir = 0.7 * 0.7;
414-
const double kLargeErr2PtI = 30.5 * 30.5;
415-
for (int ic = 15; ic--;)
393+
static constexpr float kLargeErr2Coord = 5 * 5;
394+
static constexpr float kLargeErr2Dir = 0.7 * 0.7;
395+
static constexpr float kLargeErr2PtI = 30.5 * 30.5;
396+
std::array<float, o2::track::kCovMatSize> largeCov = {0.};
397+
for (int ic = o2::track::kCovMatSize; ic--;)
416398
largeCov[ic] = 0.;
417-
largeCov[kY2] = largeCov[kZ2] = kLargeErr2Coord;
418-
largeCov[kSnp2] = largeCov[kTgl2] = kLargeErr2Dir;
419-
largeCov[kPtI2] = kLargeErr2PtI * trPars[kPtI] * trPars[kPtI];
399+
largeCov[o2::track::CovLabels::kSigY2] = largeCov[o2::track::CovLabels::kSigZ2] = kLargeErr2Coord;
400+
largeCov[o2::track::CovLabels::kSigSnp2] = largeCov[o2::track::CovLabels::kSigTgl2] = kLargeErr2Dir;
401+
largeCov[o2::track::CovLabels::kSigQ2Pt2] = kLargeErr2PtI * trPars[o2::track::ParLabels::kQ2Pt] * trPars[o2::track::ParLabels::kQ2Pt];
420402

421403
inwardTrack.setCov(largeCov);
422404
inwardTrack.checkCovariance();
@@ -434,7 +416,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
434416
continue; // failed to propagate
435417
}
436418

437-
if (std::abs(inputTrack.getZ()) > layers[il].getZ() && applyZacceptance) {
419+
if (std::abs(inputTrack.getZ()) > layers[il].getZ() && mApplyZacceptance) {
438420
continue; // out of acceptance bounds but continue inwards
439421
}
440422

@@ -444,10 +426,10 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
444426
std::vector<float> thisHit = {spacePoint[0], spacePoint[1], spacePoint[2]};
445427

446428
// towards adding cluster: move to track alpha
447-
double alpha = inwardTrack.getAlpha();
448-
double xyz1[3]{
449-
TMath::Cos(alpha) * spacePoint[0] + TMath::Sin(alpha) * spacePoint[1],
450-
-TMath::Sin(alpha) * spacePoint[0] + TMath::Cos(alpha) * spacePoint[1],
429+
float alpha = inwardTrack.getAlpha();
430+
float xyz1[3]{
431+
std::cos(alpha) * spacePoint[0] + std::sin(alpha) * spacePoint[1],
432+
-std::sin(alpha) * spacePoint[0] + std::cos(alpha) * spacePoint[1],
451433
spacePoint[2]};
452434
if (!inwardTrack.propagateTo(xyz1[0], magneticField))
453435
continue;
@@ -462,15 +444,15 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
462444
inwardTrack.checkCovariance();
463445
}
464446

465-
if (applyMSCorrection && layers[il].getRadiationLength() > 0) {
447+
if (mApplyMSCorrection && layers[il].getRadiationLength() > 0) {
466448
if (!inputTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection)) {
467449
return -6;
468450
}
469451
if (!inwardTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection)) {
470452
return -6;
471453
}
472454
}
473-
if (applyElossCorrection && layers[il].getDensity() > 0) {
455+
if (mApplyElossCorrection && layers[il].getDensity() > 0) {
474456
for (int ise = xrhosteps; ise--;) { // correct in small steps
475457
if (!inputTrack.correctForMaterial(0, layers[il].getDensity() / xrhosteps, applyAngularCorrection)) {
476458
return -7;
@@ -488,19 +470,21 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
488470

489471
hits.push_back(thisHit);
490472

491-
if (applyEffCorrection && !layers[il].isInert()) { // good hit probability calculation
492-
double sigYCmb = o2::math_utils::sqrt(inwardTrack.getSigmaY2() + layers[il].getResolutionRPhi() * layers[il].getResolutionRPhi());
493-
double sigZCmb = o2::math_utils::sqrt(inwardTrack.getSigmaZ2() + layers[il].getResolutionZ() * layers[il].getResolutionZ());
473+
if (!layers[il].isInert()) { // good hit probability calculation
474+
float sigYCmb = o2::math_utils::sqrt(inwardTrack.getSigmaY2() + layers[il].getResolutionRPhi() * layers[il].getResolutionRPhi());
475+
float sigZCmb = o2::math_utils::sqrt(inwardTrack.getSigmaZ2() + layers[il].getResolutionZ() * layers[il].getResolutionZ());
494476
goodHitProbability[il] = ProbGoodChiSqHit(layers[il].getRadius() * 100, sigYCmb * 100, sigZCmb * 100);
495477
goodHitProbability[0] *= goodHitProbability[il];
496478
}
497479
}
498480

499481
// backpropagate to original radius
500482
float finalX = 1e+3;
501-
inwardTrack.getXatLabR(initialRadius, finalX, magneticField);
502-
if (finalX > 999)
483+
bool inPropStatus = inwardTrack.getXatLabR(initialRadius, finalX, magneticField);
484+
if (finalX > 999) {
485+
LOG(debug) << "Failed to find intercept for initial radius " << initialRadius << " cm, x = " << finalX << " and status " << inPropStatus << " and sn = " << inwardTrack.getSnp() << " r = " << inwardTrack.getY() * inwardTrack.getY();
503486
return -3; // failed to find intercept
487+
}
504488

505489
if (!inwardTrack.propagateTo(finalX, magneticField)) {
506490
return -4; // failed to propagate
@@ -511,17 +495,15 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
511495
return nIntercepts;
512496

513497
// generate efficiency
514-
if (applyEffCorrection) {
515-
dNdEtaCent = nch;
516-
float eff = 1.;
517-
for (int i = 0; i < kMaxNumberOfDetectors; i++) {
518-
float iGoodHit = goodHitProbability[i];
519-
if (iGoodHit <= 0)
520-
continue;
521-
522-
eff *= iGoodHit;
523-
}
498+
float eff = 1.;
499+
for (int i = 0; i < kMaxNumberOfDetectors; i++) {
500+
float iGoodHit = goodHitProbability[i];
501+
if (iGoodHit <= 0)
502+
continue;
524503

504+
eff *= iGoodHit;
505+
}
506+
if (mApplyEffCorrection) {
525507
if (gRandom->Uniform() > eff)
526508
return -8;
527509
}
@@ -530,11 +512,11 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
530512
outputTrack.checkCovariance();
531513

532514
// Use covariance matrix based smearing
533-
std::array<double, 15> covMat = {0.};
534-
for (int ii = 0; ii < 15; ii++)
515+
std::array<float, o2::track::kCovMatSize> covMat = {0.};
516+
for (int ii = 0; ii < o2::track::kCovMatSize; ii++)
535517
covMat[ii] = outputTrack.getCov()[ii];
536518
TMatrixDSym m(5);
537-
double fcovm[5][5];
519+
float fcovm[5][5];
538520

539521
for (int ii = 0, k = 0; ii < 5; ++ii) {
540522
for (int j = 0; j < ii + 1; ++j, ++k) {
@@ -544,7 +526,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
544526
}
545527

546528
// evaluate ruben's conditional, regularise
547-
bool makePositiveDefinite = (covMatFactor > -1e-5); // apply fix
529+
const bool makePositiveDefinite = (covMatFactor > -1e-5); // apply fix
548530
bool rubenConditional = false;
549531
for (int ii = 0; ii < 5; ii++) {
550532
for (int jj = 0; jj < 5; jj++) {
@@ -571,7 +553,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
571553
}
572554

573555
if (negEigVal && rubenConditional && makePositiveDefinite) {
574-
if (verboseLevel > 0) {
556+
if (mVerboseLevel > 0) {
575557
LOG(info) << "WARNING: this diagonalization (at pt = " << inputTrack.getPt() << ") has negative eigenvalues despite Ruben's fix! Please be careful!";
576558
LOG(info) << "Printing info:";
577559
LOG(info) << "Kalman updates: " << nIntercepts;
@@ -585,9 +567,9 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
585567
covMatOK++;
586568

587569
// transform parameter vector and smear
588-
double params_[5];
570+
float params_[5];
589571
for (int ii = 0; ii < 5; ++ii) {
590-
double val = 0.;
572+
float val = 0.;
591573
for (int j = 0; j < 5; ++j)
592574
val += eigVec[j][ii] * outputTrack.getParam(j);
593575
// smear parameters according to eigenvalues
@@ -598,7 +580,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
598580
eigVec.Invert();
599581
// transform back params vector
600582
for (int ii = 0; ii < 5; ++ii) {
601-
double val = 0.;
583+
float val = 0.;
602584
for (int j = 0; j < 5; ++j)
603585
val += eigVec[j][ii] * params_[j];
604586
outputTrack.setParam(val, ii);

0 commit comments

Comments
 (0)