Reconstruct the best estimate of the hit position for pixel clusters.
108 const float fracpix = 0.45f;
110 const int nilist = 9, njlist = 5;
111 const float ilist[nilist] = {0.f, -1.f, -0.75f, -0.5f, -0.25f, 0.25f, 0.5f, 0.75f, 1.f};
112 const float jlist[njlist] = {0.f, -0.5f, -0.25f, 0.25f, 0.50f};
117 if (!templ2D.
interpolate(
id, cotalpha, cotbeta, locBz, locBx))
125 for (
int i = 0;
i < 3; ++
i) {
126 fbin[
i] = templ2D.
fbin(
i);
129 float q50 = templ2D.
s50();
130 float pseudopix = 0.2f * q50;
131 float pseudopix2 = q50 * q50;
135 float qscale = templ2D.
qscale();
139 int nclusx = cluster.
mrow;
140 int nclusy = (
int)cluster.
mcol;
141 bool* xdouble = cluster.
xdouble;
142 bool* ydouble = cluster.
ydouble;
146 int imin =
BYM2, imax = 0, jmin =
BXM2, jmax = 0;
147 for (
int k = 0;
k < nclusx * nclusy; ++
k) {
151 int i =
k -
j * nclusy;
170 int shiftx =
THXP1 - (jmin + jmax) / 2;
171 int shifty =
THYP1 - (imin + imax) / 2;
185 float fq0 = qtotal / templ2D.
qavg();
191 for (
int j = 0;
j <
BXM2; ++
j) {
192 for (
int i = 0;
i <
BYM2; ++
i) {
197 const unsigned int NPIXMAX = 200;
199 int indexxy[2][NPIXMAX];
200 float pixel[NPIXMAX];
201 float sigma2[NPIXMAX];
202 float minmax = templ2D.
pixmax();
203 float ylow0 = 0.f, yhigh0 = 0.f, xlow0 = 0.f, xhigh0 = 0.f;
210 for (
int i = 0;
i <
BYM2; ++
i) {
214 for (
int j = 0;
j <
BXM2; ++
j) {
217 for (
int i = 0;
i < nclusy; ++
i) {
220 if (iy > -1 && iy <
BYM2)
224 for (
int j = 0;
j < nclusx; ++
j) {
227 if (jx > -1 && jx <
BXM2)
234 for (
int i = 0;
i <
BYM2; ++
i) {
235 float ypitch =
ysize;
239 ye[
i + 1] = ye[
i] + ypitch;
240 ypos[
i] = ye[
i] + ypitch / 2.;
242 for (
int j = 0;
j <
BXM2; ++
j) {
243 float xpitch =
xsize;
247 xe[
j + 1] = xe[
j] + xpitch;
248 xpos[
j] = xe[
j] + xpitch / 2.;
251 for (
int i = 0;
i < nclusy; ++
i) {
257 if (iy > -1 && iy <
BYM2) {
258 for (
int j = 0;
j < nclusx; ++
j) {
260 if (jx > -1 && jx <
BXM2) {
264 clusxy[jx][iy] = cluster(
j,
i);
266 if (clusxy[jx][iy] > 0.
f) {
267 ysum[iy] += clusxy[jx][iy];
268 indexxy[0][npixel] = jx;
269 indexxy[1][npixel] = iy;
270 pixel[npixel] = clusxy[jx][iy];
280 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
281 throw cms::Exception(
"DataCorrupt") <<
"PixelTemplateReco2D::number of pixels above threshold = " << npixel
284 std::cout <<
"PixelTemplateReco2D::number of pixels above threshold = " << npixel << std::endl;
291 xhigh0 = xe[jmax + 1];
293 yhigh0 = ye[imax + 1];
297 int ypixoff =
T2HYP1 - (imin + imax) / 2;
298 for (
int k = 0;
k < npixel; ++
k) {
299 int ypixeff = ypixoff + indexxy[1][
k];
306 int imisslow = -1, imisshigh = -1, jmisslow = -1, jmisshigh = -1;
307 float ylow = -1.f, yhigh = -1.f;
308 float hmaxpix = fracpix * templ2D.
sxymax();
309 for (
int i = imin;
i <= imax; ++
i) {
310 if (ysum[
i] > hmaxpix && ysum[
i - 1] < hmaxpix && ylow < 0.
f) {
311 ylow = ypos[
i - 1] + (ypos[
i] - ypos[
i - 1]) * (hmaxpix - ysum[
i - 1]) / (ysum[
i] - ysum[
i - 1]);
318 if (ysum[
i] > hmaxpix && ysum[
i + 1] < hmaxpix) {
319 yhigh = ypos[
i] + (ypos[
i + 1] - ypos[
i]) * (ysum[
i] - hmaxpix) / (ysum[
i] - ysum[
i + 1]);
322 if (ylow < 0.
f || yhigh < 0.
f) {
327 float templeny = templ2D.
clsleny();
328 deltay = templeny - (yhigh - ylow) /
ysize;
332 float x0 = 0.5f * (xlow0 + xhigh0) - templ2D.
lorxdrift();
333 float y0 = 0.5f * (ylow + yhigh) - templ2D.
lorydrift();
347 imisshigh = imin - 1;
355 imisshigh = imin - 1;
360 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
361 throw cms::Exception(
"DataCorrupt") <<
"PixelTemplateReco2D::illegal edgeflagy = " << edgeflagy << std::endl;
363 std::cout <<
"PixelTemplate:2D:illegal edgeflagy = " << edgeflagy << std::endl;
371 jmisshigh = jmin - 1;
379 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
380 throw cms::Exception(
"DataCorrupt") <<
"PixelTemplateReco2D::illegal edgeflagx = " << edgeflagx << std::endl;
382 std::cout <<
"PixelTemplate:2D:illegal edgeflagx = " << edgeflagx << std::endl;
388 float chi2min[2], xerr2[2], yerr2[2];
389 float x2D0[2], y2D0[2], qtfrac0[2];
393 for (ipass = 0; ipass < npass; ++ipass) {
400 for (
int k = npixel;
k < tpixel; ++
k) {
401 int j = indexxy[0][
k];
402 int i = indexxy[1][
k];
410 for (
int k = 0;
k < npixel; ++
k) {
411 int j = indexxy[0][
k];
412 int i = indexxy[1][
k];
413 if ((
j - 1) != jmisshigh) {
414 if (clusxy[
j - 1][
i] < pseudopix) {
415 indexxy[0][tpixel] =
j - 1;
416 indexxy[1][tpixel] =
i;
417 clusxy[
j - 1][
i] = pseudopix;
418 pixel[tpixel] = pseudopix;
419 sigma2[tpixel] = pseudopix2;
423 if ((
j + 1) != jmisslow) {
424 if (clusxy[
j + 1][
i] < pseudopix) {
425 indexxy[0][tpixel] =
j + 1;
426 indexxy[1][tpixel] =
i;
427 clusxy[
j + 1][
i] = pseudopix;
428 pixel[tpixel] = pseudopix;
429 sigma2[tpixel] = pseudopix2;
434 if ((
i + 1) != imisslow) {
435 if ((
j - 1) != jmisshigh) {
436 if (clusxy[
j - 1][
i + 1] < pseudopix) {
437 indexxy[0][tpixel] =
j - 1;
438 indexxy[1][tpixel] =
i + 1;
439 clusxy[
j - 1][
i + 1] = pseudopix;
440 pixel[tpixel] = pseudopix;
441 sigma2[tpixel] = pseudopix2;
445 if (clusxy[
j][
i + 1] < pseudopix) {
446 indexxy[0][tpixel] =
j;
447 indexxy[1][tpixel] =
i + 1;
448 clusxy[
j][
i + 1] = pseudopix;
449 pixel[tpixel] = pseudopix;
450 sigma2[tpixel] = pseudopix2;
453 if ((
j + 1) != jmisslow) {
454 if (clusxy[
j + 1][
i + 1] < pseudopix) {
455 indexxy[0][tpixel] =
j + 1;
456 indexxy[1][tpixel] =
i + 1;
457 clusxy[
j + 1][
i + 1] = pseudopix;
458 pixel[tpixel] = pseudopix;
459 sigma2[tpixel] = pseudopix2;
465 if ((
i - 1) != imisshigh) {
466 if ((
j - 1) != jmisshigh) {
467 if (clusxy[
j - 1][
i - 1] < pseudopix) {
468 indexxy[0][tpixel] =
j - 1;
469 indexxy[1][tpixel] =
i - 1;
470 clusxy[
j - 1][
i - 1] = pseudopix;
471 pixel[tpixel] = pseudopix;
472 sigma2[tpixel] = pseudopix2;
476 if (clusxy[
j][
i - 1] < pseudopix) {
477 indexxy[0][tpixel] =
j;
478 indexxy[1][tpixel] =
i - 1;
479 clusxy[
j][
i - 1] = pseudopix;
480 pixel[tpixel] = pseudopix;
481 sigma2[tpixel] = pseudopix2;
484 if ((
j + 1) != jmisslow) {
485 if (clusxy[
j + 1][
i - 1] < pseudopix) {
486 indexxy[0][tpixel] =
j + 1;
487 indexxy[1][tpixel] =
i - 1;
488 clusxy[
j + 1][
i - 1] = pseudopix;
489 pixel[tpixel] = pseudopix;
490 sigma2[tpixel] = pseudopix2;
499 chi2min[ipass] = 1000000.f;
500 float chi2, qtemplate, qactive, qtfrac = 0.f, x2D = 0.f, y2D = 0.f;
502 float ygridscale = 0.271 * cotbeta;
503 if (ygridscale < 1.
f)
505 for (
int is = 0; is < nilist; ++is) {
506 for (
int js = 0; js < njlist; ++js) {
508 float ytry = y0 + ilist[is] * ygridscale *
ysize;
511 for (
int j = 0;
j <
BXM2; ++
j) {
512 for (
int i = 0;
i <
BYM2; ++
i) {
513 template2d[
j][
i] = 0.f;
516 templ2D.
xytemp(xtry, ytry, yd, xd, template2d,
false, dpdx2d, qtemplate);
517 for (
int k = 0;
k < tpixel; ++
k) {
518 int jpix = indexxy[0][
k];
519 int ipix = indexxy[1][
k];
520 float qtpixel = template2d[jpix][ipix];
527 if (
chi2 < chi2min[ipass]) {
528 chi2min[ipass] =
chi2;
531 qtfrac = qactive / qtemplate;
537 float xstep = 1.0f, ystep = 1.0f;
538 float minv11 = 1000.f, minv12 = 1000.f, minv22 = 1000.f;
539 chi2 = chi2min[ipass];
540 while (
chi2 <= chi2min[ipass] && niter < 15 && (niter < 2 || (
std::abs(xstep) > 0.2 ||
std::abs(ystep) > 0.2))) {
544 qtfrac0[ipass] = qtfrac;
545 xerr2[ipass] = minv11;
546 yerr2[ipass] = minv22;
547 chi2min[ipass] =
chi2;
552 for (
int j = 0;
j <
BXM2; ++
j) {
553 for (
int i = 0;
i <
BYM2; ++
i) {
554 template2d[
j][
i] = 0.f;
557 templ2D.
xytemp(x2D, y2D, yd, xd, template2d,
true, dpdx2d, qtemplate);
559 float sumptdt1 = 0., sumptdt2 = 0.;
560 float sumdtdt11 = 0., sumdtdt12 = 0., sumdtdt22 = 0.;
565 for (
int k = 0;
k < tpixel; ++
k) {
566 int jpix = indexxy[0][
k];
567 int ipix = indexxy[1][
k];
568 float qtpixel = template2d[jpix][ipix];
570 float dtdx = dpdx2d[0][jpix][ipix];
571 float dtdy = dpdx2d[1][jpix][ipix];
573 sumptdt1 +=
pt * dtdx / sigma2[
k];
574 sumptdt2 +=
pt * dtdy / sigma2[
k];
575 sumdtdt11 += dtdx * dtdx / sigma2[
k];
576 sumdtdt12 += dtdx * dtdy / sigma2[
k];
577 sumdtdt22 += dtdy * dtdy / sigma2[
k];
585 float D = sumdtdt11 * sumdtdt22 - sumdtdt12 * sumdtdt12;
590 minv11 = sumdtdt22 /
D;
591 minv12 = -sumdtdt12 /
D;
592 minv22 = sumdtdt11 /
D;
594 qtfrac = qactive / qtemplate;
598 xstep = minv11 * sumptdt1 + minv12 * sumptdt2;
599 ystep = minv12 * sumptdt1 + minv22 * sumptdt2;
603 if (sumdtdt11 > 0.0001
f) {
604 xstep = sumptdt1 / sumdtdt11;
608 if (sumdtdt22 > 0.0001
f) {
609 ystep = sumptdt2 / sumdtdt22;
628 if (chi2min[1] < chi2min[0]) {
636 if (qtfrac0[ipass] < 0.10
f || qtfrac0[ipass] > 1.
f) {
637 qtfrac0[ipass] = 1.f;
639 fq = fq0 / qtfrac0[ipass];
659 float scalex = templ2D.
scalex(qbin);
660 float scaley = templ2D.
scaley(qbin);
661 float offsetx = templ2D.
offsetx(qbin);
662 float offsety = templ2D.
offsety(qbin);
668 xrec = x2D0[ipass] - xpos[shiftx] - offsetx;
669 yrec = y2D0[ipass] - ypos[shifty] - offsety;
670 if (xerr2[ipass] > 0.
f) {
671 sigmax = scalex *
sqrt(xerr2[ipass]);
677 if (yerr2[ipass] > 0.
f) {
678 sigmay = scaley *
sqrt(yerr2[ipass]);
686 double meanxy = (double)(npixel * templ2D.
chi2ppix());
687 double chi2scale = (double)templ2D.
chi2scale();
691 double hndof = meanxy / 2.f;
692 double hchi2 = chi2scale * chi2min[ipass] / 2.f;
693 probxy = (
float)(1. - TMath::Gamma(hndof, hchi2));
695 float mpv = templ2D.
mpvvav();
698 float xvav = (qtotal / qtfrac0[ipass] - mpv) / sigmaQ;
702 float prvav = vvidist.fcn(xvav);
705 probxy = chi2min[ipass];