00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <math.h>
00019 #include <algorithm>
00020 #include <vector>
00021 #include <utility>
00022 #include <iostream>
00023
00024 #include "TMath.h"
00025 #include "Math/DistFunc.h"
00026
00027
00028
00029 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
00030 #include "RecoLocalTracker/SiStripRecHitConverter/interface/SiStripTemplateReco.h"
00031 #include "RecoLocalTracker/SiStripRecHitConverter/interface/VVIObj.h"
00032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00033 #define LOGERROR(x) edm::LogError(x)
00034 #define LOGDEBUG(x) LogDebug(x)
00035 constexpr int theVerboseLevel = 2;
00036 #define ENDL " "
00037 #include "FWCore/Utilities/interface/Exception.h"
00038 #else
00039 #include "SiStripTemplateReco.h"
00040 #include "VVIObj.h"
00041
00042 #define LOGERROR(x) std::cout << x << ": "
00043 #define LOGDEBUG(x) std::cout << x << ": "
00044 #define ENDL std::endl
00045 #endif
00046
00047 using namespace SiStripTemplateReco;
00048
00049
00083
00084 int SiStripTemplateReco::StripTempReco1D(int id, float cotalpha, float cotbeta, float locBy, std::vector<float>& cluster,
00085 SiStripTemplate& templ,
00086 float& xrec, float& sigmax, float& probx, int& qbin, int speed, float& probQ)
00087
00088 {
00089
00090 int i, j, minbin, binl, binh, binq, midpix;
00091 int fxpix, nxpix, lxpix, logxpx, shiftx, ftpix, ltpix;
00092 int nclusx;
00093 int deltaj, jmin, jmax, fxbin, lxbin, djx;
00094 float sxthr, rnorm, delta, sigma, pseudopix, qscale, q50, q100;
00095 float ss2, ssa, sa2, ssba, saba, sba2, rat, fq, qtotal, barycenter, sigmaxbcn;
00096 float originx, qfx, qlx, bias, biasbcn, maxpix;
00097 double chi2x, meanx, chi2xmin, chi21max;
00098 double hchi2, hndof, prvav, mpv, sigmaQ, kappa, xvav, beta2;
00099 float xtemp[41][BSXSIZE], xsum[BSXSIZE];
00100 float chi2xbin[41], xsig2[BSXSIZE];
00101 float xw2[BSXSIZE], xsw[BSXSIZE];
00102 bool calc_probQ, use_VVIObj;
00103 float xsize;
00104 const float probmin={1.110223e-16};
00105 const float probQmin={1.e-5};
00106
00107
00108
00109 const double mean1pix={0.100}, chi21min={0.160};
00110
00111
00112
00113
00114 if(!templ.interpolate(id, cotalpha, cotbeta, locBy)) {
00115 if (theVerboseLevel > 2) {LOGDEBUG("SiStripTemplateReco") << "input cluster direction cot(alpha) = " << cotalpha << ", cot(beta) = " << cotbeta << ", local B_y = " << locBy << ", template ID = " << id << ", no reconstruction performed" << ENDL;}
00116 return 20;
00117 }
00118
00119
00120
00121 calc_probQ = false;
00122 use_VVIObj = false;
00123 if(speed < 0) {
00124 calc_probQ = true;
00125 if(speed < -1) use_VVIObj = true;
00126 speed = 0;
00127 }
00128
00129 if(speed > 3) {
00130 calc_probQ = true;
00131 if(speed < 5) use_VVIObj = true;
00132 speed = 3;
00133 }
00134
00135
00136
00137 xsize = templ.xsize();
00138
00139
00140
00141 q50 = templ.s50();
00142 q100 = 2.f * q50;
00143 pseudopix = q50;
00144
00145
00146
00147 qscale = templ.qscale();
00148
00149
00150
00151 nclusx = (int)cluster.size();
00152
00153 if(nclusx > TSXSIZE) {nclusx = TSXSIZE;}
00154
00155
00156
00157 qtotal = 0.;
00158 for(i=0; i<BSXSIZE; ++i) {xsum[i] = 0.f;}
00159 maxpix = templ.sxmax();
00160 barycenter = 0.f;
00161 for(j=0; j<nclusx; ++j) {
00162 xsum[j] = qscale*cluster[j];
00163 qtotal += xsum[j];
00164 barycenter += j*xsize*xsum[j];
00165 if(xsum[j] > maxpix) {xsum[j] = maxpix;}
00166 }
00167
00168 barycenter = barycenter/qtotal - 0.5f*templ.lorxwidth();
00169
00170
00171
00172 fxpix = -1;
00173 ftpix = -1;
00174 nxpix=0;
00175 lxpix=0;
00176 ltpix=0;
00177 logxpx=0;
00178 for(i=0; i<BSXSIZE; ++i) {
00179 if(xsum[i] > 0.f) {
00180 if(fxpix == -1) {fxpix = i;}
00181 ++logxpx;
00182 ++nxpix;
00183 lxpix = i;
00184 if(xsum[i] > q100) {
00185 if(ftpix == -1) {ftpix = i;}
00186 ltpix = i;
00187 }
00188 }
00189 }
00190
00191
00192
00193
00194
00195
00196 if((lxpix-fxpix+1) != nxpix) {
00197
00198 LOGDEBUG("SiStripTemplateReco") << "x-length of pixel cluster doesn't agree with number of pixels above threshold" << ENDL;
00199 if (theVerboseLevel > 2) {
00200 LOGDEBUG("SiStripTemplateReco") << "xsum[] = ";
00201 for(i=0; i<BSXSIZE-1; ++i) {LOGDEBUG("SiStripTemplateReco") << xsum[i] << ", ";}
00202 LOGDEBUG("SiStripTemplateReco") << ENDL;
00203 }
00204
00205 return 2;
00206 }
00207
00208
00209
00210 if(nxpix > TSXSIZE) {
00211
00212 LOGDEBUG("SiStripTemplateReco") << "x-length of pixel cluster is larger than maximum template size" << ENDL;
00213 if (theVerboseLevel > 2) {
00214 LOGDEBUG("SiStripTemplateReco") << "xsum[] = ";
00215 for(i=0; i<BSXSIZE-1; ++i) {LOGDEBUG("SiStripTemplateReco") << xsum[i] << ", ";}
00216 LOGDEBUG("SiStripTemplateReco") << ENDL;
00217 }
00218
00219 return 7;
00220 }
00221
00222
00223
00224 midpix = (ftpix+ltpix)/2;
00225 shiftx = templ.cxtemp() - midpix;
00226
00227 if(shiftx > 0) {
00228 for(i=lxpix; i>=fxpix; --i) {
00229 xsum[i+shiftx] = xsum[i];
00230 xsum[i] = 0.f;
00231 }
00232 } else if (shiftx < 0) {
00233 for(i=fxpix; i<=lxpix; ++i) {
00234 xsum[i+shiftx] = xsum[i];
00235 xsum[i] = 0.f;
00236 }
00237 }
00238 lxpix +=shiftx;
00239 fxpix +=shiftx;
00240
00241
00242
00243 if(fxpix > 1 && fxpix < BSXM2) {
00244 xsum[fxpix-1] = pseudopix;
00245 xsum[fxpix-2] = 0.2f*pseudopix;
00246 } else {return 9;}
00247 if(lxpix > 1 && lxpix < BSXM2) {
00248 xsum[lxpix+1] = pseudopix;
00249 xsum[lxpix+2] = 0.2f*pseudopix;
00250 } else {return 9;}
00251
00252
00253
00254 originx = 0.f;
00255
00256
00257
00258 fq = qtotal/templ.qavg();
00259 if(fq > 1.5f) {
00260 binq=0;
00261 } else {
00262 if(fq > 1.0f) {
00263 binq=1;
00264 } else {
00265 if(fq > 0.85f) {
00266 binq=2;
00267 } else {
00268 binq=3;
00269 }
00270 }
00271 }
00272
00273
00274
00275 qbin = binq;
00276 if(qtotal < 0.95f*templ.qmin()) {qbin = 5;} else {
00277 if(qtotal < 0.95f*templ.qmin(1)) {qbin = 4;}
00278 }
00279 if (theVerboseLevel > 9) {
00280 LOGDEBUG("SiStripTemplateReco") <<
00281 "ID = " << id <<
00282 " cot(alpha) = " << cotalpha << " cot(beta) = " << cotbeta <<
00283 " nclusx = " << nclusx << ENDL;
00284 }
00285
00286
00287
00288
00289
00290
00291 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
00292 if(speed < 0 || speed > 3) {
00293 throw cms::Exception("DataCorrupt") << "SiStripTemplateReco::StripTempReco2D called with illegal speed = " << speed << std::endl;
00294 }
00295 #else
00296 assert(speed >= 0 && speed < 4);
00297 #endif
00298 fxbin = 2; lxbin = 38; djx = 1;
00299 if(speed > 0) {
00300 fxbin = 8; lxbin = 32;
00301 }
00302
00303 if(speed > 1) {
00304 djx = 2;
00305 if(speed > 2) {
00306 djx = 4;
00307 }
00308 }
00309
00310 if (theVerboseLevel > 9) {
00311 LOGDEBUG("SiStripTemplateReco") <<
00312 "fxpix " << fxpix << " lxpix = " << lxpix <<
00313 " fxbin = " << fxbin << " lxbin = " << lxbin <<
00314 " djx = " << djx << " logxpx = " << logxpx << ENDL;
00315 }
00316
00317
00318
00319 templ.xtemp(fxbin, lxbin, xtemp);
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 sxthr = 1.1f*maxpix;
00330
00331
00332
00333
00334 templ.xsigma2(fxpix, lxpix, sxthr, xsum, xsig2);
00335
00336
00337
00338 chi2xmin = 1.e15;
00339 for(i=fxbin; i<=lxbin; ++i) { chi2xbin[i] = -1.e15f;}
00340 ss2 = 0.f;
00341 for(i=fxpix-2; i<=lxpix+2; ++i) {
00342 xw2[i] = 1.f/xsig2[i];
00343 xsw[i] = xsum[i]*xw2[i];
00344 ss2 += xsum[i]*xsw[i];
00345 }
00346 minbin = -1;
00347 deltaj = djx;
00348 jmin = fxbin;
00349 jmax = lxbin;
00350 while(deltaj > 0) {
00351 for(j=jmin; j<=jmax; j+=deltaj) {
00352 if(chi2xbin[j] < -100.f) {
00353 ssa = 0.f;
00354 sa2 = 0.f;
00355 for(i=fxpix-2; i<=lxpix+2; ++i) {
00356 ssa += xsw[i]*xtemp[j][i];
00357 sa2 += xtemp[j][i]*xtemp[j][i]*xw2[i];
00358 }
00359 rat=ssa/ss2;
00360 if(rat <= 0.f) {LOGERROR("SiStripTemplateReco") << "illegal chi2xmin normalization (1) = " << rat << ENDL; rat = 1.;}
00361 chi2xbin[j]=ss2-2.*ssa/rat+sa2/(rat*rat);
00362 }
00363 if(chi2xbin[j] < chi2xmin) {
00364 chi2xmin = chi2xbin[j];
00365 minbin = j;
00366 }
00367 }
00368 deltaj /= 2;
00369 if(minbin > fxbin) {jmin = minbin - deltaj;} else {jmin = fxbin;}
00370 if(minbin < lxbin) {jmax = minbin + deltaj;} else {jmax = lxbin;}
00371 }
00372
00373 if (theVerboseLevel > 9) {
00374 LOGDEBUG("SiStripTemplateReco") <<
00375 "minbin " << minbin << " chi2xmin = " << chi2xmin << ENDL;
00376 }
00377
00378
00379
00380 if(nxpix == 1) {
00381
00382 delta = templ.dxone();
00383 sigma = templ.sxone();
00384 xrec = 0.5f*(fxpix+lxpix-2*shiftx+2.f*originx)*xsize-delta;
00385 if(sigma <= 0.f) {
00386 sigmax = 28.9f;
00387 } else {
00388 sigmax = sigma;
00389 }
00390
00391
00392
00393 chi21max = fmax(chi21min, (double)templ.chi2xminone());
00394 chi2xmin -=chi21max;
00395 if(chi2xmin < 0.) {chi2xmin = 0.;}
00396 meanx = fmax(mean1pix, (double)templ.chi2xavgone());
00397 hchi2 = chi2xmin/2.; hndof = meanx/2.;
00398 probx = 1. - TMath::Gamma(hndof, hchi2);
00399
00400 } else {
00401
00402
00403
00404 binl = minbin - 1;
00405 binh = binl + 2;
00406 if(binl < fxbin) { binl = fxbin;}
00407 if(binh > lxbin) { binh = lxbin;}
00408 ssa = 0.;
00409 sa2 = 0.;
00410 ssba = 0.;
00411 saba = 0.;
00412 sba2 = 0.;
00413 for(i=fxpix-2; i<=lxpix+2; ++i) {
00414 ssa += xsw[i]*xtemp[binl][i];
00415 sa2 += xtemp[binl][i]*xtemp[binl][i]*xw2[i];
00416 ssba += xsw[i]*(xtemp[binh][i] - xtemp[binl][i]);
00417 saba += xtemp[binl][i]*(xtemp[binh][i] - xtemp[binl][i])*xw2[i];
00418 sba2 += (xtemp[binh][i] - xtemp[binl][i])*(xtemp[binh][i] - xtemp[binl][i])*xw2[i];
00419 }
00420
00421
00422
00423 rat=(ssba*ssa-ss2*saba)/(ss2*sba2-ssba*ssba);
00424 if(rat < 0.f) {rat=0.f;}
00425 if(rat > 1.f) {rat=1.0f;}
00426 rnorm = (ssa+rat*ssba)/ss2;
00427
00428
00429
00430 qfx = xsum[fxpix];
00431 if(logxpx > 1) {
00432 qlx=xsum[lxpix];
00433 } else {
00434 qlx = qfx;
00435 }
00436
00437
00438
00439 float qxfrac = (qfx-qlx)/(qfx+qlx);
00440 bias = templ.xflcorr(binq,qxfrac)+templ.xavg(binq);
00441
00442
00443
00444 xrec = (0.125f*binl+BSHX-2.5f+rat*(binh-binl)*0.125f-(float)shiftx+originx)*xsize - bias;
00445 sigmax = templ.xrms(binq);
00446
00447
00448
00449 if(rnorm <= 0.f) {LOGERROR("SiStripTemplateReco") << "illegal chi2x normalization (2) = " << rnorm << ENDL; rnorm = 1.;}
00450 chi2x=ss2-2.f/rnorm*ssa-2.f/rnorm*rat*ssba+(sa2+2.f*rat*saba+rat*rat*sba2)/(rnorm*rnorm)-templ.chi2xmin(binq);
00451 if(chi2x < 0.0) {chi2x = 0.0;}
00452 meanx = templ.chi2xavg(binq);
00453 if(meanx < 0.01) {meanx = 0.01;}
00454
00455
00456
00457 hchi2 = chi2x/2.; hndof = meanx/2.;
00458 probx = 1. - TMath::Gamma(hndof, hchi2);
00459
00460
00461
00462 bias = templ.xavg(binq);
00463 biasbcn = templ.xavgbcn(binq);
00464 sigmaxbcn = templ.xrmsbcn(binq);
00465
00466 if((bias*bias+sigmax*sigmax) > (biasbcn*biasbcn+sigmaxbcn*sigmaxbcn)) {
00467
00468 xrec = barycenter - biasbcn;
00469 sigmax = sigmaxbcn;
00470
00471 }
00472
00473 }
00474
00475
00476
00477 if(probx < probmin) {probx = probmin;}
00478
00479
00480
00481 if(calc_probQ) {
00482
00483
00484
00485 templ.vavilov_pars(mpv, sigmaQ, kappa);
00486 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
00487 if((sigmaQ <=0.) || (mpv <= 0.) || (kappa < 0.01) || (kappa > 9.9)) {
00488 throw cms::Exception("DataCorrupt") << "SiStripTemplateReco::Vavilov parameters mpv/sigmaQ/kappa = " << mpv << "/" << sigmaQ << "/" << kappa << std::endl;
00489 }
00490 #else
00491 assert((sigmaQ > 0.) && (mpv > 0.) && (kappa > 0.01) && (kappa < 10.));
00492 #endif
00493 xvav = ((double)qtotal-mpv)/sigmaQ;
00494 beta2 = 1.;
00495 if(use_VVIObj) {
00496
00497 sistripvvi::VVIObj vvidist(kappa, beta2, 1);
00498 prvav = vvidist.fcn(xvav);
00499 } else {
00500
00501 prvav = TMath::VavilovI(xvav, kappa, beta2);
00502 }
00503
00504
00505
00506 probQ = 1. - prvav;
00507 if(probQ < probQmin) {probQ = probQmin;}
00508 } else {
00509 probQ = -1;
00510 }
00511
00512 return 0;
00513 }
00514