Skip to content

Commit 189bee7

Browse files
authored
[PWGCF] Add pT efficiency calculation (#15846)
1 parent e6947d3 commit 189bee7

1 file changed

Lines changed: 194 additions & 30 deletions

File tree

PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx

Lines changed: 194 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,49 +16,52 @@
1616
/// \since October 28, 2025
1717

1818
#include "PWGCF/Core/CorrelationContainer.h"
19-
#include "PWGCF/Core/PairCuts.h"
2019
#include "PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h"
2120
#include "PWGLF/DataModel/LFStrangenessTables.h"
2221
#include "PWGMM/Mult/DataModel/bestCollisionTable.h"
22+
#include "PWGUD/Core/SGCutParHolder.h"
2323
#include "PWGUD/Core/SGSelector.h"
24+
#include "PWGUD/Core/UDHelpers.h"
2425
#include "PWGUD/Core/UPCHelpers.h"
2526

27+
#include "Common/CCDB/EventSelectionParams.h"
2628
#include "Common/Core/RecoDecay.h"
2729
#include "Common/Core/TrackSelection.h"
2830
#include "Common/Core/TrackSelectionDefaults.h"
29-
#include "Common/Core/trackUtilities.h"
3031
#include "Common/DataModel/Centrality.h"
31-
#include "Common/DataModel/CollisionAssociationTables.h"
3232
#include "Common/DataModel/EventSelection.h"
33-
#include "Common/DataModel/FT0Corrected.h"
3433
#include "Common/DataModel/Multiplicity.h"
3534
#include "Common/DataModel/PIDResponseITS.h"
3635
#include "Common/DataModel/PIDResponseTOF.h"
3736
#include "Common/DataModel/PIDResponseTPC.h"
3837
#include "Common/DataModel/TrackSelectionTables.h"
3938

40-
#include "CCDB/BasicCCDBManager.h"
41-
#include "CCDB/CcdbApi.h"
42-
#include "CommonConstants/MathConstants.h"
43-
#include "CommonConstants/PhysicsConstants.h"
44-
#include "DetectorsCommonDataFormats/AlignParam.h"
45-
#include "FT0Base/Geometry.h"
46-
#include "Framework/ASoAHelpers.h"
47-
#include "Framework/AnalysisDataModel.h"
48-
#include "Framework/AnalysisTask.h"
49-
#include "Framework/HistogramRegistry.h"
50-
#include "Framework/O2DatabasePDGPlugin.h"
51-
#include "Framework/runDataProcessing.h"
52-
#include "ReconstructionDataFormats/PID.h"
53-
#include "ReconstructionDataFormats/Track.h"
54-
55-
#include <TComplex.h>
56-
#include <TH1F.h>
57-
#include <TMath.h>
58-
#include <TPDGCode.h>
59-
39+
#include <CCDB/BasicCCDBManager.h>
40+
#include <CCDB/CcdbApi.h>
41+
#include <CommonConstants/PhysicsConstants.h>
42+
#include <DetectorsCommonDataFormats/AlignParam.h>
43+
#include <FT0Base/Geometry.h>
44+
#include <Framework/AnalysisDataModel.h>
45+
#include <Framework/AnalysisHelpers.h>
46+
#include <Framework/AnalysisTask.h>
47+
#include <Framework/Configurable.h>
48+
#include <Framework/HistogramRegistry.h>
49+
#include <Framework/HistogramSpec.h>
50+
#include <Framework/InitContext.h>
51+
#include <Framework/O2DatabasePDGPlugin.h>
52+
#include <Framework/OutputObjHeader.h>
53+
#include <Framework/runDataProcessing.h>
54+
#include <MathUtils/Utils.h>
55+
#include <ReconstructionDataFormats/PID.h>
56+
57+
#include <sys/types.h>
58+
59+
#include <array>
6060
#include <chrono>
61+
#include <cmath>
62+
#include <cstdint>
6163
#include <cstdio>
64+
#include <cstdlib>
6265
#include <string>
6366
#include <vector>
6467

@@ -74,6 +77,8 @@ auto static constexpr CintZero = 0;
7477
auto static constexpr KminFt0cCell = 96;
7578
AxisSpec axisEvent{15, 0.5, 15.5, "#Event", "EventAxis"};
7679
auto static constexpr KminCharge = 3.0f;
80+
static constexpr std::string_view species[] = {"Pi", "Ka", "Pr", "K0s", "L0s"};
81+
static constexpr std::array<int, 5> speciesIds{kPiPlus, kKPlus, kProton, kK0Short, kLambda0};
7782

7883
enum KindOfV0 {
7984
kLambda = 0,
@@ -105,6 +110,7 @@ struct LongrangeMaker {
105110
Configurable<bool> isApplyCentFT0M{"isApplyCentFT0M", false, "Centrality based on FT0A + FT0C"};
106111
Configurable<bool> isApplyOccuSelection{"isApplyOccuSelection", false, "Enable occupancy selection"};
107112
Configurable<int> cfgOccuCut{"cfgOccuCut", 1000, "Occupancy selection"};
113+
Configurable<float> cfgVtxCut{"cfgVtxCut", 10.0f, "vertex Z selection"};
108114
Configurable<bool> isApplyBestCollIndex{"isApplyBestCollIndex", true, "bestCollIndex"};
109115
} cfgevtsel;
110116

@@ -130,6 +136,13 @@ struct LongrangeMaker {
130136
Configurable<float> cfgMftPtCutMax{"cfgMftPtCutMax", 10.f, "maximum accepted MFT track pT"};
131137
} cfgmfttrksel;
132138

139+
struct : ConfigurableGroup {
140+
Configurable<float> cfigFt0aEtaMax{"cfigFt0aEtaMax", 4.9f, "Maximum FT0A eta cut"};
141+
Configurable<float> cfigFt0aEtaMin{"cfigFt0aEtaMin", 3.5f, "Minimum FT0A eta cut"};
142+
Configurable<float> cfigFt0cEtaMax{"cfigFt0cEtaMax", -2.1f, "Maximum FT0C eta cut"};
143+
Configurable<float> cfigFt0cEtaMin{"cfigFt0cEtaMin", -3.3f, "Minimum FT0C eta cut"};
144+
} cfgfittrksel;
145+
133146
struct : ConfigurableGroup {
134147
Configurable<float> minTPCcrossedrows{"minTPCcrossedrows", 70.f, "cut on minimum number of crossed rows in TPC"};
135148
Configurable<float> minTPCcrossedrowsoverfindcls{"minTPCcrossedrowsoverfindcls", 0.8f, "cut on minimum value of the ratio between crossed rows and findable clusters in the TPC"};
@@ -162,6 +175,13 @@ struct LongrangeMaker {
162175
Configurable<std::vector<double>> tofNsigmaPidCut{"tofNsigmaPidCut", std::vector<double>{1.5, 1.5, 1.5, -1.5, -1.5, -1.5}, "TOF n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"};
163176
Configurable<float> cfgTofPidPtCut{"cfgTofPidPtCut", 0.3f, "Minimum pt to use TOF N-sigma"};
164177
Configurable<bool> isUseItsPid{"isUseItsPid", false, "Use ITS PID for particle identification"};
178+
Configurable<int> isUseDataLikeMult{"isUseDataLikeMult", 0, "Data like mult/cent classification"};
179+
180+
ConfigurableAxis vtxHistBin{"vtxHistBin", {20, -10, 10}, ""};
181+
ConfigurableAxis multHistBin{"multHistBin", {100, 0, 100}, ""};
182+
ConfigurableAxis etaHistBin{"etaHistBin", {20, -1, 1}, ""};
183+
ConfigurableAxis ptHistBin{"ptHistBin", {10, 0, 10}, ""};
184+
ConfigurableAxis speciesHistBin{"speciesHistBin", {6, 0.5, 6.5}, ""};
165185

166186
Service<o2::ccdb::BasicCCDBManager> ccdb;
167187
Service<o2::framework::O2DatabasePDG> pdg;
@@ -212,6 +232,27 @@ struct LongrangeMaker {
212232
x->SetBinLabel(12, "ApplyOccupancySelection");
213233
histos.add("hSelectionResult", "hSelectionResult", kTH1I, {{5, -0.5, 4.5}});
214234

235+
AxisSpec axisVtx = {vtxHistBin, "Vertex", "VtxAxis"};
236+
AxisSpec axisMult = {multHistBin, "Mult", "MultAxis"};
237+
AxisSpec axisEta = {etaHistBin, "Eta", "EtaAxis"};
238+
AxisSpec axisPt = {ptHistBin, "Pt", "PtAxis"};
239+
AxisSpec axisSpecies = {speciesHistBin, "Species", "SpeciesAxis"};
240+
241+
if (doprocessTPCtrackEff || doprocessMFTtrackEff) {
242+
histos.add("hGenMCdndpt", "hGenMCdndpt", kTHnSparseD, {axisVtx, axisMult, axisEta, axisPt, axisSpecies}, false);
243+
histos.add("hRecMCdndpt", "hRecMCdndpt", kTHnSparseD, {axisVtx, axisMult, axisEta, axisPt, axisSpecies}, false);
244+
auto hGenSpecies = histos.get<THnSparse>(HIST("hGenMCdndpt"));
245+
auto hRecSpecies = histos.get<THnSparse>(HIST("hRecMCdndpt"));
246+
auto* axisGen = hGenSpecies->GetAxis(4);
247+
auto* axisRec = hRecSpecies->GetAxis(4);
248+
for (auto i = 0U; i < speciesIds.size(); ++i) {
249+
axisGen->SetBinLabel(i + 1, species[i].data());
250+
axisRec->SetBinLabel(i + 1, species[i].data());
251+
}
252+
axisGen->SetBinLabel(6, "Other");
253+
axisRec->SetBinLabel(6, "Other");
254+
}
255+
215256
myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default);
216257
myTrackFilter.SetPtRange(cfgtrksel.cfgPtCutMin, cfgtrksel.cfgPtCutMax);
217258
myTrackFilter.SetEtaRange(-cfgtrksel.cfgEtaCut, cfgtrksel.cfgEtaCut);
@@ -604,12 +645,12 @@ struct LongrangeMaker {
604645
if (std::abs(particle.eta()) < cfgtrksel.cfgEtaCut && particle.pt() > cfgtrksel.cfgPtCutMin && particle.pt() < cfgtrksel.cfgPtCutMult)
605646
lrmidmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), particle.flags());
606647
// Fill FT0 tracks
607-
if (3.5 < particle.eta() && particle.eta() < 4.9)
648+
if (cfgfittrksel.cfigFt0aEtaMin < particle.eta() && particle.eta() < cfgfittrksel.cfigFt0aEtaMax)
608649
lrft0amctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi());
609-
if (-3.3 < particle.eta() && particle.eta() < -2.1)
650+
if (cfgfittrksel.cfigFt0cEtaMin < particle.eta() && particle.eta() < cfgfittrksel.cfigFt0cEtaMax)
610651
lrft0cmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi());
611652
// Fill MFT tracks
612-
if (-3.6 < particle.eta() && particle.eta() < -2.4)
653+
if (cfgmfttrksel.cfigMftEtaMin < particle.eta() && particle.eta() < cfgmfttrksel.cfigMftEtaMax)
613654
lrmftmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi());
614655
}
615656
}
@@ -633,16 +674,137 @@ struct LongrangeMaker {
633674
if (std::abs(particle.eta()) < cfgtrksel.cfgEtaCut && particle.pt() > cfgtrksel.cfgPtCutMin && particle.pt() < cfgtrksel.cfgPtCutMult)
634675
lrmidmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), particle.flags());
635676
// Fill FT0 tracks
636-
if (3.5 < particle.eta() && particle.eta() < 4.9)
677+
if (cfgfittrksel.cfigFt0aEtaMin < particle.eta() && particle.eta() < cfgfittrksel.cfigFt0aEtaMax)
637678
lrft0amctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi());
638-
if (-3.3 < particle.eta() && particle.eta() < -2.1)
679+
if (cfgfittrksel.cfigFt0cEtaMin < particle.eta() && particle.eta() < cfgfittrksel.cfigFt0cEtaMax)
639680
lrft0cmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi());
640681
// Fill MFT tracks
641-
if (-3.6 < particle.eta() && particle.eta() < -2.4)
682+
if (cfgmfttrksel.cfigMftEtaMin < particle.eta() && particle.eta() < cfgmfttrksel.cfigMftEtaMax)
642683
lrmftmctracks(lrmccollision.lastIndex(), particle.pt(), particle.eta(), particle.phi());
643684
}
644685
}
645686

687+
void processTPCtrackEff(ColMCTrueTable::iterator const& mcCollision, ColMCRecTable const& RecCols,
688+
TrksMCRecTable const& RecTracks, aod::McParticles const& mcparticles)
689+
{
690+
if (std::abs(mcCollision.posZ()) >= cfgevtsel.cfgVtxCut) {
691+
return;
692+
}
693+
auto multiplicity = 0;
694+
for (const auto& particle : mcparticles) {
695+
if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMin || particle.pt() > cfgtrksel.cfgPtCutMult)
696+
continue;
697+
multiplicity++;
698+
}
699+
if (isUseDataLikeMult > 0) {
700+
for (const auto& RecCol : RecCols) {
701+
if (!isEventSelected(RecCol)) {
702+
continue;
703+
}
704+
if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut) {
705+
continue;
706+
}
707+
if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) {
708+
continue;
709+
}
710+
multiplicity = selColCent(RecCol);
711+
}
712+
}
713+
714+
for (const auto& particle : mcparticles) {
715+
if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMin || particle.pt() > cfgtrksel.cfgPtCutMult)
716+
continue;
717+
auto pos = std::distance(speciesIds.begin(), std::find(speciesIds.begin(), speciesIds.end(), particle.pdgCode())) + 1;
718+
histos.fill(HIST("hGenMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), pos);
719+
}
720+
721+
for (const auto& RecCol : RecCols) {
722+
if (!isEventSelected(RecCol)) {
723+
continue;
724+
}
725+
if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut) {
726+
continue;
727+
}
728+
if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) {
729+
continue;
730+
}
731+
auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex());
732+
for (const auto& track : recTracksPart) {
733+
if (!track.isGlobalTrack())
734+
continue;
735+
if (!myTrackFilter.IsSelected(track))
736+
continue;
737+
if (!track.has_mcParticle())
738+
continue;
739+
auto particle = track.mcParticle();
740+
if (RecCol.mcCollisionId() != particle.mcCollisionId())
741+
continue;
742+
if (particle.isPhysicalPrimary()) {
743+
auto pos = std::distance(speciesIds.begin(), std::find(speciesIds.begin(), speciesIds.end(), particle.pdgCode())) + 1;
744+
histos.fill(HIST("hRecMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), pos);
745+
}
746+
}
747+
}
748+
}
749+
750+
void processMFTtrackEff(ColMCTrueTable::iterator const& mcCollision, ColMCRecTable const& RecCols,
751+
MftTrkMCRecTable const& mfttracks, aod::McParticles const& mcparticles)
752+
{
753+
if (std::abs(mcCollision.posZ()) >= cfgevtsel.cfgVtxCut) {
754+
return;
755+
}
756+
auto multiplicity = 0;
757+
for (const auto& particle : mcparticles) {
758+
if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMin || particle.pt() > cfgtrksel.cfgPtCutMult)
759+
continue;
760+
multiplicity++;
761+
}
762+
if (isUseDataLikeMult > 0) {
763+
for (const auto& RecCol : RecCols) {
764+
if (!isEventSelected(RecCol)) {
765+
continue;
766+
}
767+
if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut) {
768+
continue;
769+
}
770+
if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) {
771+
continue;
772+
}
773+
multiplicity = selColCent(RecCol);
774+
}
775+
}
776+
777+
for (const auto& particle : mcparticles) {
778+
if (!isGenPartSelected(particle) || particle.eta() > cfgmfttrksel.cfigMftEtaMax || particle.eta() < cfgmfttrksel.cfigMftEtaMin || particle.pt() < cfgmfttrksel.cfgMftPtCutMin || particle.pt() > cfgmfttrksel.cfgMftPtCutMax)
779+
continue;
780+
histos.fill(HIST("hGenMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), 1.0);
781+
}
782+
783+
for (const auto& RecCol : RecCols) {
784+
if (!isEventSelected(RecCol)) {
785+
continue;
786+
}
787+
if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut) {
788+
continue;
789+
}
790+
if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) {
791+
continue;
792+
}
793+
auto recTracksPart = mfttracks.sliceBy(perColMfttrack, RecCol.globalIndex());
794+
for (const auto& track : recTracksPart) {
795+
if (!isMftTrackSelected(track))
796+
continue;
797+
if (!track.has_mcParticle())
798+
continue;
799+
auto particle = track.mcParticle();
800+
if (RecCol.mcCollisionId() != particle.mcCollisionId())
801+
continue;
802+
if (particle.isPhysicalPrimary())
803+
histos.fill(HIST("hRecMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), 1.0);
804+
}
805+
}
806+
}
807+
646808
template <typename CheckGenPart>
647809
bool isGenPartSelected(CheckGenPart const& particle)
648810
{
@@ -945,6 +1107,8 @@ struct LongrangeMaker {
9451107
PROCESS_SWITCH(LongrangeMaker, processUpc, "process UPC collisions", false);
9461108
PROCESS_SWITCH(LongrangeMaker, processMCGen, "process MC generated collisions", false);
9471109
PROCESS_SWITCH(LongrangeMaker, processMCRec, "process MC both gen and rec collisions", false);
1110+
PROCESS_SWITCH(LongrangeMaker, processTPCtrackEff, "process TPC track efficiency", false);
1111+
PROCESS_SWITCH(LongrangeMaker, processMFTtrackEff, "process MFT track efficiency", false);
9481112
};
9491113

9501114
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)

0 commit comments

Comments
 (0)