Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 161 additions & 22 deletions PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ struct LongrangeMaker {
Configurable<float> minV0DcaPiLambda{"minV0DcaPiLambda", 0.2f, "Min V0 pion DCA for Lambda"};
Configurable<float> minV0DcaPr{"minV0DcaPr", 0.07f, "Min V0 proton DCA for Lambda"};
Configurable<float> maxLambdaLifeTime{"maxLambdaLifeTime", 30.0f, "Maximum Lambda lifetime (in cm)"};

Configurable<float> rejK0sMassWindow{"rejK0sMassWindow", 0.012f, "K0s mass rejection window for Lambda (12 MeV/c^2)"};
Configurable<int> cfgQAV0Mask{"cfgQAV0Mask", 7, "Bitmask for V0 QA: 1=K0s, 2=Lambda, 4=ALambda, 7=All"};
} cfgv0trksel;

struct : ConfigurableGroup {
Expand All @@ -216,6 +219,23 @@ struct LongrangeMaker {
ConfigurableAxis axisMFTAmbDegree{"axisMFTAmbDegree", {50, -0.5, 49.5}, "Track Ambiguity axis"};
ConfigurableAxis axisEta = {"axisEta", {100, -5, 5}, "eta axis"};
ConfigurableAxis axisPhi{"axisPhi", {72, 0, TwoPI}, "#phi axis"};

ConfigurableAxis axisV0Species{"axisV0Species", {3, -0.5, 2.5}, "V0 Species (0=K0s, 1=#Lambda, 2=#bar{#Lambda})"};
ConfigurableAxis axisAlpha{"axisAlpha", {100, -1.0, 1.0}, "Armenteros #alpha"};
ConfigurableAxis axisQt{"axisQt", {100, 0.0, 0.42}, "Armenteros q_{T} (GeV/c)"};
ConfigurableAxis axisV0Pt{"axisV0Pt", {100, 0.0, 10.0}, "V0 p_{T} (GeV/c)"};
ConfigurableAxis axisMass{"axisMass", {150, 0.4, 1.2}, "Invariant Mass (GeV/c^{2})"};
ConfigurableAxis axisDcaV0Dau{"axisDcaV0Dau", {100, 0.0, 1.5}, "DCA between V0 Daughters (cm)"};
ConfigurableAxis axisDcaPosToPv{"axisDcaPosToPv", {100, 0.0, 10.0}, "DCA Pos-Prong to PV (cm)"};
ConfigurableAxis axisDcaNegToPv{"axisDcaNegToPv", {100, 0.0, 10.0}, "DCA Neg-Prong to PV (cm)"};
ConfigurableAxis axisDcaV0ToPv{"axisDcaV0ToPv", {100, 0.0, 5.0}, "DCA V0 to PV (cm)"};
ConfigurableAxis axisCosPA{"axisCosPA", {100, 0.97, 1.0}, "Cosine of Pointing Angle (cos#theta_{PA})"};
ConfigurableAxis axisRadius{"axisRadius", {100, 0.0, 100.0}, "V0 2D Decay Radius (cm)"};
ConfigurableAxis axisCtau{"axisCtau", {100, 0.0, 50.0}, "Proper Lifetime c#tau (cm)"};

ConfigurableAxis axisPQA{"axisPQA", {100, 0.0, 10.0}, "p (GeV/c)"};
ConfigurableAxis axisTpcSignal{"axisTpcSignal", {250, 0, 250}, "TPC dE/dx (a.u.)"};
ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 15, 25, 30, 40, 50, 60, 80, 100, 150, 200}, "Multiplicity / Centrality"};
} cfgAxis;

Configurable<std::vector<double>> itsNsigmaPidCut{"itsNsigmaPidCut", std::vector<double>{3, 2.5, 2, -3, -2.5, -2}, "ITS n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"};
Expand All @@ -228,7 +248,7 @@ struct LongrangeMaker {
Service<o2::framework::O2DatabasePDG> pdg;
o2::ccdb::CcdbApi ccdbApi;
o2::ft0::Geometry ft0Det;
std::vector<o2::detectors::AlignParam>* offsetFT0;
std::vector<o2::detectors::AlignParam>* offsetFT0{nullptr};
HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject};
TrackSelection myTrackFilter;

Expand Down Expand Up @@ -315,6 +335,17 @@ struct LongrangeMaker {
histos.add("FT0C_Channel_vs_phi", "FT0C_Channel_vs_phi", kTH2D, {cfgAxis.axisPhi, cfgAxis.axisChannel});
histos.add("h3DVtxZetaPhi", "", kTH3D, {{20, -10, 10}, {16, -0.8, +0.8}, {100, 0., TwoPI}});

histos.add("hArmenteros_before", "Armenteros-Podolanski (Before Cuts);#alpha;q_{T} (GeV/c)", kTH2D, {cfgAxis.axisAlpha, cfgAxis.axisQt});
histos.add("hArmenteros_after", "Armenteros-Podolanski (After Cuts);V0 Species;#alpha;q_{T} (GeV/c)", kTH3D, {cfgAxis.axisV0Species, cfgAxis.axisAlpha, cfgAxis.axisQt});
histos.add("hTopoQA", "V0 Topological and Kinematic QA;V0 Species;DCA between V0 Daughters (cm);DCA Pos-Prong to PV (cm);DCA Neg-Prong to PV (cm);DCA V0 to PV (cm);Cosine of Pointing Angle (cos#theta_{PA});V0 2D Decay Radius (cm);Proper Lifetime c#tau (cm);V0 p_{T} (GeV/c);Invariant Mass (GeV/c^{2})", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisDcaV0Dau, cfgAxis.axisDcaPosToPv, cfgAxis.axisDcaNegToPv, cfgAxis.axisDcaV0ToPv, cfgAxis.axisCosPA, cfgAxis.axisRadius, cfgAxis.axisCtau, cfgAxis.axisV0Pt, cfgAxis.axisMass});

// V0 Daughter dE/dx Histograms
histos.add("hTpcdEdx_pos_before", "Pos-prong dE/dx Before PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal});
histos.add("hTpcdEdx_neg_before", "Neg-prong dE/dx Before PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal});

histos.add("hTpcdEdx_pos_after", "Pos-prong dE/dx After PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal});
histos.add("hTpcdEdx_neg_after", "Neg-prong dE/dx After PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal});

myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny,
TrackSelection::GlobalTrackRun3DCAxyCut::Default);
myTrackFilter.SetPtRange(cfgtrksel.cfgPtCutMin, cfgtrksel.cfgPtCutMax);
Expand Down Expand Up @@ -816,9 +847,9 @@ struct LongrangeMaker {
}
}
auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex());
float multiplicity = countNTracks(recTracksPart, RecCol.posZ());
float recMultiplicity = countNTracks(recTracksPart, RecCol.posZ());
float centrality = selColCent(RecCol);
lrcollision(bc.runNumber(), RecCol.posZ(), multiplicity, centrality, bc.timestamp());
lrcollision(bc.runNumber(), RecCol.posZ(), recMultiplicity, centrality, bc.timestamp());
lrcollisionMcLabel(RecCol.mcCollisionId());

// track loop
Expand Down Expand Up @@ -1004,6 +1035,86 @@ struct LongrangeMaker {
}
}

void processV0QA(CollTable::iterator const& col, aod::V0Datas const& V0s, TrksTable const& tracks)
{
if (!isEventSelected(col)) {
return;
}

float multiplicity = selColCent(col);
if (multiplicity == -1) {
multiplicity = countNTracks(tracks, col.posZ());
}

bool checkK0s = (cfgv0trksel.cfgQAV0Mask & 1);
bool checkLam = (cfgv0trksel.cfgQAV0Mask & 2);
bool checkALam = (cfgv0trksel.cfgQAV0Mask & 4);

for (const auto& v0 : V0s) {
if (!isSelectV0Track(v0)) {
continue;
}

auto posTrack = v0.template posTrack_as<TrksTable>();
auto negTrack = v0.template negTrack_as<TrksTable>();
float posP = posTrack.p();
float negP = negTrack.p();
float posSignal = posTrack.tpcSignal();
float negSignal = negTrack.tpcSignal();

histos.fill(HIST("hArmenteros_before"), v0.alpha(), v0.qtarm());

// Evaluate topology ONLY (PID disabled)
bool isK0sTopoOnly = checkK0s && isSelectK0s(col, v0, false);
bool isLamTopoOnly = checkLam && isSelectLambda<KindOfV0::kLambda>(col, v0, false);
bool isAlamTopoOnly = checkALam && isSelectLambda<KindOfV0::kAntiLambda>(col, v0, false);

// Evaluate full selection (PID enabled)
bool isK0sTag = checkK0s && isSelectK0s(col, v0, true);
bool lambdaTag = checkLam && isSelectLambda<KindOfV0::kLambda>(col, v0, true);
bool antilambdaTag = checkALam && isSelectLambda<KindOfV0::kAntiLambda>(col, v0, true);

// ---------------- K0s ----------------
if (isK0sTopoOnly) {
histos.fill(HIST("hTpcdEdx_pos_before"), 0.0f, multiplicity, posP, posSignal);
histos.fill(HIST("hTpcdEdx_neg_before"), 0.0f, multiplicity, negP, negSignal);
}
if (isK0sTag) {
histos.fill(HIST("hTpcdEdx_pos_after"), 0.0f, multiplicity, posP, posSignal);
histos.fill(HIST("hTpcdEdx_neg_after"), 0.0f, multiplicity, negP, negSignal);
histos.fill(HIST("hArmenteros_after"), 0.0f, v0.alpha(), v0.qtarm());
float ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassK0;
histos.fill(HIST("hTopoQA"), 0.0f, v0.dcaV0daughters(), std::abs(v0.dcapostopv()), std::abs(v0.dcanegtopv()), std::abs(v0.dcav0topv()), v0.v0cosPA(), v0.v0radius(), ctau, v0.pt(), v0.mK0Short());
}

// -------------- Lambda ---------------
if (isLamTopoOnly) {
histos.fill(HIST("hTpcdEdx_pos_before"), 1.0f, multiplicity, posP, posSignal);
histos.fill(HIST("hTpcdEdx_neg_before"), 1.0f, multiplicity, negP, negSignal);
}
if (lambdaTag) {
histos.fill(HIST("hTpcdEdx_pos_after"), 1.0f, multiplicity, posP, posSignal);
histos.fill(HIST("hTpcdEdx_neg_after"), 1.0f, multiplicity, negP, negSignal);
histos.fill(HIST("hArmenteros_after"), 1.0f, v0.alpha(), v0.qtarm());
float ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassLambda;
histos.fill(HIST("hTopoQA"), 1.0f, v0.dcaV0daughters(), std::abs(v0.dcapostopv()), std::abs(v0.dcanegtopv()), std::abs(v0.dcav0topv()), v0.v0cosPA(), v0.v0radius(), ctau, v0.pt(), v0.mLambda());
}

// ----------- Anti-Lambda -------------
if (isAlamTopoOnly) {
histos.fill(HIST("hTpcdEdx_pos_before"), 2.0f, multiplicity, posP, posSignal);
histos.fill(HIST("hTpcdEdx_neg_before"), 2.0f, multiplicity, negP, negSignal);
}
if (antilambdaTag) {
histos.fill(HIST("hTpcdEdx_pos_after"), 2.0f, multiplicity, posP, posSignal);
histos.fill(HIST("hTpcdEdx_neg_after"), 2.0f, multiplicity, negP, negSignal);
histos.fill(HIST("hArmenteros_after"), 2.0f, v0.alpha(), v0.qtarm());
float ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassLambda;
histos.fill(HIST("hTopoQA"), 2.0f, v0.dcaV0daughters(), std::abs(v0.dcapostopv()), std::abs(v0.dcanegtopv()), std::abs(v0.dcav0topv()), v0.v0cosPA(), v0.v0radius(), ctau, v0.pt(), v0.mAntiLambda());
}
}
}

template <typename CheckGenPart>
bool isGenPartSelected(CheckGenPart const& particle)
{
Expand Down Expand Up @@ -1306,7 +1417,7 @@ struct LongrangeMaker {
}

template <typename Collision, typename V0candidate>
bool isSelectK0s(Collision const& col, const V0candidate& v0)
bool isSelectK0s(Collision const& col, const V0candidate& v0, bool applyPidCut = true)
{
const auto& posTrack = v0.template posTrack_as<TrksTable>();
const auto& negTrack = v0.template negTrack_as<TrksTable>();
Expand All @@ -1316,7 +1427,7 @@ struct LongrangeMaker {
if (v0.mK0Short() < cfgv0trksel.minK0sMass || v0.mK0Short() > cfgv0trksel.maxK0sMass) {
return false;
}
if ((v0.qtarm() / std::abs(v0.alpha())) < cfgv0trksel.minqtArmenterosForK0s) {
if (v0.qtarm() < (cfgv0trksel.minqtArmenterosForK0s * std::abs(v0.alpha()))) {
return false;
}
if (v0.v0radius() > cfgv0trksel.maxK0sRadius || v0.v0radius() < cfgv0trksel.minK0sRadius) {
Expand All @@ -1331,25 +1442,40 @@ struct LongrangeMaker {
if (std::abs(ctauK0s) > cfgv0trksel.maxK0sLifeTime) {
return false;
}
if (((std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts))) {
return false;
if (applyPidCut) {
if (std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts ||
std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) {
return false;
}
}
if ((std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiK0s || std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiK0s)) {
if (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiK0s ||
std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiK0s) {
return false;
}
return true;
}

template <KindOfV0 pid, typename Collision, typename V0candidate>
bool isSelectLambda(Collision const& col, const V0candidate& v0)
bool isSelectLambda(Collision const& col, const V0candidate& v0, bool applyPidCut = true)
{
const auto& posTrack = v0.template posTrack_as<TrksTable>();
const auto& negTrack = v0.template negTrack_as<TrksTable>();
float ctauLambda = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassLambda;
if ((v0.mLambda() < cfgv0trksel.minLambdaMass || v0.mLambda() > cfgv0trksel.maxLambdaMass) &&
(v0.mAntiLambda() < cfgv0trksel.minLambdaMass || v0.mAntiLambda() > cfgv0trksel.maxLambdaMass)) {

if constexpr (pid == KindOfV0::kLambda) {
if (v0.mLambda() < cfgv0trksel.minLambdaMass || v0.mLambda() > cfgv0trksel.maxLambdaMass) {
return false;
}
} else if constexpr (pid == KindOfV0::kAntiLambda) {
if (v0.mAntiLambda() < cfgv0trksel.minLambdaMass || v0.mAntiLambda() > cfgv0trksel.maxLambdaMass) {
return false;
}
}

if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0) < cfgv0trksel.rejK0sMassWindow) {
return false;
}

if (v0.v0radius() > cfgv0trksel.maxLambdaRadius || v0.v0radius() < cfgv0trksel.minLambdaRadius) {
return false;
}
Expand All @@ -1359,17 +1485,29 @@ struct LongrangeMaker {
if (v0.dcaV0daughters() > cfgv0trksel.maxDcaV0DauLambda) {
return false;
}
if (pid == KindOfV0::kLambda && (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPr || std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiLambda)) {
return false;
}
if (pid == KindOfV0::kAntiLambda && (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiLambda || std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPr)) {
return false;
}
if (pid == KindOfV0::kLambda && ((std::abs(posTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts))) {
return false;
if constexpr (pid == KindOfV0::kLambda) {
if (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPr ||
std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiLambda) {
return false;
}
} else if constexpr (pid == KindOfV0::kAntiLambda) {
if (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiLambda ||
std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPr) {
return false;
}
}
if (pid == KindOfV0::kAntiLambda && ((std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts))) {
return false;
if (applyPidCut) {
if constexpr (pid == KindOfV0::kLambda) {
if (std::abs(posTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts ||
std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) {
return false;
}
} else if constexpr (pid == KindOfV0::kAntiLambda) {
if (std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts ||
std::abs(negTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts) {
return false;
}
}
}
if (std::abs(ctauLambda) > cfgv0trksel.maxLambdaLifeTime) {
return false;
Expand All @@ -1387,7 +1525,7 @@ struct LongrangeMaker {
if (hTrkEff == nullptr) {
LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgtrksel.cfgEffccdbPath.value.c_str());
}
LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgtrksel.cfgEffccdbPath.value.c_str(), (void*)hTrkEff);
LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgtrksel.cfgEffccdbPath.value.c_str(), static_cast<void*>(hTrkEff));
}
fLoadTrkEffCorr = true;
}
Expand All @@ -1411,6 +1549,7 @@ struct LongrangeMaker {
PROCESS_SWITCH(LongrangeMaker, processUpc, "process UPC collisions", false);
PROCESS_SWITCH(LongrangeMaker, processMCGen, "process MC generated collisions", false);
PROCESS_SWITCH(LongrangeMaker, processMCRec, "process MC both gen and rec collisions", false);
PROCESS_SWITCH(LongrangeMaker, processV0QA, "process V0 QA histograms", false);
};

WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
Expand Down
Loading
Loading