12 #include "TRandomVector.h"
15 #include "TRungeKutta.h"
24 void
TRungeKutta::TRKutaPars_t::Print(const
char *tit)
const
26 if (tit && *tit) {printf(
"TRKutaPars_t::Print(%s)\n",tit);}
27 printf(
"X= %g %g %g D= %g %g %g Pinv = %g\n"
28 ,X[0],X[1],X[2],D[0],D[1],D[2],Pinv);
31 void TRungeKutta::Print(
const char *tit)
const
33 if (tit && *tit) {printf(
"TRungeKutta::Print(%s)\n",tit);}
38 TRungeKutta::TRungeKutta(
int charge,
const double *xyz,
const double *mom,
TRKuttaMag *Mag)
43 memset(fBeg,0,fEnd-fBeg);
48 TRungeKutta::TRungeKutta()
50 memset(fBeg,0,fEnd-fBeg);
54 TRungeKutta::~TRungeKutta()
62 memset(fBeg,0,fEnd-fBeg);
65 (*fGUFLD)(from.Pos(),B);
66 assert(fabs(B[0])+fabs(B[1])<1e-3*fabs(B[2]));
67 double rho = from.GetRho();
68 int iq = ((rho>0)==(B[2]>0)) ? -1:1;
69 TCL::vscale(from.Dir(),B[2]/rho,P,3);
75 fGUFLD = (mag)? mag:fgMag;
80 void TRungeKutta::ZetMag(
const double *mag)
82 memcpy(fBInp,mag,
sizeof(fBInp));
83 memcpy(fBOut,mag,
sizeof(fBOut));
86 void TRungeKutta::Set(
int charge,
const double *xyz,
const double *mom)
88 if (charge) fCharge = charge;
89 memcpy(fInp.X,xyz,
sizeof(fInp.X));
90 memcpy(fInp.P,mom,
sizeof(fInp.P));
91 fInp.Pinv = -fCharge/sqrt(TCL::vdot(fInp.P,fInp.P,3));
92 TCL::vscale(fInp.P,fabs(fInp.Pinv),fInp.D,3);
93 if (fBInp[2]<1e3)
return;
94 (*fGUFLD)(fInp.X,fBInp);
100 *
this = *from; fEmx3d=0,fDer3d=0;
106 if (fEmx3d) {fEmx3d =
new THEmx3d_t; *fEmx3d = *from.fEmx3d;}
107 if (fDer3d) {fDer3d =
new THDer3d_t; *fDer3d = *from.fDer3d;}
112 TCL::vscale(fInp.P,-1.,fInp.P,3);
113 TCL::vscale(fInp.D,-1.,fInp.D,3);
115 fInp.Pinv = -fInp.Pinv;
116 if (fEmx3d) fEmx3d->Backward();
117 if (fDer3d) fDer3d->Backward();
124 if (fabs(fLen)<=kMicron)
return 0;
125 grkuta(fCharge ,fLen,fInp,fOut) ;
131 double TRungeKutta::GetCurv() const
133 double H = sqrt(fBInp[0]*fBInp[0]+fBInp[1]*fBInp[1]+fBInp[2]*fBInp[2]);
137 int TRungeKutta::GetDir() const
139 double qwe = TCL::vdot(Pos(),Dir(),3);
147 if (xyz) memcpy(xyz,fInp.X,
sizeof(fInp.X));
148 if (mom) memcpy(mom,fInp.P,
sizeof(fInp.P));
151 grkuta(fCharge ,fLen,fInp,fOut) ;
153 if (xyz) memcpy(xyz,fOut.X,
sizeof(fOut.X));
154 if (mom) memcpy(mom,fOut.P,
sizeof(fOut.P));
169 static const double kEps=1e-7,kRef=1e-6;
170 assert(ndca==2 || ndca==3);
171 double dx[3],gate[4]={-1e11,1e11};
172 int myDir = idir, fail = 13,myState=0;
173 fLen = 0; fOut = fInp;
174 for (
int iter=0; iter<=100; iter++) {
175 double radius = 1./(fabs(GetCurv())+1e-11);
176 double maxStep = (radius<100)? radius:100;
179 assert(fLen>=gate[0] && fLen<=gate[1]);
180 TCL::vsub(point,inp.X,dx,ndca);
181 double dis = sqrt(TCL::vdot(dx,dx,ndca));
182 if (maxStep>dis) maxStep=dis;
183 double tau = TCL::vdot(dx,inp.D,ndca);
184 if (ndca==2) tau/=sqrt((1.-inp.D[2])*(1.+inp.D[2]));
185 double space = fabs(inp.X[0])+fabs(inp.X[1]);
186 if (fabs(tau)<kEps || fabs(tau)<kRef*space) {
187 fLen+=tau; fail=0;
break;
192 if (tau<0) { tau= maxStep;}
else { myDir = 0;}
194 if (tau>0) { tau=-maxStep;}
else { myDir = 0;}
196 if (fabs(tau)>maxStep) tau = (tau<0)? -maxStep:maxStep;
197 if (tau<0) { myState|=2;
198 if (gate[1]>fLen) {gate[1]=fLen;gate[3]=-tau;}
201 if (gate[0]<fLen) {gate[0]=fLen;gate[2] = tau;}
204 tau = ((gate[0]-fLen)*gate[3]+(gate[1]-fLen)*gate[2])/(gate[3]+gate[2]);
205 int myLen = fLen+tau;
206 if (iter>20 || myLen<=gate[0] || myLen>=gate[1]) tau = (gate[0]-fLen+gate[1]-fLen)/2;
208 tau = (tau<0)? -maxStep:maxStep;
210 grkuta(fCharge ,tau,inp,fOut) ;
212 assert(fLen>=gate[0] && fLen<=gate[1]);
214 if (fail)
return 2e22;
223 gde[0] = x;gde[1] = y;
224 return Path(gde,idir,2);
230 static const double kEps=1e-5,kRef=1e-5,kBigEps=1e-1;
231 double qaLeft,posLeft=0,qaRite=0,posRite=0,qaMine,qaStep,dx[3];
232 double radius = 1./(fabs(GetCurv())+1e-11);
233 radius/= sqrt(1. - fOut.D[2]*fOut.D[2])+1e-11;
234 double maxStep = (radius<100)? radius:100;
235 double minStep = 0.1;
237 fLen = 0; fOut = fInp;
238 for (
int iter=0; iter<=20; iter++) {
240 TCL::vsub(inp.X,point,dx,3);
241 qaMine = -TCL::vdot(dx,inp.D,3);
242 if (!iter) {qaLeft = qaMine;}
243 else if (qaMine*qaLeft>0) {qaLeft = qaMine;}
244 else {qaRite = qaMine; posLeft=-qaStep; break ;}
245 qaStep = fabs(qaMine);
if (iter) qaStep*=2;
246 if (qaStep > maxStep) qaStep = maxStep;
247 if (qaStep < minStep) qaStep = minStep;
248 if (idir) { qaStep*=idir;}
else if (qaMine<0) {qaStep*=-1;};
250 grkuta(fCharge ,qaStep,inp,fOut) ;
252 if (fabs(fLen)>6*radius)
return 1e11;
253 assert(fabs(fLen)<6*radius);
255 if (!qaRite)
return 2e22;
257 for (
int iter=0; iter<=20; iter++) {
259 double denom = qaRite-qaLeft;
260 if ((iter&3)==3 || fabs(denom) < 1e-4) {
261 qaStep = 0.5*(posRite+posLeft);
263 qaStep = -(qaLeft*posRite-qaRite*posLeft)/denom;
265 grkuta(fCharge ,qaStep,inp,fOut) ;
267 TCL::vsub(fOut.X,point,dx,3);
268 qaMine = -TCL::vdot(dx,fOut.D,3);
270 if (qaLeft*qaMine>0) { qaLeft = qaMine; posLeft=0; posRite-=qaStep;}
271 else { qaRite = qaMine; posRite=0; posLeft-=qaStep;}
272 if (fabs(qaMine)>kBigEps)
continue;
273 double dis2 = TCL::vdot(dx,dx,3);;
274 if (fabs(qaMine) < kEps || qaMine*qaMine < kRef*kRef*dis2)
break;
278 return (fabs(qaMine)<kBigEps)? fLen:1e11;
284 if(point || dcaErr){};
285 assert(!
"TRungeKutta::Dca Not implemented");
292 static const double kEps=1e-5,kRef=1e-5,kBigEps=1e-1;
293 double qaLeft,posLeft=0,qaRite=0,posRite=0,qaMine,qaStep,dx[2];
294 double minStep = 0.1;
295 double radius = 1./(fabs(GetCurv())+1e-11);
296 radius/= sqrt(1. - fOut.D[2]*fOut.D[2])+1e-11;
297 double maxStep = (radius<100)? radius:100;
299 fLen = 0; fOut = fInp;
300 for (
int iter=0; iter<=20; iter++) {
302 dx[0] = inp.X[0]-x;dx[1] = inp.X[1]-y;
303 qaMine = -(dx[0]*inp.D[0] + dx[1]*inp.D[1]);
304 qaMine /=(1.-inp.D[2])*(1.+inp.D[2]);
305 if (!iter) {qaLeft = qaMine;}
306 else if (qaMine*qaLeft>0) {qaLeft = qaMine;}
307 else {qaRite = qaMine; posLeft=-qaStep; break ;}
308 qaStep = fabs(qaMine);
if (iter) qaStep*=2;
309 if (qaStep > maxStep) qaStep = maxStep;
310 if (qaStep < minStep) qaStep = minStep;
311 if (idir) { qaStep*=idir;}
else if (qaMine<0) {qaStep*=-1;};
314 grkuta(fCharge ,qaStep,inp,fOut) ;
316 if (fabs(fLen)>6*radius)
return 1e11;
317 assert(fabs(fLen)<6*radius);
318 if (fabs(fLen)>6*radius)
return 2e22;
320 if(!qaRite)
return 3e33;;
322 for (
int iter=0; iter<=20; iter++) {
324 double denom = qaRite-qaLeft;
325 if ((iter&3)==3 || fabs(denom) < 1e-4) {
326 qaStep = 0.5*(posRite+posLeft);
328 qaStep = -(qaLeft*posRite-qaRite*posLeft)/denom;
330 grkuta(fCharge ,qaStep,inp,fOut) ;
332 dx[0] = fOut.X[0]-x;dx[1] = fOut.X[1]-y;
333 qaMine = -(dx[0]*fOut.D[0]+dx[1]*fOut.D[1]);
334 qaMine /= (1.-fOut.D[2])*(1.+fOut.D[2]);
336 if (qaLeft*qaMine>0) { qaLeft = qaMine; posLeft=0; posRite-=qaStep;}
337 else { qaRite = qaMine; posRite=0; posLeft-=qaStep;}
338 if (fabs(qaMine)>kBigEps)
continue;
339 double dis2 = dx[0]*dx[0]+dx[1]*dx[1];
340 if (fabs(qaMine) < kEps || qaMine*qaMine< kRef*kRef*dis2)
break;
344 return (fabs(qaMine)<kBigEps)? fLen:1e11;
352 assert(!
"TRungeKutta::Dca(x,y,dcaError) n oy implemented");
355 void TRungeKutta::MakeMtx()
357 if (fabs(fLen) < kMicron)
return;
361 THelix3d TH0(fCharge,fInp.X,fInp.P,fBInp);
365 auto *myDer = TH0.Der();
370 TH0.Set(fCharge,fOut.X,fOut.P,fBOut);
377 Emx1.Update(Emx2.TkDir());
379 TCL::vlinco(Emx1,0.5,Emx2,0.5,(*fEmx3d),15);
380 fEmx3d->TkDir() = Emx1.TkDir();
384 void TRungeKutta::SetEmx(
const double err[15])
388 THelix3d::MakeTkDir(fInp.D,fBInp,fEmx3d->TkDir());
389 if (err) fEmx3d->Set(err);
392 void TRungeKutta::SetEmx(
const THEmx3d_t *err)
396 if (err) *fEmx3d = *err;
397 THelix3d::MakeTkDir(fInp.D,fBInp,fEmx3d->TkDir());
402 memcpy(fBeg,from.fBeg,fEnd-fBeg+1);
405 *fEmx3d = *from.fEmx3d;
409 *fDer3d = *from.fDer3d;
414 void TRungeKutta::grkuta(
double CHARGE,
double STEP
415 ,
const TRKutaPars_t &VECT,TRKutaPars_t &VOUT)
const
454 double XYZT[3], XYZ[3];
455 double SECXS[4],SECYS[4],SECZS[4],HXP[3];
459 double& X = XYZ[0];
double& Y = XYZ[1];
double& Z = XYZ[2];
460 double& XT = XYZT[0];
double& YT = XYZT[1];
double& ZT = XYZT[2];
462 enum {MAXIT = 1992, MAXCUT = 11};
463 static const double EC=2.9979251e-4,DLT=1e-6,DLT32=DLT/32;;
464 static const double ZERO=0, ONE=1, TWO=2, THREE=3;
465 static const double THIRD=ONE/THREE, HALF=ONE/TWO;
466 static const double PISQUA=.986960440109e+01;
473 double A,B,C,AT,BT,CT;
475 double PINV,TL,H,H2,H4,REST,F1,F2,F3,F4,PH,PH2,DXT,DYT,DZT ;
476 double EST,CBA,RHO,TET,HNORM,RHO1,SINT,COST;
477 double G1,G2,G3,G4,G5,G6,HP,ANG2;
490 if (fabs(H) > fabs(REST)) H = REST;
507 SECXS[0] = (B * F[2] - C * F[1]) * PH2;
508 SECYS[0] = (C * F[0] - A * F[2]) * PH2;
509 SECZS[0] = (A * F[1] - B * F[0]) * PH2;
510 ANG2 = (SECXS[0]*SECXS[0] + SECYS[0]*SECYS[0] + SECZS[0]*SECZS[0]);
511 if (ANG2 > PISQUA)
goto L40;
512 DXT = H2 * A + H4 * SECXS[0];
513 DYT = H2 * B + H4 * SECYS[0];
514 DZT = H2 * C + H4 * SECZS[0];
521 EST = fabs(DXT)+fabs(DYT)+fabs(DZT);
522 if (EST > fabs(H))
goto L30;
529 SECXS[1] = (BT * F[2] - CT * F[1]) * PH2;
530 SECYS[1] = (CT * F[0] - AT * F[2]) * PH2;
531 SECZS[1] = (AT * F[1] - BT * F[0]) * PH2;
535 SECXS[2] = (BT * F[2] - CT * F[1]) * PH2;
536 SECYS[2] = (CT * F[0] - AT * F[2]) * PH2;
537 SECZS[2] = (AT * F[1] - BT * F[0]) * PH2;
538 DXT = H * (A + SECXS[2]);
539 DYT = H * (B + SECYS[2]);
540 DZT = H * (C + SECZS[2]);
544 AT = A + TWO*SECXS[2];
545 BT = B + TWO*SECYS[2];
546 CT = C + TWO*SECZS[2];
548 EST = fabs(DXT)+fabs(DYT)+fabs(DZT);
549 if (EST > 2.*fabs(H))
goto L30;
552 memcpy(fBOut,F,
sizeof(fBOut));
554 Z = Z + (C + (SECZS[0] + SECZS[1] + SECZS[2]) * THIRD) * H;
555 Y = Y + (B + (SECYS[0] + SECYS[1] + SECYS[2]) * THIRD) * H;
556 X = X + (A + (SECXS[0] + SECXS[1] + SECXS[2]) * THIRD) * H;
558 SECXS[3] = (BT*F[2] - CT*F[1])* PH2;
559 SECYS[3] = (CT*F[0] - AT*F[2])* PH2;
560 SECZS[3] = (AT*F[1] - BT*F[0])* PH2;
561 dA = (SECXS[0]+SECXS[3]+TWO * (SECXS[1]+SECXS[2])) * THIRD;
562 dB = (SECYS[0]+SECYS[3]+TWO * (SECYS[1]+SECYS[2])) * THIRD;
563 dC = (SECZS[0]+SECZS[3]+TWO * (SECZS[1]+SECZS[2])) * THIRD;
564 A+=dA; B+=dB; C+=dC; EZT = fabs(dA)+fabs(dB) + fabs(dC);
566 EST = fabs(SECXS[0]+SECXS[3] - (SECXS[1]+SECXS[2]))
567 + fabs(SECYS[0]+SECYS[3] - (SECYS[1]+SECYS[2]))
568 + fabs(SECZS[0]+SECZS[3] - (SECZS[1]+SECZS[2]));
570 if ( EST > DLT && fabs(H) > 1.E-2)
goto L30;
574 if (ITER > MAXIT)
goto L40;
580 CBA = ONE/ sqrt(A*A + B*B + C*C);
592 if (STEP < 0.) REST = -REST;
594 if (REST > 1.E-5*fabs(STEP))
goto L20;
595 if (REST > 1.E-5)
goto L20;
600 L30: NCUT = NCUT + 1;
602 if (NCUT > MAXCUT)
goto L40;
610 F4 = sqrt(F1*F1+F2*F2+F3*F3);
613 if(fabs(TET) > 1e-6) {
619 HXP[0] = F2*VECT.D[2] - F3*VECT.D[1];
620 HXP[1] = F3*VECT.D[0] - F1*VECT.D[2];
621 HXP[2] = F1*VECT.D[1] - F2*VECT.D[0];
623 HP = F1*VECT.D[0] + F2*VECT.D[1] + F3*VECT.D[2];
627 COST = TWO*pow(sin(HALF*TET),2);
631 G3 = (TET-SINT) * HP*RHO1;
636 VOUT.X[0] = VECT.X[0] + (G1*VECT.D[0] + G2*HXP[0] + G3*F1);
637 VOUT.X[1] = VECT.X[1] + (G1*VECT.D[1] + G2*HXP[1] + G3*F2);
638 VOUT.X[0] = VECT.X[2] + (G1*VECT.D[2] + G2*HXP[2] + G3*F3);
640 VOUT.D[0] = VECT.D[0] + (G4*VECT.D[0] + G5*HXP[0] + G6*F1);
641 VOUT.D[1] = VECT.D[1] + (G4*VECT.D[1] + G5*HXP[1] + G6*F2);
642 VOUT.D[2] = VECT.D[2] + (G4*VECT.D[2] + G5*HXP[2] + G6*F3);
645 VOUT.X[0] = VECT.X[0] + STEP*VECT.D[0];
646 VOUT.X[1] = VECT.X[1] + STEP*VECT.D[1];
647 VOUT.X[0] = VECT.X[2] + STEP*VECT.D[2];
662 TestMag (
double mag[3]){memcpy (mMag,mag,
sizeof(mMag));}
664 virtual void operator()(
const double X[3],
double B[3])
665 { memcpy(B,mMag,
sizeof(mMag));};
672 void TRungeKutta::Test(
int flag)
677 assert(flag==2 || flag==3);
678 double PtGev = 3.,Rho = 1./100, Hz = PtGev*Rho ;
679 double ZER[3]= {0,0,0};
680 double HZ[3] = {0,0,Hz};
681 double XZ[3] = {100,100,100};
682 double PZ[3] = {PtGev,0,PtGev*4./3};
683 double HH[3],XX[3],PP[3] ;
685 TVector3 vPZ(PZ); vPZ.RotateZ(gRandom->Rndm()); vPZ.GetXYZ(PZ);
691 double r1 = gRandom->Rndm(),r2 = gRandom->Rndm();
693 vHZ.RotateX(r1); vHZ.RotateY(r2); vHZ.GetXYZ(HH);
696 vXZ.RotateX(r1); vXZ.RotateY(r2); vXZ.GetXYZ(XX);
698 vPZ.RotateX(r1); vPZ.RotateY(r2); vPZ.GetXYZ(PP);
702 for (
int charge=1;charge >=-1;charge-=2) {
710 s1 = TH.Path(XX[0],XX[1]);
711 s2 = T3.Path(XX[0],XX[1]);
713 TH.Move(s1); T3.Move(s2);
715 TCL::vsub(TH.Pos(),XX,dif,3);
716 double ThTest = TCL::vdot(TH.Dir(),dif,flag);
717 TCL::vsub(T3.Pos(),XX,dif,3);
718 double TrTest = TCL::vdot(T3.Dir(),dif,flag);
719 printf (
"Charge = %d ThTest,TrTest = %g/%g %g/%g\n",charge,ThTest,s1,TrTest,s2);
727 Test2Mag (
double mag[3]){memcpy (mMag,mag,
sizeof(mMag));}
729 virtual void operator()(
const double X[3],
double B[3])
731 double fak = 1./(1. + (X[0]*X[0]+X[1]*X[1]+X[2]*X[2]/100)*1e-5);
732 TCL::vscale(mMag,fak,B,3);};
733 int birth() {
return 1946;}
740 void TRungeKutta::Test2()
742 double PtGev = 3,Rho = 1./50, Hz = PtGev*Rho ;
743 double ZER[3]= {0,0,0};
744 double HZ[3] = {0,0,Hz};
745 double PZ[3] = {PtGev,0,PtGev/3*4};
746 TVector3 vPZ(PZ); vPZ.RotateZ(gRandom->Rndm()); vPZ.GetXYZ(PZ);
750 for (
int charge=1;charge >=-1;charge-=2) {
751 double myD[3]={PZ[0],PZ[1],PZ[2]};
752 double myX[3]={0,0,0};
755 int nSteps = 100./step+1e-6;
756 for (
int is=0;is<nSteps;is++) {
758 double myRho = -charge*myH[2]/PtGev;
761 TCL::ucopy(TH.Pos(),myX,3);
762 TCL::ucopy(TH.Dir(),myD,3);
767 double s2 = T3.Path(myX);
769 const double *pos = T3.Pos();
770 printf(
"Helix.X = %g %g %g\n",myX[0],myX[1],myX[2]);
771 printf(
"RKuta.X = %g %g %g\n",pos[0],pos[1],pos[2]);
772 printf (
"Charge = %d S1,S2 = %g %g \n",charge,s1,s2);
777 void TRungeKutta::Test3()
780 double PtGev = 3.,Curv = 1./100, Hz = PtGev*Curv;
781 double HZ[3] = {0,0,Hz};
782 double Pbeg[3],Xbeg[3]={0},Pend[3];
784 double X[200],Y[200],Z[200],A[200];
786 TVector3 PbegV(PtGev,0,PtGev/3*4);
787 PbegV.RotateZ(gRandom->Rndm()*3.1415*2); PbegV.GetXYZ(Pbeg);
788 TVector3 XbegV(Xbeg);
792 double r1 =gRandom->Rndm(),r2 =gRandom->Rndm();
793 magV.RotateX(r1); magV.RotateY(r2); magV.GetXYZ(Mag);
795 double stp = 3.1415/180/10;
797 double myMax = -999, myMin=999;
799 for (
int jk=-1;jk<nJk;jk++) {
803 TCL::ucopy(TR0.Mom(),Pend,3);
806 X[jk] = (Pend[0]-Plst[0])/stp;
807 Y[jk] = (Pend[1]-Plst[1])/stp;
808 Z[jk] = (Pend[2]-Plst[2])/stp;
809 if (myMax<X[jk]) myMax=X[jk];
810 if (myMax<Y[jk]) myMax=Y[jk];
811 if (myMax<Z[jk]) myMax=Z[jk];
812 if (myMin>X[jk]) myMin=X[jk];
813 if (myMin>Y[jk]) myMin=Y[jk];
814 if (myMin>Z[jk]) myMin=Z[jk];
817 TCL::ucopy(Pend,Plst,3);
820 static TGraph *Gx=0,*Gy=0,*Gz=0;
821 static TCanvas *myCanvas=0;
822 delete Gx;
delete Gy;
delete Gz;
delete myCanvas;
823 Gx =
new TGraph(nJk,A,X); Gx->SetLineColor(kRed );Gx->SetMarkerColor(kRed );
824 Gy =
new TGraph(nJk,A,Y); Gy->SetLineColor(kBlue );Gy->SetMarkerColor(kBlue );
825 Gz =
new TGraph(nJk,A,Z); Gz->SetLineColor(kGreen);Gz->SetMarkerColor(kGreen);
829 Gx->SetMaximum(myMax); Gx->SetMinimum(myMin);
830 Gy->SetMaximum(myMax); Gy->SetMinimum(myMin);
831 Gz->SetMaximum(myMax); Gz->SetMinimum(myMin);
833 myCanvas =
new TCanvas(
"TRungeKutta__Test3",
"",600,800);
838 myCanvas->Modified();
840 while(!gSystem->ProcessEvents()){gSystem->Sleep(200);};
844 void TRungeKutta::TestBak()
847 double PtGev = 3.,Curv = 1./100, Hz = PtGev*Curv;
848 TVector3 PbegV(PtGev,0,PtGev/3*4);
849 PbegV.RotateZ(gRandom->Rndm()*3.1415*2);
850 TVector3 XbegV(10,20,30),X1endV,P1endV;
854 TVector3 magV(0.,0.,Hz);
855 double r1 =gRandom->Rndm(),r2 =gRandom->Rndm();
856 magV.RotateX(r1); magV.RotateY(r2);
857 PbegV.RotateX(r1); PbegV.RotateY(r2);
861 for (
int ichar=-1; ichar<=1; ichar +=2) {
862 auto DbegV = PbegV.Unit();
863 TRungeKutta TR0(ichar,(
double*)&XbegV[0],(
double*)&PbegV[0],&myMag);
865 TVector3 P0endV,X0endV,D0endV;
866 TVector3 P1endV,X1endV,D1endV;
869 TR0.Eval(0,&X0endV[0],&P0endV[0]);
870 D0endV = P0endV.Unit();
873 TRungeKutta TR1(ichar,(
double*)&XbegV[0],(
double*)&PbegV[0],&myMag);
876 TR1.Print(
"Negativ");
879 TR1.Eval(0,&X1endV[0],&P1endV[0]);
880 D1endV = P1endV.Unit();
882 TVector3 dif = X1endV-X0endV;
883 for (
int i=0;i<3;i++) {
884 printf(
"X[%d] = %g \t%g \t%g\n",i,X0endV[i],X1endV[i],dif[i]);
887 for (
int i=0;i<3;i++) {
888 printf(
"D[%d] = %g \t%g \t%g\n",i,D0endV[i],D1endV[i],dif[i]);
890 static const char* dp[5] = {
"U",
"V",
"Fita",
"Lama",
"Pinv"};
892 for (
int i=0;i<5;i++) {
893 for (
int j=0;j<5;j++) {
894 printf(
"Der[%s][%s] = %g \t%g \t%g\n",dp[i],dp[j]
895 ,totDer0[i][j],totDer1[i][j]
896 ,totDer1[i][j]-totDer0[i][j]);
905 void TRungeKutta::TestDer()
908 double PtGev = 3.,Curv = 1./100, Hz = PtGev*Curv;
909 double tkSys[2][4][3]={{{0}}};
910 TVector3 PbegV(PtGev,0,PtGev/3*4);
911 PbegV.RotateZ(gRandom->Rndm()*3.1415*2);
912 TVector3 XbegV(10,20,30),X1endV,P1endV;
916 TVector3 magV(0.,0.,Hz);
917 double r1 =gRandom->Rndm(),r2 =gRandom->Rndm();
918 magV.RotateX(r1); magV.RotateY(r2);
927 for (
int ichar=-1; ichar<=1; ichar +=2) {
928 double Pinv = -ichar/PbegV.Mag();
929 auto DbegV = PbegV.Unit();
930 TRungeKutta TR0(ichar,(
double*)&XbegV[0],(
double*)&PbegV[0],&myMag);
931 TVector3 PendV,XendV,DendV;
934 TCL::ucopy(TR0.Dir(),tkSys[1][kKT],3);
935 TR0.Eval(0,&XendV[0],&PendV[0]);
936 DendV = PendV.Unit();
938 TCL::ucopy(totDer.TkDir(0)[0],tkSys[0][0],2*4*3);
942 static const char* dp[5] = {
"U",
"V",
"Fita",
"Lama",
"Pinv"};
943 for (
int J=0;J<5;J++) {
945 printf(
"\nTest d/d%s\n\n",dp[J]);
946 for (
int i=0;i<5;i++) {der[i] = totDer[i][J];}
950 TVector3 D1begV = DbegV;
951 TVector3 X1begV = XbegV;
952 if (J<2) { X1begV += TVector3(tkSys[0][kKU+J ])*delta;}
953 else if (J<4) { D1begV += TVector3(tkSys[0][kKU+J-2])*delta;}
954 else { P1inv += delta ;}
956 auto P1begV = D1begV; P1begV*=(1./fabs(P1inv));
957 TRungeKutta TR1(ichar,(
double*)&X1begV[0],(
double*)&P1begV[0],&myMag);
958 TR1.Eval(L,&X1endV[0],&P1endV[0]);
959 auto D1endV = P1endV.Unit();
961 TVector3 difX = X1endV-XendV;
962 TVector3 difD = D1endV-DendV;
963 for (
int j=0;j<5;j++) {
964 if (j<2) { U1endV[j] = difX.Dot(TVector3(tkSys[1][kKU+j ]));}
965 else if (j<4) { U1endV[j] = difD.Dot(TVector3(tkSys[1][kKU+j-2]));}
966 else { U1endV[4] = -ichar/P1endV.Mag()-Pinv ;}
969 TVectorD dif = U1endV;
971 double pct=0;
int ipct=-1;
972 for (
int i=0;i<5;i++) {
973 if (fabs(dif[i])<1e-2) dif[i] = 0;
974 if (fabs(der[i])<1e-2) der[i] = 0;
975 double bott = 0.5*(fabs(dif[i])+fabs(der[i]));
976 if (bott<1e-3)
continue;
977 double myPct = (dif[i]-der[i])/bott;
978 if (fabs(myPct)<fabs(pct))
continue;
979 pct = myPct; ipct = i;
981 if (pct >0.2) printf(
"################################ [%d] = %d%% \n",ipct,
int(pct*100));
982 dif.Print(
"NUMERIC ");
983 der.Print(
"ANALITIC");
984 totDif+= (dif-der).Norm1();
987 printf (
"========> TotalDiff = %g\n",totDif);
992 static double myDif(TVectorD &a,TVectorD &b,
int &idx)
995 int n = a.GetNrows();
996 double dif=0; idx = -1;
997 for (
int i=0;i<n;i++) {
998 double mydif = fabs(a[i])+fabs(b[i]);
999 if (mydif<1e-4)
continue;
1000 mydif = fabs(a[i]-b[i])/mydif;
1001 if (mydif <= dif)
continue;
1002 dif = mydif; idx = i;
1007 void TRungeKutta::TestDer2()
1011 double Ptot = 5, Pt=3;
1013 double curv = 1./30,Hz = Pt*curv;
1014 TVector3 XbegV = TVector3(10,20,30);
1015 TVector3 PbegV = TVector3(Pt,0,Pt/3*4);
1016 double HZ[3] = {0,0,Hz};
1022 TVector3 magV(HZ); magV.GetXYZ(Mag );
1024 double r1=gRandom->Rndm(),r2=gRandom->Rndm();
1025 magV.RotateX(r1); magV.RotateY(r2); magV.GetXYZ(Mag );
1026 PbegV.RotateX(r1); PbegV.RotateY(r2);
1027 XbegV.RotateX(r1); XbegV.RotateY(r2);
1030 TestMag myMag((
double*)&magV[0]);
1036 printf(
"===============PbegV:= \n"); PbegV.Print(
"");
1038 TVector3 XendV,PendV;
1040 for (
int ichar=-1; ichar<=1; ichar +=2) {
1041 TRungeKutta TR0(ichar,(
double*)&XbegV[0],(
double*)&PbegV[0],&myMag);
1046 TR0.Eval(0,&XendV[0],&PendV[0]);
1047 auto DendV = PendV.Unit();
1049 TVector3 UbegV(myDer->TkDir(0)[kKU]);
1050 TVector3 VbegV(myDer->TkDir(0)[kKV]);
1051 TVector3 TbegV(myDer->TkDir(0)[kKT]);
1053 TVector3 UendV(myDer->TkDir(1)[kKU]);
1054 TVector3 VendV(myDer->TkDir(1)[kKV]);
1055 TVector3 TendV(myDer->TkDir(1)[kKT]);
1056 assert((DendV-TendV).Mag()<1e-3);
1060 static const char* dp[5] = {
"U",
"V",
"Fita",
"Lama",
"Pinv"};
1061 for (
int J=0;J<5;J++) {
1063 printf(
"\nTest dFit/d%s\n\n",dp[J]);
1064 for (
int i=0;i<5;i++) {der[i] = (*myDer)[i][J];}
1067 TRungeKutta TR1(ichar,(
double*)&XbegV[0],(
double*)&PbegV[0],&myMag);
1069 TVector3 P1begV(TR1.Mom());
1070 TVector3 X1begV(TR1.Pos());
1072 THelix3d::MakeTkDir((
double*)&P1begV[0],Mag,myTkDir);
1073 double eps = (TVectorD(9,myTkDir[0])-TVectorD(9,myDer->TkDir(0)[0])).NormInf();
1078 double delta = 1e-6;
1079 TVector3 X1endV,P1endV;
1080 assert(TR0.Pinv()*ichar>0);
1081 assert(TR1.Pinv()*ichar>0);
1084 X1begV += UbegV*delta;
1088 X1begV += VbegV*delta;
1092 double Pinv1 = TR1.Pinv()+delta;
1093 double Ptot1 = fabs(1./Pinv1);
1094 P1begV.SetMag(Ptot1);
1098 P1begV+=VbegV*(Ptot*delta); P1begV.SetMag(Ptot);
1103 P1begV+=UbegV*(Ptot*delta); P1begV.SetMag(Ptot);
1106 default: assert(0 &&
"Wrong J");
1108 TR1.Set(0,(
double*)&X1begV[0],(
double*)&P1begV[0]);
1109 assert(TR1.Pinv()*ichar>0);
1110 TR1.Eval(-L,&X1endV[0],&P1endV[0]);
1112 TVector3 difX = X1endV-XendV;
1113 TVector3 difD = (P1endV.Unit()-PendV.Unit());
1114 dif[kU] = difX.Dot(UendV);
1115 dif[kV] = difX.Dot(VendV);
1116 dif[kPinv] = TR1.Pinv()-TR0.Pinv();
1117 dif[kFita] = difD.Dot(UendV);
1118 dif[kLama] = difD.Dot(VendV);
1121 assert(fabs(dif.NormInf())<1.);
1125 double maxa = myDif(dif,der,idx);
1127 if (maxa>1e-1) printf(
"########################[%d]= %g\n",idx,maxa);
1128 der.Print(
"ANALITIC");
1129 dif.Print(
"NUMERIC ");
1136 double PtGev = 3.,Curv = 1./100, Hz = PtGev*Curv;
1137 double HZ[3] = {0,0,Hz};
1138 double Pbeg[3],P1beg[3],Xbeg[3]={0},X1beg[3];
1139 double Pend[3],P1end[3],Xend[3] ,X1end[3];
1140 double L = 300.;
int nL = 1;
1144 static TCanvas *myCanvas[kNCanvs] = {0};
1145 static int myDiv[] = {2,5,5,5,5,0};
1146 for (
int ic = 0;myDiv[ic];ic++) {
1147 if (myDiv[ic]<0)
continue;
1148 TString ts(
"C"); ts+=ic;
1149 if (!myCanvas[ic]) myCanvas[ic] =
new TCanvas(ts.Data(),ts.Data(),600,800);
1150 myCanvas[ic]->Clear();myCanvas[ic]->Divide(1,myDiv[ic]);
1152 static TH1F *hXi2[2] = {0};
1153 for (
int jk=0;jk<2;jk++) {
1154 TString ts(
"Xi2_"); ts += jk;
1156 hXi2[jk]=
new TH1F(ts.Data(),ts.Data(),50,0,50);
1157 myCanvas[0]->cd(jk+1); hXi2[jk]->Draw();
1160 static TH1F * hh[5]={0};
1161 for (
int ih=0;ih<myDiv[1];ih++) {
1162 static const char *tit[5]={
"U",
"V",
"Fita",
"Lama",
"Pinv"};
1164 hh[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1165 myCanvas[1]->cd(ih+1); hh[ih]->Draw();
1168 static TH1F * hrt[5]={0};
1169 for (
int ih=0;ih<myDiv[1];ih++) {
1170 static const char *tit[5]={
"rU",
"rV",
"rFita",
"rLama",
"rPinv"};
1172 hrt[ih] =
new TH1F(tit[ih],tit[ih],100,-10,+10);
1173 myCanvas[2]->cd(ih+1); hrt[ih]->Draw();
1176 static TH1F * hcr[10]={0};
1178 static const char *tit[]={
"UV",
"UF",
"VF",
"UL",
"VL",
"FL",
"UP",
"VP",
"FP",
"LP"};
1179 for (
int ih=0;ih<10;ih++) {
1181 hcr[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1182 if (ih<5) myCanvas[3]->cd(ih+1 );
1183 else myCanvas[4]->cd(ih+1-5);
1188 TVector3 PbegV(PtGev,0,PtGev/3*4);
1189 double Ptot = PbegV.Mag();
1190 PbegV.RotateZ(gRandom->Rndm()*3.1415*2); PbegV.GetXYZ(Pbeg);
1191 TVector3 XbegV(Xbeg);
1193 double Mag[3]={HZ[0],HZ[1],HZ[2]};
1195 double r1 = gRandom->Rndm(),r2 = gRandom->Rndm();
1196 magV.RotateX(r1); magV.RotateY(r2); magV.GetXYZ(Mag);
1197 PbegV.RotateX(r1); PbegV.RotateY(r2); PbegV.GetXYZ(Pbeg);
1201 dia[kU]= 0.1; dia[kV]= 0.2; dia[kPinv]= 0.1/Ptot, dia[kFita]= 1./360; dia[kLama]= 2./360;
1202 for(
int jk=0;jk<5;jk++) {dia[jk]*=dia[jk];}
1204 auto &EMX = RV.GetMtx();
1205 auto &val = RV.GetLam();
1210 double Gbeg[15],GbegD[5];
1211 for (
int i=0,li=0;i< 5;li+=++i) {
1212 GbegD[i] = sqrt(EMX[i][i]);
1213 for (
int j=0;j<=i;j++) {
1214 Gbeg[li+j] = EMX[i][j];
1224 for (
int split=0;split<nL;split++) {
1227 double tkDir[3][3],tkDirE[3][3];
1228 memcpy(tkDir[0] ,TH0.TkDir(0)[0],
sizeof(tkDir ));
1229 memcpy(tkDirE[0],TH0.TkDir(1)[0],
sizeof(tkDirE));
1231 TH0.
Eval(0,Xend,Pend);
1232 auto *myEmx = TH0.Emx();
1233 const double *Gend = *myEmx;
1235 for (
int i=0,li=0;i< 5;li+=++i) {
1236 GendD[i] = sqrt(Gend[li+i]);
1244 TVector3 PendV(Pend),XendV(Xend);
1246 for (
int j=0;j<3;j++) { UendV[j+2]=Pend[j];}
1249 int nIter = 1000000;
1250 for (
int iter=0;iter<nIter;iter++) {
1251 TVectorD delta = RV.Gaus();
1253 TCL::trasat(delta.GetMatrixArray(),GbegI,&chi2,1,5);
1255 hXi2[0]->Fill(chi2);
1257 for (
int ih=0;ih<myDiv[1];ih++) { hrt[ih]->Fill(delta[ih]/GbegD[ih]);}
1258 double Pinv = -charge/PbegV.Mag(),P1inv = Pinv;
1259 TVector3 P1begV = PbegV,D1begV = P1begV.Unit();
1260 TVector3 X1begV = XbegV;
1261 for (
int i=0;i<5;i++) {
1262 if (i<2) { X1begV += TVector3(tkDir[kKU+i ])*delta[i];}
1263 else if (i<4) { D1begV += TVector3(tkDir[kKU+i-2])*delta[i];}
1264 else { P1inv += delta[kPinv]; ;}
1266 X1begV.GetXYZ(X1beg);
1267 P1begV = D1begV*(1./fabs(P1inv));
1268 P1begV.GetXYZ(P1beg);
1273 double s = TH1.
Path(Xend);
1275 TH1.
Eval(0,X1end,P1end);
1276 TVector3 X1endV(X1end),P1endV(P1end);
1278 TVector3 difX = X1endV-XendV;
1279 TVector3 difD = P1endV.Unit()-PendV.Unit();
1280 for (
int j=0;j<5;j++) {
1281 if (j<2) { U1endV[j] = difX.Dot(TVector3(tkDirE[kKU+j ]));}
1282 else if (j<kPinv) { U1endV[j] = difD.Dot(TVector3(tkDirE[kKU+j-2]));}
1283 else { U1endV[4] = -charge/P1endV.Mag()-Pinv ;}
1286 for (
int ih=0;ih<5;ih++) { hh[ih]->Fill(U1endV[ih]/GendD[ih]);}
1287 TCL::trasat(U1endV.GetMatrixArray(),GendI,&chi2,1,5);
1288 hXi2[1]->Fill(chi2);
1290 for (
int i=0,li=0;i<5;li+=++i) {
1291 for (
int j=0;j<=i;j++) {
1292 myG[li+j]+=U1endV[i]*U1endV[j];
1296 for (
int i=0,li=0;i<5;li+=++i) {
1297 for (
int j=0;j<i;j++) {
1298 double d = U1endV[i]*U1endV[j] - Gend[li+j];
1299 d/= GendD[i]*GendD[j];
1308 TCL::vscale(myG,1./nIter,myG,15);
1310 printf(
"Numerical vs Analitical Error matrices:\n");
1311 for (
int i=0,li=0;i<5;li+=++i) {
1312 for (
int j=0;j<=i;j++) {
1313 printf(
"\t%g ",myG[li+j]);
1316 for (
int j=0;j<=i;j++) {
1317 printf(
"\t%g ",Gend[li+j]);
1322 for (
int i=0,li=0;i<5;li+=++i) {
1323 for (
int j=0;j<=i;j++) {
1324 printf(
"\t%g ",Gend[li+j]/(GendD[i]*GendD[j]));
1327 for (
int j=0;j<=i;j++) {
1328 printf(
"\t%g ",myG[li+j]/ (GendD[i]*GendD[j]));
1335 for (
int i=0;myCanvas[i];i++) {
1336 if (!myCanvas[i])
continue;
1337 myCanvas[i]->Modified();myCanvas[i]->Update();}
1339 while(!gSystem->ProcessEvents()){gSystem->Sleep(200);};
1343 void TRungeKutta::TestErr2(
int charge)
1345 double PtGev = 1.,Curv = 1./100, Hz = PtGev*Curv;
1346 double HZ[3] = {0,0,Hz};
1347 double Pbeg[3],P1beg[3],Xbeg[3]={0},X1beg[3];
1348 double Pend[3],P1end[3],Xend[3] ,X1end[3];
1352 static TCanvas *myCanvas[kNCanvs] = {0};
1353 static int myDiv[] = {2,5,5,5,5,0};
1354 for (
int ic = 0;myDiv[ic];ic++) {
1355 if (myDiv[ic]<0)
continue;
1356 TString ts(
"C"); ts+=ic;
1357 if (!myCanvas[ic]) myCanvas[ic] =
new TCanvas(ts.Data(),ts.Data(),600,800);
1358 myCanvas[ic]->Clear();myCanvas[ic]->Divide(1,myDiv[ic]);
1360 static TH1F *hXi2[2] = {0};
1361 for (
int jk=0;jk<2;jk++) {
1362 TString ts(
"Xi2_"); ts += jk;
1364 hXi2[jk]=
new TH1F(ts.Data(),ts.Data(),50,0,0);
1365 myCanvas[0]->cd(jk+1); hXi2[jk]->Draw();
1368 static TH1F * hh[5]={0};
1369 for (
int ih=0;ih<myDiv[1];ih++) {
1370 const char * tit[]={
"U",
"V",
"Pinv",
"Fita",
"Lama",0};
1372 hh[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1373 myCanvas[1]->cd(ih+1); hh[ih]->Draw();
1376 static TH1F * hrt[5]={0};
1377 for (
int ih=0;ih<myDiv[1];ih++) {
1378 const char * tit[]={
"U0",
"V0",
"Pinv0",
"Fita0",
"Lama0",0};
1380 hrt[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1381 myCanvas[2]->cd(ih+1); hrt[ih]->Draw();
1384 static TH1F * hcr[10]={0};
1386 static const char *tit[]={
"UV",
"UP",
"VP",
"UL",
"VL",
"PL",
"UF",
"VF",
"PF",
"LF"};
1387 for (
int ih=0;ih<10;ih++) {
1389 hcr[ih] =
new TH1F(tit[ih],tit[ih],100,0,0);
1390 if (ih<5) myCanvas[3]->cd(ih+1 );
1391 else myCanvas[4]->cd(ih+1-5);
1396 TVector3 PbegV(PtGev,0,PtGev*3);
1397 double Ptot = PbegV.Mag();
1398 PbegV.RotateZ(gRandom->Rndm()*3.1415*2); PbegV.GetXYZ(Pbeg);
1399 TVector3 XbegV(Xbeg);
1403 double Mag[3]={HZ[0],HZ[1],HZ[2]};
1406 double r1 = gRandom->Rndm(),r2 = gRandom->Rndm();
1407 magV.RotateX(r1); magV.RotateY(r2); magV.GetXYZ(Mag);
1408 PbegV.RotateX(r1); PbegV.RotateY(r2); PbegV.GetXYZ(Pbeg);
1415 dia[kU]= 0.1; dia[kV]= 0.2; dia[kPinv]= 0.1/Ptot; dia[kFita]= 1./360; dia[kLama]= 2./360;
1418 auto &EMX = RV.GetMtx();
1419 auto &val = RV.GetLam();
1424 double Gbeg[15],GbegD[5];
1425 for (
int i=0,li=0;i< 5;li+=++i) {
1426 GbegD[i] = sqrt(EMX[i][i]);
1427 for (
int j=0;j<=i;j++) {
1428 Gbeg[li+j] = EMX[i][j];
1442 memcpy(Gbeg,*TH0i.Emx(),
sizeof(Gbeg));
1450 double tkDir[3][3],tkDirE[3][3];
1451 memcpy(tkDir[0] ,TH0.TkDir(0)[0],
sizeof(tkDir ));
1452 memcpy(tkDirE[0],TH0.TkDir(1)[0],
sizeof(tkDirE));
1454 TH0.Eval(0,Xend,Pend);
1455 auto *myEmx = TH0.Emx();
1456 const double *Gend = *myEmx;
1458 for (
int i=0,li=0;i< 5;li+=++i) {
1459 GendD[i] = sqrt(Gend[li+i]);
1465 TVector3 PendV(Pend),XendV(Xend);
1467 for (
int j=0;j<3;j++) { UendV[j+2]=Pend[j];}
1470 int nIter = 1000000;
1471 for (
int iter=0;iter<nIter;iter++) {
1472 TVectorD delta = RVi.Gaus();
1474 TCL::trasat(delta.GetMatrixArray(),GbegI,&chi2,1,5);
1476 hXi2[0]->Fill(chi2);
1478 for (
int ih=0;ih<myDiv[1];ih++) { hrt[ih]->Fill(delta[ih]/GbegD[ih]);}
1479 TVector3 P1begV(TH0i.Mom());
1480 TVector3 X1begV(TH0i.Pos());
1482 X1begV += TVector3(tkDir[kKU])*delta[kU];
1483 X1begV += TVector3(tkDir[kKV])*delta[kV];
1484 double Pinv = TH0i.Pinv();
1485 double Pinv1 = Pinv + delta[kPinv];
1486 double Ptot1 = fabs(1./Pinv1);
1487 P1begV.SetMag(Ptot1);
1488 P1begV += TVector3(tkDir[kKV])*(delta[kLama]*Ptot1);P1begV.SetMag(Ptot1);
1489 P1begV += TVector3(tkDir[kKU])*(delta[kFita]*Ptot1);P1begV.SetMag(Ptot1);
1491 X1begV.GetXYZ(X1beg);
1492 P1begV.GetXYZ(P1beg);
1493 TRungeKutta TH1(TH0i.Charge(),X1beg,P1beg,&myMag);
1495 TH1.Eval(0,X1end,P1end);
1496 TVector3 X1endV(X1end),P1endV(P1end);
1498 TVector3 difX = X1endV-XendV;
1499 TVector3 difD = (P1endV.Unit()-PendV.Unit());
1501 U1endV[kU] = difX.Dot(TVector3(tkDirE[kKU]));
1502 U1endV[kV] = difX.Dot(TVector3(tkDirE[kKV]));
1503 U1endV[kFita] = difD.Dot(TVector3(tkDirE[kKU]));
1504 U1endV[kLama] = difD.Dot(TVector3(tkDirE[kKV]));
1505 U1endV[kPinv] = (Pinv1-Pinv);
1507 for (
int ih=0;ih<5;ih++) { hh[ih]->Fill(U1endV[ih]/GendD[ih]);}
1508 TCL::trasat(U1endV.GetMatrixArray(),GendI,&chi2,1,5);
1509 hXi2[1]->Fill(chi2);
1511 for (
int i=0,li=0;i<5;li+=++i) {
1512 for (
int j=0;j<=i;j++) {
1513 myG[li+j]+=U1endV[i]*U1endV[j];
1517 for (
int i=0,li=0;i<5;li+=++i) {
1518 for (
int j=0;j<i;j++) {
1519 double d = U1endV[i]*U1endV[j] - Gend[li+j];
1520 d/= GendD[i]*GendD[j];
1525 TCL::vscale(myG,1./nIter,myG,15);
1527 printf(
"Numerical vs Analitical Error matrices:\n");
1528 for (
int i=0,li=0;i<5;li+=++i) {
1529 for (
int j=0;j<=i;j++) {
1530 printf(
"\t%g ",myG[li+j]);
1533 for (
int j=0;j<=i;j++) {
1534 printf(
"\t%g ",Gend[li+j]);
1540 for (
int i=0;myCanvas[i];i++) {
1541 if (!myCanvas[i])
continue;
1542 myCanvas[i]->Modified();myCanvas[i]->Update();}
1544 while(!gSystem->ProcessEvents()){gSystem->Sleep(200);};
1548 void TRungeKutta::TestSign()
1551 double PtGev = 3.,Rho = 1./100, Hz = PtGev*Rho ;
1552 double ZER[3]= {0,0,0};
1553 double HZ[3] = {0,0,Hz};
1554 double PZ[3] = {PtGev,0,PtGev*4./3};
1556 for (
int charge = -1 ;charge<=1;charge +=2 ) {
1557 for (
double L =-100 ;L<=100 ;L +=200) {
1558 for (
int ih =-1 ;ih<=1 ;ih +=2 ) {
1559 HZ[2] = fabs(HZ[2])*ih;
1561 double curv = -(HZ[2]*charge)/PtGev;
1571 printf(
"charge = %d \tL = %g , THelixTreack \tX=%g \tY=%g \tZ=%g \tDx=%g \tDy=%g \tDz=%g\n"
1572 , charge,L,th.Pos()[0],th.Pos()[1],th.Pos()[2]
1573 , th.Dir()[0],th.Dir()[1],th.Dir()[2]);
1574 printf(
"charge = %d \tL = %g , THelix3d \tX=%g \tY=%g \tZ=%g \tDx=%g \tDy=%g \tDz=%g\n"
1575 , charge,L,t3.Pos()[0],t3.Pos()[1],t3.Pos()[2]
1576 , t3.Dir()[0],t3.Dir()[1],t3.Dir()[2]);
1577 printf(
"charge = %d \tL = %g , TRungeKutta \tX=%g \tY=%g \tZ=%g \tDx=%g \tDy=%g \tDz=%g\n"
1578 , charge,L,tr.Pos()[0],tr.Pos()[1],tr.Pos()[2]
1579 , tr.Dir()[0],tr.Dir()[1],tr.Dir()[2]);
double Move()
Move to point founded before.
double Eval(double step, double xyz[3]=0, double mom[3]=0) const
Evaluate params with given step along helix.
double Dca(double x, double y, double *dcaErr=0) const
DCA to given 2dim point (with error matrix)
static void TestErr(int charge=1)
void Backward()
Change direction.
static float * trsinv(const float *g, float *gi, int n)
static float * trasat(const float *a, const float *s, float *r, int m, int n)
double Move(double step)
Move along track.
double Path(const double point[3], int idir=0, int ndca=3) const