Skip to content

Commit a2c0793

Browse files
committed
Refactor and complete the charm femtoscopy framework
1 parent 77dbc37 commit a2c0793

File tree

9 files changed

+1681
-846
lines changed

9 files changed

+1681
-846
lines changed

PWGCF/DataModel/FemtoDerived.h

Lines changed: 154 additions & 9 deletions
Large diffs are not rendered by default.

PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h

Lines changed: 141 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,6 @@ namespace femtoDream
3737
/// \tparam partOne Type of particle 1 (Track/V0/Cascade/...)
3838
/// \tparam partTwo Type of particle 2 (Track/V0/Cascade/...)
3939

40-
enum ProngCharmHadron {
41-
Prong0 = 0,
42-
Prong1 = 1,
43-
Prong2 = 2,
44-
Nprongs = 3
45-
};
46-
4740
template <o2::aod::femtodreamparticle::ParticleType partOne, o2::aod::femtodreamparticle::ParticleType partTwo>
4841
class FemtoDreamDetaDphiStar
4942
{
@@ -118,8 +111,14 @@ class FemtoDreamDetaDphiStar
118111
}
119112
}
120113
}
121-
if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron) {
122-
for (int i = 0; i < Nprongs; i++) {
114+
if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && (mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron3Prong || mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron2Prong)) {
115+
int nProng = 0;
116+
if (mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron3Prong)
117+
nProng = 3;
118+
if (mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron2Prong)
119+
nProng = 2;
120+
121+
for (int i = 0; i < nProng; i++) {
123122
std::string dirName = static_cast<std::string>(dirNames[2]);
124123
histdetadpi[i][0] = mHistogramRegistry->add<TH2>((dirName + static_cast<std::string>(histNames[0][i]) + static_cast<std::string>(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}});
125124
histdetadpi[i][1] = mHistogramRegistry->add<TH2>((dirName + static_cast<std::string>(histNames[1][i]) + static_cast<std::string>(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}});
@@ -495,50 +494,102 @@ class FemtoDreamDetaDphiStar
495494
}
496495

497496
return pass;
498-
} else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron) {
497+
} else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && (mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron3Prong || mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadronDstar)) { // to be fixed for Dstar
499498
// check if provided particles are in agreement with the class instantiation
500-
if (part2.candidateSelFlag() < o2::aod::fdhf::lcToPKPi) {
499+
if (!part2.candidateSelFlag()) {
501500
LOG(fatal) << "FemtoDreamDetaDphiStar: passed arguments don't agree with FemtoDreamDetaDphiStar instantiation! Please provide Charm Hadron candidates.";
502501
return false;
503502
}
504503

505504
bool pass = false;
506505

507-
for (int i = 0; i < Nprongs; ++i) {
506+
for (int i = 0; i < 3; ++i) {
508507
double deta, dphiAvg, dphi_AT_PV, dphi_AT_SpecificRadii, daughterEta, daughterPhi;
509508
bool sameCharge = false;
510-
daughterEta = -999.;
511-
daughterPhi = -999.;
512-
513-
switch (i) {
514-
case Prong0:
515-
daughterEta = part2.prong0Eta();
516-
daughterPhi = part2.prong0Phi();
517-
deta = part1.eta() - daughterEta;
518-
dphi_AT_PV = part1.phi() - daughterPhi;
519-
dphi_AT_SpecificRadii = PhiAtSpecificRadiiTPC(part1, radiiTPC) - PhiAtSpecificRadiiTPC<true, 0>(part2, radiiTPC);
520-
dphiAvg = AveragePhiStar<true>(part1, part2, 0, &sameCharge);
521-
// histdetadpi[0][0]->Fill(deta, dphiAvg);
522-
break;
523-
case Prong1:
524-
daughterEta = part2.prong1Eta();
525-
daughterPhi = part2.prong1Phi();
526-
deta = part1.eta() - daughterEta;
527-
dphi_AT_PV = part1.phi() - daughterPhi;
528-
dphi_AT_SpecificRadii = PhiAtSpecificRadiiTPC(part1, radiiTPC) - PhiAtSpecificRadiiTPC<true, 1>(part2, radiiTPC);
529-
dphiAvg = AveragePhiStar<true>(part1, part2, 1, &sameCharge);
530-
// histdetadpi[1][0]->Fill(deta, dphiAvg);
531-
break;
532-
case Prong2:
533-
daughterEta = part2.prong2Eta();
534-
daughterPhi = part2.prong2Phi();
535-
deta = part1.eta() - daughterEta;
536-
dphi_AT_PV = part1.phi() - daughterPhi;
537-
dphi_AT_SpecificRadii = PhiAtSpecificRadiiTPC(part1, radiiTPC) - PhiAtSpecificRadiiTPC<true, 2>(part2, radiiTPC);
538-
dphiAvg = AveragePhiStar<true>(part1, part2, 2, &sameCharge);
539-
// histdetadpi[2][0]->Fill(deta, dphiAvg);
540-
break;
509+
daughterEta = part2.prong2Eta();
510+
daughterPhi = part2.prong2Phi();
511+
deta = part1.eta() - daughterEta;
512+
dphi_AT_PV = part1.phi() - daughterPhi;
513+
dphi_AT_SpecificRadii = PhiAtSpecificRadiiTPC(part1, radiiTPC) - PhiAtSpecificRadiiTPC<true, 2>(part2, radiiTPC);
514+
dphiAvg = AveragePhiStar<true>(part1, part2, 2, &sameCharge);
515+
516+
if (Q3 == 999) {
517+
histdetadpi[i][0]->Fill(deta, dphiAvg);
518+
histdetadpi[i][2]->Fill(deta, dphi_AT_PV);
519+
if (fillQA) {
520+
histdetadpi_eta[i]->Fill(deta, dphiAvg, part1.eta(), daughterEta);
521+
histdetadpi_phi[i]->Fill(deta, dphiAvg, part1.phi(), daughterPhi);
522+
}
523+
} else if (Q3 < upperQ3LimitForPlotting) {
524+
histdetadpi[i][0]->Fill(deta, dphiAvg);
525+
histdetadpi[i][2]->Fill(deta, dphi_AT_PV);
526+
if (fillQA) {
527+
histdetadpi_eta[i]->Fill(deta, dphiAvg, part1.eta(), daughterEta);
528+
histdetadpi_phi[i]->Fill(deta, dphiAvg, part1.phi(), daughterPhi);
529+
}
541530
}
531+
532+
if (atWhichRadiiToSelect == 1) {
533+
if (std::pow(dphiAvg, 2) / std::pow(deltaPhiMax, 2) + std::pow(deta, 2) / std::pow(deltaEtaMax, 2) < 1.) {
534+
pass = true;
535+
} else {
536+
if (Q3 == 999) {
537+
histdetadpi[i][1]->Fill(deta, dphiAvg);
538+
histdetadpi[i][3]->Fill(deta, dphi_AT_PV);
539+
} else if (Q3 < upperQ3LimitForPlotting) {
540+
histdetadpi[i][1]->Fill(deta, dphiAvg);
541+
histdetadpi[i][3]->Fill(deta, dphi_AT_PV);
542+
}
543+
}
544+
} else if (atWhichRadiiToSelect == 0) {
545+
if (std::pow(dphi_AT_PV, 2) / std::pow(deltaPhiMax, 2) + std::pow(deta, 2) / std::pow(deltaEtaMax, 2) < 1.) {
546+
pass = true;
547+
} else {
548+
if (Q3 == 999) {
549+
histdetadpi[i][1]->Fill(deta, dphiAvg);
550+
histdetadpi[i][3]->Fill(deta, dphi_AT_PV);
551+
} else if (Q3 < upperQ3LimitForPlotting) {
552+
histdetadpi[i][1]->Fill(deta, dphiAvg);
553+
histdetadpi[i][3]->Fill(deta, dphi_AT_PV);
554+
}
555+
}
556+
} else if (atWhichRadiiToSelect == 2) {
557+
if (std::pow(dphi_AT_SpecificRadii, 2) / std::pow(deltaPhiMax, 2) + std::pow(deta, 2) / std::pow(deltaEtaMax, 2) < 1.) {
558+
pass = true;
559+
} else {
560+
if (Q3 == 999) {
561+
histdetadpi[i][1]->Fill(deta, dphiAvg);
562+
histdetadpi[i][3]->Fill(deta, dphi_AT_PV);
563+
} else if (Q3 < upperQ3LimitForPlotting) {
564+
histdetadpi[i][1]->Fill(deta, dphiAvg);
565+
histdetadpi[i][3]->Fill(deta, dphi_AT_PV);
566+
}
567+
}
568+
}
569+
}
570+
571+
return pass;
572+
573+
} else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron2Prong) {
574+
// check if provided particles are in agreement with the class instantiation
575+
if (!part2.candidateSelFlag()) {
576+
LOG(fatal) << "FemtoDreamDetaDphiStar: passed arguments don't agree with FemtoDreamDetaDphiStar instantiation! Please provide Charm Hadron candidates.";
577+
return false;
578+
}
579+
580+
bool pass = false;
581+
582+
for (int i = 0; i < 2; ++i) {
583+
double deta, dphiAvg, dphi_AT_PV, dphi_AT_SpecificRadii, daughterEta, daughterPhi;
584+
bool sameCharge = false;
585+
daughterEta = part2.prong1Eta();
586+
daughterPhi = part2.prong1Phi();
587+
deta = part1.eta() - daughterEta;
588+
dphi_AT_PV = part1.phi() - daughterPhi;
589+
dphi_AT_SpecificRadii = PhiAtSpecificRadiiTPC(part1, radiiTPC) - PhiAtSpecificRadiiTPC<true, 1>(part2, radiiTPC);
590+
dphiAvg = AveragePhiStar<true>(part1, part2, 1, &sameCharge);
591+
// histdetadpi[1][0]->Fill(deta, dphiAvg);
592+
542593
if (Q3 == 999) {
543594
histdetadpi[i][0]->Fill(deta, dphiAvg);
544595
histdetadpi[i][2]->Fill(deta, dphi_AT_PV);
@@ -775,27 +826,25 @@ class FemtoDreamDetaDphiStar
775826
float PhiAtSpecificRadiiTPC(const T& part, float radii)
776827
{
777828
int charge = 0;
778-
float phi0, pt;
829+
float phi0 = 0.f;
830+
float pt = 0.f;
831+
779832
if constexpr (isHF) {
780-
switch (prong) {
781-
case Prong0:
782-
charge = part.charge(); // charge calculation according to 3-prong decay, Lc^+ --> P^+ + K^- + pi^+
783-
phi0 = part.prong0Phi();
784-
pt = part.prong0Pt();
785-
break;
786-
case Prong1:
787-
charge = -part.charge();
788-
phi0 = part.prong1Phi();
789-
pt = part.prong1Pt();
790-
break;
791-
case Prong2:
792-
charge = part.charge();
793-
phi0 = part.prong2Phi();
794-
pt = part.prong2Pt();
795-
break;
796-
default:
797-
// Handle invalid prong value if necessary
798-
break;
833+
static_assert(prong == 0 || prong == 1 || prong == 2,
834+
"PhiAtSpecificRadiiTPC: invalid prong index for HF");
835+
836+
if constexpr (prong == 0) {
837+
charge = part.charge();
838+
phi0 = part.prong0Phi();
839+
pt = part.prong0Pt();
840+
} else if constexpr (prong == 1) {
841+
charge = -part.charge();
842+
phi0 = part.prong1Phi();
843+
pt = part.prong1Pt();
844+
} else if constexpr (prong == 2) {
845+
charge = part.charge();
846+
phi0 = part.prong2Phi();
847+
pt = part.prong2Pt();
799848
}
800849
} else {
801850
phi0 = part.phi();
@@ -833,42 +882,42 @@ class FemtoDreamDetaDphiStar
833882
int PhiAtRadiiTPCForHF(const T& part, std::vector<float>& tmpVec, int prong)
834883
{
835884
int charge = 0;
836-
float pt = -999.;
837-
float phi0 = -999.;
838-
switch (prong) {
839-
case Prong0:
840-
pt = part.prong0Pt();
841-
phi0 = part.prong0Phi();
885+
if constexpr (mPartTwoType == o2::aod::femtodreamparticle::kCharmHadron3Prong) {
886+
if (prong == 0 || prong == 2) {
842887
charge = part.charge();
843-
break;
844-
case Prong1:
845-
pt = part.prong1Pt();
846-
phi0 = part.prong1Phi();
888+
} else if (prong == 1) {
847889
charge = -part.charge();
848-
break;
849-
case Prong2:
850-
pt = part.prong2Pt();
851-
phi0 = part.prong2Phi();
890+
} else {
891+
return 0;
892+
}
893+
for (size_t i = 0; i < 9; ++i) {
894+
if (prong == 0) {
895+
tmpVec.push_back(PhiAtSpecificRadiiTPC<true, 0>(part, tmpRadiiTPC[i]));
896+
} else if (prong == 1) {
897+
tmpVec.push_back(PhiAtSpecificRadiiTPC<true, 1>(part, tmpRadiiTPC[i]));
898+
} else { // prong == 2
899+
tmpVec.push_back(PhiAtSpecificRadiiTPC<true, 2>(part, tmpRadiiTPC[i]));
900+
}
901+
}
902+
903+
} else {
904+
if (prong == 0) {
852905
charge = part.charge();
853-
break;
854-
default:
855-
// Handle invalid prong value
856-
break;
857-
}
858-
for (size_t i = 0; i < 9; i++) {
859-
if (runOldVersion) {
860-
tmpVec.push_back(phi0 - std::asin(0.3 * charge * 0.1 * magfield * tmpRadiiTPC[i] * 0.01 / (2. * pt)));
906+
} else if (prong == 1) {
907+
charge = -part.charge();
908+
} else {
909+
return 0;
861910
}
862-
if (!runOldVersion) {
863-
auto arg = 0.3 * charge * magfield * tmpRadiiTPC[i] * 0.01 / (2. * pt);
864-
// for very low pT particles, this value goes outside of range -1 to 1 at at large tpc radius; asin fails
865-
if (std::fabs(arg) < 1) {
866-
tmpVec.push_back(phi0 - std::asin(0.3 * charge * magfield * tmpRadiiTPC[i] * 0.01 / (2. * pt)));
867-
} else {
868-
tmpVec.push_back(999);
911+
912+
for (size_t i = 0; i < 9; ++i) {
913+
if (prong == 0) {
914+
tmpVec.push_back(PhiAtSpecificRadiiTPC<true, 0>(part, tmpRadiiTPC[i]));
915+
} else { // prong == 1
916+
tmpVec.push_back(PhiAtSpecificRadiiTPC<true, 1>(part, tmpRadiiTPC[i]));
869917
}
870918
}
871919
}
920+
872921
return charge;
873922
}
874923

PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define PWGCF_FEMTODREAM_CORE_FEMTODREAMPAIRCLEANER_H_
1818

1919
#include "PWGCF/DataModel/FemtoDerived.h"
20+
2021
#include "Framework/HistogramRegistry.h"
2122

2223
using namespace o2::framework;
@@ -74,9 +75,9 @@ class FemtoDreamPairCleaner
7475
return true;
7576
}
7677
return false;
77-
} else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron) {
78+
} else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && (mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron3Prong || mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadronDstar)) {
7879
/// Track-CharmHadron combination
79-
if (part2.candidateSelFlag() < o2::aod::fdhf::lcToPKPi) {
80+
if (!part2.candidateSelFlag()) {
8081
LOG(fatal) << "FemtoDreamPairCleaner: passed arguments don't agree with FemtoDreamPairCleaner instantiation! Please provide second argument Charm candidate.";
8182
return false;
8283
}
@@ -85,6 +86,17 @@ class FemtoDreamPairCleaner
8586
return true;
8687
}
8788
return false;
89+
} else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron2Prong) {
90+
/// Track-CharmHadron combination
91+
if (!part2.candidateSelFlag()) {
92+
LOG(fatal) << "FemtoDreamPairCleaner: passed arguments don't agree with FemtoDreamPairCleaner instantiation! Please provide second argument Charm candidate.";
93+
return false;
94+
}
95+
96+
if (part1.trackId() != part2.prong0Id() && part1.trackId() != part2.prong1Id()) {
97+
return true;
98+
}
99+
return false;
88100
} else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCascade) {
89101
/// Track-Cascade combination
90102
if (part2.partType() != o2::aod::femtodreamparticle::ParticleType::kCascade) {

0 commit comments

Comments
 (0)