CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/TopQuarkAnalysis/TopHitFit/src/gentop.cc

Go to the documentation of this file.
00001 //
00002 // $Id: gentop.cc,v 1.1 2011/05/26 09:47:00 mseidel Exp $
00003 //
00004 // File: src/gentop.cc
00005 // Purpose: Toy ttbar event generator for testing.
00006 // Created: Jul, 2000, sss.
00007 //
00008 // CMSSW File      : src/gentop.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 
00038 #include "TopQuarkAnalysis/TopHitFit/interface/gentop.h"
00039 #include "CLHEP/Random/RandFlat.h"
00040 #include "CLHEP/Random/RandExponential.h"
00041 #include "CLHEP/Random/RandBreitWigner.h"
00042 #include "CLHEP/Random/RandGauss.h"
00043 #include "CLHEP/Units/PhysicalConstants.h"
00044 #include "TopQuarkAnalysis/TopHitFit/interface/fourvec.h"
00045 #include "TopQuarkAnalysis/TopHitFit/interface/Lepjets_Event.h"
00046 #include "TopQuarkAnalysis/TopHitFit/interface/Defaults.h"
00047 #include <cmath>
00048 #include <ostream>
00049 
00050 
00051 using std::ostream;
00052 
00053 
00054 // Event number counter.
00058 namespace {
00059 int next_evnum = 0;
00060 }
00061 
00062 
00063 namespace hitfit {
00064 
00065 
00066 //**************************************************************************
00067 // Argument handling.
00068 //
00069 
00070 
00071 Gentop_Args::Gentop_Args (const Defaults& defs)
00072 //
00073 // Purpose: Constructor.
00074 //
00075 // Inputs:
00076 //   defs -        The Defaults instance from which to initialize.
00077 //
00078   : _t_pt_mean      (defs.get_float ("t_pt_mean")),
00079     _mt             (defs.get_float ("mt")),
00080     _sigma_mt       (defs.get_float ("sigma_mt")),
00081     _mh             (defs.get_float ("mh")),
00082     _sigma_mh       (defs.get_float ("sigma_mh")),
00083     _recoil_pt_mean (defs.get_float ("recoil_pt_mean")),
00084     _boost_sigma    (defs.get_float ("boost_sigma")),
00085     _m_boost        (defs.get_float ("m_boost")),
00086     _mb             (defs.get_float ("mb")),
00087     _sigma_mb       (defs.get_float ("sigma_mb")),
00088     _mw             (defs.get_float ("mw")),
00089     _sigma_mw       (defs.get_float ("sigma_mw")),
00090     _svx_tageff     (defs.get_float ("svx_tageff")),
00091     _smear          (defs.get_bool ("smear")),
00092     _smear_dir      (defs.get_bool ("smear_dir")),
00093     _muon           (defs.get_bool ("muon")),
00094     _ele_res_str    (defs.get_string ("ele_res_str")),
00095     _muo_res_str    (defs.get_string ("muo_res_str")),
00096     _jet_res_str    (defs.get_string ("jet_res_str")),
00097     _kt_res_str     (defs.get_string ("kt_res_str"))
00098 {
00099 }
00100 
00101 
00102 double Gentop_Args::t_pt_mean () const
00103 //
00104 // Purpose: Return the t_pt_mean parameter.
00105 //          See the header for documentation.
00106 //
00107 {
00108   return _t_pt_mean;
00109 }
00110 
00111 
00112 double Gentop_Args::mt () const
00113 //
00114 // Purpose: Return the mt parameter.
00115 //          See the header for documentation.
00116 //
00117 {
00118   return _mt;
00119 }
00120 
00121 
00122 double Gentop_Args::sigma_mt () const
00123 //
00124 // Purpose: Return the sigma_mt parameter.
00125 //          See the header for documentation.
00126 //
00127 {
00128   return _sigma_mt;
00129 }
00130 
00131 
00132 double Gentop_Args::svx_tageff () const
00133 //
00134 // Purpose: Return the svx_tageff parameter.
00135 //          See the header for documentation.
00136 //
00137 {
00138   return _svx_tageff;
00139 }
00140 
00141 
00142 double Gentop_Args::mh () const
00143 //
00144 // Purpose: Return the mh parameter.
00145 //          See the header for documentation.
00146 //
00147 {
00148   return _mh;
00149 }
00150 
00151 
00152 double Gentop_Args::sigma_mh () const
00153 //
00154 // Purpose: Return the sigma_mh parameter.
00155 //          See the header for documentation.
00156 //
00157 {
00158   return _sigma_mh;
00159 }
00160 
00161 
00162 bool Gentop_Args::smear () const
00163 //
00164 // Purpose: Return the smear parameter.
00165 //          See the header for documentation.
00166 //
00167 {
00168   return _smear;
00169 }
00170 
00171 
00172 bool Gentop_Args::smear_dir () const
00173 //
00174 // Purpose: Return the smear_dir parameter.
00175 //          See the header for documentation.
00176 //
00177 {
00178   return _smear_dir;
00179 }
00180 
00181 
00182 bool Gentop_Args::muon () const
00183 //
00184 // Purpose: Return the muon parameter.
00185 //          See the header for documentation.
00186 //
00187 {
00188   return _muon;
00189 }
00190 
00191 
00192 double Gentop_Args::recoil_pt_mean () const
00193 //
00194 // Purpose: Return the recoil_pt_mean parameter.
00195 //          See the header for documentation.
00196 //
00197 {
00198   return _recoil_pt_mean;
00199 }
00200 
00201 
00202 double Gentop_Args::boost_sigma () const
00203 //
00204 // Purpose: Return the boost_sigma parameter.
00205 //          See the header for documentation.
00206 //
00207 {
00208   return _boost_sigma;
00209 }
00210 
00211 
00212 double Gentop_Args::m_boost () const
00213 //
00214 // Purpose: Return the m_boost parameter.
00215 //          See the header for documentation.
00216 //
00217 {
00218   return _m_boost;
00219 }
00220 
00221 
00222 double Gentop_Args::mb () const
00223 //
00224 // Purpose: Return the mb parameter.
00225 //          See the header for documentation.
00226 //
00227 {
00228   return _mb;
00229 }
00230 
00231 
00232 double Gentop_Args::sigma_mb () const
00233 //
00234 // Purpose: Return the sigma_mb parameter.
00235 //          See the header for documentation.
00236 //
00237 {
00238   return _sigma_mb;
00239 }
00240 
00241 
00242 double Gentop_Args::mw () const
00243 //
00244 // Purpose: Return the mw parameter.
00245 //          See the header for documentation.
00246 //
00247 {
00248   return _mw;
00249 }
00250 
00251 
00252 double Gentop_Args::sigma_mw () const
00253 //
00254 // Purpose: Return the sigma_mw parameter.
00255 //          See the header for documentation.
00256 //
00257 {
00258   return _sigma_mw;
00259 }
00260 
00261 
00262 std::string Gentop_Args::ele_res_str () const
00263 //
00264 // Purpose: Return the ele_res_str parameter.
00265 //          See the header for documentation.
00266 //
00267 {
00268   return _ele_res_str;
00269 }
00270 
00271 
00272 std::string Gentop_Args::muo_res_str () const
00273 //
00274 // Purpose: Return the muo_res_str parameter.
00275 //          See the header for documentation.
00276 //
00277 {
00278   return _muo_res_str;
00279 }
00280 
00281 
00282 std::string Gentop_Args::jet_res_str () const
00283 //
00284 // Purpose: Return the jet_res_str parameter.
00285 //          See the header for documentation.
00286 //
00287 {
00288   return _jet_res_str;
00289 }
00290 
00291 
00292 std::string Gentop_Args::kt_res_str () const
00293 //
00294 // Purpose: Return the kt_res_str parameter.
00295 //          See the header for documentation.
00296 //
00297 {
00298   return _kt_res_str;
00299 }
00300 
00301 
00302 //**************************************************************************
00303 // Internal helper functions.
00304 //
00305 
00306 
00307 namespace {
00308 
00309 
00316 Threevec rand_spher (CLHEP::HepRandomEngine& engine)
00317 //
00318 // Purpose: Return a unit vector with (theta, phi) uniformly distributed
00319 //          over a sphere.
00320 //
00321 // Inputs:
00322 //   engine -      The underlying RNG.
00323 //
00324 // Returns:
00325 //   The generated vector.
00326 //
00327 {
00328   CLHEP::RandFlat r (engine);
00329 
00330   Threevec v;
00331 
00332   double U = r.fire(0.0,1.0);
00333   double V = r.fire(0.0,1.0);
00334 
00335   double theta = 2.0*CLHEP::pi*U ;
00336   double phi   = acos(2*V - 1.0);
00337 
00338   double x = sin(theta)*cos(phi);
00339   double y = sin(theta)*sin(phi);
00340   double z = cos(theta);
00341 
00342   v = Threevec(x,y,z);
00343 
00344   return v.unit ();
00345 }
00346 
00347 
00362 Fourvec make_massive (const Threevec& p,
00363                       double m_true,
00364                       double sigma,
00365                       CLHEP::HepRandomEngine& engine)
00366 //
00367 // Purpose: Given a direction, mass, and width, choose a mass from a
00368 //          Breit-Wigner and return a 4-vector with the chosen mass
00369 //          and the specified direction.
00370 //
00371 // Inputs:
00372 //   p -           The direction.
00373 //   m_true -      The mean for the Breit-Wigner.
00374 //   sigma -       The width for the Breit-Wigner.
00375 //   engine -      The underlying RNG.
00376 //
00377 // Returns:
00378 //   The generated 4-vector.
00379 //
00380 {
00381   CLHEP::RandBreitWigner rbw (engine);
00382   double m = rbw.fire (m_true, sigma);
00383   return Fourvec (p, sqrt (m*m + p.mag2()));
00384 }
00385 
00403 void decay (const Fourvec& v, double m1, double m2,
00404             CLHEP::HepRandomEngine& engine,
00405             Fourvec& vout1, Fourvec& vout2)
00406 //
00407 // Purpose: v decays into two particles w/masses m1, m2.
00408 //
00409 // Inputs:
00410 //   v -           The incoming 4-vector.
00411 //   m1 -          Mass of the first decay product.
00412 //   m2 -          Mass of the second decay product.
00413 //   engine -      The underlying RNG.
00414 //
00415 // Outputs:
00416 //   vout1 -       Outgoing 4-vector of the first decay product.
00417 //   vout2 -       Outgoing 4-vector of the second decay product.
00418 //
00419 {
00420   // Construct a decay in the incoming particle's rest frame,
00421   // uniformly distributed in direction.
00422   Threevec p = rand_spher (engine);
00423   double m0 = v.m();
00424 
00425   if (m1 + m2 > m0) {
00426     // What ya gonna do?
00427     double f = m0 / (m1 + m2);
00428     m1 *= f;
00429     m2 *= f;
00430   }
00431 
00432   double m0_2 = m0*m0;
00433   double m1_2 = m1*m1;
00434   double m2_2 = m2*m2;
00435 
00436   // Calculate the 3-momentum of each particle in the decay frame.
00437   p *= 0.5/m0 * sqrt (    m0_2*m0_2 +   m1_2*m1_2 +   m2_2*m2_2
00438                       - 2*m0_2*m1_2 - 2*m0_2*m2_2 - 2*m1_2*m2_2);
00439   double p2 = p.mag2();
00440 
00441   vout1 = Fourvec ( p, sqrt (p2 + m1_2));
00442   vout2 = Fourvec (-p, sqrt (p2 + m2_2));
00443 
00444   // Boost out of the rest frame.
00445   vout1.boost (v.boostVector ());
00446   vout2.boost (v.boostVector ());
00447 }
00448 
00449 
00459 Threevec rand_pt (double pt_mean,
00460                   CLHEP::HepRandomEngine& engine)
00461 //
00462 // Purpose: Generate a vector in a (uniformly) random direction,
00463 //          with pt chosen from an exponential distribution with mean pt_mean.
00464 //
00465 // Inputs:
00466 //   pt_mean -     The mean of the distribution.
00467 //   engine -      The underlying RNG.
00468 //
00469 // Returns:
00470 //   The generated vector.
00471 //
00472 {
00473   CLHEP::RandExponential rexp (engine);
00474 
00475   // A random direction.
00476   Threevec p = rand_spher (engine);
00477 
00478   // Scale by random pt.
00479   p *= (rexp.fire (pt_mean) / p.perp());
00480 
00481   return p;
00482 }
00483 
00484 
00492 Fourvec rand_boost (const Gentop_Args& args, CLHEP::HepRandomEngine& engine)
00493 //
00494 // Purpose: Generate a random boost for the event.
00495 //
00496 // Inputs:
00497 //   args -        The parameter settings.
00498 //   engine -      The underlying RNG.
00499 //
00500 // Returns:
00501 //   The generated boost.
00502 //
00503 {
00504   CLHEP::RandExponential rexp (engine);
00505   CLHEP::RandFlat rflat (engine);
00506   CLHEP::RandGauss rgauss (engine);
00507 
00508   // Boost in pt and z.
00509   Threevec p (1, 0, 0);
00510   p.rotateZ (rflat.fire (0, 2 * M_PI));
00511   p *= rexp.fire (args.recoil_pt_mean());
00512   p.setZ (rgauss.fire (0, args.boost_sigma()));
00513   return Fourvec (p, sqrt (p.mag2() + args.m_boost()*args.m_boost()));
00514 }
00515 
00516 
00526 void tagsim (const Gentop_Args& args,
00527              Lepjets_Event& ev,
00528              CLHEP::HepRandomEngine& engine)
00529 //
00530 // Purpose: Simulate SVX tagging.
00531 //
00532 // Inputs:
00533 //   args -        The parameter settings.
00534 //   ev -          The event to tag.
00535 //   engine -      The underlying RNG.
00536 //
00537 // Outputs:
00538 //   ev -          The event with tags filled in.
00539 //
00540 {
00541   CLHEP::RandFlat rflat (engine);
00542   for (std::vector<Lepjets_Event_Jet>::size_type i=0; i < ev.njets(); i++) {
00543     int typ = ev.jet(i).type();
00544     if (typ == hadb_label || typ == lepb_label || typ == higgs_label) {
00545       if (rflat.fire() < args.svx_tageff())
00546         ev.jet(i).svx_tag() = true;
00547     }
00548   }
00549 }
00550 
00551 
00552 } // unnamed namespace
00553 
00554 
00555 //**************************************************************************
00556 // External interface.
00557 //
00558 
00559 
00560 Lepjets_Event gentop (const Gentop_Args& args,
00561                       CLHEP::HepRandomEngine& engine)
00562 //
00563 // Purpose: Generate a ttbar -> ljets event.
00564 //
00565 // Inputs:
00566 //   args -        The parameter settings.
00567 //   engine -      The underlying RNG.
00568 //
00569 // Returns:
00570 //   The generated event.
00571 //
00572 {
00573   CLHEP::RandBreitWigner rbw (engine);
00574   CLHEP::RandGauss rgauss (engine);
00575 
00576   // Get the t decay momentum in the ttbar rest frame.
00577   Threevec p = rand_pt (args.t_pt_mean(), engine);
00578 
00579   // Make the t/tbar vectors.
00580   Fourvec lept = make_massive ( p, args.mt(), args.sigma_mt(), engine);
00581   Fourvec hadt = make_massive (-p, args.mt(), args.sigma_mt(), engine);
00582 
00583   // Boost the rest frame.
00584   Fourvec boost = rand_boost (args, engine);
00585   lept.boost (boost.boostVector());
00586   hadt.boost (boost.boostVector());
00587 
00588   // Decay t -> b W, leptonic side.
00589   Fourvec lepb, lepw;
00590   double mlb = rgauss.fire (args.mb(), args.sigma_mb());
00591   double mlw = rbw.fire (args.mw(), args.sigma_mw());
00592   decay (lept, 
00593          mlb,
00594          mlw,
00595          engine,
00596          lepb,
00597          lepw);
00598 
00599   // Decay t -> b W, hadronic side.
00600   Fourvec hadb, hadw;
00601   double mhb = rgauss.fire (args.mb(), args.sigma_mb());
00602   double mhw = rbw.fire (args.mw(), args.sigma_mw());
00603   decay (hadt, 
00604          mhb,
00605          mhw,
00606          engine,
00607          hadb,
00608          hadw);
00609 
00610   // Decay W -> l nu.
00611   Fourvec lep, nu;
00612   decay (lepw, 0, 0, engine, lep, nu);
00613 
00614   // Decay W -> qqbar.
00615   Fourvec q1, q2;
00616   decay (hadw, 0, 0, engine, q1, q2);
00617 
00618   // Fill in the event.
00619   Lepjets_Event ev (0, ++next_evnum);
00620   Vector_Resolution lep_res (args.muon() ? 
00621                              args.muo_res_str() :
00622                              args.ele_res_str());
00623   Vector_Resolution jet_res (args.jet_res_str());
00624   Resolution kt_res = (args.kt_res_str());
00625 
00626   ev.add_lep (Lepjets_Event_Lep (lep,
00627                                  args.muon() ? muon_label : electron_label,
00628                                  lep_res));
00629 
00630   ev.add_jet (Lepjets_Event_Jet (lepb,  lepb_label, jet_res));
00631   ev.add_jet (Lepjets_Event_Jet (hadb,  hadb_label, jet_res));
00632   ev.add_jet (Lepjets_Event_Jet (  q1, hadw1_label, jet_res));
00633   ev.add_jet (Lepjets_Event_Jet (  q2, hadw2_label, jet_res));
00634 
00635   ev.met() = nu;
00636   ev.kt_res() = kt_res;
00637 
00638   // Simulate SVX tagging.
00639   tagsim (args, ev, engine);
00640 
00641   // Smear the event, if requested.
00642   if (args.smear())
00643     ev.smear (engine, args.smear_dir());
00644 
00645   // Done!
00646   return ev;
00647 }
00648 
00649 
00650 Lepjets_Event gentth (const Gentop_Args& args,
00651                       CLHEP::HepRandomEngine& engine)
00652 //
00653 // Purpose: Generate a ttH -> ljets event.
00654 //
00655 // Inputs:
00656 //   args -        The parameter settings.
00657 //   engine -      The underlying RNG.
00658 //
00659 // Returns:
00660 //   The generated event.
00661 //
00662 {
00663   CLHEP::RandBreitWigner rbw (engine);
00664   CLHEP::RandGauss rgauss (engine);
00665 
00666   // Generate three-vectors for two tops.
00667   Threevec p_t1 = rand_pt (args.t_pt_mean(), engine);
00668   Threevec p_t2 = rand_pt (args.t_pt_mean(), engine);
00669 
00670   // Conserve momentum.
00671   Threevec p_h = -(p_t1 + p_t2);
00672 
00673   // Construct the 4-vectors.
00674   Fourvec lept = make_massive  (p_t1, args.mt(), args.sigma_mt(), engine);
00675   Fourvec hadt = make_massive  (p_t2, args.mt(), args.sigma_mt(), engine);
00676   Fourvec higgs = make_massive ( p_h, args.mh(), args.sigma_mh(), engine);
00677 
00678   // Boost the rest frame.
00679   Fourvec boost = rand_boost (args, engine);
00680   lept.boost (boost.boostVector());
00681   hadt.boost (boost.boostVector());
00682   higgs.boost (boost.boostVector());
00683 
00684   // Decay t -> b W, leptonic side.
00685   Fourvec lepb, lepw;
00686   decay (lept, 
00687          rgauss.fire (args.mb(), args.sigma_mb()),
00688          rbw.fire (args.mw(), args.sigma_mw()),
00689          engine,
00690          lepb,
00691          lepw);
00692 
00693   // Decay t -> b W, hadronic side.
00694   Fourvec hadb, hadw;
00695   decay (hadt, 
00696          rgauss.fire (args.mb(), args.sigma_mb()),
00697          rbw.fire (args.mw(), args.sigma_mw()),
00698          engine,
00699          hadb,
00700          hadw);
00701 
00702   // Decay W -> l nu.
00703   Fourvec lep, nu;
00704   decay (lepw, 0, 0, engine, lep, nu);
00705 
00706   // Decay W -> qqbar.
00707   Fourvec q1, q2;
00708   decay (hadw, 0, 0, engine, q1, q2);
00709 
00710   // Decay H -> bbbar.
00711   Fourvec hb1, hb2;
00712   decay (higgs, 
00713          rgauss.fire (args.mb(), args.sigma_mb()),
00714          rgauss.fire (args.mb(), args.sigma_mb()),
00715          engine,
00716          hb1,
00717          hb2);
00718 
00719   // Fill in the event.
00720   Lepjets_Event ev (0, ++next_evnum);
00721   Vector_Resolution lep_res (args.muon() ? 
00722                              args.muo_res_str() :
00723                              args.ele_res_str());
00724   Vector_Resolution jet_res (args.jet_res_str());
00725   Resolution kt_res = (args.kt_res_str());
00726 
00727   ev.add_lep (Lepjets_Event_Lep (lep,
00728                                  args.muon() ? muon_label : electron_label,
00729                                  lep_res));
00730 
00731   ev.add_jet (Lepjets_Event_Jet (lepb,  lepb_label, jet_res));
00732   ev.add_jet (Lepjets_Event_Jet (hadb,  hadb_label, jet_res));
00733   ev.add_jet (Lepjets_Event_Jet (  q1, hadw1_label, jet_res));
00734   ev.add_jet (Lepjets_Event_Jet (  q2, hadw2_label, jet_res));
00735   ev.add_jet (Lepjets_Event_Jet ( hb1, higgs_label, jet_res));
00736   ev.add_jet (Lepjets_Event_Jet ( hb2, higgs_label, jet_res));
00737 
00738   ev.met() = nu;
00739   ev.kt_res() = kt_res;
00740 
00741   // Simulate SVX tagging.
00742   tagsim (args, ev, engine);
00743 
00744   // Smear the event, if requested.
00745   if (args.smear())
00746     ev.smear (engine, args.smear_dir());
00747 
00748   // Done!
00749   return ev;
00750 }
00751 
00752 
00753 } // namespace hitfit