ATLAS Offline Software
CalcTtbarGammaPartonHistory.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3  */
4 
8 
10 
11 namespace top {
14 
16  xAOD::PartonHistory* ttbarGammaPartonHistory) {
17  ttbarGammaPartonHistory->IniVarTtGamma();
18  TLorentzVector ph_t;
19  bool has_ph_t;
20  int branchtype_t = -1;
21  int branchtype_tbar = -1;
36  int init_type = -1;
42  TLorentzVector t_before, t_after;
43  TLorentzVector Wp;
44  TLorentzVector b;
45  TLorentzVector WpDecay1;
46  TLorentzVector WpDecay2;
47  int WpDecay1_pdgId;
48  int WpDecay2_pdgId;
49  bool missTop;
50  bool missTbar;
51  bool event_top = CalcTopPartonHistory::topPhWb(truthParticles, 6, t_before, t_after, ph_t, Wp, b, WpDecay1,
52  WpDecay1_pdgId, WpDecay2, WpDecay2_pdgId, has_ph_t, branchtype_t,
53  init_type, missTbar);
54 
55  TLorentzVector ph_tbar;
56  bool has_ph_tbar;
57  TLorentzVector tbar_before, tbar_after;
58  TLorentzVector Wm;
59  TLorentzVector bbar;
60  TLorentzVector WmDecay1;
61  TLorentzVector WmDecay2;
62  int WmDecay1_pdgId;
63  int WmDecay2_pdgId;
64  bool event_topbar = CalcTopPartonHistory::topPhWb(truthParticles, -6, tbar_before, tbar_after, ph_tbar, Wm, bbar,
65  WmDecay1, WmDecay1_pdgId, WmDecay2, WmDecay2_pdgId, has_ph_tbar,
66  branchtype_tbar, init_type, missTop);
67 
68  if (event_top && missTbar && has_ph_t && branchtype_t != 10 && branchtype_t != 50 && branchtype_t != 15 &&
69  branchtype_t != 55) {
70  bool Wonshell = false;
71  for (const xAOD::TruthParticle* particle : *truthParticles) {
72  if (HepMC::barcode(particle) != 3) continue; // FIXME barcode-based - comparison against a specific value
73  for (size_t q = 0; q < particle->nChildren(); q++) {
74  if (particle->child(q) && particle->child(q)->pdgId() == -5) bbar =PartonHistoryUtils::findAfterFSR(particle->child(
75  q))->
76  p4();
77  if (particle->child(q) && particle->child(q)->pdgId() == -24) {
78  Wm = particle->child(q)->p4();
79  Wonshell = true;
80  for (size_t Wc = 0; Wc < particle->child(q)->nChildren(); Wc++) {
81  if (particle->child(q)->child(Wc)->pdgId() > 0) {
82  WmDecay1 = PartonHistoryUtils::findAfterFSR(particle->child(q)->child(Wc))->p4();
83  WmDecay1_pdgId = particle->child(q)->child(Wc)->pdgId();
84  }
85  if (particle->child(q)->child(Wc)->pdgId() < 0) {
86  WmDecay2 = PartonHistoryUtils::findAfterFSR(particle->child(q)->child(Wc))->p4();
87  WmDecay2_pdgId = particle->child(q)->child(Wc)->pdgId();
88  }
89  }
90  }
91  if (!Wonshell) {
92  if (particle->child(q) && particle->child(q)->pdgId() != 6 && particle->child(q)->pdgId() != 22 &&
93  particle->child(q)->pdgId() > 0) {
94  WmDecay1 = PartonHistoryUtils::findAfterFSR(particle->child(q))->p4();
95  WmDecay1_pdgId = particle->child(q)->pdgId();
96  }
97  if (particle->child(q) && particle->child(q)->pdgId() != -6 && particle->child(q)->pdgId() != 22 &&
98  particle->child(q)->pdgId() < 0) {
99  WmDecay2 = PartonHistoryUtils::findAfterFSR(particle->child(q))->p4();
100  WmDecay2_pdgId = particle->child(q)->pdgId();
101  }
102  Wm = WmDecay1 + WmDecay2;
103  }
104  }
105  if (WmDecay1_pdgId >= 1 && WmDecay1_pdgId <= 4) branchtype_tbar = 50;
106  else if (WmDecay1_pdgId >= 11 && WmDecay1_pdgId <= 16) branchtype_tbar = 10;
107 
108  if (branchtype_tbar == 50 || branchtype_tbar == 10) {
109  event_topbar = true;
110  has_ph_tbar = false;
111  }
112  }
113  } else if (event_topbar && missTop && has_ph_tbar && branchtype_tbar != 10 && branchtype_tbar != 50 &&
114  branchtype_tbar != 15 && branchtype_tbar != 55) {
115  bool Wonshell = false;
116  for (const xAOD::TruthParticle* particle : *truthParticles) {
117  if (HepMC::barcode(particle) != 3) continue; // FIXME barcode-based - comparison against a specific value
118  for (size_t q = 0; q < particle->nChildren(); q++) {
119  if (particle->child(q) && particle->child(q)->pdgId() == 5) b = PartonHistoryUtils::findAfterFSR(particle->child(
120  q))->p4();
121 
122  if (particle->child(q) && particle->child(q)->pdgId() == 24) {
123  Wp = particle->child(q)->p4();
124  Wonshell = true;
125  for (size_t Wc = 0; Wc < particle->child(q)->nChildren(); Wc++) {
126  if (particle->child(q)->child(Wc)->pdgId() > 0) {
127  WmDecay1 = PartonHistoryUtils::findAfterFSR(particle->child(q)->child(Wc))->p4();
128  WmDecay1_pdgId = particle->child(q)->child(Wc)->pdgId();
129  }
130  if (particle->child(q)->child(Wc)->pdgId() < 0) {
131  WmDecay2 = PartonHistoryUtils::findAfterFSR(particle->child(q)->child(Wc))->p4();
132  WmDecay2_pdgId = particle->child(q)->child(Wc)->pdgId();
133  }
134  }
135  }
136  if (!Wonshell) {
137  if (particle->child(q) && particle->child(q)->pdgId() != 6 && particle->child(q)->pdgId() != 22 &&
138  particle->child(q)->pdgId() > 0) {
139  WmDecay1 = PartonHistoryUtils::findAfterFSR(particle->child(q))->p4();
140  WmDecay1_pdgId = particle->child(q)->pdgId();
141  }
142  if (particle->child(q) && particle->child(q)->pdgId() != -6 && particle->child(q)->pdgId() != 22 &&
143  particle->child(q)->pdgId() < 0) {
144  WmDecay2 = PartonHistoryUtils::findAfterFSR(particle->child(q))->p4();
145  WmDecay2_pdgId = particle->child(q)->pdgId();
146  }
147  Wp = WpDecay1 + WpDecay2;
148  }
149  }
150  if (abs(WmDecay1_pdgId) >= 1 && abs(WmDecay1_pdgId) <= 4) branchtype_t = 50;
151  else if (abs(WmDecay1_pdgId) >= 11 && abs(WmDecay1_pdgId) <= 16) branchtype_t = 10;
152  if (branchtype_t == 50 || branchtype_t == 10) {
153  event_top = true;
154  has_ph_t = false;
155  }
156  }
157  }
158 
159  TLorentzVector ph;
160  int ph_source = -1;
167  int category = -2;
185 
186  if ((event_top && !event_topbar) || (!event_top && event_topbar) || (!event_top && !event_topbar)) {// missing top
187  for (const xAOD::TruthParticle* particle : *truthParticles) {
188  if (HepMC::barcode(particle) != 3) continue; // FIXME barcode-based - comparison against a specific value
189  if (abs(particle->pdgId()) == 21) init_type = 1; //gg
190  else if (abs(particle->pdgId()) < 6) init_type = 2; //qq
191  }
192  category = 0;
193  ph_source = 3;
194  branchtype_t = 0;
195  branchtype_tbar = 0;
196  ttbarGammaPartonHistory->auxdecor< int >("MC_branchtype_t") = branchtype_t;
197  ttbarGammaPartonHistory->auxdecor< int >("MC_branchtype_tbar") = branchtype_tbar;
198  ttbarGammaPartonHistory->auxdecor< int >("MC_initial_parton") = init_type;
199  ttbarGammaPartonHistory->auxdecor< int >("MC_Event_Category") = category;
200  ttbarGammaPartonHistory->auxdecor< int >("MC_ph_from_t_tbar") = ph_source;
201  }// one of the top is virtual
202  else if (event_top && event_topbar) { // && (has_ph_t || has_ph_tbar)
203  if (has_ph_t && has_ph_tbar) {// isr should give the same photon to both tops
204  if (ph_t.Pt() > ph_tbar.Pt()) {
205  ph = ph_t;
206  }// FOR EXTRA SAFETY
207  else {
208  ph = ph_tbar;
209  }
210  ph_source = 0; // isr
211  } else if (has_ph_t) {
212  ph = ph_t;
213  ph_source = 1;
214  }// top
215  else if (has_ph_tbar) {
216  ph = ph_tbar;
217  ph_source = 2;
218  }// antitop
219  else if (!has_ph_t && !has_ph_tbar) {
220  ph_source = -1;
221  }
222 
223  // determination of event category
224  // ISR
225  if (ph_source == 0) {
226  if (init_type == 2) {
227  category = 1;
228  if (branchtype_t == 15 && branchtype_tbar == 15) {
229  category = 9;
230  } // ISR_qq_DL
231  } //ISR_qq
232  else if (init_type == 1) {
233  category = 2;
234  if (branchtype_t == 15 && branchtype_tbar == 15) {
235  category = 10;
236  } // ISR_gg_DL
237  } //ISR_gg/top
238  } else if (ph_source == 1 || ph_source == 2) {
239  if ((branchtype_t == 12 && branchtype_tbar == 50) || (branchtype_t == 50 && branchtype_tbar == 12)) {
240  category = 3;
241  }// top Radiation leptonic
242  else if ((branchtype_t == 52 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 52)) {
243  category = 4;
244  }// top Radiation hadronic
245  else if ((branchtype_t == 14 && branchtype_tbar == 50) || (branchtype_t == 50 && branchtype_tbar == 14)) {
246  category = 5;
247  }// W Radiation leptonic
248  else if ((branchtype_t == 54 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 54)) {
249  category = 6;
250  }// W Radiation hadronic
251  else if ((branchtype_t == 18 && branchtype_tbar == 50) || (branchtype_t == 50 && branchtype_tbar == 18)) {
252  category = 7;
253  }// b Radiation leptonic
254  else if ((branchtype_t == 58 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 58)) {
255  category = 8;
256  }// b Radiation hadronic
257  else if ((branchtype_t == 12 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 12)) {
258  category = 11;
259  }// Top Radiation dileptonic
260  else if ((branchtype_t == 14 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 14)) {
261  category = 12;
262  }// W Radiation dileptonic
263  else if ((branchtype_t == 18 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 18)) {
264  category = 13;
265  }// W Radiation dileptonic
266  else if (branchtype_t == 1 || branchtype_tbar == 1) {
267  category = -1;
268  }// missing W
269  else {
270  category = 0;
271  }// missing top
272  } else if (ph_source == -1) {
273  category = -2;
274  } // undefined
275 
276 //------------------------------------------------------------------------------------------
277 
278  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_ph", ph);
279  fillEtaBranch(ttbarGammaPartonHistory, "MC_ph_eta", ph);
280 
281  ttbarGammaPartonHistory->auxdecor< int >("MC_branchtype_t") = branchtype_t;
282  ttbarGammaPartonHistory->auxdecor< int >("MC_branchtype_tbar") = branchtype_tbar;
283  ttbarGammaPartonHistory->auxdecor< int >("MC_initial_parton") = init_type;
284  ttbarGammaPartonHistory->auxdecor< int >("MC_ph_from_t_tbar") = ph_source;
285  ttbarGammaPartonHistory->auxdecor< int >("MC_Event_Category") = category;
286 //------------------------------------------------------------------------------------------
287 
288  TLorentzVector temp = t_before + tbar_before;
289  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_ttbar_beforeFSR", temp);
290  fillEtaBranch(ttbarGammaPartonHistory, "MC_ttbar_beforeFSR_eta", temp);
291 
292  temp = WmDecay1 + WmDecay2 + b + WpDecay1 + WpDecay2 + bbar + ph;
293  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_ttbar_afterFSR", temp);
294  fillEtaBranch(ttbarGammaPartonHistory, "MC_ttbar_afterFSR_eta", temp);
295  }
296 
297 //------------------------------------------------------------------------------------------
298  if (event_top) {
299  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_t_beforeFSR", t_before);
300  fillEtaBranch(ttbarGammaPartonHistory, "MC_t_beforeFSR_eta", t_before);
301 
302  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_t_afterFSR", t_after);
303  fillEtaBranch(ttbarGammaPartonHistory, "MC_t_afterFSR_eta", t_after);
304 
305  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_W_from_t", Wp);
306  fillEtaBranch(ttbarGammaPartonHistory, "MC_W_from_t_eta", Wp);
307 
308  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_b_from_t", b);
309  fillEtaBranch(ttbarGammaPartonHistory, "MC_b_from_t_eta", b);
310 
311  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_Wdecay1_from_t", WpDecay1);
312  ttbarGammaPartonHistory->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = WpDecay1_pdgId;
313  fillEtaBranch(ttbarGammaPartonHistory, "MC_Wdecay1_from_t_eta", WpDecay1);
314 
315  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_Wdecay2_from_t", WpDecay2);
316  ttbarGammaPartonHistory->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = WpDecay2_pdgId;
317  fillEtaBranch(ttbarGammaPartonHistory, "MC_Wdecay2_from_t_eta", WpDecay2);
318  }
319 
320 
321 //-------------------------------------------------------------------------------------------
322  if (event_topbar) {
323  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_tbar_beforeFSR", tbar_before);
324  fillEtaBranch(ttbarGammaPartonHistory, "MC_tbar_beforeFSR_eta", tbar_before);
325 
326  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_tbar_afterFSR", tbar_after);
327  fillEtaBranch(ttbarGammaPartonHistory, "MC_tbar_afterFSR_eta", tbar_after);
328 
329  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_W_from_tbar", Wm);
330  fillEtaBranch(ttbarGammaPartonHistory, "MC_W_from_tbar_eta", Wm);
331 
332  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_b_from_tbar", bbar);
333  fillEtaBranch(ttbarGammaPartonHistory, "MC_b_from_tbar_eta", bbar);
334 
335  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_Wdecay1_from_tbar", WmDecay1);
336  ttbarGammaPartonHistory->auxdecor< int >("MC_Wdecay1_from_tbar_pdgId") = WmDecay1_pdgId;
337  fillEtaBranch(ttbarGammaPartonHistory, "MC_Wdecay1_from_tbar_eta", WmDecay1);
338 
339  decorateWithMPtPhi(ttbarGammaPartonHistory,"MC_Wdecay2_from_tbar", WmDecay2);
340  ttbarGammaPartonHistory->auxdecor< int >("MC_Wdecay2_from_tbar_pdgId") = WmDecay2_pdgId;
341  fillEtaBranch(ttbarGammaPartonHistory, "MC_Wdecay2_from_tbar_eta", WmDecay2);
342  }
343  }
344 
346  // Get the Truth Particles
347  const xAOD::TruthParticleContainer* truthParticles(nullptr);
348 
349  if(m_config->getDerivationStream() == "PHYS") //in DAOD_PHYS we don't have the truth particles container
350  {
351  // To obtain both tops and the phpton, we need the collections for both
352  std::vector<std::string> collections = {"TruthTop", "TruthBosonsWithDecayParticles", "HardScatterParticles"};
353  ATH_CHECK(buildContainerFromMultipleCollections(collections,"AT_TtbarGammaPartonHistory_TruthParticles"));
354  ATH_CHECK(evtStore()->retrieve(truthParticles, "AT_TtbarGammaPartonHistory_TruthParticles"));
355 
356  //we need to be able to navigate from the Ws to their decayProducts, see CalcTopPartonHistory.h for details
358  }
359  else //otherwise we retrieve the container as usual
360  {
361  ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle()));
362  }
363 
364  // Create the partonHistory xAOD object
365  std::unique_ptr<xAOD::PartonHistoryAuxContainer> partonAuxCont(new xAOD::PartonHistoryAuxContainer());
366  std::unique_ptr<xAOD::PartonHistoryContainer> partonCont(new xAOD::PartonHistoryContainer());
367  partonCont->setStore(partonAuxCont.release());
368  //cppcheck-suppress uninitvar
369  xAOD::PartonHistory* ttbarGammaPartonHistory = new xAOD::PartonHistory {};
370  partonCont->push_back(ttbarGammaPartonHistory);
371 
372  // Recover the parton history for ttbargamma events
373  ttbarGammaHistorySaver(truthParticles, ttbarGammaPartonHistory);
374 
375  // Save to StoreGate / TStore
376  std::string outputSGKey = m_config->sgKeyTopPartonHistory();
377  std::string outputSGKeyAux = outputSGKey + "Aux.";
378 
379  StatusCode save = evtStore()->tds()->record(partonCont.release(), outputSGKey);
380  StatusCode saveAux = evtStore()->tds()->record(partonAuxCont.release(), outputSGKeyAux);
381  if (!save || !saveAux) {
382  return StatusCode::FAILURE;
383  }
384 
385  return StatusCode::SUCCESS;
386  }
387 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::PartonHistory
Interface class.
Definition: PartonHistory.h:48
top::CalcTopPartonHistory::buildContainerFromMultipleCollections
StatusCode buildContainerFromMultipleCollections(const std::vector< std::string > &collections, const std::string &out_contName)
used to build container from multiple collections in DAOD_PHYS we don't have the TruthParticles colle...
Definition: CalcTopPartonHistory.cxx:21
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
top::CalcTopPartonHistory::topPhWb
bool topPhWb(const xAOD::TruthParticleContainer *truthParticles, int topId, TLorentzVector &t_beforeFSR_p4, TLorentzVector &t_afterFSR_p4, TLorentzVector &Ph_p4, TLorentzVector &W_p4, TLorentzVector &b_p4, TLorentzVector &Wdecay1_p4, int &Wdecay1_pdgId, TLorentzVector &Wdecay2_p4, int &Wdecay2_pdgId, bool &has_ph, int &BranchType, int &IniPartonType, bool &missingTop)
Store the four-momentum of photon coming from virtual top in ttgamma events.
Definition: CalcTopPartonHistory.cxx:448
top
TopConfig A simple configuration that is NOT a singleton.
Definition: AnalysisTrackingHelper.cxx:58
top::CalcTopPartonHistory::linkBosonCollections
StatusCode linkBosonCollections()
currently in DAOD_PHYS TruthTop have links to Ws from the TruthBoson collection, which have no link t...
Definition: CalcTopPartonHistory.cxx:39
top::CalcTtbarGammaPartonHistory::ttbarGammaHistorySaver
void ttbarGammaHistorySaver(const xAOD::TruthParticleContainer *truthParticles, xAOD::PartonHistory *ttbarGammaPartonHistory)
Definition: CalcTtbarGammaPartonHistory.cxx:15
CalcTtbarGammaPartonHistory.h
SG::AuxElement::auxdecor
Decorator< T, ALLOC >::reference_type auxdecor(const std::string &name) const
Fetch an aux decoration, as a non-const reference.
top::CalcTopPartonHistory::m_config
std::shared_ptr< top::TopConfig > m_config
Definition: CalcTopPartonHistory.h:87
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
checkTP.save
def save(self, fileName="./columbo.out")
Definition: checkTP.py:178
top::CalcTopPartonHistory::b
bool b(const xAOD::TruthParticleContainer *truthParticles, TLorentzVector &b_beforeFSR, TLorentzVector &b_afterFSR)
Store the four-momentum of b (not from tops_ before and after FSR.
Definition: CalcTopPartonHistory.cxx:156
top::PartonHistoryUtils::findAfterFSR
const xAOD::TruthParticle * findAfterFSR(const xAOD::TruthParticle *particle)
Return particle after FSR (before the decay vertex)
Definition: PartonHistoryUtils.cxx:8
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ReweightUtils.category
category
Definition: ReweightUtils.py:15
HepMC::barcode
int barcode(const T *p)
Definition: Barcode.h:16
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:41
xAOD::PartonHistory::IniVarTtGamma
void IniVarTtGamma()
Definition: PartonHistory.cxx:374
PartonHistoryUtils.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
top::CalcTtbarGammaPartonHistory::CalcTtbarGammaPartonHistory
CalcTtbarGammaPartonHistory(const std::string &name)
Definition: CalcTtbarGammaPartonHistory.cxx:13
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
MagicNumbers.h
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
TopConfig.h
top::CalcTtbarGammaPartonHistory::execute
virtual StatusCode execute()
Definition: CalcTtbarGammaPartonHistory.cxx:345
top::CalcTopPartonHistory
Definition: CalcTopPartonHistory.h:39
xAOD::PartonHistoryAuxContainer
Aux Container.
Definition: PartonHistory.h:41
extractSporadic.q
list q
Definition: extractSporadic.py:98
xAOD::TruthParticle_v1::p4
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
Definition: TruthParticle_v1.cxx:196
top::CalcTopPartonHistory::fillEtaBranch
void fillEtaBranch(xAOD::PartonHistory *partonHistory, std::string branchName, TLorentzVector &tlv)
Definition: CalcTopPartonHistory.cxx:692
top::PartonHistoryUtils::decorateWithMPtPhi
void decorateWithMPtPhi(xAOD::PartonHistory *pHistory, const std::string &prefix, const TLorentzVector &vec)
Perform decoration M, Pt, Phi of the history from a TLorentzVector.
Definition: PartonHistoryUtils.cxx:187