15 #include "TGraphErrors.h"
17 #include "TPolyLine.h"
21 #include "TObjArray.h"
26 #include "TFitResult.h"
27 #include "TStopwatch.h"
28 #include "TProfile2D.h"
34 // Plot utilities class - loaded by rootlogon.C + .rootrc
37 const char* inputFileName = ""; // Assign in macro
38 const char* cfDef = "cA"; // s, m, cA or cB. Only for phi projections.
39 double minRidgeDEta = 0.8;
40 double maxRidgeDEta = 1.799;
41 const int gNMax = 12; // Global const -- largest n in VnDelta
43 // Don't do global fit to points outside these pt bin
44 // indices. Globally scoped for availability in vntvna(). Reassigned
45 // within individual functions.
46 double minFitPtBin = 0, maxFitPtBin = 999;
49 //============================================================
50 bool usePtBinCenter = 1;
54 //============================================================
55 void SetProtonProtonFlag(int val) { ispp = val; }
56 void SetMinRidgeDEta(int val) { minRidgeDEta = val; }
57 bool IsProtonProton() { return ispp; }
58 void SetCFDef(char* def) { cfDef = def; }
59 void SaveGraphs(const char* outputFileName, TString opt = "");
60 TF1* DoGlobalFit(int n, int k, int includedPtBin1 = 0, int includedPtBin2 = 999,
61 const char* region = "RIDGE", const char* cfDef = "cA", TString opt = "");
62 void VnDelta(int n, const TH1 &h, double &vnd, double &vnd_err, TString opt="");
63 void VnDelta(int n, const TF1 &f, double &vnd, double &vnd_err, TString opt="");
64 void MakeVnDVsQGraphs(int n1, int n2, int k, const char* region, const char* corrtype, TString opt="");
65 TF1* Harmonic(TH1* h, int n, TString opt);
66 TF1* HarmonicSum(TH1* h, int n1, int n2, TString opt="");
67 TH1* Hist(const char* region, const char* type, int i, int j, int k, TString opt="");
68 TH2* EtaPhiHist(int cent, int ptt, int pta);
70 TH2F* Agreement2DHist(int k, int n);
71 void ijkFromHistName(TH1* h, int& i, int& j, int& k);
73 TGraphErrors* VnDeltaVsN(int i, int j, int k, int nMax, TString opt);
74 TGraphErrors* VnDeltaNFVsN(int i, int j, int k, int nMax, TString opt);
75 TGraphErrors* GlobalvnVsN(int i, int k, int nMax, TString opt);
76 TGraphErrors* VnDeltaVsPtAssoc(int i, int k, int n, TString opt="");
77 TGraphErrors* VnDeltaVsPtTrig(int j, int k, int n, TString opt="");
78 TGraphErrors* AgreementVsPtSum(int k, int n);
79 TGraphErrors* VnDVsQ(int n, int k, const char* region = "RIDGE", const char* cfDef = "cA", TString opt="");
80 TGraphErrors* GlobalFitVsPtAssoc(int i, int k, int n, TString opt=""); // v_n(ptt)v_n(pta) vs. assoc pt
81 TGraphErrors* vnGFvsPt(int n, int k, int ipt1, int ipt2,
82 const char* region = "RIDGE",
83 const char* corrtype = "cA", TString opt = "");
84 TF1* GlobalFitVsQ(int n, int k, int ipt1=0, int ipt2=999, const char* region="RIDGE",
85 const char* corrtype="cA", TString opt=""); // The real fit function
86 //TF1* GlobalFitVsQSubset(int n, int k, int i, TString opt = "");
87 TGraph* Luzumv1(int cent, const char* pid);
88 double MomCorrection(int i, int j, int k);
90 // Global fit function - give to TF1 constructor
91 double vntvna(double *x, double *par);
92 double Chi2(TH1* h, TF1* f, TString opt = ""); // "", "ndf" or "prob"
93 double ReducedChi2(int i, int k, int n);
94 double SineError(int i, int j, int k); // RMS of <sin n D phi> vs. n about zero
95 double vnGF(int n, int k, int ptBin, int includedPtBin1 = 0, int includedPtBin2 = 999,
96 const char* region = "RIDGE", const char* cfDef = "cA", TString opt = "");
98 // Show +/- solutions in chi2 space by varying one fixed parameter (par)
99 TCanvas* FitStudy(int icent, int n, int par);
100 TCanvas* DrawQ(int k, int n, TString opt = "");
101 TCanvas* SingleDraw(int cent, int ptt, int pta, TString opt="");
102 TCanvas* SingleDrawEta(int cent, int ptt, int pta, TString opt);
103 TCanvas* SingleDrawPlain(int cent, int ptt, int pta, TString opt);
104 TCanvas* DrawVnVsPtTrig(int k, int npta, int ptabins[], TString opt = "");
105 TCanvas* SingleDraw2D(int cent, int ptt, int pta, TString opt="");
106 TCanvas* MultiDraw(int cent, TString opt);
107 TCanvas* DrawVnFromGlobalFit(int n, int ipt1=0, int ipt2=999, int ncb = 999,
108 int centbins[] = 0, TString opt=""); // little v_n
109 TCanvas* TwoPanelVert(double ydiv, const char* canvName, const char* canvTitle);
110 TCanvas* DrawChi2vsPtTrig(int npta, int ptabins[], int ncb, int centbins[], TString opt);
111 TCanvas* DrawAgreement(int icent, TString opt = "");
112 TCanvas* Drawv1to5(int ncb, int centbins[], int ipt1=0, int ipt2=999, TString opt="");
113 TCanvas* Drawv2to5(int ncb, int centbins[], int ipt1=0, int ipt2=999, TString opt="");
114 TCanvas* DrawGlobalvnVsN(int npt, int ptbins[], int ncb, int centbins[], TString opt="");
116 // functions needed for above routine
117 void initialize(const char* ifName = inputFileName);
118 void AddPrelimStampToCurrentPad(float x1, float y1, float x2, float y2, TString opt="");
120 void SaveCanvases(TObjArray* canvases, const char* fileName);
121 void SaveCanvasesFromFile(const char* rootFile, const char* targetDir, const char* tag, const char* fileType);
122 TObjArray* GetObjectsFromFile(TFile& file, TString clname, TString dir="");
126 //============================================================
129 int centlow[100]; // low and high percentile for each selection
136 int colorsPale[] = {kOrange-3, kGreen-6, kAzure-9, kGray+1, kRed-9, kRed-7, kBlue-9, kViolet-9};
137 int colorsDark[] = {kOrange-8, kGreen+1, kAzure+2, kBlack, kCyan+1, kRed+0, kBlue+1, kViolet+1};
138 int centColors[] = {kBlack, kRed, kOrange-3, kGreen+1, kCyan+2, kBlue-1, kViolet, kGreen+1, kOrange-3, kRed+0, kOrange-8, kRed+1, kBlue+1};
139 int centColorsPale[] = {kGray, kRed-9, kOrange-4, kGreen-7, kCyan-7, kBlue-9, kViolet-9, kGreen, kOrange, kRed-4, kOrange-9, kRed-1, kBlue-1};
142 TLatex ltx2; // absolute
144 // Global container for graphs, TF1s, etc.
145 TObjArray* gList = new TObjArray();
146 TObjArray* gFitList = new TObjArray();
149 TGraphErrors *gi, *gj, *gk;
150 char* trigLabel(int i);
151 char* asscLabel(int j);
152 char* centLabel(int k);
153 double MeanPt(int i, int j, int k, TString t_or_a = "t" /* "t" or "a" */,
154 TString opt="" /* "" or "squared" */);
155 int CentBin(double cntLo, double cntHi);
156 int PtBin(double ptLo, double ptHi);
157 int CentColor(double cen1, double cen2);
158 int CentColorPale(double cen1, double cen2);
159 int PtColor(double p1, double p2);
160 int PtColorPale(double p1, double p2);
164 //============================================================
166 void SaveGraphs(const char* outputFileName, TString opt)
168 const char* mode = "recreate";
169 if (opt.Contains("update"))
172 TFile* outputFile = new TFile(outputFileName, mode);
179 void initialize(const char* ifName) {
181 // TH1F files with histograms for:
182 // NSJET_y_PTTRIG_PTASSOC_CENT (tracks with |delta-eta| < 0.8)
183 // RIDGE_y_PTTRIG_PTASSOC_CENT (tracks with |delta-eta| = 0.8 - 1.6)
185 if (fin) // don't keep re-initializing
188 fin = new TFile(ifName);
190 Error("FourierPlus - initialize()", "%s not found", ifName);
194 TList* info = (TList*)fin->Get("FileInfo");
198 gi = (TGraphErrors*) fin->Get("TrigPtBins");
199 gj = (TGraphErrors*) fin->Get("AsscPtBins");
200 gk = (TGraphErrors*) fin->Get("EvCentBins");
203 maxcent = gk->GetN();
204 gList->Add(gi); gList->Add(gj); gList->Add(gk);
206 if (gj->GetN() != maxpt)
207 Warning("initialize()",
208 "Trigger and assc. binning are not symmetric: %d vs. %d",
211 for (int k=0; k<maxcent; k++) {
212 centlow[k] = gk->GetX()[k] - gk->GetEX()[k];
213 centhigh[k] = gk->GetX()[k] + gk->GetEX()[k];
214 // cout << centlow[k] << " " << centhigh[k] << endl;
217 for (int i=0; i<maxpt; i++) {
218 ptlow[i] = gi->GetX()[i] - gi->GetEX()[i];
219 pthigh[i] = gi->GetX()[i] + gi->GetEX()[i];
220 // cout << ptlow[i] << " " << pthigh[i] << endl;
223 // OK, leave hard-coded for now....
224 ptmean[0] = 0.66; // 0.5-1 GeV
225 ptmean[1] = 1.30; // 1-2 GeV
226 ptmean[2] = 2.30; // 2-3 GeV
227 ptmean[3] = 3.30; // 3-4 GeV
228 ptmean[4] = 4.60; // 4-6 GeV
229 ptmean[5] = 6.60; // 6-8 GeV
230 ptmean[6] = 11.7; // 8-15 GeV
233 for (int i=0; i<maxpt; i++) {
234 ptmean[i] = gi->GetX()[i];
237 gROOT->SetStyle("Plain");
238 gStyle->SetOptTitle(0);
239 gStyle->SetOptStat(0);
243 TH1* Hist(const char* region, const char* type, int i, int j, int k, TString opt)
246 // "sys": return measured pts. w/systematic errors.
247 // "hi_sys": meas. pts + sys, unmodified stat. errors.
248 // "lo_sys": meas. pts - sys, unmodified stat. errors.
250 TH1* h_in=0, *h_out=0;
251 const char* name = Form("PbPb/%s_%s_%d_%d_%d",region,type,i,j,k);
252 h_in = (TH1*)fin->Get(name);
254 Error("Hist()","%s not found, exiting.", name);
258 h_out = (TH1*)h_in->Clone(Form("%s_%s", name, opt.Data()));
260 // Stat --> sys error bars. Error estimated as difference in Fourier
261 // series (0<n<6) between same-event dist. and CF.
262 if (opt.Contains("sys")) {
263 const char* s = Form("PbPb/%s_s_%d_%d_%d",region,i,j,k);
264 TH1* htmp = (TH1*)fin->Get(s);
267 hs = (TH1*)htmp->Clone();
269 Error("Hist()", "No hist %s", s);
271 double c = double(hs->GetNbinsX())/hs->Integral();
274 TF1* fs = HarmonicSum(hs, 1,5);
275 TF1* fc = HarmonicSum(h_in,1,5);
277 for (int n=1; n<=hs->GetNbinsX(); n++) {
278 double x = hs->GetBinCenter(n);
279 double err = TMath::Abs(fs->Eval(x) - fc->Eval(x));
280 double bc = h_in->GetBinContent(n);
282 if (opt.Contains("hi_sys"))
283 h_out->SetBinContent(n, bc+err);
284 else if (opt.Contains("lo_sys"))
285 h_out->SetBinContent(n, bc-err);
287 h_out->SetBinError(n, err);
288 h_out->SetFillColor(kGray);
301 void ijkFromHistName(TH1* h, int& i, int& j, int& k)
303 TString tok, name(h->GetName());
306 while (name.Tokenize(tok, from, "_")) {
307 if (counter==2) i = tok.Atoi();
308 if (counter==3) j = tok.Atoi();
309 if (counter==4) k = tok.Atoi();
313 cout << i<<j<<k << endl;
318 double PtBinCenterSum(int ptt, int pta)
320 if ((ptt<0 || ptt>=maxpt) || (pta>ptt))
321 Error("PtBinCenterSum()","Bad arg(s): ptt %d pta %d", ptt, pta);
323 double pti = gi->GetX()[ptt];
324 double ptj = gj->GetX()[pta];
328 int GlobalIndex(int ptt, int pta)
330 // Find the global index from the trig and assc. pt bins.
331 // It is useful that TMath::Binomial(n,k) returns 0 when n < k.
332 if (pta > ptt) return -1;
333 return TMath::Binomial(ptt+1, 2) + pta;
336 void ijFromGlobalIndex(int q, int& ptt, int& pta)
338 // Assign ptt and pta from the global index q. This function is
339 // effectively the inverse of GlobalIndex(i,j).
340 for (int i=0; i<maxpt; i++) {
341 for (int j=0; j<=i; j++) {
342 if (GlobalIndex(i,j)==q) {
351 // Needs to be updated! Has hard-coded numbers like 27.9. -AMA 11/15/2011
352 TCanvas* FitStudy(int icent, int n, int par)
354 // First get the VnDelta vs q graph...
355 TGraphErrors* gVn = VnDVsQ(n, icent);
357 // Then setup fit function
358 TF1 *fn = new TF1(Form("fn_cent%dto%d_n%d", centlow[icent],centhigh[icent], n),
359 vntvna, 0.0, 27.9, maxpt);
361 fn->SetLineColor(kRed);
363 TCanvas* c = new TCanvas(Form("chi2_cent%dto%d_n%d", centlow[icent],centhigh[icent], n),
364 Form("chi2 test for %s, varying v_{%d}(%.1f)",
365 centLabel(icent), n, ptmean[par]),
367 c->Divide(1, 3, 0.001, 0.001);
369 TGraphErrors *g = new TGraphErrors();
370 TGraphErrors *chi2 = new TGraphErrors();
371 chi2->SetTitle(Form("Total #chi^{2} for n=%d;v_{%d}(p_{T}=%.2f);total #chi^{2}", n,n, ptmean[par]));
372 utils.set_tgraph_props(g, kGray, kGray, kFullCircle, 1.3);
373 utils.set_tgraph_props(chi2, kBlue, kBlue, kFullCircle, 0.8);
376 double bestvn = vnGF(n,icent,par,0,999,"RIDGE","cA","");
377 double bestvn_err = vnGF(n,icent,par,0,999,"RIDGE","cA","err");
381 double parmax = TMath::Abs(2*(bestvn + bestvn_err));
382 double parmin = -parmax;
384 // First panel: step thru one fixed vn
386 TH1F* hf1 = gPad->DrawFrame(0.0, 1.2*parmin, 12.5, 1.2*parmax);
387 hf1->SetTitle(Form("title;p_{T};v_{%d}(p_{T})", n));
389 for (int step=0; step<=nsteps; step++) {
390 double stepsize = (parmax-parmin)/nsteps;
391 double val = parmin + step*stepsize;
393 for (int ip=0;ip<maxpt;ip++) fn->SetParameter(ip,0.0);
394 fn->FixParameter(par, val);
397 for (int i=0;i<maxpt;i++) {
398 g->SetPoint(i, ptmean[i], fn->GetParameter(i));
399 g->SetPointError(i, 0.0, fn->GetParError(i));
402 g->DrawClone("elpsame");
404 // store chi2 at this val
405 chi2->SetPoint(step, val, fn->GetChisquare());
407 // Finally, draw once with no fixed parameters...
408 utils.set_tgraph_props(g, kBlack, kBlack, kFullCircle, 1.3);
409 for (int ip=0;ip<maxpt;ip++) fn->ReleaseParameter(ip);
411 for (int i=0;i<maxpt;i++) {
412 g->SetPoint(i, ptmean[i], fn->GetParameter(i));
413 g->SetPointError(i, 0.0, fn->GetParError(i));
415 g->DrawClone("elpsame");
416 ltx.SetTextSize(0.08);
417 ltx.DrawLatex(0.6, 0.8, Form("v_{%d}, %s", n, centLabel(icent)));
419 // Plot chi2 over full range
422 chi2->DrawClone("alp");
424 // and zoomed to see 1 sigma interval
427 double ymin = 1e9;//chi2->GetHistogram()->GetMinimum();
428 for (int j=0; j<chi2->GetN(); j++)
429 if (chi2->GetY()[j] < ymin)
430 ymin = chi2->GetY()[j];
431 double nsigma = n==2? 3 : 3;
432 TH1F* hf3 = gPad->DrawFrame(parmin, ymin - 1, parmax, ymin + nsigma);
433 hf3->SetTitle(Form("Total #chi^{2} for n=%d;v_{%d}(p_{T}=%.2f);total #chi^{2}", n,n, ptmean[par]));
434 chi2->DrawClone("lpsame");
436 best.SetLineWidth(3);
437 onesig.SetLineWidth(3);
438 onesig.SetLineColor(kGray);
439 best.DrawLine(parmin, ymin, parmax, ymin);
440 onesig.DrawLine(parmin, ymin+1, parmax, ymin+1);
442 lbl.DrawLatex(parmin + 0.05*(parmax-parmin), ymin+0.1, Form("Best v_{%d}(%.2f)",n,ptmean[par]));
443 lbl.DrawLatex(parmin + 0.05*(parmax-parmin), ymin+1.1, "+ 1#sigma");
448 TCanvas* MultiDraw(int cent, TString opt)
450 // TODO: make this function much more flexible. Pass in an array of
451 // bins or histos and m,n ints to plot in an m x n grid.
452 TCanvas* c = new TCanvas(Form("cfmulti_%s_%d",opt.Data(),cent),
453 Form("Corr. Functions - %s", centLabel(cent)),
455 c->Divide(maxpt, maxpt-2, 0, 0);
459 // Combine first 3 rows (i=0,1,2) to save space
460 // Then draw the rest as usual
461 for (int i=0; i<maxpt; i++) {
462 for (int j=0; j<maxpt; j++) {
465 if (opt.Contains("2D"))
466 cs = SingleDraw2D(cent, i, j, "");
467 else if (opt.Contains("deta"))
468 cs = SingleDrawEta(cent, i, j, "");
470 cs = SingleDraw(cent, i, j, "");
474 if (ipad==maxpt) ipad++;
476 else if (i > 2) ipad++;
480 // Add some labeling in empty pads
481 ltx.SetTextSize(0.15);
483 ltx.DrawLatex(0.1, 0.8, "p_{T}^{trig}: 0.5-1,");
484 ltx.DrawLatex(0.1, 0.6, "1-2, 2-3 GeV/c");
486 ltx.DrawLatex(0.1, 0.8, "p_{T}^{trig}:");
487 ltx.DrawLatex(0.1, 0.6, "3-4 GeV/c");
489 ltx.DrawLatex(0.1, 0.8, "p_{T}^{trig}:");
490 ltx.DrawLatex(0.1, 0.6, "4-6 GeV/c");
492 ltx.DrawLatex(0.1, 0.8, "p_{T}^{trig}:");
493 ltx.DrawLatex(0.1, 0.6, "6-8 GeV/c");
496 ltx.SetTextSize(0.2);
497 ltx.DrawLatex(0.1, 0.7, "Pb+Pb");
498 ltx.DrawLatex(0.1, 0.4, "LHC10h");
499 ltx.DrawLatex(0.1, 0.1, centLabel(cent));
504 TH2* EtaPhiHist(int cent, int ptt, int pta)
507 TH2* htmp = (TH2*)fin->Get(Form("PbPb/ETAPHI_c_%1d_%1d_%1d",ptt,pta,cent));
509 Error("EtaPhiHist()",
510 "Problem getting pointer to histogram. cent %d ptt %d pta %d",
514 TH2* h = (TH2*)htmp->Clone(Form("EtaPhi_c_%1d_%1d_%1d",ptt,pta,cent));
515 TAxis *ax = h->GetXaxis(), *ay = h->GetYaxis(), *az = h->GetZaxis();
516 ax->SetTitle("#Delta#phi");
517 ay->SetTitle("#Delta#eta");
518 az->SetTitle("C(#Delta#phi, #Delta#eta)");
519 ay->SetRangeUser(-maxRidgeDEta, maxRidgeDEta);
520 ax->SetTitleOffset(1.3);
521 ay->SetTitleOffset(1.3);
522 az->SetTitleOffset(1.4);
527 TCanvas* SingleDraw2D(int cent, int ptt, int pta, TString opt)
530 TCanvas* c = 0; // The canvas to be returned
531 double labelScale = 1.3;
534 // See if we have already made this once
537 name = Form("etaphi_cent%dto%d_%d_%d",
538 centlow[cent],centhigh[cent],ptt,pta );
540 name = Form("etaphi_cent%dto%d_%d_%d_%s",
541 centlow[cent],centhigh[cent],ptt,pta, opt.Data() );
543 const char* title = Form("dphideta_cent%dto%d_pTtrig%.2gto%.2g_pTassoc%.2gto%.2g_%s",
544 centlow[cent],centhigh[cent],
545 ptlow[ptt], pthigh[ptt],
546 ptlow[pta], pthigh[pta],
549 if (gDirectory->FindObject(name)) {
550 c = (TCanvas*) gDirectory->FindObject(name);
554 c = new TCanvas(name, title, 1);
556 TH2* h = EtaPhiHist(cent, ptt,pta);
558 Error("SingleDraw2D()",
559 "Problem getting pointer to histogram. cent %d ptt %d pta %d",
563 utils.make_nice_axes(c, h, labelScale, nDiv, nDiv);
564 TAxis *ax = h->GetXaxis(), *ay = h->GetYaxis(), *az = h->GetZaxis();
565 ax->SetTitle("#Delta#phi [rad]");
566 ay->SetTitle("#Delta#eta");
567 az->SetTitle("C(#Delta#phi, #Delta#eta)");
568 ay->SetRangeUser(-maxRidgeDEta, maxRidgeDEta);
569 ax->SetTitleOffset(1.3);
570 ay->SetTitleOffset(1.3);
571 az->SetTitleOffset(1.4);
573 double czlo=0, czhi=5.0;
574 if (opt.Contains("zoom"))
575 az->SetRangeUser(czlo, czhi);
577 if (opt.Contains("colz"))
582 ltx.SetTextSize(0.05);
583 if (opt.Contains("colz")) {
584 if (opt.Contains("zoom"))
585 ltx.DrawLatex(0.6, 0.9, Form("C(#Delta#phi) (C(#Delta#phi) < %.3g)", czhi));
587 ltx.DrawLatex(0.6, 0.9, Form("C(#Delta#phi) (full range)"));
590 // Label pt, centrality, energy
591 TString ptStr(Form("#splitline"
592 "{%.3g < p_{T}^{t} < %.3g GeV/c}"
593 "{%.3g < p_{T}^{a} < %.3g GeV/c}",
594 ptlow[ptt], pthigh[ptt],
595 ptlow[pta], pthigh[pta]));
596 ltx.SetTextSize(0.07);
597 ltx.DrawLatex(0.01, 0.86, ptStr.Data());
599 ltx.DrawLatex(0.65, 0.9, Form("#splitline{pp 2.76 TeV}{}"));
601 ltx.DrawLatex(0.65, 0.9, Form("#splitline{Pb-Pb 2.76 TeV}{%s}", centLabel(cent)));
606 TCanvas* SingleDrawEta(int cent, int ptt, int pta, TString opt)
609 int lineWidth = opt.Contains("small") ? 1 : 4;
610 double mrkSize = opt.Contains("small") ? 0.5 : 1.5;
612 const char* name = Form("deta_cent%dto%d_%d_%d",
613 centlow[cent],centhigh[cent],ptt,pta);
615 // See if we have already made this once
616 if (gDirectory->FindObject(name)) {
617 c = (TCanvas*) gDirectory->FindObject(name);
618 Info("SingleDrawEta()", "%s already created", c->GetName());
622 c = new TCanvas(name, name, 600, 600);
624 TH1 *hNS = 0, *hAS = 0; // divide-then-project
625 TH1 *hNS2 = 0, *hAS2 = 0; // project-then-divide
627 bool includeProjThenDiv = 0;
629 if (1) { // Recreate CFs using divide-then-project method
631 TH2* hc = (TH2*)fin->Get(Form("PbPb/ETAPHI_c_%1d_%1d_%1d",ptt,pta,cent));
633 Error("SingleDrawEta()", "Problem getting hc\n");
637 int bin1 = hc->GetXaxis()->FindBin(-TMath::PiOver2()+0.001);
638 int bin2 = hc->GetXaxis()->FindBin(TMath::PiOver2()-0.001);
639 int bin3 = hc->GetXaxis()->FindBin(TMath::PiOver2()+0.001);
640 int bin4 = hc->GetXaxis()->FindBin(3*TMath::PiOver2()-0.001);
642 bool smallEtaRange = false;
644 bin1 = hc->GetXaxis()->FindBin(-TMath::PiOver2()+0.001);
645 bin2 = hc->GetXaxis()->FindBin(TMath::PiOver2()-0.001);
646 bin3 = hc->GetXaxis()->FindBin(TMath::Pi()-0.5);
647 bin4 = hc->GetXaxis()->FindBin(TMath::Pi()+0.5);
650 const char* ns_name = Form("ns_deta_cent%dto%d_%d_%d",
651 centlow[cent],centhigh[cent],ptt,pta);
652 const char* as_name = Form("as_deta_cent%dto%d_%d_%d",
653 centlow[cent],centhigh[cent],ptt,pta);
655 hNS = hc->ProjectionY(ns_name, bin1, bin2, "e");
656 hAS = hc->ProjectionY(as_name, bin3, bin4, "e");
658 hNS->Scale(1./(bin2-bin1+1));
659 hAS->Scale(1./(bin4-bin3+1));
663 if (includeProjThenDiv) { // As created by Project.C (project-then-divide)
664 const char* ns = Form("PbPb/ETA_NS_c_%1d_%1d_%1d",ptt,pta,cent);
665 const char* as = Form("PbPb/ETA_AS_c_%1d_%1d_%1d",ptt,pta,cent);
666 hNS2 = (TH1*)fin->Get(ns);
667 hAS2 = (TH1*)fin->Get(as);
669 Error("SingleDrawEta()", "Problem getting %s\n", ns);
673 Error("SingleDrawEta()", "Problem getting %s\n", as);
678 utils.set_hist_props(hNS, kBlack, kNone, kBlack, kFullDotLarge, mrkSize);
679 utils.set_hist_props(hAS, kRed, kNone, kRed, kFullDotLarge, mrkSize);
680 utils.set_ylimits(hNS, hAS);
681 hNS->SetLineWidth(lineWidth);
682 hAS->SetLineWidth(lineWidth);
684 // hNS->Draw("hist");
685 // hAS->Draw("histsame");
686 hNS->DrawClone("ep");
687 hAS->DrawClone("epsame");
689 if (includeProjThenDiv) {
690 utils.set_hist_props(hNS2, kGray+2, kNone, kGray+2, kFullDotLarge, mrkSize);
691 utils.set_hist_props(hAS2, kCyan, kNone, kCyan, kFullDotLarge, mrkSize);
692 hNS2->SetLineWidth(lineWidth);
693 hAS2->SetLineWidth(lineWidth);
695 hNS2->DrawClone("epsame");
696 hAS2->DrawClone("epsame");
702 TCanvas* SingleDrawPlain(int cent, int ptt, int pta, TString opt)
705 const char* region = "RIDGE";
706 const char* yTitle = Form("%.2g < |#Delta#eta| < %.2g",
707 minRidgeDEta, maxRidgeDEta);
708 if (opt.Contains("ALL")) {
710 yTitle = Form("%.2g < |#Delta#eta| < %.2g", 0.0, maxRidgeDEta);
712 if (opt.Contains("NSJET")) {
714 yTitle = Form("%.2g < |#Delta#eta| < %.2g", 0.0, minRidgeDEta);
717 const char* name = Form("%s_cent%dto%d_%d_%d_%s", region,
718 centlow[cent],centhigh[cent],ptt,pta, opt.Data());
719 const char* title = Form("dphiPlain_%s_cent%dto%d_pTtrig%.2gto%.2g_pTassoc%.2gto%.2g_%s",
721 centlow[cent],centhigh[cent],
722 ptlow[ptt], pthigh[ptt],
723 ptlow[pta], pthigh[pta],
726 if (gDirectory->FindObject(name)) {
728 c = (TCanvas*) gDirectory->FindObject(name);
729 Info("SingleDrawPlain()", "%s already created", c->GetName());
733 c = new TCanvas(name, title, 700, 700);
736 TH1* h_sys = Hist(region, cfDef, ptt,pta,cent, "sys");
737 TH1* h = Hist(region, cfDef, ptt,pta,cent);
740 TAxis* ax = h->GetXaxis();
741 TAxis* ay = h->GetYaxis();
743 h->SetTitle(Form(";#Delta#phi [rad];C(#Delta#phi), %s", yTitle));
745 ax->SetNdivisions(208);
746 ay->SetNdivisions(208);
747 ax->SetLabelSize(0.04);
748 ay->SetLabelSize(0.04);
749 ax->SetTitleSize(0.05);
750 ay->SetTitleSize(0.05);
751 ax->SetTitleOffset(1.5);
752 ay->SetTitleOffset(-1.9);
753 c->SetFrameLineWidth(2);
754 c->SetLeftMargin(0.2);
755 c->SetBottomMargin(0.15);
756 c->SetTopMargin(0.01);
757 c->SetRightMargin(0.01);
763 utils.set_ylimits(h, h, 0.05);
764 utils.set_hist_props(h, kBlack, kNone, kBlack, kFullDotLarge, 1.4);
766 h_sys->Draw("e2psame");
768 if (opt.Contains("harmonics"))
769 for (int n=1; n<6; n++)
770 Harmonic(h, n, "draw");
771 if (opt.Contains("sum"))
772 HarmonicSum(h,1,5,"draw");
774 ltx.SetTextSize(0.045);
775 double top = 0.92, gap = 0.08;
776 double x1 = (TString(region)=="RIDGE" && (ptlow[ptt] > 4 || ispp))? 0.25 : 0.5;
777 ltx.DrawLatex(x1, top-0*gap, Form("p_{T}^{t} %s GeV/c", trigLabel(ptt)));
778 ltx.DrawLatex(x1, top-1*gap, Form("p_{T}^{a} %s GeV/c", asscLabel(pta)));
780 ltx.DrawLatex(x1, top-2*gap, Form("pp 2.76 TeV"));
782 ltx.DrawLatex(x1, top-2*gap, Form("Pb-Pb 2.76 TeV, %s", centLabel(cent)));
784 ltx.DrawLatex(0.22, 0.92, Form("|#Delta#eta| > %.1f", minRidgeDEta));
786 // ltx.SetTextColor(kBlack);
787 // ltx.SetTextSize(0.03);
788 // ltx.DrawLatex(0.7, 0.18, "statistical error only");
793 TF1* Harmonic(TH1* h, int n, TString opt)
796 double vndelta=0, vndelta_err=0;
797 double phiMin = -0.5*TMath::Pi();
798 double phiMax = +1.5*TMath::Pi();
799 double b0 = h->Integral() / h->GetNbinsX();
800 int color = opt.Contains("gray")? kGray : colorsPale[n-1];
802 VnDelta(n, *h, vndelta, vndelta_err);
804 f = new TF1(Form("%scos%ddphi", h->GetName(), n),
805 "[0]*(1. + 2.*[1]*cos([2]*x))",
807 f->SetParameters(b0, vndelta, n);
808 f->SetLineColor(color);
810 if (opt.Contains("draw"))
816 TF1* HarmonicSum(TH1* h, int n1, int n2, TString opt)
819 Warning("HarmonicSum()", "n1=%d but should be > 0", n1);
821 double phiMin = -0.5*TMath::Pi();
822 double phiMax = +1.5*TMath::Pi();
824 // Function definition string
825 TString fdef("[0]*(1.0 + 2.0*(");
826 for (int n=n1; n<=n2; n++) {
827 fdef.Append(Form(" [%d]*cos(%d*x) ", n, n));
828 fdef.Append( n<n2 ? "+" : "))");
832 TF1 *ff = new TF1("ff", fdef.Data(), phiMin,phiMax);
833 ff->SetParameter(0, h->Integral()/h->GetNbinsX());
836 for (int n=n1; n<=n2; n++) {
838 // Sum of vnt x vna from global fit
839 if (opt.Contains("global") ) {
840 int i=-1, j=-1, k=-1;
841 ijkFromHistName(h,i,j,k);
842 double vnt = vnGF(n,k,i,0,999,"RIDGE","cA","");
843 double vna = vnGF(n,k,j,0,999,"RIDGE","cA","");
844 ff->SetParameter(n, vnt*vna); // TODO: consider including errors
845 ff->SetLineColor(kRed+1);
847 else { // sum of directly-extracted pair moments
848 double Vn=0, VnErr=0;
849 VnDelta(n, *h, Vn, VnErr);
850 ff->SetParameter(n, Vn);
851 ff->SetLineColor(kBlack); // ff->SetLineColor(kAzure);
852 // ff->SetLineWidth(4);
853 ff->SetLineStyle(kDashed);
855 ff->SetLineColor(kGreen);
860 if (opt.Contains("draw"))
866 TCanvas* SingleDraw(int cent, int ptt, int pta, TString opt)
868 int lineWidth = opt.Contains("small") ? 1 : 4;
869 double mrkSize = opt.Contains("small") ? 0.5 : 1.5;
870 TString dEtaLabel = "";
872 const char* region = "RIDGE";
873 if (opt.Contains("ALL")) {
875 dEtaLabel = Form("%.2g < |#Delta#eta| < %.2g", 0.0, maxRidgeDEta);
877 if (opt.Contains("NSJET")) {
879 dEtaLabel = Form("%.2g < |#Delta#eta| < %.2g", 0.0, minRidgeDEta);
881 if (TString(region)=="RIDGE")
882 dEtaLabel = Form("%.2g < |#Delta#eta| < %.2g", minRidgeDEta, maxRidgeDEta);
886 TCanvas* c1 = 0; // The canvas to be returned
888 // See if we have already made this once
889 TString name = Form("dphi_etamin%02d_cent%dto%d_%d_%d", (int)(10*minRidgeDEta),
890 centlow[cent],centhigh[cent],ptt,pta);
891 TString title = Form("dphiFourier_%s_cent%dto%d_pTtrig%.2gto%.2g_pTassoc%.2gto%.2g",
893 centlow[cent],centhigh[cent],
894 ptlow[ptt], pthigh[ptt],
895 ptlow[pta], pthigh[pta]);
898 name.Append("_"); name.Append(opt);
899 title.Append("_"); title.Append(opt);
902 if (gDirectory->FindObject(name.Data())) {
904 c1 = (TCanvas*) gDirectory->FindObject(name.Data());
905 Info("SingleDraw()", "%s already created", c1->GetName());
909 c1 = TwoPanelVert(0.3, name.Data(), title.Data());
912 gPad->SetTopMargin(0.1);
915 TH1* h = Hist(region, cfDef, ptt,pta,cent);
916 TH1* h_sys = Hist(region, cfDef, ptt,pta,cent, "sys");
917 utils.set_hist_props(h, kBlack, kNone, kBlack, kFullDotLarge, mrkSize);
918 h->SetLineWidth(opt.Contains("small") ? 1 : 2);
919 h->GetXaxis()->SetTitle("#Delta#phi [rad]");
920 h->GetYaxis()->SetTitle("C(#Delta#phi)");
922 TF1* ff5 = HarmonicSum(h, 1, 5, "");
923 ff5->SetLineWidth(lineWidth);
924 TF1* fflowg = HarmonicSum(h, 1, 5, "global");
925 fflowg->SetLineWidth(lineWidth);
926 TF1* ff10 = HarmonicSum(h, 1, 10, "");
927 ff10->SetLineWidth(lineWidth);
928 TF1* ff12 = HarmonicSum(h, 1, 12, "");
929 ff12->SetLineWidth(lineWidth);
933 int nXticks = 404, nYticks = 210;
934 double pad1Scale = 1.6;
935 double pad2Scale = 2.3;
936 utils.make_nice_axes(c1, h, pad1Scale, nXticks, nYticks, 0.05, 0.01);
937 h->GetXaxis()->SetTitleOffset(1.2);
938 h->GetYaxis()->SetTitleOffset(1.5);
939 utils.set_ylimits(h,h);
942 h_sys->Draw("e2psame");
945 if (opt.Contains("gray"))
946 for (int n=1; n<6; n++)
947 Harmonic(h, n, "gray, draw");
948 else if (opt.Contains("color"))
949 for (int n=1; n<6; n++)
950 Harmonic(h, n, "draw");
952 if (opt.Contains("upto10")) {
953 ff10->SetLineWidth(lineWidth+2);
954 ff10->SetLineColor(kBlack);
955 ff10->DrawClone("same");
956 ff10->SetLineWidth(lineWidth);
957 ff10->SetLineColor(kGreen);
958 ff10->SetLineStyle(kDashed);
962 // ff10->Draw("same");
966 if (opt.Contains("global")) {
967 fflowg->Draw("same");
970 ltx.SetTextSize(0.06);
971 double top = 0.82, gap = 0.08;
972 double x1 = (TString(region)=="RIDGE" && ptlow[ptt] > 6)? 0.25 : 0.6;
974 ltx.DrawLatex(0.2, 0.92, Form("pp 2.76 TeV"));
976 ltx.DrawLatex(0.2, 0.92, Form("Pb-Pb 2.76 TeV, %s central", centLabel(cent)));
977 ltx.DrawLatex(x1, top-0*gap, Form("%.3g < p_{T}^{t} < %.3g GeV/c",
978 ptlow[ptt], pthigh[ptt]));
979 ltx.DrawLatex(x1, top-1*gap, Form("%.3g < p_{T}^{a} < %.3g GeV/c",
980 ptlow[pta], pthigh[pta]));
981 // ltx.DrawLatex(x1, top-0*gap, Form("p_{T}^{trig} %s GeV/c", trigLabel(ptt)));
982 // ltx.DrawLatex(x1, top-1*gap, Form("p_{T}^{assoc} %s GeV/c", asscLabel(pta)));
983 ltx.DrawLatex(x1, top-2*gap, dEtaLabel.Data());
988 TH1F *hsub = static_cast <TH1F *> (h->Clone());
989 TH1F *hsub10 = static_cast <TH1F *> (h->Clone());
990 TH1F *hsubg = (TH1F*) (h->Clone());
992 utils.set_hist_props(hsub10, kBlack, kNone, kBlack, kOpenCircle, mrkSize);
993 utils.set_hist_props(hsub, kAzure, kNone, kAzure, kFullSquare, mrkSize);
994 utils.set_hist_props(hsubg, kRed+1, kNone, kRed+1, kFullSquare, mrkSize);
996 for (int i=1;i<=hsub->GetNbinsX();i++) {
998 val = h->GetBinContent(i) * h->GetBinWidth(i);
999 err = h->GetBinError(i) * h->GetBinWidth(i);
1000 double dphi1 = h->GetXaxis()->GetBinLowEdge(i);
1001 double dphi2 = h->GetXaxis()->GetBinUpEdge(i);
1002 double fSum5, fSum10, fSumGlobal;
1003 fSum5 = ff5->Integral(dphi1, dphi2);
1004 fSum10 = ff10->Integral(dphi1, dphi2);
1005 fSumGlobal = fflowg->Integral(dphi1, dphi2);
1006 hsub->SetBinContent(i, val/fSum5);
1007 hsub->SetBinError(i, err/fSum5);
1008 hsub10->SetBinContent(i, val/fSum10);
1009 hsub10->SetBinError(i, err/fSum10);
1010 hsubg->SetBinContent(i, val/fSumGlobal);
1011 hsubg->SetBinError(i, err/fSumGlobal);
1013 utils.make_nice_axes(c1, hsub, pad2Scale, nXticks, 5, 0.05, 0.01);
1014 if (opt.Contains("global"))
1015 utils.set_ylimits(hsub, hsubg, 0.2);
1017 utils.set_ylimits(hsub, hsub10, 0.2);
1019 hsub->SetTitle(Form(";#Delta#phi [rad];ratio"));
1020 // hsub->SetTitle(Form(";#Delta#phi [rad];data/#Sigma_{n=1}^{%s}", opt.Contains("global")?"5":"N"));
1021 hsub->GetXaxis()->SetTitleOffset(1.25);
1022 hsub->GetYaxis()->SetTitleOffset(0.7);
1023 hsub->GetXaxis()->SetTicks("+-"); hsub->GetXaxis()->SetTickLength(0.08);
1024 hsub10->SetTitle(";#Delta#phi [rad];data/#Sigma_{n=1}^{N}");
1025 hsub10->GetXaxis()->SetTitleOffset(1.25);
1026 hsub10->GetYaxis()->SetTitleOffset(0.7);
1027 hsubg->SetTitle(";#Delta#phi [rad];data/calc");
1028 hsubg->GetXaxis()->SetTitleOffset(1.25);
1029 hsubg->GetYaxis()->SetTitleOffset(0.7);
1031 TLegend* leg = new TLegend(0.2, 0.01, 0.38, 0.38);
1032 leg->SetFillColor(kNone);
1033 leg->SetBorderSize(1);
1034 if (opt.Contains("global")) {
1035 leg->AddEntry(hsub, "#LTcos(n#Delta#phi)#GT", "epl");
1036 leg->SetBorderSize(0);
1039 leg->AddEntry(hsub, "1#leqn#leq5", "epl");
1044 if (opt.Contains("global")) {
1045 hsubg->Draw("epsame");
1046 leg->AddEntry(hsubg, "v(p_{Tt})v(p_{Ta})", "epl");
1048 else if (opt.Contains("upto10")) {
1049 TH1* hsub10green = (TH1*)hsub10->Clone();
1050 utils.set_hist_props(hsub10green, kBlack, kNone, kGreen, kFullCircle, mrkSize);
1051 hsub10green->Draw("epsame");
1052 hsub10->Draw("epsame");
1053 leg->AddEntry(hsub10green, "1#leqn#leq10", "epl");
1056 unity.DrawLine(-TMath::PiOver2(), 1.0, 3*TMath::PiOver2(), 1.0);
1059 if (opt.Contains("global"))
1064 TF1* flat = new TF1("flat", "1.0", -TMath::PiOver2(), 3*TMath::PiOver2());
1065 double chi2 = Chi2(hsub, flat);
1066 double chi2_10 = Chi2(hsub10, flat);
1067 int ndof = hsub->GetNbinsX();
1070 ltx.DrawLatex(0.65, 0.05, Form("#chi^{2}/ndf = %.3g / %d", chi2, ndof-1));
1072 cout << "Chi2[5] = " << chi2 << " Chi2[10] = " << chi2_10
1073 << " ndof = " << ndof-1 << " (Prob = " << TMath::Prob(chi2,ndof-6)
1074 << " , " << TMath::Prob(chi2_10,ndof-11) << " )" << endl;
1079 double Chi2(TH1* h, TF1* f, TString opt) {
1082 for (int i=1;i<=h->GetNbinsX();i++) {
1083 double fy = f->Eval(h->GetBinCenter(i));
1084 chi2 += pow( (h->GetBinContent(i) - fy)/h->GetBinError(i) , 2.0);
1089 if (opt.Contains("ndf") && ndf > 0)
1092 if (opt.Contains("prob") )
1093 return TMath::Prob(chi2, ndf);
1098 double vntvna(double *x, double *par)
1100 // This function is called many times during a fit. For a 1-d fit,
1101 // x[0] is the x-position of the nth point,
1102 // i.e. graph->GetX()[n]. For a single-valued TGraph, it can be used
1103 // to indicate which point the fitter is currently working on. The
1104 // par array contains maxpt free parameters that are continually
1105 // updated during the fit process.
1107 // q is the global index
1108 int q = (int)x[0]; // Assume points are at q + 0.5.
1111 int nPoints = (maxpt*(maxpt+1))/2;
1112 TF1::fgRejectPoint = kFALSE;
1114 // Assign i and j from q
1115 ijFromGlobalIndex(q, i, j);
1117 if (q < 0 || q >= nPoints) {
1119 "Problem finding global index. x[0]=%f, q=%d, i=%d, j=%d",
1125 // Exclude points from fit. Warning: TF1::fgRejectPoint is a global
1126 // flag checked by all TF1s, beware of side-effects.
1127 if (j < minFitPtBin || j > maxFitPtBin) {
1130 cout << Form("Rejecting x[0],q,i,j = %f %d %d %d",
1136 double v2t = par[i];
1137 double v2a = par[j];
1138 int n = par[maxpt]; // Fourier coeff. index
1139 int k = par[maxpt+1]; // cent. bin index
1140 double fitval = v2t * v2a;
1142 // Add extra fit term for momentum conservation
1143 // It is 1/<\sum pt2> * <ptt><pta>
1144 // From ML & JYO, PRL 106, 102301 (2011) eqs 3-7
1145 double mptt=0, mpta=0, v1fac=0;
1147 mptt = MeanPt(i, j, k, "t");
1148 mpta = MeanPt(i, j, k, "a");
1149 v1fac = par[maxpt+2];
1151 fitval += v1fac * mptt * mpta;
1154 // Odd vnd's < 0 at high pt. // can I replace the below by saying if
1155 // (vndelta < 0) then make fitval < 0?
1156 if (j >= PtBin(5., 6.) && (n%2) )
1162 void VnDelta(int n, const TH1 &h, double &vnd, double &vnd_err, TString opt)
1164 // Extract fourier coefficient n directly from h. If opt is "hi" or
1165 // "lo", the coefficient is calculated for the points + or - their
1166 // errors. "hi" and "lo" are meant for an h with systematic (not
1167 // statistical) errors, so vnd_err is not calculated.
1171 // Calculate and set coeff. vnd
1172 for (int ib=1; ib<=h.GetNbinsX(); ib++) {
1173 double deltaphi = h.GetBinCenter(ib);
1174 double weight = h.GetBinContent(ib);
1176 if (opt.Contains("hi"))
1177 weight += h.GetBinError(ib);
1178 else if (opt.Contains("lo"))
1179 weight -= h.GetBinError(ib);
1181 if (opt.Contains("sin") )
1182 VN += sin(n * deltaphi ) * weight;
1184 VN += cos(n * deltaphi ) * weight;
1190 ::Error("VnDelta()", "Div/0 error");
1194 // // Mom. cons correction?????????????????????????????????
1195 // if (n==1) VN += 0.002*ptmean[i]*ptmean[j];
1198 if (opt.Contains("hi") || opt.Contains("lo")) {
1203 // Statistical uncertainty vnd_err
1204 double quad_sum_uncertainty = 0.0;
1205 for (int ib=1; ib<=h.GetNbinsX(); ib++) {
1206 double deltaphi = h.GetBinCenter(ib);
1207 double dfdwi = cos(n * deltaphi)/norm - VN/norm;
1209 if (opt.Contains("sin") )
1210 dfdwi = sin(n * deltaphi)/norm - VN/norm;
1212 double sigma = h.GetBinError(ib);
1213 quad_sum_uncertainty += dfdwi*dfdwi * sigma*sigma;
1216 vnd_err = TMath::Sqrt(quad_sum_uncertainty);
1220 void VnDelta(int n, const TF1 &f, double &vnd, double &vnd_err, TString opt)
1222 // Extract fourier coefficient n from f.
1228 double dx = (x2-x1)/nSteps;
1230 if (!opt.IsNull() ) cout<<opt.Data()<<endl;
1232 // Calculate and set coeff. vnd
1233 for (int ib=0; ib<nSteps; ib++) {
1235 double deltaphi = x1 + ib*dx;
1236 double weight = f.Eval(deltaphi);
1238 VN += cos(n * deltaphi ) * weight;
1243 Error("VnDelta()", "Div/0 error");
1247 vnd_err = 0; // for now
1253 // The argument ydiv is the division between pads as a fraction of the
1255 TCanvas* TwoPanelVert(double ydiv, const char* canvName, const char* canvTitle)
1257 TCanvas* c = new TCanvas(canvName, canvTitle, 800, 800);
1258 // Extents of pads inside canvas
1259 double x1=0.01, x2=0.99, y1=0.01, y2=0.99;
1260 double lm=0.2, rm=0.02;
1262 // Division between top and bottom pads
1263 double ysplit = y1 + ydiv*(y2-y1);
1265 // Divide first, adjust afterward.
1267 TPad* ptop = (TPad*)(c->GetPad(1));
1268 TPad* pbot = (TPad*)(c->GetPad(2));
1270 ptop->SetPad(x1, ysplit, x2, y2);
1271 ptop->SetMargin(lm, rm, 0.01, 0.01); // left, right, bottom, top.
1272 ptop->SetFrameLineWidth(2);
1274 pbot->SetPad(x1, y1, x2, ysplit);
1275 pbot->SetMargin(lm, rm, 0.4, 0.01); // left, right, bottom, top.
1276 pbot->SetFrameLineWidth(2);
1283 char* trigLabel(int i)
1286 return Form("Error: no trig pt bin %d", i);
1288 double x1 = gi->GetX()[i] - gi->GetEX()[i];
1289 double x2 = gi->GetX()[i] + gi->GetEX()[i];
1291 // int prec1 = 0, prec2 = 0;
1292 // if (x1 - (int)x1 > 0)
1294 // if (x2 - (int)x2 > 0)
1297 return Form("%.3g-%.3g", x1, x2);
1300 char* asscLabel(int j)
1303 return Form("Error: no assc pt bin %d", j);
1305 double x1 = gj->GetX()[j] - gj->GetEX()[j];
1306 double x2 = gj->GetX()[j] + gj->GetEX()[j];
1309 int prec1 = 0, prec2 = 0;
1311 if (x1 - (int)x1 > 0)
1313 if (x2 - (int)x2 > 0)
1317 return Form("%.3g-%.3g", x1, x2);
1320 char* centLabel(int k)
1322 if (k<0 || k>maxcent)
1323 return Form("Error: no cent bin %d", k);
1325 double c1 = gk->GetX()[k] - gk->GetEX()[k];
1326 double c2 = gk->GetX()[k] + gk->GetEX()[k];
1328 return Form("%.0f-%.0f%%", c1, c2);
1332 void VnLimits(double &minVn_k, double &maxVn_k, int k, int imin, int imax)
1334 // Find limits for each centrality bin k between imin (inclusive)
1335 // and imax (also inclusive) to plot a common y axis.
1336 // for (int k=0; k < maxcent; k++) {
1337 for (int n=1; n<=5; n++) {
1338 for (int i=imin; i<=imax; i++) {
1339 TGraphErrors* gc = VnDeltaVsPtAssoc(i, k, n);
1341 Error("VnLimits()", "No graph i %d k %d n %d", i,k,n );
1344 for (int j=0; j<gc->GetN(); j++) {
1345 double vn = gc->GetY()[j];
1346 double evn = gc->GetEY()[j];
1347 if (vn+evn > maxVn_k) maxVn_k = vn+evn;
1348 if (vn-evn < minVn_k) minVn_k = vn-evn;
1356 TCanvas* DrawQ(int k, int n, TString opt)
1358 TStopwatch ts1, ts2;
1359 int fitCurveColor = kRed-4;
1360 int divColor = kBlue;
1361 const char* region = "RIDGE";
1362 if (opt.Contains("ALL"))
1365 TString title = Form("globalfit_%d_cent%dto%d",
1366 n, centlow[k],centhigh[k]);
1367 TString name = Form("V%dvsQ_etamin%02d_cent%dto%d",
1368 n, (int)(10*minRidgeDEta),
1369 centlow[k],centhigh[k]);
1371 if (!opt.IsNull()) {
1373 name.Append(opt.Data());
1375 title.Append(opt.Data());
1378 TCanvas* c = TwoPanelVert(0.4, name.Data(), title.Data());
1379 int cwidth = opt.Contains("highptfit") ? 500 : 1200;
1380 c->SetCanvasSize(cwidth, 450);
1381 c->SetWindowSize(cwidth+50, 500);
1383 if (opt.Contains("highptfit")) {
1384 c->GetPad(1)->SetLeftMargin(0.2);
1385 c->GetPad(2)->SetLeftMargin(0.2);
1386 c->GetPad(1)->SetRightMargin(0.05);
1387 c->GetPad(2)->SetRightMargin(0.05);
1391 TLegend* lq = new TLegend(0.14, 0.56, 0.25, 0.83);
1392 lq->SetFillColor(kNone);
1393 lq->SetBorderSize(0);
1395 // g: global VnDelta vs global index (stat errors).
1396 // gs: global VnDelta vs global index (sys errors).
1397 // fn: global fit TF1.
1398 // r: ratio of g/fit.
1400 if (opt.Contains("ALL"))
1401 opt1.Append("_ALL");
1402 if (opt.Contains("ptcons"))
1403 opt1.Append("_ptcons");
1405 TGraphErrors* g = VnDVsQ(n, k, region, cfDef, opt1);
1406 opt1.Append("_sys");
1407 TGraphErrors* gs = VnDVsQ(n, k, region, cfDef, opt1);
1409 int ptaLo = 0, ptaHi = 999;
1410 if (opt.Contains("lowptfit")) {
1411 ptaHi = PtBin(3., 4.);
1413 if (opt.Contains("highptfit")) {
1414 ptaLo = PtBin(5., 6.);
1416 // If custom pta range was passed in, e.g.
1417 // Form("ptabin%dto%d", PtBin(1.5, 2.0), PtBin(8, 15))
1418 if (opt.Contains("ptabin")) {
1419 TRegexp re("ptabin[0-9]+to[0-9]+");
1420 TRegexp re1("ptabin[0-9]+");
1421 TRegexp re2("to[0-9]+");
1422 TString rx = opt(re), pta1s = rx(re1), pta2s = rx(re2);
1423 pta1s.ReplaceAll("ptabin","");
1424 pta2s.ReplaceAll("to","");
1425 ptaLo = pta1s.Atoi();
1426 ptaHi = pta2s.Atoi();
1429 TF1* fn = GlobalFitVsQ(n, k, ptaLo, ptaHi, region, cfDef, "");
1430 TF1* fn_hi = GlobalFitVsQ(n, k, ptaLo, ptaHi, region, cfDef, "hi_sys");
1431 TF1* fn_lo = GlobalFitVsQ(n, k, ptaLo, ptaHi, region, cfDef, "lo_sys");
1433 // Systematic band on ratio line at unity
1434 TH1F *r_sys = new TH1F(Form("r_sys_%s", title.Data()), "r_sys",
1435 g->GetN()-0.5, 0, g->GetN()-0.5);
1436 utils.set_hist_props(r_sys, kBlack, kGray, kBlack, kDot, 1.0);
1438 TGraphErrors* r = new TGraphErrors();
1439 TString rname(g->GetName());
1440 rname.Append("_ratio");
1441 r->SetName(rname.Data());
1444 Error("DrawQ()","Problem getting/creating global fit function");
1448 // Set visual properties
1449 utils.set_tgraph_props(g, kBlack, kBlack, kFullSquare, 1.0);
1450 utils.set_tgraph_props(gs, kBlack, kBlack, kDot, 0.5);
1451 gs->SetFillColor(kGray);
1452 utils.set_tgraph_props(r, kBlack, kBlack, kFullCircle, 1.0);
1455 fn->SetLineWidth(1);
1456 fn->SetLineColor(fitCurveColor);
1457 fn_hi->SetLineStyle(kDashed);
1458 fn_lo->SetLineStyle(kDashed);
1459 fn_hi->SetLineWidth(1);
1460 fn_lo->SetLineWidth(1);
1462 // Compute ratio for r graph
1463 for (int q=0; q<g->GetN(); q++) {
1465 ijFromGlobalIndex(q, ii, jj);
1467 double fy = fn->Eval(q+0.5);
1468 double y = fy==0? 1e9 : g->GetY()[q]/fy;
1469 double rerr = fn_hi->Eval(q+0.5) / fy - 1;
1471 if (opt.Contains("highptfit") && n%2 && g->GetY()[q]!=0)
1472 y = fy/g->GetY()[q];
1474 // No error band when no fit point!
1475 if (jj < ptaLo || jj > ptaHi)
1478 r->SetPoint(q, g->GetX()[q], y);
1479 r->SetPointError(q, 0.0, TMath::Abs(g->GetEY()[q]/fy));
1481 r_sys->SetBinContent(q+1, 1.0);
1482 r_sys->SetBinError(q+1, rerr);
1485 // Set up plot ranges for top panel (g and f)
1488 double sf = 1; // scale factor
1489 fn->GetRange(x1,x2);
1490 if (opt.Contains("highptfit")) {
1493 y1 = sf*fn->GetMinimum(x1,x2);
1494 y2 = sf*fn->GetMaximum(x1,x2);
1495 double marg = 0.4*(y2-y1);
1496 // if (opt.Contains("lowptfit") || opt.Contains("highptfit") ) marg = 2*(y2-y1);
1502 // Set up plot ranges for lower panel (r)
1503 double ry1=0.21, ry2=1.79;
1504 if (opt.Contains("highptfit")) {
1509 // Get / make frame histos for top and bottom
1510 TH2F* hf1 = 0; // (TH2F*)gDirectory->Get("qhf1");
1511 TH2F* hf2 = 0; // (TH2F*)gDirectory->Get("qhf2");
1512 TString name1 = Form("qhf1_%s", title.Data());
1513 TString name2 = Form("qhf2_%s", title.Data());
1514 // TString sv = n==1 ? "#LTcos(#Delta#phi)#GT" :
1515 // Form("#LTcos(%d#Delta#phi)#GT", n);
1516 TString sv = Form("V_{%d#Delta}", n);
1517 TString sgf = Form("(v_{%d}^{t}v_{%d}^{a})_{fit}", n, n);
1520 hf1 = new TH2F(name1.Data(), "hf1", nx+1, x1, x2, 1000, y1, y2);
1522 hf2 = new TH2F(name2.Data(), "hf2", nx+1, x1, x2, 1000, ry1, ry2);
1525 TAxis* ax1 = hf1->GetXaxis();
1526 TAxis* ay1 = hf1->GetYaxis();
1527 TAxis* ax2 = hf2->GetXaxis();
1528 TAxis* ay2 = hf2->GetYaxis();
1529 hf1->SetBins(nx+1, x1, x2, 100, y1, y2);
1530 hf2->SetBins(nx+1, x1, x2, 100, ry1, ry2);
1531 hf1->SetAxisRange(x1, x2, "X");
1532 hf1->SetAxisRange(y1, y2, "Y");
1533 hf2->SetAxisRange(x1, x2, "X");
1534 hf2->SetAxisRange(ry1, ry2, "Y");
1535 ax1->SetLabelOffset(0.02);
1536 ax1->SetLabelSize(0.04); ay1->SetLabelSize(0.08);
1537 ax2->SetLabelSize(0.18); ay2->SetLabelSize(0.12);
1538 ax1->SetNdivisions(1); ax2->SetNdivisions(1);
1539 ay1->SetNdivisions(208); ay2->SetNdivisions(opt.Contains("highptfit")?104:210);
1540 ax1->SetTickLength(0.02);
1542 //ay1->SetTitle(Form("%s and #color[%d]{%s}",sv.Data(), fitCurveColor, sgf.Data()));
1543 ay1->SetTitle(Form("%s", sv.Data()));
1544 ay2->SetTitle(Form("#frac{%s}{fit}", sv.Data()));
1545 // ay2->SetTitle(Form("#frac{%s}{%s}", sv.Data(), sgf.Data()));
1546 // ax2->SetTitle(Form("#splitline{associated p_{T}^{a}}{#color[%d]{ trigger p_{T}^{t}}} [GeV/c]", divColor));
1547 ax2->SetTitle(Form("#color[%d]{p_{T}^{t}}, p_{T}^{a} [GeV/c]", divColor));
1548 ay1->SetTitleOffset(opt.Contains("highptfit") ? 1. : 0.45);
1549 ay1->SetTitleSize(0.09);
1551 ay2->SetTitleOffset(opt.Contains("highptfit") ? 0.6 : 0.26);
1552 ay2->SetTitleSize(0.14);
1554 ax2->SetLabelOffset(2.1);
1555 ax2->SetTitleOffset(1.3);
1556 ax2->SetTitleSize(0.14);
1559 double leftMarg = opt.Contains("highptfit") ? 0.2 : 0.08;
1561 gPad->SetFrameLineWidth(1);
1562 gPad->SetLeftMargin(leftMarg);
1565 zero.DrawLine(x1, 0., x2, 0.);
1568 // NEW========================================
1569 for (int i=0; i<gi->GetN(); i++) {
1570 int q1 = GlobalIndex(i, 1), q2 = GlobalIndex(i, i);
1571 TF1* ifn = 0, *ifn_hi = 0, *ifn_lo = 0;
1572 // TF1* _ifn = 0, *_ifn_hi = 0, *_ifn_lo = 0; // temp, unscaled.
1574 // This works, but has lines between \ptt groups :(
1575 // TH1F *hfn=0, *hfn_hi=0, *hfn_lo=0;
1576 // int nq = g->GetN();
1577 // hfn = new TH1F(Form("%s_%d", fn->GetName(), i), Form("%s_%d", fn->GetName(), i),
1579 // hfn->SetLineColor(kMagenta);
1580 // for (int q=0; q<g->GetN(); q++) {
1581 // hfn->SetBinContent(q+1, sf*fn->Eval(q+0.5));
1584 ifn = (TF1*) fn->Clone(Form("%s_%d", fn->GetName(), i));
1585 ifn_hi = (TF1*) fn_hi->Clone(Form("%s_%d", fn_hi->GetName(), i));
1586 ifn_lo = (TF1*) fn_lo->Clone(Form("%s_%d", fn_lo->GetName(), i));
1588 ifn->SetName(Form("%s_%d", fn->GetName(), i));
1589 ifn_hi->SetName(Form("%s_%d", fn_hi->GetName(), i));
1590 ifn_lo->SetName(Form("%s_%d", fn_lo->GetName(), i));
1592 double r1 = q1-0.9, r2 = q2+0.92;
1593 ifn->SetRange(r1, r2);
1594 ifn_hi->SetRange(r1, r2);
1595 ifn_lo->SetRange(r1, r2);
1598 // for (int ip=0; ip<ifn->GetNpar(); ip++) {
1599 // double par = ifn->GetParameter(ip);
1600 // ifn->SetParameter(ip, 1000*par);
1601 // cout<<par<< " " << ifn->GetParameter(ip) << endl;
1605 // ifn = new TF1(Form("%s_%d", fn->GetName(), i), Form("100*%s", _ifn->GetName()));
1606 // ifn_hi = new TF1(Form("%s_%d", fn_hi->GetName(), i), Form("100*%s", _ifn_hi->GetName()));
1607 // ifn_lo = new TF1(Form("%s_%d", fn_lo->GetName(), i), Form("100*%s", _ifn_lo->GetName()));
1609 ifn_hi->Draw("same");
1610 ifn_lo->Draw("same");
1612 // hfn->Draw("same");
1614 // NEW========================================
1616 for (int i=0; i<gi->GetN(); i++) {
1617 char* newName = Form("%s_ptt%d", g->GetName(), i);
1618 TGraphErrors* gcol = (TGraphErrors*)g->Clone(newName);
1619 int col = PtColor(ptlow[i], pthigh[i]);
1620 utils.set_tgraph_props(gcol, kBlack, col, kFullSquare, 1.0);
1621 gcol->SetLineWidth(1);
1623 newName = Form("%s_ptt%d", gs->GetName(), i);
1624 TGraphErrors* g_sy = (TGraphErrors*)gs->Clone(newName);
1625 int col_sy = PtColorPale(ptlow[i], pthigh[i]);
1626 utils.set_tgraph_props(g_sy, kBlack, col_sy, kDot, 0.5);
1627 g_sy->SetFillColor(col_sy);
1629 for (int q=0; q<gcol->GetN(); q++) {
1631 ijFromGlobalIndex(q,i2,j);
1633 gcol->SetPoint(q, gcol->GetX()[q], -99.);
1634 g_sy->SetPoint(q, gcol->GetX()[q], -99.);
1637 // Scale points by sf
1638 gcol->SetPoint(q, gcol->GetX()[q], sf*gcol->GetY()[q]);
1639 g_sy->SetPoint(q, g_sy->GetX()[q], sf*g_sy->GetY()[q]);
1640 gcol->SetPointError(q, gcol->GetEX()[q], sf*gcol->GetEY()[q]);
1641 g_sy->SetPointError(q, g_sy->GetEX()[q], sf*g_sy->GetEY()[q]);
1644 g_sy->Draw("e2psame");
1645 gcol->Draw("ezpsame");
1649 gPad->SetFrameLineWidth(1);
1650 gPad->SetLeftMargin(leftMarg);
1652 r_sys->Draw("e2psame");
1654 // Overlay lines, arrows, text, etc.
1655 TLine div, div_a; // division ticks for trigger and assoc
1657 double tipSize = 0.008; // size of arrowhead
1659 div.SetLineWidth(2);
1660 div.SetLineColor(fitCurveColor);
1661 div.DrawLine(x1, 1.0, x2, 1.0);
1665 for (int i=0; i<gi->GetN(); i++) {
1666 char* newName = Form("%s_ptt%d", r->GetName(), i);
1667 TGraphErrors* rcol = (TGraphErrors*)r->Clone(newName);
1668 int col = PtColor(ptlow[i], pthigh[i]);
1669 utils.set_tgraph_props(rcol, kBlack, col, kFullCircle, 1.0);
1670 for (int q=0; q<rcol->GetN(); q++) {
1672 ijFromGlobalIndex(q,i2,j);
1673 if (i2!=i) rcol->SetPoint(q, rcol->GetX()[q], -99.);
1675 rcol->SetLineWidth(1);
1676 rcol->Draw("ezpsame");
1679 div.SetLineColor(divColor);
1680 div.SetLineStyle(kSolid);
1682 // Label centrality and fourier index
1684 ltx.SetTextSize(0.14);
1685 ltx.DrawLatex(opt.Contains("highptfit")?0.25:0.14, 0.85, Form("n = %d", n));
1687 if (!opt.Contains("highptfit")) {
1689 ltx.SetTextSize(0.1);
1691 ltx.DrawLatex(0.14, 0.70, Form("pp 2.76 TeV"));
1693 ltx.DrawLatex(0.14, 0.70, Form("Pb-Pb 2.76 TeV"));
1694 ltx.DrawLatex(0.14, 0.61, Form("%d-%d%%", centlow[k],centhigh[k]));
1696 if (opt.Contains("ptcons")) {
1697 ltx.DrawLatex(0.14, 0.58, Form("#LT#sum p_{T}^{2}#GT = 4.76 GeV^{2}"));
1702 lq->AddEntry(g, Form("V_{n#Delta}"), "epl");
1703 lq->AddEntry(fn, Form("fit"), "l");
1707 ltx.SetTextSize(0.07);
1708 double ptaFitLow = ptlow[ptaLo];
1709 double ptaFitHigh = ptaHi<999? pthigh[ptaHi] : pthigh[maxpt-1];
1710 // if (!opt.Contains("highptfit"))
1711 ltx.DrawLatex(0.14, 0.09,
1712 Form("Global fit range: %3.2g < p_{T}^{a} < min(p_{T}^{t}, %3.2g GeV/c)",
1713 ptaFitLow, ptaFitHigh));
1716 for (int q=0; q<g->GetN(); q++) {
1718 ijFromGlobalIndex(q,i,j);
1720 double ptt = gi->GetX()[i] + gi->GetEX()[i];
1721 double pta = gj->GetX()[j] + gj->GetEX()[j];
1722 double tickLength = 0.03*(y2-y1);
1724 // Draw divisions between trigger pt intervals...
1725 bool skipTicks = opt.Contains("highptfit") && (pta < 5.);
1726 if (i==j && !skipTicks) {
1729 div.DrawLine(q+1, y1, q+1, y1+tickLength);
1731 tickLength = drop-0.1;
1732 div.DrawLine(q+1, ry2-tickLength, q+1, ry2+tickLength);
1733 div.DrawLine(q+1, ry1-tickLength, q+1, ry1+tickLength);
1736 // Alignment: align = 10*HorizontalAlign + VerticalAlign
1737 // For horizontal alignment the following convention applies:
1738 // 1=left adjusted, 2=centered, 3=right adjusted
1739 // For vertical alignment the following convention applies:
1740 // 1=bottom adjusted, 2=centered, 3=top adjusted
1741 ltx2.SetTextAlign(23);
1742 ltx2.SetTextSize(0.12);
1743 ltx2.SetTextColor(divColor);
1745 if (ptt != 0.75) // too cluttered otherwise
1746 ltx2.DrawLatex(q+1, ry1-drop, Form("%.2g", ptt) ); // pt_trig labels
1749 if (pta < ptt && (pta == (int)pta || pta == 0.5) && !skipTicks) {
1750 div_a.DrawLine(q+1, ry1-drop/8, q+1, ry1+drop/4);
1751 ltx2.SetTextColor(kBlack);
1752 ltx2.SetTextFont(52); // italic
1753 ltx2.DrawLatex(q+1, ry1-drop/4, Form("%.2g", pta) ); // pt_assoc labels
1754 ltx2.SetTextColor(divColor);
1755 ltx2.SetTextFont(62); // 62 is default
1758 // Draw arrows to off-scale points
1760 double y = g->GetY()[q];
1761 double ymax = hf1->GetYaxis()->GetXmax();
1762 double ymin = hf1->GetYaxis()->GetXmin();
1763 double len = 0.06*(ymax-ymin);
1764 double gap = 0.01*(ymax-ymin);
1767 a.DrawArrow(q+0.5, ymax-len-gap, q+0.5, ymax-gap, tipSize, ">");
1769 a.DrawArrow(q+0.5, ymin+len+gap, q+0.5, ymin+gap, tipSize, ">");
1771 // Do the same for the ratio.
1772 // If fit has not been applied to some points, don't draw the arrow.
1774 // gPad->SetTickx();
1776 ymax = hf2->GetYaxis()->GetXmax();
1777 ymin = hf2->GetYaxis()->GetXmin();
1778 len = 0.06/0.4*(ymax-ymin); // 0.4 from TwoPanelVert ctor
1779 gap = 0.02*(ymax-ymin);
1781 if (0) { // Draw at upper or lower edge of panel
1783 a.DrawArrow(q+0.5, ymax-len-gap, q+0.5, ymax-gap, tipSize, ">");
1785 a.DrawArrow(q+0.5, ymin+len+gap, q+0.5, ymin+gap, tipSize, ">");
1787 // Draw with arrow based from ref. line.
1788 // No arrow when no fit point!
1789 if (j < ptaLo || j > ptaHi)
1792 a.DrawArrow(q+0.5, 1.0, q+0.5, 1.0+len, tipSize, ">");
1794 a.DrawArrow(q+0.5, 1.0, q+0.5, 1.0-len, tipSize, ">");
1797 // ax2->LabelsOption("h");
1803 TCanvas* DrawVn(int k, int ptt1, int ptt2)
1805 // Draw Fourier coefficients on one canvas for each centrality bin k
1806 // for trigger pt bins from ptt1 to (and including) ptt2.
1807 // The x-axis is associated pt.
1808 const char* name = Form("vndelta_etamin%02d_cent%dto%d_trig%dto%d",
1809 (int)(10*minRidgeDEta), centlow[k],centhigh[k], ptt1, ptt2);
1810 TCanvas* cv = new TCanvas(name, name, 1200, 500);
1811 TLegend* lv = new TLegend(0.09, 0.72, 0.27, 0.88); // w.r.t. cv
1812 lv->SetFillColor(kNone);
1813 lv->SetBorderSize(0);
1815 double lv2bottom = ptt2<5? 0.65 : 0.8;
1816 TLegend* lv2 = new TLegend(0.82, lv2bottom, 0.94, 0.95, "p_{T}^{t} (GeV/c)");
1817 lv2->SetFillColor(kNone);
1818 lv2->SetBorderSize(0);
1819 utils.padsetup(cv, 5, 1, "", 0.12, 0.01, 0.03, 0.2);
1822 double minVn_k=1000, maxVn_k=-1000;
1823 VnLimits(minVn_k, maxVn_k, k, ptt1, ptt2);
1825 for (int n=1; n<=5; n++) {
1827 double vertMargin = 0.1*(maxVn_k - minVn_k);
1828 double xmax = gj->GetX()[ptt2] + gj->GetEX()[ptt2];
1829 double xmin = -0.43;
1830 TH1F* hf = gPad->DrawFrame(xmin, minVn_k - vertMargin,
1831 xmax, maxVn_k + vertMargin);
1835 utils.make_nice_axes(cv, hf, 2., nXticks, nYticks, -0.02, 0.02);
1836 hf->SetLabelOffset(-0.01, "X");
1839 utils.make_nice_axes(cv, hf, 3.4, nXticks, nYticks, -0.075, 0.0);
1840 hf->SetLabelOffset(-0.057, "X");
1841 hf->SetTickLength(0.02, "X");
1842 hf->SetTickLength(0.05, "Y");
1844 hf->GetXaxis()->SetTicks("+-");
1845 hf->GetYaxis()->SetTicks("+-");
1847 // Loop backwards to improve visibility of low-pt points
1848 for (int i=ptt2; i>=ptt1; i--) {
1851 gc = VnDeltaVsPtAssoc(i, k, n);
1853 Error("DrawVn()", "Problem finding graph n%d, i%d, k%d" ,n,i,k);
1857 utils.set_tgraph_props(gc, colorsDark[i], colorsDark[i], kFullSquare, 1.6);
1859 TGraphErrors* gfit = GlobalFitVsPtAssoc(i, k, n);
1861 gfit->Draw("plsame");
1865 lv2->AddEntry(gc,trigLabel(i), "p");
1871 TPad* overlay = new TPad("overlay", "overlay", 0,0,1,1);
1872 overlay->SetFillStyle(4000); // transparent
1876 ltx.SetTextSize(0.07);
1878 ltx.DrawLatex(0.14, 0.76, Form("%s", centLabel(k)));
1880 for (int n=1; n<=4; n++) {
1882 ltx.SetTextSize(n==1? 0.1 : 0.15);
1883 ltx.DrawLatex((n==1)? 0.45 : 0.1, 0.86, Form("V_{%d#Delta}", n));
1886 ltx.DrawLatex(0.72, 0.86, Form("V_{%d#Delta}", 5));
1888 ltx.SetTextSize(0.075);
1889 ltx.DrawLatex(0.4, 0.05, "associated p_{T} [GeV/c]");
1890 ltx.SetTextAngle(90);
1891 ltx.DrawLatex(0.03, 0.4, "V_{n#Delta}(p_{T}^{assoc.})");
1892 ltx.SetTextAngle(0);
1897 TCanvas* DrawVnVsPtTrig(int k, int npta, int ptabins[], TString opt)
1899 TString title = Form("VnDeltaVsPtTrig_cent%dto%d_pTassoc%.2gto%.2g",
1900 centlow[k],centhigh[k],
1901 ptlow[ptabins[0]], pthigh[ptabins[npta-1]]);
1902 if (!opt.IsNull()) {
1906 TCanvas* cv = new TCanvas(title.Data(), title.Data(), 1400, 500);
1907 double lv2bot = 0.9 - 0.07*npta;
1908 TLegend* lv2 = new TLegend(0.82, lv2bot, 0.98, 0.95, "p_{T}^{a} (GeV/c)");
1909 lv2->SetFillColor(kNone);
1910 lv2->SetBorderSize(0);
1911 utils.padsetup(cv, 5, 1, "", 0.12, 0.01, 0.03, 0.2);
1913 // Start without knowing y-limits, adjust below.
1914 double minVn_k=-1., maxVn_k=1.;
1915 TObjArray* graphs = new TObjArray();
1917 for (int n=1; n<=5; n++) {
1919 double vertMargin = 0.1*(maxVn_k - minVn_k);
1921 double xmin = -0.43;
1923 TH1F* hf = gPad->DrawFrame(xmin, minVn_k - 4*vertMargin,
1924 xmax, maxVn_k + vertMargin);
1926 l.DrawLine(xmin, 0, xmax, 0);
1931 utils.make_nice_axes(cv, hf, 2., nXticks, nYticks, -0.02, 0.02);
1932 hf->SetLabelOffset(-0.01, "X");
1935 utils.make_nice_axes(cv, hf, 3.4, nXticks, nYticks, -0.075, 0.0);
1936 hf->SetLabelOffset(-0.057, "X");
1937 hf->SetTickLength(0.02, "X");
1938 hf->SetTickLength(0.05, "Y");
1940 hf->GetXaxis()->SetTicks("+-");
1941 hf->GetYaxis()->SetTicks("+-");
1943 for (int jpta=0; jpta<npta; jpta++) {
1944 int j = ptabins[jpta];
1945 TGraphErrors *gc = VnDeltaVsPtTrig(j, k, n);
1947 Error("DrawVnVsPtTrig()", "Problem finding gc n%d, i%d, k%d" ,n,j,k);
1950 TGraphErrors *gs = VnDeltaVsPtTrig(j, k, n, "sys");
1952 Error("DrawVnVsPtTrig()", "Problem finding gs n%d, i%d, k%d" ,n,j,k);
1956 int col = PtColor(ptlow[j], pthigh[j]);
1957 utils.set_tgraph_props(gc, col, col, kFullSquare, 1.2);
1958 gs->SetFillColor(PtColorPale(ptlow[j], pthigh[j]));
1959 TGraphErrors* open = (TGraphErrors*)gc->Clone();
1960 utils.set_tgraph_props(open, kBlack, kBlack, kOpenSquare, 1.2);
1962 gs->Draw("e2psame");
1964 open->Draw("epsame");
1967 lv2->AddEntry(gc,asscLabel(j), "elp");
1969 graphs->Add(gc); // store graph array to find y limits for plot
1974 double newYmin = 0, newYmax = 0, newSpace = 0;
1975 for (int m=0; m<graphs->GetEntries(); m++) {
1976 TGraphErrors* tg = (TGraphErrors*)graphs->At(m);
1977 double yhi = TMath::MaxElement(tg->GetN()-1, tg->GetY());
1978 double ylo = TMath::MinElement(tg->GetN()-1, tg->GetY());
1979 double ey = TMath::MaxElement(tg->GetN()-1, tg->GetEY());
1981 if (yhi > newYmax) newYmax = yhi;
1982 if (ylo < newYmin) newYmin = ylo;
1984 newSpace = 0.1*(newYmax - newYmin);
1985 for (int n=1; n<=5; n++) {
1987 TH1F* hf = (TH1F*)gPad->FindObject("hframe");
1988 hf->GetYaxis()->SetRangeUser(newYmin-3*newSpace, newYmax+newSpace);
1989 gPad->Modified(); // Signal to redraw
1993 TPad* overlay = new TPad("overlay", "overlay", 0,0,1,1);
1994 overlay->SetFillStyle(4000); // transparent
1998 ltx.SetTextSize(0.05);
1999 ltx.DrawLatex(0.14, 0.88, Form("%s 2.76 TeV", ispp?"pp":"Pb-Pb"));
2000 ltx.SetTextSize(0.07);
2002 ltx.DrawLatex(0.14, 0.8, Form("%s", centLabel(k)));
2004 for (int n=1; n<=5; n++) {
2006 ltx.SetTextSize(n==1? 0.1 : 0.15);
2008 ltx.DrawLatex(0.44, 0.24, Form("n=%d", n));
2010 ltx.DrawLatex(0.04, 0.24, Form("n=%d", n));
2014 ltx.SetTextSize(0.075);
2015 ltx.DrawLatex(0.48, 0.05, "trigger p_{T}^{t} [GeV/c]");
2016 ltx.SetTextAngle(90);
2017 ltx.DrawLatex(0.06, 0.48, "V_{n#Delta} [10^{-2}]");
2018 ltx.SetTextAngle(0);
2022 TGraphErrors* AgreementVsPtSum(int k, int n)
2024 TGraphErrors* gVn = VnDVsQ(n, k);
2025 TF1* fVn = GlobalFitVsQ(n,k);
2026 TGraphErrors* g = new TGraphErrors();
2027 int N = gVn->GetN(); // And f better have the same N.
2030 Error("AgreementVsPtSum()", "Invalid number of points: %d", N);
2034 for (int q=0; q<N; q++) {
2035 ijFromGlobalIndex(q,i,j);
2036 double gy = gVn->GetY()[q];
2037 double fy = fVn->Eval(q+0.5);
2038 double r = TMath::Abs((gy-fy)/gy);
2039 g->SetPoint(q, PtBinCenterSum(i, j), r);
2041 g->SetMarkerStyle(kFullCircle);
2045 TGraph2D* Agreement2D(int k, int n)
2047 TGraphErrors* gVn = VnDVsQ(n, k);
2048 TF1* fVn = GlobalFitVsQ(n,k);
2049 TGraph2D* g = new TGraph2D();
2050 int N = gVn->GetN(); // And f better have the same N.
2053 Error("AgreementVsPtSum()", "Invalid number of points: %d", N);
2057 for (int q=0; q<N; q++) {
2058 ijFromGlobalIndex(q,i,j);
2059 double gy = gVn->GetY()[q];
2060 double fy = fVn->Eval(q+0.5);
2061 double r = TMath::Abs((gy-fy)/fy);
2062 g->SetPoint(q, ptmean[j], ptmean[i], r);
2067 TH2F* Agreement2DHist(int k, int n)
2069 TGraphErrors* gVn = VnDVsQ(n, k);
2070 TF1* fVn = GlobalFitVsQ(n,k);
2074 for (int i=0; i<maxpt; i++) ptarr[i] = gi->GetX()[i] - gi->GetEX()[i];
2075 ptarr[maxpt] = gi->GetX()[maxpt-1] + gi->GetEX()[maxpt-1];
2077 int N = gVn->GetN(); // And f better have the same N.
2080 Error("AgreementVsPtSum()", "Invalid number of points: %d", N);
2083 const char* name = Form("agmt_cent%dto%d_n%d",
2084 centlow[k],centhigh[k], n);
2085 TH2F* h = new TH2F(name, name, maxpt, ptarr, maxpt, ptarr);
2086 h->SetTitle("title;p_{T}^{a};p_{T}^{t};");
2088 for (int q=0; q<N; q++) {
2089 ijFromGlobalIndex(q,i,j);
2090 double gy = gVn->GetY()[q];
2091 double fy = fVn->Eval(q+0.5);
2093 // double r = fy==0? 0 : TMath::Abs(gy-fy) / fy;
2094 double r = gy==0? 0 : TMath::Abs((gy-fy) / gy);
2095 // double r = fy==0? 0 : TMath::Abs(gy / fy);
2096 h->SetBinContent(j+1, i+1, r);
2105 for (int i=0; i<maxpt; i++) ptarr[i] = gi->GetX()[i] - gi->GetEX()[i];
2106 ptarr[maxpt] = gi->GetX()[maxpt-1] + gi->GetEX()[maxpt-1];
2109 const char* name = Form("PttPtaHist");
2110 TH2F* h = new TH2F(name, name, maxpt, ptarr, maxpt, ptarr);
2111 h->SetTitle("title;p_{T}^{a} (GeV/c);p_{T}^{t} (GeV/c);");
2112 h->GetXaxis()->CenterTitle();
2113 h->GetYaxis()->CenterTitle();
2114 int N = maxpt * (maxpt + 1) / 2;
2115 for (int q=0; q<N; q++) {
2116 ijFromGlobalIndex(q,i,j);
2117 h->SetBinContent(j+1, i+1, 1.);
2122 TGraphErrors* Chi2VsTrigPt(int k, int n)
2124 TGraphErrors* g = new TGraphErrors();
2125 for (int i=0; i<maxpt; i++) {
2126 g->SetPoint(i, ptmean[i], ReducedChi2(i, k, n));
2128 g->SetMarkerStyle(kFullCircle);
2133 CorrFnChi2VsTrigPt(int j, int k, int n1, int n2, TString opt)
2135 TGraphErrors* g = new TGraphErrors();
2137 for (int i=j; i<maxpt; i++) {
2138 TH1* h = Hist("RIDGE", "cA", i, j, k);
2139 double x = MeanPt(i, j, k, "t");
2140 double y = Chi2(h, HarmonicSum(h, n1, n2, "global"), opt);
2141 g->SetPoint(ip, x, y);
2144 g->SetMarkerStyle(kFullCircle);
2148 double ReducedChi2(int i, int k, int n)
2150 TGraphErrors* g = VnDeltaVsPtAssoc(i, k, n);
2151 TGraphErrors* f = GlobalFitVsPtAssoc(i, k, n);
2152 int N = g->GetN(); // And f better have the same N.
2155 // Value (or one-sigma error if opt=="err") of v_n
2156 // double vnerr = Bestvn(k,n,i,"err");
2157 double vnerr = vnGF(n,k,i,0,999,"RIDGE","cA","err");
2159 if(N<=0 || N!= f->GetN()) {
2160 Error("ReducedChi2()", "Invalid number of points: %d", N);
2164 for (int j=0; j<N; j++) {
2165 double errj = g->GetEY()[j];
2168 (g->GetY()[j] - f->GetY()[j]) * (g->GetY()[j] - f->GetY()[j]) /
2169 pow(errj + vnerr, 2);
2175 TGraphErrors* VnDeltaVsPtAssoc(int i, int k, int n, TString opt)
2177 // Create a TGraph from VnDelta points
2178 TGraphErrors* gALL = VnDVsQ(n, k, "RIDGE", "cA", opt);
2179 TGraphErrors* g = new TGraphErrors();
2180 TString gname(Form("VnDeltaVsPtAssoc_ptt%d_cent%d_n%d",i,k,n));
2182 g->SetName(gname.Data());
2184 for (int j=0; j<=i; j++) {
2185 int q = GlobalIndex(i, j);
2186 g->SetPoint(j, gj->GetX()[j], gALL->GetY()[q] );
2187 g->SetPointError(j, 0, gALL->GetEY()[q] );
2188 utils.set_tgraph_props(g, colorsDark[i], colorsDark[i], kFullSquare, 1.0);
2195 TGraphErrors* VnDeltaVsPtTrig(int j, int k, int n, TString opt)
2197 // Create a TGraph from VnDelta points
2198 TGraphErrors* gALL = VnDVsQ(n, k, "RIDGE", "cA", opt);
2199 TGraphErrors* g = new TGraphErrors();
2200 TString gname(Form("VnDeltaVsPtTrig_pta%d_cent%dto%d_n%d",
2201 j,centlow[k],centhigh[k],n));
2203 g->SetName(gname.Data());
2206 for (int i=j; i<maxpt; i++) {
2207 int q = GlobalIndex(i, j);
2210 if (opt.Contains("sys")) {
2211 if (gi->GetEX()[i] < 0.126)
2212 xerr = gi->GetEX()[i];
2216 double mpt = MeanPt(i, j, k, "t");
2217 double sf = 100; // Scale y-value; make sure to label accordingly!!
2218 g->SetPoint(ip, mpt, sf*gALL->GetY()[q] );
2219 g->SetPointError(ip, xerr, sf*gALL->GetEY()[q] );
2221 utils.set_tgraph_props(g, colorsDark[j], colorsDark[j], kFullSquare, 1.0);
2229 TGraphErrors* VnDeltaVsN(int i, int j, int k, int nMax, TString opt)
2231 // Create a TGraph from VnDelta points
2232 // Stat errors by default. Call with opt "sys" to get sys errors.
2233 // Call with opt "sine" to get residual <sin n Delta phi> for sys. est.
2234 int q = GlobalIndex(i, j);
2235 TString gname(Form("VnDeltaVsN_ptt%.2gto%.2g_pta%.2gto%.2g_cent%dto%d",
2236 ptlow[i],pthigh[i],ptlow[j],pthigh[j],
2237 centlow[k],centhigh[k]));
2238 if (!opt.IsNull()) {
2242 TGraphErrors* g = (TGraphErrors*) gList->FindObject(gname.Data());
2247 g = new TGraphErrors();
2248 g->SetName(gname.Data());
2252 gStyle->SetEndErrorSize(5);
2253 for (int n=1; n<=nMax; n++) {
2255 TGraphErrors* gALL = VnDVsQ(n, k, "RIDGE", "cA", opt);
2256 double xerr = opt.Contains("sys") ? 0. : 0.0; // 0.2
2257 g->SetPoint(ip, n, 100*gALL->GetY()[q] );
2258 g->SetPointError(ip, xerr, 100*gALL->GetEY()[q] );
2260 cout<<gALL->GetName()<< " " << g->GetY()[ip] << endl;
2265 utils.set_tgraph_props(g, kBlack, kBlack, kFullCircle, 1.2);
2271 TGraphErrors* GlobalvnVsN(int i, int k, int nMax, TString opt)
2273 // Create a TGraph from vn{GF} points
2274 // Stat errors by default. Call with opt "sys" to get sys errors.
2276 TString gname(Form("GlobalvnVsN_pt%.2gto%.2g_cent%dto%d",
2277 ptlow[i],pthigh[i], centlow[k],centhigh[k]));
2278 if (!opt.IsNull()) {
2282 TGraphErrors* g = (TGraphErrors*) gList->FindObject(gname.Data());
2287 g = new TGraphErrors();
2288 g->SetName(gname.Data());
2290 g->SetName(gname.Data());
2293 for (int n=1; n<=nMax; n++) {
2295 // point, stat err, sys err.
2296 double vnp = vnGF(n, k, i, 0, 999, "RIDGE", "cA", "");
2297 double vne = vnGF(n, k, i, 0, 999, "RIDGE", "cA", "err");
2298 double vns = vnGF(n, k, i, 0, 999, "RIDGE", "cA", "sys");
2299 double xerr = opt.Contains("sys") ? 0. : 0.0; // 0.2
2300 double yerr = opt.Contains("sys") ? vns : vne;
2302 g->SetPoint(ip, n, vnp );
2303 g->SetPointError(ip, xerr, yerr);
2307 utils.set_tgraph_props(g, kBlack, kBlack, kFullCircle, 1.2);
2313 TGraphErrors* VnDeltaNFVsN(int i, int j, int k, int nMax, TString opt)
2316 TGraphErrors* VnD = VnDeltaVsN(i,j,k,nMax,opt);
2317 TGraphErrors* vnt = GlobalvnVsN(i,k,nMax,opt);
2318 TGraphErrors* vna = GlobalvnVsN(j,k,nMax,opt);
2319 TString gname(Form("VnDeltaNFVsN_ptt%.2gto%.2g_pta%.2gto%.2g_cent%dto%d",
2320 ptlow[i],pthigh[i],ptlow[j],pthigh[j],
2321 centlow[k],centhigh[k]));
2322 if (!opt.IsNull()) {
2326 TGraphErrors* g = (TGraphErrors*) gList->FindObject(gname.Data());
2331 g = new TGraphErrors();
2332 g->SetName(gname.Data());
2334 g->SetName(gname.Data());
2337 for (int n=1; n<=nMax; n++) {
2339 // Uncertainty vne is stat or sys depending on opt.
2340 double vnp = VnD->GetY()[ip] - 100*vnt->GetY()[ip]*vna->GetY()[ip];
2341 double vne = VnD->GetEY()[ip] - 100*vnt->GetEY()[ip]*vna->GetEY()[ip];
2342 g->SetPoint(ip, n, vnp );
2343 g->SetPointError(ip, 0.0, vne);
2347 utils.set_tgraph_props(g, kBlack, kBlack, kOpenSquare, 1.2);
2353 TF1* GlobalFitVsQ(int n, int k, int ipt1, int ipt2, const char* region,
2354 const char* corrtype, TString opt)
2357 // vn{GF}(trig) x vn{GF}(assc) vs. q, where the points between (and
2358 // including) ipt1 and ipt2 were used in the global fit.
2359 // Note: gfname must be identical format to fnName in GlobalFitVsQ().
2361 TString errType("meas");
2362 if (opt.Contains("hi_sys"))
2364 if (opt.Contains("lo_sys"))
2367 Form("globalFitFn_cent%dto%d_n%d_ptbins%dto%d_%s_corrtype_%s_%s",
2368 centlow[k],centhigh[k], n, ipt1, ipt2,
2369 region, corrtype, errType.Data());
2370 fitfn = (TF1*)gFitList->FindObject(gfname.Data());
2373 Info("GlobalFitVsQ()", "Returning cached TF1 %s", gfname.Data());
2377 // If nonexistent, create (& store) a new one
2378 fitfn = DoGlobalFit(n,k,ipt1,ipt2,region,corrtype,opt);
2379 // fitfn = (TF1*)gFitList->FindObject(gfname.Data());
2382 Warning("GlobalFitVsQ()",
2383 "no fitfn %s,\neven after calling DoGlobalFit()",
2389 TF1* DoGlobalFit(int n, int k, int ipt1, int ipt2,
2390 const char* region, const char* corrtype, TString opt)
2392 // fnName must be identical format to gfname in GlobalFitVsQ().
2393 TF1 *globalFitFn = 0;
2394 TGraphErrors* g = 0;
2395 TString errType("meas");
2396 if (opt.Contains("hi_sys"))
2398 if (opt.Contains("lo_sys"))
2401 Form("globalFitFn_cent%dto%d_n%d_ptbins%dto%d_%s_corrtype_%s_%s",
2402 centlow[k],centhigh[k], n, ipt1, ipt2,
2403 region, corrtype, errType.Data());
2405 g = VnDVsQ(n, k, region, corrtype, opt);
2408 Error("DoGlobalFit()", "No graph found");
2412 // Assign global variables that will get checked in the vntvna
2413 // function during the fit.
2417 // Set up the global fit function...
2418 double qmax = g->GetN() - 0.4999;
2419 int nPars = maxpt + 3;
2420 globalFitFn = new TF1(fnName.Data(), vntvna, 0.0, qmax, nPars);
2422 /* Not needed now, I just flip the v1 points later...AMA 11/15/2011 */
2423 // Each parameter has an equally good minimum at + or - v_nbest. The
2424 // starting value is chosen to steer the fit to the positive "root".
2425 // v_1 is special because it is the only coefficient that crosses
2426 // zero at low pt, so it gets a negative starting point. Pars are
2427 // vn(ipt), then last one is n.
2428 // double startVal = (n==1)? -0.02 : 0.01;
2430 double startVal = 0.01;
2431 for (int ip=0; ip<maxpt; ip++) {
2432 globalFitFn->SetParameter(ip, startVal);
2433 globalFitFn->SetParName(ip, Form("v_%d(%.3g)",n,ptmean[ip]));
2436 // Pass n into vntvna(). Access as par[maxpt].
2437 globalFitFn->FixParameter(maxpt, double(n));
2439 // Pass k into vntvna(). Access as par[maxpt+1].
2440 globalFitFn->FixParameter(maxpt+1, double(k));
2442 // Mom. conservation term prefactor. Access as par[maxpt+2].
2444 globalFitFn->FixParameter(maxpt+2, 0.);
2445 // globalFitFn->SetParLimits(maxpt+2, 0., 1e-3);
2448 globalFitFn->FixParameter(maxpt+2, 0.);
2450 globalFitFn->SetNpx(1000);
2452 TFitResultPtr result = g->Fit(globalFitFn,"QRNS"); // fast, takes ~15 ms
2455 cout<<globalFitFn->GetName();
2459 // migradResult + 10*minosResult + 100*hesseResult + 1000*improveResult
2460 // 0:ok, <0:user error, >0: see above.
2461 int fitStatus = result;
2463 Warning("DoGlobalFit()", "TMinuit status %d", fitStatus);
2465 gFitList->Add(globalFitFn);
2470 double vnGF(int n, int k, int ptBin, int ipt1, int ipt2,
2471 const char* region, const char* corrtype, TString opt)
2475 TF1* gfn = GlobalFitVsQ(n,k,ipt1,ipt2,region,corrtype,opt);
2477 Error("vnGF()", "!gfn");
2478 vn = gfn->GetParameter(ptBin); // ptBin is the q index
2479 err = gfn->GetParError(ptBin);
2481 if (opt.Contains("sys")) {
2482 TF1* hi = GlobalFitVsQ(n,k,ipt1,ipt2,region,corrtype,"hi_sys");
2483 TF1* lo = GlobalFitVsQ(n,k,ipt1,ipt2,region,corrtype,"lo_sys");
2484 double vhi = hi->GetParameter(ptBin);
2485 double vlo = lo->GetParameter(ptBin);
2486 return 0.5*TMath::Abs(vhi-vlo);
2489 // v1 can be negative, otherwise ensure the positive solution is chosen
2490 // if (n>1 && vn < 0)
2493 // if (ptlow[ipt1] > 4.) // !!!!!!!!!!!!!!!!!!!!!!!!!
2494 // vn = TMath::Abs(vn);
2497 // vn += MomCorrection(i, j, k);
2499 return opt.Contains("err") ? err : vn;
2502 TGraphErrors* vnGFvsPt(int n, int k, int ipt1, int ipt2,
2503 const char* region, const char* corrtype, TString opt)
2506 // vn{GF} vs. pt, where the points between (and including) ipt1 and
2507 // ipt2 were used in the global fit.
2508 bool isHighPtFit = ipt1 > 0 && ipt2==999;
2509 bool flipSign = n==1; // Flip v1?
2512 if (opt.Contains("keepsign"))
2514 TString name(Form("v%dGFvsPt_fitpt%dto%d_cent%dto%d",
2515 n, ipt1, ipt2, centlow[k], centhigh[k]));
2516 if (opt.Contains("sys"))
2517 name.Append("_sys");
2518 if (opt.Contains("ptcons"))
2519 name.Append("_ptcons");
2521 TGraphErrors* g = (TGraphErrors*)gList->FindObject(name.Data());
2525 g = new TGraphErrors();
2528 for (int i=0; i<maxpt; i++) {
2530 if (opt.Contains("ptcons"))
2531 opt1.Append("_ptcons");
2532 double vn = vnGF(n,k,i,ipt1,ipt2,region,corrtype,opt1);
2537 // if (isHighPtFit && i<ipt1)
2541 double mpt = MeanPt(i, 0, k, "t");
2544 g->SetPoint(i, mpt, vn);
2546 if (opt.Contains("sys")) {
2547 opt1.Append("_sys");
2548 double ex = (gi->GetEX()[i] < 0.126) ? gi->GetEX()[i] : 0.250;
2549 double vns = vnGF(n,k,i,ipt1,ipt2,region,corrtype, opt1);
2550 g->SetPointError(i, ex, vns);
2551 // g->SetPointError(i, gi->GetEX()[i], vns); // too wide
2554 opt1.Append("_err");
2555 double vne = vnGF(n,k,i,ipt1,ipt2,region,corrtype,opt1);
2556 g->SetPointError(i, 0.0, vne);
2560 int col = CentColor(centlow[k], centhigh[k]);
2561 int col_pale = CentColorPale(centlow[k], centhigh[k]);
2563 g->SetFillColor(col_pale); // for sys
2564 utils.set_tgraph_props(g, col, col, kFullCircle, 1.2);
2566 if (0) cout<<opt.Data()<<endl;
2571 TGraph* Luzumv1(int cent, const char* pid)
2573 // v1 for pions vs pt from viscous hydro calc by Matt Luzum
2574 // valid cent args 0-4 - 10% bins.
2575 // pid = "pi", "K", "p".
2576 const char* dat = Form("v1LHCGlauber%ssv08.dat", pid);
2577 TString fmt("%lg "); // pt
2578 for (int ky=0; ky<5; ky++)
2579 fmt.Append( ky==cent? "%lg " : "%*lg "); // centrality - skip if *lg
2580 return new TGraph(dat, fmt.Data());
2583 TGraphErrors* GlobalFitVsPtAssoc(int i, int k, int n, TString opt)
2585 // Create a TGraph of vnt{gf} x vna{gf} vs. pt_assoc from gfit
2586 TF1* gfit = GlobalFitVsQ(n, k, 0, 999, "RIDGE", cfDef, opt);
2587 TGraphErrors* g = new TGraphErrors();
2588 TString gname(Form("GlobalFitVsPtAssoc_ptt%d_cent%d_n%d",i,k,n));
2593 for (int j=0; j<=i; j++) {
2594 int q = GlobalIndex(i, j);
2595 g->SetPoint(j, gj->GetX()[j], gfit->Eval(q + 0.5) );
2596 g->SetPointError(j, 0, 0 );
2597 utils.set_tgraph_props(g, colorsPale[i], colorsPale[i], kFullCircle, 1.0);
2603 double SineError(int i, int j, int k)
2606 double resid_sin=0, rs_err=0;
2607 TH1* hst = Hist("RIDGE", "cA", i, j, k, "");
2608 double arr[100] = {0};
2610 for (int n=1; n<=gNMax; n++) {
2611 VnDelta(n, *hst, resid_sin, rs_err, "sin");
2612 arr[n-1] = resid_sin;
2615 rms = TMath::RMS(gNMax, arr) / 2;
2617 cout << " SineError: " << rms << endl;
2622 TCanvas* DrawVnDeltaVsN(int nptt, int pttbins[], int npta,
2623 int ptabins[], int ncb, int centbins[], TString opt)
2626 double t1=ptlow[pttbins[0]], t2=pthigh[pttbins[nptt-1]];
2627 double a1=ptlow[ptabins[0]], a2=pthigh[ptabins[npta-1]];
2628 TString cname = Form("VnDeltaVsN_ptt%.2gto%.2g_pta%.2gto%.2g",t1,t2,a1,a2);
2629 if (!opt.IsNull()) {
2633 TCanvas* c = new TCanvas(cname.Data(), cname.Data(), 650,700);
2634 double legbottom = 0.9 - 0.07*ncb;
2635 TLegend* leg = new TLegend(0.62, legbottom, 0.98, 0.98, "Centrality");
2636 leg->SetFillColor(kNone);
2637 leg->SetBorderSize(0);
2638 leg->SetName("leg");
2640 TObjArray* graphs = new TObjArray();
2642 double xmax = opt.Contains("ext") ? gNMax + 0.5 : 8.5;
2643 int nXticks = 10, nYticks = 210;
2645 TH1F* hf = gPad->DrawFrame(xmin, 0.0001, xmax, 0.26);
2646 // bool scale1000 = 0;
2648 hf->SetTitle(Form(";n;V_{n#Delta} [10^{-2}]"));
2649 if (opt.Contains("sine"))
2650 hf->SetTitle(Form(";n;#LTsin(n#Delta#phi)#GT [10^{-2}]"));
2652 // if (opt.Contains("ext") )
2653 // if (!opt.Contains("sine")) {
2655 // hf->SetTitle(Form(";n;V_{n#Delta}"));
2658 l.SetLineStyle(kDashed);
2660 utils.make_nice_axes(c, hf, 1.3, nXticks, nYticks, 1.4,-1.4);
2661 hf->SetLabelOffset(0.0, "X");
2662 hf->SetTitleOffset(-1.96, "Y");
2664 hf->GetXaxis()->SetTicks("+-");
2665 hf->GetYaxis()->SetTicks("+-");
2666 l.DrawLine(hf->GetXaxis()->GetXmin(), 0, hf->GetXaxis()->GetXmax(),0);
2667 gPad->SetLeftMargin(0.22);
2668 gPad->SetTopMargin(0.01);
2669 gPad->SetRightMargin(0.01);
2671 for (int i=0; i<nptt; i++) {
2672 for (int j=0; j<npta; j++) {
2673 for(int k=0; k<ncb; k++) {
2675 // Stat errors on g, sys errors on gs.
2676 TString opt1 = opt.Contains("sine") ? "sine" : "";
2678 VnDeltaVsN(pttbins[i], ptabins[j], centbins[k], gNMax, opt1);
2680 VnDeltaVsN(pttbins[i], ptabins[j], centbins[k], gNMax, "sys");
2681 TGraphErrors* gc = (TGraphErrors*)g->Clone();
2682 int dark = CentColor(centlow[centbins[k]], centhigh[centbins[k]]);
2683 int pale = CentColorPale(centlow[centbins[k]], centhigh[centbins[k]]);
2684 utils.set_tgraph_props(g, dark, dark, kFullCircle, 1.5);
2685 utils.set_tgraph_props(gs, dark, dark, kDot, 2.);
2686 utils.set_tgraph_props(gc, kBlack, kBlack, kOpenCircle, 1.5);
2687 g->SetFillColor(pale);
2688 gs->SetFillColor(dark);
2690 TGraphErrors* gnf = 0;
2691 TGraphErrors* gnf_sys = 0;
2692 TGraphErrors* gnf_solid = 0;
2693 if (opt.Contains("vnf")) { // Non-factorizing part
2695 VnDeltaNFVsN(pttbins[i], ptabins[j], centbins[k], gNMax, "");
2697 VnDeltaNFVsN(pttbins[i], ptabins[j], centbins[k], gNMax, "sys");
2699 // Just for appearance...
2700 gnf_solid = (TGraphErrors*) gnf->Clone(Form("%s_solid", gnf->GetName()));
2701 utils.set_tgraph_props(gnf_solid, pale, pale, kFullSquare, gnf->GetMarkerSize());
2704 // for (int ip=0; ip<g->GetN(); ip++) {
2705 // g->SetPoint(ip, g->GetX()[ip], 1000* g->GetY()[ip]);
2706 // gs->SetPoint(ip, gs->GetX()[ip], 1000*gs->GetY()[ip]);
2707 // gc->SetPoint(ip, gc->GetX()[ip], 1000*gc->GetY()[ip]);
2709 // g->SetPointError(ip, g->GetEX()[ip], 1000* g->GetEY()[ip]);
2710 // gs->SetPointError(ip, gs->GetEX()[ip], 1000*gs->GetEY()[ip]);
2711 // gc->SetPointError(ip, gc->GetEX()[ip], 1000*gc->GetEY()[ip]);
2715 if (opt.Contains("sine")) {
2716 g->Fit("pol0", "Q");
2717 TF1* gfit = g->GetFunction("pol0");
2718 gfit->SetLineColor(dark);
2721 else if (!opt.Contains("nobars"))
2722 g->Draw("Bsame"); // bars
2724 if (opt.Contains("vnf")) { // Non-factorizing part
2725 utils.draw_errorbox(gnf_sys, pale, 0.3);
2726 gnf_solid->Draw("epsame");
2727 gnf->Draw("epsame");
2730 g->Draw("psame"); // colored markers
2731 gc->Draw("epsame"); // open markers w/black stat error bars
2733 if (!opt.Contains("sine"))
2734 utils.draw_errorbox(gs, dark, 0.3);
2737 leg->AddEntry(g,Form("%d-%d%%",centlow[centbins[k]],centhigh[centbins[k]]),"l,p");
2739 if (opt.Contains("vnf")) { // Non-factorizing part
2740 leg->AddEntry(gnf_solid,"NF V_{n#Delta}","l,p");
2741 // leg->AddEntry(gnf_solid,"[v_{n}(p_{T}^{t}) #times v_{n}(p_{T}^{a})]_{GF}","l,p");
2750 double newYmin = 0, newYmax = 0, newSpace = 0;
2751 for (int m=0; m<graphs->GetEntries(); m++) {
2752 TGraphErrors* tg = (TGraphErrors*)graphs->At(m);
2753 double yhi = TMath::MaxElement(tg->GetN()-1, tg->GetY());
2754 double ylo = TMath::MinElement(tg->GetN()-1, tg->GetY());
2755 if (yhi > newYmax) newYmax = yhi;
2756 if (ylo < newYmin) newYmin = ylo;
2759 newSpace = 0.1*(newYmax - newYmin);
2761 if (opt.Contains("ext"))
2762 hf->GetYaxis()->SetRangeUser(newYmin-newSpace, newYmax+4*newSpace);
2764 hf->GetYaxis()->SetRangeUser(newYmin-newSpace, newYmax+newSpace);
2766 // if (opt.Contains("sine")) {
2767 // hf->GetYaxis()->SetRangeUser(0.0001, newYmax+4*newSpace);
2771 if (!opt.Contains("sine"))
2775 ltx.SetTextSize(0.04); // 0.05
2777 if ( opt.Contains("sine") )
2779 else if (opt.Contains("ext") && !opt.Contains("vnf") )
2782 double xstart = 0.6;
2783 ltx.DrawLatex(xstart, legbottom-1*0.07, Form("%.2g < p_{T}^{t} < %.2g GeV/c", t1, t2));
2784 ltx.DrawLatex(xstart, legbottom-2*0.07, Form("%.2g < p_{T}^{a} < %.2g GeV/c", a1, a2));
2791 TCanvas* DrawGlobalvnVsN(int npt, int ptbins[], int ncb, int centbins[], TString opt)
2793 double t1=ptlow[ptbins[0]], t2=pthigh[ptbins[npt-1]];
2794 TString cname = Form("GlobalvnVsN_pt%.2gto%.2g",t1,t2);
2795 if (!opt.IsNull()) {
2799 TCanvas* c = new TCanvas(cname.Data(), cname.Data(), 600,700);
2800 double legbottom = 0.9 - 0.07*ncb;
2801 TLegend* leg = new TLegend(0.62, legbottom, 0.98, 0.98, "Centrality");
2802 leg->SetFillColor(kNone);
2803 leg->SetBorderSize(0);
2804 leg->SetName("leg");
2806 TObjArray* graphs = new TObjArray();
2807 double xmin = opt.Contains("zoom") ? 2.6 : 0.4;
2809 int nXticks = 10, nYticks = 210;
2811 TH1F* hf = gPad->DrawFrame(xmin, -0.06, xmax, 0.26);
2812 hf->SetTitle(Form(";n;v_{n}{GF}"));
2813 l.SetLineStyle(kDashed);
2815 utils.make_nice_axes(c, hf, 1.3, nXticks, nYticks, 1.4,-1.4);
2816 hf->SetLabelOffset(0.0, "X");
2817 if (opt.Contains("zoom"))
2818 hf->SetTitleOffset(-2.3, "Y");
2820 hf->SetTitleOffset(-1.9, "Y");
2822 hf->GetXaxis()->SetTicks("+-");
2823 hf->GetYaxis()->SetTicks("+-");
2824 l.DrawLine(hf->GetXaxis()->GetXmin(), 0, hf->GetXaxis()->GetXmax(),0);
2825 if (opt.Contains("zoom"))
2826 gPad->SetLeftMargin(0.25);
2828 gPad->SetLeftMargin(0.2);
2829 gPad->SetTopMargin(0.01);
2830 gPad->SetRightMargin(0.01);
2832 for (int i=0; i<npt; i++) {
2833 for(int k=0; k<ncb; k++) {
2835 // Stat errors on g, sys errors on gs.
2836 TGraphErrors* g = GlobalvnVsN(ptbins[i], centbins[k], gNMax, "");
2837 TGraphErrors* gs = GlobalvnVsN(ptbins[i], centbins[k], gNMax, "sys");
2838 TGraphErrors* gc = (TGraphErrors*)g->Clone();
2839 int dark = CentColor(centlow[centbins[k]], centhigh[centbins[k]]);
2840 int pale = CentColorPale(centlow[centbins[k]], centhigh[centbins[k]]);
2841 utils.set_tgraph_props(g, dark, dark, kFullCircle, 1.5);
2842 // utils.set_tgraph_props(gs, dark, dark, kDot, 2.);
2843 utils.set_tgraph_props(gc, kBlack, kBlack, kOpenCircle, 1.5);
2844 g->SetFillColor(pale);
2845 // gs->SetFillColor(dark);
2846 g->Draw("Bsame"); // colored bars
2847 utils.draw_errorbox(gs, dark, 0.3);
2848 g->Draw("psame"); // colored markers
2849 // gs->Draw("e[]psame"); // sys error filled rectangles
2850 gc->Draw("epsame"); // open markers w/black stat error bars
2852 leg->AddEntry(g,Form("%d-%d%%",centlow[centbins[k]],centhigh[centbins[k]]),"l,p");
2857 double newYmin = 0, newYmax = 0, newSpace = 0;
2858 for (int m=0; m<graphs->GetEntries(); m++) {
2859 TGraphErrors* tg = (TGraphErrors*)graphs->At(m);
2860 double yhi = TMath::MaxElement(tg->GetN()-1, tg->GetY());
2861 double ylo = TMath::MinElement(tg->GetN()-1, tg->GetY());
2862 if (yhi > newYmax) newYmax = yhi;
2863 if (ylo < newYmin) newYmin = ylo;
2866 newSpace = 0.1*(newYmax - newYmin);
2867 hf->GetYaxis()->SetRangeUser(newYmin-newSpace, newYmax+newSpace);
2868 if (opt.Contains("zoom"))
2869 hf->GetYaxis()->SetRangeUser(-0.0008, 0.0085);
2875 // if (opt.Contains("zoom"))
2876 // ltx.SetTextSize(0.03); // 0.04
2879 // ltx.SetTextSize(0.04); // 0.05
2881 double xstart = (opt.Contains("zoom")) ? 0.7 : 0.6;
2882 ltx.DrawLatex(xstart, legbottom-1*0.07, Form("%.2g < p_{T} < %.2g GeV/c", t1, t2));
2883 // ltx.DrawLatex(xstart, legbottom-2*0.07, Form("%.2g < p_{T}^{assoc} < %.2g GeV/c", a1, a2));
2889 TCanvas* DrawVnFromGlobalFit(int n, int ipt1, int ipt2, int ncb,
2890 int centbins[], TString opt)
2892 // Draw vn for one n on one canvas - many centralities
2894 double maxPtFit = ipt2==999 ? pthigh[maxpt-1] : pthigh[ipt2];
2895 const char* cname = Form("v%d_global%s_ptfit%.2gto%.2g",
2896 n, opt.Data(), ptlow[ipt1], maxPtFit);
2897 const char* title = Form("v%d_global%s_ptfit%.2gto%.2g",
2898 n, opt.Data(), ptlow[ipt1], maxPtFit);
2899 double lvleft = opt.Contains("multi")? 0.74 : 0.82;
2900 double lvbot = opt.Contains("multi")? 0.25 : 0.56;
2901 int cvHeight = opt.Contains("multi")? 500 : 500;
2902 TCanvas* cv = new TCanvas(cname, title, 700, cvHeight);
2903 TLegend* lv = new TLegend(lvleft, lvbot, 0.99, 0.97);
2904 lv->SetFillColor(kNone); lv->SetName("lv");
2906 lv->SetBorderSize(1);
2907 lv->SetHeader("#splitline{Fit range}{(GeV/c):}");
2908 utils.padsetup(cv, 1, 1, "", 0.12, 0.01, 0.03, 0.2); // ######
2909 // gPad->SetRightMargin(0.15);
2914 TObjArray* graphs = new TObjArray();
2915 double xmin = 0., xmax = 14.8; // 8.3;
2916 double ymin = -0.06, ymax = 0.26;
2917 if (opt.Contains("multi")) {
2921 TH1F* hf = gPad->DrawFrame(xmin, ymin, xmax, ymax);
2922 hf->SetTitle(Form(";p_{T}^{t} (GeV/c);v_{%d}{GF}",n));
2926 l.SetLineStyle(kDashed);
2929 inset = new TPad("inset", "inset", 0.18, 0.18, 0.45, 0.59, kNone, 1, 0);
2932 TH1F* hfi = gPad->DrawFrame(-0.05, -0.04, 4.2, 0.16);
2933 TAxis* hx = hfi->GetXaxis();
2934 TAxis* hy = hfi->GetYaxis();
2935 hx->SetLabelSize(0.1);
2936 hy->SetLabelSize(0.1);
2937 hx->SetNdivisions(104);
2938 hy->SetNdivisions(104);
2939 gPad->SetBottomMargin(0.2);
2940 gPad->SetLeftMargin(0.2);
2941 gPad->SetRightMargin(0.01);
2942 gPad->SetTopMargin(0.01);
2943 // utils.make_nice_axes(inset, hfi, 3, nXticks, nYticks, 1.4,-1.4);
2944 l.DrawLine(-0.05, 0, 4.2, 0);
2948 utils.make_nice_axes(cv, hf, 1.3, nXticks, nYticks, 1.4,-1.4);
2949 hf->SetLabelOffset(0.0, "X");
2950 hf->SetTitleOffset(1.5, "Y");
2951 hf->GetXaxis()->SetTicks("+");
2952 // hf->GetYaxis()->SetTicks("+-");
2955 if (opt.Contains("luzum")) {
2956 int lSty[] = {7, kSolid, kSolid};
2957 int lCol[] = {kBlack, kCyan, kBlue, kGreen+1, kRed};
2958 TString pidString[] = {"pi", "K", "p"};
2959 for (int m=0; m<5; m++) {
2960 for (int pid=0; pid<3; pid++) {
2961 v1h[m][pid] = Luzumv1(m, pidString[pid].Data());
2962 TGraph* g1 = v1h[m][pid];
2963 g1->SetLineStyle(lSty[pid]);
2964 g1->SetLineColor(lCol[m]);
2965 g1->SetLineWidth(2);
2968 hf->GetXaxis()->SetRangeUser(0, 4.8);
2969 l.DrawLine(0, 0, 4.8, 0);
2970 v1h[0][0]->Draw("plsame");
2971 v1h[0][2]->Draw("plsame");
2972 v1h[4][0]->Draw("plsame");
2973 v1h[4][2]->Draw("plsame");
2976 l.DrawLine(hf->GetXaxis()->GetXmin(), 0, hf->GetXaxis()->GetXmax(),0);
2978 for (int cb=0; cb<ncb; cb++) {
2979 int k = centbins[cb];
2981 if (!opt.Contains("multi")) {
2982 // last 2 args are included pt bins
2983 TGraphErrors* gtmp = vnGFvsPt(n, k, ipt1, ipt2);
2985 // clone to modify without ripples
2986 TGraphErrors* gc = (TGraphErrors*) gtmp->Clone();
2988 Error("DrawVnFromGlobalFit()", "Problem making graph" );
2991 TGraphErrors* gtmp_sys = vnGFvsPt(n, k, ipt1, ipt2, "RIDGE", cfDef, "sys");
2992 TGraphErrors* gs = (TGraphErrors*) gtmp_sys->Clone();
2994 if (opt.Contains("luzum")) {
2996 utils.set_tgraph_props(gc, kBlue, kBlue, kFullCircle, 1.2);
2998 utils.set_tgraph_props(gc, kRed, kRed, kFullCircle, 1.2);
3001 utils.draw_errorbox(gs, gs->GetFillColor());
3005 TGraphErrors* open = (TGraphErrors*) gc->Clone(Form("%s_open", gc->GetName()));
3006 utils.set_tgraph_props(open, kBlack, kBlack, kOpenCircle, 1.2);
3007 open->Draw("epsame");
3009 lv->AddEntry(gc,Form("%d-%d%%",centlow[k],centhigh[k]),"l,p");
3012 if (opt.Contains("multi")) {
3018 TGraphErrors* gg1 = vnGFvsPt(n, k, b1, b2, "RIDGE", cfDef, "");
3019 TGraphErrors* gg2 = vnGFvsPt(n, k, b3, b4, "RIDGE", cfDef, "keepsign");
3020 TGraphErrors* gs1 = vnGFvsPt(n, k, b1, b2, "RIDGE", cfDef, "sys");
3021 TGraphErrors* gs2 = vnGFvsPt(n, k, b3, b4, "RIDGE", cfDef, "sys_keepsign");
3022 utils.set_tgraph_props(gg1, gg1->GetLineColor(), gg1->GetMarkerColor(), kOpenCircle, 1.0);
3023 utils.set_tgraph_props(gg2, gg2->GetLineColor(), gg2->GetMarkerColor(), kFullSquare, 1.0);
3025 utils.draw_errorbox(gs1, gs1->GetFillColor());
3026 utils.draw_errorbox(gs2, gs2->GetFillColor());
3027 gg1->Draw("epsame");
3028 gg2->Draw("epsame");
3031 const char* s1 = Form("#splitline{%.2g < p_{T}^{a} < %.2g }{%d-%d%%}",
3032 ptlow[b1], pthigh[b2], centlow[k],centhigh[k]);
3033 const char* s2 = Form("#splitline{%.2g < p_{T}^{a} < %.2g }{%d-%d%%}",
3034 ptlow[b3], pthigh[b4], centlow[k],centhigh[k]);
3035 lv->AddEntry(gg1, s1, "l,p");
3036 lv->AddEntry(gg2, s2, "l,p");
3041 gg1->Draw("epsame");
3042 gg2->Draw("epsame");
3048 } // centrality bin loop
3050 if (opt.Contains("luzum")) {
3051 lv->AddEntry(v1h[0][0], Form("v.h. (#pi)"),"l,p");
3052 lv->AddEntry(v1h[0][2], Form("v.h. (p)"), "l,p");
3055 ltx.SetTextSize(0.05);
3057 if (opt.Contains("multi")) {
3058 gPad->SetTopMargin(0.02);
3060 ltx.DrawLatex(0.19, 0.92, Form("%s", "#splitline{pp}{2.76 TeV}"));
3062 ltx.DrawLatex(0.19, 0.92, Form("%s", "#splitline{Pb-Pb}{2.76 TeV}"));
3063 ltx.DrawLatex(0.49, 0.94, Form("%.2g < |#Delta#eta| < 1.8", minRidgeDEta) );
3067 ltx.DrawLatex(0.17, 0.88, Form("%.2g < |#Delta#eta| < 1.8", minRidgeDEta) );
3068 ltx.DrawLatex(0.17, 0.94, Form("%.2g < fit p_{T}^{a} < %.2g GeV/c",
3069 ptlow[ipt1], maxPtFit));
3070 ltx.DrawLatex(0.19, 0.78, Form("%s", "#splitline{Pb-Pb}{2.76 TeV}"));
3072 double newYmin = 0, newYmax = 0, newSpace = 0;
3073 for (int m=0; m<graphs->GetEntries(); m++) {
3074 TGraphErrors* tg = (TGraphErrors*)graphs->At(m);
3075 double yhi = TMath::MaxElement(tg->GetN()-1, tg->GetY());
3076 double ylo = TMath::MinElement(tg->GetN()-1, tg->GetY());
3077 if (yhi > newYmax) newYmax = yhi;
3078 if (ylo < newYmin) newYmin = ylo;
3081 if (opt.Contains("multi")) {
3088 newSpace = 0.2*(newYmax - newYmin);
3089 // if (opt.Contains("multi")) newSpace /= 2;
3090 if (n==5) newSpace *= 2;
3091 hf->GetYaxis()->SetRangeUser(newYmin-newSpace, newYmax+newSpace);
3098 TCanvas* Drawv1to5(int ncb, int centbins[], int ipt1, int ipt2, TString opt)
3101 cout<<opt.Data()<<endl;
3104 int cent1 = centlow[0];
3105 int cent2 = centhigh[centbins[ncb-1]];
3108 pmax = pthigh[ipt2];
3109 const char* cname = Form("vn_etamin%02d_cent%dto%d_fitptbin%dto%d",
3110 (int)(10*minRidgeDEta), cent1, cent2, ipt1, ipt2);
3111 const char* title = Form("v1to5gf_etamin%02d_cent%dto%d_fitpt%.2gto%.2g",
3112 (int)(10*minRidgeDEta), cent1, cent2, ptlow[ipt1], pmax);
3113 TCanvas* cv = new TCanvas(cname, title, 1400, 500);
3114 TLegend* lv = new TLegend(0.09, 0.72, 0.27, 0.88);
3115 lv->SetFillColor(kNone);
3116 lv->SetBorderSize(0);
3118 double lv2bottom = 0.62;
3119 TLegend* lv2 = new TLegend(0.82, lv2bottom, 0.93, 0.95, "Centrality");
3120 lv2->SetFillColor(kNone);
3121 lv2->SetBorderSize(0);
3122 utils.padsetup(cv, 5, 1, "", 0.12, 0.01, 0.03, 0.2);
3124 for (int n=1; n<=5; n++) {
3125 Printf("Drawv1to5() n = %d / 5", n);
3127 double xmin = -0.43, xmax = 8.3;
3128 double ymin = -0.09, ymax = 0.26;
3129 if (ptlow[ipt1] > 4.) {
3133 if (pthigh[ipt2] > 6.) {
3137 if (opt.Contains("split")) {
3144 TH1F* hf = gPad->DrawFrame(xmin, ymin, xmax, ymax);
3148 utils.make_nice_axes(cv, hf, 2., nXticks, nYticks, -0.02, 0.02);
3149 hf->SetLabelOffset(-0.01, "X");
3152 utils.make_nice_axes(cv, hf, 3.4, nXticks, nYticks, -0.075, 0.0);
3153 hf->SetLabelOffset(-0.057, "X");
3154 hf->SetTickLength(0.02, "X");
3155 hf->SetTickLength(0.05, "Y");
3157 hf->GetXaxis()->SetTicks("+-");
3158 hf->GetYaxis()->SetTicks("+-");
3159 zero.SetLineStyle(kDashed);
3160 zero.DrawLine(xmin, 0., xmax, 0.);
3162 // Loop thru every cent bin. Skip non-requested ones.
3163 // for (int k=0; k<maxcent; k++) {
3165 // if (ncb != 999) {
3167 // for (int cb=0; cb<ncb; cb++)
3168 // if(k==centbins[cb])
3174 for (int cb=0; cb<ncb; cb++) {
3175 int k = centbins[cb];
3176 TGraphErrors* gc = vnGFvsPt(n, k, ipt1, ipt2);
3177 TGraphErrors* gs = vnGFvsPt(n, k, ipt1, ipt2, "RIDGE", cfDef, "sys");
3180 Error("Drawv1to5()", "Problem finding graph");
3184 TGraphErrors* gc_hipt=0;
3185 TGraphErrors* gs_hipt=0;
3186 if (opt.Contains("highptfit") || opt.Contains("split")) {
3187 gc_hipt = vnGFvsPt(n, k, ipt2+1, 999, "highptfit");
3188 gs_hipt = vnGFvsPt(n, k, ipt2+1, 999, "RIDGE", cfDef, "sys");
3189 gc_hipt->SetMarkerStyle(kOpenCircle);
3192 int pale = gs->GetFillColor(); // it is CentColor(centlow[k], centhigh[k]).
3193 utils.draw_errorbox(gs, pale);
3196 if (opt.Contains("split")) {
3197 utils.draw_errorbox(gs_hipt, pale);
3198 gc_hipt->Draw("epsame");
3201 TGraphErrors* open = (TGraphErrors*) gc->Clone(Form("%s_open", gc->GetName()));
3202 utils.set_tgraph_props(open, kBlack, kBlack, kOpenCircle, 1.2);
3203 open->Draw("epsame");
3206 lv2->AddEntry(gc,Form("%d-%d%%",centlow[k],centhigh[k]),"l,p");
3209 } // Fourier moment n
3212 TPad* overlay = new TPad("overlay", "overlay", 0,0,1,1);
3213 overlay->SetFillStyle(4000); // transparent
3217 ltx.SetTextSize(0.07);
3220 for (int n=1; n<=5; n++) {
3222 ltx.SetTextSize(n==1? 0.1 : 0.15);
3223 ltx.DrawLatex((n==1)? 0.85 : 0.7, 0.86, Form("v_{%d}", n));
3226 AddPrelimStampToCurrentPad(0.45,0.7,0.75,0.95, "");
3229 ltx.SetTextSize(0.075);
3230 ltx.DrawLatex(0.5, 0.05, "p_{T} [GeV/c]");
3231 ltx.SetTextAngle(90);
3232 ltx.DrawLatex(0.05, 0.5, "v_{n }(p_{T})");
3233 ltx.SetTextAngle(0);
3234 ltx.SetTextSize(0.05);
3235 ltx.DrawLatex(0.14, 0.88, Form("%s", "#splitline{Pb-Pb}{2.76 TeV}"));
3236 ltx.SetTextSize(0.05);
3237 ltx.DrawLatex(0.13, 0.24, Form("%.2g < |#Delta#eta| < 1.8", minRidgeDEta) );
3239 const char* frange = Form("%.2g < fit p_{T}^{a} < %.2g GeV",
3241 const char* frange1 = Form("#splitline{solid:}{%.2g < fit p_{T}^{a} < %.2g GeV}",
3242 ptlow[ipt1], pthigh[ipt2]);
3243 const char* frange2 = Form("#splitline{open:}{%.2g < fit p_{T}^{a} < %.2g GeV}",
3244 ptlow[ipt2+1], pthigh[maxpt-1]);
3246 if (opt.Contains("split")) {
3247 ltx.SetTextSize(0.04);
3248 ltx.DrawLatex(0.31, 0.8, frange1);
3249 ltx.DrawLatex(0.31, 0.7, frange2);
3252 ltx.DrawLatex(0.3, 0.27, frange);
3257 TCanvas* Drawv2to5(int ncb, int centbins[], int ipt1, int ipt2, TString opt)
3260 cout<<opt.Data()<<endl;
3263 int cent1 = centlow[0];
3264 int cent2 = centhigh[centbins[ncb-1]];
3267 pmax = pthigh[ipt2];
3268 const char* cname = Form("v2to5_etamin%02d_cent%dto%d_fitptbin%dto%d",
3269 (int)(10*minRidgeDEta), cent1, cent2, ipt1, ipt2);
3270 const char* title = Form("v2to5gf_etamin%02d_cent%dto%d_fitpt%.2gto%.2g",
3271 (int)(10*minRidgeDEta), cent1, cent2, ptlow[ipt1], pmax);
3272 TCanvas* cv = new TCanvas(cname, title, 1400, 500);
3274 double lv2bottom = 0.58; // 0.5;
3275 TLegend* lv2 = new TLegend(0.77, lv2bottom, 0.9, 0.95, "Centrality");
3276 lv2->SetFillColor(kNone);
3277 lv2->SetBorderSize(0);
3278 utils.padsetup(cv, 4, 1, "", 0.08, 0.01, 0.03, 0.2);
3280 for (int n=2; n<=5; n++) {
3281 Printf("Drawv2to5() n = %d", n);
3285 TH1F* hf = gPad->DrawFrame(xmin, -0.12, xmax, 0.26); //was y = -0.03, 0.26
3289 utils.make_nice_axes(cv, hf, 2., nXticks, nYticks, -0.02, 0.02);
3290 hf->SetLabelOffset(0.0, "X"); // hf->SetLabelOffset(-0.01, "X");
3293 utils.make_nice_axes(cv, hf, 2.6, nXticks, nYticks, -0.075, 0.0);
3294 hf->SetLabelOffset(-0.02, "X");
3295 hf->SetTickLength(0.02, "X");
3296 hf->SetTickLength(0.05, "Y");
3298 hf->GetXaxis()->SetTicks("+-");
3299 hf->GetYaxis()->SetTicks("+-");
3300 zero.SetLineStyle(kDashed);
3301 zero.DrawLine(xmin, 0., xmax, 0.);
3303 for (int cb=0; cb<ncb; cb++) {
3304 int k = centbins[cb];
3306 TGraphErrors* gc = vnGFvsPt(n, k, ipt1, ipt2);
3307 TGraphErrors* gs = vnGFvsPt(n, k, ipt1, ipt2, "RIDGE", cfDef, "sys");
3310 Error("Drawv2to5()", "Problem finding graph");
3314 int pale = gs->GetFillColor(); // it is CentColor(centlow[k], centhigh[k]).
3315 utils.draw_errorbox(gs, pale);
3316 // gs->Draw("e2psame");
3318 TGraphErrors* open = (TGraphErrors*) gc->Clone(Form("%s_open", gc->GetName()));
3319 utils.set_tgraph_props(open, kBlack, kBlack, kOpenCircle, 1.2);
3320 open->Draw("epsame");
3323 lv2->AddEntry(gc,Form("%d-%d%%",centlow[k],centhigh[k]),"l,p");
3326 } // Fourier moment n
3329 TPad* overlay = new TPad("overlay", "overlay", 0,0,1,1);
3330 overlay->SetFillStyle(4000); // transparent
3334 ltx.SetTextSize(0.07);
3337 for (int n=2; n<=5; n++) {
3339 ltx.SetTextSize(n==2? 0.1 : 0.15);
3340 ltx.DrawLatex((n==2)? 0.85 : 0.7, 0.86, Form("v_{%d}", n));
3343 ltx.SetTextSize(0.075);
3344 ltx.DrawLatex(0.48, 0.04, "p_{T} [GeV/c]");
3345 ltx.SetTextAngle(90);
3346 ltx.DrawLatex(0.02, 0.5, "v_{n }{GF}");
3347 ltx.SetTextAngle(0);
3348 ltx.SetTextSize(0.05);
3349 ltx.DrawLatex(0.33, 0.88, Form("%s", "#splitline{Pb-Pb}{2.76 TeV}"));
3350 ltx.SetTextSize(0.05);
3351 ltx.DrawLatex(0.33, 0.75, Form("%.2g < |#Delta#eta| < 1.8", minRidgeDEta) );
3353 const char* frange = Form("#splitline{Global fit range}{%.2g < p_{T} < %.2g GeV}",
3355 ltx.DrawLatex(0.56, 0.75, frange);
3360 TCanvas* DrawChi2vsPtTrig(int npta, int ptabins[], int ncb, int centbins[], TString opt)
3363 // TODO: options-- global or 1to5, chi2/N or prob
3364 double a1=ptlow[ptabins[0]], a2=pthigh[ptabins[npta-1]];
3365 int c1=centlow[centbins[0]], c2=centhigh[centbins[ncb-1]];
3366 TString cname = Form("chi2_etamin%02d_pta%.2gto%.2g_cent%dto%d",
3367 (int)(10*minRidgeDEta), a1, a2, c1, c2 );
3369 if (!opt.IsNull() ) {
3371 cname.Append(opt.Data());
3374 TCanvas* cv = new TCanvas(cname, cname, 1);
3375 TLegend* lv = new TLegend(0.09, 0.72, 0.27, 0.88); // w.r.t. cv
3376 lv->SetFillColor(kNone);
3377 lv->SetBorderSize(0);
3379 double lv2bottom = 0.62;
3380 TLegend* lv2 = new TLegend(0.82, lv2bottom, 0.93, 0.95, "Centrality"); // w.r.t. cv
3381 lv2->SetFillColor(kNone);
3382 lv2->SetBorderSize(0);
3383 utils.padsetup(cv, 1, 1, "", 0.12, 0.01, 0.03, 0.2);
3385 double xmin = -0.43;
3387 TH1F* hf = gPad->DrawFrame(xmin, -0.09, xmax, 26);
3388 // int nXticks = 210;
3389 // int nYticks = 210;
3390 hf->GetXaxis()->SetTicks("+-");
3391 hf->GetYaxis()->SetTicks("+-");
3393 // IN PROGRESS---------------
3394 for (int j=0; j<npta; j++) {
3395 for(int k=0; k<ncb; k++) {
3397 TGraphErrors *gc = CorrFnChi2VsTrigPt(ptabins[j], centbins[k], 1, 5, "ndf");
3399 Error("DrawChi2()", "!gc");
3402 int col = CentColor(centlow[centbins[k]], centhigh[centbins[k]]);
3403 utils.set_tgraph_props(gc, col, col, kFullCircle, 1.6);
3405 lv2->AddEntry(gc, centLabel(centbins[k]), "l,p");
3410 // TPad* overlay = new TPad("overlay", "overlay", 0,0,1,1);
3411 // overlay->SetFillStyle(4000); // transparent
3415 // ltx.SetTextSize(0.07);
3418 // ltx.SetTextSize(0.075);
3419 // ltx.DrawLatex(0.5, 0.05, "trigger p_{T} [GeV/c]");
3420 // ltx.SetTextAngle(90);
3421 // ltx.DrawLatex(0.05, 0.5, "#chi^{2} / NDF");
3422 // ltx.SetTextAngle(0);
3428 TCanvas* DrawAgreement(int icent, TString opt)
3430 // Draw Chi2 on one canvas for each
3431 // centrality bin k.
3434 int cent1 = centlow[icent];
3435 int cent2 = centhigh[icent];
3442 TString cname = Form("agmt_etamin%02d_cent%dto%d_%s",
3443 (int)(10*minRidgeDEta), cent1, cent2, opt.Data());
3444 if (!opt.IsNull()) {
3446 cname.Append(opt.Data());
3449 TCanvas* cv = new TCanvas(cname.Data(), cname.Data(), 1400, 500);
3450 TLegend* lv = new TLegend(0.09, 0.72, 0.27, 0.88);
3451 lv->SetFillColor(kNone);
3452 lv->SetBorderSize(0);
3454 double lv2bottom = 0.62;
3455 TLegend* lv2 = new TLegend(0.82, lv2bottom, 0.93, 0.95, "Centrality");
3456 lv2->SetFillColor(kNone);
3457 lv2->SetBorderSize(0);
3460 for (int n=1; n<=5; n++) {
3463 TH2F *gc = Agreement2DHist(k,n);
3465 Error("DrawAgreement()", "Problem finding graph" );
3469 // gc->GetZaxis()->SetRangeUser(1.e-1, 1000);
3471 gPad->SetLogx(); gPad->SetLogy(); gPad->SetLogz();
3473 if (opt.Contains("lego")) {
3474 gc->SetTitleOffset(0.8, "X");
3475 gc->GetXaxis()->SetLabelSize(0.07);
3476 gc->GetYaxis()->SetLabelSize(0.07);
3477 gc->GetZaxis()->SetLabelSize(0.07);
3478 gc->GetXaxis()->SetTitleSize(0.1);
3479 gc->GetYaxis()->SetTitleSize(0.1);
3480 gc->GetZaxis()->SetTitleSize(0.1);
3481 gc->GetXaxis()->SetNdivisions(8);
3482 gc->GetYaxis()->SetNdivisions(8);
3484 gPad->SetTopMargin(0.2);
3485 gPad->SetLeftMargin(0.12);
3486 gPad->SetRightMargin(0.01);
3489 else if (opt.Contains("contour"))
3493 lv2->AddEntry(gc, Form("%d-%d%%",centlow[k],centhigh[k]),"l,p");
3496 } // Fourier moment n
3499 TPad* overlay = new TPad("overlay", "overlay", 0,0,1,1);
3500 overlay->SetFillStyle(4000); // transparent
3504 ltx.SetTextSize(0.07);
3505 const char* str = Form("#left|V_{n#Delta} / (v_{n}^{t} v_{n}^{a})#right|");
3506 ltx.DrawLatex(0.42, 0.92, str);
3507 ltx.DrawLatex(0.91, 0.92, Form("%s", centLabel(k)));
3509 for (int n=1; n<=5; n++) {
3511 ltx.SetTextSize(0.10);
3512 ltx.DrawLatex(0.05, 0.76, Form("n = %d", n));
3517 void AddPrelimStampToCurrentPad(float x1, float y1, float x2, float y2, TString opt)
3519 TASImage* logo = new TASImage("../commonfigs/alice-prelim.png"); // 287x323
3520 TPad* logopad = new TPad("logopad", "logo", x1,y1,x2,y2);
3521 if (opt.Contains("border")) {
3522 logopad->SetFillColor(kRed);
3523 logopad->SetBorderSize(2);
3531 int CentBin(double cntLo, double cntHi)
3534 for (int k=0; k<maxcent; k++) {
3535 if (centlow[k]==cntLo && centhigh[k]==cntHi)
3539 Warning("CentBin","No bin for %.2g - %.2g", cntLo, cntHi);
3544 int PtBin(double ptLo, double ptHi)
3547 for (int i=0; i<maxpt; i++) {
3548 if (ptlow[i]==ptLo && pthigh[i]==ptHi)
3552 Warning("PtBin","No bin for %.2g - %.2g", ptLo, ptHi);
3557 double MomCorrection(int i, int j, int k)
3559 if(0)cout<<i<<j<<k<<endl;
3560 // For momentum (non)conservation in v1.
3561 // Multiplicitave weight: w = w_t*w_a.
3562 // w_t = ptt - <pt^2>/<pt>
3563 // w_a = pta - <pt^2>/<pt>
3565 // double c = 1./3 * -0.00185;
3567 // (ptmean[i]-)* ptmean[j]
3569 double correction = 1./3 * -0.00185 * ptmean[i]* ptmean[j];
3573 void MakeVnDVsQGraphs(int n1, int n2, int k, const char* region, const char* corrtype, TString opt)
3575 // The first two errType constants have points set at the central measured value of
3576 // VnDelta, with statistical and systematic error bars
3577 // respectively. The last two have points set at the upper and lower
3578 // systematic value, with statistical error bars set to be the same
3579 // as for meas_stat.
3580 const int nErrTypes = 4;
3581 enum errType {MEAS_STAT, MEAS_SYS, HI, LO};
3582 // const char* errTypeStr[] = {"meas_stat","meas_sys","hi","lo"};
3584 // Fill a huge array with all the coefficients, then use it to set the tgraphs.
3585 const int nN = gNMax + 1; // 1-10, don't use 0.
3586 const int nI = maxpt+1;
3587 const int nJ = maxpt+1;
3588 const int nT = nErrTypes;
3589 double vVal[nN][nI][nJ][nT];
3590 double vErr[nN][nI][nJ][nT];
3591 double vMix[nN][nI][nJ][nT]; // Just the acceptance correction unc.
3593 double vSin[nN][nI][nJ][nT]; // <sin n delta phi> for sys. estimation
3594 double vSinErr[nN][nI][nJ][nT];
3596 for (int i=0; i<maxpt; i++) {
3597 for (int j=0; j<=i; j++) {
3599 double esin = 0; // residual sine error
3600 double ebw = 0; // bin width error \propto n / (# dphi bins)
3601 double ecnt = 0; // centrality determination
3602 double emix = 0; // acc. correction error
3603 double etrk = 0; // tracking resolution
3604 double ev1 = 0; // v1
3605 double esys = 0; // quadrature sum
3607 TH1* hst=0, *hsys=0; // stat and sys error, but same points
3609 hst = Hist(region, corrtype, i, j, k, "");
3610 hsys = Hist(region, corrtype, i, j, k, "sys");
3612 if (!hst) Error("MakeVnDVsQGraphs()","!hst");
3613 if (!hsys) Error("MakeVnDVsQGraphs()","!hsys");
3615 esin = SineError(i,j,k); // resid_sin / 2;
3617 for (int n=n1; n<=n2; n++) { // Order of coeff.
3619 // VnDelta on measured points, with statistical errors.
3620 double val=0, err=0, resid_sin=0, rs_err=0;
3621 VnDelta(n, *hst, val, err, "");
3622 VnDelta(n, *hst, resid_sin, rs_err, "sin");
3624 // VnDelta on high and low sys values. Stat err. not used.
3625 double val_hi=0, xxx=0;
3626 VnDelta(n, *hsys, val_hi, xxx, "hi");
3627 double val_lo=0, yyy=0;
3628 VnDelta(n, *hsys, val_lo, yyy, "lo");
3630 // Momentum conservation correction
3631 if (n==1 && opt.Contains("ptcons")) { // eqs. 3-7, PRL 106, 102301 (2011)
3632 double factor = ispp ? 0.212 : 0; // 7e-5; <------ trial & error: 7e-5 must be close for 0-20%
3633 val += factor*ptmean[i]*ptmean[j];
3634 val_hi += factor*ptmean[i]*ptmean[j];
3635 val_lo += factor*ptmean[i]*ptmean[j];
3638 int nbins = hst->GetNbinsX();
3639 double mean = (val_hi + val_lo + val) / 3.;
3641 (val_hi-mean)*(val_hi-mean) +
3642 (val_lo-mean)*(val_lo-mean) +
3643 (val -mean)*(val -mean);
3644 double rms = TMath::Sqrt(ms/2); // sqrt(1/(N-1) sum (x_i - <x>)^2 )
3647 ebw = n/nbins/TMath::Sqrt(12)*val; // This is about 0.008 * n * val
3648 etrk = 0.01*ptmean[j]*val; // see comments in comparisons/VnDcomparison.C
3650 emix = rms/2; // take half not to double-count stat err. // 0.25*TMath::Abs(val_hi - val_lo);
3651 ev1 = (n==1) ? 0.001*ptmean[i]*ptmean[j]*val : 0.;
3653 esys = TMath::Sqrt(ecnt*ecnt + emix*emix + ebw*ebw + etrk*etrk + ev1*ev1 + esin*esin);
3655 double pointVal = val;
3656 double pointErr = err;
3658 vVal[n][i][j][MEAS_STAT] = pointVal;
3659 vErr[n][i][j][MEAS_STAT] = pointErr;
3660 vVal[n][i][j][MEAS_SYS] = pointVal;
3661 vErr[n][i][j][MEAS_SYS] = esys;
3662 vVal[n][i][j][HI] = pointVal + esys;
3663 vErr[n][i][j][HI] = pointErr;
3664 vVal[n][i][j][LO] = pointVal - esys;
3665 vErr[n][i][j][LO] = pointErr;
3666 vSin[n][i][j][MEAS_STAT] = resid_sin;
3667 vSinErr[n][i][j][MEAS_STAT] = rs_err;
3668 vMix[n][i][j][MEAS_SYS] = emix;
3674 // Now set the graphs from the arrays.
3675 for (int n=n1; n<=n2; n++) {
3676 for (int t=0; t<nErrTypes; t++) {
3678 TString gname = Form("V%dDeltaVsGlobalIndex_cent%dto%d",
3679 n,centlow[k],centhigh[k]);
3684 else if (t==MEAS_SYS)
3685 gname.Append("meas_sys");
3687 gname.Append("meas_stat");
3689 if (opt.Contains("sine"))
3690 gname.Append("_sine");
3692 if (opt.Contains("ALL"))
3693 gname.Append("_ALL");
3695 TGraphErrors* g = (TGraphErrors*) gList->FindObject(gname.Data());
3697 g = new TGraphErrors();
3698 g->SetName(gname.Data());
3701 TGraphErrors* gmix = 0;
3703 gmix = new TGraphErrors();
3704 gname.Append("_mix");
3705 gmix->SetName(gname.Data());
3708 double xer = 0.4; // was 0.5
3709 for (int i=0; i<maxpt; i++) {
3710 for (int j=0; j<=i; j++) {
3711 int q = GlobalIndex(i, j);
3712 g->SetPoint(q, q+0.5, vVal[n][i][j][t]);
3713 g->SetPointError(q, xer, vErr[n][i][j][t]);
3715 if (opt.Contains("sine")) {
3716 g->SetPoint(q, q+0.5, vSin[n][i][j][MEAS_STAT]);
3717 g->SetPointError(q, xer, vSinErr[n][i][j][MEAS_STAT]);
3721 gmix->SetPoint(q, q+0.5, vVal[n][i][j][t]);
3722 gmix->SetPointError(q, xer, vMix[n][i][j][t]);
3729 if (gmix) gList->Add(gmix);
3736 TGraphErrors* VnDVsQ(int n, int k, const char* region, const char* corrtype, TString opt)
3739 // Graph of pair fourier coefficients VnDelta vs. the linear
3740 // global index q. Arguments:
3742 // n, k: fourier index, centrality bin
3743 // region: "RIDGE", "NSJET" or "ALL"
3744 // corrtype: "s", "m", "cA", "cB"
3746 // Select opt "hi_sys" or "lo_sys" for hi and low pts
3747 // with central stat errors and "sys" for the central points
3748 // with sys. errors. Just like Hist().
3750 TString gname = Form("V%dDeltaVsGlobalIndex_cent%dto%d",
3751 n,centlow[k],centhigh[k]);
3753 if (opt.Contains("hi"))
3755 else if (opt.Contains("lo"))
3757 else if (opt.Contains("sys"))
3758 gname.Append("meas_sys");
3760 gname.Append("meas_stat");
3762 if (opt.Contains("sine"))
3763 gname.Append("_sine");
3765 if (opt.Contains("ALL"))
3766 gname.Append("_ALL");
3768 TGraphErrors* g = (TGraphErrors*) gList->FindObject(gname.Data());
3771 Info("VnDVsQ()", "Returning preexisting graph");
3775 TString opt1 = (opt.Contains("sine")) ? "sine" : "";
3776 if (opt.Contains("ALL"))
3777 opt1.Append("_ALL");
3778 if (opt.Contains("ptcons"))
3779 opt1.Append("_ptcons");
3781 MakeVnDVsQGraphs(1, gNMax, k, region, corrtype, opt1);
3782 g = (TGraphErrors*) gList->FindObject(gname.Data());
3784 Error("VnDVsQ()", "No graph %s", gname.Data());
3790 double MeanPt(int i, int j, int k, TString t_or_a, TString opt)
3792 // For combined centralities, map k's to the closest available bin
3793 // double cb1[] = {0, 0, 0,2,2, 1,3,0, 0, 1, 2, 3, 4, 5, 10, 20, 30, 40, 60 };
3794 // double cb2[] = {10,20,2,5,10,3,5,5, 1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 90 };
3795 // OBJ: TProfile2D hMeanPtTrgCen1 cen=1 (0.5) : 0 at: 0x102af06e0
3796 // OBJ: TProfile2D hMeanPtAssCen1 cen=1 (0.5) : 0 at: 0x108308e60
3797 // OBJ: TProfile2D hMean2PtTrgCen1 cen=1 (0.5) : 0 at: 0x108309480
3798 // OBJ: TProfile2D hMean2PtAssCen1 cen=1 (0.5) : 0 at: 0x108309ad0
3799 // OBJ: TProfile2D hMeanPtTrgCen2 cen=2 (1.5) : 0 at: 0x10830a120
3800 // OBJ: TProfile2D hMeanPtAssCen2 cen=2 (1.5) : 0 at: 0x10830a770
3801 // OBJ: TProfile2D hMean2PtTrgCen2 cen=2 (1.5) : 0 at: 0x10830adc0
3802 // OBJ: TProfile2D hMean2PtAssCen2 cen=2 (1.5) : 0 at: 0x10830b410
3803 // OBJ: TProfile2D hMeanPtTrgCen3 cen=3 (2.5) : 0 at: 0x10830ba60
3804 // OBJ: TProfile2D hMeanPtAssCen3 cen=3 (2.5) : 0 at: 0x10830c0b0
3805 // OBJ: TProfile2D hMean2PtTrgCen3 cen=3 (2.5) : 0 at: 0x10830c700
3806 // OBJ: TProfile2D hMean2PtAssCen3 cen=3 (2.5) : 0 at: 0x10830cd50
3807 // OBJ: TProfile2D hMeanPtTrgCen4 cen=4 (3.5) : 0 at: 0x10830d3a0
3808 // OBJ: TProfile2D hMeanPtAssCen4 cen=4 (3.5) : 0 at: 0x10830d9f0
3809 // OBJ: TProfile2D hMean2PtTrgCen4 cen=4 (3.5) : 0 at: 0x10830e040
3810 // OBJ: TProfile2D hMean2PtAssCen4 cen=4 (3.5) : 0 at: 0x10830e690
3811 // OBJ: TProfile2D hMeanPtTrgCen5 cen=5 (4.5) : 0 at: 0x10830ece0
3812 // OBJ: TProfile2D hMeanPtAssCen5 cen=5 (4.5) : 0 at: 0x10830f330
3813 // OBJ: TProfile2D hMean2PtTrgCen5 cen=5 (4.5) : 0 at: 0x10830f980
3814 // OBJ: TProfile2D hMean2PtAssCen5 cen=5 (4.5) : 0 at: 0x10830ffd0
3815 // OBJ: TProfile2D hMeanPtTrgCen6 cen=6 (7.5) : 0 at: 0x108310620
3816 // OBJ: TProfile2D hMeanPtAssCen6 cen=6 (7.5) : 0 at: 0x108310c70
3817 // OBJ: TProfile2D hMean2PtTrgCen6 cen=6 (7.5) : 0 at: 0x1083112c0
3818 // OBJ: TProfile2D hMean2PtAssCen6 cen=6 (7.5) : 0 at: 0x108311910
3819 // OBJ: TProfile2D hMeanPtTrgCen7 cen=7 (15.0) : 0 at: 0x108311f60
3820 // OBJ: TProfile2D hMeanPtAssCen7 cen=7 (15.0) : 0 at: 0x1083125b0
3821 // OBJ: TProfile2D hMean2PtTrgCen7 cen=7 (15.0) : 0 at: 0x108312c00
3822 // OBJ: TProfile2D hMean2PtAssCen7 cen=7 (15.0) : 0 at: 0x108313250
3823 // OBJ: TProfile2D hMeanPtTrgCen8 cen=8 (25.0) : 0 at: 0x1083138a0
3824 // OBJ: TProfile2D hMeanPtAssCen8 cen=8 (25.0) : 0 at: 0x108313ef0
3825 // OBJ: TProfile2D hMean2PtTrgCen8 cen=8 (25.0) : 0 at: 0x108314540
3826 // OBJ: TProfile2D hMean2PtAssCen8 cen=8 (25.0) : 0 at: 0x108314b90
3827 // OBJ: TProfile2D hMeanPtTrgCen9 cen=9 (35.0) : 0 at: 0x1083151e0
3828 // OBJ: TProfile2D hMeanPtAssCen9 cen=9 (35.0) : 0 at: 0x108315830
3829 // OBJ: TProfile2D hMean2PtTrgCen9 cen=9 (35.0) : 0 at: 0x108315e80
3830 // OBJ: TProfile2D hMean2PtAssCen9 cen=9 (35.0) : 0 at: 0x1083164d0
3831 // OBJ: TProfile2D hMeanPtTrgCen10 cen=10 (45.0) : 0 at: 0x108316b20
3832 // OBJ: TProfile2D hMeanPtAssCen10 cen=10 (45.0) : 0 at: 0x108317170
3833 // OBJ: TProfile2D hMean2PtTrgCen10 cen=10 (45.0) : 0 at: 0x1083177c0
3834 // OBJ: TProfile2D hMean2PtAssCen10 cen=10 (45.0) : 0 at: 0x108317e10
3835 // OBJ: TProfile2D hMeanPtTrgCen11 cen=11 (55.0) : 0 at: 0x108318460
3836 // OBJ: TProfile2D hMeanPtAssCen11 cen=11 (55.0) : 0 at: 0x108318ab0
3837 // OBJ: TProfile2D hMean2PtTrgCen11 cen=11 (55.0) : 0 at: 0x108319100
3838 // OBJ: TProfile2D hMean2PtAssCen11 cen=11 (55.0) : 0 at: 0x108319750
3839 // OBJ: TProfile2D hMeanPtTrgCen12 cen=12 (75.0) : 0 at: 0x108319da0
3840 // OBJ: TProfile2D hMeanPtAssCen12 cen=12 (75.0) : 0 at: 0x10831a3f0
3841 // OBJ: TProfile2D hMean2PtTrgCen12 cen=12 (75.0) : 0 at: 0x10831aa40
3842 // OBJ: TProfile2D hMean2PtAssCen12 cen=12 (75.0) : 0 at: 0x10831b090
3845 if (k == CentBin(0, 1)) k2 = 1;
3846 else if (k == CentBin(1, 2)) k2 = 2;
3847 else if (k == CentBin(2, 3)) k2 = 3;
3848 else if (k == CentBin(3, 4)) k2 = 4;
3849 else if (k == CentBin(4, 5)) k2 = 5;
3850 else if (k == CentBin(5, 10)) k2 = 6;
3851 else if (k == CentBin(10,20)) k2 = 7;
3852 else if (k == CentBin(20,30)) k2 = 8;
3853 else if (k == CentBin(30,40)) k2 = 9;
3854 else if (k == CentBin(40,50)) k2 = 10;
3855 else if (k == CentBin(50,60)) k2 = 11;
3856 else if (k == CentBin(60,90)) k2 = 12;
3857 else if (k == CentBin(0, 10)) k2 = 5; //CentBin(4, 5);
3858 else if (k == CentBin(0, 20)) k2 = 6; //CentBin(5, 10);
3859 else if (k == CentBin(0, 2)) k2 = 1; //CentBin(0, 1);
3860 else if (k == CentBin(2, 5)) k2 = 4; //CentBin(3, 4);
3861 else if (k == CentBin(2, 10)) k2 = 6; //CentBin(5, 10);
3862 else if (k == CentBin(1, 3)) k2 = 2; //CentBin(1, 2);
3863 else if (k == CentBin(3, 5)) k2 = 4; //CentBin(3, 4);
3864 else if (k == CentBin(0, 5)) k2 = 3; //CentBin(2, 3);
3866 else if (k == CentBin(0, 0)) k2 = 1; //pp
3868 Error("MeanPt()", "cent bin %d (%d-%d%%) not assigned", k, centlow[k], centhigh[k]);
3871 const char* m = opt.Contains("squared") ? "Mean2" : "Mean";
3873 TString prName_t = Form("h%sPtTrgCen%d", m, k2);
3874 TString prName_a = Form("h%sPtAssCen%d", m, k2);
3875 TProfile2D* hmpt_t = (TProfile2D*)fin->Get(prName_t.Data());
3876 TProfile2D* hmpt_a = (TProfile2D*)fin->Get(prName_a.Data());
3879 Error("MeanPt", "Problem finding TProfile %s. Input %d", prName_t.Data(), k);
3882 // cout << hmpt_t->GetTitle() << " " << centlow[k] << " " << centhigh[k] << endl;
3884 double mptt = hmpt_t->GetBinContent(i+1, j+1);
3885 double mpta = hmpt_a->GetBinContent(i+1, j+1);
3888 // x axis is trig pt, y axis assc pt
3889 TAxis* ax = hmpt_t->GetXaxis();
3890 TAxis* ay = hmpt_t->GetYaxis();
3891 Printf("trig %.3g - %.3g, assc: %.3g - %.3g, <pt_t,a> %.3g, %.3g",
3892 ax->GetBinLowEdge(i+1),
3893 ax->GetBinUpEdge(i+1),
3894 ay->GetBinLowEdge(j+1),
3895 ay->GetBinUpEdge(j+1),
3899 if (t_or_a.Contains("t"))
3901 if (t_or_a.Contains("a"))
3908 int CentColor(double cen1, double cen2)
3910 if (cen1==0 && cen2==10)
3912 if (cen1==0 && cen2==20)
3914 if (cen1==0 && cen2==2)
3916 if (cen1==2 && cen2==10)
3918 if (cen1==10 && cen2==20)
3920 if (cen1==20 && cen2==30)
3922 if (cen1==30 && cen2==40)
3924 if (cen1==40 && cen2==50)
3926 if (cen1==50 && cen2==60)
3928 if (cen1==60 && cen2==90)
3934 int CentColorPale(double cen1, double cen2)
3936 if (cen1==0 && cen2==10)
3938 if (cen1==0 && cen2==20)
3939 return kPink-1; // kPink-6;
3940 if (cen1==0 && cen2==2)
3942 if (cen1==2 && cen2==10)
3944 if (cen1==10 && cen2==20)
3946 if (cen1==20 && cen2==30)
3948 if (cen1==30 && cen2==40)
3950 if (cen1==40 && cen2==50)
3952 if (cen1==50 && cen2==60)
3954 if (cen1==60 && cen2==90)
3960 int PtColor(double p1, double p2)
3962 if (p1==0.25 && p2==0.5)
3964 if (p1==0.5 && p2==0.75)
3966 if (p1==0.75 && p2==1.0)
3968 if (p1==1.0 && p2==1.5)
3970 if (p1==1.5 && p2==2.0)
3972 if (p1==2.0 && p2==2.5)
3974 if (p1==2.5 && p2==3)
3986 if (p1==8 && p2==15)
3992 int PtColorPale(double p1, double p2)
3994 if (p1==0.25 && p2==0.5)
3996 if (p1==0.5 && p2==0.75)
3998 if (p1==0.75 && p2==1.0)
4000 if (p1==1.0 && p2==1.5)
4002 if (p1==1.5 && p2==2.0)
4004 if (p1==2.0 && p2==2.5)
4006 if (p1==2.5 && p2==3)
4018 if (p1==8 && p2==15)
4024 int PtaColor(double p1, double p2)
4026 if (p1==0.25 && p2==0.5)
4028 if (p1==0.5 && p2==0.75)
4030 if (p1==0.75 && p2==1.0)
4032 if (p1==1.0 && p2==1.5)
4033 return kOrange-3;//kBlack;
4034 if (p1==1.5 && p2==2.0)
4035 return kGreen+2;//kRed;
4036 if (p1==2.0 && p2==2.5)
4037 return kAzure-3;//kOrange-3;
4038 if (p1==2.5 && p2==3)
4039 return kViolet + 2;//kBlue;
4041 return kViolet + 10;//kBlue;
4043 return kMagenta+3; //kViolet + 2;
4050 if (p1==8 && p2==15)
4056 int PtaColorPale(double p1, double p2)
4058 if (p1==0.25 && p2==0.5)
4060 if (p1==0.5 && p2==0.75)
4062 if (p1==0.75 && p2==1.0)
4064 if (p1==1.0 && p2==1.5)
4066 if (p1==1.5 && p2==2.0)
4068 if (p1==2.0 && p2==2.5)
4070 if (p1==2.5 && p2==3)
4082 if (p1==8 && p2==15)
4088 void SaveCanvases(TObjArray* canvases, const char* fileName)
4090 TFile* f = new TFile(fileName, "recreate");
4092 for (int n=0; n<canvases->GetEntries(); n++) {
4093 TCanvas* c = (TCanvas*)canvases->At(n);
4094 c->Write(c->GetTitle());
4100 void SaveCanvasesFromFile(const char* rootFile, const char* targetDir, const char* tag, const char* fileType)
4102 // Get a list of canvases from rootFile into array, then save each
4103 // to its own file in targetDir/. fileType = "eps", "pdf", "C",
4104 // "png", etc. Not all formats have been tested.
4105 gStyle->SetOptTitle(0);
4106 gStyle->SetOptStat(0);
4108 TString base(targetDir);
4109 TFile *cFile = new TFile(rootFile, "read");
4110 cout << cFile->GetName() << endl;
4111 TObjArray* cList = GetObjectsFromFile(*cFile, "TCanvas");
4113 for (int n=0; n<cList->GetEntries(); n++) {
4114 TCanvas* c = (TCanvas*)cList->At(n);
4118 name += TString("/");
4119 name += TString(fileType);
4120 name += TString("/");
4121 name += TString(c->GetTitle());
4122 name += TString(".");
4123 name += TString(fileType);
4124 cout<<name.Data()<<endl;
4129 c->SaveAs(name.Data());
4132 Error("SaveCanvasesFromFile()", "!c");
4136 utils.print_pdf(cList, Form("%s/all-figs%s", targetDir, tag), "pdf");
4142 //void SaveCanvases(TObjArray* canvases, const char* fileName)
4143 //void SaveCanvasesFromFile(const char* rootFile, const char* targetDir, const char* fileType)
4144 TObjArray* GetObjectsFromFile(TFile& file, TString clname, TString dir)
4146 file.cd(dir.Data());
4148 TObjArray* objList = new TObjArray();
4149 TIter next(gDirectory->GetListOfKeys());
4152 while ((key=(TKey*)next())) {
4153 TString className(key->GetClassName());
4154 TString keyName(key->GetName());
4156 printf("%10s %20s\n", className.Data(), keyName.Data());
4158 if (className.Contains(clname)) {
4159 objList->Add(gDirectory->Get(keyName.Data()));
4163 cout << objList->GetEntries() << " objects retrieved from "
4164 << file.GetName() << "/" << gDirectory->GetName()