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