53 #ifndef SI_PIXEL_TEMPLATE_STANDALONE 64 #include "Math/DistFunc.h" 68 #ifndef SI_PIXEL_TEMPLATE_STANDALONE 72 #define LOGERROR(x) edm::LogError(x) 73 #define LOGDEBUG(x) LogDebug(x) 81 #define LOGERROR(x) std::cout << x << ": " 82 #define LOGDEBUG(x) std::cout << x << ": " 83 #define ENDL std::endl 151 std::vector<std::pair<int, int> >& zeropix,
158 int i,
j,
k, minbin, binl, binh, binq, midpix, fypix, lypix, logypx;
159 int fxpix, lxpix, logxpx, shifty, shiftx, nyzero[
TYSIZE];
161 int deltaj, jmin, jmax, fxbin, lxbin, fybin, lybin, djy, djx;
163 float sythr, sxthr, rnorm,
delta, sigma, sigavg, pseudopix, qscale, q50;
164 float ss2, ssa, sa2, ssba, saba, sba2, rat, fq, qtotal, qpixel, fbin[3];
165 float originx, originy, qfy, qly, qfx, qlx, bias,
maxpix, minmax;
166 double chi2x, meanx, chi2y, meany, chi2ymin, chi2xmin, chi21max;
167 double hchi2, hndof, prvav, mpv, sigmaQ,
kappa, xvav, beta2;
169 float chi2ybin[41], chi2xbin[41], ysig2[
BYSIZE], xsig2[
BXSIZE];
171 bool yd[
BYSIZE], xd[
BXSIZE], anyyd, anyxd, calc_probQ, use_VVIObj;
173 const float probmin = {1.110223e-16};
174 const float probQmin = {1.e-5};
178 const double mean1pix = {0.100}, chi21min = {0.160};
183 if (!templ.
interpolate(
id, cotalpha, cotbeta, locBz, locBx)) {
185 LOGDEBUG(
"SiPixelTemplateReco") <<
"input cluster direction cot(alpha) = " << cotalpha
186 <<
", cot(beta) = " << cotbeta <<
", local B_z = " << locBz
187 <<
", local B_x = " << locBx <<
", template ID = " <<
id 188 <<
", no reconstruction performed" <<
ENDL;
213 xsize = templ.
xsize();
214 ysize = templ.
ysize();
218 for (i = 0; i < 3; ++
i) {
219 fbin[
i] = templ.
fbin(i);
225 pseudopix = 0.2f * q50;
233 nclusx = cluster.
mrow;
235 auto const xdouble = cluster.
xdouble;
236 auto const ydouble = cluster.
ydouble;
240 for (i = 0; i < nclusx * nclusy; ++
i) {
246 for (j = 0; j < nclusx; ++
j)
247 for (i = 0; i < nclusy; ++
i) {
252 if (cluster(j, i) > maxpix) {
262 memset(nyzero, 0,
TYSIZE *
sizeof(
int));
263 memset(ysum, 0,
BYSIZE *
sizeof(
float));
264 for (i = 0; i < nclusy; ++
i) {
266 for (j = 0; j < nclusx; ++
j) {
267 ysum[
i] += cluster(j, i);
284 std::vector<std::pair<int, int> >::const_iterator zeroIter = zeropix.begin(), zeroEnd = zeropix.end();
285 for (; zeroIter != zeroEnd; ++zeroIter) {
286 i = zeroIter->second;
287 if (i < 0 || i >
TYSIZE - 1) {
288 LOGERROR(
"SiPixelTemplateReco") <<
"dead pixel column y-index " << i <<
", no reconstruction performed" <<
ENDL;
303 nypix = lypix - fypix + 1;
307 for (zeroIter = zeropix.begin(); zeroIter != zeroEnd; ++zeroIter) {
308 i = zeroIter->second;
310 if (j < 0 || j >
TXSIZE - 1) {
311 LOGERROR(
"SiPixelTemplateReco") <<
"dead pixel column x-index " << j <<
", no reconstruction performed" <<
ENDL;
314 if ((i == fypix || i == lypix) && nypix > 1) {
315 maxpix = templ.
symax() / 2.;
317 maxpix = templ.
symax();
322 if (nyzero[i] > 0 && nyzero[i] < 3) {
323 qpixel = (maxpix - ysum[
i]) / (
float)nyzero[
i];
330 cluster(j, i) = qpixel;
345 for (i = 0; i < nclusy; ++
i) {
346 for (j = 0; j < nclusx; ++
j) {
347 ysum[
k] += cluster(j, i);
354 ysum[k + 1] = ysum[
k];
376 for (j = 0; j < nclusx; ++
j) {
377 for (i = 0; i < nclusy; ++
i) {
378 xsum[
k] += cluster(j, i);
385 xsum[k + 1] = xsum[
k];
411 ysort[logypx] = ysum[
i];
423 if ((lypix - fypix + 1) != nypix || nypix == 0) {
424 LOGDEBUG(
"SiPixelTemplateReco") <<
"y-length of pixel cluster doesn't agree with number of pixels above threshold" 427 LOGDEBUG(
"SiPixelTemplateReco") <<
"ysum[] = ";
428 for (i = 0; i < BYSIZE - 1; ++
i) {
429 LOGDEBUG(
"SiPixelTemplateReco") << ysum[
i] <<
", ";
431 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BYSIZE - 1] <<
ENDL;
440 LOGDEBUG(
"SiPixelTemplateReco") <<
"y-length of pixel cluster is larger than maximum template size" <<
ENDL;
442 LOGDEBUG(
"SiPixelTemplateReco") <<
"ysum[] = ";
443 for (i = 0; i < BYSIZE - 1; ++
i) {
444 LOGDEBUG(
"SiPixelTemplateReco") << ysum[
i] <<
", ";
446 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BYSIZE - 1] <<
ENDL;
459 midpix = (fypix + lypix) / 2;
460 shifty = templ.
cytemp() - midpix;
464 int lytmp = lypix + shifty;
465 int fytmp = fypix + shifty;
479 for (i = lypix; i >= fypix; --
i) {
480 ysum[i + shifty] = ysum[
i];
482 yd[i + shifty] = yd[
i];
485 }
else if (shifty < 0) {
486 for (i = fypix; i <= lypix; ++
i) {
487 ysum[i + shifty] = ysum[
i];
489 yd[i + shifty] = yd[
i];
499 ysum[fypix - 1] = pseudopix;
500 ysum[fypix - 2] = pseudopix;
501 ysum[lypix + 1] = pseudopix;
502 ysum[lypix + 2] = pseudopix;
524 xsort[logxpx] = xsum[
i];
536 if ((lxpix - fxpix + 1) != nxpix) {
537 LOGDEBUG(
"SiPixelTemplateReco") <<
"x-length of pixel cluster doesn't agree with number of pixels above threshold" 540 LOGDEBUG(
"SiPixelTemplateReco") <<
"xsum[] = ";
541 for (i = 0; i < BXSIZE - 1; ++
i) {
542 LOGDEBUG(
"SiPixelTemplateReco") << xsum[
i] <<
", ";
544 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BXSIZE - 1] <<
ENDL;
553 LOGDEBUG(
"SiPixelTemplateReco") <<
"x-length of pixel cluster is larger than maximum template size" <<
ENDL;
555 LOGDEBUG(
"SiPixelTemplateReco") <<
"xsum[] = ";
556 for (i = 0; i < BXSIZE - 1; ++
i) {
557 LOGDEBUG(
"SiPixelTemplateReco") << xsum[
i] <<
", ";
559 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BXSIZE - 1] <<
ENDL;
572 midpix = (fxpix + lxpix) / 2;
573 shiftx = templ.
cxtemp() - midpix;
577 int lxtmp = lxpix + shiftx;
578 int fxtmp = fxpix + shiftx;
592 for (i = lxpix; i >= fxpix; --
i) {
593 xsum[i + shiftx] = xsum[
i];
595 xd[i + shiftx] = xd[
i];
598 }
else if (shiftx < 0) {
599 for (i = fxpix; i <= lxpix; ++
i) {
600 xsum[i + shiftx] = xsum[
i];
602 xd[i + shiftx] = xd[
i];
610 xsum[fxpix - 1] = pseudopix;
611 xsum[fxpix - 2] = pseudopix;
612 xsum[lxpix + 1] = pseudopix;
613 xsum[lxpix + 2] = pseudopix;
625 fq = qtotal / templ.
qavg();
643 if (!deadpix && qtotal < 0.95
f * templ.
qmin()) {
646 if (!deadpix && qtotal < 0.95
f * templ.
qmin(1)) {
651 LOGDEBUG(
"SiPixelTemplateReco") <<
"ID = " <<
id <<
" cot(alpha) = " << cotalpha <<
" cot(beta) = " << cotbeta
652 <<
" nclusx = " << nclusx <<
" nclusy = " << nclusy <<
ENDL;
659 #ifndef SI_PIXEL_TEMPLATE_STANDALONE 660 if (speed < 0 || speed > 3) {
661 throw cms::Exception(
"DataCorrupt") <<
"SiPixelTemplateReco::PixelTempReco1D called with illegal speed = " << speed
665 assert(speed >= 0 && speed < 4);
714 LOGDEBUG(
"SiPixelTemplateReco") <<
"fypix " << fypix <<
" lypix = " << lypix <<
" fybin = " << fybin
715 <<
" lybin = " << lybin <<
" djy = " << djy <<
" logypx = " << logypx <<
ENDL;
716 LOGDEBUG(
"SiPixelTemplateReco") <<
"fxpix " << fxpix <<
" lxpix = " << lxpix <<
" fxbin = " << fxbin
717 <<
" lxbin = " << lxbin <<
" djx = " << djx <<
" logxpx = " << logxpx <<
ENDL;
722 templ.
ytemp(fybin, lybin, ytemp);
724 templ.
xtemp(fxbin, lxbin, xtemp);
732 if (nypix > logypx) {
735 if (yd[i] && !yd[i + 1]) {
736 for (j = fybin; j <= lybin; ++
j) {
739 sigavg = (ytemp[
j][
i] + ytemp[
j][i + 1]) / 2.
f;
740 ytemp[
j][
i] = sigavg;
741 ytemp[
j][i + 1] = sigavg;
752 sythr = 1.1 * (templ.
symax());
756 std::sort(&ysort[0], &ysort[logypx]);
758 sythr = 1.01f * ysort[0];
760 if (ysort[1] > sythr) {
761 sythr = 1.01f * ysort[1];
768 templ.
ysigma2(fypix, lypix, sythr, ysum, ysig2);
773 for (i = fybin; i <= lybin; ++
i) {
774 chi2ybin[
i] = -1.e15f;
777 for (i = fypix - 2; i <= lypix + 2; ++
i) {
778 yw2[
i] = 1.f / ysig2[
i];
779 ysw[
i] = ysum[
i] * yw2[
i];
780 ss2 += ysum[
i] * ysw[
i];
788 for (j = jmin; j <= jmax; j += deltaj) {
789 if (chi2ybin[j] < -100.
f) {
792 for (i = fypix - 2; i <= lypix + 2; ++
i) {
793 ssa += ysw[
i] * ytemp[
j][
i];
794 sa2 += ytemp[
j][
i] * ytemp[
j][
i] * yw2[
i];
798 LOGERROR(
"SiPixelTemplateReco") <<
"illegal chi2ymin normalization (1) = " << rat <<
ENDL;
801 chi2ybin[
j] = ss2 - 2.f * ssa / rat + sa2 / (rat * rat);
803 if (chi2ybin[j] < chi2ymin) {
804 chi2ymin = chi2ybin[
j];
809 if (minbin > fybin) {
810 jmin = minbin - deltaj;
814 if (minbin < lybin) {
815 jmax = minbin + deltaj;
822 LOGDEBUG(
"SiPixelTemplateReco") <<
"minbin " << minbin <<
" chi2ymin = " << chi2ymin <<
ENDL;
829 delta = templ.
dyone();
830 sigma = templ.
syone();
832 delta = templ.
dytwo();
833 sigma = templ.
sytwo();
836 yrec = 0.5f * (fypix + lypix - 2 * shifty + 2.f * originy) * ysize - delta;
845 chi21max = fmax(chi21min, (
double)templ.
chi2yminone());
846 chi2ymin -= chi21max;
851 meany = fmax(mean1pix, (
double)templ.
chi2yavgone());
852 hchi2 = chi2ymin / 2.;
854 proby = 1. - TMath::Gamma(hndof, hchi2);
872 for (i = fypix - 2; i <= lypix + 2; ++
i) {
873 ssa += ysw[
i] * ytemp[binl][
i];
874 sa2 += ytemp[binl][
i] * ytemp[binl][
i] * yw2[
i];
875 ssba += ysw[
i] * (ytemp[binh][
i] - ytemp[binl][
i]);
876 saba += ytemp[binl][
i] * (ytemp[binh][
i] - ytemp[binl][
i]) * yw2[i];
877 sba2 += (ytemp[binh][
i] - ytemp[binl][
i]) * (ytemp[binh][i] - ytemp[binl][i]) * yw2[
i];
882 rat = (ssba * ssa - ss2 * saba) / (ss2 * sba2 - ssba * ssba);
889 rnorm = (ssa + rat * ssba) / ss2;
895 qfy += ysum[fypix + 1];
900 qly += ysum[lypix - 1];
908 float qyfrac = (qfy - qly) / (qfy + qly);
909 bias = templ.
yflcorr(binq, qyfrac) + templ.
yavg(binq);
913 yrec = (0.125f * binl +
BHY - 2.5f + rat * (binh - binl) * 0.125
f - (
float)shifty + originy) * ysize - bias;
914 sigmay = templ.
yrms(binq);
919 LOGERROR(
"SiPixelTemplateReco") <<
"illegal chi2y normalization (2) = " << rnorm <<
ENDL;
922 chi2y = ss2 - 2. / rnorm * ssa - 2. / rnorm * rat * ssba +
923 (sa2 + 2. * rat * saba + rat * rat * sba2) / (rnorm * rnorm) - templ.
chi2ymin(binq);
936 proby = 1. - TMath::Gamma(hndof, hchi2);
945 if (nxpix > logxpx) {
948 if (xd[i] && !xd[i + 1]) {
949 for (j = fxbin; j <= lxbin; ++
j) {
952 sigavg = (xtemp[
j][
i] + xtemp[
j][i + 1]) / 2.
f;
953 xtemp[
j][
i] = sigavg;
954 xtemp[
j][i + 1] = sigavg;
965 sxthr = 1.1f * templ.
sxmax();
968 std::sort(&xsort[0], &xsort[logxpx]);
970 sxthr = 1.01f * xsort[0];
972 if (xsort[1] > sxthr) {
973 sxthr = 1.01f * xsort[1];
980 templ.
xsigma2(fxpix, lxpix, sxthr, xsum, xsig2);
985 for (i = fxbin; i <= lxbin; ++
i) {
986 chi2xbin[
i] = -1.e15f;
989 for (i = fxpix - 2; i <= lxpix + 2; ++
i) {
990 xw2[
i] = 1.f / xsig2[
i];
991 xsw[
i] = xsum[
i] * xw2[
i];
992 ss2 += xsum[
i] * xsw[
i];
999 for (j = jmin; j <= jmax; j += deltaj) {
1000 if (chi2xbin[j] < -100.
f) {
1004 for (i = fxpix - 2; i <= lxpix + 2; ++
i) {
1006 ssa += xsw[
i] * xtemp[
j][
i];
1007 sa2 += xtemp[
j][
i] * xtemp[
j][
i] * xw2[
i];
1012 LOGERROR(
"SiPixelTemplateReco") <<
"illegal chi2xmin normalization (1) = " << rat <<
ENDL;
1015 chi2xbin[
j] = ss2 - 2.f * ssa / rat + sa2 / (rat * rat);
1017 if (chi2xbin[j] < chi2xmin) {
1018 chi2xmin = chi2xbin[
j];
1023 if (minbin > fxbin) {
1024 jmin = minbin - deltaj;
1028 if (minbin < lxbin) {
1029 jmax = minbin + deltaj;
1036 LOGDEBUG(
"SiPixelTemplateReco") <<
"minbin " << minbin <<
" chi2xmin = " << chi2xmin <<
ENDL;
1043 delta = templ.
dxone();
1044 sigma = templ.
sxone();
1046 delta = templ.
dxtwo();
1047 sigma = templ.
sxtwo();
1049 xrec = 0.5 * (fxpix + lxpix - 2 * shiftx + 2. * originx) * xsize - delta;
1058 chi21max = fmax(chi21min, (
double)templ.
chi2xminone());
1059 chi2xmin -= chi21max;
1060 if (chi2xmin < 0.) {
1063 meanx = fmax(mean1pix, (
double)templ.
chi2xavgone());
1064 hchi2 = chi2xmin / 2.;
1066 probx = 1. - TMath::Gamma(hndof, hchi2);
1084 for (i = fxpix - 2; i <= lxpix + 2; ++
i) {
1085 ssa += xsw[
i] * xtemp[binl][
i];
1086 sa2 += xtemp[binl][
i] * xtemp[binl][
i] * xw2[
i];
1087 ssba += xsw[
i] * (xtemp[binh][
i] - xtemp[binl][
i]);
1088 saba += xtemp[binl][
i] * (xtemp[binh][
i] - xtemp[binl][
i]) * xw2[i];
1089 sba2 += (xtemp[binh][
i] - xtemp[binl][
i]) * (xtemp[binh][i] - xtemp[binl][i]) * xw2[
i];
1094 rat = (ssba * ssa - ss2 * saba) / (ss2 * sba2 - ssba * ssba);
1101 rnorm = (ssa + rat * ssba) / ss2;
1107 qfx += xsum[fxpix + 1];
1111 if (xd[lxpix - 1]) {
1112 qlx += xsum[lxpix - 1];
1120 float qxfrac = (qfx - qlx) / (qfx + qlx);
1121 bias = templ.
xflcorr(binq, qxfrac) + templ.
xavg(binq);
1125 xrec = (0.125f * binl +
BHX - 2.5f + rat * (binh - binl) * 0.125
f - (
float)shiftx + originx) * xsize - bias;
1126 sigmax = templ.
xrms(binq);
1131 LOGERROR(
"SiPixelTemplateReco") <<
"illegal chi2x normalization (2) = " << rnorm <<
ENDL;
1134 chi2x = ss2 - 2. / rnorm * ssa - 2. / rnorm * rat * ssba +
1135 (sa2 + 2. * rat * saba + rat * rat * sba2) / (rnorm * rnorm) - templ.
chi2xmin(binq);
1148 probx = 1. - TMath::Gamma(hndof, hchi2);
1153 if (proby < probmin) {
1156 if (probx < probmin) {
1166 #ifndef SI_PIXEL_TEMPLATE_STANDALONE 1167 if ((sigmaQ <= 0.) || (mpv <= 0.) || (kappa < 0.01) || (kappa > 9.9)) {
1168 throw cms::Exception(
"DataCorrupt") <<
"SiPixelTemplateReco::Vavilov parameters mpv/sigmaQ/kappa = " << mpv <<
"/" 1169 << sigmaQ <<
"/" << kappa << std::endl;
1172 assert((sigmaQ > 0.) && (mpv > 0.) && (kappa > 0.01) && (kappa < 10.));
1174 xvav = ((double)qtotal - mpv) / sigmaQ;
1178 VVIObjF vvidist(kappa, beta2, 1);
1179 prvav = vvidist.
fcn(xvav);
1182 prvav = TMath::VavilovI(xvav, kappa, beta2);
1188 if (probQ < probQmin) {
1251 const bool deadpix =
false;
1252 std::vector<std::pair<int, int> > zeropix;
1323 const bool deadpix =
false;
1324 std::vector<std::pair<int, int> > zeropix;
1328 if (cotbeta < 0.
f) {
1332 if (cotalpha < 0.
f) {
1400 const bool deadpix =
false;
1401 std::vector<std::pair<int, int> > zeropix;
1405 if (cotbeta < 0.
f) {
1409 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
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
static const G4double kappa
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)