FemtoDstAnalyzer_PID.C 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. /**
  2. * \brief Example of how to read a file (list of files) using StFemtoEvent classes
  3. *
  4. * RunFemtoDstAnalyzer.C is an example of reading FemtoDst format.
  5. * One can use either FemtoDst file or a list of femtoDst files (inFile.lis or
  6. * inFile.list) as an input, and preform physics analysis
  7. *
  8. * \author Grigory Nigmatkulov
  9. * \date May 29, 2018
  10. */
  11. // This is needed for calling standalone classes
  12. #define _VANILLA_ROOT_
  13. // C++ headers
  14. #include <iostream>
  15. #include <vector>
  16. #include <map>
  17. // ROOT headers
  18. #include "TROOT.h"
  19. #include "TFile.h"
  20. #include "TChain.h"
  21. #include "TVector2.h"
  22. #include "TVector3.h"
  23. #include "TTree.h"
  24. #include "TSystem.h"
  25. #include "TH1.h"
  26. #include "TH2.h"
  27. #include "TMath.h"
  28. #include "TProfile2D.h"
  29. #include "TStopwatch.h"
  30. // FemtoDst headers
  31. #include "StFemtoDstReader.h"
  32. #include "StFemtoDst.h"
  33. #include "StFemtoEvent.h"
  34. #include "StFemtoTrack.h"
  35. // Load libraries (for ROOT_VERSTION_CODE >= 393215)
  36. #if ROOT_VERSION_CODE >= ROOT_VERSION(6, 0, 0)
  37. R__LOAD_LIBRARY(/mnt/pool/rhic/4/parfenovpeter/STAR/build/libStFemtoDst.so)
  38. #endif
  39. #include "Constants.h"
  40. // inFile - is a name of name.FemtoDst.root file or a name
  41. // of a name.lis(t) files, that contains a list of
  42. // name1.FemtoDst.root, name2.FemtoDst.root, ... files
  43. //Used functions (see them below)
  44. Bool_t isGoodEvent(StFemtoEvent *const &event);
  45. Bool_t isGoodTrackFlow(StFemtoTrack *const &track, Float_t _energy, TVector3 pVtx);
  46. Double_t GetMeanNsig(StFemtoTrack *const &track, const Int_t PID);
  47. Double_t GetWidthM2(StFemtoTrack *const &track, const Int_t PID);
  48. Double_t GetRotAngle(StFemtoTrack *const &track);
  49. std::pair<Double_t,Double_t> GetNewXY(StFemtoTrack *const &track);
  50. Bool_t isMesonXY(Double_t x, Double_t y);
  51. Double_t GetSigmNewX(StFemtoTrack *const &track, Int_t PID);
  52. Double_t GetSigmNewY(StFemtoTrack *const &track, Int_t PID);
  53. //_________________
  54. void FemtoDstAnalyzer_PID(const Char_t *inFile = "st_physics_12150008_raw_4030001.femtoDst.root",
  55. const Char_t *outFile = "./oPIDTest.root")
  56. {
  57. std::cout << "Hi! Lets do some physics, Master!" << std::endl;
  58. TStopwatch timer;
  59. timer.Start();
  60. #if ROOT_VERSION_CODE < ROOT_VERSION(6, 0, 0)
  61. gSystem->Load("../libStFemtoDst.so");
  62. #endif
  63. StFemtoDstReader *femtoReader = new StFemtoDstReader(inFile);
  64. femtoReader->Init();
  65. // This is a way if you want to spead up IO
  66. std::cout << "Explicit read status for some branches" << std::endl;
  67. femtoReader->SetStatus("*", 0);
  68. femtoReader->SetStatus("Event", 1);
  69. femtoReader->SetStatus("Track", 1);
  70. std::cout << "Status has been set" << std::endl;
  71. std::cout << "Now I know what to read, Master!" << std::endl;
  72. if (!femtoReader->chain())
  73. {
  74. std::cout << "No chain has been found." << std::endl;
  75. }
  76. Long64_t eventsInTree = femtoReader->tree()->GetEntries();
  77. std::cout << "eventsInTree: " << eventsInTree << std::endl;
  78. Long64_t events2read = femtoReader->chain()->GetEntries();
  79. std::cout << "Number of events to read: " << events2read << std::endl;
  80. const int NptBins = 18;
  81. const double ptBin [NptBins+1] = {0.2,0.4,0.6,0.8,1.,1.2,1.4,1.6,1.8,2.,2.2,2.4,2.6,2.8,3.,3.2,3.4,3.6,3.8};
  82. TH2D *hNsigPionMSqr[NptBins];
  83. TH2D *hPionNewXY[NptBins];
  84. TH2D *hPionNewXYCut[NptBins];
  85. TH2D *hPionNewXYPion[NptBins];
  86. TH2D *hPionNewXYKaon[NptBins];
  87. TH2D *hPionNewXYProton[NptBins];
  88. TH2D *hNsigKaonMSqr[NptBins];
  89. TH2D *hNsigProtonMSqr[NptBins];
  90. TH1D *hNsigPion = new TH1D(Form("hNsigPion") ,Form("n#sigma_{#pi} for %.2f < p < %.2f GeV/c;n#sigma_{#pi};N_{counts}",0.6,0.7),1400,-35.,35.);
  91. TH1D *hNsigKaon = new TH1D(Form("hNsigKaon") ,Form("n#sigma_{K} for %.2f < p_{T} < %.2f GeV/c;n#sigma_{K};N_{counts}",0.6,0.7),1400,-35.,35.);
  92. TH1D *hNsigProton = new TH1D(Form("hNsigProton") ,Form("n#sigma_{p} for %.2f < p_{T} < %.2f GeV/c;n#sigma_{p};N_{counts}",0.9,1.2),1400,-35.,35.);
  93. TH1D *hNsigPionCut = new TH1D(Form("hNsigPionCut") ,Form("n#sigma_{#pi} w/ Cut for %.2f < p < %.2f GeV/c;n#sigma_{#pi};N_{counts}",0.6,0.7),1400,-35.,35.);
  94. TH1D *hNsigKaonCut = new TH1D(Form("hNsigKaonCut") ,Form("n#sigma_{K} w/ Cut for %.2f < p_{T} < %.2f GeV/c;n#sigma_{K};N_{counts}",0.6,0.7),1400,-35.,35.);
  95. TH1D *hNsigProtonCut = new TH1D(Form("hNsigProtonCut") ,Form("n#sigma_{p} w/ Cut for %.2f < p_{T} < %.2f GeV/c;n#sigma_{p};N_{counts}",0.9,1.2),1400,-35.,35.);
  96. //Initialization
  97. for (int i=0; i<NptBins; i++)
  98. {
  99. hNsigPionMSqr[i] = new TH2D(Form("hNsigPionMSqr%i",i) ,Form("n#sigma_{#pi} vs M^{2} for %.2f < p_{T} < %.2f GeV/c;n#sigma_{#pi};m^{2} [GeV/c^{2}]^{2}",ptBin[i],ptBin[i+1]),1400,-35.,35.,1400,-2.,5.);
  100. hNsigKaonMSqr[i] = new TH2D(Form("hNsigKaonMSqr%i",i) ,Form("n#sigma_{K} vs M^{2} for %.2f < p_{T} < %.2f GeV/c;n#sigma_{K};m^{2} [GeV/c^{2}]^{2}",ptBin[i],ptBin[i+1]),1400,-35.,35.,1400,-2.,5.);
  101. hNsigProtonMSqr[i] = new TH2D(Form("hNsigProtonMSqr%i",i) ,Form("n#sigma_{p} vs M^{2} for %.2f < p_{T} < %.2f GeV/c;n#sigma_{p};m^{2} [GeV/c^{2}]^{2}",ptBin[i],ptBin[i+1]),1400,-35.,35.,1400,-2.,5.);
  102. hPionNewXY[i] = new TH2D(Form("hPionNewXY%i",i) ,Form("x(n#sigma_{#pi},M^{2}) vs y(n#sigma_{#pi},M^{2}) for %.2f < p_{T} < %.2f GeV/c;X;Y",ptBin[i],ptBin[i+1]),600,-0.5,1.,600,-1.,0.5);
  103. hPionNewXYCut[i] = new TH2D(Form("hPionNewXYCut%i",i) ,Form("x(n#sigma_{#pi},M^{2}) vs y(n#sigma_{#pi},M^{2}) with cut for %.2f < p_{T} < %.2f GeV/c;X;Y",ptBin[i],ptBin[i+1]),600,-0.5,1.,600,-1.,0.5);
  104. hPionNewXYPion[i] = new TH2D(Form("hPionNewXYPion%i",i) ,Form("x(n#sigma_{#pi},M^{2}) vs y(n#sigma_{#pi},M^{2}) for #pi^{#pm} for %.2f < p_{T} < %.2f GeV/c;X;Y",ptBin[i],ptBin[i+1]),600,-0.5,1.,600,-1.,0.5);
  105. hPionNewXYKaon[i] = new TH2D(Form("hPionNewXYKaon%i",i) ,Form("x(n#sigma_{#pi},M^{2}) vs y(n#sigma_{#pi},M^{2}) for K^{#pm} for %.2f < p_{T} < %.2f GeV/c;X;Y",ptBin[i],ptBin[i+1]),600,-0.5,1.,600,-1.,0.5);
  106. hPionNewXYProton[i] = new TH2D(Form("hPionNewXYProton%i",i) ,Form("x(n#sigma_{#pi},M^{2}) vs y(n#sigma_{#pi},M^{2}) for (p#bar{p}) for %.2f < p_{T} < %.2f GeV/c;X;Y",ptBin[i],ptBin[i+1]),600,-0.5,1.,600,-1.,0.5);
  107. }
  108. std::pair<Double_t,Double_t> XY_pid;
  109. // Loop over events
  110. for (Long64_t iEvent = 0; iEvent < events2read; iEvent++)
  111. {
  112. if ((iEvent+1) % 1000 == 0){
  113. std::cout << "Working on event #[" << (iEvent + 1)
  114. << "/" << events2read << "]" << std::endl;
  115. }
  116. Bool_t readEvent = femtoReader->readFemtoEvent(iEvent);
  117. if (!readEvent)
  118. {
  119. std::cout << "Something went wrong, Master! Nothing to analyze..." << std::endl;
  120. break;
  121. }
  122. // Retrieve femtoDst
  123. StFemtoDst *dst = femtoReader->femtoDst();
  124. // Retrieve event information
  125. StFemtoEvent *event = dst->event();
  126. if (!event)
  127. {
  128. std::cout << "Something went wrong, Master! Event is hiding from me..." << std::endl;
  129. break;
  130. }
  131. TVector3 pVtx = event->primaryVertex();
  132. // Event selection
  133. if ( !isGoodEvent(event) ) continue;
  134. // Track analysis
  135. Int_t nTracks = dst->numberOfTracks();
  136. // Track loop
  137. for (Int_t iTrk = 0; iTrk < nTracks; iTrk++)
  138. {
  139. // Retrieve i-th femto track
  140. StFemtoTrack *femtoTrack = dst->track(iTrk);
  141. if (!femtoTrack)
  142. continue;
  143. // Must be a primary track
  144. if (!femtoTrack->isPrimary())
  145. continue;
  146. //Track selection
  147. if (!isGoodTrackFlow(femtoTrack, energy, pVtx)) continue;
  148. // Determine pt bin for PID plots
  149. int i_pt = -1;
  150. for (int i=0;i<NptBins;i++)
  151. {
  152. if (femtoTrack->pt() >= (ptBin[i]) && femtoTrack->pt() < (ptBin[i+1]))
  153. {
  154. i_pt = i;
  155. }
  156. }
  157. if (i_pt == -1) continue;
  158. if (!femtoTrack->isTofTrack())
  159. {
  160. if (femtoTrack->ptot() >= 0.6 && femtoTrack->ptot() < 0.7)
  161. {
  162. hNsigPion->Fill(femtoTrack->nSigmaPion());
  163. if (femtoTrack->nSigmaKaon() > 2 && femtoTrack->nSigmaPion() < 2) hNsigPionCut->Fill(femtoTrack->nSigmaPion());
  164. hNsigKaon->Fill(femtoTrack->nSigmaKaon());
  165. if (femtoTrack->nSigmaPion() > 3 && femtoTrack->nSigmaKaon() < 2) hNsigKaonCut->Fill(femtoTrack->nSigmaKaon());
  166. }
  167. if (femtoTrack->ptot() >= 0.9 && femtoTrack->ptot() < 1.2)
  168. {
  169. hNsigProton->Fill(femtoTrack->nSigmaProton());
  170. if (femtoTrack->nSigmaPion() > 3 && femtoTrack->nSigmaProton() < 2) hNsigProtonCut->Fill(femtoTrack->nSigmaProton());
  171. }
  172. }
  173. // Check if track has TOF signal
  174. if (femtoTrack->isTofTrack())
  175. {
  176. if (femtoTrack->gDCA(pVtx).Mag() >= 1.) continue;
  177. XY_pid = GetNewXY(femtoTrack);
  178. hPionNewXY[i_pt]->Fill(XY_pid.first,XY_pid.second);
  179. if (isMesonXY(XY_pid.first, XY_pid.second))
  180. {
  181. hPionNewXYCut[i_pt]->Fill(XY_pid.first,XY_pid.second);
  182. if ( TMath::Power(XY_pid.first / (2*GetSigmNewX(femtoTrack,0)),2) + TMath::Power(XY_pid.second / (2*GetSigmNewY(femtoTrack,0)),2) < 1. &&
  183. TMath::Power((XY_pid.first - 0.23) / (2*GetSigmNewX(femtoTrack,1)),2) + TMath::Power(XY_pid.second / (2*GetSigmNewY(femtoTrack,1)),2) > 1. )
  184. {
  185. hPionNewXYPion[i_pt]->Fill(XY_pid.first,XY_pid.second);
  186. }
  187. if ( TMath::Power((XY_pid.first - 0.23) / (2*GetSigmNewX(femtoTrack,1)),2) + TMath::Power(XY_pid.second / (2*GetSigmNewY(femtoTrack,1)),2) < 1. &&
  188. TMath::Power(XY_pid.first / (2*GetSigmNewX(femtoTrack,0)),2) + TMath::Power(XY_pid.second / (2*GetSigmNewY(femtoTrack,0)),2) > 1. )
  189. {
  190. hPionNewXYKaon[i_pt]->Fill(XY_pid.first,XY_pid.second);
  191. }
  192. }
  193. else
  194. {
  195. hPionNewXYProton[i_pt]->Fill(XY_pid.first,XY_pid.second);
  196. }
  197. hNsigPionMSqr[i_pt]->Fill(femtoTrack->nSigmaPion(),femtoTrack->massSqr());
  198. hNsigKaonMSqr[i_pt]->Fill(femtoTrack->nSigmaKaon(),femtoTrack->massSqr());
  199. hNsigProtonMSqr[i_pt]->Fill(femtoTrack->nSigmaProton(),femtoTrack->massSqr());
  200. } //if( isTofTrack() )
  201. } //for(Int_t iTrk=0; iTrk<nTracks; iTrk++)
  202. } //for(Long64_t iEvent=0; iEvent<events2read; iEvent++)
  203. femtoReader->Finish();
  204. TFile *output = new TFile(outFile,"recreate");
  205. for (int i=0; i<NptBins; i++)
  206. {
  207. hNsigPionMSqr[i] -> Write();
  208. hNsigKaonMSqr[i] -> Write();
  209. hNsigProtonMSqr[i] -> Write();
  210. }
  211. for (int i=0; i<NptBins; i++)
  212. {
  213. hPionNewXY[i] -> Write();
  214. hPionNewXYCut[i] -> Write();
  215. }
  216. for (int i=0; i<NptBins; i++)
  217. {
  218. hPionNewXYPion[i] -> Write();
  219. hPionNewXYKaon[i] -> Write();
  220. hPionNewXYProton[i] -> Write();
  221. }
  222. hNsigPion->Write();
  223. hNsigKaon->Write();
  224. hNsigProton->Write();
  225. hNsigPionCut->Write();
  226. hNsigKaonCut->Write();
  227. hNsigProtonCut->Write();
  228. output->Close();
  229. std::cout << "I'm done with analysis. We'll have a Nobel Prize, Master!"
  230. << std::endl;
  231. timer.Stop();
  232. timer.Print();
  233. }
  234. Bool_t isGoodEvent(StFemtoEvent *const &event)
  235. {
  236. if (!event) return false;
  237. if (event == nullptr) return false;
  238. if (event->primaryVertex().Perp() > cutVtxR) return false;
  239. if (TMath::Abs(event->primaryVertex().Z()) > cutVtxZEnergy.at(energy)) return false;
  240. if ((energy == 200.) && TMath::Abs(event->primaryVertex().Z() - event->vpdVz()) > cutVpdVz) return false;
  241. return true;
  242. }
  243. Bool_t isGoodTrackFlow(StFemtoTrack *const &track, Float_t _energy, TVector3 pVtx)
  244. {
  245. if (!track) return false;
  246. // if (!track->isPrimary()) return false;
  247. if (track->nHitsFit() < cutNhits) return false;
  248. if (track->nHitsPoss() <= cutNhitsPoss) return false;
  249. if ((Double_t) track->nHitsFit()/track->nHitsPoss() < cutNhitsRatio) return false;
  250. if (TMath::Abs(track->eta()) >= cutEta) return false;
  251. if (track->pt() <= cutPtMin.at(_energy)) return false;
  252. //if (track->pt() > cutPtMax) return false;
  253. if (track->ptot() > cutPMax) return false;
  254. if (track->gDCA(pVtx).Mag() >= cutDCA.at(_energy)) return false;
  255. return true;
  256. }
  257. Double_t GetMeanNsig(StFemtoTrack *const &track, const Int_t PID)
  258. {
  259. Double_t pt, par0, par1, par2, par3;
  260. if (PID == 0) return 0.;
  261. if (PID == 1)
  262. {
  263. par0 = 5.84263e+00;
  264. par1 = -6.65912e+00;
  265. par2 = 8.32204e-01;
  266. par3 = 8.28440e-01;
  267. }
  268. if (PID == 2)
  269. {
  270. par0 = 1.09685e+01;
  271. par1 = -8.61499e+00;
  272. par2 = 8.92938e-01;
  273. par3 = 8.08397e-01;
  274. }
  275. pt = track->pt();
  276. if (pt != 0)
  277. {
  278. return (par0*TMath::Power(1./pt,par2) + par1 + par3*pt);
  279. }
  280. else
  281. {
  282. return 0.;
  283. }
  284. }
  285. Double_t GetWidthM2(StFemtoTrack *const &track, const Int_t PID)
  286. {
  287. Double_t pt, pol0, pol1, pol2;
  288. if (PID != 0) return 0.;
  289. pol0 = 8.74975e-04;
  290. pol1 = -1.62659e-03;
  291. pol2 = 2.89828e-02;
  292. pt = track->pt();
  293. return (pol0 + pol1*pt + pol2*pt*pt);
  294. }
  295. Double_t GetScaleFactor(StFemtoTrack *const &track)
  296. {
  297. Double_t wM2pion = GetWidthM2(track,0);
  298. Double_t exScale = 1./0.8273; // = 1. for BES energies
  299. if (wM2pion == 0) return 1.;
  300. else return (exScale/wM2pion);
  301. }
  302. Double_t GetRotAngle(StFemtoTrack *const &track)
  303. {
  304. Double_t scaleFactor = GetScaleFactor(track);
  305. Double_t MeanKaonNsig = GetMeanNsig(track,1);
  306. Double_t new_x = (MeanKaonNsig - 0.)/scaleFactor;
  307. Double_t new_y = (kaonMassSqr - pionMassSqr);
  308. return ( -TMath::ATan2(new_y,new_x) );
  309. }
  310. std::pair<Double_t,Double_t> GetNewXY(StFemtoTrack *const &track)
  311. {
  312. std::pair<Double_t,Double_t> coord;
  313. Double_t scaleFactor = GetScaleFactor(track);
  314. Double_t new_x = (track->nSigmaPion() - 0.)/scaleFactor;
  315. Double_t new_y = (track->massSqr() - pionMassSqr);
  316. Double_t rotAngle = GetRotAngle(track);
  317. coord.first = new_x * TMath::Cos(rotAngle) - new_y * TMath::Sin(rotAngle);
  318. coord.second = new_x * TMath::Sin(rotAngle) + new_y * TMath::Cos(rotAngle);
  319. return coord;
  320. }
  321. Bool_t isMesonXY(Double_t x, Double_t y)
  322. // Used to exclude proton peak from new XY coord distribution
  323. {
  324. Double_t pol0, pol1;
  325. pol0 = -0.92857143;
  326. pol1 = 1.4285714;
  327. // Not a proton
  328. if (y > (pol0 + pol1*x)) return true;
  329. // Proton
  330. if (y <= (pol0 + pol1*x)) return false;
  331. // just in case...
  332. return false;
  333. }
  334. Double_t GetSigmNewX(StFemtoTrack *const &track, Int_t PID)
  335. {
  336. if (PID != 0 && PID != 1 && PID != 2) return 0.;
  337. Double_t pol0, pol1, pol2, pol3;
  338. Double_t pt = track->pt();
  339. if (PID == 0) // pion
  340. {
  341. pol0 = 0.00061920122;
  342. pol1 = 0.00064431355;
  343. pol2 = 0.013672155;
  344. pol3 = 0.0012772833;
  345. }
  346. if (PID == 1) // kaon
  347. {
  348. pol0 = 0.0057203659;
  349. pol1 = 0.0013767144;
  350. pol2 = 0.0063761902;
  351. pol3 = 0.0073111853;
  352. }
  353. return ( pol0 + pol1*pt + pol2*pt*pt + pol3*pt*pt*pt );
  354. }
  355. Double_t GetSigmNewY(StFemtoTrack *const &track, Int_t PID)
  356. {
  357. if (PID != 0 && PID != 1 && PID != 2) return 0.;
  358. Double_t pol0, pol1, pol2, pol3;
  359. Double_t pt = track->pt();
  360. if (PID == 0) // pion
  361. {
  362. pol0 = 0.0017345792;
  363. pol1 = -0.0059824003;
  364. pol2 = 0.029537517;
  365. pol3 = -0.0037990834;
  366. }
  367. if (PID == 1) // kaon
  368. {
  369. pol0 = 0.0041058086;
  370. pol1 = -0.0041708451;
  371. pol2 = 0.026109827;
  372. pol3 = -0.0018772891;
  373. }
  374. return ( pol0 + pol1*pt + pol2*pt*pt + pol3*pt*pt*pt );
  375. }