@@ -221,6 +221,9 @@ void TrackInterpolation::prepareInputTrackSample(const o2::globaltracking::RecoC
221221 int nv = vtxRefs.size () - 1 ;
222222 GTrackID::mask_t allowedSources = GTrackID::getSourcesMask (" ITS-TPC,ITS-TPC-TRD,ITS-TPC-TOF,ITS-TPC-TRD-TOF" ) & mSourcesConfigured ;
223223 constexpr std::array<int , 3 > SrcFast = {int (GTrackID::ITSTPCTRD), int (GTrackID::ITSTPCTOF), int (GTrackID::ITSTPCTRDTOF)};
224+ if (mParams ->refitITS ) {
225+ mITSRefitSeedID .resize (mRecoCont ->getITSTracks ().size (), -1 );
226+ }
224227
225228 for (int iv = 0 ; iv < nv; iv++) {
226229 LOGP (debug, " processing PV {} of {}" , iv, nv);
@@ -281,6 +284,7 @@ void TrackInterpolation::prepareInputTrackSample(const o2::globaltracking::RecoC
281284 mGIDtables .push_back (gidTable);
282285 mTrackTimes .push_back (pv.getTimeStamp ().getTimeStamp ());
283286 mTrackIndices [mTrackTypes [vid.getSource ()]].push_back (nTrackSeeds++);
287+ mTrackPVID .push_back (iv);
284288 }
285289 }
286290 }
@@ -360,13 +364,13 @@ void TrackInterpolation::process()
360364 if (mParams ->enableTrackDownsampling && !isTrackSelected (mSeeds [seedIndex])) {
361365 continue ;
362366 }
363-
364367 auto addPart = [this , seedIndex](GTrackID::Source src) {
365368 this ->mGIDs .push_back (this ->mGIDtables [seedIndex][src]);
366369 this ->mGIDtables .push_back (this ->mRecoCont ->getSingleDetectorRefs (this ->mGIDs .back ()));
367370 this ->mTrackTimes .push_back (this ->mTrackTimes [seedIndex]);
368371 this ->mSeeds .push_back (this ->mSeeds [seedIndex]);
369372 this ->mParentID .push_back (seedIndex); // store parent seed id
373+ this ->mTrackPVID .push_back (this ->mTrackPVID [seedIndex]);
370374 };
371375
372376 GTrackID::mask_t partsAdded;
@@ -450,9 +454,12 @@ void TrackInterpolation::interpolateTrack(int iSeed)
450454 (*trackDataExtended).clsITS .push_back (clsITS);
451455 }
452456 }
457+ if (mParams ->refitITS && !refITSTrack (gidTable[GTrackID::ITS], iSeed)) {
458+ return ;
459+ }
453460 trackData.gid = mGIDs [iSeed];
454461 trackData.par = mSeeds [iSeed];
455- auto & trkWork = mSeeds [iSeed];
462+ auto trkWork = mSeeds [iSeed];
456463 o2::track::TrackPar trkInner{trkWork};
457464 // reset the cache array (sufficient to set cluster available to zero)
458465 for (auto & elem : mCache ) {
@@ -734,6 +741,27 @@ void TrackInterpolation::interpolateTrack(int iSeed)
734741 trackData.nExtDetResid ++;
735742 }
736743 }
744+ if (!stopPropagation) { // add residual to PV
745+ const auto & pv = mRecoCont ->getPrimaryVertices ()[mTrackPVID [iSeed]];
746+ o2::math_utils::Point3D<float > vtx{pv.getX (), pv.getY (), pv.getZ ()};
747+ if (!propagator->propagateToDCA (vtx, trkWorkITS, mBz , mParams ->maxStep , mMatCorr )) {
748+ LOGP (debug, " Failed propagation to DCA to PV ({} {} {}), {}" , pv.getX (), pv.getY (), pv.getZ (), trkWorkITS.asString ());
749+ stopPropagation = true ;
750+ break ;
751+ }
752+ // rotate PV to the track frame
753+ float sn, cs, alpha = trkWorkITS.getAlpha ();
754+ math_utils::detail::bringToPMPi (alpha);
755+ math_utils::detail::sincos<float >(alpha, sn, cs);
756+ float xv = vtx.X () * cs + vtx.Y () * sn, yv = -vtx.X () * sn + vtx.Y () * cs, zv = vtx.Z ();
757+ auto dy = yv - trkWorkITS.getY ();
758+ auto dz = zv - trkWorkITS.getZ ();
759+ if ((std::abs (dy) < param::MaxResid) && (std::abs (dz) < param::MaxResid) && (std::abs (trkWorkITS.getY ()) < param::MaxY) && (std::abs (trkWorkITS.getZ ()) < param::MaxZ) && abs (xv) < param::MaxVtxX) {
760+ short compXV = static_cast <short >(xv * 0x7fff / param::MaxVtxX);
761+ mClRes .emplace_back (dy, dz, alpha / TMath::Pi (), trkWorkITS.getY (), trkWorkITS.getZ (), 190 , -1 , compXV);
762+ trackData.nExtDetResid ++;
763+ }
764+ }
737765 break ;
738766 }
739767 }
@@ -826,6 +854,9 @@ void TrackInterpolation::extrapolateTrack(int iSeed)
826854 (*trackDataExtended).clsITS .push_back (clsITS);
827855 }
828856 }
857+ if (mParams ->refitITS && !refITSTrack (gidTable[GTrackID::ITS], iSeed)) {
858+ return ;
859+ }
829860 trackData.gid = mGIDs [iSeed];
830861 trackData.par = mSeeds [iSeed];
831862
@@ -987,7 +1018,7 @@ void TrackInterpolation::extrapolateTrack(int iSeed)
9871018 int chip = cls.getSensorID ();
9881019 float chipX, chipAlpha;
9891020 geom->getSensorXAlphaRefPlane (cls.getSensorID (), chipX, chipAlpha);
990- if (!trkWorkITS.rotate (chipAlpha) || !propagator->PropagateToXBxByBz (trkWorkITS, chipX, mParams ->maxSnp , mParams ->maxStep , mMatCorr )) {
1021+ if (!trkWorkITS.rotate (chipAlpha) || !propagator->propagateToX (trkWorkITS, chipX, mBz , mParams ->maxSnp , mParams ->maxStep , mMatCorr )) {
9911022 LOGP (debug, " Failed final propagation to ITS X={} alpha={}" , chipX, chipAlpha);
9921023 stopPropagation = true ;
9931024 break ;
@@ -1000,6 +1031,27 @@ void TrackInterpolation::extrapolateTrack(int iSeed)
10001031 trackData.nExtDetResid ++;
10011032 }
10021033 }
1034+ if (!stopPropagation) { // add residual to PV
1035+ const auto & pv = mRecoCont ->getPrimaryVertices ()[mTrackPVID [iSeed]];
1036+ o2::math_utils::Point3D<float > vtx{pv.getX (), pv.getY (), pv.getZ ()};
1037+ if (!propagator->propagateToDCA (vtx, trkWorkITS, mBz , mParams ->maxStep , mMatCorr )) {
1038+ LOGP (debug, " Failed propagation to DCA to PV ({} {} {}), {}" , pv.getX (), pv.getY (), pv.getZ (), trkWorkITS.asString ());
1039+ stopPropagation = true ;
1040+ break ;
1041+ }
1042+ // rotate PV to the track frame
1043+ float sn, cs, alpha = trkWorkITS.getAlpha ();
1044+ math_utils::detail::bringToPMPi (alpha);
1045+ math_utils::detail::sincos<float >(alpha, sn, cs);
1046+ float xv = vtx.X () * cs + vtx.Y () * sn, yv = -vtx.X () * sn + vtx.Y () * cs, zv = vtx.Z ();
1047+ auto dy = yv - trkWorkITS.getY ();
1048+ auto dz = zv - trkWorkITS.getZ ();
1049+ if ((std::abs (dy) < param::MaxResid) && (std::abs (dz) < param::MaxResid) && (std::abs (trkWorkITS.getY ()) < param::MaxY) && (std::abs (trkWorkITS.getZ ()) < param::MaxZ) && abs (xv) < param::MaxVtxX) {
1050+ short compXV = static_cast <short >(xv * 0x7fff / param::MaxVtxX);
1051+ mClRes .emplace_back (dy, dz, alpha / TMath::Pi (), trkWorkITS.getY (), trkWorkITS.getZ (), 190 , -1 , compXV);
1052+ trackData.nExtDetResid ++;
1053+ }
1054+ }
10031055 break ;
10041056 }
10051057 }
@@ -1403,6 +1455,8 @@ void TrackInterpolation::reset()
14031455 mGIDtables .clear ();
14041456 mTrackTimes .clear ();
14051457 mSeeds .clear ();
1458+ mITSRefitSeedID .clear ();
1459+ mTrackPVID .clear ();
14061460}
14071461
14081462// ______________________________________________
@@ -1416,3 +1470,50 @@ void TrackInterpolation::setTPCVDrift(const o2::tpc::VDriftCorrFact& v)
14161470 o2::tpc::TPCFastTransformHelperO2::instance ()->updateCalibration (*mFastTransform , 0 , 1.0 , mTPCVDriftRef , mTPCDriftTimeOffsetRef );
14171471 }
14181472}
1473+
1474+ // ______________________________________________
1475+ bool TrackInterpolation::refITSTrack (o2::dataformats::GlobalTrackID gid, int seedID)
1476+ {
1477+ // refit ITS track outwards taking PID (unless already refitted) from the seed and reassign to the seed
1478+ auto & seed = mSeeds [seedID];
1479+ int refitID = mITSRefitSeedID [gid.getIndex ()];
1480+ if (refitID >= 0 ) { // track was already refitted
1481+ if (mSeeds [refitID].getPID () == seed.getPID ()) {
1482+ seed = mSeeds [refitID];
1483+ }
1484+ return true ;
1485+ }
1486+ const auto & trkITS = mRecoCont ->getITSTrack (gid);
1487+ // fetch clusters
1488+ auto nCl = trkITS.getNumberOfClusters ();
1489+ auto clEntry = trkITS.getFirstClusterEntry ();
1490+ o2::track::TrackParCov track (trkITS); // start from the inner param
1491+ track.setPID (seed.getPID ());
1492+ o2::track::TrackPar refLin (track); // and use it also as linearization reference
1493+ auto geom = o2::its::GeometryTGeo::Instance ();
1494+ auto prop = o2::base::Propagator::Instance ();
1495+ for (int iCl = nCl - 1 ; iCl >= 0 ; iCl--) { // clusters are stored from outer to inner layers
1496+ const auto & cls = mITSClustersArray [mITSTrackClusIdx [clEntry + iCl]];
1497+ int chip = cls.getSensorID ();
1498+ float chipX, chipAlpha;
1499+ geom->getSensorXAlphaRefPlane (cls.getSensorID (), chipX, chipAlpha);
1500+ if (!track.rotate (chipAlpha, refLin, mBz )) {
1501+ LOGP (debug, " failed to rotate ITS tracks to alpha={} for the refit: {}" , chipAlpha, track.asString ());
1502+ return false ;
1503+ }
1504+ if (!prop->propagateToX (track, refLin, cls.getX (), mBz , o2::base::PropagatorImpl<float >::MAX_SIN_PHI, o2::base::PropagatorImpl<float >::MAX_STEP, o2::base::PropagatorF::MatCorrType::USEMatCorrLUT)) {
1505+ LOGP (debug, " failed to propagate ITS tracks to X={}: {}" , cls.getX (), track.asString ());
1506+ return false ;
1507+ }
1508+ std::array<float , 2 > posTF{cls.getY (), cls.getZ ()};
1509+ std::array<float , 3 > covTF{cls.getSigmaY2 (), cls.getSigmaYZ (), cls.getSigmaZ2 ()};
1510+ if (!track.update (posTF, covTF)) {
1511+ LOGP (debug, " failed to update ITS tracks by cluster ({},{})/({},{},{})" , track.asString (), cls.getY (), cls.getZ (), cls.getSigmaY2 (), cls.getSigmaYZ (), cls.getSigmaZ2 ());
1512+ return false ;
1513+ }
1514+ }
1515+ seed = track;
1516+ // memorize that this ITS track was already refitted
1517+ mITSRefitSeedID [gid.getIndex ()] = seedID;
1518+ return true ;
1519+ }
0 commit comments