3 #include "StiTrackNode.h"
9 #define NICE(a) ( ((a) <= -M_PI)? ((a)+2*M_PI) :\
10 ((a) > M_PI)? ((a)-2*M_PI) : (a))
12 int StiTrackNode::mgFlag=0;
13 static const int idx66[6][6] =
14 {{ 0, 1, 3, 6,10,15},{ 1, 2, 4, 7,11,16},{ 3, 4, 5, 8,12,17}
15 ,{ 6, 7, 8, 9,13,18},{10,11,12,13,14,19},{15,16,17,18,19,20}};
16 static const double MAX1ERR[]={3,3,3,0.1,3.,0.1};
17 static const double MAX2ERR[]={MAX1ERR[0]*MAX1ERR[0]
18 ,MAX1ERR[1]*MAX1ERR[1]
19 ,MAX1ERR[2]*MAX1ERR[2]
20 ,MAX1ERR[3]*MAX1ERR[3]
21 ,MAX1ERR[4]*MAX1ERR[4]
22 ,MAX1ERR[5]*MAX1ERR[5]};
24 static const double MIN1ERR[]={1e-4,1e-4,1e-4,1e-5,1e-3,1e-5};
25 static const double MIN2ERR[]={MIN1ERR[0]*MIN1ERR[0]
26 ,MIN1ERR[1]*MIN1ERR[1]
27 ,MIN1ERR[2]*MIN1ERR[2]
28 ,MIN1ERR[3]*MIN1ERR[3]
29 ,MIN1ERR[4]*MIN1ERR[4]
30 ,MIN1ERR[5]*MIN1ERR[5]};
31 static const double recvCORRMAX = 0.99999;
32 static const double chekCORRMAX = 0.99999;
33 static double MAXPARS[]={500,500,500,3.15,100,100};
50 double g[NE]; memcpy(g, G,
sizeof( g));
51 double fg[NP][NP]; memset(fg[0],0,
sizeof(fg));
53 for (
int i=0;i<nF;i++) {
54 for (
int j=0;j<nF;j++) {
55 if (!F[i][j])
continue;
56 for (
int k=0;k<NP;k++) {
59 fg[i][k] += F[i][j]*g[jk];
62 for (
int i=0;i<NP;i++) {
63 for (
int k=i;k<NP;k++) {
66 for (
int j=0;j<NP;j++) {
67 if (!F[k][j])
continue;
68 s += fg[i][j]*F[k][j];
70 G[ik] += (s + fg[i][k] + fg[k][i]);
76 void StiHitContino::reset()
82 void StiHitContino::add(
StiHit *
hit,
double chi2,
double detr)
85 for (;i<kMaxSize;i++) {
87 if (chi2 > mChi2[i])
continue;
88 for (
int jr = kMaxSize-2;jr>=i;jr--)
89 {mHits[jr+1]=mHits[jr]; mChi2[jr+1]=mChi2[jr];mDetr[jr+1]=mDetr[jr];}
92 if (i>=kMaxSize)
return;
93 mHits[i]=hit; mChi2[i]=chi2;mDetr[i]=detr;
96 void StiHitContino::print(
const char* tit)
const
98 if (!tit || !*tit) tit =
"print()";
100 LOG_DEBUG << Form(
" **** StiHitContino::%s nHits=%d",tit,n)<< endm;
101 for (
int i=0;i<n;i++) {
102 LOG_DEBUG << Form(
"%3d - hit=%p chi2 = %g",i,(
void*)mHits[i],mChi2[i]);}
106 int StiHitContino::getNHits()
const
107 {
int n=0;
for(
int i=0;i<kMaxSize;i++) {
if (mHits[i]) n++;};
return n;}
109 int StiTrackNode::cylCross(
const double Xp[2],
const double Dp[2],
const double Rho
110 ,
const double rp ,
int dir,
double out[2][3])
114 #define DOT(a,b) a[0]*b[0]+a[1]*b[1]
115 #define MAG2(a) DOT(a,a)
116 #define MAG(a) sqrt(MAG2(a))
142 static int nCall=0;nCall++;
143 StiDebug::Break(nCall);
145 int sRho = (Rho<0) ? -1:1;
146 double aRho = fabs(Rho), d=0;
150 double C[2], Cd[2], Cn[2], N[2];
160 double LLmRR = XX*aRho+2*XN*sRho;
161 double LL = LLmRR*aRho+1; L = sqrt(LL);
162 d = (r*r*aRho+LLmRR)/(2*L);
163 double P = ((r-d)*(r+d));
166 r = fabs(LLmRR/(L+1));
167 d = (r*r*aRho+LLmRR)/(2*L);
172 C[0] = Xp[0]*aRho+N[0]*sRho;
173 C[1] = Xp[1]*aRho+N[1]*sRho;
176 double CMag = MAG(C);
189 Out[0][0] = Cd[0]*d + Cn[0]*P;
190 Out[0][1] = Cd[1]*d + Cn[1]*P;
191 Out[1][0] = Cd[0]*d - Cn[0]*P;
192 Out[1][1] = Cd[1]*d - Cn[1]*P;
196 for (
int ix = 0;ix<2; ix++) {
197 tmp[0] = Out[ix][0] - Xp[0];
198 tmp[1] = Out[ix][1] - Xp[1];
200 double len = MAG(tmp);
201 double lenaRho =len*aRho;
if (lenaRho>2) lenaRho = 1.999;
202 if (lenaRho > 0.01) len = 2*asin(0.5*lenaRho)/aRho;
204 double tst = tmp[0]*Dp[0] + tmp[1]*Dp[1];
205 if ( tst < 0 ) len = -len;
211 out[ix][0] = Out[ix][0];
212 out[ix][1] = Out[ix][1];
214 if ((out[0][2])>out[1][2]) {
215 for (
int j=0;j<3;j++) {
216 double t=out[0][j]; out[0][j] = out[1][j]; out[1][j] = t;
221 TVector3 tC(C[0],C[1],0.);
222 for (
int i=0;i<2;i++) {
224 TVector3 Out(out[i][0],out[i][1],0.);
225 double dif = (Out*aRho-tC).Mag()-1.;
227 assert(fabs(dif)<1e-5);
230 assert(fabs(dif)<1e-5);
239 double StiTrackNode::sinX(
double x)
242 if (x2>0.5)
return (sin(x)-x)/x2/x;
245 for (
int it=4;1;it+=2) {
246 nom = -nom*x2/(it*(it+1));
248 if (fabs(nom) <= 1e-10*fabs(sum))
break;
253 void StiTrackNode::mult6(
double Rot[kNPars][kNPars],
const double Pro[kNPars][kNPars])
255 double T[kNPars][kNPars];
257 if (!Rot[0][0]) {memcpy(Rot[0],Pro[0],
sizeof(T));
return;}
259 memcpy(T[0],Pro[0],
sizeof(T));
261 for (
int i=0;i<kNPars;i++) {
262 for (
int j=0;j<kNPars;j++) {
263 if(!Rot[i][j])
continue;
264 for (
int k=0;k<kNPars;k++) {
265 if (!Pro[k][i])
continue;
266 T[k][j] += Pro[k][i]*Rot[i][j];
268 for (
int i=0;i<kNPars;i++) {
269 for (
int k=0;k<kNPars;k++) {
270 Rot[i][k] += T[i][k];
274 double StiTrackNode::getRefPosition()
const
281 return place->getLayerRadius();
285 double StiTrackNode::getLayerAngle()
const
290 return place->getLayerAngle();
294 double StiNodeErrs::operator()(
int i,
int j)
const
296 return G()[idx66[i][j]];
302 for (
int i=0;i<kNErrs;i++) {G()[i] = wt0*G()[i] + wt*other.G()[i];}
307 void StiNodeErrs::get00(
double *a)
const
309 memcpy(a,G(),6*
sizeof(
double));
312 void StiNodeErrs::set00(
const double *a)
314 memcpy(G(),a,6*
sizeof(
double));
318 void StiNodeErrs::get10(
double *a)
const
326 const double *A = G();
327 memcpy(a+0,A+ 6,3*
sizeof(
double));
328 memcpy(a+3,A+10,3*
sizeof(
double));
329 memcpy(a+6,A+15,3*
sizeof(
double));
332 void StiNodeErrs::set10(
const double *a)
335 memcpy(A+ 6,a+0,3*
sizeof(
double));
336 memcpy(A+10,a+3,3*
sizeof(
double));
337 memcpy(A+15,a+6,3*
sizeof(
double));
340 void StiNodeErrs::get11(
double *a)
const
342 const double *A = G();
343 memcpy(a+0,A+ 9,1*
sizeof(
double));
344 memcpy(a+1,A+13,2*
sizeof(
double));
345 memcpy(a+3,A+18,3*
sizeof(
double));
348 void StiNodeErrs::set11(
const double *a)
351 memcpy(A+ 9,a+0,1*
sizeof(
double));
352 memcpy(A+13,a+1,2*
sizeof(
double));
353 memcpy(A+18,a+3,3*
sizeof(
double));
356 void StiNodeErrs::zeroX()
359 for (
int i=0;i<kNPars;i++) {A[idx66[i][0]]=0;}
362 void StiNodeErrs::rotate(
double alpha,
const StiNodePars &pars)
367 double ca = cos(alpha),sa=sin(alpha);
369 double dYdX = pars._sinCA/dX;
370 double dZdX = pars.tanl()/dX;
372 double F[6][6]= {{ -1, 0,0,0,0,0}
373 ,{-ca*dYdX-sa,-sa*dYdX+ca-1,0,0,0,0}
374 ,{-ca*dZdX ,-sa*dZdX ,0,0,0,0}
380 for (
int i=0,li=0;i<kNPars ;li+=++i) {
381 assert(fabs(A[li+0]) <1e-6);
386 void StiNodeErrs::recov(
int force)
388 static int nCall = 0; nCall++;
389 StiDebug::Break(nCall);
392 int i0=1,li0=1,isMod=0;
393 if (_cXX>0) {i0=0;li0=0;}
395 double dia[kNPars],fak[kNPars]={1,1,1,1,1,1},corrMax=1;;
396 for (
int i=i0,li=li0;i<kNPars ;li+=++i) {
397 double &aii = A[li+i];
398 if (aii < MIN2ERR[i]) aii = MIN2ERR[i];
399 if (aii > MAX2ERR[i]) { fak[i] = sqrt(MAX2ERR[i]/aii); aii = MAX2ERR[i]; isMod=2014;}
401 for (
int j=i0;j<i;j++) {
402 double &aij = A[li+j];
403 if (isMod) aij*=fak[i]*fak[j];
404 if (aij*aij <= dia[i]*dia[j]*chekCORRMAX)
continue;
405 double qwe = aij*aij/(dia[i]*dia[j]);
406 if (corrMax>=qwe)
continue;
409 if (corrMax>=chekCORRMAX) {
410 corrMax = sqrt(corrMax/recvCORRMAX);
411 for (
int i=i0,li=li0;i<kNPars ;li+=++i) {
412 for (
int j=i0;j<i;j++) {
416 while (((force)? sign():zign())<=0) {
417 for (
int i=i0,li=li0;i<kNPars ;li+=++i) {
418 for (
int j=i0;j<i;j++) {
424 void StiNodeErrs::print()
const
426 const double *d = G();
427 for (
int n=1;n<=6;n++) {
428 LOG_DEBUG << Form(
"%d - ",n);
429 for (
int i=0;i<n;i++){LOG_DEBUG << Form(
"%g\t",*(d++));}; LOG_DEBUG << endm;
434 int StiNodeErrs::check(
const char *pri)
const
437 const double *A = G();
438 int i=-2008,j=2009,kase=0;
439 double aii=-20091005,ajj=-20101005,aij=-20111005;
440 int i0=0;
if (!_cXX) i0 = 1;
441 for (i=i0;i<kNPars;i++) {
442 aii = A[idx66[i][i]];
443 if (aii<0) {kase = 1;
break;}
446 for (i=i0;i<kNPars;i++) {
447 aii = A[idx66[i][i]];
448 for (j=i+1;j<kNPars ;j++) {
449 ajj = A[idx66[j][j]];
450 if (ajj<=0)
continue;
451 aij = A[idx66[i][j]];
452 if ((aij*aij)> aii*ajj) {kase = 2;
break;}
458 if (!kase)
return kase;
459 if (!pri )
return kase;
462 case 1: LOG_DEBUG << Form(
"StiNodeErrs::check(%s) FAILED: Negative diagonal %g[%d][%d]",pri,aii,i,i)<< endm;
464 case 2: LOG_DEBUG << Form(
"StiNodeErrs::check(%s) FAILED: Correlation too big %g[%d][%d]>%g"
465 ,pri,aij,i,j,sqrt(aii*ajj))<<endm;
467 case 3: LOG_DEBUG << Form(
"StiNodeErrs::check(%s) FAILED: Non Positive matrix",pri)<<endm;
472 double StiNodeErrs::zign()
const
474 const double *A = G();
476 double minCorr = 1e11;
477 for (
int i=1,li=1;i<kNPars ;li+=++i) {
478 const double &aii = A[li+i];
479 if (aii<0)
return aii;
481 for (
int j=1;j<i;j++) {
482 const double &aij = A[li+j];
483 double dis = 1-(aij*aij)/(dia[i]*dia[j]);
484 if (dis<0)
return dis;
485 if (dis<minCorr) minCorr = dis;
491 double StiNodeErrs::sign()
const
495 const double *a = G();
496 double *xx = (
double *)G();
497 double save = *xx;
if (!save) *xx = 1;
505 int ipiv, kpiv, i__, j;
529 for (j = i__; j <= n; ++j) {
531 if (i__ == 1)
goto L40;
532 if (r__ == 0.)
goto L42;
537 sum += b[kd] * b[id];
544 if (j != i__) b[kpiv] = sum * r__;
546 if (sum<ans) ans = sum;
547 if (sum<=0.)
goto RETN;
550 if (r__ > 0.) r__ = (double)1. / dc;
561 int StiNodeErrs::nan()
const
563 const double *A = G();
564 for (
int i=0; i<kNPars;i++) {
565 if (!finite(A[i]))
return 100+i;
571 double sign(
const double *a,
int n)
574 double *aa = (
double *)a;
575 double save = aa[0];
if (!save) aa[0] = 1;
578 if (n>kNErrs) b =
new double[n];
585 int ipiv, kpiv, i__, j;
609 for (j = i__; j <= n; ++j) {
611 if (i__ == 1)
goto L40;
612 if (r__ == 0.)
goto L42;
617 sum += b[kd] * b[id];
624 if (j != i__) b[kpiv] = sum * r__;
626 if (sum<ans) ans = sum;
627 if (sum<=0.)
goto RETN;
630 if (r__ > 0.) r__ = (double)1. / dc;
638 if (n>kNErrs)
delete [] b;
642 int StiNodePars::check(
const char *pri)
const
647 assert(fabs(
_cosCA) <=1 && fabs(_sinCA)<=1);
648 double tmp = (fabs(curv())<1e-6)? 0: curv()-ptin()*hz();
651 if (fabs(hz())>=1e-5 && fabs(tmp)> 1e-3*fabs(curv())) {ierr=1313;
goto FAILED;}
652 for (
int i=0;i<kNPars;i++) {
if (fabs(P[i]) > MAXPARS[i]) {ierr = i+1 ;
break;}}
653 if(ierr)
goto FAILED;
655 if (fabs(
_cosCA) > 1) {ierr = 12;}
656 if (fabs(_sinCA) > 1) {ierr = 13;}
658 if (!ierr)
return ierr;
659 if (!pri )
return ierr;
660 LOG_DEBUG << Form(
"StiNodePars::check(%s) == FAILED(%d)",pri,ierr)<<endm;
668 for (
int i=0;i<kNPars+1;i++) {P[i] = wt0*P[i] + wt*other.P[i];}
675 assert(fabs(fr._sinCA)<=1);
676 assert(fabs(fr.
_cosCA)<=1);
677 memcpy (
this,&fr,
sizeof(fr));
681 void StiNodePars::rotate(
double alpha)
688 double sinCA0 = _sinCA;
690 double ca = cos(alpha);
691 double sa = sin(alpha);
693 x() = xt1*ca + yt1*sa;
694 y() = -xt1*sa + yt1*ca;
695 _cosCA = cosCA0*ca+sinCA0*sa;
696 _sinCA = -cosCA0*sa+sinCA0*ca;
700 eta()= NICE(eta()-alpha);
703 int StiNodePars::nan()
const
705 const double *d = &(
_cosCA);
706 for (
int i=-2; i<=kHz;i++) {
707 if (!finite(*(d++)))
return 100+i;
712 void StiNodePars::print()
const
714 static const char* tit[]={
"cosCA",
"sinCA",
"X",
"Y",
"Z",
"Eta",
"Ptin",
"TanL",
"Curv",0};
715 const double *d = P-2;
716 for (
int i=-2;i<kNPars+1;i++) {LOG_DEBUG << Form(
"%s = %g, ",tit[i+2],*(d++));}
720 void StiHitErrs::rotate(
double angle)
723 t[0][0] = cos(angle); t[0][1] = -sin(angle);
724 t[1][0] = -t[0][1] ; t[1][1] = t[0][0];
727 TCL::ucopy(r,&hXX,3);
732 mPar[0]=pars.y(); mPar[1]=pars.z();
static void errPropag6(double G[21], const double F[6][6], int nF)
static float * trasat(const float *a, const float *s, float *r, int m, int n)
double _cosCA
sine and cosine of cross angle