macros/calib/fiterr.C
00001
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
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;
00109 float pze;
00110 float uyy;
00111 float uzz;
00112 float fye;
00113 float fze;
00114 float hye;
00115 float hze;
00116 float curv;
00117 float dens;
00118 float grf;
00119 float gpf;
00120 float gzf;
00121 float ang;
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];
00177 double *mErrs[kNDETS][2];
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
00294
00295 const int &run = th("mRun");
00296 const int &evt = th("mEvt");
00297
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
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
00358
00359 float uzz = (lZPulErr[ih]-lZHitErr[ih])*(lZHitErr[ih]+lZPulErr[ih]);
00360
00361
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
00376 mp.zpul = lZPul[ih];
00377
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
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
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
00436
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
00459
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
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
00732
00733
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
00749
00750
00751
00752
00753
00754
00755
00756
00757
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
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
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
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
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
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
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) {
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
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
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++) {
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 ) {
01213 nCut = 0; Best = Now; iAkt = 0;
01214
01215 } else if (nCut>MAXCUT[iAkt]) {
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
01227
01228
01229 static int rnd=0; rnd++;
01230 if (!(rnd&3)) iAkt=1;
01231
01232
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 }
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
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
01325 void HInit()
01326 {
01327 memset(hh,0,sizeof(hh));
01328 memset(C,0,sizeof(C));
01329
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
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])) {
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
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
01485
01486
01487
01488
01489
01490
01491
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
01526
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
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
01684
01685
01686
01687
01688
01689
01690
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
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) {
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
01736
01737
01738
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
01794
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
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
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
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
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
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
01916
01917
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
01947
01948
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
02164
02165
02166
02167
02168
02169 static TCanvas *myCanvas=0;
02170 static TGraph *graph[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
02171
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
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) {
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 {
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 }
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 }
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 }
02250 }
02251
02252 }
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) {
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
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
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
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;}
02424
02425
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
02440
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) {
02454 if (add[freCons]*freSide > -kSMALL) {
02455 Side[freCons]=freSide; nCons++; continue;}
02456 }
02457
02458
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
02477 Side[addCons] = addSide ;nCons++;
02478
02479 }
02480 x = xx;
02481 return abs(con);
02482 }
02483 #endif
Generated on Sun Mar 15 04:50:46 2009 for StRoot by
1.3.7