00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "dFitter3d.h"
00014 #include "Stiostream.h"
00015 #include "TMath.h"
00016 #include "TH3.h"
00017 #include "TH1.h"
00018 #include "TMinuit.h"
00019 #include <TVector3.h>
00020 #include "TString.h"
00021 #include "TObject.h"
00022
00023
00024 ClassImp(dFitter3d)
00025
00026
00027
00028
00029
00030 void gfcn(Int_t &nParamters, Double_t *gin, Double_t &finalChi2, Double_t *parameterSet, Int_t iflag)
00031 {
00032 dFitter3d* dummy = dynamic_cast<dFitter3d*>(gMinuit->GetObjectFit()) ;
00033 dummy->mfcn(nParamters, gin, finalChi2 , parameterSet, iflag) ;
00034 }
00035
00036
00037
00038 dFitter3d::dFitter3d(TMinuit* gMinuit,TH3D* numerator, TH3D* denominator, TString opt , TString opt2)
00039 {
00040
00041 mMinuit = gMinuit ;
00042
00043
00044 mNumerator = numerator ;
00045 mDenominator = denominator ;
00046
00047
00048 if ( opt == "ykp" )
00049 {
00050 mCorrFctnType = "ykp" ;
00051 cout << "Fitting function set to Yano Koonin Podgoretskii. \n" ;
00052 }
00053 else if ( opt == "bp" )
00054 {
00055 mCorrFctnType = "bp" ;
00056 cout << "Fitting function set to Bertsch Pratt. \n" ;
00057 }
00058 else
00059 {
00060 mCorrFctnType = "ykp" ;
00061 cout << "Bad option : fitting function set to Yano Koonin Podgoretskii. \n" ;
00062 }
00063
00064
00065 if ( opt2 == "chi2" )
00066 {
00067 mFitMethod = "chi2" ;
00068 cout << "Using chi2.\n" ;
00069 }
00070 else if ( opt2 == "mml" )
00071 {
00072 mFitMethod = "mml" ;
00073 cout << "Using mml.\n" ;
00074 }
00075 else
00076 {
00077 mFitMethod = "chi2" ;
00078 cout << "Bad option : Using chi2 method.\n" ;
00079 } ;
00080
00081
00082
00083 mhc = 0.197326960277 ;
00084 mhc2 = 0.038937929230 ;
00085
00086
00087 mThresholdNumerator = 1.0 ;
00088 mThresholdDenominator = 1.0 ;
00089 }
00090
00091 dFitter3d::~dFitter3d()
00092 {
00093
00094 }
00095
00096 void dFitter3d::FillInternalArrays()
00097 {
00098
00099 cout << " Filling internal arrays with norm factor : " << mNorm
00100 << " numerator threshold : " << mThresholdNumerator
00101 << " denominator threshold : " << mThresholdDenominator << endl ;
00102
00103
00104
00105 int maximumInternalArraySize = (mNumerator->GetNbinsX()+2) * (mNumerator->GetNbinsY()+2) * (mNumerator->GetNbinsZ()+2) ;
00106 if ( maximumInternalArraySize != (mDenominator->GetNbinsX()+2) * (mDenominator->GetNbinsY()+2) * (mDenominator->GetNbinsZ()+2) )
00107 cerr << "Warning : different histogram sizes in numerator and denominator\n " ;
00108
00109
00110 mNumeratorInternalArray = new double[maximumInternalArraySize] ;
00111 mDenominatorInternalArray = new double[maximumInternalArraySize] ;
00112 mErrorInternalArray = new double[maximumInternalArraySize] ;
00113 mVariablePositionArray = new TVector3[maximumInternalArraySize] ;
00114
00115
00116 mInternalArraySize = 0 ;
00117
00118
00119 for (int index = 0 ; index < maximumInternalArraySize ; index++)
00120 {
00121 if ( mNumerator->GetBinContent(index) > mThresholdNumerator && mDenominator->GetBinContent(index) > mThresholdDenominator )
00122 {
00123
00124 int binX = 0 ;
00125 int binY = 0 ;
00126 int binZ = 0 ;
00127 Bin1ToBin3(mNumerator, index, binX, binY, binZ) ;
00128 double qx = mNumerator->GetXaxis()->GetBinCenter(binX) ;
00129 double qy = mNumerator->GetYaxis()->GetBinCenter(binY) ;
00130 double qz = mNumerator->GetZaxis()->GetBinCenter(binZ) ;
00131
00132 if ( qx*qx+qy*qy+qz*qz < mSphereLimit )
00133 {
00134
00136
00138 double num = mNumerator->GetBinContent(index) ;
00139 double denom = mDenominator->GetBinContent(index) ;
00140
00141 mNumeratorInternalArray[mInternalArraySize] = num ;
00142
00143 mDenominatorInternalArray[mInternalArraySize] = denom * mNorm ;
00144
00145
00146 double error = num/(denom*mNorm) * ::sqrt( (1/num) + (1/denom) ) ;
00147 mErrorInternalArray[mInternalArraySize] = error ;
00148
00149 mVariablePositionArray[mInternalArraySize].SetX(qx) ;
00150 mVariablePositionArray[mInternalArraySize].SetY(qy) ;
00151 mVariablePositionArray[mInternalArraySize].SetZ(qz) ;
00152
00153
00154 if (0)
00155 {
00156 cout << (double) num << "\t" << (double) (denom*mNorm) ;
00157 cout << "\t" << (double) (num/(denom*mNorm)) ;
00158 double xx = mNumerator->GetXaxis()->GetBinCenter(binX) ;
00159 double yy = mNumerator->GetYaxis()->GetBinCenter(binY) ;
00160 double zz = mNumerator->GetZaxis()->GetBinCenter(binZ) ;
00161 cout << "xa " << xx << "\t" << binX << "\t" ;
00162 cout << "ya " << yy << "\t" << binY << "\t" ;
00163 cout << "za " << zz << "\t" << binZ << endl ;
00164 }
00165
00166
00167 mInternalArraySize++ ;
00168 }
00169 }
00170 }
00171
00172 cout << "Internal array size :" << mInternalArraySize << endl ;
00173 }
00174
00175 void dFitter3d::mfcn(Int_t &nParameters, Double_t *gin, Double_t &finalChi2, Double_t *parameterSet, Int_t iflag)
00176 {
00177 if ( mFitMethod == "chi2")
00178 {
00179 fcnChi2(nParameters,gin,finalChi2,parameterSet,iflag) ;
00180 }
00181 else if ( mFitMethod == "mml")
00182 {
00183 fcnMml(nParameters,gin,finalChi2,parameterSet,iflag) ;
00184 } ;
00185 }
00186
00187 void dFitter3d::fcnChi2(Int_t &nParameters, Double_t *gin, Double_t &finalChi2, Double_t *parameterSet, Int_t iflag)
00188 {
00190
00192 double chi2 = 0.0 ;
00193
00194
00195 for (Int_t index = 0 ; index < mInternalArraySize ; index++)
00196 {
00197
00198 double theoreticalValue = mCorrelationFunction( mVariablePositionArray[index] , parameterSet) ;
00199
00200 double delta = (mNumeratorInternalArray[index]/mDenominatorInternalArray[index]-theoreticalValue)/mErrorInternalArray[index];
00201
00202 chi2 += delta*delta;
00203
00204
00205
00206 if(countMinuitCalls == 100 && index%10000==0)
00207 {
00208 cout << "ql : " << mVariablePositionArray[index].x() << "\t"
00209 << "qp : " << mVariablePositionArray[index].y() << "\t"
00210 << "q0 : " << mVariablePositionArray[index].z()<< "\t"
00211 << "thval: " << theoreticalValue << "\t"
00212 << "mes " << mNumeratorInternalArray[index]/mDenominatorInternalArray[index] << "\t"
00213 << "num: " << mNumeratorInternalArray[index] << "\t"
00214 << "th-mea" << fabs( mNumeratorInternalArray[index]/mDenominatorInternalArray[index] - theoreticalValue) << "\t"
00215 << "err " << mErrorInternalArray[index] << endl ;
00216 }
00217
00218 }
00219
00220 finalChi2 = chi2 ;
00221
00222
00223 countMinuitCalls++ ;
00224
00225 };
00226
00227 void dFitter3d::fcnMml(Int_t &nParameters, Double_t *gin, Double_t &finalMLH, Double_t *parameterSet, Int_t iflag)
00228 {
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 double MLH = 0.0 ;
00239
00240
00241 for (Int_t index = 0 ; index < mInternalArraySize ; index++)
00242 {
00243
00244 double expectedValue = mCorrelationFunction( mVariablePositionArray[index] , parameterSet) * mDenominatorInternalArray[index] ;
00245
00246 double measueredValue = mNumeratorInternalArray[index] ;
00247
00248 MLH += -expectedValue + measueredValue * ::log(expectedValue) - lnfactorial(measueredValue) ;
00249 }
00250
00251 finalMLH = - MLH ;
00252
00253
00254 countMinuitCalls++ ;
00255 }
00256
00257 double dFitter3d::lnfactorial(double arg)
00258 {
00259
00260 double fac = 1.0 ;
00261 int iarg = (int) arg ;
00262 if(iarg<50)
00263 {
00264 for (int index = 1; index < iarg+1 ; index++)
00265 { fac *=(double)index; } ;
00266 fac = ::log(fac) ;
00267 }
00268 else
00269 {
00270
00271 fac = 0.91 + (iarg+0.5) * ::log(double(iarg)) - iarg ;
00272 }
00273
00274 return fac;
00275 }
00276
00277 double dFitter3d::mCorrelationFunction(TVector3& position, double* parameterSet )
00278 {
00279 if ( mCorrFctnType == "ykp")
00280 {
00281 return ykpCorrelationFunction( position, parameterSet ) ;
00282 }
00283 else if ( mCorrFctnType == "bp")
00284 {
00285 return bpCorrelationFunction( position, parameterSet ) ;
00286 }
00287 else
00288 {
00289
00290 cout << "this should never happen.\n " ;
00291 return 0.0 ;
00292 }
00293 }
00294
00295 double dFitter3d::ykpCorrelationFunction(TVector3& position, double* parameterSet )
00296 {
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 double gamma2 = 1.0/fabs(1.0-::pow(parameterSet[4],2)) ;
00308 double mhcc = 0.038937929230 ;
00309 double c2 = 1.0 + parameterSet[0] * TMath::Exp(
00310 (
00311 (-1.0) * ::pow(position.y(),2) * ::pow(parameterSet[2],2)
00312 - gamma2 * ::pow((position.x() - parameterSet[4]*position.z()),2) * ::pow(parameterSet[1],2)
00313 - gamma2 * ::pow((position.z() - parameterSet[4]*position.x()),2) * ::pow(parameterSet[3],2)
00314 )
00315 / mhcc );
00316 return c2;
00317 };
00318
00319 double dFitter3d::bpCorrelationFunction(TVector3& position, double* parameterSet )
00320 {
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 double c2 = 1.0 + parameterSet[0] * TMath::Exp(
00332 (
00333 (-1.0) * ::pow(position.y(),2) * ::pow(parameterSet[1],2)
00334 - ::pow(position.z(),2) * ::pow(parameterSet[2],2)
00335 - ::pow(position.x(),2) * ::pow(parameterSet[3],2)
00336 - 2* position.x() * position.z() * ::pow(parameterSet[4],2)
00337 )
00338 / mhc2 );
00339 return c2 ;
00340 };
00341
00342 void dFitter3d::doFit()
00343 {
00344
00345 int ierflg = 0 ;
00346 double arglist[4];
00347
00348 if ( mCorrFctnType == "ykp")
00349 {
00350
00351 double startValues[5] = { 0.2 , 5.0 , 7.0 , 6.0 , 0.5} ;
00352
00353 double stepSize[5] = {0.1 ,0.1, 0.1 ,0.1 ,0.1 };
00354
00355 mMinuit->mnparm(0, "lambda", startValues[0], stepSize[0], 0,0,ierflg);
00356 mMinuit->mnparm(1, "Rlong", startValues[1], stepSize[1], 0,0,ierflg);
00357 mMinuit->mnparm(2, "Rperp", startValues[2], stepSize[2], 0,0,ierflg);
00358 mMinuit->mnparm(3, "Rnull", startValues[3], stepSize[3], 0,0,ierflg);
00359 mMinuit->mnparm(4, "beta", startValues[4], stepSize[4], 0,0,ierflg);
00360 }
00361 else if ( mCorrFctnType == "bp")
00362 {
00363
00364 double startValues[5] = { 0.5 , 6.0 , 6.0 , 6.0 , 6.0} ;
00365
00366 double stepSize[5] = {0.1 ,0.1, 0.1 ,0.1 ,0.1 };
00367
00368 mMinuit->mnparm(0, "lambda", startValues[0], stepSize[0], 0,0,ierflg);
00369 mMinuit->mnparm(1, "Rside", startValues[1], stepSize[1], 0,0,ierflg);
00370 mMinuit->mnparm(2, "Rout", startValues[2], stepSize[2], 0,0,ierflg);
00371 mMinuit->mnparm(3, "Rlong", startValues[3], stepSize[3], 0,0,ierflg);
00372 mMinuit->mnparm(4, "Routlong", startValues[4], stepSize[4], 0,0,ierflg);
00373 }
00374 else
00375 {
00376
00377 cout << "this should never happen.\n " ;
00378 return ;
00379 }
00380
00381
00382
00383 mMinuit->SetObjectFit(this) ;
00384 mMinuit->SetFCN(gfcn) ;
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 arglist[0] = 0; mMinuit->mnexcm("MIGRATE", arglist ,0,ierflg) ;
00405
00406
00408
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 cout << "Number of to Minuit calls : " << countMinuitCalls << endl ;
00430 }
00431
00432
00433 void dFitter3d::SetHistos(TH3D* numerator, TH3D* denominator)
00434 {
00435
00436 mNumerator = numerator ;
00437 mDenominator = denominator ;
00438
00439
00440 mRatio = (TH3D*) numerator->Clone() ;
00441 mRatio->Reset() ;
00442 mRatio->Divide(numerator,denominator,1.0,mNorm) ;
00443 }
00444
00445 void dFitter3d::Bin1ToBin3(TH3D* histo, int bin, int& binx, int& biny, int& binz)
00446 {
00447
00448
00449
00450 int nbbinX = (histo->GetNbinsX()) + 2 ;
00451 int nbbinY = (histo->GetNbinsY()) + 2 ;
00452
00453 binx = bin%nbbinX ;
00454 biny = (bin/nbbinX) % nbbinY ;
00455 binz = (bin/nbbinX) / nbbinY ;
00456
00457 }
00458
00459 void dFitter3d::setCorrFctn(TString opt)
00460 {
00461
00462 };
00463
00464 void dFitter3d::setFitMethod(TString opt2)
00465 {
00466
00467 if ( opt2 == "chi2" )
00468 {
00469 mFitMethod = "chi2" ;
00470 cout << "Using chi2.\n" ;
00471 }
00472 else if ( opt2 == "mml" )
00473 {
00474 mFitMethod = "mml" ;
00475 cout << "Using mml.\n" ;
00476 }
00477 else
00478 {
00479 mFitMethod = "chi2" ;
00480 cout << "Bad option : Using chi2 method.\n" ;
00481 } ;
00482
00483 };