StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StFlowLeeYangZerosMaker.cxx
1 //
3 // $Id: StFlowLeeYangZerosMaker.cxx,v 1.8 2018/02/26 23:10:59 smirnovd Exp $
4 //
5 // Authors: Markus Oldenberg and Art Poskanzer, LBNL
6 // with advice from Jean-Yves Ollitrault and Nicolas Borghini
7 //
9 //
10 // Description: Maker to analyze Flow using the LeeYangZeros method
11 // Selection 1 (k=0) uses the Sum Generating Function
12 // Selection 2 (k=1) uses the Product Generating Function
13 // Equation numbers are from Big Paper (BP) Nucl. Phys. A 727, 373 (2003)
14 // Practical Guide (PG) J. Phys. G: Nucl. Part. Phys. 30, S1213 (2004)
15 // Directed Flow (DF) Nucl. Phys. A 742, 130 (2004)
16 // The errors come from the variations with theta and batch job variations
17 // This treats the acceptance variations with theta as statistical
18 // Particles which would normally be correlated with the event plane are analyzed
19 // The event plane selections are not used
20 // The ZeroPass determines the recentering parameters
21 //
23 
24 #include <Stiostream.h>
25 #include <stdlib.h>
26 #include <math.h>
27 #include "StMaker.h"
28 #include "StFlowLeeYangZerosMaker.h"
29 #include "StFlowMaker/StFlowMaker.h"
30 #include "StFlowMaker/StFlowEvent.h"
31 #include "StFlowMaker/StFlowConstants.h"
32 #include "StFlowMaker/StFlowSelection.h"
33 #include "StEnumerations.h"
34 #include "PhysicalConstants.h"
35 #include "SystemOfUnits.h"
36 #include "TVector2.h"
37 #include "TFile.h"
38 #include "TString.h"
39 #include "TH1.h"
40 #include "TProfile.h"
41 #include "TProfile2D.h"
42 #include "TOrdCollection.h"
43 #include "StMessMgr.h"
44 #include "TMath.h"
45 #include "TComplex.h"
46 //#include "StTimer.hh"
47 #define PR(x) cout << "##### FlowLYZ: " << (#x) << " = " << (x) << endl;
48 
50 
51 Bool_t StFlowLeeYangZerosMaker::mV1Mixed = kTRUE;
52 
53 //-----------------------------------------------------------------------
54 
56  MakerName(name) {
57  pFlowSelect = new StFlowSelection();
58  SetHistoRanges();
59  SetPtRange_for_vEta(0., 0.);
60  SetEtaRange_for_vPt(0., 0.);
61 }
62 
64  const StFlowSelection& flowSelect) :
65  StMaker(name), MakerName(name) {
66  pFlowSelect = new StFlowSelection(flowSelect);
67  SetHistoRanges();
68  SetPtRange_for_vEta(0., 0.);
69  SetEtaRange_for_vPt(0., 0.);
70 }
71 
72 //-----------------------------------------------------------------------
73 
75 }
76 
77 //-----------------------------------------------------------------------
78 
80  // Fill histograms
81 
82  // Get a pointer to StFlowEvent
83  StFlowMaker* pFlowMaker = NULL;
84  pFlowMaker = (StFlowMaker*)GetMaker("Flow");
85  if (pFlowMaker) pFlowEvent = pFlowMaker->FlowEventPointer();
86  if (pFlowEvent && pFlowSelect->Select(pFlowEvent)) { // event selected
87  if (FillFromFlowEvent()) { // fill event histograms
88  if (!mFirstPass) { FillParticleHistograms(); } // fill particle histograms
89  } else {
90  gMessMgr->Info("##### FlowLeeYangZero: Event Q = 0");
91  }
92  } else {
93  gMessMgr->Info("##### FlowLeeYangZero: FlowEvent pointer null");
94  return kStOK;
95  }
96 
97  if (Debug()) StMaker::PrintInfo();
98 
99  return kStOK;
100 }
101 
102 //-----------------------------------------------------------------------
103 
104 Int_t StFlowLeeYangZerosMaker::Init() {
105  // Book histograms
106 
107 // timeEvent = StTimer::StTimer();
108 // timePart = StTimer::StTimer();
109 // timeFinish = StTimer::StTimer();
110 // timeInit.start();
111 
112  float ptMaxPart = Flow::ptMaxPart;
113  if (pFlowSelect->PtMaxPart()) {
114  ptMaxPart = pFlowSelect->PtMaxPart();
115  }
116 
117  mPtBinsPart = Flow::nPtBinsPart;
118  if (pFlowSelect->PtBinsPart()) {
119  mPtBinsPart = pFlowSelect->PtBinsPart();
120  }
121  xLabel = "Pseudorapidity";
122  if (strlen(pFlowSelect->PidPart()) != 0) { xLabel = "Rapidity"; }
123 
124  StFlowMaker* pFlowMaker = NULL;
125  pFlowMaker = (StFlowMaker*)GetMaker("Flow");
126  Bool_t reCentCalc = pFlowMaker->ReCentCalc();
127 
128  const float multMin = 0.;
129  const float multMax = 2000.;
130 
131  enum { nMultBins = 200
132  };
133 
134  TString* histTitle;
135  mZeroPass = kFALSE;
136  mFirstPass = kFALSE;
137  mV1Mixed = kTRUE;
138 
139  // Make array of G(r) bins
140  // Initial bin width is smaller than the mean bin width by the factor F
141  // The increase in bin width per channel is eps
142  Double_t rBinArray[Flow::nRBins+1];
143  Double_t meanBinWidth = Flow::rMax / Flow::nRBins;
144  //Double_t F = 1.; // for equal size bins
145  Double_t F = 8.;
146  Double_t initialBinWidth = meanBinWidth / F;
147  Double_t eps = 2. * meanBinWidth * (1. - 1./F) / (double)(Flow::nRBins-1);
148  rBinArray[0]= 0.;
149 // PR(meanBinWidth);
150 // PR(initialBinWidth);
151 // PR(eps);
152  Double_t binWidth = initialBinWidth;
153  for (int rBin = 1; rBin < Flow::nRBins+1; rBin++) {
154  rBinArray[rBin] = rBinArray[rBin-1] + binWidth;
155 // cout << rBin << ": " << binWidth << ", " << rBinArray[rBin] << endl;
156  binWidth += eps;
157  }
158 
159  // Yield of particles
160  mHistYieldPartPt = new TH1D("FlowLYZ_YieldPartPt", "FlowLYZ_YieldPartPt", mPtBinsPart,
161  Flow::ptMin, ptMaxPart);
162  mHistYieldPartPt->SetXTitle("Pt (GeV/c)");
163 
164  mHistYieldPartEta = new TH1D("FlowLYZ_YieldPartEta", "FlowLYZ_YieldPartEta", mNEtaBins,
165  mEtaMin, mEtaMax);
166  mHistYieldPartEta->SetXTitle((char*)xLabel.Data());
167 
168  // multiplicity
169  mHistMult = new TH1F("FlowLYZ_Mult", "FlowLYZ_Mult", nMultBins, multMin, multMax);
170  mHistMult->SetXTitle("Multiplicity");
171  mHistMult->SetYTitle("Counts");
172 
173  mNEvents = 0;
174 
175  // neumerator for v1 mixed harmonics: DF Eq. 7
176  for (int Ntheta = 0; Ntheta < Flow::nTheta; Ntheta++) {
177  mV1neum[Ntheta](0., 0.);
178  }
179 
180  // for each selection
181  for (int k = 0; k < Flow::nSels; k++) {
182 
183  // V
184  histTitle = new TString("FlowProLYZ_V_Sel");
185  *histTitle += k+1;
186  histFull[k].mHistPro_V = new TProfile(histTitle->Data(), histTitle->Data(),
187  Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5, -1000., 1000.);
188  histFull[k].mHistPro_V->SetXTitle("Harmonic");
189  histFull[k].mHistPro_V->SetYTitle("mean V_{n}");
190  delete histTitle;
191 
192  // "v integrated" from r0
193  histTitle = new TString("FlowProLYZ_vr0_Sel");
194  *histTitle += k+1;
195  histFull[k].mHistPro_vr0 = new TProfile(histTitle->Data(), histTitle->Data(),
196  Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5, -100., 100.);
197  histFull[k].mHistPro_vr0->SetXTitle("Harmonic");
198  histFull[k].mHistPro_vr0->SetYTitle("v from r0 (%)");
199  delete histTitle;
200 
201  // v doubly integrated
202  histTitle = new TString("FlowLYZ_v_Sel");
203  *histTitle += k+1;
204  histFull[k].mHist_v = new TH1F(histTitle->Data(), histTitle->Data(),
205  Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5);
206  histFull[k].mHist_v->SetXTitle("Harmonic");
207  histFull[k].mHist_v->SetYTitle("v (%)");
208  delete histTitle;
209 
210  // for each harmonic
211  for (int j = 0; j < Flow::nHars; j++) {
212  mQ[k][j].Set(0.,0.);
213  mQ2[k][j] = 0.;
214 
215  // Flow
216  histTitle = new TString("FlowProLYZ_vEta_Sel");
217  *histTitle += k+1;
218  *histTitle += "_Har";
219  *histTitle += j+1;
220  histFull[k].histFullHar[j].mHistPro_vEta = new TProfile(histTitle->Data(),
221  histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, -1000., 1000.);
222  histFull[k].histFullHar[j].mHistPro_vEta->SetXTitle((char*)xLabel.Data());
223  histFull[k].histFullHar[j].mHistPro_vEta->SetYTitle("v (%)");
224  delete histTitle;
225 
226  histTitle = new TString("FlowProLYZ_vPt_Sel");
227  *histTitle += k+1;
228  *histTitle += "_Har";
229  *histTitle += j+1;
230  histFull[k].histFullHar[j].mHistPro_vPt = new TProfile(histTitle->Data(),
231  histTitle->Data(), mPtBinsPart, Flow::ptMin, ptMaxPart, -1000., 1000.);
232  histFull[k].histFullHar[j].mHistPro_vPt->SetXTitle("Pt (GeV/c)");
233  histFull[k].histFullHar[j].mHistPro_vPt->SetYTitle("v (%)");
234  delete histTitle;
235 
236  // for each theta
237  for (Int_t Ntheta = 0; Ntheta < Flow::nTheta; Ntheta++) {
238 
239  // Gtheta
240  histTitle = new TString("FlowLYZ_Gtheta");
241  *histTitle += Ntheta;
242  *histTitle += "_Sel";
243  *histTitle += k+1;
244  *histTitle += "_Har";
245  *histTitle += j+1;
246  histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta = new TH1D(histTitle->Data(),
247  histTitle->Data(), Flow::nRBins, rBinArray);
248  histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->SetXTitle("r");
249  histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->SetYTitle("|G^{#theta}(ir)|^{2}");
250  delete histTitle;
251 
252  // Re(Gtheta)
253  histTitle = new TString("FlowReGtheta");
254  *histTitle += Ntheta;
255  *histTitle += "_Sel";
256  *histTitle += k+1;
257  *histTitle += "_Har";
258  *histTitle += j+1;
259  histFull[k].histFullHar[j].histTheta[Ntheta].mHistProReGtheta = new TProfile(histTitle->Data(),
260  histTitle->Data(), Flow::nRBins, rBinArray);
261  histFull[k].histFullHar[j].histTheta[Ntheta].mHistProReGtheta->SetXTitle("r");
262  histFull[k].histFullHar[j].histTheta[Ntheta].mHistProReGtheta->SetYTitle("Re(G^{#theta}(ir))");
263  delete histTitle;
264 
265  // Im(Gtheta)
266  histTitle = new TString("FlowImGtheta");
267  *histTitle += Ntheta;
268  *histTitle += "_Sel";
269  *histTitle += k+1;
270  *histTitle += "_Har";
271  *histTitle += j+1;
272  histFull[k].histFullHar[j].histTheta[Ntheta].mHistProImGtheta = new TProfile(histTitle->Data(),
273  histTitle->Data(), Flow::nRBins, rBinArray);
274  histFull[k].histFullHar[j].histTheta[Ntheta].mHistProImGtheta->SetXTitle("r");
275  histFull[k].histFullHar[j].histTheta[Ntheta].mHistProImGtheta->SetYTitle("Im(G^{#theta}(ir))");
276  delete histTitle;
277 
278  // Re(Numerator) 2D
279  histTitle = new TString("FlowReNumer2D");
280  *histTitle += Ntheta;
281  *histTitle += "_Sel";
282  *histTitle += k+1;
283  *histTitle += "_Har";
284  *histTitle += j+1;
285  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumer2D = new TProfile2D(histTitle->Data(),
286  histTitle->Data(), 2, mEtaMin, mEtaMax, mPtBinsPart, Flow::ptMin, ptMaxPart);
287  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumer2D->SetXTitle((char*)xLabel.Data());
288  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumer2D->SetYTitle("Pt (GeV/c)");
289  delete histTitle;
290 
291  // Re(Numerator)(eta)
292  histTitle = new TString("FlowReNumerEta");
293  *histTitle += Ntheta;
294  *histTitle += "_Sel";
295  *histTitle += k+1;
296  *histTitle += "_Har";
297  *histTitle += j+1;
298  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumerEta = new TProfile(histTitle->Data(),
299  histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax);
300  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumerEta->SetXTitle((char*)xLabel.Data());
301  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumerEta->SetYTitle("v (%)");
302  delete histTitle;
303 
304  // Im(Numerator) 2D
305  histTitle = new TString("FlowImNumer2D");
306  *histTitle += Ntheta;
307  *histTitle += "_Sel";
308  *histTitle += k+1;
309  *histTitle += "_Har";
310  *histTitle += j+1;
311  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumer2D = new TProfile2D(histTitle->Data(),
312  histTitle->Data(), 2, mEtaMin, mEtaMax, mPtBinsPart, Flow::ptMin, ptMaxPart);
313  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumer2D->SetXTitle((char*)xLabel.Data());
314  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumer2D->SetYTitle("Pt (GeV/c)");
315  delete histTitle;
316 
317  // Im(Numerator)(eta)
318  histTitle = new TString("FlowImNumerEta");
319  *histTitle += Ntheta;
320  *histTitle += "_Sel";
321  *histTitle += k+1;
322  *histTitle += "_Har";
323  *histTitle += j+1;
324  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumerEta = new TProfile(histTitle->Data(),
325  histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax);
326  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumerEta->SetXTitle((char*)xLabel.Data());
327  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumerEta->SetYTitle("v (%)");
328  delete histTitle;
329 
330  } // theta
331 
332  // V
333  TString *histTitleVtheta;
334  histTitle = new TString("FlowProLYZ_Vtheta_Sel");
335  *histTitle += k+1;
336  *histTitle += "_Har";
337  *histTitle += j+1;
338  histFull[k].histFullHar[j].mHistPro_Vtheta = new TProfile(histTitle->Data(),
339  histTitle->Data(), Flow::nTheta, -0.5, Flow::nTheta-0.5, -1000., 1000.);
340  histFull[k].histFullHar[j].mHistPro_Vtheta->SetXTitle("#theta");
341  histFull[k].histFullHar[j].mHistPro_Vtheta->SetYTitle("V_{n}^{#theta}");
342  histTitleVtheta = new TString(histTitle->Data());
343  delete histTitle;
344 
345  // Re(Denom)
346  histTitle = new TString("FlowReDenom_Sel");
347  *histTitle += k+1;
348  *histTitle += "_Har";
349  *histTitle += j+1;
350  histFull[k].histFullHar[j].mHistReDenom = new TProfile(histTitle->Data(),
351  histTitle->Data(), Flow::nTheta, -0.5, Flow::nTheta-0.5);
352  histFull[k].histFullHar[j].mHistReDenom->SetXTitle("#theta");
353  histFull[k].histFullHar[j].mHistReDenom->SetYTitle("Re(Q^{#theta}e^{ir_{0}^{#theta}Q^{#theta}})");
354  delete histTitle;
355 
356  // Im(Denom)
357  histTitle = new TString("FlowImDenom_Sel");
358  *histTitle += k+1;
359  *histTitle += "_Har";
360  *histTitle += j+1;
361  histFull[k].histFullHar[j].mHistImDenom = new TProfile(histTitle->Data(),
362  histTitle->Data(), Flow::nTheta, -0.5, Flow::nTheta-0.5);
363  histFull[k].histFullHar[j].mHistImDenom->SetXTitle("#theta");
364  histFull[k].histFullHar[j].mHistImDenom->SetYTitle("Im(Q^{#theta}e^{ir_{0}^{#theta}Q^{#theta}})");
365  delete histTitle;
366 
367  // Recenter
368  histTitle = new TString("FlowCentX_Sel");
369  *histTitle += k+1;
370  *histTitle += "_Har";
371  *histTitle += j+1;
372  histFull[k].histFullHar[j].mHistCentX = new TProfile(histTitle->Data(),
373  histTitle->Data(), 3, 0.5, 3.5);
374  histFull[k].histFullHar[j].mHistCentX->SetXTitle("TPCE, TPCW, TPC");
375  histFull[k].histFullHar[j].mHistCentX->SetYTitle("<cos n #phi>");
376  delete histTitle;
377 
378  histTitle = new TString("FlowCentY_Sel");
379  *histTitle += k+1;
380  *histTitle += "_Har";
381  *histTitle += j+1;
382  histFull[k].histFullHar[j].mHistCentY = new TProfile(histTitle->Data(),
383  histTitle->Data(), 3, 0.5, 3.5);
384  histFull[k].histFullHar[j].mHistCentY->SetXTitle("TPCE, TPCW, TPC");
385  histFull[k].histFullHar[j].mHistCentY->SetYTitle("<sin n #phi>");
386  delete histTitle;
387 
388  histTitle = new TString("FlowQCent_Sel");
389  *histTitle += k+1;
390  *histTitle += "_Har";
391  *histTitle += j+1;
392  histFull[k].histFullHar[j].mHistQCent = new TProfile(histTitle->Data(),
393  histTitle->Data(), 2, 0.5, 2.5);
394  histFull[k].histFullHar[j].mHistQCent->SetXTitle("X, Y");
395  histFull[k].histFullHar[j].mHistQCent->SetYTitle("<Q_{n}/M>");
396  delete histTitle;
397 
398  // r0
399  histTitle = new TString("FlowProLYZ_r0theta_Sel");
400  *histTitle += k+1;
401  *histTitle += "_Har";
402  *histTitle += j+1;
403  histFull[k].histFullHar[j].mHistPro_r0theta = new TProfile(histTitle->Data(),
404  histTitle->Data(), Flow::nTheta, -0.5, Flow::nTheta-0.5, 0., 2.);
405  histFull[k].histFullHar[j].mHistPro_r0theta->SetXTitle("#theta");
406  histFull[k].histFullHar[j].mHistPro_r0theta->SetYTitle("r_{0}^{#theta}");
407  delete histTitle;
408 
409  if (j > 1) continue; // only for first two harmonics
410  TString *histTitleForReadIn;
411  histTitleForReadIn = new TString("FlowLYZ_r0theta_Sel");
412  *histTitle += k+1;
413  *histTitle += "_Har";
414  *histTitle += j+1;
415 
416  // Zero pass for recenter paramerters?
417  TFile fileZeroPass("flow.reCent.root","R");
418  if (fileZeroPass.IsOpen() || !reCentCalc) { // not zero pass
419 
420  // Read the hists from the first pass file
421  TFile fileFirstPass("flow.firstPassLYZ.root","R");
422  if (fileFirstPass.IsOpen()) { // second pass
423  gMessMgr->Info("##### FlowLeeYangZero: Second Pass");
424  //fileFirstPass.ls();
425  TH1D* tempHist =
426  dynamic_cast<TH1D*>(fileFirstPass.Get(histTitleForReadIn->Data()));
427  if (!tempHist) {
428  cout << "##### FlowLeeYangZeros: dynamic cast can't find " <<
429  histTitleForReadIn->Data() << endl;
430  return kFALSE;
431  } else if (tempHist->GetNbinsX() != Flow::nTheta) {
432  cout << "##### FlowLeeYangZeros: nTheta of 1st pass not equal to 2nd pass" <<
433  endl;
434  PR(tempHist->GetNbinsX());
435  PR(Flow::nTheta);
436  return kStFatal;
437  }
438  delete histTitleForReadIn;
439 
440  for (Int_t Ntheta = 0; Ntheta < Flow::nTheta; Ntheta++) {
441  mr0theta[k][j][Ntheta] = tempHist->GetBinContent(Ntheta+1);
442  mr0theta[k][j+2][Ntheta] = tempHist->GetBinContent(Ntheta+1); // for higher harmonics
443  //cout << k << " " << j << " " << Ntheta << " " << mr0theta[k][j][Ntheta] << endl;
444  }
445  fileFirstPass.Close();
446  } else {
447  gMessMgr->Info("##### FlowLeeYangZero: First Pass");
448  mFirstPass = kTRUE;
449  }
450  } else {
451  gMessMgr->Info("##### FlowLeeYangZero: Zero Pass");
452  mZeroPass = kTRUE;
453  }
454  } // j
455  } // k
456 
457  gMessMgr->SetLimit("##### FlowLeeYangZero", 5);
458  gMessMgr->Info("##### FlowLeeYangZero: $Id: StFlowLeeYangZerosMaker.cxx,v 1.8 2018/02/26 23:10:59 smirnovd Exp $");
459 
460  return StMaker::Init();
461 }
462 
463 //-----------------------------------------------------------------------
464 
465 Bool_t StFlowLeeYangZerosMaker::FillFromFlowEvent() {
466  // Get event quantities from StFlowEvent for all particles
467 // timeEvent.start();
468 
469  // multiplicity
470  mMult = (int)pFlowEvent->MultPart(pFlowSelect);
471  mHistMult->Fill((float)mMult);
472 
473  mNEvents++; // increment number of events
474 
475  TVector2 Q, q;
476  Float_t theta, theta1, order, r0;
477  TComplex expo, denom, Gtheta;
478  Double_t Qtheta, cosTheta12, mult;
479  Int_t m;
480 
481  for (int k = 0; k < Flow::nSels; k++) {
482  pFlowSelect->SetSelection(k);
483  for (int j = 0; j < Flow::nHars; j++) {
484  m = 1;
485  pFlowSelect->SetHarmonic(j); // for integrated flow and denominator
486  if (j==2) {
487  m = 3;
488  pFlowSelect->SetHarmonic(0);
489  } else if (j==3) {
490  m = 2;
491  pFlowSelect->SetHarmonic(1);
492  }
493  order = (double)((j+1)/m);
494 
495  if (mZeroPass) {
496  // calculate recentering parameters
497  q = pFlowEvent->ReCentPar(pFlowSelect,"TPCE");
498  histFull[k].histFullHar[j].mHistCentX->Fill(1., q.X());
499  histFull[k].histFullHar[j].mHistCentY->Fill(1., q.Y());
500  q = pFlowEvent->ReCentPar(pFlowSelect,"TPCW");
501  histFull[k].histFullHar[j].mHistCentX->Fill(2., q.X());
502  histFull[k].histFullHar[j].mHistCentY->Fill(2., q.Y());
503  q = pFlowEvent->ReCentPar(pFlowSelect,"TPC");
504  histFull[k].histFullHar[j].mHistCentX->Fill(3., q.X());
505  histFull[k].histFullHar[j].mHistCentY->Fill(3., q.Y());
506 
507  continue;;
508  }
509 
510  // event Q
511  Q = pFlowEvent->QPart(pFlowSelect);
512  if (Q.Mod() == 0.) return kFALSE; // to eliminate Q=0
513  mQ[k][j] += Q; // for chi calculation
514  mQ2[k][j] += Q.Mod2();
515 
516  if (!mZeroPass) {
517  // test recentering of Q per particle
518  mult = (double)(pFlowEvent->MultPart(pFlowSelect));
519  histFull[k].histFullHar[j].mHistQCent->Fill(1., Q.X()/mult);
520  histFull[k].histFullHar[j].mHistQCent->Fill(2., Q.Y()/mult);
521  }
522 
523  // for each theta
524  for (int Ntheta = 0; Ntheta < Flow::nTheta; Ntheta++) {
525  theta = ((float)Ntheta / (float)Flow::nTheta) * TMath::Pi()/order;
526  if (j<=1) {
527  mQtheta[k][j][Ntheta] = pFlowEvent->Qtheta(pFlowSelect, theta);
528  } else {
529  mQtheta[k][j][Ntheta] = mQtheta[k][j-2][Ntheta];
530  }
531  Qtheta = mQtheta[k][j][Ntheta];
532 
533  if (mFirstPass && j<=1) {
534  // G for "integrated v"
535  for (int rBin = 1; rBin < Flow::nRBins; rBin++) {
536  Float_t r = histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->GetBinCenter(rBin);
537  if (!k) { // Sum G
538  expo(0., r * Qtheta);
539  Gtheta = TComplex::Exp(expo); // BP Eq. 6
540  } else if (!mV1Mixed || j) { // Product G, skip for v1 mixed
541  Gtheta = pFlowEvent->Grtheta(pFlowSelect, r, theta); // PG Eq. 3
542  if (Gtheta.Rho2() > 1000.) { break; } // stop when G gets too big
543  }
544  histFull[k].histFullHar[j].histTheta[Ntheta].mHistProReGtheta->Fill(r, Gtheta.Re());
545  histFull[k].histFullHar[j].histTheta[Ntheta].mHistProImGtheta->Fill(r, Gtheta.Im());
546  }
547  } else if (!mFirstPass) {
548  // denominator for differential v, and "integrated" v1 mixed
549  r0 = mr0theta[k][j][Ntheta];
550  if (!k) {
551  expo(0., r0 * Qtheta);
552  denom = Qtheta * TComplex::Exp(expo); // BP Eq. 12
553  } else {
554  mGr0theta[k][j][Ntheta] = pFlowEvent->Grtheta(pFlowSelect, r0, theta);
555  denom = mGr0theta[k][j][Ntheta] *
556  pFlowEvent->Gder_r0theta(pFlowSelect, r0, theta); // PG Eq. 9 & DF Eq. 5
557  }
558  histFull[k].histFullHar[j].mHistReDenom->Fill(Ntheta, denom.Re());
559  histFull[k].histFullHar[j].mHistImDenom->Fill(Ntheta, denom.Im());
560  } // second pass
561  } // theta
562  } // j
563  } // k
564 
565  // for v1 mixed harmonics: neumerator of DF Eq. 7
566  // also stores G for use in DF Eq. 8
567  if (!mFirstPass && mV1Mixed) {
568  for (int Ntheta = 0; Ntheta < Flow::nTheta; Ntheta++) {
569  theta = ((float)Ntheta / (float)Flow::nTheta) * TMath::Pi()/2.; // theta = theta2
570  r0 = mr0theta[1][1][Ntheta]; // selection 2, harmonic 2
571  TComplex theta1Term(0.,0.);
572  for (int Ntheta1 = 0; Ntheta1 < Flow::nTheta1; Ntheta1++) {
573  theta1 = ((float)Ntheta1 / (float)Flow::nTheta1) * 2. * TMath::Pi();
574  cosTheta12 = cos(2.*(theta1 - theta));
575  mGV1r0theta[Ntheta1][Ntheta] = pFlowEvent->GV1r0theta(pFlowSelect, r0, theta1, theta);
576  theta1Term += (cosTheta12 * mGV1r0theta[Ntheta1][Ntheta]);
577  //cout << Ntheta << ", " << Ntheta1 << ": " << cosTheta12 << " * " << mGV1r0theta[Ntheta1][Ntheta] << endl;
578  }
579  mV1neum[Ntheta] += (theta1Term / (double)Flow::nTheta1); // averaged over theta1
580  //cout << Ntheta << " :" << mV1neum[Ntheta] << endl;
581  }
582  }
583 
584 // timeEvent.stop();
585  return kTRUE;
586 }
587 
588 //-----------------------------------------------------------------------
589 
590 void StFlowLeeYangZerosMaker::FillParticleHistograms() {
591  // Fill histograms from the particles on 2nd pass
592 // timePart.start();
593 
594  // Initialize Iterator
595  StFlowTrackCollection* pFlowTracks = pFlowEvent->TrackCollection();
596  StFlowTrackIterator itr;
597 
598  Float_t theta, theta1, phi, eta, pt, m, r0;
599  TVector2 reCent, reCent2, reCent1;
600  Double_t order, wgt, wgt2, cosTerm, reCentTheta, reCentTheta2, reCentTheta1;
601  TComplex expo, numer, cosTermComp;
602  for (itr = pFlowTracks->begin(); itr != pFlowTracks->end(); itr++) {
603  StFlowTrack* pFlowTrack = *itr;
604 
605  phi = pFlowTrack->Phi();
606  if (phi < 0.) phi += twopi;
607  eta = pFlowTrack->Eta();
608  pt = pFlowTrack->Pt();
609 
610  // Yield
611  if (pFlowSelect->SelectPart(pFlowTrack)) {
612  if (mPtRange_for_vEta[1] > mPtRange_for_vEta[0]) { // cut is used
613  if (pt < mPtRange_for_vEta[1] && pt >= mPtRange_for_vEta[0]) { // check cut range
614  mHistYieldPartEta->Fill(eta);
615  }
616  } else { // cut is not used, fill in any case
617  mHistYieldPartEta->Fill(eta);
618  }
619 // if (strlen(pFlowSelect->PidPart()) != 0) { // identified particles not implemented
620 // Float_t rapidity = pFlowTrack->Y();
621 // mHistYieldPartEta->Fill(rapidity);
622 // } else {
623 // mHistYieldPartEta->Fill(eta);
624 // }
625  if (mEtaRange_for_vPt[1] > mEtaRange_for_vPt[0]) { // cut is used
626  if (TMath::Abs(eta) < mEtaRange_for_vPt[1] && TMath::Abs(eta) >= mEtaRange_for_vPt[0]) { // check cut range
627  mHistYieldPartPt->Fill(pt);
628  }
629  } else { // cut is not used, fill in any case
630  mHistYieldPartPt->Fill(pt);
631  }
632  }
633 
634  for (int k = 0; k < Flow::nSels; k++) {
635  pFlowSelect->SetSelection(k);
636  for (int j = 0; j < Flow::nHars; j++) {
637  m = 1.; // float
638  pFlowSelect->SetHarmonic(j);
639  if (j==2) { m = 3.; } // for cos(m*n...)
640  else if (j==3) { m = 2.; }
641  order = (double)(j+1)/m; // for theta calc.
642 
643  // Caculate numerator for all particles selected
644  if (pFlowSelect->SelectPart(pFlowTrack)) {
645  reCent = pFlowEvent->ReCent(k, j, pFlowTrack);
646  for (int Ntheta = 0; Ntheta < Flow::nTheta; Ntheta++) {
647  theta = ((float)Ntheta / (float)Flow::nTheta) * TMath::Pi()/order;
648  reCentTheta = reCent.X() * cos(m*order*theta) + reCent.Y() * sin(m*order*theta);
649  r0 = mr0theta[k][j][Ntheta];
650  if (!k) {
651  expo(0., r0 * mQtheta[k][j][Ntheta]);
652  numer = (cos(m*order*(phi - theta)) - reCentTheta) * TComplex::Exp(expo); // BP Eq. 12
653  } else {
654  wgt = pFlowEvent->Weight(k, j, pFlowTrack);
655  if (!j && mV1Mixed) { // for v1 mixed harmonic differential flow
656  theta = ((float)Ntheta / (float)Flow::nTheta) * TMath::Pi()/2.; // goes only to pi/2
657  r0 = mr0theta[k][1][Ntheta]; // use r0 for 2nd harmonic
658  wgt2 = pFlowEvent->Weight(k, 1, pFlowTrack); // weight for 2nd harmonic
659  reCent2 = pFlowEvent->ReCent(k, 1, pFlowTrack); // for 2nd harmonic
660  reCentTheta2 = reCent2.X() * cos(2.*theta) + reCent2.Y() * sin(2.*theta);
661  double Gim2 = r0 * wgt2 * (cos(2*(phi - theta)) - reCentTheta2);
662  TComplex theta1Term(0.,0.);
663  for (int Ntheta1 = 0; Ntheta1 < Flow::nTheta1; Ntheta1++) { // loop over theta1
664  theta1 = ((float)Ntheta1 / (float)Flow::nTheta1) * 2. * TMath::Pi();
665  reCentTheta1 = reCent.X() * cos(1.*theta1) + reCent.Y() * sin(1.*theta1); // for 1st harmonic
666  double Gim1 = r0 * Flow::epsV1 * wgt * (cos(phi - theta1) - reCentTheta1);
667  TComplex Gr0denom(1., Gim1+Gim2);
668  TComplex Gr0neum(0., r0 * Flow::epsV1 * (cos(phi - theta1)) - reCentTheta1);
669  TComplex Gder_r0theta = mGV1r0theta[Ntheta1][Ntheta] * Gr0neum / Gr0denom; // DF Eq. 8
670  Double_t cosTheta12 = cos(2.*(theta1 - theta));
671  theta1Term += (cosTheta12 * Gder_r0theta);
672  }
673  numer = theta1Term / (double)Flow::nTheta1; // DF Eq. 9 neumerator averaged over theta1
674  } else if (j==2 && mV1Mixed) { // 3rd harmonic not defined for mixed
675  numer = 0.;
676  } else {
677  cosTerm = cos(m*order*(phi - theta)) - reCentTheta;
678  cosTermComp(1., r0*cosTerm);
679  numer = mGr0theta[k][j][Ntheta] * cosTerm / cosTermComp; // PG Eq. 9
680  }
681  }
682 
683  if (mPtRange_for_vEta[1] > mPtRange_for_vEta[0]) { // cut is used
684  if (pt < mPtRange_for_vEta[1] && pt >= mPtRange_for_vEta[0]) { // check cut range
685  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumerEta->Fill(eta, numer.Re());
686  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumerEta->Fill(eta, numer.Im());
687  }
688  }
689  else { // cut is not used, fill in any case
690  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumerEta->Fill(eta, numer.Re());
691  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumerEta->Fill(eta, numer.Im());
692  }
693 
694  if (mEtaRange_for_vPt[1] > mEtaRange_for_vPt[0]) { // cut is used
695  if (TMath::Abs(eta) < mEtaRange_for_vPt[1] && TMath::Abs(eta) >= mEtaRange_for_vPt[0]) { // check cut range
696  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumer2D->Fill(eta, pt, numer.Re());
697  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumer2D->Fill(eta, pt, numer.Im());
698  }
699  }
700  else { // cut is not used, fill in any case
701  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumer2D->Fill(eta, pt, numer.Re());
702  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumer2D->Fill(eta, pt, numer.Im());
703  }
704 
705  } // theta
706  } // select
707  } // j
708  } // k
709  } // track
710 
711 // timePart.stop();
712 }
713 
714 //-----------------------------------------------------------------------
715 
717  // In the zero pass write out the recentering parameters
718  // In the first pass, from Gtheta find the first minimum to get r0(theta) and write it out.
719  // In the second pass calculate V(theta), average over theta, and then calculate v
720 // timeFinish.start();
721 
722  TOrdCollection* savedHistNames = new TOrdCollection(Flow::nSels * Flow::nHars);
723  TOrdCollection* savedHistFirstPassNames = new TOrdCollection(Flow::nSels * Flow::nTheta * 3);
724  TOrdCollection* savedHistZeroPassNames = new TOrdCollection(Flow::nSels * Flow::nHars * 2);
725  TString* histTitle;
726 
727  cout << endl << "##### LeeYangZeros Maker:" << endl;
728 
729  Float_t reCentX, reCentY;
730  if (mFirstPass) { cout << "Test of recentering of Q vector per particle:" << endl; }
731  for (int k = 0; k < Flow::nSels; k++) {
732  for (int j = 0; j < Flow::nHars; j++) {
733  if (mZeroPass) {
734  reCentX = histFull[k].histFullHar[j].mHistCentX->GetBinContent(3);
735  reCentY = histFull[k].histFullHar[j].mHistCentY->GetBinContent(3);
736  cout << setprecision(3) << "Sel = " << k+1 << ", Har = " << j+1 << " : reCent_x = " << reCentX
737  << ", reCent_y = " << reCentY << endl;
738  reCentX = histFull[k].histFullHar[j].mHistCentX->GetBinContent(1);
739  reCentY = histFull[k].histFullHar[j].mHistCentY->GetBinContent(1);
740  cout << setprecision(3) << "Sel = " << k+1 << ", Har = " << j+1 << " : reCentE_x = " << reCentX
741  << ", reCentE_y = " << reCentY << endl;
742  reCentX = histFull[k].histFullHar[j].mHistCentX->GetBinContent(2);
743  reCentY = histFull[k].histFullHar[j].mHistCentY->GetBinContent(2);
744  cout << setprecision(3) << "Sel = " << k+1 << ", Har = " << j+1 << " : reCentW_x = " << reCentX
745  << ", reCentW_y = " << reCentY << endl;
746  savedHistZeroPassNames->AddLast(histFull[k].histFullHar[j].mHistCentX);
747  savedHistZeroPassNames->AddLast(histFull[k].histFullHar[j].mHistCentY);
748  } else if (mFirstPass) {
749  reCentX = histFull[k].histFullHar[j].mHistQCent->GetBinContent(1);
750  reCentY = histFull[k].histFullHar[j].mHistQCent->GetBinContent(2);
751  cout << setprecision(3) << "Sel = " << k+1 << ", Har = " << j+1 << " : reCentedQ_x = " << reCentX
752  << ", reCentedQ_y = " << reCentY << endl;
753  savedHistFirstPassNames->AddLast(histFull[k].histFullHar[j].mHistQCent);
754  } else {
755  savedHistNames->AddLast(histFull[k].histFullHar[j].mHistQCent);
756  }
757  }
758  }
759  cout << endl;
760  if (mZeroPass) {
761  TFile fileZeroPass("flow.reCent.root", "RECREATE");
762  fileZeroPass.cd();
763  savedHistZeroPassNames->Write();
764  fileZeroPass.Close();
765  delete savedHistZeroPassNames;
766  delete pFlowSelect;
767 
768  return StMaker::Finish();
769  }
770 
771  cout << "integrated flow: (errors just show variation with theta)" << endl;
772 
773  Float_t reG, imG, reNumer, imNumer, reDenom, imDenom, reDiv;
774  TComplex Gtheta, denom, numer, div;
775  TComplex i = TComplex::I();
776  Float_t mult = mHistMult->GetMean();
777  Float_t _v, vErr, Vtheta, V, V1SqTheta, V1Sq, yield, eta, pt;
778  Double_t r0, yieldSum, vSum, err2Sum, Glast, G0, Gnext, GnextNext, v1DiffConst;
779  Float_t Xlast, X0, Xnext, sigma2, chi;
780  Float_t BesselRatio[3] = {1., 1.202, 2.69}; // is 2.69 correct?
781  Int_t m, v2Sign;
782  Bool_t etaPtNoCut;
783  Double_t T, B, F;
784  if (!mFirstPass) {
785  Int_t etaBins = mHistYieldPartEta->GetNbinsX();
786  T = mHistYieldPartEta->Integral(0, etaBins+1);
787  B = mHistYieldPartEta->Integral(0, etaBins/2);
788  F = mHistYieldPartEta->Integral(etaBins/2+1, etaBins+1);
789  //cout << "bins= " << etaBins << ", B= " << B << ", F= " << F << ", T= " << T << endl;
790  }
791 
792  int rBins = Flow::nRBins;
793  for (int k = 0; k < Flow::nSels; k++) {
794  for (int j = 0; j < Flow::nHars; j++) {
795  bool oddHar = (j+1) % 2;
796  m = 1; // int for index of BesselRatio and i^^(m-1)
797  if (j==2) { m = 3; }
798  else if (j==3) { m = 2; }
799  if (mFirstPass && j<=1) {
800  for (int Ntheta = 0; Ntheta < Flow::nTheta; Ntheta++) {
801  for (int rBin = 1; rBin <= rBins; rBin++) {
802 
803  // "Integrated flow"
804  // G, the generating function, as a function of r for each theta
805  reG = histFull[k].histFullHar[j].histTheta[Ntheta].mHistProReGtheta->GetBinContent(rBin);
806  imG = histFull[k].histFullHar[j].histTheta[Ntheta].mHistProImGtheta->GetBinContent(rBin);
807  Gtheta(reG, imG); // BP Eqs. 6 & A1
808  histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->SetBinContent(rBin, Gtheta.Rho2());
809  } // rBin
810  // Find first minimum of the square of the modulus of G for each theta
811  r0 = histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->GetXaxis()->
812  GetBinCenter(rBins); // default value if no minimum
813  for (int N = 2; N < rBins-1; N++) {
814  G0 = histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->GetBinContent(N);
815  Gnext = histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->GetBinContent(N+1);
816  GnextNext = histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->GetBinContent(N+2);
817 
818  if (Gnext > G0 && GnextNext > G0) { // next two points are higher (footnote 3)
819  Glast = histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->GetBinContent(N-1);
820  Xlast = histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->GetBinCenter(N-1);
821  X0 = histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->GetBinCenter(N);
822  Xnext = histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta->GetBinCenter(N+1);
823  if (X0 < 0.005) break; // treat like no minimum
824  r0 = X0;
825  r0 -= ((X0 - Xlast)*(X0 - Xlast)*(G0 - Gnext) - (X0 - Xnext)*(X0 - Xnext)*(G0 - Glast)) /
826  (2.*((X0 - Xlast)*(G0 - Gnext) - (X0 - Xnext)*(G0 - Glast))); // intopolated minimum
827  // from "Numerical Recepes in C", p. 402.
828  break;
829  } // if
830  } // N
831  histFull[k].histFullHar[j].mHistPro_r0theta->Fill(Ntheta, r0); // for first pass output
832  Vtheta = Flow::j01 / r0; // BP Eq. 9
833  histFull[k].histFullHar[j].mHistPro_Vtheta->Fill(Ntheta, Vtheta);
834  _v = (m==1) ? Vtheta / mult : 0.; // BP Eq. 5, v from r0 for each theta
835  histFull[k].mHistPro_vr0->Fill(j+1, _v/perCent);
836 
837  savedHistFirstPassNames->AddLast(histFull[k].histFullHar[j].histTheta[Ntheta].mHistGtheta);
838 
839  // Project the profile hists to 1D hists
840 
841  histTitle = new TString("FlowReGtheta");
842  *histTitle += Ntheta;
843  *histTitle += "_Sel";
844  *histTitle += k+1;
845  *histTitle += "_Har";
846  *histTitle += j+1;
847  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReGtheta =
848  histFull[k].histFullHar[j].histTheta[Ntheta].mHistProReGtheta->ProjectionX(histTitle->Data());
849  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReGtheta->SetTitle(histTitle->Data());
850  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReGtheta->SetXTitle("r");
851  histFull[k].histFullHar[j].histTheta[Ntheta].mHistReGtheta->SetYTitle("Re(G^{#theta}(ir))");
852  delete histTitle;
853  savedHistFirstPassNames->AddLast(histFull[k].histFullHar[j].histTheta[Ntheta].mHistReGtheta);
854 
855  histTitle = new TString("FlowImGtheta");
856  *histTitle += Ntheta;
857  *histTitle += "_Sel";
858  *histTitle += k+1;
859  *histTitle += "_Har";
860  *histTitle += j+1;
861  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImGtheta =
862  histFull[k].histFullHar[j].histTheta[Ntheta].mHistProImGtheta->ProjectionX(histTitle->Data());
863  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImGtheta->SetTitle(histTitle->Data());
864  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImGtheta->SetXTitle("r");
865  histFull[k].histFullHar[j].histTheta[Ntheta].mHistImGtheta->SetYTitle("Im(G^{#theta}(ir))");
866  delete histTitle;
867  savedHistFirstPassNames->AddLast(histFull[k].histFullHar[j].histTheta[Ntheta].mHistImGtheta);
868 
869  } // Ntheta
870 
871  } else if (!mFirstPass) { // second pass
872 
873  V1Sq = 0.;
874  for (int Ntheta = 0; Ntheta < Flow::nTheta; Ntheta++) {
875 
876  if (k && !j && mV1Mixed) { // v1 "integrated" from mixed harmonics: selection 2, harmonic 1
877  mV1neum[Ntheta] /= mNEvents; // averaged over events
878  //PR(mV1neum[Ntheta]);
879  r0 = mr0theta[1][1][Ntheta]; // selection 2, harmonic 2
880  reDenom = histFull[k].histFullHar[1].mHistReDenom->GetBinContent(Ntheta+1);
881  imDenom = histFull[k].histFullHar[1].mHistImDenom->GetBinContent(Ntheta+1);
882  denom(reDenom,imDenom); // selection 2, harmonic 2
883  div = mV1neum[Ntheta] / denom;
884  reDiv = div.Re();
885  V1SqTheta = -8. * Flow::j01 / (Flow::epsV1*Flow::epsV1) / TMath::Power(r0,3.) * reDiv; // DF Eq. 7 for each theta2
886  V1Sq += V1SqTheta;
887  if (!std::isnan(V1SqTheta) && V1SqTheta != 0.) {
888  Vtheta = TMath::Sqrt(fabs(V1SqTheta)); // absolute values of negatives
889  }
890  } else {
891  Vtheta = Flow::j01 / mr0theta[k][j][Ntheta]; // BP Eq. 9
892  }
893  histFull[k].mHistPro_V->Fill(j+1, Vtheta);
894  _v = (m==1) ? Vtheta / mult : 0.; // BP Eq. 5, v from r0 for each theta
895  histFull[k].mHistPro_vr0->Fill(j+1, _v/perCent); // gives error for vr0
896 
897  } // Ntheta
898 
899  if (k && !j && mV1Mixed) { // v1 from mixed harmonics: selection 2, harmonic 1
900  V1Sq /= Flow::nTheta;
901  v2Sign = (int)(V1Sq / fabs(V1Sq));
902  cout << "The sign of v2 is " << v2Sign << endl;
903  //float Vhist = histFull[k].mHistPro_V->GetBinContent(j+1);
904  V = TMath::Sqrt(fabs(V1Sq));
905  //cout << "pro hist, V1Sq: " << Vhist << ", " << V << endl;
906  v1DiffConst = -4. * Flow::j01 * (double)v2Sign / V / (Flow::epsV1*Flow::epsV1) /
907  TMath::Power(r0,3.);
908  }
909 
910  // Differential flow
911 
912  for (int Ntheta = 0; Ntheta < Flow::nTheta; Ntheta++) {
913 
914  if (k && !j && mV1Mixed) { // v1 mixed harmonics, use denom for 2nd harmonic
915  reDenom = histFull[k].histFullHar[1].mHistReDenom->GetBinContent(Ntheta+1);
916  imDenom = histFull[k].histFullHar[1].mHistImDenom->GetBinContent(Ntheta+1);
917  denom(reDenom,imDenom);
918  } else {
919  reDenom = histFull[k].histFullHar[j].mHistReDenom->GetBinContent(Ntheta+1);
920  imDenom = histFull[k].histFullHar[j].mHistImDenom->GetBinContent(Ntheta+1);
921  denom(reDenom,imDenom);
922  denom *= TComplex::Power(i, m-1);
923  Vtheta = Flow::j01 / mr0theta[k][j][Ntheta]; // BP Eq. 9
924  }
925 
926  // v(eta)
927  int etaMax = histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumerEta->GetNbinsX();
928  for (int binEta = 1; binEta <= etaMax; binEta++) {
929  eta = histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumerEta->GetXaxis()->
930  GetBinCenter(binEta);
931 
932  reNumer = histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumerEta->
933  GetBinContent(binEta);
934  imNumer = histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumerEta->
935  GetBinContent(binEta);
936  numer(reNumer,imNumer);
937 
938  reDiv = (numer / denom).Re();
939  if (!std::isnan(reDiv) && reDiv != 0.) {
940  if (k && !j && mV1Mixed) { // v1 from mixed harmonics: selection 2, harmonic 1
941  _v = v1DiffConst * reDiv /perCent; // DF Eq. 9
942  } else {
943  _v = BesselRatio[m-1] * reDiv * Vtheta /perCent; // BP Eq. 12
944  }
945  histFull[k].histFullHar[j].mHistPro_vEta->Fill(eta, _v);
946  //cout << k << " " << j << " " << Ntheta << " " << binEta << " " << eta << " " << _v << endl;
947  }
948  }
949 
950  // v(pt)
951  Float_t v[2];
952  int etaMax2D = histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumer2D->
953  GetNbinsX(); // 2
954  for (int binPt = 1; binPt <= mPtBinsPart; binPt++) {
955  pt = histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumer2D->GetYaxis()->
956  GetBinCenter(binPt);
957  for (int binEta = 1; binEta <= etaMax2D; binEta++) {
958  eta = histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumer2D->GetXaxis()->
959  GetBinCenter(binEta);
960 
961  reNumer = histFull[k].histFullHar[j].histTheta[Ntheta].mHistReNumer2D->
962  GetBinContent(binEta, binPt);
963  imNumer = histFull[k].histFullHar[j].histTheta[Ntheta].mHistImNumer2D->
964  GetBinContent(binEta, binPt);
965  numer(reNumer,imNumer);
966 
967  reDiv = (numer / denom).Re();
968  if (k && !j && mV1Mixed) { // v1 from mixed harmonics: selection 2, harmonic 1
969  v[binEta-1] = v1DiffConst * reDiv /perCent; // DF Eq. 9
970  } else {
971  v[binEta-1] = BesselRatio[m-1] * reDiv * Vtheta /perCent; // BP Eq. 12
972  }
973  }
974  if (!std::isnan(reDiv) && reDiv != 0.) {
975  if (oddHar) {
976  _v = (F * v[1] - B * v[0]) / T; // weighted forward minus back
977  } else {
978  _v = (B * v[0] + F * v[1]) / T; // weighted mean of forward and back
979  }
980  histFull[k].histFullHar[j].mHistPro_vPt->Fill(pt, _v);
981  }
982  }
983 
984  } // Ntheta
985 
986  } // second pass
987 
988  if (j <=1) {
989  // sigma2 and chi
990  mQ[k][j] /= (float)mNEvents;
991  mQ2[k][j] /= (float)mNEvents;
992 
993  V = histFull[k].mHistPro_V->GetBinContent(j+1);
994  sigma2 = mQ2[k][j] - TMath::Power(mQ[k][j].X(), 2.) - TMath::Power(mQ[k][j].Y(), 2.)
995  - TMath::Power(V, 2.); // BP Eq. 62
996  //cout << mQ2[k][j] << ", " << mQ[k][j].X() << ", " << mQ[k][j].Y() << ", " << V << endl;
997  chi = V / TMath::Sqrt(sigma2); // BP Eq. 59
998 
999  // output v from r0, and chi
1000  _v = histFull[k].mHistPro_vr0->GetBinContent(j+1);
1001  vErr = histFull[k].mHistPro_vr0->GetBinError(j+1); // from the spread with theta
1002  if (k && !j && mV1Mixed) {
1003  if (!mFirstPass) {
1004  cout << setprecision(3) << "Sel = " << k+1 << ": v" << j+1 << " from r0 = (" << _v <<
1005  " +/- " << vErr << ") %"<< " from mixed harmonics" << endl;
1006  }
1007  } else if (mFirstPass) {
1008  cout << setprecision(3) << "Sel = " << k+1 << ": v" << j+1 << " from r0 = (" << _v <<
1009  " +/- " << vErr << ") %" << endl;
1010  } else {
1011  cout << setprecision(3) << "Sel = " << k+1 << ": v" << j+1 << " from r0 = (" << _v <<
1012  " +/- " << vErr << ") % chiJYO = " << chi << endl;
1013  }
1014  }
1015 
1016  // Project the profile hists to 1D hists
1017 
1018  if (mFirstPass && j<=1) {
1019 
1020  histTitle = new TString("FlowLYZ_r0theta_Sel");
1021  *histTitle += k+1;
1022  *histTitle += "_Har";
1023  *histTitle += j+1;
1024  histFull[k].histFullHar[j].mHist_r0theta =
1025  histFull[k].histFullHar[j].mHistPro_r0theta->ProjectionX(histTitle->Data());
1026  histFull[k].histFullHar[j].mHist_r0theta->SetTitle(histTitle->Data());
1027  histFull[k].histFullHar[j].mHist_r0theta->SetXTitle("#theta");
1028  histFull[k].histFullHar[j].mHist_r0theta->SetYTitle("r_{0}^{#theta}");
1029  delete histTitle;
1030  savedHistFirstPassNames->AddLast(histFull[k].histFullHar[j].mHist_r0theta);
1031 
1032  histTitle = new TString("FlowLYZ_Vtheta_Sel");
1033  *histTitle += k+1;
1034  *histTitle += "_Har";
1035  *histTitle += j+1;
1036  histFull[k].histFullHar[j].mHist_Vtheta =
1037  histFull[k].histFullHar[j].mHistPro_Vtheta->ProjectionX(histTitle->Data());
1038  histFull[k].histFullHar[j].mHist_Vtheta->SetTitle(histTitle->Data());
1039  histFull[k].histFullHar[j].mHist_Vtheta->SetXTitle("#theta");
1040  histFull[k].histFullHar[j].mHist_Vtheta->SetYTitle("V_{n}^{#theta}");
1041  delete histTitle;
1042  savedHistFirstPassNames->AddLast(histFull[k].histFullHar[j].mHist_Vtheta);
1043 
1044  } else if (!mFirstPass) { // second pass
1045 
1046  histTitle = new TString("FlowLYZ_vEta_Sel");
1047  *histTitle += k+1;
1048  *histTitle += "_Har";
1049  *histTitle += j+1;
1050  histFull[k].histFullHar[j].mHist_vEta =
1051  histFull[k].histFullHar[j].mHistPro_vEta->ProjectionX(histTitle->Data());
1052  histFull[k].histFullHar[j].mHist_vEta->SetTitle(histTitle->Data());
1053  histFull[k].histFullHar[j].mHist_vEta->SetXTitle((char*)xLabel.Data());
1054  histFull[k].histFullHar[j].mHist_vEta->SetYTitle("v (%)");
1055  delete histTitle;
1056  savedHistNames->AddLast(histFull[k].histFullHar[j].mHist_vEta);
1057 
1058  histTitle = new TString("FlowLYZ_vPt_Sel");
1059  *histTitle += k+1;
1060  *histTitle += "_Har";
1061  *histTitle += j+1;
1062  histFull[k].histFullHar[j].mHist_vPt =
1063  histFull[k].histFullHar[j].mHistPro_vPt->ProjectionX(histTitle->Data());
1064  histFull[k].histFullHar[j].mHist_vPt->SetTitle(histTitle->Data());
1065  histFull[k].histFullHar[j].mHist_vPt->SetXTitle("Pt (GeV/c)");
1066  histFull[k].histFullHar[j].mHist_vPt->SetYTitle("v (%)");
1067  delete histTitle;
1068  savedHistNames->AddLast(histFull[k].histFullHar[j].mHist_vPt);
1069 
1070  // Doubly integrated v with cuts
1071 
1072  // from v(eta)
1073  yieldSum = 0.;
1074  vSum = 0.;
1075  err2Sum = 0.;
1076  for (int bin=1; bin<=mNEtaBins; bin++) {
1077  etaPtNoCut = kTRUE;
1078  eta = histFull[k].histFullHar[j].mHistPro_vEta->GetBinCenter(bin);
1079  if (mEtaRange_for_vPt[1] > mEtaRange_for_vPt[0] &&
1080  (TMath::Abs(eta) < mEtaRange_for_vPt[0] ||
1081  TMath::Abs(eta) >= mEtaRange_for_vPt[1])) {
1082  etaPtNoCut = kFALSE;
1083  }
1084  _v = histFull[k].histFullHar[j].mHistPro_vEta->GetBinContent(bin);
1085  if (_v != 0. && etaPtNoCut) {
1086  yield = mHistYieldPartEta->GetBinContent(bin);
1087  yieldSum += yield;
1088  if (oddHar && eta < 0.) { _v *= -1.; }
1089  vSum += yield * _v;
1090  vErr = histFull[k].histFullHar[j].mHistPro_vEta->GetBinError(bin);
1091  err2Sum += yield*vErr * yield*vErr;
1092  }
1093  }
1094  if (yieldSum) {
1095  _v = vSum / yieldSum;
1096  vErr = TMath::Sqrt(err2Sum) / yieldSum;
1097  cout << setprecision(3) << "Sel = " << k+1 << ": v" << j+1 << " from eta= (" << _v <<
1098  " +/- " << vErr << ") %" << endl;
1099  }
1100 
1101  // from v(pt)
1102  yieldSum = 0.;
1103  vSum = 0.;
1104  err2Sum = 0.;
1105  for (int bin=1; bin<=mPtBinsPart; bin++) {
1106  etaPtNoCut = kTRUE;
1107  pt = histFull[k].histFullHar[j].mHistPro_vPt->GetBinCenter(bin);
1108  if (mPtRange_for_vEta[1] > mPtRange_for_vEta[0] &&
1109  (pt < mPtRange_for_vEta[0] || pt >= mPtRange_for_vEta[1])) {
1110  etaPtNoCut = kFALSE;
1111  }
1112  _v = histFull[k].histFullHar[j].mHistPro_vPt->GetBinContent(bin);
1113  if (_v != 0. && etaPtNoCut) {
1114  yield = mHistYieldPartPt->GetBinContent(bin);
1115  yieldSum += yield;
1116  vSum += yield * _v;
1117  vErr = histFull[k].histFullHar[j].mHistPro_vPt->GetBinError(bin);
1118  err2Sum += yield*vErr * yield*vErr;
1119  }
1120  }
1121  if (yieldSum) {
1122  _v = vSum / yieldSum;
1123  vErr = TMath::Sqrt(err2Sum) / yieldSum;
1124  histFull[k].mHist_v->SetBinContent(j+1, _v);
1125  histFull[k].mHist_v->SetBinError(j+1, vErr);
1126  cout << setprecision(3) << "Sel = " << k+1 << ": v" << j+1 << " from pt = (" << _v <<
1127  " +/- " << vErr << ") %" << endl;
1128  }
1129 
1130  } // second pass
1131 
1132  } // j
1133 
1134  histTitle = new TString("FlowLYZ_vr0_Sel");
1135  *histTitle += k+1;
1136  histFull[k].mHist_vr0 =
1137  histFull[k].mHistPro_vr0->ProjectionX(histTitle->Data());
1138  histFull[k].mHist_vr0->SetTitle(histTitle->Data());
1139  histFull[k].mHist_vr0->SetXTitle("Harmonic");
1140  histFull[k].mHist_vr0->SetYTitle("v from r_{0} (%)");
1141  delete histTitle;
1142  savedHistFirstPassNames->AddLast(histFull[k].mHist_vr0);
1143  savedHistNames->AddLast(histFull[k].mHist_vr0);
1144 
1145  if (!mFirstPass) {
1146  // Project the profile hists to 1D hists
1147 
1148  histTitle = new TString("FlowLYZ_V_Sel");
1149  *histTitle += k+1;
1150  histFull[k].mHist_V =
1151  histFull[k].mHistPro_V->ProjectionX(histTitle->Data());
1152  histFull[k].mHist_V->SetTitle(histTitle->Data());
1153  histFull[k].mHist_V->SetXTitle("Harmonic");
1154  histFull[k].mHist_V->SetYTitle("mean V_{n}");
1155  delete histTitle;
1156  savedHistNames->AddLast(histFull[k].mHist_V);
1157 
1158  savedHistNames->AddLast(histFull[k].mHist_v);
1159  }
1160 
1161  } // k
1162 
1163  // Write histograms
1164  // first and second pass outputs are combined in doFlowEvents.C
1165  TFile fileFirstPassNew("flow.firstPassLYZNew.root", "RECREATE");
1166  TFile histFile("flow.LeeYangZeros.root", "RECREATE");
1167  if (mFirstPass) {
1168  savedHistFirstPassNames->AddLast(mHistMult);
1169  fileFirstPassNew.cd();
1170  savedHistFirstPassNames->Write();
1171  histFile.cd();
1172  savedHistFirstPassNames->Write();
1173  } else {
1174  histFile.cd();
1175  savedHistNames->AddLast(mHistMult);
1176  savedHistNames->AddLast(mHistYieldPartPt);
1177  savedHistNames->AddLast(mHistYieldPartEta);
1178  savedHistNames->Write();
1179  }
1180  fileFirstPassNew.Close(); // on second pass it is empty
1181  histFile.Close();
1182 
1183  delete savedHistNames;
1184  delete savedHistFirstPassNames;
1185  delete pFlowSelect;
1186 
1187 // timeFinish.stop();
1188 // cout << endl << "###### time Event = " << timeEvent.elapsedTime() << " sec" << endl;
1189 // cout << "###### time Part = " << timePart.elapsedTime() << " sec" << endl;
1190 // cout << "###### time Finish = " << timeFinish.elapsedTime() << " sec" << endl;
1191 
1192  return StMaker::Finish();
1193 }
1194 
1195 //-----------------------------------------------------------------------
1196 
1197 void StFlowLeeYangZerosMaker::SetHistoRanges(Bool_t ftpc_included) {
1198 
1199  if (ftpc_included) {
1200  mEtaMin = Flow::etaMin;
1201  mEtaMax = Flow::etaMax;
1202  mNEtaBins = Flow::nEtaBins;
1203  }
1204  else {
1205  mEtaMin = Flow::etaMinTpcOnly;
1206  mEtaMax = Flow::etaMaxTpcOnly;
1207  mNEtaBins = Flow::nEtaBinsTpcOnly;
1208  }
1209 
1210  return;
1211 }
1212 
1213 //------------------------------------------------------------------------
1214 
1215 inline void StFlowLeeYangZerosMaker::SetPtRange_for_vEta(Float_t lo, Float_t hi) {
1216 
1217  // Sets the pt range for the v(eta) histograms.
1218 
1219  mPtRange_for_vEta[0] = lo;
1220  mPtRange_for_vEta[1] = hi;
1221 
1222  return;
1223 }
1224 
1225 //------------------------------------------------------------------------
1226 
1227 inline void StFlowLeeYangZerosMaker::SetEtaRange_for_vPt(Float_t lo, Float_t hi) {
1228 
1229  // Sets the |eta| range for the v(pt) histograms.
1230 
1231  mEtaRange_for_vPt[0] = lo;
1232  mEtaRange_for_vPt[1] = hi;
1233 
1234  return;
1235 }
1236 
1237 //------------------------------------------------------------------------
virtual ~StFlowLeeYangZerosMaker()
Destructor.
StFlowLeeYangZerosMaker(const Char_t *name="FlowLeeYangZeros")
Default constructor.
Definition: Stypes.h:40
virtual Int_t Finish()
Definition: StMaker.cxx:776