]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG2/FORWARD/analysis2/DrawdNdeta.C
updated dphi correlation analysis
[u/mrichter/AliRoot.git] / PWG2 / FORWARD / analysis2 / DrawdNdeta.C
CommitLineData
e1f47419 1/**
ffca499d 2 * @file DrawdNdeta.C
3 * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
4 * @date Wed Mar 23 14:07:10 2011
5 *
5bb5d1f6 6 * @brief Script to visualise the dN/deta for pp and PbPb
e1f47419 7 *
ffca499d 8 * This script is independent of any AliROOT code - and should stay
9 * that way.
10 *
5bb5d1f6 11 * The script is <emph>very</emph> long - sigh - the joy of drawing
12 * things nicely in ROOT
ffca499d 13 *
14 * @ingroup pwg2_forward_dndeta
e1f47419 15 */
b2e7f2d6 16#include <TH1.h>
f709afcf 17#include <TColor.h>
b2e7f2d6 18#include <THStack.h>
19#include <TGraphErrors.h>
20#include <TGraphAsymmErrors.h>
21#include <TMultiGraph.h>
22#include <TFile.h>
23#include <TList.h>
24#include <TString.h>
25#include <TError.h>
26#include <TSystem.h>
27#include <TROOT.h>
28#include <TMath.h>
29#include <TCanvas.h>
30#include <TPad.h>
31#include <TStyle.h>
32#include <TLegend.h>
33#include <TLegendEntry.h>
34#include <TLatex.h>
35#include <TImage.h>
36
2f92ff0e 37/**
38 * Class to draw dN/deta results
39 *
ffca499d 40 * @ingroup pwg2_forward_tasks_dndeta
41 * @ingroup pwg2_forward_dndeta
2f92ff0e 42 */
b2e7f2d6 43struct dNdetaDrawer
44{
2f92ff0e 45 /**
46 * POD of data for range zooming
47 */
b2e7f2d6 48 struct RangeParam
49 {
50 TAxis* fMasterAxis; // Master axis
51 TAxis* fSlave1Axis; // First slave axis
52 TVirtualPad* fSlave1Pad; // First slave pad
53 TAxis* fSlave2Axis; // Second slave axis
54 TVirtualPad* fSlave2Pad; // Second slave pad
55 };
56 //__________________________________________________________________
2f92ff0e 57 /**
58 * Constructor
59 *
60 */
b2e7f2d6 61 dNdetaDrawer()
62 : fShowOthers(false), // Bool_t
63 fShowAlice(false), // Bool_t
64 fShowRatios(false), // Bool_t
65 fShowLeftRight(false), // Bool_t
f709afcf 66 fShowRings(false), // Bool_t
b2e7f2d6 67 fRebin(5), // UShort_t
68 fCutEdges(false), // Bool_t
69 fTitle(""), // TString
b2e7f2d6 70 fTrigString(0), // TNamed*
0be6c8cd 71 fNormString(0), // TNamed*
b2e7f2d6 72 fSNNString(0), // TNamed*
73 fSysString(0), // TNamed*
74 fVtxAxis(0), // TAxis*
ffca499d 75 fCentAxis(0), // TAxis*
b2e7f2d6 76 fTriggers(0), // TH1*
77 fRangeParam(0)
78
79 {
80 fRangeParam = new RangeParam;
81 fRangeParam->fMasterAxis = 0;
82 fRangeParam->fSlave1Axis = 0;
83 fRangeParam->fSlave1Pad = 0;
84 fRangeParam->fSlave2Axis = 0;
85 fRangeParam->fSlave2Pad = 0;
86 }
ffca499d 87 //__________________________________________________________________
88 virtual ~dNdetaDrawer()
89 {
90 if (fRatios && fRatios->GetHists()) fRatios->GetHists()->Delete();
91 if (fResults && fResults->GetHists()) fResults->GetHists()->Delete();
92
93 if (fTrigString) { delete fTrigString; fTrigString = 0; }
94 if (fSNNString) { delete fSNNString; fSNNString = 0; }
95 if (fSysString) { delete fSysString; fSysString = 0; }
96 if (fVtxAxis) { delete fVtxAxis; fVtxAxis = 0; }
97 if (fCentAxis) { delete fCentAxis; fCentAxis = 0; }
98 if (fResults) { delete fResults; fResults = 0; }
99 if (fRatios) { delete fRatios; fRatios = 0; }
100 if (fOthers) { delete fOthers; fOthers = 0; }
101 if (fTriggers) { delete fTriggers; fTriggers = 0; }
102 fRangeParam = 0;
103 }
104
2f92ff0e 105 //==================================================================
106 /**
107 * @{
108 * @name Set parameters
109 */
110 /**
111 * Show other (UA5, CMS, ...) data
112 *
113 * @param x Whether to show or not
114 */
b2e7f2d6 115 void SetShowOthers(Bool_t x) { fShowOthers = x; }
2f92ff0e 116 //__________________________________________________________________
117 /**
118 * Show ALICE published data
119 *
120 * @param x Wheter to show or not
121 */
b2e7f2d6 122 void SetShowAlice(Bool_t x) { fShowAlice = x; }
2f92ff0e 123 //__________________________________________________________________
124 /**
125 * Whether to show ratios or not. If there's nothing to compare to,
126 * the ratio panel will be implicitly disabled
127 *
128 * @param x Whether to show or not
129 */
b2e7f2d6 130 void SetShowRatios(Bool_t x) { fShowRatios = x; }
2f92ff0e 131 //__________________________________________________________________
132 /**
133 *
134 * Whether to show the left/right asymmetry
135 *
136 * @param x To show or not
137 */
b2e7f2d6 138 void SetShowLeftRight(Bool_t x) { fShowLeftRight = x; }
f709afcf 139 void SetShowRings(Bool_t x) { fShowRings = x; }
2f92ff0e 140 //__________________________________________________________________
141 /**
142 * Set the rebinning factor
143 *
144 * @param x Rebinning factor (must be a divisor in the number of bins)
145 */
b2e7f2d6 146 void SetRebin(UShort_t x) { fRebin = x; }
2f92ff0e 147 //__________________________________________________________________
148 /**
149 * Wheter to cut away the edges
150 *
151 * @param x Whether or not to cut away edges
152 */
b2e7f2d6 153 void SetCutEdges(Bool_t x) { fCutEdges = x; }
2f92ff0e 154 //__________________________________________________________________
155 /**
156 * Set the title of the plot
157 *
158 * @param x Title
159 */
b2e7f2d6 160 void SetTitle(TString x) { fTitle = x; }
2f92ff0e 161 /* @} */
162 //==================================================================
163 /**
164 * @{
165 * @name Override settings from input
166 */
167 /**
168 * Override setting from file
169 *
170 * @param sNN Center of mass energy per nucleon pair (GeV)
171 */
172 void SetSNN(UShort_t sNN)
173 {
cdb9e20f 174 fSNNString = new TNamed("sNN", Form("%04dGeV", sNN));
2f92ff0e 175 fSNNString->SetUniqueID(sNN);
176 }
177 //__________________________________________________________________
178 /**
179 * Set the collision system
180 * - 1: pp
181 * - 2: PbPb
182 *
183 * @param sys collision system
184 */
185 void SetSys(UShort_t sys)
186 {
fe52e455 187 fSysString = new TNamed("sys", (sys == 1 ? "pp" :
2f92ff0e 188 sys == 2 ? "PbPb" : "unknown"));
fe52e455 189 fSysString->SetUniqueID(sys);
2f92ff0e 190 }
191 //__________________________________________________________________
192 /**
193 * Set the vertex range in centimeters
194 *
195 * @param vzMin Min @f$ v_z@f$
196 * @param vzMax Max @f$ v_z@f$
197 */
198 void SetVertexRange(Double_t vzMin, Double_t vzMax)
199 {
200 fVtxAxis = new TAxis(10, vzMin, vzMax);
201 fVtxAxis->SetName("vtxAxis");
202 fVtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", vzMin, vzMax));
203 }
b2e7f2d6 204 //__________________________________________________________________
2f92ff0e 205 void SetTrigger(UShort_t trig)
206 {
207 fTrigString = new TNamed("trigString", (trig & 0x1 ? "INEL" :
208 trig & 0x2 ? "INEL>0" :
209 trig & 0x4 ? "NSD" :
210 "unknown"));
211 fTrigString->SetUniqueID(trig);
212 }
213
214
215 //==================================================================
216 /**
217 * @{
218 * @name Main steering functions
219 */
220 /**
221 * Run the code to produce the final result.
222 *
223 * @param filename File containing the data
224 */
e308a636 225 void Run(const char* filename="forward_dndeta.root")
b2e7f2d6 226 {
e308a636 227 Double_t max = 0, rmax=0, amax=0;
b2e7f2d6 228
e308a636 229 gStyle->SetPalette(1);
e1f47419 230
e308a636 231 // --- Open input file -------------------------------------------
232 TFile* file = TFile::Open(filename, "READ");
233 if (!file) {
234 Error("Open", "Cannot open %s", filename);
235 return;
236 }
237 // --- Get forward list ------------------------------------------
238 TList* forward = static_cast<TList*>(file->Get("ForwardResults"));
239 if (!forward) {
240 Error("Open", "Couldn't find list ForwardResults");
241 return;
242 }
243 // --- Get information on the run --------------------------------
244 FetchInformation(forward);
245 // --- Set the macro pathand load other data script --------------
246 gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2",
247 gROOT->GetMacroPath()));
248 gROOT->LoadMacro("OtherData.C");
249
250 // --- Get the central results -----------------------------------
251 TList* clusters = static_cast<TList*>(file->Get("CentralResults"));
252 if (!clusters) Warning("Open", "Couldn't find list CentralResults");
b2e7f2d6 253
e308a636 254 // --- Make our containtes ---------------------------------------
255 fResults = new THStack("results", "Results");
256 fRatios = new THStack("ratios", "Ratios");
257 fLeftRight = new THStack("asymmetry", "Left-right asymmetry");
258 fOthers = new TMultiGraph();
b2e7f2d6 259
e308a636 260 // --- Loop over input data --------------------------------------
261 FetchResults(forward, "Forward", max, rmax, amax);
262 FetchResults(clusters, "Central", max, rmax, amax);
b2e7f2d6 263
e308a636 264 // --- Get trigger information -----------------------------------
265 TList* sums = static_cast<TList*>(file->Get("ForwardSums"));
266 if (sums) {
267 TList* all = static_cast<TList*>(sums->FindObject("all"));
268 if (all) {
269 fTriggers = FetchResult(all, "triggers");
270 if (!fTriggers) all->ls();
271 }
272 else {
273 Warning("Run", "List all not found in ForwardSums");
274 sums->ls();
275 }
276 }
277 else {
278 Warning("Run", "No ForwardSums directory found in %s", file->GetName());
279 file->ls();
280 }
281
282 // --- Check our stacks ------------------------------------------
283 if (!fResults->GetHists() ||
284 fResults->GetHists()->GetEntries() <= 0) {
285 Error("Run", "No histograms in result stack!");
286 return;
287 }
288 if (!fOthers->GetListOfGraphs() ||
289 fOthers->GetListOfGraphs()->GetEntries() <= 0) {
290 Warning("Run", "No other data found - disabling that");
291 fShowOthers = false;
292 }
293 if (!fRatios->GetHists() ||
294 fRatios->GetHists()->GetEntries() <= 0) {
295 Warning("Run", "No ratio data found - disabling that");
296 // fRatios->ls();
297 fShowRatios = false;
298 }
299 if (!fLeftRight->GetHists() ||
300 fLeftRight->GetHists()->GetEntries() <= 0) {
301 Warning("Run", "No left/right data found - disabling that");
302 // fLeftRight->ls();
303 fShowLeftRight = false;
304 }
305
306 // --- Close the input file --------------------------------------
307 file->Close();
308
309
b2e7f2d6 310
e308a636 311 // --- Plot results ----------------------------------------------
312 Plot(max, rmax, amax);
b2e7f2d6 313 }
e1f47419 314
b2e7f2d6 315 //__________________________________________________________________
2f92ff0e 316 /**
e1f47419 317 * Fetch the information on the run from the results list
2f92ff0e 318 *
e1f47419 319 * @param results Results list
2f92ff0e 320 */
e1f47419 321 void FetchInformation(const TList* results)
b2e7f2d6 322 {
2f92ff0e 323 if (!fTrigString)
0be6c8cd 324 fTrigString = static_cast<TNamed*>(results->FindObject("trigger"));
325 if (!fNormString)
326 fNormString = static_cast<TNamed*>(results->FindObject("scheme"));
2f92ff0e 327 if (!fSNNString)
328 fSNNString = static_cast<TNamed*>(results->FindObject("sNN"));
329 if (!fSysString)
330 fSysString = static_cast<TNamed*>(results->FindObject("sys"));
331 if (!fVtxAxis)
332 fVtxAxis = static_cast<TAxis*>(results->FindObject("vtxAxis"));
e308a636 333 if (!fCentAxis)
334 fCentAxis = static_cast<TAxis*>(results->FindObject("centAxis"));
c25b5e1b 335
336 TNamed* options = static_cast<TAxis*>(results->FindObject("options"));
0be6c8cd 337 if (!fTrigString) fTrigString = new TNamed("trigger", "unknown");
338 if (!fNormString) fNormString = new TNamed("scheme", "unknown");
bad9a3c1 339 if (!fSNNString) fSNNString = new TNamed("sNN", "unknown");
340 if (!fSysString) fSysString = new TNamed("sys", "unknown");
341 if (!fVtxAxis) {
342 fVtxAxis = new TAxis(1,0,0);
343 fVtxAxis->SetName("vtxAxis");
344 fVtxAxis->SetTitle("v_{z} range unspecified");
345 }
b2e7f2d6 346
0be6c8cd 347 TString centTxt("none");
e308a636 348 if (fCentAxis) {
349 Int_t nCent = fCentAxis->GetNbins();
0be6c8cd 350 centTxt = Form("%d bins", nCent);
e308a636 351 for (Int_t i = 0; i <= nCent; i++)
0be6c8cd 352 centTxt.Append(Form("%c%d", i == 0 ? ' ' : '-',
ffca499d 353 int(fCentAxis->GetXbins()->At(i))));
e308a636 354 }
e1f47419 355 Info("FetchInformation",
fe52e455 356 "Initialized for\n"
0be6c8cd 357 " Trigger: %-30s (%d)\n"
358 " sqrt(sNN): %-30s (%dGeV)\n"
359 " System: %-30s (%d)\n"
360 " Vz range: %-30s (%f,%f)\n"
361 " Normalization: %-30s (%d)\n"
c25b5e1b 362 " Centrality: %s\n"
363 " Options: %s",
fe52e455 364 fTrigString->GetTitle(), fTrigString->GetUniqueID(),
365 fSNNString->GetTitle(), fSNNString->GetUniqueID(),
366 fSysString->GetTitle(), fSysString->GetUniqueID(),
e308a636 367 fVtxAxis->GetTitle(), fVtxAxis->GetXmin(), fVtxAxis->GetXmax(),
0be6c8cd 368 fNormString->GetTitle(), fNormString->GetUniqueID(),
c25b5e1b 369 centTxt.Data(), (options ? options->GetTitle() : "none"));
e1f47419 370 }
e308a636 371 //__________________________________________________________________
372 TMultiGraph* FetchOthers(UShort_t centLow, UShort_t centHigh)
373 {
374 TMultiGraph* thisOther = 0;
375 if (!fShowOthers && !fShowAlice) return 0;
376
377 Bool_t onlya = (fShowOthers ? false : true);
f709afcf 378 Bool_t nomc = true;
e308a636 379 UShort_t sys = (fSysString ? fSysString->GetUniqueID() : 0);
380 UShort_t trg = (fTrigString ? fTrigString->GetUniqueID() : 0);
381 UShort_t snn = (fSNNString ? fSNNString->GetUniqueID() : 0);
f709afcf 382 Long_t ret = gROOT->ProcessLine(Form("GetData(%d,%d,%d,%d,%d,%d,%d);",
e308a636 383 sys,snn,trg,
f709afcf 384 centLow,centHigh,onlya,nomc));
e308a636 385 if (!ret) {
5bb5d1f6 386#if 0
e308a636 387 Warning("FetchResults", "No other data found for sys=%d, sNN=%d, "
388 "trigger=%d %d%%-%d%% central %s",
389 sys, snn, trg, centLow, centHigh,
390 onlya ? " (ALICE results)" : "all");
5bb5d1f6 391#endif
e308a636 392 return 0;
393 }
394 thisOther = reinterpret_cast<TMultiGraph*>(ret);
e1f47419 395
e308a636 396 return thisOther;
397 }
e1f47419 398 //__________________________________________________________________
399 /**
e308a636 400 * Get the results from the top-level list
e1f47419 401 *
e308a636 402 * @param list List
403 * @param name name
404 * @param max On return, maximum of data
405 * @param rmax On return, maximum of ratios
406 * @param amax On return, maximum of left-right comparisons
e1f47419 407 */
e308a636 408 void FetchResults(const TList* list,
409 const char* name,
410 Double_t& max,
411 Double_t& rmax,
412 Double_t& amax)
e1f47419 413 {
e308a636 414 UShort_t n = fCentAxis ? fCentAxis->GetNbins() : 0;
415 if (n == 0) {
416 TList* all = static_cast<TList*>(list->FindObject("all"));
417 if (!all)
418 Error("FetchResults", "Couldn't find list 'all' in %s",
419 list->GetName());
420 else
5bb5d1f6 421 FetchResults(all, name, FetchOthers(0,0), -1000, 0, max, rmax, amax);
e308a636 422 return;
b2e7f2d6 423 }
e1f47419 424
e308a636 425 for (UShort_t i = 0; i < n; i++) {
5bb5d1f6 426 UShort_t centLow = fCentAxis->GetBinLowEdge(i+1);
427 UShort_t centHigh = fCentAxis->GetBinUpEdge(i+1);
e308a636 428 TString lname = Form("cent%03d_%03d", centLow, centHigh);
429 TList* thisCent = static_cast<TList*>(list->FindObject(lname));
5bb5d1f6 430 Int_t col = GetCentralityColor(i+1);
e308a636 431
432 TString centTxt = Form("%3d%%-%3d%% central", centLow, centHigh);
433 if (!thisCent)
434 Error("FetchResults", "Couldn't find list '%s' in %s",
435 lname.Data(), list->GetName());
436 else
437 FetchResults(thisCent, name, FetchOthers(centLow, centHigh),
438 col, centTxt.Data(), max, rmax, amax);
e1f47419 439 }
e308a636 440 }
441 //__________________________________________________________________
5bb5d1f6 442 Int_t GetCentralityColor(Int_t bin) const
443 {
444 UShort_t centLow = fCentAxis->GetBinLowEdge(bin);
445 UShort_t centHigh = fCentAxis->GetBinUpEdge(bin);
446 Float_t fc = (centLow+double(centHigh-centLow)/2) / 100;
447 Int_t nCol = gStyle->GetNumberOfColors();
448 Int_t icol = TMath::Min(nCol-1,int(fc * nCol + .5));
449 Int_t col = gStyle->GetColorPalette(icol);
450 //Info("GetCentralityColor","%3d: %3d-%3d -> %3d",bin,centLow,centHigh,col);
451 return col;
452 }
453 //__________________________________________________________________
e308a636 454 void SetAttributes(TH1* h, Int_t color)
455 {
456 if (!h) return;
457 if (color < 0) return;
ffca499d 458 // h->SetLineColor(color);
e308a636 459 h->SetMarkerColor(color);
ffca499d 460 // h->SetFillColor(color);
e308a636 461 }
462 //__________________________________________________________________
463 void SetAttributes(TGraph* g, Int_t color)
464 {
465 if (!g) return;
466 if (color < 0) return;
ffca499d 467 // g->SetLineColor(color);
e308a636 468 g->SetMarkerColor(color);
ffca499d 469 // g->SetFillColor(color);
b2e7f2d6 470 }
471 //__________________________________________________________________
e308a636 472 void ModifyTitle(TNamed* h, const char* centTxt)
473 {
5bb5d1f6 474 return;
475 // if (!centTxt || !h) return;
476 // h->SetTitle(Form("%s, %s", h->GetTitle(), centTxt));
e308a636 477 }
478
479 //__________________________________________________________________
480 /**
481 * Fetch results for a particular centrality bin
482 *
483 * @param list List
484 * @param name Name
ffca499d 485 * @param thisOther Other graphs
486 * @param color Color
487 * @param centTxt Centrality text
e308a636 488 * @param max On return, data maximum
489 * @param rmax On return, ratio maximum
490 * @param amax On return, left-right maximum
491 */
492 void FetchResults(const TList* list,
493 const char* name,
494 TMultiGraph* thisOther,
495 Int_t color,
496 const char* centTxt,
497 Double_t& max,
498 Double_t& rmax,
499 Double_t& amax)
b2e7f2d6 500 {
e1f47419 501 TH1* dndeta = FetchResult(list, Form("dndeta%s", name));
502 TH1* dndetaMC = FetchResult(list, Form("dndeta%sMC", name));
503 TH1* dndetaTruth = FetchResult(list, "dndetaTruth");
504 TH1* dndetaSym = 0;
505 TH1* dndetaMCSym = 0;
e308a636 506 TH1* tracks = FetchResult(list, "tracks");
ffca499d 507 if (tracks) tracks->SetTitle("ALICE Tracks");
e308a636 508 SetAttributes(dndeta, color);
5bb5d1f6 509 SetAttributes(dndetaMC, fCentAxis ? color : color+2);
e308a636 510 SetAttributes(dndetaTruth,color);
511 SetAttributes(dndetaSym, color);
5bb5d1f6 512 SetAttributes(dndetaMCSym,fCentAxis ? color : color+2);
513 SetAttributes(tracks, fCentAxis ? color : color+3);
514 if (dndetaMC && fCentAxis)
515 dndetaMC->SetMarkerStyle(dndetaMC->GetMarkerStyle()+2);
516 if (dndetaMCSym && fCentAxis)
517 dndetaMCSym->SetMarkerStyle(dndetaMCSym->GetMarkerStyle()+2);
518 if (dndetaTruth && fCentAxis)
519 dndetaTruth->SetMarkerStyle(34);
e308a636 520 ModifyTitle(dndeta, centTxt);
521 ModifyTitle(dndetaMC, centTxt);
522 ModifyTitle(dndetaTruth,centTxt);
523 ModifyTitle(dndetaSym, centTxt);
524 ModifyTitle(dndetaMCSym,centTxt);
525 ModifyTitle(tracks, centTxt);
526
e1f47419 527
e308a636 528 max = TMath::Max(max, AddHistogram(fResults, dndetaTruth, "e5 p"));
529 max = TMath::Max(max, AddHistogram(fResults, dndetaMC, dndetaMCSym));
530 max = TMath::Max(max, AddHistogram(fResults, dndeta, dndetaSym));
531 max = TMath::Max(max, AddHistogram(fResults, tracks));
5bb5d1f6 532
f709afcf 533 if (fShowRings) {
534 THStack* rings = static_cast<THStack*>(list->FindObject("dndetaRings"));
535 if (rings) {
536 TIter next(rings->GetHists());
537 TH1* hist = 0;
538 while ((hist = static_cast<TH1*>(next())))
539 max = TMath::Max(max, AddHistogram(fResults, hist));
540 }
5bb5d1f6 541 }
e308a636 542 // Info("FetchResults", "Got %p, %p, %p from %s with name %s, max=%f",
543 // dndeta, dndetaMC, dndetaTruth, list->GetName(), name, max);
b2e7f2d6 544
e308a636 545 if (fShowLeftRight) {
546 fLeftRight->Add(Asymmetry(dndeta, amax));
547 fLeftRight->Add(Asymmetry(dndetaMC, amax));
548 fLeftRight->Add(Asymmetry(tracks, amax));
e1f47419 549 }
b2e7f2d6 550
e308a636 551 if (thisOther) {
552 TIter next(thisOther->GetListOfGraphs());
553 TGraph* g = 0;
554 while ((g = static_cast<TGraph*>(next()))) {
555 fRatios->Add(Ratio(dndeta, g, rmax));
556 fRatios->Add(Ratio(dndetaSym, g, rmax));
557 SetAttributes(g, color);
558 ModifyTitle(g, centTxt);
559 if (!fOthers->GetListOfGraphs() ||
ffca499d 560 !fOthers->GetListOfGraphs()->FindObject(g->GetName())) {
561 max = TMath::Max(max,TMath::MaxElement(g->GetN(), g->GetY()));
e308a636 562 fOthers->Add(g);
ffca499d 563 }
b2e7f2d6 564 }
e308a636 565 // fOthers->Add(thisOther);
b2e7f2d6 566 }
e308a636 567 if (tracks) {
ffca499d 568 if (!fRatios->GetHists() ||
569 !fRatios->GetHists()->FindObject(tracks->GetName()))
e308a636 570 fRatios->Add(Ratio(dndeta, tracks, rmax));
b2e7f2d6 571 }
b2e7f2d6 572
5bb5d1f6 573 if (dndetaMC) {
574 fRatios->Add(Ratio(dndeta, dndetaMC, rmax));
575 fRatios->Add(Ratio(dndetaSym, dndetaMCSym, rmax));
576 }
e308a636 577 if (dndetaTruth) {
578 fRatios->Add(Ratio(dndeta, dndetaTruth, rmax));
579 fRatios->Add(Ratio(dndetaSym, dndetaTruth, rmax));
b2e7f2d6 580 }
b2e7f2d6 581 }
582 //__________________________________________________________________
2f92ff0e 583 /**
584 * Plot the results
2f92ff0e 585 * @param max Max value
2f92ff0e 586 * @param rmax Maximum diviation from 1 of ratios
2f92ff0e 587 * @param amax Maximum diviation from 1 of asymmetries
588 */
e308a636 589 void Plot(Double_t max,
b2e7f2d6 590 Double_t rmax,
b2e7f2d6 591 Double_t amax)
592 {
593 gStyle->SetOptTitle(0);
594 gStyle->SetTitleFont(132, "xyz");
595 gStyle->SetLabelFont(132, "xyz");
596
e308a636 597 Int_t h = 800;
598 Int_t w = 800; // h / TMath::Sqrt(2);
599 Double_t y1 = 0;
600 Double_t y2 = 0;
601 Double_t y3 = 0;
602 if (!fShowRatios) w *= 1.4;
603 else y1 = 0.3;
604 if (!fShowLeftRight) w *= 1.4;
605 else {
606 Double_t y11 = y1;
607 y1 = (y11 > 0.0001 ? 0.4 : 0.2);
ffca499d 608 y2 = (y11 > 0.0001 ? 0.2 : 0.3);
e308a636 609 }
b2e7f2d6 610 TCanvas* c = new TCanvas("Results", "Results", w, h);
611 c->SetFillColor(0);
612 c->SetBorderSize(0);
613 c->SetBorderMode(0);
614
e308a636 615 PlotResults(max, y1);
b2e7f2d6 616 c->cd();
617
e308a636 618 PlotRatios(rmax, y2, y1);
b2e7f2d6 619 c->cd( );
620
e308a636 621 PlotLeftRight(amax, y3, y2);
b2e7f2d6 622 c->cd();
bad9a3c1 623
624
625 Int_t vMin = fVtxAxis->GetXmin();
626 Int_t vMax = fVtxAxis->GetXmax();
627 TString trg(fTrigString->GetTitle());
e308a636 628 Int_t nev = 0;
ffca499d 629 if (fTriggers) nev = fTriggers->GetBinContent(1);
bad9a3c1 630 trg = trg.Strip(TString::kBoth);
f709afcf 631 trg.ReplaceAll(" ", "_");
632 trg.ReplaceAll(">", "Gt");
bad9a3c1 633 TString base(Form("dndeta_%s_%s_%s_%c%02d%c%02dcm_%09dev",
634 fSysString->GetTitle(),
635 fSNNString->GetTitle(),
636 trg.Data(),
637 vMin < 0 ? 'm' : 'p', TMath::Abs(vMin),
638 vMax < 0 ? 'm' : 'p', TMath::Abs(vMax),
639 nev));
640 c->SaveAs(Form("%s.png", base.Data()));
641 c->SaveAs(Form("%s.root", base.Data()));
642 c->SaveAs(Form("%s.C", base.Data()));
b2e7f2d6 643 }
644 //__________________________________________________________________
e308a636 645 /**
646 * Build main legend
647 *
ffca499d 648 * @param stack Stack to include
649 * @param mg (optional) Multi graph to include
650 * @param x1 Lower X coordinate in the range [0,1]
651 * @param y1 Lower Y coordinate in the range [0,1]
652 * @param x2 Upper X coordinate in the range [0,1]
653 * @param y2 Upper Y coordinate in the range [0,1]
e308a636 654 */
ffca499d 655 void BuildLegend(THStack* stack, TMultiGraph* mg,
656 Double_t x1, Double_t y1, Double_t x2, Double_t y2)
e308a636 657 {
658 TLegend* l = new TLegend(x1,y1,x2,y2);
5bb5d1f6 659 l->SetNColumns(fCentAxis ? 1 : 2);
e308a636 660 l->SetFillColor(0);
661 l->SetFillStyle(0);
662 l->SetBorderSize(0);
663 l->SetTextFont(132);
664
ffca499d 665 TIter next(stack->GetHists());
5bb5d1f6 666 TH1* hist = 0;
667 TObjArray unique;
668 unique.SetOwner();
669 while ((hist = static_cast<TH1*>(next()))) {
e308a636 670 TString n(hist->GetTitle());
671 if (n.Contains("mirrored")) continue;
5bb5d1f6 672 if (unique.FindObject(n.Data())) continue;
673 TObjString* s = new TObjString(n);
674 s->SetUniqueID(((hist->GetMarkerStyle() & 0xFFFF) << 16) |
675 ((hist->GetMarkerColor() & 0xFFFF) << 0));
676 unique.Add(s);
677 // l->AddEntry(hist, hist->GetTitle(), "pl");
e308a636 678 }
ffca499d 679 if (mg) {
680 TIter nexto(mg->GetListOfGraphs());
5bb5d1f6 681 TGraph* g = 0;
682 while ((g = static_cast<TGraph*>(nexto()))) {
683 TString n(g->GetTitle());
ffca499d 684 if (n.Contains("mirrored")) continue;
5bb5d1f6 685 if (unique.FindObject(n.Data())) continue;
686 TObjString* s = new TObjString(n);
687 s->SetUniqueID(((g->GetMarkerStyle() & 0xFFFF) << 16) |
688 ((g->GetMarkerColor() & 0xFFFF) << 0));
689 unique.Add(s);
690 // l->AddEntry(hist, hist->GetTitle(), "pl");
ffca499d 691 }
e308a636 692 }
f709afcf 693 // unique.ls();
5bb5d1f6 694 TIter nextu(&unique);
695 TObject* s = 0;
696 Int_t i = 0;
697 while ((s = nextu())) {
698 TLegendEntry* dd = l->AddEntry(Form("data%2d", i++),
699 s->GetName(), "lp");
700 Int_t style = (s->GetUniqueID() >> 16) & 0xFFFF;
701 Int_t color = (s->GetUniqueID() >> 0) & 0xFFFF;
702 dd->SetLineColor(kBlack);
703 if (fCentAxis) dd->SetMarkerColor(kBlack);
704 else dd->SetMarkerColor(color);
705 dd->SetMarkerStyle(style);
706 }
e308a636 707 TLegendEntry* d1 = l->AddEntry("d1", "Data", "lp");
708 d1->SetLineColor(kBlack);
709 d1->SetMarkerColor(kBlack);
710 d1->SetMarkerStyle(20);
711 TLegendEntry* d2 = l->AddEntry("d2", "Mirrored data", "lp");
712 d2->SetLineColor(kBlack);
713 d2->SetMarkerColor(kBlack);
714 d2->SetMarkerStyle(24);
715
716 l->Draw();
717 }
718 //__________________________________________________________________
5bb5d1f6 719 /**
720 * Build centrality legend
721 *
722 * @param axis Stack to include
723 * @param x1 Lower X coordinate in the range [0,1]
724 * @param y1 Lower Y coordinate in the range [0,1]
725 * @param x2 Upper X coordinate in the range [0,1]
726 * @param y2 Upper Y coordinate in the range [0,1]
727 */
728 void BuildCentLegend(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
729 {
730 if (!fCentAxis) return;
731
732 TLegend* l = new TLegend(x1,y1,x2,y2);
733 l->SetNColumns(1);
734 l->SetFillColor(0);
735 l->SetFillStyle(0);
736 l->SetBorderSize(0);
737 l->SetTextFont(132);
738
739 Int_t n = fCentAxis->GetNbins();
740 for (Int_t i = 1; i <= n; i++) {
741 Double_t low = fCentAxis->GetBinLowEdge(i);
742 Double_t upp = fCentAxis->GetBinUpEdge(i);
743 TLegendEntry* e = l->AddEntry(Form("dummy%02d", i),
744 Form("%3d%% - %3d%%",
745 int(low), int(upp)), "pl");
746 e->SetMarkerColor(GetCentralityColor(i));
747 }
748 l->Draw();
749 }
750 //__________________________________________________________________
2f92ff0e 751 /**
752 * Plot the results
753 *
2f92ff0e 754 * @param max Maximum
755 * @param yd Bottom position of pad
756 */
e308a636 757 void PlotResults(Double_t max, Double_t yd)
b2e7f2d6 758 {
759 // Make a sub-pad for the result itself
760 TPad* p1 = new TPad("p1", "p1", 0, yd, 1.0, 1.0, 0, 0, 0);
761 p1->SetTopMargin(0.05);
762 p1->SetBorderSize(0);
763 p1->SetBorderMode(0);
764 p1->SetBottomMargin(yd > 0.001 ? 0.001 : 0.1);
765 p1->SetRightMargin(0.05);
766 p1->SetGridx();
767 p1->SetTicks(1,1);
768 p1->SetNumber(1);
769 p1->Draw();
770 p1->cd();
771
e308a636 772 // Info("PlotResults", "Plotting results with max=%f", max);
773 fResults->SetMaximum(1.15*max);
774 fResults->SetMinimum(yd > 0.00001 ? -0.1 : 0);
b2e7f2d6 775
f709afcf 776 Double_t s = (yd > 0.00001 ? 1/(1-yd)/1.7 : 1.2);
777 FixAxis(fResults, s, "#frac{1}{N} #frac{dN_{ch}}{d#eta}");
b2e7f2d6 778
779 p1->Clear();
e308a636 780 fResults->DrawClone("nostack e1");
b2e7f2d6 781
e308a636 782 fRangeParam->fSlave1Axis = fResults->GetXaxis();
b2e7f2d6 783 fRangeParam->fSlave1Pad = p1;
784
785 // Draw other data
e308a636 786 if (fShowOthers || fShowAlice) {
b2e7f2d6 787 TGraphAsymmErrors* o = 0;
e308a636 788 TIter nextG(fOthers->GetListOfGraphs());
b2e7f2d6 789 while ((o = static_cast<TGraphAsymmErrors*>(nextG())))
790 o->DrawClone("same p");
791 }
792
793 // Make a legend in the main result pad
5bb5d1f6 794 BuildCentLegend(.12, 1-p1->GetTopMargin()-.01-.5,
795 .35, 1-p1->GetTopMargin()-.01-.1);
796 Double_t x1 = (fCentAxis ? .7 : .15);
797 Double_t x2 = (fCentAxis ? 1-p1->GetRightMargin()-.01: .90);
798 Double_t y1 = (fCentAxis ? .5: p1->GetBottomMargin()+.01);
799 Double_t y2 = (fCentAxis ? 1-p1->GetTopMargin()-.01-.15 : .35);
800
801 BuildLegend(fResults, fOthers, x1, y1, x2, y2);
b2e7f2d6 802
803 // Put a title on top
ffca499d 804 fTitle.ReplaceAll("@", " ");
b2e7f2d6 805 TLatex* tit = new TLatex(0.10, 0.95, fTitle.Data());
806 tit->SetNDC();
807 tit->SetTextFont(132);
808 tit->SetTextSize(0.05);
809 tit->Draw();
810
f709afcf 811 Int_t aliceBlue = TColor::GetColor(41,73,156);
b2e7f2d6 812 // Put a nice label in the plot
813 TString eS;
bad9a3c1 814 UShort_t snn = fSNNString->GetUniqueID();
815 const char* sys = fSysString->GetTitle();
5bb5d1f6 816 if (snn == 2750) snn = 2760;
b2e7f2d6 817 if (snn > 1000) eS = Form("%4.2fTeV", float(snn)/1000);
818 else eS = Form("%3dGeV", snn);
5bb5d1f6 819 TLatex* tt = new TLatex(.93, .93, Form("%s #sqrt{s%s}=%s, %s",
b2e7f2d6 820 sys,
5bb5d1f6 821 (fCentAxis ? "_{NN}" : ""),
b2e7f2d6 822 eS.Data(),
5bb5d1f6 823 fCentAxis ? "by centrality" :
bad9a3c1 824 fTrigString->GetTitle()));
f709afcf 825 tt->SetTextColor(aliceBlue);
b2e7f2d6 826 tt->SetNDC();
827 tt->SetTextFont(132);
828 tt->SetTextAlign(33);
829 tt->Draw();
830
831 // Put number of accepted events on the plot
e308a636 832 Int_t nev = 0;
ffca499d 833 if (fTriggers) nev = fTriggers->GetBinContent(1);
b2e7f2d6 834 TLatex* et = new TLatex(.93, .83, Form("%d events", nev));
f709afcf 835 et->SetTextColor(aliceBlue);
b2e7f2d6 836 et->SetNDC();
837 et->SetTextFont(132);
838 et->SetTextAlign(33);
839 et->Draw();
840
841 // Put number of accepted events on the plot
842 if (fVtxAxis) {
843 TLatex* vt = new TLatex(.93, .88, fVtxAxis->GetTitle());
844 vt->SetNDC();
845 vt->SetTextFont(132);
846 vt->SetTextAlign(33);
f709afcf 847 vt->SetTextColor(aliceBlue);
b2e7f2d6 848 vt->Draw();
849 }
850 // results->Draw("nostack e1 same");
851
e308a636 852 fRangeParam->fSlave1Axis = FindXAxis(p1, fResults->GetName());
b2e7f2d6 853 fRangeParam->fSlave1Pad = p1;
854
855
856 // Mark the plot as preliminary
f709afcf 857 TLatex* pt = new TLatex(.12, .93, "Work in progress");
b2e7f2d6 858 pt->SetNDC();
859 pt->SetTextFont(22);
f709afcf 860 // pt->SetTextSize();
861 pt->SetTextColor(TColor::GetColor(234,26,46));
b2e7f2d6 862 pt->SetTextAlign(13);
863 pt->Draw();
864
f709afcf 865 const char* logos[] = { "ALICE.png", "FMD.png", 0 };
866 const char** logo = logos;
867 while (*logo) {
868 if (gSystem->AccessPathName(*logo)) {
869 logo++;
870 continue;
871 }
872 TPad* pad = new TPad("logo", "logo", .12, .65, .25, .85, 0, 0, 0);
873 pad->SetFillStyle(0);
874 pad->Draw();
875 pad->cd();
b2e7f2d6 876 TImage* i = TImage::Create();
f709afcf 877 i->ReadImage(*logo);
b2e7f2d6 878 i->Draw();
f709afcf 879 break;
b2e7f2d6 880 }
881 p1->cd();
882 }
883 //__________________________________________________________________
2f92ff0e 884 /**
885 * Plot the ratios
886 *
2f92ff0e 887 * @param max Maximum diviation from 1
888 * @param y1 Lower y coordinate of pad
889 * @param y2 Upper y coordinate of pad
890 */
e308a636 891 void PlotRatios(Double_t max, Double_t y1, Double_t y2)
b2e7f2d6 892 {
e308a636 893 if (!fShowRatios) return;
894
b2e7f2d6 895 bool isBottom = (y1 < 0.0001);
896 Double_t yd = y2 - y1;
897 // Make a sub-pad for the result itself
898 TPad* p2 = new TPad("p2", "p2", 0, y1, 1.0, y2, 0, 0, 0);
899 p2->SetTopMargin(0.001);
900 p2->SetRightMargin(0.05);
901 p2->SetBottomMargin(isBottom ? 1/yd * 0.07 : 0.0001);
902 p2->SetGridx();
903 p2->SetTicks(1,1);
904 p2->SetNumber(2);
905 p2->Draw();
906 p2->cd();
907
908 // Fix up axis
e308a636 909 FixAxis(fRatios, 1/yd/1.7, "Ratios", 7);
b2e7f2d6 910
e308a636 911 fRatios->SetMaximum(1+TMath::Max(.22,1.05*max));
912 fRatios->SetMinimum(1-TMath::Max(.32,1.05*max));
b2e7f2d6 913 p2->Clear();
e308a636 914 fRatios->DrawClone("nostack e1");
b2e7f2d6 915
916
917 // Make a legend
ffca499d 918 BuildLegend(fRatios, 0, .15,p2->GetBottomMargin()+.01,.9,
919 isBottom ? .6 : .4);
920#if 0
b2e7f2d6 921 TLegend* l2 = p2->BuildLegend(.15,p2->GetBottomMargin()+.01,.9,
922 isBottom ? .6 : .4);
923 l2->SetNColumns(2);
924 l2->SetFillColor(0);
925 l2->SetFillStyle(0);
926 l2->SetBorderSize(0);
927 l2->SetTextFont(132);
ffca499d 928#endif
b2e7f2d6 929 // Make a nice band from 0.9 to 1.1
930 TGraphErrors* band = new TGraphErrors(2);
e1f47419 931 band->SetPoint(0, fResults->GetXaxis()->GetXmin(), 1);
932 band->SetPoint(1, fResults->GetXaxis()->GetXmax(), 1);
b2e7f2d6 933 band->SetPointError(0, 0, .1);
934 band->SetPointError(1, 0, .1);
935 band->SetFillColor(kYellow+2);
936 band->SetFillStyle(3002);
937 band->SetLineStyle(2);
938 band->SetLineWidth(1);
939 band->Draw("3 same");
940 band->DrawClone("X L same");
941
942 // Replot the ratios on top
e308a636 943 fRatios->DrawClone("nostack e1 same");
b2e7f2d6 944
945 if (isBottom) {
e308a636 946 fRangeParam->fMasterAxis = FindXAxis(p2, fRatios->GetName());
b2e7f2d6 947 p2->AddExec("range", Form("RangeExec((dNdetaDrawer::RangeParam*)%p)",
948 fRangeParam));
949 }
950 else {
e308a636 951 fRangeParam->fSlave2Axis = FindXAxis(p2, fRatios->GetName());
b2e7f2d6 952 fRangeParam->fSlave2Pad = p2;
953 }
954 }
955 //__________________________________________________________________
2f92ff0e 956 /**
957 * Plot the asymmetries
958 *
2f92ff0e 959 * @param max Maximum diviation from 1
960 * @param y1 Lower y coordinate of pad
961 * @param y2 Upper y coordinate of pad
962 */
e308a636 963 void PlotLeftRight(Double_t max, Double_t y1, Double_t y2)
b2e7f2d6 964 {
e308a636 965 if (!fShowLeftRight) return;
966
b2e7f2d6 967 bool isBottom = (y1 < 0.0001);
968 Double_t yd = y2 - y1;
969 // Make a sub-pad for the result itself
970 TPad* p3 = new TPad("p3", "p3", 0, y1, 1.0, y2, 0, 0, 0);
971 p3->SetTopMargin(0.001);
972 p3->SetRightMargin(0.05);
973 p3->SetBottomMargin(isBottom ? 1/yd * 0.07 : 0.0001);
974 p3->SetGridx();
975 p3->SetTicks(1,1);
976 p3->SetNumber(2);
977 p3->Draw();
978 p3->cd();
979
b2e7f2d6 980 // Fix up axis
e308a636 981 FixAxis(fLeftRight, 1/yd/1.7, "Right/Left", 4);
b2e7f2d6 982
e308a636 983 fLeftRight->SetMaximum(1+TMath::Max(.12,1.05*max));
984 fLeftRight->SetMinimum(1-TMath::Max(.15,1.05*max));
b2e7f2d6 985 p3->Clear();
e308a636 986 fLeftRight->DrawClone("nostack e1");
b2e7f2d6 987
988
989 // Make a legend
5bb5d1f6 990 Double_t xx1 = (fCentAxis ? .7 : .15);
991 Double_t xx2 = (fCentAxis ? 1-p3->GetRightMargin()-.01 : .90);
992 Double_t yy1 = p3->GetBottomMargin()+.01;
993 Double_t yy2 = (fCentAxis ? 1-p3->GetTopMargin()-.01-.15 : .5);
994 BuildLegend(fLeftRight, 0, xx1, yy1, xx2, yy2);
995 // TLegend* l2 = p3->BuildLegend(.15,p3->GetBottomMargin()+.01,.9,.5);
996 // l2->SetNColumns(2);
997 // l2->SetFillColor(0);
998 // l2->SetFillStyle(0);
999 // l2->SetBorderSize(0);
1000 // l2->SetTextFont(132);
ffca499d 1001
b2e7f2d6 1002 // Make a nice band from 0.9 to 1.1
1003 TGraphErrors* band = new TGraphErrors(2);
e1f47419 1004 band->SetPoint(0, fResults->GetXaxis()->GetXmin(), 1);
1005 band->SetPoint(1, fResults->GetXaxis()->GetXmax(), 1);
b2e7f2d6 1006 band->SetPointError(0, 0, .05);
1007 band->SetPointError(1, 0, .05);
1008 band->SetFillColor(kYellow+2);
1009 band->SetFillStyle(3002);
1010 band->SetLineStyle(2);
1011 band->SetLineWidth(1);
1012 band->Draw("3 same");
1013 band->DrawClone("X L same");
1014
e308a636 1015 fLeftRight->DrawClone("nostack e1 same");
b2e7f2d6 1016 if (isBottom) {
e308a636 1017 fRangeParam->fMasterAxis = FindXAxis(p3, fLeftRight->GetName());
b2e7f2d6 1018 p3->AddExec("range", Form("RangeExec((dNdetaDrawer::RangeParam*)%p)",
1019 fRangeParam));
1020 }
1021 else {
e308a636 1022 fRangeParam->fSlave2Axis = FindXAxis(p3, fLeftRight->GetName());
b2e7f2d6 1023 fRangeParam->fSlave2Pad = p3;
1024 }
1025 }
2f92ff0e 1026 /** @} */
1027 //==================================================================
1028 /**
1029 * @{
1030 * @name Data utility functions
1031 */
1032 /**
1033 * Get a result from the passed list
1034 *
1035 * @param list List to search
1036 * @param name Object name to search for
1037 *
1038 * @return
1039 */
e1f47419 1040 TH1* FetchResult(const TList* list, const char* name) const
2f92ff0e 1041 {
1042 if (!list) return 0;
1043
e308a636 1044 TH1* ret = static_cast<TH1*>(list->FindObject(name));
5bb5d1f6 1045#if 0
e1f47419 1046 if (!ret) {
1047 // all->ls();
1048 Warning("GetResult", "Histogram %s not found", name);
2f92ff0e 1049 }
5bb5d1f6 1050#endif
b2e7f2d6 1051
e1f47419 1052 return ret;
2f92ff0e 1053 }
b2e7f2d6 1054 //__________________________________________________________________
2f92ff0e 1055 /**
1056 * Add a histogram to the stack after possibly rebinning it
1057 *
1058 * @param stack Stack to add to
1059 * @param hist histogram
1060 * @param option Draw options
1061 *
1062 * @return Maximum of histogram
1063 */
e308a636 1064 Double_t AddHistogram(THStack* stack, TH1* hist, Option_t* option="") const
b2e7f2d6 1065 {
1066 // Check if we have input
1067 if (!hist) return 0;
1068
1069 // Rebin if needed
1070 Rebin(hist);
1071
1072 stack->Add(hist, option);
1073 return hist->GetMaximum();
1074 }
1075 //__________________________________________________________________
2f92ff0e 1076 /**
1077 * Add a histogram to the stack after possibly rebinning it
1078 *
1079 * @param stack Stack to add to
1080 * @param hist histogram
1081 * @param option Draw options
1082 * @param sym On return, the data symmetriced (added to stack)
1083 *
1084 * @return Maximum of histogram
1085 */
e308a636 1086 Double_t AddHistogram(THStack* stack, TH1* hist, TH1*& sym,
1087 Option_t* option="") const
b2e7f2d6 1088 {
1089 // Check if we have input
1090 if (!hist) return 0;
1091
1092 // Rebin if needed
1093 Rebin(hist);
1094 stack->Add(hist, option);
1095
1096 // Now symmetrice the histogram
1097 sym = Symmetrice(hist);
1098 stack->Add(sym, option);
1099
1100 return hist->GetMaximum();
1101 }
1102
1103 //__________________________________________________________________
1104 /**
1105 * Rebin a histogram
1106 *
1107 * @param h Histogram to rebin
b2e7f2d6 1108 *
1109 * @return
1110 */
1111 virtual void Rebin(TH1* h) const
1112 {
1113 if (fRebin <= 1) return;
1114
1115 Int_t nBins = h->GetNbinsX();
1116 if(nBins % fRebin != 0) {
1117 Warning("Rebin", "Rebin factor %d is not a devisor of current number "
1118 "of bins %d in the histogram %s", fRebin, nBins, h->GetName());
1119 return;
1120 }
1121
1122 // Make a copy
1123 TH1* tmp = static_cast<TH1*>(h->Clone("tmp"));
1124 tmp->Rebin(fRebin);
1125 tmp->SetDirectory(0);
e28f5fc5 1126 tmp->Reset();
b2e7f2d6 1127 // The new number of bins
1128 Int_t nBinsNew = nBins / fRebin;
1129 for(Int_t i = 1;i<= nBinsNew; i++) {
1130 Double_t content = 0;
1131 Double_t sumw = 0;
1132 Double_t wsum = 0;
1133 Int_t nbins = 0;
1134 for(Int_t j = 1; j<=fRebin;j++) {
1135 Int_t bin = (i-1)*fRebin + j;
1136 Double_t c = h->GetBinContent(bin);
1137
1138 if (c <= 0) continue;
1139
1140 if (fCutEdges) {
1141 if (h->GetBinContent(bin+1)<=0 ||
1142 h->GetBinContent(bin-1)) {
1143 Warning("Rebin", "removing bin %d=%f of %s (%d=%f,%d=%f)",
1144 bin, c, h->GetName(),
1145 bin+1, h->GetBinContent(bin+1),
1146 bin-1, h->GetBinContent(bin-1));
1147 continue;
1148 }
1149 }
1150 Double_t e = h->GetBinError(bin);
1151 Double_t w = 1 / (e*e); // 1/c/c
1152 content += c;
1153 sumw += w;
1154 wsum += w * c;
1155 nbins++;
1156 }
1157
e28f5fc5 1158 if(content > 0 && nbins > 1 ) {
b2e7f2d6 1159 tmp->SetBinContent(i, wsum / sumw);
1160 tmp->SetBinError(i,1./TMath::Sqrt(sumw));
1161 }
1162 }
1163
1164 // Finally, rebin the histogram, and set new content
1165 h->Rebin(fRebin);
1166 h->Reset();
1167 for(Int_t i = 1; i<= nBinsNew; i++) {
1168 h->SetBinContent(i,tmp->GetBinContent(i));
1169 h->SetBinError(i, tmp->GetBinError(i));
1170 }
1171
1172 delete tmp;
1173 }
1174 //__________________________________________________________________
1175 /**
1176 * Make an extension of @a h to make it symmetric about 0
1177 *
1178 * @param h Histogram to symmertrice
1179 *
1180 * @return Symmetric extension of @a h
1181 */
1182 TH1* Symmetrice(const TH1* h) const
1183 {
1184 Int_t nBins = h->GetNbinsX();
1185 TH1* s = static_cast<TH1*>(h->Clone(Form("%s_mirror", h->GetName())));
1186 s->SetTitle(Form("%s (mirrored)", h->GetTitle()));
1187 s->Reset();
1188 s->SetBins(nBins, -h->GetXaxis()->GetXmax(), -h->GetXaxis()->GetXmin());
1189 s->SetMarkerColor(h->GetMarkerColor());
1190 s->SetMarkerSize(h->GetMarkerSize());
1191 s->SetMarkerStyle(h->GetMarkerStyle()+4);
1192 s->SetFillColor(h->GetFillColor());
1193 s->SetFillStyle(h->GetFillStyle());
1194 s->SetDirectory(0);
1195
1196 // Find the first and last bin with data
1197 Int_t first = nBins+1;
1198 Int_t last = 0;
1199 for (Int_t i = 1; i <= nBins; i++) {
1200 if (h->GetBinContent(i) <= 0) continue;
1201 first = TMath::Min(first, i);
1202 last = TMath::Max(last, i);
1203 }
1204
1205 Double_t xfirst = h->GetBinCenter(first-1);
1206 Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
1207 Int_t l2 = s->GetXaxis()->FindBin(xfirst);
1208 for (Int_t i = f1, j=l2; i <= last; i++,j--) {
1209 s->SetBinContent(j, h->GetBinContent(i));
1210 s->SetBinError(j, h->GetBinError(i));
1211 }
1212 // Fill in overlap bin
1213 s->SetBinContent(l2+1, h->GetBinContent(first));
1214 s->SetBinError(l2+1, h->GetBinError(first));
1215 return s;
1216 }
1217 //__________________________________________________________________
2f92ff0e 1218 /**
1219 * Calculate the left-right asymmetry of input histogram
1220 *
1221 * @param h Input histogram
1222 * @param max On return, the maximum distance from 1 of the histogram
1223 *
1224 * @return Asymmetry
1225 */
1226 TH1* Asymmetry(TH1* h, Double_t& max)
1227 {
1228 if (!h) return 0;
1229
1230 TH1* ret = static_cast<TH1*>(h->Clone(Form("%s_leftright", h->GetName())));
1231 // Int_t oBins = h->GetNbinsX();
1232 // Double_t high = h->GetXaxis()->GetXmax();
1233 // Double_t low = h->GetXaxis()->GetXmin();
1234 // Double_t dBin = (high - low) / oBins;
1235 // Int_t tBins = Int_t(2*high/dBin+.5);
1236 // ret->SetBins(tBins, -high, high);
e308a636 1237 ret->SetDirectory(0);
2f92ff0e 1238 ret->Reset();
1239 ret->SetTitle(Form("%s (+/-)", h->GetTitle()));
1240 ret->SetYTitle("Right/Left");
1241 Int_t nBins = h->GetNbinsX();
1242 for (Int_t i = 1; i <= nBins; i++) {
1243 Double_t x = h->GetBinCenter(i);
1244 if (x > 0) break;
1245
1246 Double_t c1 = h->GetBinContent(i);
1247 Double_t e1 = h->GetBinError(i);
1248 if (c1 <= 0) continue;
1249
1250 Int_t j = h->FindBin(-x);
1251 if (j <= 0 || j > nBins) continue;
1252
1253 Double_t c2 = h->GetBinContent(j);
1254 Double_t e2 = h->GetBinError(j);
1255
1256 Double_t c12 = c1*c1;
1257 Double_t e = TMath::Sqrt((e2*e2*c1*c1+e1*e1*c2*c2)/(c12*c12));
1258
1259 Int_t k = ret->FindBin(x);
1260 ret->SetBinContent(k, c2/c1);
1261 ret->SetBinError(k, e);
1262 }
1263 max = TMath::Max(max, RatioMax(ret));
1264
1265 return ret;
1266 }
1267 //__________________________________________________________________
1268 /**
1269 * Transform a graph into a histogram
1270 *
1271 * @param g
1272 *
1273 * @return
1274 */
1275 TH1* Graph2Hist(const TGraphAsymmErrors* g) const
1276 {
1277 Int_t nBins = g->GetN();
1278 TArrayF bins(nBins+1);
1279 Double_t dx = 0;
1280 for (Int_t i = 0; i < nBins; i++) {
1281 Double_t x = g->GetX()[i];
1282 Double_t exl = g->GetEXlow()[i];
1283 Double_t exh = g->GetEXhigh()[i];
1284 bins.fArray[i] = x-exl;
1285 bins.fArray[i+1] = x+exh;
1286 Double_t dxi = exh+exl;
1287 if (i == 0) dx = dxi;
1288 else if (dxi != dx) dx = 0;
1289 }
1290 TString name(g->GetName());
1291 TString title(g->GetTitle());
1292 TH1D* h = 0;
1293 if (dx != 0) {
1294 h = new TH1D(name.Data(), title.Data(), nBins, bins[0], bins[nBins]);
1295 }
1296 else {
1297 h = new TH1D(name.Data(), title.Data(), nBins, bins.fArray);
1298 }
1299 h->SetMarkerStyle(g->GetMarkerStyle());
1300 h->SetMarkerColor(g->GetMarkerColor());
1301 h->SetMarkerSize(g->GetMarkerSize());
1302
1303 return h;
1304 }
1305 /* @} */
1306 //==================================================================
1307 /**
1308 * @{
1309 * @name Ratio utility functions
1310 */
1311 /**
1312 * Get the maximum diviation from 1 in the passed ratio
1313 *
1314 * @param h Ratio histogram
1315 *
1316 * @return Max diviation from 1
1317 */
b2e7f2d6 1318 Double_t RatioMax(TH1* h) const
1319 {
1320 Int_t nBins = h->GetNbinsX();
1321 Double_t ret = 0;
1322 for (Int_t i = 1; i <= nBins; i++) {
1323 Double_t c = h->GetBinContent(i);
1324 if (c == 0) continue;
1325 Double_t e = h->GetBinError(i);
1326 Double_t d = TMath::Abs(1-c-e);
1327 ret = TMath::Max(d, ret);
1328 }
1329 return ret;
1330 }
1331 //__________________________________________________________________
e1f47419 1332 /**
1333 * Make the ratio of h1 to h2
1334 *
ffca499d 1335 * @param o1 First object (numerator)
1336 * @param o2 Second object (denominator)
1337 * @param max Maximum diviation from 1
e1f47419 1338 *
ffca499d 1339 * @return o1 / o2
e1f47419 1340 */
1341 TH1* Ratio(const TObject* o1, const TObject* o2, Double_t& max) const
1342 {
b30dee70 1343 if (!o1 || !o2) return 0;
1344
5bb5d1f6 1345 TH1* r = 0;
1346 const TAttMarker* m1 = 0;
1347 const TAttMarker* m2 = 0;
e1f47419 1348 const TH1* h1 = dynamic_cast<const TH1*>(o1);
1349 if (h1) {
5bb5d1f6 1350 m1 = h1;
e1f47419 1351 const TH1* h2 = dynamic_cast<const TH1*>(o2);
ffca499d 1352 if (h2) {
5bb5d1f6 1353 m2 = h2;
1354 r = RatioHH(h1,h2);
ffca499d 1355 }
1356 else {
1357 const TGraph* g2 = dynamic_cast<const TGraph*>(o2);
1358 if (g2) {
5bb5d1f6 1359 m2 = g2;
1360 r = RatioHG(h1,g2);
ffca499d 1361 }
1362 }
e1f47419 1363 }
ffca499d 1364 else {
1365 const TGraphAsymmErrors* g1 = dynamic_cast<const TGraphAsymmErrors*>(o1);
1366 if (g1) {
5bb5d1f6 1367 m1 = g1;
ffca499d 1368 const TGraphAsymmErrors* g2 =
1369 dynamic_cast<const TGraphAsymmErrors*>(o2);
1370 if (g2) {
5bb5d1f6 1371 m2 = g2;
1372 r = RatioGG(g1, g2);
ffca499d 1373 }
1374 }
e1f47419 1375 }
ffca499d 1376 if (!r) {
1377 Warning("Ratio", "Don't know how to divide a %s (%s) with a %s (%s)",
1378 o1->ClassName(), o1->GetName(), o2->ClassName(), o2->GetName());
1379 return 0;
1380 }
1381 // Check that the histogram isn't empty
1382 if (r->GetEntries() <= 0) {
1383 delete r;
1384 r = 0;
1385 }
5bb5d1f6 1386 if (r) {
1387 r->SetMarkerStyle(m1->GetMarkerStyle());
1388 r->SetMarkerColor(m2->GetMarkerColor());
1389 r->SetMarkerSize(0.9*m1->GetMarkerSize());
1390 r->SetName(Form("%s_over_%s", o1->GetName(), o2->GetName()));
1391 r->SetTitle(Form("%s / %s", o1->GetTitle(), o2->GetTitle()));
1392 r->SetDirectory(0);
1393 max = TMath::Max(RatioMax(r), max);
1394 }
1395
ffca499d 1396 return r;
e1f47419 1397 }
1398 //__________________________________________________________________
b2e7f2d6 1399 /**
1400 * Compute the ratio of @a h to @a g. @a g is evaluated at the bin
1401 * centers of @a h
1402 *
1403 * @param h Numerator
1404 * @param g Divisor
1405 *
1406 * @return h/g
1407 */
5bb5d1f6 1408 TH1* RatioHG(const TH1* h, const TGraph* g) const
b2e7f2d6 1409 {
1410 if (!h || !g) return 0;
1411
1412 TH1* ret = static_cast<TH1*>(h->Clone("tmp"));
b2e7f2d6 1413 ret->Reset();
b2e7f2d6 1414 Double_t xlow = g->GetX()[0];
1415 Double_t xhigh = g->GetX()[g->GetN()-1];
1416 if (xlow > xhigh) { Double_t t = xhigh; xhigh = xlow; xlow = t; }
1417
1418 for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
1419 Double_t c = h->GetBinContent(i);
1420 if (c <= 0) continue;
1421
1422 Double_t x = h->GetBinCenter(i);
1423 if (x < xlow || x > xhigh) continue;
1424
1425 Double_t f = g->Eval(x);
1426 if (f <= 0) continue;
1427
1428 ret->SetBinContent(i, c / f);
1429 ret->SetBinError(i, h->GetBinError(i) / f);
1430 }
b2e7f2d6 1431 return ret;
1432 }
1433 //__________________________________________________________________
1434 /**
1435 * Make the ratio of h1 to h2
1436 *
1437 * @param h1 First histogram (numerator)
1438 * @param h2 Second histogram (denominator)
1439 *
1440 * @return h1 / h2
1441 */
5bb5d1f6 1442 TH1* RatioHH(const TH1* h1, const TH1* h2) const
b2e7f2d6 1443 {
1444 if (!h1 || !h2) return 0;
5bb5d1f6 1445 TH1* t1 = static_cast<TH1*>(h1->Clone("tmp"));
b2e7f2d6 1446 t1->Divide(h2);
b2e7f2d6 1447 return t1;
1448 }
1449 //__________________________________________________________________
1450 /**
1451 * Calculate the ratio of two graphs - g1 / g2
1452 *
1453 * @param g1 Numerator
1454 * @param g2 Denominator
1455 *
1456 * @return g1 / g2 in a histogram
1457 */
ffca499d 1458 TH1* RatioGG(const TGraphAsymmErrors* g1,
5bb5d1f6 1459 const TGraphAsymmErrors* g2) const
b2e7f2d6 1460 {
1461 Int_t nBins = g1->GetN();
1462 TArrayF bins(nBins+1);
1463 Double_t dx = 0;
1464 for (Int_t i = 0; i < nBins; i++) {
1465 Double_t x = g1->GetX()[i];
1466 Double_t exl = g1->GetEXlow()[i];
1467 Double_t exh = g1->GetEXhigh()[i];
1468 bins.fArray[i] = x-exl;
1469 bins.fArray[i+1] = x+exh;
1470 Double_t dxi = exh+exl;
1471 if (i == 0) dx = dxi;
1472 else if (dxi != dx) dx = 0;
1473 }
b2e7f2d6 1474 TH1* h = 0;
1475 if (dx != 0) {
5bb5d1f6 1476 h = new TH1F("tmp", "tmp", nBins, bins[0], bins[nBins]);
b2e7f2d6 1477 }
1478 else {
5bb5d1f6 1479 h = new TH1F("tmp", "tmp", nBins, bins.fArray);
b2e7f2d6 1480 }
b2e7f2d6 1481
1482 Double_t low = g2->GetX()[0];
1483 Double_t high = g2->GetX()[g2->GetN()-1];
1484 if (low > high) { Double_t t = low; low = high; high = t; }
1485 for (Int_t i = 0; i < nBins; i++) {
1486 Double_t x = g1->GetX()[i];
1487 if (x < low-dx || x > high+dx) continue;
1488 Double_t c1 = g1->GetY()[i];
1489 Double_t e1 = g1->GetErrorY(i);
1490 Double_t c2 = g2->Eval(x);
1491
1492 h->SetBinContent(i+1, c1 / c2);
1493 h->SetBinError(i+1, e1 / c2);
1494 }
b2e7f2d6 1495 return h;
2f92ff0e 1496 }
1497 /* @} */
1498 //==================================================================
1499 /**
1500 * @{
1501 * @name Graphics utility functions
1502 */
1503 /**
1504 * Find an X axis in a pad
1505 *
1506 * @param p Pad
1507 * @param name Histogram to find axis for
1508 *
1509 * @return Found axis or null
1510 */
1511 TAxis* FindXAxis(TVirtualPad* p, const char* name)
b2e7f2d6 1512 {
2f92ff0e 1513 TObject* o = p->GetListOfPrimitives()->FindObject(name);
1514 if (!o) {
1515 Warning("FindXAxis", "%s not found in pad", name);
1516 return 0;
b2e7f2d6 1517 }
2f92ff0e 1518 THStack* stack = dynamic_cast<THStack*>(o);
1519 if (!stack) {
1520 Warning("FindXAxis", "%s is not a THStack", name);
1521 return 0;
b2e7f2d6 1522 }
2f92ff0e 1523 if (!stack->GetHistogram()) {
1524 Warning("FindXAxis", "%s has no histogram", name);
1525 return 0;
b2e7f2d6 1526 }
2f92ff0e 1527 TAxis* ret = stack->GetHistogram()->GetXaxis();
1528 return ret;
b2e7f2d6 1529 }
2f92ff0e 1530
b2e7f2d6 1531 //__________________________________________________________________
2f92ff0e 1532 /**
1533 * Fix the apperance of the axis in a stack
1534 *
1535 * @param stack stack of histogram
1536 * @param s Scaling factor
1537 * @param ytitle Y axis title
1538 * @param force Whether to draw the stack first or not
1539 * @param ynDiv Divisions on Y axis
1540 */
1541 void FixAxis(THStack* stack, Double_t s, const char* ytitle,
1542 Int_t ynDiv=210, Bool_t force=true)
b2e7f2d6 1543 {
e308a636 1544 if (!stack) {
1545 Warning("FixAxis", "No stack passed for %s!", ytitle);
1546 return;
1547 }
2f92ff0e 1548 if (force) stack->Draw("nostack e1");
b2e7f2d6 1549
2f92ff0e 1550 TH1* h = stack->GetHistogram();
e308a636 1551 if (!h) {
1552 Warning("FixAxis", "Stack %s has no histogram", stack->GetName());
1553 return;
1554 }
1555
2f92ff0e 1556 h->SetXTitle("#eta");
1557 h->SetYTitle(ytitle);
1558 TAxis* xa = h->GetXaxis();
1559 TAxis* ya = h->GetYaxis();
1560 if (xa) {
1561 xa->SetTitle("#eta");
1562 // xa->SetTicks("+-");
1563 xa->SetTitleSize(s*xa->GetTitleSize());
1564 xa->SetLabelSize(s*xa->GetLabelSize());
1565 xa->SetTickLength(s*xa->GetTickLength());
e308a636 1566
1567 if (stack != fResults) {
1568 TAxis* rxa = fResults->GetXaxis();
1569 xa->Set(rxa->GetNbins(), rxa->GetXmin(), rxa->GetXmax());
1570 }
2f92ff0e 1571 }
1572 if (ya) {
1573 ya->SetTitle(ytitle);
1574 ya->SetDecimals();
1575 // ya->SetTicks("+-");
1576 ya->SetNdivisions(ynDiv);
1577 ya->SetTitleSize(s*ya->GetTitleSize());
1578 ya->SetTitleOffset(ya->GetTitleOffset()/s);
1579 ya->SetLabelSize(s*ya->GetLabelSize());
b2e7f2d6 1580 }
b2e7f2d6 1581 }
2f92ff0e 1582 /* @} */
1583
b2e7f2d6 1584
1585
1586 //__________________________________________________________________
e308a636 1587 Bool_t fShowOthers; // Show other data
1588 Bool_t fShowAlice; // Show ALICE published data
1589 Bool_t fShowRatios; // Show ratios
1590 Bool_t fShowLeftRight;// Show asymmetry
f709afcf 1591 Bool_t fShowRings; // Show rings too
e308a636 1592 UShort_t fRebin; // Rebinning factor
1593 Bool_t fCutEdges; // Whether to cut edges
1594 TString fTitle; // Title on plot
1595 TNamed* fTrigString; // Trigger string (read, or set)
0be6c8cd 1596 TNamed* fNormString; // Normalisation string (read, or set)
e308a636 1597 TNamed* fSNNString; // Energy string (read, or set)
1598 TNamed* fSysString; // Collision system string (read or set)
1599 TAxis* fVtxAxis; // Vertex cuts (read or set)
1600 TAxis* fCentAxis; // Centrality axis
1601 THStack* fResults; // Stack of results
1602 THStack* fRatios; // Stack of ratios
1603 THStack* fLeftRight; // Left-right asymmetry
1604 TMultiGraph* fOthers; // Older data
1605 TH1* fTriggers; // Number of triggers
1606 RangeParam* fRangeParam; // Parameter object for range zoom
b2e7f2d6 1607
1608};
1609
1610//=== Stuff for auto zooming =========================================
1611void UpdateRange(dNdetaDrawer::RangeParam* p)
1612{
1613 if (!p) {
1614 Warning("UpdateRange", "No parameters %p", p);
1615 return;
1616 }
1617 if (!p->fMasterAxis) {
1618 Warning("UpdateRange", "No master axis %p", p->fMasterAxis);
1619 return;
1620 }
1621 Int_t first = p->fMasterAxis->GetFirst();
1622 Int_t last = p->fMasterAxis->GetLast();
1623 Double_t x1 = p->fMasterAxis->GetBinCenter(first);
1624 Double_t x2 = p->fMasterAxis->GetBinCenter(last);
b2e7f2d6 1625
1626 if (p->fSlave1Axis) {
1627 Int_t i1 = p->fSlave1Axis->FindBin(x1);
1628 Int_t i2 = p->fSlave1Axis->FindBin(x2);
1629 p->fSlave1Axis->SetRange(i1, i2);
1630 p->fSlave1Pad->Modified();
1631 p->fSlave1Pad->Update();
1632 }
1633 if (p->fSlave2Axis) {
1634 Int_t i1 = p->fSlave2Axis->FindBin(x1);
1635 Int_t i2 = p->fSlave2Axis->FindBin(x2);
1636 p->fSlave2Axis->SetRange(i1, i2);
1637 p->fSlave2Pad->Modified();
1638 p->fSlave2Pad->Update();
1639 }
1640 TCanvas* c = gPad->GetCanvas();
1641 c->cd();
1642}
1643
1644//____________________________________________________________________
1645void RangeExec(dNdetaDrawer::RangeParam* p)
1646{
1647 // Event types:
1648 // 51: Mouse move
1649 // 53:
1650 // 1: Button down
1651 // 21: Mouse drag
1652 // 11: Mouse release
1653 // dNdetaDrawer::RangeParam* p =
1654 // reinterpret_cast<dNdetaDrawer::RangeParam*>(addr);
1655 Int_t event = gPad->GetEvent();
1656 TObject *select = gPad->GetSelected();
1657 if (event == 53) {
1658 UpdateRange(p);
1659 return;
1660 }
1661 if (event != 11 || !select || select != p->fMasterAxis) return;
1662 UpdateRange(p);
1663}
1664
1665//=== Steering function ==============================================
ffca499d 1666/**
1667 * Draw @f$ dN/d\eta@f$
1668 *
1669 * @param filename File name
1670 * @param flags Flags
1671 * @param title Title
1672 * @param rebin Rebinning factor
1673 * @param cutEdges Whether to cut edges when rebinning
1674 * @param sNN (optional) Collision energy [GeV]
1675 * @param sys (optional) Collision system (1: pp, 2: PbPb)
1676 * @param trg (optional) Trigger (1: INEL, 2: INEL>0, 4: NSD)
1677 * @param vzMin Least @f$ v_z@f$
1678 * @param vzMax Largest @f$ v_z@f$
1679 *
1680 * @ingroup pwg2_forward_dndeta
1681 */
b2e7f2d6 1682void
1683DrawdNdeta(const char* filename="forward_dndeta.root",
1684 Int_t flags=0xf,
bad9a3c1 1685 const char* title="",
b2e7f2d6 1686 UShort_t rebin=5,
fe52e455 1687 Bool_t cutEdges=false,
1688 UShort_t sNN=0,
1689 UShort_t sys=0,
ffca499d 1690 UShort_t trg=0,
fe52e455 1691 Float_t vzMin=999,
1692 Float_t vzMax=-999)
b2e7f2d6 1693{
ffca499d 1694 dNdetaDrawer* pd = new dNdetaDrawer;
1695 dNdetaDrawer& d = *pd;
b2e7f2d6 1696 d.SetRebin(rebin);
1697 d.SetCutEdges(cutEdges);
1698 d.SetTitle(title);
b2e7f2d6 1699 d.SetShowOthers(flags & 0x1);
1700 d.SetShowAlice(flags & 0x2);
1701 d.SetShowRatios(flags & 0x4);
1702 d.SetShowLeftRight(flags & 0x8);
f709afcf 1703 d.SetShowRings(flags & 0x10);
2f92ff0e 1704 // Do the below if your input data does not contain these settings
fe52e455 1705 if (sNN > 0) d.SetSNN(sNN); // Collision energy per nucleon pair (GeV)
1706 if (sys > 0) d.SetSys(sys); // Collision system (1:pp, 2:PbPB)
1707 if (trg > 0) d.SetTrigger(trg); // Collision trigger (1:INEL, 2:INEL>0, 4:NSD)
1708 if (vzMin < 999 && vzMax > -999)
1709 d.SetVertexRange(vzMin,vzMax); // Collision vertex range (cm)
b2e7f2d6 1710 d.Run(filename);
1711}
2f92ff0e 1712//____________________________________________________________________
1713//
1714// EOF
1715//
1716