diff --git a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx index 67837173150..17dcdd62ec5 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx @@ -230,6 +230,8 @@ std::shared_ptr hFlowHists[2][5]; std::shared_ptr hDCAHists[2][5]; std::shared_ptr hMatchingStudy[2]; std::shared_ptr hMatchingStudyHadrons[2]; +std::shared_ptr hMatchingCountsHadrons; +std::shared_ptr hMatchingCountsHe3; o2::base::MatLayerCylSet* lut = nullptr; std::vector candidates; @@ -366,6 +368,7 @@ struct nucleiSpectra { ConfigurableAxis cfgNITSClusBins{"cfgNITSClusBins", {3, 4.5, 7.5}, "N ITS clusters binning"}; ConfigurableAxis cfgNTPCClusBins{"cfgNTPCClusBins", {3, 89.5, 159.5}, "N TPC clusters binning"}; + Configurable cfgMatchingCounts{"cfgMatchingCounts", false, "Enable event-level ITS-TPC matching counts for binomiality studies"}; Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", false, "Skimmed dataset processing"}; Configurable cfgTriggerList{"cfgTriggerList", "fHe", "Trigger List"}; Configurable cfgSelectTrgEv{"cfgSelectTrgEv", false, "If true, select events with active trigger list"}; @@ -601,6 +604,10 @@ struct nucleiSpectra { if (doprocessMatching) { std::vector occBins{-0.5, 499.5, 999.5, 1999.5, 2999.5, 3999.5, 4999.5, 10000., 50000.}; AxisSpec occAxis{occBins, "Occupancy"}; + if (cfgMatchingCounts) { + nuclei::hMatchingCountsHadrons = spectra.add("hMatchingCountsHadrons", ";N_{ITS};N_{ITS+TPC};Centrality;Occupancy;Charge sign", HistType::kTHnSparseD, {{10001, -0.5, 10000.5}, {10001, -0.5, 10000.5}, {8, 0., 80.}, occAxis, {2, -0.5, 1.5}}); + nuclei::hMatchingCountsHe3 = spectra.add("hMatchingCountsHe3", ";N_{ITS};N_{ITS+TPC};Centrality;Occupancy;Charge sign", HistType::kTHnSparseD, {{10001, -0.5, 10000.5}, {10001, -0.5, 10000.5}, {8, 0., 80.}, occAxis, {2, -0.5, 1.5}}); + } for (unsigned int iC{0}; iC < nuclei::matter.size(); ++iC) { nuclei::hMatchingStudy[iC] = spectra.add(fmt::format("hMatchingStudy{}", nuclei::matter[iC]).data(), ";#it{p}_{T};#phi;#eta;n#sigma_{ITS};n#sigma{TPC};n#sigma_{TOF};Centrality", HistType::kTHnSparseF, {{20, 1., 9.}, {10, 0., o2::constants::math::TwoPI}, {10, -1., 1.}, {50, -5., 5.}, {50, -5., 5.}, {50, 0., 1.}, {8, 0., 80.}}); nuclei::hMatchingStudyHadrons[iC] = spectra.add(fmt::format("hMatchingStudyHadrons{}", nuclei::matter[iC]).data(), ";#it{p}_{T};#phi;#eta;Centrality;Track type; Occupancy", HistType::kTHnF, {{23, 0.4, 5.}, {20, 0., o2::constants::math::TwoPI}, {10, -1., 1.}, {8, 0., 80.}, {2, -0.5, 1.5}, occAxis}); @@ -1156,12 +1163,17 @@ struct nucleiSpectra { } PROCESS_SWITCH(nucleiSpectra, processMC, "MC analysis", false); - void processMatching(soa::Join::iterator const& collision, TrackCandidates const& tracks, aod::BCsWithTimestamps const&) + void processMatching(soa::Join::iterator const& collision, TrackCandidates const& tracks, aod::BCsWithTimestamps const&) { - if (!eventSelection(collision) || !collision.triggereventep()) { + if (!eventSelection(collision) || !collision.isCalibrated()) { return; } const float centrality = collision.centFT0C(); + const float psi2FT0C = std::atan2(collision.qvecFT0CIm(), collision.qvecFT0CRe()) / 2.f; + int nITSHadrons[2]{}; + int nITSTPCHadrons[2]{}; + int nITSHe3[2]{}; + int nITSTPCHe3[2]{}; o2::aod::ITSResponse itsResponse; for (const auto& track : tracks) { if (std::abs(track.eta()) > cfgTrackCut.EtaMax || @@ -1173,13 +1185,28 @@ struct nucleiSpectra { double expSigma{expBethe * cfgBetheBlochParams->get(4, 5u)}; double nSigmaTPC{(track.tpcSignal() - expBethe) / expSigma}; int iC = track.signed1Pt() > 0; + if (cfgMatchingCounts) { + ++nITSHadrons[iC]; + nITSTPCHadrons[iC] += track.hasTPC(); + } const float pt = track.pt(); - const float phi = 2.f * RecoDecay::constrainAngle(track.phi() - collision.psiFT0C(), 0.f, 2); + const float phi = 2.f * RecoDecay::constrainAngle(track.phi() - psi2FT0C, 0.f, 2); nuclei::hMatchingStudyHadrons[iC]->Fill(pt, phi, track.eta(), centrality, track.hasTPC(), collision.trackOccupancyInTimeRange()); - if (itsResponse.nSigmaITS(track) > -1.) { + if (itsResponse.nSigmaITS(track) > -2.) { + if (cfgMatchingCounts) { + ++nITSHe3[iC]; + nITSTPCHe3[iC] += track.hasTPC(); + } nuclei::hMatchingStudy[iC]->Fill(pt * 2, phi, track.eta(), itsResponse.nSigmaITS(track), nSigmaTPC, o2::pid::tof::Beta::GetBeta(track), centrality); } } + if (cfgMatchingCounts) { + // One entry per collision and charge sign, including zero-track events. + for (unsigned int iC{0}; iC < nuclei::matter.size(); ++iC) { + nuclei::hMatchingCountsHadrons->Fill(nITSHadrons[iC], nITSTPCHadrons[iC], centrality, collision.trackOccupancyInTimeRange(), iC); + nuclei::hMatchingCountsHe3->Fill(nITSHe3[iC], nITSTPCHe3[iC], centrality, collision.trackOccupancyInTimeRange(), iC); + } + } } PROCESS_SWITCH(nucleiSpectra, processMatching, "Matching analysis", false);