CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/TopQuarkAnalysis/TopHitFit/src/Resolution.cc

Go to the documentation of this file.
00001 //
00002 // $Id: Resolution.cc,v 1.1 2011/05/26 09:47:00 mseidel Exp $
00003 //
00004 // File: src/Resolution.cc
00005 // Purpose: Calculate resolutions for a quantity.
00006 // Created: Jul, 2000, sss, based on run 1 mass analysis code.
00007 //
00008 // CMSSW File      : src/Resolution.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 
00035 #include "TopQuarkAnalysis/TopHitFit/interface/Resolution.h"
00036 #include "CLHEP/Random/RandGauss.h"
00037 #include <cmath>
00038 #include <iostream>
00039 #include <cctype>
00040 #include <cstdlib>
00041 
00042 
00043 using std::sqrt;
00044 using std::ostream;
00045 using std::string;
00046 using std::isspace;
00047 using std::isdigit;
00048 #ifndef __GNUC__
00049 using std::atof;
00050 #endif
00051 
00052 
00053 
00054 namespace {
00055 
00056 
00057 bool get_field (string s, string::size_type i, double& x)
00058 //
00059 // Purpose: Scan string S starting at position I.
00060 //          Find the value of the first floating-point number we
00061 //          find there.
00062 //
00063 // Inputs:
00064 //   s -           The string to scan.
00065 //   i -           Starting character position in the string.
00066 //
00067 // Outputs:
00068 //   x -           The value of the number we found.
00069 //
00070 // Returns:
00071 //   True if we found something that looks like a number, false otherwise.
00072 //
00073 {
00074   string::size_type j = i;
00075   while (j < s.size() && s[j] != ',' && !isdigit (s[j]) && s[j] != '.')
00076     ++j;
00077   if (j < s.size() && (isdigit (s[j]) || s[j] == '.')) {
00078     x = atof (s.c_str() + j);
00079     return true;
00080   }
00081   return false;
00082 }
00083 
00084 
00085 } // unnamed namespace
00086 
00087 
00088 namespace hitfit {
00089 
00090 
00091 Resolution::Resolution (std::string s /*= ""*/)
00092 //
00093 // Purpose: Constructor.
00094 //
00095 // Inputs:
00096 //   s -           String encoding the resolution parameters, as described
00097 //                 in the comments in the header.
00098 //
00099         :_resolution_exponent(0)
00100 {
00101   _inverse = false;
00102   _constant_sigma = 0;
00103   _resolution_sigma = 0;
00104   _noise_sigma = 0;
00105 
00106   // Skip spaces.
00107   double x;
00108   string::size_type i = 0;
00109   while (i < s.size() && isspace (s[i]))
00110     ++i;
00111 
00112   // Check for the inverse flag.
00113   if (s[i] == '-') {
00114     _inverse = true;
00115     ++i;
00116   }
00117   else if (s[i] == '+') {
00118     ++i;
00119   }
00120 
00121   // Get the constant term.
00122   if (get_field (s, i, x)) _constant_sigma = x;
00123   i = s.find (',', i);
00124 
00125   // Look for a resolution term.
00126   if (i != string::npos) {
00127     ++i;
00128     if (get_field (s, i, x)) _resolution_sigma = x;
00129 
00130     // Look for a noise term.
00131     i = s.find (',', i);
00132     if (i != string::npos) {
00133       if (get_field (s, i+1, x)) _noise_sigma = x;
00134     }
00135   }
00136 }
00137 
00138 
00139 Resolution::Resolution (double C,
00140                         double R,
00141                         double m,
00142                         double N,
00143                         bool inverse /*= false*/)
00144   : _constant_sigma (C),
00145     _resolution_sigma (R),
00146     _resolution_exponent(m),
00147     _noise_sigma (N),
00148     _inverse (inverse)
00149 {
00150 }
00151 
00152 
00153 Resolution::Resolution (double res,
00154                         bool inverse /*= false*/)
00155 //
00156 // Purpose: Constructor, to give a constant resolution.
00157 //          I.e., sigma() will always return RES.
00158 //
00159 // Inputs:
00160 //   res -         The resolution value.
00161 //   inverse -     The inverse flag.
00162 //
00163   : _constant_sigma (0),
00164     _resolution_sigma (0),
00165     _resolution_exponent(0),
00166     _noise_sigma (res),
00167     _inverse (inverse)
00168 {
00169 }
00170 
00171 
00172 bool Resolution::inverse () const
00173 //
00174 // Purpose: Return the inverse flag.
00175 //
00176 // Returns:
00177 //   The inverse flag.
00178 //
00179 {
00180   return _inverse;
00181 }
00182 
00183 
00184 double Resolution::C() const
00185 {
00186     return _constant_sigma;
00187 }
00188 
00189 
00190 double Resolution::R() const
00191 {
00192     return _resolution_sigma;
00193 }
00194 
00195 
00196 double Resolution::m() const
00197 {
00198     return _resolution_exponent;
00199 }
00200 
00201 
00202 double Resolution::N() const
00203 {
00204     return _noise_sigma;
00205 }
00206 
00207 
00208 double Resolution::sigma (double p) const
00209 //
00210 // Purpose: Return the uncertainty for a momentum P.
00211 //
00212 // Inputs:
00213 //    p -          The momentum
00214 //
00215 // Returns:
00216 //   The uncertainty for a momentum P.
00217 //
00218 {
00219   if (_inverse)
00220     p = 1 / p;
00221 
00222   return sqrt ((_constant_sigma*_constant_sigma*p +
00223         _resolution_sigma*_resolution_sigma)*p +
00224            _noise_sigma*_noise_sigma);
00225 }
00226 
00227 
00228 double Resolution::pick (double x, double p, CLHEP::HepRandomEngine& engine) const
00229 //
00230 // Purpose: Given a value X, measured for an object with momentum P, 
00231 //          pick a new value from a Gaussian distribution
00232 //          described by this resolution --- with mean X and width sigma(P).
00233 //
00234 // Inputs:
00235 //    x -          The quantity value (distribution mean).
00236 //    p -          The momentum, for calculating the width.
00237 //    engine -     The underlying RNG.
00238 //
00239 // Returns:
00240 //   A smeared value of X.
00241 //
00242 {
00243   CLHEP::RandGauss gen (engine);
00244   if (_inverse)
00245     return 1 / gen.fire (1 / x, sigma (p));
00246   else
00247     return gen.fire (x, sigma (p));
00248 }
00249 
00250 
00259 std::ostream& operator<< (std::ostream& s, const Resolution& r)
00260 //
00261 // Purpose: Dump this object to S.
00262 //
00263 // Inputs:
00264 //    s -          The stream to which to write.
00265 //    r -          The object to dump.
00266 //
00267 // Returns:
00268 //   The stream S.
00269 //   
00270 {
00271   if (r._inverse) s << "-";
00272   s << r._constant_sigma << ","
00273     << r._resolution_sigma << ","
00274     << r._noise_sigma;
00275   return s;
00276 }
00277 
00278 
00279 } // namespace hitfit