1717#define HomogeneousField // o2-linter: disable=name/macro (required by KFParticle)
1818#endif
1919
20+ #include " PWGHF/Core/CentralityEstimation.h"
2021#include " PWGJE/DataModel/EMCALClusters.h"
2122
2223#include " Common/Core/RecoDecay.h"
24+ #include " Common/DataModel/Centrality.h"
2325#include " Common/DataModel/EventSelection.h"
26+ #include " Common/DataModel/Multiplicity.h"
2427#include " Common/DataModel/PIDResponseTPC.h"
2528#include " Common/DataModel/TrackSelectionTables.h"
2629#include " EventFiltering/Zorro.h"
5861using namespace o2 ;
5962using namespace o2 ::framework;
6063using namespace o2 ::framework::expressions;
64+ using namespace o2 ::hf_centrality;
6165
6266struct HfTaskElectronWeakBoson {
6367
@@ -121,6 +125,12 @@ struct HfTaskElectronWeakBoson {
121125 Configurable<int > kfConstructMethod{" kfConstructMethod" , 2 , " KF Construct Method" };
122126 Configurable<int > chiSqNdfMax{" chiSqNdfMax" , 10 , " Chi2 Max for mass reco by KF particle" };
123127
128+ // Centrality estimator configuration
129+ Configurable<int > centralityEstimator{" centralityEstimator" , 2 , " Centrality estimator (0=FT0A, 1=FT0C, 2=FT0M, 3=FV0A, 4=NTracksPV)" };
130+ Configurable<bool > enableCentralityAnalysis{" enableCentralityAnalysis" , true , " Enable centrality-dependent analysis" };
131+ Configurable<float > centralityMin{" centralityMin" , -1 , " minimum cut on centrality selection" };
132+ Configurable<float > centralityMax{" centralityMax" , 101 , " maximum cut on centrality selection" };
133+
124134 // CCDB service object
125135 Service<o2::ccdb::BasicCCDBManager> ccdb;
126136
@@ -142,7 +152,7 @@ struct HfTaskElectronWeakBoson {
142152 : pt(ptr), eta(e), phi(ph), mass(m), ptchild0(ptzee0), ptchild1(ptzee1), charge(ch) {}
143153 };
144154 std::vector<HfZeeCandidate> reconstructedZ;
145-
155+ using CollisionsWithCent = soa::Join<aod::Collisions, aod::CentFT0As, aod::CentFT0Cs, aod::CentFT0Ms, aod::CentFV0As>;
146156 using SelectedClusters = o2::aod::EMCALClusters;
147157 // PbPb
148158 // using TrackEle = o2::soa::Join<o2::aod::Tracks, o2::aod::FullTracks, o2::aod::TracksExtra, o2::aod::TracksDCA, o2::aod::TrackSelection, o2::aod::pidTPCFullEl>;
@@ -217,11 +227,14 @@ struct HfTaskElectronWeakBoson {
217227 const AxisSpec axisPtHadron{50 , 0 , 50 , " p_{T,hadron} (GeV/c)" };
218228 const AxisSpec axisPtZ{150 , 0 , 150 , " p_{T,Z} (GeV/c)" };
219229 const AxisSpec axisSign{2 , -2 , 2 , " charge sign" };
230+ const AxisSpec axisCentrality{10 , 0 , 100 , " Centrality (%)" };
231+ const AxisSpec axisPtRatio{200 , 0 , 2.0 , " pt ratio for h and Z" };
220232
221233 // create registrygrams
222234 registry.add (" hZvtx" , " Z vertex" , kTH1D , {axisZvtx});
223235 registry.add (" hEventCounterInit" , " hEventCounterInit" , kTH1D , {axisCounter});
224236 registry.add (" hEventCounter" , " hEventCounter" , kTH1D , {axisCounter});
237+ registry.add (" hCentrality" , " Centrality distribution" , kTH1F , {axisCentrality});
225238 registry.add (" hITSchi2" , " ITS #chi^{2}" , kTH1F , {axisChi2});
226239 registry.add (" hTPCchi2" , " TPC #chi^{2}" , kTH1F , {axisChi2});
227240 registry.add (" hTPCnCls" , " TPC NCls" , kTH1F , {axisCluster});
@@ -243,21 +256,27 @@ struct HfTaskElectronWeakBoson {
243256 registry.add (" hEMCtime" , " EMC timing" , kTH1F , {axisEMCtime});
244257 registry.add (" hIsolationEnergy" , " Isolation Energy" , kTH2F , {{axisE}, {axisIsoEnergy}});
245258 registry.add (" hIsolationTrack" , " Isolation Track" , kTH2F , {{axisE}, {axisIsoTrack}});
246- registry.add (" hInvMassZeeLs" , " invariant mass for Z LS pair" , kTH2F , {{axisPt}, {axisInvMassZ}});
247- registry.add (" hInvMassZeeUls" , " invariant mass for Z ULS pair" , kTH2F , {{axisPt}, {axisInvMassZ}});
248- registry.add (" hKfInvMassZeeLs" , " invariant mass for Z LS pair KFp" , kTH2F , {{axisPt}, {axisInvMassZ}});
249- registry.add (" hKfInvMassZeeUls" , " invariant mass for Z ULS pair KFp" , kTH2F , {{axisPt}, {axisInvMassZ}});
259+ registry.add (" hInvMassZee" , " invariant mass for Z ULS pair" , HistType::kTHnSparseF , {axisSign, axisPt, axisInvMassZ});
260+ registry.add (" hKfInvMassZee" , " invariant mass for Z ULS pair KFp" , HistType::kTHnSparseF , {axisSign, axisPt, axisInvMassZ});
250261 registry.add (" hTHnElectrons" , " electron info" , HistType::kTHnSparseF , {axisPt, axisNsigma, axisM02, axisEop, axisIsoEnergy, axisIsoTrack, axisEta, axisDedx});
251262 registry.add (" hTHnTrMatch" , " Track EMC Match" , HistType::kTHnSparseF , {axisPt, axisdPhi, axisdEta});
252263
253264 // Z-hadron correlation histograms
254- registry.add (" hZHadronDphi" , " Z-hadron #Delta#phi correlation" , HistType::kTHnSparseF , {axisSign, axisPtZ, axisDPhiZh});
265+ registry.add (" hZHadronDphi" , " Z-hadron #Delta#phi correlation" , HistType::kTHnSparseF , {axisSign, axisPtZ, axisDPhiZh, axisPtRatio, axisPtHadron });
255266 registry.add (" hZptSpectrum" , " Z boson p_{T} spectrum" , kTH2F , {{axisSign}, {axisPtZ}});
256267
257268 // hisotgram for EMCal trigger
258269 registry.add (" hEMCalTrigger" , " EMCal trigger" , kTH1D , {axisTrigger});
259270 }
260271
272+ // Centrality estimation function
273+ template <typename CollType>
274+ float getCentrality (const CollType& collision)
275+ {
276+ // Use PWGHF centrality estimation framework
277+ return o2::hf_centrality::getCentralityColl (collision, centralityEstimator);
278+ }
279+
261280 double getIsolatedCluster (const o2::aod::EMCALCluster& cluster,
262281 const SelectedClusters& clusters)
263282 {
@@ -323,6 +342,9 @@ struct HfTaskElectronWeakBoson {
323342 // LOG(info) << "Invarimass cal by KF particle ";
324343 for (const auto & track : tracks) {
325344
345+ if (std::abs (track.pt () - kfpIsoEle.GetPt ()) < ptMatch) {
346+ continue ;
347+ }
326348 if (track.pt () < ptZeeMin) {
327349 continue ;
328350 }
@@ -344,6 +366,8 @@ struct HfTaskElectronWeakBoson {
344366 auto child2 = RecoDecayPtEtaPhi::pVector (kfpAssEle.GetPt () * correctionPtElectron, kfpAssEle.GetEta (), kfpAssEle.GetPhi ());
345367 double invMassEE = RecoDecay::m (std::array{child1, child2}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron});
346368
369+ registry.fill (HIST (" hInvMassZee" ), track.sign () * charge, kfpIsoEle.GetPt (), invMassEE);
370+
347371 // reco by KFparticle
348372 const KFParticle* electronPairs[2 ] = {&kfpIsoEle, &kfpAssEle};
349373 KFParticle zeeKF;
@@ -362,17 +386,9 @@ struct HfTaskElectronWeakBoson {
362386 }
363387 float massZee, massZeeErr;
364388 zeeKF.GetMass (massZee, massZeeErr);
389+ registry.fill (HIST (" hKfInvMassZee" ), track.sign () * charge, kfpIsoEle.GetPt (), massZee);
365390 // LOG(info) << "Invarimass cal by KF particle mass = " << massZee;
366391 // LOG(info) << "Invarimass cal by RecoDecay = " << invMassEE;
367-
368- if (track.sign () * charge > 0 ) {
369- registry.fill (HIST (" hKfInvMassZeeLs" ), kfpIsoEle.GetPt (), massZee);
370- registry.fill (HIST (" hInvMassZeeLs" ), kfpIsoEle.GetPt (), invMassEE);
371- } else {
372- registry.fill (HIST (" hKfInvMassZeeUls" ), kfpIsoEle.GetPt (), massZee);
373- registry.fill (HIST (" hInvMassZeeUls" ), kfpIsoEle.GetPt (), invMassEE);
374- }
375-
376392 reconstructedZ.emplace_back (
377393 zeeKF.GetPt (),
378394 zeeKF.GetEta (),
@@ -384,7 +400,8 @@ struct HfTaskElectronWeakBoson {
384400 }
385401 }
386402
387- void process (soa::Filtered<aod::Collisions>::iterator const & collision,
403+ // void process(soa::Filtered<aod::Collisions>::iterator const& collision,
404+ void process (soa::Filtered<CollisionsWithCent>::iterator const & collision,
388405 aod::BCsWithTimestamps const &,
389406 SelectedClusters const & emcClusters,
390407 TrackEle const & tracks,
@@ -446,6 +463,16 @@ struct HfTaskElectronWeakBoson {
446463
447464 registry.fill (HIST (" hZvtx" ), collision.posZ ());
448465
466+ // Calculate centrality
467+ if (enableCentralityAnalysis) {
468+ float centrality = getCentrality (collision);
469+ // LOG(info) << centrality;
470+ if (centrality < centralityMin || centrality > centralityMax) {
471+ return ;
472+ }
473+ registry.fill (HIST (" hCentrality" ), centrality);
474+ }
475+
449476 for (const auto & track : tracks) {
450477
451478 if (std::abs (track.eta ()) > etaTrMax) {
@@ -562,8 +589,9 @@ struct HfTaskElectronWeakBoson {
562589 }
563590 // LOG(info) << "E/p" << eop;
564591 registry.fill (HIST (" hEopNsigTPC" ), match.track_as <TrackEle>().tpcNSigmaEl (), eop);
565- if (match.emcalcluster_as <SelectedClusters>().m02 () < m02Min || match.emcalcluster_as <SelectedClusters>().m02 () > m02Max)
592+ if (match.emcalcluster_as <SelectedClusters>().m02 () < m02Min || match.emcalcluster_as <SelectedClusters>().m02 () > m02Max) {
566593 continue ;
594+ }
567595
568596 if (match.track_as <TrackEle>().tpcNSigmaEl () > nsigTpcMin && match.track_as <TrackEle>().tpcNSigmaEl () < nsigTpcMax) {
569597 registry.fill (HIST (" hEop" ), match.track_as <TrackEle>().pt (), eop);
@@ -624,7 +652,8 @@ struct HfTaskElectronWeakBoson {
624652 }
625653 // calculate Z-h correlation
626654 double deltaPhi = RecoDecay::constrainAngle (trackAss.phi - zBoson.phi , -o2::constants::math::PIHalf);
627- registry.fill (HIST (" hZHadronDphi" ), zBoson.charge , zBoson.pt , deltaPhi);
655+ double ptRatio = trackAss.pt / zBoson.pt ;
656+ registry.fill (HIST (" hZHadronDphi" ), zBoson.charge , zBoson.pt , deltaPhi, ptRatio, trackAss.pt );
628657 }
629658 }
630659 } // end of Z-hadron correlation
0 commit comments