Skip to content
Merged
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
122 changes: 73 additions & 49 deletions PWGCF/TableProducer/filter2Prong.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -55,52 +55,54 @@
O2_DEFINE_CONFIGURABLE(cfgImCutPt, float, 0.2f, "Minimal pT for candidates")
O2_DEFINE_CONFIGURABLE(cfgImMinInvMass, float, 0.95f, "Minimum invariant mass for generic 2 prong")
O2_DEFINE_CONFIGURABLE(cfgImMaxInvMass, float, 1.07f, "Maximum invariant mass for generic 2 prong")
O2_DEFINE_CONFIGURABLE(cfgImSigmaFormula, std::string, "(z < 0.5 && abs(x) < 3.0) || (z >= 0.5 && abs(x) < 2.5 && abs(y) < 3.0)", "pT dependent daughter track sigma pass condition (x = TPC sigma, y = TOF sigma, z = pT)")

struct : ConfigurableGroup{
O2_DEFINE_CONFIGURABLE(tpcNClsCrossedRowsTrackMin, float, 70, "Minimum number of crossed rows in TPC")
O2_DEFINE_CONFIGURABLE(etaTrackMax, float, 0.8, "Maximum pseudorapidity")
O2_DEFINE_CONFIGURABLE(ptTrackMin, float, 0.1, "Minimum transverse momentum")
O2_DEFINE_CONFIGURABLE(minV0DCAPr, float, 0.1, "Min V0 proton DCA")
O2_DEFINE_CONFIGURABLE(minV0DCAPiLambda, float, 0.1, "Min V0 pion DCA for lambda")
O2_DEFINE_CONFIGURABLE(minV0DCAPiK0s, float, 0.1, "Min V0 pion DCA for K0s")
O2_DEFINE_CONFIGURABLE(daughPIDCuts, float, 4.0, "PID nsigma for V0s")
O2_DEFINE_CONFIGURABLE(massK0Min, float, 0.4, "Minimum mass for K0")
O2_DEFINE_CONFIGURABLE(massK0Max, float, 0.6, "Maximum mass for K0")
O2_DEFINE_CONFIGURABLE(massLambdaMin, float, 1.0, "Minimum mass for lambda")
O2_DEFINE_CONFIGURABLE(massLambdaMax, float, 1.3, "Maximum mass for lambda")
O2_DEFINE_CONFIGURABLE(radiusMaxLambda, float, 2.3, "Maximum decay radius (cm) for lambda")
O2_DEFINE_CONFIGURABLE(radiusMinLambda, float, 0.0, "Minimum decay radius (cm) for lambda")
O2_DEFINE_CONFIGURABLE(radiusMaxK0s, float, 2.3, "Maximum decay radius (cm) for K0s")
O2_DEFINE_CONFIGURABLE(radiusMinK0s, float, 0.0, "Minimum decay radius (cm) for K0s")
O2_DEFINE_CONFIGURABLE(cosPaMinLambda, float, 0.98, "Minimum cosine of pointing angle for lambda")
O2_DEFINE_CONFIGURABLE(cosPaMinK0s, float, 0.98, "Minimum cosine of pointing angle for K0s")
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxLambda, float, 0.2, "Maximum DCA among the V0 daughters (cm) for lambda")
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxK0s, float, 0.2, "Maximum DCA among the V0 daughters (cm) for K0s")
O2_DEFINE_CONFIGURABLE(qtArmenterosMinForK0s, float, 0.12, "Minimum Armenteros' qt for K0s")
O2_DEFINE_CONFIGURABLE(maxLambdaLifeTime, float, 30, "Maximum lambda lifetime (in cm)")
O2_DEFINE_CONFIGURABLE(maxK0sLifeTime, float, 30, "Maximum K0s lifetime (in cm)")} grpV0;

struct : ConfigurableGroup{
O2_DEFINE_CONFIGURABLE(ImMinInvMassPhiMeson, float, 0.98f, "Minimum invariant mass Phi meson (GeV)")
O2_DEFINE_CONFIGURABLE(ImMaxInvMassPhiMeson, float, 1.07f, "Maximum invariant mass Phi meson (GeV)")
O2_DEFINE_CONFIGURABLE(ITSPIDSelection, bool, true, "PID ITS")
O2_DEFINE_CONFIGURABLE(ITSPIDPthreshold, float, 1.0, "Momentum threshold for ITS PID (GeV/c) (only used if ITSPIDSelection is true)")
O2_DEFINE_CONFIGURABLE(lowITSPIDNsigma, float, 3.0, "lower cut on PID nsigma for ITS")
O2_DEFINE_CONFIGURABLE(highITSPIDNsigma, float, 3.0, "higher cut on PID nsigma for ITS")
O2_DEFINE_CONFIGURABLE(ITSclusterPhiMeson, int, 5, "Minimum number of ITS cluster for phi meson track")
O2_DEFINE_CONFIGURABLE(TPCCrossedRowsPhiMeson, int, 80, "Minimum number of TPC Crossed Rows for phi meson track")
O2_DEFINE_CONFIGURABLE(cutDCAxyPhiMeson, float, 0.1, "Maximum DCAxy for phi meson track")
O2_DEFINE_CONFIGURABLE(cutDCAzPhiMeson, float, 0.1, "Maximum DCAz for phi meson track")
O2_DEFINE_CONFIGURABLE(cutEtaPhiMeson, float, 0.8, "Maximum eta for phi meson track")
O2_DEFINE_CONFIGURABLE(cutPTPhiMeson, float, 0.15, "Maximum pt for phi meson track")
O2_DEFINE_CONFIGURABLE(isDeepAngle, bool, true, "Flag for applying deep angle")
O2_DEFINE_CONFIGURABLE(deepAngle, float, 0.04, "Deep angle cut")
O2_DEFINE_CONFIGURABLE(nsigmaCutTPC, float, 2.5, "nsigma tpc")
O2_DEFINE_CONFIGURABLE(nsigmaCutTOF, float, 2.5, "nsigma tof")
O2_DEFINE_CONFIGURABLE(cutTOFBeta, float, 0.5, "TOF beta")
O2_DEFINE_CONFIGURABLE(confFakeKaonCut, float, 0.15, "Cut based on track from momentum difference")
O2_DEFINE_CONFIGURABLE(removefaketrack, bool, true, "Flag to remove fake kaon")} grpPhi;
O2_DEFINE_CONFIGURABLE(cfgImSigmaFormula, std::string, "(([p] < 0.5 || [hasTOF] <= 0.0) && abs([sTPC]) < 3.0) || ([p] >= 0.5 && abs([sTPC]) < 2.5 && abs([sTOF]) < 3.0)", "pT dependent daughter track sigma pass condition. Parameters: [p] momentum, [sTPC] sigma TPC, [sTOF] sigma TOF, [hasTOF] has TOF.")

struct : ConfigurableGroup {
O2_DEFINE_CONFIGURABLE(tpcNClsCrossedRowsTrackMin, float, 70, "Minimum number of crossed rows in TPC");
O2_DEFINE_CONFIGURABLE(etaTrackMax, float, 0.8, "Maximum pseudorapidity");
O2_DEFINE_CONFIGURABLE(ptTrackMin, float, 0.1, "Minimum transverse momentum");
O2_DEFINE_CONFIGURABLE(minV0DCAPr, float, 0.1, "Min V0 proton DCA");
O2_DEFINE_CONFIGURABLE(minV0DCAPiLambda, float, 0.1, "Min V0 pion DCA for lambda");
O2_DEFINE_CONFIGURABLE(minV0DCAPiK0s, float, 0.1, "Min V0 pion DCA for K0s");
O2_DEFINE_CONFIGURABLE(daughPIDCuts, float, 4.0, "PID nsigma for V0s");
O2_DEFINE_CONFIGURABLE(massK0Min, float, 0.4, "Minimum mass for K0");
O2_DEFINE_CONFIGURABLE(massK0Max, float, 0.6, "Maximum mass for K0");
O2_DEFINE_CONFIGURABLE(massLambdaMin, float, 1.0, "Minimum mass for lambda");
O2_DEFINE_CONFIGURABLE(massLambdaMax, float, 1.3, "Maximum mass for lambda");
O2_DEFINE_CONFIGURABLE(radiusMaxLambda, float, 2.3, "Maximum decay radius (cm) for lambda");
O2_DEFINE_CONFIGURABLE(radiusMinLambda, float, 0.0, "Minimum decay radius (cm) for lambda");
O2_DEFINE_CONFIGURABLE(radiusMaxK0s, float, 2.3, "Maximum decay radius (cm) for K0s");
O2_DEFINE_CONFIGURABLE(radiusMinK0s, float, 0.0, "Minimum decay radius (cm) for K0s");
O2_DEFINE_CONFIGURABLE(cosPaMinLambda, float, 0.98, "Minimum cosine of pointing angle for lambda");
O2_DEFINE_CONFIGURABLE(cosPaMinK0s, float, 0.98, "Minimum cosine of pointing angle for K0s");
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxLambda, float, 0.2, "Maximum DCA among the V0 daughters (cm) for lambda");
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxK0s, float, 0.2, "Maximum DCA among the V0 daughters (cm) for K0s");
O2_DEFINE_CONFIGURABLE(qtArmenterosMinForK0s, float, 0.12, "Minimum Armenteros' qt for K0s");
O2_DEFINE_CONFIGURABLE(maxLambdaLifeTime, float, 30, "Maximum lambda lifetime (in cm)");
O2_DEFINE_CONFIGURABLE(maxK0sLifeTime, float, 30, "Maximum K0s lifetime (in cm)");
} grpV0;

struct : ConfigurableGroup {
O2_DEFINE_CONFIGURABLE(ImMinInvMassPhiMeson, float, 0.98f, "Minimum invariant mass Phi meson (GeV)");
O2_DEFINE_CONFIGURABLE(ImMaxInvMassPhiMeson, float, 1.07f, "Maximum invariant mass Phi meson (GeV)");
O2_DEFINE_CONFIGURABLE(ITSPIDSelection, bool, true, "PID ITS");
O2_DEFINE_CONFIGURABLE(ITSPIDPthreshold, float, 1.0, "Momentum threshold for ITS PID (GeV/c) (only used if ITSPIDSelection is true)");
O2_DEFINE_CONFIGURABLE(lowITSPIDNsigma, float, 3.0, "lower cut on PID nsigma for ITS");
O2_DEFINE_CONFIGURABLE(highITSPIDNsigma, float, 3.0, "higher cut on PID nsigma for ITS");
O2_DEFINE_CONFIGURABLE(ITSclusterPhiMeson, int, 5, "Minimum number of ITS cluster for phi meson track");
O2_DEFINE_CONFIGURABLE(TPCCrossedRowsPhiMeson, int, 80, "Minimum number of TPC Crossed Rows for phi meson track");
O2_DEFINE_CONFIGURABLE(cutDCAxyPhiMeson, float, 0.1, "Maximum DCAxy for phi meson track");
O2_DEFINE_CONFIGURABLE(cutDCAzPhiMeson, float, 0.1, "Maximum DCAz for phi meson track");
O2_DEFINE_CONFIGURABLE(cutEtaPhiMeson, float, 0.8, "Maximum eta for phi meson track");
O2_DEFINE_CONFIGURABLE(cutPTPhiMeson, float, 0.15, "Maximum pt for phi meson track");
O2_DEFINE_CONFIGURABLE(isDeepAngle, bool, true, "Flag for applying deep angle");
O2_DEFINE_CONFIGURABLE(deepAngle, float, 0.04, "Deep angle cut");
O2_DEFINE_CONFIGURABLE(nsigmaCutTPC, float, 2.5, "nsigma tpc");
O2_DEFINE_CONFIGURABLE(nsigmaCutTOF, float, 2.5, "nsigma tof");
O2_DEFINE_CONFIGURABLE(cutTOFBeta, float, 0.5, "TOF beta");
O2_DEFINE_CONFIGURABLE(confFakeKaonCut, float, 0.15, "Cut based on track from momentum difference");
O2_DEFINE_CONFIGURABLE(removefaketrack, bool, true, "Flag to remove fake kaon");
} grpPhi;

HfHelper hfHelper;
Produces<aod::CF2ProngTracks> output2ProngTracks;
Expand All @@ -121,11 +123,25 @@
using ResoV0s = aod::V0Datas;

std::unique_ptr<TFormula> sigmaFormula;
std::array<uint, 4> sigmaFormulaParamIndex;

void init(InitContext&)
{
if (doprocessDataInvMass)
if (doprocessDataInvMass) {
if (static_cast<std::size_t>(sigmaFormula->GetNpar()) > std::size(sigmaFormulaParamIndex))
LOGF(fatal, "Number of parameters in cfgImSigmaFormula can not be larger than %d.", std::size(sigmaFormulaParamIndex));
sigmaFormula = std::make_unique<TFormula>("sigmaFormula", cfgImSigmaFormula.value.c_str());
// could do SetParameter(name,value) directly, but pre-lookup of the names will result in faster process
std::array<std::string, 4> pars = {"p", "sTPC", "sTOF", "hasTOF"};
std::fill_n(sigmaFormulaParamIndex.begin(), std::size(sigmaFormulaParamIndex), ~0u);
for (uint i = 0, n = sigmaFormula->GetNpar(); i < n; ++i) {
auto m = std::find(pars.begin(), pars.end(), sigmaFormula->GetParName(i));
if (m != pars.end())
sigmaFormulaParamIndex[std::distance(pars.begin(), m)] = i;
else
LOGF(warning, "Unrecognized cfgImSigmaFormula parameter %s.", sigmaFormula->GetParName(i));
}
}
}

template <class HFCandidatesType>
Expand Down Expand Up @@ -241,7 +257,7 @@
pz2 = candidate2.pz();
p1 = candidate1.p();
p2 = candidate2.p();
angle = TMath::ACos((pt1 * pt2 + pz1 * pz2) / (p1 * p2));

Check failure on line 260 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[root/entity]

Replace ROOT entities with equivalents from standard C++ or from O2.
if (grpPhi.isDeepAngle && angle < grpPhi.deepAngle) {
return false;
}
Expand All @@ -253,7 +269,7 @@
{
const auto pglobal = track.p();
const auto ptpc = track.tpcInnerParam();
if (TMath::Abs(pglobal - ptpc) > grpPhi.confFakeKaonCut) {

Check failure on line 272 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[root/entity]

Replace ROOT entities with equivalents from standard C++ or from O2.
return true;
}
return false;
Expand Down Expand Up @@ -288,7 +304,7 @@
if (((std::abs(posTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts))) {
return false;
}
if ((TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPiK0s || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPiK0s)) {

Check failure on line 307 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[root/entity]

Replace ROOT entities with equivalents from standard C++ or from O2.
return false;
}
return true;
Expand All @@ -315,10 +331,10 @@
if (v0.dcaV0daughters() > grpV0.dcaV0DaughtersMaxLambda) {
return false;
}
if (pid == LambdaPid::kLambda && (TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPr || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPiLambda)) {

Check failure on line 334 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[root/entity]

Replace ROOT entities with equivalents from standard C++ or from O2.
return false;
}
if (pid == LambdaPid::kAntiLambda && (TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPiLambda || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPr)) {

Check failure on line 337 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[root/entity]

Replace ROOT entities with equivalents from standard C++ or from O2.
return false;
}
if (pid == LambdaPid::kLambda && ((std::abs(posTrack.tpcNSigmaPr()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts))) {
Expand Down Expand Up @@ -362,18 +378,18 @@
{
if (cfgMomDepPID) {
if (candidate.p() < 0.5) {
if (!candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < grpPhi.nsigmaCutTPC) {

Check failure on line 381 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[root/entity]

Replace ROOT entities with equivalents from standard C++ or from O2.
return true;
} else if (candidate.hasTOF() && TMath::Sqrt(candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa() + candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) < grpPhi.nsigmaCutTOF && candidate.beta() > grpPhi.cutTOFBeta) {

Check failure on line 383 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[root/entity]

Replace ROOT entities with equivalents from standard C++ or from O2.
return true;
}
} else if (candidate.hasTOF() && TMath::Sqrt(candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa() + candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) < grpPhi.nsigmaCutTOF && candidate.beta() > grpPhi.cutTOFBeta) {

Check failure on line 386 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[root/entity]

Replace ROOT entities with equivalents from standard C++ or from O2.
return true;
}
} else {
if (!candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < grpPhi.nsigmaCutTPC) {

Check failure on line 390 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[root/entity]

Replace ROOT entities with equivalents from standard C++ or from O2.
return true;
} else if (candidate.hasTOF() && TMath::Sqrt(candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa() + candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) < grpPhi.nsigmaCutTOF && candidate.beta() > grpPhi.cutTOFBeta) {

Check failure on line 392 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[root/entity]

Replace ROOT entities with equivalents from standard C++ or from O2.
return true;
}
}
Expand All @@ -389,15 +405,23 @@
const auto& p1 = tracks.iteratorAt(cftrack1.trackId() - tracks.begin().globalIndex());
if (p1.sign() != 1)
continue;
if (sigmaFormula->Eval(o2::aod::pidutils::tpcNSigma(cfgImPart1PID, p1), o2::aod::pidutils::tofNSigma(cfgImPart1PID, p1)) <= 0.0f)
sigmaFormula->SetParameter(sigmaFormulaParamIndex[0], p1.p());
sigmaFormula->SetParameter(sigmaFormulaParamIndex[1], o2::aod::pidutils::tpcNSigma(cfgImPart1PID, p1));
sigmaFormula->SetParameter(sigmaFormulaParamIndex[2], o2::aod::pidutils::tofNSigma(cfgImPart1PID, p1));
sigmaFormula->SetParameter(sigmaFormulaParamIndex[3], static_cast<double>(p1.hasTOF()));
if (sigmaFormula->Eval() <= 0.0f)
continue;
for (const auto& cftrack2 : cftracks) {
if (cftrack2.globalIndex() == cftrack1.globalIndex())
continue;
const auto& p2 = tracks.iteratorAt(cftrack2.trackId() - tracks.begin().globalIndex());
if (p2.sign() != -1)
continue;
if (sigmaFormula->Eval(o2::aod::pidutils::tpcNSigma(cfgImPart2PID, p2), o2::aod::pidutils::tofNSigma(cfgImPart2PID, p2)) <= 0.0f)
sigmaFormula->SetParameter(sigmaFormulaParamIndex[0], p2.p());
sigmaFormula->SetParameter(sigmaFormulaParamIndex[1], o2::aod::pidutils::tpcNSigma(cfgImPart1PID, p2));
sigmaFormula->SetParameter(sigmaFormulaParamIndex[2], o2::aod::pidutils::tofNSigma(cfgImPart1PID, p2));
sigmaFormula->SetParameter(sigmaFormulaParamIndex[3], static_cast<double>(p2.hasTOF()));
if (sigmaFormula->Eval() <= 0.0f)
continue;
ROOT::Math::PtEtaPhiMVector vec1(p1.pt(), p1.eta(), p1.phi(), cfgImPart1Mass);
ROOT::Math::PtEtaPhiMVector vec2(p2.pt(), p2.eta(), p2.phi(), cfgImPart2Mass);
Expand Down
Loading