Go to the documentation of this file.00001 #include "TrackingTools/GsfTools/interface/GSUtilities.h"
00002
00003 #include <TMath.h>
00004
00005
00006 #include <cmath>
00007
00008 #include <map>
00009 #include <functional>
00010
00011 float
00012 GSUtilities::quantile (const float q) const
00013 {
00014 float qq = q;
00015 if (q>1) qq = 1;
00016 else if (q<0) qq = 0;
00017
00018
00019
00020 int iwMax(-1);
00021 float wMax(0.);
00022 for ( unsigned i=0; i<theNComp; i++ ) {
00023 if ( theWeights[i]>wMax ) {
00024 iwMax = i;
00025 wMax = theWeights[i];
00026 }
00027 }
00028
00029
00030
00031
00032
00033
00034 double x1(theParameters[iwMax]);
00035 double y1(cdf(x1)-qq);
00036 double dx = y1>0. ? -theErrors[iwMax] : theErrors[iwMax];
00037 double x2(x1+dx);
00038 double y2(cdf(x2)-qq);
00039 int cnt =0;
00040 while ( y1*y2>0. ) {
00041 x1 = x2;
00042 y1 = y2;
00043 x2 += dx;
00044 y2 = cdf(x2) - qq;
00045 cnt++;
00046 }
00047
00048
00049
00050
00051
00052 double x(0.);
00053 while ( true ) {
00054
00055 x = -(x2*y1-x1*y2)/(y2-y1);
00056 double y = cdf(x) - qq;
00057
00058 if ( fabs(y)<1.e-6 ) break;
00059 if ( y*y1>0. ) {
00060 y1 = y;
00061 x1 = x;
00062 }
00063 else {
00064 y2 = y;
00065 x2 = x;
00066 }
00067 }
00068 return x;
00069 }
00070
00071
00072 float
00073 GSUtilities::errorHighestWeight() const
00074 {
00075 int iwMax(-1);
00076 float wMax(0.);
00077 for ( unsigned i=0; i<theNComp; i++ ) {
00078 if ( theWeights[i]>wMax ) {
00079 iwMax = i;
00080 wMax = theWeights[i];
00081 }
00082 }
00083 return theErrors[iwMax];
00084 }
00085
00086
00087 float
00088 GSUtilities::mode () const
00089 {
00090
00091
00092
00093 typedef std::multimap<double, double, std::greater<double> > StartMap;
00094 StartMap xStart;
00095 for ( unsigned i=0; i<theNComp; i++ ) {
00096 xStart.insert(std::pair<double,float>(pdf(theParameters[i]),
00097 theParameters[i]));
00098 }
00099
00100
00101
00102 typedef std::multimap<double, double, std::greater<double> > ResultMap;
00103 ResultMap xFound;
00104 for ( StartMap::const_iterator i=xStart.begin();
00105 i!=xStart.end(); i++ ) {
00106 double x = findMode((*i).second);
00107 xFound.insert(std::pair<double,double>(pdf(x),x));
00108
00109
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 return xFound.begin()->second;
00119 }
00120
00121 double
00122 GSUtilities::findMode (const double xStart) const
00123 {
00124
00125
00126
00127 double y1(0.);
00128 double x(xStart);
00129 double y2(pdf(xStart));
00130 double yd(dpdf1(xStart));
00131 int nLoop(0);
00132 if ( (y1+y2)<10*DBL_MIN ) return xStart;
00133 while ( nLoop++<20 && fabs(y2-y1)/(y2+y1)>1.e-6 ) {
00134
00135 double yd2 = dpdf2(x);
00136 if ( fabs(yd2)<10*DBL_MIN ) return xStart;
00137 x -= yd/dpdf2(x);
00138 yd = dpdf1(x);
00139 y1 = y2;
00140 y2 = pdf(x);
00141
00142 }
00143 if ( nLoop >= 20 ) return xStart;
00144 return x;
00145 }
00146
00147 double
00148 GSUtilities::pdf (const double& x) const
00149 {
00150 double result(0.);
00151 for ( unsigned i=0; i<theNComp; i++ )
00152 result += theWeights[i]*gauss(x,theParameters[i],theErrors[i]);
00153 return result;
00154 }
00155
00156 double
00157 GSUtilities::cdf (const double& x) const
00158 {
00159 double result(0.);
00160 for ( unsigned i=0; i<theNComp; i++ )
00161 result += theWeights[i]*gaussInt(x,theParameters[i],theErrors[i]);
00162 return result;
00163 }
00164
00165 double
00166 GSUtilities::dpdf1 (const double& x) const
00167 {
00168 double result(0.);
00169 for ( unsigned i=0; i<theNComp; i++ ) {
00170 double dx = (x-theParameters[i])/theErrors[i];
00171 result += -theWeights[i]*dx/theErrors[i]*
00172 gauss(x,theParameters[i],theErrors[i]);
00173 }
00174 return result;
00175 }
00176
00177 double
00178 GSUtilities::dpdf2 (const double& x) const
00179 {
00180 double result(0.);
00181 for ( unsigned i=0; i<theNComp; i++ ) {
00182 double dx = (x-theParameters[i])/theErrors[i];
00183 result += theWeights[i]/theErrors[i]/theErrors[i]*
00184 (dx*dx-1)*gauss(x,theParameters[i],theErrors[i]);
00185 }
00186 return result;
00187 }
00188
00189 double
00190 GSUtilities::gauss (const double& x, const double& mean,
00191 const double& sigma) const
00192 {
00193 const double fNorm(1./sqrt(2*TMath::Pi()));
00194 double result(0.);
00195
00196 double d((x-mean)/sigma);
00197 if ( fabs(d)<20. ) result = exp(-d*d/2.);
00198 result *= fNorm/sigma;
00199 return result;
00200 }
00201
00202 double
00203 GSUtilities::gaussInt (const double& x, const double& mean,
00204 const double& sigma) const
00205 {
00206 return TMath::Freq((x-mean)/sigma);
00207 }
00208
00209 double
00210 GSUtilities::combinedMean () const
00211 {
00212 double s0(0.);
00213 double s1(0.);
00214 for ( unsigned i=0; i<theNComp; i++ ) {
00215 s0 += theWeights[i];
00216 s1 += theWeights[i]*theParameters[i];
00217 }
00218 return s1/s0;
00219 }
00220
00221 double
00222 GSUtilities::errorCombinedMean () const
00223 {
00224 double s0(0.);
00225 for ( unsigned i=0; i<theNComp; i++ ) {
00226 s0 += theWeights[i];
00227 }
00228 return 1./(sqrt(s0));
00229 }
00230
00231 float
00232 GSUtilities::maxWeight () const
00233 {
00234
00235
00236
00237 float wMax(0.);
00238 for ( unsigned i=0; i<theNComp; i++ ) {
00239 if ( theWeights[i]>wMax ) {
00240
00241 wMax = theWeights[i];
00242 }
00243 }
00244 return wMax;
00245 }
00246
00247
00248 float
00249 GSUtilities::errorMode()
00250 {
00251 float mod = mode();
00252 float min = getMin(mod);
00253 float max = getMax(mod);
00254 int nBins = 1000;
00255 float dx = (max - min )/(float)nBins;
00256
00257 float x1=mod, x2=mod, x1f=mod, x2f=mod;
00258 float I=0;
00259 int cnt=0;
00260 while (I<.68) {
00261 x1 -= dx;
00262 x2 += dx;
00263 if (pdf(x1)>=pdf(x2)) {
00264 x1f = x1;
00265 x2 -= dx;
00266 } else {
00267 x2f = x2;
00268 x1 += dx;
00269 }
00270 I = cdf(x2f) - cdf(x1f);
00271 cnt++;
00272
00273 if (cnt>2500) return 100000.;
00274 }
00275 return (x2f - x1f)/2;
00276 }
00277
00278 float GSUtilities::getMin(float x)
00279 {
00280 int cnt=0;
00281 float dx;
00282 if (fabs(x)<2) dx = .5;
00283 else dx = fabs(x)/10;
00284 while( cdf(x)>.1 && cnt<1000) {
00285 x -= dx;
00286 cnt++;
00287 }
00288 return x;
00289 }
00290
00291 float GSUtilities::getMax(float x)
00292 {
00293 int cnt=0;
00294 float dx;
00295 if (fabs(x)<2) dx = .5;
00296 else dx = fabs(x)/10;
00297 while( cdf(x)<.9 && cnt<1000) {
00298 x += dx;
00299 cnt++;
00300 }
00301 return x;
00302 }