3 * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
4 * @date Wed Mar 23 14:07:10 2011
6 * @brief Script to visualise the dN/deta
8 * This script is independent of any AliROOT code - and should stay
12 * @ingroup pwg2_forward_dndeta
16 #include <TGraphErrors.h>
17 #include <TGraphAsymmErrors.h>
18 #include <TMultiGraph.h>
30 #include <TLegendEntry.h>
35 * Class to draw dN/deta results
37 * @ingroup pwg2_forward_tasks_dndeta
38 * @ingroup pwg2_forward_dndeta
43 * POD of data for range zooming
47 TAxis* fMasterAxis; // Master axis
48 TAxis* fSlave1Axis; // First slave axis
49 TVirtualPad* fSlave1Pad; // First slave pad
50 TAxis* fSlave2Axis; // Second slave axis
51 TVirtualPad* fSlave2Pad; // Second slave pad
53 //__________________________________________________________________
59 : fShowOthers(false), // Bool_t
60 fShowAlice(false), // Bool_t
61 fShowRatios(false), // Bool_t
62 fShowLeftRight(false), // Bool_t
63 fRebin(5), // UShort_t
64 fCutEdges(false), // Bool_t
65 fTitle(""), // TString
66 fTrigString(0), // TNamed*
67 fSNNString(0), // TNamed*
68 fSysString(0), // TNamed*
69 fVtxAxis(0), // TAxis*
70 fCentAxis(0), // TAxis*
75 fRangeParam = new RangeParam;
76 fRangeParam->fMasterAxis = 0;
77 fRangeParam->fSlave1Axis = 0;
78 fRangeParam->fSlave1Pad = 0;
79 fRangeParam->fSlave2Axis = 0;
80 fRangeParam->fSlave2Pad = 0;
82 //__________________________________________________________________
83 virtual ~dNdetaDrawer()
85 if (fRatios && fRatios->GetHists()) fRatios->GetHists()->Delete();
86 if (fResults && fResults->GetHists()) fResults->GetHists()->Delete();
88 if (fTrigString) { delete fTrigString; fTrigString = 0; }
89 if (fSNNString) { delete fSNNString; fSNNString = 0; }
90 if (fSysString) { delete fSysString; fSysString = 0; }
91 if (fVtxAxis) { delete fVtxAxis; fVtxAxis = 0; }
92 if (fCentAxis) { delete fCentAxis; fCentAxis = 0; }
93 if (fResults) { delete fResults; fResults = 0; }
94 if (fRatios) { delete fRatios; fRatios = 0; }
95 if (fOthers) { delete fOthers; fOthers = 0; }
96 if (fTriggers) { delete fTriggers; fTriggers = 0; }
100 //==================================================================
103 * @name Set parameters
106 * Show other (UA5, CMS, ...) data
108 * @param x Whether to show or not
110 void SetShowOthers(Bool_t x) { fShowOthers = x; }
111 //__________________________________________________________________
113 * Show ALICE published data
115 * @param x Wheter to show or not
117 void SetShowAlice(Bool_t x) { fShowAlice = x; }
118 //__________________________________________________________________
120 * Whether to show ratios or not. If there's nothing to compare to,
121 * the ratio panel will be implicitly disabled
123 * @param x Whether to show or not
125 void SetShowRatios(Bool_t x) { fShowRatios = x; }
126 //__________________________________________________________________
129 * Whether to show the left/right asymmetry
131 * @param x To show or not
133 void SetShowLeftRight(Bool_t x) { fShowLeftRight = x; }
134 //__________________________________________________________________
136 * Set the rebinning factor
138 * @param x Rebinning factor (must be a divisor in the number of bins)
140 void SetRebin(UShort_t x) { fRebin = x; }
141 //__________________________________________________________________
143 * Wheter to cut away the edges
145 * @param x Whether or not to cut away edges
147 void SetCutEdges(Bool_t x) { fCutEdges = x; }
148 //__________________________________________________________________
150 * Set the title of the plot
154 void SetTitle(TString x) { fTitle = x; }
156 //==================================================================
159 * @name Override settings from input
162 * Override setting from file
164 * @param sNN Center of mass energy per nucleon pair (GeV)
166 void SetSNN(UShort_t sNN)
168 fSNNString = new TNamed("sNN", Form("%04dGeV", sNN));
169 fSNNString->SetUniqueID(sNN);
171 //__________________________________________________________________
173 * Set the collision system
177 * @param sys collision system
179 void SetSys(UShort_t sys)
181 fSysString = new TNamed("sys", (sys == 1 ? "pp" :
182 sys == 2 ? "PbPb" : "unknown"));
183 fSysString->SetUniqueID(sys);
185 //__________________________________________________________________
187 * Set the vertex range in centimeters
189 * @param vzMin Min @f$ v_z@f$
190 * @param vzMax Max @f$ v_z@f$
192 void SetVertexRange(Double_t vzMin, Double_t vzMax)
194 fVtxAxis = new TAxis(10, vzMin, vzMax);
195 fVtxAxis->SetName("vtxAxis");
196 fVtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", vzMin, vzMax));
198 //__________________________________________________________________
199 void SetTrigger(UShort_t trig)
201 fTrigString = new TNamed("trigString", (trig & 0x1 ? "INEL" :
202 trig & 0x2 ? "INEL>0" :
205 fTrigString->SetUniqueID(trig);
209 //==================================================================
212 * @name Main steering functions
215 * Run the code to produce the final result.
217 * @param filename File containing the data
219 void Run(const char* filename="forward_dndeta.root")
221 Double_t max = 0, rmax=0, amax=0;
223 gStyle->SetPalette(1);
225 // --- Open input file -------------------------------------------
226 TFile* file = TFile::Open(filename, "READ");
228 Error("Open", "Cannot open %s", filename);
231 // --- Get forward list ------------------------------------------
232 TList* forward = static_cast<TList*>(file->Get("ForwardResults"));
234 Error("Open", "Couldn't find list ForwardResults");
237 // --- Get information on the run --------------------------------
238 FetchInformation(forward);
239 // --- Set the macro pathand load other data script --------------
240 gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2",
241 gROOT->GetMacroPath()));
242 gROOT->LoadMacro("OtherData.C");
244 // --- Get the central results -----------------------------------
245 TList* clusters = static_cast<TList*>(file->Get("CentralResults"));
246 if (!clusters) Warning("Open", "Couldn't find list CentralResults");
248 // --- Make our containtes ---------------------------------------
249 fResults = new THStack("results", "Results");
250 fRatios = new THStack("ratios", "Ratios");
251 fLeftRight = new THStack("asymmetry", "Left-right asymmetry");
252 fOthers = new TMultiGraph();
254 // --- Loop over input data --------------------------------------
255 FetchResults(forward, "Forward", max, rmax, amax);
256 FetchResults(clusters, "Central", max, rmax, amax);
258 // --- Get trigger information -----------------------------------
259 TList* sums = static_cast<TList*>(file->Get("ForwardSums"));
261 TList* all = static_cast<TList*>(sums->FindObject("all"));
263 fTriggers = FetchResult(all, "triggers");
264 if (!fTriggers) all->ls();
267 Warning("Run", "List all not found in ForwardSums");
272 Warning("Run", "No ForwardSums directory found in %s", file->GetName());
276 // --- Check our stacks ------------------------------------------
277 if (!fResults->GetHists() ||
278 fResults->GetHists()->GetEntries() <= 0) {
279 Error("Run", "No histograms in result stack!");
282 if (!fOthers->GetListOfGraphs() ||
283 fOthers->GetListOfGraphs()->GetEntries() <= 0) {
284 Warning("Run", "No other data found - disabling that");
287 if (!fRatios->GetHists() ||
288 fRatios->GetHists()->GetEntries() <= 0) {
289 Warning("Run", "No ratio data found - disabling that");
293 if (!fLeftRight->GetHists() ||
294 fLeftRight->GetHists()->GetEntries() <= 0) {
295 Warning("Run", "No left/right data found - disabling that");
297 fShowLeftRight = false;
300 // --- Close the input file --------------------------------------
305 // --- Plot results ----------------------------------------------
306 Plot(max, rmax, amax);
309 //__________________________________________________________________
311 * Fetch the information on the run from the results list
313 * @param results Results list
315 void FetchInformation(const TList* results)
318 fTrigString = static_cast<TNamed*>(results->FindObject("trigString"));
320 fSNNString = static_cast<TNamed*>(results->FindObject("sNN"));
322 fSysString = static_cast<TNamed*>(results->FindObject("sys"));
324 fVtxAxis = static_cast<TAxis*>(results->FindObject("vtxAxis"));
326 fCentAxis = static_cast<TAxis*>(results->FindObject("centAxis"));
327 if (!fTrigString) fTrigString = new TNamed("trigString", "unknown");
328 if (!fSNNString) fSNNString = new TNamed("sNN", "unknown");
329 if (!fSysString) fSysString = new TNamed("sys", "unknown");
331 fVtxAxis = new TAxis(1,0,0);
332 fVtxAxis->SetName("vtxAxis");
333 fVtxAxis->SetTitle("v_{z} range unspecified");
338 Int_t nCent = fCentAxis->GetNbins();
339 centTxt = Form("\n Centrality: %d bins", nCent);
340 for (Int_t i = 0; i <= nCent; i++)
341 centTxt.Append(Form("%c%d", i == 0 ? ' ' : ',',
342 int(fCentAxis->GetXbins()->At(i))));
344 Info("FetchInformation",
346 " Trigger: %s (%d)\n"
347 " sqrt(sNN): %s (%dGeV)\n"
349 " Vz range: %s (%f,%f)%s",
350 fTrigString->GetTitle(), fTrigString->GetUniqueID(),
351 fSNNString->GetTitle(), fSNNString->GetUniqueID(),
352 fSysString->GetTitle(), fSysString->GetUniqueID(),
353 fVtxAxis->GetTitle(), fVtxAxis->GetXmin(), fVtxAxis->GetXmax(),
356 //__________________________________________________________________
357 TMultiGraph* FetchOthers(UShort_t centLow, UShort_t centHigh)
359 TMultiGraph* thisOther = 0;
360 if (!fShowOthers && !fShowAlice) return 0;
362 Bool_t onlya = (fShowOthers ? false : true);
363 UShort_t sys = (fSysString ? fSysString->GetUniqueID() : 0);
364 UShort_t trg = (fTrigString ? fTrigString->GetUniqueID() : 0);
365 UShort_t snn = (fSNNString ? fSNNString->GetUniqueID() : 0);
366 Long_t ret = gROOT->ProcessLine(Form("GetData(%d,%d,%d,%d,%d,%d);",
368 centLow,centHigh,onlya));
370 Warning("FetchResults", "No other data found for sys=%d, sNN=%d, "
371 "trigger=%d %d%%-%d%% central %s",
372 sys, snn, trg, centLow, centHigh,
373 onlya ? " (ALICE results)" : "all");
376 thisOther = reinterpret_cast<TMultiGraph*>(ret);
380 //__________________________________________________________________
382 * Get the results from the top-level list
386 * @param max On return, maximum of data
387 * @param rmax On return, maximum of ratios
388 * @param amax On return, maximum of left-right comparisons
390 void FetchResults(const TList* list,
396 UShort_t n = fCentAxis ? fCentAxis->GetNbins() : 0;
398 TList* all = static_cast<TList*>(list->FindObject("all"));
400 Error("FetchResults", "Couldn't find list 'all' in %s",
403 FetchResults(all, name, FetchOthers(0,0), -1, 0, max, rmax, amax);
407 Int_t nCol = gStyle->GetNumberOfColors();
408 for (UShort_t i = 0; i < n; i++) {
409 UShort_t centLow = fCentAxis->GetXbins()->At(i);
410 UShort_t centHigh = fCentAxis->GetXbins()->At(i+1);
411 TString lname = Form("cent%03d_%03d", centLow, centHigh);
412 TList* thisCent = static_cast<TList*>(list->FindObject(lname));
414 Float_t fc = (centLow+double(centHigh-centLow)/2) / 100;
415 Int_t icol = TMath::Min(nCol-1,int(fc * nCol + .5));
416 Int_t col = gStyle->GetColorPalette(icol);
417 Info("FetchResults","Centrality %d-%d color index %d (=%d*%f) -> %d",
418 centLow, centHigh, icol, nCol, fc, col);
420 TString centTxt = Form("%3d%%-%3d%% central", centLow, centHigh);
422 Error("FetchResults", "Couldn't find list '%s' in %s",
423 lname.Data(), list->GetName());
425 FetchResults(thisCent, name, FetchOthers(centLow, centHigh),
426 col, centTxt.Data(), max, rmax, amax);
429 //__________________________________________________________________
430 void SetAttributes(TH1* h, Int_t color)
433 if (color < 0) return;
434 // h->SetLineColor(color);
435 h->SetMarkerColor(color);
436 // h->SetFillColor(color);
438 //__________________________________________________________________
439 void SetAttributes(TGraph* g, Int_t color)
442 if (color < 0) return;
443 // g->SetLineColor(color);
444 g->SetMarkerColor(color);
445 // g->SetFillColor(color);
447 //__________________________________________________________________
448 void ModifyTitle(TNamed* h, const char* centTxt)
450 if (!centTxt || !h) return;
451 h->SetTitle(Form("%s, %s", h->GetTitle(), centTxt));
454 //__________________________________________________________________
456 * Fetch results for a particular centrality bin
460 * @param thisOther Other graphs
462 * @param centTxt Centrality text
463 * @param max On return, data maximum
464 * @param rmax On return, ratio maximum
465 * @param amax On return, left-right maximum
467 void FetchResults(const TList* list,
469 TMultiGraph* thisOther,
476 TH1* dndeta = FetchResult(list, Form("dndeta%s", name));
477 TH1* dndetaMC = FetchResult(list, Form("dndeta%sMC", name));
478 TH1* dndetaTruth = FetchResult(list, "dndetaTruth");
480 TH1* dndetaMCSym = 0;
481 TH1* tracks = FetchResult(list, "tracks");
482 if (tracks) tracks->SetTitle("ALICE Tracks");
483 SetAttributes(dndeta, color);
484 SetAttributes(dndetaMC, color+2);
485 SetAttributes(dndetaTruth,color);
486 SetAttributes(dndetaSym, color);
487 SetAttributes(dndetaMCSym,color+2);
488 SetAttributes(tracks, color+3);
489 ModifyTitle(dndeta, centTxt);
490 ModifyTitle(dndetaMC, centTxt);
491 ModifyTitle(dndetaTruth,centTxt);
492 ModifyTitle(dndetaSym, centTxt);
493 ModifyTitle(dndetaMCSym,centTxt);
494 ModifyTitle(tracks, centTxt);
497 max = TMath::Max(max, AddHistogram(fResults, dndetaTruth, "e5 p"));
498 max = TMath::Max(max, AddHistogram(fResults, dndetaMC, dndetaMCSym));
499 max = TMath::Max(max, AddHistogram(fResults, dndeta, dndetaSym));
500 max = TMath::Max(max, AddHistogram(fResults, tracks));
502 // Info("FetchResults", "Got %p, %p, %p from %s with name %s, max=%f",
503 // dndeta, dndetaMC, dndetaTruth, list->GetName(), name, max);
505 if (fShowLeftRight) {
506 fLeftRight->Add(Asymmetry(dndeta, amax));
507 fLeftRight->Add(Asymmetry(dndetaMC, amax));
508 fLeftRight->Add(Asymmetry(tracks, amax));
512 TIter next(thisOther->GetListOfGraphs());
514 while ((g = static_cast<TGraph*>(next()))) {
515 fRatios->Add(Ratio(dndeta, g, rmax));
516 fRatios->Add(Ratio(dndetaSym, g, rmax));
517 SetAttributes(g, color);
518 ModifyTitle(g, centTxt);
519 if (!fOthers->GetListOfGraphs() ||
520 !fOthers->GetListOfGraphs()->FindObject(g->GetName())) {
521 max = TMath::Max(max,TMath::MaxElement(g->GetN(), g->GetY()));
525 // fOthers->Add(thisOther);
528 if (!fRatios->GetHists() ||
529 !fRatios->GetHists()->FindObject(tracks->GetName()))
530 fRatios->Add(Ratio(dndeta, tracks, rmax));
534 fRatios->Add(Ratio(dndeta, dndetaTruth, rmax));
535 fRatios->Add(Ratio(dndetaSym, dndetaTruth, rmax));
536 fRatios->Add(Ratio(dndetaMC, dndetaTruth, rmax));
537 fRatios->Add(Ratio(dndetaMCSym, dndetaTruth, rmax));
540 //__________________________________________________________________
543 * @param max Max value
544 * @param rmax Maximum diviation from 1 of ratios
545 * @param amax Maximum diviation from 1 of asymmetries
547 void Plot(Double_t max,
551 gStyle->SetOptTitle(0);
552 gStyle->SetTitleFont(132, "xyz");
553 gStyle->SetLabelFont(132, "xyz");
556 Int_t w = 800; // h / TMath::Sqrt(2);
560 if (!fShowRatios) w *= 1.4;
562 if (!fShowLeftRight) w *= 1.4;
565 y1 = (y11 > 0.0001 ? 0.4 : 0.2);
566 y2 = (y11 > 0.0001 ? 0.2 : 0.3);
568 TCanvas* c = new TCanvas("Results", "Results", w, h);
574 Info("Plot", "y1=%f, y2=%f, y3=%f extra: %s %s",
575 y1, y2, y2, (fShowRatios ? "ratios" : ""),
576 (fShowLeftRight ? "right/left" : ""));
577 Info("Plot", "Maximum is %f", max);
579 PlotResults(max, y1);
582 PlotRatios(rmax, y2, y1);
585 PlotLeftRight(amax, y3, y2);
589 Int_t vMin = fVtxAxis->GetXmin();
590 Int_t vMax = fVtxAxis->GetXmax();
591 TString trg(fTrigString->GetTitle());
593 if (fTriggers) nev = fTriggers->GetBinContent(1);
594 trg = trg.Strip(TString::kBoth);
595 TString base(Form("dndeta_%s_%s_%s_%c%02d%c%02dcm_%09dev",
596 fSysString->GetTitle(),
597 fSNNString->GetTitle(),
599 vMin < 0 ? 'm' : 'p', TMath::Abs(vMin),
600 vMax < 0 ? 'm' : 'p', TMath::Abs(vMax),
602 c->SaveAs(Form("%s.png", base.Data()));
603 c->SaveAs(Form("%s.root", base.Data()));
604 c->SaveAs(Form("%s.C", base.Data()));
606 //__________________________________________________________________
610 * @param stack Stack to include
611 * @param mg (optional) Multi graph to include
612 * @param x1 Lower X coordinate in the range [0,1]
613 * @param y1 Lower Y coordinate in the range [0,1]
614 * @param x2 Upper X coordinate in the range [0,1]
615 * @param y2 Upper Y coordinate in the range [0,1]
617 void BuildLegend(THStack* stack, TMultiGraph* mg,
618 Double_t x1, Double_t y1, Double_t x2, Double_t y2)
620 TLegend* l = new TLegend(x1,y1,x2,y2);
627 TIter next(stack->GetHists());
629 while ((hist = next())) {
630 TString n(hist->GetTitle());
631 if (n.Contains("mirrored")) continue;
632 l->AddEntry(hist, hist->GetTitle(), "pl");
635 TIter nexto(mg->GetListOfGraphs());
636 while ((hist = nexto())) {
637 TString n(hist->GetTitle());
638 if (n.Contains("mirrored")) continue;
639 l->AddEntry(hist, hist->GetTitle(), "pl");
642 TLegendEntry* d1 = l->AddEntry("d1", "Data", "lp");
643 d1->SetLineColor(kBlack);
644 d1->SetMarkerColor(kBlack);
645 d1->SetMarkerStyle(20);
646 TLegendEntry* d2 = l->AddEntry("d2", "Mirrored data", "lp");
647 d2->SetLineColor(kBlack);
648 d2->SetMarkerColor(kBlack);
649 d2->SetMarkerStyle(24);
653 //__________________________________________________________________
658 * @param yd Bottom position of pad
660 void PlotResults(Double_t max, Double_t yd)
662 // Make a sub-pad for the result itself
663 TPad* p1 = new TPad("p1", "p1", 0, yd, 1.0, 1.0, 0, 0, 0);
664 p1->SetTopMargin(0.05);
665 p1->SetBorderSize(0);
666 p1->SetBorderMode(0);
667 p1->SetBottomMargin(yd > 0.001 ? 0.001 : 0.1);
668 p1->SetRightMargin(0.05);
675 // Info("PlotResults", "Plotting results with max=%f", max);
676 fResults->SetMaximum(1.15*max);
677 fResults->SetMinimum(yd > 0.00001 ? -0.1 : 0);
679 FixAxis(fResults, 1/(1-yd)/1.7, "#frac{1}{N} #frac{dN_{ch}}{d#eta}");
682 fResults->DrawClone("nostack e1");
684 fRangeParam->fSlave1Axis = fResults->GetXaxis();
685 fRangeParam->fSlave1Pad = p1;
688 if (fShowOthers || fShowAlice) {
689 TGraphAsymmErrors* o = 0;
690 TIter nextG(fOthers->GetListOfGraphs());
691 while ((o = static_cast<TGraphAsymmErrors*>(nextG())))
692 o->DrawClone("same p");
695 // Make a legend in the main result pad
696 BuildLegend(fResults, fOthers, .15,p1->GetBottomMargin()+.01,.90,.35);
698 TLegend* l = p1->BuildLegend(.15,p1->GetBottomMargin()+.01,.90,.35);
706 // Put a title on top
707 fTitle.ReplaceAll("@", " ");
708 TLatex* tit = new TLatex(0.10, 0.95, fTitle.Data());
710 tit->SetTextFont(132);
711 tit->SetTextSize(0.05);
714 // Put a nice label in the plot
716 UShort_t snn = fSNNString->GetUniqueID();
717 const char* sys = fSysString->GetTitle();
718 if (snn > 1000) eS = Form("%4.2fTeV", float(snn)/1000);
719 else eS = Form("%3dGeV", snn);
720 TLatex* tt = new TLatex(.93, .93, Form("%s #sqrt{s}=%s, %s",
723 fTrigString->GetTitle()));
725 tt->SetTextFont(132);
726 tt->SetTextAlign(33);
729 // Put number of accepted events on the plot
731 if (fTriggers) nev = fTriggers->GetBinContent(1);
732 TLatex* et = new TLatex(.93, .83, Form("%d events", nev));
734 et->SetTextFont(132);
735 et->SetTextAlign(33);
738 // Put number of accepted events on the plot
740 TLatex* vt = new TLatex(.93, .88, fVtxAxis->GetTitle());
742 vt->SetTextFont(132);
743 vt->SetTextAlign(33);
746 // results->Draw("nostack e1 same");
748 fRangeParam->fSlave1Axis = FindXAxis(p1, fResults->GetName());
749 fRangeParam->fSlave1Pad = p1;
752 // Mark the plot as preliminary
753 TLatex* pt = new TLatex(.12, .93, "Preliminary");
756 pt->SetTextSize(0.07);
757 pt->SetTextColor(kRed+1);
758 pt->SetTextAlign(13);
761 if (!gSystem->AccessPathName("ALICE.png")) {
762 TPad* logo = new TPad("logo", "logo", .12, .65, .25, .85, 0, 0, 0);
763 logo->SetFillStyle(0);
766 TImage* i = TImage::Create();
767 i->ReadImage("ALICE.png");
772 //__________________________________________________________________
776 * @param max Maximum diviation from 1
777 * @param y1 Lower y coordinate of pad
778 * @param y2 Upper y coordinate of pad
780 void PlotRatios(Double_t max, Double_t y1, Double_t y2)
782 if (!fShowRatios) return;
784 bool isBottom = (y1 < 0.0001);
785 Double_t yd = y2 - y1;
786 // Make a sub-pad for the result itself
787 TPad* p2 = new TPad("p2", "p2", 0, y1, 1.0, y2, 0, 0, 0);
788 p2->SetTopMargin(0.001);
789 p2->SetRightMargin(0.05);
790 p2->SetBottomMargin(isBottom ? 1/yd * 0.07 : 0.0001);
798 FixAxis(fRatios, 1/yd/1.7, "Ratios", 7);
800 fRatios->SetMaximum(1+TMath::Max(.22,1.05*max));
801 fRatios->SetMinimum(1-TMath::Max(.32,1.05*max));
803 fRatios->DrawClone("nostack e1");
807 BuildLegend(fRatios, 0, .15,p2->GetBottomMargin()+.01,.9,
810 TLegend* l2 = p2->BuildLegend(.15,p2->GetBottomMargin()+.01,.9,
815 l2->SetBorderSize(0);
816 l2->SetTextFont(132);
818 // Make a nice band from 0.9 to 1.1
819 TGraphErrors* band = new TGraphErrors(2);
820 band->SetPoint(0, fResults->GetXaxis()->GetXmin(), 1);
821 band->SetPoint(1, fResults->GetXaxis()->GetXmax(), 1);
822 band->SetPointError(0, 0, .1);
823 band->SetPointError(1, 0, .1);
824 band->SetFillColor(kYellow+2);
825 band->SetFillStyle(3002);
826 band->SetLineStyle(2);
827 band->SetLineWidth(1);
828 band->Draw("3 same");
829 band->DrawClone("X L same");
831 // Replot the ratios on top
832 fRatios->DrawClone("nostack e1 same");
835 fRangeParam->fMasterAxis = FindXAxis(p2, fRatios->GetName());
836 p2->AddExec("range", Form("RangeExec((dNdetaDrawer::RangeParam*)%p)",
840 fRangeParam->fSlave2Axis = FindXAxis(p2, fRatios->GetName());
841 fRangeParam->fSlave2Pad = p2;
844 //__________________________________________________________________
846 * Plot the asymmetries
848 * @param max Maximum diviation from 1
849 * @param y1 Lower y coordinate of pad
850 * @param y2 Upper y coordinate of pad
852 void PlotLeftRight(Double_t max, Double_t y1, Double_t y2)
854 if (!fShowLeftRight) return;
856 bool isBottom = (y1 < 0.0001);
857 Double_t yd = y2 - y1;
858 // Make a sub-pad for the result itself
859 TPad* p3 = new TPad("p3", "p3", 0, y1, 1.0, y2, 0, 0, 0);
860 p3->SetTopMargin(0.001);
861 p3->SetRightMargin(0.05);
862 p3->SetBottomMargin(isBottom ? 1/yd * 0.07 : 0.0001);
870 FixAxis(fLeftRight, 1/yd/1.7, "Right/Left", 4);
872 fLeftRight->SetMaximum(1+TMath::Max(.12,1.05*max));
873 fLeftRight->SetMinimum(1-TMath::Max(.15,1.05*max));
875 fLeftRight->DrawClone("nostack e1");
879 TLegend* l2 = p3->BuildLegend(.15,p3->GetBottomMargin()+.01,.9,.5);
883 l2->SetBorderSize(0);
884 l2->SetTextFont(132);
886 // Make a nice band from 0.9 to 1.1
887 TGraphErrors* band = new TGraphErrors(2);
888 band->SetPoint(0, fResults->GetXaxis()->GetXmin(), 1);
889 band->SetPoint(1, fResults->GetXaxis()->GetXmax(), 1);
890 band->SetPointError(0, 0, .05);
891 band->SetPointError(1, 0, .05);
892 band->SetFillColor(kYellow+2);
893 band->SetFillStyle(3002);
894 band->SetLineStyle(2);
895 band->SetLineWidth(1);
896 band->Draw("3 same");
897 band->DrawClone("X L same");
899 fLeftRight->DrawClone("nostack e1 same");
901 fRangeParam->fMasterAxis = FindXAxis(p3, fLeftRight->GetName());
902 p3->AddExec("range", Form("RangeExec((dNdetaDrawer::RangeParam*)%p)",
906 fRangeParam->fSlave2Axis = FindXAxis(p3, fLeftRight->GetName());
907 fRangeParam->fSlave2Pad = p3;
911 //==================================================================
914 * @name Data utility functions
917 * Get a result from the passed list
919 * @param list List to search
920 * @param name Object name to search for
924 TH1* FetchResult(const TList* list, const char* name) const
928 TH1* ret = static_cast<TH1*>(list->FindObject(name));
931 Warning("GetResult", "Histogram %s not found", name);
936 //__________________________________________________________________
938 * Add a histogram to the stack after possibly rebinning it
940 * @param stack Stack to add to
941 * @param hist histogram
942 * @param option Draw options
944 * @return Maximum of histogram
946 Double_t AddHistogram(THStack* stack, TH1* hist, Option_t* option="") const
948 // Check if we have input
954 // Info("AddHistogram", "Adding %s to %s",
955 // hist->GetName(), stack->GetName());
956 stack->Add(hist, option);
958 return hist->GetMaximum();
960 //__________________________________________________________________
962 * Add a histogram to the stack after possibly rebinning it
964 * @param stack Stack to add to
965 * @param hist histogram
966 * @param option Draw options
967 * @param sym On return, the data symmetriced (added to stack)
969 * @return Maximum of histogram
971 Double_t AddHistogram(THStack* stack, TH1* hist, TH1*& sym,
972 Option_t* option="") const
974 // Check if we have input
979 stack->Add(hist, option);
981 // Now symmetrice the histogram
982 sym = Symmetrice(hist);
983 stack->Add(sym, option);
985 // Info("AddHistogram", "Adding %s and %s to %s",
986 // hist->GetName(), sym->GetName(), stack->GetName());
987 return hist->GetMaximum();
990 //__________________________________________________________________
994 * @param h Histogram to rebin
998 virtual void Rebin(TH1* h) const
1000 if (fRebin <= 1) return;
1002 Int_t nBins = h->GetNbinsX();
1003 if(nBins % fRebin != 0) {
1004 Warning("Rebin", "Rebin factor %d is not a devisor of current number "
1005 "of bins %d in the histogram %s", fRebin, nBins, h->GetName());
1010 TH1* tmp = static_cast<TH1*>(h->Clone("tmp"));
1012 tmp->SetDirectory(0);
1014 // The new number of bins
1015 Int_t nBinsNew = nBins / fRebin;
1016 for(Int_t i = 1;i<= nBinsNew; i++) {
1017 Double_t content = 0;
1021 for(Int_t j = 1; j<=fRebin;j++) {
1022 Int_t bin = (i-1)*fRebin + j;
1023 Double_t c = h->GetBinContent(bin);
1025 if (c <= 0) continue;
1028 if (h->GetBinContent(bin+1)<=0 ||
1029 h->GetBinContent(bin-1)) {
1030 Warning("Rebin", "removing bin %d=%f of %s (%d=%f,%d=%f)",
1031 bin, c, h->GetName(),
1032 bin+1, h->GetBinContent(bin+1),
1033 bin-1, h->GetBinContent(bin-1));
1037 Double_t e = h->GetBinError(bin);
1038 Double_t w = 1 / (e*e); // 1/c/c
1045 if(content > 0 && nbins > 1 ) {
1046 tmp->SetBinContent(i, wsum / sumw);
1047 tmp->SetBinError(i,1./TMath::Sqrt(sumw));
1051 // Finally, rebin the histogram, and set new content
1054 for(Int_t i = 1; i<= nBinsNew; i++) {
1055 h->SetBinContent(i,tmp->GetBinContent(i));
1056 h->SetBinError(i, tmp->GetBinError(i));
1061 //__________________________________________________________________
1063 * Make an extension of @a h to make it symmetric about 0
1065 * @param h Histogram to symmertrice
1067 * @return Symmetric extension of @a h
1069 TH1* Symmetrice(const TH1* h) const
1071 Int_t nBins = h->GetNbinsX();
1072 TH1* s = static_cast<TH1*>(h->Clone(Form("%s_mirror", h->GetName())));
1073 s->SetTitle(Form("%s (mirrored)", h->GetTitle()));
1075 s->SetBins(nBins, -h->GetXaxis()->GetXmax(), -h->GetXaxis()->GetXmin());
1076 s->SetMarkerColor(h->GetMarkerColor());
1077 s->SetMarkerSize(h->GetMarkerSize());
1078 s->SetMarkerStyle(h->GetMarkerStyle()+4);
1079 s->SetFillColor(h->GetFillColor());
1080 s->SetFillStyle(h->GetFillStyle());
1083 // Find the first and last bin with data
1084 Int_t first = nBins+1;
1086 for (Int_t i = 1; i <= nBins; i++) {
1087 if (h->GetBinContent(i) <= 0) continue;
1088 first = TMath::Min(first, i);
1089 last = TMath::Max(last, i);
1092 Double_t xfirst = h->GetBinCenter(first-1);
1093 Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
1094 Int_t l2 = s->GetXaxis()->FindBin(xfirst);
1095 for (Int_t i = f1, j=l2; i <= last; i++,j--) {
1096 s->SetBinContent(j, h->GetBinContent(i));
1097 s->SetBinError(j, h->GetBinError(i));
1099 // Fill in overlap bin
1100 s->SetBinContent(l2+1, h->GetBinContent(first));
1101 s->SetBinError(l2+1, h->GetBinError(first));
1104 //__________________________________________________________________
1106 * Calculate the left-right asymmetry of input histogram
1108 * @param h Input histogram
1109 * @param max On return, the maximum distance from 1 of the histogram
1113 TH1* Asymmetry(TH1* h, Double_t& max)
1117 TH1* ret = static_cast<TH1*>(h->Clone(Form("%s_leftright", h->GetName())));
1118 // Int_t oBins = h->GetNbinsX();
1119 // Double_t high = h->GetXaxis()->GetXmax();
1120 // Double_t low = h->GetXaxis()->GetXmin();
1121 // Double_t dBin = (high - low) / oBins;
1122 // Int_t tBins = Int_t(2*high/dBin+.5);
1123 // ret->SetBins(tBins, -high, high);
1124 ret->SetDirectory(0);
1126 ret->SetTitle(Form("%s (+/-)", h->GetTitle()));
1127 ret->SetYTitle("Right/Left");
1128 Int_t nBins = h->GetNbinsX();
1129 for (Int_t i = 1; i <= nBins; i++) {
1130 Double_t x = h->GetBinCenter(i);
1133 Double_t c1 = h->GetBinContent(i);
1134 Double_t e1 = h->GetBinError(i);
1135 if (c1 <= 0) continue;
1137 Int_t j = h->FindBin(-x);
1138 if (j <= 0 || j > nBins) continue;
1140 Double_t c2 = h->GetBinContent(j);
1141 Double_t e2 = h->GetBinError(j);
1143 Double_t c12 = c1*c1;
1144 Double_t e = TMath::Sqrt((e2*e2*c1*c1+e1*e1*c2*c2)/(c12*c12));
1146 Int_t k = ret->FindBin(x);
1147 ret->SetBinContent(k, c2/c1);
1148 ret->SetBinError(k, e);
1150 max = TMath::Max(max, RatioMax(ret));
1154 //__________________________________________________________________
1156 * Transform a graph into a histogram
1162 TH1* Graph2Hist(const TGraphAsymmErrors* g) const
1164 Int_t nBins = g->GetN();
1165 TArrayF bins(nBins+1);
1167 for (Int_t i = 0; i < nBins; i++) {
1168 Double_t x = g->GetX()[i];
1169 Double_t exl = g->GetEXlow()[i];
1170 Double_t exh = g->GetEXhigh()[i];
1171 bins.fArray[i] = x-exl;
1172 bins.fArray[i+1] = x+exh;
1173 Double_t dxi = exh+exl;
1174 if (i == 0) dx = dxi;
1175 else if (dxi != dx) dx = 0;
1177 TString name(g->GetName());
1178 TString title(g->GetTitle());
1181 h = new TH1D(name.Data(), title.Data(), nBins, bins[0], bins[nBins]);
1184 h = new TH1D(name.Data(), title.Data(), nBins, bins.fArray);
1186 h->SetMarkerStyle(g->GetMarkerStyle());
1187 h->SetMarkerColor(g->GetMarkerColor());
1188 h->SetMarkerSize(g->GetMarkerSize());
1193 //==================================================================
1196 * @name Ratio utility functions
1199 * Get the maximum diviation from 1 in the passed ratio
1201 * @param h Ratio histogram
1203 * @return Max diviation from 1
1205 Double_t RatioMax(TH1* h) const
1207 Int_t nBins = h->GetNbinsX();
1209 for (Int_t i = 1; i <= nBins; i++) {
1210 Double_t c = h->GetBinContent(i);
1211 if (c == 0) continue;
1212 Double_t e = h->GetBinError(i);
1213 Double_t d = TMath::Abs(1-c-e);
1214 ret = TMath::Max(d, ret);
1218 //__________________________________________________________________
1220 * Make the ratio of h1 to h2
1222 * @param o1 First object (numerator)
1223 * @param o2 Second object (denominator)
1224 * @param max Maximum diviation from 1
1228 TH1* Ratio(const TObject* o1, const TObject* o2, Double_t& max) const
1231 const TH1* h1 = dynamic_cast<const TH1*>(o1);
1233 // Info("Ratio", "First is a TH1");
1234 const TH1* h2 = dynamic_cast<const TH1*>(o2);
1236 // Info("Ratio", "Second is a TH1");
1237 r = RatioHH(h1,h2,max);
1240 const TGraph* g2 = dynamic_cast<const TGraph*>(o2);
1242 // Info("Ratio", "Second os a TGraph");
1243 r = RatioHG(h1,g2,max);
1248 const TGraphAsymmErrors* g1 = dynamic_cast<const TGraphAsymmErrors*>(o1);
1250 // Info("Ratio", "First is a TGraphAsymmErrors");
1251 const TGraphAsymmErrors* g2 =
1252 dynamic_cast<const TGraphAsymmErrors*>(o2);
1254 // Info("Ratio", "Second is a TGraphAsymmErrors");
1255 r = RatioGG(g1, g2, max);
1260 Warning("Ratio", "Don't know how to divide a %s (%s) with a %s (%s)",
1261 o1->ClassName(), o1->GetName(), o2->ClassName(), o2->GetName());
1264 // Check that the histogram isn't empty
1265 if (r->GetEntries() <= 0) {
1269 // for (Int_t bin = 1; bin <= r->GetNbinsX(); bin++)
1270 // if (r->GetBinContent(bin) != 0) return r;
1274 //__________________________________________________________________
1276 * Compute the ratio of @a h to @a g. @a g is evaluated at the bin
1279 * @param h Numerator
1281 * @param max Maximum diviation from 1
1285 TH1* RatioHG(const TH1* h, const TGraph* g, Double_t& max) const
1287 if (!h || !g) return 0;
1289 TH1* ret = static_cast<TH1*>(h->Clone("tmp"));
1290 ret->SetName(Form("%s_over_%s", h->GetName(), g->GetName()));
1291 ret->SetTitle(Form("%s / %s", h->GetTitle(), g->GetTitle()));
1293 ret->SetMarkerStyle(h->GetMarkerStyle());
1294 ret->SetMarkerColor(g->GetMarkerColor());
1295 ret->SetMarkerSize(0.9*h->GetMarkerSize());
1296 // ret->SetMarkerStyle(g->GetMarkerStyle());
1297 // ret->SetMarkerColor(h->GetMarkerColor());
1298 // ret->SetMarkerSize(0.9*g->GetMarkerSize());
1299 ret->SetDirectory(0);
1300 Double_t xlow = g->GetX()[0];
1301 Double_t xhigh = g->GetX()[g->GetN()-1];
1302 if (xlow > xhigh) { Double_t t = xhigh; xhigh = xlow; xlow = t; }
1304 for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
1305 Double_t c = h->GetBinContent(i);
1306 if (c <= 0) continue;
1308 Double_t x = h->GetBinCenter(i);
1309 if (x < xlow || x > xhigh) continue;
1311 Double_t f = g->Eval(x);
1312 if (f <= 0) continue;
1314 ret->SetBinContent(i, c / f);
1315 ret->SetBinError(i, h->GetBinError(i) / f);
1317 if (ret->GetEntries() > 0)
1318 max = TMath::Max(RatioMax(ret), max);
1321 //__________________________________________________________________
1323 * Make the ratio of h1 to h2
1325 * @param h1 First histogram (numerator)
1326 * @param h2 Second histogram (denominator)
1327 * @param max Maximum diviation from 1
1331 TH1* RatioHH(const TH1* h1, const TH1* h2, Double_t& max) const
1333 if (!h1 || !h2) return 0;
1334 TH1* t1 = static_cast<TH1*>(h1->Clone(Form("%s_%s",
1337 t1->SetTitle(Form("%s / %s", h1->GetTitle(), h2->GetTitle()));
1339 // t1->SetMarkerColor(h1->GetMarkerColor());
1340 // t1->SetMarkerStyle(h2->GetMarkerStyle());
1341 t1->SetMarkerColor(h2->GetMarkerColor());
1342 t1->SetMarkerStyle(h1->GetMarkerStyle());
1343 t1->SetMarkerSize(0.9*h1->GetMarkerSize());
1344 t1->SetDirectory(0);
1345 max = TMath::Max(RatioMax(t1), max);
1348 //__________________________________________________________________
1350 * Calculate the ratio of two graphs - g1 / g2
1352 * @param g1 Numerator
1353 * @param g2 Denominator
1354 * @param max Maximum diviation from 1
1356 * @return g1 / g2 in a histogram
1358 TH1* RatioGG(const TGraphAsymmErrors* g1,
1359 const TGraphAsymmErrors* g2, Double_t& max) const
1361 Int_t nBins = g1->GetN();
1362 TArrayF bins(nBins+1);
1364 for (Int_t i = 0; i < nBins; i++) {
1365 Double_t x = g1->GetX()[i];
1366 Double_t exl = g1->GetEXlow()[i];
1367 Double_t exh = g1->GetEXhigh()[i];
1368 bins.fArray[i] = x-exl;
1369 bins.fArray[i+1] = x+exh;
1370 Double_t dxi = exh+exl;
1371 if (i == 0) dx = dxi;
1372 else if (dxi != dx) dx = 0;
1374 TString name(Form("%s_%s", g1->GetName(), g2->GetName()));
1375 TString title(Form("%s / %s", g1->GetTitle(), g2->GetTitle()));
1378 h = new TH1F(name.Data(), title.Data(), nBins, bins[0], bins[nBins]);
1381 h = new TH1F(name.Data(), title.Data(), nBins, bins.fArray);
1383 h->SetMarkerStyle(g1->GetMarkerStyle());
1384 h->SetMarkerColor(g2->GetMarkerColor());
1385 h->SetMarkerSize(0.9*g1->GetMarkerSize());
1386 // h->SetMarkerStyle(g2->GetMarkerStyle());
1387 // h->SetMarkerColor(g1->GetMarkerColor());
1388 // h->SetMarkerSize(0.9*g2->GetMarkerSize());
1391 Double_t low = g2->GetX()[0];
1392 Double_t high = g2->GetX()[g2->GetN()-1];
1393 if (low > high) { Double_t t = low; low = high; high = t; }
1394 for (Int_t i = 0; i < nBins; i++) {
1395 Double_t x = g1->GetX()[i];
1396 if (x < low-dx || x > high+dx) continue;
1397 Double_t c1 = g1->GetY()[i];
1398 Double_t e1 = g1->GetErrorY(i);
1399 Double_t c2 = g2->Eval(x);
1401 h->SetBinContent(i+1, c1 / c2);
1402 h->SetBinError(i+1, e1 / c2);
1404 max = TMath::Max(RatioMax(h), max);
1408 //==================================================================
1411 * @name Graphics utility functions
1414 * Find an X axis in a pad
1417 * @param name Histogram to find axis for
1419 * @return Found axis or null
1421 TAxis* FindXAxis(TVirtualPad* p, const char* name)
1423 TObject* o = p->GetListOfPrimitives()->FindObject(name);
1425 Warning("FindXAxis", "%s not found in pad", name);
1428 THStack* stack = dynamic_cast<THStack*>(o);
1430 Warning("FindXAxis", "%s is not a THStack", name);
1433 if (!stack->GetHistogram()) {
1434 Warning("FindXAxis", "%s has no histogram", name);
1437 TAxis* ret = stack->GetHistogram()->GetXaxis();
1441 //__________________________________________________________________
1443 * Fix the apperance of the axis in a stack
1445 * @param stack stack of histogram
1446 * @param s Scaling factor
1447 * @param ytitle Y axis title
1448 * @param force Whether to draw the stack first or not
1449 * @param ynDiv Divisions on Y axis
1451 void FixAxis(THStack* stack, Double_t s, const char* ytitle,
1452 Int_t ynDiv=210, Bool_t force=true)
1455 Warning("FixAxis", "No stack passed for %s!", ytitle);
1458 if (force) stack->Draw("nostack e1");
1460 TH1* h = stack->GetHistogram();
1462 Warning("FixAxis", "Stack %s has no histogram", stack->GetName());
1466 h->SetXTitle("#eta");
1467 h->SetYTitle(ytitle);
1468 TAxis* xa = h->GetXaxis();
1469 TAxis* ya = h->GetYaxis();
1471 xa->SetTitle("#eta");
1472 // xa->SetTicks("+-");
1473 xa->SetTitleSize(s*xa->GetTitleSize());
1474 xa->SetLabelSize(s*xa->GetLabelSize());
1475 xa->SetTickLength(s*xa->GetTickLength());
1477 if (stack != fResults) {
1478 TAxis* rxa = fResults->GetXaxis();
1479 xa->Set(rxa->GetNbins(), rxa->GetXmin(), rxa->GetXmax());
1483 ya->SetTitle(ytitle);
1485 // ya->SetTicks("+-");
1486 ya->SetNdivisions(ynDiv);
1487 ya->SetTitleSize(s*ya->GetTitleSize());
1488 ya->SetTitleOffset(ya->GetTitleOffset()/s);
1489 ya->SetLabelSize(s*ya->GetLabelSize());
1496 //__________________________________________________________________
1497 Bool_t fShowOthers; // Show other data
1498 Bool_t fShowAlice; // Show ALICE published data
1499 Bool_t fShowRatios; // Show ratios
1500 Bool_t fShowLeftRight;// Show asymmetry
1501 UShort_t fRebin; // Rebinning factor
1502 Bool_t fCutEdges; // Whether to cut edges
1503 TString fTitle; // Title on plot
1504 TNamed* fTrigString; // Trigger string (read, or set)
1505 TNamed* fSNNString; // Energy string (read, or set)
1506 TNamed* fSysString; // Collision system string (read or set)
1507 TAxis* fVtxAxis; // Vertex cuts (read or set)
1508 TAxis* fCentAxis; // Centrality axis
1509 THStack* fResults; // Stack of results
1510 THStack* fRatios; // Stack of ratios
1511 THStack* fLeftRight; // Left-right asymmetry
1512 TMultiGraph* fOthers; // Older data
1513 TH1* fTriggers; // Number of triggers
1514 RangeParam* fRangeParam; // Parameter object for range zoom
1518 //=== Stuff for auto zooming =========================================
1519 void UpdateRange(dNdetaDrawer::RangeParam* p)
1522 Warning("UpdateRange", "No parameters %p", p);
1525 if (!p->fMasterAxis) {
1526 Warning("UpdateRange", "No master axis %p", p->fMasterAxis);
1529 Int_t first = p->fMasterAxis->GetFirst();
1530 Int_t last = p->fMasterAxis->GetLast();
1531 Double_t x1 = p->fMasterAxis->GetBinCenter(first);
1532 Double_t x2 = p->fMasterAxis->GetBinCenter(last);
1533 //Info("UpdateRange", "Range set to [%3d,%3d]->[%f,%f]", first, last, x1,x2);
1535 if (p->fSlave1Axis) {
1536 Int_t i1 = p->fSlave1Axis->FindBin(x1);
1537 Int_t i2 = p->fSlave1Axis->FindBin(x2);
1538 p->fSlave1Axis->SetRange(i1, i2);
1539 p->fSlave1Pad->Modified();
1540 p->fSlave1Pad->Update();
1542 if (p->fSlave2Axis) {
1543 Int_t i1 = p->fSlave2Axis->FindBin(x1);
1544 Int_t i2 = p->fSlave2Axis->FindBin(x2);
1545 p->fSlave2Axis->SetRange(i1, i2);
1546 p->fSlave2Pad->Modified();
1547 p->fSlave2Pad->Update();
1549 TCanvas* c = gPad->GetCanvas();
1553 //____________________________________________________________________
1554 void RangeExec(dNdetaDrawer::RangeParam* p)
1561 // 11: Mouse release
1562 // dNdetaDrawer::RangeParam* p =
1563 // reinterpret_cast<dNdetaDrawer::RangeParam*>(addr);
1564 Int_t event = gPad->GetEvent();
1565 TObject *select = gPad->GetSelected();
1570 if (event != 11 || !select || select != p->fMasterAxis) return;
1574 //=== Steering function ==============================================
1576 * Draw @f$ dN/d\eta@f$
1578 * @param filename File name
1579 * @param flags Flags
1580 * @param title Title
1581 * @param rebin Rebinning factor
1582 * @param cutEdges Whether to cut edges when rebinning
1583 * @param sNN (optional) Collision energy [GeV]
1584 * @param sys (optional) Collision system (1: pp, 2: PbPb)
1585 * @param trg (optional) Trigger (1: INEL, 2: INEL>0, 4: NSD)
1586 * @param vzMin Least @f$ v_z@f$
1587 * @param vzMax Largest @f$ v_z@f$
1589 * @ingroup pwg2_forward_dndeta
1592 DrawdNdeta(const char* filename="forward_dndeta.root",
1594 const char* title="",
1596 Bool_t cutEdges=false,
1603 dNdetaDrawer* pd = new dNdetaDrawer;
1604 dNdetaDrawer& d = *pd;
1606 d.SetCutEdges(cutEdges);
1608 d.SetShowOthers(flags & 0x1);
1609 d.SetShowAlice(flags & 0x2);
1610 d.SetShowRatios(flags & 0x4);
1611 d.SetShowLeftRight(flags & 0x8);
1612 // Do the below if your input data does not contain these settings
1613 if (sNN > 0) d.SetSNN(sNN); // Collision energy per nucleon pair (GeV)
1614 if (sys > 0) d.SetSys(sys); // Collision system (1:pp, 2:PbPB)
1615 if (trg > 0) d.SetTrigger(trg); // Collision trigger (1:INEL, 2:INEL>0, 4:NSD)
1616 if (vzMin < 999 && vzMax > -999)
1617 d.SetVertexRange(vzMin,vzMax); // Collision vertex range (cm)
1620 //____________________________________________________________________