Skip to content

Commit 2dac499

Browse files
author
Gian Michele Innocenti
committed
include filling table xicc
1 parent 084cf40 commit 2dac499

4 files changed

Lines changed: 332 additions & 80 deletions

File tree

Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -481,31 +481,6 @@ auto InvMassXicToPiKP(const T& candidate)
481481
return InvMassLcpiKp(candidate);
482482
}
483483

484-
// Ξcc±± → p± K∓ π± π±
485-
486-
template <typename T>
487-
auto CtXicc(const T& candidate)
488-
{
489-
return candidate.ct(RecoDecay::getMassPDG(pdg::Code::kXiCCPlusPlus));
490-
}
491-
492-
template <typename T>
493-
auto YXicc(const T& candidate)
494-
{
495-
return candidate.y(RecoDecay::getMassPDG(pdg::Code::kXiCCPlusPlus));
496-
}
497-
498-
template <typename T>
499-
auto EXicc(const T& candidate)
500-
{
501-
return candidate.e(RecoDecay::getMassPDG(pdg::Code::kXiCCPlusPlus));
502-
}
503-
504-
template <typename T>
505-
auto InvMassXiccToXicPi(const T& candidate)
506-
{
507-
return candidate.m(array{RecoDecay::getMassPDG(pdg::Code::kXiCPlus), RecoDecay::getMassPDG(kPiPlus)});
508-
}
509484
} // namespace hf_cand_prong3
510485

511486
// 3-prong decay candidate table
@@ -568,7 +543,7 @@ DECLARE_SOA_TABLE(HfCandProng3MCGen, "AOD", "HFCANDP3MCGEN", //!
568543
// specific Xicc candidate properties
569544
namespace hf_cand_xicc
570545
{
571-
DECLARE_SOA_INDEX_COLUMN_FULL(Index0, index0, int, HfCandProng3, "_0"); // Xicc index
546+
DECLARE_SOA_INDEX_COLUMN_FULL(Index0, index0, int, HfCandProng2, "_0"); // Xic index
572547
// MC matching result:
573548
DECLARE_SOA_COLUMN(FlagMCMatchRec, flagMCMatchRec, int8_t); // reconstruction level
574549
DECLARE_SOA_COLUMN(FlagMCMatchGen, flagMCMatchGen, int8_t); // generator level
@@ -578,6 +553,32 @@ DECLARE_SOA_COLUMN(FlagMCDecayChanRec, flagMCDecayChanRec, int8_t); // resonant
578553
DECLARE_SOA_COLUMN(FlagMCDecayChanGen, flagMCDecayChanGen, int8_t); // resonant decay channel flag, generator level
579554
// mapping of decay types
580555
enum DecayType { XiccToXicPi = 0 }; // move this to a dedicated cascade namespace in the future?
556+
557+
// Ξcc±± → p± K∓ π± π±
558+
559+
template <typename T>
560+
auto CtXicc(const T& candidate)
561+
{
562+
return candidate.ct(RecoDecay::getMassPDG(pdg::Code::kXiCCPlusPlus));
563+
}
564+
565+
template <typename T>
566+
auto YXicc(const T& candidate)
567+
{
568+
return candidate.y(RecoDecay::getMassPDG(pdg::Code::kXiCCPlusPlus));
569+
}
570+
571+
template <typename T>
572+
auto EXicc(const T& candidate)
573+
{
574+
return candidate.e(RecoDecay::getMassPDG(pdg::Code::kXiCCPlusPlus));
575+
}
576+
577+
template <typename T>
578+
auto InvMassXiccToXicPi(const T& candidate)
579+
{
580+
return candidate.m(array{RecoDecay::getMassPDG(pdg::Code::kXiCPlus), RecoDecay::getMassPDG(kPiPlus)});
581+
}
581582
} // namespace hf_cand_xicc
582583

583584
// declare dedicated Xicc candidate table

Analysis/Tasks/PWGHF/CMakeLists.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ o2_add_dpl_workflow(hf-task-xic
113113
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing
114114
COMPONENT_NAME Analysis)
115115

116-
#o2_add_dpl_workflow(hf-task-xicc
117-
#SOURCES taskXicc.cxx
118-
#PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing
119-
#COMPONENT_NAME Analysis)
116+
o2_add_dpl_workflow(hf-task-xicc
117+
SOURCES taskXicc.cxx
118+
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing
119+
COMPONENT_NAME Analysis)
120120

121121
o2_add_dpl_workflow(hf-task-x
122122
SOURCES taskX.cxx

Analysis/Tasks/PWGHF/HFCandidateCreatorXicc.cxx

Lines changed: 109 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
/// \note Extended from HFCandidateCreator2Prong, HFCandidateCreator3Prong, HFCandidateCreatorX
1414
///
1515
/// \author Gian Michele Innocenti <gian.michele.innocenti@cern.ch>, CERN
16+
/// \author Luigi Dello Stritto <luigi.dello.stritto@cern.ch >, SALERNO
17+
/// \author Mattia Faggin <mattia.faggin@cern.ch>, University and INFN PADOVA
1618

1719
#include "Framework/AnalysisTask.h"
1820
#include "DetectorsVertexing/DCAFitterN.h"
@@ -25,8 +27,6 @@
2527
using namespace o2;
2628
using namespace o2::framework;
2729
using namespace o2::aod::hf_cand;
28-
using namespace o2::aod::hf_cand_prong2;
29-
using namespace o2::aod::hf_cand_prong3;
3030
using namespace o2::aod::hf_cand_xicc;
3131
using namespace o2::framework::expressions; //FIXME not sure if this is needed
3232

@@ -53,11 +53,12 @@ struct HFCandidateCreatorXicc {
5353
OutputObj<TH1F> hmassXic{TH1F("hmassXic", "xic candidates;inv. mass (#pi K #pi) (GeV/#it{c}^{2});entries", 500, 1.6, 2.6)};
5454
OutputObj<TH1F> hCovPVXX{TH1F("hCovPVXX", "3-prong candidates;XX element of cov. matrix of prim. vtx position (cm^{2});entries", 100, 0., 1.e-4)};
5555
OutputObj<TH1F> hCovSVXX{TH1F("hCovSVXX", "3-prong candidates;XX element of cov. matrix of sec. vtx position (cm^{2});entries", 100, 0., 0.2)};
56-
OutputObj<TH1F> hmassXicc{TH1F("hmassXicc", "xicc candidates;inv. mass (#Xi_{c} #pi) (GeV/#it{c}^{2});entries", 400, 2.5, 4.5)};
56+
OutputObj<TH1F> hmassXicc{TH1F("hmassXicc", "xicc candidates;inv. mass (#Xi_{cc} #pi) (GeV/#it{c}^{2});entries", 400, 2.5, 6.5)};
5757

5858
double massPi = RecoDecay::getMassPDG(kPiPlus);
5959
double massK = RecoDecay::getMassPDG(kKPlus);
60-
double massPiKPi{0.};
60+
double massXic = RecoDecay::getMassPDG(4232);
61+
double massXicc{0.};
6162

6263
Configurable<int> d_selectionFlagXic{"d_selectionFlagXic", 1, "Selection Flag for Xic"};
6364
Configurable<double> cutYCandMax{"cutYCandMax", -1., "max. cand. rapidity"};
@@ -88,59 +89,101 @@ struct HFCandidateCreatorXicc {
8889
df2.setUseAbsDCA(true);
8990

9091
for (auto& xicCand : xicCands) {
91-
if (!(xicCand.hfflag() & 1 << XicToPKPi)) {
92+
if (!(xicCand.hfflag() & 1 << o2::aod::hf_cand_prong3::XicToPKPi)) {
9293
continue;
94+
}
95+
if (xicCand.isSelXicToPKPi() >= d_selectionFlagXic) {
96+
hmassXic->Fill(InvMassXicToPKPi(xicCand), xicCand.pt());
97+
}
98+
if (xicCand.isSelXicToPiKP() >= d_selectionFlagXic) {
99+
hmassXic->Fill(InvMassXicToPiKP(xicCand), xicCand.pt());
100+
}
101+
auto track0 = xicCand.index0_as<aod::BigTracks>();
102+
auto track1 = xicCand.index1_as<aod::BigTracks>();
103+
auto track2 = xicCand.index2_as<aod::BigTracks>();
104+
auto trackParVar0 = getTrackParCov(track0);
105+
auto trackParVar1 = getTrackParCov(track1);
106+
auto trackParVar2 = getTrackParCov(track2);
107+
auto collision = track0.collision(); //FIXME: not sure we need it.
93108

94-
if (xicCand.isSelXicToPKPi() >= d_selectionFlagXic) {
95-
hmassXic->Fill(InvMassXicToPKPi(xicCand), xicCand.pt());
109+
// reconstruct the 3-prong secondary vertex
110+
if (df3.process(trackParVar0, trackParVar1, trackParVar2) == 0) {
111+
continue;
112+
}
113+
const auto& secondaryVertex = df3.getPCACandidate();
114+
trackParVar0.propagateTo(secondaryVertex[0], magneticField);
115+
trackParVar1.propagateTo(secondaryVertex[0], magneticField);
116+
trackParVar2.propagateTo(secondaryVertex[0], magneticField);
117+
118+
array<float, 3> pvecpK = {track0.px() + track1.px(), track0.py() + track1.py(), track0.pz() + track1.pz()};
119+
array<float, 3> pvecxic = {pvecpK[0] + track2.px(), pvecpK[1] + track2.py(), pvecpK[2] + track2.pz()};
120+
auto trackpK = o2::dataformats::V0(df3.getPCACandidatePos(), pvecpK, df3.calcPCACovMatrixFlat(),
121+
trackParVar0, trackParVar1, {0, 0}, {0, 0});
122+
auto trackxic = o2::dataformats::V0(df3.getPCACandidatePos(), pvecxic, df3.calcPCACovMatrixFlat(),
123+
trackpK, trackParVar2, {0, 0}, {0, 0});
124+
125+
int index0Xic = track0.globalIndex();
126+
int index1Xic = track1.globalIndex();
127+
int index2Xic = track2.globalIndex();
128+
int charge = track0.sign() + track1.sign() + track2.sign();
129+
130+
for (auto& trackpion : tracks) {
131+
if (trackpion.pt() < 1.0) {
132+
continue;
96133
}
97-
if (xicCand.isSelXicToPiKP() >= d_selectionFlagXic) {
98-
hmassXic->Fill(InvMassXicToPiKP(xicCand), xicCand.pt());
134+
if (trackpion.sign() * charge < 0) {
135+
continue;
99136
}
100-
auto track0 = xicCand.index0_as<aod::BigTracks>();
101-
auto track1 = xicCand.index1_as<aod::BigTracks>();
102-
auto track2 = xicCand.index2_as<aod::BigTracks>();
103-
auto trackParVar0 = getTrackParCov(track0);
104-
auto trackParVar1 = getTrackParCov(track1);
105-
auto trackParVar2 = getTrackParCov(track2);
106-
auto collision = track0.collision(); //FIXME: not sure we need it.
107-
108-
// reconstruct the 3-prong secondary vertex
109-
if (df3.process(trackParVar0, trackParVar1, trackParVar2) == 0) {
137+
if (trackpion.globalIndex() == index0Xic || trackpion.globalIndex() == index1Xic || trackpion.globalIndex() == index2Xic) {
110138
continue;
111139
}
112-
const auto& secondaryVertex = df3.getPCACandidate();
113-
trackParVar0.propagateTo(secondaryVertex[0], magneticField);
114-
trackParVar1.propagateTo(secondaryVertex[0], magneticField);
115-
trackParVar2.propagateTo(secondaryVertex[0], magneticField);
116-
117-
array<float, 3> pvecpK = {track0.px() + track1.px(), track0.py() + track1.py(), track0.pz() + track1.pz()};
118-
array<float, 3> pvecxic = {pvecpK[0] + track2.px(), pvecpK[1] + track2.py(), pvecpK[2] + track2.pz()};
119-
auto trackpK = o2::dataformats::V0(df3.getPCACandidatePos(), pvecpK, df3.calcPCACovMatrixFlat(),
120-
trackParVar0, trackParVar1, {0, 0}, {0, 0});
121-
auto trackxic = o2::dataformats::V0(df3.getPCACandidatePos(), pvecxic, df3.calcPCACovMatrixFlat(),
122-
trackpK, trackParVar2, {0, 0}, {0, 0});
123-
124-
int index0Xic = track0.globalIndex();
125-
int index1Xic = track1.globalIndex();
126-
int index2Xic = track2.globalIndex();
127-
for (auto& trackPos : tracks) {
128-
if (trackPos.sign() < 0) { // select only positive tracks - use partitions?
129-
continue;
130-
}
131-
132-
rowCandidateBase(collision.globalIndex(),
133-
collision.posX(), collision.posY(), collision.posZ(),
134-
secondaryVertex[0], secondaryVertex[1], secondaryVertex[2],
135-
0., 0.,
136-
0.,
137-
1., 0., 0.,
138-
0., 0., 0.,
139-
0., 0.,
140-
0., 0.,
141-
0, 0,
142-
1);
140+
array<float, 3> pvecpion;
141+
auto trackParVarPi = getTrackParCov(trackpion);
142+
143+
// reconstruct the 3-prong X vertex
144+
if (df2.process(trackxic, trackParVarPi) == 0) {
145+
continue;
143146
}
147+
148+
// calculate relevant properties
149+
const auto& secondaryVertexXicc = df2.getPCACandidate();
150+
auto chi2PCA = df2.getChi2AtPCACandidate();
151+
auto covMatrixPCA = df2.calcPCACovMatrix().Array();
152+
153+
df2.propagateTracksToVertex();
154+
df2.getTrack(0).getPxPyPzGlo(pvecxic);
155+
df2.getTrack(1).getPxPyPzGlo(pvecpion);
156+
157+
auto primaryVertex = getPrimaryVertex(collision);
158+
auto covMatrixPV = primaryVertex.getCov();
159+
o2::dataformats::DCA impactParameter0;
160+
o2::dataformats::DCA impactParameter1;
161+
trackxic.propagateToDCA(primaryVertex, magneticField, &impactParameter0);
162+
trackParVarPi.propagateToDCA(primaryVertex, magneticField, &impactParameter1);
163+
164+
// get uncertainty of the decay length
165+
double phi, theta;
166+
getPointDirection(array{collision.posX(), collision.posY(), collision.posZ()}, secondaryVertexXicc, phi, theta);
167+
auto errorDecayLength = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, theta) + getRotatedCovMatrixXX(covMatrixPCA, phi, theta));
168+
auto errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.) + getRotatedCovMatrixXX(covMatrixPCA, phi, 0.));
169+
170+
int hfFlag = 1 << DecayType::XiccToXicPi;
171+
172+
rowCandidateBase(collision.globalIndex(),
173+
collision.posX(), collision.posY(), collision.posZ(),
174+
secondaryVertexXicc[0], secondaryVertexXicc[1], secondaryVertexXicc[2],
175+
errorDecayLength, errorDecayLengthXY,
176+
chi2PCA,
177+
pvecxic[0], pvecxic[1], pvecxic[2],
178+
pvecpion[0], pvecpion[1], pvecpion[2],
179+
impactParameter0.getY(), impactParameter1.getY(),
180+
std::sqrt(impactParameter0.getSigmaY2()), std::sqrt(impactParameter1.getSigmaY2()),
181+
xicCand.globalIndex(), trackpion.globalIndex(),
182+
hfFlag);
183+
// calculate invariant mass
184+
auto arrayMomenta = array{pvecxic, pvecpion};
185+
massXicc = RecoDecay::M(std::move(arrayMomenta), array{massXic, massPi});
186+
hmassXicc->Fill(massXicc);
144187
} // if on selected Xicc
145188
} // loop over candidates
146189
} // end of process
@@ -178,10 +221,26 @@ struct HFCandidateCreatorXiccMC {
178221

179222
// Match generated particles.
180223
for (auto& particle : particlesMC) {
224+
181225
//Printf("New gen. candidate");
182226
flag = 1;
183227
origin = 0;
184228
channel = 0;
229+
// Xicc → Xic + π+
230+
if (RecoDecay::isMatchedMCGen(particlesMC, particle, 4422, array{4232, +kPiPlus}, true)) {
231+
// Match Xic -> pKπ
232+
std::vector<int> arrDaughter;
233+
RecoDecay::getDaughters(particlesMC, particle, &arrDaughter, array{4232}, 1);
234+
auto XicCandMC = particlesMC.iteratorAt(arrDaughter[0]);
235+
//Printf("Checking Ξc± → p± K∓ π±");
236+
if (RecoDecay::isMatchedMCGen(particlesMC, particle, pdg::Code::kXiCPlus, array{+kProton, -kKPlus, +kPiPlus}, true, &sign)) {
237+
flag = sign * (1 << XiccToXicPi);
238+
}
239+
}
240+
// Check whether the particle is non-prompt (from a b quark).
241+
if (flag != 0) {
242+
origin = (RecoDecay::getMother(particlesMC, particle, 5, true) > -1 ? NonPrompt : Prompt);
243+
}
185244
rowMCMatchGen(flag, origin, channel);
186245
}
187246
}

0 commit comments

Comments
 (0)