HbtFitter.cxx 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483
  1. #include "HbtFitter.h"
  2. #include <TMath.h>
  3. #include <TString.h>
  4. #include <iostream>
  5. Double_t R_GAUS_TO_EXPO = 1./TMath::Sqrt( TMath::Pi() );
  6. Double_t hBar = 0.1973269718;
  7. //_________________
  8. HbtFitter* HbtFitter::objHbtFitter=0;
  9. //_________________
  10. HbtFitter::HbtFitter(Int_t PartType, Int_t SourceForm,
  11. Int_t NonFemtoForm, Bool_t ExcludePoints) {
  12. //Set basic parameters
  13. SetPartType(PartType);
  14. SetSourceForm(SourceForm);
  15. SetNonFemtoForm(NonFemtoForm);
  16. SetExcludeFromFit(ExcludePoints);
  17. SetFitMethod(0);
  18. //Correct on MC or not
  19. mCorrectOnMc = false;
  20. //Project by bins or by vals
  21. mProjectionType = false;
  22. //Number of femtoscopic parameters: lambda, R
  23. mFemto1DParNum = 2;
  24. mFemto3DParNum = 7;
  25. //Fixed parameter vector initialization
  26. if(!mFixParameters1D.empty()) {
  27. mFixParameters1D.clear();
  28. }
  29. if(!mFixParameters3D.empty()) {
  30. mFixParameters3D.clear();
  31. }
  32. //Initialize fit parameters
  33. mQinvVal[0] = 0.; mQinvVal[1] = 1.;
  34. mQoutVal[0] = 0.; mQoutVal[1] = 1.;
  35. mQsideVal[0] = 0.; mQsideVal[1] = 1.;
  36. mQlongVal[0] = 0.; mQlongVal[1] = 1.;
  37. //Number of Q bins
  38. mQinvNbins = 50;
  39. mQoutNbins = 50;
  40. mQsideNbins = 50;
  41. mQlongNbins = 50;
  42. //Projection ranges (in bins and in vals)
  43. mOutProjBins[0] = 1; mOutProjBins[1] = 6;
  44. mSideProjBins[0] = 1; mSideProjBins[1] = 6;
  45. mLongProjBins[0] = 1; mLongProjBins[1] = 6;
  46. mOutProjVals[0] = 0.; mOutProjVals[1] = 0.05;
  47. mSideProjVals[0] = 0.; mSideProjVals[1] = 0.05;
  48. mLongProjVals[0] = 0.; mLongProjVals[1] = 0.05;
  49. //Clean fit parameters
  50. if(!mFemto1DVal.empty()) {
  51. mFemto1DVal.clear();
  52. }
  53. if(!mFemto1DValErr.empty()) {
  54. mFemto1DValErr.clear();
  55. }
  56. if(!mNonFemto1DVal.empty()) {
  57. mNonFemto1DVal.clear();
  58. }
  59. if(!mNonFemto1DValErr.empty()) {
  60. mNonFemto1DValErr.clear();
  61. }
  62. if(!mFemto3DVal.empty()) {
  63. mFemto3DVal.clear();
  64. }
  65. if(!mFemto3DValErr.empty()) {
  66. mFemto3DValErr.clear();
  67. }
  68. if(!mNonFemto3DVal.empty()) {
  69. mNonFemto3DVal.clear();
  70. }
  71. if(!mNonFemto3DValErr.empty()) {
  72. mNonFemto3DValErr.clear();
  73. }
  74. //Use Coulomb correction if it is not set
  75. mUseCoulombCorrection = true;
  76. //Initialize 1D non-femto parameters
  77. for(Int_t iIter=0; iIter<3; iIter++) {
  78. mNonFemto1DParArr[iIter] = 0;
  79. mNonFemto1DParErrArr[iIter] = 0;
  80. }
  81. //Initialize 3D non-femto parameters
  82. for(Int_t iIter1=0; iIter1<3; iIter1++) { //Out,Side,Long
  83. //iIter1 corresponds to out,side,long
  84. for(Int_t iIter2=0; iIter2<3; iIter2++) {
  85. //iIter2 corresponds to the mNonFemtoParNum
  86. mNonFemto3DParArr[iIter1][iIter2] = 0;
  87. mNonFemto3DParErrArr[iIter1][iIter2] = 0;
  88. }
  89. }
  90. //Set null pointers to the histograms
  91. h1dNumer = NULL;
  92. h1dDenom = NULL;
  93. h1dCorrFctn = NULL;
  94. h1dMcNumer = NULL;
  95. h1dMcDenom = NULL;
  96. h1dMcCorrFctn = NULL;
  97. h3dNumer = NULL;
  98. h3dDenom = NULL;
  99. h3dCorrFctn = NULL;
  100. h3dCoulombWeight = NULL;
  101. h3dMcNumer = NULL;
  102. h3dMcDenom = NULL;
  103. h3dMcCorrFctn = NULL;
  104. //3D fit numerator
  105. h3dFitNumerator = NULL;
  106. h3dFitQoutProj = NULL;
  107. h3dFitQsideProj = NULL;
  108. h3dFitQlongProj = NULL;
  109. //3D correlation function and 3D fit projections
  110. h3dQoutProjNum = NULL;
  111. h3dQoutProjDen = NULL;
  112. h3dMcQoutProjNum = NULL;
  113. h3dMcQoutProjDen = NULL;
  114. h3dQsideProjNum = NULL;
  115. h3dQsideProjDen = NULL;
  116. h3dMcQsideProjNum = NULL;
  117. h3dMcQsideProjDen = NULL;
  118. h3dQlongProjNum = NULL;
  119. h3dQlongProjDen = NULL;
  120. h3dMcQlongProjNum = NULL;
  121. h3dMcQlongProjDen = NULL;
  122. h3dCorrFctnOutProj = NULL;
  123. h3dCorrFctnFitOutProj = NULL;
  124. h3dCorrFctnSideProj = NULL;
  125. h3dCorrFctnFitSideProj = NULL;
  126. h3dCorrFctnLongProj = NULL;
  127. h3dCorrFctnFitLongProj = NULL;
  128. //Pointer to the current object
  129. SetObject(this);
  130. }
  131. //_________________
  132. HbtFitter::~HbtFitter() {
  133. /* empty */
  134. }
  135. //_________________
  136. void HbtFitter::SetCorrectOnMc(Bool_t corr) {
  137. mCorrectOnMc = corr;
  138. std::cout << "HbtFitter::SetCorrectOnMc : " << mCorrectOnMc << std::endl;
  139. }
  140. //_________________
  141. void HbtFitter::SetSourceForm(Int_t SourceForm) {
  142. mSourceForm = SourceForm;
  143. std::cout << "HbtFitter::SetSourceForm : " << mSourceForm << std::endl;
  144. }
  145. //_________________
  146. void HbtFitter::SetNonFemtoForm(Int_t form) {
  147. /*
  148. Non-femtoscopic forms:
  149. 0 - constant
  150. 1 - linear
  151. 2 - 2nd oreder polynomial
  152. 3 - sqrt(1 + a x^2 + b x^4) (sqrt tail)
  153. 4 - a ( 1 + e^{b x^2}) (Gaussian tail)
  154. 5 - a / (1 + b x^2) (hyperbolic tail)
  155. */
  156. mNonFemtoForm = form;
  157. switch(mNonFemtoForm) {
  158. case 0 :
  159. mNonFemto1DParNum = 1;
  160. mNonFemto3DParNum = 1;
  161. break;
  162. case 1 :
  163. mNonFemto1DParNum = 2;
  164. mNonFemto3DParNum = 4;
  165. break;
  166. case 2 :
  167. mNonFemto1DParNum = 3;
  168. mNonFemto3DParNum = 7;
  169. break;
  170. case 3 :
  171. mNonFemto1DParNum = 3;
  172. mNonFemto3DParNum = 7;
  173. break;
  174. case 4 :
  175. mNonFemto1DParNum = 2;
  176. mNonFemto3DParNum =4;
  177. break;
  178. case 5 :
  179. mNonFemto1DParNum = 2;
  180. mNonFemto3DParNum = 4;
  181. break;
  182. default:
  183. std::cout << "SetNonFemtoForm: Unknown non-femtoscopic form" << std::cout;
  184. mNonFemto1DParNum = 1;
  185. mNonFemto3DParNum = 1;
  186. break;
  187. }
  188. std::cout << "HbtFitter::SetNonFemtoForm : " << mNonFemtoForm << std::endl;
  189. }
  190. //_________________
  191. void HbtFitter::SetFitMethod(Int_t method) {
  192. switch(method) {
  193. case 0: //ChiSquare
  194. mFitMethod = 0;
  195. std::cout << "HbtFitter::FitMethod : ChiSquare" << std::endl;
  196. break;
  197. case 1: //Log-likelihood
  198. mFitMethod = 1;
  199. std::cout << "HbtFitter::FitMethod : Log-Likelihood" << std::endl;
  200. break;
  201. default: //ChiSquare
  202. mFitMethod = 0;
  203. std::cout << "HbtFitter::FitMethod : [WARNING] - unknown fit method"
  204. << "\nReset to ChiSquare" << std::endl;
  205. break;
  206. }
  207. }
  208. //_________________
  209. void HbtFitter::Set1DFitRange(Double_t qLo, Double_t qHi) {
  210. mQinvFitRange[0] = qLo;
  211. mQinvFitRange[1] = qHi;
  212. if(h1dNumer) {
  213. mQinvFitRangeBin[0] = h1dNumer->GetXaxis()->FindBin(mQinvFitRange[0]);
  214. mQinvFitRangeBin[1] = h1dNumer->GetXaxis()->FindBin(mQinvFitRange[1]);
  215. }
  216. else {
  217. std::cout << "HbtFitter::Set1DFitRange [WARNING] Fit range is set to default values" << std::endl;
  218. mQinvFitRangeBin[0] = 1;
  219. mQinvFitRangeBin[1] = mQinvNbins;
  220. }
  221. }
  222. //_________________
  223. void HbtFitter::Set3DFitRange(Double_t qOutLo, Double_t qOutHi,
  224. Double_t qSideLo, Double_t qSideHi,
  225. Double_t qLongLo, Double_t qLongHi) {
  226. mQoutFitRange[0] = qOutLo; mQoutFitRange[1] = qOutHi;
  227. mQsideFitRange[0] = qSideLo; mQsideFitRange[1] = qSideHi;
  228. mQlongFitRange[0] = qLongLo; mQlongFitRange[1] = qLongHi;
  229. if(h3dNumer) {
  230. mQoutFitRangeBin[0] = h3dNumer->GetXaxis()->FindBin(mQoutFitRange[0]);
  231. mQoutFitRangeBin[1] = h3dNumer->GetXaxis()->FindBin(mQoutFitRange[1]);
  232. mQsideFitRangeBin[0] = h3dNumer->GetXaxis()->FindBin(mQsideFitRange[0]);
  233. mQsideFitRangeBin[1] = h3dNumer->GetXaxis()->FindBin(mQsideFitRange[1]);
  234. mQlongFitRangeBin[0] = h3dNumer->GetXaxis()->FindBin(mQlongFitRange[0]);
  235. mQlongFitRangeBin[1] = h3dNumer->GetXaxis()->FindBin(mQlongFitRange[1]);
  236. }
  237. else {
  238. std::cout << "HbtFitter::Set3DFitRange [WARNING] Fit range is set to default values" << std::endl;
  239. mQoutFitRangeBin[0] = 1; mQoutFitRangeBin[1] = mQoutNbins;
  240. mQsideFitRangeBin[0] = 1; mQsideFitRangeBin[1] = mQsideNbins;
  241. mQlongFitRangeBin[0] = 1; mQlongFitRangeBin[1] = mQlongNbins;
  242. }
  243. std::cout << "Fit ranges: " << std::endl
  244. << "Qout : " << mQoutFitRange[0] << "<=Qout<=" << mQoutFitRange[1]
  245. << " " << mQoutFitRangeBin[0] << "<=QoutBin<=" << mQoutFitRangeBin[1] << std::endl
  246. << "Qside : " << mQsideFitRange[0] << "<=Qside<=" << mQsideFitRange[1]
  247. << " " << mQsideFitRangeBin[0] << "<=QsideBin<=" << mQsideFitRangeBin[1] << std::endl
  248. << "Qlong : " << mQlongFitRange[0] << "<=Qlong<=" << mQlongFitRange[1]
  249. << " " << mQlongFitRangeBin[0] << "<=QlongBin<=" << mQlongFitRangeBin[1] << std::endl;
  250. }
  251. //_________________
  252. void HbtFitter::Fit1D() {
  253. //Double check if the points were really exluded
  254. /*
  255. if(mExcludeRange == 1) {
  256. if(x[0] > mExcludedVal[0] && x[0]<mExcludedVal[1]) {
  257. TF1::RejectPoint();
  258. return 0;
  259. }
  260. }
  261. */
  262. Double_t mAutoParVal[5] = {0.5, 5., 1., 0., 0.};
  263. Double_t mAutoParValErr[5] = {0.01, 0.01, 0.01, 0.01, 0.01};
  264. TString mParNames[5] = {"#lambda", "R_{inv}", "N", "a", "b"};
  265. Int_t mFitParNum = mFemto1DParNum + mNonFemto1DParNum;
  266. //From Victor M. Perevozchikov
  267. SetObject(this);
  268. TMinuit mFit(mFitParNum);
  269. switch(mFitMethod) {
  270. case 0:
  271. std::cout << "Fit1D: ChiSquare method has been initialized" << std::endl;
  272. mFit.SetFCN(HbtFitter::FitFunc1DChiSquare);
  273. break;
  274. case 1:
  275. std::cout << "Fit1D: Log-likelihood method has been initialized" << std::endl;
  276. mFit.SetFCN(HbtFitter::FitFunc1DLogLike);
  277. break;
  278. default:
  279. std::cout << "Fit1D: Default method has been initialized" << std::endl;
  280. mFit.SetFCN(HbtFitter::FitFunc1DChiSquare);
  281. break;
  282. }
  283. Double_t mInitParVal[mFitParNum];
  284. Double_t mInitParValErr[mFitParNum];
  285. TString mInitParName[mFitParNum];
  286. for(Int_t iIter=0; iIter<mFitParNum; iIter++) {
  287. mInitParVal[iIter] = mAutoParVal[iIter];
  288. mInitParValErr[iIter] = mAutoParValErr[iIter];
  289. mInitParName[iIter] = mParNames[iIter];
  290. mFit.DefineParameter(iIter,mInitParName[iIter].Data(),mInitParVal[iIter],mInitParValErr[iIter], 0, 0);
  291. }
  292. //Fix fit parameters
  293. if(!mFixParameters1D.empty()) {
  294. for(UInt_t iIter=0; iIter<mFixParameters1D.size(); iIter++) {
  295. mFit.FixParameter(mFixParameters1D.at(iIter));
  296. }
  297. }
  298. Double_t mArgList[mFitParNum];
  299. Int_t ierflag = 0;
  300. Int_t mNFitCycles = 0;
  301. do {
  302. mNFitCycles++;
  303. std::cout << "********** Fit loop " <<mNFitCycles << std::endl;
  304. //mFit.mnexcm("SIMPLEX", mArgList, 0, ierflag);
  305. mFit.mnexcm("MIGRAD", mArgList, 0, ierflag);
  306. } while( (ierflag!=0) && (mNFitCycles!=50) );
  307. Double_t mFitVal, mFitValErr;
  308. //Return femtoscopic fit parameters
  309. for(Int_t iIter=0; iIter<mFemto1DParNum; iIter++) {
  310. mFitVal=0.; mFitValErr=0.;
  311. mFit.GetParameter(iIter, mFitVal, mFitValErr);
  312. mFemto1DVal.push_back(mFitVal);
  313. mFemto1DValErr.push_back(mFitValErr);
  314. std::cout << Form("%s = %3.2f +- %3.2f", mParNames[iIter].Data(),
  315. mFitVal, mFitValErr) << std::endl;
  316. }
  317. //Return non-femtoscopic fit parameters
  318. for(Int_t iIter=mFemto1DParNum; iIter<mFitParNum; iIter++) {
  319. mFitVal=0.; mFitValErr=0.;
  320. mFit.GetParameter(iIter, mFitVal, mFitValErr);
  321. mNonFemto1DVal.push_back(mFitVal);
  322. mNonFemto1DValErr.push_back(mFitValErr);
  323. std::cout << Form("%s = %3.2f +- %3.2f", mParNames[iIter].Data(),
  324. mFitVal, mFitValErr) << std::endl;
  325. }
  326. }
  327. //_________________
  328. void HbtFitter::Fit3D() {
  329. //Initial values: L Ro Rs Rl Ros Rol Rsl
  330. // N ao as al bo bs bl
  331. Double_t mAutoParVal[14] = {0.5, 4., 4., 4., 0., 0., 0.,
  332. 2.0, 0., 0., 0., 0., 0., 0.};
  333. // L Ro Rs Rl Ros Rol Rsl
  334. // N ao as al bo bs bl
  335. Double_t mAutoParValErr[14] = {0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01,
  336. 0.001, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01};
  337. // L Ro Rs Rl Ros Rol Rsl
  338. // N ao as al bo bs bl
  339. Double_t mAutoParValLo[14] = {0., 0., 0., 0., 0., 0., 0.,
  340. 0., -5., -5., -5., -2., -2., -2.};
  341. // L Ro Rs Rl Ros Rol Rsl
  342. // N ao as al bo bs bl
  343. Double_t mAutoParValHi[14] = {1.05, 60., 60., 60., 60., 60., 60.,
  344. 5., 5., 5., 5., 2., 2., 2.};
  345. TString mParNames[14] = {"Lambda", "R_{out}", "R_{side}", "R_{long}",
  346. "R_{out-side}", "R_{out-long}", "R_{side-long}",
  347. "Norm", "A_{out}", "A_{side}", "A_{long}",
  348. "B_{out}", "B_{side}", "B_{long}"};
  349. Int_t mFitParNum = mFemto3DParNum + mNonFemto3DParNum;
  350. TMinuit mFit(mFitParNum);
  351. switch(mFitMethod) {
  352. case 0:
  353. std::cout << "Fit3D: ChiSquare method has been initialized" << std::endl;
  354. mFit.SetFCN(HbtFitter::FitFunc3DChiSquare);
  355. break;
  356. case 1:
  357. std::cout << "Fit3D: Log-likelihood method has been initialized" << std::endl;
  358. mFit.SetFCN(HbtFitter::FitFunc3DLogLike);
  359. break;
  360. default:
  361. std::cout << "Fit3D: Default method has been initialized" << std::endl;
  362. mFit.SetFCN(HbtFitter::FitFunc3DLogLike);
  363. break;
  364. }
  365. Double_t mInitParVal[mFitParNum];
  366. Double_t mInitParValErr[mFitParNum];
  367. Double_t mInitParValLo[mFitParNum];
  368. Double_t mInitParValHi[mFitParNum];
  369. TString mInitParName[mFitParNum];
  370. for(Int_t iIter=0; iIter<mFitParNum; iIter++) {
  371. mInitParVal[iIter] = mAutoParVal[iIter];
  372. mInitParValErr[iIter] = mAutoParValErr[iIter];
  373. mInitParValLo[iIter] = mAutoParValLo[iIter];
  374. mInitParValHi[iIter] = mAutoParValHi[iIter];
  375. mInitParName[iIter] = mParNames[iIter];
  376. mFit.DefineParameter(iIter, mInitParName[iIter].Data(),
  377. mInitParVal[iIter], mInitParValErr[iIter],
  378. mInitParValLo[iIter], mInitParValHi[iIter]);
  379. }
  380. //Fix fit parameters
  381. if(!mFixParameters3D.empty()) {
  382. for(UInt_t iIter=0; iIter<mFixParameters3D.size(); iIter++) {
  383. mFit.FixParameter(mFixParameters3D.at(iIter));
  384. }
  385. }
  386. mFit.SetErrorDef(0.5); //Log-likelihood minimization
  387. Double_t mArgList[mFitParNum];
  388. Int_t ierflag = 0;
  389. Int_t mNFitCycles = 0;
  390. std::cout << "Start 3D fit" << std::endl;
  391. do {
  392. mNFitCycles++;
  393. std::cout << "********** Fit loop " <<mNFitCycles << std::endl;
  394. mFit.mnexcm("MIGRAD", mArgList, 0, ierflag);
  395. } while( (ierflag!=0) && (mNFitCycles!=50) );
  396. std::cout << "The 3D fit has been finished" << std::endl;
  397. Double_t mFitVal, mFitValErr;
  398. //Return femtoscopic fit parameters
  399. for(Int_t iIter=0; iIter<mFemto3DParNum; iIter++) {
  400. mFitVal=0.; mFitValErr=0.;
  401. mFit.GetParameter(iIter, mFitVal, mFitValErr);
  402. mFemto3DVal.push_back(mFitVal);
  403. mFemto3DValErr.push_back(mFitValErr);
  404. }
  405. //Return non-femtoscopic fit parameters
  406. for(Int_t iIter=mFemto3DParNum; iIter<mFitParNum; iIter++) {
  407. mFitVal=0.; mFitValErr=0.;
  408. mFit.GetParameter(iIter, mFitVal, mFitValErr);
  409. mNonFemto3DVal.push_back(mFitVal);
  410. mNonFemto3DValErr.push_back(mFitValErr);
  411. }
  412. if(!h3dCorrFctn) {
  413. h3dCorrFctn = new TH3F("h3dCorrFctn","h3dCorrFctn",
  414. mQoutNbins,mQoutVal[0],mQoutVal[1],
  415. mQsideNbins,mQsideVal[0],mQsideVal[1],
  416. mQlongNbins,mQlongVal[0],mQlongVal[1]);
  417. h3dCorrFctn->Divide(h3dNumer,h3dDenom);
  418. }
  419. }
  420. //_________________
  421. void HbtFitter::Set3DBinsNum(Int_t OutNBins, Int_t SideNBins, Int_t LongNBins) {
  422. mQoutNbins = OutNBins;
  423. mQsideNbins = SideNBins;
  424. mQlongNbins = LongNBins;
  425. }
  426. //_________________
  427. void HbtFitter::Set3DHistoRange(Double_t outLo, Double_t outHi,
  428. Double_t sideLo, Double_t sideHi,
  429. Double_t longLo, Double_t longHi) {
  430. mQoutVal[0] = outLo; mQoutVal[1] = outHi;
  431. mQsideVal[0] = sideLo; mQsideVal[1] = sideHi;
  432. mQlongVal[0] = longLo; mQlongVal[1] = longHi;
  433. }
  434. //_________________
  435. void HbtFitter::Set1DNonFemtoParameters(vector<double> par) {
  436. for(UInt_t i=0; i<par.size(); i++) {
  437. mNonFemto1DParArr[i] = par.at(i);
  438. }
  439. }
  440. //_________________
  441. void HbtFitter::Set3DNonFemtoParameters(vector<double> parOut,
  442. vector<double> parSide,
  443. vector<double> parLong) {
  444. //Assuming the same amount of parameters
  445. //for out, side and long components
  446. for(UInt_t i=0; i<parOut.size(); i++) {
  447. mNonFemto3DParArr[0][i] = parOut.at(i);
  448. mNonFemto3DParArr[1][i] = parSide.at(i);
  449. mNonFemto3DParArr[2][i] = parLong.at(i);
  450. }
  451. }
  452. //_________________
  453. void HbtFitter::SetExcludeRange(Double_t qInvLo, Double_t qInvHi) {
  454. //Exlude range from the fit
  455. mExcludedVal[0] = qInvLo;
  456. mExcludedVal[1] = qInvHi;
  457. }
  458. //_________________
  459. Double_t HbtFitter::Coulomb1D(Int_t qInvBin) {
  460. Double_t coulombVal;
  461. switch(mPartType) {
  462. case 3:
  463. coulombVal = PI_LONG[qInvBin-1];
  464. break;
  465. case 4:
  466. coulombVal = KK_LONG[qInvBin-1];
  467. break;
  468. default:
  469. std::cout << "Coulomb1D: Unknown particle type" << std::endl;
  470. coulombVal = 1.;
  471. break;
  472. }
  473. return coulombVal;
  474. }
  475. //_________________
  476. Double_t HbtFitter::Coulomb3D(Int_t qOutBin, Int_t qSideBin, Int_t qLongBin) {
  477. Double_t coulombVal;
  478. if(!h3dCoulombWeight) { //If coulomb qInv weight function is not set
  479. std::cout << "Coulomb3D: The histogram with Coulomb weights is not set" << std::endl;
  480. coulombVal = 1.;
  481. }
  482. else { //If 3D qInv weight function is set
  483. //Obtain qInv weight from 3D
  484. Double_t qInvWeight = h3dCoulombWeight->GetBinContent(qOutBin, qSideBin, qLongBin);
  485. //Calculation of the Coulomb bin correction
  486. Int_t qBins = mQoutNbins;
  487. Double_t qHi = mQoutVal[1];
  488. Double_t qLow = h3dCoulombWeight->GetXaxis()->GetBinLowEdge(1);
  489. Double_t qStep = (qHi-qLow)/qBins;
  490. Int_t qCoulBin = (Int_t)(qInvWeight/qStep);
  491. //Obtain 1D Coulomb correction
  492. switch(mPartType) {
  493. case 3:
  494. coulombVal = PI_LONG[qCoulBin];
  495. break;
  496. case 4:
  497. coulombVal = KK_LONG[qCoulBin];
  498. break;
  499. default:
  500. std::cout << "Coulomb3D: Unknown particle type" << std::endl;
  501. coulombVal = 1.;
  502. break;
  503. }
  504. if(coulombVal<0.0001) {
  505. coulombVal=1.;
  506. }
  507. /*
  508. std::cout << Form("Coulomb3D: oBin=%2d sBin=%2d lBin=%2d cVal=%4.3f",
  509. qOutBin, qSideBin, qLongBin, coulombVal) << std::endl;
  510. */
  511. }
  512. return coulombVal;
  513. }
  514. //_________________
  515. Double_t HbtFitter::TheorCorrFctn1D(Double_t *par, Int_t qInvBin) {
  516. Double_t mArg = 0;
  517. Double_t mTheory = 0;
  518. Double_t mNonFemto = 0;
  519. Double_t qInv = h1dNumer->GetBinCenter(qInvBin);
  520. Double_t qCoul;
  521. if(mUseCoulombCorrection==0) {
  522. qCoul = 1.;
  523. }
  524. else {
  525. qCoul = Coulomb1D(qInvBin);
  526. }
  527. switch(mSourceForm) {
  528. case 0: //Gaussian source
  529. mArg = qInv*qInv*par[1]*par[1];
  530. mArg /= -1.*hBar*hBar;
  531. break;
  532. case 1: //Exponential source
  533. mArg = qInv*par[1];
  534. mArg /= -1.*hBar*hBar;
  535. mArg /= R_GAUS_TO_EXPO; //Scale from expo to gauss
  536. break;
  537. default:
  538. std::cout << "TheorCorrFctn1D: Unknown source form" << std::endl;
  539. mArg = qInv*qInv*par[1]*par[1];
  540. break;
  541. }
  542. mTheory = (1 - par[0]) + par[0]*qCoul*(1+TMath::Exp(mArg)) *
  543. NonFemto1D(&par[2], qInv); //Ideal * NonFemto
  544. return mTheory;
  545. }
  546. //_________________
  547. Double_t HbtFitter::TheorCorrFctn3D(Double_t *par, Int_t qOutBin, Int_t qSideBin, Int_t qLongBin) {
  548. Double_t mArg = 0.;
  549. Double_t mTheory = 0.;
  550. Double_t mNonFemto = 0.;
  551. Double_t qOut = h3dNumer->GetXaxis()->GetBinCenter(qOutBin);
  552. Double_t qSide = h3dNumer->GetYaxis()->GetBinCenter(qSideBin);
  553. Double_t qLong = h3dNumer->GetZaxis()->GetBinCenter(qLongBin);
  554. Double_t qCoul;
  555. if(mUseCoulombCorrection == 0) {
  556. qCoul = 1.;
  557. }
  558. else {
  559. qCoul = Coulomb3D(qOutBin, qSideBin, qLongBin);
  560. }
  561. switch(mSourceForm) {
  562. case 0: //Gaussian source
  563. mArg = par[1]*par[1]*qOut*qOut; //Out^2
  564. mArg += par[2]*par[2]*qSide*qSide; //Side^2
  565. mArg += par[3]*par[3]*qLong*qLong; //Long^2
  566. mArg += 2*par[4]*par[4]*qOut*qSide; //Out*Side
  567. mArg += 2*par[5]*par[5]*qOut*qLong; //Out*Long
  568. mArg += 2*par[6]*par[6]*qSide*qLong; //Side*Long
  569. mArg /= -1.*hBar*hBar;
  570. break;
  571. case 1: //Exponential source. Note that the cross-terms should not present in fit
  572. mArg = TMath::Abs(par[1]*par[1]*qOut*qOut); //Out
  573. mArg += TMath::Abs(par[2]*par[2]*qSide*qSide); //Side
  574. mArg += TMath::Abs(par[3]*par[3]*qLong*qLong); //Long
  575. mArg += 2*par[4]*qOut*qSide; //Out*Side
  576. mArg += 2*par[5]*qOut*qLong; //Out*Long
  577. mArg += 2*par[6]*qSide*qLong; //Side*Long
  578. mArg /= -1.*hBar*hBar;
  579. mArg /= R_GAUS_TO_EXPO; //Scale from expo to gaus
  580. break;
  581. }
  582. mTheory = (1 - par[0] + par[0]*qCoul*(1+TMath::Exp(mArg))) *
  583. NonFemto3D(&par[7], qOut, qSide, qLong); //Ideal*NonFemto
  584. return mTheory;
  585. }
  586. //_________________
  587. Double_t HbtFitter::NonFemto1D(Double_t *par, Double_t qInv) {
  588. Double_t nonFemtoVal = 0;
  589. switch(mNonFemtoForm) {
  590. case 0: //Constant
  591. nonFemtoVal = par[0];
  592. break;
  593. case 1: //Linear
  594. nonFemtoVal = par[0]*(1 + par[1]*qInv);
  595. break;
  596. case 2: //Second oreder polynomial
  597. nonFemtoVal = par[0]*(1 + par[1]*qInv + par[2]*qInv*qInv);
  598. break;
  599. case 3: //Sqrt(pol4)
  600. nonFemtoVal = par[0]*TMath::Sqrt(1 + par[1]*qInv*qInv + par[2]*qInv*qInv*qInv*qInv);
  601. break;
  602. case 4: //Gaussian-like
  603. nonFemtoVal = par[0]*(1 + TMath::Exp(-par[1]*qInv*qInv));
  604. break;
  605. case 5: //Hyperbolic
  606. nonFemtoVal = par[0] / (1 + par[1]*qInv*qInv);
  607. break;
  608. default:
  609. nonFemtoVal = par[0];
  610. break;
  611. }
  612. return nonFemtoVal;
  613. }
  614. //_________________
  615. Double_t HbtFitter::NonFemto3D(Double_t *par, Double_t qOut, Double_t qSide, Double_t qLong) {
  616. Double_t nonFemtoVal = 0;
  617. Double_t mArg;
  618. switch(mNonFemtoForm) {
  619. case 0: //Constant
  620. nonFemtoVal = par[0];
  621. break;
  622. case 1: //Linear
  623. nonFemtoVal = 1;
  624. nonFemtoVal += par[1]*qOut;
  625. nonFemtoVal += par[2]*qSide;
  626. nonFemtoVal += par[3]*qLong;
  627. nonFemtoVal *= par[0];
  628. break;
  629. case 2: //Second order polynomial
  630. nonFemtoVal = 1;
  631. nonFemtoVal += par[1]*qOut;
  632. nonFemtoVal += par[2]*qSide;
  633. nonFemtoVal += par[3]*qLong;
  634. nonFemtoVal += par[4]*qOut*qOut;
  635. nonFemtoVal += par[5]*qSide*qSide;
  636. nonFemtoVal += par[6]*qLong*qLong;
  637. nonFemtoVal *= par[0];
  638. break;
  639. case 3: //Sqrt(Pol4)
  640. mArg = 1;
  641. mArg += par[1]*qOut*qOut;
  642. mArg += par[2]*qSide*qSide;
  643. mArg += par[3]*qLong*qLong;
  644. mArg += par[4]*qOut*qOut*qOut*qOut;
  645. mArg += par[5]*qSide*qSide*qSide*qSide;
  646. mArg += par[6]*qLong*qLong*qLong*qLong;
  647. nonFemtoVal = TMath::Sqrt(mArg);
  648. nonFemtoVal *= par[0];
  649. break;
  650. case 4: //Gaussian-like
  651. nonFemtoVal = 1;
  652. nonFemtoVal += TMath::Exp(-1.*par[1]*qOut*qOut);
  653. nonFemtoVal += TMath::Exp(-1.*par[2]*qSide*qSide);
  654. nonFemtoVal += TMath::Exp(-1.*par[3]*qLong*qLong);
  655. nonFemtoVal *= par[0];
  656. break;
  657. case 5: //Hyperbolic
  658. nonFemtoVal = par[0];
  659. mArg = 1;
  660. mArg += par[1]*qOut*qOut;
  661. mArg += par[2]*qSide*qSide;
  662. mArg += par[3]*qLong*qLong;
  663. nonFemtoVal /= mArg;
  664. break;
  665. default:
  666. nonFemtoVal = par[0];
  667. break;
  668. }
  669. return nonFemtoVal;
  670. }
  671. //_________________
  672. Double_t HbtFitter::CorrFctn1DChiSqr(Int_t &npar, Double_t *gin, Double_t &f,
  673. Double_t *par, Int_t iflag) {
  674. f = 0.;
  675. Double_t mChisq = 0;
  676. Double_t mDelta;
  677. Double_t mQinvErr, A, B, C;
  678. Double_t mcA, mcB;
  679. Int_t mNQinvBins = mQinvNbins;
  680. Double_t mNonFemtoCorrFactor = 1.;
  681. TH1F hCorrectedOnMc("hCorrectedOnMc","hCorrectedOnMc",mQinvNbins, mQinvVal[0], mQinvVal[1]);
  682. if(mCorrectOnMc) {
  683. hCorrectedOnMc.Divide(h1dCorrFctn,h1dMcCorrFctn);
  684. }
  685. //Calculating overall chi2
  686. for(Int_t iQbin = mQinvFitRangeBin[1]; iQbin>=mQinvFitRangeBin[0]; iQbin--) {
  687. mQinvErr = h1dCorrFctn->GetBinError(iQbin);
  688. A = h1dNumer->GetBinContent(iQbin);
  689. B = h1dDenom->GetBinContent(iQbin);
  690. C = A/B;
  691. //If divide on MC CorrFctn
  692. if(mCorrectOnMc) {
  693. mNonFemtoCorrFactor = h1dMcCorrFctn->GetBinContent(iQbin);
  694. C /= mNonFemtoCorrFactor;
  695. mQinvErr = hCorrectedOnMc.GetBinError(iQbin);
  696. }
  697. if( (A>=0.0001) && (B>=0.0001)) {
  698. mDelta = (C - TheorCorrFctn1D(par, iQbin))/mQinvErr;
  699. mChisq += mDelta*mDelta;
  700. }
  701. }
  702. f = mChisq;
  703. return f;
  704. }
  705. //_________________
  706. Double_t HbtFitter::CorrFctn1DLogLike(Int_t &npar, Double_t *gin, Double_t &f,
  707. Double_t *par, Int_t iflag) {
  708. f = 0.;
  709. Double_t mChisq = 0;
  710. Double_t mDelta;
  711. Double_t A, B, C, mcA, mcB;
  712. Int_t mNQinvBins = mQinvNbins;
  713. Double_t mNonFemtoCorrFactor;
  714. //Calculating of the log-likelihood chi2
  715. for(Int_t iQbin = mQinvFitRangeBin[1]; iQbin>=mQinvFitRangeBin[0]; iQbin--) {
  716. A = h1dNumer->GetBinContent(iQbin);
  717. B = h1dDenom->GetBinContent(iQbin);
  718. if(mCorrectOnMc) {
  719. mcA = h1dMcNumer->GetBinContent(iQbin);
  720. mcB = h1dMcDenom->GetBinContent(iQbin);
  721. A *= mcB;
  722. B *= mcA;
  723. }
  724. if( (A>=0.0001) && (B>=0.0001) ) {
  725. C = TheorCorrFctn1D(par, iQbin);
  726. mDelta = -2* ( A * TMath::Log( (C/A)*((A+B)/(C+1)) ) +
  727. B * TMath::Log( (A+B)/(B*(C+1)) ) );
  728. mChisq += mDelta;
  729. }
  730. } //for(Int_t iQbin = 1; iQbin<=mNQinvBins; iQbin++)
  731. f = mChisq;
  732. return f;
  733. }
  734. //_________________
  735. Double_t HbtFitter::CorrFctn3DChiSqr(Int_t &npar, Double_t *gin, Double_t &f,
  736. Double_t *par, Int_t iflag) {
  737. f = 0.;
  738. Double_t mChisq = 0;
  739. Double_t mDelta = 0;
  740. Double_t A, B, C, mQcorrErr, mcA, mcB, mNonFemtoCorrFactor;
  741. Int_t mNqOutBins = mQoutNbins;
  742. Int_t mNqSideBins = mQsideNbins;
  743. Int_t mNqLongBins = mQlongNbins;
  744. mNonFemtoCorrFactor = 1.;
  745. TH3F hCorrectedOnMc("hCorrectedOnMc","hCorrectedOnMc",
  746. mQoutNbins,mQoutVal[0],mQoutVal[1],
  747. mQsideNbins,mQsideVal[0],mQsideVal[1],
  748. mQlongNbins,mQlongVal[0],mQlongVal[1]);
  749. if(mCorrectOnMc) {
  750. hCorrectedOnMc.Divide(h3dCorrFctn,h3dMcCorrFctn);
  751. }
  752. for(Int_t iOutBin=mQoutFitRangeBin[1]; iOutBin>=mQoutFitRangeBin[0]; iOutBin--) {
  753. for(Int_t iSideBin=mQsideFitRangeBin[1]; iSideBin>=mQsideFitRangeBin[0]; iSideBin--) {
  754. for(Int_t iLongBin=mQlongFitRangeBin[1]; iLongBin>=mQlongFitRangeBin[0]; iLongBin--) {
  755. mQcorrErr = h3dCorrFctn->GetBinError(iOutBin, iSideBin, iLongBin);
  756. if(mQcorrErr<=0.0) continue;
  757. A = h3dNumer->GetBinContent(iOutBin, iSideBin, iLongBin);
  758. B = h3dDenom->GetBinContent(iOutBin, iSideBin, iLongBin);
  759. C = A/B;
  760. //If divide on MC CorrFctn
  761. if(mCorrectOnMc) {
  762. mNonFemtoCorrFactor = h3dMcCorrFctn->GetBinContent(iOutBin, iSideBin, iLongBin);
  763. C /= mNonFemtoCorrFactor;
  764. mQcorrErr = hCorrectedOnMc.GetBinError(iOutBin, iSideBin, iLongBin);
  765. }
  766. if( (A>=0.0001) && (B>=0.0001)) {
  767. mDelta = (C - TheorCorrFctn3D(par, iOutBin, iSideBin, iLongBin))/mQcorrErr;
  768. mChisq += mDelta*mDelta;
  769. }
  770. } //for(Int_t iLongBin=1; iLongBin<=mNqLongBins; iLongBin++)
  771. } //for(Int_t iSideBin=1; iSideBin<=mNqSideBins; iSideBin++)
  772. } //for(Int_t iOutBin=1; iOutBin<=mNqOutBins; iOutBin++)
  773. f = mChisq;
  774. return f;
  775. }
  776. //_________________
  777. Double_t HbtFitter::CorrFctn3DLogLike(Int_t &npar, Double_t *gin, Double_t &f,
  778. Double_t *par, Int_t iflag) {
  779. f = 0.;
  780. Double_t mChisq = 0;
  781. Double_t mDelta = 0;
  782. Double_t A, B, C, mcA, mcB;
  783. Int_t mNqOutBins = mQoutNbins;
  784. Int_t mNqSideBins = mQsideNbins;
  785. Int_t mNqLongBins = mQlongNbins;
  786. //Calculation of the log-likelihood chi2
  787. for(Int_t iOutBin=mQoutFitRangeBin[1]; iOutBin>=mQoutFitRangeBin[0]; iOutBin--) {
  788. for(Int_t iSideBin=mQsideFitRangeBin[1]; iSideBin>=mQsideFitRangeBin[0]; iSideBin--) {
  789. for(Int_t iLongBin=mQlongFitRangeBin[1]; iLongBin>=mQlongFitRangeBin[0]; iLongBin--) {
  790. A = h3dNumer->GetBinContent(iOutBin, iSideBin, iLongBin);
  791. B = h3dDenom->GetBinContent(iOutBin, iSideBin, iLongBin);
  792. if( (A>=0.0001) && (B>=0.0001) ) {
  793. C = TheorCorrFctn3D(par, iOutBin, iSideBin, iLongBin);
  794. if(mCorrectOnMc) {
  795. mcA = h3dMcNumer->GetBinContent(iOutBin, iSideBin, iLongBin);
  796. mcB = h3dMcDenom->GetBinContent(iOutBin, iSideBin, iLongBin);
  797. C *= mcA;
  798. C /= mcB;
  799. }
  800. mDelta = -2. * ( A * TMath::Log( (C/A) * ((A+B)/(C+1)) ) +
  801. B * TMath::Log( (1.0/B) * ((A+B)/(C+1))) );
  802. mChisq += mDelta;
  803. }
  804. } //for(Int_t iLongBin=1; iLongBin<=mNqLongBins; iLongBin++)
  805. } //for(Int_t iSideBin=1; iSideBin<=mNqSideBins; iSideBin++)
  806. } //for(Int_t iOutBin=1; iOutBin<=mNqOutBins; iOutBin++)
  807. f = mChisq;
  808. return f;
  809. }
  810. //_________________
  811. void HbtFitter::FitFunc1DChiSquare(Int_t &npar, Double_t *gin, Double_t &f,
  812. Double_t *par, Int_t iflag) {
  813. f = objHbtFitter->CorrFctn1DChiSqr(npar, gin, f, par, iflag);
  814. }
  815. //_________________
  816. void HbtFitter::FitFunc1DLogLike(Int_t &npar, Double_t *gin, Double_t &f,
  817. Double_t *par, Int_t iflag) {
  818. f = objHbtFitter->CorrFctn1DLogLike(npar, gin, f, par, iflag);
  819. }
  820. //_________________
  821. void HbtFitter::FitFunc3DChiSquare(Int_t &npar, Double_t *gin, Double_t &f,
  822. Double_t *par, Int_t iflag) {
  823. f = objHbtFitter->CorrFctn3DChiSqr(npar, gin, f, par, iflag);
  824. }
  825. //_________________
  826. void HbtFitter::FitFunc3DLogLike(Int_t &npar, Double_t *gin, Double_t &f,
  827. Double_t *par, Int_t iflag) {
  828. f = objHbtFitter->CorrFctn3DLogLike(npar, gin, f, par, iflag);
  829. }
  830. //_________________
  831. void HbtFitter::MakeProjections() {
  832. std::cout << "Start making projections";
  833. //Experimental Q distribution projections
  834. MakeExpProjections();
  835. if(mCorrectOnMc) {
  836. //MC Q distribution projections
  837. MakeMcProjections();
  838. //Correct projections
  839. h3dCorrFctnOutProj->Divide(h3dMcCorrFctnOutProj);
  840. h3dCorrFctnSideProj->Divide(h3dMcCorrFctnSideProj);
  841. h3dCorrFctnLongProj->Divide(h3dMcCorrFctnLongProj);
  842. }
  843. //Calculate 3D fit projections
  844. MakeFitProjections();
  845. //Scale distributions
  846. Double_t mScale = 1./mNonFemto3DVal.at(0);
  847. h3dCorrFctn->Scale(mScale);
  848. h3dFitNumerator->Divide(h3dDenom);
  849. h3dFitNumerator->Scale(mScale);
  850. Calculate3DChi2();
  851. //Correlation function scale
  852. h3dCorrFctnOutProj->Scale(mScale);
  853. h3dCorrFctnSideProj->Scale(mScale);
  854. h3dCorrFctnLongProj->Scale(mScale);
  855. //Fit function scale
  856. h3dCorrFctnFitOutProj->Scale(mScale);
  857. h3dCorrFctnFitSideProj->Scale(mScale);
  858. h3dCorrFctnFitLongProj->Scale(mScale);
  859. std::cout << "\t[DONE]" << std::endl;
  860. }
  861. //_________________
  862. void HbtFitter::Calculate3DChi2() {
  863. mChi2PerNDF = 0.;
  864. mChi2 = 0;
  865. double mNBinsNDF = 0;
  866. double mError;
  867. double mCorrFctnVal, mFitFctnVal, mDelta;
  868. for(Int_t iOutBin=mQoutFitRangeBin[1]; iOutBin>=mQoutFitRangeBin[0]; iOutBin--) {
  869. for(Int_t iSideBin=mQsideFitRangeBin[1]; iSideBin>=mQsideFitRangeBin[0]; iSideBin--) {
  870. for(Int_t iLongBin=mQlongFitRangeBin[1]; iLongBin>=mQlongFitRangeBin[0]; iLongBin--) {
  871. mError = h3dCorrFctn->GetBinError(iOutBin,iSideBin,iLongBin);
  872. if(mError<=0) continue;
  873. mNBinsNDF++;
  874. mCorrFctnVal = h3dCorrFctn->GetBinContent(iOutBin,iSideBin,iLongBin);
  875. mFitFctnVal = h3dFitNumerator->GetBinContent(iOutBin,iSideBin,iLongBin);
  876. mDelta = (mCorrFctnVal - mFitFctnVal)/mError;
  877. mChi2 += (mDelta*mDelta);
  878. }
  879. }
  880. }
  881. mNDF = mNBinsNDF - (mFemto3DParNum+mNonFemto3DParNum) + mFixParameters3D.size();
  882. mChi2PerNDF = mChi2/mNDF;
  883. }
  884. //_________________
  885. void HbtFitter::MakeFitProjections() {
  886. //Make fit numerator
  887. MakeFitNumerator();
  888. if(!h3dFitQoutProj || !h3dQoutProjDen) {
  889. std::cout << "MakeFitProjections: Out projections are empty" << std::endl;
  890. std::cout << "Fit out proj numerator address: " << h3dFitQoutProj
  891. << " Fit out proj denominator address: " << h3dQoutProjDen << std::endl;
  892. return;
  893. }
  894. if(!h3dFitQsideProj || !h3dQsideProjDen) {
  895. std::cout << "MakeFitProjections: Side projections are empty" << std::endl;
  896. std::cout << "Fit side proj numerator address: " << h3dFitQsideProj
  897. << " Fit side proj denominator address: " << h3dQsideProjDen << std::endl;
  898. return;
  899. }
  900. if(!h3dFitQlongProj || !h3dQlongProjDen) {
  901. std::cout << "MakeFitProjections: Long projections are empty" << std::endl;
  902. std::cout << "Fit long proj numerator address: " << h3dFitQlongProj
  903. << " Fit long proj denominator address: " << h3dQlongProjDen << std::endl;
  904. return;
  905. }
  906. //TString name, title;
  907. //Out
  908. TH1F* hCorrOut = new TH1F(*h3dFitQoutProj);
  909. /*
  910. name=""; title="";
  911. name = hCorrOut->GetName();
  912. title = hCorrOut->GetTitle();
  913. name += "_fit";
  914. title += " fit";
  915. */
  916. hCorrOut->Divide(h3dQoutProjDen);
  917. for(Int_t iBin=1; iBin<=(hCorrOut->GetNbinsX()); iBin++) {
  918. if(hCorrOut->GetBinContent(iBin) != 0) {
  919. hCorrOut->SetBinError(iBin, 0.);
  920. }
  921. }
  922. h3dCorrFctnFitOutProj = hCorrOut;
  923. //h3dCorrFctnFitOutProj->Scale(1./mNonFemto3DVal.at(0));
  924. //Side
  925. TH1F* hCorrSide = new TH1F(*h3dFitQsideProj);
  926. /*
  927. name=""; title="";
  928. name = hCorrSide->GetName();
  929. title = hCorrSide->GetTitle();
  930. name += "_fit";
  931. title += " fit";
  932. */
  933. hCorrSide->Divide(h3dQsideProjDen);
  934. for(Int_t iBin=1; iBin<=(hCorrSide->GetNbinsX()); iBin++) {
  935. if(hCorrSide->GetBinContent(iBin) != 0) {
  936. hCorrSide->SetBinError(iBin, 0.);
  937. }
  938. }
  939. h3dCorrFctnFitSideProj = hCorrSide;
  940. //h3dCorrFctnFitSideProj->Scale(1./mNonFemto3DVal.at(0));
  941. //Long
  942. TH1F* hCorrLong = new TH1F(*h3dFitQlongProj);
  943. /*
  944. name=""; title="";
  945. name = hCorrLong->GetName();
  946. title = hCorrLong->GetTitle();
  947. name += "_fit";
  948. title += " fit";
  949. */
  950. hCorrLong->Divide(h3dQlongProjDen);
  951. for(Int_t iBin=1; iBin<=(hCorrLong->GetNbinsX()); iBin++) {
  952. if(hCorrLong->GetBinContent(iBin) != 0) {
  953. hCorrLong->SetBinError(iBin, 0.);
  954. }
  955. }
  956. h3dCorrFctnFitLongProj = hCorrLong;
  957. //h3dCorrFctnFitLongProj->Scale(1./mNonFemto3DVal.at(0));
  958. }
  959. //_________________
  960. void HbtFitter::MakeFitNumerator() {
  961. //Obtain fit parameters
  962. Double_t fitPar[mFemto3DParNum+mNonFemto3DParNum];
  963. for(Int_t iIter=0; iIter<mFemto3DParNum; iIter++) {
  964. fitPar[iIter] = mFemto3DVal.at(iIter);
  965. }
  966. for(Int_t iIter=0; iIter<mNonFemto3DParNum; iIter++) {
  967. fitPar[mFemto3DParNum+iIter] = mNonFemto3DVal.at(iIter);
  968. }
  969. h3dFitNumerator = new TH3F("h3dFitNumerator","h3dFitNumerator",
  970. mQoutNbins, mQoutVal[0],mQoutVal[1],
  971. mQsideNbins, mQsideVal[0],mQsideVal[1],
  972. mQlongNbins, mQlongVal[0],mQlongVal[1]);
  973. Double_t mNonFemtoCorrFactor = 1.;
  974. Double_t wTheor, wFitNum;
  975. //Bin-by-bin loop
  976. /*
  977. for(Int_t iOutBin=1; iOutBin<=mQoutNbins; iOutBin++) {
  978. for(Int_t iSideBin=1; iSideBin<=mQsideNbins; iSideBin++) {
  979. for(Int_t iLongBin=1; iLongBin<=mQlongNbins; iLongBin++) {
  980. */
  981. for(Int_t iOutBin=mQoutFitRangeBin[0]; iOutBin<=mQoutFitRangeBin[1]; iOutBin++) {
  982. for(Int_t iSideBin=mQsideFitRangeBin[0]; iSideBin<=mQsideFitRangeBin[1]; iSideBin++) {
  983. for(Int_t iLongBin=mQlongFitRangeBin[0]; iLongBin<=mQlongFitRangeBin[1]; iLongBin++) {
  984. wTheor = TheorCorrFctn3D(fitPar, iOutBin, iSideBin, iLongBin);
  985. if(mCorrectOnMc) {
  986. mNonFemtoCorrFactor = h3dMcCorrFctn->GetBinContent(iOutBin, iSideBin, iLongBin);
  987. wTheor *= mNonFemtoCorrFactor;
  988. }
  989. wFitNum = wTheor * h3dDenom->GetBinContent(iOutBin, iSideBin, iLongBin);
  990. h3dFitNumerator->SetBinContent(iOutBin, iSideBin, iLongBin, wFitNum);
  991. h3dFitNumerator->SetBinError(iOutBin, iSideBin, iLongBin, 0.);
  992. } //for(Int_t iLongBin=1; iLongBin<=mQlongNbins; iLongBin++)
  993. } //for(Int_t iSideBin=1; iSideBin<=mQsideNbins, iSideBin++)
  994. } //for(Int_t iOutBin=1; iOutBin<=mQoutNbins, iOutBin++)
  995. if(mProjectionType == 0) { //By bins
  996. Project3DDistribution(h3dFitNumerator,
  997. h3dFitQoutProj, h3dFitQsideProj, h3dFitQlongProj,
  998. mOutProjBins[0], mOutProjBins[1],
  999. mSideProjBins[0], mSideProjBins[1],
  1000. mLongProjBins[0], mLongProjBins[1]);
  1001. }
  1002. else { //By values
  1003. Project3DDistribution(h3dFitNumerator,
  1004. h3dFitQoutProj, h3dFitQsideProj, h3dFitQlongProj,
  1005. mOutProjVals[0], mOutProjVals[1],
  1006. mSideProjVals[0], mSideProjVals[1],
  1007. mLongProjVals[0], mLongProjVals[1]);
  1008. }
  1009. }
  1010. //_________________
  1011. void HbtFitter::MakeExpProjections() {
  1012. if(!h3dNumer) {
  1013. std::cout << "MakeExpProjections: 3D numerator is not set" << std::endl;
  1014. return;
  1015. }
  1016. if(!h3dDenom) {
  1017. std::cout << "MakeExpProjections: 3D denominator is not set" << std::endl;
  1018. return;
  1019. }
  1020. //h3dNumer->Draw();
  1021. if(mProjectionType == 0) { //By bins
  1022. Project3DCorrFctn(h3dNumer, h3dDenom,
  1023. h3dQoutProjNum, h3dQsideProjNum, h3dQlongProjNum,
  1024. h3dQoutProjDen, h3dQsideProjDen, h3dQlongProjDen,
  1025. mOutProjBins[0], mOutProjBins[1],
  1026. mSideProjBins[0], mSideProjBins[1],
  1027. mLongProjBins[0], mLongProjBins[1]);
  1028. }
  1029. else { //By values
  1030. Project3DCorrFctn(h3dNumer, h3dDenom,
  1031. h3dQoutProjNum, h3dQsideProjNum, h3dQlongProjNum,
  1032. h3dQoutProjDen, h3dQsideProjDen, h3dQlongProjDen,
  1033. mOutProjVals[0], mOutProjVals[1],
  1034. mSideProjVals[0], mSideProjVals[1],
  1035. mLongProjVals[0], mLongProjVals[1]);
  1036. }
  1037. if(!h3dQoutProjNum || !h3dQsideProjNum || !h3dQlongProjNum) {
  1038. std::cout << "MakeExpProjections: Numerator projections are not defined" << std::endl;
  1039. std::cout << "Out proj address: " << h3dQoutProjNum
  1040. << " Side proj address: " << h3dQsideProjNum
  1041. << " Long proj address: " << h3dQlongProjNum << std::endl;
  1042. return;
  1043. }
  1044. if(!h3dQoutProjDen || !h3dQsideProjDen || !h3dQlongProjDen) {
  1045. std::cout << "MakeExpProjections: Denominator projections are not defined" << std::endl;
  1046. std::cout << "Out proj address: " << h3dQoutProjDen
  1047. << " Side proj address: " << h3dQsideProjDen
  1048. << " Long proj address: " << h3dQlongProjDen << std::endl;
  1049. return;
  1050. }
  1051. //Out
  1052. TH1F* hCorrOut = new TH1F(*h3dQoutProjNum);
  1053. hCorrOut->Divide(h3dQoutProjDen);
  1054. h3dCorrFctnOutProj = hCorrOut;
  1055. //Side
  1056. TH1F* hCorrSide = new TH1F(*h3dQsideProjNum);
  1057. hCorrSide->Divide(h3dQsideProjDen);
  1058. h3dCorrFctnSideProj = hCorrSide;
  1059. //Long
  1060. TH1F* hCorrLong = new TH1F(*h3dQlongProjNum);
  1061. hCorrLong->Divide(h3dQlongProjDen);
  1062. h3dCorrFctnLongProj = hCorrLong;
  1063. }
  1064. //_________________
  1065. void HbtFitter::MakeMcProjections() {
  1066. if(!h3dMcNumer) {
  1067. std::cout << "MakeMcProjections: 3D numerator is not set" << std::endl;
  1068. return;
  1069. }
  1070. if(!h3dMcDenom) {
  1071. std::cout << "MakeMcProjections: 3D denominator is not set" << std::endl;
  1072. return;
  1073. }
  1074. if(mProjectionType == 0) { //By bins
  1075. Project3DCorrFctn(h3dMcNumer, h3dMcDenom,
  1076. h3dMcQoutProjNum, h3dMcQsideProjNum, h3dMcQlongProjNum,
  1077. h3dMcQoutProjDen, h3dMcQsideProjDen, h3dMcQlongProjDen,
  1078. mOutProjBins[0], mOutProjBins[1],
  1079. mSideProjBins[0], mSideProjBins[1],
  1080. mLongProjBins[0], mLongProjBins[1]);
  1081. }
  1082. else { //By values
  1083. Project3DCorrFctn(h3dMcNumer, h3dMcDenom,
  1084. h3dMcQoutProjNum, h3dMcQsideProjNum, h3dMcQlongProjNum,
  1085. h3dMcQoutProjDen, h3dMcQsideProjDen, h3dMcQlongProjDen,
  1086. mOutProjVals[0], mOutProjVals[1],
  1087. mSideProjVals[0], mSideProjVals[1],
  1088. mLongProjVals[0], mLongProjVals[1]);
  1089. }
  1090. if(!h3dMcQoutProjNum || !h3dMcQsideProjNum || !h3dMcQlongProjNum) {
  1091. std::cout << "MakeMcProjections: Numerator projections are not defined" << std::endl;
  1092. std::cout << "Out proj address: " << h3dMcQoutProjNum
  1093. << " Side proj address: " << h3dMcQsideProjNum
  1094. << " Long proj address: " << h3dMcQlongProjNum << std::endl;
  1095. return;
  1096. }
  1097. if(!h3dMcQoutProjDen || !h3dMcQsideProjDen || !h3dMcQlongProjDen) {
  1098. std::cout << "MakeMcProjections: Denominator projections are not defined" << std::endl;
  1099. std::cout << "Out proj address: " << h3dMcQoutProjDen
  1100. << " Side proj address: " << h3dMcQsideProjDen
  1101. << " Long proj address: " << h3dMcQlongProjDen << std::endl;
  1102. return;
  1103. }
  1104. //Out
  1105. TH1F* hCorrOut = new TH1F(*h3dMcQoutProjNum);
  1106. hCorrOut->Divide(h3dMcQoutProjDen);
  1107. h3dMcCorrFctnOutProj = hCorrOut;
  1108. //Side
  1109. TH1F* hCorrSide = new TH1F(*h3dMcQsideProjNum);
  1110. hCorrSide->Divide(h3dMcQsideProjDen);
  1111. h3dMcCorrFctnSideProj = hCorrSide;
  1112. //Long
  1113. TH1F* hCorrLong = new TH1F(*h3dMcQlongProjNum);
  1114. hCorrLong->Divide(h3dMcQlongProjDen);
  1115. h3dMcCorrFctnLongProj = hCorrLong;
  1116. }
  1117. //_________________
  1118. void HbtFitter::Project3DCorrFctn(TH3F* hNumer, TH3F* hDenom,
  1119. TH1F *&hOutProjNum, TH1F *&hSideProjNum,
  1120. TH1F *&hLongProjNum,
  1121. TH1F *&hOutProjDen, TH1F *&hSideProjDen,
  1122. TH1F *&hLongProjDen,
  1123. Int_t mOutBinLow, Int_t mOutBinHi,
  1124. Int_t mSideBinLow, Int_t mSideBinHi,
  1125. Int_t mLongBinLow, Int_t mLongBinHi) {
  1126. Project3DDistribution(hNumer, hOutProjNum, hSideProjNum, hLongProjNum,
  1127. mOutBinLow, mOutBinHi,
  1128. mSideBinLow, mSideBinHi,
  1129. mLongBinLow, mLongBinHi);
  1130. if(!hOutProjNum || !hSideProjNum || !hLongProjNum) {
  1131. std::cout << "Project3DCorrFctn: One of the numerator projections is not set" << std::endl;
  1132. }
  1133. Project3DDistribution(hDenom, hOutProjDen, hSideProjDen, hLongProjDen,
  1134. mOutBinLow, mOutBinHi,
  1135. mSideBinLow, mSideBinHi,
  1136. mLongBinLow, mLongBinHi);
  1137. if(!hOutProjDen || !hSideProjDen || !hLongProjDen) {
  1138. std::cout << "Project3DCorrFctn: One of the denominator projections is not set" << std::endl;
  1139. }
  1140. }
  1141. //_________________
  1142. void HbtFitter::Project3DCorrFctn(TH3F* hNumer, TH3F* hDenom,
  1143. TH1F *&hOutProjNum, TH1F *&hSideProjNum,
  1144. TH1F *&hLongProjNum,
  1145. TH1F *&hOutProjDen, TH1F *&hSideProjDen,
  1146. TH1F *&hLongProjDen,
  1147. Double_t mQoutLow, Double_t mQoutHi,
  1148. Double_t mQsideLow, Double_t mQsideHi,
  1149. Double_t mQlongLow, Double_t mQlongHi) {
  1150. Project3DDistribution(hNumer,
  1151. hOutProjNum, hSideProjNum, hLongProjNum,
  1152. mQoutLow, mQoutHi,
  1153. mQsideLow, mQsideHi,
  1154. mQlongLow, mQlongHi);
  1155. if(!hOutProjNum || !hSideProjNum || !hLongProjNum) {
  1156. std::cout << "Project3DCorrFctn: One of the numerator projections is not set" << std::endl;
  1157. }
  1158. Project3DDistribution(hDenom,
  1159. hOutProjDen, hSideProjDen, hLongProjDen,
  1160. mQoutLow, mQoutHi,
  1161. mQsideLow, mQsideHi,
  1162. mQlongLow, mQlongHi);
  1163. if(!hOutProjDen || !hSideProjDen || !hLongProjDen) {
  1164. std::cout << "Project3DCorrFctn: One of the denominator projections is not set" << std::endl;
  1165. }
  1166. }
  1167. //_________________
  1168. void HbtFitter::Project3DDistribution(TH3F* hQdist,
  1169. TH1F *&hQoutProj, TH1F *&hQsideProj, TH1F *&hQlongProj,
  1170. Int_t mOutBinLow, Int_t mOutBinHi,
  1171. Int_t mSideBinLow, Int_t mSideBinHi,
  1172. Int_t mLongBinLow, Int_t mLongBinHi) {
  1173. if(!hQdist) {
  1174. std::cout << "Project3DDistribution: 3D histogram is not set" << std::endl;
  1175. return;
  1176. }
  1177. //hQdist->Draw();
  1178. //Obtaining number of bins in each axis
  1179. Int_t mNbinsX = hQdist->GetNbinsX();
  1180. Int_t mNbinsY = hQdist->GetNbinsY();
  1181. Int_t mNbinsZ = hQdist->GetNbinsZ();
  1182. if(!mNbinsX || !mNbinsY || !mNbinsZ) {
  1183. std::cout << "Project3DDistribution: 3D distribution is empty" << std::endl;
  1184. return;
  1185. }
  1186. TH1F* hXproj;
  1187. TH1F* hYproj;
  1188. TH1F* hZproj;
  1189. TString name, title;
  1190. //Project 3D histogram using number of bins
  1191. //Out
  1192. name = hQdist->GetName();
  1193. title = hQdist->GetTitle();
  1194. name += "_out";
  1195. title += " out projection";
  1196. hXproj = (TH1F*)hQdist->ProjectionX("hQoutProj",
  1197. mSideBinLow, mSideBinHi,
  1198. mLongBinLow, mLongBinHi);
  1199. hXproj->SetNameTitle(name.Data(), title.Data());
  1200. //Side
  1201. name = hQdist->GetName();
  1202. title = hQdist->GetTitle();
  1203. name += "_side";
  1204. title += " side projection";
  1205. hYproj = (TH1F*)hQdist->ProjectionY("hQsideProj",
  1206. mOutBinLow, mOutBinHi,
  1207. mLongBinLow, mLongBinHi);
  1208. hYproj->SetNameTitle(name.Data(), title.Data());
  1209. //Long
  1210. name = hQdist->GetName();
  1211. title = hQdist->GetTitle();
  1212. name += "_long";
  1213. title += " long projection";
  1214. hZproj = (TH1F*)hQdist->ProjectionZ("hQlongProj",
  1215. mOutBinLow, mOutBinHi,
  1216. mSideBinLow, mSideBinHi);
  1217. hZproj->SetNameTitle(name.Data(), title.Data());
  1218. hQoutProj = hXproj;
  1219. hQsideProj = hYproj;
  1220. hQlongProj = hZproj;
  1221. }
  1222. //_________________
  1223. void HbtFitter::Project3DDistribution(TH3F* hQdist,
  1224. TH1F *&hQoutProj, TH1F *&hQsideProj, TH1F *&hQlongProj,
  1225. Double_t mQoutLow, Double_t mQoutHi,
  1226. Double_t mQsideLow, Double_t mQsideHi,
  1227. Double_t mQlongLow, Double_t mQlongHi) {
  1228. if(!hQdist) {
  1229. std::cout << "Project3DDistribution: 3D histogram is not set" << std::endl;
  1230. return;
  1231. }
  1232. //hQdist->Draw();
  1233. //Obtaining number of bins in each axis
  1234. Int_t mNbinsX = hQdist->GetNbinsX();
  1235. Int_t mNbinsY = hQdist->GetNbinsY();
  1236. Int_t mNbinsZ = hQdist->GetNbinsZ();
  1237. if(!mNbinsX || !mNbinsY || !mNbinsZ) {
  1238. std::cout << "Project3DDistribution: 3D distribution has no bins" << std::endl;
  1239. return;
  1240. }
  1241. //Obtaining the ranges
  1242. Double_t xLow = hQdist->GetXaxis()->GetXmin();
  1243. Double_t xHi = hQdist->GetXaxis()->GetXmax();
  1244. Double_t yLow = hQdist->GetYaxis()->GetXmin();
  1245. Double_t yHi = hQdist->GetYaxis()->GetXmax();
  1246. Double_t zLow = hQdist->GetZaxis()->GetXmin();
  1247. Double_t zHi = hQdist->GetZaxis()->GetXmax();
  1248. TH1F* hXproj;
  1249. TH1F* hYproj;
  1250. TH1F* hZproj;
  1251. TString name, title;
  1252. //Project 3D histogram using the ranges
  1253. //Out
  1254. name = hQdist->GetName();
  1255. title = hQdist->GetTitle();
  1256. name += "_out";
  1257. title += " out projection";
  1258. hQdist->SetAxisRange(xLow, xHi, "x");
  1259. hQdist->SetAxisRange(mQsideLow, mQsideHi, "y");
  1260. hQdist->SetAxisRange(mQlongLow, mQlongHi, "z");
  1261. hXproj = (TH1F*)hQdist->Project3D("xe");
  1262. hXproj->SetNameTitle(name.Data(), title.Data());;
  1263. //Side
  1264. name = hQdist->GetName();
  1265. title = hQdist->GetTitle();
  1266. name += "_side";
  1267. title += " side projection";
  1268. hQdist->SetAxisRange(mQoutLow, mQoutHi, "x");
  1269. hQdist->SetAxisRange(yLow, yHi, "y");
  1270. hQdist->SetAxisRange(mQlongLow, mQlongHi, "z");
  1271. hYproj = (TH1F*)hQdist->Project3D("ye");
  1272. hYproj->SetNameTitle(name.Data(), title.Data());
  1273. //Long
  1274. name = hQdist->GetName();
  1275. title = hQdist->GetTitle();
  1276. name += "_long";
  1277. title += " long projection";
  1278. hQdist->SetAxisRange(mQoutLow, mQoutHi, "x");
  1279. hQdist->SetAxisRange(mQsideLow, mQsideHi, "y");
  1280. hQdist->SetAxisRange(zLow, zHi, "z");
  1281. hZproj = (TH1F*)hQdist->Project3D("ze");
  1282. hZproj->SetNameTitle(name.Data(), title.Data());
  1283. hQoutProj = hXproj;
  1284. hQsideProj = hYproj;
  1285. hQlongProj = hZproj;
  1286. }