StFemtoDstPythia6Maker.cxx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. #include "StFemtoDstPythia6Maker.h"
  2. #include "TBranch.h"
  3. #include "TMath.h"
  4. #include "TLorentzVector.h"
  5. #include "TClonesArray.h"
  6. #include "TObjArray.h"
  7. #include "TDatabasePDG.h"
  8. ClassImp(StFemtoDstPythia6Maker)
  9. #define MAXFILESIZE 1900000000
  10. const Float_t PYTHIA_BFIELD = 4.510600000;
  11. const Float_t PYTHIA_RBFIELD = -4.510600000;
  12. //_________________
  13. StFemtoDstPythia6Maker::StFemtoDstPythia6Maker(TPythia6 *pythiaDst,
  14. const Char_t *oFileName) {
  15. std::cout << "StFemtoDstPythia6Maker::StFemtoDstPythia6Maker - Creating an instance...";
  16. mOutFileName = oFileName;
  17. mPythiaDst = pythiaDst;
  18. mCompression = 9;
  19. mEventIsGood = false;
  20. mNEventsIn = 0;
  21. mIsGoodTrack = false;
  22. mMatrix = new TMatrixTSym<double>(2);
  23. mPtCut = 0.1;
  24. mIsFullField = false;
  25. //Initialize single-particle cut variables
  26. mTrackMomentum[0] = 0.15;
  27. mTrackMomentum[1] = 1.75;
  28. mTrackDca[0] = 0.;
  29. mTrackDca[1] = 3.;
  30. mTrackDcaGlobal[0] = 0.;
  31. mTrackDcaGlobal[1] = 3.;
  32. mTrackEta[0] = -1.1;
  33. mTrackEta[1] = 1.1;
  34. //Flags and cuts for exclusion
  35. mRemovePions = false;
  36. mRemoveKaons = false;
  37. mRemoveProtons = true;
  38. randy = new TRandom3(0);
  39. std::cout << "\t[DONE]" << std::endl;
  40. }
  41. //_________________
  42. StFemtoDstPythia6Maker::~StFemtoDstPythia6Maker() {
  43. /* nothing to do */
  44. }
  45. //_________________
  46. Int_t StFemtoDstPythia6Maker::Init() {
  47. std::cout << "StFemtoDstPythia6Maker::Init - Initializing the maker"
  48. << std::endl
  49. << "Creating output file: " << mOutFileName;
  50. mFemtoEvent = new StFemtoEvent();
  51. mOutFile = new TFile(mOutFileName, "RECREATE");
  52. mOutFile->SetCompressionLevel(mCompression);
  53. std::cout << "\t[DONE]" << std::endl;
  54. mTree = new TTree("StFemtoDst","StFemtoDst");
  55. mTree->SetMaxTreeSize(MAXFILESIZE);
  56. mTree->Branch("StFemtoEvent","StFemtoEvent", &mFemtoEvent);
  57. mNBytes = 0;
  58. std::cout << "StFemtoDstPythia6Maker::Init - Initialization has been finished"
  59. << std::endl;
  60. return StMaker::Init();
  61. }
  62. //_________________
  63. void StFemtoDstPythia6Maker::Clear(Option_t *option) {
  64. StMaker::Clear();
  65. }
  66. //_________________
  67. Int_t StFemtoDstPythia6Maker::Make() {
  68. Float_t mMagneticField;
  69. if(mIsFullField) {
  70. mMagneticField = PYTHIA_BFIELD;
  71. }
  72. else {
  73. mMagneticField = PYTHIA_RBFIELD;
  74. }
  75. TObjArray *pyParticles = NULL;
  76. TMCParticle *pyParticle = NULL;
  77. Int_t mNumParticles = 0;
  78. Int_t pyPosTrkNum = 0;
  79. Int_t pyPosTrk2Num = 0;
  80. //Int_t pyNegTrkNum = 0;
  81. Int_t pyRefMult = 0;
  82. Int_t pyRefMult2 = 0;
  83. Int_t pyPrimTracksNum = 0;
  84. Int_t pyGlobTracksNum = 0;
  85. Int_t pyKF, pyKS, pyCharge;
  86. Float_t pyTrkMass;
  87. Float_t pyTrkNSigmaElectron, pyTrkNSigmaPion;
  88. Float_t pyTrkNSigmaKaon, pyTrkNSigmaProton;
  89. Float_t pyPx, pyPy, pyPz, pyP, pyEta;
  90. Float_t pyVx, pyVy, pyVz, pyDcaXY;
  91. //Generate non-empty event
  92. do {
  93. CleanVariables();
  94. mPythiaDst->GenerateEvent();
  95. pyParticles = mPythiaDst->GetListOfParticles();
  96. if(pyParticles) {
  97. mEventIsGood = true;
  98. }
  99. } while(!mEventIsGood);
  100. mNEventsIn++;
  101. mNumParticles = pyParticles->GetEntries();
  102. //mPythiaDst->Pylist(1);
  103. //Number of particles in acceptance
  104. pyRefMult = 0;
  105. StFemtoTrack *mFTrack = NULL;
  106. float sph = -999.;
  107. float pt_full = 0.0;
  108. mMatrix->Zero();
  109. //Simulated track loop
  110. for(Int_t iTrk=0; iTrk<mNumParticles; iTrk++) {
  111. pyParticle = (TMCParticle*)pyParticles->At(iTrk);
  112. mIsGoodTrack = false;
  113. pyKF = 0;
  114. pyKS = 0;
  115. pyKS = pyParticle->GetKS();
  116. pyCharge = 0;
  117. //Use final-state particles
  118. if(!pyParticle || pyKS!=1) continue;
  119. pyKF = pyParticle->GetKF();
  120. pyCharge = TDatabasePDG::Instance()->GetParticle(pyKF)->Charge();
  121. pyPx = pyParticle->GetPx();
  122. pyPy = pyParticle->GetPy();
  123. pyPz = pyParticle->GetPz();
  124. float pyPt = sqrt(pyPx*pyPx + pyPy*pyPy);
  125. pyP = TMath::Sqrt(pyPx*pyPx + pyPy*pyPy + pyPz*pyPz);
  126. pyEta = 0.5 * TMath::Log( (pyP + pyPz)/ (pyP - pyPz) );
  127. pyVx = pyParticle->GetVx() * 0.1;
  128. pyVy = pyParticle->GetVy() * 0.1;
  129. pyVz = pyParticle->GetVz() * 0.1;
  130. pyDcaXY = TMath::Sqrt(pyVx*pyVx + pyVy*pyVy);
  131. if (pyCharge !=0 && fabs(pyEta) < 1.0 && pyPt > mPtCut)
  132. {
  133. (*mMatrix)(0, 0) += pyPx*pyPx/pyPt;
  134. (*mMatrix)(1, 1) += pyPy*pyPy/pyPt;
  135. (*mMatrix)(0, 1) += pyPx*pyPy/pyPt;
  136. (*mMatrix)(1, 0) += pyPx*pyPy/pyPt;
  137. pt_full += pyPt;
  138. }
  139. //Calculate refMult
  140. if(TMath::Abs(pyEta)<=0.5 && pyP>=0.075 && pyCharge!=0) {
  141. pyRefMult++;
  142. if(pyCharge>0) {
  143. pyPosTrkNum++;
  144. }
  145. /*
  146. if(pyCharge<0) {
  147. pyNegTrkNum++;
  148. }
  149. */
  150. }
  151. //Calculate refMult2
  152. if(TMath::Abs(pyEta)<=1. && pyP>=0.075 && pyCharge!=0) {
  153. pyRefMult2++;
  154. if(pyCharge>0) {
  155. pyPosTrk2Num++;
  156. }
  157. }
  158. //Calculate number of primary and global tracks
  159. if(TMath::Abs(pyEta)<=1. && pyP>0.14) {
  160. pyGlobTracksNum++;
  161. if(pyDcaXY<=2. && pyVz<=2.) {
  162. pyPrimTracksNum++;
  163. }
  164. }
  165. //Use pions and kaons only
  166. if( TMath::Abs(pyKF)!=211 && TMath::Abs(pyKF)!=321 &&
  167. TMath::Abs(pyKF)!=2212 ) continue;
  168. if(mRemovePions==true && TMath::Abs(pyKF)==211) continue;
  169. if(mRemoveKaons==true && TMath::Abs(pyKF)==321) continue;
  170. if(mRemoveProtons==true && TMath::Abs(pyKF)==2212) continue;
  171. mIsGoodTrack = AcceptTrack(pyParticle, pyCharge);
  172. if(!mIsGoodTrack) continue;
  173. mFTrack = NULL;
  174. pyTrkMass = pyParticle->GetMass();
  175. pyCharge = TDatabasePDG::Instance()->GetParticle(pyKF)->Charge();
  176. if(pyCharge > 0) {
  177. pyCharge = 1;
  178. }
  179. else if(pyCharge < 0) {
  180. pyCharge = -1;
  181. }
  182. Int_t mNHits = 45;
  183. unsigned int tmap1 = 0;
  184. unsigned int tmap2 = 0;
  185. //Set some track parameters
  186. switch(TMath::Abs(pyKF)) {
  187. case 211:
  188. pyTrkNSigmaElectron = -999.;
  189. pyTrkNSigmaPion = 0.;
  190. pyTrkNSigmaKaon = -999.;
  191. pyTrkNSigmaProton = -999.;
  192. break;
  193. case 321:
  194. pyTrkNSigmaElectron = -999.;
  195. pyTrkNSigmaPion = -999.;
  196. pyTrkNSigmaKaon = 0.;
  197. pyTrkNSigmaProton = -999.;
  198. break;
  199. case 2212:
  200. pyTrkNSigmaElectron = -999.;
  201. pyTrkNSigmaPion = -999.;
  202. pyTrkNSigmaKaon = -999.;
  203. pyTrkNSigmaProton = 0.;
  204. break;
  205. default:
  206. pyTrkNSigmaElectron = -999.;
  207. pyTrkNSigmaPion = -999.;
  208. pyTrkNSigmaKaon = -999.;
  209. pyTrkNSigmaProton = -999.;
  210. }
  211. Float_t ptot = TMath::Sqrt(pyPx*pyPx + pyPy*pyPy + pyPz*pyPz);
  212. Float_t energy = TMath::Sqrt(ptot*ptot + pyTrkMass*pyTrkMass);
  213. mFTrack = mFemtoEvent->AddFemtoTrack();
  214. mFTrack->SetId( iTrk );
  215. mFTrack->SetNHits( (Char_t) (pyCharge * mNHits) );
  216. mFTrack->SetNHitsPoss( mNHits );
  217. //mFTrack->SetNHitsDedx( mNHits );
  218. mFTrack->SetNSigmaElectron( pyTrkNSigmaElectron );
  219. mFTrack->SetNSigmaPion( pyTrkNSigmaPion );
  220. mFTrack->SetNSigmaKaon( pyTrkNSigmaKaon );
  221. mFTrack->SetNSigmaProton( pyTrkNSigmaProton );
  222. mFTrack->SetDedx( dedxMean(pyTrkMass, pyP) );
  223. //mFTrack->SetChi2( 1. );
  224. if(ptot < 0.15) { //Tracks only in the inner sector. R=1m
  225. tmap1 = 0;
  226. tmap2 = 0;
  227. for(int iBit=0; iBit<32; iBit++) {
  228. if(randy->Rndm() < 0.95) {
  229. tmap1 |= 1 << iBit;
  230. }
  231. else {
  232. tmap1 |= 0 << iBit;
  233. }
  234. }
  235. //Default set to the first bit: primary-vertex-used
  236. tmap1 |= 1 << 0;
  237. }
  238. else if(ptot < 0.3) { //Tracks may come to the end of the outer sector: R = 2m
  239. tmap1 = 0;
  240. tmap2 = 0;
  241. for(int iBit=0; iBit<32; iBit++) {
  242. if(randy->Rndm() < 0.95) {
  243. tmap1 |= 1 << iBit;
  244. }
  245. else {
  246. tmap1 |= 0 << iBit;
  247. }
  248. if(iBit < 27) {
  249. if(randy->Rndm() < 0.85) {
  250. tmap2 |= 1 << iBit;
  251. }
  252. else {
  253. tmap2 |= 0 << iBit;
  254. }
  255. }
  256. }
  257. //Default set to the first bit: primary-vertex-used
  258. tmap1 |= 1 << 0;
  259. }
  260. else {
  261. tmap1 = 0;
  262. tmap2 = 0;
  263. for(int iBit=0; iBit<32; iBit++) {
  264. if(randy->Rndm() < 0.95) {
  265. tmap1 |= 1 << iBit;
  266. }
  267. else {
  268. tmap1 |= 0 << iBit;
  269. }
  270. if(iBit < 27) {
  271. if(randy->Rndm() < 0.95) {
  272. tmap2 |= 1 << iBit;
  273. }
  274. else {
  275. tmap2 |= 0 << iBit;
  276. }
  277. }
  278. }
  279. //Default set to the first bit: primary-vertex-used
  280. tmap1 |= 1 << 0;
  281. }
  282. mFTrack->SetMap0( tmap1 );
  283. mFTrack->SetMap1( tmap2 );
  284. mFTrack->SetP( pyPx, pyPy, pyPz );
  285. mFTrack->SetDCAxGlobal( pyVx );
  286. mFTrack->SetDCAyGlobal( pyVy );
  287. mFTrack->SetDCAzGlobal( pyVz );
  288. mFTrack->SetGlobalP( pyPx, pyPy, pyPz );
  289. mFTrack->SetBeta( ptot/energy );
  290. } //for(Int_t iTrk=0; iTrk<mNumParticles; iTrk++)
  291. *mMatrix *= 1./pt_full;
  292. TMatrixDSymEigen death_machine(*mMatrix);
  293. TVectorD eigen = death_machine.GetEigenValues();
  294. sph = 2.*eigen.Min()/(eigen[0] + eigen[1]);
  295. mFemtoEvent->SetSphericity(sph);
  296. mFemtoEvent->SetEventId( mNEventsIn );
  297. mFemtoEvent->SetRunId( randy->Uniform(1, 10000000) );
  298. mFemtoEvent->SetCollisionType( false );
  299. mFemtoEvent->SetRefMult( pyRefMult );
  300. mFemtoEvent->SetRefMult2( pyRefMult2 );
  301. mFemtoEvent->SetRefMultCorr( pyRefMult );
  302. mFemtoEvent->SetRefMultCorrWeight( 1. );
  303. mFemtoEvent->SetCent16( 0 );
  304. mFemtoEvent->SetRefMultPos( pyPosTrkNum );
  305. mFemtoEvent->SetRefMult2Pos( pyPosTrk2Num );
  306. //mFemtoEvent->SetRefMultNeg( pyNegTrkNum );
  307. //mFemtoEvent->SetZDCe( 45000 );
  308. //mFemtoEvent->SetZDCw( 45000 );
  309. mFemtoEvent->SetNumberOfBTofHit( pyRefMult );
  310. mFemtoEvent->SetNumberOfPrimaryTracks( pyPrimTracksNum );
  311. mFemtoEvent->SetNumberOfGlobalTracks( pyGlobTracksNum );
  312. mFemtoEvent->SetMagneticField( mMagneticField );
  313. mFemtoEvent->SetPrimaryVertexPosition(0., 0., 0.);
  314. mFemtoEvent->SetVpdVz( 0. );
  315. mFemtoEvent->SetTriggerId( mTriggerId );
  316. mFemtoEvent->SetPrimaryVertexRanking( 10000 );
  317. if(mEventIsGood) {
  318. mNBytes += mTree->Fill();
  319. mFemtoEvent->Clear();
  320. }
  321. return kStOk;
  322. }
  323. //_________________
  324. Int_t StFemtoDstPythia6Maker::Finish() {
  325. mOutFile->cd();
  326. mOutFile->Write();
  327. mOutFile->Close();
  328. std::cout << "****************************************" << std::endl
  329. << "StFemtoDstPythia6Maker has been finished" << std::endl
  330. << "\t nEventsGenerated: " << mNEventsIn << std::endl
  331. << "****************************************" << std::endl;
  332. return kStOk;
  333. }
  334. //_________________
  335. void StFemtoDstPythia6Maker::CleanVariables() {
  336. mEventIsGood = false;
  337. }
  338. //_________________
  339. Bool_t StFemtoDstPythia6Maker::AcceptTrack(TMCParticle *trk, Int_t charge) {
  340. Float_t px = trk->GetPx();
  341. Float_t py = trk->GetPy();
  342. Float_t pz = trk->GetPz();
  343. Float_t p = TMath::Sqrt(px*px + py*py + pz*pz);
  344. Float_t eta = 0.5*TMath::Log( (p + pz)/ (p - pz) );
  345. Float_t vx = trk->GetVx() / 10.;
  346. Float_t vy = trk->GetVy() / 10.;
  347. Float_t vz = trk->GetVz() / 10.;
  348. //dcaXY is dcaXYZ now
  349. Float_t dcaXY = TMath::Sqrt(vx*vx + vy*vy + vz*vz);
  350. Bool_t mIsGoodKinematics = false;
  351. Bool_t mIsGoodCharge = false;
  352. Bool_t mIsGoodParticle = false;
  353. if(charge > 0. || charge < 0.) {
  354. mIsGoodCharge = true;
  355. }
  356. if( p >= mTrackMomentum[0] &&
  357. p <= mTrackMomentum[1] &&
  358. eta >= mTrackEta[0] &&
  359. eta <= mTrackEta[1] &&
  360. dcaXY >= mTrackDca[0] &&
  361. dcaXY <= mTrackDca[1] &&
  362. dcaXY >= mTrackDcaGlobal[0] &&
  363. dcaXY <= mTrackDcaGlobal[1]) {
  364. mIsGoodKinematics = true;
  365. }
  366. if(mIsGoodKinematics == true &&
  367. mIsGoodCharge == true) {
  368. mIsGoodParticle = true;
  369. }
  370. return mIsGoodParticle;
  371. }
  372. //________________
  373. Double_t StFemtoDstPythia6Maker::dedxMean(Double_t mass, Double_t momentum) {
  374. Double_t dedxMean;
  375. Double_t tpcDedxGain = 0.174325e-06;
  376. Double_t tpcDedxOffset = -2.71889;
  377. Double_t tpcDedxRise = 776.626;
  378. Double_t gamma = TMath::Sqrt(momentum*momentum/(mass*mass)+1.);
  379. Double_t beta = TMath::Sqrt(1. - 1./(gamma*gamma));
  380. Double_t rise = tpcDedxRise* beta*beta*gamma*gamma;
  381. if ( beta > 0)
  382. dedxMean = tpcDedxGain/(beta*beta) * (0.5*TMath::Log(rise) - beta*beta
  383. - tpcDedxOffset);
  384. else
  385. dedxMean = 1000.;
  386. return dedxMean;
  387. }