18using ROOT::Math::PtEtaPhiMVector;
21 const std::string& str_lep2, PtEtaPhiMVector& p1,
22 int& pdgId1, PtEtaPhiMVector& p2,
int& pdgId2) {
31 "classifierParticleOrigin");
33 "classifierParticleType");
34 std::vector<const xAOD::TruthParticle*> Z_offshell_decay1_candidates;
35 std::vector<const xAOD::TruthParticle*> Z_offshell_decay2_candidates;
41 for (
const auto* pDecay1 : Z_offshell_decay1_candidates) {
42 for (
const auto* pDecay2 : Z_offshell_decay2_candidates) {
45 if ((pDecay1->pdgId() * pDecay2->pdgId()) > 0)
49 if (pDecay1->absPdgId() != pDecay2->absPdgId())
53 if (!acc_classifierParticleOrigin.
isAvailable(*pDecay1) ||
54 !acc_classifierParticleOrigin.
isAvailable(*pDecay2) ||
55 !acc_classifierParticleType.
isAvailable(*pDecay1) ||
58 const unsigned int o1 = acc_classifierParticleOrigin(*pDecay1);
59 const unsigned int o2 = acc_classifierParticleOrigin(*pDecay2);
60 const unsigned int t1 = acc_classifierParticleType(*pDecay1);
61 const unsigned int t2 = acc_classifierParticleType(*pDecay2);
78 pdgId1 = pDecay1->pdgId();
80 pdgId2 = pDecay2->pdgId();
89 const std::string& fsr) {
93 static constexpr std::array<const char*, 2> tauKeys{{
"MC_l_",
"MC_lbar_"}};
94 static constexpr std::array<std::array<const char*, 3>, 2> tauDecayKeys{
95 {{{
"MC_l_l_",
"MC_l_nubar_",
"MC_l_nu_"}},
96 {{
"MC_lbar_lbar_",
"MC_lbar_nu_",
"MC_lbar_nubar_"}}}};
99 for (std::size_t i = 0; i < tauKeys.size(); ++i) {
100 std::vector<const xAOD::TruthParticle*> tau_candidates;
104 tau_candidates.at(0)->pdgId(),
true};
107 std::array<std::vector<const xAOD::TruthParticle*>, 3> decay_candidates;
108 bool has_decay_candidates =
true;
109 for (std::size_t j = 0; j < decay_candidates.size(); ++j) {
110 has_decay_candidates =
111 has_decay_candidates &&
113 decay_candidates[j]);
115 if (has_decay_candidates) {
116 for (std::size_t j = 0; j < decay_candidates.size(); ++j) {
117 result.tauDecays[i][j] = {
119 decay_candidates[j].at(0)->pdgId(),
true};
128 PtEtaPhiMVector
Z, Z_decay1, Z_decay2;
129 int Z_decay1_pdgId, Z_decay2_pdgId;
130 m_dec.decorateCustom(
"MC_Z_IsOnShell", 0);
134 Z_decay1, Z_decay1_pdgId, Z_decay2, Z_decay2_pdgId);
137 Z = Z_decay1 + Z_decay2;
138 m_dec.decorateParticle(
"MC_Z_" + fsr,
Z, 23);
139 m_dec.decorateParticle(
"MC_Zdecay1_" + fsr, Z_decay1, Z_decay1_pdgId);
140 m_dec.decorateParticle(
"MC_Zdecay2_" + fsr, Z_decay2, Z_decay2_pdgId);
143 ANA_MSG_ERROR(
"Reconstruction of multiple Zs is not supported yet!");
149 const bool has_Z = decay.
taus[0].found && decay.
taus[1].found;
152 m_dec.decorateParticle(
"MC_Z_" + fsr,
153 decay.
taus[0].p4 + decay.
taus[1].p4, 23);
154 for (std::size_t i = 0; i < decay.
taus.size(); ++i) {
155 const std::string zDecay =
"MC_Zdecay" + std::to_string(i + 1);
156 m_dec.decorateParticle(zDecay +
"_" + fsr, decay.
taus[i].p4,
157 decay.
taus[i].pdgId);
158 for (std::size_t j = 0; j < decay.
tauDecays[i].size(); ++j) {
159 const std::string
name =
160 zDecay +
"_decay" + std::to_string(j + 1) +
"_" + fsr;
172 ANA_MSG_ERROR(
"Reconstruction of multiple Zs is not supported yet!");
176 const std::string& mode) {
177 std::string parentstring = parent.empty() ?
"" :
"_from_" + parent;
180 std::string mapPrefix =
181 m_prefix +
"_" +
"MC_" + (parent.empty() ?
"Z" : parent +
"_Z");
185 std::string decPrefix =
"MC_" + (parent.empty() ?
"Z" : parent +
"_Z");
187 if (mode ==
"resonant") {
190 m_dec.decorateCustom(
"MC_Z_IsOnShell", 1);
192 "MC_Z" + parentstring +
"_beforeFSR", 0);
194 "MC_Zdecay1" + parentstring +
"_beforeFSR", 0);
196 "MC_Zdecay2" + parentstring +
"_beforeFSR", 0);
198 "MC_Z" + parentstring +
"_afterFSR", 0);
200 "MC_Zdecay1" + parentstring +
"_afterFSR", 0);
202 "MC_Zdecay2" + parentstring +
"_afterFSR", 0);
204 setZ(
"beforeFSR", nZs);
205 setZ(
"afterFSR", nZs);
208 for (
int idx = 0; idx < nZs; idx++) {
209 const std::string idxStr = std::to_string(idx + 1);
210 m_dec.decorateCustom(
"MC_Z" + idxStr +
"_IsOnShell", 1);
212 "MC_Z" + idxStr + parentstring +
"_beforeFSR",
215 decPrefix +
"Decay1_beforeFSR",
216 "MC_Z" + idxStr +
"decay1" + parentstring +
"_beforeFSR", idx);
218 decPrefix +
"Decay2_beforeFSR",
219 "MC_Z" + idxStr +
"decay2" + parentstring +
"_beforeFSR", idx);
221 "MC_Z" + idxStr + parentstring +
"_afterFSR",
224 decPrefix +
"Decay1_afterFSR",
225 "MC_Z" + idxStr +
"decay1" + parentstring +
"_afterFSR", idx);
227 decPrefix +
"Decay2_afterFSR",
228 "MC_Z" + idxStr +
"decay2" + parentstring +
"_afterFSR", idx);
231 }
else if (mode ==
"non_resonant") {
232 setZ(
"beforeFSR", nZs);
233 setZ(
"afterFSR", nZs);
239 const std::string& mode) {
240 std::string parentstring = parent.empty() ?
"" :
"_from_" + parent;
242 std::string decPrefix =
"MC_" + (parent.empty() ?
"Z" : parent +
"_Z");
245 m_dec.decorateCustom(
"MC_Z_IsOnShell",
247 if (mode ==
"resonant") {
249 m_dec.decorateCustom(
"MC_Z_IsOnShell", 1);
251 decPrefix +
"Decay1_Decay1_beforeFSR",
252 "MC_Zdecay1_decay1" + parentstring +
"_beforeFSR", 0);
254 decPrefix +
"Decay1_Decay2_beforeFSR",
255 "MC_Zdecay1_decay2" + parentstring +
"_beforeFSR", 0);
257 decPrefix +
"Decay1_Decay3_beforeFSR",
258 "MC_Zdecay1_decay3" + parentstring +
"_beforeFSR", 0);
260 "MC_Zdecay1_decay1" + parentstring +
"_afterFSR",
263 "MC_Zdecay1_decay2" + parentstring +
"_afterFSR",
266 "MC_Zdecay1_decay3" + parentstring +
"_afterFSR",
269 for (
int idx = 0; idx < nZs; idx++) {
270 const std::string idxStr = std::to_string(idx + 1);
271 m_dec.decorateCustom(
"MC_Z" + idxStr +
"_IsOnShell", 1);
273 decPrefix +
"Decay1_Decay1_beforeFSR",
274 "MC_Z" + idxStr +
"decay1_decay1" + parentstring +
"_beforeFSR",
277 decPrefix +
"Decay1_Decay2_beforeFSR",
278 "MC_Z" + idxStr +
"decay1_decay2" + parentstring +
"_beforeFSR",
281 decPrefix +
"Decay1_Decay3_beforeFSR",
282 "MC_Z" + idxStr +
"decay1_decay3" + parentstring +
"_beforeFSR",
285 decPrefix +
"Decay1_Decay1_afterFSR",
286 "MC_Z" + idxStr +
"decay1_decay1" + parentstring +
"_afterFSR",
289 decPrefix +
"Decay1_Decay2_afterFSR",
290 "MC_Z" + idxStr +
"decay1_decay2" + parentstring +
"_afterFSR",
293 decPrefix +
"Decay1_Decay3_afterFSR",
294 "MC_Z" + idxStr +
"decay1_decay3" + parentstring +
"_afterFSR",
298 }
else if (mode ==
"non_resonant") {
Helper class to provide constant type-safe access to aux data.
ROOT::Math::PtEtaPhiMVector GetPtEtaPhiMfromTruth(const xAOD::TruthParticle *TruthParticle)
bool getZ(const std::string &str_lep1, const std::string &str_lep2, PtEtaPhiMVector &p1, int &pdgId1, PtEtaPhiMVector &p2, int &pdgId2)
bool RetrieveParticleInfo(const std::string &prefix, std::vector< const xAOD::TruthParticle * > &particles)
Gaudi::Property< std::string > m_prefix
void setZ(const std::string &fsr, int nZs)
bool ExistsInMap(const std::string &key) const
void FillZtautauPartonHistory(const std::string &parent, int nZs=1, const std::string &mode="resonant")
void FillZPartonHistory(const std::string &parent, int nZs=1, const std::string &mode="resonant")
void FillGenericPartonHistory(const std::string &retrievalstring, const std::string &decorationstring, const int idx)
ZTauTauDecay getZFromTaus(const std::string &fsr)
void setZtautau(const std::string &fsr, int nZs)
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Select isolated Photons, Electrons and Muons.
Z->tautau decay chain: taus[0] = tau- (Zdecay1), taus[1] = tau+ (Zdecay2); tauDecays[i][j] = decay pr...
std::array< ZTauTauProduct, 2 > taus
std::array< std::array< ZTauTauProduct, 3 >, 2 > tauDecays
One Z->tautau decay product: kinematics, PDG ID and whether it was found.