7 #include "TBenchmark.h"
20 #include "StarRoot/TTreeIter.h"
22 #include "TInterpreter.h"
24 #include "THelixTrack.h"
27 #define SQ(X) ((X)*(X))
28 #define PW2(X) ((X)*(X))
29 #define PW3(X) ((X)*(X)*(X))
31 enum {kNOBAGR=0,kNDETS=4,kMINHITS=50};
32 static const double WINDOW_NSTD=3;
34 static const double kAGREE=1e-7,kSMALL=1e-9,kBIG=1.,kDAMPR=0.1;
35 static const int MinErr[4][2] = {{200,200},{200,200},{30,500},{20,20}};
36 static char gTimeStamp[16]={0};
39 int fiterr(
const char *opt);
52 void FillPulls(
int befAft);
64 static double vmaxa (
const double *a,
int na);
65 static double vmaxa (
const TVectorD &a);
66 static void vfill (
double *a,
double f,
int na);
67 static void mxmlrt(
const TMatrixD &A,
const TMatrixD &B,TMatrixD &X);
68 static void mxmlrtS(
const TMatrixD &A,
const TMatrixD &B,TMatrixD &X);
69 static void mxmlrtS(
const double *A,
const double *B,
double *X,
int nra,
int nca);
70 static void eigen2(
const double err[3],
double lam[2],
double eig[2][2]);
71 static double simpson(
const double *F,
double A,
double B,
int NP);
72 static double vasum(
const double *a,
int na);
73 static double vasum(
const TVectorD &a);
74 static int SqProgSimple( TVectorD &x
75 ,
const TVectorD &g,
const TMatrixD &G
77 ,
const TVectorD &Max,
int iAkt);
92 float x_g()
const {
return grf*cos(gpf);}
93 float y_g()
const {
return grf*sin(gpf);}
94 float z_g()
const {
return gzf ;}
96 float xhg()
const {
return xyz[0]*cos(ang) - xyz[1]*sin(ang);}
97 float yhg()
const {
return xyz[0]*sin(ang) + xyz[1]*cos(ang);}
98 float zhg()
const {
return xyz[2] ;}
129 const double &Err(
int idx)
const {
return mDrr[idx];}
130 double &Err(
int idx) {
return mDrr[idx];}
131 double Err(
int iYZ,
const HitAccr &accr)
const;
132 double Err(
int iDet,
int iYZ,
const double A[3])
const;
133 const double &operator[](
int i)
const;
134 double &operator[](
int i);
139 HitPars_t &operator+=(
const TVectorD &add);
140 int NPars()
const {
return mNPars ;}
141 int Len(
int iDet,
int iYZ=0)
const {
return mLen[iDet][iYZ];}
142 int Lim(
int i)
const ;
143 const double &Min(
int i)
const {
return mMin[i];}
144 double &Min(
int i) {
return mMin[i];}
145 const double &Max(
int i)
const {
return mMax[i];}
146 double &Max(
int i) {
return mMax[i];}
148 const double &Min(
int iDet,
int iYZ,
int i)
const {
return mMin[IPar(iDet,iYZ)+i];}
149 const double &Max(
int iDet,
int iYZ,
int i)
const {
return mMax[IPar(iDet,iYZ)+i];}
150 double &Min(
int iDet,
int iYZ,
int i) {
return mMin[IPar(iDet,iYZ)+i];}
151 double &Max(
int iDet,
int iYZ,
int i) {
return mMax[IPar(iDet,iYZ)+i];}
153 int IPar(
int iDet,
int iYZ,
int *npars=0)
const;
154 void Set(
int iDet,
int iYZ,
int nini,
const double *ini);
156 double Deriv(
int npt,
const MyPull *pt,TVectorD &Di,TMatrixD &Dij)
const;
157 double DERIV(
int npt,
const MyPull *pt,TVectorD &Di,TMatrixD &Dij,
int maxTrk=9999999);
158 int Test(
int npt,
const MyPull *pt)
const;
159 void Print(
const HitPars_t *init=0)
const;
160 double Diff (
const HitPars_t &init)
const;
161 static void Prep(
int npt,
const MyPull *pt,TVectorD &Y,TVectorD &Z
162 ,TVectorD &S,TVectorD &cos2Psi);
165 static void Show(
int npt,
const MyPull *pt);
166 static double Dens(
double rxy,
int ntk);
167 static double Err(
const double Pars[3],
int nPars,
const double A[3]);
168 static void myDers(
double fake,
double wy,
double wz,
double dens
169 ,
double g[2][3],
double G[2][3][3]);
170 static double myFake(
double fake,
double wy,
double wz,
double dens
171 ,
double Cd[3],
double Cdd[3][3]);
177 double *mPars[kNDETS][2];
178 double *mErrs[kNDETS][2];
179 double mDat[1+kNDETS*2*3];
180 double mDrr[1+kNDETS*2*3];
181 double mMin[1+kNDETS*2*3];
182 double mMax[1+kNDETS*2*3];
185 static void myTrans(
double fake,
double wy,
double wz,
double dens, TMatrixD *mx);
198 Poli2(
int npw,
int n,
const double *X,
const double *Y,
const double *W);
201 void Add(
double x,
double y,
double w);
202 double Xi2()
const {
return fXi2;}
203 double Xi2(
int ipt)
const;
204 double EvalXi2()
const;
205 int Pw()
const {
return fPw ;}
206 int NPt()
const {
return fN ;}
207 double Fun(
double x )
const;
208 double dXi2dW(
int ipt )
const;
209 double d2Xi2d2W(
int ipt,
int jpt )
const;
210 double Deriv( TVectorD &Di, TMatrixD &Dij )
const;
232 #if !defined(__MAKECINT__)
238 std::vector<MyPull> MyVect;
239 double aveRes[4][6],aveTrk[4][2][3];
241 double pSTI[8][3] = {{0.000421985 ,0.00124327 ,0.0257111 }
242 ,{0.000402954 ,0.00346896 ,0.0377259 }
243 ,{0. ,0.0009366 ,0.0004967 }
244 ,{0.00018648 ,0.00507244 ,0.002654 }
245 ,{0.0030*0.0030 ,0.0 ,0.0 }
246 ,{0.0700*0.0700 ,0.0 ,0.0 }
247 ,{0.0080*0.0080 ,0.0 ,0.0 }
248 ,{0.0080*0.0080 ,0.0 ,0.0 }};
251 static const char *DETS[]={
"OutY",
"OutZ",
"InnY",
"InnZ"
252 ,
"SsdY",
"SsdZ",
"SvtY",
"SvtZ"};
253 static const char *DETZ[]={
"Out" ,
"Inn",
"Ssd",
"Svt"};
254 int FitOk[4]={0,0,0,0};
255 static char dbFile[4][100] = {
256 "StarDb/Calibrations/tracker/tpcOuterHitError.20050101.235959.C",
257 "StarDb/Calibrations/tracker/tpcInnerHitError.20050101.235959.C",
258 "StarDb/Calibrations/tracker/ssdHitError.20050101.235959.C" ,
259 "StarDb/Calibrations/tracker/svtHitError.20050101.235959.C" };
262 void myBreak(
int kase) {
263 static int myKase=-1946;
264 if (kase != myKase)
return;
268 int fiterr(
const char *opt)
271 int optH = strstr(opt,
"H")!=0;
272 int optU = strstr(opt,
"U")!=0;
273 int optT = strstr(opt,
"T")!=0;
274 memcpy(gTimeStamp,strstr(opt,
"20"),15);
279 th.AddFile(
"pulls.root");
282 const int &run = th(
"mRun");
283 const int &evt = th(
"mEvt");
285 const int &mTrksG = th(
"mTrksG");
286 const int &nGlobs = th(
"mHitsG");
287 const float *&mCurv = th(
"mHitsG.mCurv");
288 const float *&mPt = th(
"mHitsG.mPt");
289 const short *&mTrackNumber = th(
"mHitsG.mTrackNumber");
290 const float *&mNormalRefAngle = th(
"mHitsG.mNormalRefAngle");
291 const UChar_t *&nTpcHits = th(
"mHitsG.nTpcHits");
292 const UChar_t *&nSsdHits = th(
"mHitsG.nSsdHits");
293 const UChar_t *&nSvtHits = th(
"mHitsG.nSvtHits");
294 const float *&lYPul = th(
"mHitsG.lYPul");
295 const float *&lZPul = th(
"mHitsG.lZPul");
296 const float *&lXHit = th(
"mHitsG.lXHit");
297 const float *&lYHit = th(
"mHitsG.lYHit");
298 const float *&lZHit = th(
"mHitsG.lZHit");
299 const float *&lYFit = th(
"mHitsG.lYFit");
300 const float *&lZFit = th(
"mHitsG.lZFit");
301 const float *&lPsi = th(
"mHitsG.lPsi");
302 const float *&lDip = th(
"mHitsG.lDip");
303 const float *&lYFitErr = th(
"mHitsG.lYFitErr");
304 const float *&lZFitErr = th(
"mHitsG.lZFitErr");
305 const float *&lYHitErr = th(
"mHitsG.lYHitErr");
306 const float *&lZHitErr = th(
"mHitsG.lZHitErr");
307 const float *&lYPulErr = th(
"mHitsG.lYPulErr");
308 const float *&lZPulErr = th(
"mHitsG.lZPulErr");
309 const float *&gRFit = th(
"mHitsG.gRFit");
310 const float *&gPFit = th(
"mHitsG.gPFit");
311 const float *&gZFit = th(
"mHitsG.gZFit");
313 printf(
"*lYPul = %p\n",lYPul);
314 printf(
"&run=%p &evt=%p\n",&run,&evt);
317 int nTpc=0,nPre=0,iTk=-1,iTkSkip=-1;
322 for (
int ih=0;ih<nGlobs;ih++) {
323 if (mTrackNumber[ih]==iTkSkip)
continue;
324 float rxy00 = rxy; rxy=lXHit[ih];
325 if (mTrackNumber[ih]!=iTk || rxy<rxy00) {
326 iTk = mTrackNumber[ih];
328 if (nTpcHits[ih] <25)
continue;
329 if (fabs(mCurv[ih])>1./200)
continue;
330 if (fabs(mPt[ih]/cos(lDip[ih]))<0.5)
continue;
331 int nSS = nSsdHits[ih]+nSvtHits[ih];
332 if (nSS && nSS<2)
continue;
333 if (!nSS && nPre && nTpc>100 && nTpc>3*nPre)
continue;
339 memset(&mp,0,
sizeof(mp));
340 mp.trk = mTrackNumber[ih];
341 mp.pye = lYPulErr[ih];
342 mp.pze = lZPulErr[ih];
343 float uyy = (lYPulErr[ih]-lYHitErr[ih])*(lYHitErr[ih]+lYPulErr[ih]);
346 float uzz = (lZPulErr[ih]-lZHitErr[ih])*(lZHitErr[ih]+lZPulErr[ih]);
351 mp.fye = lYFitErr[ih];
352 mp.fze = lZFitErr[ih];
353 mp.hye = lYHitErr[ih];
354 mp.hze = lZHitErr[ih];
355 mp.xyz[0] = lXHit[ih];
356 if (mp.xyz[0]<4)
continue;
357 mp.xyz[1] = lYHit[ih];
358 mp.xyz[2] = lZHit[ih];
367 mp.dens = HitPars_t::Dens(mp.xyz[0],mTrksG);
372 mp.ang = mNormalRefAngle[ih];
374 MyVect.push_back(mp);
379 printf(
"fiterr:: %d hits accepted\n\n",MyVect.size());
380 printf(
"fiterr:: %d Tpc and %d Svt/Ssd tracks accepted\n\n",nTpc,nPre);
385 if (optH) CheckErr();
386 if (optH) FillPulls(0);
387 if (optT)
return HitErr.Test(MyVect.size(),&(MyVect[0]));
389 double maxPct = Fit(HitErr);
391 if (optH) FillPulls(1);
395 return (maxPct< 3) ? 99:0;
398 Poli2::Poli2(
int npw):fP(npw+1),fB(npw+1),fA(npw+1,npw+1),fAi(npw+1,npw+1)
408 memset(fBeg,0,fEnd-fBeg+1);
411 Poli2::Poli2(
int npw,
int N,
const double *X,
const double *Y,
const double *W)
412 :fP(npw+1),fB(npw+1),fA(npw+1,npw+1),fAi(npw+1,npw+1)
418 int nb = N*
sizeof(double);
424 void Poli2::Add(
double x,
double y,
double w)
426 fX[fN]=x; fY[fN]=y, fW[fN]=w; fN++;
432 double Wt=0,Wx=0,Wy=0;
433 for (
int i=0;i<fN;i++) { Wt += fW[i]; Wx += fW[i]*fX[i];Wy += fW[i]*fY[i];}
434 fX0 = Wx/Wt; fY0 = Wy/Wt;
435 for (
int i=0;i<fN;i++) { fX[i]-=fX0; fY[i]-=fY0;}
437 double A[3][3]={{0}},B[3]={0};
440 for (
int i=0;i<fN;i++) {
442 x[1] = fX[i]; x[2]=x[1]*x[1];
443 double y = fY[i],y2=y*y;
444 for (
int j=0;j<=fPw;j++) { B[j] +=w*x[j]*y;
445 for (
int k=0;k<=j ;k++) { A[j][k] +=w*x[j]*x[k];}}
448 for (
int j=0;j<=fPw;j++){ fB[j] = B[j];
449 for (
int k=0;k<=j ;k++){ fA(j,k) = A[j][k]; fA(k,j)=A[j][k];}}
452 fAi=fA;fAi.InvertFast(&det);
458 double Poli2::Fun(
double x )
const
461 double xx[3]={1,x,x*x};
462 TVectorD XX(fPw+1,xx);
466 double Poli2::Xi2(
int ipt)
const
468 double dy = Fun(fX[ipt]+fX0) - (fY[ipt]+fY0);
469 return dy*dy*fW[ipt];
472 double Poli2::EvalXi2()
const
475 for (
int ipt=0;ipt<fN;ipt++) {sum+=Xi2(ipt);}
479 double Poli2::dXi2dW(
int ipt )
const
485 double der = fY[ipt]*fY[ipt];
487 TMatrixD dA(fPw+1,fPw+1);
488 double x[3]={1,fX[ipt],fX[ipt]*fX[ipt]};
489 for (
int j=0;j<=fPw;j++) { dB[j] = x[j]*fY[ipt];
490 for (
int k=0;k<=fPw;k++) { dA(j,k) = x[j]*x[k]; }}
491 der -= (2*(dB*(fAi*fB))-(fP*(dA*fP)));
496 double Poli2::d2Xi2d2W(
int ipt,
int jpt )
const
509 double xi[3]={1,fX[ipt],fX[ipt]*fX[ipt]};
510 double xj[3]={1,fX[jpt],fX[jpt]*fX[jpt]};
512 TVectorD diB(fPw+1) ,djB(fPw+1);
513 TMatrixD diA(fPw+1,fPw+1),djA(fPw+1,fPw+1);
514 for (
int j=0;j<=fPw;j++) { diB[j]=fY[ipt]*xi[j]; djB[j]=fY[jpt]*xj[j];
515 for (
int k=0;k<=fPw;k++) { diA(j,k) = xi[j]*xi[k]; djA(j,k) = xj[j]*xj[k];}}
516 double der = -2*(-((fAi*diB)*(djA*fP))
518 -((fAi*djB)*(diA*fP))
519 +(fP*(djA*(fAi*(diA*fP)))));
523 double Poli2::Deriv( TVectorD &Di, TMatrixD &Dij )
const
527 TVectorD diB(fPw+1) ,djB(fPw+1);
528 TMatrixD diA(fPw+1,fPw+1),djA(fPw+1,fPw+1);
529 for (
int ipt=0;ipt<fN;ipt++) {
530 double der = fY[ipt]*fY[ipt];
531 double xi[3]={1,fX[ipt],fX[ipt]*fX[ipt]};
532 for (
int k=0;k<=fPw;k++) { diB[k] = fY[ipt]*xi[k];
533 for (
int l=0;l<=fPw;l++) { diA(k,l) = xi[k]*xi[l];}}
534 der -= (2*(diB*(fAi*fB))-(fP*(diA*fP)));
536 for (
int jpt=0;jpt<=ipt;jpt++) {
537 double xj[3]={1,fX[jpt],fX[jpt]*fX[jpt]};
538 for (
int k=0;k<=fPw;k++) { djB[k] = fY[jpt]*xj[k];
539 for (
int l=0;l<=fPw;l++) { djA(k,l) = xj[k]*xj[l];}}
540 der = -2*(-((fAi*diB)*(djA*fP))
542 -((fAi*djB)*(diA*fP))
543 +(fP*(djA*(fAi*(diA*fP)))));
552 void Poli2::MyTest()
const
558 printf(
"Print Ai\n");
560 printf(
"Print A*Ai\n");
561 TMatrixD tst(fPw+1,fPw+1);
569 double X[20],Y[20],W[20];
570 for (
int i=0;i<20;i++) {
572 Y[i]= 3+X[i]*(.02+.03*X[i]);
574 Y[i]+=gRandom->Gaus(0,sqrt(1./W[i]));
576 Poli2 pp(npw,20,X,Y,W);
579 double Xi2 = pp.Xi2();
580 double Xi2Eva = pp.Xi2();
581 printf (
"Xi2 = %g == %g\n",Xi2,Xi2Eva);
582 for (
int i=0; i<20; i++) {
583 printf(
" %g %g : %g\n",X[i],Y[i],pp.Fun(X[i]));
586 printf(
"\n check d/dWi\n");
588 for (
int k=0;k<20;k++) {
590 for (
int i=0;i<20;i++) {
593 ppp.Add(X[i],Y[i],w);
596 double ana = pp.dXi2dW(k);
597 double num = (ppp.Xi2()-pp.Xi2())/delta;
598 double dif = 2*(num-ana)/(fabs(num+ana)+3e-33);
599 if (fabs(dif)<0.01)
continue;
600 printf (
"dXi2dW(%2d) \tana=%g \tnum = %g \tdif=%g\n",k,ana,num,dif);
603 printf(
"\n check d2/dWi/DWj\n");
604 for (
int i=0;i<20;i++) {
605 double sav = W[i]; W[i]=sav+delta;
606 Poli2 ppp(npw,20,X,Y,W);
609 for (
int j=0;j<20;j++) {
610 double ana = pp.d2Xi2d2W(i,j);
611 double num = (ppp.dXi2dW(j)-pp.dXi2dW(j))/delta;
612 double dif = 2*(num-ana)/(fabs(num+ana)+3e-33);
613 if (fabs(dif)<0.01)
continue;
614 printf (
"d2Xi2d2W(%2d,%2d) \tana=%g \tnum = %g \tdif=%g\n",i,j,ana,num,dif);
619 for (
int i=0;i<20;i++) {
620 double tst = pp.dXi2dW(i)-g[i];
621 if (fabs(tst)>1e-10) printf(
"g[%d] %g **************\n",i,tst);
622 for (
int j=0;j<20;j++) {
623 double tst = pp.d2Xi2d2W(i,j)-gg[i][j];
624 if (fabs(tst)>1e-10) printf(
"gg[%d][%d] %g **************\n",i,j,tst);
630 void Poli2::TestIt()
const
636 double Xi2 = pp.Deriv(g,G);
639 for (
int k=0;k<fN;k++) {
640 double sav = pp.fW[k];
643 double Xi2T = pp.Deriv(gT,GT);
646 double ana = 0.5*(g[k]+gT[k]);
647 double num = (Xi2T-Xi2)/delta;
648 double dif = 2*(num-ana)/(fabs(num+ana)+1e-10);
650 printf (
"\ndXi2dW(%2d) \tana=%g \tnum = %g \tdif=%g\n\n",k,ana,num,dif);
652 for (
int i=0;i<fN;i++) {
653 ana = 0.5*(GT[k][i]+G[k][i]);
654 num = (gT[i]-g[i])/delta;
655 dif = 2*(num-ana)/(fabs(num+ana)+1e-10);
657 printf (
"d2Xi2dW2(%2d,%2d) \tana=%g \tnum = %g \tdif=%g\n",k,i,ana,num,dif);
671 for (
int iDet=0;iDet<kNDETS;iDet++) {
672 if (numRes[iDet]<kMINHITS)
continue;
673 int n = (iDet<=1)? 3:1;
674 hiterr.Set(iDet,0,n,pSTI[iDet*2+0]);
675 hiterr.Set(iDet,1,n,pSTI[iDet*2+1]);
676 hiterr.Min(iDet,0,0) = pow(MinErr[iDet][0]*1.e-4,2);
677 hiterr.Min(iDet,1,0) = pow(MinErr[iDet][1]*1.e-4,2);
688 int Saddle()
const {
return neg<0;}
689 int LimX(
int i)
const;
690 double Der()
const {
return der;}
691 double Fcn()
const {
return fcn;}
692 void Deriv(
const std::vector<MyPull> &MyVect);
693 int MaxStp(TVectorD &add,
int mode)
const;
697 static int FixWeak( TVectorD &g, TMatrixD &G);
711 FitState_t::FitState_t()
713 memset(myBeg,0,myEnd-myBeg+1);
714 der = 1e99;fcn = 1e99;neg =-1e99;
719 memset(myBeg,0,myEnd-myBeg+1);
720 der = 1e99;fcn = 1e99;neg =-1e99;
723 void FitState_t::Deriv(
const std::vector<MyPull> &MyVect)
726 fcn = DERIV(npt,&(MyVect[0]),g,G);
728 der = -1; ider =-1; neg = 0;
729 for (
int i=0;i<mNPars;i++) {
730 if (G[i][i]<neg) neg =G[i][i];
731 if(LimX(i))
continue;
732 if (fabs(g[i])>der) { ider = i; der = fabs(g[i]);}
735 double myMax=myTCL::vmaxa(G.GetMatrixArray(),G.GetNoElements());
736 fak = pow(2.,-
int(log(myMax)/log(2.)));
739 for (
int i = 0; i<mNPars && neg>0; i++){
740 for (
int j = 0; j<i && neg>0; j++) {
741 if (pow(G[i][j],2) >= G[i][i]*G[j][j]) neg = -1;
748 int FitState_t::operator<(
const FitState_t &old)
const
751 double delta = (Fcn()-old.Fcn())/Fcn();
753 if (Der()<0 )
return 0;
754 if (Fcn()<old.Fcn())
return 1;
756 && Fcn()-old.Fcn()-0.1*fabs(old.Fcn())<0)
return 1;
762 memcpy(myBeg,other.myBeg,myEnd-myBeg+1);
767 HitPars_t::operator=(other);
771 int FitState_t::MaxStp(TVectorD &add,
int mode)
const
775 for (
int i=0;i<mNPars;i++) {
776 double maxStp = (0.01+mDat[i])*0.3;
777 if (maxStp>fak*fabs(add[i]))
continue;
779 if (!mode) { add[i] = (add[i]<0)? -maxStp:maxStp;}
780 else { fak = maxStp/fabs(add[i]);}
786 void FitState_t::MakeErrs()
790 for (
int i=0;i<mNPars;i++) {
791 if (!Lim(i))
continue;
792 for (
int j=0;j<mNPars;j++) {E(i,j) = 0; E(j,i) = 0;}; E(i,i) = 1;
794 double det=12345; E.InvertFast(&det);
796 for (
int i=0;i<mNPars;i++) {Err(i) = sqrt(E(i,i));}
799 int FitState_t::LimX(
int i)
const
803 if (lim<0 && g[i]<0)
return 0;
804 if (lim>0 && g[i]>0)
return 0;
808 int FitState_t::FixWeak( TVectorD &g, TMatrixD &G)
810 int n = g.GetNrows();
812 double ave = myTCL::vasum(g)/n;
813 for (
int i=0;i<n;i++) {
814 if (fabs(g[i])>=ave)
continue;
816 for (
int j=0;j<n;j++) {G[i][j]=0; G[j][i]=0;}
824 enum {kMAXITER=10000};
825 static int const MAXCUT[2]={4,10};
828 int ifail = 99,nPars,iAkt=0,iter,nCut,lim=0,con=0;
829 nPars = pout.NPars();
833 TVectorD add(nPars),g(nPars),ge(nPars),Gg(nPars);
835 double dif,difFcn=0,difDer;
837 static int idebug = 1;
841 for (iter=0;iter<kMAXITER;iter++) {
844 difFcn = Now.fcn-Best.fcn;
845 difDer = Now.der-Best.der;
847 printf(
"Fit(%3d) \tFcn = %g(%g) \tDer(%2d)=%g(%g) \tLim=%d \tCon=%d\tAkt=%d Cut=%d Sad=%d\n"
848 ,iter,Now.fcn,difFcn,Now.ider,Now.der,difDer,lim,con,iAkt,nCut,Now.Saddle());
850 if (Now.Der()<0) {ifail=1;
break;
851 }
else if (Now.Der() < kAGREE) {
852 Best=Now; ifail=0;
break;
854 }
else if (Now < Best ) {
855 nCut = 0; Best = Now; iAkt = 0;
857 }
else if (nCut>MAXCUT[iAkt]) {
858 if (iAkt==0) Now=Best;
859 Best=Now; nCut=0; iAkt=1-iAkt;
864 Now.Pars() = Best.Pars()+add;
871 static int rnd=0; rnd++;
872 if (!(rnd&3)) iAkt=1;
875 TVectorD P0(nPars,&Best[0]);
876 for (
int jAkt=iAkt;jAkt<2;jAkt++) {
879 con = myTCL::SqProgSimple(P1,Now.g,Now.G
880 ,TVectorD(nPars,&Now.Min(0))
881 ,TVectorD(nPars,&Now.Max(0)),jAkt);
884 double along = -(add*Now.g);
885 if (along <0)
continue;
886 lim=Best.MaxStp(add,1);
887 Now.Pars() = Best.Pars()+add;
892 if (ifail==0 || ifail==99) Best.MakeErrs();
895 dif = pout.Diff(init);
896 printf(
"\nFit: Iter=%d Fcn=%g Der=%g Dif=%6.3g%% Fail=%d\n"
897 ,iter,Best.fcn,Best.der,dif,ifail);
899 return (ifail)? 1e10:dif;
906 memset(aveRes[0] ,0,
sizeof(aveRes));
907 memset(aveTrk[0][0],0,
sizeof(aveTrk));
908 memset(numRes ,0,
sizeof(numRes));
909 for (
int jhit=0; jhit<(int)MyVect.size(); jhit++) {
910 MyPull &myRes = MyVect[jhit];
911 int jdx = kind(myRes.xyz[0]);
912 aveRes[jdx][0]+= myRes.ypul*myRes.ypul;
913 aveRes[jdx][1]+= myRes.zpul*myRes.zpul;
914 aveRes[jdx][2]+= myRes.uyy;
915 aveRes[jdx][3]+= myRes.uzz;
916 aveRes[jdx][4]+= pow(myRes.xyz[1]-myRes.yfit,2);
917 aveRes[jdx][5]+= pow(myRes.xyz[2]-myRes.zfit,2);
918 if (hh[jdx*2+0+30]) hh[jdx*2+0+30]->Fill(myRes.ypul);
919 if (hh[jdx*2+1+30]) hh[jdx*2+1+30]->Fill(myRes.zpul);
922 HitPars_t::HitCond(myRes,ha);
923 TCL::vadd(aveTrk[jdx][0],ha.A[0],aveTrk[jdx][0],3);
924 TCL::vadd(aveTrk[jdx][1],ha.A[1],aveTrk[jdx][1],3);
929 for (
int jhit=0; jhit<(int)MyVect.size(); jhit++) {
930 MyPull &myRes = MyVect[jhit];
931 int jdx = kind(myRes.xyz[0]);
932 if (numRes[jdx]<kMINHITS)
continue;
933 aveRes[jdx][0]+= myRes.ypul*myRes.ypul;
934 if (ihit!=jhit) MyVect[ihit]=MyVect[jhit];
939 for(
int jdx=0;jdx<4;jdx++) {
940 if (numRes[jdx]<kMINHITS)
continue;
941 double f = 1./numRes[jdx];
942 TCL::vscale(aveRes[jdx],f,aveRes[jdx],6);
943 TCL::vscale(aveTrk[jdx][0],f,aveTrk[jdx][0],6);
944 double hitYErr,hitZErr;
945 TCL::vsub(aveRes[jdx]+0,aveRes[jdx]+2,aveRes[jdx]+2,2);
946 hitYErr = aveRes[jdx][2];
947 hitYErr = (hitYErr<0)? -sqrt(-hitYErr):sqrt(hitYErr);
948 hitZErr = aveRes[jdx][3];
949 hitZErr = (hitZErr<0)? -sqrt(-hitZErr):sqrt(hitZErr);
950 printf(
"AveRes:: N=%5d \taveRes[%s][yz]=%g %g \tavePul[yz]=%g %g \thitErr(yz)=%g %g\n\n"
951 ,numRes[jdx],DETZ[jdx]
952 ,sqrt(aveRes[jdx][4]),sqrt(aveRes[jdx][5])
953 ,sqrt(aveRes[jdx][0]),sqrt(aveRes[jdx][1])
963 static const double radds[5]={120,25,16,0,0};
964 for(
int jdx=0;1;jdx++) {
if (x>radds[jdx])
return jdx;}
969 memset(hh,0,
sizeof(hh));
970 memset(C,0,
sizeof(C));
972 static const char *NamPuls[]={
973 "YOut.bef",
"YOut.aft",
"ZOut.bef",
"ZOut.aft",
974 "YInn.bef",
"YInn.aft",
"ZInn.bef",
"ZInn.aft",
975 "YSsdBef",
"YSsdAft",
"ZSsdBef",
"ZSsdAft",
976 "YSvtBef",
"YSvtAft",
"ZSvtBef",
"ZSvtAft"};
977 static const char *NamRes[]={
978 "YOut.res",
"ZOut.res",
979 "YInn.res",
"ZInn.res",
980 "YSsd.res",
"ZSsd.res",
981 "YSvt.res",
"ZSvt.res"};
983 for (
int ih=0;ih<16;ih++) {
984 hh[ih] =
new TH1F(NamPuls[ih],NamPuls[ih],100,-3,3);}
985 C[0] =
new TCanvas(
"C0",
"",600,800);
987 C[1] =
new TCanvas(
"C1",
"",600,800);
989 for (
int ih=0;ih<8;ih++) {C[0]->cd(ih+1);hh[ih+0]->Draw();}
990 for (
int ih=0;ih<8;ih++) {C[1]->cd(ih+1);hh[ih+8]->Draw();}
992 hh[20]=
new TH1F(
"ChekErr",
"ChekErr",100,-100.,100.);
993 hh[21]=
new TH1F(
"ChekPul",
"ChekPul",100,-100.,100.);
994 C[2] =
new TCanvas(
"C2",
"",600,800);
996 for (
int ih=0;ih<2;ih++) {C[2]->cd(ih+1);hh[ih+20]->Draw();}
999 for (
int ih=0;ih<8;ih++) {
1000 hh[ih+30] =
new TH1F(NamRes[ih],NamRes[ih],100,-0.3,0.3);}
1001 C[3] =
new TCanvas(
"C3",
"",600,800);
1003 for (
int ih=0;ih<8;ih++) {C[3]->cd(ih+1);hh[ih+30]->Draw();}
1008 void FillPulls(
int befAft)
1011 for (
int jhit=0; jhit<(int)MyVect.size(); jhit++) {
1012 myRes = MyVect[jhit];
1013 int jdx = kind(myRes.xyz[0]);
1015 hh[jdx*4+0]->Fill(myRes.ypul/(myRes.pye));
1016 hh[jdx*4+2]->Fill(myRes.zpul/(myRes.pze));
1018 hh[jdx*4+1]->Fill(newPull(0,myRes,HitErr));
1019 hh[jdx*4+3]->Fill(newPull(1,myRes,HitErr));
1027 HitPars_t::HitCond(myRes,accr);
1028 double S = pars.Err(iYZ,accr)+accr.PredErr[iYZ];
1030 return accr.Pull[iYZ]/sqrt(S);
1036 gSystem->Load(
"libStDb_Tables.so");
1039 for (
int idb=0;idb<4;idb++) {
1040 memcpy(strstr(dbFile[idb],
"20"),gTimeStamp,15);
1042 if (!gSystem->AccessPathName(dbFile[idb])) {
1043 command =
".L "; command += dbFile[idb];
1044 gInterpreter->ProcessLine(command);
1045 newdat = (
TTable *) gInterpreter->Calc(
"CreateTable()");
1046 command.ReplaceAll(
".L ",
".U ");
1047 gInterpreter->ProcessLine(command);
1050 newdat = (
TTable *)gInterpreter->Calc(
"new St_HitError(\"someHitError\",1)");
1051 newdat->SetUsedRows(1);
1054 dbTab[idb] = newdat;
1062 for (
int idb=0;idb<4;idb++)
1064 if (numRes[idb]<kMINHITS)
continue;
1065 double *d = (
double *)dbTab[idb]->GetArray();
1066 if (d[0]<=0) {d[0]=aveRes[idb][0];d[3]=aveRes[idb][1];}
1067 TCL::ucopy(d+0,pSTI[idb*2+0],3);
1068 TCL::ucopy(d+3,pSTI[idb*2+1],3);
1075 for (
int idb=0;idb<kNDETS;idb++)
1077 memset(par,0,
sizeof(par));
1078 if (!HitErr.mPars[idb][0])
continue;
1079 if (!HitErr.Len(idb))
continue;
1080 TString ts(dbFile[idb]);
1082 gSystem->Rename(dbFile[idb],ts);
1083 int ny = HitErr.Len(idb,0);
1084 TCL::ucopy(HitErr.mPars[idb][0],par[0],ny);
1085 int nz = HitErr.Len(idb,1);
1086 TCL::ucopy(HitErr.mPars[idb][1],par[1],nz);
1088 TCL::ucopy(par[0],(
double*)dbTab[idb]->GetArray()+0,3+3);
1090 std::ofstream ofs(dbFile[idb]);
1098 for (
int ic=0;ic<(int)(
sizeof(C)/
sizeof(
void*));ic++) {
1099 TCanvas *cc = C[ic];
if (!cc)
continue;
1100 cc->Modified();cc->Update();
1102 while(!gSystem->ProcessEvents()){};
1108 for (
int jhit=0; jhit<(int)MyVect.size(); jhit++) {
1109 MyPull &myRes = MyVect[jhit];
1110 int jdx = kind(myRes.xyz[0]);
if(jdx){};
1111 if (jdx != 2)
continue;
1112 float pye = myRes.pye;
1113 float hye = myRes.hye;
1115 float ypul = myRes.ypul;
1116 if (fabs(ypul/pye)<2) {
1117 double tmp = (ypul*ypul-pye*pye)/(hye*hye);
1120 hh[21]->Fill(pye/hye);
1135 for (
int iDet=0;iDet<kNDETS;iDet++) {
1136 for (
int iYZ=0;iYZ<2;iYZ++) {
1137 int idx = iYZ + 2*iDet;
1138 int nPars = HitErr.Len(iDet,iYZ);
1139 double sum=0,sum2=0,sig[3]={0};
1141 for (
int jhit=0; jhit<(int)MyVect.size(); jhit++) {
1142 MyPull &myRes = MyVect[jhit];
1143 int jdx = kind(myRes.xyz[0]);
1144 if (jdx != iDet)
continue;
1147 HitPars_t::HitCond(myRes,accr);
1148 double S = HitErr.Err(iYZ,accr);
1149 double delta = pow((&myRes.ypul)[iYZ],2);
1150 double P0 = delta/((&myRes.uyy)[iYZ]+pow((&myRes.hye)[iYZ],2));
1151 double P1 = delta/((&myRes.uyy)[iYZ]+HitPars_t::Err(pSTI[idx],nPars,accr.A[iYZ]));
1152 double P2 = delta/((&myRes.uyy)[iYZ]+S);
1153 sum +=S; sum2 += S*S; sig[0]+=P0; sig[1]+=P1;sig[2]+=P2;
1155 if (!nTot)
continue;
1156 sum/=nTot; sum2/=nTot; sum2-=sum*sum;
if (sum2<0) sum2=0; sum2=sqrt(sum2);
1157 sum = sqrt(sum); sum2 /= 2*sum;
1158 for (
int i=0;i<3;i++) {sig[i]=sqrt(sig[i]/nTot);}
1160 int isig = int(10000*sum +0.5);
1161 int esig = int(10000*sum2+0.5);
1162 double newErr = sum;
1163 double oldErr = sqrt(HitPars_t::Err(pSTI[idx],nPars,aveTrk[iDet][iYZ]));
1164 double pct = 200*fabs(newErr-oldErr)/(newErr+oldErr);
1165 if (pct>pctMax) pctMax=pct;
1166 int iold = int(10000*oldErr +0.5);
1169 printf(
"AveErr(%s): <Err.old> = %4d <Err.new> %4d(+-%4dmu) Dif=%4.1g%%\t// evts=%d\n"
1170 ,DETS[idx],iold,isig,esig,pct,nTot);
1172 printf(
"AveErr(): maxPct = %4.1g%%\n\n", pctMax );
1180 if (!hh[30+4])
return;
1186 HitPars_t::HitPars_t ()
1190 int n =
sizeof(mMin)/
sizeof(*mMin);
1191 myTCL::vfill(mMin,kSMALL,n);
1192 myTCL::vfill(mMax,kBIG ,n);
1197 HitPars_t::HitPars_t (
const HitPars_t &fr)
1205 int inc = (
char*)mDat-(
char*)fr.mDat;
1206 int n =
sizeof(mPars)/
sizeof(mPars[0][0]);
1207 char **p = (
char**)mPars[0];
1208 for (
int i=0;i<n;i++) {
if (p[i]) p[i] += inc;}
1209 assert(mDat <=mPars[0][0]);
1213 const double &HitPars_t::operator[](
int i)
const
1217 double &HitPars_t::operator[](
int i)
1220 HitPars_t &HitPars_t::operator*(
double f)
1221 {
for (
int i=0;i<mNPars;i++) { (*this)[i]*=f;}
return *
this; }
1223 HitPars_t &HitPars_t::operator+=(
const double *f)
1224 {
for (
int i=0;i<mNPars;i++) {(*this)[i]+=f[i];}
return *
this;}
1226 HitPars_t &HitPars_t::operator=(
double f)
1227 {
for (
int i=0;i<mNPars;i++) {(*this)[i]=f;}
return *
this;}
1239 int HitPars_t::IPar(
int iDet,
int iYZ,
int *npars)
const
1241 if (npars) *npars=Len(iDet,iYZ);
1242 int ans = mPars[iDet][iYZ]-mDat;
1243 assert(ans>=0 && ans < 100);
1247 int HitPars_t::Lim(
int i)
const
1250 if (mDat[i] <= mMin[i]*1.1) lim = -1;
1251 if (mDat[i] >= mMax[i]*0.9) lim = 1;
1255 double HitPars_t::Err(
int iDet,
int iYZ,
const double A[3])
const
1257 return Err(mPars[iDet][iYZ],Len(iDet,iYZ),A);
1260 double HitPars_t::Err(
int iYZ,
const HitAccr &accr)
const
1262 return Err(accr.iDet,iYZ,accr.A[iYZ]);
1265 HitPars_t &HitPars_t::operator+=(
const TVectorD &add)
1267 for (
int i=0;i<mNPars;i++) {
1269 if (mDat[i]<mMin[i]) mDat[i]=mMin[i];
1270 if (mDat[i]>mMax[i]) mDat[i]=mMax[i];
1275 void HitPars_t::Set(
int iDet,
int iYZ,
int nini,
const double *ini)
1277 mLen[iDet][iYZ]=nini;
1278 if (iDet+1>mNDets) mNDets=iDet+1;;
1279 mPars[iDet][iYZ]=mDat+mNPars;
1280 mErrs[iDet][iYZ]=mDrr+mNPars;
1282 for (
int i=0;i<nini;i++) {
1283 int ipar = IPar(iDet,iYZ);
1285 mDat[ipar+i]=ini[i];
1286 if (mDat[ipar+i]< mMin[ipar+i]) mDat[ipar+i]= mMin[ipar+i];
1287 if (mDat[ipar+i]> mMax[ipar+i]) mDat[ipar+i]= mMax[ipar+i];
1292 double HitPars_t::Dens(
double rxy,
int ntk)
1297 return ntk/(4*3.14*rxy*rxy);
1302 memset(acc.A[0],0,
sizeof(acc.A));
1303 acc.iDet = kind(myRes.xyz[0]);
1304 for (
int iyz=0;iyz<2;iyz++) {
1306 acc.A[iyz][1]= 0.01*(200-fabs(myRes.xyz[2]));
1309 ang = myRes.psi; acc.Pull[0]=myRes.ypul;
1310 acc.PredErr[0] = myRes.uyy;
1312 ang = myRes.dip; acc.Pull[1]=myRes.zpul;
1313 acc.PredErr[1] = myRes.uzz;
1316 if (ca<0.01) ca=0.01;
1318 double ta2=(1-ca2)/ca2;
1319 acc.A[iyz][1]/= ca2;
1320 acc.A[iyz][2] = ta2;
1324 double HitPars_t::Deriv(
int npt,
const MyPull *pt,TVectorD &Di,TMatrixD &Dij)
const
1336 Di.ResizeTo(mNPars);
1337 Dij.ResizeTo(mNPars,mNPars);
1338 int npt21 = npt*2+1;
1343 TVectorD wy(npt),wz(npt),cos2Psi(npt21);
1344 TMatrixD toPars(mNPars,npt21);
1351 double len = 0,oldCurv,oldXyz[3],nowXyz[3];
1352 assert(pt[0].xyz[0]<pt[npt-1].xyz[0]);
1353 for (
int ipt=0;ipt<npt;ipt++) {
1354 HitCond(pt[ipt],ha);
1356 if (!mPars[iDet][0])
continue;
1357 double nowCurv=pt[ipt].curv;
1358 nowXyz[0] = pt[ipt].grf*cos(pt[ipt].gpf);
1359 nowXyz[1] = pt[ipt].grf*sin(pt[ipt].gpf);
1361 double dl = sqrt(SQ(nowXyz[0]-oldXyz[0])+SQ(nowXyz[1]-oldXyz[1]));
1362 double curv=0.5*fabs(nowCurv+oldCurv);
1363 if (dl*curv<1e-3) dl*=(1.+SQ(dl*curv)/24);
1364 else dl = 2*asin(0.5*dl*curv)/curv;
1368 double dy = pt[ipt].xyz[1]-pt[ipt].yfit;
1369 double cosPsi = cos(pt[ipt].psi);
1370 cos2Psi[ipt+1] = cosPsi*cosPsi;
1372 double dz = pt[ipt].xyz[2]-pt[ipt].zfit;
1373 wy[ipt] = (1./Err(0,ha))/cos2Psi[ipt+1];
1374 wz[ipt] = (1./Err(1,ha));
1375 double fake = myFake( mDat[0],wy[ipt],wz[ipt],pt[ipt].dens,0,0);
1376 ply.Add(len,dy,wy[ipt]*fake);
1377 plz.Add(len,dz,wz[ipt]*fake);
1383 for (
int jk=0;jk<2;jk++) {
1384 int ip = 1 +ipt + jk*npt;
1385 ipar = IPar(iDet,jk,&n);
1387 for (
int in=0;in<n;in++) {toPars[ipar+in][ip]+=ha.A[jk][in];}
1389 memcpy(oldXyz,nowXyz,
sizeof(oldXyz));
1395 Prep(npt,pt,Y,Z,S,cos2Psi);
1396 for (
int ipt=0;ipt<npt;ipt++) {
1397 HitCond(pt[ipt],ha);
1398 wy[ipt] = (1./Err(0,ha))/cos2Psi[ipt+1];
1399 wz[ipt] = (1./Err(1,ha));
1400 double fake = myFake( mDat[0],wy[ipt],wz[ipt],pt[ipt].dens,0,0);
1401 ply.Add(S[ipt],Y[ipt],wy[ipt]*fake);
1402 plz.Add(S[ipt],Z[ipt],wz[ipt]*fake);
1403 pfy.Add(S[ipt],Y[ipt],1./(wy[ipt]*fake));
1404 pfz.Add(S[ipt],Z[ipt],1./(wz[ipt]*fake));
1405 double emx[3]={1./(wy[ipt]*fake),0,1./(wy[ipt]*fake)};
1406 cf.Add(S[ipt],Y[ipt],emx);
1407 int n,ipar,iDet = ha.iDet;
1408 static int myCall=0; myCall++;
1409 for (
int jk=0;jk<2;jk++) {
1410 int ip = 1 +ipt + jk*npt;
1411 ipar = IPar(iDet,jk,&n);
1413 for (
int in=0;in<n;in++) {toPars[ipar+in][ip]+=ha.A[jk][in];}
1420 static int testIt=1;
1421 if (testIt) {testIt--; ply.TestIt(); plz.TestIt(); }
1423 TVectorD dW(npt21),dWy(npt),dWz(npt);
1424 TMatrixD dWW(npt21,npt21),dWWy(npt,npt),dWWz(npt,npt);
1425 double Xi2y = ply.Deriv(dWy,dWWy);
1426 double Xi2z = plz.Deriv(dWz,dWWz);
1427 double Fcn = Xi2y+Xi2z;
1432 double gi[2][3],gj[2][3],G[2][3][3];
1433 for (
int ipt=0;ipt<npt;ipt++) {
1434 int idx[3]={0,ipt+1,ipt+1+npt};
1435 myDers(mDat[0],wy[ipt],wz[ipt],pt[ipt].dens,gi,G);
1436 for (
int i=0;i<3;i++) {
1437 dW[idx[i]] += dWy[ipt]*gi[0][i]+dWz[ipt]*gi[1][i];
1438 for (
int j=0;j<=i;j++) {
1439 dWW[idx[i]][idx[j]] += dWy[ipt]*G[0][i][j]+dWz[ipt]*G[1][i][j];
1441 for (
int jpt=0;jpt<npt;jpt++) {
1442 int jdx[3]={0,jpt+1,jpt+1+npt};
1443 myDers(mDat[0],wy[jpt],wz[jpt],pt[jpt].dens,gj,0);
1445 for (
int i=0;i<3;i++) {
1446 for (
int j=0;j<=i;j++) {
1447 if(idx[i]<jdx[j])
break;
1448 dWW[idx[i]][jdx[j]] += dWWy[ipt][jpt]*gi[0][i]*gj[0][j]
1449 +dWWz[ipt][jpt]*gi[1][i]*gj[1][j];
1454 double C,Cd[3],Cdd[3][3];
1455 for (
int ipt=0;ipt<npt;ipt++) {
1456 int idx[3]={0,ipt+1,ipt+1+npt};
1457 C = myFake( mDat[0],wy[ipt],wz[ipt],pt[ipt].dens,Cd,Cdd);
1458 Fcn += - log(wy[ipt]) - log(wz[ipt]) - log(C);
1459 dW[idx[1]] += -1./wy[ipt];
1460 dW[idx[2]] += -1./wz[ipt];
1461 dWW[idx[1]][idx[1]]+= 1./pow(wy[ipt],2);
1462 dWW[idx[2]][idx[2]]+= 1./pow(wz[ipt],2);
1463 for (
int i=0;i<3;i++) {
1464 dW[idx[i]] += - Cd[i]/C;
1465 for (
int j=0;j<=i;j++) {
1466 dWW[idx[i]][idx[j]] += (-Cdd[i][j]+Cd[i]*Cd[j]/C)/C;
1470 for (
int ii=0;ii<npt21;ii++) {
1471 if (ii && ii<=npt) wy[ii-1]*=cos2Psi[ii];
1472 dW[ii] /=cos2Psi[ii];
1473 for (
int jj=0;jj<=ii;jj++) {
1474 dWW[ii][jj]/=cos2Psi[ii]*cos2Psi[jj];
1479 wt.SetSub(1,wy); wt.SetSub(1+npt,wz);
1480 for (
int ii=1;ii<npt21;ii++) {
1481 double wi = wt[ii],wi2 =wi*wi;
1484 for (
int jj=1;jj<=ii;jj++) {
1485 double wj2 = wt[jj]*wt[jj];
1486 dWW[ii][jj] *= wi2*wj2;
1488 dWW[ii][ii] += -2*dW[ii]*wi;
1493 for (
int i=1;i<npt21;i++) {
1494 for (
int j=0;j< i;j++) {
1495 assert(fabs(dWW[j][i])<=0);
1496 dWW[j][i] = dWW[i][j];
1501 myTCL::mxmlrtS(toPars,dWW,Dij);
1502 for (
int i=0;i<mNPars;i++) {
1503 for (
int j=0;j<i;j++) {
1504 assert(fabs(dWW[i][j]-dWW[j][i])<1e-10);}}
1508 double HitPars_t::DERIV(
int npt,
const MyPull *pt,TVectorD &Di,TMatrixD &Dij,
int maxTrk)
1511 Di.ResizeTo(mNPars);
1512 Dij.ResizeTo(mNPars,mNPars);
1513 Di = 0.; Dij=0.; mNTrks=0;
1514 TVectorD Ti ,TiM (mNPars);
1515 TMatrixD Tij,TijM(mNPars,mNPars);
1516 int jl=0,trk=pt[0].trk;
1518 double sum=0,sumM=0;
1519 int NSave = (int)sqrt((npt/30.));
1521 for (
int jr=1; 1; jr++) {
1522 double xl0 = xl; xl = pt[jr].xyz[0];
1523 if (jr<npt && pt[jr].trk==trk && xl0<xl)
continue;
1526 double tsum = Deriv(n,pt+jl,Ti,Tij);
1531 if (mNTrks>=maxTrk)
break;
1532 if (((mNTrks+1)%NSave)==0 ) {
1533 sumM += sum; sum= 0.;
1534 TiM += Di ; Di = 0.;
1535 TijM += Dij; Dij= 0.;
1548 void HitPars_t::myDers(
double fake,
double wy,
double wz,
double dens
1549 ,
double g[2][3],
double G[2][3][3])
1554 double u[3]={fake,wy,wz};
1555 double Cd[3],Cdd[3][3];
1556 double (*myCdd)[3] = Cdd;
1558 double C0 = myFake(fake,wy,wz,dens,Cd,myCdd);
1560 memset(g[0],0,2*3*
sizeof(g[0][0]));
1561 for (
int iyz=0;iyz<2;iyz++) {
1562 for (
int ivar=0;ivar<3;ivar++) {
1563 g[iyz][ivar] = u[iyz+1]*Cd[ivar];
1564 if (ivar==iyz+1) g[iyz][ivar]+= C0; }}
1568 memset(G[0][0],0,2*3*3*
sizeof(G[0][0][0]));
1569 for (
int iyz=0;iyz<2;iyz++) {
1570 for (
int i=0;i<3;i++) {
1571 for (
int j=0;j<3;j++) {
1572 G[iyz][i][j] = u[iyz+1]*Cdd[i][j];
1573 if (i==iyz+1) G[iyz][i][j]+=Cd[j];
1574 if (j==iyz+1) G[iyz][i][j]+=Cd[i];
1579 double HitPars_t::myFake(
double fake,
double wy,
double wz,
double dens
1580 ,
double Cd[3],
double Cdd[3][3])
1585 double dens2 = 2*dens;
1587 double A = 3.14/sqrt(wy*wz);
1588 double Ay = -0.5*A/wy ;
1589 double Az = -0.5*A/wz ;
1591 double C0 = (1+fake*dens2*A);
1594 Cd[1] = fake*dens2*Ay;
1595 Cd[2] = fake*dens2*Az;
1596 if (!Cdd)
return C0;
1598 double Ayy = 0.5*(-Ay + A/wy)/wy;
1599 double Ayz = 0.5*(-Az )/wy;
1600 double Azz = 0.5*(-Az + A/wz)/wz;
1603 Cdd[0][1] = dens2*Ay;
1604 Cdd[0][2] = dens2*Az;
1605 Cdd[1][0] = Cdd[0][1];
1606 Cdd[1][1] = fake*dens2*Ayy;
1607 Cdd[1][2] = fake*dens2*Ayz;
1608 Cdd[2][0] = Cdd[0][2];
1609 Cdd[2][1] = Cdd[1][2];
1610 Cdd[2][2] = fake*dens2*Azz;
1614 void HitPars_t::Print(
const HitPars_t *init)
const
1616 const char *TYZ[]={
"y",
"z"};
1619 printf(
"HitPars(Fake ) ");
1620 bnd = (Lim(0))?
"*":
" ";
1621 if (init) printf(
"\t ");
1622 printf(
"\tpout=%8.4g(+-%8.4g)%s\n",mDat[0],mDrr[0],bnd);
1624 for (
int iDet=0;iDet<mNDets;iDet++) {
1625 for (
int iYZ=0;iYZ<2;iYZ++) {
1626 int ln = Len(iDet,iYZ);
1627 int ipar0 = IPar(iDet,iYZ);
1629 for (
int ip=0;ip<ln;ip++) {
1630 bnd = (Lim(ipar0+ip))?
"*":
" ";
1631 double p = mPars[iDet][iYZ][ip];
1632 double e = mErrs[iDet][iYZ][ip];
1633 printf(
"HitPars(%d,%s,%d) ",iDet,TYZ[iYZ],ip);
1635 printf(
"\tinit=%8.4g ",init->mPars[iDet][iYZ][ip]);}
1636 printf(
"\tpout=%8.4g(+-%8.4g)%s",p,e,bnd);
1642 double HitPars_t::Diff(
const HitPars_t &init)
const
1645 for (
int i=0;i<mNPars;i++) {
1646 double dif = fabs((*
this)[i]-init[i]);
1647 double err = init.Err(i);
1648 if (err<=0) err = 0.5*((*this)[i]+init[i])+1e-10;
1650 if (pctMax<dif) pctMax=dif;
1655 int HitPars_t::Test(
int npt,
const MyPull *pt)
const
1662 int npars = HP.NPars();
1663 double fcn = HP.DERIV(npt,pt,Di,Dij,kNTrkTst);
1664 for (
int i=0;i<npars;i++) {
1666 double delta = fabs(sav)*1e-3;
1667 if (delta<1e-6) delta=1e-6;
1669 double fcnT = HP.DERIV(npt,pt,DiT,DijT,kNTrkTst);
1671 double ana = 0.5*(Di[i]+DiT[i]);
1672 double num = (fcnT-fcn)/delta;
1673 double dif = (num-ana)/(fabs(num+ana)+1e-5);
1674 if (fabs(dif)>0.001)
1675 printf(
"\nDer(%2d): ana = %g \tnum = %g \tdif = %g\n\n",i,ana,num,dif);
1676 for (
int k=0;k<npars;k++) {
1677 ana = 0.5*(Dij[i][k]+DijT[i][k]);
1678 num = (DiT[k]-Di[k])/delta;
1679 dif = (num-ana)/(fabs(num+ana)+1e-5);
1680 if (fabs(dif)>0.001)
1681 printf(
"Der(%2d,%2d): ana = %g \tnum = %g \tdif = %g\n",i,k,ana,num,dif);
1688 double HitPars_t::Err(
const double Pars[3],
int nPars,
const double A[3])
1690 static const double tenMicrons = 1e-3;
1691 static const double min2Err = tenMicrons*tenMicrons;
1692 static const double max2Err = 1.;
1693 double err = TCL::vdot(A,Pars,nPars);
1694 if (nPars<=1)
return err;
1695 if (err<min2Err) err=min2Err;
1696 if (err>max2Err) err=max2Err;
1700 void HitPars_t::Limit()
1702 for (
int i=0;i<mNPars;i++) {
1703 if (mDat[i]<mMin[i]) mDat[i]=mMin[i];
1704 if (mDat[i]>mMax[i]) mDat[i]=mMax[i];
1709 void HitPars_t::Prep(
int npt,
const MyPull *pt,TVectorD &Y,TVectorD &Z
1710 ,TVectorD &S,TVectorD &cos2Psi)
1712 static int myDebug=0;
1717 if (myDebug) Show(npt,pt);
1718 int npt21 = npt*2+1;
1719 cos2Psi.ResizeTo(npt21);cos2Psi = 1.;
1722 for (
int ipt=0;ipt<npt;ipt++) {
1724 point[0] = pt[ipt].xhg();
1725 point[1] = pt[ipt].yhg();
1726 point[2] = pt[ipt].zhg();
1727 helx.Add(point[0],point[1],point[2]);
1728 double emx[3]={pow(pt[ipt].hye,2),0,pow(pt[ipt].hye,2)};
1729 helx.AddErr(emx,pow(pt[ipt].hze,2));
1734 for (
int ipt=0;ipt<npt;ipt++) {
1736 point[0] = pt[ipt].xhg();
1737 point[1] = pt[ipt].yhg();
1738 point[2] = pt[ipt].zhg();
1739 double ds = move.Path(point[0],point[1]);
1742 TVector3 pos(move.Pos());
1743 TVector3 dir(move.Dir());
1744 TVector3 nor(dir[1],-dir[0],0.); nor = nor.Unit();
1745 double dy = (point-pos)*nor;
1746 double dz = point[2]-pos[2];
1750 cos2Psi[ipt+1]=pow(cos(pt[ipt].psi),2);
1755 void HitPars_t::Show(
int npt,
const MyPull *pt)
1763 static TCanvas *myCanvas=0;
1764 static TGraph *graph[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
1766 float X[3][3][100],Y[3][3][100];
1769 if (!myCanvas) {myCanvas =
new TCanvas(
"C1",
"",600,800);
1770 myCanvas->Divide(1,3);}
1772 double curv = 0,xPrev,yPrev;
int nCurv = 0;
1773 for (
int i=0;i<9;i++) {
delete graph[0][i];graph[0][i]=0;}
1774 for (
int ig=0;ig<3;ig++) {
1778 for (
int ipt=0;ipt<npt;ipt++) {
1779 const MyPull *node = pt+ipt;
1781 double xNode = node->x_g();
1782 double yNode = node->y_g();
1784 double ds = sqrt(pow(xNode-xPrev,2)+pow(yNode-yPrev,2));
1785 double si = 0.5*ds*curv;
if (si>0.99) si=0.99;
1786 if (si>0.01) ds = 2*asin(si)/curv;
1792 if (ig==0) { curv += node->curv; nCurv++;
continue;}
1794 X[0][ig][n] = node->x_g();
1795 Y[0][ig][n] = node->y_g();
1796 Y[2][ig][n] = node->z_g();
1798 X[0][ig][n] = node->xhg();
1799 Y[0][ig][n] = node->yhg();
1800 Y[2][ig][n] = node->zhg();
1804 float xh = X[0][ig][n]-X[0][ig][0];
1805 float yh = Y[0][ig][n]-Y[0][ig][0];
1806 float rh = xh*xh+yh*yh+1E-10;
1807 X[1][ig][n-1] = xh/rh;
1808 Y[1][ig][n-1] = yh/rh;
1813 if (ig==0) { curv=fabs(curv)/nCurv;
continue;}
1819 for (
int ip=0;ip<3;ip++) {
1820 double xMin=999,xMax=-999,yMin=999,yMax=-999;
1821 for (
int ig=1;ig<3;ig++) {
1822 for (
int j=0;j<N[ip][ig];j++) {
1823 double x = X[ip][ig][j];
1824 if (xMin> x) xMin = x;
1825 if (xMax< x) xMax = x;
1826 double y = Y[ip][ig][j];
1827 if (yMin> y) yMin = y;
1828 if (yMax< y) yMax = y;
1831 X[ip][0][0] = xMin; Y[ip][0][0] = yMin;
1832 X[ip][0][1] = xMin; Y[ip][0][1] = yMax;
1833 X[ip][0][2] = xMax; Y[ip][0][2] = yMin;
1834 X[ip][0][3] = xMax; Y[ip][0][3] = yMax;
1837 static const char *opt[]={
"AP",
"Same CP",
"Same *"};
1838 for (
int ip=0;ip<3;ip++) {
1839 for (
int ig =0;ig<3;ig++) {
1840 graph[ip][ig] =
new TGraph(N[ip][ig] , X[ip][ig], Y[ip][ig]);
1841 if(ig==2) graph[ip][ig]->SetMarkerColor(kRed);
1842 myCanvas->cd(ip+1); graph[ip][ig]->Draw(opt[ig]);
1849 if (!myCanvas)
return;
1850 myCanvas->Modified();
1852 while(!gSystem->ProcessEvents()){};
1855 int HitPars_t::Test()
1863 double myTCL::vmaxa(
const double *a,
int na)
1866 for (
int i=0;i<na;i++){
if (r < fabs(a[i])) r = fabs(a[i]);}
1870 double myTCL::vmaxa(
const TVectorD &a)
1872 return vmaxa(a.GetMatrixArray(),a.GetNrows());
1875 void myTCL::vfill(
double *a,
double f,
int na)
1877 for (
int i=0;i<na;i++) {a[i]=f;}
1880 void myTCL::eigen2(
const double err[3],
double lam[2],
double eig[2][2])
1883 double spur = err[0]+err[2];
1884 double det = err[0]*err[2]-err[1]*err[1];
1885 double dis = spur*spur-4*det;
1888 lam[0] = 0.5*(spur+dis);
1889 lam[1] = 0.5*(spur-dis);
1890 eig[0][0] = 1; eig[0][1]=0;
1891 if (dis>1e-6*spur) {
1892 if (fabs(err[0]-lam[0])>fabs(err[2]-lam[0])) {
1893 eig[0][1] = 1; eig[0][0]= -err[1]/(err[0]-lam[0]);
1895 eig[0][0] = 1; eig[0][1]= -err[1]/(err[2]-lam[0]);
1897 double tmp = sqrt(eig[0][0]*eig[0][0]+eig[0][1]*eig[0][1]);
1898 eig[0][0]/=tmp; eig[0][1]/=tmp;
1900 eig[1][0]=-eig[0][1]; eig[1][1]= eig[0][0];
1922 double myTCL::simpson(
const double *F,
double A,
double B,
int NP)
1925 assert(N2>0 && !(N2&1));
1929 for (
int N = 1;N<=N2-3;N+=2) {S1+=F[N];S2+=F[N+1];}
1931 double H=(F[0]+F[N2]+S1+S1)*(B-A)/(3*N2);
1935 void myTCL::mxmlrt(
const TMatrixD &A,
const TMatrixD &B,TMatrixD &X)
1937 int nRowA = A.GetNrows();
1938 int nColA = A.GetNcols();
1939 int nRowB = B.GetNrows();
1940 int nColB = B.GetNcols();
if(nColB){}
1941 assert(nColA ==nRowB);
1942 X.ResizeTo(nRowA,nRowA);
1943 TCL::mxmlrt(A.GetMatrixArray(),B.GetMatrixArray()
1944 ,X.GetMatrixArray(),nRowA,nColA);
1948 void myTCL::mxmlrtS(
const double *A,
const double *B,
double *X,
int nra,
int nca)
1950 TCL::vzero(X,nra*nra);
1951 for (
int i=0,ii=0;i<nra;i++,ii+=nca) {
1952 for (
int j=0,jj=0;j<nca;j++,jj+=nca) {
1953 if(!A[ii+j])
continue;
1954 for (
int k=0,kk=0;k<=i;k++,kk+=nca) {
1955 double &Xik =X[i*nra+k];
1956 for (
int l=0;l<nca;l++) {
1957 if(!A[kk+l])
continue;
1958 Xik +=A[ii+j]*A[kk+l]*B[jj+l];
1960 for (
int i=0;i<nra;i++){
1961 for (
int k=0;k<i ;k++){X[k*nra+i] = X[i*nra+k];}}
1964 void myTCL::mxmlrtS(
const TMatrixD &A,
const TMatrixD &B,TMatrixD &X)
1966 int nRowA = A.GetNrows();
1967 int nColA = A.GetNcols();
1968 int nRowB = B.GetNrows();
1969 int nColB = B.GetNcols();
if(nColB){}
1970 assert(nColA ==nRowB);
1971 X.ResizeTo(nRowA,nRowA);
1972 myTCL::mxmlrtS(A.GetMatrixArray(),B.GetMatrixArray()
1973 ,X.GetMatrixArray(),nRowA,nColA);
1977 double myTCL::vasum(
const double *a,
int na)
1980 for (
int i=0;i<na;i++) { sum += fabs(a[i]);}
1984 double myTCL::vasum(
const TVectorD &a)
1986 return vasum(a.GetMatrixArray(),a.GetNrows());
1989 int myTCL::SqProgSimple( TVectorD &x
1990 ,
const TVectorD &g,
const TMatrixD &G
1991 ,
const TVectorD &Min
1992 ,
const TVectorD &Max,
int iAktp)
1994 static int nCall=0; nCall++;
1995 enum {kINIT=0,kADDCONS,kFREECONS};
1997 int nPars = g.GetNrows();
1998 TVectorD xx(x),gg(g),add(nPars);
1999 TArrayI Side(nPars);
2000 int nCons=0,addCons = -1,freCons=-1,freSide=0,addSide=0,con=0;
2005 freCons=-1; freSide=0;
2006 if (nCons && kase==kFREECONS ) {
2007 double tryGra=kSMALL; freCons=-1;
2008 for (
int ix=0;ix<nPars;ix++) {
2009 if(!Side[ix])
continue;
2010 double gra = gg[ix]*Side[ix];
2011 if (gra< tryGra)
continue;
2012 if (gra>=maxGra)
continue;
2013 freCons=ix; tryGra=gra;
2017 freSide = Side[freCons];
2023 if(kase==kFREECONS && freCons<0) {
break;}
2029 for (
int ix=0;ix<nPars;ix++) {
2030 if (Side[ix]==0)
continue;
2031 for (
int jx=0;jx<nPars;jx++) {S[ix][jx]=0; S[jx][ix]=0;}
2032 S[ix][ix]=1; B[ix]=0;
2036 double det=S.Determinant();
2037 if (fabs(det)<1e-100)
return -99;
2042 double along = B*add;
2043 if (along>0) add*=(-1.);
2048 double bSb = (B*(S*B));
2049 double tau = -bb/(fabs(bSb)+3e-33);
2053 if(kase==kFREECONS && freSide) {
2054 if (add[freCons]*freSide > -kSMALL) {
2055 Side[freCons]=freSide; nCons++;
continue;}
2060 addCons = -1; addSide = 0;
2062 for (
int ix=0;ix<nPars;ix++) {
2063 if (Side[ix]) {add[ix]=0; con = 100*con+ix+1;
continue;}
2064 double xi = xx[ix]+fak*add[ix];
2065 if (xi < Min[ix]){fak = (Min[ix]-xx[ix])/add[ix]; addCons=ix;addSide=-1;}
2066 if (xi > Max[ix]){fak = (Max[ix]-xx[ix])/add[ix]; addCons=ix;addSide= 1;}
2067 assert(fak<=1. && fak>=0.);
2073 kase = kFREECONS;
if (!addSide)
continue;
2075 xx[addCons] = (addSide<0)? Min[addCons]:Max[addCons];
2077 Side[addCons] = addSide ;nCons++;
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".