CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10/src/TopQuarkAnalysis/TopHitFit/src/Top_Decaykin.cc

Go to the documentation of this file.
00001 //
00002 // $Id: Top_Decaykin.cc,v 1.1 2011/05/26 09:47:00 mseidel Exp $
00003 //
00004 // File: src/Top_Decaykin.cc
00005 // Purpose: Calculate some kinematic quantities for ttbar events.
00006 // Created: Jul, 2000, sss, based on run 1 mass analysis code.
00007 //
00008 // CMSSW File      : src/Top_Decaykin.cc
00009 // Original Author : Scott Stuart Snyder <snyder@bnl.gov> for D0
00010 // Imported to CMSSW by Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>
00011 //
00012 
00013 
00037 #include "TopQuarkAnalysis/TopHitFit/interface/Top_Decaykin.h"
00038 #include "TopQuarkAnalysis/TopHitFit/interface/Lepjets_Event.h"
00039 #include "TopQuarkAnalysis/TopHitFit/interface/fourvec.h"
00040 #include <cmath>
00041 #include <algorithm>
00042 #include <ostream>
00043 
00044 
00045 using std::sqrt;
00046 using std::abs;
00047 using std::swap;
00048 using std::ostream;
00049 
00050 
00051 namespace hitfit {
00052 
00053 
00054 namespace {
00055 
00056 
00062 Fourvec leptons (const Lepjets_Event& ev)
00063 //
00064 // Purpose: Sum all leptons in EV.
00065 //
00066 // Inputs:
00067 //   ev -          The event.
00068 //
00069 // Returns:
00070 //   The sum of all leptons in EV.
00071 //
00072 {
00073   return (ev.sum (lepton_label) +
00074           ev.sum (electron_label) +
00075           ev.sum (muon_label));
00076 }
00077 
00078 
00079 } // unnamed namespace
00080 
00081 
00082 bool Top_Decaykin::solve_nu_tmass (const Lepjets_Event& ev,
00083                                    double tmass,
00084                                    double& nuz1, double& nuz2)
00085 //
00086 // Purpose: Solve for the neutrino longitudinal z-momentum that makes
00087 //          the leptonic top have mass TMASS.
00088 //
00089 // Inputs:
00090 //   ev -          The event to solve.
00091 //   tmass -       The desired top mass.
00092 //
00093 // Outputs:
00094 //   nuz1 -        First solution (smaller absolute value).
00095 //   nuz2 -        Second solution.
00096 //
00097 // Returns:
00098 //   True if there was a real solution.  False if there were only
00099 //   imaginary solutions.  (In that case, we just set the imaginary
00100 //   part to zero.)
00101 //
00102 {
00103   bool discrim_flag = true;
00104 
00105   const Fourvec& vnu = ev.met ();
00106   Fourvec cprime = leptons (ev) + ev.sum (lepb_label);
00107   double alpha1 = tmass*tmass - cprime.m2();
00108   double a = 2 * 4 * (cprime.z()*cprime.z() - cprime.e()*cprime.e());
00109   double alpha = alpha1 + 2*(cprime.x()*vnu.x() + cprime.y()*vnu.y());
00110   double b = 4 * alpha * cprime.z();
00111   double c = alpha*alpha - 4 * cprime.e()*cprime.e() * vnu.vect().perp2();
00112   double d = b*b - 2*a*c;
00113   if (d < 0) {
00114     discrim_flag = false;
00115     d = 0;
00116   }
00117 
00118   double dd = sqrt (d);
00119   nuz1 = (-b + dd)/a;
00120   nuz2 = (-b - dd)/a;
00121   if (abs (nuz1) > abs (nuz2))
00122     swap (nuz1, nuz2);
00123 
00124   return discrim_flag;
00125 }
00126 
00127 
00128 bool Top_Decaykin::solve_nu_tmass (const Lepjets_Event& ev,
00129                                    double tmass,
00130                                    double& re_nuz1,
00131                                    double& im_nuz1,
00132                                    double& re_nuz2,
00133                                    double& im_nuz2)
00134 //
00135 // Purpose: Solve for the neutrino longitudinal z-momentum that makes
00136 //          the leptonic top have mass TMASS, including the imaginary
00137 //          component of the z-component of the neutrino'somentum.
00138 //
00139 // Inputs:
00140 //   ev -          The event to solve.
00141 //   tmass -       The desired top mass.
00142 //
00143 // Outputs:
00144 //   re_nuz1 -     Real component of the first solution.
00145 //   im_nuz1 -     Imaginary component of the first solution (in the lower half of
00146 //                 the complex plane).
00147 //   re_nuz2 -     Real component of the second solution.
00148 //   im_nuz2 -     Imaginary component of the second solution (in the upper half of
00149 //                 the complex plane).
00150 //
00151 // Returns:
00152 //   True if there was a real solution.  False if there were only
00153 //   complex solutions.
00154 //
00155 {
00156   bool discrim_flag = true;
00157 
00158   const Fourvec& vnu = ev.met ();
00159   Fourvec cprime = leptons (ev) + ev.sum (lepb_label);
00160   double alpha1 = tmass*tmass - cprime.m2();
00161   double a = 2 * 4 * (cprime.z()*cprime.z() - cprime.e()*cprime.e());
00162   // Haryo's note: Here a is equivalent to '2a' in the quadratic
00163   // equation ax^2 + bx + c = 0
00164   double alpha = alpha1 + 2*(cprime.x()*vnu.x() + cprime.y()*vnu.y());
00165   double b = 4 * alpha * cprime.z();
00166   double c = alpha*alpha - 4 * cprime.e()*cprime.e() * vnu.vect().perp2();
00167   double d = b*b - 2*a*c;
00168   if (d < 0) {
00169     discrim_flag = false;
00170   }
00171 
00172   if (discrim_flag) {
00173 
00174       re_nuz1 = (-b + sqrt(d))/a ;
00175       im_nuz1 = 0 ;
00176       re_nuz2 = (-b - sqrt(d))/a ;
00177       im_nuz2 = 0 ;
00178       if (abs(re_nuz1) > abs(re_nuz2)) {
00179           swap(re_nuz1,re_nuz2);
00180       }
00181 
00182   } else {
00183 
00184       // Take absolute value of the imaginary component of nuz, in case
00185       // a is negative, before multiplying by +1 or -1 to get the upper-half
00186       // or lower-half imaginary value.
00187       re_nuz1   = -b / a;
00188       im_nuz1   = -fabs(sqrt(-d)/a );
00189       re_nuz2   = -b / a;
00190       im_nuz2   =  fabs(sqrt(-d)/a );
00191 
00192 
00193   }
00194 
00195 
00196   return discrim_flag;
00197 }
00198 
00199 
00200 bool Top_Decaykin::solve_nu (const Lepjets_Event& ev,
00201                              double wmass,
00202                              double& nuz1,
00203                              double& nuz2)
00204 //
00205 // Purpose: Solve for the neutrino longitudinal z-momentum that makes
00206 //          the leptonic W have mass WMASS.
00207 //
00208 // Inputs:
00209 //   ev -          The event to solve.
00210 //   wmass -       The desired W mass.
00211 //
00212 // Outputs:
00213 //   nuz1 -        First solution (smaller absolute value).
00214 //   nuz2 -        Second solution.
00215 //
00216 // Returns:
00217 //   True if there was a real solution.  False if there were only
00218 //   imaginary solutions.  (In that case, we just set the imaginary
00219 //   part to zero.)
00220 //
00221 {
00222   bool discrim_flag = true;
00223 
00224   Fourvec vnu  = ev.met();
00225   Fourvec vlep = leptons (ev);
00226 
00227   double x = vlep.x()*vnu.x() + vlep.y()*vnu.y() + wmass*wmass/2;
00228   double a = vlep.z()*vlep.z() - vlep.e()*vlep.e();
00229   double b = 2*x*vlep.z();
00230   double c = x*x - vnu.perp2() * vlep.e()*vlep.e();
00231 
00232   double d = b*b - 4*a*c;
00233   if (d < 0) {
00234     d = 0;
00235     discrim_flag = false;
00236   }
00237 
00238   nuz1 = (-b + sqrt (d))/2/a;
00239   nuz2 = (-b - sqrt (d))/2/a;
00240   if (abs (nuz1) > abs (nuz2))
00241     swap (nuz1, nuz2);
00242 
00243   return discrim_flag;
00244 }
00245 
00246 
00247 bool Top_Decaykin::solve_nu (const Lepjets_Event& ev,
00248                              double wmass,
00249                              double& re_nuz1,
00250                              double& im_nuz1,
00251                              double& re_nuz2,
00252                              double& im_nuz2)
00253 //
00254 // Purpose: Solve for the neutrino longitudinal z-momentum that makes
00255 //          the leptonic W have mass WMASS, including the imaginary
00256 //          component of the z-component of the neutrino'somentum.
00257 //
00258 // Inputs:
00259 //   ev -          The event to solve.
00260 //   wmass -       The desired W mass.
00261 //
00262 // Outputs:
00263 //   re_nuz1 -     Real component of the first solution.
00264 //   im_nuz1 -     Imaginary component of the first solution  (in the lower half of
00265 //                 the complex plane).
00266 //   re_nuz2 -     Real component of the second solution.
00267 //   im_nuz2 -     Imaginary component of the second solution  (in the upper half of
00268 //                 the complex plane).
00269 //
00270 // Returns:
00271 //   True if there was a real solution.  False if there were only
00272 //   complex solutions.
00273 //x
00274 {
00275   bool discrim_flag = true;
00276 
00277   Fourvec vnu  = ev.met();
00278   Fourvec vlep = leptons (ev);
00279 
00280   double x = vlep.x()*vnu.x() + vlep.y()*vnu.y() + wmass*wmass/2;
00281   double a = vlep.z()*vlep.z() - vlep.e()*vlep.e();
00282   double b = 2*x*vlep.z();
00283   double c = x*x - vnu.perp2() * vlep.e()*vlep.e();
00284 
00285   double d = b*b - 4*a*c;
00286   if (d < 0) {
00287     discrim_flag = false;
00288   }
00289 
00290   if (discrim_flag) {
00291 
00292       re_nuz1 = (-b + sqrt(d))/2/a ;
00293       im_nuz1 = 0.0 ;
00294       re_nuz2 = (-b - sqrt(d))/2/a ;
00295       im_nuz2 = 0.0 ;
00296       if (fabs(re_nuz1) > fabs(re_nuz2)) {
00297           swap(re_nuz1,re_nuz2);
00298       }
00299 
00300   } else {
00301 
00302       // Take absolute value of the imaginary component of nuz, in case
00303       // a is negative, before multiplying by +1 or -1 to get the upper-half
00304       // or lower-half imaginary value.
00305 
00306       re_nuz1 = -b /2/a ;
00307       im_nuz1 = -fabs(sqrt(-d)/a);
00308       re_nuz2 = -b /2/a ;
00309       im_nuz2 =  fabs(sqrt(-d)/a);
00310 
00311   }
00312 
00313   return discrim_flag;
00314 }
00315 
00316 
00317 Fourvec Top_Decaykin::hadw (const Lepjets_Event& ev)
00318 //
00319 // Purpose: Sum up the appropriate 4-vectors to find the hadronic W.
00320 //
00321 // Inputs:
00322 //   ev -          The event.
00323 //
00324 // Returns:
00325 //   The hadronic W.
00326 //
00327 {
00328   return (ev.sum (hadw1_label) + ev.sum (hadw2_label));
00329 }
00330 
00331 
00332 Fourvec Top_Decaykin::hadw1 (const Lepjets_Event& ev)
00333 //
00334 // Purpose:
00335 //
00336 // Inputs:
00337 //   ev -          The event.
00338 //
00339 // Returns:
00340 //   The higher-pT hadronic jet from W
00341 //
00342 {
00343   return ev.sum (hadw1_label);
00344 }
00345 
00346 
00347 Fourvec Top_Decaykin::hadw2 (const Lepjets_Event& ev)
00348 //
00349 // Purpose:
00350 //
00351 // Inputs:
00352 //   ev -          The event.
00353 //
00354 // Returns:
00355 //   The lower-pT hadronic jet from W
00356 //
00357 //
00358 {
00359   return ev.sum (hadw2_label);
00360 }
00361 
00362 
00363 Fourvec Top_Decaykin::lepw (const Lepjets_Event& ev)
00364 //
00365 // Purpose: Sum up the appropriate 4-vectors to find the leptonic W.
00366 //
00367 // Inputs:
00368 //   ev -          The event.
00369 //
00370 // Returns:
00371 //   The leptonic W.
00372 //
00373 {
00374   return (leptons (ev) + ev.met ());
00375 }
00376 
00377 
00378 Fourvec Top_Decaykin::hadt (const Lepjets_Event& ev)
00379 //
00380 // Purpose: Sum up the appropriate 4-vectors to find the hadronic t.
00381 //
00382 // Inputs:
00383 //   ev -          The event.
00384 //
00385 // Returns:
00386 //   The hadronic t.
00387 //
00388 {
00389   return (ev.sum (hadb_label) + hadw (ev));
00390 }
00391 
00392 
00393 Fourvec Top_Decaykin::lept (const Lepjets_Event& ev)
00394 //
00395 // Purpose: Sum up the appropriate 4-vectors to find the leptonic t.
00396 //
00397 // Inputs:
00398 //   ev -          The event.
00399 //
00400 // Returns:
00401 //   The leptonic t.
00402 //
00403 {
00404   return (ev.sum (lepb_label) + lepw (ev));
00405 }
00406 
00407 
00408 ostream& Top_Decaykin::dump_ev (std::ostream& s, const Lepjets_Event& ev)
00409 //
00410 // Purpose: Print kinematic information for EV.
00411 //
00412 // Inputs:
00413 //   s -           The stream to which to write.
00414 //   ev -          The event to dump.
00415 //
00416 // Returns:
00417 //   The stream S.
00418 //
00419 {
00420   s << ev;
00421   Fourvec p;
00422 
00423   p = lepw (ev);
00424   s << "lepw " << p << " " << p.m() << "\n";
00425   p = lept (ev);
00426   s << "lept " << p << " " << p.m() << "\n";
00427   p = hadw (ev);
00428   s << "hadw " << p << " " << p.m() << "\n";
00429   p = hadt (ev);
00430   s << "hadt " << p << " " << p.m() << "\n";
00431 
00432   return s;
00433 }
00434 
00435 
00436 double Top_Decaykin::cos_theta_star(const Fourvec fermion,
00437                                     const Fourvec W,
00438                                     const Fourvec top)
00439 //
00440 // Purpose: Calculate cos theta star in top decay
00441 //
00442 // Inputs:
00443 //   fermion -     The four momentum of fermion from W
00444 //   W -           The four momentum of W from top
00445 //   top -         The four momentum of top
00446 // Returns:
00447 //   cos theta star
00448 //
00449 {
00450 
00451     if (W.isLightlike() || W.isSpacelike()) {
00452         return 100.0;
00453     }
00454 
00455     CLHEP::HepBoost BoostWCM(W.findBoostToCM());
00456 
00457     CLHEP::Hep3Vector boost_v3fermion       = BoostWCM(fermion).vect();
00458     CLHEP::Hep3Vector boost_v3top           = BoostWCM(top).vect();
00459 
00460     double costhetastar = boost_v3fermion.cosTheta(-boost_v3top);
00461 
00462     return costhetastar;
00463 }
00464 
00465 
00466 double Top_Decaykin::cos_theta_star(const Lepjets_Event& ev)
00467 //
00468 // Purpose: Calculate lepton cos theta star in top decay
00469 //
00470 // Inputs:
00471 //   ev -          A lepton+jets event
00472 // Returns:
00473 //   cos theta star of lepton
00474 //
00475 {
00476 
00477     return cos_theta_star(leptons(ev),
00478                           lepw(ev),
00479                           lept(ev));
00480 
00481 }
00482 
00483 
00484 double Top_Decaykin::cos_theta_star_lept(const Lepjets_Event& ev)
00485 //
00486 // Purpose: Calculate lepton cos theta star in top decay
00487 //
00488 // Inputs:
00489 //   ev -          A lepton+jets event
00490 // Returns:
00491 //   cos theta star of lepton
00492 //
00493 {
00494 
00495     return cos_theta_star(ev);
00496 
00497 }
00498 
00499 
00500 double Top_Decaykin::cos_theta_star_hadt(const Lepjets_Event& ev)
00501 //
00502 // Purpose: Calculate absolute value of cos theta star of
00503 //          one of the hadronic W jet from hadronic top.
00504 //
00505 // Inputs:
00506 //   ev -          A lepton+jets event
00507 // Returns:
00508 //   absolute value of cos theta star
00509 //
00510 {
00511 
00512     return fabs(cos_theta_star(hadw1(ev),
00513                                hadw(ev),
00514                                hadt(ev)));
00515 
00516 }
00517 
00518 
00519 } // namespace hitfit
00520 
00521