macros/calib/fiterr.C

00001 //#ifndef __CINT__ 00002 #include <stdio.h> 00003 #include <iostream> 00004 #include <fstream> 00005 #include "TSystem.h" 00006 #include "TBenchmark.h" 00007 #include "TFile.h" 00008 #include "TTree.h" 00009 #include "TH1.h" 00010 #include "TF1.h" 00011 #include "TCanvas.h" 00012 #include "TGraph.h" 00013 #include "TCL.h" 00014 #include "TMatrixD.h" 00015 #include "TRandom.h" 00016 #include "TVectorD.h" 00017 #include "TVector2.h" 00018 #include "TVector3.h" 00019 #include "StarRoot/TTreeIter.h" 00020 #include "TTable.h" 00021 #include "TInterpreter.h" 00022 #include "TPolinom.h" 00023 #include "THelixTrack.h" 00024 #include <vector> 00025 //#endif 00026 #define SQ(X) ((X)*(X)) 00027 #define PW2(X) ((X)*(X)) 00028 #define PW3(X) ((X)*(X)*(X)) 00029 00030 enum {kNOBAGR=0,kNDETS=4,kMINHITS=50}; 00031 static const double WINDOW_NSTD=3; 00032 00033 static const double kAGREE=1e-7,kSMALL=1e-9,kBIG=1.,kDAMPR=0.1; 00034 static const int MinErr[4][2] = {{200,200},{200,200},{30,500},{20,20}}; 00035 static char gTimeStamp[16]={0}; 00036 class MyPull; 00037 class HitPars_t; 00038 int fiterr(const char *opt); 00039 double Fit(HitPars_t &pout); 00040 void AveRes(); 00041 double AveErr(); 00042 int kind(double xl); 00043 void DbInit(); 00044 void DbDflt(); 00045 void DbEnd(); 00046 void Init(HitPars_t &hitp); 00047 void HInit(); 00048 void HFit(); 00049 void HEnd(); 00050 void CheckErr(); 00051 void FillPulls(int befAft); 00052 double newPull(int iYZ,const MyPull& myRes,const HitPars_t &pars); 00053 TBranch *tb=0; 00054 TFile *pulFile =0; 00055 TTree *pulTree=0; 00056 TH1F *hz=0; 00057 TH1F *hx=0; 00058 TH1F *hh[100]; 00059 TCanvas *C[10]; 00060 00061 class myTCL { 00062 public: 00063 static double vmaxa (const double *a, int na); 00064 static double vmaxa (const TVectorD &a); 00065 static void vfill (double *a,double f,int na); 00066 static void mxmlrt(const TMatrixD &A,const TMatrixD &B,TMatrixD &X); 00067 static void mxmlrtS(const TMatrixD &A,const TMatrixD &B,TMatrixD &X); 00068 static void mxmlrtS(const double *A,const double *B,double *X,int nra,int nca); 00069 static void eigen2(const double err[3], double lam[2], double eig[2][2]); 00070 static double simpson(const double *F,double A,double B,int NP); 00071 static double vasum(const double *a, int na); 00072 static double vasum(const TVectorD &a); 00073 static int SqProgSimple( TVectorD &x 00074 ,const TVectorD &g,const TMatrixD &G 00075 ,const TVectorD &Min 00076 ,const TVectorD &Max,int iAkt); 00077 }; 00078 00079 00080 class HitAccr { 00081 public: 00082 int iDet; 00083 double A[2][3]; 00084 double Pull[2]; 00085 double PredErr[2]; 00086 }; 00087 00088 00089 class MyPull { 00090 public: 00091 float x_g() const { return grf*cos(gpf);} 00092 float y_g() const { return grf*sin(gpf);} 00093 float z_g() const { return gzf ;} 00094 00095 float xhg() const { return xyz[0]*cos(ang) - xyz[1]*sin(ang);} 00096 float yhg() const { return xyz[0]*sin(ang) + xyz[1]*cos(ang);} 00097 float zhg() const { return xyz[2] ;} 00098 public: 00099 int trk; 00100 float xyz[3]; 00101 float psi; 00102 float dip; 00103 float pt; 00104 float ypul; 00105 float zpul; 00106 float yfit; 00107 float zfit; 00108 float pye; //pull y errvmaxa 00109 float pze; //pull z err 00110 float uyy; //untouched y err 00111 float uzz; //untouched z err 00112 float fye; //fited y err 00113 float fze; //fited z err 00114 float hye; //hited y err 00115 float hze; //hited z err 00116 float curv; //curva 00117 float dens; 00118 float grf; // Rxy of Fit in global Sti frame 00119 float gpf; // Phi of Fit in global Sti frame 00120 float gzf; // Z of Fit in global Sti frame 00121 float ang; // rotation angle 00122 }; 00123 00124 class HitPars_t { 00125 public: 00126 HitPars_t(); 00127 HitPars_t(const HitPars_t &fr); 00128 const double &Err(int idx) const {return mDrr[idx];} 00129 double &Err(int idx) {return mDrr[idx];} 00130 double Err( int iYZ,const HitAccr &accr) const; 00131 double Err(int iDet,int iYZ,const double A[3]) const; 00132 const double &operator[](int i) const; 00133 double &operator[](int i); 00134 HitPars_t &operator= (const HitPars_t &fr); 00135 HitPars_t &operator* (double f); 00136 HitPars_t &operator+=(const double *f); 00137 HitPars_t &operator= (double f); 00138 HitPars_t &operator+=(const TVectorD &add); 00139 int NPars() const {return mNPars ;} 00140 int Len(int iDet,int iYZ=0) const {return mLen[iDet][iYZ];} 00141 int Lim(int i) const ; 00142 const double &Min(int i) const {return mMin[i];} 00143 double &Min(int i) {return mMin[i];} 00144 const double &Max(int i) const {return mMax[i];} 00145 double &Max(int i) {return mMax[i];} 00146 00147 const double &Min(int iDet,int iYZ,int i) const {return mMin[IPar(iDet,iYZ)+i];} 00148 const double &Max(int iDet,int iYZ,int i) const {return mMax[IPar(iDet,iYZ)+i];} 00149 double &Min(int iDet,int iYZ,int i) {return mMin[IPar(iDet,iYZ)+i];} 00150 double &Max(int iDet,int iYZ,int i) {return mMax[IPar(iDet,iYZ)+i];} 00151 00152 int IPar(int iDet,int iYZ,int *npars=0) const; 00153 void Set(int iDet,int iYZ,int nini,const double *ini); 00154 void Limit(); 00155 double Deriv(int npt, const MyPull *pt,TVectorD &Di,TMatrixD &Dij) const; 00156 double DERIV(int npt, const MyPull *pt,TVectorD &Di,TMatrixD &Dij,int maxTrk=9999999); 00157 int Test(int npt, const MyPull *pt) const; 00158 void Print(const HitPars_t *init=0) const; 00159 double Diff (const HitPars_t &init) const; 00160 static void Prep(int npt, const MyPull *pt,TVectorD &Y,TVectorD &Z 00161 ,TVectorD &S,TVectorD &cos2Psi); 00162 static int Test(); 00163 static void HitCond(const MyPull& myRes,HitAccr &acc); 00164 static void Show(int npt,const MyPull *pt); 00165 static double Dens(double rxy,int ntk); 00166 static double Err(const double Pars[3],int nPars,const double A[3]); 00167 static void myDers( double fake, double wy, double wz, double dens 00168 , double g[2][3],double G[2][3][3]); 00169 static double myFake( double fake, double wy, double wz, double dens 00170 , double Cd[3],double Cdd[3][3]); 00171 public: 00172 int mNDets; 00173 int mNPars; 00174 int mNTrks; 00175 int mLen[kNDETS][2]; 00176 double *mPars[kNDETS][2]; //mPars[iDet][iYZ][3] 00177 double *mErrs[kNDETS][2]; //mErrs[iDet][iYZ][3] 00178 double mDat[1+kNDETS*2*3]; 00179 double mDrr[1+kNDETS*2*3]; 00180 double mMin[1+kNDETS*2*3]; 00181 double mMax[1+kNDETS*2*3]; 00182 00183 private: 00184 static void myTrans( double fake,double wy, double wz, double dens, TMatrixD *mx); 00185 }; 00186 HitPars_t operator+(const HitPars_t &a,const double *add); 00187 HitPars_t operator+(const HitPars_t &a,const TVectorD &add); 00188 00189 00190 00191 class LogDensity { 00192 public: 00193 LogDensity(double y,double z,double dens,double A,double B); 00194 void Set(double y,double z,double dens,double A,double B); 00195 void Set(double dens,double A,double B); 00196 double Fcn(); 00197 double Deriv(int dXi2,int dMu=0); 00198 double Deriv(double dd[4][3]); 00199 int Teriv(); 00200 double dNdRho() const {return mMuF;} 00201 static void Test(); 00202 static void Test2(); 00203 private: 00204 double mXi2; 00205 double mYZ[2]; 00206 double mMu; 00207 double mMuF; 00208 double mAB[2]; 00209 double mFcn; 00210 }; 00211 00212 //______________________________________________________________________________ 00213 class Poli2 { 00214 public: 00215 Poli2(int npw=1); 00216 Poli2(int npw,int n,const double *X,const double *Y,const double *W); 00217 void Init(); 00218 void Clear(); 00219 void Add(double x, double y, double w); 00220 double Xi2() const {return fXi2;} 00221 double Xi2(int ipt) const; 00222 double EvalXi2() const; 00223 int Pw() const {return fPw ;} 00224 int NPt() const {return fN ;} 00225 double Fun( double x ) const; 00226 double dXi2dW( int ipt ) const; 00227 double d2Xi2d2W( int ipt,int jpt ) const; 00228 double Deriv( TVectorD &Di, TMatrixD &Dij ) const; 00229 void TestIt() const; 00230 void MyTest() const; 00231 static void Test(); 00232 private: 00233 int fPw; 00234 char fBeg[1]; 00235 int fN; 00236 double fX[100]; 00237 double fY[100]; 00238 double fW[100]; 00239 double fXi2; 00240 double fX0,fY0; 00241 char fEnd[1]; 00242 TVectorD fP; 00243 TVectorD fB; 00244 TMatrixD fA; 00245 TMatrixD fAi; 00246 }; 00247 00248 00249 00250 #if !defined(__MAKECINT__) 00251 00252 00253 00254 00255 00256 std::vector<MyPull> MyVect; 00257 double aveRes[4][6],aveTrk[4][2][3]; 00258 int numRes[4]; 00259 double pSTI[8][3] = {{0.000421985 ,0.00124327 ,0.0257111 } 00260 ,{0.000402954 ,0.00346896 ,0.0377259 } 00261 ,{0. ,0.0009366 ,0.0004967 } 00262 ,{0.00018648 ,0.00507244 ,0.002654 } 00263 ,{0.0030*0.0030 ,0.0 ,0.0 } 00264 ,{0.0700*0.0700 ,0.0 ,0.0 } 00265 ,{0.0080*0.0080 ,0.0 ,0.0 } 00266 ,{0.0080*0.0080 ,0.0 ,0.0 }}; 00267 HitPars_t HitErr; 00268 00269 static const char *DETS[]={"OutY","OutZ","InnY","InnZ" 00270 ,"SsdY","SsdZ","SvtY","SvtZ"}; 00271 static const char *DETZ[]={"Out" ,"Inn","Ssd","Svt"}; 00272 int FitOk[4]={0,0,0,0}; 00273 static char dbFile[4][100] = { 00274 "StarDb/Calibrations/tracker/tpcOuterHitError.20050101.235959.C", 00275 "StarDb/Calibrations/tracker/tpcInnerHitError.20050101.235959.C", 00276 "StarDb/Calibrations/tracker/ssdHitError.20050101.235959.C" , 00277 "StarDb/Calibrations/tracker/svtHitError.20050101.235959.C" }; 00278 00279 static TTable *dbTab[4]; 00280 00281 int fiterr(const char *opt) 00282 { 00283 if (!opt) opt = "H"; 00284 int optH = strstr(opt,"H")!=0; 00285 int optU = strstr(opt,"U")!=0; 00286 int optT = strstr(opt,"T")!=0; 00287 memcpy(gTimeStamp,strstr(opt,"20"),15); 00288 00289 DbInit(); 00290 if (optH) HInit(); 00291 TTreeIter th(pulTree); 00292 th.AddFile("pulls.root"); 00293 // th.ls(); 00294 // return; 00295 const int &run = th("mRun"); 00296 const int &evt = th("mEvt"); 00297 //const int *&mNTrks = th("mNTrks[2]"); 00298 const int &mTrksG = th("mTrksG"); 00299 const int &nGlobs = th("mHitsG"); 00300 const float *&mCurv = th("mHitsG.mCurv"); 00301 const float *&mPt = th("mHitsG.mPt"); 00302 const short *&mTrackNumber = th("mHitsG.mTrackNumber"); 00303 const float *&mNormalRefAngle = th("mHitsG.mNormalRefAngle"); 00304 const UChar_t *&nTpcHits = th("mHitsG.nTpcHits"); 00305 const UChar_t *&nSsdHits = th("mHitsG.nSsdHits"); 00306 const UChar_t *&nSvtHits = th("mHitsG.nSvtHits"); 00307 const float *&lYPul = th("mHitsG.lYPul"); 00308 const float *&lZPul = th("mHitsG.lZPul"); 00309 const float *&lXHit = th("mHitsG.lXHit"); 00310 const float *&lYHit = th("mHitsG.lYHit"); 00311 const float *&lZHit = th("mHitsG.lZHit"); 00312 const float *&lYFit = th("mHitsG.lYFit"); 00313 const float *&lZFit = th("mHitsG.lZFit"); 00314 const float *&lPsi = th("mHitsG.lPsi"); 00315 const float *&lDip = th("mHitsG.lDip"); 00316 const float *&lYFitErr = th("mHitsG.lYFitErr"); 00317 const float *&lZFitErr = th("mHitsG.lZFitErr"); 00318 const float *&lYHitErr = th("mHitsG.lYHitErr"); 00319 const float *&lZHitErr = th("mHitsG.lZHitErr"); 00320 const float *&lYPulErr = th("mHitsG.lYPulErr"); 00321 const float *&lZPulErr = th("mHitsG.lZPulErr"); 00322 const float *&gRFit = th("mHitsG.gRFit"); 00323 const float *&gPFit = th("mHitsG.gPFit"); 00324 const float *&gZFit = th("mHitsG.gZFit"); 00325 00326 printf("*lYPul = %p\n",lYPul); 00327 printf("&run=%p &evt=%p\n",&run,&evt); 00328 MyPull mp; 00329 MyVect.clear(); 00330 int nTpc=0,nPre=0,iTk=-1,iTkSkip=-1; 00331 while (th.Next()) 00332 { 00333 // printf("serial = %d run=%d evt=%d nGlo = %d\n",n,run,evt,nGlobs);n++; 00334 float rxy=0; 00335 for (int ih=0;ih<nGlobs;ih++) { 00336 if (mTrackNumber[ih]==iTkSkip) continue; 00337 float rxy00 = rxy; rxy=lXHit[ih]; 00338 if (mTrackNumber[ih]!=iTk || rxy<rxy00) { 00339 iTk = mTrackNumber[ih]; 00340 iTkSkip = iTk; 00341 if (nTpcHits[ih] <25) continue; 00342 if (fabs(mCurv[ih])>1./200) continue; 00343 if (fabs(mPt[ih]/cos(lDip[ih]))<0.5) continue; 00344 int nSS = nSsdHits[ih]+nSvtHits[ih]; 00345 if (nSS && nSS<2) continue; 00346 if (!nSS && nPre && nTpc>100 && nTpc>3*nPre) continue; 00347 nTpc += (nSS==0); 00348 nPre += (nSS!=0); 00349 iTkSkip = -1; 00350 } 00351 00352 memset(&mp,0,sizeof(mp)); 00353 mp.trk = mTrackNumber[ih]; 00354 mp.pye = lYPulErr[ih]; 00355 mp.pze = lZPulErr[ih]; 00356 float uyy = (lYPulErr[ih]-lYHitErr[ih])*(lYHitErr[ih]+lYPulErr[ih]); 00357 // printf ("yy = %g %g %g \n",yy,lYHitErr[ih],lYPulErr[ih]); 00358 // if (uyy <1e-8 ) continue; 00359 float uzz = (lZPulErr[ih]-lZHitErr[ih])*(lZHitErr[ih]+lZPulErr[ih]); 00360 // printf ("zz = %g\n",zz); 00361 // if (uzz <1e-8 ) continue; 00362 mp.uyy = uyy; 00363 mp.uzz = uzz; 00364 mp.fye = lYFitErr[ih]; 00365 mp.fze = lZFitErr[ih]; 00366 mp.hye = lYHitErr[ih]; 00367 mp.hze = lZHitErr[ih]; 00368 mp.xyz[0] = lXHit[ih]; 00369 if (mp.xyz[0]<4) continue; 00370 mp.xyz[1] = lYHit[ih]; 00371 mp.xyz[2] = lZHit[ih]; 00372 mp.psi = lPsi[ih] ; 00373 mp.dip = lDip[ih] ; 00374 mp.ypul = lYPul[ih]; 00375 // if (fabs(mp.ypul)<1e-8) continue; 00376 mp.zpul = lZPul[ih]; 00377 // if (fabs(mp.zpul)<1e-8) continue; 00378 mp.yfit = lYFit[ih]; 00379 mp.zfit = lZFit[ih]; 00380 mp.dens = HitPars_t::Dens(mp.xyz[0],mTrksG); 00381 mp.grf = gRFit[ih]; 00382 mp.gpf = gPFit[ih]; 00383 mp.gzf = gZFit[ih]; 00384 mp.curv = mCurv[ih]; 00385 mp.ang = mNormalRefAngle[ih]; 00386 00387 MyVect.push_back(mp); 00388 00389 } 00390 // printf("lYPul[0]=%g\n",lYPul[0]); 00391 } 00392 printf("fiterr:: %d hits accepted\n\n",MyVect.size()); 00393 printf("fiterr:: %d Tpc and %d Svt/Ssd tracks accepted\n\n",nTpc,nPre); 00394 AveRes(); 00395 HFit(); 00396 DbDflt(); 00397 Init(HitErr); 00398 if (optH) CheckErr(); 00399 if (optH) FillPulls(0); 00400 if (optT) return HitErr.Test(MyVect.size(),&(MyVect[0])); 00401 00402 double maxPct = Fit(HitErr); 00403 maxPct= AveErr(); 00404 if (optH) FillPulls(1); 00405 if (optU) DbEnd(); 00406 if (optH) HEnd(); 00407 //return (maxPct<10) ? 99:0; 00408 return (maxPct< 3) ? 99:0; 00409 } 00410 //______________________________________________________________________________ 00411 //______________________________________________________________________________ 00412 LogDensity::LogDensity(double y,double z,double dens,double A,double B) 00413 { 00414 Set(y,z,dens,A,B); 00415 } 00416 //______________________________________________________________________________ 00417 void LogDensity::Set(double y,double z,double dens,double A,double B) 00418 { 00419 mYZ[0]=y*y; mYZ[1]=z*z; 00420 Set(dens,A,B); 00421 } 00422 //______________________________________________________________________________ 00423 void LogDensity::Set(double dens,double A,double B) 00424 { 00425 mAB[0] = A;mAB[1] = B; 00426 mXi2 = mYZ[0]/mAB[0]+mYZ[1]/mAB[1]; 00427 mMuF = TMath::Pi()*sqrt(mAB[0]*mAB[1]); 00428 mMu = mMuF*dens; 00429 mFcn = -(0.5+mMu)*mXi2 -0.5*log(mAB[0]*mAB[1])+log(0.5+mMu); 00430 00431 } 00432 //______________________________________________________________________________ 00433 double LogDensity::Fcn() 00434 { 00435 // k = Pi*Rho*a*b 00436 // Dtot(R2) = (0.5+k)exp(-(0.5+k)*R2)/(a*b) 00437 // 00438 return mFcn; 00439 } 00440 //______________________________________________________________________________ 00441 double LogDensity::Deriv(int dXi2,int dMu) 00442 { 00443 00444 int kase = dXi2+10*dMu; 00445 switch(kase) { 00446 case 0: return mFcn; 00447 case 1: return -(0.5+mMu); 00448 case 2: return 0; 00449 case 10: return (-mXi2 +1./(0.5+mMu)); 00450 case 20: return -1./pow(0.5+mMu,2); 00451 case 11: return -1; 00452 default: assert(0); return 0; 00453 } 00454 } 00455 //______________________________________________________________________________ 00456 double LogDensity::Deriv(double der[4][3]) 00457 { 00458 // fcn = -(0.5+k)*R2 +log(0.5+k)-log(a*b) 00459 // enum {kGrad=3}; 00460 int kGrad=3; 00461 double g[2][3],gg[2][3][3],d[2],dd[2][2]; 00462 g[0][0] = mMuF; 00463 g[0][1] = 0.5*mMu/mAB[0]; 00464 g[0][2] = 0.5*mMu/mAB[1]; 00465 g[1][0] =0 ; 00466 g[1][1] =-mYZ[0]/(mAB[0]*mAB[0]); 00467 g[1][2] =-mYZ[1]/(mAB[1]*mAB[1]); 00468 00469 gg[0][0][0] = 0; 00470 gg[0][0][1] = 0.5*mMuF/mAB[0]; 00471 gg[0][0][2] = 0.5*mMuF/mAB[1]; 00472 gg[0][1][0] = gg[0][0][1]; 00473 gg[0][1][1] =-0.25*mMu/(mAB[0]*mAB[0]); 00474 gg[0][1][2] = 0.25*mMu/(mAB[0]*mAB[1]); 00475 gg[0][2][0] = gg[0][0][2]; 00476 gg[0][2][1] = gg[0][1][2]; 00477 gg[0][2][2] =-0.25*mMu/(mAB[1]*mAB[1]); 00478 00479 gg[1][0][0] = 0; 00480 gg[1][0][1] = 0; 00481 gg[1][0][2] = 0; 00482 gg[1][1][0] = gg[1][0][1]; 00483 gg[1][1][1] =2*mYZ[0]/(mAB[0]*mAB[0]*mAB[0]); 00484 gg[1][1][2] = 0; 00485 gg[1][2][0] = gg[1][0][2]; 00486 gg[1][2][1] = gg[1][1][2]; 00487 gg[1][2][2] = 2*mYZ[1]/(mAB[1]*mAB[1]*mAB[1]); 00488 00489 00490 00491 00492 00493 d[0] = Deriv(0,1); 00494 d[1] = Deriv(1,0); 00495 dd[0][0] = Deriv(0,2); dd[1][1] = Deriv(2,0); 00496 dd[1][0] = Deriv(1,1); dd[0][1] = dd[1][0]; 00497 00498 double *gra = der[kGrad]; 00499 // for (int i=0;i<3;i++) { gra[i]=d[0]*g[0][i]+d[1]*g[1][i];} 00500 00501 00502 TCL::mxmpy2(g[0],d ,gra ,3,2,1); 00503 TCL::mxmltr(g[0],dd[0],der[0],3,2 ); 00504 00505 for (int muxi =0; muxi <2; muxi++) { 00506 TCL::vlinco(gg[muxi][0],d[muxi],der[0],1,der[0],3*3); 00507 } 00508 for (int i=0;i<2;i++) { 00509 gra[i+1] += -0.5/mAB[i]; 00510 der[i+1][i+1] += 0.5/(mAB[i]*mAB[i]); 00511 } 00512 return Fcn(); 00513 00514 } 00515 //______________________________________________________________________________ 00516 void LogDensity::Test2() 00517 { 00518 double Xi2Max=20, y=1,z=2,Mu=3.1,A=1.1*1.1,B=2.2*2.2; 00519 LogDensity ld( y,z,Mu,A,B); 00520 double fcn = ld.Fcn(); 00521 printf("fcn = %g\n",fcn); 00522 double sum=0; 00523 int n = 5000; 00524 double dXi2 = Xi2Max/n; 00525 double val2,val1=0,val0; 00526 00527 for (int i=0;i<n;i++) { 00528 double Xi2= (i+0.5)*dXi2; 00529 double y=sqrt(Xi2*A); 00530 double z=0; 00531 LogDensity ld( y,z,Mu,A,B); 00532 val2 =(ld.Fcn()); 00533 sum += exp(val2)*dXi2; 00534 if (i>1 && i<4) { 00535 double a1 = ld.Deriv(1); 00536 double n1 = (val2-val1)/dXi2; 00537 double a2 = ld.Deriv(2); 00538 double n2 = (val2-2*val1+val0)/dXi2/dXi2; 00539 printf("%d Deriv a1=%g n1=%g \ta2=%g n2=%g\n",i,a1,n1,a2,n2); 00540 } 00541 val0=val1; val1 = val2; 00542 } 00543 sum*= sqrt(A*B); 00544 printf("sum = %g ~= 1.0\n",sum); 00545 00546 double sml = 0.05; 00547 double dMu = Mu*sml; 00548 y=sqrt(0.7*Xi2Max*A); z=0; 00549 LogDensity ld0m( y,z,Mu ,A,B); 00550 double f = ld0m.dNdRho(); 00551 LogDensity ld1m( y,z,Mu+dMu,A,B); 00552 LogDensity ld2m( y,z,Mu+2*dMu,A,B); 00553 double a1 = f*(ld2m.Deriv(0,1)+ ld1m.Deriv(0,1) + ld0m.Deriv(0,1))/3; 00554 double n1 = (ld2m.Fcn() - ld0m.Fcn())/dMu*0.5; 00555 double a2 = f*f*(ld2m.Deriv(0,2)+ ld1m.Deriv(0,2) + ld0m.Deriv(0,2))/3; 00556 double n2 = (ld2m.Fcn() - 2*ld1m.Fcn()+ld0m.Fcn())/(dMu*dMu); 00557 printf("d/dMu a1=%g n1=%g \ta2=%g n2=%g\n",a1,n1,a2,n2); 00558 00559 double a11 = f*ld0m.Deriv(1,1); 00560 double n11 = (ld1m.Deriv(1,0)-ld0m.Deriv(1,0))/dMu; 00561 printf("d/dMu a11=%g n11=%g \n",a11,n11); 00562 00563 y=2;z=2; 00564 printf("Mu,A,B = %g %g %g\n",Mu,A,B); 00565 ld.Set ( y,z,Mu ,A ,B); 00566 LogDensity ld0( y,z,Mu*(1+sml),A ,B); 00567 LogDensity ld1( y,z,Mu ,A*(1+sml),B); 00568 LogDensity ld2( y,z,Mu ,A ,B*(1+sml)); 00569 double tst[3],der[4][3],ner[4][3],par[3]={Mu,A,B}; 00570 00571 ld.Deriv(der); 00572 tst[0] = (ld0.Fcn()-ld.Fcn())/(Mu*sml); 00573 tst[1] = (ld1.Fcn()-ld.Fcn())/(A *sml); 00574 tst[2] = (ld2.Fcn()-ld.Fcn())/(B *sml); 00575 for (int i=0;i<3;i++) { 00576 printf("Grad: A%d = %g \tN%d = %g\n",i,tst[i],i,der[3][i]); 00577 } 00578 for (int i=0;i<3;i++) { 00579 double sav = par[i]; par[i] *=(1+sml); 00580 ld1.Set( y,z,par[0],par[1],par[2]); 00581 par[i] =sav; 00582 ld1.Deriv(ner); 00583 for (int j=0;j<3;j++) { 00584 double num = (ner[3][j]-der[3][j])/(par[i]*sml); 00585 printf("Der[%d][%d]: A = %g \tN = %g\n",i,j,der[i][j],num);} 00586 } 00587 00588 } 00589 //______________________________________________________________________________ 00590 void LogDensity::Test() 00591 { 00592 double y=1,z=2,Mu=3.1,A=1.1*1.1,B=2.2*2.2; 00593 LogDensity ld( y,z,Mu,A,B); 00594 ld.Teriv(); 00595 } 00596 //______________________________________________________________________________ 00597 int LogDensity::Teriv() 00598 { 00599 00600 int iFail=0; 00601 LogDensity ld(*this); 00602 00603 double derA[4][3],derB[4][3],derC[4][3]; 00604 double par[3]={ld.mMu/ld.mMuF,ld.mAB[0],ld.mAB[1]}; 00605 static const double EPS = 0.001,SML=1e-4; 00606 double num,ana,dif,fcn0,fcn1,fcn2; 00607 00608 ld.Set(par[0],par[1],par[2]); 00609 fcn0=ld.Deriv(derA); 00610 for (int kase=0;kase<2;kase++) { 00611 for (int i=0;i<3;i++) { 00612 double sav = par[i]; 00613 double dlt = sav*EPS/(fabs(derA[3][i])+SML); 00614 if (dlt>sav*EPS) dlt = sav*EPS; 00615 if (dlt<1e-6) dlt=1e-6; 00616 00617 dlt*=2; 00618 for (int iter=0;iter<10;iter++) { 00619 dlt/=2; 00620 par[i] = sav-dlt; 00621 ld.Set(par[0],par[1],par[2]); 00622 fcn1 = ld.Deriv(derB); 00623 par[i] =sav+dlt; 00624 ld.Set(par[0],par[1],par[2]); 00625 fcn2 = ld.Deriv(derC); 00626 par[i] =sav; 00627 num = (fcn2-fcn1)/(2*dlt); 00628 ana = derA[3][i]; 00629 dif = (fcn1-fcn0)/dlt; 00630 dif = 2*fabs(num-dif)/(fabs(num+dif)+SML); 00631 if (dif>0.1) continue; 00632 } 00633 dif = 2*fabs(ana-num)/(fabs(ana+num)+SML); 00634 if (!kase && fabs(dif) >0.1) { 00635 iFail++; 00636 printf("Der(%d): ana = %g \tnum = %g \tdif = %g\n",i,ana,num,dif); 00637 } 00638 for (int j=0;kase && j<3;j++) { 00639 num = (derC[3][j]-derB[3][j])/(2*dlt); 00640 ana = derA[i][j]; 00641 dif = 2*fabs(ana-num)/(fabs(ana+num)+SML); 00642 if (dif <0.1) continue; 00643 if (fabs(ana*dlt) < 1e-5*fabs(derA[3][j])) continue; 00644 iFail++; 00645 printf("Der[%d][%d]: ana = %g \tnum = %g \tdif=%g\n",i,j,ana,num,dif);} 00646 }} 00647 return iFail; 00648 } 00649 //______________________________________________________________________________ 00650 Poli2::Poli2(int npw):fP(npw+1),fB(npw+1),fA(npw+1,npw+1),fAi(npw+1,npw+1) 00651 { 00652 fPw = npw; 00653 Clear(); 00654 00655 } 00656 //______________________________________________________________________________ 00657 void Poli2::Clear() 00658 { 00659 memset(fBeg,0,fEnd-fBeg+1); 00660 } 00661 //______________________________________________________________________________ 00662 Poli2::Poli2(int npw,int N,const double *X,const double *Y,const double *W) 00663 :fP(npw+1),fB(npw+1),fA(npw+1,npw+1),fAi(npw+1,npw+1) 00664 { 00665 fPw = npw; 00666 Clear(); 00667 fN = N; 00668 int nb = N*sizeof(double); 00669 memcpy(fX,X,nb); 00670 memcpy(fY,Y,nb); 00671 memcpy(fW,W,nb); 00672 } 00673 //______________________________________________________________________________ 00674 void Poli2::Add(double x, double y, double w) 00675 { 00676 fX[fN]=x; fY[fN]=y, fW[fN]=w; fN++; 00677 assert(fN<=100); 00678 } 00679 //______________________________________________________________________________ 00680 void Poli2::Init() 00681 { 00682 double Wt=0,Wx=0,Wy=0; 00683 for (int i=0;i<fN;i++) { Wt += fW[i]; Wx += fW[i]*fX[i];Wy += fW[i]*fY[i];} 00684 fX0 = Wx/Wt; fY0 = Wy/Wt; 00685 for (int i=0;i<fN;i++) { fX[i]-=fX0; fY[i]-=fY0;} 00686 00687 double A[3][3]={{0}},B[3]={0}; 00688 double x[3]={1}; 00689 fXi2=0; 00690 for (int i=0;i<fN;i++) { 00691 double w = fW[i]; 00692 x[1] = fX[i]; x[2]=x[1]*x[1]; 00693 double y = fY[i],y2=y*y; 00694 for (int j=0;j<=fPw;j++) { B[j] +=w*x[j]*y; 00695 for (int k=0;k<=j ;k++) { A[j][k] +=w*x[j]*x[k];}} 00696 fXi2 +=w*y2; 00697 } 00698 for (int j=0;j<=fPw;j++){ fB[j] = B[j]; 00699 for (int k=0;k<=j ;k++){ fA(j,k) = A[j][k]; fA(k,j)=A[j][k];}} 00700 00701 double det=0; 00702 fAi=fA;fAi.InvertFast(&det); 00703 fP=fAi*fB; 00704 fXi2 -= (fB*fP); 00705 00706 } 00707 //______________________________________________________________________________ 00708 double Poli2::Fun( double x ) const 00709 { 00710 x -= fX0; 00711 double xx[3]={1,x,x*x}; 00712 TVectorD XX(fPw+1,xx); 00713 return fP*XX + fY0; 00714 } 00715 //______________________________________________________________________________ 00716 double Poli2::Xi2(int ipt) const 00717 { 00718 double dy = Fun(fX[ipt]+fX0) - (fY[ipt]+fY0); 00719 return dy*dy*fW[ipt]; 00720 } 00721 //______________________________________________________________________________ 00722 double Poli2::EvalXi2() const 00723 { 00724 double sum=0; 00725 for (int ipt=0;ipt<fN;ipt++) {sum+=Xi2(ipt);} 00726 return sum; 00727 } 00728 //______________________________________________________________________________ 00729 double Poli2::dXi2dW( int ipt ) const 00730 { 00731 // Xi2 = B*Ai*B 00732 // dXi2 = 2*dB*Ai*B - B*Ai*dA*Ai*B 00733 // dXi2 = 2*dB*Ai*B - P*dA*P 00734 00735 double der = fY[ipt]*fY[ipt]; 00736 TVectorD dB(fPw+1); 00737 TMatrixD dA(fPw+1,fPw+1); 00738 double x[3]={1,fX[ipt],fX[ipt]*fX[ipt]}; 00739 for (int j=0;j<=fPw;j++) { dB[j] = x[j]*fY[ipt]; 00740 for (int k=0;k<=fPw;k++) { dA(j,k) = x[j]*x[k]; }} 00741 der -= (2*(dB*(fAi*fB))-(fP*(dA*fP))); 00742 return der; 00743 } 00744 //______________________________________________________________________________ 00745 //______________________________________________________________________________ 00746 double Poli2::d2Xi2d2W( int ipt,int jpt ) const 00747 { 00748 // P = Ai*B 00749 // dXi2/dWi = 2*diB*Ai*B - B*Ai*diA*Ai*B 00750 // d2Xi2/dWi/dWj = -2*diB*Ai*djA*Ai*B 00751 // +2*diB*Ai*djB 00752 // -2*djB*Ai*diA*Ai*B 00753 // +2*B*Ai*djA*Ai*diA*Ai*B 00754 // d2Xi2/dWi/dWj = -2*diB*Ai*djA*P 00755 // +2*diB*Ai*djB 00756 // -2*djB*Ai*diA*P 00757 // +2*P*djA*Ai*diA*P 00758 00759 double xi[3]={1,fX[ipt],fX[ipt]*fX[ipt]}; 00760 double xj[3]={1,fX[jpt],fX[jpt]*fX[jpt]}; 00761 00762 TVectorD diB(fPw+1) ,djB(fPw+1); 00763 TMatrixD diA(fPw+1,fPw+1),djA(fPw+1,fPw+1); 00764 for (int j=0;j<=fPw;j++) { diB[j]=fY[ipt]*xi[j]; djB[j]=fY[jpt]*xj[j]; 00765 for (int k=0;k<=fPw;k++) { diA(j,k) = xi[j]*xi[k]; djA(j,k) = xj[j]*xj[k];}} 00766 double der = -2*(-((fAi*diB)*(djA*fP)) 00767 +(diB*(fAi*djB)) 00768 -((fAi*djB)*(diA*fP)) 00769 +(fP*(djA*(fAi*(diA*fP))))); 00770 return der; 00771 } 00772 //______________________________________________________________________________ 00773 double Poli2::Deriv( TVectorD &Di, TMatrixD &Dij ) const 00774 { 00775 Di.ResizeTo(fN); 00776 Dij.ResizeTo(fN,fN); 00777 TVectorD diB(fPw+1) ,djB(fPw+1); 00778 TMatrixD diA(fPw+1,fPw+1),djA(fPw+1,fPw+1); 00779 for (int ipt=0;ipt<fN;ipt++) { 00780 double der = fY[ipt]*fY[ipt]; 00781 double xi[3]={1,fX[ipt],fX[ipt]*fX[ipt]}; 00782 for (int k=0;k<=fPw;k++) { diB[k] = fY[ipt]*xi[k]; 00783 for (int l=0;l<=fPw;l++) { diA(k,l) = xi[k]*xi[l];}} 00784 der -= (2*(diB*(fAi*fB))-(fP*(diA*fP))); 00785 Di[ipt] = der; 00786 for (int jpt=0;jpt<=ipt;jpt++) { 00787 double xj[3]={1,fX[jpt],fX[jpt]*fX[jpt]}; 00788 for (int k=0;k<=fPw;k++) { djB[k] = fY[jpt]*xj[k]; 00789 for (int l=0;l<=fPw;l++) { djA(k,l) = xj[k]*xj[l];}} 00790 der = -2*(-((fAi*diB)*(djA*fP)) 00791 +(diB*(fAi*djB)) 00792 -((fAi*djB)*(diA*fP)) 00793 +(fP*(djA*(fAi*(diA*fP))))); 00794 Dij[ipt][jpt]=der; 00795 Dij[jpt][ipt]=der; 00796 } 00797 } 00798 return Xi2(); 00799 } 00800 00801 //______________________________________________________________________________ 00802 void Poli2::MyTest() const 00803 { 00804 printf("Print B\n"); 00805 fB.Print(); 00806 printf("Print A\n"); 00807 fA.Print(); 00808 printf("Print Ai\n"); 00809 fAi.Print(); 00810 printf("Print A*Ai\n"); 00811 TMatrixD tst(fPw+1,fPw+1); 00812 tst = fA*fAi; 00813 tst.Print(); 00814 } 00815 //______________________________________________________________________________ 00816 void Poli2::Test() 00817 { 00818 int npw=2; 00819 double X[20],Y[20],W[20]; 00820 for (int i=0;i<20;i++) { 00821 X[i]=i; 00822 Y[i]= 3+X[i]*(.02+.03*X[i]); 00823 W[i]= 1-0.01*i; 00824 Y[i]+=gRandom->Gaus(0,sqrt(1./W[i])); 00825 } 00826 Poli2 pp(npw,20,X,Y,W); 00827 pp.Init(); 00828 // pp.MyTest(); 00829 double Xi2 = pp.Xi2(); 00830 double Xi2Eva = pp.Xi2(); 00831 printf ("Xi2 = %g == %g\n",Xi2,Xi2Eva); 00832 for (int i=0; i<20; i++) { 00833 printf(" %g %g : %g\n",X[i],Y[i],pp.Fun(X[i])); 00834 } 00835 // check d/dW 00836 printf("\n check d/dWi\n"); 00837 double delta = 1e-3; 00838 for (int k=0;k<20;k++) { 00839 Poli2 ppp(npw); 00840 for (int i=0;i<20;i++) { 00841 double w = W[i]; 00842 if (i==k) w+=delta; 00843 ppp.Add(X[i],Y[i],w); 00844 } 00845 ppp.Init(); 00846 double ana = pp.dXi2dW(k); 00847 double num = (ppp.Xi2()-pp.Xi2())/delta; 00848 double dif = 2*(num-ana)/(fabs(num+ana)+3e-33); 00849 if (fabs(dif)<0.01) continue; 00850 printf ("dXi2dW(%2d) \tana=%g \tnum = %g \tdif=%g\n",k,ana,num,dif); 00851 } 00852 // check d2/dWi/DWj 00853 printf("\n check d2/dWi/DWj\n"); 00854 for (int i=0;i<20;i++) { 00855 double sav = W[i]; W[i]=sav+delta; 00856 Poli2 ppp(npw,20,X,Y,W); 00857 W[i]=sav; 00858 ppp.Init(); 00859 for (int j=0;j<20;j++) { 00860 double ana = pp.d2Xi2d2W(i,j); 00861 double num = (ppp.dXi2dW(j)-pp.dXi2dW(j))/delta; 00862 double dif = 2*(num-ana)/(fabs(num+ana)+3e-33); 00863 if (fabs(dif)<0.01) continue; 00864 printf ("d2Xi2d2W(%2d,%2d) \tana=%g \tnum = %g \tdif=%g\n",i,j,ana,num,dif); 00865 } } 00866 TVectorD g; 00867 TMatrixD gg; 00868 pp.Deriv(g,gg); 00869 for (int i=0;i<20;i++) { 00870 double tst = pp.dXi2dW(i)-g[i]; 00871 if (fabs(tst)>1e-10) printf("g[%d] %g **************\n",i,tst); 00872 for (int j=0;j<20;j++) { 00873 double tst = pp.d2Xi2d2W(i,j)-gg[i][j]; 00874 if (fabs(tst)>1e-10) printf("gg[%d][%d] %g **************\n",i,j,tst); 00875 } } 00876 00877 00878 } 00879 //______________________________________________________________________________ 00880 void Poli2::TestIt() const 00881 { 00882 TVectorD g,gT; 00883 TMatrixD G,GT; 00884 Poli2 pp(*this); 00885 pp.Init(); 00886 double Xi2 = pp.Deriv(g,G); 00887 00888 double delta = 1e-3; 00889 for (int k=0;k<fN;k++) { 00890 double sav = pp.fW[k]; 00891 pp.fW[k]=sav+delta; 00892 pp.Init(); 00893 double Xi2T = pp.Deriv(gT,GT); 00894 pp.fW[k]=sav; 00895 00896 double ana = 0.5*(g[k]+gT[k]); 00897 double num = (Xi2T-Xi2)/delta; 00898 double dif = 2*(num-ana)/(fabs(num+ana)+1e-10); 00899 if (fabs(dif)>0.01) 00900 printf ("\ndXi2dW(%2d) \tana=%g \tnum = %g \tdif=%g\n\n",k,ana,num,dif); 00901 // check d2/dWi/DWj 00902 for (int i=0;i<fN;i++) { 00903 ana = 0.5*(GT[k][i]+G[k][i]); 00904 num = (gT[i]-g[i])/delta; 00905 dif = 2*(num-ana)/(fabs(num+ana)+1e-10); 00906 if (fabs(dif)>0.01) 00907 printf ("d2Xi2dW2(%2d,%2d) \tana=%g \tnum = %g \tdif=%g\n",k,i,ana,num,dif); 00908 } } 00909 00910 00911 } 00912 //______________________________________________________________________________ 00913 void poli2() 00914 { 00915 Poli2::Test(); 00916 } 00917 //______________________________________________________________________________ 00918 class LogErf { 00919 public: 00920 LogErf(double s,double d); 00921 double Deriv(int der); 00922 double Deriv(int der,double x2); 00923 00924 static double Erf(double x); 00925 static void Test(); 00926 private: 00927 double fErf; 00928 double fS; 00929 double fD; 00930 }; 00931 //______________________________________________________________________________ 00932 LogErf::LogErf(double s2,double d) 00933 { 00934 fS=s2; fD=d; fErf=Erf(fD/sqrt(2*fS)); 00935 } 00936 //______________________________________________________________________________ 00937 double LogErf::Erf(double x) 00938 { 00939 static const double f = 1.12837916709551256e+00; 00940 00941 if (fabs(x)>0.1) return TMath::Erf(x); 00942 double xx = x*x; 00943 return f*x*(1+xx*(-1./3+xx*(1./10-xx/42))); 00944 } 00945 //______________________________________________________________________________ 00946 double LogErf::Deriv(int der) 00947 { 00948 //static double fak = 2./sqrt(TMath::Pi()); 00949 static const double fak = 1.12837916709551256e+00; 00950 switch(der) { 00951 case 0: return log(fErf); 00952 case 1: { 00953 double a = fD/sqrt(2.*fS); 00954 double da = -a*0.5/fS; 00955 double texp = exp(-a*a); 00956 double derf = fak*texp*da; 00957 return derf/fErf;} 00958 00959 case 2: { 00960 double a = fD/sqrt(2*fS); 00961 double da = -a*0.5/fS; 00962 double dda = 0.5*(-da+ a/fS)/fS; 00963 double texp = exp(-a*a); 00964 double dexp = -texp*2*a*da; 00965 double derf = fak*texp*da; 00966 return fak*(dexp*da+texp*dda-texp*da/fErf*derf)/fErf;} 00967 default: assert(0); return 0; 00968 00969 } 00970 } 00971 //______________________________________________________________________________ 00972 double LogErf::Deriv(int der,double x2) 00973 { 00974 // LF =log(sqrt(2/pi)) 00975 static const double LF =-0.225791352644727380; 00976 switch(der) { 00977 case 0: return LF -0.5*(x2/fS + log(fS)) -Deriv(0); 00978 00979 case 1: return -0.5*(fS-x2)/fS/fS -Deriv(1); 00980 00981 case 2: return -0.5*(2*x2-fS)/fS/fS/fS -Deriv(2); 00982 00983 default: assert(0); return 0; 00984 } 00985 } 00986 //______________________________________________________________________________ 00987 void LogErf::Test() 00988 { 00989 const char *mess[]={"\t OK ","\t*** WARNING ***"}; 00990 int warn; 00991 double x2=9.; 00992 double s2=4.; 00993 s2 =0.0020253375740469752; 00994 x2 =0.0014216406552001321; 00995 double kkk = 2; 00996 double lim = kkk*sqrt(s2); 00997 lim = 0.082794256508350372; 00998 double delta = s2/100; 00999 LogErf le1(s2,lim); 01000 LogErf le2(s2+delta,lim); 01001 double da = le1.Deriv(1); 01002 double dn = (le2.Deriv(0)-le1.Deriv(0))/delta; 01003 printf("\n ========== Check LogErf::Deriv(1)===========\n"); 01004 warn = 2*fabs(dn-da)/(fabs(dn)+fabs(da)+1e10) > 0.1; 01005 printf("Da=%g == Dn=%g %s\n",da,dn,mess[warn]); 01006 01007 01008 01009 da = le1.Deriv(1,x2); 01010 dn = (le2.Deriv(0,x2)-le1.Deriv(0,x2))/delta; 01011 printf("\n ========== Check LogErf::Deriv(1,x2)===========\n"); 01012 warn = 2*fabs(dn-da)/(fabs(dn)+fabs(da)+1e10) > 0.1; 01013 printf("Da=%g == Dn=%g %s\n",da,dn,mess[warn]); 01014 01015 da = le1.Deriv(2,x2); 01016 dn = (le2.Deriv(1,x2)-le1.Deriv(1,x2))/delta; 01017 printf("\n ========== Check LogErf::Deriv(2,x2)===========\n"); 01018 warn = 2*fabs(dn-da)/(fabs(dn)+fabs(da)+1e10) > 0.1; 01019 printf("Da=%g == Dn=%g %s\n",da,dn,mess[warn]); 01020 01021 01022 01023 01024 } 01025 //______________________________________________________________________________ 01026 void Init(HitPars_t &hiterr) 01027 { 01028 hiterr[0] = 0.0; 01029 for (int iDet=0;iDet<kNDETS;iDet++) { 01030 if (numRes[iDet]<kMINHITS) continue; 01031 int n = (iDet<=1)? 3:1; 01032 hiterr.Set(iDet,0,n,pSTI[iDet*2+0]); 01033 hiterr.Set(iDet,1,n,pSTI[iDet*2+1]); 01034 hiterr.Min(iDet,0,0) = pow(MinErr[iDet][0]*1.e-4,2); 01035 hiterr.Min(iDet,1,0) = pow(MinErr[iDet][1]*1.e-4,2); 01036 } 01037 } 01038 01039 01040 //______________________________________________________________________________ 01041 //______________________________________________________________________________ 01042 class FitState_t : public HitPars_t { 01043 public: 01044 FitState_t(); 01045 FitState_t(HitPars_t &hp); 01046 const HitPars_t &Pars() const { return (const HitPars_t &)(*this);} 01047 HitPars_t &Pars() { return ( HitPars_t &)(*this);} 01048 int Saddle() const {return neg<0;} 01049 int LimX(int i) const; 01050 double Der() const {return der;} 01051 double Fcn() const {return fcn;} 01052 void Deriv(const std::vector<MyPull> &MyVect); 01053 int MaxStp(TVectorD &add,int mode) const; 01054 void MakeErrs(); 01055 int operator<(const FitState_t &other) const; 01056 FitState_t &operator=(const FitState_t &other); 01057 static int FixWeak( TVectorD &g, TMatrixD &G); 01058 public: 01059 TVectorD g; 01060 TMatrixD G; 01061 char myBeg[1]; 01062 int npt; 01063 int ider; 01064 double fak; 01065 double fcn; 01066 double der; 01067 double neg; 01068 char myEnd[1]; 01069 }; 01070 //______________________________________________________________________________ 01071 FitState_t::FitState_t() 01072 { 01073 memset(myBeg,0,myEnd-myBeg+1); 01074 der = 1e99;fcn = 1e99;neg =-1e99; 01075 } 01076 //______________________________________________________________________________ 01077 FitState_t::FitState_t(HitPars_t &hp) :HitPars_t(hp) 01078 { 01079 memset(myBeg,0,myEnd-myBeg+1); 01080 der = 1e99;fcn = 1e99;neg =-1e99; 01081 } 01082 //______________________________________________________________________________ 01083 void FitState_t::Deriv(const std::vector<MyPull> &MyVect) 01084 { 01085 npt = MyVect.size(); 01086 fcn = DERIV(npt,&(MyVect[0]),g,G); 01087 fcn/=npt; 01088 der = -1; ider =-1; neg = 0; 01089 for (int i=0;i<mNPars;i++) { 01090 if (G[i][i]<neg) neg =G[i][i]; 01091 if(LimX(i)) continue; 01092 if (fabs(g[i])>der) { ider = i; der = fabs(g[i]);} 01093 } 01094 der/=npt; 01095 double myMax=myTCL::vmaxa(G.GetMatrixArray(),G.GetNoElements()); 01096 fak = pow(2.,-int(log(myMax)/log(2.))); 01097 G*=fak; g*=fak; 01098 if (neg>=0) { //Check positiveness 01099 for (int i = 0; i<mNPars && neg>0; i++){ 01100 for (int j = 0; j<i && neg>0; j++) { 01101 if (pow(G[i][j],2) >= G[i][i]*G[j][j]) neg = -1; 01102 } } 01103 } 01104 } 01105 01106 01107 //______________________________________________________________________________ 01108 int FitState_t::operator<(const FitState_t &old) const 01109 { 01110 //if (Pos()<old.Pos()) return 1; 01111 if (Der()<0 ) return 0; 01112 if (Fcn()<old.Fcn()) return 1; 01113 if (Der()<old.Der() 01114 && Fcn()-old.Fcn()-0.1*fabs(old.Fcn())<0) return 1; 01115 return 0; 01116 } 01117 //______________________________________________________________________________ 01118 FitState_t &FitState_t::operator=(const FitState_t &other) 01119 { 01120 memcpy(myBeg,other.myBeg,myEnd-myBeg+1); 01121 g.ResizeTo(other.g); 01122 G.ResizeTo(other.G); 01123 g = other.g; 01124 G = other.G; 01125 HitPars_t::operator=(other); 01126 return *this; 01127 } 01128 //______________________________________________________________________________ 01129 int FitState_t::MaxStp(TVectorD &add,int mode) const 01130 { 01131 int lim=0; 01132 double fak=1; 01133 for (int i=0;i<mNPars;i++) { 01134 double maxStp = (0.01+mDat[i])*0.3; 01135 if (maxStp>fak*fabs(add[i])) continue; 01136 lim = lim*100+i+1; 01137 if (!mode) { add[i] = (add[i]<0)? -maxStp:maxStp;} 01138 else { fak = maxStp/fabs(add[i]);} 01139 } 01140 if (fak<1) add*=fak; 01141 return lim; 01142 } 01143 //______________________________________________________________________________ 01144 void FitState_t::MakeErrs() 01145 { 01146 // Evaluate errors 01147 TMatrixD E(G); 01148 for (int i=0;i<mNPars;i++) { 01149 if (!Lim(i)) continue; 01150 for (int j=0;j<mNPars;j++) {E(i,j) = 0; E(j,i) = 0;}; E(i,i) = 1; 01151 } 01152 double det=12345; E.InvertFast(&det); 01153 E*=fak; 01154 for (int i=0;i<mNPars;i++) {Err(i) = sqrt(E(i,i));} 01155 } 01156 //______________________________________________________________________________ 01157 int FitState_t::LimX(int i) const 01158 { 01159 int lim = Lim(i); 01160 if (!lim) return 0; 01161 if (lim<0 && g[i]<0) return 0; 01162 if (lim>0 && g[i]>0) return 0; 01163 return lim; 01164 } 01165 //______________________________________________________________________________ 01166 int FitState_t::FixWeak( TVectorD &g, TMatrixD &G) 01167 { 01168 int n = g.GetNrows(); 01169 int nfix = 0; 01170 double ave = myTCL::vasum(g)/n; 01171 for (int i=0;i<n;i++) { 01172 if (fabs(g[i])>=ave) continue; 01173 nfix++; g[i]=0; 01174 for (int j=0;j<n;j++) {G[i][j]=0; G[j][i]=0;} 01175 G[i][i]=1; 01176 } 01177 return nfix; 01178 } 01179 //______________________________________________________________________________ 01180 double Fit(HitPars_t &pout) 01181 { 01182 enum {kMAXITER=10000}; 01183 static int const MAXCUT[2]={4,10}; 01184 static int kount=0; 01185 01186 int ifail = 99,nPars,iAkt=0,iter,nCut,lim=0,con=0; 01187 nPars = pout.NPars(); 01188 HitPars_t init(pout); 01189 init.Limit(); 01190 01191 TVectorD add(nPars),g(nPars),ge(nPars),Gg(nPars); 01192 FitState_t Best(init),Now(init); 01193 double dif,difFcn=0,difDer; 01194 01195 static int idebug = 1; 01196 01197 iAkt=0;nCut=0; 01198 01199 for (iter=0;iter<kMAXITER;iter++) {// Iterations 01200 kount++; 01201 Now.Deriv(MyVect); 01202 difFcn = Now.fcn-Best.fcn; 01203 difDer = Now.der-Best.der; 01204 if (idebug) { 01205 printf("Fit(%3d) \tFcn = %g(%g) \tDer(%2d)=%g(%g) \tLim=%d \tCon=%d\tAkt=%d Cut=%d Sad=%d\n" 01206 ,iter,Now.fcn,difFcn,Now.ider,Now.der,difDer,lim,con,iAkt,nCut,Now.Saddle()); 01207 } 01208 if (Now.Der()<0) {ifail=1; break; 01209 } else if (Now.Der() < kAGREE) { 01210 Best=Now; ifail=0; break; 01211 01212 } else if (Now < Best ) {//Accept 01213 nCut = 0; Best = Now; iAkt = 0; 01214 01215 } else if (nCut>MAXCUT[iAkt]) {//Cut step failed 01216 if (iAkt==0) Now=Best; 01217 Best=Now; nCut=0; iAkt=1-iAkt; 01218 01219 } else { 01220 nCut++; 01221 add*= 0.5; 01222 Now.Pars() = Best.Pars()+add; 01223 continue; 01224 } 01225 01226 // SOLVING 01227 01228 // Sometimes try grad method randomly 01229 static int rnd=0; rnd++; 01230 if (!(rnd&3)) iAkt=1; 01231 01232 // if (Now.Saddle() && iter&1)iAkt=1; 01233 TVectorD P0(nPars,&Best[0]); 01234 for (int jAkt=iAkt;jAkt<2;jAkt++) { 01235 iAkt = jAkt; 01236 TVectorD P1(P0); 01237 con = myTCL::SqProgSimple(P1,Now.g,Now.G 01238 ,TVectorD(nPars,&Now.Min(0)) 01239 ,TVectorD(nPars,&Now.Max(0)),jAkt); 01240 if (con<0) continue; 01241 add = P1-P0; 01242 double along = -(add*Now.g); 01243 if (along <0) continue; 01244 lim=Best.MaxStp(add,1); 01245 Now.Pars() = Best.Pars()+add; 01246 break; 01247 } 01248 }// End Iters 01249 01250 if (ifail==0 || ifail==99) Best.MakeErrs(); 01251 pout=Best.Pars(); 01252 01253 dif = pout.Diff(init); 01254 printf("\nFit: Iter=%d Fcn=%g Der=%g Dif=%6.3g%% Fail=%d\n" 01255 ,iter,Best.fcn,Best.der,dif,ifail); 01256 pout.Print(&init); 01257 return (ifail)? 1e10:dif; 01258 01259 } 01260 01261 //______________________________________________________________________________ 01262 void AveRes() 01263 { 01264 memset(aveRes[0] ,0,sizeof(aveRes)); 01265 memset(aveTrk[0][0],0,sizeof(aveTrk)); 01266 memset(numRes ,0,sizeof(numRes)); 01267 for (int jhit=0; jhit<(int)MyVect.size(); jhit++) { 01268 MyPull &myRes = MyVect[jhit]; 01269 int jdx = kind(myRes.xyz[0]); 01270 aveRes[jdx][0]+= myRes.ypul*myRes.ypul; 01271 aveRes[jdx][1]+= myRes.zpul*myRes.zpul; 01272 aveRes[jdx][2]+= myRes.uyy; 01273 aveRes[jdx][3]+= myRes.uzz; 01274 aveRes[jdx][4]+= pow(myRes.xyz[1]-myRes.yfit,2); 01275 aveRes[jdx][5]+= pow(myRes.xyz[2]-myRes.zfit,2); 01276 if (hh[jdx*2+0+30]) hh[jdx*2+0+30]->Fill(myRes.ypul); 01277 if (hh[jdx*2+1+30]) hh[jdx*2+1+30]->Fill(myRes.zpul); 01278 numRes[jdx]++; 01279 HitAccr ha; 01280 HitPars_t::HitCond(myRes,ha); 01281 TCL::vadd(aveTrk[jdx][0],ha.A[0],aveTrk[jdx][0],3); 01282 TCL::vadd(aveTrk[jdx][1],ha.A[1],aveTrk[jdx][1],3); 01283 01284 } 01285 // CleanUp 01286 int ihit=0; 01287 for (int jhit=0; jhit<(int)MyVect.size(); jhit++) { 01288 MyPull &myRes = MyVect[jhit]; 01289 int jdx = kind(myRes.xyz[0]); 01290 if (numRes[jdx]<kMINHITS) continue; 01291 aveRes[jdx][0]+= myRes.ypul*myRes.ypul; 01292 if (ihit!=jhit) MyVect[ihit]=MyVect[jhit]; 01293 ihit++; 01294 } 01295 MyVect.resize(ihit); 01296 01297 for(int jdx=0;jdx<4;jdx++) { 01298 if (numRes[jdx]<kMINHITS) continue; 01299 double f = 1./numRes[jdx]; 01300 TCL::vscale(aveRes[jdx],f,aveRes[jdx],6); 01301 TCL::vscale(aveTrk[jdx][0],f,aveTrk[jdx][0],6); 01302 double hitYErr,hitZErr; 01303 TCL::vsub(aveRes[jdx]+0,aveRes[jdx]+2,aveRes[jdx]+2,2); 01304 hitYErr = aveRes[jdx][2]; 01305 hitYErr = (hitYErr<0)? -sqrt(-hitYErr):sqrt(hitYErr); 01306 hitZErr = aveRes[jdx][3]; 01307 hitZErr = (hitZErr<0)? -sqrt(-hitZErr):sqrt(hitZErr); 01308 printf("AveRes:: N=%5d \taveRes[%s][yz]=%g %g \tavePul[yz]=%g %g \thitErr(yz)=%g %g\n\n" 01309 ,numRes[jdx],DETZ[jdx] 01310 ,sqrt(aveRes[jdx][4]),sqrt(aveRes[jdx][5]) 01311 ,sqrt(aveRes[jdx][0]),sqrt(aveRes[jdx][1]) 01312 ,hitYErr,hitZErr); 01313 01314 01315 01316 } 01317 } 01318 //______________________________________________________________________________ 01319 int kind(double x) 01320 { 01321 static const double radds[5]={120,25,16,0,0}; 01322 for(int jdx=0;1;jdx++) {if (x>radds[jdx]) return jdx;} 01323 } 01324 //___________________________________myRes___________________________________________ 01325 void HInit() 01326 { 01327 memset(hh,0,sizeof(hh)); 01328 memset(C,0,sizeof(C)); 01329 // Pulls before and after 01330 static const char *NamPuls[]={ 01331 "YOut.bef","YOut.aft","ZOut.bef","ZOut.aft", 01332 "YInn.bef","YInn.aft","ZInn.bef","ZInn.aft", 01333 "YSsdBef","YSsdAft","ZSsdBef","ZSsdAft", 01334 "YSvtBef","YSvtAft","ZSvtBef","ZSvtAft"}; 01335 static const char *NamRes[]={ 01336 "YOut.res","ZOut.res", 01337 "YInn.res","ZInn.res", 01338 "YSsd.res","ZSsd.res", 01339 "YSvt.res","ZSvt.res"}; 01340 01341 for (int ih=0;ih<16;ih++) { 01342 hh[ih] = new TH1F(NamPuls[ih],NamPuls[ih],100,-3,3);} 01343 C[0] = new TCanvas("C0","",600,800); 01344 C[0]->Divide(1,8); 01345 C[1] = new TCanvas("C1","",600,800); 01346 C[1]->Divide(1,8); 01347 for (int ih=0;ih<8;ih++) {C[0]->cd(ih+1);hh[ih+0]->Draw();} 01348 for (int ih=0;ih<8;ih++) {C[1]->cd(ih+1);hh[ih+8]->Draw();} 01349 01350 hh[20]= new TH1F("ChekErr","ChekErr",100,-100.,100.); 01351 hh[21]= new TH1F("ChekPul","ChekPul",100,-100.,100.); 01352 C[2] = new TCanvas("C2","",600,800); 01353 C[2]->Divide(1,2); 01354 for (int ih=0;ih<2;ih++) {C[2]->cd(ih+1);hh[ih+20]->Draw();} 01355 // hh[20]->Draw(); 01356 01357 for (int ih=0;ih<8;ih++) { 01358 hh[ih+30] = new TH1F(NamRes[ih],NamRes[ih],100,-0.3,0.3);} 01359 C[3] = new TCanvas("C3","",600,800); 01360 C[3]->Divide(1,8); 01361 for (int ih=0;ih<8;ih++) {C[3]->cd(ih+1);hh[ih+30]->Draw();} 01362 01363 } 01364 01365 //______________________________________________________________________________ 01366 void FillPulls(int befAft) 01367 { 01368 MyPull myRes; 01369 for (int jhit=0; jhit<(int)MyVect.size(); jhit++) { 01370 myRes = MyVect[jhit]; 01371 int jdx = kind(myRes.xyz[0]); 01372 if (befAft==0) { 01373 hh[jdx*4+0]->Fill(myRes.ypul/(myRes.pye)); 01374 hh[jdx*4+2]->Fill(myRes.zpul/(myRes.pze)); 01375 } else { 01376 hh[jdx*4+1]->Fill(newPull(0,myRes,HitErr)); 01377 hh[jdx*4+3]->Fill(newPull(1,myRes,HitErr)); 01378 } 01379 } 01380 } 01381 //______________________________________________________________________________ 01382 double newPull(int iYZ,const MyPull& myRes,const HitPars_t &pars) 01383 { 01384 HitAccr accr; 01385 HitPars_t::HitCond(myRes,accr); 01386 double S = pars.Err(iYZ,accr)+accr.PredErr[iYZ]; 01387 if (S<1e-6) S=1e-6; 01388 return accr.Pull[iYZ]/sqrt(S); 01389 } 01390 01391 //______________________________________________________________________________ 01392 void DbInit() 01393 { 01394 gSystem->Load("libStDb_Tables.so"); 01395 TString command; 01396 TTable *newdat = 0; 01397 for (int idb=0;idb<4;idb++) { 01398 memcpy(strstr(dbFile[idb],"20"),gTimeStamp,15); 01399 int ready=0; 01400 if (!gSystem->AccessPathName(dbFile[idb])) {//file exists 01401 command = ".L "; command += dbFile[idb]; 01402 gInterpreter->ProcessLine(command); 01403 newdat = (TTable *) gInterpreter->Calc("CreateTable()"); 01404 command.ReplaceAll(".L ",".U "); 01405 gInterpreter->ProcessLine(command); 01406 ready = 2006; 01407 } else { 01408 newdat = (TTable *)gInterpreter->Calc("new St_HitError(\"someHitError\",1)"); 01409 newdat->SetUsedRows(1); 01410 } 01411 assert(newdat); 01412 dbTab[idb] = newdat; 01413 } 01414 } 01415 //______________________________________________________________________________ 01416 void DbDflt() 01417 { 01418 // Set initial values if db file was non existing 01419 01420 for (int idb=0;idb<4;idb++) 01421 { 01422 if (numRes[idb]<kMINHITS) continue; 01423 double *d = (double *)dbTab[idb]->GetArray(); 01424 if (d[0]<=0) {d[0]=aveRes[idb][0];d[3]=aveRes[idb][1];} 01425 TCL::ucopy(d+0,pSTI[idb*2+0],3); 01426 TCL::ucopy(d+3,pSTI[idb*2+1],3); 01427 } 01428 } 01429 //______________________________________________________________________________ 01430 void DbEnd() 01431 { 01432 double par[2][3]; 01433 for (int idb=0;idb<kNDETS;idb++) 01434 { 01435 memset(par,0,sizeof(par)); 01436 if (!HitErr.mPars[idb][0]) continue; 01437 if (!HitErr.Len(idb)) continue; 01438 TString ts(dbFile[idb]); 01439 ts +=".BAK"; 01440 gSystem->Rename(dbFile[idb],ts); 01441 int ny = HitErr.Len(idb,0); 01442 TCL::ucopy(HitErr.mPars[idb][0],par[0],ny); 01443 int nz = HitErr.Len(idb,1); 01444 TCL::ucopy(HitErr.mPars[idb][1],par[1],nz); 01445 01446 TCL::ucopy(par[0],(double*)dbTab[idb]->GetArray()+0,3+3); 01447 01448 std::ofstream ofs(dbFile[idb]); 01449 dbTab[idb]->SavePrimitive(ofs); 01450 } 01451 } 01452 01453 //______________________________________________________________________________ 01454 void HEnd() 01455 { 01456 for (int ic=0;ic<(int)(sizeof(C)/sizeof(void*));ic++) { 01457 TCanvas *cc = C[ic]; if (!cc) continue; 01458 cc->Modified();cc->Update(); 01459 } 01460 while(!gSystem->ProcessEvents()){}; 01461 } 01462 01463 //______________________________________________________________________________ 01464 void CheckErr() 01465 { 01466 for (int jhit=0; jhit<(int)MyVect.size(); jhit++) { 01467 MyPull &myRes = MyVect[jhit]; 01468 int jdx = kind(myRes.xyz[0]); if(jdx){}; 01469 if (jdx != 2) continue; 01470 float pye = myRes.pye; 01471 float hye = myRes.hye; 01472 01473 float ypul = myRes.ypul; 01474 if (fabs(ypul/pye)<2) { 01475 double tmp = (ypul*ypul-pye*pye)/(hye*hye); 01476 hh[20]->Fill(tmp); 01477 } 01478 hh[21]->Fill(pye/hye); 01479 } 01480 } 01481 //______________________________________________________________________________ 01482 double AveErr() 01483 { 01484 // idx=0 outer resY 01485 // idx=1 outer resZ 01486 // idx=2 inner resY 01487 // idx=3 inner resZ 01488 // idx=4 Ssd resY 01489 // idx=5 Ssd resZ 01490 // idx=4 Svt resY 01491 // idx=5 Svt resZ 01492 double pctMax=0; 01493 for (int iDet=0;iDet<kNDETS;iDet++) { 01494 for (int iYZ=0;iYZ<2;iYZ++) { 01495 int idx = iYZ + 2*iDet; 01496 int nPars = HitErr.Len(iDet,iYZ); 01497 double sum=0,sum2=0,sig[3]={0}; 01498 int nTot=0; 01499 for (int jhit=0; jhit<(int)MyVect.size(); jhit++) { 01500 MyPull &myRes = MyVect[jhit]; 01501 int jdx = kind(myRes.xyz[0]); 01502 if (jdx != iDet) continue; 01503 nTot++; 01504 HitAccr accr; 01505 HitPars_t::HitCond(myRes,accr); 01506 double S = HitErr.Err(iYZ,accr); 01507 double delta = pow((&myRes.ypul)[iYZ],2); 01508 double P0 = delta/((&myRes.uyy)[iYZ]+pow((&myRes.hye)[iYZ],2)); 01509 double P1 = delta/((&myRes.uyy)[iYZ]+HitPars_t::Err(pSTI[idx],nPars,accr.A[iYZ])); 01510 double P2 = delta/((&myRes.uyy)[iYZ]+S); 01511 sum +=S; sum2 += S*S; sig[0]+=P0; sig[1]+=P1;sig[2]+=P2; 01512 } 01513 if (!nTot) continue; 01514 sum/=nTot; sum2/=nTot; sum2-=sum*sum; if (sum2<0) sum2=0; sum2=sqrt(sum2); 01515 sum = sqrt(sum); sum2 /= 2*sum; 01516 for (int i=0;i<3;i++) {sig[i]=sqrt(sig[i]/nTot);} 01517 01518 int isig = int(10000*sum +0.5); 01519 int esig = int(10000*sum2+0.5); 01520 double newErr = sum; 01521 double oldErr = sqrt(HitPars_t::Err(pSTI[idx],nPars,aveTrk[iDet][iYZ])); 01522 double pct = 200*fabs(newErr-oldErr)/(newErr+oldErr); 01523 if (pct>pctMax) pctMax=pct; 01524 int iold = int(10000*oldErr +0.5); 01525 // printf("AveErr(%s): <Err.old> = %4d <Err.new> %4d(+-%4dmu) <Sig> =%g %g %g\t//evts=%d\n" 01526 // ,DETS[idx],iold,isig,esig,sig[0],sig[1],sig[2],nTot); 01527 printf("AveErr(%s): <Err.old> = %4d <Err.new> %4d(+-%4dmu) Dif=%4.1g%%\t// evts=%d\n" 01528 ,DETS[idx],iold,isig,esig,pct,nTot); 01529 } } 01530 printf("AveErr(): maxPct = %4.1g%%\n\n", pctMax ); 01531 01532 01533 return pctMax; 01534 } 01535 //______________________________________________________________________________ 01536 void HFit() 01537 { 01538 if (!hh[30+4]) return; 01539 } 01540 //_____________________________________________________________________________ 01541 //_____________________________________________________________________________ 01542 //_____________________________________________________________________________ 01543 //_____________________________________________________________________________ 01544 HitPars_t::HitPars_t () 01545 { 01546 memset(this,0,sizeof(HitPars_t)); 01547 mNPars=1; 01548 int n = sizeof(mMin)/sizeof(*mMin); 01549 myTCL::vfill(mMin,kSMALL,n); 01550 myTCL::vfill(mMax,kBIG ,n); 01551 mMax[0] = 3; 01552 mDat[0] = 0.1; 01553 } 01554 //_____________________________________________________________________________ 01555 HitPars_t::HitPars_t (const HitPars_t &fr) 01556 { 01557 *this = fr; 01558 } 01559 //_____________________________________________________________________________ 01560 HitPars_t &HitPars_t::operator=(const HitPars_t &fr) 01561 { 01562 memcpy(this,&fr,sizeof(HitPars_t)); 01563 int inc = mDat-fr.mDat; 01564 int n = sizeof(mPars)/sizeof(mPars[0][0])*2; 01565 double **p = mPars[0]; 01566 for (int i=0;i<n;i++) { 01567 if (!p[i]) continue; 01568 p[i] += inc; 01569 } 01570 return *this; 01571 } 01572 //_____________________________________________________________________________ 01573 const double &HitPars_t::operator[](int i) const 01574 { return mDat[i];} 01575 01576 //_____________________________________________________________________________ 01577 double &HitPars_t::operator[](int i) 01578 { return mDat[i];} 01579 //_____________________________________________________________________________ 01580 HitPars_t &HitPars_t::operator*(double f) 01581 { for (int i=0;i<mNPars;i++) { (*this)[i]*=f;} return *this; } 01582 //_____________________________________________________________________________ 01583 HitPars_t &HitPars_t::operator+=(const double *f) 01584 { for (int i=0;i<mNPars;i++) {(*this)[i]+=f[i];} return *this;} 01585 //_____________________________________________________________________________ 01586 HitPars_t &HitPars_t::operator=(double f) 01587 { for (int i=0;i<mNPars;i++) {(*this)[i]=f;} return *this;} 01588 //_____________________________________________________________________________ 01589 HitPars_t operator+(const HitPars_t &a,const double *add) 01590 { 01591 HitPars_t tmp(a); tmp+=add; return tmp; 01592 } 01593 //_____________________________________________________________________________ 01594 HitPars_t operator+(const HitPars_t &a,const TVectorD &add) 01595 { 01596 HitPars_t tmp(a); tmp+=add; return tmp; 01597 } 01598 //_____________________________________________________________________________ 01599 int HitPars_t::IPar(int iDet,int iYZ, int *npars) const 01600 { 01601 if (npars) *npars=Len(iDet,iYZ); 01602 return mPars[iDet][iYZ]-mDat; 01603 } 01604 //_____________________________________________________________________________ 01605 int HitPars_t::Lim(int i) const 01606 { 01607 int lim = 0; 01608 if (mDat[i] <= mMin[i]*1.1) lim = -1; 01609 if (mDat[i] >= mMax[i]*0.9) lim = 1; 01610 return lim; 01611 } 01612 //_____________________________________________________________________________ 01613 double HitPars_t::Err(int iDet,int iYZ,const double A[3]) const 01614 { 01615 return Err(mPars[iDet][iYZ],Len(iDet,iYZ),A); 01616 } 01617 //_____________________________________________________________________________ 01618 double HitPars_t::Err(int iYZ,const HitAccr &accr) const 01619 { 01620 return Err(accr.iDet,iYZ,accr.A[iYZ]); 01621 } 01622 //_____________________________________________________________________________ 01623 HitPars_t &HitPars_t::operator+=(const TVectorD &add) 01624 { 01625 for (int i=0;i<mNPars;i++) { 01626 mDat[i]+=add[i]; 01627 if (mDat[i]<mMin[i]) mDat[i]=mMin[i]; 01628 if (mDat[i]>mMax[i]) mDat[i]=mMax[i]; 01629 } 01630 return *this; 01631 } 01632 //_____________________________________________________________________________ 01633 void HitPars_t::Set(int iDet,int iYZ,int nini,const double *ini) 01634 { 01635 mLen[iDet][iYZ]=nini; 01636 if (iDet+1>mNDets) mNDets=iDet+1;; 01637 mPars[iDet][iYZ]=mDat+mNPars; 01638 mErrs[iDet][iYZ]=mDrr+mNPars; 01639 mNPars+=nini; 01640 for (int i=0;i<nini;i++) { 01641 int ipar = IPar(iDet,iYZ); 01642 mDat[ipar+i]=ini[i]; 01643 if (mDat[ipar+i]< mMin[ipar+i]) mDat[ipar+i]= mMin[ipar+i]; 01644 if (mDat[ipar+i]> mMax[ipar+i]) mDat[ipar+i]= mMax[ipar+i]; 01645 } 01646 } 01647 01648 //_____________________________________________________________________________ 01649 double HitPars_t::Dens(double rxy,int ntk) 01650 { 01651 // pseudo-rapidity = -log(tan(theta/2)) theta angle btw track & beam 01652 01653 01654 return ntk/(4*3.14*rxy*rxy); 01655 } 01656 //______________________________________________________________________________ 01657 void HitPars_t::HitCond(const MyPull& myRes,HitAccr &acc) 01658 { 01659 memset(acc.A[0],0,sizeof(acc.A)); 01660 acc.iDet = kind(myRes.xyz[0]); 01661 for (int iyz=0;iyz<2;iyz++) { 01662 acc.A[iyz][0]=1; 01663 acc.A[iyz][1]= 0.01*(200-fabs(myRes.xyz[2])); 01664 double ang; 01665 if (!iyz) { 01666 ang = myRes.psi; acc.Pull[0]=myRes.ypul; 01667 acc.PredErr[0] = myRes.uyy; 01668 } else { 01669 ang = myRes.dip; acc.Pull[1]=myRes.zpul; 01670 acc.PredErr[1] = myRes.uzz; 01671 } 01672 double ca=cos(ang); 01673 if (ca<0.01) ca=0.01; 01674 double ca2 = ca*ca; 01675 double ta2=(1-ca2)/ca2; 01676 acc.A[iyz][1]/= ca2; 01677 acc.A[iyz][2] = ta2; 01678 } 01679 } 01680 //______________________________________________________________________________ 01681 double HitPars_t::Deriv(int npt, const MyPull *pt,TVectorD &Di,TMatrixD &Dij) const 01682 { 01683 // Ai = ErrYi**2; Bi = ErrZi**2; 01684 // Wy_i = 1./Ai ; Wz_i = 1./Bi ; 01685 // Area_i = Pi*sqrt(Ai*Bi); 01686 // -log(Fcn_i) = 0.5*(1+2*fake*area_i*dens_i)*(Wy_i*(Yi-Pol_y(Li))**2 01687 // +Wz_i*(Zi-Pol_z(Li))**2) 01688 // - 0.5*log(1+2*fake*area_i*dens_i) 01689 // - 0.5*log(Wyi) - 0.5*log(Wzi) 01690 // Fcn = Fcn_0+Fcn_1+... 01691 01692 01693 Di.ResizeTo(mNPars); 01694 Dij.ResizeTo(mNPars,mNPars); 01695 int npt21 = npt*2+1; 01696 01697 HitAccr ha; 01698 Poli2 ply(2); 01699 Poli2 plz(1); 01700 TVectorD wy(npt),wz(npt),cos2Psi(npt21); 01701 TMatrixD toPars(mNPars,npt21); 01702 toPars[0][0]=1; 01703 cos2Psi=1.; 01704 TPoliFitter pfy(2),pfz(1); //????? 01705 TCircleFitter cf; 01706 //#define NEWPOLIFIT 01707 #ifndef NEWPOLIFIT 01708 double len = 0,oldCurv,oldXyz[3],nowXyz[3]; 01709 assert(pt[0].xyz[0]<pt[npt-1].xyz[0]); 01710 for (int ipt=0;ipt<npt;ipt++) { 01711 HitCond(pt[ipt],ha); 01712 int iDet = ha.iDet; 01713 if (!mPars[iDet][0]) continue; 01714 double nowCurv=pt[ipt].curv; 01715 nowXyz[0] = pt[ipt].grf*cos(pt[ipt].gpf); 01716 nowXyz[1] = pt[ipt].grf*sin(pt[ipt].gpf); 01717 if (ipt) { //calc length 01718 double dl = sqrt(SQ(nowXyz[0]-oldXyz[0])+SQ(nowXyz[1]-oldXyz[1])); 01719 double curv=0.5*fabs(nowCurv+oldCurv); 01720 if (dl*curv<1e-3) dl*=(1.+SQ(dl*curv)/24); 01721 else dl = 2*asin(0.5*dl*curv)/curv; 01722 len+=dl; 01723 } 01724 01725 double dy = pt[ipt].xyz[1]-pt[ipt].yfit; 01726 double cosPsi = cos(pt[ipt].psi); 01727 cos2Psi[ipt+1] = cosPsi*cosPsi; 01728 dy *= cosPsi; 01729 double dz = pt[ipt].xyz[2]-pt[ipt].zfit; 01730 wy[ipt] = (1./Err(0,ha))/cos2Psi[ipt+1]; 01731 wz[ipt] = (1./Err(1,ha)); 01732 double fake = myFake( mDat[0],wy[ipt],wz[ipt],pt[ipt].dens,0,0); 01733 ply.Add(len,dy,wy[ipt]*fake); 01734 plz.Add(len,dz,wz[ipt]*fake); 01735 // pfy.Add(len,dy,1./(wy[ipt]*fake));//???? 01736 // pfz.Add(len,dz,1./(wz[ipt]*fake));//???? 01737 // double emx[3]={1./(wy[ipt]*fake),0,1./(wy[ipt]*fake)}; 01738 // cf.Add(len,dy,emx);//???? 01739 int n,ipar; 01740 for (int jk=0;jk<2;jk++) { 01741 int ip = 1 +ipt + jk*npt; 01742 ipar = IPar(iDet,jk,&n); 01743 for (int in=0;in<n;in++) {toPars[ipar+in][ip]+=ha.A[jk][in];} 01744 } 01745 memcpy(oldXyz,nowXyz,sizeof(oldXyz)); 01746 oldCurv=nowCurv; 01747 } 01748 #endif //0 01749 #ifdef NEWPOLIFIT 01750 TVectorD Y,Z,S; 01751 Prep(npt,pt,Y,Z,S,cos2Psi); 01752 for (int ipt=0;ipt<npt;ipt++) { 01753 HitCond(pt[ipt],ha); 01754 wy[ipt] = (1./Err(0,ha))/cos2Psi[ipt+1]; 01755 wz[ipt] = (1./Err(1,ha)); 01756 double fake = myFake( mDat[0],wy[ipt],wz[ipt],pt[ipt].dens,0,0); 01757 ply.Add(S[ipt],Y[ipt],wy[ipt]*fake); 01758 plz.Add(S[ipt],Z[ipt],wz[ipt]*fake); 01759 pfy.Add(S[ipt],Y[ipt],1./(wy[ipt]*fake)); 01760 pfz.Add(S[ipt],Z[ipt],1./(wz[ipt]*fake)); 01761 double emx[3]={1./(wy[ipt]*fake),0,1./(wy[ipt]*fake)}; 01762 cf.Add(S[ipt],Y[ipt],emx); 01763 int n,ipar,iDet = ha.iDet; 01764 for (int jk=0;jk<2;jk++) { 01765 int ip = 1 +ipt + jk*npt; 01766 ipar = IPar(iDet,jk,&n); 01767 for (int in=0;in<n;in++) {toPars[ipar+in][ip]+=ha.A[jk][in];} 01768 } 01769 } 01770 #endif //0 01771 ply.Init(); 01772 plz.Init(); 01773 #if 0 01774 double cfyXi2 = cf.Fit()*cf.Ndf(); 01775 double pfyXi2 = pfy.Fit()*pfy.Ndf(); 01776 double pfzXi2 = pfz.Fit()*pfz.Ndf(); 01777 double plyXi2 = ply.Xi2(); 01778 double plzXi2 = plz.Xi2(); 01779 static int printIt=0; 01780 if (printIt) 01781 printf("Xi2Y = %g %g %g \tXi2Z = %g %g\n",plyXi2,pfyXi2,cfyXi2,plzXi2,pfzXi2); 01782 #endif 01783 01784 static int testIt=1; 01785 if (testIt) {testIt--; ply.TestIt(); plz.TestIt(); } 01786 01787 TVectorD dW(npt21),dWy(npt),dWz(npt); 01788 TMatrixD dWW(npt21,npt21),dWWy(npt,npt),dWWz(npt,npt); 01789 double Xi2y = ply.Deriv(dWy,dWWy); 01790 double Xi2z = plz.Deriv(dWz,dWWz); 01791 double Fcn = Xi2y+Xi2z; 01792 01793 // account that W was multiplied by fake, where 01794 // fake = (1+2*mFake*pt[ipt].dens*Pi/sqrt(wx[ipt]*wy[ipt])) 01795 01796 double gi[2][3],gj[2][3],G[2][3][3]; 01797 for (int ipt=0;ipt<npt;ipt++) { 01798 int idx[3]={0,ipt+1,ipt+1+npt}; 01799 myDers(mDat[0],wy[ipt],wz[ipt],pt[ipt].dens,gi,G); 01800 for (int i=0;i<3;i++) { 01801 dW[idx[i]] += dWy[ipt]*gi[0][i]+dWz[ipt]*gi[1][i]; 01802 for (int j=0;j<=i;j++) { 01803 dWW[idx[i]][idx[j]] += dWy[ipt]*G[0][i][j]+dWz[ipt]*G[1][i][j]; 01804 } } 01805 for (int jpt=0;jpt<npt;jpt++) { 01806 int jdx[3]={0,jpt+1,jpt+1+npt}; 01807 myDers(mDat[0],wy[jpt],wz[jpt],pt[jpt].dens,gj,0); 01808 01809 for (int i=0;i<3;i++) { 01810 for (int j=0;j<=i;j++) { 01811 if(idx[i]<jdx[j]) break; 01812 dWW[idx[i]][jdx[j]] += dWWy[ipt][jpt]*gi[0][i]*gj[0][j] 01813 +dWWz[ipt][jpt]*gi[1][i]*gj[1][j]; 01814 } } } } 01815 01816 01817 // account log() terms 01818 double C,Cd[3],Cdd[3][3]; 01819 for (int ipt=0;ipt<npt;ipt++) { 01820 int idx[3]={0,ipt+1,ipt+1+npt}; 01821 C = myFake( mDat[0],wy[ipt],wz[ipt],pt[ipt].dens,Cd,Cdd); 01822 Fcn += - log(wy[ipt]) - log(wz[ipt]) - log(C); 01823 dW[idx[1]] += -1./wy[ipt]; 01824 dW[idx[2]] += -1./wz[ipt]; 01825 dWW[idx[1]][idx[1]]+= 1./pow(wy[ipt],2); 01826 dWW[idx[2]][idx[2]]+= 1./pow(wz[ipt],2); 01827 for (int i=0;i<3;i++) { 01828 dW[idx[i]] += - Cd[i]/C; 01829 for (int j=0;j<=i;j++) { 01830 dWW[idx[i]][idx[j]] += (-Cdd[i][j]+Cd[i]*Cd[j]/C)/C; 01831 } } } 01832 01833 // account Wy = wy/cos2Psi 01834 for (int ii=0;ii<npt21;ii++) { 01835 if (ii && ii<=npt) wy[ii-1]*=cos2Psi[ii]; 01836 dW[ii] /=cos2Psi[ii]; 01837 for (int jj=0;jj<=ii;jj++) { 01838 dWW[ii][jj]/=cos2Psi[ii]*cos2Psi[jj]; 01839 } } 01840 01841 // change W to E where W=1/E 01842 TVectorD wt(npt21); 01843 wt.SetSub(1,wy); wt.SetSub(1+npt,wz); 01844 for (int ii=1;ii<npt21;ii++) { 01845 double wi = wt[ii],wi2 =wi*wi; 01846 dW [ii] *= -wi2; 01847 dWW[ii][0] *= -wi2; 01848 for (int jj=1;jj<=ii;jj++) { 01849 double wj2 = wt[jj]*wt[jj]; 01850 dWW[ii][jj] *= wi2*wj2; 01851 } 01852 dWW[ii][ii] += -2*dW[ii]*wi; 01853 } 01854 01855 01856 // Symmetrisation 01857 for (int i=1;i<npt21;i++) { 01858 for (int j=0;j< i;j++) { 01859 assert(fabs(dWW[j][i])<=0); 01860 dWW[j][i] = dWW[i][j]; 01861 } } 01862 01863 Di = toPars*dW; 01864 // Dij = (toPars*dWW)*(toPars.T()); 01865 myTCL::mxmlrtS(toPars,dWW,Dij); 01866 for (int i=0;i<mNPars;i++) { 01867 for (int j=0;j<i;j++) { 01868 assert(fabs(dWW[i][j]-dWW[j][i])<1e-10);}} 01869 return Fcn; 01870 } 01871 //______________________________________________________________________________ 01872 double HitPars_t::DERIV(int npt, const MyPull *pt,TVectorD &Di,TMatrixD &Dij,int maxTrk) 01873 { 01874 01875 Di.ResizeTo(mNPars); 01876 Dij.ResizeTo(mNPars,mNPars); 01877 Di = 0.; Dij=0.; mNTrks=0; 01878 TVectorD Ti ,TiM (mNPars); 01879 TMatrixD Tij,TijM(mNPars,mNPars); 01880 int jl=0,trk=pt[0].trk; 01881 double xl=0; 01882 double sum=0,sumM=0; 01883 int NSave = (int)sqrt((npt/30.)); 01884 01885 for (int jr=1; 1; jr++) { 01886 double xl0 = xl; xl = pt[jr].xyz[0]; 01887 if (jr<npt && pt[jr].trk==trk && xl0<xl) continue; 01888 int n = jr-jl; 01889 if (n>15) { 01890 double tsum = Deriv(n,pt+jl,Ti,Tij); 01891 sum += tsum; 01892 Di += Ti ; 01893 Dij += Tij; 01894 mNTrks++; 01895 if (mNTrks>=maxTrk) break; 01896 if (((mNTrks+1)%NSave)==0 ) { 01897 sumM += sum; sum= 0.; 01898 TiM += Di ; Di = 0.; 01899 TijM += Dij; Dij= 0.; 01900 } 01901 } 01902 if (jr>=npt) break; 01903 trk = pt[jr].trk; 01904 jl = jr; 01905 } 01906 sum +=sumM; 01907 Di +=TiM ; 01908 Dij +=TijM; 01909 return sum; 01910 } 01911 //______________________________________________________________________________ 01912 void HitPars_t::myDers( double fake,double wy, double wz, double dens 01913 , double g[2][3],double G[2][3][3]) 01914 { 01915 //A = 3.14/sqrt(wy*wz) 01916 //WY = wy*(1+2*fake*dens*A) 01917 //WZ = wz*(1+2*fake*dens*A) 01918 double u[3]={fake,wy,wz}; 01919 double Cd[3],Cdd[3][3]; 01920 double (*myCdd)[3] = Cdd; 01921 if (!G) myCdd=0; 01922 double C0 = myFake(fake,wy,wz,dens,Cd,myCdd); 01923 01924 memset(g[0],0,2*3*sizeof(g[0][0])); 01925 for (int iyz=0;iyz<2;iyz++) { 01926 for (int ivar=0;ivar<3;ivar++) { 01927 g[iyz][ivar] = u[iyz+1]*Cd[ivar]; 01928 if (ivar==iyz+1) g[iyz][ivar]+= C0; }} 01929 01930 if (!G) return; 01931 01932 memset(G[0][0],0,2*3*3*sizeof(G[0][0][0])); 01933 for (int iyz=0;iyz<2;iyz++) { 01934 for (int i=0;i<3;i++) { 01935 for (int j=0;j<3;j++) { 01936 G[iyz][i][j] = u[iyz+1]*Cdd[i][j]; 01937 if (i==iyz+1) G[iyz][i][j]+=Cd[j]; 01938 if (j==iyz+1) G[iyz][i][j]+=Cd[i]; 01939 } } } 01940 01941 } 01942 //______________________________________________________________________________ 01943 double HitPars_t::myFake( double fake,double wy, double wz, double dens 01944 , double Cd[3],double Cdd[3][3]) 01945 { 01946 //A = 3.14/sqrt(wy*wz) 01947 //WY = wy*(1+2*fake*dens*A) 01948 //WZ = wz*(1+2*fake*dens*A) 01949 double dens2 = 2*dens; 01950 01951 double A = 3.14/sqrt(wy*wz); 01952 double Ay = -0.5*A/wy ; 01953 double Az = -0.5*A/wz ; 01954 01955 double C0 = (1+fake*dens2*A); 01956 if (!Cd) return C0; 01957 Cd[0] = dens2*A; 01958 Cd[1] = fake*dens2*Ay; 01959 Cd[2] = fake*dens2*Az; 01960 if (!Cdd) return C0; 01961 01962 double Ayy = 0.5*(-Ay + A/wy)/wy; 01963 double Ayz = 0.5*(-Az )/wy; 01964 double Azz = 0.5*(-Az + A/wz)/wz; 01965 01966 Cdd[0][0] = 0; 01967 Cdd[0][1] = dens2*Ay; 01968 Cdd[0][2] = dens2*Az; 01969 Cdd[1][0] = Cdd[0][1]; 01970 Cdd[1][1] = fake*dens2*Ayy; 01971 Cdd[1][2] = fake*dens2*Ayz; 01972 Cdd[2][0] = Cdd[0][2]; 01973 Cdd[2][1] = Cdd[1][2]; 01974 Cdd[2][2] = fake*dens2*Azz; 01975 return C0; 01976 } 01977 //______________________________________________________________________________ 01978 void HitPars_t::Print(const HitPars_t *init) const 01979 { 01980 const char *TYZ[]={"y","z"}; 01981 const char *bnd; 01982 01983 printf("HitPars(Fake ) "); 01984 bnd = (Lim(0))? "*":" "; 01985 if (init) printf("\t "); 01986 printf("\tpout=%8.4g(+-%8.4g)%s\n",mDat[0],mDrr[0],bnd); 01987 01988 for (int iDet=0;iDet<mNDets;iDet++) { 01989 for (int iYZ=0;iYZ<2;iYZ++) { 01990 int ln = Len(iDet,iYZ); 01991 int ipar0 = IPar(iDet,iYZ); 01992 for (int ip=0;ip<ln;ip++) { 01993 bnd = (Lim(ipar0+ip))? "*":" "; 01994 double p = mPars[iDet][iYZ][ip]; 01995 double e = mErrs[iDet][iYZ][ip]; 01996 printf("HitPars(%d,%s,%d) ",iDet,TYZ[iYZ],ip); 01997 if (init) { 01998 printf("\tinit=%8.4g ",init->mPars[iDet][iYZ][ip]);} 01999 printf("\tpout=%8.4g(+-%8.4g)%s",p,e,bnd); 02000 printf("\n"); 02001 } } } 02002 02003 } 02004 //______________________________________________________________________________ 02005 double HitPars_t::Diff(const HitPars_t &init) const 02006 { 02007 double pctMax=0; 02008 for (int i=0;i<mNPars;i++) { 02009 double dif = fabs((*this)[i]-init[i]); 02010 double err = init.Err(i); 02011 if (err<=0) err = 0.5*((*this)[i]+init[i])+1e-10; 02012 dif/= err; 02013 if (pctMax<dif) pctMax=dif; 02014 } 02015 return pctMax*100; 02016 } 02017 //______________________________________________________________________________ 02018 int HitPars_t::Test(int npt, const MyPull *pt) const 02019 { 02020 enum {kNTrkTst=5}; 02021 TVectorD Di ,DiT ; 02022 TMatrixD Dij,DijT; 02023 HitPars_t HP(*this); 02024 HP[0]=9; 02025 int npars = HP.NPars(); 02026 double fcn = HP.DERIV(npt,pt,Di,Dij,kNTrkTst); 02027 for (int i=0;i<npars;i++) { 02028 double sav = HP[i]; 02029 double delta = fabs(sav)*1e-3; 02030 if (delta<1e-6) delta=1e-6; 02031 HP[i]=sav+delta; 02032 double fcnT = HP.DERIV(npt,pt,DiT,DijT,kNTrkTst); 02033 HP[i]=sav; 02034 double ana = 0.5*(Di[i]+DiT[i]); 02035 double num = (fcnT-fcn)/delta; 02036 double dif = (num-ana)/(fabs(num+ana)+1e-5); 02037 if (fabs(dif)>0.001) 02038 printf("\nDer(%2d): ana = %g \tnum = %g \tdif = %g\n\n",i,ana,num,dif); 02039 for (int k=0;k<npars;k++) { 02040 ana = 0.5*(Dij[i][k]+DijT[i][k]); 02041 num = (DiT[k]-Di[k])/delta; 02042 dif = (num-ana)/(fabs(num+ana)+1e-5); 02043 if (fabs(dif)>0.001) 02044 printf("Der(%2d,%2d): ana = %g \tnum = %g \tdif = %g\n",i,k,ana,num,dif); 02045 } 02046 02047 } 02048 return 0; 02049 } 02050 //______________________________________________________________________________ 02051 double HitPars_t::Err(const double Pars[3],int nPars,const double A[3]) 02052 { 02053 static const double tenMicrons = 1e-3; 02054 static const double min2Err = tenMicrons*tenMicrons; 02055 static const double max2Err = 1.; 02056 double err = TCL::vdot(A,Pars,nPars); 02057 if (nPars<=1) return err; 02058 if (err<min2Err) err=min2Err; 02059 if (err>max2Err) err=max2Err; 02060 return err; 02061 } 02062 //______________________________________________________________________________ 02063 void HitPars_t::Limit() 02064 { 02065 for (int i=0;i<mNPars;i++) { 02066 if (mDat[i]<mMin[i]) mDat[i]=mMin[i]; 02067 if (mDat[i]>mMax[i]) mDat[i]=mMax[i]; 02068 } 02069 } 02070 #if 0 02071 //______________________________________________________________________________ 02072 void HitPars_t::Prep(int npt, const MyPull *pt,TVectorD &Y,TVectorD &Z 02073 ,TVectorD &S,TVectorD &cos2Psi) 02074 { 02075 static int myDebug=0; 02076 02077 Y.ResizeTo(npt); 02078 Z.ResizeTo(npt); 02079 S.ResizeTo(npt); 02080 if (myDebug) Show(npt,pt); 02081 int npt21 = npt*2+1; 02082 cos2Psi.ResizeTo(npt21);cos2Psi = 1.; 02083 TVector2 fst(pt[0].x_g(),pt[0].y_g()); 02084 TVector2 tst(fst.Rotate(-pt[0].ang)); 02085 assert(fabs(tst.X()-pt[0].xyz[0])+fabs(tst.Y()-pt[0].xyz[1])<1); 02086 int l = npt-1; 02087 TVector2 lst(pt[l].x_g(),pt[l].y_g()); 02088 tst = lst.Rotate(-pt[l].ang); 02089 assert(fabs(tst.X()-pt[l].xyz[0])+fabs(tst.Y()-pt[l].xyz[1])<1); 02090 double sA = fst.Mod(); 02091 double sB = lst.Mod(); 02092 double Z0 = pt[0].z_g(); 02093 double dZdS = (pt[l].z_g()-Z0)/(sB-sA); 02094 TVector2 dir((lst-fst).Unit()); 02095 02096 for (int ipt=0;ipt<npt;ipt++) { 02097 TVector2 fstL(fst.Rotate(-pt[ipt].ang)); 02098 TVector2 dirL(dir.Rotate(-pt[ipt].ang)); 02099 TVector2 meas(pt[ipt].xyz[0],pt[ipt].xyz[1]); 02100 meas -=fstL; 02101 double s = (meas)*dirL; 02102 TVector2 ort(-dirL.Y(),dirL.X()); 02103 double dy = meas*ort; 02104 double dz = pt[ipt].xyz[2]-(Z0 + dZdS*(s)); 02105 S[ipt]=s; 02106 Y[ipt]=dy; 02107 Z[ipt]=dz; 02108 cos2Psi[ipt+1]=dirL.X()*dirL.X(); 02109 } 02110 02111 } 02112 #endif //0 02113 #if 1 02114 //______________________________________________________________________________ 02115 void HitPars_t::Prep(int npt, const MyPull *pt,TVectorD &Y,TVectorD &Z 02116 ,TVectorD &S,TVectorD &cos2Psi) 02117 { 02118 static int myDebug=0; 02119 02120 Y.ResizeTo(npt); 02121 Z.ResizeTo(npt); 02122 S.ResizeTo(npt); 02123 if (myDebug) Show(npt,pt); 02124 int npt21 = npt*2+1; 02125 cos2Psi.ResizeTo(npt21);cos2Psi = 1.; 02126 02127 THelixFitter helx; 02128 for (int ipt=0;ipt<npt;ipt++) { 02129 TVector3 point; 02130 point[0] = pt[ipt].xhg(); 02131 point[1] = pt[ipt].yhg(); 02132 point[2] = pt[ipt].zhg(); 02133 helx.Add(point[0],point[1],point[2]); 02134 double emx[3]={pow(pt[ipt].hye,2),0,pow(pt[ipt].hye,2)}; 02135 helx.AddErr(emx,pow(pt[ipt].hze,2)); 02136 } 02137 helx.Fit(); 02138 THelixTrack move(helx); 02139 double s = 0; 02140 for (int ipt=0;ipt<npt;ipt++) { 02141 TVector3 point; 02142 point[0] = pt[ipt].xhg(); 02143 point[1] = pt[ipt].yhg(); 02144 point[2] = pt[ipt].zhg(); 02145 double ds = move.Path(point[0],point[1]); 02146 if (ipt) s+=ds; 02147 move.Move(ds); 02148 TVector3 pos(move.Pos()); 02149 TVector3 dir(move.Dir()); 02150 TVector3 nor(dir[1],-dir[0],0.); nor = nor.Unit(); 02151 double dy = (point-pos)*nor; 02152 double dz = point[2]-pos[2]; 02153 S[ipt]=s; 02154 Y[ipt]=dy; 02155 Z[ipt]=dz; 02156 cos2Psi[ipt+1]=pow(cos(pt[ipt].psi),2); 02157 } 02158 } 02159 #endif//1 02160 //______________________________________________________________________________ 02161 void HitPars_t::Show(int npt, const MyPull *pt) 02162 { 02163 // lev=0 draw all nodes 02164 // lev=1 draw hit nodes 02165 // lev=2 draw hits only 02166 02167 02168 02169 static TCanvas *myCanvas=0; 02170 static TGraph *graph[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; 02171 // P G P G 02172 float X[3][3][100],Y[3][3][100]; 02173 int N[3][3]; 02174 02175 if (!myCanvas) {myCanvas = new TCanvas("C1","",600,800); 02176 myCanvas->Divide(1,3);} 02177 if(pt) { 02178 double curv = 0,xPrev,yPrev; int nCurv = 0; 02179 for (int i=0;i<9;i++) {delete graph[0][i];graph[0][i]=0;} 02180 for (int ig=0;ig<3;ig++) { 02181 int n=0; 02182 double s = 0; 02183 xPrev = 3e33; 02184 for (int ipt=0;ipt<npt;ipt++) { 02185 const MyPull *node = pt+ipt; 02186 // S calculation common based on node x,y for both hit and node 02187 double xNode = node->x_g(); 02188 double yNode = node->y_g(); 02189 if (xPrev<3e33) { 02190 double ds = sqrt(pow(xNode-xPrev,2)+pow(yNode-yPrev,2)); 02191 double si = 0.5*ds*curv; if (si>0.99) si=0.99; 02192 if (si>0.01) ds = 2*asin(si)/curv; 02193 s += ds; 02194 } 02195 xPrev = xNode; 02196 yPrev = yNode; 02197 02198 if (ig==0) { curv += node->curv; nCurv++; continue;} 02199 if (ig==1) {//draw nodes 02200 X[0][ig][n] = node->x_g(); 02201 Y[0][ig][n] = node->y_g(); 02202 Y[2][ig][n] = node->z_g(); 02203 } else {//draw hits only 02204 X[0][ig][n] = node->xhg(); 02205 Y[0][ig][n] = node->yhg(); 02206 Y[2][ig][n] = node->zhg(); 02207 } 02208 02209 if (n) { 02210 float xh = X[0][ig][n]-X[0][ig][0]; 02211 float yh = Y[0][ig][n]-Y[0][ig][0]; 02212 float rh = xh*xh+yh*yh+1E-10; 02213 X[1][ig][n-1] = xh/rh; 02214 Y[1][ig][n-1] = yh/rh; 02215 } 02216 X[2][ig][n]=s; 02217 n++; 02218 }//end for nodes 02219 if (ig==0) { curv=fabs(curv)/nCurv; continue;} 02220 N[0][ig] = n; 02221 N[1][ig] = n-1; 02222 N[2][ig] = n; 02223 }//end for ig 02224 02225 for (int ip=0;ip<3;ip++) { 02226 double xMin=999,xMax=-999,yMin=999,yMax=-999; 02227 for (int ig=1;ig<3;ig++) { 02228 for (int j=0;j<N[ip][ig];j++) { 02229 double x = X[ip][ig][j]; 02230 if (xMin> x) xMin = x; 02231 if (xMax< x) xMax = x; 02232 double y = Y[ip][ig][j]; 02233 if (yMin> y) yMin = y; 02234 if (yMax< y) yMax = y; 02235 } 02236 } 02237 X[ip][0][0] = xMin; Y[ip][0][0] = yMin; 02238 X[ip][0][1] = xMin; Y[ip][0][1] = yMax; 02239 X[ip][0][2] = xMax; Y[ip][0][2] = yMin; 02240 X[ip][0][3] = xMax; Y[ip][0][3] = yMax; 02241 N[ip][0] = 4; 02242 } 02243 static const char *opt[]={"AP","Same CP","Same *"}; 02244 for (int ip=0;ip<3;ip++) { 02245 for (int ig =0;ig<3;ig++) { 02246 graph[ip][ig] = new TGraph(N[ip][ig] , X[ip][ig], Y[ip][ig]); 02247 if(ig==2) graph[ip][ig]->SetMarkerColor(kRed); 02248 myCanvas->cd(ip+1); graph[ip][ig]->Draw(opt[ig]); 02249 }//end for ig 02250 }//end ip 02251 02252 }//end if 02253 02254 02255 if (!myCanvas) return; 02256 myCanvas->Modified(); 02257 myCanvas->Update(); 02258 while(!gSystem->ProcessEvents()){}; 02259 } 02260 //______________________________________________________________________________ 02261 int HitPars_t::Test() 02262 { 02263 return 0; 02264 } 02265 //______________________________________________________________________________ 02266 //______________________________________________________________________________ 02267 //______________________________________________________________________________ 02268 //______________________________________________________________________________ 02269 double myTCL::vmaxa(const double *a,int na) 02270 { 02271 double r=0; 02272 for (int i=0;i<na;i++){if (r < fabs(a[i])) r = fabs(a[i]);} 02273 return r; 02274 } 02275 //______________________________________________________________________________ 02276 double myTCL::vmaxa(const TVectorD &a) 02277 { 02278 return vmaxa(a.GetMatrixArray(),a.GetNrows()); 02279 } 02280 //______________________________________________________________________________ 02281 void myTCL::vfill(double *a,double f,int na) 02282 { 02283 for (int i=0;i<na;i++) {a[i]=f;} 02284 } 02285 //_____________________________________________________________________________ 02286 void myTCL::eigen2(const double err[3], double lam[2], double eig[2][2]) 02287 { 02288 02289 double spur = err[0]+err[2]; 02290 double det = err[0]*err[2]-err[1]*err[1]; 02291 double dis = spur*spur-4*det; 02292 if (dis<0) dis = 0; 02293 dis = sqrt(dis); 02294 lam[0] = 0.5*(spur+dis); 02295 lam[1] = 0.5*(spur-dis); 02296 eig[0][0] = 1; eig[0][1]=0; 02297 if (dis>1e-6*spur) {// eigenvalues are different 02298 if (fabs(err[0]-lam[0])>fabs(err[2]-lam[0])) { 02299 eig[0][1] = 1; eig[0][0]= -err[1]/(err[0]-lam[0]); 02300 } else { 02301 eig[0][0] = 1; eig[0][1]= -err[1]/(err[2]-lam[0]); 02302 } 02303 double tmp = sqrt(eig[0][0]*eig[0][0]+eig[0][1]*eig[0][1]); 02304 eig[0][0]/=tmp; eig[0][1]/=tmp; 02305 } 02306 eig[1][0]=-eig[0][1]; eig[1][1]= eig[0][0]; 02307 } 02308 //______________________________________________________________________________ 02309 /* 02310 * $Id: fiterr.C,v 1.6 2008/01/20 00:43:02 perev Exp $ 02311 * 02312 * $Log: fiterr.C,v $ 02313 * Revision 1.6 2008/01/20 00:43:02 perev 02314 * Mess with timestamps fixed 02315 * 02316 * Revision 1.5 2007/04/26 04:25:32 perev 02317 * Cleanup 02318 * 02319 * Revision 1.1.1.1 1996/04/01 15:02:13 mclareni 02320 * Mathlib gen 02321 */ 02322 double myTCL::simpson(const double *F,double A,double B,int NP) 02323 { 02324 int N2=NP-1; 02325 assert(N2>0 && !(N2&1)); 02326 double S1=F[N2-1]; 02327 double S2=0; 02328 02329 for (int N = 1;N<=N2-3;N+=2) {S1+=F[N];S2+=F[N+1];} 02330 S1=S1+S1+S2; 02331 double H=(F[0]+F[N2]+S1+S1)*(B-A)/(3*N2); 02332 return H; 02333 } 02334 //______________________________________________________________________________ 02335 void myTCL::mxmlrt(const TMatrixD &A,const TMatrixD &B,TMatrixD &X) 02336 { 02337 int nRowA = A.GetNrows(); 02338 int nColA = A.GetNcols(); 02339 int nRowB = B.GetNrows(); 02340 int nColB = B.GetNcols(); if(nColB){} 02341 assert(nColA ==nRowB); 02342 X.ResizeTo(nRowA,nRowA); 02343 TCL::mxmlrt(A.GetMatrixArray(),B.GetMatrixArray() 02344 ,X.GetMatrixArray(),nRowA,nColA); 02345 02346 } 02347 //______________________________________________________________________________ 02348 void myTCL::mxmlrtS(const double *A,const double *B,double *X,int nra,int nca) 02349 { 02350 TCL::vzero(X,nra*nra); 02351 for (int i=0,ii=0;i<nra;i++,ii+=nca) { 02352 for (int j=0,jj=0;j<nca;j++,jj+=nca) { 02353 if(!A[ii+j]) continue; 02354 for (int k=0,kk=0;k<=i;k++,kk+=nca) { 02355 double &Xik =X[i*nra+k]; 02356 for (int l=0;l<nca;l++) { 02357 if(!A[kk+l]) continue; 02358 Xik +=A[ii+j]*A[kk+l]*B[jj+l]; 02359 } } } } 02360 for (int i=0;i<nra;i++){ 02361 for (int k=0;k<i ;k++){X[k*nra+i] = X[i*nra+k];}} 02362 } 02363 //______________________________________________________________________________ 02364 void myTCL::mxmlrtS(const TMatrixD &A,const TMatrixD &B,TMatrixD &X) 02365 { 02366 int nRowA = A.GetNrows(); 02367 int nColA = A.GetNcols(); 02368 int nRowB = B.GetNrows(); 02369 int nColB = B.GetNcols(); if(nColB){} 02370 assert(nColA ==nRowB); 02371 X.ResizeTo(nRowA,nRowA); 02372 myTCL::mxmlrtS(A.GetMatrixArray(),B.GetMatrixArray() 02373 ,X.GetMatrixArray(),nRowA,nColA); 02374 02375 } 02376 //______________________________________________________________________________ 02377 double myTCL::vasum(const double *a, int na) 02378 { 02379 double sum = 0; 02380 for (int i=0;i<na;i++) { sum += fabs(a[i]);} 02381 return sum; 02382 } 02383 //______________________________________________________________________________ 02384 double myTCL::vasum(const TVectorD &a) 02385 { 02386 return vasum(a.GetMatrixArray(),a.GetNrows()); 02387 } 02388 //______________________________________________________________________________ 02389 int myTCL::SqProgSimple( TVectorD &x 02390 ,const TVectorD &g,const TMatrixD &G 02391 ,const TVectorD &Min 02392 ,const TVectorD &Max, int iAktp) 02393 { 02394 static int nCall=0; nCall++; 02395 enum {kINIT=0,kADDCONS,kFREECONS}; 02396 int kase = kINIT; 02397 int nPars = g.GetNrows(); 02398 TVectorD xx(x),gg(g),add(nPars); 02399 TArrayI Side(nPars); 02400 int nCons=0,addCons = -1,freCons=-1,freSide=0,addSide=0,con=0; 02401 double maxGra=3e33; 02402 int iAkt = iAktp; 02403 while(1946) { 02404 // Eliminate outdated constrains 02405 freCons=-1; freSide=0; 02406 if (nCons && kase==kFREECONS ) { 02407 double tryGra=kSMALL; freCons=-1; 02408 for (int ix=0;ix<nPars;ix++) { 02409 if(!Side[ix]) continue; 02410 double gra = gg[ix]*Side[ix]; 02411 if (gra< tryGra) continue; 02412 if (gra>=maxGra) continue; 02413 freCons=ix; tryGra=gra; 02414 } 02415 if (freCons>=0) { 02416 maxGra = tryGra; 02417 freSide = Side[freCons]; 02418 Side[freCons]=0; 02419 nCons--; 02420 } 02421 } 02422 02423 if(kase==kFREECONS && freCons<0) { break;} //DONE 02424 02425 // Make new matrix, etc... 02426 TMatrixD S(G); 02427 TVectorD B(gg); 02428 if (nCons) { 02429 for (int ix=0;ix<nPars;ix++) { 02430 if (Side[ix]==0) continue; 02431 for (int jx=0;jx<nPars;jx++) {S[ix][jx]=0; S[jx][ix]=0;} 02432 S[ix][ix]=1; B[ix]=0; 02433 } } 02434 if (iAkt==0 ) { 02435 02436 double det=S.Determinant(); 02437 if (fabs(det)<1e-100) return -99; 02438 S.Invert(0); 02439 // if (det<0) iAkt=1; 02440 // else add = (-1.)*(S*B); 02441 add = (-1.)*(S*B); 02442 double along = B*add; 02443 if (along>0) add*=(-1.); 02444 } 02445 02446 if (iAkt==1 ) { 02447 double bb = (B*B); 02448 double bSb = (B*(S*B)); 02449 double tau = -bb/(fabs(bSb)+3e-33); 02450 add = tau*B; 02451 02452 } 02453 if(kase==kFREECONS && freSide) { //Free constrain case 02454 if (add[freCons]*freSide > -kSMALL) { 02455 Side[freCons]=freSide; nCons++; continue;} 02456 } 02457 02458 // Do we need new constrain? 02459 double fak=1; 02460 addCons = -1; addSide = 0; 02461 con = 0; 02462 for (int ix=0;ix<nPars;ix++) { 02463 if (Side[ix]) {add[ix]=0; con = 100*con+ix+1;continue;} 02464 double xi = xx[ix]+fak*add[ix]; 02465 if (xi < Min[ix]){fak = (Min[ix]-xx[ix])/add[ix]; addCons=ix;addSide=-1;} 02466 if (xi > Max[ix]){fak = (Max[ix]-xx[ix])/add[ix]; addCons=ix;addSide= 1;} 02467 assert(fak<=1. && fak>=0.); 02468 } 02469 add*=fak; 02470 xx+= add; 02471 gg += G*add; 02472 maxGra=3e33; 02473 kase = kFREECONS; if (!addSide) continue; 02474 kase = kADDCONS; 02475 xx[addCons] = (addSide<0)? Min[addCons]:Max[addCons]; 02476 // Add new constrain; 02477 Side[addCons] = addSide ;nCons++; 02478 02479 } //end of while(1) 02480 x = xx; 02481 return abs(con); 02482 } 02483 #endif

Generated on Sun Mar 15 04:50:46 2009 for StRoot by doxygen 1.3.7