@@ -64,12 +64,16 @@ struct FwdTrackPropagation {
6464 Configurable<float > minRabs{" minRabs" , 17.6 , " min. R at absorber end" };
6565 Configurable<float > midRabs{" midRabs" , 26.5 , " middle R at absorber end for pDCA cut" };
6666 Configurable<float > maxRabs{" maxRabs" , 89.5 , " max. R at absorber end" };
67+ Configurable<float > maxDCAxy{" maxDCAxy" , 1e+10 , " max. DCAxy for global muons" };
6768 Configurable<float > maxPDCAforLargeR{" maxPDCAforLargeR" , 324 .f , " max. pDCA for large R at absorber end" };
6869 Configurable<float > maxPDCAforSmallR{" maxPDCAforSmallR" , 594 .f , " max. pDCA for small R at absorber end" };
6970 Configurable<float > maxMatchingChi2MCHMFT{" maxMatchingChi2MCHMFT" , 50 .f , " max. chi2 for MCH-MFT matching" };
70- Configurable<float > maxChi2{" maxChi2" , 1e+6 , " max. chi2 for muon tracking" };
71- Configurable<bool > refitGlobalMuon{" refitGlobalMuon" , false , " flag to refit global muon" };
72- Configurable<bool > applyEtaCutToSAinGL{" applyEtaCutToSAinGL" , false , " flag to apply eta cut to samuon in global muon" };
71+ Configurable<float > maxChi2SA{" maxChi2SA" , 1e+6 , " max. chi2 for standalone muon" };
72+ Configurable<float > maxChi2GL{" maxChi2GL" , 1e+6 , " max. chi2 for global muon" };
73+ Configurable<bool > refitGlobalMuon{" refitGlobalMuon" , true , " flag to refit global muon" };
74+ Configurable<bool > applyDEtaDPhi{" cfgApplyDEtaDPhi" , false , " flag to apply deta-dphi elliptic cut" };
75+ Configurable<float > minDEta{" minDEta" , 0.1 , " min deta between MFT-MCH-MID and its attached MID-MCH at PV" };
76+ Configurable<float > minDPhi{" minDPhi" , 0.1 , " min dphi between MFT-MCH-MID and its attached MID-MCH at PV" };
7377
7478 HistogramRegistry fRegistry {" fRegistry" };
7579 static constexpr std::string_view muon_types[5 ] = {" MFTMCHMID/" , " MFTMCHMIDOtherMatch/" , " MFTMCH/" , " MCHMID/" , " MCH/" };
@@ -138,9 +142,9 @@ struct FwdTrackPropagation {
138142 fRegistry .add (" MFTMCHMID/hChi2MatchMCHMID" , " chi2 match MCH-MID;chi2" , kTH1F , {{100 , 0 .0f , 100 }}, false );
139143 fRegistry .add (" MFTMCHMID/hChi2MatchMCHMFT" , " chi2 match MCH-MFT;chi2" , kTH1F , {{100 , 0 .0f , 100 }}, false );
140144 fRegistry .add (" MFTMCHMID/hMatchScoreMCHMFT" , " match score MCH-MFT;score" , kTH1F , {{100 , 0 .0f , 100 }}, false );
141- fRegistry .add (" MFTMCHMID/hDCAxy2D" , " DCA x vs. y;DCA_{x} (cm);DCA_{y} (cm)" , kTH2F , {{200 , -0.1 , 0.1 }, {200 , -0.1 , +0.1 }}, false );
145+ fRegistry .add (" MFTMCHMID/hDCAxy2D" , " DCA x vs. y;DCA_{x} (cm);DCA_{y} (cm)" , kTH2F , {{200 , -0.5 , 0.5 }, {200 , -0.5 , +0.5 }}, false );
142146 fRegistry .add (" MFTMCHMID/hDCAxy2DinSigma" , " DCA x vs. y in sigma;DCA_{x} (#sigma);DCA_{y} (#sigma)" , kTH2F , {{200 , -10 , 10 }, {200 , -10 , +10 }}, false );
143- fRegistry .add (" MFTMCHMID/hDCAxy" , " DCAxy;DCA_{xy} (cm);" , kTH1F , {{100 , 0 , 0. 1 }}, false );
147+ fRegistry .add (" MFTMCHMID/hDCAxy" , " DCAxy;DCA_{xy} (cm);" , kTH1F , {{100 , 0 , 1 }}, false );
144148 fRegistry .add (" MFTMCHMID/hDCAxyinSigma" , " DCAxy in sigma;DCA_{xy} (#sigma);" , kTH1F , {{100 , 0 , 10 }}, false );
145149 fRegistry .addClone (" MFTMCHMID/" , " MCHMID/" );
146150 fRegistry .add (" MFTMCHMID/hDCAxResolutionvsPt" , " DCA_{x} vs. p_{T};p_{T} (GeV/c);DCA_{x} resolution (#mum);" , kTH2F , {{100 , 0 , 10 .f }, {500 , 0 , 500 }}, false );
@@ -149,36 +153,111 @@ struct FwdTrackPropagation {
149153 fRegistry .add (" MCHMID/hDCAyResolutionvsPt" , " DCA_{y} vs. p_{T};p_{T} (GeV/c);DCA_{y} resolution (#mum);" , kTH2F , {{100 , 0 , 10 .f }, {500 , 0 , 5e+5 }}, false );
150154 }
151155
152- bool isSelected (const float pt, const float eta, const float rAtAbsorberEnd, const float pDCA, const float chi2, const uint8_t trackType, const float etaMatchedMCHMID )
156+ bool isSelected (const float pt, const float eta, const float rAtAbsorberEnd, const float pDCA, const float chi2, const uint8_t trackType, const float dcaXY )
153157 {
154158 if (pt < minPt || maxPt < pt) {
155159 return false ;
156160 }
157-
158161 if (rAtAbsorberEnd < minRabs || maxRabs < rAtAbsorberEnd) {
159162 return false ;
160163 }
161-
162- if (chi2 < 0 .f || maxChi2 < chi2) {
164+ if (rAtAbsorberEnd < midRabs ? pDCA > maxPDCAforSmallR : pDCA > maxPDCAforLargeR) {
163165 return false ;
164166 }
165167
166168 if (trackType == static_cast <uint8_t >(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack)) {
167169 if (eta < minEtaGL || maxEtaGL < eta) {
168170 return false ;
169171 }
170- if (applyEtaCutToSAinGL && (etaMatchedMCHMID < minEtaSA || maxEtaSA < etaMatchedMCHMID)) {
172+ if (maxDCAxy < dcaXY) {
173+ return false ;
174+ }
175+ if (chi2 < 0 .f || maxChi2GL < chi2) {
171176 return false ;
172177 }
173178 } else if (trackType == static_cast <uint8_t >(o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack)) {
174179 if (eta < minEtaSA || maxEtaSA < eta) {
175180 return false ;
176181 }
182+ if (chi2 < 0 .f || maxChi2SA < chi2) {
183+ return false ;
184+ }
177185 } else {
178186 return false ;
179187 }
180188
181- if (rAtAbsorberEnd < midRabs ? pDCA > maxPDCAforSmallR : pDCA > maxPDCAforLargeR) {
189+ return true ;
190+ }
191+
192+ template <typename TFwdTracks, typename TMFTTracks, typename TCollision, typename TTarget, typename TCandidates>
193+ bool isBestMatch (TCollision const & collision, TTarget const & target, TCandidates const & candidates)
194+ {
195+ std::map<int64_t , float > map_chi2MFTMCH;
196+ for (const auto & matchedtrack : candidates) { // MFT-MCH-MID or MFT-MCH
197+ if (matchedtrack.trackType () != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) {
198+ continue ;
199+ }
200+ o2::dataformats::GlobalFwdTrack propmuonAtPV = propagateMuon (matchedtrack, collision, propagationPoint::kToVertex );
201+ float eta = propmuonAtPV.getEta ();
202+ float phi = propmuonAtPV.getPhi ();
203+ if (refitGlobalMuon) {
204+ const auto & mfttrack = matchedtrack.template matchMFTTrack_as <TMFTTracks>();
205+ eta = mfttrack.eta ();
206+ phi = mfttrack.phi ();
207+ }
208+ o2::math_utils::bringTo02Pi (phi);
209+ if (eta < minEtaGL || maxEtaGL < eta) {
210+ continue ;
211+ }
212+
213+ const auto & mchtrack = matchedtrack.template matchMCHTrack_as <TFwdTracks>(); // MCH-MID
214+ o2::dataformats::GlobalFwdTrack propmuonAtPV_Matched = propagateMuon (mchtrack, collision, propagationPoint::kToVertex );
215+ float etaMatchedMCHMID = propmuonAtPV_Matched.getEta ();
216+ float phiMatchedMCHMID = propmuonAtPV_Matched.getPhi ();
217+ o2::math_utils::bringTo02Pi (phiMatchedMCHMID);
218+
219+ float deta = etaMatchedMCHMID - eta;
220+ float dphi = phiMatchedMCHMID - phi;
221+ o2::math_utils::bringToPMPi (dphi);
222+ if (applyDEtaDPhi && std::sqrt (std::pow (deta / minDEta, 2 ) + std::pow (dphi / minDPhi, 2 )) > 1 .f ) {
223+ continue ;
224+ }
225+
226+ if (matchedtrack.chi2 () < 0 .f || maxChi2GL < matchedtrack.chi2 ()) {
227+ continue ;
228+ }
229+
230+ float rAtAbsorberEnd = matchedtrack.rAtAbsorberEnd (); // this works only for GlobalMuonTrack
231+ if (rAtAbsorberEnd < minRabs || maxRabs < rAtAbsorberEnd) {
232+ continue ;
233+ }
234+ o2::dataformats::GlobalFwdTrack propmuonAtDCA = propagateMuon (matchedtrack, collision, propagationPoint::kToDCA );
235+ float dcaX = propmuonAtDCA.getX () - collision.posX ();
236+ float dcaY = propmuonAtDCA.getY () - collision.posY ();
237+ float dcaXY = std::sqrt (dcaX * dcaX + dcaY * dcaY);
238+ if (maxDCAxy < dcaXY) {
239+ continue ;
240+ }
241+
242+ o2::dataformats::GlobalFwdTrack propmuonAtDCA_Matched = propagateMuon (mchtrack, collision, propagationPoint::kToDCA );
243+ float dcaX_Matched = propmuonAtDCA_Matched.getX () - collision.posX ();
244+ float dcaY_Matched = propmuonAtDCA_Matched.getY () - collision.posY ();
245+ float dcaXY_Matched = std::sqrt (dcaX_Matched * dcaX_Matched + dcaY_Matched * dcaY_Matched);
246+ float pDCA = mchtrack.p () * dcaXY_Matched;
247+
248+ if (rAtAbsorberEnd < midRabs ? pDCA > maxPDCAforSmallR : pDCA > maxPDCAforLargeR) {
249+ continue ;
250+ }
251+
252+ map_chi2MFTMCH[matchedtrack.globalIndex ()] = matchedtrack.chi2MatchMCHMFT ();
253+ }
254+ if (map_chi2MFTMCH.begin ()->first != target.globalIndex ()) { // search for minimum matching chi2
255+ map_chi2MFTMCH.clear ();
256+ return false ;
257+ }
258+ map_chi2MFTMCH.clear ();
259+
260+ if (target.chi2MatchMCHMFT () > maxMatchingChi2MCHMFT) {
182261 return false ;
183262 }
184263 return true ;
@@ -188,23 +267,11 @@ struct FwdTrackPropagation {
188267 void fillFwdTrackTable (TCollision const & collision, TFwdTrack fwdtrack, TFwdTracks const & fwdtracks, TMFTTracks const &, const bool isAmbiguous)
189268 {
190269 if (fwdtrack.trackType () == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) {
191- std::map<int64_t , float > map_chi2MFTMCH;
192270 const auto & matchedGlobalTracks = fwdtracks.sliceBy (perMFTTrack, fwdtrack.matchMFTTrackId ()); // MFT-MCH-MID or MFT-MCH
193- for (const auto & matchedtrack : matchedGlobalTracks) {
194- if (matchedtrack.trackType () == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) {
195- map_chi2MFTMCH[matchedtrack.globalIndex ()] = matchedtrack.chi2MatchMCHMFT ();
196- }
197- }
198- if (map_chi2MFTMCH.begin ()->first != fwdtrack.globalIndex ()) { // search for minimum chi2
199- map_chi2MFTMCH.clear ();
200- return ;
201- }
202- map_chi2MFTMCH.clear ();
203-
204- if (fwdtrack.chi2MatchMCHMFT () > maxMatchingChi2MCHMFT) {
271+ if (!isBestMatch<TFwdTracks, TMFTTracks>(collision, fwdtrack, matchedGlobalTracks)) {
205272 return ;
206273 }
207- } // reduce useless propagation
274+ } // find the best match between MFT and MCH-MID
208275
209276 o2::dataformats::GlobalFwdTrack propmuonAtPV = propagateMuon (fwdtrack, collision, propagationPoint::kToVertex );
210277 o2::dataformats::GlobalFwdTrack propmuonAtDCA = propagateMuon (fwdtrack, collision, propagationPoint::kToDCA );
@@ -240,9 +307,6 @@ struct FwdTrackPropagation {
240307
241308 if (fwdtrack.trackType () == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) {
242309 const auto & mchtrack = fwdtrack.template matchMCHTrack_as <TFwdTracks>(); // MCH-MID
243- // etaMatchedMCHMID = mchtrack.eta();
244- // phiMatchedMCHMID = mchtrack.phi();
245- // o2::math_utils::bringTo02Pi(phiMatchedMCHMID);
246310 o2::dataformats::GlobalFwdTrack propmuonAtPV_Matched = propagateMuon (mchtrack, collision, propagationPoint::kToVertex );
247311 etaMatchedMCHMID = propmuonAtPV_Matched.getEta ();
248312 phiMatchedMCHMID = propmuonAtPV_Matched.getPhi ();
@@ -276,7 +340,7 @@ struct FwdTrackPropagation {
276340 return ;
277341 }
278342
279- if (!isSelected (pt, eta, rAtAbsorberEnd, pDCA, fwdtrack.chi2 (), fwdtrack.trackType (), etaMatchedMCHMID )) {
343+ if (!isSelected (pt, eta, rAtAbsorberEnd, pDCA, fwdtrack.chi2 (), fwdtrack.trackType (), dcaXY )) {
280344 return ;
281345 }
282346
0 commit comments