2 * @file DrawAODSummary.C
3 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
4 * @date Tue Oct 30 09:47:30 2012
6 * @brief Script to draw summary of AOD pass into a PDF
11 # include <TCollection.h>
15 # include <TParameter.h>
22 # include <TLegendEntry.h>
23 # include <TPaveText.h>
39 //____________________________________________________________________
41 * Find an object in a collection
43 * @param parent Parent list
44 * @param name Name of object
46 * @return Pointer to object or null
48 TObject* GetObject(const TCollection* parent, const TString& name)
50 // Info("GetObject", "Getting object %s from %p", name.Data(), parent);
51 // --- Check parent ------------------------------------------------
53 Warning("GetObject", "No parent list");
56 // --- Check name --------------------------------------------------
58 Warning("GetObject", "No name specified");
61 // --- Find the object ---------------------------------------------
62 TObject* o = parent->FindObject(name);
64 Warning("GetObject", "Object \"%s\" not found in parent \"%s\"",
65 name.Data(), parent->GetName());
70 //____________________________________________________________________
72 * Find an object in a directory
74 * @param parent Parent directory
75 * @param name Name of object
77 * @return Pointer to object or null
79 TObject* GetObject(TDirectory* parent, const TString& name)
81 // Info("GetObject", "Getting object %s from %p", name.Data(), parent);
82 // --- Check parent ------------------------------------------------
84 Warning("GetObject", "No parent directory");
87 // --- Check name --------------------------------------------------
89 Warning("GetObject", "No name specified");
92 // --- Find the object ---------------------------------------------
93 TObject* o = parent->Get(name);
95 Warning("GetObject", "Object \"%s\" not found in parent \"%s\"",
96 name.Data(), parent->GetName());
102 //____________________________________________________________________
104 * Check the type of a found object
108 * @param src Source of object
110 * @return true on success, false otherwise
112 Bool_t CheckType(const TObject* o, const TClass* cl, const TString& src)
114 // Info("CheckType", "Checking type of %s vs %s", o->GetName(), cl->GetName());
115 if (!o->IsA()->InheritsFrom(cl)) {
116 Warning("CheckType", "Object \"%s\" retrieved from \"%s\" is not a "
117 "%s but a %s", o->GetName(), src.Data(), cl->GetName(),
124 //_____________________________________________________________________
125 void GetParameter(const TCollection* c, const TString& name, UShort_t& value)
127 // Info("GetParameter", "Getting parameter of %s from %p", name.Data(), c);
128 TObject* o = GetObject(c, name);
130 value = o->GetUniqueID();
132 //_____________________________________________________________________
133 void GetParameter(const TCollection* c, const TString& name, Int_t& value)
135 // Info("GetParameter", "Getting parameter of %s from %p", name.Data(), c);
136 TObject* o = GetObject(c, name);
138 value = o->GetUniqueID();
140 //_____________________________________________________________________
141 void GetParameter(const TCollection* c, const TString& name, Double_t& value)
143 // Info("GetParameter", "Getting parameter of %s from %p", name.Data(), c);
144 TObject* o = GetObject(c, name);
146 UInt_t i = o->GetUniqueID();
147 Float_t v = *reinterpret_cast<Float_t*>(&i);
150 //_____________________________________________________________________
151 void GetParameter(const TCollection* c, const TString& name, Bool_t& value)
153 // Info("GetParameter", "Getting parameter of %s from %p", name.Data(), c);
154 TObject* o = GetObject(c, name);
156 value = o->GetUniqueID();
159 //____________________________________________________________________
161 * Find a collection in another collection
163 * @param parent Parent collection
164 * @param name Name of the collection
166 * @return pointer to collection on success, otherwise null
168 TCollection* GetCollection(const TCollection* parent, const TString& name)
170 // Info("GetCollection", "Getting collection of %s from %p", name.Data(), c);
171 // --- Find the object ---------------------------------------------
172 TObject* o = GetObject(parent, name);
175 // --- Check type of found object ----------------------------------
176 if (!CheckType(o, TCollection::Class(), parent->GetName())) return 0;
178 // --- Return the collection ---------------------------------------
179 return static_cast<TCollection*>(o);
182 //____________________________________________________________________
184 * Find a collection in a directory
186 * @param parent Parent directory
187 * @param name Name of the collection
189 * @return pointer to collection on success, otherwise null
191 TCollection* GetCollection(TDirectory* parent, const TString& name)
193 // Info("GetCollection", "Getting collection of %s from %p",
194 // name.Data(), parent);
195 // --- Find the object ---------------------------------------------
196 TObject* o = GetObject(parent, name);
199 // --- Check the type of object ------------------------------------
200 if (!CheckType(o, TCollection::Class(), parent->GetName())) return 0;
202 // --- Return the collection ---------------------------------------
203 return static_cast<TCollection*>(o);
206 //____________________________________________________________________
208 * Get a 1D histogram from a collection
210 * @param parent Parent collection
211 * @param name Name of histogram
213 * @return pointer or null
215 TH1* GetH1(const TCollection* parent, const TString& name)
217 // Info("GetH1", "Getting 1D histogram of %s from %p", name.Data(), c);
218 // --- Find the object ---------------------------------------------
219 TObject* o = GetObject(parent, name);
222 // --- Check the type of object ------------------------------------
223 if (!CheckType(o, TH1::Class(), parent->GetName())) return 0;
225 // --- Return the collection ---------------------------------------
226 return static_cast<TH1*>(o);
228 //____________________________________________________________________
230 * Get a 2D histogram from a collection
232 * @param parent Parent collection
233 * @param name Name of histogram
235 * @return pointer or null
237 TH2* GetH2(const TCollection* parent, const TString& name)
239 // Info("GetH2", "Getting 2D histogram of %s from %p", name.Data(), c);
240 // --- Find the object ---------------------------------------------
241 TObject* o = GetObject(parent, name);
244 // --- Check the type of object ------------------------------------
245 if (!CheckType(o, TH2::Class(), parent->GetName())) return 0;
247 // --- Return the collection ---------------------------------------
248 return static_cast<TH2*>(o);
250 //____________________________________________________________________
252 * Get a histogram stack from a collection
254 * @param parent Parent collection
255 * @param name Name of histogram
257 * @return pointer or null
259 THStack* GetStack(const TCollection* parent, const TString& name,
262 // Info("GetStack", "Getting histogram stack %s from %p", name.Data(), parent);
263 // --- Find the object ---------------------------------------------
264 TObject* o = GetObject(parent, name);
267 // --- Check the type of object ------------------------------------
268 if (!CheckType(o, THStack::Class(), parent->GetName())) return 0;
270 THStack* stack = static_cast<THStack*>(o);
271 if (sub == 0) return stack;
273 if (stack->GetHists()->GetEntries() <= 0 ||stack->GetMaximum() < 1) {
274 stack->GetHists()->Delete();
275 const char* subs[] = { "FMD1I", "FMD2I", "FMD2O", "FMD3O", "FMD3I", 0 };
276 const char** ptr = subs;
278 TCollection* sc = GetCollection(parent, *ptr);
279 if (!sc) { ptr++; continue; }
281 TH2* h = GetH2(sc, sub);
283 TH1* p = h->ProjectionX(*ptr, 1, h->GetNbinsY(), "e");
284 p->Scale(1., "width");
291 // --- Return the collection ---------------------------------------
295 //____________________________________________________________________
298 printf("Press enter to continue");
302 //____________________________________________________________________
306 * @param c Canvas to clear
308 * @ingroup pwglf_forward_scripts_corr
311 ClearCanvas(TCanvas* c)
313 // Info("ClearCanvas", "Clearing canvas");
314 c->SetLeftMargin(.1);
315 c->SetRightMargin(.05);
316 c->SetBottomMargin(.1);
317 c->SetTopMargin(.05);
321 TPad* p1 = new TPad("top", "Top", 0, 1-dy, 1, 1, 0, 0);
323 p1->SetFillColor(kBlue-5);
324 p1->SetBorderSize(0);
325 p1->SetBorderMode(0);
329 TPad* p2 = new TPad("body", "Body", 0, 0, 1, 1-dy, 0, 0);
333 p2->SetBorderSize(0);
334 p2->SetBorderMode(0);
340 //____________________________________________________________________
344 * @param pname Name of PDF file to make
346 * @return Created canvas
348 TCanvas* CreateCanvas(const TString& pname)
350 // Info("CreateCanvas", "Creating canvas");
352 TCanvas* c = new TCanvas("c", pname.Data(), size / TMath::Sqrt(2), size);
356 c->Print(Form("%s[", pname.Data()));
358 gStyle->SetOptStat(0);
359 gStyle->SetTitleColor(0);
360 gStyle->SetTitleStyle(0);
361 gStyle->SetTitleBorderSize(0);
362 gStyle->SetTitleX(.5);
363 gStyle->SetTitleY(1);
364 gStyle->SetTitleW(.8);
365 gStyle->SetTitleH(.09);
366 gStyle->SetFrameFillColor(kWhite);
367 gStyle->SetFrameBorderSize(1);
368 gStyle->SetFrameBorderMode(1);
369 gStyle->SetPalette(1);
376 //____________________________________________________________________
382 void CloseCanvas(TCanvas* c)
384 // Info("CloseCanvas", "Closing canvas");
386 c->Print(Form("%s]", c->GetTitle()));
389 //____________________________________________________________________
396 void PrintCanvas(TCanvas* c, const TString& title,
397 Float_t size=.7, Bool_t pause=false)
399 // Info("PrintCanvas", "Printing page %s", title.Data());
401 tit.Form("Title:%s", title.Data());
404 TLatex* ltx = new TLatex(.5, .5, title);
406 ltx->SetTextAlign(22);
407 ltx->SetTextSize(size);
408 ltx->SetTextColor(kWhite);
409 ltx->SetTextFont(62);
415 gSystem->RedirectOutput("/dev/null");
416 c->Print(c->GetTitle(), tit);
417 gSystem->RedirectOutput(0);
424 //____________________________________________________________________
426 * Make a chapter page
431 void MakeChapter(TCanvas* c, const TString& title)
435 // Info("MakeChapter", "Making chapter %s", title.Data());
436 TLatex* ltx = new TLatex(.5, .5, title);
438 ltx->SetTextAlign(22);
441 PrintCanvas(c, title);
443 //____________________________________________________________________
444 void DrawInPad(TVirtualPad* c, Int_t padNo, TObject* h, Option_t* opts="",
447 // Info("DrawInPad", "Drawing %p in pad # %d of %p w/options %s, flags 0x%x",
448 // h, padNo, c, opts, flags);
449 TVirtualPad* p = c->cd(padNo);
451 Warning("DrawInPad", "Pad # %d not found in %s", padNo, c->GetName());
454 if (flags & 0x1) p->SetLogx();
455 if (flags & 0x2) p->SetLogy();
456 if (flags & 0x4) p->SetLogz();
459 if (o.Contains("colz", TString::kIgnoreCase))
460 p->SetRightMargin(0.15);
461 if (o.Contains("text", TString::kIgnoreCase)) {
462 TH1* hh = static_cast<TH1*>(h);
463 hh->SetMaximum(1.1*hh->GetMaximum());
464 hh->SetMarkerSize(2);
469 Warning("DrawInPad", "Nothing to draw in pad # %d", padNo);
475 TLegend* l = p->BuildLegend();
484 //____________________________________________________________________
485 void CreateTemplates(TLatex*& name, TLatex*& value, Float_t size=.03)
490 name = new TLatex(x1, y, "");
491 name->SetTextAlign(13);
493 name->SetTextSize(size);
495 value = new TLatex(x2, y, "");
496 value->SetTextAlign(13);
498 value->SetTextSize(size);
501 //____________________________________________________________________
502 void DrawParameter(TLatex* name, TLatex* value, Double_t& y,
503 const TString& sName, const TString& sValue)
505 if (sName.IsNull() && sValue.IsNull()) return;
507 name->DrawLatex(name->GetX(), y, Form("%s:", sName.Data()));
508 if (!sValue.IsNull())
509 value->DrawLatex(value->GetX(), y, sValue.Data());
510 y -= name->GetTextSize() + .02;
514 //____________________________________________________________________
515 void DrawCentSum(const TCollection* sums, TCanvas* can, const TString& base,
516 Int_t cLow, Int_t cHigh)
519 if (cLow < 0 || cHigh < 0 || cLow >= cHigh) {
523 else folder.Form("cent%03d_%03d", cLow, cHigh);
525 TCollection* c = GetCollection(sums, folder);
528 TVirtualPad* body = can->cd(2);
531 DrawInPad(body, 1, GetH1(c, "triggers"), "HIST TEXT");
532 DrawInPad(body, 2, GetH1(c, Form("%sEvents",base.Data())), "HIST TEXT");
533 DrawInPad(body, 3, GetH2(c, base.Data()), "colz");
534 DrawInPad(body, 4, GetH2(c, Form("%s0", base.Data())), "colz");
536 PrintCanvas(can, Form("%s sums: %3d%% - %3d%%", base.Data(), cLow, cHigh));
539 //____________________________________________________________________
540 void DrawSums(TDirectory* top, const TString& base, TCanvas* can, bool onlyMB)
542 TCollection* c = GetCollection(top, Form("%sSums", base.Data()));
545 TAxis* centAxis = static_cast<TAxis*>(GetObject(c, "centAxis"));
547 TVirtualPad* body = can->cd(2);
554 CreateTemplates(name, value);
555 for (Int_t i = 1; i <= centAxis->GetNbins(); i++) {
556 DrawParameter(name, value, y, (i == 1 ? "Centrality classes" : ""),
557 Form("%3d%% - %3d%%",
558 Int_t(centAxis->GetBinLowEdge(i)),
559 Int_t(centAxis->GetBinUpEdge(i))));
561 Int_t sys, sNN, scheme, trigger;
562 GetParameter(c, "sNN", sNN);
563 GetParameter(c, "sys", sys);
564 GetParameter(c, "scheme", scheme);
565 GetParameter(c, "trigger", trigger);
566 DrawParameter(name, value, y, "Collision system",
567 (sys == 1 ? "pp" : (sys == 2 ? "PbPb" : (sys == 3 ? "pPb" :
569 DrawParameter(name, value, y, "#sqrt{s_{NN}}", Form("%4dGeV", sNN));
570 DrawParameter(name, value, y, "Normalization scheme", Form("0x%x", scheme));
571 DrawParameter(name, value, y, "Triggers", Form("0x%x", trigger));
573 DrawInPad(body, 2, GetH1(c, "cent"));
575 PrintCanvas(can, Form("%s sums", base.Data()));
577 DrawCentSum(c, can, base, centAxis->GetXmin(), -centAxis->GetXmax());
580 for (Int_t i = 1; i <= centAxis->GetNbins(); i++)
581 DrawCentSum(c, can, base, centAxis->GetBinLowEdge(i),
582 centAxis->GetBinUpEdge(i));
585 //____________________________________________________________________
586 void CleanStack(THStack* stack, TLegend* l, const TAxis* axis)
588 TList* hists = stack->GetHists();
589 // Clean up list of histogram. Histograms with no entries or
590 // no functions are deleted. We have to do this using the TObjLink
591 // objects stored in the list since ROOT cannot guaranty the validity
592 // of iterators when removing from a list - tsck. Should just implement
594 TObjLink* lnk = hists->FirstLink();
597 TH1* h = static_cast<TH1*>(lnk->GetObject());
599 TString name(h->GetName());
600 if (name.Contains("_mirror")) {
601 // AliWarning(Form("No entries in %s - removing", h->GetName()));
606 name.Form("%3d%% - %3d%%",
607 Int_t(axis->GetBinLowEdge(j)),
608 Int_t(axis->GetBinUpEdge(j)));
609 TLegendEntry* e = l->AddEntry("dummy", name, "f");
610 e->SetFillStyle(1001);
611 e->SetFillColor(h->GetMarkerColor());
614 TObjLink* keep = lnk->Next();
623 //____________________________________________________________________
624 void DrawCentRes(const TCollection* sums, TCanvas* can, const TString& base,
625 Int_t cLow, Int_t cHigh)
628 if (cLow < 0 || cHigh < 0 || cLow >= cHigh) {
632 else folder.Form("cent%03d_%03d", cLow, cHigh);
634 TCollection* c = GetCollection(sums, folder);
637 TVirtualPad* body = can->cd(2);
640 DrawInPad(body, 1, GetH1(c, "triggers"), "HIST TEXT");
641 DrawInPad(body, 2, GetH1(c, Form("norm%s",base.Data())));
642 DrawInPad(body, 3, GetH1(c, Form("dndeta%s",base.Data())));
643 DrawInPad(body, 4, GetH1(c, Form("dndeta%s_rebin05",base.Data())));
644 DrawInPad(body, 5, GetH2(c, Form("d2Ndetadphi%s", base.Data())),"colz");
646 TObject* normCalc = GetObject(c, "normCalc");
647 TString calc = normCalc->GetTitle();
648 TObjArray* lines = calc.Tokenize("\n");
649 TPaveText* disp = new TPaveText(.1,.1,.9,.9, "NDC");
652 while ((line = next()))
653 disp->AddText(line->GetName());
654 disp->SetBorderSize(0);
655 disp->SetBorderSize(0);
656 disp->SetFillStyle(0);
657 DrawInPad(body, 6, disp);
659 PrintCanvas(can, Form("%s result: %3d%% - %3d%%", base.Data(), cLow, cHigh));
662 //____________________________________________________________________
664 DrawRes(TDirectory* top, const TString& base, TCanvas* can, Bool_t onlyMB)
666 TCollection* c = GetCollection(top, Form("%sResults", base.Data()));
669 TAxis* centAxis = static_cast<TAxis*>(GetObject(c, "centAxis"));
676 CreateTemplates(name, value, .02);
677 for (Int_t i = 1; i <= centAxis->GetNbins(); i++) {
678 DrawParameter(name, value, y, (i == 1 ? "Centrality classes" : ""),
679 Form("%3d%% - %3d%%",
680 Int_t(centAxis->GetBinLowEdge(i)),
681 Int_t(centAxis->GetBinUpEdge(i))));
684 DrawParameter(name, value, y, "Collision system",
685 GetObject(c, "sys")->GetTitle());
686 DrawParameter(name, value, y, "#sqrt{s_{NN}}",GetObject(c,"sNN")->GetTitle());
687 DrawParameter(name, value, y, "trigger",GetObject(c,"trigger")->GetTitle());
688 DrawParameter(name, value, y, "scheme", GetObject(c,"scheme")->GetTitle());
690 Double_t epsT, epsT0;
691 GetParameter(c, "triggerEff", epsT);
692 GetParameter(c, "triggerEff0", epsT0);
693 DrawParameter(name, value, y, "#epsilon_{T}", Form("%f", epsT));
694 DrawParameter(name, value, y, "#epsilon_{T,zero bin}", Form("%f", epsT0));
696 PrintCanvas(can, Form("%s results", base.Data()));
698 TVirtualPad* body = can->cd(2);
701 TLegend* l = new TLegend(0.1, 0.1, 0.9, 0.9, "Centralities");
705 THStack* dndeta = GetStack(c, "dndeta");
706 CleanStack(dndeta, l, centAxis);
707 THStack* dndeta5 = GetStack(c, "dndeta_rebin05");
708 CleanStack(dndeta5, 0, 0);
710 DrawInPad(body, 1, dndeta, "nostack");
711 DrawInPad(body, 2, dndeta5, "nostack");
712 DrawInPad(body, 3, l, "");
714 PrintCanvas(can, Form("%s results - stacks", base.Data()));
716 DrawCentRes(c, can, base, centAxis->GetXmin(), -centAxis->GetXmax());
717 if (onlyMB) return dndeta;
719 for (Int_t i = 1; i <= centAxis->GetNbins(); i++)
720 DrawCentRes(c, can, base, centAxis->GetBinLowEdge(i),
721 centAxis->GetBinUpEdge(i));
727 //____________________________________________________________________
728 void DrawdNdetaSummary(const char* fname="forward_dndeta.root",
731 // --- Open the file -----------------------------------------------
732 TString filename(fname);
733 TFile* file = TFile::Open(filename.Data(), "READ");
735 Error("DrawAODSummary", "Failed to open \"%s\"", filename.Data());
739 // --- Make our canvas ---------------------------------------------
740 TString pdfName(filename);
741 pdfName.ReplaceAll(".root", ".pdf");
743 TCanvas* c = CreateCanvas(pdfName);
745 // --- Do each sub-algorithm ---------------------------------------
746 DrawSums(file, "Forward", c, onlyMB);
747 THStack* rF = DrawRes(file, "Forward", c, onlyMB);
749 DrawSums(file, "Central", c, onlyMB);
750 THStack* rC = DrawRes(file, "Central", c, onlyMB);
752 TIter next(rF->GetHists());
754 while ((h = static_cast<TH1*>(next()))) rC->Add(h);
757 PrintCanvas(c, "Both");