AliPhysics  63e47e1 (63e47e1)
DrawdNdeta.C
Go to the documentation of this file.
1 
16 #include <TH1.h>
17 #include <TH2.h>
18 #include <TColor.h>
19 #include <THStack.h>
20 #include <TGraphErrors.h>
21 #include <TGraphAsymmErrors.h>
22 #include <TMultiGraph.h>
23 #include <TFile.h>
24 #include <TList.h>
25 #include <TString.h>
26 #include <TError.h>
27 #include <TSystem.h>
28 #include <TROOT.h>
29 #include <TMath.h>
30 #include <TCanvas.h>
31 #include <TPad.h>
32 #include <TStyle.h>
33 #include <TLegend.h>
34 #include <TLegendEntry.h>
35 #include <TLatex.h>
36 #include <TArrow.h>
37 #include <TImage.h>
38 #include <TRandom.h>
39 #include <TParameter.h>
40 #include <TGClient.h>
41 #include <fstream>
42 #include <iostream>
44 // #define SYSERR_COLOR kGray;
45 // #define SYSERR_COLOR kBlue-10
46 // #define SYSERR_COLOR kCyan-10
47 #define SYSERR_COLOR TColor::GetColor(220, 220, 255)
48 
49 #define SYSERR_STYLE 1001
50 
52 
53 
60 struct dNdetaDrawer
61 {
62  enum EFlags {
63  kShowRatios = 0x00001,
64  kShowLeftRight = 0x00002,
65  kShowSysError = 0x00004,
66  kShowRings = 0x00008,
67  kCutEdges = 0x00010,
68  kRemoveOuters = 0x00020,
69  kUseFinalMC = 0x00040,
70  kUseEmpirical = 0x00080,
71  kForceMB = 0x00100,
72  kMirror = 0x00200,
73  kExport = 0x00400,
74  kAddExec = 0x00800,
75  kOldFormat = 0x01000,
76  kVerbose = 0x02000,
77  kHiRes = 0x04000,
78  kExtraWhite = 0x08000,
79  kLogo = 0x10000,
80  kNoCentral = 0x20000,
81  kNoLabels = 0x40000,
82  kDefaultOptions = 0x1CE07
83  };
84  enum EOutFormat {
85  kPNG = 0x1,
86  kPDF = 0x2,
87  kROOT = 0x4,
88  kScript = 0x8,
90  };
91  struct MarkerUtil
92  {
96  enum {
97  kSolid = 0x000,
98  kHollow = 0x001,
99  kCircle = 0x002,
100  kSquare = 0x004,
101  kUpTriangle = 0x006,
102  kDownTriangle = 0x008,
103  kDiamond = 0x00a,
104  kCross = 0x00c,
105  kStar = 0x00e
106  };
115  {
116  Int_t base = bits & (0xFE);
117  Bool_t hollow = bits & kHollow;
118  switch (base) {
119  case kCircle: return (hollow ? 24 : 20);
120  case kSquare: return (hollow ? 25 : 21);
121  case kUpTriangle: return (hollow ? 26 : 22);
122  case kDownTriangle: return (hollow ? 32 : 23);
123  case kDiamond: return (hollow ? 27 : 33);
124  case kCross: return (hollow ? 28 : 34);
125  case kStar: return (hollow ? 30 : 29);
126  }
127  return 1;
128  }
137  {
138  UShort_t bits = 0;
139  switch (style) {
140  case 24: case 25: case 26: case 27: case 28: case 30: case 32:
141  bits |= kHollow; break;
142  }
143  switch (style) {
144  case 20: case 24: bits |= kCircle; break;
145  case 21: case 25: bits |= kSquare; break;
146  case 22: case 26: bits |= kUpTriangle; break;
147  case 23: case 32: bits |= kDownTriangle; break;
148  case 27: case 33: bits |= kDiamond; break;
149  case 28: case 34: bits |= kCross; break;
150  case 29: case 30: bits |= kStar; break;
151  }
152  return bits;
153  }
162  {
163  UShort_t bits = GetMarkerBits(style);
164  Int_t ret = GetMarkerStyle(bits ^ kHollow);
165  return ret;
166  }
167  };
168 
172  struct RangeParam
173  {
174  TAxis* fMasterAxis; // Master axis
175  TAxis* fSlave1Axis; // First slave axis
176  TVirtualPad* fSlave1Pad; // First slave pad
177  TAxis* fSlave2Axis; // Second slave axis
178  TVirtualPad* fSlave2Pad; // Second slave pad
179  };
180  //__________________________________________________________________
188  fShowOthers(0), // Show other data
189  // Settings
190  fRebin(0), // Rebinning factor
191  fFwdSysErr(0.07), // Systematic error in forward range
192  fCenSysErr(0.02), // Systematic error in central range
193  fTitle(""), // Title on plot
194  fBase(""), // Optional base name of output files
195  fClusterScale(""), // Scaling of clusters to tracklets
196  fFinalMC(""), // Final MC correction file name
197  fEmpirical(""), // Empirical correction file name
198  fDelta(0.), // IP_delta wrt to (0.005,0.184)
199  // Read (or set) information
200  fTrigString(0), // Trigger string (read, or set)
201  fNormString(0), // Normalisation string (read, or set)
202  fSNNString(0), // Energy string (read, or set)
203  fSysString(0), // Collision system string (read or set)
204  fVtxAxis(0), // Vertex cuts (read or set)
205  fCentAxis(0), // Centrality axis
206  fCentMeth(0), // Centrality axis
207  fTriggerEff(1), // Trigger efficency
208  fExtTriggerEff(false), // True if fTriggerEff was read
209  fCentMin(0), // Least centrality to plot
210  fCentMax(100), // Largest centrality to plot
211  fCentSeen(0x0), // 32bits of centtraliy seen flags
212  // Resulting plots
213  fResults(0), // Stack of results
214  fRatios(0), // Stack of ratios
215  fLeftRight(0), // Left-right asymmetry
216  fOthers(0), // Older data
217  fTriggers(0), // Number of triggers
218  fTruth(0), // Pointer to truth
219  // Other stuff
220  fRangeParam(0), // Parameter object for range zoom
221  fEmpCorr(0)
222  {
223  fRangeParam = new RangeParam;
226  fRangeParam->fSlave1Pad = 0;
228  fRangeParam->fSlave2Pad = 0;
229 
230  TColor* sysErr = gROOT->GetColor(kSysErrColor);
231  sysErr->SetAlpha(0.7);
232  }
243  dNdetaDrawer& operator=(const dNdetaDrawer&) { return *this; }
244 
245  //__________________________________________________________________
249  virtual ~dNdetaDrawer()
250  {
251  if (fRatios && fRatios->GetHists()) fRatios->GetHists()->Delete();
252  if (fResults && fResults->GetHists()) fResults->GetHists()->Delete();
253 
254  if (fTrigString) { delete fTrigString; fTrigString = 0; }
255  if (fSNNString) { delete fSNNString; fSNNString = 0; }
256  if (fSysString) { delete fSysString; fSysString = 0; }
257  if (fVtxAxis) { delete fVtxAxis; fVtxAxis = 0; }
258  if (fCentAxis) { delete fCentAxis; fCentAxis = 0; }
259  if (fCentMeth) { delete fCentMeth; fCentMeth = 0; }
260  if (fResults) { delete fResults; fResults = 0; }
261  if (fRatios) { delete fRatios; fRatios = 0; }
262  if (fOthers) { delete fOthers; fOthers = 0; }
263  if (fTriggers) { delete fTriggers; fTriggers = 0; }
264  fRangeParam = 0;
265  }
266 
267  //==================================================================
268  void SetShowOthers(UInt_t others) { fShowOthers = others; }
274  void SetRebin(UShort_t x) { fRebin = x; }
275  //__________________________________________________________________
281  void SetTitle(TString x) { fTitle = x; }
282  //__________________________________________________________________
288  void SetBase(TString x) { fBase = x; }
289  //__________________________________________________________________
296  //__________________________________________________________________
309  void SetFinalMC(const TString& file) { fFinalMC = file; }
325  void SetDelta(Double_t delta) { fDelta = delta; }
326  void SetDelta(Double_t meanIpx, Double_t meanIpy)
327  {
328  Info("","Setting delta from %f,%f",meanIpx,meanIpy);
329  if (meanIpx < 0 && meanIpy < 0) return;
330  const Double_t refX = -0.004;
331  const Double_t refY = 0.184;
332  Double_t dx = (meanIpx - refX);
333  Double_t dy = (meanIpy - refY);
334  Info("","Shifts (%f-%f)=%f, (%f-%f)=%f",
335  meanIpx, refX, dx,
336  meanIpy, refY, dy);
337  if (TMath::Abs(dx) < 1e-3 && TMath::Abs(dy) < 1e-3) return;
338  Double_t delta = TMath::Sqrt(dx*dx+dy*dy);
339  fDelta = delta;
340  }
341 
342  /* @} */
343  //==================================================================
353  void SetSNN(UShort_t sNN)
354  {
355  fSNNString = new TNamed("sNN", Form("%04dGeV", sNN));
356  fSNNString->SetUniqueID(sNN);
357  }
358  //__________________________________________________________________
366  void SetSys(UShort_t sys)
367  {
368  fSysString = new TNamed("sys", (sys == 1 ? "pp" :
369  sys == 2 ? "PbPb" :
370  sys == 3 ? "pPb" :
371  sys == 4 ? "Pbp" :
372  "unknown"));
373  fSysString->SetUniqueID(sys);
374  }
375  //__________________________________________________________________
382  void SetVertexRange(Double_t vzMin, Double_t vzMax)
383  {
384  fVtxAxis = new TAxis(10, vzMin, vzMax);
385  fVtxAxis->SetName("vtxAxis");
386  fVtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", vzMin, vzMax));
387  }
388  //__________________________________________________________________
396  {
397  fCentMin = centMin;
398  fCentMax = centMax;
399  }
400  //__________________________________________________________________
406  void SetTrigger(UShort_t trig)
407  {
408  fTrigString = new TNamed("trigString", (trig & 0x1 ? "MBOR" :
409  trig & 0x2 ? "INEL>0" :
410  trig & 0x4 ? "MBAND5" :
411  trig & 0x2000 ? "V0-AND" :
412  "unknown"));
413  fTrigString->SetUniqueID(trig);
414  }
415  //__________________________________________________________________
423  {
424  fTriggerEff = eff;
425  fExtTriggerEff = false;
426  }
439  Bool_t useCen,
440  TObject*& fwdEmp,
441  TObject*& cenEmp,
442  TString& empName)
443  {
444  empName = "";
445  TString path(prx);
446  if (!path.Contains("empirical.root")) {
447  path = gSystem->ConcatFileName(gSystem->ExpandPathName(prx.Data()),
448  "empirical.root");
449  path.Append("#default");
450  }
451  TUrl empUrl(path);
452  TFile* empirical = TFile::Open(empUrl.GetUrl(), "READ");
453  if (!empirical) return false;
454 
455  const char* empPath = empUrl.GetAnchor();
456  TObject* fwdObj = empirical->Get(Form("Forward/%s", empPath));
457  TObject* cenObj = empirical->Get(Form("Central/%s", empPath));
458  if (!(fwdObj &&
459  (fwdObj->IsA()->InheritsFrom(TH1::Class()) ||
460  fwdObj->IsA()->InheritsFrom(TGraphAsymmErrors::Class())))) {
461  Warning("Run", "Didn't get the object Forward/%s from %s",
462  empPath, empUrl.GetUrl());
463  }
464  if (useCen &&
465  !(cenObj &&
466  (cenObj->IsA()->InheritsFrom(TH1::Class()) ||
467  cenObj->IsA()->InheritsFrom(TGraphAsymmErrors::Class())))) {
468  Warning("Run", "Didn't get the object Central/%s from %s",
469  empPath, empUrl.GetUrl());
470  }
471  else {
472  fwdEmp = fwdObj;
473  cenEmp = fwdObj;
474  empName = empUrl.GetUrl();
475  if (fwdEmp->IsA()->InheritsFrom(TH1::Class())) {
476  TH1* h = static_cast<TH1*>(fwdEmp);
477  h->SetDirectory(0);
478  if (fDelta) {
479 #if 0
480  TF1* f = new TF1("corr",
481  "1+[0]"
482  "+(x<0)*sqrt(2)*[0]"
483  "+(x<[1])*[2]*[0]*TMath::Power(x-[1],2)",
484  -6, 6);
485 #else
486  TF1* f = new TF1("corr", "1+[2]*([0]+(x<[1])*pow([0]*(x-[1]),2))");
487 #endif
488  f->SetParNames("delta","eta0","a");
489  f->SetParameter(0,fDelta);
490  f->SetParameter(1,-2.0);
491  f->SetParameter(2,.10); //TMath::Sqrt(2)); // 0.5);
492  // f->Print();
493  Info("", "Applying correction for IP_delta=%f", fDelta);
494  for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
495  Double_t c = h->GetBinContent(i);
496  if (c < 1e-6) continue;
497 
498  Double_t e = h->GetBinError(i);
499  Double_t eta = h->GetXaxis()->GetBinCenter(i);
500  Double_t cor = f->Eval(eta);
501  // Info("", "%5.2f -> %7.4f", eta, cor);
502  h->SetBinContent(i, c*cor);
503  h->SetBinError(i, e*cor);
504  }
505  }
506  }
507  if (cenEmp->IsA()->InheritsFrom(TH1::Class()))
508  static_cast<TH1*>(cenEmp)->SetDirectory(0);
509  }
510  empirical->Close();
511  return !empName.IsNull();
512  }
513 
514  //==================================================================
519  void Run(const char* filename="forward_dndeta.root",
520  const char* title="",
521  const char* others="all",
522  const char* options="default",
523  const char* formats="all",
524  UShort_t rebin=5,
525  Float_t eff=0,
526  UShort_t centMin=0,
527  UShort_t centMax=0,
528  Float_t vzMin=+999,
529  Float_t vzMax=-999,
530  const char* base="")
531  {
532  Warning("Run","\n"
533  "============================================================\n"
534  "\n"
535  "This script is deprecated. Please use new GSE based drawing\n"
536  "\n"
537  "============================================================\n");
538  TString ostr(others); ostr.ToUpper();
539  UShort_t obits = 0x0;
540  if (ostr.EqualTo("ALL")) obits = 0xf;
541  else {
542  if (ostr.Contains("UA5")) obits |= 0x1;
543  if (ostr.Contains("CMS")) obits |= 0x2;
544  if (ostr.Contains("ALICE")) obits |= 0x4;
545  if (ostr.Contains("WIP")) obits |= 0x8;
546  }
547 
548  TString fstr(options);
549  UInt_t fbits = 0;
550  if (fstr.EqualTo("default", TString::kIgnoreCase)) fbits = kDefaultOptions;
551  else {
552  TObjArray* farr = fstr.Tokenize(" ,");
553  TIter next(farr);
554  TObjString* ftoken = 0;
555  while ((ftoken = static_cast<TObjString*>(next()))) {
556  TString& token = ftoken->String();
557  token.ToLower();
558  if (token.BeginsWith("ratio")) fbits |= kShowRatios;
559  else if (token.BeginsWith("asym")) fbits |= kShowLeftRight;
560  else if (token.BeginsWith("left")) fbits |= kShowLeftRight;
561  else if (token.BeginsWith("syse")) fbits |= kShowSysError;
562  else if (token.BeginsWith("rings")) fbits |= kShowRings;
563  else if (token.BeginsWith("noedge")) fbits |= kCutEdges;
564  else if (token.BeginsWith("noout")) fbits |= kRemoveOuters;
565  else if (token.BeginsWith("finalmc")) fbits |= kUseFinalMC;
566  else if (token.BeginsWith("mb")) fbits |= kForceMB;
567  else if (token.BeginsWith("mirror")) fbits |= kMirror;
568  else if (token.BeginsWith("export")) fbits |= kExport;
569  else if (token.BeginsWith("exec")) fbits |= kAddExec;
570  else if (token.BeginsWith("old")) fbits |= kOldFormat;
571  else if (token.BeginsWith("verbose")) fbits |= kVerbose;
572  else if (token.BeginsWith("hires")) fbits |= kHiRes;
573  else if (token.BeginsWith("extraw")) fbits |= kExtraWhite;
574  else if (token.BeginsWith("logo")) fbits |= kLogo;
575  else if (token.BeginsWith("nocentr")) fbits |= kNoCentral;
576  else if (token.BeginsWith("nolabels")) fbits |= kNoLabels;
577  else if (token.BeginsWith("empirical")) {
578  fbits |= kUseEmpirical;
579  TObjArray* parts=token.Tokenize("=");
580  if (parts->GetEntriesFast() > 1)
581  SetEmpirical(parts->At(1)->GetName());
582  delete parts;
583  }
584  }
585  delete farr;
586  }
587  TString estr(formats); estr.ToUpper();
588  UShort_t ebits = 0x0;
589  if (ostr.EqualTo("ALL")) ebits = kAllFormats;
590  else {
591  if (ostr.Contains("PNG")) ebits |= kPNG;
592  if (ostr.Contains("PDF")) ebits |= kPDF;
593  if (ostr.Contains("ROOT")) ebits |= kROOT;
594  if (ostr.Contains("C")) ebits |= kScript;
595  }
596 
597  Run(filename, title, rebin, obits, fbits, 0, 0, 0, eff,
598  centMin, centMax, vzMin, vzMax, base, ebits);
599  }
619  void Run(const char* filename,
620  const char* title,
621  UShort_t rebin,
622  UShort_t others=0x7,
623  UInt_t flags=kDefaultOptions,
624  UShort_t sys=0,
625  UShort_t sNN=0,
626  UShort_t trg=0,
627  Float_t eff=0,
628  UShort_t centMin=0,
629  UShort_t centMax=0,
630  Float_t vzMin=+999,
631  Float_t vzMax=-999,
632  const char* base="",
633  UShort_t formats=kAllFormats)
634  {
635  SetRebin(rebin);
636  SetTitle(title);
637  SetShowOthers(others);
638  SetBase(base);
639  // d.fClusterScale = "1.06 -0.003*x +0.0119*x*x";
640  // Do the below if your input data does not contain these settings
641  if (sNN > 0) SetSNN(sNN); // Collision energy per nucleon pair (GeV)
642  if (sys > 0) SetSys(sys); // Collision system (1:pp, 2:PbPB)
643  if (trg > 0) SetTrigger(trg); // Collision trigger (1:INEL, 2:INEL>0, 4:NSD)
644  if (eff > 0) SetTriggerEfficiency(eff); // Trigger efficiency
645  if (vzMin < 999 && vzMax > -999)
646  SetVertexRange(vzMin,vzMax); // Collision vertex range (cm)
647  SetCentralityRange(centMin,centMax); // Collision vertex range (cm)
648 
649  fCentSeen = 0;
650  fOptions = flags;
651  fFormats = formats;
652  SetForwardSysError(flags & kShowSysError ? 0.07 : 0);
653  SetFinalMC (flags & kUseFinalMC ? "forward_dndetamc.root" : "");
654  // "EmpiricalCorrection.root"
655  SetEmpirical (flags & kUseEmpirical ? fEmpirical.Data() : "");
656  // SetBase(base);
657 
658  Double_t max = 0, rmax=0, amax=0;
659 
660  gStyle->SetPalette(1);
661 
662  // --- Open input file -------------------------------------------
663  TFile* file = TFile::Open(filename, "READ");
664  if (!file) {
665  Error("Run", "Cannot open %s", filename);
666  return;
667  }
668  Info("Run", "Drawing results from %s", file->GetName());
669 
670  // --- Get forward list ------------------------------------------
671  TList* forward = static_cast<TList*>(file->Get("ForwarddNdetaResults"));
672  if (!forward) {
673  Error("Run", "Couldn't find list ForwarddNdetaResults");
674  return;
675  }
676  TList* sums = static_cast<TList*>(file->Get("ForwarddNdetaSums"));
677  if (!sums) {
678  Error("Run", "Couldn't find list ForwarddNdetaSums");
679  return;
680  }
681 
682  if (!fEmpirical.IsNull()) {
683  TParameter<bool>* p =
684  static_cast<TParameter<bool>*>(sums->FindObject("empirical"));
685  if (p && p->GetVal() && !fEmpirical.IsNull()) {
686  Warning("Run", "Empirical correction already applied");
687  fEmpirical = "__task__";
688  }
689  else if (forward->FindObject("dndetaEmp")) {
690  Warning("Run", "Empirical correction already applied");
691  fEmpirical = "__task__";
692  }
693  }
694 
695  if (!forward->FindObject("deltaIP")) {
696  TH2* vertexXY = static_cast<TH2*>(sums->FindObject("vertexAccXY"));
697  if (vertexXY && fDelta <= 0)
698  SetDelta(vertexXY->GetMean(1), vertexXY->GetMean(2));
699  }
700 
701  // --- Get information on the run --------------------------------
702  FetchInformation(forward);
703 
704  // --- Print settings --------------------------------------------
705  Info("Run", "Settings for the drawer:\n"
706  " Show ratios: %5s\n"
707  " Show Left/right: %5s\n"
708  " Show rings: %5s\n"
709  " Cut edges when rebinning: %5s\n"
710  " Remove outer rings: %5s\n"
711  " Force minimum bias: %5s\n"
712  " Mirror to un-covered regions: %5s\n"
713  " Export to file: %5s\n"
714  " Add Zoom code: %5s\n"
715  " Assume old format: %5s\n"
716  " Be verbose: %5s\n"
717  " Hi-resolution plot: %5s\n"
718  " Extra whitespace: %5s\n"
719  " Show logo: %5s\n"
720  " Show clusters: %5s\n"
721  " Show y-axis labels: %5s\n"
722  " Show other results: 0x%03x\n"
723  " Rebinning factor: %5d\n"
724  " Forward systematic error: %5.1f%%\n"
725  " Central systematic error: %5.1f%%\n"
726  " Trigger efficiency: %5.1f%%\n"
727  " Title on plot: %s\n"
728  " Scaling of clusters to tracklets: %s\n"
729  " Final MC correction file: %s\n"
730  " Empirical correction file: %s",
731  ((fOptions & kShowRatios) ? "yes" : "no"),
732  ((fOptions & kShowLeftRight) ? "yes" : "no"),
733  ((fOptions & kShowRings) ? "yes" : "no"),
734  ((fOptions & kCutEdges) ? "yes" : "no"),
735  ((fOptions & kRemoveOuters) ? "yes" : "no"),
736  ((fOptions & kForceMB) ? "yes" : "no"),
737  ((fOptions & kMirror) ? "yes" : "no"),
738  ((fOptions & kExport) ? "yes" : "no"),
739  ((fOptions & kAddExec) ? "yes" : "no"),
740  ((fOptions & kOldFormat) ? "yes" : "no"),
741  ((fOptions & kVerbose) ? "yes" : "no"),
742  ((fOptions & kHiRes) ? "yes" : "no"),
743  ((fOptions & kExtraWhite) ? "yes" : "no"),
744  ((fOptions & kLogo) ? "yes" : "no"),
745  ((fOptions & kNoCentral) ? "no" : "yes"),
746  ((fOptions & kNoLabels) ? "no" : "yes"),
747  fShowOthers,
748  fRebin,
749  (100*fFwdSysErr),
750  (100*fCenSysErr),
751  (100*fTriggerEff),
752  fTitle.Data(),
753  fClusterScale.Data(),
754  fFinalMC.Data(),
755  fEmpirical.Data());
756 
757  // --- Set the macro pathand load other data script --------------
758  TString savPath(gROOT->GetMacroPath());
759  gROOT->SetMacroPath(Form("%s:$(ALICE_PHYSICS)/PWGLF/FORWARD/analysis2",
760  gROOT->GetMacroPath()));
761  // Always recompile
762  if (!gROOT->GetClass("RefData"))
763  gROOT->LoadMacro("OtherData.C+");
764  gROOT->SetMacroPath(savPath);
765 
766  Bool_t useCen = !(fOptions & kNoCentral);
767  // --- Get the central results -----------------------------------
768  TList* clusters = 0;
769  if (useCen) {
770  clusters = static_cast<TList*>(file->Get("CentraldNdetaResults"));
771  if (!clusters) Warning("Run", "Couldn't find list CentraldNdetaResults");
772  }
773 
774  // --- Get the central results -----------------------------------
775  TList* mcTruth = static_cast<TList*>(file->Get("MCTruthdNdetaResults"));
776  if (!mcTruth) Warning("Run", "Couldn't find list MCTruthdNdetaResults");
777 
778  // --- Make our containtes ---------------------------------------
779  fResults = new THStack("results", "Results");
780  fRatios = new THStack("ratios", "Ratios");
781  fLeftRight = new THStack("asymmetry", "Left-right asymmetry");
782  fOthers = new TMultiGraph();
783 
784  // --- Try to open the final MC file, and find relevant lists ----
785  TList* forwardMC = 0;
786  // TList* centralMC = 0;
787  if (!fFinalMC.IsNull()) {
788  TFile* finalMC = TFile::Open(fFinalMC, "READ");
789  if (!finalMC) {
790  Warning("Run", "Failed to open file %s for final MC corrections",
791  fFinalMC.Data());
792  }
793  else {
794  forwardMC = static_cast<TList*>(finalMC->Get("ForwarddNdetaResults"));
795  if (!forwardMC)
796  Warning("Run","Couldn't find list ForwarddNdetaResults for final MC");
797 #if 0
798  centralMC = static_cast<TList*>(finalMC->Get("CentradNdetalResults"));
799  if (!centralMC)
800  Warning("Run","Couldn't find list CentraldNdetaResults for final MC");
801 #endif
802  }
803  }
804  if (!forwardMC) fFinalMC = "";
805 
806  // --- Try to get the emperical correction -----------------------
807  TObject* fwdEmp = 0;
808  TObject* cenEmp = 0;
809  TUrl empUrl(fEmpirical);
810  TFile* empirical = 0;
811  if (!fEmpirical.IsNull() && !fEmpirical.EqualTo("__task__")) {
812  // Try some other locations
813  const char* test[] = {
814  fEmpirical.Data(),
815  "file://${ANA_SRC}",
816  "file://${FWD}",
817  "file://${OADB_PATH}/PWGLF/FORWARD/EMPIRICAL",
818  "file://${ALICE_PHYSICS}/OADB/PWGLF/FORWARD/EMPIRICAL",
819  0 };
820  const char** ptr = test;
821  Bool_t ok = false;
822  while (*ptr) {
823  const char* testf[] = { "", "empirical_000138190.root", 0 };
824  const char** ptr2 = testf;
825  while (*ptr2) {
826  TString path(gSystem->ConcatFileName(*ptr, *ptr2));
827  if (GetEmpirical(*ptr, useCen, fwdEmp, cenEmp, fEmpirical)) {
828  ok = true;
829  break;
830  }
831  ptr2++;
832  }
833  if (ok) break;
834  ptr++;
835  }
836  }
837 
838  // --- Loop over input data --------------------------------------
839  TObjArray truths;
840  FetchTopResults(mcTruth, 0, 0, "MCTruth", max, rmax, amax,truths);
841  TObjArray* fwdA = FetchTopResults(forward, forwardMC, fwdEmp, "Forward",
842  max, rmax, amax,truths);
843  TObjArray* cenA = FetchTopResults(clusters, 0, cenEmp, "Central",
844  max, rmax, amax,truths);
845 
846  // --- Get trigger information -----------------------------------
847  // TList* sums = static_cast<TList*>(file->Get("ForwardSums"));
848  if (sums) {
849  TList* all = (fOptions & kOldFormat ? sums :
850  static_cast<TList*>(sums->FindObject("all")));
851  if (all) {
852  fTriggers = FetchHistogram(all, "triggers");
853  if (!fTriggers) all->ls();
854  }
855  else {
856  Warning("Run", "List all not found in ForwardSums");
857  sums->ls();
858  }
859  }
860  else {
861  Warning("Run", "No ForwardSums directory found in %s", file->GetName());
862  file->ls();
863  }
864 
865  // --- Check our stacks ------------------------------------------
866  if (!fResults->GetHists() ||
867  fResults->GetHists()->GetEntries() <= 0) {
868  Error("Run", "No histograms in result stack!");
869  return;
870  }
871  if (!fOthers->GetListOfGraphs() ||
872  fOthers->GetListOfGraphs()->GetEntries() <= 0) {
873  Warning("Run", "No other data found - disabling that");
874  fShowOthers = 0;
875  }
876  if (!fRatios->GetHists() ||
877  fRatios->GetHists()->GetEntries() <= 0) {
878  Warning("Run", "No ratio data found - disabling that");
879  // fRatios->ls();
880  fOptions &= ~kShowRatios;
881  }
882  if (!fLeftRight->GetHists() ||
883  fLeftRight->GetHists()->GetEntries() <= 0) {
884  Warning("Run", "No left/right data found - disabling that");
885  // fLeftRight->ls();
886  fOptions &= ~kShowLeftRight;
887  }
888  if (fFwdSysErr > 0) {
889  if (fCenSysErr <= 0) fCenSysErr = fFwdSysErr;
890  for (Int_t i = 0; i < fwdA->GetEntriesFast(); i++) {
891  TH1* fwd = static_cast<TH1*>(fwdA->At(i));
892  TH1* cen = (cenA ? static_cast<TH1*>(cenA->At(i)) : 0);
893  CorrectForward(fwd);
894  CorrectCentral(cen);
895  Double_t low, high;
896  TH1* tmp = Merge(cen, fwd, low, high);
897  TF1* f = 0; // FitMerged(tmp, low, high);
898  MakeSysError(tmp, cen, fwd, f);
899  delete f;
900 
901  if (fOptions & kNoCentral && tmp) {
902  // Split Sys error into two histograms
903  const char* nme = tmp->GetName();
904  TH1* tmpp = static_cast<TH1*>(tmp->Clone(Form("%s_a", nme)));
905  tmp->SetName(Form("%s_c", nme));
906  for (Int_t k = 1; k <= tmp->GetNbinsX(); k++) {
907  Double_t x = tmp->GetXaxis()->GetBinCenter(k);
908  TH1* tmppp = (x < 0 ? tmpp : tmp);
909  tmppp->SetBinError(k, 0);
910  tmppp->SetBinContent(k, 0);
911  }
912  fResults->GetHists()->AddFirst(tmpp, (f ? "e5" : "e2"));
913  }
914 
915  if (fOptions & kVerbose)
916  Info("", "Adding systematic error histogram %s", tmp->GetName());
917  fResults->GetHists()->AddFirst(tmp, (f ? "e5" : "e2"));
918 
919  if (!(fOptions & kMirror)) continue;
920 
921  TH1* tmp2 = Symmetrice(tmp);
922  if (tmp2) {
923  tmp2->SetFillColor(tmp->GetFillColor());
924  tmp2->SetFillStyle(tmp->GetFillStyle());
925  tmp2->SetMarkerStyle(tmp->GetMarkerStyle());
926  tmp2->SetLineWidth(tmp->GetLineWidth());
927  fResults->GetHists()->AddFirst(tmp2, "e5");
928  fResults->Modified();
929  }
930  }
931  }
932  delete fwdA;
933  delete cenA;
934 
935  // --- Close the input file --------------------------------------
936  file->Close();
937 
938 
939 
940  // --- Plot results ----------------------------------------------
941  Plot(max, rmax, amax);
942  }
943 
944  //__________________________________________________________________
950  void FetchInformation(const TList* results)
951  {
952  if (!fTrigString)
953  fTrigString = static_cast<TNamed*>(results->FindObject("trigger"));
954  if (!fNormString)
955  fNormString = static_cast<TNamed*>(results->FindObject("scheme"));
956  if (!fSNNString)
957  fSNNString = static_cast<TNamed*>(results->FindObject("sNN"));
958  if (!fSysString)
959  fSysString = static_cast<TNamed*>(results->FindObject("sys"));
960  if (!fVtxAxis)
961  fVtxAxis = static_cast<TAxis*>(results->FindObject("vtxAxis"));
962  if (!fCentAxis) {
963  TObject* cO = results->FindObject("centAxis");
964  if (cO) {
965  if (cO->IsA()->InheritsFrom(TH1::Class())) {
966  TH1* cH = static_cast<TH1*>(cO);
967  fCentAxis = cH->GetXaxis();
968  }
969  else if (cO->IsA()->InheritsFrom(TAxis::Class()))
970  fCentAxis = static_cast<TAxis*>(cO);
971  }
972  }
973  if (!fCentMeth)
974  fCentMeth = results->FindObject("centEstimator");
975  if (!fCentMeth && HasCent()) {
976  TString tmp(fTitle);
977  tmp.Remove(0,tmp.Index("CENT")+4);
978  fCentMeth = new TNamed("centEstimator", tmp.Data()); // default");
979  fCentMeth->SetUniqueID(1);
980  }
981  if (fSysString && fSysString->GetUniqueID() != 1 &&
982  fCentMin == 0 && fCentMax == 0) {
983  fCentMin = 0;
984  fCentMax = 100;
985  }
986 
987  if (fTriggerEff < 0) {
988  // Allow complete overwrite by passing negative number
989  SetTriggerEfficiency(TMath::Abs(fTriggerEff));
990  }
991  else if (fTriggerEff <= 0 || TMath::Abs(1-fTriggerEff)<1e-6) {
992  TParameter<double>* eff =
993  static_cast<TParameter<double>*>(results->FindObject("triggerEff"));
994  if (eff) {
995  fTriggerEff = eff->GetVal();
996  fExtTriggerEff = true;
997  Info("FetchInformation", "External trigger efficicency: %5.3f",
998  fTriggerEff);
999  }
1000  if (fTriggerEff <= 0) SetTriggerEfficiency(1);
1001  }
1002 
1003  TNamed* options = static_cast<TAxis*>(results->FindObject("options"));
1004  if (!fTrigString) fTrigString = new TNamed("trigger", "unknown");
1005  if (!fNormString) fNormString = new TNamed("scheme", "unknown");
1006  if (!fSNNString) fSNNString = new TNamed("sNN", "unknown");
1007  if (!fSysString) fSysString = new TNamed("sys", "unknown");
1008  if (!fVtxAxis) {
1009  fVtxAxis = new TAxis(1,0,0);
1010  fVtxAxis->SetName("vtxAxis");
1011  fVtxAxis->SetTitle("v_{z} range unspecified");
1012  }
1013  if (fCentAxis) {
1014  Printf("Centrality axis: %d [%f,%f] vs [%f,%f]",
1015  fCentAxis->GetNbins(),
1016  fCentAxis->GetXmin(),
1017  fCentAxis->GetXmax(),
1018  fCentMin,
1019  fCentMax);
1020  TArrayD bins(fCentAxis->GetNbins()+1);
1021  Int_t nBins = 0;
1022  Double_t high = -1;
1023  for (Int_t i = 1; i <= fCentAxis->GetNbins(); i++) {
1024  Double_t binLow = fCentAxis->GetBinLowEdge(i);
1025  Double_t binHigh = fCentAxis->GetBinUpEdge(i);
1026  if (binLow < fCentMin-.5) continue;
1027  if (binHigh > fCentMax+.5) continue;
1028  high = binHigh;
1029  bins[nBins] = binLow;
1030  nBins++;
1031  }
1032  bins[nBins] = high;
1033  fCentAxis->Set(nBins, bins.GetArray());
1034  }
1035 
1036  if (fTrigString) {
1037  UInt_t mask = 0x200f & fTrigString->GetUniqueID();
1038  if (mask == 0x2) fTrigString->SetTitle("INEL>0");
1039  else if (fTriggerEff != 1) {
1040  if (mask == 0x1) fTrigString->SetTitle("INEL");
1041  else if (mask == 0x2000) fTrigString->SetTitle("NSD");
1042  else if (mask == 0x4) fTrigString->SetTitle("NSD");
1043  }
1044  }
1045 
1046  if (true /*fOptions & kVerbose*/) {
1047  TString centTxt("none");
1048  TString centMeth(fCentMeth ? fCentMeth->GetTitle() : "V0M");
1049  if (fCentAxis) {
1050  Int_t nCent = fCentAxis->GetNbins();
1051  centTxt = Form("%s %d bins", centMeth.Data(), nCent);
1052  for (Int_t i = 0; i <= nCent; i++)
1053  centTxt.Append(Form("%c%d", i == 0 ? ' ' : '-',
1054  int(fCentAxis->GetXbins()->At(i))));
1055  }
1056  Info("FetchInformation",
1057  "Initialized for\n"
1058  " Trigger: %-30s (0x%x)\n"
1059  " Efficiency: %-6.4f\n"
1060  " sqrt(sNN): %-30s (%dGeV)\n"
1061  " System: %-30s (%d)\n"
1062  " Vz range: %-30s (%f,%f)\n"
1063  " Normalization: %-30s (%d)\n"
1064  " Centrality: %s\n"
1065  " Options: %s",
1066  fTrigString->GetTitle(), fTrigString->GetUniqueID(),
1067  fTriggerEff,
1068  fSNNString->GetTitle(), fSNNString->GetUniqueID(),
1069  fSysString->GetTitle(), fSysString->GetUniqueID(),
1070  fVtxAxis->GetTitle(), fVtxAxis->GetXmin(), fVtxAxis->GetXmax(),
1071  fNormString->GetTitle(), fNormString->GetUniqueID(),
1072  centTxt.Data(), (options ? options->GetTitle() : "none"));
1073  }
1074  if (fSysString->GetUniqueID() == 3 ||
1075  fSysString->GetUniqueID() == 4) {
1076  Info("FetchInformation", "Left/Right asymmetry, and mirroring "
1077  "explicitly disabled for pPb/Pbp");
1079  fOptions &= ~kMirror;
1080  }
1081  }
1082  //__________________________________________________________________
1083  TMultiGraph* FetchOthers(UShort_t centLow, UShort_t centHigh)
1084  {
1085  TMultiGraph* thisOther = 0;
1086  if (fShowOthers == 0) return 0;
1087 
1088  UShort_t sys = (fSysString ? fSysString->GetUniqueID() : 0);
1089  UShort_t trg = (fTrigString ? fTrigString->GetUniqueID() : 0);
1090  UShort_t snn = (fSNNString ? fSNNString->GetUniqueID() : 0);
1091  UShort_t cen = (fCentMeth ? fCentMeth->GetUniqueID() : 0);
1092  if (centLow < centHigh) {
1093  // Possibly modify trg according to method
1094  // Printf("We have centrality cen=%d meth=%s", cen,
1095  // (fCentMeth ? fCentMeth->GetTitle() : "?"));
1096  UShort_t msk = 0x01; // Default to V0M comparison
1097  if (cen == 0 && fCentMeth) {
1098  TString cm(fCentMeth->GetTitle());
1099  if (cm.EqualTo("V0M", TString::kIgnoreCase)) msk = 0x01;
1100  else if (cm.EqualTo("V0A", TString::kIgnoreCase)) msk = 0x02;
1101  else if (cm.EqualTo("ZNA", TString::kIgnoreCase)) msk = 0x04;
1102  else if (cm.EqualTo("ZNC", TString::kIgnoreCase)) msk = 0x08;
1103  else if (cm.EqualTo("V0C", TString::kIgnoreCase)) msk = 0x10;
1104  else if (cm.EqualTo("Cl1", TString::kIgnoreCase)) msk = 0x20;
1105  }
1106  else {
1107  switch (cen) {
1108  case 1: msk = 0x01; break; // default V0M
1109  case 2: msk = 0x01; break; // V0M
1110  case 3: msk = 0x02; break; // V0A
1111  case 4: break; // V0A123
1112  case 5: msk = 0x10; break; // V0C
1113  case 6: break; // FMD
1114  case 7: break; // Tracks
1115  case 8: break; // Tracklets
1116  case 9: break; // CL0
1117  case 10: msk = 0x20; break; // CL1
1118  case 11: break; // CND
1119  case 12: msk = 0x04; break; // ZNA
1120  case 13: msk = 0x08; break; // ZNC
1121  case 14: break; // ZPA
1122  case 15: break; // ZPC
1123  case 16: break; // NPA
1124  case 17: break; // V0MvsFMD
1125  case 18: break; // V0MvsTracklets
1126  case 19: break; // ZEMvsZDC
1127  case 20: break; // RefMult
1128  case 21: break; // HMTF V0A
1129  case 22: break; // HMTF V0M
1130  case 23: break; // HMTF V0C
1131  default: break;
1132  }
1133  }
1134  trg = (trg & 0x200f) | (msk << 4);
1135  }
1136  Long_t ret =
1137  gROOT->ProcessLine(Form("RefData::GetData(%d,%d,%d,%d,%d,%d);",
1138  sys,snn,trg,centLow,centHigh,fShowOthers));
1139  if (!ret) {
1140 #if 0
1141  Warning("", "RefData::GetData(%d,%d,0x%x,%d,%d,0x%x);",
1142  sys,snn,trg,centLow,centHigh,fShowOthers);
1143  Warning("FetchOthers",
1144  "No other data for %s %s %s %3d%%-%3d%% central (0x%x)",
1145  fSysString ? fSysString->GetTitle() : "unknown",
1146  fTrigString ? fTrigString->GetTitle() : "unknown",
1147  fSNNString ? fSNNString->GetTitle() : "unknown",
1148  centLow, centHigh, fShowOthers);
1149 #endif
1150  return 0;
1151  }
1152 
1153  thisOther = reinterpret_cast<TMultiGraph*>(ret);
1154  return thisOther;
1155  }
1156  //__________________________________________________________________
1171  TObjArray*
1172  FetchTopResults(const TList* list,
1173  const TList* mcList,
1174  TObject* empCorr,
1175  const char* name,
1176  Double_t& max,
1177  Double_t& rmax,
1178  Double_t& amax,
1179  TObjArray& truths)
1180  {
1181  if (!list) return 0;
1182  UShort_t n = HasCent() ? fCentAxis->GetNbins() : 1;
1183  // // Info("FetchTopResults","got %d centrality bins", n);
1184  // if (n == 0) {
1185  // TH1* h = FetchOne(list, mcList, empCorr, name, "all",
1186  // FetchOthers(0,0), -1000, 0,
1187  // max, rmax, amax, truths);
1188  // if (!h) return 0;
1189  // TObjArray* a = new TObjArray;
1190  // // Info("FetchTopResults", "Adding %s to result stack", h->GetName());
1191  // a->AddAt(h, 0);
1192  // return a;
1193  // }
1194 
1195  TObjArray* a = new TObjArray;
1196  truths.Expand(n);
1197  for (UShort_t i = 0; i < n; i++) {
1198  Float_t centLow = 0;
1199  Float_t centHigh = 0;
1200  TString lname = "all";
1201  Int_t col = -1000;
1202  TString centTxt = "";
1203  if (HasCent()) {
1204  centLow = fCentAxis->GetBinLowEdge(i+1);
1205  centHigh = fCentAxis->GetBinUpEdge(i+1);
1206  lname = Form("cent%03dd%02d_%03dd%02d",
1207  Int_t(centLow), Int_t(centLow *100)%100,
1208  Int_t(centHigh), Int_t(centHigh*100)%100);
1209  col = GetCentralityColor(i+1);
1210  centTxt = Form("%6.2f%%-%6.2f%% central", centLow, centHigh);
1211  }
1212  TH1* tt = static_cast<TH1*>(truths.At(i));
1213  TH1* ot = tt;
1214  TH1* h = FetchOne(list, mcList, empCorr, name, lname,
1215  FetchOthers(centLow,centHigh), col,
1216  centTxt.Data(), max, rmax, amax, tt);
1217  if (!h) continue;
1218  fCentSeen |= (1 << i);
1219 
1220  if (tt != ot) {
1221  truths.AddAt(tt, i);
1222  }
1223  // Info("FetchTopResults", "Adding %pto result stack", h);
1224  a->AddAt(h, i);
1225  }
1226  if (a->GetEntries() <= 0) {
1227  delete a;
1228  a = 0;
1229  }
1230  return a;
1231  }
1232  //__________________________________________________________________
1251  TH1* FetchOne(const TList* list,
1252  const TList* mcList,
1253  TObject* empCorr,
1254  const char* name,
1255  const char* folderName,
1256  TMultiGraph* others,
1257  Int_t col,
1258  const char* txt,
1259  Double_t& max,
1260  Double_t& rmax,
1261  Double_t& amax,
1262  TH1*& truth)
1263  {
1264  TString foldName(folderName);
1265  TList* folder = (fOptions & kOldFormat ? const_cast<TList*>(list) :
1266  static_cast<TList*>(list->FindObject(foldName)));
1267  if (!folder) {
1268  Warning("FetchOne",
1269  "Couldn't find list '%s' in %s, trying w/o decimals (%s)",
1270  foldName.Data(), list->GetName(), txt);
1271  foldName.ReplaceAll("d00", "");
1272  foldName.ReplaceAll("d10", "");
1273  folder = (fOptions & kOldFormat ? const_cast<TList*>(list) :
1274  static_cast<TList*>(list->FindObject(foldName)));
1275  if (!folder) {
1276  Error("FetchOne", "Couldn't find list '%s' in %s",
1277  foldName.Data(), list->GetName());
1278  return 0;
1279  }
1280  }
1281  TList* mcFolder = 0;
1282  if (mcList) {
1283  mcFolder = static_cast<TList*>(mcList->FindObject(folderName));
1284  if (!mcFolder)
1285  Warning("FetchOne",
1286  "Didn't find the list '%s' in %s for final MC correction",
1287  folderName, mcList->GetName());
1288  }
1289  if (fOptions & kVerbose) {
1290  TObject* normCalc = folder->FindObject("normCalc");
1291  if (normCalc)
1292  Info("FetchOne", "%s:\n%s",
1293  folderName, normCalc->GetTitle());
1294  }
1295  TH1* h = FetchCentResults(folder, mcFolder, empCorr, name,
1296  others, col, folderName, max, rmax, amax, truth);
1297  return h;
1298  }
1299  //__________________________________________________________________
1317  TH1* FetchCentResults(const TList* list,
1318  const TList* mcList,
1319  TObject* empCorr,
1320  const char* name,
1321  TMultiGraph* thisOther,
1322  Int_t color,
1323  const char* centTxt,
1324  Double_t& max,
1325  Double_t& rmax,
1326  Double_t& amax,
1327  TH1*& truth)
1328  {
1329  TH1* norm = FetchHistogram(list, Form("norm%s", name));
1330  if (!norm) return 0;
1331  if (norm->GetMaximum() < 1000) {
1332  Warning("FetchCentResults", "Too few events in %s: %ld",
1333  list->GetName(), Long_t(norm->GetMaximum()));
1334  // return 0;
1335  }
1336 
1337  TH1* dndeta = FetchHistogram(list, Form("dndeta%s", name));
1338  TH1* dndetaMC = FetchHistogram(list, Form("dndeta%sMC", name));
1339  TH1* dndetaTruth = FetchHistogram(list, "dndetaTruth");
1340  TH1* dndetaEmp = FetchHistogram(list, Form("dndeta%sEmp", name));
1341  // Info("", "dN/deta truth from %s: %p", list->GetName(), dndetaTruth);
1342  // Info("", "dN/deta truth from external: %p", truth);
1343  if (dndetaEmp) dndeta = dndetaEmp;
1344 
1345  if (mcList && FetchHistogram(mcList, "finalMCCorr"))
1346  Warning("FetchCentResults", "dNdeta already corrected for final MC");
1347  else
1348  CorrectFinalMC(dndeta, mcList);
1349 
1350  CorrectEmpirical(dndeta, empCorr);
1351  CorrectTriggerEff(dndeta);
1352  CorrectTriggerEff(dndetaMC);
1353 
1354  TH1* dndetaSym = 0;
1355  TH1* dndetaMCSym = 0;
1356  SetAttributes(dndeta, color);
1357  SetAttributes(dndetaMC, HasCent() ? color : color+2);
1358  SetAttributes(dndetaTruth,color);
1359  SetAttributes(dndetaSym, color);
1360  SetAttributes(dndetaMCSym,HasCent() ? color : color+2);
1361  if (dndetaMC && HasCent())
1362  dndetaMC->SetMarkerStyle(dndetaMC->GetMarkerStyle()+2);
1363  if (dndetaMCSym && HasCent())
1364  dndetaMCSym->SetMarkerStyle(dndetaMCSym->GetMarkerStyle()+2);
1365  if (dndetaTruth && HasCent()) {
1366  dndetaTruth->SetMarkerStyle(34);
1367  dndetaTruth->SetMarkerColor(kYellow-1);
1368  }
1369  if (dndetaTruth) {
1370  dndetaTruth->SetLineColor(kBlack);
1371  dndetaTruth->SetFillColor(kBlack);
1372  dndetaTruth->SetFillStyle(3002);
1373  // dndetaTruth->SetLineColor(kBlack);
1374  }
1375  ModifyTitle(dndeta, centTxt);
1376  ModifyTitle(dndetaMC, centTxt);
1377  ModifyTitle(dndetaTruth,centTxt);
1378  ModifyTitle(dndetaSym, centTxt);
1379  ModifyTitle(dndetaMCSym,centTxt);
1380 
1381 
1382  max = TMath::Max(max, AddHistogram(fResults, dndetaTruth, "e5"));
1383  max = TMath::Max(max, AddHistogram(fResults, dndetaMC, dndetaMCSym));
1384  max = TMath::Max(max, AddHistogram(fResults, dndeta, dndetaSym));
1385 
1386  if (dndetaTruth) {
1387  truth = dndetaTruth;
1388  }
1389  else {
1390  if ((fOptions & kShowRings)) {
1391  THStack* rings = static_cast<THStack*>(list->FindObject("dndetaRings"));
1392  if (rings) {
1393  TIter next(rings->GetHists());
1394  TH1* hist = 0;
1395  while ((hist = static_cast<TH1*>(next())))
1396  max = TMath::Max(max, AddHistogram(fResults, hist));
1397  }
1398  } // If show rings
1399  // Info("FetchCentResults", "Got %p, %p, %p from %s with name %s, max=%f",
1400  // dndeta, dndetaMC, dndetaTruth, list->GetName(), name, max);
1401 
1402  if ((fOptions & kShowLeftRight)) {
1403  fLeftRight->Add(Asymmetry(dndeta, amax));
1404  fLeftRight->Add(Asymmetry(dndetaMC, amax));
1405  }
1406 
1407  if (thisOther) {
1408  TIter next(thisOther->GetListOfGraphs());
1409  TGraph* g = 0;
1410  while ((g = static_cast<TGraph*>(next()))) {
1411  fRatios->Add(Ratio(dndeta, g, rmax));
1412  fRatios->Add(Ratio(dndetaSym, g, rmax));
1413  SetAttributes(g, color);
1414  ModifyTitle(g, centTxt);
1415  if (!fOthers->GetListOfGraphs() ||
1416  !fOthers->GetListOfGraphs()->FindObject(g->GetName())) {
1417  max = TMath::Max(max,TMath::MaxElement(g->GetN(), g->GetY()));
1418  fOthers->Add(g);
1419  }
1420  }
1421  // fOthers->Add(thisOther);
1422  } // if others for this
1423  } // if not truth
1424  if (dndetaMC) {
1425  fRatios->Add(Ratio(dndeta, dndetaMC, rmax));
1426  fRatios->Add(Ratio(dndetaSym, dndetaMCSym, rmax));
1427  }
1428  if (truth) {
1429  Info("", "Forming ratio to truth:\n\t%s\n\t%s",
1430  dndeta->GetName(),
1431  truth->GetName());
1432  fRatios->Add(Ratio(dndeta, truth, rmax));
1433  fRatios->Add(Ratio(dndetaSym, truth, rmax));
1434  }
1435  return dndeta;
1436  }
1437  //__________________________________________________________________
1438  void CorrectFinalMC(TH1* dndeta, const TList* mcList)
1439  {
1440  if (!dndeta) return;
1441  if (!mcList) return;
1442 
1443  TH1* dndetaMC = FetchHistogram(mcList, dndeta->GetName());
1444  TH1* dndetaTruth = FetchHistogram(mcList, "dndetaTruth");
1445  if (!dndetaMC || !dndetaTruth) return;
1446 
1447  TH1* corr = static_cast<TH1*>(dndetaMC->Clone("finalMCCorr"));
1448  corr->Divide(dndetaTruth);
1449 
1450  Info("CorrectFinalMC", "Correcting dN/deta with final MC correction");
1451  dndeta->Divide(corr);
1452  }
1453  //__________________________________________________________________
1454  void CorrectEmpirical(TH1* dndeta, TObject* empObj)
1455  {
1456  if (!dndeta) return;
1457  if (!empObj) return;
1458 
1459 
1460  if (empObj->IsA()->InheritsFrom(TGraphAsymmErrors::Class())) {
1461  Info("CorrectEmpirical", "Doing empirical correction of dN/deta");
1462  TGraphAsymmErrors* empCorr = static_cast<TGraphAsymmErrors*>(empObj);
1463  TAxis* xAxis = dndeta->GetXaxis();
1464  for (Int_t i = 1; i <= xAxis->GetNbins(); i++) {
1465  Double_t x = xAxis->GetBinCenter(i);
1466  Double_t y = dndeta->GetBinContent(i);
1467  Double_t c = empCorr->Eval(x);
1468  dndeta->SetBinContent(i, y / c);
1469  }
1470  }
1471  else if (empObj->IsA()->InheritsFrom(TH1::Class())) {
1472  Info("CorrectEmpirical", "Doing empirical correction of dN/deta");
1473  TH1* empCorr = static_cast<TH1*>(empObj);
1474  dndeta->Divide(empCorr);
1475  }
1476  else {
1477  Warning("CorrectEmpirical",
1478  "Don't know how to apply a %s as an empirical correction",
1479  empObj->IsA()->GetName());
1480  }
1481  }
1482  //__________________________________________________________________
1483  void CorrectTriggerEff(TH1* dndeta)
1484  {
1485  if (fExtTriggerEff) return;
1486  if (!dndeta) return;
1487  if (fTriggerEff <= 0) return; // || fTriggerEff >= 1) return;
1488  Info("CorrectTriggerEff", "Correcting with trigger efficiency %5.3f",
1489  fTriggerEff);
1490  dndeta->Scale(fTriggerEff);
1491  }
1492  //__________________________________________________________________
1499  void Plot(Double_t max,
1500  Double_t rmax,
1501  Double_t amax)
1502  {
1503  gStyle->SetOptTitle(0);
1504  gStyle->SetTitleFont(kFont, "xyz");
1505  gStyle->SetLabelFont(kFont, "xyz");
1506 
1507  Int_t h = (gROOT->IsBatch() ?
1508  ((fOptions & kHiRes) ? 1600 : 900) :
1509  gClient->GetDisplayHeight());
1510  Int_t w = h; // h / TMath::Sqrt(2);
1511  Double_t y1 = 0;
1512  Double_t y2 = 0;
1513  Double_t y3 = 0;
1514  if (!(fOptions & kShowRatios)) w *= 1.3;
1515  else y1 = 0.3;
1516  if (!(fOptions & kShowLeftRight)) w *= 1.3;
1517  else {
1518  Double_t y11 = y1;
1519  y1 = (y11 > 0.0001 ? 0.4 : 0.2);
1520  y2 = (y11 > 0.0001 ? 0.2 : 0.2);
1521  }
1522  TCanvas* c = new TCanvas("Results", "Results", w, h);
1523  c->SetFillColor(0);
1524  c->SetBorderSize(0);
1525  c->SetBorderMode(0);
1526 
1527  Double_t s = Float_t(h) / 900;
1528 
1529  PlotResults(max, y1, s);
1530  c->cd();
1531 
1532  PlotRatios(rmax, y2, y1);
1533  c->cd( );
1534 
1535  PlotLeftRight(amax, y3, y2);
1536  c->cd();
1537 
1538 
1539  Int_t vMin = fVtxAxis->GetXmin();
1540  Int_t vMax = fVtxAxis->GetXmax();
1541  TString trg(fTrigString->GetTitle());
1542  Int_t nev = 0;
1543  if (fTriggers) nev = fTriggers->GetBinContent(1);
1544  if (HasCent()) trg = "CENT";
1545  trg = trg.Strip(TString::kBoth);
1546  trg.ReplaceAll(" ", "_");
1547  trg.ReplaceAll(">", "Gt");
1548  trg.ReplaceAll("&", "AND");
1549  trg.ReplaceAll("|", "OR");
1550  if (fBase.IsNull())
1551  fBase = "dndeta_<sys>_<snn>_<trig>_<ipmin><ipmax>cm_<nev>ev";
1552  fBase.ReplaceAll("<sys>", fSysString->GetTitle());
1553  fBase.ReplaceAll("<snn>", fSNNString->GetTitle());
1554  fBase.ReplaceAll("<trig>", trg.Data());
1555  fBase.ReplaceAll("<ipmin>", Form("%c%02d",vMin<0?'m':'p',TMath::Abs(vMin)));
1556  fBase.ReplaceAll("<ipmax>", Form("%c%02d",vMax<0?'m':'p',TMath::Abs(vMax)));
1557  fBase.ReplaceAll("<nev>", Form("%09d", nev));
1558  if ((fFormats & kPNG)) c->SaveAs(Form("%s.png", fBase.Data()));
1559  if ((fFormats & kROOT)) c->SaveAs(Form("%s.root", fBase.Data()));
1560  if ((fFormats & kScript))c->SaveAs(Form("%s.C", fBase.Data()));
1561  if ((fFormats & kPDF)) c->SaveAs(Form("%s.pdf", fBase.Data()));
1562  if (fOptions & kExport) {
1563  TString exp(fBase);
1564  exp.ReplaceAll("dndeta", "export");
1565  exp.ReplaceAll("dNdeta", "export");
1566  Export(exp);
1567  }
1568  }
1569  //__________________________________________________________________
1577  void PlotTitle(TVirtualPad* p, Double_t yd, Bool_t bottom=true)
1578  {
1579  // Put a title on top
1580  p->cd();
1581  fTitle.ReplaceAll("@", " ");
1582  Double_t s = 1/yd/1.2;
1583  TLatex* tit = new TLatex((bottom ? kRightMargin : p->GetLeftMargin()),
1584  (bottom ? 0.01 : .99), fTitle.Data());
1585  tit->SetNDC();
1586  tit->SetTextFont(kFont);
1587  tit->SetTextAlign(bottom ? 11 : 13);
1588  tit->SetTextSize(s*0.045);
1589  tit->SetTextColor(kAlicePurple);
1590  tit->Draw();
1591  }
1592 
1593  //__________________________________________________________________
1605  void BuildLegend(THStack* stack, TMultiGraph* mg,
1606  Double_t x1, Double_t y1, Double_t x2, Double_t y2,
1607  Int_t forceCol=0)
1608  {
1609  TLegend* l = new TLegend(x1,y1,x2,y2);
1610  Int_t nCol = forceCol;
1611  if (nCol <= 0) nCol = HasCent() ? 1 : 2;
1612  l->SetNColumns(nCol);
1613  l->SetFillColor(0);
1614  l->SetFillStyle(0);
1615  l->SetBorderSize(0);
1616  l->SetTextFont(kFont);
1617  l->SetTextColor(kAliceBlue);
1618 
1619  // Loop over items in stack and get unique items, while ignoring
1620  // mirrored data and systematic error bands
1621  TIter next(stack->GetHists());
1622  TH1* hist = 0;
1623  TObjArray unique;
1624  unique.SetOwner();
1625  Bool_t sysErrSeen = false;
1626  Bool_t mirrorSeen = false;
1627  while ((hist = static_cast<TH1*>(next()))) {
1628  TString t(hist->GetTitle());
1629  TString n(hist->GetName());
1630  n.ToLower();
1631  if (t.Contains("mirrored")) { mirrorSeen = true; continue; }
1632  if (n.Contains("syserror")) { sysErrSeen = true; continue; }
1633  if (unique.FindObject(t.Data())) continue;
1634  // TObjString* s1 = new TObjString(hist->GetTitle());
1635  TParameter<float>* s1 = new TParameter<float>(t,hist->GetMarkerSize());
1636  s1->SetUniqueID(((hist->GetMarkerStyle() & 0xFFFF) << 16) |
1637  ((hist->GetMarkerColor() & 0xFFFF) << 0));
1638  unique.Add(s1);
1639  // l->AddEntry(hist, hist->GetTitle(), "pl");
1640  }
1641  if (mg) {
1642  // If we have other stuff, scan for unique names
1643  TIter nexto(mg->GetListOfGraphs());
1644  TGraph* g = 0;
1645  while ((g = static_cast<TGraph*>(nexto()))) {
1646  TString n(g->GetTitle());
1647  if (n.Contains("mirrored")) continue;
1648  if (unique.FindObject(n.Data())) continue;
1649  // TObjString* s2 = new TObjString(n);
1650  TParameter<float>* s2 = new TParameter<float>(n,g->GetMarkerSize());
1651  s2->SetUniqueID(((g->GetMarkerStyle() & 0xFFFF) << 16) |
1652  ((g->GetMarkerColor() & 0xFFFF) << 0));
1653  unique.Add(s2);
1654  // l->AddEntry(hist, hist->GetTitle(), "pl");
1655  }
1656  }
1657 
1658  // Add legend entries for unique items only
1659  TIter nextu(&unique);
1660  // TObject* s = 0;
1661  TParameter<float>* s = 0;
1662  Int_t i = 0;
1663  while ((s = static_cast<TParameter<float>*>(nextu()))) {
1664  TLegendEntry* dd = l->AddEntry(Form("data%2d", i++),
1665  s->GetName(), "lp");
1666  Int_t style = (s->GetUniqueID() >> 16) & 0xFFFF;
1667  Int_t color = (s->GetUniqueID() >> 0) & 0xFFFF;
1668  dd->SetLineColor(kBlack);
1669  if (HasCent()) dd->SetMarkerColor(kBlack);
1670  else dd->SetMarkerColor(color);
1671  dd->SetMarkerStyle(style);
1672  dd->SetMarkerSize(s->GetVal());
1673  }
1674  if (sysErrSeen) {
1675  // Add entry for systematic errors
1676  TLegendEntry* d0 = l->AddEntry("d0", Form("%4.1f%% Systematic error",
1677  100*fFwdSysErr), "f");
1678  d0->SetLineColor(kSysErrColor);
1679  d0->SetMarkerColor(kSysErrColor);
1680  d0->SetFillColor(kSysErrColor);
1681  d0->SetFillStyle(SYSERR_STYLE);
1682  d0->SetMarkerStyle(0);
1683  d0->SetLineWidth(0);
1684  i++;
1685  }
1686  if (nCol == 2 && i % 2 == 1) {
1687  // To make sure the 'data' and 'mirrored' entries are on a line
1688  // by themselves
1689  TLegendEntry* dd = l->AddEntry("dd", " ", "");
1690  dd->SetTextSize(0);
1691  dd->SetFillStyle(0);
1692  dd->SetFillColor(0);
1693  dd->SetLineWidth(0);
1694  dd->SetLineColor(0);
1695  dd->SetMarkerSize(0);
1696  }
1697  if (mirrorSeen /* (fOptions & kMirror) */) {
1698  // Add entry for 'data'
1699  TLegendEntry* d1 = l->AddEntry("d1", "Data", "lp");
1700  d1->SetLineColor(kBlack);
1701  d1->SetMarkerColor(kBlack);
1702  d1->SetMarkerStyle(20);
1703 
1704  // Add entry for 'mirrored data'
1705  TLegendEntry* d2 = l->AddEntry("d2", "Mirrored data", "lp");
1706  d2->SetLineColor(kBlack);
1707  d2->SetMarkerColor(kBlack);
1708  d2->SetMarkerStyle(24);
1709  }
1710 
1711  l->Draw();
1712  }
1713  const char* CentLimitName(Bool_t isMult, Float_t v)
1714  {
1715  if (isMult) return Form("%3d", Int_t(v));
1716  if ((Int_t(v*100) % 100) == 0) return Form("%3d%%", Int_t(v));
1717  if ((Int_t(v*100) % 10) == 0) return Form("%5.1f%%", v);
1718  return Form("%6.2f%%", v);
1719  }
1720  //__________________________________________________________________
1730  {
1731  if (!HasCent()) return;
1732 
1733  Printf("Centralities seen 0x%x", fCentSeen);
1734 
1735  if (fCentAxis->GetNbins() <= 4) y1 += .15;
1736  TLegend* l = new TLegend(x1,y1,x2,y2);
1737  l->SetNColumns(1);
1738  l->SetFillColor(0);
1739  l->SetFillStyle(0);
1740  l->SetBorderSize(0);
1741  l->SetTextFont(kFont);
1742  l->SetTextColor(kAliceBlue);
1743 
1744  TString centMeth(fCentMeth->GetTitle());
1745  Bool_t isMult = centMeth.EqualTo("MULT");
1746  Int_t lowOff = (isMult ? 1 : 0);
1747  Int_t nextOff = 0;
1748  Int_t n = fCentAxis->GetNbins();
1749  for (Int_t i = 1; i <= n; i++) {
1750  if (!(fCentSeen & (1 << (i-1)))) { nextOff = 0; continue; }
1751  Double_t low = fCentAxis->GetBinLowEdge(i) + lowOff + nextOff;
1752  Double_t upp = fCentAxis->GetBinUpEdge(i);
1753  TString txt = Form("%s - %s",
1754  CentLimitName(isMult,low),
1755  CentLimitName(isMult,upp));
1756  if (isMult && upp == low) {
1757  nextOff = -1;
1758  txt = CentLimitName(isMult,low-1);
1759  }
1760  else
1761  nextOff = 0;
1762  TLegendEntry* e = l->AddEntry(Form("dummy%02d", i), txt, "pl");
1763  e->SetMarkerColor(GetCentralityColor(i));
1764  }
1765  l->Draw();
1766  }
1767  //__________________________________________________________________
1768  void AttachExec(TVirtualPad* p, const char* plot, UShort_t id,
1769  Bool_t isBottom)
1770  {
1771  if (!(fOptions & kAddExec)) return;
1772 
1773  if (isBottom) {
1774  fRangeParam->fMasterAxis = FindXAxis(p, plot);
1775  p->AddExec("range", Form("RangeExec((dNdetaDrawer::RangeParam*)%p)",
1776  fRangeParam));
1777  }
1778  else {
1779  if (id == 1) {
1780  fRangeParam->fSlave1Axis = FindXAxis(p, plot);
1781  fRangeParam->fSlave1Pad = p;
1782  }
1783  else if (id == 2) {
1784  fRangeParam->fSlave2Axis = FindXAxis(p, plot);
1785  fRangeParam->fSlave2Pad = p;
1786  }
1787  }
1788  }
1789  //__________________________________________________________________
1798  {
1799  // --- Make a sub-pad for the result itself ----------------------
1800  TPad* p1 = new TPad("p1", "p1", 0, yd, 1.0, 1.0, 0, 0, 0);
1801  p1->SetTopMargin(kRightMargin);
1802  p1->SetBorderSize(0);
1803  p1->SetBorderMode(0);
1804  p1->SetBottomMargin(yd > 0.001 ? 0.001 : 0.1);
1805  p1->SetRightMargin(kRightMargin);
1806  if ((fOptions & kShowLeftRight) || (fOptions & kShowRatios)) p1->SetGridx();
1807  p1->SetTicks(1,1);
1808  p1->SetNumber(1);
1809  p1->Draw();
1810  p1->cd();
1811 
1812  // --- Figure out min/max ----------------------------------------
1813  // Info("PlotResults", "Plotting results with max=%f", max);
1814  fResults->SetMaximum((fOptions & kExtraWhite ? 1.4 : 1.15)*max);
1815  fResults->SetMinimum(yd > 0.00001 ? -0.02*max : 0);
1816  // fResults->SetMinimum(yd > 0.00001 ? -0.02*max : 0);
1817 
1818  // --- Fix up axis -----------------------------------------------
1819  Double_t yyd = (1-yd)*(yd > .001 ? 1 : .9 / 1.2);
1820  FixAxis(fResults, yyd,
1821  "1/#it{N}#kern[.1]{d#it{N}_{ch}/d#it{#eta}}"
1822  //"#frac{1}{#it{N}}#kern[.1]{#frac{d#it{N}_{ch}}{d#it{#eta}}}"
1823  );
1824 
1825  // --- Fix up marker size ---------------------------------------
1826  TIter next(fResults->GetHists());
1827  TH1* h = 0;
1828  while ((h = static_cast<TH1*>(next())))
1829  h->SetMarkerSize(h->GetMarkerSize()*s);
1830  // --- Clear pad and re-draw ------------------------------------
1831  p1->Clear();
1832  fResults->DrawClone("nostack e1");
1833 
1834  // --- Draw other data -------------------------------------------
1835  if (fShowOthers != 0) {
1836  TGraphAsymmErrors* o = 0;
1837  TIter nextG(fOthers->GetListOfGraphs());
1838  while ((o = static_cast<TGraphAsymmErrors*>(nextG()))) {
1839  Double_t gS = s;
1840  switch (o->GetMarkerStyle()) {
1841  case 29:
1842  case 30: gS *= 1.2; break; // Star
1843  case 27:
1844  case 33: gS *= 1.2; break; // Diamond
1845  }
1846  o->SetMarkerSize(o->GetMarkerSize()*gS);
1847 
1848  o->DrawClone("same p");
1849  }
1850  }
1851 
1852  // --- Make a legend in the result pad ---------------------------
1853  Double_t x1 = p1->GetLeftMargin()+.08;
1854  Double_t x2 = 1-p1->GetRightMargin()-.08;
1855  Double_t y1 = p1->GetBottomMargin()+.01;
1856  Double_t y2 = .35;
1857  Int_t nC = 2;
1858  if (HasCent()) {
1859  if (fCentAxis->GetNbins() <= 4) {
1860  x1 = p1->GetLeftMargin()+.15;
1861  x2 = 1-p1->GetRightMargin()-.15;
1862  y2 = .2;
1863  }
1864  else {
1865  nC = 1;
1866  if (fOptions & kExtraWhite) {
1867  x1 = .40;
1868  x2 = .60;
1869  y1 = .70;
1870  y2 = 1-p1->GetTopMargin()-0.06;
1871  }
1872  else {
1873  x1 = .70;
1874  x2 = 1-p1->GetRightMargin()-.01;
1875  y1 = .50;
1876  y2 = 1-p1->GetTopMargin()-0.16;
1877  }
1878  }
1879  }
1880  BuildLegend(fResults, fOthers, x1, y1, x2, y2, nC);
1881 
1882  // --- Parameters for stuff on the right -------------------------
1883  Double_t yTop = 1-p1->GetTopMargin()-.02;
1884  Double_t xR = .95;
1885  Double_t yR = yTop;
1886 
1887  // --- Put a nice label in the plot ------------------------------
1888  TString eS;
1889  UShort_t snn = fSNNString->GetUniqueID();
1890  const char* sys = fSysString->GetTitle();
1891  if (snn == 2750) snn = 2760;
1892  if (snn < 1000) eS = Form("%3dGeV", snn);
1893  else if (snn % 1000 == 0) eS = Form("%dTeV", snn/1000);
1894  else eS = Form("%.2fTeV", float(snn)/1000);
1895  Bool_t nn = (fSysString->GetUniqueID() != 1);
1896  TString tS(fTrigString->GetTitle());
1897  if (HasCent()) {
1898  TString centMeth(fCentMeth ? fCentMeth->GetTitle() : "CENTV0M");
1899  if (centMeth.EqualTo("MULT"))
1900  tS = "by N_{#lower[-.2]{ch}} |#it{#eta}|<0.8";
1901  else
1902  tS = "by centrality";
1903  if (fCentMeth && fCentMeth->GetTitle()[0] != '\0')
1904  tS.Append(Form(" (%s)", fCentMeth->GetTitle()));
1905 #if 0
1906  UShort_t trg = fTrigString->GetUniqueID();
1907  switch (trg) {
1908  case 0x10: tS.Append(" (V0M)"); break;
1909  case 0x20: tS.Append(" (V0A)"); break;
1910  case 0x40: tS.Append(" (ZNA)"); break;
1911  case 0x80: tS.Append(" (ZNC)"); break;
1912  }
1913 #endif
1914  }
1915 
1916  TLatex* tt = new TLatex(xR, yR, Form("%s #sqrt{s%s}=%s, %s",
1917  sys, (nn ? "_{NN}" : ""),
1918  eS.Data(), tS.Data()));
1919  tt->SetTextColor(kAliceBlue);
1920  tt->SetNDC();
1921  tt->SetTextFont(kFont);
1922  tt->SetTextAlign(33);
1923  tt->Draw();
1924  yR -= tt->GetTextSize() + .01;
1925 
1926  if (fSysString->GetUniqueID() == 3) {
1927  // pPb - put arrow at y_CM
1928  UShort_t a1 = 1;
1929  UShort_t a2 = 208;
1930  UShort_t z1 = 1;
1931  UShort_t z2 = 82;
1932  Double_t yCM = .5 * TMath::Log(Float_t(z1*a2)/z2/a1);
1933  TArrow* a = new TArrow(yCM, 0, yCM, 0.05*max, 0.01, "<|");
1934  a->SetAngle(30);
1935  a->SetFillColor(kAliceBlue);
1936  a->SetLineColor(kAliceBlue);
1937  a->Draw();
1938  }
1939 
1940  // --- Put number of accepted events on the plot -----------------
1941  Int_t nev = 0;
1942  if (fTriggers) nev = fTriggers->GetBinContent(1);
1943  TLatex* et = new TLatex(xR, yR, Form("%d events", nev));
1944  et->SetTextColor(kAliceBlue);
1945  et->SetNDC();
1946  et->SetTextFont(kFont);
1947  et->SetTextAlign(33);
1948  et->Draw();
1949  yR -= et->GetTextSize() + .01;
1950 
1951  // --- Put vertex axis on the plot -------------------------------
1952  if (fVtxAxis) {
1953  TLatex* vt = new TLatex(xR, yR, fVtxAxis->GetTitle());
1954  vt->SetNDC();
1955  vt->SetTextFont(kFont);
1956  vt->SetTextAlign(33);
1957  vt->SetTextColor(kAliceBlue);
1958  vt->Draw();
1959  yR -= vt->GetTextSize() + .01;
1960  }
1961  // results->Draw("nostack e1 same");
1962 
1963  // --- Put statement on corrections used on the plot -------------
1964  TString corrs;
1965  if (!fEmpirical.IsNull()) corrs.Append("Emperical");
1966  if (fDelta > 0) {
1967  if (!corrs.IsNull()) corrs.Append("+");
1968  corrs.Append("IP_{xy}");
1969  }
1970  if (!fFinalMC.IsNull()) {
1971  if (!corrs.IsNull()) corrs.Append("+");
1972  corrs.Append("Final MC");
1973  }
1974 
1975  if (!corrs.IsNull()) {
1976  corrs.Append(" correction");
1977  if (corrs.Index("+") != kNPOS) corrs.Append("s");
1978  TLatex* em = new TLatex(xR, yR, corrs);
1979  em->SetNDC();
1980  em->SetTextFont(kFont);
1981  em->SetTextAlign(33);
1982  em->SetTextColor(kAliceBlue);
1983  em->Draw();
1984  yR -= em->GetTextSize() + .01;
1985  }
1986 
1987  // --- Put trigger efficiency on the plot (only pp and if != 1) --
1988  if (fTriggerEff > 0 && fTriggerEff < 1 && !HasCent()) {
1989  TLatex* ef = new TLatex(xR, yR, Form("#varepsilon_{%s} = %5.3f",
1990  fTrigString->GetTitle(),
1991  fTriggerEff));
1992  ef->SetNDC();
1993  ef->SetTextFont(kFont);
1994  ef->SetTextAlign(33);
1995  ef->SetTextColor(kAliceBlue);
1996  ef->Draw();
1997  yR -= ef->GetTextSize() + .01;
1998  }
1999 
2000  // --- Put logo on the plot --------------------------------------
2001  if (fOptions & kLogo) {
2002  TString savPath(gROOT->GetMacroPath());
2003  TString fwd("$(ALICE_PHYSICS)/PWGLF/FORWARD/analysis2");
2004  gROOT->SetMacroPath(Form("%s:%s/scripts",
2005  gROOT->GetMacroPath(), fwd.Data()));
2006  // Always recompile
2007  if (!gROOT->GetClass("AliceLogo"))
2008  gROOT->LoadMacro("AliceLogo.C+");
2009  gROOT->SetMacroPath(savPath);
2010 
2011  if (gROOT->GetClass("AliceLogo")) {
2012  yR -= .22;
2013  p1->cd();
2014  p1->Range(0,0,1,1);
2015  gROOT->ProcessLine("AliceLogo* al = new AliceLogo();");
2016  gROOT->ProcessLine(Form("al->Draw(0,.88,%f,.2, 0, 0);", yR));
2017  yR -= .01;
2018  }
2019  }
2020 
2021 
2022  // --- Parameter for stuff on the left ---------------------------
2023  Double_t yL = yTop;
2024  Double_t xL = .12;
2025 
2026  // --- Mark as work in progress ----------------------------------
2027  TLatex* pt = new TLatex(xL, yL, "Work in progress");
2028  pt->SetNDC();
2029  pt->SetTextFont(62);
2030  // pt->SetTextSize();
2031  pt->SetTextColor(kAliceRed);
2032  pt->SetTextAlign(13);
2033  pt->Draw();
2034  yL -= pt->GetTextSize()+.01;
2035 
2036  TDatime now;
2037  TLatex* dt = new TLatex(xL, yL, now.AsSQLString());
2038  dt->SetNDC();
2039  dt->SetTextFont(42);
2040  dt->SetTextSize(0.04);
2041  dt->SetTextColor(kAliceBlue); // kAliceRed);
2042  dt->SetTextAlign(13);
2043  dt->Draw();
2044  yL -= dt->GetTextSize()+.01;
2045 
2046  // --- Possible centrality legend --------------------------------
2047  if (fSysString->GetUniqueID() == 1) { xL += .2; yL = y1; }
2048  BuildCentLegend(xL, yL-.4, xL+.23, yL);
2049 
2050  // --- Attach Zoom executor --------------------------------------
2051  AttachExec(p1, fResults->GetName(), 1, false);
2052 
2053  // --- Possibly add title ----------------------------------------
2054  if (yd < 0.0001) PlotTitle(p1, yyd, true);
2055 
2056  p1->cd();
2057  }
2058  //__________________________________________________________________
2067  {
2068  if ((fOptions & kShowRatios) == 0) return;
2069 
2070  bool isBottom = (y1 < 0.0001);
2071  Double_t yd = y2 - y1;
2072 
2073  // --- Make a sub-pad for the ratios -----------------------------
2074  TPad* p2 = new TPad("p2", "p2", 0, y1, 1.0, y2, 0, 0, 0);
2075  p2->SetTopMargin(0.001);
2076  p2->SetRightMargin(kRightMargin);
2077  p2->SetBottomMargin(isBottom ? 1/yd * 0.07 : 0.0001);
2078  p2->SetGridx();
2079  p2->SetTicks(1,1);
2080  p2->SetNumber(2);
2081  p2->Draw();
2082  p2->cd();
2083 
2084  // --- Fix up axis -----------------------------------------------
2085  FixAxis(fRatios, yd, "Ratios", 7);
2086 
2087  // --- Set up min/max --------------------------------------------
2088  fRatios->SetMaximum(1+TMath::Max(.22,1.05*max));
2089  fRatios->SetMinimum(1-TMath::Max(.32,1.05*max));
2090 
2091  // --- Clear pad and draw ----------------------------------------
2092  p2->Clear();
2093  fRatios->DrawClone("nostack e1");
2094 
2095 
2096  // --- Make a legend ---------------------------------------------
2097  BuildLegend(fRatios, 0, .15,p2->GetBottomMargin()+.01,.9,
2098  isBottom ? .6 : .4, 2);
2099 
2100  // --- Make a nice band from 0.9 to 1.1 --------------------------
2101  TGraphErrors* band = new TGraphErrors(2);
2102  band->SetPoint(0, fResults->GetXaxis()->GetXmin(), 1);
2103  band->SetPoint(1, fResults->GetXaxis()->GetXmax(), 1);
2104  band->SetPointError(0, 0, (fFwdSysErr > 0 ? fFwdSysErr : .1));
2105  band->SetPointError(1, 0, (fFwdSysErr > 0 ? fFwdSysErr : .1));
2106  band->SetFillColor(kYellow+2);
2107  band->SetFillStyle(3002);
2108  band->SetLineStyle(2);
2109  band->SetLineWidth(1);
2110  band->Draw("3 same");
2111  band->DrawClone("X L same");
2112 
2113  // --- Replot the ratios on top ----------------------------------
2114  fRatios->DrawClone("nostack e1 same");
2115 
2116  // --- Some more stuff -------------------------------------------
2117  AttachExec(p2, fRatios->GetName(), 2, isBottom);
2118  if (isBottom) PlotTitle(p2, yd, true);
2119  }
2120  //__________________________________________________________________
2129  {
2130  if (!(fOptions & kShowLeftRight)) return;
2131 
2132  bool isBottom = (y1 < 0.0001);
2133  Double_t yd = y2 - y1;
2134  // --- Make a sub-pad for the asymmetry --------------------------
2135  TPad* p3 = new TPad("p3", "p3", 0, y1, 1.0, y2, 0, 0, 0);
2136  p3->SetTopMargin(0.001);
2137  p3->SetRightMargin(kRightMargin);
2138  p3->SetBottomMargin(isBottom ? 1/yd * 0.07 : 0.0001);
2139  p3->SetGridx();
2140  p3->SetTicks(1,1);
2141  p3->SetNumber(2);
2142  p3->Draw();
2143  p3->cd();
2144 
2145  // --- Fix up axis -----------------------------------------------
2146  FixAxis(fLeftRight, yd, "Right/Left", 4);
2147 
2148  // ---- Setup min/max --------------------------------------------
2149  fLeftRight->SetMaximum(1+TMath::Max(.12,1.05*max));
2150  fLeftRight->SetMinimum(1-TMath::Max(.15,1.05*max));
2151 
2152  // --- Clear pad and redraw --------------------------------------
2153  p3->Clear();
2154  fLeftRight->DrawClone("nostack e1");
2155 
2156 
2157  // --- Make a legend ---------------------------------------------
2158  Double_t xx1 = (HasCent() ? .7 : .15);
2159  Double_t xx2 = (HasCent() ? 1-p3->GetRightMargin()-.01 : .90);
2160  Double_t yy1 = p3->GetBottomMargin()+.01;
2161  Double_t yy2 = (HasCent() ? 1-p3->GetTopMargin()-.01-.15 : .5);
2162  BuildLegend(fLeftRight, 0, xx1, yy1, xx2, yy2);
2163 
2164  // --- Make a nice band from 0.9 to 1.1 --------------------------
2165  TGraphErrors* band = new TGraphErrors(2);
2166  band->SetPoint(0, fResults->GetXaxis()->GetXmin(), 1);
2167  band->SetPoint(1, fResults->GetXaxis()->GetXmax(), 1);
2168  band->SetPointError(0, 0, (fFwdSysErr > 0 ? fFwdSysErr : .05));
2169  band->SetPointError(1, 0, (fFwdSysErr > 0 ? fFwdSysErr : .05));
2170  band->SetFillColor(kYellow+2);
2171  band->SetFillStyle(3002);
2172  band->SetLineStyle(2);
2173  band->SetLineWidth(1);
2174  band->Draw("3 same");
2175  band->DrawClone("X L same");
2176 
2177  // --- Re-draw over ----------------------------------------------
2178  fLeftRight->DrawClone("nostack e1 same");
2179 
2180  // --- Misc stuff ------------------------------------------------
2181  AttachExec(p3, fLeftRight->GetName(), 2, isBottom);
2182  if (isBottom) PlotTitle(p3, yd, true);
2183  }
2185  //==================================================================
2190  Color_t Brighten(Color_t origNum, Int_t nTimes=2) const
2191  {
2192  TColor* col = gROOT->GetColor(origNum);
2193  if (!col) return origNum;
2194  Int_t origR = Int_t(0xFF * col->GetRed());
2195  Int_t origG = Int_t(0xFF * col->GetGreen());
2196  Int_t origB = Int_t(0xFF * col->GetBlue());
2197  // TColor::Pixel2RGB(TColor::Number2Pixel(origNum), origR, origG, origB);
2198  Int_t off = nTimes*0x33;
2199  Int_t newR = TMath::Min((origR+off),0xff);
2200  Int_t newG = TMath::Min((origG+off),0xff);
2201  Int_t newB = TMath::Min((origB+off),0xff);
2202  Int_t newNum = TColor::GetColor(newR, newG, newB);
2203  return newNum;
2204  }
2205  //__________________________________________________________________
2214  {
2215  if (fCentAxis->GetNbins() < 6) {
2216  switch (bin) {
2217  case 1: return kRed+2;
2218  case 2: return kGreen+2;
2219  case 3: return kBlue+1;
2220  case 4: return kCyan+1;
2221  case 5: return kMagenta+1;
2222  case 6: return kYellow+2;
2223  }
2224  }
2225  // Double_t centLow = fCentAxis->GetBinLowEdge(bin);
2226  Double_t max = fCentAxis->GetXmax();
2227  Double_t min = fCentAxis->GetXmin();
2228  Double_t centHigh = fCentAxis->GetBinUpEdge(bin);
2229  Double_t centLow = fCentAxis->GetBinUpEdge(bin);
2230  Float_t fc = ((centHigh+centLow)/2-min) / (max-min);
2231  Int_t nCol = gStyle->GetNumberOfColors();
2232  Int_t icol = TMath::Min(nCol-1,int(fc * nCol + .5));
2233  Int_t col = gStyle->GetColorPalette(icol);
2234  //Info("GetCentralityColor","%3d: %3d-%3d -> %3d",bin,centLow,centHigh,col);
2235  return col;
2236  // return Brighten(col);
2237  }
2238  //__________________________________________________________________
2246  {
2247  if (!h) return;
2248  if (color < 0) return;
2249  h->SetLineColor(color);
2250  h->SetMarkerColor(color);
2251  // h->SetFillColor(color);
2252  }
2253  //__________________________________________________________________
2261  {
2262  if (!g) return;
2263  if (color < 0) return;
2264  // g->SetLineColor(color);
2265  g->SetMarkerColor(color);
2266  // g->SetFillColor(color);
2267  }
2268  //__________________________________________________________________
2273  void ModifyTitle(TNamed* h, const char* centTxt)
2274  {
2275  if (!h) return;
2276 
2277  TString title(h->GetTitle());
2278  title.ReplaceAll("ALICE ","");
2279  if (title.Contains("Central"))
2280  title.ReplaceAll("CentraldNdeta", "SPD clusters");
2281  if (title.Contains("Forward"))
2282  title.ReplaceAll("ForwarddNdeta", "FMD");
2283  h->SetTitle(title);
2284 
2285  if (centTxt && centTxt[0] != '\0') {
2286  TString name(h->GetName());
2287  name.Append(Form("_%s", centTxt));
2288  h->SetName(name);
2289  }
2290 
2291  return;
2292  // if (!centTxt || !h) return;
2293  // h->SetTitle(Form("%s, %s", h->GetTitle(), centTxt));
2294  }
2303  TH1* FetchHistogram(const TList* list, const char* name) const
2304  {
2305  if (!list) return 0;
2306 
2307  TH1* ret = static_cast<TH1*>(list->FindObject(name));
2308 #if 0
2309  if (!ret) {
2310  // all->ls();
2311  Warning("GetResult", "Histogram %s not found", name);
2312  }
2313 #endif
2314 
2315  return ret;
2316  }
2317  //__________________________________________________________________
2327  Double_t AddHistogram(THStack* stack, TH1* hist, Option_t* option="") const
2328  {
2329  // Check if we have input
2330  if (!hist) return 0;
2331 
2332  // Rebin if needed
2333  Rebin(hist);
2334 
2335  stack->Add(hist, option);
2336  return hist->GetMaximum();
2337  }
2338  //__________________________________________________________________
2349  Double_t AddHistogram(THStack* stack, TH1* hist, TH1*& sym,
2350  Option_t* option="") const
2351  {
2352  // Check if we have input
2353  if (!hist) return 0;
2354 
2355  // Rebin if needed
2356  Rebin(hist);
2357  stack->Add(hist, option);
2358 
2359  // Now symmetrice the histogram
2360  if ((fOptions & kMirror)) {
2361  sym = Symmetrice(hist);
2362  stack->Add(sym, option);
2363  }
2364 
2365  return hist->GetMaximum();
2366  }
2367 
2368  //__________________________________________________________________
2374  virtual void Rebin(TH1* h) const
2375  {
2376  if (fRebin <= 1) return;
2377 
2378  Int_t nBins = h->GetNbinsX();
2379  if(nBins % fRebin != 0) {
2380  Warning("Rebin", "Rebin factor %d is not a devisor of current number "
2381  "of bins %d in the histogram %s", fRebin, nBins, h->GetName());
2382  return;
2383  }
2384 
2385  // Make a copy
2386  TH1* tmp = static_cast<TH1*>(h->Clone("tmp"));
2387  tmp->Rebin(fRebin);
2388  tmp->SetDirectory(0);
2389  tmp->Reset();
2390  // The new number of bins
2391  Int_t nBinsNew = nBins / fRebin;
2392  for(Int_t i = 1;i<= nBinsNew; i++) {
2393  Double_t content = 0;
2394  Double_t sumw = 0;
2395  Double_t wsum = 0;
2396  Int_t nbins = 0;
2397  for(Int_t j = 1; j<=fRebin;j++) {
2398  Int_t bin = (i-1)*fRebin + j;
2399  Double_t c = h->GetBinContent(bin);
2400 
2401  if (c <= 0) continue;
2402 
2403  if ((fOptions & kCutEdges)) {
2404  if (h->GetBinContent(bin+1)<=0 ||
2405  h->GetBinContent(bin-1)<=0) {
2406  Warning("Rebin", "removing bin %d=%f of %s (%d=%f,%d=%f)",
2407  bin, c, h->GetName(),
2408  bin+1, h->GetBinContent(bin+1),
2409  bin-1, h->GetBinContent(bin-1));
2410  continue;
2411  }
2412  }
2413  Double_t e = h->GetBinError(bin);
2414  Double_t w = 1 / (e*e); // 1/c/c
2415  content += c;
2416  sumw += w;
2417  wsum += w * c;
2418  nbins++;
2419  }
2420 
2421  if(content > 0 && nbins > 1 ) {
2422  tmp->SetBinContent(i, wsum / sumw);
2423  tmp->SetBinError(i,1./TMath::Sqrt(sumw));
2424  }
2425  }
2426 
2427  // Finally, rebin the histogram, and set new content
2428  h->Rebin(fRebin);
2429  h->Reset();
2430  for(Int_t i = 1; i<= nBinsNew; i++) {
2431  h->SetBinContent(i,tmp->GetBinContent(i));
2432  h->SetBinError(i, tmp->GetBinError(i));
2433  }
2434 
2435  delete tmp;
2436  }
2437  //__________________________________________________________________
2445  TH1* Symmetrice(const TH1* h) const
2446  {
2447  if (!h) return 0;
2448  Int_t nBins = h->GetNbinsX();
2449  TH1* s = static_cast<TH1*>(h->Clone(Form("%s_mirror", h->GetName())));
2450  s->SetTitle(Form("%s (mirrored)", h->GetTitle()));
2451  s->Reset();
2452  s->SetBins(nBins, -h->GetXaxis()->GetXmax(), -h->GetXaxis()->GetXmin());
2453  s->SetMarkerColor(h->GetMarkerColor());
2454  s->SetMarkerSize(h->GetMarkerSize());
2455  s->SetMarkerStyle(h->GetMarkerStyle()+4);
2456  s->SetFillColor(h->GetFillColor());
2457  s->SetFillStyle(h->GetFillStyle());
2458  s->SetDirectory(0);
2459 
2460  // Find the first and last bin with data
2461  Int_t first = nBins+1;
2462  Int_t last = 0;
2463  for (Int_t i = 1; i <= nBins; i++) {
2464  if (h->GetBinContent(i) <= 0) continue;
2465  first = TMath::Min(first, i);
2466  last = TMath::Max(last, i);
2467  }
2468 
2469  Double_t xfirst = h->GetBinCenter(first-1);
2470  Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
2471  Int_t l2 = s->GetXaxis()->FindBin(xfirst);
2472  for (Int_t i = f1, j=l2; i <= last; i++,j--) {
2473  s->SetBinContent(j, h->GetBinContent(i));
2474  s->SetBinError(j, h->GetBinError(i));
2475  }
2476  // Fill in overlap bin
2477  s->SetBinContent(l2+1, h->GetBinContent(first));
2478  s->SetBinError(l2+1, h->GetBinError(first));
2479  return s;
2480  }
2481  //__________________________________________________________________
2491  {
2492  if (!h) return 0;
2493 
2494  TH1* ret = static_cast<TH1*>(h->Clone(Form("%s_leftright", h->GetName())));
2495  // Int_t oBins = h->GetNbinsX();
2496  // Double_t high = h->GetXaxis()->GetXmax();
2497  // Double_t low = h->GetXaxis()->GetXmin();
2498  // Double_t dBin = (high - low) / oBins;
2499  // Int_t tBins = Int_t(2*high/dBin+.5);
2500  // ret->SetBins(tBins, -high, high);
2501  ret->SetDirectory(0);
2502  ret->Reset();
2503  ret->SetTitle(Form("%s (+/-)", h->GetTitle()));
2504  ret->SetYTitle("Right/Left");
2505  Int_t nBins = h->GetNbinsX();
2506  for (Int_t i = 1; i <= nBins; i++) {
2507  Double_t x = h->GetBinCenter(i);
2508  if (x > 0) break;
2509 
2510  Double_t c1 = h->GetBinContent(i);
2511  Double_t e1 = h->GetBinError(i);
2512  if (c1 <= 0) continue;
2513 
2514  Int_t j = h->FindBin(-x);
2515  if (j <= 0 || j > nBins) continue;
2516 
2517  Double_t c2 = h->GetBinContent(j);
2518  Double_t e2 = h->GetBinError(j);
2519 
2520  Double_t c12 = c1*c1;
2521  Double_t e = TMath::Sqrt((e2*e2*c1*c1+e1*e1*c2*c2)/(c12*c12));
2522 
2523  Int_t k = ret->FindBin(x);
2524  ret->SetBinContent(k, c2/c1);
2525  ret->SetBinError(k, e);
2526  }
2527  max = TMath::Max(max, RatioMax(ret));
2528 
2529  return ret;
2530  }
2531  //__________________________________________________________________
2540  {
2541  Int_t nBins = g->GetN();
2542  TArrayF bins(nBins+1);
2543  Double_t dx = 0;
2544  for (Int_t i = 0; i < nBins; i++) {
2545  Double_t x = g->GetX()[i];
2546  Double_t exl = g->GetEXlow()[i];
2547  Double_t exh = g->GetEXhigh()[i];
2548  bins.fArray[i] = x-exl;
2549  bins.fArray[i+1] = x+exh;
2550  Double_t dxi = exh+exl;
2551  if (i == 0) dx = dxi;
2552  else if (dxi != dx) dx = 0;
2553  }
2554  TString name(g->GetName());
2555  TString title(g->GetTitle());
2556  TH1D* h = 0;
2557  if (dx != 0) {
2558  h = new TH1D(name.Data(), title.Data(), nBins, bins[0], bins[nBins]);
2559  }
2560  else {
2561  h = new TH1D(name.Data(), title.Data(), nBins, bins.fArray);
2562  }
2563  h->SetMarkerStyle(g->GetMarkerStyle());
2564  h->SetMarkerColor(g->GetMarkerColor());
2565  h->SetMarkerSize(g->GetMarkerSize());
2566 
2567  return h;
2568  }
2569  /* @} */
2570  //==================================================================
2583  {
2584  Int_t nBins = h->GetNbinsX();
2585  Double_t ret = 0;
2586  for (Int_t i = 1; i <= nBins; i++) {
2587  Double_t c = h->GetBinContent(i);
2588  if (c == 0) continue;
2589  Double_t e = h->GetBinError(i);
2590  Double_t d = TMath::Abs(1-c-e);
2591  ret = TMath::Max(d, ret);
2592  }
2593  return ret;
2594  }
2602  static void ErrorGraphs(const TGraph* g, TGraph*& low, TGraph*& up)
2603  {
2604  Warning("ErrorGraphs", "Called with vanila TGraph (%s)",
2605  g->IsA()->GetName());
2606  Int_t n = g->GetN();
2607  low = new TGraph(n);
2608  up = new TGraph(n);
2609  for (Int_t i = 0; i < n; i++) {
2610  low->SetPoint(i, 0, 0);
2611  up->SetPoint(i, 0, 0);
2612  }
2613  }
2617  static void ErrorGraphs(const TGraphErrors* g, TGraph*& low, TGraph*& up)
2618  {
2619  // Info("ErrorGraphs", "Called with TGraphErrors");
2620  Int_t n = g->GetN();
2621  low = new TGraph(n);
2622  up = new TGraph(n);
2623  for (Int_t i = 0; i < n; i++) {
2624  low->SetPoint(i, g->GetX()[i], g->GetY()[i] - g->GetEY()[i]);
2625  up->SetPoint(i, g->GetX()[i], g->GetY()[i] + g->GetEY()[i]);
2626  }
2627  }
2631  static void ErrorGraphs(const TGraphAsymmErrors* g, TGraph*& low, TGraph*& up)
2632  {
2633  // Info("ErrorGraphs", "Called with TGraphAsymmErrors");
2634  Int_t n = g->GetN();
2635  low = new TGraph(n);
2636  up = new TGraph(n);
2637  for (Int_t i = 0; i < n; i++) {
2638  low->SetPoint(i, g->GetX()[i], g->GetY()[i] - g->GetEYlow()[i]);
2639  up->SetPoint(i, g->GetX()[i], g->GetY()[i] + g->GetEYhigh()[i]);
2640  }
2641  }
2642 
2643  //__________________________________________________________________
2653  TH1* Ratio(const TObject* o1, const TObject* o2, Double_t& max) const
2654  {
2655  if (!o1 || !o2) return 0;
2656 
2657  bool mirror = false;
2658  TString n1(o1->GetName());
2659  if (n1.Contains("mirror")) mirror = true;
2660 
2661  TH1* r = 0;
2662  const TAttMarker* m1 = 0;
2663  const TAttMarker* m2 = 0;
2664  const TH1* h1 = dynamic_cast<const TH1*>(o1);
2665  if (h1) {
2666  m1 = h1;
2667  const TH1* h2 = dynamic_cast<const TH1*>(o2);
2668  if (h2) {
2669  m2 = h2;
2670  r = RatioHH(h1,h2);
2671  }
2672  else {
2673  const TGraph* g2 = dynamic_cast<const TGraph*>(o2);
2674  if (g2) {
2675  m2 = g2;
2676  r = RatioHG(h1,g2);
2677  }
2678  }
2679  }
2680  else {
2681  const TGraphAsymmErrors* g1 = dynamic_cast<const TGraphAsymmErrors*>(o1);
2682  if (g1) {
2683  m1 = g1;
2684  const TGraphAsymmErrors* g2 =
2685  dynamic_cast<const TGraphAsymmErrors*>(o2);
2686  if (g2) {
2687  m2 = g2;
2688  r = RatioGG(g1, g2);
2689  }
2690  }
2691  }
2692  if (!r) {
2693  // Warning("Ratio", "Don't know how to divide a %s (%s) with a %s (%s)",
2694  // o1->ClassName(),o1->GetName(),o2->ClassName(),o2->GetName());
2695  return 0;
2696  }
2697  // Check that the histogram isn't empty
2698  if (r->GetEntries() <= 0) {
2699  delete r;
2700  r = 0;
2701  }
2702  if (r) {
2703  UShort_t m2bits = MarkerUtil::GetMarkerBits(m2->GetMarkerStyle());
2704  if (mirror) m2bits |= MarkerUtil::kHollow;
2705  else m2bits &= ~MarkerUtil::kHollow;
2706  r->SetMarkerStyle(MarkerUtil::GetMarkerStyle(m2bits));
2707  r->SetMarkerColor(m1->GetMarkerColor());
2708  if (TString(o2->GetName()).Contains("truth", TString::kIgnoreCase))
2709  r->SetMarkerStyle(m1->GetMarkerStyle());
2710  r->SetMarkerSize(0.9*m1->GetMarkerSize());
2711  r->SetName(Form("%s_over_%s", o1->GetName(), o2->GetName()));
2712  r->SetTitle(Form("%s / %s", o1->GetTitle(), o2->GetTitle()));
2713  r->SetDirectory(0);
2714  max = TMath::Max(RatioMax(r), max);
2715  }
2716 
2717  return r;
2718  }
2719  //__________________________________________________________________
2729  TH1* RatioHG(const TH1* h, const TGraph* g) const
2730  {
2731  if (!h || !g) return 0;
2732 
2733  TH1* ret = static_cast<TH1*>(h->Clone("tmp"));
2734  ret->Reset();
2735  Int_t n = g->GetN();
2736  Double_t xlow = g->GetX()[0];
2737  Double_t xhigh = g->GetX()[n-1];
2738  TGraph* glow = 0;
2739  TGraph* ghigh = 0;
2740  if (g->IsA()->InheritsFrom(TGraphErrors::Class())) {
2741  const TGraphErrors* ge = static_cast<const TGraphErrors*>(g);
2742  xlow -= ge->GetErrorXlow(0);
2743  xhigh += ge->GetErrorXhigh(n-1);
2744  ErrorGraphs(ge, glow, ghigh);
2745  }
2746  if (g->IsA()->InheritsFrom(TGraphAsymmErrors::Class())) {
2747  const TGraphAsymmErrors* ge = static_cast<const TGraphAsymmErrors*>(g);
2748  xlow -= ge->GetErrorXlow(0);
2749  xhigh += ge->GetErrorXhigh(n-1);
2750  ErrorGraphs(ge, glow, ghigh);
2751  }
2752  if (xlow > xhigh) { Double_t t = xhigh; xhigh = xlow; xlow = t; }
2753 
2754  for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
2755  Double_t c = h->GetBinContent(i);
2756  if (c <= 0) continue;
2757 
2758  Double_t x = h->GetBinCenter(i);
2759  if (x < xlow || x > xhigh) continue;
2760 
2761  Double_t f = g->Eval(x);
2762  if (f <= 0) continue;
2763 
2764  Double_t efl = f - glow->Eval(x);
2765  Double_t efh = ghigh->Eval(x) - f;
2766  Double_t ec = h->GetBinError(i);
2767  Double_t e = TMath::Max(ec, TMath::Max(efl, efh));
2768 
2769  ret->SetBinContent(i, c / f);
2770  ret->SetBinError(i, e / f);
2771  }
2772  return ret;
2773  }
2774  //__________________________________________________________________
2783  TH1* RatioHH(const TH1* h1, const TH1* h2) const
2784  {
2785  if (!h1 || !h2) return 0;
2786  Bool_t bad = false;
2787  if (h1->GetNbinsX() != h2->GetNbinsX()) {
2788  Error("RatioHH", "They have differnet number of bins");
2789  bad = true;
2790  }
2791  for (Int_t i = 1; i <= h1->GetNbinsX(); i++) {
2792  if (h1->GetXaxis()->GetBinLowEdge(i) !=
2793  h2->GetXaxis()->GetBinLowEdge(i)) {
2794  // Error("RatioHH", "They have incompatible variable bins");
2795  bad = true;
2796  break;
2797  }
2798  }
2799  if (bad) return 0;
2800 
2801  TH1* t1 = static_cast<TH1*>(h1->Clone("tmp"));
2802  // Printf("Dividing %s with %s", h1->GetName(), h2->GetName());
2803  t1->Divide(h2);
2804  return t1;
2805  }
2806  //__________________________________________________________________
2816  const TGraphAsymmErrors* g2) const
2817  {
2818  Int_t nBins = g1->GetN();
2819  TArrayF bins(nBins+1);
2820  Double_t dx = 0;
2821  for (Int_t i = 0; i < nBins; i++) {
2822  Double_t x = g1->GetX()[i];
2823  Double_t exl = g1->GetEXlow()[i];
2824  Double_t exh = g1->GetEXhigh()[i];
2825  bins.fArray[i] = x-exl;
2826  bins.fArray[i+1] = x+exh;
2827  Double_t dxi = exh+exl;
2828  if (i == 0) dx = dxi;
2829  else if (dxi != dx) dx = 0;
2830  }
2831  TH1* h = 0;
2832  if (dx != 0) {
2833  h = new TH1F("tmp", "tmp", nBins, bins[0], bins[nBins]);
2834  }
2835  else {
2836  h = new TH1F("tmp", "tmp", nBins, bins.fArray);
2837  }
2838 
2839  Double_t low = g2->GetX()[0];
2840  Double_t high = g2->GetX()[g2->GetN()-1];
2841  if (low > high) { Double_t t = low; low = high; high = t; }
2842  for (Int_t i = 0; i < nBins; i++) {
2843  Double_t x = g1->GetX()[i];
2844  if (x < low-dx || x > high+dx) continue;
2845  Double_t c1 = g1->GetY()[i];
2846  Double_t e1 = g1->GetErrorY(i);
2847  Double_t c2 = g2->Eval(x);
2848 
2849  h->SetBinContent(i+1, c1 / c2);
2850  h->SetBinError(i+1, e1 / c2);
2851  }
2852  return h;
2853  }
2854  /* @} */
2855  //==================================================================
2868  TAxis* FindXAxis(TVirtualPad* p, const char* name)
2869  {
2870  TObject* o = p->GetListOfPrimitives()->FindObject(name);
2871  if (!o) {
2872  Warning("FindXAxis", "%s not found in pad", name);
2873  return 0;
2874  }
2875  THStack* stack = dynamic_cast<THStack*>(o);
2876  if (!stack) {
2877  Warning("FindXAxis", "%s is not a THStack", name);
2878  return 0;
2879  }
2880  if (!stack->GetHistogram()) {
2881  Warning("FindXAxis", "%s has no histogram", name);
2882  return 0;
2883  }
2884  TAxis* ret = stack->GetHistogram()->GetXaxis();
2885  return ret;
2886  }
2887 
2888  //__________________________________________________________________
2898  void FixAxis(THStack* stack, Double_t yd, const char* ytitle,
2899  Int_t ynDiv=210, Bool_t force=true)
2900  {
2901  if (!stack) {
2902  Warning("FixAxis", "No stack passed for %s!", ytitle);
2903  return;
2904  }
2905  Bool_t supLabel = (fResults == stack && ((fOptions & kNoLabels)));
2906  if (force) stack->Draw("nostack e1");
2907 
2908  TH1* h = stack->GetHistogram();
2909  if (!h) {
2910  Warning("FixAxis", "Stack %s has no histogram", stack->GetName());
2911  return;
2912  }
2913  Double_t s = 1/yd/1.2;
2914  // Info("FixAxis", "for %s, s=1/%f=%f", stack->GetName(), yd, s);
2915 
2916  h->SetXTitle("#it{#eta}");
2917  h->SetYTitle(ytitle);
2918  TAxis* xa = h->GetXaxis();
2919  TAxis* ya = h->GetYaxis();
2920 
2921  // Int_t npixels = 20
2922  // Float_t dy = gPad->AbsPixeltoY(0) - gPad->AbsPixeltoY(npixels);
2923  // Float_t ts = dy/(gPad->GetY2() - gPad->GetY1());
2924 
2925  if (xa) {
2926  // xa->SetTitle(h->GetXTitle());
2927  // xa->SetTicks("+-");
2928  xa->SetTitleSize(s*xa->GetTitleSize());
2929  xa->SetLabelSize(s*xa->GetLabelSize());
2930  xa->SetTickLength(s*xa->GetTickLength());
2931  // xa->SetTitleOffset(xa->GetTitleOffset()/s);
2932 
2933  if (stack != fResults) {
2934  TAxis* rxa = fResults->GetXaxis();
2935  xa->Set(rxa->GetNbins(), rxa->GetXmin(), rxa->GetXmax());
2936  }
2937  }
2938  if (ya) {
2939  // ya->SetTitle(h->GetYTitle());
2940  ya->SetDecimals();
2941  // ya->SetTicks("+-");
2942  ya->SetNdivisions(ynDiv);
2943  ya->SetTitleSize(s*ya->GetTitleSize());
2944  ya->SetTitleOffset(/*1.15*/1.4*ya->GetTitleOffset()/s);
2945  ya->SetLabelSize(supLabel ? 0 : s*ya->GetLabelSize());
2946  }
2947  }
2948  //__________________________________________________________________
2959  TH1*
2960  Merge(const TH1* cen, const TH1* fwd, Double_t& xlow, Double_t& xhigh)
2961  {
2962  if (!fwd) return 0;
2963  TH1* tmp = static_cast<TH1*>(fwd->Clone("tmp"));
2964  TString name(fwd->GetName());
2965  name.ReplaceAll("Forward", "Merged");
2966  tmp->SetName(name);
2967 
2968  // tmp->SetMarkerStyle(28);
2969  // tmp->SetMarkerColor(kBlack);
2970  tmp->SetDirectory(0);
2971  if (!cen) return tmp;
2972 
2973  xlow = 100;
2974  xhigh = -100;
2975  for (Int_t i = 1; i <= tmp->GetNbinsX(); i++) {
2976  Double_t cc = cen->GetBinContent(i);
2977  Double_t cf = fwd->GetBinContent(i);
2978  Double_t ec = cen->GetBinError(i);
2979  Double_t ef = fwd->GetBinError(i);
2980  Double_t nc = cf;
2981  Double_t ne = ef;
2982  if (cc < 0.001 && cf < 0.01) continue;
2983  xlow = TMath::Min(tmp->GetXaxis()->GetBinLowEdge(i),xlow);
2984  xhigh = TMath::Max(tmp->GetXaxis()->GetBinUpEdge(i),xhigh);
2985  if (cc > 0.001) {
2986  nc = cc;
2987  ne = ec;
2988  if (cf > 0.001) {
2989  nc = (cf + cc) / 2;
2990  ne = TMath::Sqrt(ec*ec + ef*ef);
2991  }
2992  }
2993  tmp->SetBinContent(i, nc);
2994  tmp->SetBinError(i, ne);
2995  }
2996  return tmp;
2997  }
2998  //____________________________________________________________________
3008  TF1*
3009  FitMerged(TH1* tmp, Double_t xlow, Double_t xhigh)
3010  {
3011  if (!tmp) return 0;
3012  TF1* tmpf = new TF1("tmpf", "gaus", xlow, xhigh);
3013  tmp->Fit(tmpf, "NQ", "");
3014  tmp->SetDirectory(0);
3015 
3016  TF1* fit = new TF1("f", myFunc, xlow, xhigh, 4);
3017  fit->SetParNames("a_{1}", "a_{2}", "#sigma_{1}", "#sigma_{2}");
3018  fit->SetParameters(tmpf->GetParameter(0),
3019  .2,
3020  tmpf->GetParameter(2),
3021  tmpf->GetParameter(2)/4);
3022  fit->SetParLimits(3, 0, 100);
3023  fit->SetParLimits(4, 0, 100);
3024  const char* fitOpts = (fOptions & kVerbose ? "0W" : "Q0W");
3025  tmp->Fit(fit,fitOpts,"");
3026 
3027  delete tmpf;
3028  return fit;
3029  }
3030  //____________________________________________________________________
3039  void
3040  MakeSysError(TH1* tmp, TH1* cen, TH1* fwd, TF1* fit)
3041  {
3042  if (!tmp || !fwd) return;
3043  for (Int_t i = 1; i <= tmp->GetNbinsX(); i++) {
3044  Double_t tc = tmp->GetBinContent(i);
3045  if (tc < 0.01) continue;
3046  Double_t fc = fwd->GetBinContent(i);
3047  Double_t cc = cen ? cen->GetBinContent(i) : 0;
3048  Double_t sysErr = fFwdSysErr;
3049  Double_t mc = fc;
3050  if (cc > .01 && fc > 0.01) {
3051  sysErr = (fFwdSysErr+fCenSysErr) / 2;
3052  mc = (fc+cc) / 2;
3053  }
3054  else if (cc > .01) {
3055  sysErr = fCenSysErr;
3056  mc = cc;
3057  }
3058  Double_t x = tmp->GetXaxis()->GetBinCenter(i);
3059  Double_t y = (fit ? fit->Eval(x) : mc);
3060  tmp->SetBinContent(i, y);
3061  tmp->SetBinError(i,sysErr*y);
3062  }
3063  TString name(tmp->GetName());
3064  name.ReplaceAll("Merged", "SysError");
3065  tmp->SetName(name);
3066  tmp->SetMarkerColor(kSysErrColor);
3067  tmp->SetLineColor(kSysErrColor);
3068  tmp->SetFillColor(kSysErrColor);
3069  tmp->SetFillStyle(SYSERR_STYLE);
3070  tmp->SetMarkerStyle(0);
3071  tmp->SetLineWidth(0);
3072  }
3073  void CorrectForward(TH1* h) const
3074  {
3075  if (!(fOptions & kRemoveOuters)) return;
3076 
3077  for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
3078  Double_t eta = h->GetBinCenter(i);
3079  if (TMath::Abs(eta) < 2.3) {
3080  h->SetBinContent(i, 0);
3081  h->SetBinError(i, 0);
3082  }
3083  }
3084  }
3085  void CorrectCentral(TH1* h) const
3086  {
3087  if (!h) return;
3088  if (fClusterScale.IsNull()) return;
3089  TString t(h->GetTitle());
3090  Info("CorrectCentral", "Replacing Central with Tracklets in %s", t.Data());
3091  t.ReplaceAll("Central", "Tracklets");
3092  h->SetTitle(t);
3093 
3094  TF1* cf = new TF1("clusterScale", fClusterScale);
3095  for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
3096  Double_t eta = h->GetBinCenter(i);
3097  Double_t f = cf->Eval(eta);
3098  Double_t c = h->GetBinContent(i);
3099  if (f < .1) f = 1;
3100  h->SetBinContent(i, c / f);
3101  }
3102  delete cf;
3103  }
3104  //____________________________________________________________________
3105  void Export(const char* basename)
3106  {
3107  TString bname(basename);
3108  bname.ReplaceAll(" ", "_");
3109  bname.ReplaceAll("-", "_");
3110  TString fname(Form("%s.C", bname.Data()));
3111 
3112  std::ofstream outf(fname.Data());
3113  if (!outf) {
3114  Error("Export", "Failed to open output file %s", fname.Data());
3115  return;
3116  }
3117  Info("Export", "Exporting data to %s", fname.Data());
3118  outf << "// Create by dNdetaDrawer\n"
3119  << "// Setting for this draw\n"
3120  << "//\n"
3121  << "// Draw(\"\",\"" << fTitle << "\"," << fRebin << ",0x"
3122  << std::hex << fShowOthers << ",0x" << fOptions << ","
3123  << std::dec << fSNNString->GetUniqueID() << ","
3124  << fSysString->GetUniqueID() << ","
3125  << std::hex << fTrigString->GetUniqueID() << ","
3126  << std::dec << fTriggerEff << "," << fCentMin << "," << fCentMax << ","
3127  << fVtxAxis->GetXmin() << "," << fVtxAxis->GetXmax() << ",\""
3128  << fBase << "\",0x" << std::hex << fFormats
3129  << std::dec << ");\n"
3130  << "//\n"
3131  << "void " << bname << "(THStack* stack, TLegend* l, Int_t m)\n"
3132  << "{"
3133  << " Int_t ma[] = { 24, 25, 26, 32,\n"
3134  << " 20, 21, 22, 33,\n"
3135  << " 34, 30, 29, 0, \n"
3136  << " 23, 27 };\n"
3137  << " Int_t mm = ((m < 20 || m > 34) ? 0 : ma[m-20]);\n\n";
3138  TList* hists = fResults->GetHists();
3139  TIter next(hists);
3140  TH1* hist = 0;
3141  while ((hist = static_cast<TH1*>(next()))) {
3142  TString hname = hist->GetName();
3143  hname.Append(Form("_%04x", (gRandom->Integer(0xffff) & 0xffff)));
3144  hist->SetName(hname);
3145  hist->GetListOfFunctions()->Clear();
3146  hist->SavePrimitive(outf, "nodraw");
3147  bool mirror = hname.Contains("mirror");
3148  bool syserr = hname.Contains("SysError");
3149  if (!syserr)
3150  outf << " " << hname << "->SetMarkerStyle("
3151  << (mirror ? "mm" : "m") << ");\n";
3152  else
3153  outf << " " << hname << "->SetMarkerStyle(1);\n";
3154  outf << " stack->Add(" << hname
3155  << (syserr ? ",\"e5\"" : "") << ");\n\n";
3156  }
3157  UShort_t snn = fSNNString->GetUniqueID();
3158  // const char* sys = fSysString->GetTitle();
3159  TString eS;
3160  if (snn == 2750) snn = 2760;
3161  if (snn < 1000) eS = Form("%3dGeV", snn);
3162  else if (snn % 1000 == 0) eS = Form("%dTeV", snn/1000);
3163  else eS = Form("%4.2fTeV", float(snn)/1000);
3164  outf << " if (l) {\n"
3165  << " TLegendEntry* e = l->AddEntry(\"\",\"" << eS << "\",\"pl\");\n"
3166  << " e->SetMarkerStyle(m);\n"
3167  << " e->SetMarkerColor(kBlack);\n"
3168  << " }\n"
3169  << "}\n" << std::endl;
3170 
3171  TString tgt(fRebin > 1 ? "rebin" : "full");
3172  TString clean(Form("sed -e 's/_[0-9a-f]\\{4\\}"
3173  "\\(\\|_\\{1,4\\}[0-9a-f]\\{1,4\\}\\)\\b//g'"
3174  " -e 's/%s/%s/g' < %s > %s.C",
3175  bname.Data(), tgt.Data(), fname.Data(), tgt.Data()));
3176  Printf("Execute \"%s\"", clean.Data());
3177  gSystem->Exec(clean);
3178  TString trg(fTrigString->GetTitle());
3179  TString mth;
3180  if (HasCent()) {
3181  trg = "CENT"; // Form("CENT%s", fCentMeth->GetTitle());
3182  mth = fCentMeth->GetTitle();
3183  }
3184  Printf("Copy %s.C to %s/%s/%05d/%s%s/%s.C",tgt.Data(),
3185  (fEmpirical.IsNull() ? "normal" : "nosec"),
3186  fSysString->GetTitle(), snn, trg.Data(), mth.Data(),
3187  tgt.Data());
3188 
3189  if (trg.EqualTo("INEL") || trg.EqualTo("MBOR")) trg = "INEL";
3190  else if (trg.EqualTo("INEL>0") || trg.EqualTo("INELGt0")) trg = "INELGt0";
3191  else if (trg.EqualTo("NSD") || trg.EqualTo("V0AND")) trg = "NSD";
3192 
3193 
3194  std::ofstream outs("gse.C");
3195  if (!outs) {
3196  Error("Export", "Failed to open output file %s", fname.Data());
3197  return;
3198  }
3199  outs << "// \n"
3200  << "TList* gse() {\n"
3201  << " TString mkLib = gSystem->GetMakeSharedLib();\n"
3202  << " mkLib.ReplaceAll(\"-std=c++14\", \"-std=c++98\");\n"
3203  << " gSystem->SetMakeSharedLib(mkLib);\n"
3204  << " TString gseDir(gSystem->ExpandPathName(\"~/GraphSysErr\"));\n"
3205  << " TString phyDir(gSystem->ExpandPathName(\"${ALICE_PHYSICS}\"));\n"
3206  << " gROOT->SetMacroPath(Form(\"%s:%s/PWGLF/FORWARD/analysis2/dndeta:%s\",gseDir.Data(),phyDir.Data(),gROOT->GetMacroPath()));\n"
3207  << " gSystem->AddIncludePath(Form(\"-I%s\",gseDir.Data()));\n"
3208  << " gROOT->LoadMacro(\"GraphSysErr.C+g\");\n"
3209  << " gROOT->LoadMacro(\"SysErrorAdder.C+g\");\n"
3210  << " TString t = \"" << trg << "\";\n"
3211  << " TString c = \"" << mth <<"\";\n"
3212  << " TString s = \"" << fSysString->GetTitle() << "\";\n"
3213  << " UShort_t e = " << snn << ";\n"
3214  << " TString m = \"" << tgt << ".C\";\n"
3215  << " TList* r = new TList;\n"
3216  << " THStack* l = new THStack(\"l\",\"l\");\n"
3217  << " gROOT->Macro(Form(\"%s((THStack*)%p,0,20)\",m.Data(),l));\n"
3218  << " SysErrorAdder* a = SysErrorAdder::Create(t,s,e,c);\n"
3219  << " TIter n(l->GetHists());\n"
3220  << " TH1* h = 0;\n"
3221  << " Bool_t f = true;\n"
3222  << " while ((h = static_cast<TH1*>(n()))) {\n"
3223  << " TString nme(h->GetName());\n"
3224  << " if (nme.Contains(\"mirror\")||nme.Contains(\"SysError\"))\n"
3225  << " continue;\n"
3226  << " h->SetMarkerColor(kBlack);\n"
3227  << " h->SetFillColor(kBlack);\n"
3228  << " h->SetLineColor(kBlack);\n"
3229  << " GraphSysErr* g = a->Make(h,0);\n"
3230  << " g->SetSumOption(GraphSysErr::kBox);\n"
3231  << " g->SetSumFillColor(g->GetMarkerColor());\n"
3232  << " g->SetSumFillStyle(3002);\n"
3233  << " g->SetCommonSumOption(GraphSysErr::kBox);\n"
3234  << " g->SetCommonSumFillColor(g->GetMarkerColor());\n"
3235  << " g->SetCommonSumFillStyle(3001);\n"
3236  << " if (f) g->Draw(\"SUM QUAD AXIS\");\n"
3237  << " else g->Draw(\"SUM QUAD\");\n"
3238  << " f = false;\n"
3239  << " r->Add(g);\n"
3240  << " }\n"
3241  << " TFile* file = TFile::Open(Form(\"%s_%05d_%s%s.root\",s.Data(),e,t.Data(),c.Data()),\"RECREATE\");\n"
3242  << " r->Write(\"container\",TObject::kSingleKey);\n"
3243  << " file->Write();\n"
3244  << " return r;\n"
3245  << "}\n"
3246  << "// EOF" << std::endl;
3247  outs.close();
3248  }
3249  /* @} */
3257  Bool_t HasCent() const
3258  {
3259  return (!(fOptions & kForceMB) &&
3260  fCentAxis &&
3261  (fCentAxis->GetNbins() > 1 ||
3262  (fCentAxis->GetNbins() == 1 &&
3263  fCentAxis->GetXmin() <= fCentAxis->GetXmax())));
3264  }
3265 
3266 
3267 
3268  //__________________________________________________________________
3273  UInt_t fOptions; // Options
3274  UInt_t fFormats; // Output formats
3275  UShort_t fShowOthers; // Show other data
3276  /* @} */
3281  UShort_t fRebin; // Rebinning factor
3282  Double_t fFwdSysErr; // Systematic error in forward range
3283  Double_t fCenSysErr; // Systematic error in central range
3284  TString fTitle; // Title on plot
3285  TString fBase; // Base name of output
3286  TString fClusterScale; // Scaling of clusters to tracklets
3287  TString fFinalMC; // Final MC correction file name
3288  TString fEmpirical; // Empirical correction file name
3289  Double_t fDelta; // IP_delta wrt to (0.005,0.184)
3290  /* @} */
3295  TNamed* fTrigString; // Trigger string (read, or set)
3296  TNamed* fNormString; // Normalisation string (read, or set)
3297  TNamed* fSNNString; // Energy string (read, or set)
3298  TNamed* fSysString; // Collision system string (read or set)
3299  TAxis* fVtxAxis; // Vertex cuts (read or set)
3300  TAxis* fCentAxis; // Centrality axis
3301  TObject* fCentMeth; // Centrality method
3302  Float_t fTriggerEff; // Trigger efficiency
3303  Bool_t fExtTriggerEff;// True if read externally
3304  UShort_t fCentMin; // Least centrality to plot
3305  UShort_t fCentMax; // Largest centrality to plot
3306  UInt_t fCentSeen; // List of seen centralities
3307  /* @} */
3312  THStack* fResults; // Stack of results
3313  THStack* fRatios; // Stack of ratios
3314  THStack* fLeftRight; // Left-right asymmetry
3315  TMultiGraph* fOthers; // Older data
3316  TH1* fTriggers; // Number of triggers
3317  TH1* fTruth; // Pointer to truth
3318  /* @} */
3319  RangeParam* fRangeParam; // Parameter object for range zoom
3320  TObject* fEmpCorr; // Empirical correction
3321 
3322  static const Float_t kRightMargin;
3323  static const Int_t kFont;
3324  static const Int_t kAliceBlue;
3325  static const Int_t kAliceRed;
3326  static const Int_t kAlicePurple;
3327  static const Int_t kAliceYellow;
3328  static const Int_t kSysErrColor;
3329 };
3330 
3331 const Float_t dNdetaDrawer::kRightMargin = 0.01;
3332 const Int_t dNdetaDrawer::kFont = 42; // 132 for serif
3333 const Int_t dNdetaDrawer::kAliceBlue = TColor::GetColor(40, 58, 68);
3334 const Int_t dNdetaDrawer::kAliceRed = TColor::GetColor(226, 0, 26);
3335 const Int_t dNdetaDrawer::kAlicePurple = TColor::GetColor(202, 71, 67);
3336 const Int_t dNdetaDrawer::kAliceYellow = TColor::GetColor(238, 125, 17);
3338 
3339 
3340 //____________________________________________________________________
3355 {
3356  Double_t x = xp[0];
3357  Double_t a1 = pp[0];
3358  Double_t a2 = pp[1];
3359  Double_t s1 = pp[2];
3360  Double_t s2 = pp[3];
3361  return a1*(TMath::Gaus(x, 0, s1) - a2 * TMath::Gaus(x, 0, s2));
3362 }
3363 
3364 //=== Stuff for auto zooming =========================================
3371 {
3372  if (!p) {
3373  Warning("UpdateRange", "No parameters %p", p);
3374  return;
3375  }
3376  if (!p->fMasterAxis) {
3377  Warning("UpdateRange", "No master axis %p", p->fMasterAxis);
3378  return;
3379  }
3380  Int_t first = p->fMasterAxis->GetFirst();
3381  Int_t last = p->fMasterAxis->GetLast();
3382  Double_t x1 = p->fMasterAxis->GetBinCenter(first);
3383  Double_t x2 = p->fMasterAxis->GetBinCenter(last);
3384 
3385  if (p->fSlave1Axis) {
3386  Int_t i1 = p->fSlave1Axis->FindBin(x1);
3387  Int_t i2 = p->fSlave1Axis->FindBin(x2);
3388  p->fSlave1Axis->SetRange(i1, i2);
3389  p->fSlave1Pad->Modified();
3390  p->fSlave1Pad->Update();
3391  }
3392  if (p->fSlave2Axis) {
3393  Int_t i1 = p->fSlave2Axis->FindBin(x1);
3394  Int_t i2 = p->fSlave2Axis->FindBin(x2);
3395  p->fSlave2Axis->SetRange(i1, i2);
3396  p->fSlave2Pad->Modified();
3397  p->fSlave2Pad->Update();
3398  }
3399  TCanvas* c = gPad->GetCanvas();
3400  c->cd();
3401 }
3402 
3403 //____________________________________________________________________
3410 {
3411  // Event types:
3412  // 51: Mouse move
3413  // 53:
3414  // 1: Button down
3415  // 21: Mouse drag
3416  // 11: Mouse release
3417  // dNdetaDrawer::RangeParam* p =
3418  // reinterpret_cast<dNdetaDrawer::RangeParam*>(addr);
3419  Int_t event = gPad->GetEvent();
3420  TObject *select = gPad->GetSelected();
3421  if (event == 53) {
3422  UpdateRange(p);
3423  return;
3424  }
3425  if (event != 11 || !select || select != p->fMasterAxis) return;
3426  UpdateRange(p);
3427 }
3428 
3429 //=== Steering functions
3430 //==============================================
3436 void
3438 {
3439  std::ostream& o = std::cout;
3440  o << "Usage: DrawdNdeta(FILE,TITLE,REBIN,OTHERS,FLAGS,"
3441  << "SNN,SYS,TRIG,IPZMIN,IPZMAX,BASE,FMT)\n"
3442  << " const char* FILE File name to open (\"forward_dndeta.root\")\n"
3443  << " const char* TITLE Title to put on plot (\"\")\n"
3444  << " UShort_t REBIN Rebinning factor (1)\n"
3445  << " UShort_t OTHERS Other data to draw - more below (0x7)\n"
3446  << " UShort_t FLAGS Visualisation flags - more below (0x7)\n"
3447  << " UShort_t SYS (optional) 1:pp, 2:PbPb, 3:pPb\n"
3448  << " UShort_t SNN (optional) sqrt(s_NN) in GeV\n"
3449  << " UShort_t TRIG (optional) 1: INEL, 2: INEL>0, 4: NSD, ...\n"
3450  << " Float_t EFF (optional) Trigger efficiency\n"
3451  << " Float_t IPZMIN (optional) Least z coordinate of IP\n"
3452  << " Float_t IPZMAX (optional) Largest z coordinate of IP\n"
3453  << " const char* BASE (optional) base name of output files\n"
3454  << " UShort_t FMT (optional) Output formats\n"
3455  << "\n";
3456  o << " OTHERS is a bit mask of\n"
3457  << " 0x1 Show UA5 data (INEL,NSD, ppbar, 900GeV)\n"
3458  << " 0x2 Show CMS data (NSD, pp)\n"
3459  << " 0x4 Show published ALICE data (INEL,INEL>0,NSD, pp)\n"
3460  << " 0x8 Show event genertor data\n"
3461  << "\n";
3462  o << " FMT is a bit mask of\n"
3463  << " 0x1 Make PNG output\n"
3464  << " 0x2 Make PDF output\n"
3465  << " 0x4 Make ROOT file output\n"
3466  << " 0x8 Make ROOT script output\n"
3467  << "\n";
3468  o << " FLAGS is a bit mask of\n"
3469  << " 0x1 Show ratios of data to other data and possibly MC\n"
3470  << " 0x2 Show left-right asymmetry\n"
3471  << " 0x4 Show systematic error band\n"
3472  << " 0x8 Show individual ring results (INEL only)\n"
3473  << " 0x10 Cut edges when rebinning\n"
3474  << " 0x20 Remove FMDxO points\n"
3475  << " 0x40 Apply `final MC' correction\n"
3476  << " 0x80 Apply `Emperical' correction\n"
3477  << " 0x100 Force use of MB\n"
3478  << " 0x200 Mirror data\n"
3479  << " 0x400 Export results to script\n"
3480  << " 0x800 Add code to do combined zooms on eta axis\n"
3481  << " 0x1000 Assume old-style input\n"
3482  << " 0x2000 Be verbose\n"
3483  << " 0x4000 Hi-res batch output\n"
3484  << " 0x8000 Add aditional white-space above results\n"
3485  << "\n";
3486  o << "0x200 requires the file forward_dndetamc.root\n"
3487  << "0x400 requires the file EmpiricalCorrection.root\n"
3488  << "To specify that you want ratios, force MB, apply empirical "
3489  << "correction, and export to script, set flags to\n\n"
3490  << " 0x1|0x100|0x80|0x400=0x581\n"
3491  << std::endl;
3492 
3493 }
3494 
3495 //____________________________________________________________________
3513 void
3514 DrawdNdeta(const char* filename="forward_dndeta.root",
3515  const char* title="",
3516  UShort_t rebin=5,
3517  UShort_t others=0x7,
3519  Double_t meanIpX=-1,
3520  Double_t meanIpY=-1,
3521  Float_t eff=0,
3522  const char* base="",
3524 {
3525  TString fname(filename);
3526  fname.ToLower();
3527  if (fname.CompareTo("help") == 0 ||
3528  fname.CompareTo("--help") == 0) {
3529  Usage();
3530  return;
3531  }
3532  dNdetaDrawer* pd = new dNdetaDrawer;
3533  pd->SetEmpirical("file://../empirical.root#default");
3534  pd->SetDelta(meanIpX, meanIpY);
3535  // d.fClusterScale = "1.06 -0.003*x +0.0119*x*x";
3536  pd->Run(filename, title, rebin, others, flags, 0, 0, 0, eff,
3537  0, 0, +999, -999, base, outflg);
3538 }
3539 
3544 void
3546 {
3547  std::ostream& o = std::cout;
3548  o << "Usage: DrawdNdeta(FILE,TITLE,OTHERS,OPTIONS,FORMATS,REBIN,EFF,"
3549  << "CMIN,CMAX,IPZMIN,IPZMAX,BASE)\n"
3550  << " const char* FILE File name to open (\"forward_dndeta.root\")\n"
3551  << " const char* TITLE Title to put on plot (\"\")\n"
3552  << " const char* OTHERS Other data to draw - more below (\"all\")\n"
3553  << " const char* FLAGS Visualisation flags - more below (\"default\")\n"
3554  << " const char* FMT (optional) Output formats (\"all\")\n"
3555  << " UShort_t REBIN (optional) Rebinning factor (5)\n"
3556  << " Float_t EFF (optional) Trigger efficiency\n"
3557  << " Float_t IPZMIN (optional) Least z coordinate of IP\n"
3558  << " Float_t IPZMAX (optional) Largest z coordinate of IP\n"
3559  << " UShort_t CMIN (optional) Least centrality\n"
3560  << " UShort_t CMAX (optional) Largest centrality\n"
3561  << " const char* BASE (optional) base name of output files\n"
3562  << "\n";
3563  o << " OTHERS space separated list of\n"
3564  << " UA5 Show UA5 data (INEL,NSD, ppbar, 900GeV)\n"
3565  << " CMS Show CMS data (NSD, pp)\n"
3566  << " ALICE Show published ALICE data (INEL,INEL>0,NSD, pp)\n"
3567  << " WIP Show event genertor data/work-in-progress\n"
3568  << "\n";
3569  o << " FMT space separated list of \n"
3570  << " PNG Make PNG output\n"
3571  << " PDF Make PDF output\n"
3572  << " ROOT Make ROOT file output\n"
3573  << " C Make ROOT script output\n"
3574  << "\n";
3575  o << " FLAGS is a bit mask of\n"
3576  << " ratio Show ratios of data to other data and possibly MC\n"
3577  << " asymmetry Show left-right asymmetry\n"
3578  << " syserror Show systematic error band\n"
3579  << " rings Show individual ring results (INEL only)\n"
3580  << " noedges Cut edges when rebinning\n"
3581  << " noouters Remove FMDxO points\n"
3582  << " finalmc Apply `final MC' correction\n"
3583  << " empirical[=URL] Apply `Emperical' correction\n"
3584  << " mb Force use of MB\n"
3585  << " mirror Mirror data\n"
3586  << " export Export results to script\n"
3587  << " exec Add code to do combined zooms on eta axis\n"
3588  << " old Assume old-style input\n"
3589  << " verbose Be verbose\n"
3590  << " hires Hi-res batch output\n"
3591  << " extrawhite Add aditional white-space above results\n"
3592  << " logo Add ALICE logo\n"
3593  << " nocentral Do not plot cluster data\n"
3594  << " nolabels No labels on y-axis\n"
3595  << "\n";
3596  o << "finalmc requires the file forward_dndetamc.root\n"
3597  << "empirical requires the histogram at URL \n"
3598  << std::endl;
3599 
3600 }
3601 
3602 void
3603 Draw(const char* filename,
3604  const char* title="",
3605  const char* others="ALL",
3606  const char* options="DEFAULT",
3607  const char* outFlg="ALL",
3608  UShort_t rebin=5,
3609  Float_t eff=0,
3610  const char* base="")
3611 {
3612  TString fname(filename);
3613  fname.ToLower();
3614  if (fname.CompareTo("help") == 0 ||
3615  fname.CompareTo("--help") == 0) {
3616  UsageS();
3617  return;
3618  }
3619 
3620  dNdetaDrawer* pd = new dNdetaDrawer;
3621  pd->SetEmpirical("file://../empirical.root#default");
3622 
3623  pd->Run(filename, title, others, options, outFlg, rebin, eff,
3624  0, 0, +999, -999, base);
3625 }
3626 //____________________________________________________________________
3627 //
3628 // EOF
3629 //
3630 
Int_t color[]
print message on plot with ok/not ok
UShort_t fRebin
Definition: DrawdNdeta.C:3281
RangeParam * fRangeParam
Definition: DrawdNdeta.C:3319
TH1 * FetchOne(const TList *list, const TList *mcList, TObject *empCorr, const char *name, const char *folderName, TMultiGraph *others, Int_t col, const char *txt, Double_t &max, Double_t &rmax, Double_t &amax, TH1 *&truth)
Definition: DrawdNdeta.C:1251
void ModifyTitle(TNamed *h, const char *centTxt)
Definition: DrawdNdeta.C:2273
const char * filename
Definition: TestFCM.C:1
TH1 * RatioGG(const TGraphAsymmErrors *g1, const TGraphAsymmErrors *g2) const
Definition: DrawdNdeta.C:2815
dNdetaDrawer & operator=(const dNdetaDrawer &)
Definition: DrawdNdeta.C:243
const Color_t cc[]
Definition: DrawKs.C:1
Double_t fDelta
Definition: DrawdNdeta.C:3289
double Double_t
Definition: External.C:58
void SetTitle(TString x)
Definition: DrawdNdeta.C:281
void Draw(const char *filename, const char *title="", const char *others="ALL", const char *options="DEFAULT", const char *outFlg="ALL", UShort_t rebin=5, Float_t eff=0, const char *base="")
Definition: DrawdNdeta.C:3603
static const Int_t kAlicePurple
Definition: DrawdNdeta.C:3326
const char * title
Definition: MakeQAPdf.C:27
void PlotLeftRight(Double_t max, Double_t y1, Double_t y2)
Definition: DrawdNdeta.C:2128
static const Int_t kFont
Definition: DrawdNdeta.C:3323
TH1 * Graph2Hist(const TGraphAsymmErrors *g) const
Definition: DrawdNdeta.C:2539
THStack * fResults
Definition: DrawdNdeta.C:3312
TString fTitle
Definition: DrawdNdeta.C:3284
virtual void Rebin(TH1 *h) const
Definition: DrawdNdeta.C:2374
virtual ~dNdetaDrawer()
Definition: DrawdNdeta.C:249
Double_t fFwdSysErr
Definition: DrawdNdeta.C:3282
TNamed * fTrigString
Definition: DrawdNdeta.C:3295
UInt_t fFormats
Definition: DrawdNdeta.C:3274
void SetEmpirical(const TString &file)
Definition: DrawdNdeta.C:318
void SetAttributes(TGraph *g, Int_t color)
Definition: DrawdNdeta.C:2260
TSystem * gSystem
void Run(const char *filename, const char *title, UShort_t rebin, UShort_t others=0x7, UInt_t flags=kDefaultOptions, UShort_t sys=0, UShort_t sNN=0, UShort_t trg=0, Float_t eff=0, UShort_t centMin=0, UShort_t centMax=0, Float_t vzMin=+999, Float_t vzMax=-999, const char *base="", UShort_t formats=kAllFormats)
Definition: DrawdNdeta.C:619
static const Int_t kAliceRed
Definition: DrawdNdeta.C:3325
void CorrectCentral(TH1 *h) const
Definition: DrawdNdeta.C:3085
TMultiGraph * FetchOthers(UShort_t centLow, UShort_t centHigh)
Definition: DrawdNdeta.C:1083
TH1 * Merge(const TH1 *cen, const TH1 *fwd, Double_t &xlow, Double_t &xhigh)
Definition: DrawdNdeta.C:2960
TH1 * Ratio(const TObject *o1, const TObject *o2, Double_t &max) const
Definition: DrawdNdeta.C:2653
static void ErrorGraphs(const TGraphAsymmErrors *g, TGraph *&low, TGraph *&up)
Definition: DrawdNdeta.C:2631
TVirtualPad * fSlave2Pad
Definition: DrawdNdeta.C:178
void SetShowOthers(UInt_t others)
Definition: DrawdNdeta.C:268
UShort_t fCentMax
Definition: DrawdNdeta.C:3305
static UShort_t GetMarkerBits(Int_t style)
Definition: DrawdNdeta.C:136
TH1 * fTriggers
Definition: DrawdNdeta.C:3316
TCanvas * c
Definition: TestFitELoss.C:172
THStack * fLeftRight
Definition: DrawdNdeta.C:3314
void UsageS()
Definition: DrawdNdeta.C:3545
static const Int_t kSysErrColor
Definition: DrawdNdeta.C:3328
UInt_t fCentSeen
Definition: DrawdNdeta.C:3306
UShort_t fShowOthers
Definition: DrawdNdeta.C:3275
TObject * fCentMeth
Definition: DrawdNdeta.C:3301
UShort_t fCentMin
Definition: DrawdNdeta.C:3304
Bool_t GetEmpirical(const TString &prx, Bool_t useCen, TObject *&fwdEmp, TObject *&cenEmp, TString &empName)
Definition: DrawdNdeta.C:438
TString fEmpirical
Definition: DrawdNdeta.C:3288
AliStack * stack
void Export(const char *basename)
Definition: DrawdNdeta.C:3105
void SetTriggerEfficiency(Float_t eff)
Definition: DrawdNdeta.C:422
TRandom * gRandom
void SetRebin(UShort_t x)
Definition: DrawdNdeta.C:274
void BuildCentLegend(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: DrawdNdeta.C:1729
static void ErrorGraphs(const TGraphErrors *g, TGraph *&low, TGraph *&up)
Definition: DrawdNdeta.C:2617
Double_t fCenSysErr
Definition: DrawdNdeta.C:3283
TObject * fEmpCorr
Definition: DrawdNdeta.C:3320
void SetTrigger(UShort_t trig)
Definition: DrawdNdeta.C:406
Definition: External.C:92
void PlotResults(Double_t max, Double_t yd, Double_t s)
Definition: DrawdNdeta.C:1797
void CorrectTriggerEff(TH1 *dndeta)
Definition: DrawdNdeta.C:1483
#define SYSERR_STYLE
Definition: DrawdNdeta.C:49
Bool_t HasCent() const
Definition: DrawdNdeta.C:3257
TAxis * fVtxAxis
Definition: DrawdNdeta.C:3299
Double_t myFunc(Double_t *xp, Double_t *pp)
Definition: DrawdNdeta.C:3354
static const Float_t kRightMargin
Definition: DrawdNdeta.C:3322
void DrawdNdeta(const char *filename="forward_dndeta.root", const char *title="", UShort_t rebin=5, UShort_t others=0x7, UInt_t flags=dNdetaDrawer::kDefaultOptions, Double_t meanIpX=-1, Double_t meanIpY=-1, Float_t eff=0, const char *base="", UShort_t outflg=dNdetaDrawer::kAllFormats)
Definition: DrawdNdeta.C:3514
Int_t cH
Definition: Combine.C:26
TMultiGraph * fOthers
Definition: DrawdNdeta.C:3315
void Usage()
Definition: DrawdNdeta.C:3437
void Run(const char *filename="forward_dndeta.root", const char *title="", const char *others="all", const char *options="default", const char *formats="all", UShort_t rebin=5, Float_t eff=0, UShort_t centMin=0, UShort_t centMax=0, Float_t vzMin=+999, Float_t vzMax=-999, const char *base="")
Definition: DrawdNdeta.C:519
dNdetaDrawer(const dNdetaDrawer &)
Definition: DrawdNdeta.C:236
int Int_t
Definition: External.C:63
TAxis * FindXAxis(TVirtualPad *p, const char *name)
Definition: DrawdNdeta.C:2868
unsigned int UInt_t
Definition: External.C:33
static void ErrorGraphs(const TGraph *g, TGraph *&low, TGraph *&up)
Definition: DrawdNdeta.C:2602
float Float_t
Definition: External.C:68
void UpdateRange(dNdetaDrawer::RangeParam *p)
Definition: DrawdNdeta.C:3370
TString fClusterScale
Definition: DrawdNdeta.C:3286
Bool_t fExtTriggerEff
Definition: DrawdNdeta.C:3303
void BuildLegend(THStack *stack, TMultiGraph *mg, Double_t x1, Double_t y1, Double_t x2, Double_t y2, Int_t forceCol=0)
Definition: DrawdNdeta.C:1605
TH1 * FetchHistogram(const TList *list, const char *name) const
Definition: DrawdNdeta.C:2303
static const Int_t kAliceBlue
Definition: DrawdNdeta.C:3324
TString fBase
Definition: DrawdNdeta.C:3285
Definition: External.C:212
Int_t GetCentralityColor(Int_t bin) const
Definition: DrawdNdeta.C:2213
TAxis * fCentAxis
Definition: DrawdNdeta.C:3300
void SetDelta(Double_t meanIpx, Double_t meanIpy)
Definition: DrawdNdeta.C:326
static Int_t FlipHollowStyle(Int_t style)
Definition: DrawdNdeta.C:161
THStack * fRatios
Definition: DrawdNdeta.C:3313
TVirtualPad * fSlave1Pad
Definition: DrawdNdeta.C:176
void SetAttributes(TH1 *h, Int_t color)
Definition: DrawdNdeta.C:2245
void plot()
Definition: plot.C:3
void SetVertexRange(Double_t vzMin, Double_t vzMax)
Definition: DrawdNdeta.C:382
void CorrectEmpirical(TH1 *dndeta, TObject *empObj)
Definition: DrawdNdeta.C:1454
Double_t centMax
const char * fwd
TNamed * fSNNString
Definition: DrawdNdeta.C:3297
Double_t AddHistogram(THStack *stack, TH1 *hist, TH1 *&sym, Option_t *option="") const
Definition: DrawdNdeta.C:2349
void RangeExec(dNdetaDrawer::RangeParam *p)
Definition: DrawdNdeta.C:3409
void PlotRatios(Double_t max, Double_t y1, Double_t y2)
Definition: DrawdNdeta.C:2066
TNamed * fSysString
Definition: DrawdNdeta.C:3298
static const Int_t kAliceYellow
Definition: DrawdNdeta.C:3327
Definition: External.C:220
void Plot(Double_t max, Double_t rmax, Double_t amax)
Definition: DrawdNdeta.C:1499
#define SYSERR_COLOR
Definition: DrawdNdeta.C:47
TF1 * FitMerged(TH1 *tmp, Double_t xlow, Double_t xhigh)
Definition: DrawdNdeta.C:3009
TObjArray * FetchTopResults(const TList *list, const TList *mcList, TObject *empCorr, const char *name, Double_t &max, Double_t &rmax, Double_t &amax, TObjArray &truths)
Definition: DrawdNdeta.C:1172
TH1 * Asymmetry(TH1 *h, Double_t &max)
Definition: DrawdNdeta.C:2490
TFile * file
TList with histograms for a given trigger.
TNamed * fNormString
Definition: DrawdNdeta.C:3296
Int_t rebin
Double_t RatioMax(TH1 *h) const
Definition: DrawdNdeta.C:2582
TString fFinalMC
Definition: DrawdNdeta.C:3287
Float_t fTriggerEff
Definition: DrawdNdeta.C:3302
void SetSys(UShort_t sys)
Definition: DrawdNdeta.C:366
void SetSNN(UShort_t sNN)
Definition: DrawdNdeta.C:353
unsigned short UShort_t
Definition: External.C:28
TList * ef
Definition: TestFitELoss.C:145
void SetCentralityRange(UShort_t centMin, UShort_t centMax)
Definition: DrawdNdeta.C:395
void SetBase(TString x)
Definition: DrawdNdeta.C:288
const char Option_t
Definition: External.C:48
void test(int runnumber=195345)
Double_t AddHistogram(THStack *stack, TH1 *hist, Option_t *option="") const
Definition: DrawdNdeta.C:2327
UInt_t fOptions
Definition: DrawdNdeta.C:3273
void MakeSysError(TH1 *tmp, TH1 *cen, TH1 *fwd, TF1 *fit)
Definition: DrawdNdeta.C:3040
void CorrectForward(TH1 *h) const
Definition: DrawdNdeta.C:3073
const Int_t nbins
TH1 * RatioHG(const TH1 *h, const TGraph *g) const
Definition: DrawdNdeta.C:2729
bool Bool_t
Definition: External.C:53
void SetCentralSysError(Double_t e=0)
Definition: DrawdNdeta.C:302
void FixAxis(THStack *stack, Double_t yd, const char *ytitle, Int_t ynDiv=210, Bool_t force=true)
Definition: DrawdNdeta.C:2898
TH1 * RatioHH(const TH1 *h1, const TH1 *h2) const
Definition: DrawdNdeta.C:2783
TH1 * FetchCentResults(const TList *list, const TList *mcList, TObject *empCorr, const char *name, TMultiGraph *thisOther, Int_t color, const char *centTxt, Double_t &max, Double_t &rmax, Double_t &amax, TH1 *&truth)
Definition: DrawdNdeta.C:1317
void SetFinalMC(const TString &file)
Definition: DrawdNdeta.C:309
void AttachExec(TVirtualPad *p, const char *plot, UShort_t id, Bool_t isBottom)
Definition: DrawdNdeta.C:1768
void CorrectFinalMC(TH1 *dndeta, const TList *mcList)
Definition: DrawdNdeta.C:1438
void SetForwardSysError(Double_t e=0)
Definition: DrawdNdeta.C:295
TH1 * Symmetrice(const TH1 *h) const
Definition: DrawdNdeta.C:2445
Definition: External.C:196
void FetchInformation(const TList *results)
Definition: DrawdNdeta.C:950
void SetDelta(Double_t delta)
Definition: DrawdNdeta.C:325
const char * CentLimitName(Bool_t isMult, Float_t v)
Definition: DrawdNdeta.C:1713
static Int_t GetMarkerStyle(UShort_t bits)
Definition: DrawdNdeta.C:114
void PlotTitle(TVirtualPad *p, Double_t yd, Bool_t bottom=true)
Definition: DrawdNdeta.C:1577
Double_t centMin
Color_t Brighten(Color_t origNum, Int_t nTimes=2) const
Definition: DrawdNdeta.C:2190