CMS 3D CMS Logo

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