CMS 3D CMS Logo

Top_Decaykin.cc
Go to the documentation of this file.
1 //
2 //
3 // File: src/Top_Decaykin.cc
4 // Purpose: Calculate some kinematic quantities for ttbar events.
5 // Created: Jul, 2000, sss, based on run 1 mass analysis code.
6 //
7 // CMSSW File : src/Top_Decaykin.cc
8 // Original Author : Scott Stuart Snyder <snyder@bnl.gov> for D0
9 // Imported to CMSSW by Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>
10 //
11 
38 #include <cmath>
39 #include <algorithm>
40 #include <ostream>
41 
42 using std::abs;
43 using std::ostream;
44 using std::sqrt;
45 using std::swap;
46 
47 namespace hitfit {
48 
49  namespace {
50 
56  Fourvec leptons(const Lepjets_Event& ev)
57  //
58  // Purpose: Sum all leptons in EV.
59  //
60  // Inputs:
61  // ev - The event.
62  //
63  // Returns:
64  // The sum of all leptons in EV.
65  //
66  {
67  return (ev.sum(lepton_label) + ev.sum(electron_label) + ev.sum(muon_label));
68  }
69 
70  } // unnamed namespace
71 
72  bool Top_Decaykin::solve_nu_tmass(const Lepjets_Event& ev, double tmass, double& nuz1, double& nuz2)
73  //
74  // Purpose: Solve for the neutrino longitudinal z-momentum that makes
75  // the leptonic top have mass TMASS.
76  //
77  // Inputs:
78  // ev - The event to solve.
79  // tmass - The desired top mass.
80  //
81  // Outputs:
82  // nuz1 - First solution (smaller absolute value).
83  // nuz2 - Second solution.
84  //
85  // Returns:
86  // True if there was a real solution. False if there were only
87  // imaginary solutions. (In that case, we just set the imaginary
88  // part to zero.)
89  //
90  {
91  bool discrim_flag = true;
92 
93  const Fourvec& vnu = ev.met();
94  Fourvec cprime = leptons(ev) + ev.sum(lepb_label);
95  double alpha1 = tmass * tmass - cprime.m2();
96  double a = 2 * 4 * (cprime.z() * cprime.z() - cprime.e() * cprime.e());
97  double alpha = alpha1 + 2 * (cprime.x() * vnu.x() + cprime.y() * vnu.y());
98  double b = 4 * alpha * cprime.z();
99  double c = alpha * alpha - 4 * cprime.e() * cprime.e() * vnu.vect().perp2();
100  double d = b * b - 2 * a * c;
101  if (d < 0) {
102  discrim_flag = false;
103  d = 0;
104  }
105 
106  double dd = sqrt(d);
107  nuz1 = (-b + dd) / a;
108  nuz2 = (-b - dd) / a;
109  if (abs(nuz1) > abs(nuz2))
110  swap(nuz1, nuz2);
111 
112  return discrim_flag;
113  }
114 
116  const Lepjets_Event& ev, double tmass, double& re_nuz1, double& im_nuz1, double& re_nuz2, double& im_nuz2)
117  //
118  // Purpose: Solve for the neutrino longitudinal z-momentum that makes
119  // the leptonic top have mass TMASS, including the imaginary
120  // component of the z-component of the neutrino'somentum.
121  //
122  // Inputs:
123  // ev - The event to solve.
124  // tmass - The desired top mass.
125  //
126  // Outputs:
127  // re_nuz1 - Real component of the first solution.
128  // im_nuz1 - Imaginary component of the first solution (in the lower half of
129  // the complex plane).
130  // re_nuz2 - Real component of the second solution.
131  // im_nuz2 - Imaginary component of the second solution (in the upper half of
132  // the complex plane).
133  //
134  // Returns:
135  // True if there was a real solution. False if there were only
136  // complex solutions.
137  //
138  {
139  bool discrim_flag = true;
140 
141  const Fourvec& vnu = ev.met();
142  Fourvec cprime = leptons(ev) + ev.sum(lepb_label);
143  double alpha1 = tmass * tmass - cprime.m2();
144  double a = 2 * 4 * (cprime.z() * cprime.z() - cprime.e() * cprime.e());
145  // Haryo's note: Here a is equivalent to '2a' in the quadratic
146  // equation ax^2 + bx + c = 0
147  double alpha = alpha1 + 2 * (cprime.x() * vnu.x() + cprime.y() * vnu.y());
148  double b = 4 * alpha * cprime.z();
149  double c = alpha * alpha - 4 * cprime.e() * cprime.e() * vnu.vect().perp2();
150  double d = b * b - 2 * a * c;
151  if (d < 0) {
152  discrim_flag = false;
153  }
154 
155  if (discrim_flag) {
156  re_nuz1 = (-b + sqrt(d)) / a;
157  im_nuz1 = 0;
158  re_nuz2 = (-b - sqrt(d)) / a;
159  im_nuz2 = 0;
160  if (abs(re_nuz1) > abs(re_nuz2)) {
161  swap(re_nuz1, re_nuz2);
162  }
163 
164  } else {
165  // Take absolute value of the imaginary component of nuz, in case
166  // a is negative, before multiplying by +1 or -1 to get the upper-half
167  // or lower-half imaginary value.
168  re_nuz1 = -b / a;
169  im_nuz1 = -fabs(sqrt(-d) / a);
170  re_nuz2 = -b / a;
171  im_nuz2 = fabs(sqrt(-d) / a);
172  }
173 
174  return discrim_flag;
175  }
176 
177  bool Top_Decaykin::solve_nu(const Lepjets_Event& ev, double wmass, double& nuz1, double& nuz2)
178  //
179  // Purpose: Solve for the neutrino longitudinal z-momentum that makes
180  // the leptonic W have mass WMASS.
181  //
182  // Inputs:
183  // ev - The event to solve.
184  // wmass - The desired W mass.
185  //
186  // Outputs:
187  // nuz1 - First solution (smaller absolute value).
188  // nuz2 - Second solution.
189  //
190  // Returns:
191  // True if there was a real solution. False if there were only
192  // imaginary solutions. (In that case, we just set the imaginary
193  // part to zero.)
194  //
195  {
196  bool discrim_flag = true;
197 
198  const Fourvec& vnu = ev.met();
199  Fourvec vlep = leptons(ev);
200 
201  double x = vlep.x() * vnu.x() + vlep.y() * vnu.y() + wmass * wmass / 2;
202  double a = vlep.z() * vlep.z() - vlep.e() * vlep.e();
203  double b = 2 * x * vlep.z();
204  double c = x * x - vnu.perp2() * vlep.e() * vlep.e();
205 
206  double d = b * b - 4 * a * c;
207  if (d < 0) {
208  d = 0;
209  discrim_flag = false;
210  }
211 
212  nuz1 = (-b + sqrt(d)) / 2 / a;
213  nuz2 = (-b - sqrt(d)) / 2 / a;
214  if (abs(nuz1) > abs(nuz2))
215  swap(nuz1, nuz2);
216 
217  return discrim_flag;
218  }
219 
221  const Lepjets_Event& ev, double wmass, double& re_nuz1, double& im_nuz1, double& re_nuz2, double& im_nuz2)
222  //
223  // Purpose: Solve for the neutrino longitudinal z-momentum that makes
224  // the leptonic W have mass WMASS, including the imaginary
225  // component of the z-component of the neutrino'somentum.
226  //
227  // Inputs:
228  // ev - The event to solve.
229  // wmass - The desired W mass.
230  //
231  // Outputs:
232  // re_nuz1 - Real component of the first solution.
233  // im_nuz1 - Imaginary component of the first solution (in the lower half of
234  // the complex plane).
235  // re_nuz2 - Real component of the second solution.
236  // im_nuz2 - Imaginary component of the second solution (in the upper half of
237  // the complex plane).
238  //
239  // Returns:
240  // True if there was a real solution. False if there were only
241  // complex solutions.
242  //x
243  {
244  bool discrim_flag = true;
245 
246  const Fourvec& vnu = ev.met();
247  Fourvec vlep = leptons(ev);
248 
249  double x = vlep.x() * vnu.x() + vlep.y() * vnu.y() + wmass * wmass / 2;
250  double a = vlep.z() * vlep.z() - vlep.e() * vlep.e();
251  double b = 2 * x * vlep.z();
252  double c = x * x - vnu.perp2() * vlep.e() * vlep.e();
253 
254  double d = b * b - 4 * a * c;
255  if (d < 0) {
256  discrim_flag = false;
257  }
258 
259  if (discrim_flag) {
260  re_nuz1 = (-b + sqrt(d)) / 2 / a;
261  im_nuz1 = 0.0;
262  re_nuz2 = (-b - sqrt(d)) / 2 / a;
263  im_nuz2 = 0.0;
264  if (fabs(re_nuz1) > fabs(re_nuz2)) {
265  swap(re_nuz1, re_nuz2);
266  }
267 
268  } else {
269  // Take absolute value of the imaginary component of nuz, in case
270  // a is negative, before multiplying by +1 or -1 to get the upper-half
271  // or lower-half imaginary value.
272 
273  re_nuz1 = -b / 2 / a;
274  im_nuz1 = -fabs(sqrt(-d) / a);
275  re_nuz2 = -b / 2 / a;
276  im_nuz2 = fabs(sqrt(-d) / a);
277  }
278 
279  return discrim_flag;
280  }
281 
283  //
284  // Purpose: Sum up the appropriate 4-vectors to find the hadronic W.
285  //
286  // Inputs:
287  // ev - The event.
288  //
289  // Returns:
290  // The hadronic W.
291  //
292  {
293  return (ev.sum(hadw1_label) + ev.sum(hadw2_label));
294  }
295 
297  //
298  // Purpose:
299  //
300  // Inputs:
301  // ev - The event.
302  //
303  // Returns:
304  // The higher-pT hadronic jet from W
305  //
306  {
307  return ev.sum(hadw1_label);
308  }
309 
311  //
312  // Purpose:
313  //
314  // Inputs:
315  // ev - The event.
316  //
317  // Returns:
318  // The lower-pT hadronic jet from W
319  //
320  //
321  {
322  return ev.sum(hadw2_label);
323  }
324 
326  //
327  // Purpose: Sum up the appropriate 4-vectors to find the leptonic W.
328  //
329  // Inputs:
330  // ev - The event.
331  //
332  // Returns:
333  // The leptonic W.
334  //
335  {
336  return (leptons(ev) + ev.met());
337  }
338 
340  //
341  // Purpose: Sum up the appropriate 4-vectors to find the hadronic t.
342  //
343  // Inputs:
344  // ev - The event.
345  //
346  // Returns:
347  // The hadronic t.
348  //
349  {
350  return (ev.sum(hadb_label) + hadw(ev));
351  }
352 
354  //
355  // Purpose: Sum up the appropriate 4-vectors to find the leptonic t.
356  //
357  // Inputs:
358  // ev - The event.
359  //
360  // Returns:
361  // The leptonic t.
362  //
363  {
364  return (ev.sum(lepb_label) + lepw(ev));
365  }
366 
367  ostream& Top_Decaykin::dump_ev(std::ostream& s, const Lepjets_Event& ev)
368  //
369  // Purpose: Print kinematic information for EV.
370  //
371  // Inputs:
372  // s - The stream to which to write.
373  // ev - The event to dump.
374  //
375  // Returns:
376  // The stream S.
377  //
378  {
379  s << ev;
380  Fourvec p;
381 
382  p = lepw(ev);
383  s << "lepw " << p << " " << p.m() << "\n";
384  p = lept(ev);
385  s << "lept " << p << " " << p.m() << "\n";
386  p = hadw(ev);
387  s << "hadw " << p << " " << p.m() << "\n";
388  p = hadt(ev);
389  s << "hadt " << p << " " << p.m() << "\n";
390 
391  return s;
392  }
393 
394  double Top_Decaykin::cos_theta_star(const Fourvec& fermion, const Fourvec& W, const Fourvec& top)
395  //
396  // Purpose: Calculate cos theta star in top decay
397  //
398  // Inputs:
399  // fermion - The four momentum of fermion from W
400  // W - The four momentum of W from top
401  // top - The four momentum of top
402  // Returns:
403  // cos theta star
404  //
405  {
406  if (W.isLightlike() || W.isSpacelike()) {
407  return 100.0;
408  }
409 
410  CLHEP::HepBoost BoostWCM(W.findBoostToCM());
411 
412  CLHEP::Hep3Vector boost_v3fermion = BoostWCM(fermion).vect();
413  CLHEP::Hep3Vector boost_v3top = BoostWCM(top).vect();
414 
415  double costhetastar = boost_v3fermion.cosTheta(-boost_v3top);
416 
417  return costhetastar;
418  }
419 
421  //
422  // Purpose: Calculate lepton cos theta star in top decay
423  //
424  // Inputs:
425  // ev - A lepton+jets event
426  // Returns:
427  // cos theta star of lepton
428  //
429  {
430  return cos_theta_star(leptons(ev), lepw(ev), lept(ev));
431  }
432 
434  //
435  // Purpose: Calculate lepton cos theta star in top decay
436  //
437  // Inputs:
438  // ev - A lepton+jets event
439  // Returns:
440  // cos theta star of lepton
441  //
442  {
443  return cos_theta_star(ev);
444  }
445 
447  //
448  // Purpose: Calculate absolute value of cos theta star of
449  // one of the hadronic W jet from hadronic top.
450  //
451  // Inputs:
452  // ev - A lepton+jets event
453  // Returns:
454  // absolute value of cos theta star
455  //
456  {
457  return fabs(cos_theta_star(hadw1(ev), hadw(ev), hadt(ev)));
458  }
459 
460 } // namespace hitfit
static bool solve_nu_tmass(const Lepjets_Event &ev, double tmass, double &nuz1, double &nuz2)
Solve for the neutrino longitudinal momentum that makes the leptonic top have a certain value of mas...
Definition: Top_Decaykin.cc:72
Define three-vector and four-vector classes for the HitFit package, and supply a few additional opera...
static Fourvec hadw2(const Lepjets_Event &ev)
Return the hadronic boson jet which have lower .
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:112
string dd
Definition: createTree.py:154
static Fourvec hadw1(const Lepjets_Event &ev)
Return the hadronic boson jet which have higher .
static bool solve_nu(const Lepjets_Event &ev, double wmass, double &nuz1, double &nuz2)
Solve for the longitudinal momentum that makes the leptonic -boson to have a certain value of mass...
Represent a simple event consisting of lepton(s) and jet(s).
T sqrt(T t)
Definition: SSEVec.h:19
A class to hold functions to calculate kinematic quantities of interest in events.
static double cos_theta_star_lept(const Lepjets_Event &ev)
Calculate the lepton in top quark leptonic decay.
Represent a simple event consisting of lepton(s) and jet(s). An instance of this class holds a list o...
Definition: Lepjets_Event.h:62
CLHEP::HepLorentzVector Fourvec
Typedef for a HepLorentzVector.
Definition: fourvec.h:55
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
d
Definition: ztail.py:151
static double cos_theta_star_hadt(const Lepjets_Event &ev)
Calculate the hadronic in top quark leptonic decay. As there is no information on the weak isospin c...
static Fourvec hadt(const Lepjets_Event &ev)
Sum up the appropriate four-momenta to find the hadronic top quark.
static double cos_theta_star(const Fourvec &fermion, const Fourvec &W, const Fourvec &top)
Calculate in top quark decay.
double b
Definition: hdecay.h:120
static Fourvec lept(const Lepjets_Event &ev)
Sum up the appropriate four-momenta to find the leptonic top quark.
double a
Definition: hdecay.h:121
float x
static Fourvec lepw(const Lepjets_Event &ev)
Sum up the appropriate four-momenta to find the leptonic boson.
static Fourvec hadw(const Lepjets_Event &ev)
Sum up the appropriate four-momenta to find the hadronic boson.
static std::ostream & dump_ev(std::ostream &s, const Lepjets_Event &ev)
Print the kinematic information for an event.