diff --git a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx index 4539149c69d..9ea3763b482 100644 --- a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx +++ b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx @@ -70,12 +70,14 @@ struct HfTaskElectronWeakBoson { Configurable vtxZ{"vtxZ", 10.f, ""}; - Configurable etaTrMim{"etaTrMim", -1.0f, "minimun track eta"}; + Configurable etaTrMin{"etaTrMin", -1.0f, "minimun track eta"}; Configurable etaTrMax{"etaTrMax", 1.0f, "maximum track eta"}; Configurable etaEmcMax{"etaEmcMax", 0.6f, "maximum track eta"}; Configurable dcaxyMax{"dcaxyMax", 2.0f, "mximum DCA xy"}; Configurable chi2ItsMax{"chi2ItsMax", 15.0f, "its chi2 cut"}; Configurable ptMin{"ptMin", 3.0f, "minimum pT cut"}; + Configurable ptAssMin{"ptAssMin", 0.15, "minimum pT cut for associated hadrons"}; + Configurable ptMatch{"ptMatch", 0.001, "pT match in Z->ee and associated tracks"}; Configurable ptZeeMin{"ptZeeMin", 20.0f, "minimum pT cut for Zee"}; Configurable chi2TpcMax{"chi2TpcMax", 4.0f, "tpc chi2 cut"}; Configurable nclItsMin{"nclItsMin", 2.0f, "its # of cluster cut"}; @@ -100,6 +102,9 @@ struct HfTaskElectronWeakBoson { Configurable energyIsolationMax{"energyIsolationMax", 0.1, "isolation cut on energy"}; Configurable trackIsolationMax{"trackIsolationMax", 3, "Maximum number of tracks in isolation cone"}; + Configurable massZMin{"massZMin", 60.0, "Minimum Z mass (GeV/c^2)"}; + Configurable massZMax{"massZMax", 120.0, "Maximum Z mass (GeV/c^2)"}; + // flag for THn Configurable isTHnElectron{"isTHnElectron", true, "Enables THn for electrons"}; Configurable ptTHnThresh{"ptTHnThresh", 5.0, "Threshold for THn make"}; @@ -114,7 +119,7 @@ struct HfTaskElectronWeakBoson { // KFParticle Configurable kfConstructMethod{"kfConstructMethod", 2, "KF Construct Method"}; - Configurable kfChisqMassMax{"kfChisqMassMax", 10, "Chi2 Max for mass reco by KF particle"}; + Configurable chiSqNdfMax{"chiSqNdfMax", 10, "Chi2 Max for mass reco by KF particle"}; // CCDB service object Service ccdb; @@ -129,7 +134,14 @@ struct HfTaskElectronWeakBoson { }; std::vector selectedElectronsIso; std::vector selectedElectronsAss; - std::vector reconstructedZ; + + struct HfZeeCandidate { + float pt, eta, phi, mass, ptchild0, ptchild1; + int charge; + HfZeeCandidate(float ptr, float e, float ph, float m, int ch, float ptzee0, float ptzee1) + : pt(ptr), eta(e), phi(ph), mass(m), ptchild0(ptzee0), ptchild1(ptzee1), charge(ch) {} + }; + std::vector reconstructedZ; using SelectedClusters = o2::aod::EMCALClusters; // PbPb @@ -143,7 +155,7 @@ struct HfTaskElectronWeakBoson { Filter eventFilter = (o2::aod::evsel::sel8 == true); Filter posZFilter = (nabs(o2::aod::collision::posZ) < vtxZ); - Filter etafilter = (aod::track::eta < etaTrMax) && (aod::track::eta > etaTrMim); + Filter etafilter = (aod::track::eta < etaTrMax) && (aod::track::eta > etaTrMin); Filter dcaxyfilter = (nabs(aod::track::dcaXY) < dcaxyMax); Filter filterGlobalTr = requireGlobalTrackInFilter(); @@ -200,6 +212,9 @@ struct HfTaskElectronWeakBoson { const AxisSpec axisIsoTrack{15, -0.5, 14.5, "Isolation Track"}; const AxisSpec axisInvMassZ{150, 0, 150, "M_{ee} (GeV/c^{2})"}; const AxisSpec axisTrigger{3, -0.5, 2.5, "Trigger status of zorro"}; + const AxisSpec axisDPhiZh{64, -o2::constants::math::PIHalf, 3 * o2::constants::math::PIHalf, "#Delta#phi(Z-h)"}; + const AxisSpec axisPtHadron{50, 0, 50, "p_{T,hadron} (GeV/c)"}; + const AxisSpec axisZpt{150, 0, 150, "p_{T,Z} (GeV/c)"}; // create registrygrams registry.add("hZvtx", "Z vertex", kTH1F, {axisZvtx}); @@ -233,6 +248,10 @@ struct HfTaskElectronWeakBoson { registry.add("hTHnElectrons", "electron info", HistType::kTHnSparseF, {axisPt, axisNsigma, axisM02, axisEop, axisIsoEnergy, axisIsoTrack}); registry.add("hTHnTrMatch", "Track EMC Match", HistType::kTHnSparseF, {axisPt, axisdPhi, axisdEta}); + // Z-hadron correlation histograms + registry.add("hZHadronDphi", "Z-hadron #Delta#phi correlation", kTH2F, {{axisZpt}, {axisDPhiZh}}); + registry.add("hZptSpectrum", "Z boson p_{T} spectrum", kTH1F, {axisZpt}); + // hisotgram for EMCal trigger registry.add("hEMCalTrigger", "EMCal trigger", kTH1F, {axisTrigger}); } @@ -302,13 +321,15 @@ struct HfTaskElectronWeakBoson { // LOG(info) << "Invarimass cal by KF particle "; for (const auto& track : tracks) { - if (track.pt() < ptZeeMin) + if (track.pt() < ptZeeMin) { continue; - if (std::abs(track.tpcNSigmaEl()) > nsigTpcMax) + } + if (std::abs(track.tpcNSigmaEl()) > nsigTpcMax) { continue; - if (std::abs(track.eta()) > etaTrMax) + } + if (std::abs(track.eta()) > etaTrMax) { continue; - + } int pdgAss = kElectron; if (track.sign() > 0) { pdgAss = kPositron; @@ -316,24 +337,35 @@ struct HfTaskElectronWeakBoson { KFPTrack kfpTrackAssEle = createKFPTrackFromTrack(track); KFParticle kfpAssEle(kfpTrackAssEle, pdgAss); + // reco by RecoDecay + auto child1 = RecoDecayPtEtaPhi::pVector(kfpIsoEle.GetPt(), kfpIsoEle.GetEta(), kfpIsoEle.GetPhi()); + auto child2 = RecoDecayPtEtaPhi::pVector(kfpAssEle.GetPt(), kfpAssEle.GetEta(), kfpAssEle.GetPhi()); + double invMassEE = RecoDecay::m(std::array{child1, child2}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron}); + + // reco by KFparticle const KFParticle* electronPairs[2] = {&kfpIsoEle, &kfpAssEle}; KFParticle zeeKF; zeeKF.SetConstructMethod(kfConstructMethod); zeeKF.Construct(electronPairs, 2); // LOG(info) << "Invarimass cal by KF particle Chi2/NDF = " << zeeKF.GetChi2()/zeeKF.GetNDF(); - float massZeeChi2 = zeeKF.GetChi2() / zeeKF.GetNDF(); - if (zeeKF.GetNDF() < 1) + float chiSqNdf = zeeKF.GetChi2() / zeeKF.GetNDF(); + if (zeeKF.GetNDF() < 1) { continue; - if (std::abs(massZeeChi2) > kfChisqMassMax) + } + if (chiSqNdf > chiSqNdfMax) { continue; + } float massZee, massZeeErr; zeeKF.GetMass(massZee, massZeeErr); // LOG(info) << "Invarimass cal by KF particle mass = " << massZee; + // LOG(info) << "Invarimass cal by RecoDecay = " << invMassEE; if (track.sign() * charge > 0) { registry.fill(HIST("hKfInvMassZeeLs"), kfpIsoEle.GetPt(), massZee); + registry.fill(HIST("hInvMassZeeLs"), kfpIsoEle.GetPt(), invMassEE); } else { registry.fill(HIST("hKfInvMassZeeUls"), kfpIsoEle.GetPt(), massZee); + registry.fill(HIST("hInvMassZeeUls"), kfpIsoEle.GetPt(), invMassEE); } reconstructedZ.emplace_back( @@ -341,7 +373,9 @@ struct HfTaskElectronWeakBoson { zeeKF.GetEta(), zeeKF.GetPhi(), massZee, - track.sign() * charge); + track.sign() * charge, + kfpIsoEle.GetPt(), + kfpAssEle.GetPt()); } } @@ -409,22 +443,27 @@ struct HfTaskElectronWeakBoson { for (const auto& track : tracks) { - if (std::abs(track.eta()) > etaTrMax) - continue; - if (track.tpcNClsCrossedRows() < nclcrossTpcMin) + if (std::abs(track.eta()) > etaTrMax) { continue; - if (std::abs(track.dcaXY()) > dcaxyMax) + } + if (track.tpcNClsCrossedRows() < nclcrossTpcMin) { continue; - if (track.itsChi2NCl() > chi2ItsMax) + } + if (std::abs(track.dcaXY()) > dcaxyMax) { continue; - if (track.tpcChi2NCl() > chi2TpcMax) + } + if (track.itsChi2NCl() > chi2ItsMax) { continue; - if (track.tpcNClsFound() < nclTpcMin) + } + if (track.tpcChi2NCl() > chi2TpcMax) { continue; - if (track.itsNCls() < nclItsMin) + } + if (track.tpcNClsFound() < nclTpcMin) { continue; - if (track.pt() < ptMin) + } + if (track.itsNCls() < nclItsMin) { continue; + } registry.fill(HIST("hEta"), track.eta()); registry.fill(HIST("hITSchi2"), track.itsChi2NCl()); @@ -437,7 +476,7 @@ struct HfTaskElectronWeakBoson { float energyTrk = 0.0; - if (track.tpcNSigmaEl() > nsigTpcMinLose && track.tpcNSigmaEl() < nsigTpcMax && track.pt() > ptZeeMin) { + if (track.pt() > ptAssMin) { selectedElectronsAss.emplace_back( track.pt(), track.eta(), @@ -446,6 +485,9 @@ struct HfTaskElectronWeakBoson { track.sign()); } + if (track.pt() < ptMin) { + continue; + } // track - match // continue; @@ -550,7 +592,6 @@ struct HfTaskElectronWeakBoson { } } } - nMatch++; } } @@ -561,30 +602,26 @@ struct HfTaskElectronWeakBoson { } } // end of track loop - - // calculate inv. mass - if (selectedElectronsIso.size() > 0) { - for (size_t i = 0; i < selectedElectronsIso.size(); i++) { - const auto& e1 = selectedElectronsIso[i]; - for (size_t j = 0; j < selectedElectronsAss.size(); j++) { - const auto& e2 = selectedElectronsAss[j]; - - float ptIso = e1.pt; - float ptAss = e2.pt; - if (ptIso == ptAss) + // Z-hadron + if (reconstructedZ.size() > 0) { + for (const auto& zBoson : reconstructedZ) { + // Z boson selection + if (zBoson.mass < massZMin || zBoson.mass > massZMax) + continue; + registry.fill(HIST("hZptSpectrum"), zBoson.pt); + for (const auto& trackAss : selectedElectronsAss) { + if (std::abs(trackAss.pt - zBoson.ptchild0) < ptMatch) { + continue; + } + if (std::abs(trackAss.pt - zBoson.ptchild1) < ptMatch) { continue; - auto arr1 = RecoDecayPtEtaPhi::pVector(e1.pt, e1.eta, e1.phi); - auto arr2 = RecoDecayPtEtaPhi::pVector(e2.pt, e2.eta, e2.phi); - double mass = RecoDecay::m(std::array{arr1, arr2}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron}); - - if (e1.sign() * e2.sign() > 0) { - registry.fill(HIST("hInvMassZeeLs"), ptIso, mass); - } else { - registry.fill(HIST("hInvMassZeeUls"), ptIso, mass); } + // calculate Z-h correlation + double deltaPhi = RecoDecay::constrainAngle(trackAss.phi - zBoson.phi, -o2::constants::math::PIHalf); + registry.fill(HIST("hZHadronDphi"), zBoson.pt, deltaPhi); } } - } // end of inv. mass calculation + } // end of Z-hadron correlation } };