53 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
64 #include "Math/DistFunc.h"
69 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
73 #define LOGERROR(x) edm::LogError(x)
74 #define LOGDEBUG(x) LogDebug(x)
80 #define LOGERROR(x) std::cout << x << ": "
81 #define LOGDEBUG(x) std::cout << x << ": "
82 #define ENDL std::endl
85 using namespace SiPixelTemplateReco;
157 int i,
j,
k, minbin, binl, binh, binq, midpix, fypix, lypix, logypx;
158 int fxpix, lxpix, logxpx, shifty, shiftx, nyzero[
TYSIZE];
160 int deltaj, jmin, jmax, fxbin, lxbin, fybin, lybin, djy, djx;
162 float sythr, sxthr, rnorm,
delta, sigma, sigavg, pseudopix, qscale, q50;
163 float ss2, ssa, sa2, ssba, saba, sba2, rat, fq, qtotal, qpixel, fbin[3];
164 float originx, originy, qfy, qly, qfx, qlx, bias,
maxpix, minmax;
165 double chi2x, meanx, chi2y,
meany, chi2ymin, chi2xmin, chi21max;
166 double hchi2, hndof, prvav, mpv, sigmaQ, kappa, xvav, beta2;
168 float chi2ybin[41], chi2xbin[41], ysig2[
BYSIZE], xsig2[
BXSIZE];
170 bool yd[
BYSIZE], xd[
BXSIZE], anyyd, anyxd, calc_probQ, use_VVIObj;
172 const float probmin = {1.110223e-16};
173 const float probQmin = {1.e-5};
177 const double mean1pix = {0.100};
178 #ifdef SI_PIXEL_TEMPLATE_STANDALONE
179 const double chi21min = {0.};
181 const double chi21min = {0.160};
188 if (!templ.
interpolate(
id, cotalpha, cotbeta, locBz, locBx)) {
190 LOGDEBUG(
"SiPixelTemplateReco") <<
"input cluster direction cot(alpha) = " << cotalpha
191 <<
", cot(beta) = " << cotbeta <<
", local B_z = " << locBz
192 <<
", local B_x = " << locBx <<
", template ID = " <<
id
193 <<
", no reconstruction performed" <<
ENDL;
219 xsize = templ.
xsize();
220 ysize = templ.
ysize();
224 for (i = 0; i < 3; ++
i) {
225 fbin[
i] = templ.
fbin(i);
231 pseudopix = 0.2f * q50;
239 nclusx = cluster.
mrow;
240 nclusy = (int)cluster.
mcol;
241 auto const xdouble = cluster.
xdouble;
242 auto const ydouble = cluster.
ydouble;
246 for (i = 0; i < nclusx * nclusy; ++
i) {
252 for (j = 0; j < nclusx; ++
j)
253 for (i = 0; i < nclusy; ++
i) {
258 if (cluster(j, i) > maxpix) {
268 memset(nyzero, 0,
TYSIZE *
sizeof(
int));
269 memset(ysum, 0,
BYSIZE *
sizeof(
float));
270 for (i = 0; i < nclusy; ++
i) {
272 for (j = 0; j < nclusx; ++
j) {
273 ysum[
i] += cluster(j, i);
290 std::vector<std::pair<int, int> >::const_iterator zeroIter = zeropix.begin(), zeroEnd = zeropix.end();
291 for (; zeroIter != zeroEnd; ++zeroIter) {
292 i = zeroIter->second;
293 if (i < 0 || i >
TYSIZE - 1) {
294 LOGERROR(
"SiPixelTemplateReco") <<
"dead pixel column y-index " << i <<
", no reconstruction performed" <<
ENDL;
309 nypix = lypix - fypix + 1;
313 for (zeroIter = zeropix.begin(); zeroIter != zeroEnd; ++zeroIter) {
314 i = zeroIter->second;
316 if (j < 0 || j >
TXSIZE - 1) {
317 LOGERROR(
"SiPixelTemplateReco") <<
"dead pixel column x-index " << j <<
", no reconstruction performed" <<
ENDL;
320 if ((i == fypix || i == lypix) && nypix > 1) {
321 maxpix = templ.
symax() / 2.;
323 maxpix = templ.
symax();
328 if (nyzero[i] > 0 && nyzero[i] < 3) {
329 qpixel = (maxpix - ysum[
i]) / (
float)nyzero[
i];
336 cluster(j, i) = qpixel;
351 for (i = 0; i < nclusy; ++
i) {
352 for (j = 0; j < nclusx; ++
j) {
353 ysum[
k] += cluster(j, i);
360 ysum[k + 1] = ysum[
k];
382 for (j = 0; j < nclusx; ++
j) {
383 for (i = 0; i < nclusy; ++
i) {
384 xsum[
k] += cluster(j, i);
391 xsum[k + 1] = xsum[
k];
417 ysort[logypx] = ysum[
i];
429 if ((lypix - fypix + 1) != nypix || nypix == 0) {
430 LOGDEBUG(
"SiPixelTemplateReco") <<
"y-length of pixel cluster doesn't agree with number of pixels above threshold"
433 LOGDEBUG(
"SiPixelTemplateReco") <<
"ysum[] = ";
434 for (i = 0; i < BYSIZE - 1; ++
i) {
435 LOGDEBUG(
"SiPixelTemplateReco") << ysum[
i] <<
", ";
437 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BYSIZE - 1] <<
ENDL;
446 LOGDEBUG(
"SiPixelTemplateReco") <<
"y-length of pixel cluster is larger than maximum template size" <<
ENDL;
448 LOGDEBUG(
"SiPixelTemplateReco") <<
"ysum[] = ";
449 for (i = 0; i < BYSIZE - 1; ++
i) {
450 LOGDEBUG(
"SiPixelTemplateReco") << ysum[
i] <<
", ";
452 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BYSIZE - 1] <<
ENDL;
465 midpix = (fypix + lypix) / 2;
466 shifty = templ.
cytemp() - midpix;
470 int lytmp = lypix + shifty;
471 int fytmp = fypix + shifty;
485 for (i = lypix; i >= fypix; --
i) {
486 ysum[i + shifty] = ysum[
i];
488 yd[i + shifty] = yd[
i];
491 }
else if (shifty < 0) {
492 for (i = fypix; i <= lypix; ++
i) {
493 ysum[i + shifty] = ysum[
i];
495 yd[i + shifty] = yd[
i];
505 ysum[fypix - 1] = pseudopix;
506 ysum[fypix - 2] = pseudopix;
507 ysum[lypix + 1] = pseudopix;
508 ysum[lypix + 2] = pseudopix;
530 xsort[logxpx] = xsum[
i];
542 if ((lxpix - fxpix + 1) != nxpix) {
543 LOGDEBUG(
"SiPixelTemplateReco") <<
"x-length of pixel cluster doesn't agree with number of pixels above threshold"
546 LOGDEBUG(
"SiPixelTemplateReco") <<
"xsum[] = ";
547 for (i = 0; i < BXSIZE - 1; ++
i) {
548 LOGDEBUG(
"SiPixelTemplateReco") << xsum[
i] <<
", ";
550 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BXSIZE - 1] <<
ENDL;
559 LOGDEBUG(
"SiPixelTemplateReco") <<
"x-length of pixel cluster is larger than maximum template size" <<
ENDL;
561 LOGDEBUG(
"SiPixelTemplateReco") <<
"xsum[] = ";
562 for (i = 0; i < BXSIZE - 1; ++
i) {
563 LOGDEBUG(
"SiPixelTemplateReco") << xsum[
i] <<
", ";
565 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BXSIZE - 1] <<
ENDL;
578 midpix = (fxpix + lxpix) / 2;
579 shiftx = templ.
cxtemp() - midpix;
583 int lxtmp = lxpix + shiftx;
584 int fxtmp = fxpix + shiftx;
598 for (i = lxpix; i >= fxpix; --
i) {
599 xsum[i + shiftx] = xsum[
i];
601 xd[i + shiftx] = xd[
i];
604 }
else if (shiftx < 0) {
605 for (i = fxpix; i <= lxpix; ++
i) {
606 xsum[i + shiftx] = xsum[
i];
608 xd[i + shiftx] = xd[
i];
616 xsum[fxpix - 1] = pseudopix;
617 xsum[fxpix - 2] = pseudopix;
618 xsum[lxpix + 1] = pseudopix;
619 xsum[lxpix + 2] = pseudopix;
631 fq = qtotal / templ.
qavg();
649 if (!deadpix && qtotal < 0.95
f * templ.
qmin()) {
652 if (!deadpix && qtotal < 0.95
f * templ.
qmin(1)) {
657 LOGDEBUG(
"SiPixelTemplateReco") <<
"ID = " <<
id <<
" cot(alpha) = " << cotalpha <<
" cot(beta) = " << cotbeta
658 <<
" nclusx = " << nclusx <<
" nclusy = " << nclusy <<
ENDL;
665 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
666 if (speed < 0 || speed > 3) {
667 throw cms::Exception(
"DataCorrupt") <<
"SiPixelTemplateReco::PixelTempReco1D called with illegal speed = " << speed
671 assert(speed >= 0 && speed < 4);
720 LOGDEBUG(
"SiPixelTemplateReco") <<
"fypix " << fypix <<
" lypix = " << lypix <<
" fybin = " << fybin
721 <<
" lybin = " << lybin <<
" djy = " << djy <<
" logypx = " << logypx <<
ENDL;
722 LOGDEBUG(
"SiPixelTemplateReco") <<
"fxpix " << fxpix <<
" lxpix = " << lxpix <<
" fxbin = " << fxbin
723 <<
" lxbin = " << lxbin <<
" djx = " << djx <<
" logxpx = " << logxpx <<
ENDL;
728 templ.
ytemp(fybin, lybin, ytemp);
730 templ.
xtemp(fxbin, lxbin, xtemp);
738 if (nypix > logypx) {
741 if (yd[i] && !yd[i + 1]) {
742 for (j = fybin; j <= lybin; ++
j) {
745 sigavg = (ytemp[
j][
i] + ytemp[
j][i + 1]) / 2.
f;
746 ytemp[
j][
i] = sigavg;
747 ytemp[
j][i + 1] = sigavg;
758 sythr = 1.1 * (templ.
symax());
762 std::sort(&ysort[0], &ysort[logypx]);
764 sythr = 1.01f * ysort[0];
766 if (ysort[1] > sythr) {
767 sythr = 1.01f * ysort[1];
774 templ.
ysigma2(fypix, lypix, sythr, ysum, ysig2);
779 for (i = fybin; i <= lybin; ++
i) {
780 chi2ybin[
i] = -1.e15f;
783 for (i = fypix - 2; i <= lypix + 2; ++
i) {
784 yw2[
i] = 1.f / ysig2[
i];
785 ysw[
i] = ysum[
i] * yw2[
i];
786 ss2 += ysum[
i] * ysw[
i];
794 for (j = jmin; j <= jmax; j += deltaj) {
795 if (chi2ybin[j] < -100.
f) {
798 for (i = fypix - 2; i <= lypix + 2; ++
i) {
799 ssa += ysw[
i] * ytemp[
j][
i];
800 sa2 += ytemp[
j][
i] * ytemp[
j][
i] * yw2[
i];
804 LOGERROR(
"SiPixelTemplateReco") <<
"illegal chi2ymin normalization (1) = " << rat <<
ENDL;
807 chi2ybin[
j] = ss2 - 2.f * ssa / rat + sa2 / (rat * rat);
809 if (chi2ybin[j] < chi2ymin) {
810 chi2ymin = chi2ybin[
j];
815 if (minbin > fybin) {
816 jmin = minbin - deltaj;
820 if (minbin < lybin) {
821 jmax = minbin + deltaj;
828 LOGDEBUG(
"SiPixelTemplateReco") <<
"minbin " << minbin <<
" chi2ymin = " << chi2ymin <<
ENDL;
835 delta = templ.
dyone();
836 sigma = templ.
syone();
838 delta = templ.
dytwo();
839 sigma = templ.
sytwo();
842 yrec = 0.5f * (fypix + lypix - 2 * shifty + 2.f * originy) * ysize - delta;
851 chi21max = fmax(chi21min, (
double)templ.
chi2yminone());
852 chi2ymin -= chi21max;
857 meany = fmax(mean1pix, (
double)templ.
chi2yavgone());
858 hchi2 = chi2ymin / 2.;
860 proby = 1. - TMath::Gamma(hndof, hchi2);
878 for (i = fypix - 2; i <= lypix + 2; ++
i) {
879 ssa += ysw[
i] * ytemp[binl][
i];
880 sa2 += ytemp[binl][
i] * ytemp[binl][
i] * yw2[
i];
881 ssba += ysw[
i] * (ytemp[binh][
i] - ytemp[binl][
i]);
882 saba += ytemp[binl][
i] * (ytemp[binh][
i] - ytemp[binl][
i]) * yw2[i];
883 sba2 += (ytemp[binh][
i] - ytemp[binl][
i]) * (ytemp[binh][i] - ytemp[binl][i]) * yw2[
i];
888 rat = (ssba * ssa - ss2 * saba) / (ss2 * sba2 - ssba * ssba);
895 rnorm = (ssa + rat * ssba) / ss2;
901 qfy += ysum[fypix + 1];
906 qly += ysum[lypix - 1];
914 float qyfrac = (qfy - qly) / (qfy + qly);
915 bias = templ.
yflcorr(binq, qyfrac) + templ.
yavg(binq);
919 yrec = (0.125f * binl +
BHY - 2.5f + rat * (binh - binl) * 0.125
f - (
float)shifty + originy) * ysize - bias;
920 sigmay = templ.
yrms(binq);
925 LOGERROR(
"SiPixelTemplateReco") <<
"illegal chi2y normalization (2) = " << rnorm <<
ENDL;
928 chi2y = ss2 - 2. / rnorm * ssa - 2. / rnorm * rat * ssba +
929 (sa2 + 2. * rat * saba + rat * rat * sba2) / (rnorm * rnorm) - templ.
chi2ymin(binq);
942 proby = 1. - TMath::Gamma(hndof, hchi2);
951 if (nxpix > logxpx) {
954 if (xd[i] && !xd[i + 1]) {
955 for (j = fxbin; j <= lxbin; ++
j) {
958 sigavg = (xtemp[
j][
i] + xtemp[
j][i + 1]) / 2.
f;
959 xtemp[
j][
i] = sigavg;
960 xtemp[
j][i + 1] = sigavg;
971 sxthr = 1.1f * templ.
sxmax();
974 std::sort(&xsort[0], &xsort[logxpx]);
976 sxthr = 1.01f * xsort[0];
978 if (xsort[1] > sxthr) {
979 sxthr = 1.01f * xsort[1];
986 templ.
xsigma2(fxpix, lxpix, sxthr, xsum, xsig2);
991 for (i = fxbin; i <= lxbin; ++
i) {
992 chi2xbin[
i] = -1.e15f;
995 for (i = fxpix - 2; i <= lxpix + 2; ++
i) {
996 xw2[
i] = 1.f / xsig2[
i];
997 xsw[
i] = xsum[
i] * xw2[
i];
998 ss2 += xsum[
i] * xsw[
i];
1004 while (deltaj > 0) {
1005 for (j = jmin; j <= jmax; j += deltaj) {
1006 if (chi2xbin[j] < -100.
f) {
1010 for (i = fxpix - 2; i <= lxpix + 2; ++
i) {
1012 ssa += xsw[
i] * xtemp[
j][
i];
1013 sa2 += xtemp[
j][
i] * xtemp[
j][
i] * xw2[
i];
1018 LOGERROR(
"SiPixelTemplateReco") <<
"illegal chi2xmin normalization (1) = " << rat <<
ENDL;
1021 chi2xbin[
j] = ss2 - 2.f * ssa / rat + sa2 / (rat * rat);
1023 if (chi2xbin[j] < chi2xmin) {
1024 chi2xmin = chi2xbin[
j];
1029 if (minbin > fxbin) {
1030 jmin = minbin - deltaj;
1034 if (minbin < lxbin) {
1035 jmax = minbin + deltaj;
1042 LOGDEBUG(
"SiPixelTemplateReco") <<
"minbin " << minbin <<
" chi2xmin = " << chi2xmin <<
ENDL;
1049 delta = templ.
dxone();
1050 sigma = templ.
sxone();
1052 delta = templ.
dxtwo();
1053 sigma = templ.
sxtwo();
1055 xrec = 0.5 * (fxpix + lxpix - 2 * shiftx + 2. * originx) * xsize - delta;
1064 chi21max = fmax(chi21min, (
double)templ.
chi2xminone());
1065 chi2xmin -= chi21max;
1066 if (chi2xmin < 0.) {
1069 meanx = fmax(mean1pix, (
double)templ.
chi2xavgone());
1070 hchi2 = chi2xmin / 2.;
1072 probx = 1. - TMath::Gamma(hndof, hchi2);
1090 for (i = fxpix - 2; i <= lxpix + 2; ++
i) {
1091 ssa += xsw[
i] * xtemp[binl][
i];
1092 sa2 += xtemp[binl][
i] * xtemp[binl][
i] * xw2[
i];
1093 ssba += xsw[
i] * (xtemp[binh][
i] - xtemp[binl][
i]);
1094 saba += xtemp[binl][
i] * (xtemp[binh][
i] - xtemp[binl][
i]) * xw2[i];
1095 sba2 += (xtemp[binh][
i] - xtemp[binl][
i]) * (xtemp[binh][i] - xtemp[binl][i]) * xw2[
i];
1100 rat = (ssba * ssa - ss2 * saba) / (ss2 * sba2 - ssba * ssba);
1107 rnorm = (ssa + rat * ssba) / ss2;
1113 qfx += xsum[fxpix + 1];
1117 if (xd[lxpix - 1]) {
1118 qlx += xsum[lxpix - 1];
1126 float qxfrac = (qfx - qlx) / (qfx + qlx);
1127 bias = templ.
xflcorr(binq, qxfrac) + templ.
xavg(binq);
1131 xrec = (0.125f * binl +
BHX - 2.5f + rat * (binh - binl) * 0.125
f - (
float)shiftx + originx) * xsize - bias;
1132 sigmax = templ.
xrms(binq);
1137 LOGERROR(
"SiPixelTemplateReco") <<
"illegal chi2x normalization (2) = " << rnorm <<
ENDL;
1140 chi2x = ss2 - 2. / rnorm * ssa - 2. / rnorm * rat * ssba +
1141 (sa2 + 2. * rat * saba + rat * rat * sba2) / (rnorm * rnorm) - templ.
chi2xmin(binq);
1154 probx = 1. - TMath::Gamma(hndof, hchi2);
1159 if (proby < probmin) {
1162 if (probx < probmin) {
1172 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1173 if ((sigmaQ <= 0.) || (mpv <= 0.) || (kappa < 0.01) || (kappa > 9.9)) {
1174 throw cms::Exception(
"DataCorrupt") <<
"SiPixelTemplateReco::Vavilov parameters mpv/sigmaQ/kappa = " << mpv <<
"/"
1175 << sigmaQ <<
"/" << kappa << std::endl;
1178 assert((sigmaQ > 0.) && (mpv > 0.) && (kappa > 0.01) && (kappa < 10.));
1180 xvav = ((double)qtotal - mpv) / sigmaQ;
1184 VVIObjF vvidist(kappa, beta2, 1);
1185 prvav = vvidist.
fcn(xvav);
1188 prvav = TMath::VavilovI(xvav, kappa, beta2);
1194 if (probQ < probQmin) {
1257 const bool deadpix =
false;
1258 std::vector<std::pair<int, int> > zeropix;
1329 const bool deadpix =
false;
1330 std::vector<std::pair<int, int> > zeropix;
1334 if (cotbeta < 0.
f) {
1338 if (cotalpha < 0.
f) {
1406 const bool deadpix =
false;
1407 std::vector<std::pair<int, int> > zeropix;
1411 if (cotbeta < 0.
f) {
1415 if (cotalpha < 0.
f) {
float fbin(int i)
Return lower bound of Qbin definition.
float chi2xminone()
//!< minimum of x chi^2 for 1 pixel clusters
bool interpolate(int id, float cotalpha, float cotbeta, float locBz, float locBx)
float symax()
average pixel signal for y-projection of cluster
float yavg(int i)
average y-bias of reconstruction binned in 4 charge bins
int cytemp()
Return central pixel of y template pixels above readout threshold.
void xsigma2(int fxpix, int lxpix, float sxthr, float xsum[13+4], float xsig2[13+4])
float chi2xmin(int i)
minimum y chi^2 in 4 charge bins
float chi2ymin(int i)
minimum y chi^2 in 4 charge bins
float xrms(int i)
average x-rms of reconstruction binned in 4 charge bins
float qmin()
minimum cluster charge for valid hit (keeps 99.9% of simulated hits)
int PixelTempReco1D(int id, float cotalpha, float cotbeta, float locBz, float locBx, ClusMatrix &cluster, SiPixelTemplate &templ, float &yrec, float &sigmay, float &proby, float &xrec, float &sigmax, float &probx, int &qbin, int speed, bool deadpix, std::vector< std::pair< int, int > > &zeropix, float &probQ, int &nypix, int &nxpix)
float xflcorr(int binq, float qflx)
float sytwo()
rms for one double-pixel y-clusters
float chi2yminone()
//!< minimum of y chi^2 for 1 pixel clusters
float sxone()
rms for one pixel x-clusters
void ytemp(int fybin, int lybin, float ytemplate[41][21+4])
int cxtemp()
Return central pixel of x-template pixels above readout threshold.
float qscale()
charge scaling factor
float dxone()
mean offset/correction for one pixel x-clusters
float chi2yavg(int i)
average y chi^2 in 4 charge bins
void vavilov_pars(double &mpv, double &sigma, double &kappa)
float yrms(int i)
average y-rms of reconstruction binned in 4 charge bins
float yflcorr(int binq, float qfly)
float xsize()
pixel x-size (microns)
void ysigma2(int fypix, int lypix, float sythr, float ysum[21+4], float ysig2[21+4])
float sxtwo()
rms for one double-pixel x-clusters
float dytwo()
mean offset/correction for one double-pixel y-clusters
float s50()
1/2 of the pixel threshold signal in electrons
for(Iditer=Id.begin();Iditer!=Id.end();Iditer++)
void xtemp(int fxbin, int lxbin, float xtemplate[41][13+4])
float syone()
rms for one pixel y-clusters
static const int theVerboseLevel
float chi2yavgone()
//!< average y chi^2 for 1 pixel clusters
float qavg()
average cluster charge for this set of track angles
float sxmax()
average pixel signal for x-projection of cluster
float chi2xavgone()
//!< average x chi^2 for 1 pixel clusters
float pixmax()
maximum pixel charge
float chi2xavg(int i)
averaage x chi^2 in 4 charge bins
float dyone()
mean offset/correction for one pixel y-clusters
float xavg(int i)
average x-bias of reconstruction binned in 4 charge bins
float dxtwo()
mean offset/correction for one double-pixel x-clusters
float ysize()
pixel y-size (microns)