@@ -132,30 +132,28 @@ struct UpcCandProducerGlobalMuon {
132132 histRegistry.get <TH1>(HIST (" MuonsSelCounter" ))->GetXaxis ()->SetBinLabel (upchelpers::kFwdSelChi2 + 1 , " Chi2" );
133133
134134 // NEW: Add histograms for global track monitoring
135- if (fEnableMFT ) {
136- const AxisSpec axisTrackType{5 , -0.5 , 4.5 , " Track Type" };
137- histRegistry.add (" hTrackTypes" , " Track type distribution" , kTH1F , {axisTrackType});
138- histRegistry.get <TH1>(HIST (" hTrackTypes" ))->GetXaxis ()->SetBinLabel (1 , " MuonStandalone" );
139- histRegistry.get <TH1>(HIST (" hTrackTypes" ))->GetXaxis ()->SetBinLabel (2 , " MCHStandalone" );
140- histRegistry.get <TH1>(HIST (" hTrackTypes" ))->GetXaxis ()->SetBinLabel (3 , " GlobalMuon" );
141- histRegistry.get <TH1>(HIST (" hTrackTypes" ))->GetXaxis ()->SetBinLabel (4 , " GlobalFwd" );
142-
143- const AxisSpec axisEta{100 , -4.0 , -2.0 , " #eta" };
144- histRegistry.add (" hEtaGlobal" , " Global track eta" , kTH1F , {axisEta});
145-
146- const AxisSpec axisDCAxy{200 , 0 ., 10 ., " DCA_{xy} (cm)" };
147- const AxisSpec axisDCAz{200 , -10 ., 10 ., " DCA_{z} (cm)" };
148- histRegistry.add (" hDCAxyGlobal" , " DCAxy of global tracks to best collision" , kTH1F , {axisDCAxy});
149- histRegistry.add (" hDCAzGlobal" , " DCAz of global tracks to best collision" , kTH1F , {axisDCAz});
150- histRegistry.add (" hNCompatColls" , " Number of compatible collisions per global track" , kTH1F , {{21 , -0.5 , 20.5 }});
151-
152- const AxisSpec axisChi2Match{200 , 0 ., 100 ., " #chi^{2}_{MCH-MFT}" };
153- histRegistry.add (" hChi2MatchMCHMFT" , " Chi2 of MCH-MFT matching (before cut)" , kTH1F , {axisChi2Match});
154-
155- const AxisSpec axisMass{500 , 0 ., 10 ., " m_{inv} (GeV/c^{2})" };
156- histRegistry.add (" hMassGlobalMuon" , " Invariant mass from MCH-MID-MFT tracks only" , kTH1F , {axisMass});
157- histRegistry.add (" hMassGlobalMuonWithMCHMFT" , " Invariant mass from MCH-MID-MFT + MCH-MFT tracks" , kTH1F , {axisMass});
158- }
135+ const AxisSpec axisTrackType{5 , -0.5 , 4.5 , " Track Type" };
136+ histRegistry.add (" hTrackTypes" , " Track type distribution" , kTH1F , {axisTrackType});
137+ histRegistry.get <TH1>(HIST (" hTrackTypes" ))->GetXaxis ()->SetBinLabel (1 , " MuonStandalone" );
138+ histRegistry.get <TH1>(HIST (" hTrackTypes" ))->GetXaxis ()->SetBinLabel (2 , " MCHStandalone" );
139+ histRegistry.get <TH1>(HIST (" hTrackTypes" ))->GetXaxis ()->SetBinLabel (3 , " GlobalMuon" );
140+ histRegistry.get <TH1>(HIST (" hTrackTypes" ))->GetXaxis ()->SetBinLabel (4 , " GlobalFwd" );
141+
142+ const AxisSpec axisEta{100 , -4.0 , -2.0 , " #eta" };
143+ histRegistry.add (" hEtaGlobal" , " Global track eta" , kTH1F , {axisEta});
144+
145+ const AxisSpec axisDCAxy{200 , 0 ., 10 ., " DCA_{xy} (cm)" };
146+ const AxisSpec axisDCAz{200 , -10 ., 10 ., " DCA_{z} (cm)" };
147+ histRegistry.add (" hDCAxyGlobal" , " DCAxy of global tracks to best collision" , kTH1F , {axisDCAxy});
148+ histRegistry.add (" hDCAzGlobal" , " DCAz of global tracks to best collision" , kTH1F , {axisDCAz});
149+ histRegistry.add (" hNCompatColls" , " Number of compatible collisions per global track" , kTH1F , {{21 , -0.5 , 20.5 }});
150+
151+ const AxisSpec axisChi2Match{200 , 0 ., 100 ., " #chi^{2}_{MCH-MFT}" };
152+ histRegistry.add (" hChi2MatchMCHMFT" , " Chi2 of MCH-MFT matching (before cut)" , kTH1F , {axisChi2Match});
153+
154+ const AxisSpec axisMass{500 , 0 ., 10 ., " m_{inv} (GeV/c^{2})" };
155+ histRegistry.add (" hMassGlobalMuon" , " Invariant mass from MCH-MID-MFT tracks only" , kTH1F , {axisMass});
156+ histRegistry.add (" hMassGlobalMuonWithMCHMFT" , " Invariant mass from MCH-MID-MFT + MCH-MFT tracks" , kTH1F , {axisMass});
159157 }
160158
161159 bool cut (const o2::dataformats::GlobalFwdTrack& pft, const ForwardTracks::iterator& fwdTrack)
@@ -393,13 +391,11 @@ struct UpcCandProducerGlobalMuon {
393391 float px, py, pz;
394392 int sign;
395393
396- // NEW: Fill track type histogram if MFT enabled
397- if (fEnableMFT ) {
398- histRegistry.fill (HIST (" hTrackTypes" ), track.trackType ());
399- if (track.trackType () == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack ||
400- track.trackType () == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalForwardTrack) {
401- histRegistry.fill (HIST (" hEtaGlobal" ), track.eta ());
402- }
394+ // NEW: Fill track type histogram
395+ histRegistry.fill (HIST (" hTrackTypes" ), track.trackType ());
396+ if (track.trackType () == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack ||
397+ track.trackType () == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalForwardTrack) {
398+ histRegistry.fill (HIST (" hEtaGlobal" ), track.eta ());
403399 }
404400
405401 if (fUpcCuts .getUseFwdCuts ()) {
@@ -502,6 +498,23 @@ struct UpcCandProducerGlobalMuon {
502498 return {dcaXY, dcaOrig[2 ], dcaOrig[0 ], dcaOrig[1 ]};
503499 }
504500
501+ // Dispatch DCA computation: use MFT helix propagation when fEnableMFT is true,
502+ // otherwise fall back to MCH extrapolation to (0,0,0) via propagateToZero.
503+ // Returns {DCAxy, DCAz, DCAx, DCAy}
504+ std::array<double , 4 > propagateFwdToDCA (ForwardTracks::iterator const & track,
505+ double colX, double colY, double colZ)
506+ {
507+ if (fEnableMFT ) {
508+ return propagateGlobalToDCA (track, colX, colY, colZ);
509+ }
510+ auto pft = propagateToZero (track);
511+ double dcaX = pft.getX () - colX;
512+ double dcaY = pft.getY () - colY;
513+ double dcaXY = std::sqrt (dcaX * dcaX + dcaY * dcaY);
514+ double dcaZ = pft.getZ () - colZ;
515+ return {dcaXY, dcaZ, dcaX, dcaY};
516+ }
517+
505518 void createCandidates (ForwardTracks const & fwdTracks,
506519 o2::aod::FwdTrkCls const & fwdTrkCls,
507520 o2::aod::AmbiguousFwdTracks const & ambFwdTracks,
@@ -616,12 +629,12 @@ struct UpcCandProducerGlobalMuon {
616629 mapGlobalBcsWithMCHMIDTrackIds[globalBC].push_back (trackId);
617630 } else if (trackType == MCHStandaloneTrack) { // MCH-only
618631 mapGlobalBcsWithMCHTrackIds[globalBC].push_back (trackId);
619- } else if (fEnableMFT && trackType == GlobalMuonTrack) { // MCH-MID-MFT: good timing, used as anchor
632+ } else if (trackType == GlobalMuonTrack) { // MCH-MID-MFT: good timing, used as anchor
620633 histRegistry.fill (HIST (" hChi2MatchMCHMFT" ), fwdTrack.chi2MatchMCHMFT ());
621634 if (fwdTrack.chi2MatchMCHMFT () > 0 && fwdTrack.chi2MatchMCHMFT () < fMaxChi2MatchMCHMFT ) {
622635 mapGlobalBcsWithGlobalMuonTrackIds[globalBC].push_back (trackId);
623636 }
624- } else if (fEnableMFT && trackType == GlobalForwardTrack) { // MCH-MFT: poor timing, matched to anchors
637+ } else if (trackType == GlobalForwardTrack) { // MCH-MFT: poor timing, matched to anchors
625638 histRegistry.fill (HIST (" hChi2MatchMCHMFT" ), fwdTrack.chi2MatchMCHMFT ());
626639 if (fwdTrack.chi2MatchMCHMFT () > 0 && fwdTrack.chi2MatchMCHMFT () < fMaxChi2MatchMCHMFT ) {
627640 mapGlobalBcsWithMCHMFTTrackIds[globalBC].push_back (trackId);
@@ -631,11 +644,9 @@ struct UpcCandProducerGlobalMuon {
631644
632645 // Map global BC to collisions for DCA-based vertex assignment
633646 std::map<uint64_t , std::vector<int64_t >> mapGlobalBCtoCollisions;
634- if (fEnableMFT ) {
635- for (const auto & col : collisions) {
636- uint64_t gbc = vGlobalBCs[col.bcId ()];
637- mapGlobalBCtoCollisions[gbc].push_back (col.globalIndex ());
638- }
647+ for (const auto & col : collisions) {
648+ uint64_t gbc = vGlobalBCs[col.bcId ()];
649+ mapGlobalBCtoCollisions[gbc].push_back (col.globalIndex ());
639650 }
640651
641652 std::vector<int64_t > selTrackIds{}; // NEW: For cluster saving
@@ -645,7 +656,7 @@ struct UpcCandProducerGlobalMuon {
645656 // Process global tracks: MCH-MID-MFT anchors + MCH-MFT in BC window
646657 // MCH-MID-MFT tracks have good timing (from MID) and serve as anchors.
647658 // MCH-MFT tracks have poor timing and are searched in a BC window around anchors.
648- if (fEnableMFT && !mapGlobalBcsWithGlobalMuonTrackIds.empty ()) {
659+ if (!mapGlobalBcsWithGlobalMuonTrackIds.empty ()) {
649660 for (const auto & gbc_anchorids : mapGlobalBcsWithGlobalMuonTrackIds) {
650661 uint64_t globalBcAnchor = gbc_anchorids.first ;
651662 auto itFv0Id = mapGlobalBcWithV0A.find (globalBcAnchor);
@@ -691,7 +702,7 @@ struct UpcCandProducerGlobalMuon {
691702 int nTracks = 0 ;
692703 for (const auto & iglobal : allTrackIds) {
693704 const auto & trk = fwdTracks.iteratorAt (iglobal);
694- auto dca = propagateGlobalToDCA (trk, col.posX (), col.posY (), col.posZ ());
705+ auto dca = propagateFwdToDCA (trk, col.posX (), col.posY (), col.posZ ());
695706 sumDCAxy += dca[0 ];
696707 nTracks++;
697708 }
@@ -715,7 +726,7 @@ struct UpcCandProducerGlobalMuon {
715726 for (const auto & ianchor : vAnchorIds) {
716727 if (hasVertex) {
717728 const auto & trk = fwdTracks.iteratorAt (ianchor);
718- auto dca = propagateGlobalToDCA (trk, bestVtxX, bestVtxY, bestVtxZ);
729+ auto dca = propagateFwdToDCA (trk, bestVtxX, bestVtxY, bestVtxZ);
719730 histRegistry.fill (HIST (" hDCAxyGlobal" ), dca[0 ]);
720731 histRegistry.fill (HIST (" hDCAzGlobal" ), dca[1 ]);
721732 if (dca[0 ] > static_cast <double >(fMaxDCAxy ))
@@ -744,7 +755,7 @@ struct UpcCandProducerGlobalMuon {
744755 for (const auto & [imchMft, gbc] : mapMchMftIdBc) {
745756 if (hasVertex) {
746757 const auto & trk = fwdTracks.iteratorAt (imchMft);
747- auto dca = propagateGlobalToDCA (trk, bestVtxX, bestVtxY, bestVtxZ);
758+ auto dca = propagateFwdToDCA (trk, bestVtxX, bestVtxY, bestVtxZ);
748759 histRegistry.fill (HIST (" hDCAxyGlobal" ), dca[0 ]);
749760 histRegistry.fill (HIST (" hDCAzGlobal" ), dca[1 ]);
750761 if (dca[0 ] > static_cast <double >(fMaxDCAxy ))
0 commit comments