23 #include "genFitDca.h"
30 double *Arr(TVector3 &v) {
return (
double*)&v[0];}
32 double EmxSign(
int n,
const double *a);
33 double DOT2(
const TVector3 A,
const TVector3 B) {
return A[0]*B[0]+A[1]*B[1];}
38 StDcaGenFit::StDcaGenFit()
40 memset(mBeg,0,mEnd-mBeg+1);
44 StDcaGenFit::~StDcaGenFit() {}
47 TVector3 StDcaGenFit::origin()
const
51 return TVector3(x,y,
mZ);
55 TVector3 StDcaGenFit::momentum()
const
58 double x = ptt*cos(
mPsi);
59 double y = ptt*sin(
mPsi);
61 return TVector3(x,y,z);
65 void StDcaGenFit::set(
const float pars[kNMinPars],
const float errs[kNMinErrs])
67 if (pars) memcpy(&
mImp ,pars,
sizeof(
float)*kNMinPars );
68 if (errs) memcpy(&
mImpImp,errs,
sizeof(
float)*kNMinErrs);
71 void StDcaGenFit::set(
const double pars[kNMinPars],
const double errs[kNMinErrs])
73 if (pars) TCL::ucopy(pars, &
mImp, 6);
74 if (errs) TCL::ucopy(errs, &
mImpImp, kNMinErrs);
78 ostream& operator<<(ostream& os,
const StDcaGenFit& dca) {
79 const Float_t *errMx = dca.errMatrix();
80 return os << Form(
"Dca: imp %7.2f +/-%7.2f, Z:%7.2f +/-%7.2f, psi:%7.2f +/-%7.2f, pT/q:%7.2f +/-%6.1f%%, TanL:%8.3f +/-%8.3f",
81 dca.impact(), (errMx[0] >= 0) ? sqrt(errMx[0]) : -13,
82 dca.z(), (errMx[2] >= 0) ? sqrt(errMx[2]) : -13,
83 dca.psi(), (errMx[5] >= 0) ? sqrt(errMx[5]) : -13,
84 dca.charge()*dca.pt(), (errMx[9] >= 0 && dca.pt() > 0) ? 100*sqrt(errMx[9])*dca.pt() : -13,
85 dca.tanDip(), (errMx[14] >= 0) ? sqrt(errMx[14]): -13);
88 void StDcaGenFit::Print(
const char *)
const {cout << *
this << endl;}
92 TCL::vzero(mH,3+3+3*3);
97 memset((
char*)&mqPinv,0,(
char*)&mSig+
sizeof(mSig)-(
char*)&mqPinv);
102 memset((
char*)&qPqP,0,(
char*)&VV+
sizeof(VV)-(
char*)&qPqP);
105 void GFull::SetMag(
const double h[3])
106 { memcpy(mGlob.mH,h,
sizeof(mGlob.mH));}
109 void GFull::SetGlob(
const double pos[3],
const double uvn[3][3])
111 memcpy(mGlob.mPos, pos,
sizeof(mGlob.mPos));
112 memcpy(mGlob.mUVN[0],uvn[0],
sizeof(mGlob.mUVN));
113 for (
int i=0;i<3;i++) {
114 for (
int k=0;k<3;k++) {
115 double tmp = TCL::vdot(mGlob.mUVN[i],mGlob.mUVN[k],3);
117 assert(fabs(tmp)<1e-6);
121 void GFull::SetPars(
double qpinv,
double uc,
double vc,
double u,
double v,
int sig)
123 mPars.SetPars(qpinv,uc,vc,u,v,sig);
127 void GFitPars::SetPars(
double qpinv,
double uc,
double vc,
double u,
double v,
int sig)
132 mNc = 1-(mUc*mUc+mVc*mVc); mNc = (mNc<0)? 0:sqrt(mNc)*sig;
140 void GFull::SetPars(
const double pars[kNMinPars] ,
int sig)
142 SetPars( pars[0],pars[1],pars[2],pars[3],pars[4],sig);
145 TVectorD GFull::GetPars(
int* iSig)
const
147 TVectorD v(kNMinPars);
148 v[0] = mPars.mqPinv ;
153 if (iSig) *iSig = mPars.mSig;
157 void GFull::SetPars(
int icharge,
const TVector3 pos,
const TVector3 mom)
159 TVector3 XlocV = pos-TVector3(mGlob.mPos);
160 double pars[kNMinPars];
161 pars[0] = icharge/mom.Mag();
162 pars[1] = mom.Unit().Dot(TVector3(mGlob.mUVN[0]));
163 pars[2] = mom.Unit().Dot(TVector3(mGlob.mUVN[1]));
164 double tmp = mom.Unit().Dot(TVector3(mGlob.mUVN[2]));
165 int iSig = (tmp<0) ? -1:1;
166 pars[3] = XlocV.Dot(TVector3(mGlob.mUVN[0]));
167 pars[4] = XlocV.Dot(TVector3(mGlob.mUVN[1]));
168 tmp = XlocV.Dot(TVector3(mGlob.mUVN[2]));
169 assert(fabs(tmp) <1e-5);
175 void GFull::SetBigPars(
int icharge,
const TVector3 Pos,
const TVector3 Mom)
177 mBigPars[kqPtInv] = icharge/Mom.Mag()/CosL();
178 double tau = -DOT2(Pos,Mom)/DOT2(Mom,Mom);
179 TVector3 pos = Pos + tau*Mom;
181 for (
int i=0;i<3;i++) {
182 mBigPars[kDirX+i] = Mom.Unit()[i];
183 mBigPars[kPosX+i] = pos[i];
187 void GFull::MakeTrak()
189 mqPinv = mPars.mqPinv;
191 TCL::ucopy(&mPars.mUc,uc,2);
192 uc[2] = 1.-(uc[0]*uc[0]+uc[1]*uc[1]);
194 if (uc[2]<1e-6) uc[2] = 0.;
195 uc[2] = sqrt(uc[2])*mPars.mSig;
197 mDir = TVector3(mGlob.mUVN[0])*uc[0];
198 mDir+= TVector3(mGlob.mUVN[1])*uc[1];
199 mDir+= TVector3(mGlob.mUVN[2])*uc[2];
200 assert(fabs(mDir.Mag()-1)<1e-5);
202 mPos= TVector3(mGlob.mPos);
203 mPos+= TVector3(mGlob.mUVN[0])*mPars.mU;
204 mPos+= TVector3(mGlob.mUVN[1])*mPars.mV;
205 mPos+= TVector3(mGlob.mUVN[2])*mPars.mN;
209 void GFull::SetErrs(
const double emx[kNMinErrs])
214 double sig=EmxSign(kNMinPars,emx);
218 for (
int i=0,li=0;i< kNMaxPars;li+=++i) {
219 if (i == kNc)
continue;
220 for (
int j = 0;j<=i;j++) {
221 if (j == kNc)
continue;
227 double Nc = mPars.mNc;
228 if (Nc<0.01) Nc = 0.01;
230 double Uc = mPars.mUc,Vc = mPars.mVc;
231 E.qPNc =-(E.qPUc*Uc + E.qPVc*Vc)/Nc;
232 E.UcNc =-(E.UcUc*Uc + E.UcVc*Vc)/Nc;
233 E.VcNc =-(E.UcVc*Uc + E.VcVc*Vc)/Nc;
234 E.NcNc = (E.UcUc*Uc*Uc + E.VcVc*Vc*Vc + 2*E.UcVc*Uc*Vc)/(Nc*Nc);
235 E.NcU =-(E.UcU*Uc + E.VcU*Vc )/Nc;
236 E.NcV =-(E.UcV*Uc + E.VcV*Vc )/Nc;
239 double sig=EmxSign(kNMaxPars,e);
240 assert(fabs(sig)<1e-6);
244 TVector3 GFull::Pos()
const
247 TCL::vmatr(&mPars.mU,mGlob.mUVN[0],xx,3,3);
248 TCL::vadd(xx,mGlob.mPos,xx,3);
252 TVectorD GFull::BigVal()
const
254 TVectorD v(kNBigPars);
256 for (
int i=0;i<3;i++) {
257 v[kDirX+i] = Dir()[i];
258 v[kPosX+i] = Pos()[i];
264 double GFull::BigDer(
int ib,
int iu)
266 TVectorD A(kNBigPars),B(kNBigPars),C(kNBigPars);
267 double *U = &(mPars.mqPinv);
268 double delta = fabs(U[iu])*1e-2;
269 if (delta<1e-6) delta = 1e-6;
274 C = (B-A); C*=(1./delta);
276 double DdX = (A[kDirX]*C[kPosX]+A[kDirY]*C[kPosY]);
277 double XdD = (A[kPosX]*C[kDirX]+A[kPosY]*C[kDirY]);
278 double DD = (A[kDirX]*A[kDirX]+A[kDirY]*A[kDirY]);
279 double tau = -(DdX+XdD)/DD;
280 C[kPosX] += A[kDirX]*tau;
281 C[kPosY] += A[kDirY]*tau;
282 C[kPosZ] += A[kDirZ]*tau;
289 TVector3 GFull::Dir()
const
292 TCL::vmatr(&mPars.mUc,mGlob.mUVN[0],xx,3,3);
297 double GFull::SinL()
const
299 return Dir().CosTheta();
302 double GFull::CosL()
const
304 return Dir().Unit().Perp();
307 double GFull::TanL()
const
309 return Dir()[2]/Dir().Perp();
312 double GFull::Lam()
const
314 return atan2(Dir()[2],Dir().Perp());
317 double GFull::Psi()
const
322 double GFull::Pti()
const
324 return mPars.mqPinv/CosL();
327 double GFull::Pinv()
const
332 double GFull::Imp()
const
334 return -Pos()[0]*sin(Psi()) + Pos()[1]*cos(Psi());
339 TVector3 dir = Dir(),pos = Pos();
340 double tau = -DOT2(pos,dir)/DOT2(dir,dir);
342 dca.
mImp = (pos[0])*(-sin(Psi())) + (pos[1])*(cos(Psi()));
382 #define dDir_du(iX,iU) ((iU >2 )? 0:mGlob.mUVN[iU ][iX])
383 #define dPos_du(iX,iU) ((iU <3 || (iU>4))? 0:mGlob.mUVN[iU-3][iX])
384 double bigDers[kNBigPars][kNMaxPars] = {{0}};
385 double impDers[kNMinPars][kNBigPars] = {{0}};
387 TVector3 dir = Dir(),pos = Pos();
388 double cosl = CosL(), cos2l = cosl*cosl;
389 double cosp = cos(Psi()), sinp = sin(Psi());
390 double pinv = Pinv();
396 bigDers[kqPtInv][kqPinv] = 1./cosl;
398 double dCosIdX[3],x = dir[0],y = dir[1],z = dir[2],r2 = x*x+y*y,z2 = z*z,r=sqrt(r2),r4 = r2*r2;
399 dCosIdX[0] = -r*z2*x/r4; dCosIdX[1] = -r*z2*y/r4; dCosIdX[2] = r*r2*z/r4;
400 for (
int iu=0;iu<3;iu++) {
402 for (
int ix=0;ix<3;ix++) { sum += dCosIdX[ix]*dDir_du(ix,iu);}
403 bigDers[kqPtInv][kUc+iu] = pinv*sum;
407 for (
int ix=0;ix<3;ix++) {
408 for (
int iu=0;iu<3;iu++) {bigDers[kDirX+ix][kUc+iu]=dDir_du(ix,iu);}}
415 for (
int ix=0;ix<3;ix++) {
416 for (
int iu=0;iu<5;iu++) {
417 bigDers[kPosX+ix][kUc+iu] = dPos_du(ix,iu) - dir[ix]/cos2l*(
418 (pos[0]*dDir_du(0,iu) + pos[1]*dDir_du(1,iu))+
419 (dir[0]*dPos_du(0,iu) + dir[1]*dPos_du(1,iu)));}};
422 for (
int ix = 0; ix<kNBigPars;ix++) {
423 for (
int iu = 0; iu<kNMaxPars;iu++) {
424 printf(
"UUU(%d,%d) %g == %g\n",ix,iu,bigDers[ix][iu],BigDer(ix,iu));
430 TCL::trasat(bigDers[0],mErrs,mBigErrs,kNBigPars,kNMaxPars);
432 double tmp = EmxSign(kNMaxPars,mBigErrs);
433 assert(fabs(tmp)<1e-6);
436 impDers[kPsi][kDirX] = - dir[1]/cos2l;
437 impDers[kPsi][kDirY] = dir[0]/cos2l;
446 impDers[kImp][kPosX] =-sinp;
447 impDers[kImp][kPosY] = cosp;
448 impDers[kImp][kDirX] = (-pos[0]*cosp-pos[1]*sinp)*impDers[kPsi][kDirX];
449 impDers[kImp][kDirY] = (-pos[0]*cosp-pos[1]*sinp)*impDers[kPsi][kDirY];
451 impDers[kPti][kqPtInv] = 1;
453 impDers[kTan][kDirZ] = 1./(cos2l*cosl);
454 impDers[kZ ][kPosZ] = 1.;
456 double tmpErrs[kNMinErrs],tmpPars[kNMinPars];
457 TCL::trasat(impDers[0],mBigErrs,tmpErrs,kNMinPars,kNBigPars);
459 double tmp = EmxSign(kNMinPars,tmpErrs);
463 tmpPars[kImp] = Imp();
464 tmpPars[kZ ] = Pos()[2];
465 tmpPars[kPsi] = Psi();
466 tmpPars[kPti] = Pti();
467 tmpPars[kTan] = TanL();
468 dca.set(tmpPars,tmpErrs);
472 double EmxSign(
int n,
const double *a)
474 long double ans=3e33;
476 double *B = (n<=10) ? buf :
new double[n];
483 int ipiv, kpiv, i__, j;
507 for (j = i__; j <= n; ++j) {
509 if (i__ == 1)
goto L40;
510 if (r__ == 0.)
goto L42;
515 sum += b[kd] * b[id];
522 if (j != i__) b[kpiv] = sum * r__;
524 if (sum<ans) ans = sum;
525 if (sum<0.)
goto RETN;
528 if (r__ > 0.) r__ = (double)1. / dc;
535 RETN:
if (B!=buf)
delete B;
541 #include "TVectorD.h"
544 #include "TRandomVector.h"
549 void GFull::TestConvertErrs()
553 static TCanvas* myCanvas[20] = {0};
554 static TH1F* hh[100] = {0};
555 static int Mh[10] = {0,21,21+15,-9999};
557 static const char* kom[] = {
558 "6_GFI",
"4_GFI",
"5_GFI",
"6_GFI",
559 "6_IMP",
"4_IMP",
"5_IMP",
560 "6_BIG",
"4_BIG",
"5_BIG",
"6_BIG",
"7_BIG",
563 static const char* tit[] = {
566 "qPVc",
"UcVc",
"_Vc_",
567 "qPNc",
"UcNc",
"VcNc",
"_Nc_",
568 "qPU",
" UcU",
" VcU" ,
"NcU" ,
"_U_",
569 "qPV",
" UcV",
" VcV" ,
"NcV" ,
"UV",
"_V_",
573 "PsiIp",
"PsiZ",
"_Psi_",
574 "PtiIp",
"PtiZ",
"PtiPsi",
"_Pti_",
575 "TanIp",
"TanZ",
"TanPsi",
"TanPti",
"_Tan_",
579 "PtiDirY",
"DirXDirY",
"_DirY_",
580 "PtiDirZ",
"DirXDirZ",
"DirYDirZ",
"_DirZ_",
581 "PtiPosX",
"DirXPosX",
"DirYPosX",
"DirZPosX",
"_PosX_",
582 "PtiPosY",
"DirXPosY",
"DirYPosY",
"DirZPosY",
"PosXPosY",
"_PosY_",
583 "PtiPosZ",
"DirXPosZ",
"DirYPosZ",
"DirZPosZ",
"PosXPosZ",
"PosYPosZ",
"_PosZ_",
586 int ic=-1,nPad=0,jPad=99;
587 for (
int ih=0;tit[ih];ih++) {
588 if (jPad>=nPad) { ic++; jPad=0; nPad = kom[ic][0]-
'0';
589 TString ts(kom[ic]+2); ts+=(ic);
590 if (!myCanvas[ic]) myCanvas[ic] =
new TCanvas(ts.Data(),ts.Data(),600,800);
591 myCanvas[ic]->Clear();myCanvas[ic]->Divide(1,nPad);
593 TString ts(tit[ih]);
delete hh[ih];
594 hh[ih] =
new TH1F(ts.Data(),ts.Data(),100,-5,5);
595 myCanvas[ic]->cd(++jPad); hh[ih]->Draw();
601 double PtGev = 1.,Curv = 1./100, Mag[3] = {0,0,PtGev*Curv};
602 double Pbeg[3]={PtGev,0,4./3*PtGev};
603 TVector3 PbegV(Pbeg),MidV(1.,1.,1.);MidV.SetMag(1.);
606 double UVN[3][3]={{0}};
607 for (
int ix=0;ix<3;ix++) { UVN[ix][ix]=1.;}
608 double ang = PbegV.Angle(MidV);
609 TVector3 Axi = MidV.Cross(PbegV); Axi.SetMag(1.);
610 MidV.Rotate(ang,Axi);
611 if (MidV.Dot(PbegV)<0) {
612 MidV.Rotate(-ang,Axi);
614 MidV.Rotate(ang,Axi);
616 assert(fabs(MidV.Dot(PbegV.Unit())-1)<1e-6);
617 for (
int i=0;i<3;i++) {
618 TVector3 uvn(UVN[i]);
623 TVector3 PosV(gRandom->Rndm()+1,gRandom->Rndm()+1,gRandom->Rndm()+2);
625 int icharge = (-Curv*PtGev/Mag[2]<0)? -1:1;
626 PbegV.RotateZ(gRandom->Rndm()*3.1415);
628 TVector3 XbegV(-PbegV[1],PbegV[0],0);
629 XbegV.SetMag(gRandom->Rndm()+1);
630 XbegV[2] = gRandom->Rndm();
631 assert(fabs(XbegV[0]*PbegV[0]+XbegV[1]*PbegV[1])<1e-5);
634 TVectorD dia(kNMinPars);
635 dia[0]= 0.1*PtGev; dia[1]= 0.1; dia[2]= 0.2, dia[3]= 0.3, dia[4]=0.4;
637 for (
int i=0;i<kNMinPars;i++) {dia[i]*=dia[i];}
640 auto &EMX = RV.GetMtx();
641 auto &val = RV.GetLam();
646 double gfiErrs[kNMinErrs];
647 for (
int i=0,li=0;i< kNMinPars;li+=++i) {
648 for (
int j=0;j<=i;j++) {
649 gfiErrs[li+j] = EMX[i][j];
652 double sig = EmxSign(kNMinPars,gfiErrs);
656 gf.SetGlob(Arr(PosV),UVN);
657 gf.SetPars(icharge,PosV,PbegV); gf.SetBigPars(icharge,PosV,PbegV);
660 TVectorD xPars = TVectorD(kNMaxPars,gf.XtdPars());
661 const double *xErrs = gf.XtdErrs();
667 gf.SetBigPars(icharge,PosV,PbegV);
668 const TVectorD &bigPars = gf.GetBigPars();
669 const double *bigErrs = gf.GetBigErrs();
672 TVectorD dcaPars(TVectorF(kNMinPars,dca.params() ));
673 TVectorD dcaErrs(TVectorF(kNMinErrs,dca.errMatrix()));
676 for (
int iter=0;iter<nIter;iter++) {
677 TVectorD delta = RV.Gaus();
679 TVectorD pars1 = delta;
681 pars1 += gf.GetPars(&iSig);
682 gf1.SetPars((
double*)&pars1[0],iSig);
683 gf1.FillDcaPars(dca1);
686 TVectorD dcaPars1(TVectorF(kNMinPars,dca1.params()));
687 TVectorD xPars1 (kNMaxPars,gf1.XtdPars());
689 gf1.SetBigPars(icharge,gf1.Pos(),gf1.Mom());
690 const TVectorD &bigPars1 = gf1.GetBigPars();
693 TVectorD xDif = xPars1 -xPars;
694 TVectorD bigDif = bigPars1-bigPars;
695 TVectorD dcaDif = dcaPars1-dcaPars;
702 for (
int i=0,li=0;i< kNMaxPars;li+=++i) {
703 dia[i] = sqrt(xErrs[li+i]);
704 hh[Mh[0] +li+i]->Fill(xDif[i]/ dia[i]);
705 for (
int j = 0;j<i;j++) {
706 hh[Mh[0] + li+j]->Fill((xDif[i]*xDif[j]-xErrs[li+j])/(dia[i]*dia[j]));
710 for (
int i=0,li=0;i< kNMinPars;li+=++i) {
711 dia[i] = sqrt(dcaErrs[li+i]);
712 hh[Mh[1] +li+i]->Fill(dcaDif[i]/ dia[i]);
713 for (
int j = 0;j<i;j++) {
714 hh[Mh[1] + li+j]->Fill((dcaDif[i]*dcaDif[j]-dcaErrs[li+j])/(dia[i]*dia[j]));
718 for (
int i=0,li=0;i< kNBigPars;li+=++i) {
719 dia[i] = sqrt(bigErrs[li+i]);
720 hh[Mh[2] +li+i]->Fill(bigDif[i]/ dia[i]);
721 for (
int j = 0;j<i;j++) {
722 hh[Mh[2] + li+j]->Fill((bigDif[i]*bigDif[j]-bigErrs[li+j])/(dia[i]*dia[j]));
726 for (
int ih=0;hh[ih];ih++) {
727 const char *name = hh[ih]->GetName();
728 int ent = hh[ih]->GetEntries();
729 double ave = hh[ih]->GetMean();
730 double rms = hh[ih]->GetRMS();
731 printf(
"%d - %s(%d) \tAve = %g \tRms = %g\n",ih,name,ent,ave,rms);
735 for (
int i=0;myCanvas[i];i++) {
736 myCanvas[i]->Modified();myCanvas[i]->Update();}
740 while(!gSystem->ProcessEvents()){gSystem->Sleep(200);};
float mPsi
Psi angle of the track.
float mZ
Z-coordinate of this track (reference plane)
float mPti
signed invert pt [sign = sign(-qB)]
static float * trasat(const float *a, const float *s, float *r, int m, int n)
float mTan
tangent of the track momentum dip angle