Skip to content

Commit 9598848

Browse files
committed
Update FastTracker
1 parent 7d7062b commit 9598848

File tree

2 files changed

+129
-137
lines changed

2 files changed

+129
-137
lines changed

ALICE3/Core/FastTracker.cxx

Lines changed: 80 additions & 99 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);
@@ -310,38 +295,54 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
310295
const float initialRadius = std::hypot(posIni[0], posIni[1]);
311296
const float kTrackingMargin = 0.1;
312297
const int kMaxNumberOfDetectors = 20;
298+
if (kMaxNumberOfDetectors < layers.size()) {
299+
LOG(fatal) << "Too many layers in FastTracker, increase kMaxNumberOfDetectors";
300+
return -1; // too many layers
301+
}
302+
int firstActiveLayer = -1; // first layer that is not inert
303+
for (size_t i = 0; i < layers.size(); ++i) {
304+
if (!layers[i].isInert()) {
305+
firstActiveLayer = i;
306+
break;
307+
}
308+
}
309+
if (firstActiveLayer <= 0) {
310+
LOG(fatal) << "No active layers found in FastTracker, check layer setup";
311+
return -2; // no active layers
312+
}
313313
const int xrhosteps = 100;
314314
const bool applyAngularCorrection = true;
315315

316316
goodHitProbability.clear();
317-
for (int i = 0; i < kMaxNumberOfDetectors; ++i)
317+
for (int i = 0; i < kMaxNumberOfDetectors; ++i) {
318318
goodHitProbability.push_back(-1.);
319-
goodHitProbability[0] = 1.;
319+
}
320+
goodHitProbability[0] = 1.; // we use layer zero to accumulate
320321

321322
// +-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+
322323
// Outward pass to find intercepts
323324
int firstLayerReached = -1;
324325
int lastLayerReached = -1;
325326
new (&outputTrack)(o2::track::TrackParCov)(inputTrack);
326-
for (uint32_t il = 0; il < layers.size(); il++) {
327+
for (size_t il = 0; il < layers.size(); il++) {
327328
// check if layer is doable
328-
if (layers[il].getRadius() < initialRadius)
329+
if (layers[il].getRadius() < initialRadius) {
329330
continue; // this layer should not be attempted, but go ahead
331+
}
330332

331333
// check if layer is reached
332334
float targetX = 1e+3;
333-
bool ok = true;
334335
inputTrack.getXatLabR(layers[il].getRadius(), targetX, magneticField);
335336
if (targetX > 999.f) {
336337
LOGF(debug, "Failed to find intercept for layer %d at radius %.2f cm", il, layers[il].getRadius());
337338
break; // failed to find intercept
338339
}
339340

340-
ok = inputTrack.propagateTo(targetX, magneticField);
341-
if (ok && applyMSCorrection && layers[il].getRadiationLength() > 0) {
341+
bool ok = inputTrack.propagateTo(targetX, magneticField);
342+
if (ok && mApplyMSCorrection && layers[il].getRadiationLength() > 0) {
342343
ok = inputTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection);
343344
}
344-
if (ok && applyElossCorrection && layers[il].getDensity() > 0) { // correct in small steps
345+
if (ok && mApplyElossCorrection && layers[il].getDensity() > 0) { // correct in small steps
345346
for (int ise = xrhosteps; ise--;) {
346347
ok = inputTrack.correctForMaterial(0, -layers[il].getDensity() / xrhosteps, applyAngularCorrection);
347348
if (!ok)
@@ -361,7 +362,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
361362
break;
362363
}
363364
}
364-
if (std::abs(inputTrack.getZ()) > layers[il].getZ() && applyZacceptance) {
365+
if (std::abs(inputTrack.getZ()) > layers[il].getZ() && mApplyZacceptance) {
365366
break; // out of acceptance bounds
366367
}
367368

@@ -384,39 +385,19 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
384385
o2::track::TrackParCov inwardTrack(inputTrack);
385386

386387
// Enlarge covariance matrix
387-
std::array<float, 5> trPars = {0.};
388-
for (int ip = 0; ip < 5; ip++) {
388+
std::array<float, o2::track::kNParams> trPars = {0.};
389+
for (int ip = 0; ip < o2::track::kNParams; ip++) {
389390
trPars[ip] = outputTrack.getParam(ip);
390391
}
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--;)
392+
static constexpr float kLargeErr2Coord = 5 * 5;
393+
static constexpr float kLargeErr2Dir = 0.7 * 0.7;
394+
static constexpr float kLargeErr2PtI = 30.5 * 30.5;
395+
std::array<float, o2::track::kCovMatSize> largeCov = {0.};
396+
for (int ic = o2::track::kCovMatSize; ic--;)
416397
largeCov[ic] = 0.;
417-
largeCov[kY2] = largeCov[kZ2] = kLargeErr2Coord;
418-
largeCov[kSnp2] = largeCov[kTgl2] = kLargeErr2Dir;
419-
largeCov[kPtI2] = kLargeErr2PtI * trPars[kPtI] * trPars[kPtI];
398+
largeCov[o2::track::CovLabels::kSigY2] = largeCov[o2::track::CovLabels::kSigZ2] = kLargeErr2Coord;
399+
largeCov[o2::track::CovLabels::kSigSnp2] = largeCov[o2::track::CovLabels::kSigTgl2] = kLargeErr2Dir;
400+
largeCov[o2::track::CovLabels::kSigQ2Pt2] = kLargeErr2PtI * trPars[o2::track::ParLabels::kQ2Pt] * trPars[o2::track::ParLabels::kQ2Pt];
420401

421402
inwardTrack.setCov(largeCov);
422403
inwardTrack.checkCovariance();
@@ -434,7 +415,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
434415
continue; // failed to propagate
435416
}
436417

437-
if (std::abs(inputTrack.getZ()) > layers[il].getZ() && applyZacceptance) {
418+
if (std::abs(inputTrack.getZ()) > layers[il].getZ() && mApplyZacceptance) {
438419
continue; // out of acceptance bounds but continue inwards
439420
}
440421

@@ -444,8 +425,8 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
444425
std::vector<float> thisHit = {spacePoint[0], spacePoint[1], spacePoint[2]};
445426

446427
// towards adding cluster: move to track alpha
447-
double alpha = inwardTrack.getAlpha();
448-
double xyz1[3]{
428+
float alpha = inwardTrack.getAlpha();
429+
float xyz1[3]{
449430
TMath::Cos(alpha) * spacePoint[0] + TMath::Sin(alpha) * spacePoint[1],
450431
-TMath::Sin(alpha) * spacePoint[0] + TMath::Cos(alpha) * spacePoint[1],
451432
spacePoint[2]};
@@ -462,15 +443,15 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
462443
inwardTrack.checkCovariance();
463444
}
464445

465-
if (applyMSCorrection && layers[il].getRadiationLength() > 0) {
446+
if (mApplyMSCorrection && layers[il].getRadiationLength() > 0) {
466447
if (!inputTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection)) {
467448
return -6;
468449
}
469450
if (!inwardTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection)) {
470451
return -6;
471452
}
472453
}
473-
if (applyElossCorrection && layers[il].getDensity() > 0) {
454+
if (mApplyElossCorrection && layers[il].getDensity() > 0) {
474455
for (int ise = xrhosteps; ise--;) { // correct in small steps
475456
if (!inputTrack.correctForMaterial(0, layers[il].getDensity() / xrhosteps, applyAngularCorrection)) {
476457
return -7;
@@ -488,19 +469,21 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
488469

489470
hits.push_back(thisHit);
490471

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());
472+
if (!layers[il].isInert()) { // good hit probability calculation
473+
float sigYCmb = o2::math_utils::sqrt(inwardTrack.getSigmaY2() + layers[il].getResolutionRPhi() * layers[il].getResolutionRPhi());
474+
float sigZCmb = o2::math_utils::sqrt(inwardTrack.getSigmaZ2() + layers[il].getResolutionZ() * layers[il].getResolutionZ());
494475
goodHitProbability[il] = ProbGoodChiSqHit(layers[il].getRadius() * 100, sigYCmb * 100, sigZCmb * 100);
495476
goodHitProbability[0] *= goodHitProbability[il];
496477
}
497478
}
498479

499480
// backpropagate to original radius
500481
float finalX = 1e+3;
501-
inwardTrack.getXatLabR(initialRadius, finalX, magneticField);
502-
if (finalX > 999)
482+
bool inPropStatus = inwardTrack.getXatLabR(initialRadius, finalX, magneticField);
483+
if (finalX > 999) {
484+
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();
503485
return -3; // failed to find intercept
486+
}
504487

505488
if (!inwardTrack.propagateTo(finalX, magneticField)) {
506489
return -4; // failed to propagate
@@ -511,8 +494,6 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
511494
return nIntercepts;
512495

513496
// generate efficiency
514-
if (applyEffCorrection) {
515-
dNdEtaCent = nch;
516497
float eff = 1.;
517498
for (int i = 0; i < kMaxNumberOfDetectors; i++) {
518499
float iGoodHit = goodHitProbability[i];
@@ -521,7 +502,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
521502

522503
eff *= iGoodHit;
523504
}
524-
505+
if (mApplyEffCorrection) {
525506
if (gRandom->Uniform() > eff)
526507
return -8;
527508
}
@@ -530,11 +511,11 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
530511
outputTrack.checkCovariance();
531512

532513
// Use covariance matrix based smearing
533-
std::array<double, 15> covMat = {0.};
534-
for (int ii = 0; ii < 15; ii++)
514+
std::array<float, o2::track::kCovMatSize> covMat = {0.};
515+
for (int ii = 0; ii < o2::track::kCovMatSize; ii++)
535516
covMat[ii] = outputTrack.getCov()[ii];
536517
TMatrixDSym m(5);
537-
double fcovm[5][5];
518+
float fcovm[5][5];
538519

539520
for (int ii = 0, k = 0; ii < 5; ++ii) {
540521
for (int j = 0; j < ii + 1; ++j, ++k) {
@@ -544,7 +525,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
544525
}
545526

546527
// evaluate ruben's conditional, regularise
547-
bool makePositiveDefinite = (covMatFactor > -1e-5); // apply fix
528+
const bool makePositiveDefinite = (covMatFactor > -1e-5); // apply fix
548529
bool rubenConditional = false;
549530
for (int ii = 0; ii < 5; ii++) {
550531
for (int jj = 0; jj < 5; jj++) {
@@ -571,7 +552,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
571552
}
572553

573554
if (negEigVal && rubenConditional && makePositiveDefinite) {
574-
if (verboseLevel > 0) {
555+
if (mVerboseLevel > 0) {
575556
LOG(info) << "WARNING: this diagonalization (at pt = " << inputTrack.getPt() << ") has negative eigenvalues despite Ruben's fix! Please be careful!";
576557
LOG(info) << "Printing info:";
577558
LOG(info) << "Kalman updates: " << nIntercepts;
@@ -585,9 +566,9 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
585566
covMatOK++;
586567

587568
// transform parameter vector and smear
588-
double params_[5];
569+
float params_[5];
589570
for (int ii = 0; ii < 5; ++ii) {
590-
double val = 0.;
571+
float val = 0.;
591572
for (int j = 0; j < 5; ++j)
592573
val += eigVec[j][ii] * outputTrack.getParam(j);
593574
// smear parameters according to eigenvalues
@@ -598,7 +579,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa
598579
eigVec.Invert();
599580
// transform back params vector
600581
for (int ii = 0; ii < 5; ++ii) {
601-
double val = 0.;
582+
float val = 0.;
602583
for (int j = 0; j < 5; ++j)
603584
val += eigVec[j][ii] * params_[j];
604585
outputTrack.setParam(val, ii);

0 commit comments

Comments
 (0)