AliPhysics  1adf5bd (1adf5bd)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliBasedNdetaTask.cxx
Go to the documentation of this file.
1 //====================================================================
2 #include "AliBasedNdetaTask.h"
3 #include <TMath.h>
4 #include <TH2D.h>
5 #include <TH1D.h>
6 #include <TF1.h>
7 #include <THStack.h>
8 #include <TList.h>
9 #include <TProfile.h>
10 #include <AliAnalysisManager.h>
11 #include <AliAODEvent.h>
12 #include <AliAODHandler.h>
13 #include <AliAODInputHandler.h>
14 #include "AliForwardUtil.h"
15 #include "AliAODForwardMult.h"
16 #include "AliAODMultEventClass.h"
17 #include <TFile.h>
18 #include <TStyle.h>
19 #include <TROOT.h>
20 #include <TParameter.h>
21 #include <TColor.h>
22 
23 //====================================================================
24 namespace {
34  {
35  Double_t c = (c1+c2) / 2;
36  if (c < 5) return 0;
37  else if (c < 10) return 1;
38  else if (c < 20) return 2;
39  else if (c < 30) return 3;
40  else if (c < 40) return 4;
41  else if (c < 50) return 5;
42  else if (c < 60) return 6;
43  else if (c < 70) return 7;
44  else if (c < 80) return 8;
45  else if (c < 90) return 9;
46  return 10;
47  }
48  //__________________________________________________________________
57  Color_t PbPbColor(Double_t c1, Double_t c2)
58  {
59  const Color_t cc[] = { kMagenta+2, // 0
60  kBlue+2, // 1
61  kAzure-1, // 2
62  kCyan+2, // 3
63  kGreen+1, // 4
64  kSpring+5, // 5
65  kYellow+1, // 6
66  kOrange+5, // 7
67  kRed+1, // 8
68  kPink+5, // 9
69  kBlack }; // 10
70  Int_t bin = PbPbBin(c1,c2);
71  return cc[bin];
72  }
73  //__________________________________________________________________
82  Int_t pPbBin(Double_t c1, Double_t c2)
83  {
84  Double_t c = (c1+c2) / 2;
85  if (c < 5) return 0;
86  else if (c < 10) return 1;
87  else if (c < 20) return 2;
88  else if (c < 40) return 3;
89  else if (c < 60) return 4;
90  else if (c < 80) return 5;
91  else if (c < 100) return 6;
92  return 7;
93  }
94  //__________________________________________________________________
103  Color_t pPbColor(Double_t c1, Double_t c2)
104  {
105  const Color_t cc[] = { kMagenta+2, // 0
106  kBlue+2, // 1
107  kCyan+2, // 2
108  kGreen+1, // 3
109  kYellow+1, // 4
110  kRed+1, // 5
111  kPink+5, // 6
112  kBlack }; // 7
113  Int_t bin = pPbBin(c1,c2);
114  return cc[bin];
115  }
116 }
117 
118 //____________________________________________________________________
120  : AliBaseAODTask(),
121  fCorrEmpty(true),
122  fUseROOTProj(false),
123  fTriggerEff(1),
124  fTriggerEff0(1),
125  fListOfCentralities(0),
126  fNormalizationScheme(kFull),
127  fFinalMCCorrFile(""),
128  fSatelliteVertices(0),
129  fEmpiricalCorrection(0),
130  fMeanVsC(0),
131  fSeenCent(0),
132  fTakenCent(0),
133  fCentMethod("default"),
134  fAnaUtil(),
135  fUseUtilPileup(false),
136  fIpzReweight(0),
137  fCacheCent(-10),
138  fCacheQual(0xFFFF)
139 {
140  //
141  // Constructor
142  //
143  DGUARD(fDebug,3,"Default CTOR of AliBasedNdetaTask");
144 }
145 
146 //____________________________________________________________________
148  : AliBaseAODTask(Form("%sdNdeta", name),"AliBasedNdetaTask"),
149  fCorrEmpty(true),
150  fUseROOTProj(false),
151  fTriggerEff(1),
152  fTriggerEff0(1),
153  fListOfCentralities(0),
154  fNormalizationScheme(kFull),
155  fFinalMCCorrFile(""),
156  fSatelliteVertices(0),
157  fEmpiricalCorrection(0),
158  fMeanVsC(0),
159  fSeenCent(0),
160  fTakenCent(0),
161  fCentMethod("default"),
162  fAnaUtil(),
163  fUseUtilPileup(false),
164  fIpzReweight(0),
165  fCacheCent(-10),
166  fCacheQual(0xFFFF)
167 {
168  //
169  // Constructor
170  //
171  DGUARD(fDebug, 3,"Named CTOR of AliBasedNdetaTask: %s", name);
172 
173  SetIPzAxis(10,-10,+10);
176  fListOfCentralities->SetName("centralityBins");
177  // fListOfCentralities->SetTitle("Centrality bins");
178 
179  // Set the normalisation scheme
181 }
182 
183 
184 //____________________________________________________________________
186 {
187  //
188  // Destructor
189  //
190  DGUARD(fDebug,3,"Destruction of AliBasedNdetaTask");
191 }
192 
193 //________________________________________________________________________
194 void
196 {
197  AliAnalysisTaskSE::SetDebugLevel(lvl);
198  for (Int_t i = 0; i < fListOfCentralities->GetEntries(); i++) {
199  CentralityBin* bin =
200  static_cast<CentralityBin*>(fListOfCentralities->At(i));
201  bin->SetDebugLevel(lvl);
202  }
203 }
204 
205 //________________________________________________________________________
206 void
208 {
209  //
210  // Add a centrality bin
211  //
212  // Parameters:
213  // low Low cut
214  // high High cut
215  //
216  DGUARD(fDebug,3,"Add a centrality bin [%6.2f,%6.2f] @ %d", low, high, at);
217  CentralityBin* bin = MakeCentralityBin(GetName(), low, high);
218  if (!bin) {
219  Error("AddCentralityBin",
220  "Failed to create centrality bin for %s [%6.2f,%6.2f] @ %d",
221  GetName(), low, high, at);
222  return;
223  }
225  bin->SetDebugLevel(fDebug);
226  Color_t color = (bin->IsAllBin() ? kBlack : kGray+1);
227  if (HasCentrality() && !(high <= low) && (high <= 100)) {
228  if (fCentAxis.GetNbins() > 7) color = PbPbColor(low,high);
229  else color = pPbColor (low,high);
230  }
231  DMSG(fDebug, 3, "Color of bin %d", color);
232  bin->SetColor(color);
233  fListOfCentralities->AddAtAndExpand(bin, at);
234 }
235 
236 //________________________________________________________________________
239  Float_t low, Float_t high) const
240 {
241  //
242  // Make a centrality bin
243  //
244  // Parameters:
245  // name Name used for histograms
246  // low Low cut in percent
247  // high High cut in percent
248  //
249  // Return:
250  // A newly created centrality bin
251  //
252  DGUARD(fDebug,3,"Make a centrality bin %s [%6.2f,%6.2f]", name, low, high);
253  return new CentralityBin(name, low, high);
254 }
255 
256 #define TESTAPPEND(SCHEME,BIT,STRING) \
257  do { if (!(SCHEME & BIT)) break; \
258  if (!s.IsNull()) s.Append(","); s.Append(STRING); } while(false)
259 
260 //________________________________________________________________________
261 const Char_t*
263 {
264  // Create a string from normalization scheme bits
265  static TString s;
266  s = "";
267 
268  if (scheme == kNone)
269  return s.Data();
270  if (scheme == kFull) {
271  s = "FULL";
272  return s.Data();
273  }
274  TESTAPPEND(scheme, kEventLevel, "EVENT");
275  TESTAPPEND(scheme, kBackground, "BACKGROUND");
276  TESTAPPEND(scheme, kTriggerEfficiency, "TRIGGER");
277  TESTAPPEND(scheme, kZeroBin, "ZEROBIN");
278 
279  return s.Data();
280 }
281 //________________________________________________________________________
282 UShort_t
284 {
285  UShort_t scheme = 0;
286  TString twhat(what);
287  twhat.ToUpper();
288  if (twhat.EqualTo("DEFAULT"))
290  TObjString* opt;
291  TObjArray* token = twhat.Tokenize(" ,|");
292  TIter next(token);
293  while ((opt = static_cast<TObjString*>(next()))) {
294  TString s(opt->GetString());
295  if (s.IsNull()) continue;
296  Bool_t add = true;
297  switch (s[0]) {
298  case '-': add = false; // Fall through
299  case '+': s.Remove(0,1); // Remove character
300  }
301  UShort_t bit = 0;
302  if (s.EqualTo("SHAPE")) {
303  AliWarningGeneral("AliBasedNdetaTask",
304  Form("SHAPE correction no longer supported (%s)",
305  what));
306  continue;
307  }
308  if (s.CompareTo("EVENT") == 0) bit = kEventLevel;
309  else if (s.CompareTo("BACKGROUND")== 0) bit = kBackground;
310  else if (s.CompareTo("TRIGGER") == 0) bit = kTriggerEfficiency;
311  else if (s.CompareTo("FULL") == 0) bit = kFull;
312  else if (s.CompareTo("NONE") == 0) bit = kNone;
313  else if (s.CompareTo("ZEROBIN") == 0) bit = kZeroBin;
314  else
315  ::Warning("SetNormalizationScheme", "Unknown option %s", s.Data());
316  if (add) scheme |= bit;
317  else scheme ^= bit;
318  }
319  delete token;
320  return scheme;
321 }
322 //________________________________________________________________________
323 void
325 {
326  //
327  // Set normalisation scheme
328  //
329  DGUARD(fDebug,3,"Set the normalization scheme: %s", what);
331 }
332 //________________________________________________________________________
333 void
335 {
336  DGUARD(fDebug,3,"Set the normalization scheme: 0x%x", scheme);
337  fNormalizationScheme = scheme;
338 }
339 //____________________________________________________________________
340 Bool_t
342 {
343  Int_t id = GetCentMethodID(method);
344  if (id < -1) {
345  AliErrorF("Unknown centrality estimator: %s", method.Data());
346  fCentMethod = "";
347  return false;
348  }
349  if (id < 0) {
350  // Do not use any estimator
351  AliInfoF("No centrality estimator: \"%s\"", method.Data());
352  fCentMethod = "";
353  return false;
354  }
355 
356  TString meth = GetCentMethod(id);
357  if (fName.Contains("Forward", TString::kIgnoreCase) && meth.Contains("FMD"))
358  AliWarningF("Centrality estimator %s used by %s - beware of auto-corr",
359  meth.Data(), fName.Data());
360  else if (fName.Contains("Central", TString::kIgnoreCase) &&
361  (meth.Contains("CL0") || meth.Contains("TKL")))
362  AliWarningF("Centrality estimator %s used by %s - beware of auto-corr",
363  meth.Data(), fName.Data());
364 
365  fCentMethod = meth;
366  AliInfoF("Centrality estimator set to %s", fCentMethod.Data());
367  return true;
368 }
369 
370 //________________________________________________________________________
371 Int_t
373 {
374  Int_t ret = -2;
375  TString m(meth);
376  m.ToUpper();
377  if (m.EqualTo("NONE") || m.EqualTo("NO") || m.EqualTo("FALSE"))
378  ret = kCentNone;
379  else if (m.IsNull()) ret = kCentDefault;
380  else if (m.BeginsWith("DEFAULT")) ret = kCentDefault;
381  else if (m.BeginsWith("ZEMVSZDC")) ret = kCentZEMvsZDC;
382  else if (m.BeginsWith("TKLVSV0M")) ret = kCentTklvsV0M;
383  else if (m.BeginsWith("V0MVSFMD")) ret = kCentV0MvsFMD;
384  else if (m.BeginsWith("NPA")) ret = kCentNPA;
385  else if (m.BeginsWith("ZPC")) ret = kCentZPC;
386  else if (m.BeginsWith("ZPA")) ret = kCentZPA;
387  else if (m.BeginsWith("ZNC")) ret = kCentZNC;
388  else if (m.BeginsWith("ZNA")) ret = kCentZNA;
389  else if (m.BeginsWith("CND")) ret = kCentCND;
390  else if (m.BeginsWith("CL1")) ret = kCentCL1;
391  else if (m.BeginsWith("CL0")) ret = kCentCL0;
392  else if (m.BeginsWith("TKL")) ret = kCentTkl;
393  else if (m.BeginsWith("TRK")) ret = kCentTrk;
394  else if (m.BeginsWith("FMD")) ret = kCentFMD;
395  else if (m.BeginsWith("V0C")) ret = kCentV0C;
396  else if (m.BeginsWith("V0A123")) ret = kCentV0A123;
397  else if (m.BeginsWith("V0A")) ret = kCentV0A;
398  else if (m.BeginsWith("V0M")) ret = kCentV0M;
399  else if (m.BeginsWith("MULTV0A")) ret = kMultV0A;
400  else if (m.BeginsWith("MULTV0M")) ret = kMultV0M;
401  else if (m.BeginsWith("MULTV0C")) ret = kMultV0C;
402  else if (m.BeginsWith("MULT")) ret = kMult;
403  if (m.Contains("TRUE")) ret |= kCentTrue;
404  if (m.Contains("EQ")) ret |= kCentEq;
405 
406  return ret;
407 }
408 //________________________________________________________________________
409 const char*
411 {
412  static TString ret("");
413  UShort_t base = (id & 0xFF);
414  switch (base) {
415  case kCentNone: ret = "none"; break;
416  case kCentDefault: ret = ""; break;
417  case kCentV0M: ret = "V0M"; break;
418  case kCentV0A: ret = "V0A"; break;
419  case kCentV0A123: ret = "V0A123"; break;
420  case kCentV0C: ret = "V0C"; break;
421  case kCentFMD: ret = "FMD"; break;
422  case kCentTrk: ret = "TRK"; break;
423  case kCentTkl: ret = "TKL"; break;
424  case kCentCL0: ret = "CL0"; break;
425  case kCentCL1: ret = "CL1"; break;
426  case kCentCND: ret = "CND"; break;
427  case kCentZNA: ret = "ZNA"; break;
428  case kCentZNC: ret = "ZNC"; break;
429  case kCentZPA: ret = "ZPA"; break;
430  case kCentZPC: ret = "ZPC"; break;
431  case kCentNPA: ret = "NPA"; break;
432  case kCentV0MvsFMD: ret = "V0MvsFMD"; break;
433  case kCentTklvsV0M: ret = "TKLvsV0M"; break;
434  case kCentZEMvsZDC: ret = "ZEMvsZDC"; break;
435  case kMult: ret = "MULT"; break;
436  case kMultV0A: ret = "MULTV0A"; break;
437  case kMultV0M: ret = "MULTV0M"; break;
438  case kMultV0C: ret = "MULTV0C"; break;
439  default: ret = ""; break;
440  }
441  Bool_t tru = id & kCentTrue;
442  Bool_t eq = id & kCentEq;
443  if (eq) {
444  if (!tru) ret.Append("eq");
445  else ret.Append("Eq");
446  }
447  if (tru) ret.Append("true");
448 
449  return ret.Data();
450 }
451 
452 
453 //________________________________________________________________________
454 void
456 {
457  if (fListOfCentralities->GetEntries() > 0) return;
458 
459  // Automatically add 'all' centrality bin if nothing has been defined.
460  AddCentralityBin(0, 0, 0);
461 
462  // Check if the centrality method was set to none, and in that case
463  // remove the centrality axis.
464  if (fCentMethod.EqualTo("none", TString::kIgnoreCase)) {
465  fCentAxis.Set(0,0,0);
466  TH1* h = static_cast<TH1*>(fSums->FindObject(fCentAxis.GetName()));
467  if (h) {
468  Info("InitializeCentBins",
469  "No centrality, forcing centrality axis to null");
470  h->GetXaxis()->Set(0,0,0);
471  h->Rebuild();
472  }
473  }
474  if (HasCentrality()) {
475  const TArrayD* bins = fCentAxis.GetXbins();
476  Int_t nbin = fCentAxis.GetNbins();
477  for (Int_t i = 0; i < nbin; i++)
478  AddCentralityBin(i+1, (*bins)[i], (*bins)[i+1]);
479  AddCentralityBin(nbin+1, 0, 101);
480  }
481 }
482 
483 //________________________________________________________________________
484 Bool_t
486 {
487  //
488  // Create output objects.
489  //
490  // This is called once per slave process
491  //
492  DGUARD(fDebug,1,"Create user ouput object");
493 
494  // Modify axis of centrality histograms
495  fCent->SetXTitle(Form("Centrality (%s) [%%]", fCentMethod.Data()));
496  fAccCent->SetXTitle(Form("Centrality (%s) [%%]", fCentMethod.Data()));
497 
498  fSums->Add(AliForwardUtil::MakeParameter("empirical",
499  fEmpiricalCorrection != 0));
501  fSums->Add(AliForwardUtil::MakeParameter("centEstimator",
503  if (fIpzReweight) fSums->Add(fIpzReweight->Clone("ipZw"));
504  // fSums->Add(new TNamed("centEstimator", fCentMethod.Data()));
505 
506  // Make our centrality bins
508 
509  // Loop over centrality bins
510  TIter next(fListOfCentralities);
511  CentralityBin* bin = 0;
512  while ((bin = static_cast<CentralityBin*>(next())))
514 
515 
516  if (HasCentrality()) {
517  if (fCentAxis.GetXbins()->GetArray()) {
518  Int_t nbin = fCentAxis.GetNbins();
519  TArrayD a(nbin+1, fCentAxis.GetXbins()->GetArray());
520  a.Set(nbin+2);
521  a[nbin+1] = fCentAxis.GetXmax()+fCentAxis.GetBinWidth(nbin+1);
522 
523  fSeenCent = new TH1D("centSeen", "Centralities seen",
524  a.GetSize()-1, a.GetArray());
525  fMeanVsC=new TProfile("sumVsC",
526  "Integral vs centrality",
527  a.GetSize()-2, a.GetArray());
528  }
529  else {
530  fSeenCent = new TH1D("centSeen", "Centralities seen",
531  fCentAxis.GetNbins()+1,
532  fCentAxis.GetXmin(),
533  fCentAxis.GetXmax()+fCentAxis.GetBinWidth(1));
534  fMeanVsC=new TProfile("sumVsC",
535  "Integral vs centrality",
536  fCentAxis.GetNbins()+1,
537  fCentAxis.GetXmin(),
538  fCentAxis.GetXmax()+fCentAxis.GetBinWidth(1));
539  }
540  }
541  else {
542  fSeenCent = new TH1D("centSeen", "Null",1,0,100);
543  fMeanVsC = new TProfile("sumVsC", "Null",1,0,100);
544  }
545  fSeenCent->SetDirectory(0);
546  fSeenCent->SetXTitle(Form("Centrality (%s) [%%]",fCentMethod.Data()));
547  fSeenCent->SetYTitle("Events");
548  fSeenCent->SetFillStyle(3004);
549  fSeenCent->SetFillColor(kYellow-2);
550  fMeanVsC->SetDirectory(0);
551  fMeanVsC->SetXTitle(fSeenCent->GetXaxis()->GetTitle());
552  fMeanVsC->SetYTitle("#LT#int signal#GT");
553  fMeanVsC->SetMarkerStyle(20);
554  fMeanVsC->SetMarkerColor(kRed+1);
555  fMeanVsC->SetLineColor(kRed+1);
556 
557 
558  fTakenCent = static_cast<TH1D*>(fSeenCent->Clone("centTaken"));
559  fTakenCent->SetTitle("Centralities taken by bins");
560  fTakenCent->SetFillColor(kCyan-2);
561  fTakenCent->SetFillStyle(3005);
562  fTakenCent->SetDirectory(0);
563 
564  fSums->Add(fSeenCent);
565  fSums->Add(fTakenCent);
566  fSums->Add(fMeanVsC);
567 
568  // fSums->ls();
569  return true;
570 }
571 
572 //____________________________________________________________________
573 Bool_t
575 {
576  if (!fCentMethod.BeginsWith("MULT"))
578  else
580  fIPzAxis.GetXmin(),
581  fIPzAxis.GetXmax(),
582  0,
583  0,
584  fTriggers,
585  fEventStatus,
586  fFilterMask);
587 
588  // Here, we always return true, as the centrality bins will do
589  // their own checks on the events - this is needed for event
590  // normalization etc.
591  return true;
592 }
593 
594 //____________________________________________________________________
595 Double_t
597  AliAODForwardMult* forward,
598  Int_t& qual)
599 {
600  DGUARD(fDebug,2,"Getting centrality from event of object: %s",
601  fCentMethod.Data());
602  if (fCacheCent > -1) {
603  // In case we already got the centrality, don't do it again
604  DMSG(fDebug,1,"Returning cached value: %5.1f%%", fCacheCent);
605  qual = fCacheQual;
606  return fCacheCent;
607  }
608  if (fCentMethod.EqualTo("none")) {
609  fCacheQual = 0;
610  return fCacheCent = 0;
611  }
612  qual = 0;
613  Float_t cent = AliBaseAODTask::GetCentrality(event,forward,qual);
614  DMSG(fDebug,1,"Centrality stored in AOD forward: %5.1f%%", cent);
615  if (!fCentMethod.IsNull()) {
616  // Clear bad cent if already set
617  cent = AliForwardUtil::GetCentrality(event,fCentMethod,qual,(fDebug > 1));
618  if (cent < 0) cent = -.5; // Bad centrality
619  else if (TMath::Abs(cent-100) < 1.1) cent = 100; // Special centralities
620  DMSG(fDebug,1,"Centrality from mult: %5.1f%% (%d)", cent, qual);
621  }
622  fCacheQual = qual;
623  return fCacheCent = cent;
624 }
625 //____________________________________________________________________
626 Double_t
628  AliAODForwardMult* forward)
629 {
630  Int_t qual = 0;
631  Double_t cent = GetCentrality(event, forward, qual);
632  if (qual > 0) forward->SetTriggerBits(AliAODForwardMult::kCentNoCalib);
633  return cent;
634 }
635 
636 //____________________________________________________________________
637 Bool_t
639 {
640  //
641  // Process a single event
642  //
643  // Parameters:
644  // option Not used
645  //
646  // Main loop
647  DGUARD(fDebug,1,"Analyse the AOD event");
648  if (fUseUtilPileup && fAnaUtil.IsPileUpEvent(&aod)) return false;
649 
650  AliAODForwardMult* forward = GetForward(aod);
651  if (!forward) return false;
652 
653  // Fill centrality histogram
654 
655  Double_t vtx = forward->GetIpZ();
656  TH2D* data = GetHistogram(aod, false);
657  TH2D* dataMC = GetHistogram(aod, true);
658  if (!data) return false;
659 
660  CheckEventData(vtx, data, dataMC);
661 
662  if (!ApplyEmpiricalCorrection(forward,data))
663  return false;
664 
665  Double_t ipzW = 1;
666  if (fIpzReweight) {
667  ipzW = fIpzReweight->Eval(vtx);
668  DMSG(fDebug,5,"IPz=%f -> Weight %f", vtx, ipzW);
669  }
670 
671  Bool_t isZero = ((fNormalizationScheme & kZeroBin) &&
673  Bool_t taken = false;
674  // Loop over centrality bins
675  CentralityBin* allBin =
676  static_cast<CentralityBin*>(fListOfCentralities->At(0));
677  if (allBin->ProcessEvent(forward, fTriggerMask, isZero,
678  fIPzAxis.GetXmin(), fIPzAxis.GetXmax(),
679  data, dataMC, fFilterMask, ipzW)) taken = true;
680 
681  // Find this centrality bin
682  if (HasCentrality()) {
683  taken = false;
684  // After this call, the if the event isn't covered by the
685  // centrality calibrations, a flag will be set in the forward
686  // object.
687  Double_t cent = GetCentrality(aod, forward);
688  fMeanVsC->Fill(cent, data->Integral());
689 
690  // fSeenCent->Fill(cent);
691  DMSG(fDebug,1,"Got event centrality %f (%s)", cent,
694  "out-of-calib" : "in-calib");
695 
696  Int_t icent = fCentAxis.FindBin(cent);
697  DMSG(fDebug,1,"Centrality %5.2f%% maps to bin %d", cent, icent);
698  if (icent == (fCentAxis.GetNbins()+1) &&
699  TMath::Abs(cent-fCentAxis.GetXmax()) < 1e-6)
700  // Make sure that upper edge is analysed
701  icent = fCentAxis.GetNbins();
702  CentralityBin* thisBin = 0;
703  if (icent >= 1 && icent <= fCentAxis.GetNbins())
704  thisBin = static_cast<CentralityBin*>(fListOfCentralities->At(icent));
705  if (thisBin && thisBin->ProcessEvent(forward, fTriggerMask,
706  isZero,
707  fIPzAxis.GetXmin(),
708  fIPzAxis.GetXmax(),
709  data, dataMC, fFilterMask, ipzW))
710  taken = true;
711  if (taken) fTakenCent->Fill(cent);
712 
713  Int_t nbins = fCentAxis.GetNbins();
714  CentralityBin* fullBin =
715  static_cast<CentralityBin*>(fListOfCentralities->At(nbins+1));
716  if (fullBin && fullBin->ProcessEvent(forward, fTriggerMask, isZero,
717  fIPzAxis.GetXmin(),
718  fIPzAxis.GetXmax(),
719  data, dataMC,
720  fFilterMask, ipzW))
721  fSeenCent->Fill(cent);
722  }
723 
724  return taken;
725 }
726 
727 //________________________________________________________________________
729  TH2*,
730  TH2*)
731 {
732 }
733 
734 //________________________________________________________________________
735 void
737  const char* title, const char* ytitle)
738 {
739  //
740  // Set histogram graphical options, etc.
741  //
742  // Parameters:
743  // h Histogram to modify
744  // colour Marker color
745  // marker Marker style
746  // title Title of histogram
747  // ytitle Title on y-axis.
748  //
749  h->SetTitle(title);
750  h->SetMarkerColor(colour);
751  h->SetMarkerStyle(marker);
752  h->SetMarkerSize(marker == 29 || marker == 30 ? 1.2 : 1);
753  h->SetFillStyle(0);
754  TString ytit;
755  if (ytitle && ytitle[0] != '\0') ytit = ytitle;
756  ytit = "#frac{1}{#it{N}}#frac{d#it{N}_{ch}}{d#it{#eta}}";
757  h->SetYTitle(ytit);
758  h->GetXaxis()->SetTitleFont(132);
759  h->GetXaxis()->SetLabelFont(132);
760  h->GetXaxis()->SetNdivisions(10);
761  h->GetYaxis()->SetTitleFont(132);
762  h->GetYaxis()->SetLabelFont(132);
763  h->GetYaxis()->SetNdivisions(10);
764  h->GetYaxis()->SetDecimals();
765  h->SetStats(0);
766 }
767 
768 //________________________________________________________________________
769 void
771 {
772  // Normalize to the acceptance -
773  // dndeta->Divide(accNorm);
774  for (Int_t i = 1; i <= copy->GetNbinsX(); i++) {
775  Double_t a = norm->GetBinContent(i);
776  for (Int_t j = 1; j <= copy->GetNbinsY(); j++) {
777  if (a <= 0) {
778  copy->SetBinContent(i,j,0);
779  copy->SetBinError(i,j,0);
780  continue;
781  }
782  Double_t c = copy->GetBinContent(i, j);
783  Double_t e = copy->GetBinError(i, j);
784  copy->SetBinContent(i, j, c / a);
785  copy->SetBinError(i, j, e / a);
786  }
787  }
788 }
789 //________________________________________________________________________
790 void
792 {
793  // Normalize to the acceptance -
794  // dndeta->Divide(accNorm);
795  for (Int_t i = 1; i <= copy->GetNbinsX(); i++) {
796  Double_t a = norm->GetBinContent(i);
797  if (a <= 0) {
798  copy->SetBinContent(i,0);
799  copy->SetBinError(i,0);
800  continue;
801  }
802  Double_t c = copy->GetBinContent(i);
803  Double_t e = copy->GetBinError(i);
804  copy->SetBinContent(i, c / a);
805  copy->SetBinError(i, e / a);
806  }
807 }
808 
809 //________________________________________________________________________
810 TH1D*
812  const char* name,
813  Int_t firstbin,
814  Int_t lastbin,
815  bool useRoot,
816  bool corr,
817  bool error)
818 {
819  //
820  // Project onto the X axis
821  //
822  // Parameters:
823  // h 2D histogram
824  // name New name
825  // firstbin First bin to use
826  // lastbin Last bin to use
827  // error Whether to calculate errors
828  //
829  // Return:
830  // Newly created histogram or null
831  //
832  if (!h) return 0;
833  if (useRoot)
834  return h->ProjectionX(name, firstbin, lastbin, (error ? "e" : ""));
835 
836  const TAxis* xaxis = h->GetXaxis();
837  const TAxis* yaxis = h->GetYaxis();
838  TH1D* ret = new TH1D(name, h->GetTitle(), xaxis->GetNbins(),
839  xaxis->GetXmin(), xaxis->GetXmax());
840  static_cast<const TAttLine*>(h)->Copy(*ret);
841  static_cast<const TAttFill*>(h)->Copy(*ret);
842  static_cast<const TAttMarker*>(h)->Copy(*ret);
843  ret->GetXaxis()->ImportAttributes(xaxis);
844 
845  Int_t first = firstbin;
846  Int_t last = lastbin;
847  if (first < 0) first = 1;
848  else if (first >= yaxis->GetNbins()+2) first = yaxis->GetNbins()+1;
849  if (last < 0) last = yaxis->GetNbins();
850  else if (last >= yaxis->GetNbins()+2) last = yaxis->GetNbins()+1;
851  if (last-first < 0) {
852  AliWarningGeneral("AliBasedNdetaTask",
853  Form("Nothing to project [%d,%d]", first, last));
854  return 0;
855 
856  }
857 
858  // Loop over X bins
859  //DMSG(fDebug,3,"Projecting bins [%d,%d] of %s", first, last, h->GetName()));
860  Int_t ybins = (last-first+1);
861  for (Int_t xbin = 0; xbin <= xaxis->GetNbins()+1; xbin++) {
862  Double_t content = 0;
863  Double_t error2 = 0;
864  Int_t nbins = 0;
865 
866 
867  for (Int_t ybin = first; ybin <= last; ybin++) {
868  Double_t c1 = h->GetBinContent(h->GetBin(xbin, ybin));
869  Double_t e1 = h->GetBinError(h->GetBin(xbin, ybin));
870 
871  // Ignore empty bins
872  if (c1 < 1e-12) continue;
873  if (e1 < 1e-12) {
874  if (error) continue;
875  e1 = 1;
876  }
877 
878  content += c1;
879  error2 += e1*e1;
880  nbins++;
881  } // for (ybin)
882  if(content > 0 && nbins > 0) {
883  Double_t factor = (corr ? Double_t(ybins) / nbins : 1);
884 #if 0
885  AliWarningGeneral(ret->GetName(),
886  Form("factor @ %d is %d/%d -> %f",
887  xbin, ybins, nbins, factor));
888 #endif
889  if (error) {
890  // Calculate weighted average
891  ret->SetBinContent(xbin, content * factor);
892  ret->SetBinError(xbin, factor * TMath::Sqrt(error2));
893  }
894  else
895  ret->SetBinContent(xbin, factor * content);
896  }
897  } // for (xbin)
898 
899  return ret;
900 }
901 
902 //________________________________________________________________________
903 Bool_t
905 {
906  //
907  // Called at end of event processing..
908  //
909  // This is called once in the master
910  //
911  // Parameters:
912  // option Not used
913  //
914  // Draw result to screen, or perform fitting, normalizations Called
915  // once at the end of the query
916  DGUARD(fDebug,1,"Process final merged results");
917 
918  UShort_t sNN;
919  UShort_t sys;
920  ULong_t trig;
921  ULong_t filter;
922  UShort_t scheme;
923  Int_t centID;
924  AliForwardUtil::GetParameter(fSums->FindObject("sNN"), sNN);
925  AliForwardUtil::GetParameter(fSums->FindObject("sys"), sys);
926  AliForwardUtil::GetParameter(fSums->FindObject("trigger"), trig);
927  AliForwardUtil::GetParameter(fSums->FindObject("filter"), filter);
928  AliForwardUtil::GetParameter(fSums->FindObject("scheme"), scheme);
929  AliForwardUtil::GetParameter(fSums->FindObject("centEstimator"), centID);
930 
931  TH1* cH = static_cast<TH1*>(fSums->FindObject("centAxis"));
932  Info("", "centAxis: %p (%s)", cH, (cH ? cH->ClassName() : "null"));
933  // TAxis* cA = static_cast<TAxis*>(fSums->FindObject("centAxis"));
934  TAxis* cA = (cH ? cH->GetXaxis() : 0);
935  if (cA) cA->Copy(fCentAxis);
936  fCentAxis.SetName("centAxis");
937  fCentAxis.SetTitle("Centrality [%]");
938 
939  // (Re)Create our centrality bins
941 
942  // Print before we loop
943  Print();
944 
945  // Loop over centrality bins
946  TIter next(fListOfCentralities);
947  CentralityBin* bin = 0;
948  gStyle->SetPalette(1);
949  THStack* dndetaStack = new THStack("dndeta", "dN/d#eta");
950  THStack* dndetaMCStack = new THStack("dndetaMC", "dN_{ch}/d#eta");
951  THStack* dndetaEmpStack = new THStack("dndetaEmp", "dN_{ch}/d#eta");
952  THStack* leftRightStack = new THStack("leftRight", "#eta>0/#eta<0");
953 
954  TList* mclist = 0;
955  TList* truthlist = 0;
956 
957  if (fFinalMCCorrFile.Contains(".root")) {
959  TFile* ftest = TFile::Open(fFinalMCCorrFile.Data());
960  if(ftest) {
961  mclist = dynamic_cast<TList*>(ftest->Get(Form("%sResults",GetName())));
962  truthlist = dynamic_cast<TList*>(ftest->Get("MCTruthResults"));
963  }
964  else
965  AliWarning("MC analysis file invalid - no final MC correction possible");
966  }
967  Int_t style = GetMarker();
968  Int_t color = GetColor();
969 
970  DMSG(fDebug,3,"Marker style=%d, color=%d", style, color);
971  while ((bin = static_cast<CentralityBin*>(next()))) {
974  style, color, mclist, truthlist);
975  if (HasCentrality() && bin->IsAllBin()) {
976  // If we have centrality bins, do not add the min-bias
977  // distribution to the output stack.
978  AliWarning("Skipping MB bin since we have centrality");
979  continue;
980  }
981  TH1* dndeta = bin->GetResult("");
982  TH1* dndetaMC = bin->GetResult("MC", false);
983  TH1* dndetaEmp = bin->GetResult("Emp", false);
984  TH1* leftRight = Asymmetry(dndetaEmp ? dndetaEmp : dndeta);
985  // if (leftRight) bin->fOutput->Add(leftRight);
986  DMSG(fDebug,2,"Results: bare=%p mcbare=%p", dndeta, dndetaMC);
987  if (dndeta) dndetaStack->Add(dndeta);
988  if (dndetaMC) dndetaMCStack->Add(dndetaMC);
989  if (dndetaEmp) dndetaEmpStack->Add(dndetaEmp);
990  if (leftRight) leftRightStack->Add(leftRight);
991  }
992  // Output the stack
993  fResults->Add(dndetaStack);
994 
995  // If available, output track-ref stack
996  if (!dndetaMCStack->GetHists() ||
997  dndetaMCStack->GetHists()->GetEntries() <= 0) {
998  // AliWarning("No MC histograms found");
999  delete dndetaMCStack;
1000  dndetaMCStack = 0;
1001  }
1002  if (dndetaMCStack) fResults->Add(dndetaMCStack);
1003 
1004  // If available, output track-ref stack
1005  DMSG(0,fDebug,"Emp stack: %p (%d)", dndetaEmpStack,
1006  dndetaEmpStack->GetHists() && dndetaEmpStack->GetHists()->GetEntries()
1007  ? dndetaEmpStack->GetHists()->GetEntries() : -1);
1008  if (!dndetaEmpStack->GetHists() ||
1009  dndetaEmpStack->GetHists()->GetEntries() <= 0) {
1010  // AliWarning("No MC histograms found");
1011  delete dndetaEmpStack;
1012  dndetaEmpStack = 0;
1013  }
1014  if (dndetaEmpStack) fResults->Add(dndetaEmpStack);
1015 
1016 
1017  // If available, output track-ref stack
1018  if (!leftRightStack->GetHists() ||
1019  leftRightStack->GetHists()->GetEntries() <= 0) {
1020  // AliWarning("No MC histograms found");
1021  delete leftRightStack;
1022  leftRightStack = 0;
1023  }
1024  if (leftRightStack) fResults->Add(leftRightStack);
1025 
1026  // Output collision energy string
1027  if (sNN > 0) {
1028  TNamed* sNNObj = new TNamed("sNN",
1030  sNNObj->SetUniqueID(sNN);
1031  fResults->Add(sNNObj);
1032  }
1033 
1034  // Output collision system string
1035  if (sys > 0) {
1036  TNamed* sysObj = new TNamed("sys",
1038  sysObj->SetUniqueID(sys);
1039  fResults->Add(sysObj);
1040  }
1041 
1042  // Output centrality axis
1043  TNamed* centEstimator = new TNamed("centEstimator", fCentMethod.Data());
1044  centEstimator->SetUniqueID(centID);
1045  fResults->Add(&fCentAxis);
1046  fResults->Add(centEstimator);
1047  fResults->Add(AliForwardUtil::MakeParameter("absMinCent", fAbsMinCent));
1048 
1049  // Output trigger string
1050  if (trig) {
1051  TNamed* maskObj = new TNamed("trigger",
1053  maskObj->SetUniqueID(trig);
1054  fResults->Add(maskObj);
1055  }
1056  // Output filter string
1057  if (filter) {
1058  TNamed* maskObj = new TNamed("filter",
1060  " | "));
1061  maskObj->SetUniqueID(filter);
1062  fResults->Add(maskObj);
1063  }
1064 
1065  // Normalization string
1066  if (scheme > 0) {
1067  TNamed* schemeObj = new TNamed("scheme",
1068  NormalizationSchemeString(scheme));
1069  schemeObj->SetUniqueID(scheme);
1070  fResults->Add(schemeObj);
1071  }
1072 
1073  // Output vertex axis
1074  fIPzAxis.SetName("vtxAxis");
1075  fIPzAxis.SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm",
1076  fIPzAxis.GetXmin(),
1077  fIPzAxis.GetXmax()));
1078  TAxis* ipzAxis = static_cast<TAxis*>(fIPzAxis.Clone());
1079  fResults->Add(ipzAxis);
1080 
1081  // Output trigger efficiency
1082  fResults->Add(AliForwardUtil::MakeParameter("triggerEff", fTriggerEff));
1083  fResults->Add(AliForwardUtil::MakeParameter("triggerEff0", fTriggerEff0));
1084 
1085  TNamed* options = new TNamed("options","");
1086  TString str;
1087  str.Append(Form("Empty bins %scorrected for, ", fCorrEmpty ? "" : "not "));
1088  str.Append(Form("TH2::ProjectionX %sused", fUseROOTProj ? "" : "not "));
1089  options->SetTitle(str);
1090  fResults->Add(options);
1091 
1092  TObject* sumVsC = fSums->FindObject("sumVsC");
1093  if (sumVsC) {
1094  fMeanVsC = static_cast<TProfile*>(sumVsC->Clone());
1095  fMeanVsC->SetDirectory(0);
1096  fResults->Add(fMeanVsC);
1097  }
1098 
1099  return true;
1100 }
1101 
1102 #define PF(N,V,...) \
1103  AliForwardUtil::PrintField(N,V, ## __VA_ARGS__)
1104 #define PFB(N,FLAG) \
1105  do { \
1106  AliForwardUtil::PrintName(N); \
1107  std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
1108  } while(false)
1109 #define PFV(N,VALUE) \
1110  do { \
1111  AliForwardUtil::PrintName(N); \
1112  std::cout << (VALUE) << std::endl; } while(false)
1113 #if 0
1114 namespace {
1115  void appendBit(TString& str, const char* bit)
1116  {
1117  if (!str.IsNull()) str.Append("|");
1118  str.Append(bit);
1119  }
1120 }
1121 #endif
1122 
1123 //________________________________________________________________________
1124 void
1126 {
1127  //
1128  // Print information
1129  //
1130  AliBaseAODTask::Print(option);
1132 
1133  gROOT->IncreaseDirLevel();
1134  PFB("Use AnaUtil pile-up", fUseUtilPileup);
1135  PFB("Use TH2::ProjectionX", fUseROOTProj);
1136  PFB("Correct for empty", fCorrEmpty);
1137  PFV("Normalization scheme", schemeString );
1138  PFV("Trigger efficiency", fTriggerEff);
1139  PFV("Bin-0 Trigger efficiency", fTriggerEff0);
1140  PFV("Centrality estimator", (fCentMethod.IsNull() ?
1141  "-default-" : fCentMethod.Data()));
1142  PFB("Re-weight from IPz", fIpzReweight!=0);
1143  if (fIpzReweight) fIpzReweight->Print();
1144 
1145 
1146  TString opt(option);
1147  opt.ToUpper();
1148  if (opt.Contains("R") &&
1150  fListOfCentralities->GetEntries() > 0) {
1151  TIter next(fListOfCentralities);
1152  TObject* bin = 0;
1153  while ((bin = next())) bin->Print(option);
1154  }
1155  gROOT->DecreaseDirLevel();
1156 }
1157 
1158 //__________________________________________________________________
1159 Int_t
1161 {
1162  Int_t base = bits & (0xFE);
1163  Bool_t hollow = bits & kHollow;
1164  switch (base) {
1165  case kCircle: return (hollow ? 24 : 20);
1166  case kSquare: return (hollow ? 25 : 21);
1167  case kUpTriangle: return (hollow ? 26 : 22);
1168  case kDownTriangle: return (hollow ? 32 : 23);
1169  case kDiamond: return (hollow ? 27 : 33);
1170  case kCross: return (hollow ? 28 : 34);
1171  case kStar: return (hollow ? 30 : 29);
1172  }
1173  return 1;
1174 }
1175 //__________________________________________________________________
1176 UShort_t
1178 {
1179  UShort_t bits = 0;
1180  switch (style) {
1181  case 24: case 25: case 26: case 27: case 28: case 30: case 32:
1182  bits |= kHollow; break;
1183  }
1184  switch (style) {
1185  case 20: case 24: bits |= kCircle; break;
1186  case 21: case 25: bits |= kSquare; break;
1187  case 22: case 26: bits |= kUpTriangle; break;
1188  case 23: case 32: bits |= kDownTriangle; break;
1189  case 27: case 33: bits |= kDiamond; break;
1190  case 28: case 34: bits |= kCross; break;
1191  case 29: case 30: bits |= kStar; break;
1192  }
1193  return bits;
1194 }
1195 //__________________________________________________________________
1196 Int_t
1198 {
1199  UShort_t bits = GetMarkerBits(style);
1200  Int_t ret = GetMarkerStyle(bits ^ kHollow);
1201  return ret;
1202 }
1203 
1204 //====================================================================
1205 void
1207 {
1208  DGUARD(fDebug,1,"Initializing sums with %s", data->GetName());
1209  TString n(GetHistName(0));
1210  TString n0(GetHistName(1));
1211  const char* postfix = GetTitle();
1212 
1213  fSum = static_cast<TH2D*>(data->Clone(n));
1214  if (postfix) fSum->SetTitle(Form("%s (%s)", data->GetTitle(), postfix));
1215  fSum->SetDirectory(0);
1216  fSum->SetMarkerColor(col);
1217  fSum->SetMarkerStyle(GetMarkerStyle(kCircle|kSolid));
1218  fSum->Reset();
1219  list->Add(fSum);
1220 
1221  fSum0 = static_cast<TH2D*>(data->Clone(n0));
1222  if (postfix)
1223  fSum0->SetTitle(Form("%s 0-bin (%s)", data->GetTitle(), postfix));
1224  else
1225  fSum0->SetTitle(Form("%s 0-bin", data->GetTitle()));
1226  fSum0->SetDirectory(0);
1227  fSum0->SetMarkerColor(col);
1228  fSum0->SetMarkerStyle(GetMarkerStyle(kCross|kHollow));
1229  fSum0->Reset();
1230  list->Add(fSum0);
1231 
1232  fEvents = new TH1I(GetHistName(2), "Event types", 2, -.5, 1.5);
1233  fEvents->SetDirectory(0);
1234  fEvents->SetFillColor(kRed+1);
1235  fEvents->SetFillStyle(3002);
1236  fEvents->GetXaxis()->SetBinLabel(1, "Non-zero");
1237  fEvents->GetXaxis()->SetBinLabel(2, "Zero");
1238  list->Add(fEvents);
1239 }
1240 
1241 //____________________________________________________________________
1242 TString
1244  Int_t what, const char* post)
1245 {
1246  TString n;
1247  switch (what) {
1248  case 0: n = "sum"; break;
1249  case 1: n = "sum0"; break;
1250  case 2: n = "events"; break;
1251  }
1252  if (post && post[0] != '\0') n.Append(post);
1253  return n;
1254 }
1255 
1256 //____________________________________________________________________
1257 TString
1259 {
1260  return GetHistName(GetName(), what, GetTitle());
1261 }
1262 
1263 //____________________________________________________________________
1264 void
1265 AliBasedNdetaTask::Sum::Add(const TH2D* data, Bool_t isZero, Double_t weight)
1266 {
1267  DGUARD(fDebug,2,"Adding %s to sums w/weight %f (%f)",
1268  data->GetName(),weight,data->Integral());
1269  if (isZero) fSum0->Add(data, weight);
1270  else fSum->Add(data, weight);
1271  fEvents->Fill(isZero ? 1 : 0);
1272 }
1273 
1274 //____________________________________________________________________
1275 TH2D*
1277  Double_t& ntotal,
1278  Double_t epsilon0,
1279  Double_t epsilon,
1280  Int_t marker,
1281  Bool_t rootProj,
1282  Bool_t corrEmpty) const
1283 {
1284  DGUARD(fDebug,2,"Calculating final summed histogram %s", fSum->GetName());
1285 
1286  // The return value `ret' is not scaled in anyway
1287  TH2D* ret = static_cast<TH2D*>(fSum->Clone(fSum->GetName()));
1288  ret->SetDirectory(0);
1289  Int_t n = Int_t(fEvents->GetBinContent(1));
1290  Int_t n0 = Int_t(fEvents->GetBinContent(2));
1291  ntotal = n;
1292  if (n0 > 0) {
1293  ret->Reset();
1294  DMSG(fDebug,1,
1295  "Adding histograms %s(%d) and %s(%d) w/weights %f and %f resp.",
1296  fSum0->GetName(), n, fSum->GetName(), n0, 1./epsilon,1./epsilon0);
1297  ret->Add(fSum0, fSum, 1. / epsilon0, 1. / epsilon);
1298  ntotal = n / epsilon + n0 / epsilon0;
1299  }
1300 
1301  TList* out = new TList;
1302  out->SetOwner();
1303  const char* postfix = GetTitle();
1304  if (!postfix) postfix = "";
1305  out->SetName(Form("partial%s", postfix));
1306  output->Add(out);
1307 
1308  // Now make copies, normalize them, and store in output list
1309  // Note, these are the only ones normalized here
1310  // These are mainly for diagnostics
1311  TH2D* sumCopy = static_cast<TH2D*>(fSum->Clone("sum"));
1312  TH2D* sum0Copy = static_cast<TH2D*>(fSum0->Clone("sum0"));
1313  TH2D* retCopy = static_cast<TH2D*>(ret->Clone("sumAll"));
1314  sumCopy->SetMarkerStyle(FlipHollowStyle(marker));
1315  sumCopy->SetDirectory(0);
1316  sum0Copy->SetMarkerStyle(GetMarkerStyle(GetMarkerBits(marker)+4));
1317  sum0Copy->SetDirectory(0);
1318  retCopy->SetMarkerStyle(marker);
1319  retCopy->SetDirectory(0);
1320 
1321  Int_t nY = fSum->GetNbinsY();
1322  Int_t o = 0; // nY+1;
1323  TH1D* norm = ProjectX(fSum, "norm", o, o, rootProj, corrEmpty, false);
1324  TH1D* norm0 = ProjectX(fSum0, "norm0", o, o, rootProj, corrEmpty, false);
1325  TH1D* normAll = ProjectX(ret, "normAll", o, o, rootProj, corrEmpty, false);
1326  norm->SetTitle("#eta coverage - >0-bin");
1327  norm0->SetTitle("#eta coverage - 0-bin");
1328  normAll->SetTitle("#eta coverage");
1329  norm->SetDirectory(0);
1330  norm0->SetDirectory(0);
1331  normAll->SetDirectory(0);
1332 
1333  TH1D* sumCopyPx = ProjectX(sumCopy, "average", 1,nY,rootProj,corrEmpty);
1334  TH1D* sum0CopyPx = ProjectX(sum0Copy, "average0", 1,nY,rootProj,corrEmpty);
1335  TH1D* retCopyPx = ProjectX(retCopy, "averageAll", 1,nY,rootProj,corrEmpty);
1336  sumCopyPx-> SetTitle(Form("#sum_{i}^{N_{#phi}}%s", sumCopy->GetTitle()));
1337  sum0CopyPx->SetTitle(Form("#sum_{i}^{N_{#phi}}%s", sum0Copy->GetTitle()));
1338  retCopyPx-> SetTitle(Form("#sum_{i}^{N_{#phi}}%s", retCopy->GetTitle()));
1339  sumCopyPx-> SetDirectory(0);
1340  sum0CopyPx->SetDirectory(0);
1341  retCopyPx-> SetDirectory(0);
1342 
1343  TH1D* phi = ProjectX(fSum, "phi", nY+1,nY+1,rootProj,corrEmpty,false);
1344  TH1D* phi0 = ProjectX(fSum0, "phi0", nY+1,nY+1,rootProj,corrEmpty,false);
1345  TH1D* phiAll = ProjectX(ret, "phiAll", nY+1,nY+1,rootProj,corrEmpty,false);
1346  phi ->SetTitle("#phi acceptance from dead strips - >0-bin");
1347  phi0 ->SetTitle("#phi acceptance from dead strips - 0-bin");
1348  phiAll->SetTitle("#phi acceptance from dead strips");
1349  phi ->SetDirectory(0);
1350  phi0 ->SetDirectory(0);
1351  phiAll->SetDirectory(0);
1352 
1353  const TH1D* cov = (corrEmpty ? norm : phi);
1354  const TH1D* cov0 = (corrEmpty ? norm0 : phi0);
1355  const TH1D* covAll = (corrEmpty ? normAll : phiAll);
1356 
1357  // Here, we scale to the coverage (or phi acceptance)
1358  ScaleToCoverage(sumCopy, cov);
1359  ScaleToCoverage(sum0Copy, cov0);
1360  ScaleToCoverage(retCopy, covAll);
1361 
1362  // Scale our 1D histograms
1363  sumCopyPx ->Scale(1., "width");
1364  sum0CopyPx->Scale(1., "width");
1365  retCopyPx ->Scale(1., "width");
1366 
1367  DMSG(fDebug,2,"Maximum %f,%f changed to %f", sumCopyPx->GetMaximum(),
1368  sum0CopyPx->GetMaximum(), retCopyPx->GetMaximum());
1369 
1370  // Scale the normalization - they should be 1 at the maximum
1371  norm ->Scale(n > 0 ? 1. / n : 1);
1372  norm0 ->Scale(n0 > 0 ? 1. / n0 : 1);
1373  normAll->Scale(ntotal > 0 ? 1. / ntotal : 1);
1374 
1375  // Scale the normalization - they should be 1 at the maximum
1376  phi ->Scale(n > 0 ? 1. / n : 1);
1377  phi0 ->Scale(n0 > 0 ? 1. / n0 : 1);
1378  phiAll->Scale(ntotal > 0 ? 1. / ntotal : 1);
1379 
1380  out->Add(sumCopy);
1381  out->Add(sum0Copy);
1382  out->Add(retCopy);
1383  out->Add(sumCopyPx);
1384  out->Add(sum0CopyPx);
1385  out->Add(retCopyPx);
1386  out->Add(norm);
1387  out->Add(norm0);
1388  out->Add(normAll);
1389  out->Add(phi);
1390  out->Add(phi0);
1391  out->Add(phiAll);
1392 
1393  if (fDebug >= 1) {
1394  if (n0 > 0)
1395  DMSG(fDebug,1,"Returning (1/%f * %s + 1/%f * %s), "
1396  "1/%f * %d + 1/%f * %d = %d",
1397  epsilon0, fSum0->GetName(), epsilon, fSum->GetName(),
1398  epsilon0, n0, epsilon, n, int(ntotal));
1399  else
1400  DMSG(fDebug,1, "Returning %s, %d", fSum->GetName(), int(ntotal));
1401  }
1402 
1403 #if 0
1404  for (Int_t i = 1; i <= ret->GetNbinsX(); i++) {
1405  Double_t nc = sum->GetBinContent(i, 0);
1406  Double_t nc0 = sum0->GetBinContent(i, 0);
1407  ret->SetBinContent(i, 0, nc + nc0); // Just count events
1408  }
1409 #endif
1410 
1411  return ret;
1412 }
1413 //____________________________________________________________________
1414 void
1416 {
1417  PFV("dN/deta sum bin", GetName());
1418  gROOT->IncreaseDirLevel();
1419  PF("Normal sum", "%s (%p)", GetHistName(0).Data(), fSum);
1420  PF("0-bin sum", "%s (%p)", GetHistName(1).Data(), fSum0);
1421  PF("Event count","%s (%p)", GetHistName(2).Data(), fEvents);
1422  gROOT->DecreaseDirLevel();
1423 }
1424 
1425 //====================================================================
1427  : TNamed("", ""),
1428  fSums(0),
1429  fOutput(0),
1430  fSum(0),
1431  fSumMC(0),
1432  fTriggers(0),
1433  fStatus(0),
1434  fLow(0),
1435  fHigh(0),
1436  fDoFinalMCCorrection(false),
1437  fSatelliteVertices(false),
1438  fDebug(0)
1439 {
1440  //
1441  // Constructor
1442  //
1443  DGUARD(fDebug,3,"Default CTOR of AliBasedNdeta::CentralityBin");
1444 }
1445 #define TRUNC(X) (Int_t(X) + Float_t(Int_t(X*100)%100)/100)
1446 
1447 //____________________________________________________________________
1449  Float_t low, Float_t high)
1450  : TNamed(name, ""),
1451  fSums(0),
1452  fOutput(0),
1453  fSum(0),
1454  fSumMC(0),
1455  fTriggers(0),
1456  fStatus(0),
1457  fLow(TRUNC(low)),
1458  fHigh(TRUNC(high)),
1459  fDoFinalMCCorrection(false),
1460  fSatelliteVertices(false),
1461  fDebug(0)
1462 {
1463  //
1464  // Constructor
1465  //
1466  // Parameters:
1467  // name Name used for histograms (e.g., Forward)
1468  // low Lower centrality cut in percent
1469  // high Upper centrality cut in percent
1470  //
1471  DGUARD(fDebug,3,"Named CTOR of AliBasedNdeta::CentralityBin: "
1472  "%s [%6.2f,%6.2f]",name, fLow, fHigh);
1473  if (low <= 0 && high <= 0) {
1474  fLow = 0;
1475  fHigh = 0;
1476  SetTitle("All centralities");
1477  }
1478  else {
1479  fLow = TRUNC(low);
1480  fHigh = TRUNC(high);
1481  SetTitle(Form("Centrality bin from %6.2f%% to %6.2f%%", low, high));
1482  }
1483 }
1484 //____________________________________________________________________
1486  : TNamed(o),
1487  fSums(o.fSums),
1488  fOutput(o.fOutput),
1489  fSum(o.fSum),
1490  fSumMC(o.fSumMC),
1491  fTriggers(o.fTriggers),
1492  fStatus(o.fStatus),
1493  fLow(o.fLow),
1494  fHigh(o.fHigh),
1495  fDoFinalMCCorrection(o.fDoFinalMCCorrection),
1497  fDebug(o.fDebug)
1498 {
1499  //
1500  // Copy constructor
1501  //
1502  // Parameters:
1503  // other Object to copy from
1504  //
1505  DGUARD(fDebug,3,"Copy CTOR of AliBasedNdeta::CentralityBin");
1506 }
1507 //____________________________________________________________________
1509 {
1510  //
1511  // Destructor
1512  //
1513  DGUARD(fDebug,3,"DTOR of AliBasedNdeta::CentralityBin");
1514 
1515  // if (fSums) fSums->Delete();
1516  // if (fOutput) fOutput->Delete();
1517 }
1518 
1519 //____________________________________________________________________
1522 {
1523  //
1524  // Assignment operator
1525  //
1526  // Parameters:
1527  // other Object to assign from
1528  //
1529  // Return:
1530  // Reference to this
1531  //
1532  DGUARD(fDebug,3,"Centrality bin assignment");
1533  if (&o == this) return *this;
1534  SetName(o.GetName());
1535  SetTitle(o.GetTitle());
1536  fSums = o.fSums;
1537  fOutput = o.fOutput;
1538  fSum = o.fSum;
1539  fSumMC = o.fSumMC;
1540  fTriggers = o.fTriggers;
1541  fStatus = o.fStatus;
1542  fLow = o.fLow;
1543  fHigh = o.fHigh;
1544  fDoFinalMCCorrection = o.fDoFinalMCCorrection;
1546 
1547  return *this;
1548 }
1549 #if 0
1550 namespace {
1551  Color_t Brighten(Color_t origNum, Int_t nTimes=2)
1552  {
1553  TColor* col = gROOT->GetColor(origNum);
1554  if (!col) return origNum;
1555  Int_t origR = Int_t(0xFF * col->GetRed());
1556  Int_t origG = Int_t(0xFF * col->GetGreen());
1557  Int_t origB = Int_t(0xFF * col->GetBlue());
1558  Int_t off = nTimes*0x33;
1559  Int_t newR = TMath::Min((origR+off),0xff);
1560  Int_t newG = TMath::Min((origG+off),0xff);
1561  Int_t newB = TMath::Min((origB+off),0xff);
1562  Int_t newNum = TColor::GetColor(newR, newG, newB);
1563  return newNum;
1564  }
1565 }
1566 #endif
1567 //____________________________________________________________________
1568 Int_t
1570 {
1571  return fColor;
1572 #if 0
1573  if (IsAllBin()) return kBlack; // fallback;
1574  Float_t fc = /*(fLow+double(fHigh-fLow)/2)*/ fHigh / 100;
1575  Int_t nCol = gStyle->GetNumberOfColors();
1576  Int_t icol = TMath::Min(nCol-1,int(fc * nCol + .5));
1577  Int_t col = gStyle->GetColorPalette(icol);
1578 #if 0
1579  Color_t orig = col;
1580  col = Brighten(orig);
1581 #endif
1582  return col;
1583 #endif
1584 }
1585 
1586 //____________________________________________________________________
1587 const char*
1589 {
1590  //
1591  // Get the list name
1592  //
1593  // Return:
1594  // List Name
1595  //
1596  if (IsAllBin()) return "all";
1597  return Form("cent%03dd%02d_%03dd%02d",
1598  Int_t(fLow), Int_t(fLow*100) % 100,
1599  Int_t(fHigh), Int_t(fHigh*100) % 100);
1600 
1601 }
1602 //____________________________________________________________________
1603 void
1605 {
1606  //
1607  // Create output objects
1608  //
1609  // Parameters:
1610  // dir Parent list
1611  //
1612  DGUARD(fDebug,1,"Create centrality bin output objects");
1613  fSums = new TList;
1614  fSums->SetName(GetListName());
1615  fSums->SetOwner();
1616  dir->Add(fSums);
1617 
1619  fTriggers->SetDirectory(0);
1620 
1621  fStatus = AliAODForwardMult::MakeStatusHistogram("status");
1622  fStatus->SetDirectory(0);
1623 
1624  fSums->Add(fTriggers);
1625  fSums->Add(fStatus);
1626 
1627  fSums->Add(new TParameter<float>("low", fLow, 'f'));
1628  fSums->Add(new TParameter<float>("high", fHigh, 'f'));
1629 }
1630 //____________________________________________________________________
1631 void
1633 {
1634  fDebug = lvl;
1635  if (fSum) fSum->fDebug = lvl;
1636  if (fSumMC) fSumMC->fDebug = lvl;
1637 }
1638 
1639 //____________________________________________________________________
1640 Bool_t
1642 {
1643  const char* post = (mc ? "MC" : "");
1644  TString sn = Sum::GetHistName(GetName(),0,post);
1645  TString sn0 = Sum::GetHistName(GetName(),1,post);
1646  TString ev = Sum::GetHistName(GetName(),2,post);
1647  TH2D* sum = static_cast<TH2D*>(list->FindObject(sn));
1648  TH2D* sum0 = static_cast<TH2D*>(list->FindObject(sn0));
1649  TH1I* events = static_cast<TH1I*>(list->FindObject(ev));
1650  if (!sum || !sum0 || !events) {
1651  if (!mc)
1652  AliWarningF("Failed to find one or more histograms: "
1653  "%s (%p) %s (%p) %s (%p)",
1654  sn.Data(), sum,
1655  sn0.Data(), sum0,
1656  ev.Data(), events);
1657  return false;
1658  }
1659  Sum* ret = new Sum(GetName(), post);
1660  ret->fSum = sum;
1661  ret->fSum0 = sum0;
1662  ret->fEvents = events;
1663  ret->fDebug = fDebug;
1664  if (mc) fSumMC = ret;
1665  else fSum = ret;
1666 
1667  return true;
1668 }
1669 
1670 //____________________________________________________________________
1671 void
1673 {
1674  //
1675  // Create sum histogram
1676  //
1677  // Parameters:
1678  // data Data histogram to clone
1679  // mc (optional) MC histogram to clone
1680  //
1681  DGUARD(fDebug,1,"Create centrality bin sums from %s",
1682  data ? data->GetName() : "(null)");
1683  if (data) {
1684  fSum = new Sum(GetName(),"");
1685  fSum->Init(fSums, data, GetColor());
1686  fSum->fDebug = fDebug;
1687  }
1688 
1689  // If no MC data is given, then do not create MC sum histogram
1690  if (!mc) return;
1691 
1692  fSumMC = new Sum(GetName(), "MC");
1693  fSumMC->Init(fSums, mc, GetColor());
1694  fSumMC->fDebug = fDebug;
1695 }
1696 
1697 //____________________________________________________________________
1698 Bool_t
1700  Int_t triggerMask,
1701  Double_t vzMin,
1702  Double_t vzMax,
1703  Int_t filter)
1704 {
1705  //
1706  // Check the trigger, vertex, and centrality
1707  //
1708  // Parameters:
1709  // aod Event input
1710  //
1711  // Return:
1712  // true if the event is to be used
1713  //
1714  if (!forward) return false;
1715 
1716  DGUARD(fDebug,2,"Check the event "
1717  "IPz: %f < %f < %f Trigger: 0x%08x (masked 0x%08x vetoed 0x%08x)",
1718  vzMin, forward->GetIpZ(), vzMax,
1719  forward->GetTriggerBits(),
1720  forward->GetTriggerBits() & triggerMask,
1721  forward->GetTriggerBits() & filter);
1722  // We do not check for centrality here - it's already done
1723  Bool_t ret = forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0,
1724  fTriggers, fStatus, filter);
1725  DMSG(fDebug, 2, "%s", (ret ? "Accepted" : "Rejected"));
1726  return ret;
1727 }
1728 
1729 
1730 //____________________________________________________________________
1731 Bool_t
1733  UInt_t triggerMask,
1734  Bool_t isZero,
1735  Double_t vzMin,
1736  Double_t vzMax,
1737  const TH2D* data,
1738  const TH2D* mc,
1739  UInt_t filter,
1740  Double_t weight)
1741 {
1742  //
1743  // Process an event
1744  //
1745  // Parameters:
1746  // forward Forward data (for trigger, vertex, & centrality)
1747  // triggerMask Trigger mask
1748  // vzMin Minimum IP z coordinate
1749  // vzMax Maximum IP z coordinate
1750  // data Data histogram
1751  // mc MC histogram
1752  // weight Event weight
1753  //
1754  DGUARD(fDebug,1,"Process one event for %s a given centrality bin "
1755  "[%5.1f%%,%5.1f%%) w/weight %f",
1756  data ? data->GetName() : "(null)", fLow, fHigh, weight);
1757  if (!CheckEvent(forward, triggerMask, vzMin, vzMax, filter))
1758  return false;
1759  if (!data) return false;
1760  if (!fSum) CreateSums(data, mc);
1761 
1762  fSum->Add(data, isZero, weight);
1763  if (mc) fSumMC->Add(mc, isZero, weight);
1764 
1765  return true;
1766 }
1767 
1768 //________________________________________________________________________
1769 Double_t
1771  UShort_t scheme,
1772  Double_t trigEff,
1773  Double_t& ntotal,
1774  TString* text) const
1775 {
1776  //
1777  // Calculate normalization
1778  //
1779  // Parameters:
1780  // t Trigger histogram
1781  // scheme Normaliztion scheme
1782  // trigEff From MC
1783  // ntotal On return, contains the number of events.
1784  //
1785  DGUARD(fDebug,1,"Normalize centrality bin %s [%6.2f-%6.2f%%] with %s",
1786  GetName(), fLow, fHigh, t.GetName());
1787  Double_t nAll = t.GetBinContent(AliAODForwardMult::kBinAll);
1788  Double_t nB = t.GetBinContent(AliAODForwardMult::kBinB);
1789  Double_t nA = t.GetBinContent(AliAODForwardMult::kBinA);
1790  Double_t nC = t.GetBinContent(AliAODForwardMult::kBinC);
1791  Double_t nE = t.GetBinContent(AliAODForwardMult::kBinE);
1792  Double_t nOffline = t.GetBinContent(AliAODForwardMult::kBinOffline);
1793  Double_t nTriggered = t.GetBinContent(AliAODForwardMult::kWithTrigger);
1794  Double_t nWithVertex = t.GetBinContent(AliAODForwardMult::kWithVertex);
1795  Double_t nAccepted = ntotal;
1796  ntotal = 0;
1797 
1798  if (nTriggered <= 0.1) {
1799  AliError("Number of triggered events <= 0");
1800  return -1;
1801  }
1802  if (nWithVertex <= 0.1) {
1803  AliError("Number of events with vertex <= 0");
1804  return -1;
1805  }
1806  ntotal = nAccepted;
1807  Double_t vtxEff = nWithVertex / nTriggered;
1808  Double_t scaler = 1;
1809  Double_t beta = nA + nC - 2*nE;
1810 
1811 
1812  TString rhs("N = N_acc");
1813  if (!(scheme & kZeroBin)) {
1814  if (scheme & kEventLevel) {
1815  ntotal = nAccepted / vtxEff;
1816  scaler = vtxEff;
1817  DMSG(fDebug,0,"Calculating event normalisation as\n"
1818  " N = N_A * N_T / N_V = %d * %d / %d = %f (%f)",
1819  Int_t(nAccepted), Int_t(nTriggered), Int_t(nWithVertex),
1820  ntotal, scaler);
1821  if (scheme & kBackground) {
1822  // 1 E_V E_V
1823  // s = --------- = ------------- = ------------
1824  // 1 - beta 1 - beta E_V 1 - beta N_V
1825  // --- ---- -------- ---- ---
1826  // E_V N_V N_V N_V N_T
1827  //
1828  // E_V
1829  // = ------------
1830  // 1 - beta
1831  // ----
1832  // N_T
1833  //
1834  ntotal -= nAccepted * beta / nWithVertex;
1835  // This one is direct and correct.
1836  // scaler = 1. / (1. / vtxEff - beta / nWithVertex);
1837  // A simpler expresion
1838  scaler /= (1 - beta / nTriggered); // 0.831631 -> 0.780689
1839  DMSG(fDebug,0,"Calculating event normalisation as\n"
1840  " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1841  " N = N - N_A * beta / N_V = %f - %d * %d / %d = %f (%f)",
1842  Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1843  nAccepted / vtxEff, Int_t(nAccepted), Int_t(beta),
1844  Int_t(nWithVertex), ntotal, scaler);
1845  rhs.Append("(1/eps_V - beta/N_vtx)");
1846  } // Background
1847  else
1848  rhs.Append("/eps_V");
1849  } // Event-level
1850  if (scheme & kTriggerEfficiency) {
1851  Int_t old = Int_t(ntotal);
1852  ntotal /= trigEff;
1853  scaler *= trigEff;
1854  DMSG(fDebug,0,"Correcting for trigger efficiency:\n"
1855  " N = 1 / E_X * N = 1 / %f * %d = %f (%f)",
1856  trigEff, old, ntotal, scaler);
1857  rhs.Append("/eps_T");
1858  } // Trigger efficiency
1859  }
1860  else {
1861  // Calculate as
1862  //
1863  // N = N_A + 1/E_X * N_A / N_V (N_T - N_V - beta)
1864  // = N_A (1 + 1/E_X (N_T/N_V - 1 - beta / N_V))
1865  // = N_A (1 + 1/E_X (1/E_V - 1 - beta / N_V))
1866  //
1867  // s = N_A/N = 1 / (1 + 1/E_X (N_T/N_V - 1 - beta / N_V))
1868  // = N_V / (N_V + 1/E_X (N_T - N_V - beta))
1869  //
1870  if (!(scheme & kBackground)) beta = 0;
1871  ntotal = nAccepted * (1 + 1/trigEff * (nTriggered / nWithVertex - 1
1872  - beta / nWithVertex));
1873  scaler = nWithVertex / (nWithVertex +
1874  1/trigEff * (nTriggered-nWithVertex-beta));
1875  DMSG(fDebug,0,"Calculating event normalisation as\n"
1876  " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1877  " N = N_A (1 + 1/E_X (N_T/N_V - 1 - beta / N_V)) = "
1878  "%d (1 + 1 / %f (%d / %d - 1 - %d / %d)) = %f (%f)",
1879  Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1880  Int_t(nAccepted), trigEff, Int_t(nTriggered),
1881  Int_t(nWithVertex), Int_t(beta), Int_t(nWithVertex),
1882  ntotal, scaler);
1883  rhs.Append("(1+1/eps_T(1/eps_V-1-beta/N_vtx))");
1884  }
1885 
1886  if (text) {
1887  text->Append(Form("%-40s = %d\n", "N_all", UInt_t(nAll)));
1888  text->Append(Form("%-40s = %d\n", "N_acc", UInt_t(nAccepted)));
1889  text->Append(Form("%-40s = %d\n", "N_trg", UInt_t(nTriggered)));
1890  text->Append(Form("%-40s = %d\n", "N_vtx", UInt_t(nWithVertex)));
1891  text->Append(Form("%-40s = %d\n", "N_B", UInt_t(nB)));
1892  text->Append(Form("%-40s = %d\n", "N_A", UInt_t(nA)));
1893  text->Append(Form("%-40s = %d\n", "N_C", UInt_t(nC)));
1894  text->Append(Form("%-40s = %d\n", "N_E", UInt_t(nE)));
1895  text->Append(Form("%-40s = %d\n", "beta = N_A + N_C - 2N_E",UInt_t(beta)));
1896  text->Append(Form("%-40s = %f\n", "eps_V = N_vtx/N_trg",vtxEff));
1897  text->Append(Form("%-40s = %f\n", "eps_T", trigEff));
1898  text->Append(Form("%-40s = %f\n", rhs.Data(), ntotal));
1899  }
1900  TString tN = t.GetXaxis()->GetBinLabel(AliAODForwardMult::kWithTrigger);
1901  tN.ReplaceAll("w/Selected trigger (","");
1902  tN.ReplaceAll(")", "");
1903  Int_t d = fDebug;
1904  DMSG(fDebug,0,"\n"
1905  " Total of %9d events for %s\n"
1906  " of these %9d have an offline trigger\n"
1907  " of these N_T = %9d has the selected trigger (%s)\n"
1908  " of these N_V = %9d has a vertex\n"
1909  " of these N_A = %9d were in the selected range",
1910  Int_t(nAll), GetTitle(),
1911  Int_t(nOffline),
1912  Int_t(nTriggered), tN.Data(),
1913  Int_t(nWithVertex),
1914  Int_t(nAccepted));
1915  DMSG(fDebug,0,"\n"
1916  " Triggers by hardware type:\n"
1917  " N_b = %9d\n"
1918  " N_ac = %9d (%d+%d)\n"
1919  " N_e = %9d\n"
1920  " Vertex efficiency: %f\n"
1921  " Trigger efficiency: %f\n"
1922  " Total number of events: N = %f\n"
1923  " Scaler (N_A/N): %f\n"
1924  " %-25s = %f",
1925  Int_t(nB),
1926  Int_t(nA+nC),Int_t(nA),Int_t(nC),
1927  Int_t(nE),
1928  vtxEff,
1929  trigEff,
1930  ntotal,
1931  scaler,
1932  rhs.Data(), ntotal);
1933 #if 0
1934  DMSG(d,0,"\n"
1935  " Total of %9d events for %s", Int_t(nAll), GetTitle());
1936  DMSG(d,0," of these %9d have an offline trigger", Int_t(nOffline));
1937  DMSG(d,0," of these N_T = %9d has the selected trigger (%s)",
1938  Int_t(nTriggered), tN.Data());
1939  DMSG(d,0," of these N_V = %9d has a vertex",Int_t(nWithVertex));
1940  DMSG(d,0," of these N_A = %9d were in the selected range",Int_t(nAccepted));
1941  DMSG(d,0," Triggers by hardware type:");
1942  DMSG(d,0," N_b = %9d", Int_t(nB));
1943  DMSG(d,0," N_ac = %9d (%d+%d)", Int_t(nA+nC),Int_t(nA),Int_t(nC));
1944  DMSG(d,0," N_e = %9d", Int_t(nE));
1945  DMSG(d,0," Vertex efficiency: %f",vtxEff);
1946  DMSG(d,0," Trigger efficiency: %f",trigEff);
1947  DMSG(d,0," Total number of events: N = %f",ntotal);
1948  DMSG(d,0," Scaler (N_A/N): %f",scaler);
1949  DMSG(fDebug, 0," %-25s = %f", rhs.Data(), ntotal);
1950 #endif
1951  return scaler;
1952 }
1953 
1954 //________________________________________________________________________
1955 const char*
1957 {
1958  static TString n;
1959  n = GetName();
1960  n.ReplaceAll("dNdeta", "");
1961  n.Prepend("dndeta");
1962  n.Append(postfix);
1963  return n.Data();
1964 }
1965 //________________________________________________________________________
1966 TH1*
1968  Bool_t verbose) const
1969 {
1970  if (!fOutput) {
1971  AliWarningF("No output list defined in %s [%6.2f,%6.2f]", GetName(),
1972  fLow, fHigh);
1973  return 0;
1974  }
1975  TString n = GetResultName(postfix);
1976  TObject* o = fOutput->FindObject(n.Data());
1977  if (!o) {
1978  if (verbose)
1979  AliWarningF("Object %s not found in output list of %s",
1980  n.Data(), GetName());
1981  return 0;
1982  }
1983  return static_cast<TH1*>(o);
1984 }
1985 
1986 //________________________________________________________________________
1987 void
1989  const char* postfix,
1990  bool rootProj,
1991  bool corrEmpty,
1992  Double_t scaler,
1993  Int_t marker,
1994  Int_t color,
1995  TList* mclist,
1996  TList* truthlist)
1997 {
1998  //
1999  // Generate the dN/deta result from input
2000  //
2001  // Parameters:
2002  // sum Sum of 2D hists
2003  // postfix Post fix on names
2004  // rootProj Whether to use ROOT TH2::ProjectionX
2005  // corrEmpty Correct for empty bins
2006  // scaler Event-level normalization scaler
2007  //
2008  DGUARD(fDebug,1,"Make centrality bin result from %s", sum->GetName());
2009  TString base(GetName());
2010  base.ReplaceAll("dNdeta", "");
2011  base.Append(postfix);
2012  TH2D* copy = static_cast<TH2D*>(sum->Clone(Form("d2Ndetadphi%s",
2013  base.Data())));
2014 
2015  TH1D* accNorm = 0;
2016  Int_t nY = sum->GetNbinsY();
2017  // Hack HHD Hans test code to manually remove FMD2 dead channel (but
2018  // it is on outer?)
2019  //
2020  // cholm comment: The original hack has been moved to
2021  // AliForwarddNdetaTask::CheckEventData - this simplifies things a
2022  // great deal, and we could in principle use the new phi acceptance.
2023  //
2024  // However, since we may have filtered out the dead sectors in the
2025  // AOD production already, we can't be sure we can recalculate the
2026  // phi acceptance correctly, so for now, we rely on fCorrEmpty being set.
2027  Int_t o = (corrEmpty ? 0 : nY+1);
2028  accNorm = ProjectX(sum, Form("norm%s",base.Data()), o, o,
2029  rootProj, corrEmpty, false);
2030  accNorm->SetDirectory(0);
2031 
2032  // --- Normalize to the coverage -----------------------------------
2033  if (corrEmpty) {
2034  ScaleToCoverage(copy, accNorm);
2035  // --- Event-level normalization ---------------------------------
2036  copy->Scale(scaler);
2037  }
2038 
2039  // --- Project on X axis -------------------------------------------
2040  TH1D* dndeta = ProjectX(copy, Form("dndeta%s",base.Data()),
2041  1, nY, rootProj, corrEmpty);
2042  dndeta->SetDirectory(0);
2043  // Event-level normalization
2044  if (!corrEmpty) {
2045  ScaleToCoverage(dndeta, accNorm);
2046  dndeta->Scale(scaler);
2047  }
2048  dndeta->Scale(1., "width");
2049  copy->Scale(1., "width");
2050 
2051  TH1D* dndetaMCCorrection = 0;
2052  TH1D* dndetaMCtruth = 0;
2053  TList* centlist = 0;
2054  TList* truthcentlist = 0;
2055 
2056  // --- Possible final correction to <MC analysis> / <MC truth> -----
2057  // we get the rebinned distribution for satellite to make the correction
2058  TString rebinSuf(fSatelliteVertices ? "_rebin05" : "");
2059  if(mclist) {
2060  centlist = static_cast<TList*> (mclist->FindObject(GetListName()));
2061  if(centlist)
2062  dndetaMCCorrection =
2063  static_cast<TH1D*>(centlist->FindObject(Form("dndeta%s%s",
2064  base.Data(),
2065  rebinSuf.Data())));
2066  }
2067  if (truthlist) {
2068  truthcentlist = static_cast<TList*>(truthlist->FindObject(GetListName()));
2069  if (truthcentlist)
2070  // TODO here new is "dndetaTruth"
2071  dndetaMCtruth =
2072  static_cast<TH1D*>(truthcentlist->FindObject(Form("dndetaMCTruth%s",
2073  rebinSuf.Data())));
2074  }
2075 
2076  if (dndetaMCCorrection && dndetaMCtruth) {
2077  AliInfo("Correcting with final MC correction");
2078  TString testString(dndetaMCCorrection->GetName());
2079 
2080  // We take the measured MC dN/deta and divide with truth
2081  dndetaMCCorrection->Divide(dndetaMCtruth);
2082  dndetaMCCorrection->SetTitle("Final MC correction");
2083  dndetaMCCorrection->SetName("finalMCCorr");
2084  for(Int_t m = 1; m <= dndetaMCCorrection->GetNbinsX(); m++) {
2085  if(dndetaMCCorrection->GetBinContent(m) < 0.5 ||
2086  dndetaMCCorrection->GetBinContent(m) > 1.75) {
2087  dndetaMCCorrection->SetBinContent(m,1.);
2088  dndetaMCCorrection->SetBinError(m,0.1);
2089  }
2090  }
2091  // Applying the correction
2092  if (!fSatelliteVertices)
2093  // For non-satellites we took the same binning, so we do a straight
2094  // division
2095  dndeta->Divide(dndetaMCCorrection);
2096  else {
2097  // For satelitte events, we took coarser binned histograms, so
2098  // we need to do a bit more
2099  for(Int_t m = 1; m <= dndeta->GetNbinsX(); m++) {
2100  if(dndeta->GetBinContent(m) <= 0.01 ) continue;
2101 
2102  Double_t eta = dndeta->GetXaxis()->GetBinCenter(m);
2103  Int_t bin = dndetaMCCorrection->GetXaxis()->FindBin(eta);
2104  Double_t mccorr = dndetaMCCorrection->GetBinContent(bin);
2105  Double_t mcerror = dndetaMCCorrection->GetBinError(bin);
2106  if (mccorr < 1e-6) {
2107  dndeta->SetBinContent(m, 0);
2108  dndeta->SetBinError(m, 0);
2109  }
2110  Double_t value = dndeta->GetBinContent(m);
2111  Double_t error = dndeta->GetBinError(m);
2112  Double_t sumw2 = (error * error * mccorr * mccorr +
2113  mcerror * mcerror * value * value);
2114  dndeta->SetBinContent(m,value/mccorr) ;
2115  dndeta->SetBinError(m,TMath::Sqrt(sumw2)/mccorr/mccorr);
2116  }
2117  }
2118  }
2119  else
2120  DMSG(fDebug,1,"No final MC correction applied");
2121 
2122  // --- Set some histogram attributes -------------------------------
2123  TString post;
2124  Int_t rColor = GetColor(color);
2125  if (postfix && postfix[0] != '\0') post = Form(" (%s)", postfix);
2126  SetHistogramAttributes(dndeta, rColor, marker,
2127  Form("ALICE %s%s", GetName(), post.Data()));
2128  SetHistogramAttributes(accNorm, rColor, marker,
2129  Form("ALICE %s normalisation%s",
2130  GetName(), post.Data()));
2131 
2132  // --- Add the histograms to output list ---------------------------
2133  fOutput->Add(dndeta);
2134  fOutput->Add(accNorm);
2135  fOutput->Add(copy);
2136  if (dndetaMCCorrection) fOutput->Add(dndetaMCCorrection);
2137 
2138  // HHD Test of dN/deta in phi bins add flag later?
2139  //
2140  // cholm comment: We disable this for now
2141 #if 0
2142  for (Int_t nn=1; nn <= sum->GetNbinsY(); nn++) {
2143  TH1D* dndeta_phi = ProjectX(copy, Form("dndeta%s_phibin%d",
2144  base.Data(), nn),
2145  nn, nn, rootProj, corrEmpty);
2146  dndeta_phi->SetDirectory(0);
2147  // Event-level normalization
2148  dndeta_phi->Scale(TMath::Pi()/10., "width");
2149 
2150  if(centlist)
2151  dndetaMCCorrection =
2152  static_cast<TH1D*>(centlist->FindObject(Form("dndeta%s_phibin%d",
2153  base.Data(),nn)));
2154  if(truthcentlist)
2155  dndetaMCtruth
2156  = static_cast<TH1D*>(truthcentlist->FindObject("dndetaMCTruth"));
2157 
2158  if (dndetaMCCorrection && dndetaMCtruth) {
2159  AliInfo("Correcting with final MC correction");
2160  TString testString(dndetaMCCorrection->GetName());
2161  dndetaMCCorrection->Divide(dndetaMCtruth);
2162  dndetaMCCorrection->SetTitle(Form("Final_MC_correction_phibin%d",nn));
2163  dndetaMCCorrection->SetName(Form("Final_MC_correction_phibin%d",nn));
2164  for(Int_t m = 1; m <= dndetaMCCorrection->GetNbinsX(); m++) {
2165  if(dndetaMCCorrection->GetBinContent(m) < 0.25 ||
2166  dndetaMCCorrection->GetBinContent(m) > 1.75) {
2167  dndetaMCCorrection->SetBinContent(m,1.);
2168  dndetaMCCorrection->SetBinError(m,0.1);
2169  }
2170  }
2171  //Applying the correction
2172  dndeta_phi->Divide(dndetaMCCorrection);
2173  }
2174  fOutput->Add(dndeta_phi);
2175  if(dndetaMCCorrection) fOutput->Add(dndetaMCCorrection);
2176  } // End of phi
2177 #endif
2178 }
2179 
2180 //________________________________________________________________________
2181 void
2183  TList* results,
2184  UShort_t scheme,
2185  Double_t trigEff,
2186  Double_t trigEff0,
2187  Bool_t rootProj,
2188  Bool_t corrEmpty,
2189  Int_t triggerMask,
2190  Int_t marker,
2191  Int_t color,
2192  TList* mclist,
2193  TList* truthlist)
2194 {
2195  //
2196  // End of processing
2197  //
2198  // Parameters:
2199  // sums List of sums
2200  // results Output list of results
2201  // trigEff Trigger efficiency
2202  // corrEmpty Whether to correct for empty bins
2203  // triggerMask Trigger mask
2204  //
2205  DGUARD(fDebug,1,"End centrality bin procesing");
2206 
2207  fSums = dynamic_cast<TList*>(sums->FindObject(GetListName()));
2208  if(!fSums) {
2209  AliError("Could not retrieve TList fSums");
2210  return;
2211  }
2212 
2213  fOutput = new TList;
2214  fOutput->SetName(GetListName());
2215  fOutput->SetOwner();
2216  results->Add(fOutput);
2217 
2218  if (!fSum) {
2219  if (!ReadSum(fSums, false)) {
2220  AliInfo("This task did not produce any output");
2221  return;
2222  }
2223  }
2224  if (!fSumMC) ReadSum(fSums, true);
2225 
2226  fTriggers = static_cast<TH1I*>(fSums->FindObject("triggers"));
2227 
2228  if (!fTriggers) {
2229  AliError("Couldn't find histogram 'triggers' in list");
2230  return;
2231  }
2232 
2233  // --- Get normalization scaler ------------------------------------
2234  Double_t epsilonT = trigEff;
2235  Double_t epsilonT0 = trigEff0;
2236  DMSG(fDebug,2,"Using epsilonT=%f, epsilonT0=%f for 0x%x",
2237  epsilonT, epsilonT0, triggerMask);
2238 
2239  // Get our histograms
2240  Double_t nSum = 0;
2241  TH2D* sum = fSum->CalcSum(fOutput, nSum, epsilonT0, epsilonT,
2242  marker, rootProj, corrEmpty);
2243  Double_t nSumMC = 0;
2244  TH2D* sumMC = 0;
2245  if (fSumMC) sumMC = fSumMC->CalcSum(fOutput, nSumMC,
2246  epsilonT0, epsilonT, marker,
2247  rootProj, corrEmpty);
2248  if (!sum) {
2249  AliError("Failed to get sum from summer - bailing out");
2250  return;
2251  }
2252 
2253  TString text;
2254  Double_t ntotal = nSum;
2255  Double_t scaler = Normalization(*fTriggers, scheme, epsilonT, ntotal, &text);
2256  if (scaler < 0) {
2257  AliError("Failed to calculate normalization - bailing out");
2258  return;
2259  }
2260  fOutput->Add(fTriggers->Clone());
2261  fOutput->Add(new TNamed("normCalc", text.Data()));
2262  fOutput->Add(new TParameter<float>("low", fLow, 'f'));
2263  fOutput->Add(new TParameter<float>("high",fHigh, 'f'));
2264 
2265  // --- Make result and store ---------------------------------------
2266  MakeResult(sum, "", rootProj, corrEmpty, scaler, marker, color,
2267  mclist, truthlist);
2268 
2269  // --- Process result from TrackRefs -------------------------------
2270  if (sumMC)
2271  MakeResult(sumMC, "MC", rootProj, corrEmpty, scaler,
2272  GetMarkerStyle(GetMarkerBits(marker)+4), color,
2273  mclist, truthlist);
2274 
2275  // Temporary stuff
2276  // if (!IsAllBin()) return;
2277 
2278 }
2279 
2280 //____________________________________________________________________
2281 void
2283 {
2284  PFV("Centrality bin", GetTitle());
2285  gROOT->IncreaseDirLevel();
2286  PF("Range", "%6.2f - %6.2f%%", fLow, fHigh);
2287  PFB("All bin", IsAllBin());
2288  PFB("Final MC", fDoFinalMCCorrection);
2289  PFB("Satellite collisions", fSatelliteVertices);
2290 
2291  TString opt(option);
2292  opt.ToUpper();
2293  if (opt.Contains("R")) {
2294  if (fSum) fSum->Print(option);
2295  if (fSumMC) fSumMC->Print(option);
2296  }
2297 
2298  gROOT->DecreaseDirLevel();
2299 }
2300 
2301 //====================================================================
2302 Bool_t
2304  TH2D* data)
2305 {
2306  if (!fEmpiricalCorrection || !data)
2307  return true;
2308  Float_t zvertex=aod->GetIpZ();
2309  Int_t binzvertex=fEmpiricalCorrection->GetXaxis()->FindBin(zvertex);
2310  if(binzvertex<1||binzvertex>fEmpiricalCorrection->GetNbinsX())
2311  return false;
2312  for (int i=1;i<=data->GetNbinsX();i++) {
2313  Int_t bincorrection=fEmpiricalCorrection->GetYaxis()
2314  ->FindBin(data->GetXaxis()->GetBinCenter(i));
2315  if(bincorrection<1||bincorrection>fEmpiricalCorrection->GetNbinsY())
2316  return false;
2317  Float_t correction=fEmpiricalCorrection
2318  ->GetBinContent(binzvertex,bincorrection);
2319  if(correction<0.001) {
2320  data->SetBinContent(i,0,0);
2321  data->SetBinContent(i,data->GetNbinsY()+1,0);
2322  }
2323  for(int j=1;j<=data->GetNbinsY();j++) {
2324  if (data->GetBinContent(i,j)>0.0) {
2325  data->SetBinContent(i,j,data->GetBinContent(i,j)*correction);
2326  data->SetBinError(i,j,data->GetBinError(i,j)*correction);
2327  }
2328  }
2329  }
2330  return true;
2331 }
2332 
2333 //____________________________________________________________________
2334 TH1*
2336 {
2337  if (!h) return 0;
2338 
2339  TH1* ret = static_cast<TH1*>(h->Clone(Form("%s_leftright", h->GetName())));
2340  // Int_t oBins = h->GetNbinsX();
2341  // Double_t high = h->GetXaxis()->GetXmax();
2342  // Double_t low = h->GetXaxis()->GetXmin();
2343  // Double_t dBin = (high - low) / oBins;
2344  // Int_t tBins = Int_t(2*high/dBin+.5);
2345  // ret->SetBins(tBins, -high, high);
2346  ret->SetDirectory(0);
2347  ret->Reset();
2348  ret->SetTitle(Form("%s (+/-)", h->GetTitle()));
2349  ret->SetYTitle("Right/Left");
2350  Int_t nBins = h->GetNbinsX();
2351  for (Int_t i = 1; i <= nBins; i++) {
2352  Double_t x = h->GetBinCenter(i);
2353  if (x > 0) break;
2354 
2355  Double_t c1 = h->GetBinContent(i);
2356  Double_t e1 = h->GetBinError(i);
2357  if (c1 <= 0) continue;
2358 
2359  Int_t j = h->FindBin(-x);
2360  if (j <= 0 || j > nBins) continue;
2361 
2362  Double_t c2 = h->GetBinContent(j);
2363  Double_t e2 = h->GetBinError(j);
2364 
2365  Double_t c12 = c1*c1;
2366  Double_t e = TMath::Sqrt((e2*e2*c1*c1+e1*e1*c2*c2)/(c12*c12));
2367 
2368  Int_t k = ret->FindBin(x);
2369  ret->SetBinContent(k, c2/c1);
2370  ret->SetBinError(k, e);
2371  }
2372 
2373  return ret;
2374 }
2375 
2376 //
2377 // EOF
2378 //
Int_t color[]
virtual Bool_t CheckEvent(const AliAODForwardMult &forward)
#define PFB(N, FLAG)
const char * GetResultName(const char *postfix="") const
return jsonbuilder str().c_str()
const Color_t cc[]
Definition: DrawKs.C:1
static Int_t PbPbBin(Double_t c1, Double_t c2)
Definition: ExtractGSEs.C:1
void Print(Option_t *option="R") const
double Double_t
Definition: External.C:58
static void ScaleToCoverage(TH2D *copy, const TH1D *norm)
void SetTriggerBits(UInt_t bits)
static const char * CenterOfMassEnergyString(UShort_t cms)
const char * title
Definition: MakeQAPdf.C:26
static UShort_t ParseNormalizationScheme(const Char_t *what)
Double_t GetCentrality(AliAODEvent &event, AliAODForwardMult *forward, Int_t &qual)
#define TRUNC(X)
virtual Bool_t Event(AliAODEvent &aod)
char Char_t
Definition: External.C:18
TList * list
static TH1I * MakeTriggerHistogram(const char *name="triggers", UInt_t mask=0)
virtual void InitializeCentBins()
#define DMSG(L, N, F,...)
static TH1 * Asymmetry(TH1 *h)
TH2D * CalcSum(TList *o, Double_t &ntotal, Double_t zeroEff, Double_t otherEff=1, Int_t marker=20, Bool_t rootXproj=false, Bool_t corrEmpty=true) const
TCanvas * c
Definition: TestFitELoss.C:172
virtual void MakeResult(const TH2D *sum, const char *postfix, bool rootProj, bool corrEmpty, Double_t scaler, Int_t marker, Int_t color, TList *mclist, TList *truthlist)
virtual void CheckEventData(Double_t vtx, TH2 *data, TH2 *mcData)
virtual void SetDebugLevel(Int_t level)
Float_t GetIpZ() const
virtual void Print(Option_t *option="") const
void SetIPzAxis(Int_t n, Double_t min, Double_t max)
static Int_t GetMarkerStyle(UShort_t bits)
Int_t cH
Definition: Combine.C:26
static Int_t FlipHollowStyle(Int_t style)
virtual Bool_t Finalize()
AliAnalysisUtils fAnaUtil
Per-event per bin.
static Color_t PbPbColor(Double_t c1, Double_t c2)
Definition: ExtractGSEs.C:24
int Int_t
Definition: External.C:63
void SetNormalizationScheme(UShort_t scheme)
void Init(TList *list, const TH2D *data, Int_t col)
Definition: External.C:204
unsigned int UInt_t
Definition: External.C:33
Double_t fAbsMinCent
static Bool_t IsTriggerBits(UInt_t bits, UInt_t trg)
float Float_t
Definition: External.C:68
virtual Bool_t CheckEvent(const AliAODForwardMult *forward, Int_t triggerMask, Double_t vzMin, Double_t vzMax, Int_t filter)
#define PF(N, V,...)
Various utilities used in PWGLF/FORWARD.
Definition: External.C:228
Definition: External.C:212
static void GetParameter(TObject *o, UShort_t &value)
void Print(Option_t *option="") const
virtual Int_t GetColor() const
virtual void CreateSums(const TH2D *data, const TH2D *mc)
#define PFV(N, VALUE)
unsigned long ULong_t
Definition: External.C:38
virtual Bool_t ProcessEvent(const AliAODForwardMult *forward, UInt_t triggerMask, Bool_t isZero, Double_t vzMin, Double_t vzMax, const TH2D *data, const TH2D *mc, UInt_t filter, Double_t weight)
TObjArray * fListOfCentralities
static const Char_t * GetTriggerString(UInt_t mask, const char *sep="&")
#define DGUARD(L, N, F,...)
virtual Bool_t Book()
CentralityBin & operator=(const CentralityBin &other)
static Int_t GetCentMethodID(const TString &meth)
Bool_t Data(TH1F *h, Double_t *rangefit, Bool_t writefit, Double_t &sgn, Double_t &errsgn, Double_t &bkg, Double_t &errbkg, Double_t &sgnf, Double_t &errsgnf, Double_t &sigmafit, Int_t &status)
static const char * GetCentMethod(UShort_t id)
virtual CentralityBin * MakeCentralityBin(const char *name, Float_t low, Float_t high) const
static TObject * MakeParameter(const char *name, UShort_t value)
void SetSatelliteVertices(Bool_t satVtx)
const char * fwd
virtual TH2D * GetHistogram(const AliAODEvent &aod, Bool_t mc=false)=0
static TH1I * MakeStatusHistogram(const char *name="status")
virtual Bool_t ReadSum(TList *list, bool mc=false)
void AddCentralityBin(UShort_t at, Float_t low, Float_t high)
Bool_t ApplyEmpiricalCorrection(const AliAODForwardMult *aod, TH2D *data)
TH1 * GetResult(const char *postfix="", Bool_t verbose=true) const
static Float_t GetCentrality(const AliVEvent &event, const TString &method, Int_t &qual, Bool_t verbose=false)
Definition: External.C:220
static TH1D * ProjectX(const TH2D *h, const char *name, Int_t firstbin, Int_t lastbin, bool useROOT=false, bool corr=true, bool error=true)
void Add(const TH2D *data, Bool_t isZero, Double_t weight)
AliAODForwardMult * GetForward(const AliAODEvent &aod, Bool_t mc=false, Bool_t verb=true)
UInt_t GetTriggerBits() const
virtual void End(TList *sums, TList *results, UShort_t scheme, Double_t trigEff, Double_t trigEff0, Bool_t rootProj, Bool_t corrEmpty, Int_t triggerMask, Int_t marker, Int_t color, TList *mclist, TList *truthlist)
unsigned short UShort_t
Definition: External.C:28
virtual Bool_t CheckEvent(const AliAODForwardMult &forward)
const char Option_t
Definition: External.C:48
static TString GetHistName(const char *name, Int_t what=0, const char *post=0)
#define TESTAPPEND(SCHEME, BIT, STRING)
static const char * CollisionSystemString(UShort_t sys)
virtual void CreateOutputObjects(TList *dir, Int_t mask)
virtual Int_t GetMarker() const
const Int_t nbins
bool Bool_t
Definition: External.C:53
virtual Double_t GetCentrality(AliAODEvent &event, AliAODForwardMult *forward, Int_t &qual)
virtual void Print(Option_t *option="") const
Bool_t CheckEvent(UInt_t triggerMask=kInel, Double_t vzMin=-10, Double_t vzMax=10, Double_t cMin=0, Double_t cMax=100, TH1 *hist=0, TH1 *status=0, UInt_t filterMask=kDefaultFilter) const
Int_t GetColor(Int_t fallback=kRed+2) const
Definition: External.C:196
static UShort_t GetMarkerBits(Int_t style)
Bool_t HasCentrality() const
Bool_t SetCentralityMethod(const TString &method)
static const Char_t * NormalizationSchemeString(UShort_t scheme)
virtual Double_t Normalization(const TH1I &t, UShort_t scheme, Double_t trgEff, Double_t &ntotal, TString *text) const
static void SetHistogramAttributes(TH1D *h, Int_t colour, Int_t marker, const char *title, const char *ytitle=0)