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
2024namespace 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-
5731void 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