12 #include "streamlog/streamlog.h"
14 #include "CLHEP/Matrix/SymMatrix.h"
19 int HelixFit::fastHelixFit(
int npt,
double* xf,
double* yf,
float* rf,
float* pf,
double* wf,
float* zf ,
float* wzf,
int iopt,
20 float* vv0,
float* ee0,
float& ch2ph,
float& ch2z){
25 streamlog_out(ERROR) <<
"Cannot fit less than 3 points return 1" <<
std::endl;
34 #define MAX_CHI2 5000.0
39 delz[
MPT],grad[5],cov[15],vv1[5],dv[5];
43 double alf,a0,a1,a2,a22,bet,cur,
44 dd,den,
det,dy,d2,f,fact,fg,f1,g,gam,gam0,g1,
46 xa,xb,xd,xi,xm,xx,xy,x1,x2,den2,
47 ya,yb,yd,yi,ym,yy,y1,y2,wn,sa2b2,dd0,phic,aaa;
53 for(
int i=1; i < 15; ++i){
57 for(
int i=1; i < 5; ++i){
66 for (
int i = 0; i<npt; ++i) {
67 sp2[i] = wf[i]*(rf[i]*rf[i]);
86 for (
int i =0; i<npt; ++i) {
87 xm = xm + xf[i]*wf[i];
88 ym = ym + yf[i]*wf[i];
107 for (
int i =0; i<npt; ++i) {
114 xy = xy + xi*yi*wf[i];
116 xd = xd + xi*dd*wf[i];
117 yd = yd + yi*dd*wf[i];
118 d2 = d2 + dd*dd*wf[i];
142 a2 = (fg-h2-d2)/fact;
144 a1 = (d2*(f+g) - 2.0*(p2+q2))/fact;
146 a0 = (d2*(h2-fg) + 2.0*(p2*g + q2*f) - 4.0*xd*yd*h)/fact;
157 for (
int i = 0 ; i <
ITMAX; ++i) {
159 ya = a0 + xa*(a1 + xa*(a2 + xa*(xa-4.0)));
160 dy = a1 + xa*(a22 + xa*(4.0*xa - 12.0));
163 if (fabs(ya) > fabs(yb)) {
167 if (fabs(xa-xb) < eps)
break ;
182 den2= 1.0/(x1*x1 + y1*y1 + gam*det*det);
197 cur = det*den + 0.0000000001 ;
198 alf = -(xm*det + x1)*den ;
199 bet = -(ym*det + y1)*den ;
201 gam = ((rm-gam)*det + 2.0*(xm*x1 + ym*y1))*den*0.5;
209 double asym = bet*xm-alf*ym;
218 if( (alf*alf+bet*bet) <= 0.0 ){
225 sa2b2 = 1.0/sqrt(alf*alf+bet*bet);
226 dd0 = (1.0-1.0/sa2b2)/cur;
229 if( aaa > 1.0 ) aaa = 1.0;
230 if( aaa < -1.0 ) aaa =-1.0;
234 phic = asin(aaa)+ M_PI_2;
236 if( bet > 0 ) phic = 2*
M_PI - phic;
238 double ph0 = phic + M_PI_2;
240 if(rr0 <= 0.0) ph0=ph0-
M_PI;
241 if(ph0 > 2*M_PI) ph0=ph0-2*M_PI;
242 if(ph0 < 0.0) ph0=ph0+2*M_PI;
252 double check=sst*rr0*dd0;
255 if(check > 1.0-eps && check < 1.0+eps) {
266 double gg0 = ome*dd0-aa0;
268 double hh0 = 1.0/gg0;
276 for (
int i = 0 ; i < npt ; ++i) {
278 asym = bet*xf[i]-alf*yf[i] ;
281 if(asym < 0.0) ss0[i] = -1.0 ;
283 double ff0 = ome*(rf[i]*rf[i]-dd0*dd0)/(2.0*rf[i]*gg0) + dd0/rf[i];
285 if(ff0 < -1.0) ff0 = -1.0;
286 if(ff0 > 1.0) ff0 = 1.0;
288 del[i]= ph0 + (ss0[i]-aa0)* M_PI_2 + ss0[i]*asin(ff0) - pf[i];
301 if(del[i] > M_PI) del[i] = del[i] - 2*M_PI;
302 if(del[i] < -M_PI) del[i] = del[i] + 2*M_PI;
315 for (
int i = 0 ; i < npt ; ++i) {
317 eee[i] = 0.5*vv0[0] * sqrt( fabs( (rf[i] * rf[i]-vv0[3]*vv0[3]) / (1.0-aa0*vv0[0]*vv0[3]) ) );
319 if(eee[i] > 0.99990) eee[i]= 0.99990;
320 if(eee[i] < -0.99990) eee[i]= -0.99990;
322 sxy[i]=2.0*asin(eee[i])/ome;
334 for (
int i = 0; i<npt; ++i) {
335 sumw = sumw + wzf[i];
336 sums = sums + sxy[i] * wzf[i];
337 sumss = sumss + sxy[i]*sxy[i] * wzf[i];
338 sumz = sumz + zf[i] * wzf[i];
339 sumzz = sumzz + zf[i]*zf[i] * wzf[i];
340 sumsz = sumsz + zf[i]*sxy[i] * wzf[i];
343 double denom = sumw*sumss - sums*sums;
345 if (fabs(denom) < eps){
352 double dzds = (sumw*sumsz-sums*sumz) /denom;
353 double zz0 = (sumss*sumz-sums*sumsz)/denom;
361 for (
int i = 0 ; i<npt; ++i) {
363 delz[i]= zz0+dzds*sxy[i]-zf[i];
364 ch2ph = ch2ph + sp2[i]*del[i]*del[i];
365 ch2z = ch2z + wzf[i]*delz[i]*delz[i];
377 for (
int i = 0 ; i<npt; ++i) {
379 double ff0 = ome*(rf[i]*rf[i]-dd0*dd0)/(2.0*rf[i]*gg0) + dd0/rf[i];
381 if (ff0 > 0.99990) ff0 = 0.99990;
383 if (ff0 < -0.99990) ff0 = -0.99990;
385 double eta = ss0[i]/sqrt(fabs((1.0+ff0)*(1.0-ff0)));
386 double dfd = (1.0+hh0*hh0*(1.0-ome*ome*rf[i]*rf[i]))/(2.0*rf[i]);
387 double dfo = -aa0*(rf[i]*rf[i]-dd0*dd0)*hh0*hh0/(2.0*rf[i]);
388 double dpd = eta*dfd;
389 double dpo = eta*dfo;
392 double ggg = eee[i]/sqrt(fabs( (1.0+eee[i])*(1.0-eee[i])));
394 check = rf[i]*rf[i]-vv0[3]*vv0[3];
396 if(fabs(check) > 1.0-eps) check=2.*0.007;
398 double dzd = 2.0*( vv0[1]/vv0[0] ) * fabs( ggg ) * ( 0.5*aa0*vv0[0]/( 1.0-aa0*vv0[3]*vv0[0] )-vv0[3]/check );
400 double dzo = -vv0[1]*sxy[i]/vv0[0] + vv0[1] * ggg/( vv0[0]*vv0[0]) * ( 2.0+ aa0*vv0[0]*vv0[3]/(1.0-aa0*vv0[0]*vv0[3]) );
404 ee0[0] = ee0[0] + sp2[i]* dpo*dpo + wzf[i] * dzo*dzo;
405 ee0[1] = ee0[1] + wzf[i] * dza*dzo;
406 ee0[2] = ee0[2] + wzf[i] * dza*dza;
407 ee0[3] = ee0[3] + sp2[i]* dpo;
409 ee0[5] = ee0[5] + sp2[i];
410 ee0[6] = ee0[6] + sp2[i]* dpo*dpd + wzf[i] * dzo*dzd;
411 ee0[7] = ee0[7] + wzf[i] * dza*dzd;
412 ee0[8] = ee0[8] + sp2[i]* dpd;
413 ee0[9] = ee0[9] + sp2[i]* dpd*dpd + wzf[i] * dzd*dzd;
414 ee0[10]= ee0[10] + wzf[i] * dzo;
415 ee0[11]= ee0[11] + wzf[i] * dza;
417 ee0[13]= ee0[13] + wzf[i] * dzd;
418 ee0[14]= ee0[14] + wzf[i];
421 grad[0]=grad[0] - del[i] *sp2[i]*dpo - delz[i]*wzf[i]*dzo;
422 grad[1]=grad[1] - delz[i]*wzf[i]*dza;
423 grad[2]=grad[2] - del[i] *sp2[i];
424 grad[3]=grad[3] - del[i] *sp2[i]*dpd - delz[i]*wzf[i]*dzd;
425 grad[4]=grad[4] - delz[i]*wzf[i];
432 streamlog_out(DEBUG1) <<
"HelixFit: " <<
433 " d0 = " << vv0[3] <<
434 " phi0 = " << vv0[2] <<
435 " omega = " << vv0[0] <<
436 " z0 = " << vv0[4] <<
437 " tanL = " << vv0[1] <<
445 for (
int i =0; i<15; ++i) {
450 CLHEP::HepSymMatrix cov0(5) ;
454 for(
int irow=0; irow<5; ++irow ){
455 for(
int jcol=0; jcol<irow+1; ++jcol){
458 cov0[irow][jcol] = ee0[icov] ;
467 streamlog_out(ERROR) <<
"CLHEP Matrix inversion failed" <<
"return 1 " <<
std::endl;
475 for(
int irow=0; irow<5; ++irow ){
476 for(
int jcol=0; jcol<irow+1; ++jcol){
479 cov[icov] = cov0[irow][jcol];
488 for (
int i = 0; i<5; ++i) {
490 for (
int j = 0; j<5; ++j) {
493 index = (i*i-i)/2+j ;
498 dv[i] = dv[i] + cov[index] * grad[j] ;
503 for (
int i = 0; i<5; ++i) {
504 vv1[i] = vv0[i]+dv[i];
507 gg0 = vv1[0]*vv1[3]-aa0;
509 for (
int i=0; i<npt; ++i) {
510 double ff0 = vv1[0]*(rf[i]*rf[i]-vv1[3]*vv1[3]) / (2.0*rf[i]*gg0) + vv1[3]/rf[i];
512 if (ff0 > 1) ff0 = 1.0;
513 if (ff0 < -1) ff0 = -1.0;
515 deln[i] = vv1[2] + (ss0[i]-aa0)*M_PI_2+ss0[i]*asin(ff0)-pf[i];
517 if(deln[i] > M_PI) deln[i] = deln[i] - 2*M_PI;
518 if(deln[i] < -M_PI) deln[i] = deln[i] + 2*M_PI;
520 eee[i] = 0.5*vv1[0]*sqrt( fabs( (rf[i]*rf[i]-vv1[3]*vv1[3]) / (1.0-aa0*vv1[0]*vv1[3]) ) );
522 if(eee[i] > 0.99990) eee[i]= 0.99990;
523 if(eee[i] < -0.99990) eee[i]= -0.99990;
525 sxy[i] = 2.0*asin(eee[i])/vv1[0];
526 delzn[i]= vv1[4]+vv1[1]*sxy[i]-zf[i];
534 for (
int i =0; i<5; ++i) {
535 chi1 = chi1 + sp2[i]*deln[i]*deln[i] + wzf[i]*delzn[i]*delzn[i];
536 ch2ph = ch2ph + sp2[i]*deln[i]*deln[i];
537 ch2z = ch2z + wzf[i]*delzn[i]*delzn[i];
541 for (
int i =0; i<5; ++i) {
547 streamlog_out(DEBUG1) <<
"HelixFit: " <<
548 " d0 = " << vv0[3] <<
549 " phi0 = " << vv0[2] <<
550 " omega = " << vv0[0] <<
551 " z0 = " << vv0[4] <<
552 " tanL = " << vv0[1] <<
int fastHelixFit(int npt, double *xf, double *yf, float *rf, float *pf, double *wf, float *zf, float *wzf, int iopt, float *vv0, float *ee0, float &ch2ph, float &ch2z)