File indexing completed on 2024-04-06 12:31:30
0001 #include "TrackingTools/GsfTools/interface/GSUtilities.h"
0002
0003 #include <TMath.h>
0004
0005
0006 #include <cmath>
0007
0008 #include <map>
0009 #include <functional>
0010
0011 float GSUtilities::quantile(const float q) const {
0012 float qq = q;
0013 if (q > 1)
0014 qq = 1;
0015 else if (q < 0)
0016 qq = 0;
0017
0018
0019
0020 int iwMax(-1);
0021 float wMax(0.);
0022 for (unsigned i = 0; i < theNComp; i++) {
0023 if (theWeights[i] > wMax) {
0024 iwMax = i;
0025 wMax = theWeights[i];
0026 }
0027 }
0028
0029
0030
0031
0032
0033
0034 double x1(theParameters[iwMax]);
0035 double y1(cdf(x1) - qq);
0036 double dx = y1 > 0. ? -theErrors[iwMax] : theErrors[iwMax];
0037 double x2(x1 + dx);
0038 double y2(cdf(x2) - qq);
0039 while (y1 * y2 > 0.) {
0040 x1 = x2;
0041 y1 = y2;
0042 x2 += dx;
0043 y2 = cdf(x2) - qq;
0044 }
0045
0046
0047
0048
0049
0050 double x(0.);
0051 while (true) {
0052
0053 x = -(x2 * y1 - x1 * y2) / (y2 - y1);
0054 double y = cdf(x) - qq;
0055
0056 if (fabs(y) < 1.e-6)
0057 break;
0058 if (y * y1 > 0.) {
0059 y1 = y;
0060 x1 = x;
0061 } else {
0062 y2 = y;
0063 x2 = x;
0064 }
0065 }
0066 return x;
0067 }
0068
0069 float GSUtilities::errorHighestWeight() const {
0070 int iwMax(-1);
0071 float wMax(0.);
0072 for (unsigned i = 0; i < theNComp; i++) {
0073 if (theWeights[i] > wMax) {
0074 iwMax = i;
0075 wMax = theWeights[i];
0076 }
0077 }
0078 return theErrors[iwMax];
0079 }
0080
0081 float GSUtilities::mode() const {
0082
0083
0084
0085 typedef std::multimap<double, double, std::greater<double> > StartMap;
0086 StartMap xStart;
0087 for (unsigned i = 0; i < theNComp; i++) {
0088 xStart.insert(std::pair<double, float>(pdf(theParameters[i]), theParameters[i]));
0089 }
0090
0091
0092
0093 typedef std::multimap<double, double, std::greater<double> > ResultMap;
0094 ResultMap xFound;
0095 for (StartMap::const_iterator i = xStart.begin(); i != xStart.end(); i++) {
0096 double x = findMode((*i).second);
0097 xFound.insert(std::pair<double, double>(pdf(x), x));
0098
0099
0100 }
0101
0102
0103
0104
0105
0106
0107
0108 return xFound.begin()->second;
0109 }
0110
0111 double GSUtilities::findMode(const double xStart) const {
0112
0113
0114
0115 double y1(0.);
0116 double x(xStart);
0117 double y2(pdf(xStart));
0118 double yd(dpdf1(xStart));
0119 int nLoop(0);
0120 if ((y1 + y2) < 10 * DBL_MIN)
0121 return xStart;
0122 while (nLoop++ < 20 && fabs(y2 - y1) / (y2 + y1) > 1.e-6) {
0123
0124 double yd2 = dpdf2(x);
0125 if (fabs(yd2) < 10 * DBL_MIN)
0126 return xStart;
0127 x -= yd / dpdf2(x);
0128 yd = dpdf1(x);
0129 y1 = y2;
0130 y2 = pdf(x);
0131
0132 }
0133 if (nLoop >= 20)
0134 return xStart;
0135 return x;
0136 }
0137
0138 double GSUtilities::pdf(const double& x) const {
0139 double result(0.);
0140 for (unsigned i = 0; i < theNComp; i++)
0141 result += theWeights[i] * gauss(x, theParameters[i], theErrors[i]);
0142 return result;
0143 }
0144
0145 double GSUtilities::cdf(const double& x) const {
0146 double result(0.);
0147 for (unsigned i = 0; i < theNComp; i++)
0148 result += theWeights[i] * gaussInt(x, theParameters[i], theErrors[i]);
0149 return result;
0150 }
0151
0152 double GSUtilities::dpdf1(const double& x) const {
0153 double result(0.);
0154 for (unsigned i = 0; i < theNComp; i++) {
0155 double dx = (x - theParameters[i]) / theErrors[i];
0156 result += -theWeights[i] * dx / theErrors[i] * gauss(x, theParameters[i], theErrors[i]);
0157 }
0158 return result;
0159 }
0160
0161 double GSUtilities::dpdf2(const double& x) const {
0162 double result(0.);
0163 for (unsigned i = 0; i < theNComp; i++) {
0164 double dx = (x - theParameters[i]) / theErrors[i];
0165 result += theWeights[i] / theErrors[i] / theErrors[i] * (dx * dx - 1) * gauss(x, theParameters[i], theErrors[i]);
0166 }
0167 return result;
0168 }
0169
0170 double GSUtilities::gauss(const double& x, const double& mean, const double& sigma) const {
0171 const double fNorm(1. / sqrt(2 * TMath::Pi()));
0172 double result(0.);
0173
0174 double d((x - mean) / sigma);
0175 if (fabs(d) < 20.)
0176 result = exp(-d * d / 2.);
0177 result *= fNorm / sigma;
0178 return result;
0179 }
0180
0181 double GSUtilities::gaussInt(const double& x, const double& mean, const double& sigma) const {
0182 return TMath::Freq((x - mean) / sigma);
0183 }
0184
0185 double GSUtilities::combinedMean() const {
0186 double s0(0.);
0187 double s1(0.);
0188 for (unsigned i = 0; i < theNComp; i++) {
0189 s0 += theWeights[i];
0190 s1 += theWeights[i] * theParameters[i];
0191 }
0192 return s1 / s0;
0193 }
0194
0195 double GSUtilities::errorCombinedMean() const {
0196 double s0(0.);
0197 for (unsigned i = 0; i < theNComp; i++) {
0198 s0 += theWeights[i];
0199 }
0200 return 1. / (sqrt(s0));
0201 }
0202
0203 float GSUtilities::maxWeight() const {
0204
0205
0206
0207 float wMax(0.);
0208 for (unsigned i = 0; i < theNComp; i++) {
0209 if (theWeights[i] > wMax) {
0210
0211 wMax = theWeights[i];
0212 }
0213 }
0214 return wMax;
0215 }
0216
0217 float GSUtilities::errorMode() {
0218 float mod = mode();
0219 float min = getMin(mod);
0220 float max = getMax(mod);
0221 int nBins = 1000;
0222 float dx = (max - min) / (float)nBins;
0223
0224 float x1 = mod, x2 = mod, x1f = mod, x2f = mod;
0225 float I = 0;
0226 int cnt = 0;
0227 while (I < .68) {
0228 x1 -= dx;
0229 x2 += dx;
0230 if (pdf(x1) >= pdf(x2)) {
0231 x1f = x1;
0232 x2 -= dx;
0233 } else {
0234 x2f = x2;
0235 x1 += dx;
0236 }
0237 I = cdf(x2f) - cdf(x1f);
0238 cnt++;
0239
0240 if (cnt > 2500)
0241 return 100000.;
0242 }
0243 return (x2f - x1f) / 2;
0244 }
0245
0246 float GSUtilities::getMin(float x) {
0247 int cnt = 0;
0248 float dx;
0249 if (fabs(x) < 2)
0250 dx = .5;
0251 else
0252 dx = fabs(x) / 10;
0253 while (cdf(x) > .1 && cnt < 1000) {
0254 x -= dx;
0255 cnt++;
0256 }
0257 return x;
0258 }
0259
0260 float GSUtilities::getMax(float x) {
0261 int cnt = 0;
0262 float dx;
0263 if (fabs(x) < 2)
0264 dx = .5;
0265 else
0266 dx = fabs(x) / 10;
0267 while (cdf(x) < .9 && cnt < 1000) {
0268 x += dx;
0269 cnt++;
0270 }
0271 return x;
0272 }