StFlowScalarProdMaker.cxx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // $Id: StFlowScalarProdMaker.cxx,v 1.12 2004/12/09 23:47:10 posk Exp $
  4. //
  5. // Authors: Method proposed by Art and Sergei, code written by Aihong
  6. // Frame adopted from Art and Raimond's StFlowAnalysisMaker.
  7. ////////////////////////////////////////////////////////////////////////////
  8. //
  9. // Description: Maker to analyze Flow using the scalar product method
  10. //
  11. ////////////////////////////////////////////////////////////////////////////
  12. #include <Stiostream.h>
  13. #include <stdlib.h>
  14. #include <math.h>
  15. #include <float.h>
  16. #include "StMaker.h"
  17. #include "StFlowScalarProdMaker.h"
  18. #include "StFlowMaker/StFlowMaker.h"
  19. #include "StFlowMaker/StFlowEvent.h"
  20. #include "StFlowMaker/StFlowConstants.h"
  21. #include "StFlowMaker/StFlowSelection.h"
  22. #include "StEnumerations.h"
  23. #include "PhysicalConstants.h"
  24. #include "SystemOfUnits.h"
  25. #include "TVector2.h"
  26. #include "TFile.h"
  27. #include "TString.h"
  28. #include "TH1.h"
  29. #include "TH2.h"
  30. #include "TProfile.h"
  31. #include "TProfile2D.h"
  32. #include "StMessMgr.h"
  33. #include "TMath.h"
  34. #define PR(x) cout << "##### FlowScalarProdAnalysis: " << (#x) << " = " << (x) << endl;
  35. ClassImp(StFlowScalarProdMaker)
  36. //-----------------------------------------------------------------------
  37. StFlowScalarProdMaker::StFlowScalarProdMaker(const Char_t* name): StMaker(name),
  38. MakerName(name) {
  39. pFlowSelect = new StFlowSelection();
  40. SetHistoRanges();
  41. }
  42. StFlowScalarProdMaker::StFlowScalarProdMaker(const Char_t* name,
  43. const StFlowSelection& flowSelect) : StMaker(name), MakerName(name) {
  44. pFlowSelect = new StFlowSelection(flowSelect); //copy constructor
  45. SetHistoRanges();
  46. }
  47. //-----------------------------------------------------------------------
  48. StFlowScalarProdMaker::~StFlowScalarProdMaker() {
  49. }
  50. //-----------------------------------------------------------------------
  51. Int_t StFlowScalarProdMaker::Make() {
  52. // Fill histograms
  53. // Get a pointer to StFlowEvent
  54. StFlowMaker* pFlowMaker = NULL;
  55. pFlowMaker = (StFlowMaker*)GetMaker("Flow");
  56. if (pFlowMaker) pFlowEvent = pFlowMaker->FlowEventPointer();
  57. if (pFlowEvent) {
  58. if (pFlowSelect->Select(pFlowEvent)) { // event selected
  59. FillFromFlowEvent(); // get event quantities
  60. FillEventHistograms(); // fill from FlowEvent
  61. if (pFlowEvent) FillParticleHistograms(); // fill particle histograms
  62. }
  63. if (Debug()) StMaker::PrintInfo();
  64. } else {
  65. gMessMgr->Info("##### FlowScalarProdMaker: FlowEvent pointer null");
  66. }
  67. return kStOK;
  68. }
  69. //-----------------------------------------------------------------------
  70. Int_t StFlowScalarProdMaker::Init() {
  71. // Book histograms
  72. float ptMaxPart = Flow::ptMaxPart;
  73. if (pFlowSelect->PtMaxPart()) {
  74. ptMaxPart = pFlowSelect->PtMaxPart();
  75. }
  76. int nPtBinsPart = Flow::nPtBinsPart;
  77. if (pFlowSelect->PtBinsPart()) {
  78. nPtBinsPart = pFlowSelect->PtBinsPart();
  79. }
  80. xLabel = "Pseudorapidity";
  81. if (strlen(pFlowSelect->PidPart()) != 0) { xLabel = "Rapidity"; }
  82. TString* histTitle;
  83. // for each selection
  84. for (int k = 0; k < Flow::nSels; k++) {
  85. // resolution
  86. histTitle = new TString("Flow_Res_ScalarProd_Sel");
  87. *histTitle += k+1;
  88. histFull[k].mHistRes = new TProfile(histTitle->Data(), histTitle->Data(),
  89. Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5, -1.*FLT_MAX, FLT_MAX, "");
  90. histFull[k].mHistRes->SetXTitle("Harmonic");
  91. histFull[k].mHistRes->SetYTitle("Resolution");
  92. delete histTitle;
  93. // vObs
  94. histTitle = new TString("Flow_vObs_ScalarProd_Sel");
  95. *histTitle += k+1;
  96. histFull[k].mHist_vObs = new TProfile(histTitle->Data(), histTitle->Data(),
  97. Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5, -10000., 10000., "");
  98. histFull[k].mHist_vObs->SetXTitle("Harmonic");
  99. histFull[k].mHist_vObs->SetYTitle("vObs (%)");
  100. delete histTitle;
  101. // for each harmonic
  102. for (int j = 0; j < Flow::nHars; j++) {
  103. // Flow observed
  104. histTitle = new TString("Flow_vObs2D_ScalarProd_Sel");
  105. *histTitle += k+1;
  106. histTitle->Append("_Har");
  107. *histTitle += j+1;
  108. histFull[k].histFullHar[j].mHist_vObs2D = new TProfile2D(histTitle->Data(),
  109. histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, nPtBinsPart,
  110. Flow::ptMin, ptMaxPart, -10000., 10000., "");
  111. histFull[k].histFullHar[j].mHist_vObs2D->SetXTitle((char*)xLabel.Data());
  112. histFull[k].histFullHar[j].mHist_vObs2D->SetYTitle("Pt (GeV/c)");
  113. delete histTitle;
  114. // Flow observed profiles
  115. histTitle = new TString("Flow_vObsEta_ScalarProd_Sel");
  116. *histTitle += k+1;
  117. histTitle->Append("_Har");
  118. *histTitle += j+1;
  119. histFull[k].histFullHar[j].mHist_vObsEta = new TProfile(histTitle->Data(),
  120. histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax,
  121. -10000., 10000., "");
  122. histFull[k].histFullHar[j].mHist_vObsEta->SetXTitle((char*)xLabel.Data());
  123. histFull[k].histFullHar[j].mHist_vObsEta->SetYTitle("v (%)");
  124. delete histTitle;
  125. histTitle = new TString("Flow_vObsPt_ScalarProd_Sel");
  126. *histTitle += k+1;
  127. histTitle->Append("_Har");
  128. *histTitle += j+1;
  129. histFull[k].histFullHar[j].mHist_vObsPt = new TProfile(histTitle->Data(),
  130. histTitle->Data(), nPtBinsPart, Flow::ptMin, ptMaxPart, -10000., 10000., "");
  131. histFull[k].histFullHar[j].mHist_vObsPt->SetXTitle("Pt (GeV/c)");
  132. histFull[k].histFullHar[j].mHist_vObsPt->SetYTitle("v (%)");
  133. delete histTitle;
  134. }
  135. }
  136. gMessMgr->SetLimit("##### FlowScalarProd", 2);
  137. gMessMgr->Info("##### FlowScalarProdAnalysis: $Id: StFlowScalarProdMaker.cxx,v 1.12 2004/12/09 23:47:10 posk Exp $");
  138. return StMaker::Init();
  139. }
  140. //-----------------------------------------------------------------------
  141. void StFlowScalarProdMaker::FillFromFlowEvent() {
  142. // Get Q vectors from StFlowEvent
  143. for (int k = 0; k < Flow::nSels; k++) {
  144. pFlowSelect->SetSelection(k);
  145. for (int j = 0; j < Flow::nHars; j++) {
  146. pFlowSelect->SetHarmonic(j);
  147. for (int n = 0; n < Flow::nSubs; n++) {
  148. pFlowSelect->SetSubevent(n);
  149. int i = Flow::nSels*k + n;
  150. // sub-event quantities
  151. mQSub[i][j]=pFlowEvent->Q(pFlowSelect);
  152. }
  153. pFlowSelect->SetSubevent(-1);
  154. // full event quantities
  155. mQ[k][j] = pFlowEvent->Q(pFlowSelect);
  156. }
  157. }
  158. }
  159. //-----------------------------------------------------------------------
  160. void StFlowScalarProdMaker::FillEventHistograms() {
  161. // The scaler product of the subevent Q vectors
  162. for (int k = 0; k < Flow::nSels; k++) {
  163. for (int j = 0; j < Flow::nHars; j++) {
  164. float order = (float)(j+1);
  165. histFull[k].mHistRes->Fill(order, (mQSub[Flow::nSels*k + 0][j].X()) *
  166. (mQSub[Flow::nSels*k + 1][j].X()) + (mQSub[Flow::nSels*k + 0][j].Y())
  167. * (mQSub[Flow::nSels*k + 1][j].Y()) );
  168. }
  169. }
  170. }
  171. //-----------------------------------------------------------------------
  172. void StFlowScalarProdMaker::FillParticleHistograms() {
  173. // Fill histograms from the particles
  174. // Initialize Iterator
  175. StFlowTrackCollection* pFlowTracks = pFlowEvent->TrackCollection();
  176. StFlowTrackIterator itr;
  177. for (itr = pFlowTracks->begin(); itr != pFlowTracks->end(); itr++) {
  178. StFlowTrack* pFlowTrack = *itr;
  179. float phi = pFlowTrack->Phi();
  180. if (phi < 0.) phi += twopi;
  181. float eta = pFlowTrack->Eta();
  182. float pt = pFlowTrack->Pt();
  183. TVector2 q_i;
  184. TVector2 u_i;
  185. for (int k = 0; k < Flow::nSels; k++) {
  186. pFlowSelect->SetSelection(k);
  187. for (int j = 0; j < Flow::nHars; j++) {
  188. pFlowSelect->SetHarmonic(j);
  189. if (pFlowSelect->SelectPart(pFlowTrack)) {
  190. bool oddHar = (j+1) % 2;
  191. double order = (double)(j+1);
  192. TVector2 mQ_i = mQ[k][j];
  193. // Remove autocorrelations
  194. if (pFlowSelect->Select(pFlowTrack)) {
  195. double phiWgt = pFlowEvent->PhiWeight(k, j, pFlowTrack);
  196. q_i.Set(phiWgt * cos(phi * order), phiWgt * sin(phi * order));
  197. mQ_i = mQ_i - q_i;
  198. }
  199. // Caculate v for all particles selected
  200. u_i.Set(cos(phi*order), sin(phi*order));
  201. float v = (mQ_i.X()*u_i.X() + mQ_i.Y()*u_i.Y()) /perCent;
  202. float vFlip = v;
  203. if (eta < 0 && oddHar) vFlip *= -1;
  204. if (strlen(pFlowSelect->PidPart()) != 0) {
  205. float rapidity = pFlowTrack->Y();
  206. histFull[k].histFullHar[j].mHist_vObs2D-> Fill(rapidity, pt, v);
  207. histFull[k].histFullHar[j].mHist_vObsEta->Fill(rapidity, v);
  208. } else {
  209. histFull[k].histFullHar[j].mHist_vObs2D-> Fill(eta, pt, v);
  210. histFull[k].histFullHar[j].mHist_vObsEta->Fill(eta, v);
  211. }
  212. histFull[k].histFullHar[j].mHist_vObsPt-> Fill(pt, vFlip);
  213. histFull[k].mHist_vObs->Fill(order, vFlip);
  214. }
  215. }
  216. }
  217. }
  218. }
  219. //-----------------------------------------------------------------------
  220. Int_t StFlowScalarProdMaker::Finish() {
  221. // Calculates resolution and mean flow values
  222. TString* histTitle;
  223. double content;
  224. double error;
  225. double totalError;
  226. cout << endl << "##### Scalar Product Maker:" << endl;
  227. for (int k = 0; k < Flow::nSels; k++) {
  228. // Create the 1D v histogram
  229. histTitle = new TString("Flow_v_ScalarProd_Sel");
  230. *histTitle += k+1;
  231. histFull[k].mHist_v =
  232. histFull[k].mHist_vObs->ProjectionX(histTitle->Data());
  233. histFull[k].mHist_v->SetTitle(histTitle->Data());
  234. histFull[k].mHist_v->SetXTitle("Harmonic");
  235. histFull[k].mHist_v->SetYTitle("v (%)");
  236. delete histTitle;
  237. AddHist(histFull[k].mHist_v);
  238. for (int j = 0; j < Flow::nHars; j++) {
  239. //Calculate the resolution
  240. mRes[k][j] = ::sqrt(histFull[k].mHistRes->GetBinContent(j+1))*2.;
  241. mResErr[k][j] = (histFull[k].mHistRes->GetBinError(j+1))*2./mRes[k][j];
  242. // Create the v 2D histogram
  243. histTitle = new TString("Flow_v2D_ScalarProd_Sel");
  244. *histTitle += k+1;
  245. histTitle->Append("_Har");
  246. *histTitle += j+1;
  247. histFull[k].histFullHar[j].mHist_v2D =
  248. histFull[k].histFullHar[j].mHist_vObs2D->ProjectionXY(histTitle->Data());
  249. histFull[k].histFullHar[j].mHist_v2D->SetTitle(histTitle->Data());
  250. histFull[k].histFullHar[j].mHist_v2D->SetXTitle((char*)xLabel.Data());
  251. histFull[k].histFullHar[j].mHist_v2D->SetYTitle("Pt (GeV/c)");
  252. histFull[k].histFullHar[j].mHist_v2D->SetZTitle("v (%)");
  253. delete histTitle;
  254. AddHist(histFull[k].histFullHar[j].mHist_v2D);
  255. // Create the 1D v histograms
  256. histTitle = new TString("Flow_vEta_ScalarProd_Sel");
  257. *histTitle += k+1;
  258. histTitle->Append("_Har");
  259. *histTitle += j+1;
  260. histFull[k].histFullHar[j].mHist_vEta =
  261. histFull[k].histFullHar[j].mHist_vObsEta->ProjectionX(histTitle->Data());
  262. histFull[k].histFullHar[j].mHist_vEta->SetTitle(histTitle->Data());
  263. histFull[k].histFullHar[j].mHist_vEta->SetXTitle((char*)xLabel.Data());
  264. histFull[k].histFullHar[j].mHist_vEta->SetYTitle("v (%)");
  265. delete histTitle;
  266. AddHist(histFull[k].histFullHar[j].mHist_vEta);
  267. TString* histTitle = new TString("Flow_vPt_ScalarProd_Sel");
  268. *histTitle += k+1;
  269. histTitle->Append("_Har");
  270. *histTitle += j+1;
  271. histFull[k].histFullHar[j].mHist_vPt =
  272. histFull[k].histFullHar[j].mHist_vObsPt->ProjectionX(histTitle->Data());
  273. histFull[k].histFullHar[j].mHist_vPt->SetTitle(histTitle->Data());
  274. histFull[k].histFullHar[j].mHist_vPt->SetXTitle("Pt (GeV/c)");
  275. histFull[k].histFullHar[j].mHist_vPt->SetYTitle("v (%)");
  276. delete histTitle;
  277. AddHist(histFull[k].histFullHar[j].mHist_vPt);
  278. // Calulate v = vObs / Resolution or Q.u/(2::sqrt(<Q_a.Q_b>))
  279. if (mRes[k][j]) {
  280. cout << "##### Resolution of the " << j+1 << "th harmonic = " <<
  281. mRes[k][j] << " +/- " << mResErr[k][j] << endl;
  282. // The systematic error of the resolution is not folded in.
  283. histFull[k].histFullHar[j].mHist_v2D ->Scale(1. / mRes[k][j]);
  284. histFull[k].histFullHar[j].mHist_vEta->Scale(1. / mRes[k][j]);
  285. histFull[k].histFullHar[j].mHist_vPt ->Scale(1. / mRes[k][j]);
  286. content = histFull[k].mHist_v->GetBinContent(j+1);
  287. content /= mRes[k][j];
  288. histFull[k].mHist_v->SetBinContent(j+1, content);
  289. // The systematic error of the resolution is folded in.
  290. error = histFull[k].mHist_v->GetBinError(j+1);
  291. error /= mRes[k][j];
  292. totalError = fabs(content) * ::sqrt((error/content)*(error/content) +
  293. (mResErr[k][j]/mRes[k][j])*(mResErr[k][j]/mRes[k][j]));
  294. histFull[k].mHist_v->SetBinError(j+1, totalError);
  295. cout << "##### v" << j+1 << "= (" << content << " +/- " << error <<
  296. " +/- " << totalError << "(with syst.)) %" << endl;
  297. } else {
  298. cout << "##### Resolution of the " << j+1 << "th harmonic was zero."
  299. << endl;
  300. histFull[k].histFullHar[j].mHist_v2D ->Reset();
  301. histFull[k].histFullHar[j].mHist_vEta->Reset();
  302. histFull[k].histFullHar[j].mHist_vPt ->Reset();
  303. histFull[k].mHist_v->SetBinContent(j+1, 0.);
  304. histFull[k].mHist_v->SetBinError(j+1, 0.);
  305. }
  306. }
  307. }
  308. //GetHistList()->ls();
  309. // Write all histograms
  310. TFile histFile("flow.scalar.root", "RECREATE");
  311. GetHistList()->Write();
  312. histFile.Close();
  313. delete pFlowSelect;
  314. return StMaker::Finish();
  315. }
  316. //-----------------------------------------------------------------------
  317. void StFlowScalarProdMaker::SetHistoRanges(Bool_t ftpc_included) {
  318. if (ftpc_included) {
  319. mEtaMin = Flow::etaMin;
  320. mEtaMax = Flow::etaMax;
  321. mNEtaBins = Flow::nEtaBins;
  322. } else {
  323. mEtaMin = Flow::etaMinTpcOnly;
  324. mEtaMax = Flow::etaMaxTpcOnly;
  325. mNEtaBins = Flow::nEtaBinsTpcOnly;
  326. }
  327. return;
  328. }
  329. ////////////////////////////////////////////////////////////////////////////
  330. //
  331. // $Log: StFlowScalarProdMaker.cxx,v $
  332. // Revision 1.12 2004/12/09 23:47:10 posk
  333. // Minor changes in code formatting.
  334. // Added hist for TPC primary dca to AnalysisMaker.
  335. //
  336. // Revision 1.11 2003/09/02 17:58:11 perev
  337. // gcc 3.2 updates + WarnOff
  338. //
  339. // Revision 1.10 2003/07/07 21:58:20 posk
  340. // Made units of momentum GeV/c instead of GeV.
  341. //
  342. // Revision 1.9 2003/02/24 19:35:27 posk
  343. // Corrected mistake in the error of the resolution.
  344. // This only affected doubly integrated v values.
  345. //
  346. // Revision 1.8 2003/01/10 16:40:49 oldi
  347. // Several changes to comply with FTPC tracks:
  348. // - Switch to include/exclude FTPC tracks introduced.
  349. // The same switch changes the range of the eta histograms.
  350. // - Eta symmetry plots for FTPC tracks added and separated from TPC plots.
  351. // - PhiWgts and related histograms for FTPC tracks split in FarEast, East,
  352. // West, FarWest (depending on vertex.z()).
  353. // - Psi_Diff plots for 2 different selections and the first 2 harmonics added.
  354. // - Cut to exclude mu-events with no primary vertex introduced.
  355. // (This is possible for UPC events and FTPC tracks.)
  356. // - Global DCA cut for FTPC tracks added.
  357. // - Global DCA cuts for event plane selection separated for TPC and FTPC tracks.
  358. // - Charge cut for FTPC tracks added.
  359. //
  360. // Revision 1.7 2002/05/21 18:42:17 posk
  361. // Kirill's correction to minBias.C for bins with one count.
  362. //
  363. // Revision 1.6 2002/02/18 01:11:53 jeromel
  364. // Mandatory fix for FLT_MAX fix i.e. include float.h
  365. //
  366. // Revision 1.5 2002/02/13 22:31:46 posk
  367. // Pt Weight now also weights Phi Weight. Added Eta Weught, default=FALSE.
  368. //
  369. // Revision 1.4 2002/01/31 01:09:30 posk
  370. // *** empty log message ***
  371. //
  372. // Revision 1.3 2002/01/14 23:42:52 posk
  373. // Renamed ScalerProd histograms. Moved print commands to FlowMaker::Finish().
  374. //
  375. // Revision 1.2 2001/12/21 17:01:59 aihong
  376. // minor changes
  377. //
  378. // Revision 1.1 2001/12/18 23:46:47 aihong
  379. // install scalar product method
  380. //
  381. //
  382. ////////////////////////////////////////////////////////////////////////////