2 * @file SummaryDrawer.C
3 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
4 * @date Sun Nov 25 11:36:41 2012
6 * @brief Base class for classes to draw summaries
10 #ifndef SUMMARYDRAWER_C
11 # define SUMMARYDRAWER_C
16 # include <TParameter.h>
23 # include <TLegendEntry.h>
28 # include <TProfile.h>
58 fRingMap = new TVirtualPad*[6];
69 //__________________________________________________________________
71 * Find an object in a collection
73 * @param parent Parent list
74 * @param name Name of object
75 * @param verb Be verbose
77 * @return Pointer to object or null
79 static TObject* GetObject(const TCollection* parent,
84 if (verb) Warning("GetObject", "No parent list");
88 if (verb) Warning("GetObject", "No name specified");
91 TObject* o = parent->FindObject(name);
93 if (verb) Warning("GetObject", "Object \"%s\" not found in parent \"%s\"",
94 name.Data(), parent->GetName());
99 //__________________________________________________________________
101 * Find an object in a directory
103 * @param parent Parent directory
104 * @param name Name of object
105 * @param verb Be verbose
107 * @return Pointer to object or null
109 static TObject* GetObject(const TDirectory* parent,
114 if (verb) Warning("GetObject", "No parent directory");
118 if (verb) Warning("GetObject", "No name specified");
121 TObject* o = const_cast<TDirectory*>(parent)->Get(name);
123 if (verb) Warning("GetObject", "Object \"%s\" not found in parent \"%s\"",
124 name.Data(), parent->GetName());
129 //____________________________________________________________________
131 * Check the type of a found object
135 * @param src Source of object
137 * @return true on success, false otherwise
139 static Bool_t CheckType(const TObject* o,
143 if (!o->IsA()->InheritsFrom(cl)) {
144 Warning("CheckType", "Object \"%s\" retrieved from \"%s\" is not a "
145 "%s but a %s", o->GetName(), src.Data(), cl->GetName(),
151 //___________________________________________________________________
153 * Get a UShort_t parameter value
155 * @param c Parent collection
156 * @param name Name of parameter
157 * @param value On return the value
158 * @param verb If true, complain if not found
160 static void GetParameter(const TCollection* c,
165 TObject* o = GetObject(c, name, verb);
167 value = o->GetUniqueID();
169 //_____________________________________________________________________
171 * Get a Int_t parameter value
173 * @param c Parent collection
174 * @param name Name of parameter
175 * @param value On return the value
176 * @param verb If true, complain if not found
178 static void GetParameter(const TCollection* c,
184 TObject* o = GetObject(c, name, verb);
186 value = o->GetUniqueID();
188 //_____________________________________________________________________
190 * Get a Double_t parameter value
192 * @param c Parent collection
193 * @param name Name of parameter
194 * @param value On return the value
195 * @param verb If true, complain if not found
197 static void GetParameter(const TCollection* c,
203 TObject* o = GetObject(c, name, verb);
205 UInt_t i = o->GetUniqueID();
206 Float_t v = *reinterpret_cast<Float_t*>(&i);
209 //_____________________________________________________________________
211 * Get a Bool_t parameter value
213 * @param c Parent collection
214 * @param name Name of parameter
215 * @param value On return the value
216 * @param verb If true, complain if not found
218 static void GetParameter(const TCollection* c,
223 TObject* o = GetObject(c, name, verb);
225 value = o->GetUniqueID();
227 //____________________________________________________________________
229 * Find a collection in another collection
231 * @param parent Parent collection
232 * @param name Name of the collection
233 * @param verb If true and not found, complain
235 * @return pointer to collection on success, otherwise null
237 static TCollection* GetCollection(const TCollection* parent,
241 TObject* o = GetObject(parent, name, verb);
243 if (!CheckType(o, TCollection::Class(), parent->GetName())) return 0;
244 return static_cast<TCollection*>(o);
246 //____________________________________________________________________
248 * Find a collection in a directory
250 * @param parent Parent directory
251 * @param name Name of the collection
252 * @param verb If true and not found, complain
254 * @return pointer to collection on success, otherwise null
256 static TCollection* GetCollection(const TDirectory* parent,
260 TObject* o = GetObject(parent, name, verb);
262 if (!CheckType(o, TCollection::Class(), parent->GetName())) return 0;
263 return static_cast<TCollection*>(o);
266 //____________________________________________________________________
268 * Get a 1D histogram from a collection
270 * @param parent Parent collection
271 * @param name Name of histogram
272 * @param verb If true and not found, complain
274 * @return pointer or null
276 static TH1* GetH1(const TCollection* parent,
280 TObject* o = GetObject(parent, name, verb);
282 if (!CheckType(o, TH1::Class(), parent->GetName())) return 0;
283 return static_cast<TH1*>(o);
285 //____________________________________________________________________
287 * Get a 2D histogram from a collection
289 * @param parent Parent collection
290 * @param name Name of histogram
291 * @param verb If true and not found, complain
293 * @return pointer or null
295 static TH2* GetH2(const TCollection* parent,
299 // Info("GetH2", "Getting 2D histogram of %s from %p", name.Data(), c);
300 // --- Find the object -------------------------------------------
301 TObject* o = GetObject(parent, name, verb);
304 // --- Check the type of object ----------------------------------
305 if (!CheckType(o, TH2::Class(), parent->GetName())) return 0;
307 // --- Return the collection -------------------------------------
308 return static_cast<TH2*>(o);
310 //__________________________________________________________________
312 * Get a histogram stack from a collection
314 * @param parent Parent collection
315 * @param name Name of histogram
316 * @param sub Sub-component
317 * @param verb If true and not found, complain
319 * @return pointer or null
321 static THStack* GetStack(const TCollection* parent,
326 // --- Find the object -------------------------------------------
327 TObject* o = GetObject(parent, name, verb);
330 // --- Check the type of object -----------------------------------
331 if (!CheckType(o, THStack::Class(), parent->GetName())) return 0;
333 THStack* stack = static_cast<THStack*>(o);
334 if (sub == 0) return stack;
336 if (stack->GetHists()->GetEntries() <= 0 ||stack->GetMaximum() < 1) {
337 // Info("GetStack", "No entries in %s", name.Data());
338 stack->GetHists()->Delete();
339 const char* subs[] = { "FMD1I", "FMD2I", "FMD2O", "FMD3O", "FMD3I", 0 };
340 const char** ptr = subs;
342 TCollection* sc = GetCollection(parent, *ptr, true);
343 if (!sc) { ptr++; continue; }
345 TObject* obj = GetObject(sc, sub);
351 if (obj->IsA()->InheritsFrom(TH2::Class())) {
352 TH2* h = static_cast<TH2*>(obj);
353 TH1* p = h->ProjectionX(*ptr, 1, h->GetNbinsY(), "e");
354 p->Scale(1., "width");
359 else if (obj->IsA()->InheritsFrom(TH1::Class())) {
360 TH1* hh = static_cast<TH1*>(obj);
367 // --- Return the collection -------------------------------------
370 //____________________________________________________________________
379 fTop->SetFillColor(kBlue-5);
380 fTop->SetBorderSize(0);
381 fTop->SetBorderMode(0);
385 fBody->SetFillColor(0);
386 fBody->SetFillStyle(0);
387 fBody->SetBorderSize(0);
388 fBody->SetBorderMode(0);
389 fBody->SetTopMargin(0.01);
390 fBody->SetLeftMargin(0.10);
391 fBody->SetRightMargin(0.01);
392 fBody->SetBottomMargin(0.10);
403 //____________________________________________________________________
407 * @param pname Name of PDF file to make
408 * @param landscape if true, print in landscape
410 * @return Created canvas
412 void CreateCanvas(const TString& pname, Bool_t landscape=false)
414 // Info("CreateCanvas", "Creating canvas");
415 fLandscape = landscape;
417 Int_t width = height / TMath::Sqrt(2);
423 fCanvas = new TCanvas("c", pname.Data(), width, height);
424 fCanvas->SetFillColor(0);
425 fCanvas->SetBorderSize(0);
426 fCanvas->SetBorderMode(0);
427 fCanvas->Print(Form("%s[", pname.Data()),
428 Form("pdf %s", fLandscape ? "Landscape" : ""));
429 fCanvas->SetLeftMargin(.1);
430 fCanvas->SetRightMargin(.05);
431 fCanvas->SetBottomMargin(.1);
432 fCanvas->SetTopMargin(.05);
434 gStyle->SetOptStat(0);
435 gStyle->SetTitleColor(0);
436 gStyle->SetTitleStyle(0);
437 gStyle->SetTitleBorderSize(0);
438 gStyle->SetTitleX(.5);
439 gStyle->SetTitleY(1);
440 gStyle->SetTitleW(.8);
441 gStyle->SetTitleH(.09);
442 gStyle->SetFrameFillColor(kWhite);
443 gStyle->SetFrameBorderSize(1);
444 gStyle->SetFrameBorderMode(1);
445 gStyle->SetPalette(1);
448 fTop = new TPad("top", "Top", 0, 1-dy, 1, 1, 0, 0);
450 fTop->SetFillColor(kBlue-5);
451 fTop->SetBorderSize(0);
452 fTop->SetBorderMode(0);
456 fBody = new TPad("body", "Body", 0, 0, 1, 1-dy, 0, 0);
458 fBody->SetFillColor(0);
459 fBody->SetFillStyle(0);
460 fBody->SetBorderSize(0);
461 fBody->SetBorderMode(0);
465 fHeader = new TLatex(.5, .5, "Title");
467 fHeader->SetTextAlign(22);
468 fHeader->SetTextSize(.7);
469 fHeader->SetTextColor(kWhite);
470 fHeader->SetTextFont(62);
475 Double_t s = fLandscape ? 0.08 : 0.05;
476 fParName = new TLatex(x1, y, "");
477 fParName->SetTextAlign(13);
479 fParName->SetTextSize(s);
481 fParVal = new TLatex(x2, y, "");
482 fParVal->SetTextAlign(13);
484 fParVal->SetTextSize(s);
489 //____________________________________________________________________
496 // Info("CloseCanvas", "Closing canvas");
498 fCanvas->Print(Form("%s]", fCanvas->GetTitle()),
499 Form("pdf %s", fLandscape ? "Landscape" : ""));
502 //__________________________________________________________________
507 * @param size Size of text
509 void PrintCanvas(const TString& title, Float_t size=.7)
512 tit.Form("pdf %s Title:%s", fLandscape ? "Landscape" : "",
516 fHeader->SetTextSize(size);
517 fHeader->DrawLatex(.5,.5,title);
523 gSystem->RedirectOutput("/dev/null");
524 fCanvas->Print(fCanvas->GetTitle(), tit);
525 gSystem->RedirectOutput(0);
531 //__________________________________________________________________
533 * Make a chapter page
537 void MakeChapter(const TString& title)
541 TLatex* ltx = new TLatex(.5, .5, title);
543 ltx->SetTextAlign(22);
548 //__________________________________________________________________
550 * Draw an object in pad
552 * @param c PArent pad
553 * @param padNo Sub-pad number (0 is self)
554 * @param h Object to draw
555 * @param opts Options
558 void DrawInPad(TVirtualPad* c,
564 TVirtualPad* p = c->GetPad(padNo);
566 Warning("DrawInPad", "Pad # %d not found in %s", padNo, c->GetName());
569 DrawInPad(p, h, opts, flags);
571 //__________________________________________________________________
573 * Draw an object in pad
576 * @param h Object to draw
577 * @param opts Options
580 void DrawInPad(TVirtualPad* p,
586 Warning("DrawInPad", "No pad specified");
590 // Info("DrawInPad", "Drawing in pad %p", p);
592 if (flags & 0x1) p->SetLogx();
593 if (flags & 0x2) p->SetLogy();
594 if (flags & 0x4) p->SetLogz();
597 if (o.Contains("colz", TString::kIgnoreCase))
598 p->SetRightMargin(0.15);
599 if (o.Contains("text", TString::kIgnoreCase)) {
600 TH1* hh = static_cast<TH1*>(h);
601 hh->SetMaximum(1.1*hh->GetMaximum());
602 hh->SetMarkerSize(2);
606 // Warning("DrawInPad", "Nothing to draw in pad # %s", p->GetName());
612 TLegend* l = p->BuildLegend(0.33, .67, .66, .99-p->GetTopMargin());
621 //__________________________________________________________________
623 * Draw two graphs in the same frame, but with separate y-axis
625 * @param c Mother pad
626 * @param padNo Sub-pad number (0 is self)
627 * @param h1 First histogram
628 * @param h2 Second histogram
629 * @param opts Options
632 void DrawTwoInPad(TVirtualPad* c, Int_t padNo, TH1* h1, TH1* h2,
633 Option_t* opts="", UShort_t flags=0x0)
635 TVirtualPad* p = c->cd(padNo);
637 Warning("DrawInPad", "Pad # %d not found in %s", padNo, c->GetName());
640 if (flags & 0x1) p->SetLogx();
641 if (flags & 0x2) p->SetLogy();
642 if (flags & 0x4) p->SetLogz();
648 Bool_t e3 = o.Contains("e3");
650 fopts.ReplaceAll("e3", " same");
653 h1->GetYaxis()->SetLabelSize(0);
654 h1->GetYaxis()->SetTicks("");
655 h1->GetYaxis()->SetNdivisions(0);
656 h1->DrawCopy(o); // First draw with opts
657 if (e3) h1->DrawCopy(fopts);
660 Double_t m1 = 1.05 * h1->GetMaximum();
661 TGaxis* a1 = new TGaxis(p->GetUxmin(), p->GetUymin(),
662 p->GetUxmin(), p->GetUymax(),
664 a1->SetLineColor(h1->GetLineColor());
668 Double_t m2 = 1.1 * h2->GetMaximum();
669 Double_t scale = m1 / m2;
672 if (e3) h2->DrawCopy(fopts);
674 TGaxis* a2 = new TGaxis(p->GetUxmax(), p->GetUymin(),
675 p->GetUxmax(), p->GetUymax(),
677 a2->SetLineColor(h2->GetLineColor());
681 TLegend* l = p->BuildLegend();
691 //____________________________________________________________________
695 * @param y Current y position. On return new y position
696 * @param name Parameter name
697 * @param value Parameter value
698 * @param size Optional text size
700 void DrawParameter(Double_t& y,
702 const TString& value,
705 Double_t s = fParName->GetTextSize();
706 Double_t t = fParVal->GetTextSize();
707 if (name.IsNull() && value.IsNull()) return;
709 fParName->SetTextSize(size);
710 fParVal->SetTextSize(size);
713 fParName->DrawLatex(fParName->GetX(), y, Form("%s:", name.Data()));
715 fParVal->DrawLatex(fParVal->GetX(), y, value.Data());
717 y -= 1.2 * fParName->GetTextSize();
718 else if (!value.IsNull())
719 y -= 1.2 * fParVal->GetTextSize();
721 fParName->SetTextSize(s);
722 fParVal->SetTextSize(t);
724 //__________________________________________________________________
725 void DivideForRings(Bool_t commonX, Bool_t commonY)
728 // Divide canvas for rings
730 if ((!commonX && !commonY) ||
731 (commonX && commonY)) {
733 // +----------+----------+
734 // | 1: FMD1i | 2: Free |
735 // +----------+----------+
736 // | 3: FMD2i | 4: FMD2o |
737 // +----------+----------+
738 // | 5: FMD3i | 6: FMD3o |
739 // +----------+----------+
742 // +----------+----------+----------+
743 // | 1: FMD1i | 2: FMD2i | 3: FMD3i |
744 // +----------+----------+----------+
745 // | 4: Free | 5: FMD2o | 6: FMD3o |
746 // +----------+----------+----------+
748 fBody->Divide(fLandscape ? 3 : 2, fLandscape ? 2 : 3,
749 commonX ? 0 : 0.01, commonY ? 0 : 0.01);
750 fRingMap[0] = fBody->GetPad(1); // FMD1i;
751 fRingMap[1] = fBody->GetPad(fLandscape ? 2 : 3); // FMD2i;
752 fRingMap[2] = fBody->GetPad(fLandscape ? 5 : 4); // FMD2o;
753 fRingMap[3] = fBody->GetPad(fLandscape ? 3 : 5); // FMD3i;
754 fRingMap[4] = fBody->GetPad(6); // FMD3o;
755 fRingMap[5] = fBody->GetPad(fLandscape ? 4 : 2); // Free
757 else if (commonX && !commonY) {
758 // Divide into two - left/right
760 // +----------++----------+
761 // | 1: FMD1i || 1: Free |
762 // +----------++----------+
763 // | 2: FMD2i || 2: FMD2o |
764 // +----------++----------+
765 // | 3: FMD3i || 3: FMD3o |
766 // +----------++----------+
769 // +----------++----------++----------+
770 // | 1: FMD1i || 1: FMD2i || 1: FMD3i |
771 // +----------++----------++----------+
772 // | 2: Free || 2: FMD2o || 2: FMD3o |
773 // +----------++----------++----------+
775 fBody->Divide(fLandscape ? 3 : 2, 1);
776 TVirtualPad* left = fBody->cd(1);
777 left->Divide(fLandscape ? 2 : 3);
778 TVirtualPad* middle = fBody->cd(2);
779 middle->Divide(fLandscape ? 2 : 3);
781 Info("left","%p",left); left->ls();
782 Info("middle","%p",middle); middle->ls();
784 fRingMap[0] = left->GetPad(1); // FMD1i;
786 fRingMap[1] = left->GetPad(2); // FMD2i
787 fRingMap[2] = middle->GetPad(2); // FMD2o
788 fRingMap[3] = left->GetPad(3); // FMD3i
789 fRingMap[4] = middle->GetPad(3); // FMD3o
790 fRingMap[5] = middle->GetPad(1); // Free
793 TVirtualPad* right = fBody->cd(3);
794 right->Divide(fLandscape ? 2 : 3);
795 fRingMap[1] = middle->GetPad(1); // FMD2i
796 fRingMap[2] = middle->GetPad(2); // FMD2o
797 fRingMap[3] = right->GetPad(1); // FMD3i
798 fRingMap[4] = right->GetPad(2); // FMD3o
799 fRingMap[5] = left->GetPad(2); // Free
803 // Divide into two - left/right
805 // +----------+----------+
806 // | 1: FMD1i | 2: Free |
807 // +----------+----------+
808 // +----------+----------+
809 // | 1: FMD2i | 2: FMD2o |
810 // +----------+----------+
811 // +----------+----------+
812 // | 1: FMD3i | 2: FMD3o |
813 // +----------+----------+
816 // +----------+----------+----------+
817 // | 1: FMD1i | 2: FMD2i | 3: FMD3i |
818 // +----------+----------+----------+
819 // +----------+----------+----------+
820 // | 1: Free | 2: FMD2o | 3: FMD3o |
821 // +----------+----------+----------+
823 fBody->Divide(1, fLandscape ? 2 : 3);
824 TVirtualPad* top = fBody->cd(1);
825 top->Divide(fLandscape ? 3 : 2);
826 TVirtualPad* middle = fBody->cd(2);
827 middle->Divide(fLandscape ? 3 : 2);
829 fRingMap[0] = top->GetPad(1); // FMD1i;
831 TVirtualPad* bottom = fBody->cd(2);
834 fRingMap[1] = middle->GetPad(1); // FMD2i
835 fRingMap[2] = middle->GetPad(2); // FMD2o
836 fRingMap[3] = bottom->GetPad(1); // FMD3i
837 fRingMap[4] = bottom->GetPad(2); // FMD3o
838 fRingMap[5] = top->GetPad(2); // Free
841 fRingMap[1] = top->GetPad(2); // FMD2i
842 fRingMap[2] = middle->GetPad(2); // FMD2o
843 fRingMap[3] = top->GetPad(3); // FMD3i
844 fRingMap[4] = middle->GetPad(3); // FMD3o
845 fRingMap[5] = middle->GetPad(1); // Free
848 if (fRingMap[0]) fRingMap[0]->SetTitle("FMD1i");
849 if (fRingMap[1]) fRingMap[1]->SetTitle("FMD2i");
850 if (fRingMap[2]) fRingMap[2]->SetTitle("FMD2o");
851 if (fRingMap[3]) fRingMap[3]->SetTitle("FMD3i");
852 if (fRingMap[4]) fRingMap[4]->SetTitle("FMD3o");
853 if (fRingMap[5]) fRingMap[5]->SetTitle("Other");
855 //__________________________________________________________________
856 TVirtualPad* RingPad(UShort_t d, Char_t r) const
860 case 0: idx = 5; break;
861 case 1: idx = 0; break;
862 case 2: idx = 1 + ((r == 'I' || r == 'i') ? 0 : 1); break;
863 case 3: idx = 3 + ((r == 'I' || r == 'i') ? 0 : 1); break;
866 return fRingMap[idx];
867 // return fBody->GetPad(no);
869 //__________________________________________________________________
871 * Draw an object in pad
875 * @param h Object to draw
876 * @param opts Options
879 void DrawInRingPad(UShort_t d,
885 TVirtualPad* p = RingPad(d, r);
887 Warning("DrawInRingPad", "No pad found for FMD%d%c", d, r);
890 DrawInPad(p, h, opts, flags);
894 //__________________________________________________________________
896 * Pause after each plot
902 printf("Press enter to continue");
907 //__________________________________________________________________
908 TCanvas* fCanvas; // Our canvas
909 TPad* fTop; // Top part
910 TPad* fBody; // Body part
911 TLatex* fHeader; // Header text
912 TLatex* fParName; // Parameter name
913 TLatex* fParVal; // Parameter value
914 Bool_t fPause; // Whether to pause after drawing a canvas
915 Bool_t fLandscape; // Landscape or Portrait orientation
916 TVirtualPad** fRingMap;