Skip to content

Commit 114ea83

Browse files
Merge branch 'AliceO2Group:master' into kaonIsospinFluctuation2_EffCorrAdded
2 parents 01f01cc + 38cf847 commit 114ea83

38 files changed

Lines changed: 2728 additions & 1456 deletions

ALICE3/Tasks/alice3TrackingPerformance.cxx

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,20 @@ struct Alice3TrackingPerformance {
7878
}
7979
const std::string tag = "_" + prefix;
8080
prefix += "/";
81-
particlePtDistribution[pdg] = histos.add<TH1>(prefix + "particlePtDistribution" + tag, "", kTH1D, {ptAxis});
82-
particleEtaDistribution[pdg] = histos.add<TH1>(prefix + "particleEtaDistribution" + tag, "", kTH1D, {etaAxis});
81+
auto histoName = [&](const std::string& name) { return Form("%s%s%s", prefix.c_str(), name.c_str(), tag.c_str()); };
82+
particlePtDistribution[pdg] = histos.add<TH1>(histoName("particlePtDistribution"), "", kTH1D, {ptAxis});
83+
particleEtaDistribution[pdg] = histos.add<TH1>(histoName("particleEtaDistribution"), "", kTH1D, {etaAxis});
8384

84-
ptDistribution[pdg] = histos.add<TH1>(prefix + "ptDistribution" + tag, "", kTH1D, {ptAxis});
85-
ptResolutionVsPt[pdg] = histos.add<TH2>(prefix + "ptResolutionVsPt" + tag, "", kTH2D, {ptAxis, axisPtDelta});
86-
ptResolutionVsEta[pdg] = histos.add<TProfile2D>(prefix + "ptResolutionVsEta" + tag, "", kTProfile2D, {ptAxis, etaAxis});
87-
invPtResolutionVsPt[pdg] = histos.add<TH2>(prefix + "invPtResolutionVsPt" + tag, "", kTH2D, {ptAxis, invPtDeltaAxis});
88-
invPtResolutionVsEta[pdg] = histos.add<TProfile2D>(prefix + "invPtResolutionVsEta" + tag, "", kTProfile2D, {ptAxis, etaAxis});
89-
dcaXyResolutionVsPt[pdg] = histos.add<TH2>(prefix + "dcaXyResolutionVsPt" + tag, "", kTH2D, {ptAxis, axisDcaXy});
90-
dcaZResolutionVsPt[pdg] = histos.add<TH2>(prefix + "dcaZResolutionVsPt" + tag, "", kTH2D, {ptAxis, axisDcaZ});
91-
covariancePtPtVsPt[pdg] = histos.add<TH2>(prefix + "covariancePtPtVsPt" + tag, "", kTH2D, {ptAxis, axisCovariancePtPt});
92-
covarianceDcaXyDcaXyVsPt[pdg] = histos.add<TH2>(prefix + "covarianceDcaXyDcaXyVsPt" + tag, "", kTH2D, {ptAxis, axisCovarianceDcaXyDcaXy});
93-
covarianceDcaZDcaZVsPt[pdg] = histos.add<TH2>(prefix + "covarianceDcaZDcaZVsPt" + tag, "", kTH2D, {ptAxis, axisCovarianceDcaZDcaZ});
85+
ptDistribution[pdg] = histos.add<TH1>(histoName("ptDistribution"), "", kTH1D, {ptAxis});
86+
ptResolutionVsPt[pdg] = histos.add<TH2>(histoName("ptResolutionVsPt"), "", kTH2D, {ptAxis, axisPtDelta});
87+
ptResolutionVsEta[pdg] = histos.add<TProfile2D>(histoName("ptResolutionVsEta"), "", kTProfile2D, {ptAxis, etaAxis});
88+
invPtResolutionVsPt[pdg] = histos.add<TH2>(histoName("invPtResolutionVsPt"), "", kTH2D, {ptAxis, invPtDeltaAxis});
89+
invPtResolutionVsEta[pdg] = histos.add<TProfile2D>(histoName("invPtResolutionVsEta"), "", kTProfile2D, {ptAxis, etaAxis});
90+
dcaXyResolutionVsPt[pdg] = histos.add<TH2>(histoName("dcaXyResolutionVsPt"), "", kTH2D, {ptAxis, axisDcaXy});
91+
dcaZResolutionVsPt[pdg] = histos.add<TH2>(histoName("dcaZResolutionVsPt"), "", kTH2D, {ptAxis, axisDcaZ});
92+
covariancePtPtVsPt[pdg] = histos.add<TH2>(histoName("covariancePtPtVsPt"), "", kTH2D, {ptAxis, axisCovariancePtPt});
93+
covarianceDcaXyDcaXyVsPt[pdg] = histos.add<TH2>(histoName("covarianceDcaXyDcaXyVsPt"), "", kTH2D, {ptAxis, axisCovarianceDcaXyDcaXy});
94+
covarianceDcaZDcaZVsPt[pdg] = histos.add<TH2>(histoName("covarianceDcaZDcaZVsPt"), "", kTH2D, {ptAxis, axisCovarianceDcaZDcaZ});
9495
}
9596
}
9697

@@ -102,10 +103,7 @@ struct Alice3TrackingPerformance {
102103
return false;
103104
}
104105
const int etaBin = particleEtaDistribution[0]->GetXaxis()->FindBin(p.eta());
105-
if (etaBin < 1 || etaBin > particleEtaDistribution[0]->GetXaxis()->GetNbins()) {
106-
return false;
107-
}
108-
return true;
106+
return etaBin >= 1 && etaBin <= particleEtaDistribution[0]->GetXaxis()->GetNbins();
109107
};
110108

111109
for (const auto& mcParticle : mcParticles) {
@@ -115,7 +113,7 @@ struct Alice3TrackingPerformance {
115113
}
116114
particlePtDistribution[0]->Fill(mcParticle.pt());
117115
particleEtaDistribution[0]->Fill(mcParticle.eta());
118-
if (particlePtDistribution.find(mcParticle.pdgCode()) == particlePtDistribution.end()) {
116+
if (!particlePtDistribution.contains(mcParticle.pdgCode())) {
119117
continue;
120118
}
121119
particlePtDistribution[mcParticle.pdgCode()]->Fill(mcParticle.pt());
@@ -148,7 +146,7 @@ struct Alice3TrackingPerformance {
148146
if (!isParticleSelected(mcParticle)) {
149147
continue;
150148
}
151-
if (ptResolutionVsPt.find(mcParticle.pdgCode()) == ptResolutionVsPt.end()) {
149+
if (!ptResolutionVsPt.contains(mcParticle.pdgCode())) {
152150
continue;
153151
}
154152
fillResolutionHistograms(mcParticle.pdgCode());

PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx

Lines changed: 338 additions & 158 deletions
Large diffs are not rendered by default.

PWGCF/Femto/Core/mcBuilder.h

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,182 @@ class McBuilder
748748
std::unordered_map<int64_t, int64_t> mMcMotherMap;
749749
std::unordered_map<int64_t, int64_t> mMcPartonicMotherMap;
750750
};
751+
752+
struct McBuilderDerivedToDerivedProducts : o2::framework::ProducesGroup {
753+
o2::framework::Produces<o2::aod::StoredFMcCols> producedMcCollisions;
754+
o2::framework::Produces<o2::aod::StoredFMcParticles> producedMcParticles;
755+
o2::framework::Produces<o2::aod::StoredFMcMothers> producedMothers;
756+
o2::framework::Produces<o2::aod::StoredFMcPartMoths> producedPartonicMothers;
757+
o2::framework::Produces<o2::aod::StoredFMcMotherLabels> producedMcMotherLabels;
758+
759+
o2::framework::Produces<o2::aod::StoredFColLabels> producedCollisionLabels;
760+
o2::framework::Produces<o2::aod::StoredFTrackLabels> producedTrackLabels;
761+
};
762+
763+
struct ConfMcTablesDerivedToDerived : o2::framework::ConfigurableGroup {
764+
std::string prefix = std::string("McTables");
765+
o2::framework::Configurable<bool> requireMcLabel{"requireMcLabel", false, "Reject particles without an associated MC particle instead of writing a -1 label"}; // dummy configuration for now
766+
};
767+
768+
/// Copies MC information from one femto derived file into another.
769+
/// The ancestry is already resolved upstream (FMcMothers / FMcPartMoths /
770+
/// FMcMotherLabels), so this only remaps indices: each source row is copied on
771+
/// first use and cached for the rest of the dataframe.
772+
class McBuilderDerivedToDerived
773+
{
774+
public:
775+
McBuilderDerivedToDerived() = default;
776+
~McBuilderDerivedToDerived() = default;
777+
778+
template <typename T>
779+
void init(T& config)
780+
{
781+
LOG(info) << "Initialize derived-to-derived monte carlo builder...";
782+
mRequireMcLabel = config.requireMcLabel.value;
783+
LOG(info) << "Initialization done...";
784+
}
785+
786+
/// Write one FColLabels row. Call exactly once per produced collision,
787+
/// directly after collisionBuilder.processCollision().
788+
template <typename T1, typename T2, typename T3>
789+
void fillCollisionWithLabel(T1 const& col, T2 const& /*mcCols*/, T3& mcProducts)
790+
{
791+
if (!col.has_fMcCol()) {
792+
mcProducts.producedCollisionLabels(-1);
793+
return;
794+
}
795+
auto mcCol = col.template fMcCol_as<T2>();
796+
mcProducts.producedCollisionLabels(this->getOrCreateMcCollisionRow(mcCol, mcProducts));
797+
}
798+
799+
/// True if this track has no MC particle and we are configured to drop such tracks.
800+
template <typename T>
801+
bool rejectParticle(T const& particle) const
802+
{
803+
return mRequireMcLabel && !particle.has_fMcParticle();
804+
}
805+
806+
/// Write one FTrackLabels row. Call exactly once per produced track row.
807+
/// mcParticles must be joined with FMcMotherLabels so the mother indices resolve.
808+
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
809+
void fillTrackWithLabel(T1 const& track, T2 const& mcCols, T3 const& /*mcParticles*/, T4 const& mcMothers, T5 const& mcPartonicMothers, T6& mcProducts)
810+
{
811+
if (!track.has_fMcParticle()) {
812+
mcProducts.producedTrackLabels(-1);
813+
return;
814+
}
815+
auto mcParticle = track.template fMcParticle_as<T3>();
816+
mcProducts.producedTrackLabels(
817+
this->getOrCreateMcParticleRow(mcParticle, mcCols, mcMothers, mcPartonicMothers, mcProducts));
818+
}
819+
820+
template <typename T1, typename T2>
821+
void reset(T1 const& mcCols, T2 const& mcParticles)
822+
{
823+
mCollisionMap.clear();
824+
mCollisionMap.reserve(mcCols.size());
825+
mMcParticleMap.clear();
826+
mMcParticleMap.reserve(mcParticles.size());
827+
mMcMotherMap.clear();
828+
mMcMotherMap.reserve(mcParticles.size());
829+
mMcPartonicMotherMap.clear();
830+
mMcPartonicMotherMap.reserve(mcParticles.size());
831+
}
832+
833+
private:
834+
template <typename T1, typename T2>
835+
int64_t getOrCreateMcCollisionRow(T1 const& mcCol, T2& mcProducts)
836+
{
837+
const int64_t gid = mcCol.globalIndex();
838+
auto it = mCollisionMap.find(gid);
839+
if (it != mCollisionMap.end()) {
840+
return it->second;
841+
}
842+
mcProducts.producedMcCollisions(mcCol.posZ(),
843+
mcCol.mult(),
844+
mcCol.cent());
845+
const int64_t row = mcProducts.producedMcCollisions.lastIndex();
846+
mCollisionMap.emplace(gid, row);
847+
return row;
848+
}
849+
850+
/// Find-or-create the FMcParticles row. On first creation the mother and
851+
/// partonic mother rows are copied and the single matching FMcMotherLabels row
852+
/// is written, so the two tables stay in lockstep exactly as in McBuilder.
853+
template <typename T1, typename T2, typename T3, typename T4, typename T5>
854+
int64_t getOrCreateMcParticleRow(T1 const& mcParticle, T2 const& /*mcCols*/, T3 const& /*mcMothers*/, T4 const& /*mcPartonicMothers*/, T5& mcProducts)
855+
{
856+
const int64_t gid = mcParticle.globalIndex();
857+
auto it = mMcParticleMap.find(gid);
858+
if (it != mMcParticleMap.end()) {
859+
return it->second;
860+
}
861+
862+
// NOTE: the MC collision of the particle, not of the reconstructed collision.
863+
// These differ for wrongly associated particles, which is the point of keeping it.
864+
int64_t mcColId = -1;
865+
if (mcParticle.has_fMcCol()) {
866+
auto mcCol = mcParticle.template fMcCol_as<T2>();
867+
mcColId = this->getOrCreateMcCollisionRow(mcCol, mcProducts);
868+
}
869+
870+
mcProducts.producedMcParticles(mcColId,
871+
mcParticle.origin(),
872+
mcParticle.pdgCode(),
873+
mcParticle.signedPt(),
874+
mcParticle.eta(),
875+
mcParticle.phi());
876+
const int64_t row = mcProducts.producedMcParticles.lastIndex();
877+
mMcParticleMap.emplace(gid, row);
878+
879+
// --- mother ---
880+
int64_t mcMotherRow = -1;
881+
if (mcParticle.has_fMcMother()) {
882+
auto mother = mcParticle.template fMcMother_as<T3>();
883+
const int64_t motherGid = mother.globalIndex();
884+
auto itM = mMcMotherMap.find(motherGid);
885+
if (itM != mMcMotherMap.end()) {
886+
mcMotherRow = itM->second;
887+
} else {
888+
mcProducts.producedMothers(mother.origin(),
889+
mother.pdgCode(),
890+
mother.signedPt(),
891+
mother.eta(),
892+
mother.phi());
893+
mcMotherRow = mcProducts.producedMothers.lastIndex();
894+
mMcMotherMap.emplace(motherGid, mcMotherRow);
895+
}
896+
}
897+
898+
// --- partonic mother ---
899+
int64_t mcPartonicMotherRow = -1;
900+
if (mcParticle.has_fMcPartMoth()) {
901+
auto partonicMother = mcParticle.template fMcPartMoth_as<T4>();
902+
const int64_t partonicGid = partonicMother.globalIndex();
903+
auto itPM = mMcPartonicMotherMap.find(partonicGid);
904+
if (itPM != mMcPartonicMotherMap.end()) {
905+
mcPartonicMotherRow = itPM->second;
906+
} else {
907+
mcProducts.producedPartonicMothers(partonicMother.pdgCode());
908+
mcPartonicMotherRow = mcProducts.producedPartonicMothers.lastIndex();
909+
mMcPartonicMotherMap.emplace(partonicGid, mcPartonicMotherRow);
910+
}
911+
}
912+
913+
// exactly one FMcMotherLabels row per FMcParticles row, written here and only here
914+
mcProducts.producedMcMotherLabels(mcMotherRow, mcPartonicMotherRow);
915+
916+
return row;
917+
}
918+
919+
bool mRequireMcLabel = false;
920+
921+
std::unordered_map<int64_t, int64_t> mCollisionMap;
922+
std::unordered_map<int64_t, int64_t> mMcParticleMap;
923+
std::unordered_map<int64_t, int64_t> mMcMotherMap;
924+
std::unordered_map<int64_t, int64_t> mMcPartonicMotherMap;
925+
};
926+
751927
} // namespace o2::analysis::femto::mcbuilder
752928

753929
#endif // PWGCF_FEMTO_CORE_MCBUILDER_H_

PWGCF/Femto/Core/trackBuilder.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ struct ConfTrackSelection : public o2::framework::ConfigurableGroup {
134134
std::string prefix = Prefix; // Unique prefix based on the template argument
135135
// configuration parameters
136136
o2::framework::Configurable<int> pdgCodeAbs{"pdgCodeAbs", 2212, "Absolute value of PDG code. Set sign of charge to -1 for antiparticle."};
137-
o2::framework::Configurable<int> chargeAbs{"chargeAbs", 1, "Absolute value of charge (e.g. 1 for most tracks, 2 for He3). Set sign of charge to -1 for antiparticle"};
137+
o2::framework::Configurable<int> chargeAbs{"chargeAbs", 1, "Absolute value of charge (e.g. 1 for most tracks, 2 for He3)"};
138138
o2::framework::Configurable<int> chargeSign{"chargeSign", 1, "Track charge sign: +1 for positive, -1 for negative, 0 for both"};
139139
// filters for kinematics
140140
o2::framework::Configurable<float> ptMin{"ptMin", 0.0f, "Minimum pT (GeV/c)"};
@@ -920,6 +920,41 @@ class TrackBuilderDerivedToDerived
920920
return idx;
921921
}
922922

923+
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
924+
void processTracksWithMc(T1& col, T2& /*trackTable*/, T3& partitionTrack1, T4& partitionTrack2, T5& cache,
925+
T6& newTrackTable, T7& newCollisionTable,
926+
T8& mcBuilder, T9 const& mcCols, T10 const& mcParticles, T11 const& mcMothers, T12 const& mcPartonicMothers, auto& mcProducts)
927+
{
928+
if (mLimitTrack1 > 0) {
929+
auto trackSlice1 = partitionTrack1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache);
930+
for (auto const& track : trackSlice1) {
931+
this->fillTrackWithMcLabel(track, newTrackTable, newCollisionTable, mcBuilder, mcCols, mcParticles, mcMothers, mcPartonicMothers, mcProducts);
932+
}
933+
}
934+
if (mLimitTrack2 > 0) {
935+
auto trackSlice2 = partitionTrack2->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache);
936+
for (auto const& track : trackSlice2) {
937+
this->fillTrackWithMcLabel(track, newTrackTable, newCollisionTable, mcBuilder, mcCols, mcParticles, mcMothers, mcPartonicMothers, mcProducts);
938+
}
939+
}
940+
}
941+
942+
/// Same as fillTrack, but writes the matching FTrackLabels row. The indexMap
943+
/// lookup happens first, so a track selected by both partitions produces
944+
/// exactly one track row and exactly one label row.
945+
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
946+
int64_t fillTrackWithMcLabel(T1 const& track, T2& trackProducts, T3& collisionProducts,
947+
T4& mcBuilder, T5 const& mcCols, T6 const& mcParticles, T7 const& mcMothers, T8 const& mcPartonicMothers, T9& mcProducts)
948+
{
949+
auto index = utils::getIndex(track.globalIndex(), indexMap);
950+
if (index) {
951+
return index.value();
952+
}
953+
const int64_t idx = this->fillTrack(track, trackProducts, collisionProducts);
954+
mcBuilder.fillTrackWithLabel(track, mcCols, mcParticles, mcMothers, mcPartonicMothers, mcProducts);
955+
return idx;
956+
}
957+
923958
template <typename T1, typename T2, typename T3>
924959
int64_t getDaughterIndex(const T1& daughter, T2& trackProducts, T3& collisionProducts)
925960
{

0 commit comments

Comments
 (0)