@@ -114,6 +114,7 @@ struct PhotonConversionBuilder {
114114 // Operation and minimisation criteria
115115 Configurable<double > d_bz_input{" d_bz" , -999 , " bz field, -999 is automatic" };
116116 Configurable<int > useMatCorrType{" useMatCorrType" , 0 , " 0: none, 1: TGeo, 2: LUT" };
117+ Configurable<int > modeTrackPropagation{" modeTrackPropagation" , 0 , " 0: use real track propagation, including material, 1: use fast approximation using only geometry, 2: Use real track propagation and make comparison to fast propagation (only for debugging and testing)" };
117118
118119 // single track cuts
119120 Configurable<int > min_ncluster_tpc{" min_ncluster_tpc" , 0 , " min ncluster tpc" };
@@ -325,6 +326,14 @@ struct PhotonConversionBuilder {
325326 registry.add (" V0/hBDTScoreAfterCutVsPt" , " BDT score after cut vs pT; pT (GeV/c); BDT score" , {HistType::kTH2F , {{1000 , 0 .0f , 20 .0f }, {1000 , 0 .0f , 1 .0f }}});
326327 }
327328 }
329+
330+ // Compare proper propagation and fast geometrical propagation
331+ if (modeTrackPropagation == 2 ) {
332+ registry.add (" V0Leg/hDCAxyPropagationCompare" , " Comparison of DCA_{xy} propagation;DCA_{xy} (cm) proper propagation; DCA_{xy} (cm) geom. propagation" , {HistType::kTH2F , {{200 , -10 ., 10 .}, {200 , -10 ., 10 .}}});
333+ registry.add (" V0Leg/hDCAzPropagationCompare" , " Comparison of DCA_{z} propagation;DCA_{z} (cm) proper propagation; DCA_{z} (cm) geom. propagation" , {HistType::kTH2F , {{200 , -10 ., 10 .}, {200 , -10 ., 10 .}}});
334+ registry.add (" V0/hPhivPropagationCompare" , " Comparison of #phi_{v};#phi_{v} proper propagation; #phi_{v} geom. propagation" , {HistType::kTH2F , {{100 , 0 ., 1.6 }, {100 , 0 ., 1.6 }}});
335+ registry.add (" V0/hPsiPairPropagationCompare" , " Comparison of #Psi_{pair};#Psi_{pair} proper propagation; #Psi_{pair} geom. propagation" , {HistType::kTH2F , {{100 , 0 ., 1.6 }, {100 , 0 ., 1.6 }}});
336+ }
328337 }
329338
330339 void initCCDB (aod::BCsWithTimestamps::iterator const & bc)
@@ -555,8 +564,23 @@ struct PhotonConversionBuilder {
555564 return ;
556565 }
557566 auto pTrackC = pTrack;
567+ o2::math_utils::Point3D<float > vtxPrim{
568+ collision.posX (),
569+ collision.posY (),
570+ collision.posZ ()};
571+ if (modeTrackPropagation > 0 ) {
572+ dcaInfo = CalculateDCAFast (pTrackC, vtxPrim, d_bz);
573+ }
558574 pTrackC.setPID (o2::track::PID ::Electron);
559- o2::base::Propagator::Instance ()->propagateToDCABxByBz ({collision.posX (), collision.posY (), collision.posZ ()}, pTrackC, 2 .f , matCorr, &dcaInfo);
575+
576+ std::array<float , 2 > dcaInfoFast = dcaInfo;
577+ if (modeTrackPropagation != 1 ) {
578+ o2::base::Propagator::Instance ()->propagateToDCABxByBz ({collision.posX (), collision.posY (), collision.posZ ()}, pTrackC, 2 .f , matCorr, &dcaInfo);
579+ if (modeTrackPropagation == 2 ) {
580+ registry.fill (HIST (" V0Leg/hDCAxyPropagationCompare" ), dcaInfo[0 ], dcaInfoFast[0 ]);
581+ registry.fill (HIST (" V0Leg/hDCAzPropagationCompare" ), dcaInfo[1 ], dcaInfoFast[1 ]);
582+ }
583+ }
560584 auto posdcaXY = dcaInfo[0 ];
561585 auto posdcaZ = dcaInfo[1 ];
562586
@@ -566,8 +590,19 @@ struct PhotonConversionBuilder {
566590 return ;
567591 }
568592 auto nTrackC = nTrack;
593+ if (modeTrackPropagation > 0 ) {
594+ dcaInfo = CalculateDCAFast (nTrackC, vtxPrim, d_bz);
595+ }
569596 nTrackC.setPID (o2::track::PID ::Electron);
570- o2::base::Propagator::Instance ()->propagateToDCABxByBz ({collision.posX (), collision.posY (), collision.posZ ()}, nTrackC, 2 .f , matCorr, &dcaInfo);
597+
598+ dcaInfoFast = dcaInfo;
599+ if (modeTrackPropagation != 1 ) {
600+ o2::base::Propagator::Instance ()->propagateToDCABxByBz ({collision.posX (), collision.posY (), collision.posZ ()}, nTrackC, 2 .f , matCorr, &dcaInfo);
601+ if (modeTrackPropagation == 2 ) {
602+ registry.fill (HIST (" V0Leg/hDCAxyPropagationCompare" ), dcaInfo[0 ], dcaInfoFast[0 ]);
603+ registry.fill (HIST (" V0Leg/hDCAzPropagationCompare" ), dcaInfo[1 ], dcaInfoFast[1 ]);
604+ }
605+ }
571606 auto eledcaXY = dcaInfo[0 ];
572607 auto eledcaZ = dcaInfo[1 ];
573608
@@ -587,30 +622,76 @@ struct PhotonConversionBuilder {
587622
588623 float phiv = 999 .f ;
589624 float psipair = 999 .f ;
625+ float phivFast = 999 .f ;
626+ float psipairFast = 999 .f ;
590627 float baseR = std::hypot (xyz[0 ], xyz[1 ]);
591- std::array<float , 3 > offsetsR = {propV0LegsRadius, 30 .f , 10 .f };
592- bool pPropagatedSuccess = false ;
593- bool nPropagatedSuccess = false ;
594- auto pTrackProp = pTrack;
595- auto nTrackProp = nTrack;
596- for (const float & offsetR : offsetsR) {
597- pTrackProp = pTrack;
598- pTrackProp.setPID (o2::track::PID ::Electron);
599- nTrackProp = nTrack;
600- nTrackProp.setPID (o2::track::PID ::Electron);
601- o2::base::Propagator::Instance ()->propagateToDCABxByBz ({collision.posX (), collision.posY (), collision.posZ ()}, pTrackProp, 2 .f , matCorr, &dcaInfo);
602- o2::base::Propagator::Instance ()->propagateToDCABxByBz ({collision.posX (), collision.posY (), collision.posZ ()}, nTrackProp, 2 .f , matCorr, &dcaInfo);
603- pPropagatedSuccess = o2::base::Propagator::Instance ()->propagateToR (pTrackProp, baseR + offsetR);
604- nPropagatedSuccess = o2::base::Propagator::Instance ()->propagateToR (nTrackProp, baseR + offsetR);
605- if (pPropagatedSuccess && nPropagatedSuccess) {
606- KFPTrack kfp_track_posProp = createKFPTrackFromTrackParCov (pTrackProp, pos.sign (), pos.tpcNClsFound (), pos.tpcChi2NCl ());
607- KFPTrack kfp_track_eleProp = createKFPTrackFromTrackParCov (nTrackProp, ele.sign (), ele.tpcNClsFound (), ele.tpcChi2NCl ());
608- phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair (kfp_track_posProp.GetPx (), kfp_track_posProp.GetPy (), kfp_track_posProp.GetPz (), kfp_track_eleProp.GetPx (), kfp_track_eleProp.GetPy (), kfp_track_eleProp.GetPz (), pos.sign (), ele.sign (), d_bz);
609- psipair = o2::aod::pwgem::dilepton::utils::pairutil::getPsiPair (kfp_track_posProp.GetPx (), kfp_track_posProp.GetPy (), kfp_track_posProp.GetPz (), kfp_track_eleProp.GetPx (), kfp_track_eleProp.GetPy (), kfp_track_eleProp.GetPz ());
610- break ;
628+ // This method uses the track Helix instead of the full propagation.
629+ // Hence, it is only an approximation but much faster
630+ if (modeTrackPropagation > 0 ) {
631+
632+ o2::track::TrackAuxPar helixPosEle (nTrack, d_bz);
633+ o2::track::TrackAuxPar helixPosPos (pTrack, d_bz);
634+
635+ float diffX = helixPosEle.xC - helixPosPos.xC ;
636+ float diffY = helixPosEle.yC - helixPosPos.yC ;
637+ float phiHelix = std::atan2 (diffY, diffX);
638+ phiHelix -= o2::constants::math::PI / 2 .;
639+ if (phiHelix > 2 * o2::constants::math::PI ) {
640+ phiHelix -= o2::constants::math::PI * 2 ;
641+ }
642+ if (phiHelix < 0 ) {
643+ phiHelix += o2::constants::math::PI * 2 ;
611644 }
612- LOG (debug) << " Propagation to offset" << offsetR << " cm failed for " << (pPropagatedSuccess ? " negative" : " positive" ) << " track. Trying smaller offset." ;
645+
646+ // Electron
647+ float arcLenghtEle = helixPosEle.rC * 0.9 > propV0LegsRadius ? std::asin (propV0LegsRadius / helixPosEle.rC ) * helixPosEle.rC : o2::constants::math::PI / 2.2 * helixPosEle.rC ; // This assumes that the photon momentum vector is a tangent of the circle
648+ auto propTrackEle = getPropMomentumFromTrackHelix (arcLenghtEle, ele, d_bz / 10 ., helixPosEle, phiHelix - ele.phi ());
649+ // Positron
650+ float arcLenghtPos = helixPosPos.rC * 0.9 > propV0LegsRadius ? std::asin (propV0LegsRadius / helixPosPos.rC ) * helixPosPos.rC : o2::constants::math::PI / 2.2 * helixPosPos.rC ; // This assumes that the photon momentum vector is a tangent of the circle
651+ auto propTrackPos = getPropMomentumFromTrackHelix (arcLenghtPos, pos, d_bz / 10 ., helixPosPos, phiHelix - pos.phi ());
652+
653+ phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair (propTrackPos[0 ], propTrackPos[1 ], propTrackPos[2 ], propTrackEle[0 ], propTrackEle[1 ], propTrackEle[2 ], pos.sign (), ele.sign (), d_bz);
654+ psipair = o2::aod::pwgem::dilepton::utils::pairutil::getPsiPair (propTrackPos[0 ], propTrackPos[1 ], propTrackPos[2 ], propTrackEle[0 ], propTrackEle[1 ], propTrackEle[2 ]);
655+
656+ // Store values for later comparison
657+ phivFast = phiv;
658+ psipairFast = psipair;
613659 }
660+ // This uses the full propagation including material effects
661+ if (modeTrackPropagation != 1 ) {
662+ float offsetsR[3 ] = {propV0LegsRadius, 30 .f , 10 .f };
663+ bool pPropagatedSuccess = false ;
664+ bool nPropagatedSuccess = false ;
665+ auto pTrackProp = pTrack;
666+ auto nTrackProp = nTrack;
667+ for (float offsetR : offsetsR) {
668+ pTrackProp = pTrack;
669+ pTrackProp.setPID (o2::track::PID ::Electron);
670+ nTrackProp = nTrack;
671+ nTrackProp.setPID (o2::track::PID ::Electron);
672+
673+ o2::base::Propagator::Instance ()->propagateToDCABxByBz ({collision.posX (), collision.posY (), collision.posZ ()}, pTrackProp, 2 .f , matCorr, &dcaInfo);
674+ o2::base::Propagator::Instance ()->propagateToDCABxByBz ({collision.posX (), collision.posY (), collision.posZ ()}, nTrackProp, 2 .f , matCorr, &dcaInfo);
675+
676+ pPropagatedSuccess = o2::base::Propagator::Instance ()->propagateToR (pTrackProp, baseR + offsetR);
677+ nPropagatedSuccess = o2::base::Propagator::Instance ()->propagateToR (nTrackProp, baseR + offsetR);
678+
679+ if (pPropagatedSuccess && nPropagatedSuccess) {
680+ KFPTrack kfp_track_posProp = createKFPTrackFromTrackParCov (pTrackProp, pos.sign (), pos.tpcNClsFound (), pos.tpcChi2NCl ());
681+ KFPTrack kfp_track_eleProp = createKFPTrackFromTrackParCov (nTrackProp, ele.sign (), ele.tpcNClsFound (), ele.tpcChi2NCl ());
682+ phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair (kfp_track_posProp.GetPx (), kfp_track_posProp.GetPy (), kfp_track_posProp.GetPz (), kfp_track_eleProp.GetPx (), kfp_track_eleProp.GetPy (), kfp_track_eleProp.GetPz (), pos.sign (), ele.sign (), d_bz);
683+ psipair = o2::aod::pwgem::dilepton::utils::pairutil::getPsiPair (kfp_track_posProp.GetPx (), kfp_track_posProp.GetPy (), kfp_track_posProp.GetPz (), kfp_track_eleProp.GetPx (), kfp_track_eleProp.GetPy (), kfp_track_eleProp.GetPz ());
684+ break ;
685+ } else {
686+ LOG (debug) << " Propagation to offset" << offsetR << " cm failed for " << (pPropagatedSuccess ? " negative" : " positive" ) << " track. Trying smaller offset." ;
687+ }
688+ }
689+ if (modeTrackPropagation == 2 ) {
690+ registry.fill (HIST (" V0/hPhivPropagationCompare" ), phiv, phivFast);
691+ registry.fill (HIST (" V0/hPsiPairPropagationCompare" ), psipair, psipairFast);
692+ }
693+ }
694+
614695 if (phiv == 999 .f || psipair == 999 .f ) {
615696 LOG (debug) << " Propagation failed for all radii (" << propV0LegsRadius << " , 30, 10 cm). Using default values for phiv and psipair (999.f)." ;
616697 }
@@ -985,14 +1066,14 @@ struct PhotonConversionBuilder {
9851066 fillV0Table<isMC, TBCs, TCollisions, TTracks>(v0, true );
9861067 } // end of fullv0Id loop
9871068
988- for (const auto & collision : collisions) {
989- if constexpr (isMC) {
990- if (!collision.has_mcCollision ()) {
991- continue ;
992- }
993- }
994- // events_ngpcm(nv0_map[collision.globalIndex()]);
995- } // end of collision loop
1069+ // for (const auto& collision : collisions) {
1070+ // if constexpr (isMC) {
1071+ // if (!collision.has_mcCollision()) {
1072+ // continue;
1073+ // }
1074+ // }
1075+ // // events_ngpcm(nv0_map[collision.globalIndex()]);
1076+ // } // end of collision loop
9961077
9971078 pca_map.clear ();
9981079 cospa_map.clear ();
0 commit comments