28 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
31 #define LOGERROR(x) edm::LogError(x)
32 #define LOGDEBUG(x) LogDebug(x)
38 #define LOGERROR(x) std::cout << x << ": "
39 #define LOGDEBUG(x) std::cout << x << ": "
40 #define ENDL std::endl
43 using namespace SiPixelTemplateReco;
71 std::vector<bool> ydouble, std::vector<bool> xdouble,
73 float& yrec1,
float& yrec2,
float& sigmay,
float& proby,
74 float& xrec1,
float& xrec2,
float& sigmax,
float& probx,
int& qbin,
bool deadpix, std::vector<std::pair<int, int> > zeropix)
78 static int i,
j,
k, minbin, binq, midpix, fypix, nypix, lypix, logypx;
79 static int fxpix, nxpix, lxpix, logxpx, shifty, shiftx, nyzero[
TYSIZE];
80 static int nclusx, nclusy;
81 static int nybin, ycbin, nxbin, xcbin, minbinj, minbink;
82 static float sythr, sxthr,
delta,
sigma, sigavg, pseudopix, qscale;
83 static float ss2, ssa, sa2, rat, fq, qtotal, qpixel;
84 static float originx, originy, bias,
maxpix, minmax;
85 static double chi2x, meanx, chi2y, meany, chi2ymin, chi2xmin, chi21max;
86 static double hchi2, hndof;
90 const float ysize={150.}, xsize={100.}, sqrt2={2.};
91 const float probmin={1.110223e-16};
96 const double mean1pix={0.100}, chi21min={0.160};
101 if(!templ.
interpolate(
id, fpix, cotalpha, cotbeta)) {
102 LOGDEBUG(
"SiPixelTemplateReco") <<
"input cluster direction cot(alpha) = " << cotalpha <<
", cot(beta) = " << cotbeta <<
" is not within the acceptance of fpix = "
103 << fpix <<
", template ID = " <<
id <<
", no reconstruction performed" <<
ENDL;
109 pseudopix = templ.
s50();
117 if(cluster.num_dimensions() != 2) {
118 LOGERROR(
"SiPixelTemplateReco") <<
"input cluster container (BOOST Multiarray) has wrong number of dimensions" <<
ENDL;
121 nclusx = (int)cluster.shape()[0];
122 nclusy = (int)cluster.shape()[1];
123 if(nclusx != (
int)xdouble.size()) {
124 LOGERROR(
"SiPixelTemplateReco") <<
"input cluster container x-size is not equal to double pixel flag container size" <<
ENDL;
127 if(nclusy != (
int)ydouble.size()) {
128 LOGERROR(
"SiPixelTemplateReco") <<
"input cluster container y-size is not equal to double pixel flag container size" <<
ENDL;
139 for(i=0; i<nclusy; ++
i) {
140 for(j=0; j<nclusx; ++
j) {
141 if(cluster[j][i] > 0) {cluster[
j][
i] *= qscale;}
148 minmax = 2.*templ.
pixmax();
149 for(i=0; i<nclusy; ++
i) {
151 if(ydouble[i]) {maxpix *=2.;}
152 for(j=0; j<nclusx; ++
j) {
153 qtotal += cluster[
j][
i];
154 if(cluster[j][i] > maxpix) {cluster[
j][
i] =
maxpix;}
161 fypix =
BYM3; lypix = -1;
162 for(i=0; i<nclusy; ++
i) {
163 ysum[
i] = 0.; nyzero[
i] = 0;
165 for(j=0; j<nclusx; ++
j) {
166 ysum[
i] += cluster[
j][
i];
170 if(i < fypix) {fypix =
i;}
171 if(i > lypix) {lypix =
i;}
179 std::vector<std::pair<int, int> >::const_iterator zeroIter = zeropix.begin(), zeroEnd = zeropix.end();
180 for ( ; zeroIter != zeroEnd; ++zeroIter ) {
181 i = zeroIter->second;
182 if(i<0 || i>
TYSIZE-1) {
LOGERROR(
"SiPixelTemplateReco") <<
"dead pixel column y-index " << i <<
", no reconstruction performed" <<
ENDL;
188 if(i < fypix) {fypix =
i;}
189 if(i > lypix) {lypix =
i;}
192 nypix = lypix-fypix+1;
196 for (zeroIter = zeropix.begin(); zeroIter != zeroEnd; ++zeroIter ) {
197 i = zeroIter->second; j = zeroIter->first;
198 if(j<0 || j>
TXSIZE-1) {
LOGERROR(
"SiPixelTemplateReco") <<
"dead pixel column x-index " << j <<
", no reconstruction performed" <<
ENDL;
200 if((i == fypix || i == lypix) && nypix > 1) {maxpix = templ.
symax()/2.;}
else {maxpix = templ.
symax();}
201 if(ydouble[i]) {maxpix *=2.;}
202 if(nyzero[i] > 0 && nyzero[i] < 3) {qpixel = (maxpix - ysum[
i])/(
float)nyzero[
i];}
else {qpixel = 1.;}
203 if(qpixel < 1.) {qpixel = 1.;}
204 cluster[
j][
i] = qpixel;
213 for(i=0; i<
BYSIZE; ++
i) { ysum[
i] = 0.; yd[
i] =
false;}
216 for(i=0; i<nclusy; ++
i) {
217 for(j=0; j<nclusx; ++
j) {
218 ysum[
k] += cluster[
j][
i];
234 if(k >
BYM1) {
break;}
239 for(i=0; i<
BXSIZE; ++
i) { xsum[
i] = 0.; xd[
i] =
false;}
242 for(j=0; j<nclusx; ++
j) {
243 for(i=0; i<nclusy; ++
i) {
244 xsum[
k] += cluster[
j][
i];
260 if(k >
BXM1) {
break;}
271 if(fypix == -1) {fypix =
i;}
273 ysort[logypx] = ysum[
i];
283 if((lypix-fypix+1) != nypix || nypix == 0) {
284 LOGDEBUG(
"SiPixelTemplateReco") <<
"y-length of pixel cluster doesn't agree with number of pixels above threshold" <<
ENDL;
286 LOGDEBUG(
"SiPixelTemplateReco") <<
"ysum[] = ";
287 for(i=0; i<BYSIZE-1; ++
i) {
LOGDEBUG(
"SiPixelTemplateReco") << ysum[
i] <<
", ";}
288 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BYSIZE-1] <<
ENDL;
297 LOGDEBUG(
"SiPixelTemplateReco") <<
"y-length of pixel cluster is larger than maximum template size" <<
ENDL;
299 LOGDEBUG(
"SiPixelTemplateReco") <<
"ysum[] = ";
300 for(i=0; i<BYSIZE-1; ++
i) {
LOGDEBUG(
"SiPixelTemplateReco") << ysum[
i] <<
", ";}
301 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BYSIZE-1] <<
ENDL;
309 midpix = (fypix+lypix)/2;
310 shifty =
BHY - midpix;
312 for(i=lypix; i>=fypix; --
i) {
313 ysum[i+shifty] = ysum[
i];
315 yd[i+shifty] = yd[
i];
318 }
else if (shifty < 0) {
319 for(i=fypix; i<=lypix; ++
i) {
320 ysum[i+shifty] = ysum[
i];
322 yd[i+shifty] = yd[
i];
331 if(fypix > 1 && fypix <
BYM2) {
332 ysum[fypix-1] = pseudopix;
333 ysum[fypix-2] = 0.2*pseudopix;
335 if(lypix > 1 && lypix <
BYM2) {
336 ysum[lypix+1] = pseudopix;
337 ysum[lypix+2] = 0.2*pseudopix;
356 if(fxpix == -1) {fxpix =
i;}
358 xsort[logxpx] = xsum[
i];
368 if((lxpix-fxpix+1) != nxpix) {
370 LOGDEBUG(
"SiPixelTemplateReco") <<
"x-length of pixel cluster doesn't agree with number of pixels above threshold" <<
ENDL;
372 LOGDEBUG(
"SiPixelTemplateReco") <<
"xsum[] = ";
373 for(i=0; i<BXSIZE-1; ++
i) {
LOGDEBUG(
"SiPixelTemplateReco") << xsum[
i] <<
", ";}
374 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BXSIZE-1] <<
ENDL;
384 LOGDEBUG(
"SiPixelTemplateReco") <<
"x-length of pixel cluster is larger than maximum template size" <<
ENDL;
386 LOGDEBUG(
"SiPixelTemplateReco") <<
"xsum[] = ";
387 for(i=0; i<BXSIZE-1; ++
i) {
LOGDEBUG(
"SiPixelTemplateReco") << xsum[
i] <<
", ";}
388 LOGDEBUG(
"SiPixelTemplateReco") << ysum[BXSIZE-1] <<
ENDL;
396 midpix = (fxpix+lxpix)/2;
397 shiftx =
BHX - midpix;
399 for(i=lxpix; i>=fxpix; --
i) {
400 xsum[i+shiftx] = xsum[
i];
402 xd[i+shiftx] = xd[
i];
405 }
else if (shiftx < 0) {
406 for(i=fxpix; i<=lxpix; ++
i) {
407 xsum[i+shiftx] = xsum[
i];
409 xd[i+shiftx] = xd[
i];
418 if(fxpix > 1 && fxpix <
BXM2) {
419 xsum[fxpix-1] = pseudopix;
420 xsum[fxpix-2] = 0.2*pseudopix;
422 if(lxpix > 1 && lxpix <
BXM2) {
423 xsum[lxpix+1] = pseudopix;
424 xsum[lxpix+2] = 0.2*pseudopix;
437 fq = qtotal/templ.
qavg();
455 if(!deadpix && qtotal < 1.9*templ.
qmin()) {qbin = 5;}
else {
456 if(!deadpix && qtotal < 1.9*templ.
qmin(1)) {qbin = 4;}
461 "ID = " <<
id <<
" FPix = " << fpix <<
462 " cot(alpha) = " << cotalpha <<
" cot(beta) = " << cotbeta <<
463 " nclusx = " << nclusx <<
" nclusy = " << nclusy <<
ENDL;
479 nybin = ytemp.shape()[0]; ycbin = nybin/2;
486 if(yd[i] && !yd[i+1]) {
487 for(j=0; j<nybin; ++
j) {
488 for(k=0; k<=
j; ++
k) {
492 sigavg = (ytemp[
j][
k][
i] + ytemp[
j][
k][i+1])/2.;
493 ytemp[
j][
k][
i] = sigavg;
494 ytemp[
j][
k][i+1] = sigavg;
506 sythr = 2.1*(templ.
symax());
511 if(logypx == 1) {sythr = 1.01*ysort[0];}
else {
512 if (ysort[1] > sythr) { sythr = 1.01*ysort[1]; }
517 for(i=0; i<
BYSIZE; ++
i) { ysig2[
i] = 0.;}
518 templ.
ysigma2(fypix, lypix, sythr, ysum, ysig2);
525 for(j=0; j<nybin; ++
j) {
526 for(k=0; k<=
j; ++
k) {
530 for(i=fypix-2; i<=lypix+2; ++
i) {
531 ss2 += ysum[
i]*ysum[
i]/ysig2[
i];
532 ssa += ysum[
i]*ytemp[
j][
k][
i]/ysig2[
i];
533 sa2 += ytemp[
j][
k][
i]*ytemp[
j][
k][
i]/ysig2[
i];
536 if(rat <= 0.) {
LOGERROR(
"SiPixelTemplateReco") <<
"illegal chi2ymin normalization = " << rat <<
ENDL; rat = 1.;}
537 chi2y=ss2-2.*ssa/rat+sa2/(rat*rat);
538 if(chi2y < chi2ymin) {
548 "minbins " << minbinj <<
"," << minbink <<
" chi2ymin = " << chi2ymin <<
ENDL;
556 delta = templ.
dyone();
557 sigma = templ.
syone();
559 delta = templ.
dytwo();
560 sigma = templ.
sytwo();
563 yrec1 = 0.5*(fypix+lypix-2*shifty+2.*originy)*ysize-delta;
574 chi21max = fmax(chi21min, (
double)templ.
chi2yminone());
576 if(chi2ymin < 0.) {chi2ymin = 0.;}
578 meany = fmax(mean1pix, (
double)templ.
chi2yavgone());
579 hchi2 = chi2ymin/2.; hndof = meany/2.;
588 if(logypx == 2 && fabsf(cotbeta) < 0.25) {
592 yrec1 = (fypix-shifty+originy)*ysize;
593 yrec2 = (lypix-shifty+originy)*ysize;
599 yrec1 = (fypix+0.5-shifty+originy)*ysize;
600 yrec2 = (lypix-shifty+originy)*ysize;
603 yrec1 = (fypix-shifty+originy)*ysize;
604 yrec2 = (lypix-0.5-shifty+originy)*ysize;
610 yrec1 = (fypix+0.5-shifty+originy)*ysize;
611 yrec2 = (lypix-0.5-shifty+originy)*ysize;
616 LOGERROR(
"SiPixelTemplateReco") <<
"weird problem: logical y-pixels = " << logypx <<
", total ysize in normal pixels = " << nypix <<
ENDL;
624 yrec1 = (0.125*(minbink-ycbin)+
BHY-(
float)shifty+originy)*ysize - bias;
625 yrec2 = (0.125*(minbinj-ycbin)+
BHY-(
float)shifty+originy)*ysize - bias;
626 sigmay = sqrt2*templ.
yrmsc2m(binq);
632 if(chi2ymin < 0.0) {chi2ymin = 0.0;}
634 if(meany < 0.01) {meany = 0.01;}
638 hchi2 = chi2ymin/2.; hndof = meany/2.;
646 nxbin = xtemp.shape()[0]; xcbin = nxbin/2;
653 if(xd[i] && !xd[i+1]) {
654 for(j=0; j<nxbin; ++
j) {
655 for(k=0; k<=
j; ++
k) {
659 sigavg = (xtemp[
j][
k][
i] + xtemp[
j][
k][i+1])/2.;
660 xtemp[
j][
k][
i] = sigavg;
661 xtemp[
j][
k][i+1] = sigavg;
673 sxthr = 2.1*templ.
sxmax();
677 if(logxpx == 1) {sxthr = 1.01*xsort[0];}
else {
678 if (xsort[1] > sxthr) { sxthr = 1.01*xsort[1]; }
683 for(i=0; i<
BYSIZE; ++
i) { xsig2[
i] = 0.; }
684 templ.
xsigma2(fxpix, lxpix, sxthr, xsum, xsig2);
691 for(j=0; j<nxbin; ++
j) {
692 for(k=0; k<=
j; ++
k) {
696 for(i=fxpix-2; i<=lxpix+2; ++
i) {
697 ss2 += xsum[
i]*xsum[
i]/xsig2[
i];
698 ssa += xsum[
i]*xtemp[
j][
k][
i]/xsig2[
i];
699 sa2 += xtemp[
j][
k][
i]*xtemp[
j][
k][
i]/xsig2[
i];
702 if(rat <= 0.) {
LOGERROR(
"SiPixelTemplateReco") <<
"illegal chi2ymin normalization = " << rat <<
ENDL; rat = 1.;}
703 chi2x=ss2-2.*ssa/rat+sa2/(rat*rat);
704 if(chi2x < chi2xmin) {
714 "minbin " << minbin <<
" chi2xmin = " << chi2xmin <<
ENDL;
722 delta = templ.
dxone();
723 sigma = templ.
sxone();
725 delta = templ.
dxtwo();
726 sigma = templ.
sxtwo();
728 xrec1 = 0.5*(fxpix+lxpix-2*shiftx+2.*originx)*xsize-delta;
738 chi21max = fmax(chi21min, (
double)templ.
chi2xminone());
740 if(chi2xmin < 0.) {chi2xmin = 0.;}
741 meanx = fmax(mean1pix, (
double)templ.
chi2xavgone());
742 hchi2 = chi2xmin/2.; hndof = meanx/2.;
754 xrec1 = (0.125*(minbink-xcbin)+
BHX-(
float)shiftx+originx)*xsize - bias;
755 xrec2 = (0.125*(minbinj-xcbin)+
BHX-(
float)shiftx+originx)*xsize - bias;
756 sigmax = sqrt2*templ.
xrmsc2m(binq);
760 if(chi2xmin < 0.0) {chi2xmin = 0.0;}
762 if(meanx < 0.01) {meanx = 0.01;}
763 hchi2 = chi2xmin/2.; hndof = meanx/2.;
769 if(proby < probmin) {proby = probmin;}
770 if(probx < probmin) {probx = probmin;}
801 std::vector<bool> ydouble, std::vector<bool> xdouble,
803 float& yrec1,
float& yrec2,
float& sigmay,
float& proby,
804 float& xrec1,
float& xrec2,
float& sigmax,
float& probx,
int& qbin)
807 const bool deadpix =
false;
808 std::vector<std::pair<int, int> > zeropix;
811 yrec1, yrec2, sigmay, proby, xrec1, xrec2, sigmax, probx, qbin, deadpix, zeropix);
float yrmsc2m(int i)
1st pass chi2 min search: average y-rms of reconstruction binned in 4 charge bins ...
float chi2xminone()
//!< minimum of x chi^2 for 1 pixel clusters
void ytemp3d(int nypix, array_3d &ytemplate)
static int theVerboseLevel
float symax()
average pixel signal for y-projection of cluster
float qmin()
minimum cluster charge for valid hit (keeps 99.9% of simulated hits)
float xavgc2m(int i)
1st pass chi2 min search: average x-bias of reconstruction binned in 4 charge bins ...
float sytwo()
rms for one double-pixel y-clusters
float chi2yminone()
//!< minimum of y chi^2 for 1 pixel clusters
bool interpolate(int id, float cotalpha, float cotbeta, float locBz)
float sxone()
rms for one pixel x-clusters
boost::multi_array< float, 2 > array_2d
float qscale()
charge scaling factor
float dxone()
mean offset/correction for one pixel x-clusters
void xtemp3d(int nxpix, array_3d &xtemplate)
const T & max(const T &a, const T &b)
float chi2yavg(int i)
average y chi^2 in 4 charge bins
boost::multi_array< float, 3 > array_3d
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
float yavgc2m(int i)
1st pass chi2 min search: average y-bias of reconstruction binned in 4 charge bins ...
float syone()
rms for one pixel y-clusters
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
void xsigma2(int fxpix, int lxpix, float sxthr, float xsum[BXSIZE], float xsig2[BXSIZE])
float chi2xavgone()
//!< average x chi^2 for 1 pixel clusters
float pixmax()
maximum pixel charge
void ysigma2(int fypix, int lypix, float sythr, float ysum[BYSIZE], float ysig2[BYSIZE])
float chi2xavg(int i)
averaage x chi^2 in 4 charge bins
int PixelTempSplit(int id, bool fpix, float cotalpha, float cotbeta, array_2d cluster, std::vector< bool > ydouble, std::vector< bool > xdouble, SiPixelTemplate &templ, float &yrec1, float &yrec2, float &sigmay, float &proby, float &xrec1, float &xrec2, float &sigmax, float &probx, int &qbin, bool deadpix, std::vector< std::pair< int, int > > zeropix)
float dyone()
mean offset/correction for one pixel y-clusters
float dxtwo()
mean offset/correction for one double-pixel x-clusters
float xrmsc2m(int i)
1st pass chi2 min search: average x-rms of reconstruction binned in 4 charge bins ...