Skip to content

Commit a0b82ce

Browse files
iarseneIonut Cristian Arsenealibuild
authored
[PWGDQ] Implement possibility to specify exclusive decay channels via MCSignal (AliceO2Group#8744)
Co-authored-by: Ionut Cristian Arsene <[email protected]> Co-authored-by: ALICE Action Bot <[email protected]>
1 parent 8d5e790 commit a0b82ce

5 files changed

+114
-34
lines changed

PWGDQ/Core/HistogramsLibrary.cxx

+1
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h
13551355
hm->AddHistogram(histClass, "TauzProj", "", false, 4000, -0.5, 0.5, VarManager::kVertexingTauzProjected);
13561356
hm->AddHistogram(histClass, "TauxyProj", "", false, 4000, -0.5, 0.5, VarManager::kVertexingTauxyProjected);
13571357
hm->AddHistogram(histClass, "CosPointingAngle", "", false, 100, 0.0, 1.0, VarManager::kCosPointingAngle);
1358+
hm->AddHistogram(histClass, "DCAxyzBetweenProngs", "", false, 100, 0.0, 1.0, VarManager::kKFDCAxyzBetweenProngs);
13581359
}
13591360
if (subGroupStr.Contains("multidimentional-vertexing-histograms")) {
13601361
hm->AddHistogram(histClass, "Mass_Tauxy", "", false, 75, 4.0, 7.0, VarManager::kPairMass, 40, -0.0, 0.02, VarManager::kVertexingTauxy);

PWGDQ/Core/MCSignal.cxx

+21-10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12+
#include <vector>
13+
#include <iostream>
14+
1215
#include "PWGDQ/Core/MCSignal.h"
1316

1417
using std::cout;
@@ -22,7 +25,9 @@ MCSignal::MCSignal() : TNamed("", ""),
2225
fNProngs(0),
2326
fCommonAncestorIdxs({}),
2427
fExcludeCommonAncestor(false),
25-
fTempAncestorLabel(-1)
28+
fTempAncestorLabel(-1),
29+
fDecayChannelIsExclusive(false),
30+
fDecayChannelIsNotExclusive(false)
2631
{
2732
}
2833

@@ -32,31 +37,35 @@ MCSignal::MCSignal(int nProngs, const char* name /*= ""*/, const char* title /*=
3237
fNProngs(nProngs),
3338
fCommonAncestorIdxs({}),
3439
fExcludeCommonAncestor(false),
35-
fTempAncestorLabel(-1)
40+
fTempAncestorLabel(-1),
41+
fDecayChannelIsExclusive(false),
42+
fDecayChannelIsNotExclusive(false)
3643
{
3744
fProngs.reserve(nProngs);
3845
}
3946

4047
//________________________________________________________________________________________________
41-
MCSignal::MCSignal(const char* name, const char* title, std::vector<MCProng> prongs, std::vector<short> commonAncestors, bool excludeCommonAncestor) : TNamed(name, title),
42-
fProngs(prongs),
43-
fNProngs(prongs.size()),
44-
fCommonAncestorIdxs(commonAncestors),
45-
fExcludeCommonAncestor(excludeCommonAncestor),
46-
fTempAncestorLabel(-1)
48+
MCSignal::MCSignal(const char* name, const char* title, std::vector<MCProng> prongs, std::vector<int8_t> commonAncestors, bool excludeCommonAncestor) : TNamed(name, title),
49+
fProngs(prongs),
50+
fNProngs(prongs.size()),
51+
fCommonAncestorIdxs(commonAncestors),
52+
fExcludeCommonAncestor(excludeCommonAncestor),
53+
fTempAncestorLabel(-1),
54+
fDecayChannelIsExclusive(false),
55+
fDecayChannelIsNotExclusive(false)
4756
{
4857
}
4958

5059
//________________________________________________________________________________________________
51-
void MCSignal::SetProngs(std::vector<MCProng> prongs, std::vector<short> commonAncestors)
60+
void MCSignal::SetProngs(std::vector<MCProng> prongs, std::vector<int8_t> commonAncestors)
5261
{
5362
fProngs = prongs;
5463
fNProngs = fProngs.size();
5564
fCommonAncestorIdxs = commonAncestors;
5665
}
5766

5867
//________________________________________________________________________________________________
59-
void MCSignal::AddProng(MCProng prong, short commonAncestor)
68+
void MCSignal::AddProng(MCProng prong, int8_t commonAncestor)
6069
{
6170
if (fProngs.size() < fNProngs) {
6271
fProngs.push_back(prong);
@@ -71,6 +80,8 @@ void MCSignal::PrintConfig()
7180
{
7281
cout << "Name/Title: " << fName << " / " << fTitle << endl;
7382
cout << "Exclude common ancestor combinations: " << fExcludeCommonAncestor << endl;
83+
cout << "Decay channel is exclusive: " << fDecayChannelIsExclusive << endl;
84+
cout << "Decay channel is not exclusive: " << fDecayChannelIsNotExclusive << endl;
7485
cout << "Printing " << fNProngs << "/" << fProngs.size() << " prongs:" << endl;
7586
int i = 0;
7687
for (auto& pr : fProngs) {

PWGDQ/Core/MCSignal.h

+52-22
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,21 @@ class MCSignal : public TNamed
6666
{
6767
public:
6868
MCSignal();
69-
MCSignal(int nProngs, const char* name = "", const char* title = "");
70-
MCSignal(const char* name, const char* title, std::vector<MCProng> prongs, std::vector<short> commonAncestors, bool excludeCommonAncestor = false);
69+
MCSignal(int nProngs, const char* name = "", const char* title = ""); // NOLINT
70+
MCSignal(const char* name, const char* title, std::vector<MCProng> prongs, std::vector<int8_t> commonAncestors, bool excludeCommonAncestor = false);
7171
MCSignal(const MCSignal& c) = default;
7272
~MCSignal() override = default;
7373

74-
void SetProngs(std::vector<MCProng> prongs, std::vector<short> commonAncestors);
75-
void AddProng(MCProng prong, short commonAncestor = -1);
74+
void SetProngs(std::vector<MCProng> prongs, std::vector<int8_t> commonAncestors);
75+
void AddProng(MCProng prong, int8_t commonAncestor = -1);
76+
void SetDecayChannelIsExclusive(bool option = true)
77+
{
78+
fDecayChannelIsExclusive = option;
79+
}
80+
void SetDecayChannelIsNotExclusive(bool option = true)
81+
{
82+
fDecayChannelIsNotExclusive = option;
83+
}
7684

7785
int GetNProngs() const
7886
{
@@ -82,6 +90,14 @@ class MCSignal : public TNamed
8290
{
8391
return fProngs[0].fNGenerations;
8492
}
93+
bool GetDecayChannelIsExclusive() const
94+
{
95+
return fDecayChannelIsExclusive;
96+
}
97+
bool GetDecayChannelIsNotExclusive() const
98+
{
99+
return fDecayChannelIsNotExclusive;
100+
}
85101

86102
template <typename... T>
87103
bool CheckSignal(bool checkSources, const T&... args)
@@ -97,10 +113,12 @@ class MCSignal : public TNamed
97113
void PrintConfig();
98114

99115
private:
100-
std::vector<MCProng> fProngs;
101-
unsigned int fNProngs;
102-
std::vector<short> fCommonAncestorIdxs;
103-
bool fExcludeCommonAncestor;
116+
std::vector<MCProng> fProngs; // vector of MCProng
117+
unsigned int fNProngs; // number of prongs
118+
std::vector<int8_t> fCommonAncestorIdxs; // index of the most recent ancestor, relative to each prong's history
119+
bool fExcludeCommonAncestor; // explicitly request that there is no common ancestor
120+
bool fDecayChannelIsExclusive; // if true, then the indicated mother particle has a number of daughters which is equal to the number of prongs defined in this MC signal
121+
bool fDecayChannelIsNotExclusive; // if true, then the indicated mother particle has a number of daughters which is larger than the number of prongs defined in this MC signal
104122
int fTempAncestorLabel;
105123

106124
template <typename T>
@@ -139,6 +157,18 @@ bool MCSignal::CheckProng(int i, bool checkSources, const T& track)
139157
if (fNProngs > 1 && fCommonAncestorIdxs[i] == j) {
140158
if (i == 0) {
141159
fTempAncestorLabel = currentMCParticle.globalIndex();
160+
// In the case of decay channels marked as being "exclusive", check how many decay daughters this mother has registered
161+
// in the stack and compare to the number of prongs defined for this MCSignal.
162+
// If these numbers are equal, it means this decay MCSignal match is exclusive (there are no additional prongs for this mother besides the
163+
// prongs defined here).
164+
if (currentMCParticle.has_daughters()) {
165+
if (fDecayChannelIsExclusive && currentMCParticle.daughtersIds()[1] - currentMCParticle.daughtersIds()[0] + 1 != fNProngs) {
166+
return false;
167+
}
168+
if (fDecayChannelIsNotExclusive && currentMCParticle.daughtersIds()[1] - currentMCParticle.daughtersIds()[0] + 1 == fNProngs) {
169+
return false;
170+
}
171+
}
142172
} else {
143173
if (currentMCParticle.globalIndex() != fTempAncestorLabel && !fExcludeCommonAncestor)
144174
return false;
@@ -185,27 +215,27 @@ bool MCSignal::CheckProng(int i, bool checkSources, const T& track)
185215
// check each source
186216
uint64_t sourcesDecision = 0;
187217
// Check kPhysicalPrimary
188-
if (fProngs[i].fSourceBits[j] & (uint64_t(1) << MCProng::kPhysicalPrimary)) {
189-
if ((fProngs[i].fExcludeSource[j] & (uint64_t(1) << MCProng::kPhysicalPrimary)) != currentMCParticle.isPhysicalPrimary()) {
190-
sourcesDecision |= (uint64_t(1) << MCProng::kPhysicalPrimary);
218+
if (fProngs[i].fSourceBits[j] & (static_cast<uint64_t>(1) << MCProng::kPhysicalPrimary)) {
219+
if ((fProngs[i].fExcludeSource[j] & (static_cast<uint64_t>(1) << MCProng::kPhysicalPrimary)) != currentMCParticle.isPhysicalPrimary()) {
220+
sourcesDecision |= (static_cast<uint64_t>(1) << MCProng::kPhysicalPrimary);
191221
}
192222
}
193223
// Check kProducedInTransport
194-
if (fProngs[i].fSourceBits[j] & (uint64_t(1) << MCProng::kProducedInTransport)) {
195-
if ((fProngs[i].fExcludeSource[j] & (uint64_t(1) << MCProng::kProducedInTransport)) != (!currentMCParticle.producedByGenerator())) {
196-
sourcesDecision |= (uint64_t(1) << MCProng::kProducedInTransport);
224+
if (fProngs[i].fSourceBits[j] & (static_cast<uint64_t>(1) << MCProng::kProducedInTransport)) {
225+
if ((fProngs[i].fExcludeSource[j] & (static_cast<uint64_t>(1) << MCProng::kProducedInTransport)) != (!currentMCParticle.producedByGenerator())) {
226+
sourcesDecision |= (static_cast<uint64_t>(1) << MCProng::kProducedInTransport);
197227
}
198228
}
199229
// Check kProducedByGenerator
200-
if (fProngs[i].fSourceBits[j] & (uint64_t(1) << MCProng::kProducedByGenerator)) {
201-
if ((fProngs[i].fExcludeSource[j] & (uint64_t(1) << MCProng::kProducedByGenerator)) != currentMCParticle.producedByGenerator()) {
202-
sourcesDecision |= (uint64_t(1) << MCProng::kProducedByGenerator);
230+
if (fProngs[i].fSourceBits[j] & (static_cast<uint64_t>(1) << MCProng::kProducedByGenerator)) {
231+
if ((fProngs[i].fExcludeSource[j] & (static_cast<uint64_t>(1) << MCProng::kProducedByGenerator)) != currentMCParticle.producedByGenerator()) {
232+
sourcesDecision |= (static_cast<uint64_t>(1) << MCProng::kProducedByGenerator);
203233
}
204234
}
205235
// Check kFromBackgroundEvent
206-
if (fProngs[i].fSourceBits[j] & (uint64_t(1) << MCProng::kFromBackgroundEvent)) {
207-
if ((fProngs[i].fExcludeSource[j] & (uint64_t(1) << MCProng::kFromBackgroundEvent)) != currentMCParticle.fromBackgroundEvent()) {
208-
sourcesDecision |= (uint64_t(1) << MCProng::kFromBackgroundEvent);
236+
if (fProngs[i].fSourceBits[j] & (static_cast<uint64_t>(1) << MCProng::kFromBackgroundEvent)) {
237+
if ((fProngs[i].fExcludeSource[j] & (static_cast<uint64_t>(1) << MCProng::kFromBackgroundEvent)) != currentMCParticle.fromBackgroundEvent()) {
238+
sourcesDecision |= (static_cast<uint64_t>(1) << MCProng::kFromBackgroundEvent);
209239
}
210240
}
211241
// no source bit is fulfilled
@@ -246,9 +276,9 @@ bool MCSignal::CheckProng(int i, bool checkSources, const T& track)
246276
}
247277
}
248278

249-
if (fProngs[i].fPDGInHistory.size() == 0)
279+
if (fProngs[i].fPDGInHistory.size() == 0) {
250280
return true;
251-
else { // check if mother pdg is in history
281+
} else { // check if mother pdg is in history
252282
std::vector<int> pdgInHistory;
253283

254284
// while find mothers, check if the provided PDG codes are included or excluded in the particle decay history

PWGDQ/Core/MCSignalLibrary.cxx

+37
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
//
1212
1313
//
14+
#include <string>
15+
1416
#include <TPDGCode.h>
1517
#include "CommonConstants/PhysicsConstants.h"
1618
#include "PWGDQ/Core/MCSignalLibrary.h"
@@ -405,6 +407,11 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name)
405407
signal = new MCSignal(name, "Electrons from jpsi decays", {prong}, {-1});
406408
return signal;
407409
}
410+
if (!nameStr.compare("anythingFromJpsi")) {
411+
MCProng prong(2, {MCProng::kPDGCodeNotAssigned, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false});
412+
signal = new MCSignal(name, "Anything from jpsi decays", {prong}, {-1});
413+
return signal;
414+
}
408415
if (!nameStr.compare("eFromPromptJpsi")) {
409416
MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false});
410417
prong.SetSourceBit(0, MCProng::kPhysicalPrimary);
@@ -701,6 +708,20 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name)
701708
signal = new MCSignal(name, "ee pairs from j/psi decays", {prong, prong}, {1, 1}); // signal at pair level
702709
return signal;
703710
}
711+
if (!nameStr.compare("eeFromJpsiExclusive")) {
712+
MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false});
713+
prong.SetSourceBit(0, MCProng::kPhysicalPrimary);
714+
signal = new MCSignal(name, "ee pairs from j/psi decays", {prong, prong}, {1, 1}); // signal at pair level
715+
signal->SetDecayChannelIsExclusive(true);
716+
return signal;
717+
}
718+
if (!nameStr.compare("eeFromJpsiNotExclusive")) {
719+
MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false});
720+
prong.SetSourceBit(0, MCProng::kPhysicalPrimary);
721+
signal = new MCSignal(name, "ee pairs from j/psi decays", {prong, prong}, {1, 1}); // signal at pair level
722+
signal->SetDecayChannelIsNotExclusive(true);
723+
return signal;
724+
}
704725
if (!nameStr.compare("eePrimaryFromPromptJPsi")) {
705726
MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true});
706727
prong.SetSourceBit(0, MCProng::kPhysicalPrimary);
@@ -1120,6 +1141,22 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name)
11201141
return signal;
11211142
}
11221143

1144+
if (!nameStr.compare("eeKaonFromBplusExclusive")) {
1145+
MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false});
1146+
MCProng prongKaon(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false});
1147+
signal = new MCSignal(name, "Kaon and electron pair from B+", {pronge, pronge, prongKaon}, {2, 2, 1});
1148+
signal->SetDecayChannelIsExclusive(true);
1149+
return signal;
1150+
}
1151+
1152+
if (!nameStr.compare("eeKaonFromBplusNotExclusive")) {
1153+
MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false});
1154+
MCProng prongKaon(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false});
1155+
signal = new MCSignal(name, "Kaon and electron pair from B+", {pronge, pronge, prongKaon}, {2, 2, 1});
1156+
signal->SetDecayChannelIsNotExclusive(true);
1157+
return signal;
1158+
}
1159+
11231160
if (!nameStr.compare("Bplus")) {
11241161
MCProng prong(1, {521}, {true}, {false}, {0}, {0}, {false});
11251162
signal = new MCSignal(name, "B+", {prong}, {-1});

PWGDQ/Tasks/dqEfficiency_withAssoc.cxx

+3-2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ DECLARE_SOA_COLUMN(TauxyBcandidate, tauxyBcandidate, float);
7979
DECLARE_SOA_COLUMN(TauzBcandidate, tauzBcandidate, float);
8080
DECLARE_SOA_COLUMN(CosPBcandidate, cosPBcandidate, float);
8181
DECLARE_SOA_COLUMN(Chi2Bcandidate, chi2Bcandidate, float);
82+
DECLARE_SOA_COLUMN(DCAxyzBetweenProngs, dcaxyzBetweenProngs, float);
8283
DECLARE_SOA_COLUMN(McFlag, mcFlag, int8_t);
8384
} // namespace dqanalysisflags
8485

@@ -88,7 +89,7 @@ DECLARE_SOA_TABLE(BarrelAmbiguities, "AOD", "DQBARRELAMB", dqanalysisflags::Barr
8889
DECLARE_SOA_TABLE(MuonTrackCuts, "AOD", "DQANAMUONCUTS", dqanalysisflags::IsMuonSelected); //! joinable to ReducedMuonsAssoc
8990
DECLARE_SOA_TABLE(MuonAmbiguities, "AOD", "DQMUONAMB", dqanalysisflags::MuonAmbiguityInBunch, dqanalysisflags::MuonAmbiguityOutOfBunch); //! joinable to ReducedMuonTracks
9091
DECLARE_SOA_TABLE(Prefilter, "AOD", "DQPREFILTER", dqanalysisflags::IsBarrelSelectedPrefilter); //! joinable to ReducedTracksAssoc
91-
DECLARE_SOA_TABLE(BmesonCandidates, "AOD", "DQBMESONS", dqanalysisflags::massBcandidate, dqanalysisflags::pTBcandidate, dqanalysisflags::LxyBcandidate, dqanalysisflags::LxyzBcandidate, dqanalysisflags::LzBcandidate, dqanalysisflags::TauxyBcandidate, dqanalysisflags::TauzBcandidate, dqanalysisflags::CosPBcandidate, dqanalysisflags::Chi2Bcandidate, dqanalysisflags::McFlag);
92+
DECLARE_SOA_TABLE(BmesonCandidates, "AOD", "DQBMESONS", dqanalysisflags::massBcandidate, dqanalysisflags::pTBcandidate, dqanalysisflags::LxyBcandidate, dqanalysisflags::LxyzBcandidate, dqanalysisflags::LzBcandidate, dqanalysisflags::TauxyBcandidate, dqanalysisflags::TauzBcandidate, dqanalysisflags::DCAxyzBetweenProngs, dqanalysisflags::CosPBcandidate, dqanalysisflags::Chi2Bcandidate, dqanalysisflags::McFlag);
9293
} // namespace o2::aod
9394

9495
// Declarations of various short names
@@ -2136,7 +2137,7 @@ struct AnalysisDileptonTrack {
21362137
}
21372138
}
21382139
// table to be written out for ML analysis
2139-
BmesonsTable(fValuesHadron[VarManager::kPairMass], fValuesHadron[VarManager::kPairPt], fValuesHadron[VarManager::kVertexingLxy], fValuesHadron[VarManager::kVertexingLxyz], fValuesHadron[VarManager::kVertexingLz], fValuesHadron[VarManager::kVertexingTauxy], fValuesHadron[VarManager::kVertexingTauz], fValuesHadron[VarManager::kCosPointingAngle], fValuesHadron[VarManager::kVertexingChi2PCA], mcDecision);
2140+
BmesonsTable(fValuesHadron[VarManager::kPairMass], fValuesHadron[VarManager::kPairPt], fValuesHadron[VarManager::kVertexingLxy], fValuesHadron[VarManager::kVertexingLxyz], fValuesHadron[VarManager::kVertexingLz], fValuesHadron[VarManager::kVertexingTauxy], fValuesHadron[VarManager::kVertexingTauz], fValuesHadron[VarManager::kKFDCAxyzBetweenProngs], fValuesHadron[VarManager::kCosPointingAngle], fValuesHadron[VarManager::kVertexingChi2PCA], mcDecision);
21402141
}
21412142
} // end loop over dileptons
21422143
}

0 commit comments

Comments
 (0)