JHUGen MELA  JHUGen v7.5.6, MELA v2.4.2
Matrix element calculations as used in JHUGen.
MELACandidate.cc
Go to the documentation of this file.
1 #include "MELACandidate.h"
2 #include "TUtilHelpers.hh"
3 #include "MELAStreamHelpers.hh"
4 #include "TMath.h"
5 
6 
9 using namespace PDGHelpers;
10 
11 
13 MELAParticle(),
14 associatedByHighestPt(false),
15 isShallowCopy(false),
16 selfDecayMode(TVar::CandidateDecay_Stable)
17 {}
18 MELACandidate::MELACandidate(int id_, bool associatedByHighestPt_) :
19 MELAParticle(id_),
20 associatedByHighestPt(associatedByHighestPt_),
21 isShallowCopy(false),
22 selfDecayMode(TVar::CandidateDecay_Stable)
23 {}
24 MELACandidate::MELACandidate(int id_, TLorentzVector p4_, bool associatedByHighestPt_) :
25 MELAParticle(id_, p4_),
26 associatedByHighestPt(associatedByHighestPt_),
27 isShallowCopy(false),
28 selfDecayMode(TVar::CandidateDecay_Stable)
29 {}
31 MELAParticle(particle_),
32 associatedByHighestPt(particle_.associatedByHighestPt),
33 isShallowCopy(false),
34 selfDecayMode(particle_.selfDecayMode),
35 associatedLeptons(particle_.associatedLeptons),
36 associatedNeutrinos(particle_.associatedNeutrinos),
37 associatedPhotons(particle_.associatedPhotons),
38 associatedJets(particle_.associatedJets),
39 associatedTops(particle_.associatedTops),
40 sortedDaughters(particle_.sortedDaughters)
41 {
42  // Recreate the intermediate Vs since mother info needs to be reset
45 }
47  MELACandidate tmp(particle_);
48  swap(tmp);
49  return *this;
50 }
52  resetVs();
53  sortedDaughters.clear();
54  associatedTops.clear();
55  associatedJets.clear();
56  associatedLeptons.clear();
57  associatedNeutrinos.clear();
58  associatedPhotons.clear();
59 }
60 
63 
64  // Copy particle content
66  cand->setGenStatus(genStatus);
67  cand->setLifetime(lifetime);
68 
71 
72  // Copy candidate content
73  cand->setShallowCopy(true);
81 
82  return cand;
83 }
85  MELAParticle::swap(particle_);
86  std::swap(associatedByHighestPt, particle_.associatedByHighestPt);
87  std::swap(isShallowCopy, particle_.isShallowCopy);
88  std::swap(selfDecayMode, particle_.selfDecayMode);
89  std::swap(associatedLeptons, particle_.associatedLeptons);
90  std::swap(associatedNeutrinos, particle_.associatedNeutrinos);
91  std::swap(associatedPhotons, particle_.associatedPhotons);
92  std::swap(associatedJets, particle_.associatedJets);
93  std::swap(associatedTops, particle_.associatedTops);
94  std::swap(sortedDaughters, particle_.sortedDaughters);
95  std::swap(sortedVs, particle_.sortedVs);
96 }
97 
99  if (!isShallowCopy){ // Delete owned objects if not a shallow copy
100  for (MELAParticle*& aV:sortedVs) delete aV;
101  }
102  sortedVs.clear();
103  isShallowCopy=false; // Should delete sortedVs now
104 }
106  resetVs();
107  createSortedVs();
108  addAssociatedVs();
109 }
110 
111 
113 void MELACandidate::setAddAssociatedByHighestPt(bool associatedByHighestPt_){ associatedByHighestPt=associatedByHighestPt_; }
116 
119  if (debugVars::debugFlag) MELAout << "Starting MELACandidate::sortDaughters with self decay mode " << selfDecayMode << std::endl;
120  if (debugVars::debugFlag) MELAout << "Starting MELACandidate::sortDaughtersInitial" << std::endl;
122  if (debugVars::debugFlag) MELAout << "Starting MELACandidate::sortDaughtersByBestZ1" << std::endl;
124  if (debugVars::debugFlag) MELAout << "Starting MELACandidate::createSortedVs" << std::endl;
125  createSortedVs();
126 }
127 
128 std::vector<int> MELACandidate::getDaughterIds()const{
129  std::vector<int> result;
130  for (MELAParticle const* const& dau:sortedDaughters){
131  if (dau) result.push_back(dau->id);
132  }
133  return result;
134 }
136  std::vector<int> result;
137  std::vector<std::vector<MELAParticle*> const*> list; list.reserve(3);
138  list.push_back(&associatedLeptons);
139  list.push_back(&associatedPhotons);
140  list.push_back(&associatedJets);
141  for (std::vector<MELAParticle*> const*& ll:list){
142  for (MELAParticle* const& part:(*ll)){
143  if (part) result.push_back(part->id);
144  }
145  }
146  return result;
147 }
149  if ((int)sortedDaughters.size()>index) return sortedDaughters.at(index);
150  else return 0;
151 }
153  if ((int)sortedVs.size()>index) return sortedVs.at(index);
154  else return 0;
155 }
157  if ((int)associatedLeptons.size()>index) return associatedLeptons.at(index);
158  else return 0;
159 }
161  if ((int)associatedNeutrinos.size()>index) return associatedNeutrinos.at(index);
162  else return 0;
163 }
165  if ((int)associatedPhotons.size()>index) return associatedPhotons.at(index);
166  else return 0;
167 }
169  if ((int)associatedJets.size()>index) return associatedJets.at(index);
170  else return 0;
171 }
173  if ((int)associatedTops.size()>index) return associatedTops.at(index);
174  else return 0;
175 }
176 
177 std::vector<MELAParticle*>& MELACandidate::getSortedDaughters(){ return sortedDaughters; }
178 std::vector<MELAParticle*>& MELACandidate::getSortedVs(){ return sortedVs; }
179 std::vector<MELAParticle*>& MELACandidate::getAssociatedLeptons(){ return associatedLeptons; }
180 std::vector<MELAParticle*>& MELACandidate::getAssociatedNeutrinos(){ return associatedNeutrinos; }
181 std::vector<MELAParticle*>& MELACandidate::getAssociatedPhotons(){ return associatedPhotons; }
182 std::vector<MELAParticle*>& MELACandidate::getAssociatedJets(){ return associatedJets; }
183 std::vector<MELATopCandidate_t*>& MELACandidate::getAssociatedTops(){ return associatedTops; }
184 
185 const std::vector<MELAParticle*>& MELACandidate::getSortedDaughters()const{ return sortedDaughters; }
186 const std::vector<MELAParticle*>& MELACandidate::getSortedVs()const{ return sortedVs; }
187 const std::vector<MELAParticle*>& MELACandidate::getAssociatedLeptons()const{ return associatedLeptons; }
188 const std::vector<MELAParticle*>& MELACandidate::getAssociatedNeutrinos()const{ return associatedNeutrinos; }
189 const std::vector<MELAParticle*>& MELACandidate::getAssociatedPhotons()const{ return associatedPhotons; }
190 const std::vector<MELAParticle*>& MELACandidate::getAssociatedJets()const{ return associatedJets; }
191 const std::vector<MELATopCandidate_t*>& MELACandidate::getAssociatedTops()const{ return associatedTops; }
192 
193 std::vector<MELAParticle*> MELACandidate::getAssociatedSortedVs(){
194  std::vector<MELAParticle*> res;
195  std::vector<MELAParticle*>::iterator itEnd=sortedVs.end();
196  std::vector<MELAParticle*>::iterator itBegin=itEnd;
197  for (std::vector<MELAParticle*>::iterator it=sortedVs.begin(); it!=itEnd; it++){
198  bool doSkip=false;
199  for (auto const& dau:sortedDaughters){ if ((*it)->hasDaughter(dau)){ doSkip=true; break; } }
200  if (!doSkip){ itBegin=it; break; }
201  }
202  if (itBegin!=itEnd) std::copy(itBegin, itEnd, std::back_inserter(res));
203  return res;
204 }
205 std::vector<MELAParticle*> MELACandidate::getAssociatedSortedVs()const{
206  std::vector<MELAParticle*> res;
207  std::vector<MELAParticle*>::const_iterator itEnd=sortedVs.cend();
208  std::vector<MELAParticle*>::const_iterator itBegin=itEnd;
209  for (std::vector<MELAParticle*>::const_iterator it=sortedVs.cbegin(); it!=itEnd; it++){
210  bool doSkip=false;
211  for (auto const& dau:sortedDaughters){ if ((*it)->hasDaughter(dau)){ doSkip=true; break; } }
212  if (!doSkip){ itBegin=it; break; }
213  }
214  if (itBegin!=itEnd) std::copy(itBegin, itEnd, std::back_inserter(res));
215  return res;
216 }
217 
219  bool beginWithIdPair = (
225  );
227  int nDaughtersBooked=0;
228  int tmpDindex[2]={ 0 };
229  MELAParticle* df[2] ={ getDaughter(0), 0 };
230  if (df[0]!=0) nDaughtersBooked++;
231  for (int j=1; j<getNDaughters(); j++){
232  MELAParticle* dtmp = getDaughter(j);
233  if (
234  (beginWithIdPair && std::abs(dtmp->charge())-std::abs(df[0]->charge())==0 && std::abs(dtmp->id)==std::abs(df[0]->id)) // First daughter in ZZ/ZW/ZG/GG/ff requires identical |Q| and |id|.
235  ||
236  ( // First daughter in WW/WG requires a pair with |sum(Q)|=1 and opposite id signs, or two unknown jets.
237  beginWithWPair
238  &&
239  (
240  (std::abs(dtmp->charge()+df[0]->charge())==1 && TMath::Sign(1, dtmp->id)==-TMath::Sign(1, df[0]->id))
241  ||
243  )
244  )
245  ){
246  df[1] = dtmp;
247  tmpDindex[1] = j;
248  nDaughtersBooked++;
249  break;
250  }
251  }
252  MELAParticle* ds[2] ={ 0 };
253  int sindex=0;
254  for (int j=1; j<getNDaughters(); j++){
255  if (j==tmpDindex[1]) continue;
256  MELAParticle* dtmp = getDaughter(j);
257  ds[sindex] = dtmp;
258  nDaughtersBooked++;
259  sindex++;
260  if (sindex==2) break;
261  }
262 
263  if (nDaughtersBooked!=getNDaughters()){
264  if (getNDaughters()>4) MELAout << "MELACandidate::sortDaughtersInitial: Number of daughters passed " << getNDaughters() << ">4 is currently not supported." << std::endl;
265  MELAout << "MELACandidate::sortDaughtersInitial: Number of daughters passed (" << getNDaughters() << ") is not the same as number of daughters booked (" << nDaughtersBooked << ")! Aborting, no daughters can be recorded." << std::endl;
266  for (int idau=0; idau<getNDaughters(); idau++){
267  MELAParticle* part = getDaughter(idau);
268  if (part!=0) MELAout << "\t- Passed daughter " << idau << " (X, Y, Z, T, M, Id) = "
269  << part->x() << " " << part->y() << " " << part->z() << " " << part->t() << " " << part->m() << " " << part->id << std::endl;
270  else MELAout << "\t- Passed daughter " << idau << " = 0!" << std::endl;
271  }
272  for (unsigned int j=0; j<2; j++){ if (df[j]!=0) MELAout << "\t- df[" << j << "] (X, Y, Z, T, M, Id) = " << df[j]->x() << " " << df[j]->y() << " " << df[j]->z() << " " << df[j]->t() << " " << df[j]->m() << " " << df[j]->id << std::endl; }
273  for (unsigned int j=0; j<2; j++){ if (ds[j]!=0) MELAout << "\t- ds[" << j << "] (X, Y, Z, T, M, Id) = " << ds[j]->x() << " " << ds[j]->y() << " " << ds[j]->z() << " " << ds[j]->t() << " " << ds[j]->m() << " " << ds[j]->id << std::endl; }
274  return;
275  }
276 
277  if (
278  (df[0]!=0 && df[1]!=0)
279  &&
280  (
281  // Order by ubar(0)v(1)
282  (df[0]->id<df[1]->id && beginWithIdPair)
283  ||
284  (df[0]->id<df[1]->id && df[0]->id<0 && beginWithWPair)
285  ||
286  ((df[0]->id*df[1]->id>0 || (df[0]->id==0 && df[1]->id==0)) && df[0]->phi()<df[1]->phi())
287  )
288  ){
289  MELAParticle* dtmp = df[0];
290  df[0] = df[1];
291  df[1] = dtmp;
292  }
293 
294  if (
295  (ds[0]!=0 && ds[1]!=0)
296  &&
297  (
298  // Order by ubar(0)v(1)
299  (ds[0]->id<ds[1]->id && beginWithIdPair)
300  ||
301  (ds[0]->id<ds[1]->id && ds[0]->id<0 && beginWithWPair)
302  ||
303  ((ds[0]->id*ds[1]->id>0 || (ds[0]->id==0 && ds[1]->id==0)) && ds[0]->phi()<ds[1]->phi())
304  )
305  ){
306  MELAParticle* dtmp = ds[0];
307  ds[0] = ds[1];
308  ds[1] = dtmp;
309  }
310  if (df[1]==0 && df[0]!=0 && ds[0]!=0 && ds[1]!=0){ // Swap GZ to ZG
311  for (int ip=0; ip<2; ip++){
312  MELAParticle* dtmp = ds[ip];
313  ds[ip] = df[ip];
314  df[ip] = dtmp;
315  }
316  }
317  for (int i=0; i<2; i++){
318  if (df[i]!=0) sortedDaughters.push_back(df[i]);
319  }
320  for (int i=0; i<2; i++){
321  if (ds[i]!=0) sortedDaughters.push_back(ds[i]);
322  }
323 }
325  bool beginWithZPair = (
329  );
330  bool beginWithMasslessPair = (
333  );
334  bool beginWithIdPair = beginWithZPair || beginWithMasslessPair;
336 
337  double HVVmass = PDGHelpers::Zeromass;
338  if (beginWithZPair) HVVmass = PDGHelpers::Zmass;
339  else if (beginWithWPair) HVVmass = PDGHelpers::Wmass;
340 
341  MELAParticle* orderedDs[2][2]={ { 0 } };
342  TLorentzVector pZ1(0, 0, 0, 0);
343  TLorentzVector pZ2(0, 0, 0, 0);
344  if (sortedDaughters.size()>2){ // WW, ZZ, ZW, WG, ZG
345  bool dauDiffType = true;
346  if (debugVars::debugFlag) MELAout << "Ndaughters>2" << std::endl;
347 
348  for (int d=0; d<std::min(2, (int)sortedDaughters.size()); d++){
349  if (sortedDaughters.at(d)!=0) pZ1 = pZ1 + sortedDaughters.at(d)->p4;
350  }
351  for (int d=std::min(2, (int)sortedDaughters.size()); d<std::min(4, (int)sortedDaughters.size()); d++){
352  if (sortedDaughters.at(d)!=0) pZ2 = pZ2 + sortedDaughters.at(d)->p4;
353  }
354 
355  if (debugVars::debugFlag) MELAout << "Preliminary pZ1 and pZ2 calculated!" << std::endl;
356 
357  if (sortedDaughters.size()>=4){
358  if (
359  beginWithIdPair &&
360  (
361  (isALepton(sortedDaughters.at(0)->id) && isALepton(sortedDaughters.at(1)->id) && isALepton(sortedDaughters.at(2)->id) && isALepton(sortedDaughters.at(3)->id))
362  ||
364  ||
365  (isAPhoton(sortedDaughters.at(0)->id) && isAPhoton(sortedDaughters.at(1)->id) && isAPhoton(sortedDaughters.at(2)->id) && isAPhoton(sortedDaughters.at(3)->id))
366  ||
368  ||
370  ||
371  (isAGluon(sortedDaughters.at(0)->id) && isAGluon(sortedDaughters.at(1)->id) && isAGluon(sortedDaughters.at(2)->id) && isAGluon(sortedDaughters.at(3)->id))
372  ||
374  )
375  ) dauDiffType=false;
376  }
377 
378  if (
379  (dauDiffType && beginWithIdPair && (
380  sortedDaughters.size()<4 // WG, ZG
381  ||
382  (
383  // WW, ZZ, ZW (mostly relevant for Z1-Z2 sorting)
384  // Zll>Znn>?GG>Zdd>Zuu>?gg>Zjj. 0-2 swap may then give W+W-.
385  sortedDaughters.size()>=4 && (
386  isALepton(sortedDaughters.at(0)->id) ||
387  (isANeutrino(sortedDaughters.at(0)->id) && !isALepton(sortedDaughters.at(2)->id)) ||
388  (isAPhoton(sortedDaughters.at(0)->id) && !isALepton(sortedDaughters.at(2)->id) && !isANeutrino(sortedDaughters.at(2)->id)) ||
389  (isDownTypeQuark(sortedDaughters.at(0)->id) && !isALepton(sortedDaughters.at(2)->id) && !isANeutrino(sortedDaughters.at(2)->id) && !isAPhoton(sortedDaughters.at(2)->id)) ||
390  (isUpTypeQuark(sortedDaughters.at(0)->id) && !isALepton(sortedDaughters.at(2)->id) && !isANeutrino(sortedDaughters.at(2)->id) && !isAPhoton(sortedDaughters.at(2)->id) && !isDownTypeQuark(sortedDaughters.at(2)->id)) ||
391  (isAGluon(sortedDaughters.at(0)->id) && !isALepton(sortedDaughters.at(2)->id) && !isANeutrino(sortedDaughters.at(2)->id) && !isAPhoton(sortedDaughters.at(2)->id) && !isDownTypeQuark(sortedDaughters.at(2)->id) && !isUpTypeQuark(sortedDaughters.at(2)->id)) ||
392  (isAnUnknownJet(sortedDaughters.at(0)->id) && !isALepton(sortedDaughters.at(2)->id) && !isANeutrino(sortedDaughters.at(2)->id) && !isAPhoton(sortedDaughters.at(2)->id) && !isDownTypeQuark(sortedDaughters.at(2)->id) && !isUpTypeQuark(sortedDaughters.at(2)->id) && !isAGluon(sortedDaughters.at(2)->id))
393  )
394  )
395  )
396  )
397  ||
398  // ZZ->4f
399  (
400  !dauDiffType && beginWithIdPair && std::abs(pZ1.M() - HVVmass)<std::abs(pZ2.M() - HVVmass) // Z1 / Z2
401  )
402  ||
403  (sortedDaughters.at(0)!=0 && sortedDaughters.at(1)!=0 && beginWithWPair && (sortedDaughters.at(0)->charge()+sortedDaughters.at(1)->charge())>0) // W+ / W-
404  ){
405  if (debugVars::debugFlag) MELAout << "pZ1 is closer to HVVmass " << HVVmass << std::endl;
406  orderedDs[0][0]=sortedDaughters.at(0);
407  orderedDs[0][1]=sortedDaughters.at(1);
408  orderedDs[1][0]=((int)sortedDaughters.size()>2 ? sortedDaughters.at(2) : 0);
409  orderedDs[1][1]=((int)sortedDaughters.size()>3 ? sortedDaughters.at(3) : 0);
410  }
411  else{
412  if (debugVars::debugFlag) MELAout << "pZ2 is closer to HVVmass " << HVVmass << std::endl;
413  orderedDs[0][0]=((int)sortedDaughters.size()>2 ? sortedDaughters.at(2) : 0);
414  orderedDs[0][1]=((int)sortedDaughters.size()>3 ? sortedDaughters.at(3) : 0);
415  orderedDs[1][0]=sortedDaughters.at(0);
416  orderedDs[1][1]=sortedDaughters.at(1);
417  TLorentzVector ptmp = pZ1;
418  pZ1 = pZ2;
419  pZ2 = ptmp;
420  }
421  }
422  else if (sortedDaughters.size()==2){ // GG, ffbar
423  if (debugVars::debugFlag) MELAout << "Ndaughters==2" << std::endl;
424 
425  if (sortedDaughters.at(0)!=0) pZ1 = pZ1 + sortedDaughters.at(0)->p4;
426  if (sortedDaughters.at(1)!=0) pZ2 = pZ2 + sortedDaughters.at(1)->p4;
427  orderedDs[0][0]=sortedDaughters.at(0);
428  orderedDs[0][1]=0;
429  orderedDs[1][0]=sortedDaughters.at(1);
430  orderedDs[1][1]=0;
431  }
432  if (
433  (
434  (orderedDs[0][1]!=0 && orderedDs[1][1]!=0)
435  &&
436  (orderedDs[0][1]->id == orderedDs[1][1]->id)
437  )
438  ||
439  (
440  (orderedDs[1][0]!=0 && orderedDs[0][0]!=0)
441  &&
442  (orderedDs[1][0]->id == orderedDs[0][0]->id)
443  )
444  ){
445  if (debugVars::debugFlag) MELAout << "Checking alternative pairings." << std::endl;
446 
447  MELAParticle* orderedDps[2][2]={ { 0 } };
448 
449  TLorentzVector pZ1p(0, 0, 0, 0);
450  TLorentzVector pZ2p(0, 0, 0, 0);
451  for (int d=0; d<2; d++){
452  if (orderedDs[d][d]!=0) pZ1p = pZ1p + orderedDs[d][d]->p4;
453  }
454  for (int d=0; d<2; d++){
455  if (orderedDs[1-d][d]!=0) pZ2p = pZ2p + orderedDs[1-d][d]->p4;
456  }
457 
458  if (std::abs(pZ1p.M() - HVVmass)<std::abs(pZ2p.M() - HVVmass)){
459  orderedDps[0][0]=orderedDs[0][0];
460  orderedDps[0][1]=orderedDs[1][1];
461  orderedDps[1][0]=orderedDs[1][0];
462  orderedDps[1][1]=orderedDs[0][1];
463  }
464  else{
465  orderedDps[0][0]=orderedDs[1][0];
466  orderedDps[0][1]=orderedDs[0][1];
467  orderedDps[1][0]=orderedDs[0][0];
468  orderedDps[1][1]=orderedDs[1][1];
469  TLorentzVector ptmp = pZ1p;
470  pZ1p = pZ2p;
471  pZ2p = ptmp;
472  }
473  if (std::abs(pZ1p.M() - HVVmass)<std::abs(pZ1.M() - HVVmass) || (std::abs(pZ1p.M() - HVVmass)==std::abs(pZ1.M() - HVVmass) && pZ2p.Pt()>pZ2.Pt())){
474  for (int i=0; i<2; i++){
475  for (int j=0; j<2; j++) orderedDs[i][j] = orderedDps[i][j];
476  }
477  }
478  }
479  sortedDaughters.clear();
480  for (int i=0; i<2; i++){
481  for (int j=0; j<2; j++){
482  if (orderedDs[i][j]!=0) sortedDaughters.push_back(orderedDs[i][j]);
483  }
484  }
485  if (debugVars::debugFlag) MELAout << "Final number of daughters in sortedDaughters: " << sortedDaughters.size() << std::endl;
486 }
488  TLorentzVector nullVector(0, 0, 0, 0);
489  bool beginWithZPair = (
493  );
495  int VID = 21; // Gamma/Gamma*
496  if (beginWithWPair) VID = 24; // W+/W-
497  else if (beginWithZPair) VID = 23; // Z
498 
499  int icutoff = (sortedDaughters.size()>2 ? 2 : std::min(1, (int)sortedDaughters.size()));
500  int imax = std::min(4, (int)sortedDaughters.size());
501  int V1id=-9000, V2id=-9000;
502  if (icutoff==0) V1id=25;
503  else{
504  double Vcharge[2]={ 0 };
505  for (int d=0; d<icutoff; d++){
506  if (sortedDaughters.at(d)!=0){
507  if (icutoff==2){
508  V1id=VID;
509  Vcharge[0] += sortedDaughters.at(d)->charge();
510  }
511  else if (icutoff==1) V1id=sortedDaughters.at(d)->id;
512  }
513  }
514  for (int d=icutoff; d<imax; d++){
515  if (sortedDaughters.at(d)!=0){
516  if ((imax-icutoff)==2){
517  V2id=(VID!=24 ? VID : -VID);
518  Vcharge[1] += sortedDaughters.at(d)->charge();
519  }
520  else if ((imax-icutoff)==1) V2id=sortedDaughters.at(d)->id;
521  }
522  }
523  // Override selfDecayMode if charges indicate some other final state
524  if (fabs(Vcharge[0]-1.)<0.001) V1id=24;
525  else if (fabs(Vcharge[0]+1.)<0.001) V1id=-24;
526  if (fabs(Vcharge[1]-1.)<0.001) V2id=24;
527  else if (fabs(Vcharge[1]+1.)<0.001) V2id=-24;
528  }
529 
530  // If the number of Zs is less than 2, should still create empty particles
531  MELAParticle* Z1 = new MELAParticle(V1id);
532  MELAParticle* Z2 = new MELAParticle(V2id);
533 
534  // Add daughters and their 4-vectors
535  if (icutoff==0) Z1->p4 = this->p4; // V1=H, V2=invalid
536  else{
537  for (int d=0; d<icutoff; d++){ if (sortedDaughters.at(d)!=0) *Z1 += sortedDaughters.at(d); }
538  for (int d=icutoff; d<imax; d++){ if (sortedDaughters.at(d)!=0) *Z2 += sortedDaughters.at(d); }
539  }
540 
541  // Configure relationships
542  Z1->addMother(this);
543  addSortedV(Z1);
544  Z2->addMother(this);
545  addSortedV(Z2);
546 }
547 TLorentzVector MELACandidate::getAlternativeVMomentum(int index)const{
548  bool beginWithZPair = (
552  );
554 
555  double HVVmass = PDGHelpers::Zeromass;
556  if (beginWithZPair) HVVmass = PDGHelpers::Zmass;
557  else if (beginWithWPair) HVVmass = PDGHelpers::Wmass;
558 
559  TLorentzVector nullFourVector(0, 0, 0, 0);
560  if (sortedDaughters.size()>=4){
561  if (beginWithWPair){
562  TLorentzVector pUU = sortedDaughters.at(0)->p4 + sortedDaughters.at(3)->p4;
563  TLorentzVector pDD = sortedDaughters.at(2)->p4 + sortedDaughters.at(1)->p4;
564  return (index==0 ? pDD : pUU);
565  }
566  else{
567  TLorentzVector pWp = sortedDaughters.at(2)->p4 + sortedDaughters.at(1)->p4;
568  TLorentzVector pWm = sortedDaughters.at(0)->p4 + sortedDaughters.at(3)->p4;
569  if (
570  (
571  (isALepton(sortedDaughters.at(0)->id) && isALepton(sortedDaughters.at(2)->id))
572  ||
573  (isANeutrino(sortedDaughters.at(0)->id) && isANeutrino(sortedDaughters.at(2)->id))
574  ||
575  (isAJet(sortedDaughters.at(0)->id) && isAJet(sortedDaughters.at(2)->id))
576  )
577  &&
578  std::abs(pWp.M() - HVVmass) > std::abs(pWm.M() - HVVmass)
579  ) std::swap(pWp, pWm);
580  return (index==0 ? pWp : pWm);
581  }
582  }
583  else if (sortedDaughters.size()==3){
584  TLorentzVector pVa = sortedDaughters.at(0)->p4 + sortedDaughters.at(2)->p4;
585  TLorentzVector pVb = sortedDaughters.at(1)->p4 + sortedDaughters.at(2)->p4;
586  return (index==0 ? pVa : pVb);
587  }
588  else return nullFourVector;
589 }
591  bool doInterfere = false;
592  if (sortedDaughters.size()>3) doInterfere = (
593  (sortedDaughters.at(0))->id == (sortedDaughters.at(2))->id
594  &&
595  (sortedDaughters.at(1))->id == (sortedDaughters.at(3))->id
596  &&
598  );
599  return doInterfere;
600 }
601 
602 bool MELACandidate::checkDaughtership(MELAParticle const* myParticle)const{
603  return hasDaughter(myParticle);
604 }
605 
608 }
610  addAssociatedParticleToArray(myParticle, associatedLeptons); // Neutrinos are leptons at the ZZ candidate level
612 }
615 }
618 }
621 }
622 void MELACandidate::addAssociatedParticleToArray(MELAParticle* myParticle, std::vector<MELAParticle*>& particleArray){
623  if (checkDaughtership(myParticle)) return;
624  if (associatedByHighestPt) MELACandidate::addByHighestPt(myParticle, particleArray);
625  else MELACandidate::addUnordered(myParticle, particleArray);
626 }
627 void MELACandidate::addAssociatedParticleToArray(MELAThreeBodyDecayCandidate* myParticle, std::vector<MELAThreeBodyDecayCandidate*>& particleArray){
628  if (checkDaughtership(myParticle)) return;
629 
630  // Check if any of the top daughters, if present, are also daughters of the candidate.
631  if (myParticle->getPartnerParticle() && checkDaughtership(myParticle->getPartnerParticle())) return;
632  if (myParticle->getWFermion() && checkDaughtership(myParticle->getWFermion())) return;
633  if (myParticle->getWAntifermion() && checkDaughtership(myParticle->getWAntifermion())) return;
634 
635  if (associatedByHighestPt) MELACandidate::addByHighestPt(myParticle, particleArray);
636  else MELACandidate::addUnordered(myParticle, particleArray);
637 }
638 
642 }
643 void MELACandidate::createAssociatedVs(std::vector<MELAParticle*>& particleArray){
644  for (unsigned int i = 0; i<particleArray.size(); i++){
645  double Qi = particleArray.at(i)->charge();
646  const int& id_i = particleArray.at(i)->id;
647 
648  for (unsigned int j = i+1; j<particleArray.size(); j++){
649  double Qj = particleArray.at(j)->charge();
650  const int& id_j = particleArray.at(j)->id;
651 
652  int bosonId=-1;
653  if ((Qi+Qj)==0 && (id_i+id_j)==0) bosonId = (id_i==0 ? 0 : 23); // Z->(f,fb) or 0->(0,0)
654  else if (PDGHelpers::isAnUnknownJet(id_i) || PDGHelpers::isAnUnknownJet(id_j)) bosonId = 0; // 0->(q,0)/(0,qb)
655  else if ( // W->f fb'
656  abs(Qi+Qj)==1
657  &&
658  (
659  ((PDGHelpers::isALepton(id_i) || PDGHelpers::isALepton(id_j)) && std::abs(id_i+id_j)==1) // Require SF lnu particle-antiparticle pairs
660  ||
661  (PDGHelpers::isUpTypeQuark(id_i) && PDGHelpers::isDownTypeQuark(id_j)) // Require ud- or du-type pairs, qqbar requirement is satisfied with charge.
662  ||
664  )
665  ) bosonId=24*(Qi+Qj);
666 
667  if (bosonId!=-1){
668  MELAParticle* boson = new MELAParticle(bosonId);
669  // Order by f-f'b
670  int firstdaughter = i, seconddaughter = j;
671  if (
672  (particleArray.at(firstdaughter)->id<particleArray.at(seconddaughter)->id)
673  &&
674  (
675  !PDGHelpers::isAWBoson(bosonId)
676  ||
677  (particleArray.at(firstdaughter)->id<0 && PDGHelpers::isAWBoson(bosonId))
678  )
679  ) std::swap(firstdaughter, seconddaughter);
680  *boson += particleArray.at(firstdaughter);
681  *boson += particleArray.at(seconddaughter);
682 
683  boson->addMother(this);
684  addSortedV(boson);
685  }
686  }
687  }
688 }
689 
691  for (auto& dau:getDaughters()){
692  if (!dau->passSelection){
693  passSelection=false;
694  break;
695  }
696  }
697 }
698 
699 void MELACandidate::getRelatedParticles(std::vector<MELAParticle*>& particles) const{
701  for (auto* part:sortedDaughters){ if (part) part->getRelatedParticles(particles); } // Hopefully no particle gets added from here
702  for (auto* part:associatedTops){ if (part) part->getRelatedParticles(particles); }
703  for (auto* part:sortedVs){ if (part) part->getRelatedParticles(particles); }
704  for (auto* part:associatedLeptons){ if (part) part->getRelatedParticles(particles); }
705  for (auto* part:associatedPhotons){ if (part) part->getRelatedParticles(particles); }
706  for (auto* part:associatedJets){ if (part) part->getRelatedParticles(particles); }
707 }
708 void MELACandidate::getDaughterParticles(std::vector<MELAParticle*>& particles) const{
710  for (auto* part:sortedDaughters){ if (part) part->getDaughterParticles(particles); } // Hopefully no particle gets added from here
711  for (auto* sortedV:sortedVs){ // Only add sorted Vs that are actually the intermediates of the sorted daughters
712  if (!sortedV) continue;
713  bool doAddV=false;
714  for (auto& dau:sortedDaughters){ if (dau && sortedV->hasDaughter(dau)){ doAddV=true; break; } }
715  if (doAddV) sortedV->getDaughterParticles(particles);
716  }
717 }
718 
719 void MELACandidate::addUnordered(MELAParticle* myParticle, std::vector<MELAParticle*>& particleArray){
720  bool inserted = MELAParticle::checkParticleExists(myParticle, particleArray); // Test if the particle is already in the vector
721  if (!inserted) particleArray.push_back(myParticle);
722 }
723 void MELACandidate::addUnordered(MELAThreeBodyDecayCandidate* myParticle, std::vector<MELAThreeBodyDecayCandidate*>& particleArray){
724  bool inserted = MELAThreeBodyDecayCandidate::checkCandidateExists(myParticle, particleArray); // Test if the particle is already in the vector
725  if (!inserted) particleArray.push_back(myParticle);
726 }
727 void MELACandidate::addByHighestPt(MELAParticle* myParticle, std::vector<MELAParticle*>& particleArray){
728  bool inserted = MELAParticle::checkParticleExists(myParticle, particleArray); // Test if the particle is already in the vector
729  if (!inserted){
730  for (std::vector<MELAParticle*>::iterator it = particleArray.begin(); it<particleArray.end(); it++){
731  if ((*it)->pt()<myParticle->pt()){
732  inserted=true;
733  particleArray.insert(it, myParticle);
734  break;
735  }
736  }
737  if (!inserted) particleArray.push_back(myParticle);
738  }
739 }
740 void MELACandidate::addByHighestPt(MELAThreeBodyDecayCandidate* myParticle, std::vector<MELAThreeBodyDecayCandidate*>& particleArray){
741  bool inserted = MELAThreeBodyDecayCandidate::checkCandidateExists(myParticle, particleArray); // Test if the particle is already in the vector
742  if (!inserted){
743  for (std::vector<MELAThreeBodyDecayCandidate*>::iterator it = particleArray.begin(); it<particleArray.end(); it++){
744  if ((*it)->pt()<myParticle->pt()){
745  inserted=true;
746  particleArray.insert(it, myParticle);
747  break;
748  }
749  }
750  if (!inserted) particleArray.push_back(myParticle);
751  }
752 }
MELAThreeBodyDecayCandidate::getWAntifermion
MELAParticle * getWAntifermion()
Definition: MELAThreeBodyDecayCandidate.h:23
MELACandidate::getAssociatedTop
MELATopCandidate_t * getAssociatedTop(int index) const
Definition: MELACandidate.cc:172
PDGHelpers::isALepton
bool isALepton(const int id)
Definition: PDGHelpers.cc:62
MELACandidate::daughtersInterfere
bool daughtersInterfere() const
Definition: MELACandidate.cc:590
MELAParticle::MELAParticle
MELAParticle()
Definition: MELAParticle.cc:16
MELACandidate::getSortedVs
std::vector< MELAParticle * > & getSortedVs()
Definition: MELACandidate.cc:178
PDGHelpers::HDecayMode
TVar::CandidateDecayMode HDecayMode
Definition: PDGHelpers.cc:11
MELAParticle::getDaughter
MELAParticle * getDaughter(int index) const
Definition: MELAParticle.cc:68
MELACandidate::setAddAssociatedByHighestPt
void setAddAssociatedByHighestPt(bool associatedByHighestPt_)
Definition: MELACandidate.cc:113
debugVars::debugFlag
bool debugFlag
Definition: MELAParticle.cc:12
MELAParticle::pt
double pt() const
Definition: MELAParticle.h:72
MELACandidate::addAssociatedJet
void addAssociatedJet(MELAParticle *myParticle)
Definition: MELACandidate.cc:616
MELACandidate::isShallowCopy
bool isShallowCopy
Definition: MELACandidate.h:92
MELACandidate::resetVs
void resetVs()
Definition: MELACandidate.cc:98
MELACandidate::selfDecayMode
TVar::CandidateDecayMode selfDecayMode
Definition: MELACandidate.h:93
MELACandidate::operator=
MELACandidate & operator=(const MELACandidate &particle_)
Definition: MELACandidate.cc:46
TVar::CandidateDecay_ZZ
@ CandidateDecay_ZZ
Definition: TVar.hh:41
MELAParticle::getNDaughters
int getNDaughters() const
Definition: MELAParticle.h:50
MELAParticle::swap
void swap(MELAParticle &particle_)
Definition: MELAParticle.cc:52
MELACandidate::associatedByHighestPt
bool associatedByHighestPt
Definition: MELACandidate.h:91
MELACandidate::getAssociatedNeutrino
MELAParticle * getAssociatedNeutrino(int index) const
Definition: MELACandidate.cc:160
PDGHelpers
Definition: PDGHelpers.h:12
MELACandidate::createAssociatedVs
void createAssociatedVs(std::vector< MELAParticle * > &particleArray)
Definition: MELACandidate.cc:643
MELAParticle::getDaughters
std::vector< MELAParticle * > & getDaughters()
Definition: MELAParticle.h:59
MELACandidate::getSortedV
MELAParticle * getSortedV(int index) const
Definition: MELACandidate.cc:152
MELAThreeBodyDecayCandidate::checkCandidateExists
static bool checkCandidateExists(MELAThreeBodyDecayCandidate const *myParticle, std::vector< MELAThreeBodyDecayCandidate * > const &particleArray)
Definition: MELAThreeBodyDecayCandidate.cc:63
MELACandidate::addAssociatedNeutrino
void addAssociatedNeutrino(MELAParticle *myParticle)
Definition: MELACandidate.cc:609
MELAParticle::setGenStatus
void setGenStatus(int status_)
Definition: MELAParticle.h:43
MELACandidate::swap
void swap(MELACandidate &particle_)
Definition: MELACandidate.cc:84
TVar::CandidateDecayMode
CandidateDecayMode
Definition: TVar.hh:37
MELACandidate::associatedNeutrinos
std::vector< MELAParticle * > associatedNeutrinos
Definition: MELACandidate.h:96
TVar::CandidateDecay_Stable
@ CandidateDecay_Stable
Definition: TVar.hh:38
MELACandidate::addAssociatedVs
void addAssociatedVs()
Definition: MELACandidate.cc:639
TVar
Definition: TVar.hh:28
MELACandidate::getAssociatedPhoton
MELAParticle * getAssociatedPhoton(int index) const
Definition: MELACandidate.cc:164
TVar::CandidateDecay_WW
@ CandidateDecay_WW
Definition: TVar.hh:40
MELACandidate::getDaughterIds
virtual std::vector< int > getDaughterIds() const
Definition: MELACandidate.cc:128
MELACandidate::addAssociatedPhoton
void addAssociatedPhoton(MELAParticle *myParticle)
Definition: MELACandidate.cc:613
MELAParticle::t
double t() const
Definition: MELAParticle.h:70
PDGHelpers::isAnUnknownJet
bool isAnUnknownJet(const int id)
Definition: PDGHelpers.cc:22
MELACandidate::getRelatedParticles
void getRelatedParticles(std::vector< MELAParticle * > &particles) const
Definition: MELACandidate.cc:699
MELACandidate::associatedTops
std::vector< MELATopCandidate_t * > associatedTops
Definition: MELACandidate.h:99
MELAParticle::phi
double phi() const
Definition: MELAParticle.h:74
PDGHelpers::isANeutrino
bool isANeutrino(const int id)
Definition: PDGHelpers.cc:67
MELAParticle::checkParticleExists
static bool checkParticleExists(MELAParticle const *myParticle, std::vector< MELAParticle * > const &particleArray)
Definition: MELAParticle.cc:116
MELACandidate::shallowCopy
MELACandidate * shallowCopy()
Definition: MELACandidate.cc:61
PDGHelpers::isAPhoton
bool isAPhoton(const int id)
Definition: PDGHelpers.cc:72
MELAParticle::y
double y() const
Definition: MELAParticle.h:68
MELAParticle::hasDaughter
bool hasDaughter(MELAParticle const *part) const
Definition: MELAParticle.cc:88
MELAStreamHelpers::MELAout
MELAOutputStreamer MELAout
MELAParticle::x
double x() const
Definition: MELAParticle.h:67
MELACandidate::~MELACandidate
~MELACandidate()
Definition: MELACandidate.cc:51
MELAThreeBodyDecayCandidate::getPartnerParticle
MELAParticle * getPartnerParticle()
Definition: MELAThreeBodyDecayCandidate.h:21
MELAParticle::m
double m() const
Definition: MELAParticle.h:66
MELACandidate::recreateVs
void recreateVs()
Definition: MELACandidate.cc:105
MELACandidate::getAssociatedPhotons
std::vector< MELAParticle * > & getAssociatedPhotons()
Definition: MELACandidate.cc:181
PDGHelpers::isDownTypeQuark
bool isDownTypeQuark(const int id)
Definition: PDGHelpers.cc:45
MELACandidate::associatedJets
std::vector< MELAParticle * > associatedJets
Definition: MELACandidate.h:98
MELACandidate::sortedDaughters
std::vector< MELAParticle * > sortedDaughters
Definition: MELACandidate.h:101
MELACandidate::associatedPhotons
std::vector< MELAParticle * > associatedPhotons
Definition: MELACandidate.h:97
MELACandidate::getAssociatedSortedVs
std::vector< MELAParticle * > getAssociatedSortedVs()
Definition: MELACandidate.cc:193
MELAParticle::p4
TLorentzVector p4
Definition: MELAParticle.h:18
MELAParticle::daughters
std::vector< MELAParticle * > daughters
Definition: MELAParticle.h:25
MELAParticle::z
double z() const
Definition: MELAParticle.h:69
MELACandidate::addSortedV
void addSortedV(MELAParticle *myParticle)
Definition: MELACandidate.h:70
MELACandidate::getAlternativeVMomentum
TLorentzVector getAlternativeVMomentum(int index) const
Definition: MELACandidate.cc:547
PDGHelpers::isAWBoson
bool isAWBoson(const int id)
Definition: PDGHelpers.cc:80
MELAParticle::genStatus
int genStatus
Definition: MELAParticle.h:20
MELAParticle::charge
double charge() const
Definition: MELAParticle.cc:90
MELACandidate::getSortedDaughter
MELAParticle * getSortedDaughter(int index) const
Definition: MELACandidate.cc:148
MELACandidate::getAssociatedLepton
MELAParticle * getAssociatedLepton(int index) const
Definition: MELACandidate.cc:156
MELACandidate::MELACandidate
MELACandidate()
Definition: MELACandidate.cc:12
MELAParticle::setLifetime
void setLifetime(double life_)
Definition: MELAParticle.h:44
MELACandidate::getAssociatedNeutrinos
std::vector< MELAParticle * > & getAssociatedNeutrinos()
Definition: MELACandidate.cc:180
MELACandidate::getAssociatedLeptons
std::vector< MELAParticle * > & getAssociatedLeptons()
Definition: MELACandidate.cc:179
MELACandidate::setDecayMode
void setDecayMode(TVar::CandidateDecayMode flag)
Definition: MELACandidate.cc:112
MELACandidate::checkDaughtership
bool checkDaughtership(MELAParticle const *myParticle) const
Definition: MELACandidate.cc:602
MELACandidate::addUnordered
static void addUnordered(MELAParticle *myParticle, std::vector< MELAParticle * > &particleArray)
Definition: MELACandidate.cc:719
MELAParticle
Definition: MELAParticle.h:13
MELAParticle::lifetime
double lifetime
Definition: MELAParticle.h:21
MELAParticle::getDaughterParticles
virtual void getDaughterParticles(std::vector< MELAParticle * > &particles) const
Definition: MELAParticle.cc:82
TUtilHelpers::copyVector
void copyVector(std::vector< T > const &input, std::vector< T > &target)
Definition: TUtilHelpers.hh:24
MELACandidate::getDaughterParticles
void getDaughterParticles(std::vector< MELAParticle * > &particles) const
Definition: MELACandidate.cc:708
TVar::CandidateDecay_ZW
@ CandidateDecay_ZW
Definition: TVar.hh:42
MELACandidate::sortedVs
std::vector< MELAParticle * > sortedVs
Definition: MELACandidate.h:102
TVar::CandidateDecay_ZG
@ CandidateDecay_ZG
Definition: TVar.hh:43
MELACandidate::addAssociatedTop
void addAssociatedTop(MELATopCandidate_t *myParticle)
Definition: MELACandidate.cc:619
MELAThreeBodyDecayCandidate::getWFermion
MELAParticle * getWFermion()
Definition: MELAThreeBodyDecayCandidate.h:22
modttbhiggs::ds
integer, parameter ds
Definition: mod_TTBHiggs.F90:59
MELACandidate::addAssociatedLepton
void addAssociatedLepton(MELAParticle *myParticle)
Definition: MELACandidate.cc:606
MELACandidate::testShallowCopy
bool testShallowCopy()
Definition: MELACandidate.cc:115
MELAParticle::mothers
std::vector< MELAParticle * > mothers
Definition: MELAParticle.h:24
MELACandidate::getAssociatedJet
MELAParticle * getAssociatedJet(int index) const
Definition: MELACandidate.cc:168
MELACandidate::getAssociatedTops
std::vector< MELATopCandidate_t * > & getAssociatedTops()
Definition: MELACandidate.cc:183
MELAParticle::addMother
void addMother(MELAParticle *myParticle)
Definition: MELAParticle.cc:62
PDGHelpers::Zmass
const double Zmass
Definition: PDGHelpers.h:14
MELAStreamHelpers::MELAerr
MELAOutputStreamer MELAerr
MELACandidate::addByHighestPt
static void addByHighestPt(MELAParticle *myParticle, std::vector< MELAParticle * > &particleArray)
Definition: MELACandidate.cc:727
MELACandidate::addAssociatedParticleToArray
void addAssociatedParticleToArray(MELAParticle *myParticle, std::vector< MELAParticle * > &particleArray)
Definition: MELACandidate.cc:622
MELAParticle::passSelection
bool passSelection
Definition: MELAParticle.h:19
MELACandidate::associatedLeptons
std::vector< MELAParticle * > associatedLeptons
Definition: MELACandidate.h:95
PDGHelpers::Wmass
const double Wmass
Definition: PDGHelpers.h:13
MELACandidate.h
TUtilHelpers.hh
TVar::CandidateDecay_WG
@ CandidateDecay_WG
Definition: TVar.hh:44
MELACandidate::sortDaughtersByBestZ1
void sortDaughtersByBestZ1()
Definition: MELACandidate.cc:324
MELACandidate::getAssociatedJets
std::vector< MELAParticle * > & getAssociatedJets()
Definition: MELACandidate.cc:182
PDGHelpers::isAGluon
bool isAGluon(const int id)
Definition: PDGHelpers.cc:58
MELACandidate::getSortedDaughters
std::vector< MELAParticle * > & getSortedDaughters()
Definition: MELACandidate.cc:177
MELACandidate::sortDaughters
void sortDaughters()
Definition: MELACandidate.cc:117
MELACandidate
Definition: MELACandidate.h:7
MELAStreamHelpers.hh
MELACandidate::createSortedVs
void createSortedVs()
Definition: MELACandidate.cc:487
MELAThreeBodyDecayCandidate
Definition: MELAThreeBodyDecayCandidate.h:7
MELACandidate::testPreSelectedDaughters
void testPreSelectedDaughters()
Definition: MELACandidate.cc:690
MELAParticle::getRelatedParticles
virtual void getRelatedParticles(std::vector< MELAParticle * > &particles) const
Definition: MELAParticle.cc:77
TVar::CandidateDecay_ff
@ CandidateDecay_ff
Definition: TVar.hh:39
PDGHelpers::Zeromass
const double Zeromass
Definition: PDGHelpers.h:17
MELAParticle::id
int id
Definition: MELAParticle.h:17
MELAParticle::setSelected
void setSelected(bool isSelected=true)
Definition: MELAParticle.h:42
MELACandidate::getAssociatedParticleIds
std::vector< int > getAssociatedParticleIds() const
Definition: MELACandidate.cc:135
PDGHelpers::isUpTypeQuark
bool isUpTypeQuark(const int id)
Definition: PDGHelpers.cc:40
PDGHelpers::isAJet
bool isAJet(const int id)
Definition: PDGHelpers.cc:18
MELACandidate::setShallowCopy
void setShallowCopy(bool flag)
Definition: MELACandidate.cc:114
MELACandidate::sortDaughtersInitial
void sortDaughtersInitial()
Definition: MELACandidate.cc:218
TVar::CandidateDecay_GG
@ CandidateDecay_GG
Definition: TVar.hh:45