15 #include "TRandomVector.h"
16 #include "StMatrixD.hh"
21 static double EmxSign(
int n,
const double *a);
25 inline static void spheric(
const double D[3]
26 ,
double &cosL,
double &sinL
27 ,
double &cosP,
double &sinP)
30 cosL = (1.-sinL)*(1+sinL);
31 cosL = (cosL<=0)? 0.:sqrt(cosL);
33 cosP = 1; sinP = 0; cosL = 1e-6;
35 cosP = D[0]/cosL; sinP = D[1]/cosL;
39 inline static void satlit(
const double &cosL,
const double &sinL
40 ,
const double &cosP,
const double &sinP
43 U[0][0]= cosL*cosP; U[0][1] = cosL*sinP;U[0][2]= sinL;
44 U[1][0]=- sinP; U[1][1] = cosP; U[1][2]=0;
45 U[2][0]=-sinL*cosP; U[2][1] = -sinL*sinP; U[2][2]=cosL;
51 inline static double dot(
const double *a,
const double *b)
52 {
return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];}
56 inline static double nor(
double *a)
58 double N = dot(a,a);
if (fabs(N-1)<1e-7)
return N;
61 a[0]/=N; a[1]/=N; a[2]/=N;
65 inline static void lin(
const double a[3],
double f,
const double b[3],
double c[3])
67 c[0] = a[0]+f*b[0];c[1] = a[1]+f*b[1];c[2] = a[2]+f*b[2];
70 inline static void cop(
const double a[3],
double c[3])
71 { c[0] = a[0]; c[1] = a[1];c[2] = a[2]; }
73 inline static void cro(
const double a[3],
const double b[3],
double c[3])
75 c[0] = a[1]*b[2]-b[1]*a[2];
76 c[1] = a[2]*b[0]-b[2]*a[0];
77 c[2] = a[0]*b[1]-b[0]*a[1];
105 TCL::vscale(mTkd[kKT],-1.,mTkd[kKT],3*2);
108 int TkDir_t::Same(
const TkDir_t &as)
const
110 static const double eps = 0.01;
111 for (
int i=0;i<3;i++) {
112 for (
int j=0;j<3; j++) {
113 if (fabs(mTkd[i][j]-as[i][j])>eps)
return 0;
118 void THDer3d_t::Clear()
121 memset(mDer[0] ,0,
sizeof(mDer ));
122 for (
int i=0;i< 5;i++) { mDer[i][i] = 1;}
124 for (
int jk=0; jk<2;jk++) { mTkDir[jk].Clear();}
130 TCL::mxmpy(by.mDer[0],mDer[0],res[0],5,5,5);
131 TCL::ucopy(res[0],mDer[0],5*5);
132 TCL::ucopy(by.mTkDir[1][0],mTkDir[1][0],3*3);
137 void THDer3d_t::Backward()
152 mTkDir[0].Backward();
153 mTkDir[1].Backward();
158 static const int idx[]= {kU,kV , kU,kFita
159 ,kV,kU , kV,kLama , kV,kPinv
160 ,kFita,kU, kFita,kLama, kFita,kPinv
161 ,kLama,kV, kLama,kFita
162 ,kPinv,kV, kPinv,kFita, -1,-1};
164 for (
int i=0;idx[i]>=0; i+=2) {mDer[idx[i]][idx[i+1]]*=-1.;}
167 THelix3d::THelix3d(
int charge,
const double *xyz,
const double *mom,
const double *Mag)
172 memset(fBeg3d,0,fEnd3d-fBeg3d);
173 Set(charge,xyz,mom,Mag);
178 memset(fBeg3d,0,fEnd3d-fBeg3d);
181 THelix3d::~THelix3d()
187 void THelix3d::Clear(
const char*)
189 memset(fBeg3d,0,fMed3d-fBeg3d);
191 if (fDer3d) fDer3d->Clear();
192 if (fEmx3d) fEmx3d->Clear();
195 void THelix3d::Set(
int charge,
const double *xyz,
const double *mom,
const double *mag)
197 if (charge) fCharge = charge;
198 if (xyz) memcpy(fX3d,xyz,
sizeof(fX3d));
199 if (mom) memcpy(fP3d,mom,
sizeof(fP3d));
200 if (mag) memcpy(fH3d,mag,
sizeof(fH3d[0])*3);
204 void THelix3d::Build()
206 fMom = sqrt(TCL::vdot(fP3d,fP3d,3));
207 TCL::vscale(fP3d,1./fMom,fD3d,3);
208 fH3d[3] = sqrt(TCL::vdot(fH3d,fH3d,3));
209 MakeLocal(fH3d,fD3d,fLoc);
211 fPinv = -fCharge/fMom;
212 double pt = sqrt(TCL::vdot(fP,fP,2))*fMom;
213 fRho = -fCharge*fH3d[3]/pt;
214 THelixTrack_::Build();
218 fEmx3d->Update(tkDir);
220 fDer3d->SetTkDir(0,tkDir);
221 fDer3d->SetTkDir(1,tkDir);
226 memcpy(fBeg3d,from->fBeg3d,fEnd3d-fBeg3d);
232 memcpy(fBeg3d,from.fBeg3d,fEnd3d-fBeg3d);
233 if (fEmx3d) {fEmx3d =
new THEmx3d_t; *fEmx3d = *from.fEmx3d;}
234 if (fDer3d) {fDer3d =
new THDer3d_t; *fDer3d = *from.fDer3d;}
237 void THelix3d::ToGlobal(
const double locX[3],
const double locD[3]
238 ,
double gloX[3],
double gloD[3]
239 ,
double gloP[3])
const
244 TCL::vmatr (locX,fLoc[0],myX ,3,3);
245 TCL::vadd (myX ,fX3d ,gloX,3 );
246 TCL::vmatr (locD,fLoc[0],gloD,3,3);
247 TCL::vscale(gloD,fMom ,gloP,3 );
250 void THelix3d::GetdDdL(
double dDdL[3])
const
252 double dDdLloc[3] = {-fP[1]*fRho*fCosL,fP[0]*fRho*fCosL,0};
253 TCL::vmatr (dDdLloc,fLoc[0],dDdL,3,3);
256 void THelix3d::ToGlobal()
258 ToGlobal(fX,fP,fX3d,fD3d,fP3d);
261 void THelix3d::ToLocal()
264 TCL::vmatl(fLoc[0],fD3d,fP,3,3);
265 memcpy(fPpre,fP,
sizeof(fPpre));
266 fCosL = sqrt(fabs((1.-fP[2])*(1+fP[2])));
271 TCL::vscale(fP3d ,-1.,fP3d ,3);
272 TCL::vscale(fD3d ,-1.,fD3d ,3);
276 if (fEmx3d) fEmx3d->Backward();
277 if (fDer3d) fDer3d->Backward();
283 if (fabs(step) <1e-11)
return step;
284 memcpy(fX3dPre,fX3d,
sizeof(fX3dPre));
285 memcpy(fP3dPre,fP3d,
sizeof(fP3dPre));
286 memcpy(fD3dPre,fD3d,
sizeof(fD3dPre));
287 if (!IsDerOn() && !F) {
296 if (F) memcpy(F[0],fDer3d[0],
sizeof(
double)*5*5);
297 if (fEmx3d) fEmx3d->Move(fDer3d);
307 if (fabs(step)<1e-11) {
308 if (xyz) memcpy(xyz,fX3d,
sizeof(fX3d));
309 if (mom) memcpy(mom,fP3d,
sizeof(fP3d));
312 double myXE[3],myDE[3],myX3dE[3],myD3dE[3],myP3dE[3];
314 ToGlobal(myXE,myDE,myX3dE,myD3dE,myP3dE);
315 if (xyz) memcpy(xyz,myX3dE,
sizeof(myX3dE));
316 if (mom) memcpy(mom,myP3dE,
sizeof(myP3dE));
323 double myPoint[6],myXyz[3],myMom[3];
325 TCL::vsub(point,fX3d,myPoint+3,3);
326 TCL::vmatl(fLoc[0],myPoint+3,myPoint,3,3);
329 TCL::vmatr(myXyz,fLoc[0],xyz,3,3);
330 TCL::vadd(xyz,fX3d,xyz,3);
333 TCL::vmatr(mom,fLoc[0],myMom,3,3);
334 TCL::vscale(mom,fMom,mom,3);
341 if(point || dcaErr){};
342 assert(!
"THelix3d::Dca Not implemented");
348 static const double kEps=1e-5,kRef=1e-4,kBigEps=1e-1;
349 double keepStep = 1e11;
351 const double *X = TH.
Pos();
352 const double *D = TH.Dir();
353 double maxStep = GetPeriod()/6.28;
354 maxStep/= sqrt(1. - D[2]*D[2])+1e-11;
356 double qaLeft,posLeft=0,qaRite=0,posRite=0,qaMine,qaStep,dx[2];
357 for (
int iter=0; iter<=20; iter++) {
358 dx[0] = x-X[0];dx[1] = y-X[1];
359 qaMine = dx[0]*D[0] + dx[1]*D[1];
360 qaMine /=(1.-D[2])*(1.+D[2]);
361 if (fabs(qaMine) < kEps || fabs(qaMine) < kRef*fabs(fLen))
goto END;;
362 if (!iter) {qaLeft = qaMine; qaStep = qaMine; }
363 else if (qaMine*qaLeft>0) {qaLeft = qaMine; qaStep*= 2 ; }
364 else {qaRite = qaMine; posLeft=-qaStep; break ;}
365 if (fabs(qaStep)>maxStep) qaStep = (qaStep<0)? -maxStep:maxStep;
369 if (fabs(fLen)>4*maxStep)
return 1e11;
372 for (
int iter=0; iter<=20; iter++) {
373 double denom = qaRite-qaLeft;
374 if (iter&1 || fabs(denom) < 1e-4) {
375 qaStep = 0.5*(posRite+posLeft);
377 qaStep = -(qaLeft*posRite-qaRite*posLeft)/denom;
381 dx[0] = x-X[0];dx[1] = y-X[1];
382 qaMine = dx[0]*D[0]+dx[1]*D[1];
383 qaMine /=(1.-D[2])*(1.+D[2]);
384 if (fabs(qaMine) < kEps || fabs(qaMine) < kRef*fabs(fLen))
goto END;;
385 if (qaLeft*qaMine>0) { qaLeft = qaMine; posLeft=0; posRite-=qaStep;}
386 else { qaRite = qaMine; posRite=0; posLeft-=qaStep;}
387 assert(fabs(posRite-posLeft)<=keepStep);
388 keepStep= fabs(posRite-posLeft);
391 END:
return (fabs(qaMine)<kBigEps)? fLen:1e11;
398 assert(!
"THelix3d::Dca(x,y,dcaError) n oy implemented");
405 void THelix3d::MakeMtx()
407 static const double Zero[3]= {0,0,1};
411 TkDir_t &TkDir = der.mTkDir[0];
412 TkDir_t &TkDirE = der.mTkDir[1];
415 double Dhlx[5][5],to3d[5][5],to3di[5][5],tmp[5*5];
418 ConvertErrs( &preHlx, fH3d[3],0, 0,to3di);
419 ConvertErrs((
const THelixTrack_ *)
this, fH3d[3],0,to3d, 0);
421 TCL::mxmpy(to3d[0],Dhlx[0],tmp,5,5,5);
422 TCL::mxmpy(tmp,to3di[0],der[0],5,5,5);
424 MakeTkDir(fD3dPre,fH3d,TkDir );
425 MakeTkDir(fD3d ,fH3d,TkDirE);
436 else { fEmx3d->Clear() ;}
438 else { fDer3d->Clear() ;}
439 if (emx) { *fEmx3d = *emx;};
440 TkDir_t &tkDir = fEmx3d->TkDir();
443 fDer3d->SetTkDir(0,tkDir);
444 fDer3d->SetTkDir(1,tkDir);
448 THEmx3d_t *THelix3d::SetEmx(
const double G[15])
452 else { fEmx3d->Clear() ;}
455 else { fDer3d->Clear() ;}
456 TkDir_t &tkDir = fEmx3d->TkDir();
459 fDer3d->SetTkDir(0,tkDir);
460 fDer3d->SetTkDir(1,tkDir);
464 void THelix3d::MakeTkDir(
const double T[3],
const double H[3],
TkDir_t &tkDir)
473 double N = nor(tkDir[kKV]);
475 tkDir[kKV][0]=0; tkDir[kKV][1]=0; tkDir[kKV][2]=1; N=1;
477 double HT = dot(tkDir[kKV],tkDir[kKT]);
478 lin(tkDir[kKV],-HT,tkDir[kKT],tkDir[kKV]);
481 cro(tkDir[kKV],tkDir[kKT],tkDir[kKU]);
485 for (
int i=0;i< 3;i++) {
486 for (
int k=0;k<=i;k++) {
487 double dot = TCL::vdot(tkDir[i],tkDir[k],3);
489 assert(fabs(dot)<1e-4);
492 for (
int i=0;i<3;i++) {
493 int j=(i+1)%3;
int k=(j+1)%3;
494 double qwe =(TVector3(tkDir[i]).Cross(TVector3(tkDir[j]))).Dot(TVector3(tkDir[k]));
495 assert(fabs(qwe-1)<1e-4);
501 void THelix3d::DoTkDir(
TkDir_t &tkDir)
503 const double *t =fD3d;
504 MakeTkDir(t,fH3d,tkDir);
505 GetdDdL(tkDir[kKdDdL]);
508 void THelix3d::MakeLocal(
const double H[3],
const double T[3],
double tkDir[3][3])
518 double HT = dot(tkDir[1],tkDir[2]);
519 lin(tkDir[1],-HT,tkDir[2],tkDir[1]);
521 cro(tkDir[1],tkDir[2],tkDir[0]);
525 void THEmx3d_t::Clear()
527 mLen=0;mTimes[0]=0;mTimes[1]=0;
528 memset(&mUU,0,
sizeof(mUU)*15);
529 for (
int i=0,li=0;i< 5;li+=++i) { (&mUU)[li+i] = 1;}
533 void THEmx3d_t::Set(
double const err[15],
TkDir_t *tkDir)
535 TCL::ucopy(err,&mUU,15);
536 assert(tkDir || fabs(mTkDir[kKU][0])+fabs(mTkDir[kKU][1])+fabs(mTkDir[kKU][2])>0.1);
538 TCL::ucopy((*tkDir)[0],mTkDir[0],3*3);
541 void THEmx3d_t::Set(
double eUU,
double eUV,
double eVV)
543 mUU=eUU;mUV=eUV;mVV=eVV;
544 assert(fabs(mTkDir[kKU][0])+fabs(mTkDir[kKU][1])+fabs(mTkDir[kKU][2])>0.1);
547 void THEmx3d_t::Add(
double Theta2,
double Orth2,
double PinvRr)
557 void THEmx3d_t::Move(
const THDer3d_t *der)
560 assert(mTkDir.Same(der->TkDir(0)));
564 memcpy(oErr,*
this,
sizeof(oErr));
566 TCL::ucopy(der->TkDir(1)[0],mTkDir[0],3*3);
569 void THEmx3d_t::Backward()
585 void THEmx3d_t::Update(
const TkDir_t &tkDir)
594 enum {kU,kV,kFita,kLama,kPinv};
599 for (
int i=kU;i<=kV;i++) {
600 for (
int j=kU;j<=kV;j++) {
601 dots[i][j] = dot(tkDir[i+kKU],mTkDir[j+kKU]);
604 double T1U0 = dot(tkDir[kKT],mTkDir[kKU]);
605 double T1V0 = dot(tkDir[kKT],mTkDir[kKV]);
606 double UdDdL = dot(tkDir[kKU],tkDir[kKdDdL]);
607 double VdDdL = dot(tkDir[kKV],tkDir[kKdDdL]);
610 double T[5][5]={{0}};
611 T[kU][kU] = dots[kU][kU];
612 T[kU][kV] = dots[kU][kV];
613 T[kV][kU] = dots[kV][kU];
614 T[kV][kV] = dots[kV][kV];
615 T[kFita][kFita] = dots[kU][kU];
616 T[kFita][kLama] = dots[kU][kV];
617 T[kLama][kFita] = dots[kV][kU];
618 T[kLama][kLama] = dots[kV][kV];
620 T[kFita][kU] = -(UdDdL)*T1U0;
621 T[kFita][kV] = -(UdDdL)*T1V0;
622 T[kLama][kU] = -(VdDdL)*T1U0;
623 T[kLama][kV] = -(VdDdL)*T1V0;
625 double preRR[5*(5+1)/2];
626 memcpy(preRR,&mUU,
sizeof(preRR));
629 memcpy(mTkDir[0],tkDir[0],
sizeof(mTkDir));
633 double THEmx3d_t::Sign()
const
635 const double *E = &mUU;
639 double THEmx3d_t::Trace()
const {
return mUU+mVV+mFF+mLL+mPP;}
641 void THEmx3d_t::Print(
const char *tit)
const
643 static const char *N=
"UVXFLP";
645 printf(
"THEmx3d_t::::Print(%s) ==\n",tit);
646 const double *e = &mUU;
647 for (
int i=0,li=0;i< 5;li+=++i) {
649 for (
int j=0;j<=i;j++) {
650 printf(
"%g\t",e[li+j]);}
655 double mySign(
const double *a,
int n)
657 enum {kMaxDim=5,kMaxSize=(kMaxDim*(kMaxDim+1))/2 };
659 double *aa = (
double *)a;
660 double save = aa[0];
if (!save) aa[0] = 1;
663 if (n>kMaxDim) myb =
new double[(n*(n+1))/2];
670 int ipiv, kpiv, i__, j;
694 for (j = i__; j <= n; ++j) {
696 if (i__ == 1)
goto L40;
697 if (r__ == 0.)
goto L42;
702 sum += b[kd] * b[id];
709 if (j != i__) b[kpiv] = sum * r__;
711 if (sum<ans) ans = sum;
712 if (sum<=0.)
goto RETN;
715 if (r__ > 0.) r__ = (double)1. / dc;
723 if (myb!=B)
delete [] myb;
728 static double myDif(TVectorD &a,TVectorD &b,
int &idx)
731 int n = a.GetNrows();
732 double dif=0; idx = -1;
733 for (
int i=0;i<n;i++) {
734 double mydif = fabs(a[i])+fabs(b[i]);
735 if (mydif<1e-4)
continue;
736 mydif = fabs(a[i]-b[i])/mydif;
737 if (mydif <= dif)
continue;
738 dif = mydif; idx = i;
743 void THelix3d::Test()
745 double PtGev = 1.,Rho = 1./100, Hz = PtGev*Rho ;
746 double ZER[3]= {0,0,0};
747 double HZ[3] = {0,0,Hz};
748 double XZ[3] = {100,100,100};
749 double HH[3],XX[3],PP[3],PZ[3] ;
752 vHZ.RotateX(1.); vHZ.RotateY(1.); vHZ.GetXYZ(HH);
755 vXZ.RotateX(1.); vXZ.RotateY(1.); vXZ.GetXYZ(XX);
757 TVector3 vPZ(PtGev,0,4./3*PtGev);
759 vPZ.RotateX(1.); vPZ.RotateY(1.); vPZ.GetXYZ(PP);
761 for (
int charge=1;charge >=-1;charge-=2) {
764 double s1 = TH.Path(XZ);
766 double s2 = T3.Path(XX);
767 printf (
"Charge = %d S1,S2 = %g %g \n",charge,s1,s2);
772 void THelix3d::Test2()
774 printf(
"THelix3d::Test2() Empty\n");
777 void THelix3d::TestDer2()
781 double Ptot = 5, Pt=3;
783 double curv = 1./30,Hz = Pt*curv;
784 TVector3 XbegV = TVector3(10,20,30);
785 TVector3 PbegV = TVector3(Pt,0,Pt/3*4);
786 double HZ[3] = {0,0,Hz};
792 TVector3 magV(HZ); magV.GetXYZ(Mag );
794 double r1=gRandom->Rndm(),r2=gRandom->Rndm();
795 magV.RotateX(r1); magV.RotateY(r2); magV.GetXYZ(Mag );
796 PbegV.RotateX(r1); PbegV.RotateY(r2);
797 XbegV.RotateX(r1); XbegV.RotateY(r2);
804 printf(
"===============PbegV:= \n"); PbegV.Print(
"");
806 TVector3 XendV,PendV;
808 for (
int ichar=-1; ichar<=1; ichar +=2) {
809 THelix3d TH0(ichar,(
double*)&XbegV[0],(
double*)&PbegV[0],Mag);
814 TH0.Eval(0,&XendV[0],&PendV[0]);
815 auto DendV = PendV.Unit();
817 TVector3 UbegV(myDer->TkDir(0)[kKU]);
818 TVector3 VbegV(myDer->TkDir(0)[kKV]);
819 TVector3 TbegV(myDer->TkDir(0)[kKT]);
821 TVector3 UendV(myDer->TkDir(1)[kKU]);
822 TVector3 VendV(myDer->TkDir(1)[kKV]);
823 TVector3 TendV(myDer->TkDir(1)[kKT]);
824 assert((DendV-TendV).Mag()<1e-3);
828 static const char* dp[5] = {
"U",
"V",
"Fita",
"Lama",
"Pinv"};
829 for (
int J=0;J<5;J++) {
831 printf(
"\nTest dFit/d%s\n\n",dp[J]);
832 for (
int i=0;i<5;i++) {der[i] = (*myDer)[i][J];}
835 THelix3d TH1(ichar,(
double*)&XbegV[0],(
double*)&PbegV[0],Mag);
837 TVector3 P1begV(TH1.Mom());
838 TVector3 X1begV(TH1.Pos());
840 THelix3d::MakeTkDir((
double*)&P1begV[0],Mag,myTkDir);
841 double eps = (TVectorD(9,myTkDir[0])-TVectorD(9,myDer->TkDir(0)[0])).NormInf();
847 TVector3 X1endV,P1endV;
848 assert(TH0.Pinv()*ichar>0);
849 assert(TH1.Pinv()*ichar>0);
852 X1begV += UbegV*delta;
856 X1begV += VbegV*delta;
860 double Pinv1 = TH1.Pinv()+delta;
861 double Ptot1 = fabs(1./Pinv1);
862 P1begV.SetMag(Ptot1);
866 P1begV+=VbegV*(Ptot*delta); P1begV.SetMag(Ptot);
871 P1begV+=UbegV*(Ptot*delta); P1begV.SetMag(Ptot);
874 default: assert(0 &&
"Wrong J");
876 TH1.Set(0,(
double*)&X1begV[0],(
double*)&P1begV[0],0);
877 assert(TH1.Pinv()*ichar>0);
881 TH1.Eval(0,&X1endV[0],&P1endV[0]);
882 auto D1endV = P1endV.Unit();
883 double dL = -(X1endV-XendV).Dot(PendV)/(PendV.Dot(D1endV));
885 TH1.Eval(0,&X1endV[0],&P1endV[0]);
888 TVector3 difX = X1endV-XendV;
889 TVector3 difD = (P1endV.Unit()-PendV.Unit());
890 dif[kU] = difX.Dot(UendV);
891 dif[kV] = difX.Dot(VendV);
892 dif[kPinv] = TH1.Pinv()-TH0.Pinv();
893 dif[kFita] = difD.Dot(UendV);
894 dif[kLama] = difD.Dot(VendV);
897 assert(fabs(dif.NormInf())<1.);
901 double maxa = myDif(dif,der,idx);
903 if (maxa>1e-1) printf(
"########################[%d]= %g\n",idx,maxa);
904 der.Print(
"ANALITIC");
905 dif.Print(
"NUMERIC ");
910 void THelix3d::TestDer()
915 double curv = 1./30,Hz = Pt*curv;
916 TVector3 XbegV = TVector3(0,0,0);
917 TVector3 PbegV = TVector3(Pt,0,Pt/3*4);
918 double Ptot = PbegV.Mag();
919 double cosBeg = Pt/Ptot;
921 double HZ[3] = {0,0,Hz};
925 L = M_PI/curv/cosBeg;
930 TVector3 magV(HZ); magV.GetXYZ(Mag );
932 double r1=gRandom->Rndm(),r2=gRandom->Rndm();
933 magV.RotateX(r1); magV.RotateY(r2); magV.GetXYZ(Mag );
934 PbegV.RotateX(r1); PbegV.RotateY(r2);
935 XbegV.RotateX(r1); XbegV.RotateY(r2);
939 printf(
"===============PbegV:= \n"); PbegV.Print(
"");
941 TVector3 XendV,PendV;
943 for (
int ichar=-1; ichar<=1; ichar +=2) {
944 THelix3d TH0(ichar,(
double*)&XbegV[0],(
double*)&PbegV[0],Mag);
949 TH0.Eval(0,&XendV[0],&PendV[0]);
950 auto DendV = PendV.Unit();
952 TVector3 UbegV(myDer->TkDir(0)[kKU]);
953 TVector3 VbegV(myDer->TkDir(0)[kKV]);
954 TVector3 TbegV(myDer->TkDir(0)[kKT]);
956 TVector3 UendV(myDer->TkDir(1)[kKU]);
957 TVector3 VendV(myDer->TkDir(1)[kKV]);
958 TVector3 TendV(myDer->TkDir(1)[kKT]);
959 assert((DendV-TendV).Mag()<1e-3);
963 static const char* dp[5] = {
"U",
"V",
"Fita",
"Lama",
"Pinv"};
964 for (
int J=0;J<5;J++) {
966 printf(
"\nTest dFit/d%s\n",dp[J]);
967 printf(
"==============\n");
968 for (
int i=0;i<5;i++) {der[i] = (*myDer)[i][J];}
971 THelix3d TH1(ichar,(
double*)&XbegV[0],(
double*)&PbegV[0],Mag);
973 TVector3 P1begV(TH1.Mom());
974 TVector3 X1begV(TH1.Pos());
976 THelix3d::MakeTkDir((
double*)&P1begV[0],Mag,myTkDir);
977 double eps = (TVectorD(9,myTkDir[0])-TVectorD(9,myDer->TkDir(0)[0])).NormInf();
982 TVector3 X1endV,P1endV;
985 X1begV += UbegV*delta;
989 X1begV += VbegV*delta;
993 double Pinv1 = TH1.Pinv()+delta;
994 double Ptot1 = fabs(1./Pinv1);
995 P1begV.SetMag(Ptot1);
999 P1begV+=VbegV*(Ptot*delta); P1begV.SetMag(Ptot);
1004 P1begV+=UbegV*(Ptot*delta); P1begV.SetMag(Ptot);
1007 default: assert(0 &&
"Wrong J");
1009 TH1.Set(0,(
double*)&X1begV[0],(
double*)&P1begV[0],0);
1011 TH1.Eval(0,&X1endV[0],&P1endV[0]);
1012 auto D1endV = P1endV.Unit();
1013 double dL = -(X1endV-XendV).Dot(PendV)/(PendV.Dot(D1endV));
1015 TH1.Eval(0,&X1endV[0],&P1endV[0]);
1018 TVector3 difX = X1endV-XendV;
1019 TVector3 difD = (P1endV.Unit()-PendV.Unit());
1020 dif[kU] = difX.Dot(UendV);
1021 dif[kV] = difX.Dot(VendV);
1022 dif[kPinv] = TH1.Pinv()-TH0.Pinv();
1023 dif[kFita] = difD.Dot(UendV);
1024 dif[kLama] = difD.Dot(VendV);
1027 assert(fabs(dif.NormInf())<1.);
1031 double maxa = myDif(dif,der,idx);
1033 if (maxa>1e-1) printf(
"########################[%d]= %g\n",idx,maxa);
1034 der.Print(
"ANALITIC");
1035 dif.Print(
"NUMERIC ");
1040 void THelix3d::TestErr(
int charge)
1042 double PtGev = 3.,Curv = 1./100, Hz = PtGev*Curv;
1043 double HZ[3] = {0,0,Hz};
1044 double Pbeg[3],P1beg[3],Xbeg[3]={0},X1beg[3];
1045 double Pend[3],P1end[3],Xend[3] ,X1end[3];
1051 static TCanvas *myCanvas[kNCanvs] = {0};
1052 static int myDiv[] = {2,5,5,5,5,0};
1053 for (
int ic = 0;myDiv[ic];ic++) {
1054 if (myDiv[ic]<0)
continue;
1055 TString ts(
"C"); ts+=ic;
1056 if (!myCanvas[ic]) myCanvas[ic] =
new TCanvas(ts.Data(),ts.Data(),600,800);
1057 myCanvas[ic]->Clear();myCanvas[ic]->Divide(1,myDiv[ic]);
1059 static TH1F *hXi2[2] = {0};
1060 for (
int jk=0;jk<2;jk++) {
1061 TString ts(
"Xi2_"); ts += jk;
1063 hXi2[jk]=
new TH1F(ts.Data(),ts.Data(),50,0,0);
1064 myCanvas[0]->cd(jk+1); hXi2[jk]->Draw();
1067 static TH1F * hh[5]={0};
1068 for (
int ih=0;ih<myDiv[1];ih++) {
1069 const char * tit[]={
"U",
"V",
"Fita",
"Lama",
"Pinv",0};
1071 hh[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1072 myCanvas[1]->cd(ih+1); hh[ih]->Draw();
1075 static TH1F * hrt[5]={0};
1076 for (
int ih=0;ih<myDiv[1];ih++) {
1077 const char * tit[]={
"U0",
"V0",
"Pinv0",
"Fita0",
"Lama0",0};
1079 hrt[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1080 myCanvas[2]->cd(ih+1); hrt[ih]->Draw();
1083 static TH1F * hcr[10]={0};
1085 static const char *tit[]={
"UV",
"UF",
"VF",
"UL",
"VL",
"FL",
"UP",
"VP",
"FP",
"LP"};
1086 for (
int ih=0;ih<10;ih++) {
1088 hcr[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1089 if (ih<5) myCanvas[3]->cd(ih+1 );
1090 else myCanvas[4]->cd(ih+1-5);
1095 TVector3 PbegV(PtGev,0,PtGev*3/4);
1096 double Ptot = PbegV.Mag();
1097 PbegV.RotateZ(gRandom->Rndm()*3.1415*2); PbegV.GetXYZ(Pbeg);
1098 TVector3 XbegV(Xbeg);
1100 double Mag[3]={HZ[0],HZ[1],HZ[2]};
1103 double r1 = gRandom->Rndm(),r2 = gRandom->Rndm();
1104 magV.RotateX(r1); magV.RotateY(r2); magV.GetXYZ(Mag);
1105 PbegV.RotateX(r1); PbegV.RotateY(r2); PbegV.GetXYZ(Pbeg);
1108 dia[kU]= 0.1; dia[kV]= 0.2; dia[kPinv]= 0.1/Ptot; dia[kFita]= 1./360; dia[kLama]= 2./360;
1109 for(
int jk=0;jk<5;jk++) {dia[jk]*=dia[jk];}
1112 auto &EMX = RV.GetMtx();
1113 auto &val = RV.GetLam();
1118 double Gbeg[15],GbegD[5];
1119 for (
int i=0,li=0;i< 5;li+=++i) {
1120 GbegD[i] = sqrt(EMX[i][i]);
1121 for (
int j=0;j<=i;j++) {
1122 Gbeg[li+j] = EMX[i][j];
1124 assert( mySign(Gbeg,5)>0);
1129 assert( mySign(GbegI,5)>0);
1131 THelix3d TH0(charge,Xbeg,Pbeg,Mag);
1135 TH0.Eval(0,Xend,Pend);
1136 auto *myEmx = TH0.Emx();
1137 const double *Gend = *myEmx;
1138 assert(mySign(Gend,5)>0);
1140 for (
int i=0,li=0;i< 5;li+=++i) {
1141 GendD[i] = sqrt(Gend[li+i]);
1146 assert(mySign(GendI,5)>0);
1148 auto &tkDir = TH0.TkDir(0);
1149 auto &tkDirE = TH0.TkDir(1);
1150 TVector3 PendV(Pend),XendV(Xend);
1152 for (
int j=0;j<3;j++) { UendV[j+2]=Pend[j];}
1155 int nIter = 1000000;
1156 for (
int iter=0;iter<nIter;iter++) {
1157 TVectorD delta = RV.Gaus();
1159 TCL::trasat(delta.GetMatrixArray(),GbegI,&chi2,1,5);
1161 hXi2[0]->Fill(chi2);
1163 for (
int ih=0;ih<myDiv[1];ih++) { hrt[ih]->Fill(delta[ih]/GbegD[ih]);}
1164 TVector3 P1begV = PbegV;
1165 TVector3 X1begV = XbegV;
1167 X1begV += TVector3(tkDir[kKU])*delta[kU];
1168 X1begV += TVector3(tkDir[kKV])*delta[kV];
1169 double Pinv = -charge/Ptot;
1170 double Pinv1 = Pinv + delta[kPinv];
1171 double Ptot1 = fabs(1./Pinv1);
1172 P1begV.SetMag(Ptot1);
1173 P1begV += TVector3(tkDir[kKV])*(delta[kLama]*Ptot1);P1begV.SetMag(Ptot1);
1174 P1begV += TVector3(tkDir[kKU])*(delta[kFita]*Ptot1);P1begV.SetMag(Ptot1);
1176 X1begV.GetXYZ(X1beg);
1177 P1begV.GetXYZ(P1beg);
1178 THelix3d TH1(charge,X1beg,P1beg,Mag);
1179 double s = TH1.
Path(Xend);
1181 TH1.Eval(0,X1end,P1end);
1182 TVector3 X1endV(X1end),P1endV(P1end);
1184 TVector3 difX = X1endV-XendV;
1185 TVector3 difD = (P1endV.Unit()-PendV.Unit());
1187 U1endV[kU] = difX.Dot(TVector3(tkDirE[kKU]));
1188 U1endV[kV] = difX.Dot(TVector3(tkDirE[kKV]));
1189 U1endV[kPinv] = (Pinv1-Pinv);
1190 U1endV[kLama] = difD.Dot(TVector3(tkDirE[kKV]));
1191 U1endV[kFita] = difD.Dot(TVector3(tkDirE[kKU]));
1193 for (
int ih=0;ih<5;ih++) { hh[ih]->Fill(U1endV[ih]/GendD[ih]);}
1194 TCL::trasat(U1endV.GetMatrixArray(),GendI,&chi2,1,5);
1195 hXi2[1]->Fill(chi2);
1197 for (
int i=0,li=0;i<5;li+=++i) {
1198 for (
int j=0;j<=i;j++) {
1199 myG[li+j]+=U1endV[i]*U1endV[j];
1203 for (
int i=0,li=0;i<5;li+=++i) {
1204 for (
int j=0;j<i;j++) {
1205 double d = U1endV[i]*U1endV[j] - Gend[li+j];
1206 d/= GendD[i]*GendD[j];
1211 TCL::vscale(myG,1./nIter,myG,15);
1213 printf(
"Numerical vs Analitical Error matrices:\n");
1214 for (
int i=0,li=0;i<5;li+=++i) {
1215 for (
int j=0;j<=i;j++) {
1216 printf(
"\t%g ",myG[li+j]);
1219 for (
int j=0;j<=i;j++) {
1220 printf(
"\t%g ",Gend[li+j]);
1225 for (
int i=0,li=0;i<5;li+=++i) {
1226 for (
int j=0;j<=i;j++) {
1227 printf(
"\t%g ",Gend[li+j]/(GendD[i]*GendD[j]));
1232 for (
int i=0;myCanvas[i];i++) {
1233 if (!myCanvas[i])
continue;
1234 myCanvas[i]->Modified();myCanvas[i]->Update();}
1236 while(!gSystem->ProcessEvents()){gSystem->Sleep(200);};
1239 void THelix3d::TestErr2(
int charge)
1241 double PtGev = 1.,Curv = 1./30, Hz = PtGev*Curv;
1242 double HZ[3] = {0,0,Hz};
1243 double Pbeg[3],P1beg[3],Xbeg[3]={0},X1beg[3];
1244 double Pend[3],P1end[3],Xend[3] ,X1end[3];
1248 static TCanvas *myCanvas[kNCanvs] = {0};
1249 static int myDiv[] = {2,5,5,5,5,0};
1250 for (
int ic = 0;myDiv[ic];ic++) {
1251 if (myDiv[ic]<0)
continue;
1252 TString ts(
"C"); ts+=ic;
1253 if (!myCanvas[ic]) myCanvas[ic] =
new TCanvas(ts.Data(),ts.Data(),600,800);
1254 myCanvas[ic]->Clear();myCanvas[ic]->Divide(1,myDiv[ic]);
1256 static TH1F *hXi2[2] = {0};
1257 for (
int jk=0;jk<2;jk++) {
1258 TString ts(
"Xi2_"); ts += jk;
1260 hXi2[jk]=
new TH1F(ts.Data(),ts.Data(),50,0,0);
1261 myCanvas[0]->cd(jk+1); hXi2[jk]->Draw();
1264 static TH1F * hh[5]={0};
1265 for (
int ih=0;ih<myDiv[1];ih++) {
1266 const char * tit[]={
"U",
"V",
"Pinv",
"Fita",
"Lama",0};
1268 hh[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1269 myCanvas[1]->cd(ih+1); hh[ih]->Draw();
1272 static TH1F * hrt[5]={0};
1273 for (
int ih=0;ih<myDiv[1];ih++) {
1274 const char * tit[]={
"U0",
"V0",
"Pinv0",
"Fita0",
"Lama0",0};
1276 hrt[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1277 myCanvas[2]->cd(ih+1); hrt[ih]->Draw();
1280 static TH1F * hcr[10]={0};
1282 static const char *tit[]={
"UV",
"UP",
"VP",
"UL",
"VL",
"PL",
"UF",
"VF",
"PF",
"LF"};
1283 for (
int ih=0;ih<10;ih++) {
1285 hcr[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1286 if (ih<5) myCanvas[3]->cd(ih+1 );
1287 else myCanvas[4]->cd(ih+1-5);
1292 TVector3 PbegV(PtGev,0,PtGev*3);
1293 double Ptot = PbegV.Mag();
1294 PbegV.RotateZ(gRandom->Rndm()*3.1415*2); PbegV.GetXYZ(Pbeg);
1295 TVector3 XbegV(Xbeg);
1299 double Mag[3]={HZ[0],HZ[1],HZ[2]};
1302 double r1 = gRandom->Rndm(),r2 = gRandom->Rndm();
1303 magV.RotateX(r1); magV.RotateY(r2); magV.GetXYZ(Mag);
1304 PbegV.RotateX(r1); PbegV.RotateY(r2); PbegV.GetXYZ(Pbeg);
1307 dia[kU]= 0.1; dia[kV]= 0.2; dia[kPinv]= 0.1/Ptot; dia[kFita]= 1./360; dia[kLama]= 2./360;
1310 auto &EMX = RV.GetMtx();
1311 auto &val = RV.GetLam();
1316 double Gbeg[15],GbegD[5];
1317 for (
int i=0,li=0;i< 5;li+=++i) {
1318 GbegD[i] = sqrt(EMX[i][i]);
1319 for (
int j=0;j<=i;j++) {
1320 Gbeg[li+j] = EMX[i][j];
1322 assert( mySign(Gbeg,5)>0);
1326 THelix3d TH0(charge,Xbeg,Pbeg,Mag);
1334 memcpy(Gbeg,*TH0i.Emx(),
sizeof(Gbeg));
1337 assert( mySign(GbegI,5)>0);
1343 double tkDir[3][3],tkDirE[3][3];
1344 memcpy(tkDir[0] ,TH0.TkDir(0)[0],
sizeof(tkDir ));
1345 memcpy(tkDirE[0],TH0.TkDir(1)[0],
sizeof(tkDirE));
1347 TH0.Eval(0,Xend,Pend);
1348 auto *myEmx = TH0.Emx();
1349 const double *Gend = *myEmx;
1350 assert(mySign(Gend,5)>0);
1352 for (
int i=0,li=0;i< 5;li+=++i) {
1353 GendD[i] = sqrt(Gend[li+i]);
1359 TVector3 PendV(Pend),XendV(Xend);
1361 for (
int j=0;j<3;j++) { UendV[j+2]=Pend[j];}
1364 int nIter = 1000000;
1365 for (
int iter=0;iter<nIter;iter++) {
1366 TVectorD delta = RVi.Gaus();
1368 TCL::trasat(delta.GetMatrixArray(),GbegI,&chi2,1,5);
1370 hXi2[0]->Fill(chi2);
1372 for (
int ih=0;ih<myDiv[1];ih++) { hrt[ih]->Fill(delta[ih]/GbegD[ih]);}
1373 TVector3 P1begV(TH0i.Mom());
1374 TVector3 X1begV(TH0i.Pos());
1376 X1begV += TVector3(tkDir[kKU])*delta[kU];
1377 X1begV += TVector3(tkDir[kKV])*delta[kV];
1378 double Pinv = TH0i.Pinv();
1379 double Pinv1 = Pinv + delta[kPinv];
1380 double Ptot1 = fabs(1./Pinv1);
1381 P1begV.SetMag(Ptot1);
1382 P1begV += TVector3(tkDir[kKV])*(delta[kLama]*Ptot1);P1begV.SetMag(Ptot1);
1383 P1begV += TVector3(tkDir[kKU])*(delta[kFita]*Ptot1);P1begV.SetMag(Ptot1);
1385 X1begV.GetXYZ(X1beg);
1386 P1begV.GetXYZ(P1beg);
1387 THelix3d TH1(TH0i.Charge(),X1beg,P1beg,Mag);
1389 TH1.Eval(0,X1end,P1end);
1390 TVector3 X1endV(X1end),P1endV(P1end);
1392 TVector3 difX = X1endV-XendV;
1393 TVector3 difD = (P1endV.Unit()-PendV.Unit());
1395 U1endV[kU] = difX.Dot(TVector3(tkDirE[kKU]));
1396 U1endV[kV] = difX.Dot(TVector3(tkDirE[kKV]));
1397 U1endV[kFita] = difD.Dot(TVector3(tkDirE[kKU]));
1398 U1endV[kLama] = difD.Dot(TVector3(tkDirE[kKV]));
1399 U1endV[kPinv] = (Pinv1-Pinv);
1401 for (
int ih=0;ih<5;ih++) { hh[ih]->Fill(U1endV[ih]/GendD[ih]);}
1402 TCL::trasat(U1endV.GetMatrixArray(),GendI,&chi2,1,5);
1403 hXi2[1]->Fill(chi2);
1405 for (
int i=0,li=0;i<5;li+=++i) {
1406 for (
int j=0;j<=i;j++) {
1407 myG[li+j]+=U1endV[i]*U1endV[j];
1411 for (
int i=0,li=0;i<5;li+=++i) {
1412 for (
int j=0;j<i;j++) {
1413 double d = U1endV[i]*U1endV[j] - Gend[li+j];
1414 d/= GendD[i]*GendD[j];
1419 TCL::vscale(myG,1./nIter,myG,15);
1421 printf(
"Numerical vs Analitical Error matrices:\n");
1422 for (
int i=0,li=0;i<5;li+=++i) {
1423 for (
int j=0;j<=i;j++) {
1424 printf(
"\t%g ",myG[li+j]);
1427 for (
int j=0;j<=i;j++) {
1428 printf(
"\t%g ",Gend[li+j]);
1434 for (
int i=0;myCanvas[i];i++) {
1435 if (!myCanvas[i])
continue;
1436 myCanvas[i]->Modified();myCanvas[i]->Update();}
1438 while(!gSystem->ProcessEvents()){gSystem->Sleep(200);};
1441 void THelix3d::TestErr3(
int charge)
1444 double PtGev = 1.,Curv = 1./30, Hz = PtGev*Curv;
1445 double HZ[3] = {0,0,Hz};
1446 double Pbeg[3],P1beg[3],Xbeg[3]={0},X1beg[3];
1447 double Pend[3],P1end[3],Xend[3] ,X1end[3];
1448 double myTkRot = 0.1;
1452 static TCanvas *myCanvas[kNCanvs] = {0};
1453 static int myDiv[] = {2,5,5,5,5,0};
1454 for (
int ic = 0;myDiv[ic];ic++) {
1455 if (myDiv[ic]<0)
continue;
1456 TString ts(
"C"); ts+=ic;
1457 if (!myCanvas[ic]) myCanvas[ic] =
new TCanvas(ts.Data(),ts.Data(),600,800);
1458 myCanvas[ic]->Clear();myCanvas[ic]->Divide(1,myDiv[ic]);
1460 static TH1F *hXi2[2] = {0};
1461 for (
int jk=0;jk<2;jk++) {
1462 TString ts(
"Xi2_"); ts += jk;
1464 hXi2[jk]=
new TH1F(ts.Data(),ts.Data(),50,0,0);
1465 myCanvas[0]->cd(jk+1); hXi2[jk]->Draw();
1468 static TH1F * hh[5]={0};
1469 for (
int ih=0;ih<myDiv[1];ih++) {
1470 const char * tit[]={
"U",
"V",
"Fita",
"Lama",
"Pinv",0};
1472 hh[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1473 myCanvas[1]->cd(ih+1); hh[ih]->Draw();
1476 static TH1F * hrt[5]={0};
1477 for (
int ih=0;ih<myDiv[1];ih++) {
1478 const char * tit[]={
"U0",
"V0",
"Pinv0",
"Fita0",
"Lama0",0};
1480 hrt[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1481 myCanvas[2]->cd(ih+1); hrt[ih]->Draw();
1484 static TH1F * hcr[10]={0};
1486 static const char *tit[]={
"UV",
"UF",
"VF",
"UL",
"VL",
"FL",
"UP",
"VP",
"FP",
"LP"};
1487 for (
int ih=0;ih<10;ih++) {
1489 hcr[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1490 if (ih<5) myCanvas[3]->cd(ih+1 );
1491 else myCanvas[4]->cd(ih+1-5);
1496 TVector3 PbegV(PtGev,0,PtGev*3);
1497 double Ptot = PbegV.Mag();
1498 PbegV.RotateZ(gRandom->Rndm()*3.1415*2); PbegV.GetXYZ(Pbeg);
1499 TVector3 XbegV(Xbeg);
1501 double Mag[3]={HZ[0],HZ[1],HZ[2]};
1504 double r1 = gRandom->Rndm(),r2 = gRandom->Rndm();
1505 magV.RotateX(r1); magV.RotateY(r2); magV.GetXYZ(Mag);
1506 PbegV.RotateX(r1); PbegV.RotateY(r2); PbegV.GetXYZ(Pbeg);
1509 dia[kU]= 0.1; dia[kV]= 0.2; dia[kPinv]= 0.1/Ptot; dia[kFita]= 1./360; dia[kLama]= 2./360;
1512 auto &EMX = RV.GetMtx();
1513 auto &val = RV.GetLam();
1518 double Gbeg[15],GbegD[5];
1519 for (
int i=0,li=0;i< 5;li+=++i) {
1520 GbegD[i] = sqrt(EMX[i][i]);
1521 for (
int j=0;j<=i;j++) {
1522 Gbeg[li+j] = EMX[i][j];
1524 assert( mySign(Gbeg,5)>0);
1529 assert( mySign(GbegI,5)>0);
1532 THelix3d TH0(charge,Xbeg,Pbeg,Mag);
1543 TH0.Eval(0,Xbeg,Pbeg);
1544 PbegV.RotateX(myTkRot);
1545 PbegV.RotateY(myTkRot);
1548 TkDir_t tkDirE = TH0.TkDir(0);
1550 TVector3 PendV(Pbeg),XendV(Xbeg);
1551 PendV.GetXYZ(Pend); XendV.GetXYZ(Xend);
1555 auto *emxE = TH0.Emx();
1556 const double *Gend = *emxE;
1559 assert(mySign(Gend,5)>0);
1561 for (
int i=0,li=0;i< 5;li+=++i) {
1562 GendD[i] = sqrt(Gend[li+i]);
1567 assert(mySign(GendI,5)>0);
1570 for (
int j=0;j<3;j++) { UendV[j+2]=Pend[j];}
1573 int nIter = 1000000;
1574 for (
int iter=0;iter<nIter;iter++) {
1575 TVectorD delta = RV.Gaus();
1577 TCL::trasat(delta.GetMatrixArray(),GbegI,&chi2,1,5);
1580 hXi2[0]->Fill(chi2);
1582 for (
int ih=0;ih<myDiv[1];ih++) { hrt[ih]->Fill(delta[ih]/GbegD[ih]);}
1583 TVector3 P1begV = PbegV;
1584 TVector3 D1begV = P1begV.Unit();
1585 TVector3 X1begV = XbegV;
1586 double cosL = D1begV.Dot(tkDir.V());
1587 double cosLF= D1begV.Dot(tkDir.T());
1591 X1begV += TVector3(tkDir.U())*delta[kU];
1592 X1begV += TVector3(tkDir.V())*delta[kV];
1593 double Pinv = -charge/Ptot;
1594 double Pinv1 = Pinv + delta[kPinv];
1595 double Ptot1 = fabs(1./Pinv1);
1596 P1begV.SetMag(Ptot1);
1597 P1begV += TVector3(tkDir[kKV])*(delta[kLama]*Ptot1*cosL );P1begV.SetMag(Ptot1);
1598 P1begV += TVector3(tkDir[kKU])*(delta[kFita]*Ptot1*cosLF);P1begV.SetMag(Ptot1);
1600 X1begV.GetXYZ(X1beg);
1601 P1begV.GetXYZ(P1beg);
1602 THelix3d TH1(charge,X1beg,P1beg,Mag);
1603 double aa = (X1begV-XbegV).Dot(tkDirE.T());
1604 double bb = P1begV.Unit().Dot(tkDirE.T());
1605 double tau = -aa/bb;
1606 assert(fabs(tau)<1);
1608 TH1.Eval(0,X1end,P1end);
1609 TVector3 X1endV(X1end),P1endV(P1end);
1611 TVector3 difX = X1endV-XendV;
1612 TVector3 difD = (P1endV.Unit()-PendV.Unit());
1614 U1endV[kU] = difX.Dot(tkDirE[kKU]);
1615 U1endV[kV] = difX.Dot(tkDirE[kKV]);
1616 U1endV[kPinv] = (Pinv1-Pinv);
1617 U1endV[kLama] = difD.Dot(tkDirE[kKV]);
1618 U1endV[kFita] = difD.Dot(tkDirE[kKU]);
1620 for (
int ih=0;ih<5;ih++) { hh[ih]->Fill(U1endV[ih]/GendD[ih]);}
1621 TCL::trasat(U1endV.GetMatrixArray(),GendI,&chi2,1,5);
1622 hXi2[1]->Fill(chi2);
1624 for (
int i=0,li=0;i<5;li+=++i) {
1625 for (
int j=0;j<=i;j++) {
1626 myG[li+j]+=U1endV[i]*U1endV[j];
1630 for (
int i=0,li=0;i<5;li+=++i) {
1631 for (
int j=0;j<i;j++) {
1632 double d = U1endV[i]*U1endV[j] - Gend[li+j];
1633 d/= GendD[i]*GendD[j];
1638 TCL::vscale(myG,1./nIter,myG,15);
1640 printf(
"Numerical vs Analitical Error matrices:\n");
1641 for (
int i=0,li=0;i<5;li+=++i) {
1642 for (
int j=0;j<=i;j++) {
1643 printf(
"\t%g ",myG[li+j]);
1646 for (
int j=0;j<=i;j++) {
1647 printf(
"\t%g ",Gend[li+j]);
1652 for (
int i=0,li=0;i<5;li+=++i) {
1653 for (
int j=0;j<=i;j++) {
1654 printf(
"\t%g ",Gend[li+j]/(GendD[i]*GendD[j]));
1659 for (
int i=0;myCanvas[i];i++) {
1660 if (!myCanvas[i])
continue;
1661 myCanvas[i]->Modified();myCanvas[i]->Update();}
1663 while(!gSystem->ProcessEvents()){gSystem->Sleep(200);};
1666 void THelix3d::ConvertErrs(
const THelixTrack_ *he,
const double Bzp
1667 ,
double G[15],
double D[5][5],
double Di[5][5])
1786 static const double kMinBz = 0.001494399 * 1e-3;
1787 const double *T = he->Dir();
1788 double Rho = he->GetRho();
1789 double sinLam = T[2], cosLam = sqrt((1-sinLam)*(1+sinLam));
1793 double Bz = (fabs(Bzp) < kMinBz)? kMinBz:Bzp;
1795 double dVdZ = cosLam;
1796 double dFita_dPhi = cosLam;
1797 double dFita_dZ = -sinLam*cosLam*cosLam*Rho;
1798 double dLama_dLam = 1;
1799 double dPinv_dRho = cosLam/Bz;
1800 double dPinv_dLam = -Rho*sinLam/Bz;
1808 {0, dFita_dPhi, 0,dFita_dZ, 0},
1809 {0, 0, 0, 0,dLama_dLam},
1810 {0, 0,dPinv_dRho, 0,dPinv_dLam}};
1812 if ( D) memcpy(D[0],Mtx[0],
sizeof(Mtx));
1816 double dPhi_dFita = 1./cosLam;
1817 double dPhi_dV = sinLam*Rho;
1818 double dRho_dPinv = Bz/cosLam;
1819 double dRho_dLama = sinLam/cosLam*Rho;
1820 double dZdV = 1./cosLam;
1821 double dLam_dLama = 1;
1827 {0, dPhi_dV, dPhi_dFita, 0, 0},
1828 {0, 0, 0, dRho_dLama, dRho_dPinv},
1830 {0, 0, 0, dLam_dLama, 0}};
1834 TCL::mxmpy(Mtx[0],Xtm[0],qwe[0],5,5,5);
1835 for (
int i=0;i<5;i++) {
1836 for (
int j=0;j<5;j++) {
1837 double ttt = qwe[i][j];
if (i==j) ttt--;
1838 assert(fabs(ttt)<1e-8);
1840 memcpy(Di[0],Xtm[0],
sizeof(Mtx));
1846 TCL::ucopy(*he->Emx(),hemx,15);
1848 for (
int i=0,li=0;i<5;li+=++i) {
1849 assert(hemx[li+i]>0);
1854 void THelix3d::TestConvertErrs()
1856 double PtGev = 1.,Curv = 1./100, Mag[3] = {0,0,PtGev*Curv};
1857 double Pbeg[3],Xbeg[3]={0};
1859 TVector3 PbegV(PtGev,0,PtGev/3*4);
1860 int icharge = (-Curv*PtGev/Mag[2]<0)? -1:1;
1862 PbegV.RotateZ(gRandom->Rndm()*3.1415);
1865 TVector3 XbegV(Xbeg);
1869 dia[0]= 0.1; dia[1]= 3./360; dia[2]= Curv*0.01; dia[3]= 0.2; dia[4]= 2./360;
1870 for (
int i=0;i<5;i++) {dia[i]*=dia[i];}
1873 auto &EMX = RV.GetMtx();
1874 auto &val = RV.GetLam();
1879 double Gbeg[15],Gbeg1[15],Gend[15];
1880 for (
int i=0,li=0;i< 5;li+=++i) {
1881 for (
int j=0;j<=i;j++) {
1882 Gbeg[li+j] = EMX[i][j];
1886 THelix3d TH1(icharge ,Xbeg,Pbeg,Mag );
1887 assert (fabs(TH1.GetRho()-Curv)<1e-5);
1890 ConvertErrs(&TH0,Mag[2],Gbeg1);
1892 TVectorD Gbeg0V(15,Gbeg ); Gbeg0V.Print(
"Gbeg ");
1893 TVectorD Gbeg1V(15,Gbeg1 ); Gbeg1V.Print(
"Gbeg1");
1895 auto *emx = TH1.SetEmx(Gbeg1);
1896 emx->Print(
"Converted1");
1900 TVector3 vX0(TH0.Pos());
1901 TVector3 vX1(TH1.Pos());
1902 double eps = (vX1-vX0).Mag();
1904 TVector3 vD0(TH0.Dir());
1905 TVector3 vD1(TH1.Dir());
1906 eps = (vD1-vD0).Mag();
1909 ConvertErrs(&TH0,Mag[2],Gend);
1911 const double *Gend1 = *TH1.Emx();
1912 TVectorD Gend0V(15,Gend ); Gend0V.Print(
"Gend ");
1913 TVectorD Gend1V(15,Gend1 ); Gend1V.Print(
"Gend1");
1915 double GendD[5],Gend1D[5];
1916 const char *tit =
"UVFLP";
1917 for (
int i=0,li=0;i< 5;li+=++i) {
1918 GendD [i] = sqrt(Gend [li+i]);
1919 Gend1D[i] = sqrt(Gend1[li+i]);
1920 double dif = 2*(GendD[i]-Gend1D[i])/(GendD[i]+Gend1D[i]);
1921 printf(
"[%c][%c] %g %g dif = %g\n",tit[i],tit[i],Gend [li+i],Gend1[li+i],dif);
1922 for (
int j=0;j<i;j++) {
1923 double cor0 = Gend [li+j]/(GendD [i]*GendD [j]);
1924 double cor1 = Gend1[li+j]/(Gend1D[i]*Gend1D[j]);
1926 printf(
"[%c][%c] %g %g dif = %g\n",tit[i],tit[j],cor0,cor1,dif);
1931 void THelix3d::TestConvertDers()
1934 enum {kkH,kkPhi,kkCur,kkZ,kkLam};
1937 double Curv = 1./100,Hz = Pt*Curv;
1938 TVector3 XbegV = TVector3(0,0,0);
1940 TVector3 PbegV = TVector3(Pt,0,0.01);
1941 TVector3 PbegV1(PbegV);
1942 TVector3 DbegV = PbegV.Unit();
1943 double HZ[3] = {0,0,Hz};
1944 int icharge = (-Curv*Pt/HZ[2]<0)? -1:1;
1948 double Dhlx[5][5],Dh3d[5][5],ConvEnd[5][5],ConvBeg[5][5];
1949 double Der1[5][5],NumDer1[5][5];
1950 double Der2[5][5],NumDer2[5][5];
1951 double NumDer3[5][5];
1953 THelixTrack_ THbeg((
double*)&XbegV[0],(
double*)&DbegV[0],Curv);
1954 double CosBeg = THbeg.GetCos();
1955 printf(
" ==================== CosBeg = %g ==========================\n",CosBeg);
1960 THelixTrack_ THend((
double*)&XbegV[0],(
double*)&DbegV[0],Curv);
1962 double CosEnd = THend.GetCos();
1963 TVector3 XendV(THend.Pos());
1964 TVector3 DendV(THend.Dir());
1966 THelix3d T3beg(icharge,(
double*)&XbegV[0],(
double*)&PbegV[0],HZ);
1967 THelix3d T3end(icharge,(
double*)&XbegV[0],(
double*)&PbegV[0],HZ);
1968 double Pinv = T3beg.Pinv();
1973 T3beg.ConvertErrs(&THbeg,HZ[2],0,ConvBeg);
1974 T3end.ConvertErrs(&THend,HZ[2],0,ConvEnd);
1976 TCL::mxmpy(ConvEnd[0],Dhlx[0],Der1[0],5,5,5);
1977 TCL::mxmpy(Dh3d[0],ConvBeg[0],Der2[0],5,5,5);
1978 auto myDer = T3end.Der();
1980 TVector3 HbegV(myDer->TkDir(0)[kKU]);
1981 TVector3 UbegV(myDer->TkDir(0)[kKU]);
1982 TVector3 VbegV(myDer->TkDir(0)[kKV]);
1983 TVector3 ZbegV(0.,0.,1.);
1984 TVector3 TbegV(myDer->TkDir(0)[kKT]);
1986 TVector3 UendV(myDer->TkDir(1)[kKU]);
1987 TVector3 VendV(myDer->TkDir(1)[kKV]);
1988 TVector3 TendV(myDer->TkDir(1)[kKT]);
1991 for (
int J=0;J<5;J++) {
1992 TVector3 X1begV(XbegV),D1begV(DbegV);
1993 double Curv1 = Curv;
1994 double delta = 1e-4;
1997 X1begV += HbegV*delta;
2001 D1begV+=HbegV*(delta*CosBeg); D1begV.SetMag(1.);
2009 X1begV += ZbegV*delta;
2013 D1begV+=VbegV*delta; D1begV.SetMag(1.);
2017 default: assert(0 &&
"Wrong J");
2020 TVector3 X2begV(XbegV),D2begV(DbegV),P2begV;
2021 double P2invBeg=Pinv;
2022 double delta2 = delta;
2025 X2begV += UbegV*delta2;
2029 D2begV+=UbegV*(delta2); D2begV.SetMag(1.);
2038 X2begV += VbegV*delta2;
2043 D2begV+=VbegV*delta2; D1begV.SetMag(1.);
2047 default: assert(0 &&
"Wrong J");
2053 THelixTrack_ TH1((
double*)&X1begV[0],(
double*)&D1begV[0],Curv1);
2054 double CosBeg1 = TH1.GetCos();
2056 TVector3 X1endV(TH1.Pos());
2057 TVector3 D1endV(TH1.Dir());
2058 dL = -(X1endV-XendV).Dot(DendV)/(DendV.Dot(D1endV));
2060 double CosEnd1 = TH1.GetCos();
2061 X1endV = TVector3(TH1.Pos());
2062 D1endV = TVector3(TH1.Dir());
2066 TVector3 difX = X1endV-XendV;
2067 TVector3 difD = (D1endV-DendV);
2068 dif[kU] = difX.Dot(UendV);
2069 dif[kV] = difX.Dot(VendV);
2070 dif[kPinv] = -icharge*(Curv1*CosEnd1-Curv*CosEnd)/Hz;
2071 dif[kFita] = difD.Dot(UendV);
2072 dif[kLama] = difD.Dot(VendV);
2073 assert(fabs(dif.NormInf())<1.);
2075 for (
int i=0;i<5;i++) { NumDer1[i][J] = dif[i];}
2078 double P1tot1 = Hz/(Curv1*CosBeg1);
2079 auto P1begV = D1begV*=P1tot1;
2080 THelix3d T31(icharge,(
double*)&X1begV[0],(
double*)&P1begV[0],HZ);
2083 T31.Eval(0,&X1endV[0],&P1endV[0]);
2084 D1endV = P1endV.Unit();
2085 dL = -(X1endV-XendV).Dot(DendV)/(DendV.Dot(D1endV));
2087 X1endV = TVector3(T31.Pos());
2088 D1endV = TVector3(T31.Dir());
2089 double PinvEnd = T31.Pinv();
2090 difX = X1endV-XendV;
2091 difD = (D1endV-DendV);
2092 dif[kU] = difX.Dot(UendV);
2093 dif[kV] = difX.Dot(VendV);
2094 dif[kPinv] = PinvEnd-Pinv;
2095 dif[kFita] = difD.Dot(UendV);
2096 dif[kLama] = difD.Dot(VendV);
2097 assert(fabs(dif.NormInf())<1.);
2099 for (
int i=0;i<5;i++) { NumDer2[i][J] = dif[i];}
2103 double CosBeg2 = sqrt((1.-D2begV.CosTheta())*(1.+D2begV.CosTheta()));
2104 double Curv2beg = -icharge*P2invBeg/CosBeg2*Hz;
2106 THelixTrack_ TH2((
double*)&X2begV[0],(
double*)&D2begV[0],Curv2beg);
2109 P2begV = D2begV*(1/fabs(P2invBeg));
2110 THelix3d TH2(icharge,(
double*)&X2begV[0],(
double*)&P2begV[0],HZ);
2117 double CosEnd2 = TH2.GetCos();
2118 double CurvEnd2 = TH2.GetRho();
2119 TVector3 X2endV(TH2.Pos());
2120 TVector3 D2endV(TH2.Dir());
2121 difX = X2endV-XendV;
2122 difD = (D2endV-DendV);
2123 dif[kU] = difX.Dot(UendV);
2124 dif[kV] = difX.Dot(VendV);
2125 dif[kPinv] = -icharge*(CurvEnd2*CosEnd2-Curv*CosEnd)/Hz;
2126 dif[kFita] = difD.Dot(UendV);
2127 dif[kLama] = difD.Dot(VendV);
2130 for (
int i=0;i<5;i++) { NumDer3[i][J] = dif[i];}
2136 static const char* LabHlx[]={
"H ",
"Phi",
"Cur",
"Z ",
"Lam"};
2137 static const char* LabH3d[]={
"U ",
"V ",
"Fit",
"Ama",
"Pin"};
2138 for (
int ihlx=0;ihlx<5;ihlx++) {
2139 for (
int ih3d=0;ih3d<5;ih3d++) {
2140 printf(
"[%s][%s] = %g == %g == %g == %g\n",LabH3d[ih3d],LabHlx[ihlx]
2143 ,NumDer1[ih3d][ihlx]
2144 ,NumDer2[ih3d][ihlx]);
2147 for (
int ih3d=0;ih3d<5;ih3d++) {
2148 for (
int jh3d=0;jh3d<5;jh3d++) {
2149 printf(
"[%s][%s] = %g == %g \n",LabH3d[ih3d],LabH3d[jh3d]
2151 ,NumDer3[ih3d][jh3d]);
2156 double EmxSign(
int n,
const double *a)
2160 double *B = (n<=10) ? buf :
new double[n];
2167 int ipiv, kpiv, i__, j;
2191 for (j = i__; j <= n; ++j) {
2193 if (i__ == 1)
goto L40;
2194 if (r__ == 0.)
goto L42;
2195 id = ipiv - i__ + 1;
2196 kd = kpiv - i__ + 1;
2199 sum += b[kd] * b[id];
2201 }
while (
id < ipiv);
2204 sum = a[kpiv] - sum;
2206 if (j != i__) b[kpiv] = sum * r__;
2208 if (sum<ans) ans = sum;
2209 if (sum<0.)
goto RETN;
2212 if (r__ > 0.) r__ = (double)1. / dc;
2219 RETN:
if (B!=buf)
delete B;
void Backward()
Change direction.
double Eval(double step, double xyz[3]=0, double mom[3]=0)
Evaluate params with given step along helix.
double Path(double stmax, const double *surf, int nsurf, double *x=0, double *dir=0, int nearest=0) const
static float * trsinv(const float *g, float *gi, int n)
double Move(double step)
Move along helix.
const double * Pos() const
distance and DCAxy and DCAz to given space point (with error matrix)
void Backward()
Change direction.
double Move(double step, double F[5][5]=0)
Move along helix.
static float * trasat(const float *a, const float *s, float *r, int m, int n)
void MakeMtx(double step, double F[5][5])
double Eval(double step, double *xyz, double *dir=0, double *rho=0) const
Evaluate params with given step along helix.
double Path(const double point[3], double xyz[3]=0, double mom[3]=0)
Distance to nearest point to given space point.
virtual TString Path() const
return the full path of this data set
double Dca(const double point[3], double *dcaErr=0)
DCA to given space point (with error matrix)