Reconstruct the best estimate of the hit position for strip clusters, includes autoswitching to barycenter when that technique is more accurate.
90 int i,
j, minbin, binl, binh, binq, midpix;
91 int fxpix, nxpix, lxpix, logxpx, shiftx, ftpix, ltpix;
93 int deltaj, jmin, jmax, fxbin, lxbin, djx;
94 float sxthr, rnorm,
delta, sigma, pseudopix, qscale, q50, q100;
95 float ss2, ssa, sa2, ssba, saba, sba2, rat, fq, qtotal, barycenter, sigmaxbcn;
96 float originx, qfx, qlx, bias, biasbcn,
maxpix;
97 double chi2x, meanx, chi2xmin, chi21max;
98 double hchi2, hndof, prvav, mpv, sigmaQ,
kappa, xvav, beta2;
100 float chi2xbin[41], xsig2[
BSXSIZE];
102 bool calc_probQ, use_VVIObj;
104 const float probmin={1.110223e-16};
105 const float probQmin={1.e-5};
109 const double mean1pix={0.100}, chi21min={0.160};
114 if(!templ.
interpolate(
id, cotalpha, cotbeta, locBy)) {
115 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;}
125 if(speed < -1) use_VVIObj =
true;
131 if(speed < 5) use_VVIObj =
true;
137 xsize = templ.
xsize();
151 nclusx = (int)cluster.size();
158 for(i=0; i<
BSXSIZE; ++
i) {xsum[
i] = 0.f;}
159 maxpix = templ.
sxmax();
161 for(j=0; j<nclusx; ++
j) {
162 xsum[
j] = qscale*cluster[
j];
164 barycenter += j*xsize*xsum[
j];
165 if(xsum[j] > maxpix) {xsum[
j] =
maxpix;}
168 barycenter = barycenter/qtotal - 0.5f*templ.
lorxwidth();
180 if(fxpix == -1) {fxpix =
i;}
185 if(ftpix == -1) {ftpix =
i;}
196 if((lxpix-fxpix+1) != nxpix) {
198 LOGDEBUG(
"SiStripTemplateReco") <<
"x-length of pixel cluster doesn't agree with number of pixels above threshold" <<
ENDL;
200 LOGDEBUG(
"SiStripTemplateReco") <<
"xsum[] = ";
201 for(i=0; i<BSXSIZE-1; ++
i) {
LOGDEBUG(
"SiStripTemplateReco") << xsum[
i] <<
", ";}
212 LOGDEBUG(
"SiStripTemplateReco") <<
"x-length of pixel cluster is larger than maximum template size" <<
ENDL;
214 LOGDEBUG(
"SiStripTemplateReco") <<
"xsum[] = ";
215 for(i=0; i<BSXSIZE-1; ++
i) {
LOGDEBUG(
"SiStripTemplateReco") << xsum[
i] <<
", ";}
224 midpix = (ftpix+ltpix)/2;
225 shiftx = templ.
cxtemp() - midpix;
228 for(i=lxpix; i>=fxpix; --
i) {
229 xsum[i+shiftx] = xsum[
i];
232 }
else if (shiftx < 0) {
233 for(i=fxpix; i<=lxpix; ++
i) {
234 xsum[i+shiftx] = xsum[
i];
243 if(fxpix > 1 && fxpix <
BSXM2) {
244 xsum[fxpix-1] = pseudopix;
245 xsum[fxpix-2] = 0.2f*pseudopix;
247 if(lxpix > 1 && lxpix <
BSXM2) {
248 xsum[lxpix+1] = pseudopix;
249 xsum[lxpix+2] = 0.2f*pseudopix;
258 fq = qtotal/templ.
qavg();
276 if(qtotal < 0.95
f*templ.
qmin()) {qbin = 5;}
else {
277 if(qtotal < 0.95
f*templ.
qmin(1)) {qbin = 4;}
282 " cot(alpha) = " << cotalpha <<
" cot(beta) = " << cotbeta <<
283 " nclusx = " << nclusx <<
ENDL;
291 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
292 if(speed < 0 || speed > 3) {
293 throw cms::Exception(
"DataCorrupt") <<
"SiStripTemplateReco::StripTempReco2D called with illegal speed = " << speed << std::endl;
296 assert(speed >= 0 && speed < 4);
298 fxbin = 2; lxbin = 38; djx = 1;
300 fxbin = 8; lxbin = 32;
312 "fxpix " << fxpix <<
" lxpix = " << lxpix <<
313 " fxbin = " << fxbin <<
" lxbin = " << lxbin <<
314 " djx = " << djx <<
" logxpx = " << logxpx <<
ENDL;
319 templ.
xtemp(fxbin, lxbin, xtemp);
334 templ.
xsigma2(fxpix, lxpix, sxthr, xsum, xsig2);
339 for(i=fxbin; i<=lxbin; ++
i) { chi2xbin[
i] = -1.e15f;}
341 for(i=fxpix-2; i<=lxpix+2; ++
i) {
342 xw2[
i] = 1.f/xsig2[
i];
343 xsw[
i] = xsum[
i]*xw2[
i];
344 ss2 += xsum[
i]*xsw[
i];
351 for(j=jmin; j<=jmax; j+=deltaj) {
352 if(chi2xbin[j] < -100.
f) {
355 for(i=fxpix-2; i<=lxpix+2; ++
i) {
356 ssa += xsw[
i]*xtemp[
j][
i];
357 sa2 += xtemp[
j][
i]*xtemp[
j][
i]*xw2[
i];
360 if(rat <= 0.
f) {
LOGERROR(
"SiStripTemplateReco") <<
"illegal chi2xmin normalization (1) = " << rat <<
ENDL; rat = 1.;}
361 chi2xbin[
j]=ss2-2.*ssa/rat+sa2/(rat*rat);
363 if(chi2xbin[j] < chi2xmin) {
364 chi2xmin = chi2xbin[
j];
369 if(minbin > fxbin) {jmin = minbin - deltaj;}
else {jmin = fxbin;}
370 if(minbin < lxbin) {jmax = minbin + deltaj;}
else {jmax = lxbin;}
375 "minbin " << minbin <<
" chi2xmin = " << chi2xmin <<
ENDL;
382 delta = templ.
dxone();
383 sigma = templ.
sxone();
384 xrec = 0.5f*(fxpix+lxpix-2*shiftx+2.f*originx)*xsize-delta;
393 chi21max = fmax(chi21min, (
double)templ.
chi2xminone());
395 if(chi2xmin < 0.) {chi2xmin = 0.;}
396 meanx = fmax(mean1pix, (
double)templ.
chi2xavgone());
397 hchi2 = chi2xmin/2.; hndof = meanx/2.;
406 if(binl < fxbin) { binl = fxbin;}
407 if(binh > lxbin) { binh = lxbin;}
413 for(i=fxpix-2; i<=lxpix+2; ++
i) {
414 ssa += xsw[
i]*xtemp[binl][
i];
415 sa2 += xtemp[binl][
i]*xtemp[binl][
i]*xw2[
i];
416 ssba += xsw[
i]*(xtemp[binh][
i] - xtemp[binl][
i]);
417 saba += xtemp[binl][
i]*(xtemp[binh][
i] - xtemp[binl][
i])*xw2[i];
418 sba2 += (xtemp[binh][
i] - xtemp[binl][
i])*(xtemp[binh][i] - xtemp[binl][i])*xw2[
i];
423 rat=(ssba*ssa-ss2*saba)/(ss2*sba2-ssba*ssba);
424 if(rat < 0.
f) {rat=0.f;}
425 if(rat > 1.
f) {rat=1.0f;}
426 rnorm = (ssa+rat*ssba)/ss2;
439 float qxfrac = (qfx-qlx)/(qfx+qlx);
440 bias = templ.
xflcorr(binq,qxfrac)+templ.
xavg(binq);
444 xrec = (0.125f*binl+
BSHX-2.5f+rat*(binh-binl)*0.125
f-(
float)shiftx+originx)*xsize - bias;
445 sigmax = templ.xrms(binq);
449 if(rnorm <= 0.
f) {
LOGERROR(
"SiStripTemplateReco") <<
"illegal chi2x normalization (2) = " << rnorm <<
ENDL; rnorm = 1.;}
450 chi2x=ss2-2.f/rnorm*ssa-2.f/rnorm*rat*ssba+(sa2+2.f*rat*saba+rat*rat*sba2)/(rnorm*rnorm)-templ.
chi2xmin(binq);
451 if(chi2x < 0.0) {chi2x = 0.0;}
453 if(meanx < 0.01) {meanx = 0.01;}
457 hchi2 = chi2x/2.; hndof = meanx/2.;
462 bias = templ.
xavg(binq);
464 sigmaxbcn = templ.
xrmsbcn(binq);
466 if((bias*bias+sigmax*sigmax) > (biasbcn*biasbcn+sigmaxbcn*sigmaxbcn)) {
468 xrec = barycenter - biasbcn;
477 if(probx < probmin) {probx = probmin;}
486 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
487 if((sigmaQ <=0.) || (mpv <= 0.) || (kappa < 0.01) || (kappa > 9.9)) {
488 throw cms::Exception(
"DataCorrupt") <<
"SiStripTemplateReco::Vavilov parameters mpv/sigmaQ/kappa = " << mpv <<
"/" << sigmaQ <<
"/" << kappa << std::endl;
491 assert((sigmaQ > 0.) && (mpv > 0.) && (kappa > 0.01) && (kappa < 10.));
493 xvav = ((double)qtotal-mpv)/sigmaQ;
498 prvav = vvidist.fcn(xvav);
501 prvav = TMath::VavilovI(xvav, kappa, beta2);
507 if(probQ < probQmin) {probQ = probQmin;}
void xsigma2(int fxstrp, int lxstrp, float sxthr, float xsum[BSXSIZE], float xsig2[BSXSIZE])
float chi2xavg(int i)
averaage x chi^2 in 4 charge bins
float xsize()
strip x-size (microns)
void vavilov_pars(double &mpv, double &sigma, double &kappa)
float qavg()
average cluster charge for this set of track angles
float chi2xminone()
//!< minimum of x chi^2 for 1 strip clusters
float xrmsbcn(int i)
1st pass chi2 min search: average x-rms of reconstruction binned in 4 charge bins ...
float lorxwidth()
signed lorentz x-width (microns)
float xflcorr(int binq, float qflx)
float qmin()
minimum cluster charge for valid hit (keeps 99.9% of simulated hits)
static int theVerboseLevel
int cxtemp()
Return central pixel of x-template pixels above readout threshold.
float xavg(int i)
average x-bias of reconstruction binned in 4 charge bins
float dxone()
mean offset/correction for one strip x-clusters
float qscale()
charge scaling factor
float xavgbcn(int i)
1st pass chi2 min search: average x-bias of reconstruction binned in 4 charge bins ...
float chi2xavgone()
//!< average x chi^2 for 1 strip clusters
float chi2xmin(int i)
minimum y chi^2 in 4 charge bins
float s50()
1/2 of the strip threshold signal in electrons
float sxone()
rms for one strip x-clusters
float sxmax()
average strip signal for x-projection of cluster
static const G4double kappa
bool interpolate(int id, float cotalpha, float cotbeta, float locBy)
void xtemp(int fxbin, int lxbin, float xtemplate[41][BSXSIZE])