CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/TopQuarkAnalysis/TopHitFit/src/fourvec.cc

Go to the documentation of this file.
00001 //
00002 // $Id: fourvec.cc,v 1.1 2011/05/26 09:47:00 mseidel Exp $
00003 //
00004 // File: src/fourvec.cc
00005 // Purpose: Define 3- and 4-vector types for the hitfit package, and
00006 //          supply a few additional operations.
00007 // Created: Jul, 2000, sss, based on run 1 mass analysis code.
00008 //
00009 // CMSSW File      : src/fourvec.cc
00010 // Original Author : Scott Stuart Snyder <snyder@bnl.gov> for D0
00011 // Imported to CMSSW by Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>
00012 //
00013 
00036 #include "TopQuarkAnalysis/TopHitFit/interface/fourvec.h"
00037 #include <cmath>
00038 
00039 using std::fabs;
00040 using std::sqrt;
00041 using std::sin;
00042 using std::cos;
00043 using std::atan;
00044 using std::exp;
00045 using std::log;
00046 using std::tan;
00047 using std::atan2;
00048 
00049 
00050 namespace { // unnamed namespace
00051 
00052 
00053 double cal_th (double theta, double z)
00054 //
00055 // Purpose: Helper for deteta.  Find `calorimeter theta' given
00056 //          physics theta and z-vertex.  Copied from run 1 code.
00057 //
00058 // Inputs:
00059 //   theta -       Physics theta.
00060 //   z -           Z-vertex.
00061 //
00062 // Returns:
00063 //   Calorimeter theta.
00064 //
00065 {
00066   const double R_CC = 91.6;
00067   const double Z_EC = 178.9;
00068   const double BIGG = 1e8;
00069 
00070   double tanth;
00071   if (fabs (cos (theta)) < 1/BIGG)
00072     tanth = BIGG * sin (theta);
00073   else
00074     tanth = tan (theta);
00075 
00076   double z_cc = R_CC / tanth + z;
00077 
00078   if (fabs (z_cc) < Z_EC)
00079     theta = atan2 (R_CC, z_cc);
00080 
00081   else {
00082     double zz = Z_EC;
00083     if (tanth < 0) zz = - zz;
00084     double r_ec = (zz-z) * tanth;
00085     theta = atan2 (r_ec, zz);
00086   }
00087 
00088   if (theta < 0) theta += 2 * M_PI;
00089   return theta;
00090 }
00091 
00092 
00093 } // unnamed namespace
00094 
00095 
00096 namespace hitfit {
00097 
00098 
00099 void adjust_p_for_mass (Fourvec& v, double mass)
00100 //
00101 // Purpose: Adjust the 3-vector part of V (leaving the energy unchanged)
00102 //          so that it has mass MASS.  (Provided that is possible.)
00103 //
00104 // Inputs:
00105 //   v -           The 4-vector to scale.
00106 //   mass -        The desired mass of the 4-vector.
00107 //
00108 // Outputs:
00109 //   v -           The scaled 4-vector.
00110 //
00111 {
00112   CLHEP::Hep3Vector vect = v.vect();
00113   double old_p2 = vect.mag2();
00114   if (old_p2 == 0)
00115     return;
00116   double new_p2 = v.e()*v.e() - mass*mass;
00117   if (new_p2 < 0)
00118     new_p2 = 0;
00119   vect *= sqrt (new_p2 / old_p2);
00120   v.setVect (vect);
00121 }
00122 
00123 
00124 void adjust_e_for_mass (Fourvec& v, double mass)
00125 //
00126 // Purpose: Adjust the energy component of V (leaving the 3-vector part
00127 //          unchanged) so that it has mass MASS.
00128 //
00129 // Inputs:
00130 //   v -           The 4-vector to scale.
00131 //   mass -        The desired mass of the 4-vector.
00132 //
00133 // Outputs:
00134 //   v -           The scaled 4-vector.
00135 //
00136 {
00137   v.setE (sqrt (v.vect().mag2() + mass*mass));
00138 }
00139 
00140 
00141 void rottheta (Fourvec& v, double theta)
00142 //
00143 // Purpose: Rotate V through polar angle THETA.
00144 //
00145 // Inputs:
00146 //   v -           The 4-vector to rotate.
00147 //   theta -       The rotation angle.
00148 //
00149 // Outputs:
00150 //   v -           The rotated 4-vector.
00151 //
00152 {
00153   double s = sin (theta), c = cos (theta);
00154   double old_pt = v.perp();
00155   double new_pt =  old_pt*c - v.z()*s;
00156   v.setZ (old_pt*s + v.z()*c);
00157 
00158   v.setX (v.x() * new_pt / old_pt);
00159   v.setY (v.y() * new_pt / old_pt);
00160 }
00161 
00162 
00163 void roteta (Fourvec& v, double eta)
00164 //
00165 // Purpose: Rotate a Fourvec through a polar angle such that
00166 //          its pseudorapidity changes by ETA.
00167 //
00168 // Inputs:
00169 //   v -           The 4-vector to rotate.
00170 //   eta -         The rotation angle.
00171 //
00172 // Outputs:
00173 //   v -           The rotated 4-vector.
00174 //
00175 {
00176   double theta1 = v.theta ();
00177   double eta1 = theta_to_eta (theta1);
00178   double eta2 = eta1 + eta;
00179   double theta2 = eta_to_theta (eta2);
00180 
00181   rottheta (v, theta1 - theta2);
00182 }
00183 
00184 
00185 double eta_to_theta (double eta)
00186 //
00187 // Purpose: Convert psuedorapidity to polar angle.
00188 //
00189 // Inputs:
00190 //   eta -         Pseudorapidity.
00191 //
00192 // Returns:
00193 //   Polar angle.
00194 //
00195 {
00196   return 2 * atan (exp (-eta));
00197 }
00198 
00199 
00200 double theta_to_eta (double theta)
00201 //
00202 // Purpose: Convert polar angle to psuedorapidity.
00203 //
00204 // Inputs:
00205 //   theta -       Polar angle.
00206 //
00207 // Returns:
00208 //   Pseudorapidity.
00209 //
00210 {
00211   return - log (tan (theta / 2));
00212 }
00213 
00214 
00215 double deteta (const Fourvec& v, double zvert)
00216 //
00217 // Purpose: Get the detector eta (D0-specific).
00218 //
00219 // Inputs:
00220 //   v -           Vector on which to operate.
00221 //   zvert -       Z-vertex.
00222 //
00223 // Returns:
00224 //   Detector eta of V.
00225 //
00226 {
00227   return theta_to_eta (cal_th (v.theta(), zvert));
00228 }
00229 
00230 
00231 double phidiff (double phi)
00232 //
00233 // Purpose: Handle wraparound for a difference in azimuthal angles.
00234 //
00235 // Inputs:
00236 //   phi -         Azimuthal angle.
00237 //
00238 // Returns:
00239 //   PHI normalized to the range -pi .. pi.
00240 //
00241 {
00242   while (phi < -M_PI)
00243     phi += 2 * M_PI;
00244   while (phi > M_PI)
00245     phi -= 2*M_PI;
00246   return phi;
00247 }
00248 
00249 
00250 double delta_r (const Fourvec& a, const Fourvec& b)
00251 //
00252 // Purpose: Find the distance in R between two four-vectors.
00253 //
00254 // Inputs:
00255 //   a -           First four-vector.
00256 //   b -           Second four-vector.
00257 //
00258 // Returns:
00259 //   the distance in R between A and B.
00260 //
00261 {
00262   double deta = a.pseudoRapidity() - b.pseudoRapidity();
00263   double dphi = phidiff (a.phi() - b.phi());
00264   return sqrt (deta*deta + dphi*dphi);
00265 }
00266 
00267 
00268 } // namespace hitfit