/**
* @file SummaryDrawer.C
* @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
* @date Sun Nov 25 11:36:41 2012
*
* @brief Base class for classes to draw summaries
*
*
*/
#ifndef SUMMARYDRAWER_C
# define SUMMARYDRAWER_C
# ifndef __CINT__
# include <THStack.h>
# include <TH1.h>
# include <TH2.h>
# include <TH3.h>
# include <TParameter.h>
# include <TCanvas.h>
# include <TList.h>
# include <TFile.h>
# include <TError.h>
# include <TLatex.h>
# include <TLegend.h>
# include <TLegendEntry.h>
# include <TMath.h>
# include <TString.h>
# include <TStyle.h>
# include <TSystem.h>
# include <TProfile.h>
# include <TGaxis.h>
# include <TPad.h>
# include <TRegexp.h>
# include <TGraph.h>
# include <sstream>
# include <iomanip>
# else
# ifdef __ACLIC__
class THStack;
class TH1;
class TH2;
class TH3;
class TCollection;
class TCanvas;
class TVirtualPad;
class TPad;
class TLatex;
class TAxis;
# endif
# endif
/**
* Base class for summary drawers
*
*/
class SummaryDrawer
{
public:
enum {
kLogx = 0x1,
kLogy = 0x2,
kLogz = 0x4,
kLegend = 0x10,
kGridx = 0x100,
kGridy = 0x200,
kGridz = 0x400,
kSilent = 0x800,
kNorth = 0x1000,
kMiddle = 0x2000,
kSouth = 0x3000,
kEast = 0x10000,
kCenter = 0x20000,
kWest = 0x30000
};
enum {
kLandscape = 0x100,
kPause = 0x200
};
SummaryDrawer()
: fCanvas(0),
fTop(0),
fBody(0),
fHeader(0),
fParName(0),
fParVal(0),
fPause(false),
fLandscape(false),
fRingMap(0),
fPDF(true),
fLastTitle("")
{
fRingMap = new TVirtualPad*[6];
fRingMap[0] = 0;
fRingMap[1] = 0;
fRingMap[2] = 0;
fRingMap[3] = 0;
fRingMap[4] = 0;
fRingMap[5] = 0;
}
virtual ~SummaryDrawer() {}
protected:
//____________________________________________________________________
/**
* Get null terminated array of ring names
*
* @param lower If true, return in the form FMD[1-3][io], otherwise
* in the form FMD[1-3][IO]
*
* @return Null terminated array of ring names
*/
static const Char_t** GetRingNames(Bool_t lower=false)
{
static const Char_t* lN[]={ "FMD1i", "FMD2i", "FMD2o", "FMD3o", "FMD3i", 0};
static const Char_t* uN[]={ "FMD1I", "FMD2I", "FMD2O", "FMD3O", "FMD3I", 0};
return (lower ? lN : uN);
}
//____________________________________________________________________
/**
* Get the standard color for a ring
*
* @param d Detector
* @param r Ring
*
* @return
*/
static Color_t RingColor(UShort_t d, Char_t r)
{
return ((d == 1 ? kRed : (d == 2 ? kGreen : kBlue))
+ ((r == 'I' || r == 'i') ? 2 : -3));
}
//____________________________________________________________________
TLegend* DrawRingLegend(TVirtualPad* p, UInt_t flags)
{
TLegend* l = MakeLegend(p, flags, false);
for (UShort_t i = 0; i < 5; i++) {
UShort_t d = (i+1)/2+1;
Char_t r = (i/2 == 1) ? 'o' : 'i';
TLegendEntry* e = l->AddEntry("dummy", Form("FMD%d%c", d, r), "f");
e->SetFillColor(RingColor(d, r));
e->SetFillStyle(1001);
e->SetLineColor(kBlack);
}
l->Draw();
return l;
}
//____________________________________________________________________
static void SysString(UShort_t sys, TString& str)
{
str = "?";
switch (sys) {
case 1: str = "pp"; break;
case 2: str = "PbPb"; break;
case 3: str = "pPb"; break;
}
}
//____________________________________________________________________
static void SNNString(UShort_t sNN, TString& str)
{
str = "?";
if (sNN < 1000) str = Form("%dGeV", sNN);
else if (sNN < 3000) str = Form("%4.2fTeV", 0.001*sNN);
else str = Form("%dTeV", sNN/1000);
}
//____________________________________________________________________
/**
* Append an & to a string and the next term.
*
* @param trg Output string
* @param what Term
*/
static void AppendAnd(TString& trg, const TString& what)
{
if (!trg.IsNull()) trg.Append(" & ");
trg.Append(what);
}
//____________________________________________________________________
static void TriggerString(ULong_t trigger, TString& str)
{
str = "";
/**
* Bits of the trigger pattern
*/
enum {
/** In-elastic collision */
kInel = 0x0001,
/** In-elastic collision with at least one SPD tracklet */
kInelGt0 = 0x0002,
/** Non-single diffractive collision */
kNSD = 0x0004,
/** Empty bunch crossing */
kEmpty = 0x0008,
/** A-side trigger */
kA = 0x0010,
/** B(arrel) trigger */
kB = 0x0020,
/** C-side trigger */
kC = 0x0080,
/** Empty trigger */
kE = 0x0100,
/** pileup from SPD */
kPileUp = 0x0200,
/** true NSD from MC */
kMCNSD = 0x0400,
/** Offline MB triggered */
kOffline = 0x0800,
/** At least one SPD cluster */
kNClusterGt0 = 0x1000,
/** V0-AND trigger */
kV0AND = 0x2000,
/** Satellite event */
kSatellite = 0x4000
};
if ((trigger & kInel) != 0x0) AppendAnd(str, "INEL");
if ((trigger & kInelGt0) != 0x0) AppendAnd(str, "INEL>0");
if ((trigger & kNSD) != 0x0) AppendAnd(str, "NSD");
if ((trigger & kV0AND) != 0x0) AppendAnd(str, "V0AND");
if ((trigger & kA) != 0x0) AppendAnd(str, "A");
if ((trigger & kB) != 0x0) AppendAnd(str, "B");
if ((trigger & kC) != 0x0) AppendAnd(str, "C");
if ((trigger & kE) != 0x0) AppendAnd(str, "E");
if ((trigger & kMCNSD) != 0x0) AppendAnd(str, "MCNSD");
if ((trigger & kNClusterGt0) != 0x0) AppendAnd(str, "NCluster>0");
if ((trigger & kSatellite) != 0x0) AppendAnd(str, "Satellite");
}
//__________________________________________________________________
/**
* Find an object in a collection
*
* @param parent Parent directory
* @param name Name of object
* @param verb Be verbose
*
* @return Pointer to object or null
*/
static TObject* GetObject(const TObject* parent,
const TString& name,
Bool_t verb=true)
{
if (!parent) {
if (verb) Warning("GetObject", "No parent given");
return 0;
}
if (name.IsNull()) {
if (verb) Warning("GetObject", "No name specified");
return 0;
}
TObject* o = 0;
if (parent->IsA()->InheritsFrom(TCollection::Class())) {
const TCollection* p = static_cast<const TCollection*>(parent);
o = p->FindObject(name);
}
else if (parent->IsA()->InheritsFrom(TDirectory::Class())) {
const TDirectory* d = static_cast<const TDirectory*>(parent);
o = const_cast<TDirectory*>(d)->Get(name);
}
else
Warning("GetObject", "Do not know how to find an object (%s) in "
"%s (of class %s)", name.Data(),
parent ? parent->GetName() : "?",
parent ? parent->ClassName() : "?");
if (!o) {
if (verb) Warning("GetObject", "Object \"%s\" not found in parent \"%s\"",
name.Data(), parent->GetName());
return 0;
}
return o;
}
//____________________________________________________________________
/**
* Check the type of a found object
*
* @param o Object
* @param cl Class
* @param src Source of object
*
* @return true on success, false otherwise
*/
static Bool_t CheckType(const TObject* o,
const TClass* cl,
const TString& src)
{
if (!o->IsA()->InheritsFrom(cl)) {
Warning("CheckType", "Object \"%s\" retrieved from \"%s\" is not a "
"%s but a %s", o->GetName(), src.Data(), cl->GetName(),
o->ClassName());
return false;
}
return true;
}
//__________________________________________________________________
/**
* Check a possibly returned object.
*
* @param o Object found - if any
* @param p Parent of object
*
* @return A pointer to the object cast to the right type
*/
template <typename T>
static T* DoGetObject(TObject* o, const TObject* p)
{
if (!o) return 0;
if (!CheckType(o, T::Class(), p->GetName())) return 0;
return static_cast<T*>(o);
}
//__________________________________________________________________
/**
* Check a returned parameter from a parent
*
* @param o Possibly found object
* @param p Parent object
* @param value Value
*
* @return true on success, false otherwise
*/
template <typename T>
static Bool_t DoGetParameter(TObject* o, const TObject* p, T& value)
{
TParameter<T>* r = DoGetObject<TParameter<T> >(o, p);
if (!r) return false;
// if (r->TestBit(TParameter<T>::kFirst)) value = r->GetVal();
// else value = r->GetUniqueID();
value = r->GetVal();
if (!r->TestBit(BIT(19))) {
TObject* oc = GetObject(p, "count", false);
if (oc) {
TParameter<int>* pc = static_cast<TParameter<int>*>(oc);
int cnt = pc->GetVal();
value /= cnt;
}
else
value = r->GetUniqueID();
}
// value = r->GetUniqueID();
return true;
}
//___________________________________________________________________
/**
* Get a Short_t parameter value
*
* @param c Parent collection
* @param name Name of parameter
* @param value On return the value
* @param verb If true, complain if not found
*/
static Bool_t GetParameter(const TObject* c,
const TString& name,
Short_t& value,
Bool_t verb=true)
{
int v;
Bool_t r = DoGetParameter(GetObject(c, name, verb), c, v);
value = v;
return r;
}
//___________________________________________________________________
/**
* Get a UShort_t parameter value
*
* @param c Parent collection
* @param name Name of parameter
* @param value On return the value
* @param verb If true, complain if not found
*/
static Bool_t GetParameter(const TObject* c,
const TString& name,
UShort_t& value,
Bool_t verb=true)
{
int v;
Bool_t r = DoGetParameter(GetObject(c, name, verb), c, v);
value = v;
return r;
}
//___________________________________________________________________
/**
* Get a ULong_t parameter value
*
* @param c Parent collection
* @param name Name of parameter
* @param value On return the value
* @param verb If true, complain if not found
*/
static Bool_t GetParameter(const TObject* c,
const TString& name,
ULong_t& value,
Bool_t verb=true)
{
Long_t v;
Bool_t r = DoGetParameter(GetObject(c, name, verb), c, v);
value = v;
return r;
}
//_____________________________________________________________________
/**
* Get a Int_t parameter value
*
* @param c Parent collection
* @param name Name of parameter
* @param value On return the value
* @param verb If true, complain if not found
*/
static Bool_t GetParameter(const TObject* c,
const TString& name,
Int_t& value,
Bool_t verb=true)
{
return DoGetParameter(GetObject(c, name, verb), c, value);
}
//_____________________________________________________________________
/**
* Get a Double_t parameter value
*
* @param c Parent collection
* @param name Name of parameter
* @param value On return the value
* @param verb If true, complain if not found
*/
static Bool_t GetParameter(const TObject* c,
const TString& name,
Double_t& value,
Bool_t verb=true);
//_____________________________________________________________________
/**
* Get a Bool_t parameter value
*
* @param c Parent collection
* @param name Name of parameter
* @param value On return the value
* @param verb If true, complain if not found
*/
static Bool_t GetParameter(const TObject* c,
const TString& name,
Bool_t& value,
Bool_t verb=true)
{
return DoGetParameter(GetObject(c, name, verb), c, value);
}
//____________________________________________________________________
/**
* Find a collection in another collection
*
* @param parent Parent collection
* @param name Name of the collection
* @param verb If true and not found, complain
*
* @return pointer to collection on success, otherwise null
*/
static TCollection* GetCollection(const TObject* parent,
const TString& name,
Bool_t verb=true)
{
return DoGetObject<TCollection>(GetObject(parent, name, verb), parent);
}
//____________________________________________________________________
/**
* Check a 1D histogram object from a parent
*
* @param parent Parent collection
* @param name Name of histogram
* @param verb Possibly be verbose
*
* @return pointer or null
*/
static TH1* GetH1(const TObject* parent,
const TString& name,
Bool_t verb=true)
{
return DoGetObject<TH1>(GetObject(parent, name, verb), parent);
}
//____________________________________________________________________
/**
* Get a 2D histogram from a collection
*
* @param parent Parent collection
* @param name Name of histogram
* @param verb If true and not found, complain
*
* @return pointer or null
*/
static TH2* GetH2(const TObject* parent,
const TString& name,
Bool_t verb=true)
{
return DoGetObject<TH2>(GetObject(parent, name, verb), parent);
}
//____________________________________________________________________
/**
* Get a 2D histogram from a collection
*
* @param parent Parent collection
* @param name Name of histogram
* @param verb If true and not found, complain
*
* @return pointer or null
*/
static TH3* GetH3(const TCollection* parent,
const TString& name,
Bool_t verb=true)
{
// Info("GetH2", "Getting 2D histogram of %s from %p", name.Data(), c);
// --- Find the object -------------------------------------------
return DoGetObject<TH3>(GetObject(parent, name, verb), parent);
}
//__________________________________________________________________
/**
* Get a histogram stack from a collection
*
* @param parent Parent collection
* @param name Name of histogram
* @param sub If set, fill from sub-component
* @param verb If true and not found, complain
*
* @return pointer or null
*/
static THStack* GetStack(const TObject* parent,
const TString& name,
const char* sub=0,
Bool_t verb=true)
{
THStack* stack = DoGetObject<THStack>(GetObject(parent,name,verb),parent);
if (!stack) return 0;
if (sub == 0) return stack;
if (stack->GetHists()->GetEntries() <= 0 ||stack->GetMaximum() < 1) {
// Info("GetStack", "No entries in %s", name.Data());
stack->GetHists()->Delete();
const char** ptr = GetRingNames(false);
while (*ptr) {
TCollection* sc = GetCollection(parent, *ptr, true);
if (!sc) { ptr++; continue; }
TObject* obj = GetObject(sc, sub);
if (!obj) {
continue;
ptr++;
}
if (obj->IsA()->InheritsFrom(TH2::Class())) {
TH2* h = static_cast<TH2*>(obj);
TH1* p = h->ProjectionX(*ptr, 1, h->GetNbinsY(), "e");
p->Scale(1., "width");
p->SetTitle(*ptr);
p->SetDirectory(0);
stack->Add(p);
}
else if (obj->IsA()->InheritsFrom(TH1::Class())) {
TH1* hh = static_cast<TH1*>(obj);
hh->SetTitle(*ptr);
stack->Add(hh);
}
ptr++;
}
}
// --- Return the collection -------------------------------------
return stack;
}
//____________________________________________________________________
/**
* Clear canvas
*
*/
void ClearCanvas()
{
if (fTop) {
fTop->Clear();
fTop->SetNumber(1);
fTop->SetFillColor(kBlue-5);
fTop->SetBorderSize(0);
fTop->SetBorderMode(0);
}
fBody->Clear();
fBody->SetNumber(2);
fBody->SetFillColor(0);
fBody->SetFillStyle(0);
fBody->SetBorderSize(0);
fBody->SetBorderMode(0);
fBody->SetTopMargin(0.01);
fBody->SetLeftMargin(0.10);
fBody->SetRightMargin(0.01);
fBody->SetBottomMargin(0.10);
fRingMap[0] = 0;
fRingMap[1] = 0;
fRingMap[2] = 0;
fRingMap[3] = 0;
fRingMap[4] = 0;
fRingMap[5] = 0;
fCanvas->cd();
}
//____________________________________________________________________
/**
* Create a canvas
*
* @param pname Name of PDF file to make
* @param landscape If true, print in landscape
* @param pdf Make PDF
*
* @return Created canvas
*/
void CreateCanvas(const TString& pname,
Bool_t landscape=false,
Bool_t pdf=true,
Bool_t useTop=true)
{
// Info("CreateCanvas", "Creating canvas");
fLandscape = landscape;
fPDF = pdf;
Int_t height = 1000;
Int_t width = height / TMath::Sqrt(2);
if (fLandscape) {
Int_t tmp = height;
height = width;
width = tmp;
}
fCanvas = new TCanvas("c", pname.Data(), width, height);
fCanvas->SetFillColor(0);
fCanvas->SetBorderSize(0);
fCanvas->SetBorderMode(0);
if (fPDF)
fCanvas->Print(Form("%s[", pname.Data()),
Form("pdf %s", fLandscape ? "Landscape" : ""));
fCanvas->SetLeftMargin(.1);
fCanvas->SetRightMargin(.05);
fCanvas->SetBottomMargin(.1);
fCanvas->SetTopMargin(.05);
gStyle->SetOptStat(0);
gStyle->SetTitleColor(0);
gStyle->SetTitleStyle(0);
gStyle->SetTitleBorderSize(0);
gStyle->SetTitleX(.5);
gStyle->SetTitleY(1);
gStyle->SetTitleW(.8);
gStyle->SetTitleH(.09);
gStyle->SetFrameFillColor(kWhite);
gStyle->SetFrameBorderSize(1);
gStyle->SetFrameBorderMode(1);
gStyle->SetPalette(1);
Float_t dy = useTop ? .05 : 0;
if (useTop) {
fTop = new TPad("top", "Top", 0, 1-dy, 1, 1, 0, 0);
fTop->SetNumber(1);
fTop->SetFillColor(kBlue-5);
fTop->SetBorderSize(0);
fTop->SetBorderMode(0);
fCanvas->cd();
fTop->Draw();
}
fBody = new TPad("body", "Body", 0, 0, 1, 1-dy, 0, 0);
fBody->SetNumber(2);
fBody->SetFillColor(0);
fBody->SetFillStyle(0);
fBody->SetBorderSize(0);
fBody->SetBorderMode(0);
fCanvas->cd();
fBody->Draw();
fHeader = new TLatex(.5, .5, "Title");
fHeader->SetNDC();
fHeader->SetTextAlign(22);
fHeader->SetTextSize(.7);
fHeader->SetTextColor(kWhite);
fHeader->SetTextFont(62);
Double_t x1 = .1;
Double_t x2 = .6;
Double_t y = .8;
Double_t s = fLandscape ? 0.08 : 0.05;
fParName = new TLatex(x1, y, "");
fParName->SetTextAlign(13);
fParName->SetNDC();
fParName->SetTextSize(s);
fParName->SetTextFont(62);
fParVal = new TLatex(x2, y, "");
fParVal->SetTextAlign(13);
fParVal->SetNDC();
fParVal->SetTextSize(s);
fParVal->SetTextFont(42);
fCanvas->cd();
}
//____________________________________________________________________
/**
* Close the PDF
*
*/
void CloseCanvas()
{
// Info("CloseCanvas", "Closing canvas");
// ClearCanvas();
if (fPDF && fCanvas) {
// Printf("Closing canvas with last title %s", fLastTitle.Data());
fCanvas->Print(Form("%s]", fCanvas->GetTitle()),
Form("pdf %s Title:%s",
fLandscape ? "Landscape" : "",
fLastTitle.Data()));
}
if (fCanvas)
fCanvas->Close();
fCanvas = 0;
}
//__________________________________________________________________
/**
* Print the canvas
*
* @param title Title
* @param size Size of text
*/
void PrintCanvas(const TString& title, Float_t size=.7)
{
if (fTop) {
fTop->cd();
fHeader->SetTextSize(size);
fHeader->DrawLatex(.5,.5,title);
}
fCanvas->Modified();
fCanvas->Update();
fCanvas->cd();
if (fPDF) {
TString tit;
tit.Form("pdf %s Title:%s", fLandscape ? "Landscape" : "",
title.Data());
#ifdef DEBUG
Info("PrintCanvas", "Printing to %s (%s)",
fCanvas->GetTitle(), tit.Data());
#else
gSystem->RedirectOutput("/dev/null");
#endif
fCanvas->Print(fCanvas->GetTitle(), tit);
#ifndef DEBUG
gSystem->RedirectOutput(0);
#endif
fLastTitle = title;
Pause();
ClearCanvas();
}
}
//__________________________________________________________________
/**
* Make a chapter page
*
* @param title Title
*/
void MakeChapter(const TString& title)
{
fBody->cd();
TLatex* ltx = new TLatex(.5, .5, title);
ltx->SetNDC();
ltx->SetTextAlign(22);
ltx->Draw();
PrintCanvas(title);
}
//__________________________________________________________________
/**
* Draw an object in pad
*
* @param c PArent pad
* @param padNo Sub-pad number (0 is self)
* @param h Object to draw
* @param opts Options
* @param flags Flags
* @param title Title on plot
*
* @return Drawn object - if any
*/
TObject* DrawInPad(TVirtualPad* c,
Int_t padNo,
TObject* h,
Option_t* opts="",
UInt_t flags=0x0,
const char* title="")
{
TVirtualPad* p = c->GetPad(padNo);
if (!p) {
Warning("DrawInPad", "Pad # %d not found in %s", padNo, c->GetName());
return 0;
}
return DrawInPad(p, h, opts, flags, title);
}
/**
* Draw a clone of an object
*
* @param o Object
* @param options Draw options
* @param title Title of object
*
* @return Drawn object - if any
*/
virtual TObject* DrawObjClone(TObject* o, Option_t* options,
const char* title)
{
if (o->IsA()->InheritsFrom(TH1::Class()))
return DrawObjClone(static_cast<TH1*>(o), options, title);
else if (o->IsA()->InheritsFrom(THStack::Class()))
return DrawObjClone(static_cast<THStack*>(o), options, title);
else if (o->IsA()->InheritsFrom(TGraph::Class()))
return o->DrawClone(options);
else
o->Draw(options);
return o;
}
/**
* Draw an object clone
*
* @param o Stack object
* @param options Draw options
* @param title Title on plot
*
* @return Drawn object - if any
*/
virtual TObject* DrawObjClone(THStack* o, Option_t* options,
const char* title)
{
// THStack* tmp = static_cast<THStack*>(o->Clone());
o->Draw(options);
if (title && title[0] != '\0') o->GetHistogram()->SetTitle(title);
TAxis* xAxis = o->GetXaxis();
if (!xAxis) {
Warning("DrawObjClone", "No X-axis for drawn stack %s", o->GetName());
return o;
}
TH1* h = 0;
Int_t nBins = xAxis->GetNbins();
Double_t xMin = xAxis->GetXmin();
Double_t xMax = xAxis->GetXmax();
TIter next(o->GetHists());
while ((h = static_cast<TH1*>(next()))) {
TAxis* a = h->GetXaxis();
nBins = TMath::Max(nBins, a->GetNbins());
xMin = TMath::Min(xMin, a->GetXmin());
xMax = TMath::Max(xMax, a->GetXmax());
}
if (nBins != xAxis->GetNbins() ||
xMin != xAxis->GetXmin() ||
xMax != xAxis->GetXmax()) {
xAxis->Set(nBins, xMin, xMax);
o->GetHistogram()->Rebuild();
}
return o;
}
/**
* Draw an object clone
*
* @param o Histogram
* @param options Draw options
* @param title Title on plot
*
* @return Drawn object - if any
*/
virtual TObject* DrawObjClone(TH1* o, Option_t* options, const char* title)
{
TH1* tmp = o->DrawCopy(options);
if (title && title[0] != '\0') tmp->SetTitle(title);
return tmp;
}
//__________________________________________________________________
static void GetLegendPosition(UInt_t flags, TVirtualPad* p,
Double_t& x1, Double_t& y1,
Double_t& x2, Double_t& y2)
{
UInt_t horiz = (flags & 0xF0000);
UInt_t verti = (flags & 0xF000);
Double_t eps = .01;
Double_t dY = .4;
Double_t dX = .4;
Double_t yB = p->GetBottomMargin()+eps;
Double_t yT = 1-p->GetTopMargin()-eps;
Double_t xL = p->GetLeftMargin()+eps;
Double_t xR = 1-p->GetRightMargin()-eps;
switch (verti) {
case kNorth: y1 = yT-dY; break;
case kSouth: y1 = yB; break;
case kMiddle: y1 = (yB+yT-dY)/2; break;
}
y2 = TMath::Min(y1 + dY, yT);
switch (horiz) {
case kEast: x1 = xL; break;
case kWest: x1 = xR-dX; break;
case kCenter: x1 = (xL+xR-dX)/2; break;
}
x2 = TMath::Min(x1 + dX, xR);
}
//__________________________________________________________________
/**
* Make a legend
*
* @param p
* @param flags
* @param autoFill
*
* @return
*/
TLegend* MakeLegend(TVirtualPad* p, UInt_t flags, Bool_t autoFill)
{
Double_t x1 = fParVal->GetX();
Double_t y1 = fParVal->GetY();
Double_t x2 = 0;
Double_t y2 = 0;
GetLegendPosition(flags, p, x1, y1, x2, y2);
//Printf("Legend at (%f,%f)x(%f,%f)", x1, y1, x2, y2);
TLegend* l = 0;
if (autoFill) l = p->BuildLegend(x1, y1, x2, y2);
else l = new TLegend(x1, y1, x2, y2);
l->SetFillColor(0);
l->SetFillStyle(0);
l->SetBorderSize(0);
return l;
}
//__________________________________________________________________
/**
* Draw an object in pad
*
* @param p Pad
* @param h Object to draw
* @param opts Options
* @param flags Flags
* @param title Title on plot
*
* @return Drawn object - if any
*/
TObject* DrawInPad(TVirtualPad* p,
TObject* h,
Option_t* opts="",
UInt_t flags=0x0,
const char* title="")
{
if (!p) {
Warning("DrawInPad", "No pad specified");
return 0;
}
p->cd();
// Info("DrawInPad", "Drawing in pad %p", p);
// fBody->ls();
if (flags & kLogx) p->SetLogx();
if (flags & kLogy) p->SetLogy();
if (flags & kLogz) p->SetLogz();
if (flags & kGridx) p->SetGridx();
if (flags & kGridy) p->SetGridy();
// if (flags & kGridz) p->SetGridz();
p->SetFillColor(0);
TString o(opts);
if (o.Contains("colz", TString::kIgnoreCase))
p->SetRightMargin(0.15);
if (!h) {
if (!(flags & kSilent))
Warning("DrawInPad", "Nothing to draw in pad # %s", p->GetName());
return 0;
}
if (o.Contains("text", TString::kIgnoreCase)) {
TH1* hh = static_cast<TH1*>(h);
hh->SetMaximum(1.1*hh->GetMaximum());
hh->SetMarkerSize(2);
o.Append("30");
}
TObject* ret = DrawObjClone(h, o, title);
if (flags & kLegend) {
MakeLegend(p, flags, true);
}
p->Modified();
p->Update();
p->cd();
return ret;
}
//__________________________________________________________________
/**
* Draw two graphs in the same frame, but with separate y-axis
*
* @param c Mother pad
* @param padNo Sub-pad number (0 is self)
* @param h1 First histogram
* @param h2 Second histogram
* @param opts Options
* @param flags Flags
*/
void DrawTwoInPad(TVirtualPad* c, Int_t padNo, TH1* h1, TH1* h2,
Option_t* opts="", UShort_t flags=0x0)
{
TVirtualPad* p = c->cd(padNo);
if (!p) {
Warning("DrawInPad", "Pad # %d not found in %s", padNo, c->GetName());
return;
}
if (flags & kLogx) p->SetLogx();
if (flags & kLogy) p->SetLogy();
if (flags & kLogz) p->SetLogz();
if (flags & kGridx) p->SetGridx();
if (flags & kGridy) p->SetGridy();
// if (flags & kGridz) p->SetGridz();
p->SetFillColor(0);
TString o(opts);
o.ToLower();
TString fopts(o);
Bool_t e3 = o.Contains("e3");
if (e3) {
fopts.ReplaceAll("e3", " same");
}
h1->GetYaxis()->SetLabelSize(0);
h1->GetYaxis()->SetTicks("");
h1->GetYaxis()->SetNdivisions(0);
h1->DrawCopy(o); // First draw with opts
if (e3) h1->DrawCopy(fopts);
p->Update();
Double_t m1 = 1.05 * h1->GetMaximum();
if (m1 > 0) {
TGaxis* a1 = new TGaxis(p->GetUxmin(), p->GetUymin(),
p->GetUxmin(), p->GetUymax(),
0, m1, 510);
a1->SetLineColor(h1->GetLineColor());
a1->Draw();
}
o.Append(" same");
Double_t m2 = 1.1 * h2->GetMaximum();
Double_t scale = m2 > 0 ? m1 / m2 : 1;
h2->Scale(scale);
h2->DrawCopy(o);
if (e3) h2->DrawCopy(fopts);
if (m2 > 0) {
TGaxis* a2 = new TGaxis(p->GetUxmax(), p->GetUymin(),
p->GetUxmax(), p->GetUymax(),
0, m2, 510, "+L");
a2->SetLineColor(h2->GetLineColor());
a2->Draw();
}
if (flags& kLegend) {
MakeLegend(p, flags, true);
}
p->Modified();
p->Update();
p->cd();
}
//____________________________________________________________________
/**
* Draw a parameter.
*
* @param y Current y position. On return new y position
* @param name Parameter name
* @param value Parameter value
* @param size Optional text size
*/
void DrawParameter(Double_t& y,
const TString& name,
const TString& value,
Double_t size=0)
{
Double_t s = fParName->GetTextSize();
Double_t t = fParVal->GetTextSize();
if (name.IsNull() && value.IsNull()) return;
if (size > 0) {
fParName->SetTextSize(size);
fParVal->SetTextSize(size);
}
if (!name.IsNull())
fParName->DrawLatex(fParName->GetX(), y, Form("%s:", name.Data()));
if (!value.IsNull())
fParVal->DrawLatex(fParVal->GetX(), y, value.Data());
if (!name.IsNull())
y -= 1.2 * fParName->GetTextSize();
else if (!value.IsNull())
y -= 1.2 * fParVal->GetTextSize();
fParName->SetTextSize(s);
fParVal->SetTextSize(t);
}
template <typename T>
void DrawTParameter(Double_t& y,
TList* list,
const TString& name) {
T value;
if (!GetParameter(list, name, value))
return;
std::stringstream s;
s << std::boolalpha << value;
DrawParameter(y, name, s.str().c_str(), 0);
}
//__________________________________________________________________
/**
* Structure to hold a dived pad
*/
struct DividedPad {
TVirtualPad* fParent;
TVirtualPad** fSubs;
Bool_t fLandscape;
Int_t fNCol;
Int_t fNRow;
DividedPad(TVirtualPad* p, Bool_t landscape, Int_t nCol, Int_t nRow)
: fParent(p),
fSubs(0),
fLandscape(landscape),
fNCol(landscape ? nRow : nCol),
fNRow(landscape ? nCol : nRow)
{
Int_t nPad = fNCol * fNRow;
fSubs = new TVirtualPad*[nPad];
}
void Divide(Bool_t commonX, Bool_t commonY) {
if ((!commonX && !commonY) || (commonX && commonY)) {
// In case we have no common axis or do have both to be common,
// we directly use the TVirtualPad::Divide member function
fParent->Divide(fNCol, fNRow, commonX ? 0 : 0.01, commonY ? 0 : 0.01);
for (Int_t iPad = 1; iPad <= fNRow*fNCol; iPad++)
fSubs[iPad-1] = fParent->GetPad(iPad);
}
else if (commonX && !commonY) {
// We need to have common X axis, but not common Y axis. We first
// divide the pad in fNCol columns, and then each in to fNRow rows
fParent->Divide(fNCol, 1);
for (Int_t iCol = 1; iCol <= fNCol; iCol++) {
TVirtualPad* q = fParent->GetPad(iCol);
if (fNRow == 1) {
fSubs[GetIdx(iCol,0)] = q;
continue;
}
q->Divide(1,fNRow,0,0);
for (Int_t iRow = 1; iRow <= fNRow; iRow++)
fSubs[GetIdx(iCol, iRow)] = q->GetPad(iRow);
}
}
else if (!commonX && commonY) {
// We need to have common Y axis, but not common X axis. We first
// divide the pad in fNRow rows, and then each in to fNCol columns
fParent->Divide(1, fNRow);
for (Int_t iRow = 1; iRow <= fNRow; iRow++) {
TVirtualPad* q = fParent->GetPad(iRow);
if (fNCol == 1) {
fSubs[GetIdx(0,iRow)] = q;
continue;
}
q->Divide(fNCol,1,0,0);
for (Int_t iCol = 1; iCol <= fNCol; iCol++)
fSubs[GetIdx(iCol, iRow)] = q->GetPad(iCol);
}
}
}
virtual ~DividedPad() { if (fSubs) delete [] fSubs; }
/**
* Get a sub-pad
*
* @param idx Index (0 based)
*
* @return Pad or null
*/
TVirtualPad* GetPad(Int_t idx) {
if (!fSubs) {
::Warning("GetPad","No sub-pads");
return 0;
}
if (idx < 0 || idx >= (fNRow*fNCol)) {
::Warning("GetPad", "Inded %d out of bounds [%d,%d]",
idx, 0, fNRow*fNCol);
return 0;
}
return fSubs[idx];
}
Int_t GetIdx(Int_t iCol, Int_t iRow) const
{
return (iRow-1) * fNCol + iCol;
}
/**
* Get a sub-pad
*
* @param iRow Row number (1-based)
* @param iCol Column number (1-based)
*
* @return Pad or null
*/
TVirtualPad* GetPad(Int_t iCol, Int_t iRow) {
if (iRow < 0 || iRow > fNRow) return 0;
if (iCol < 0 || iRow > fNCol) return 0;
return GetPad(GetIdx(iCol, iRow));
}
};
//__________________________________________________________________
void DivideForRings(Bool_t commonX, Bool_t commonY)
{
//
// Divide canvas for rings
//
if ((!commonX && !commonY) ||
(commonX && commonY)) {
// Portrait:
// +----------+----------+
// | 1: FMD1i | 2: Free |
// +----------+----------+
// | 3: FMD2i | 4: FMD2o |
// +----------+----------+
// | 5: FMD3i | 6: FMD3o |
// +----------+----------+
//
// Landscape:
// +----------+----------+----------+
// | 1: FMD1i | 2: FMD2i | 3: FMD3i |
// +----------+----------+----------+
// | 4: Free | 5: FMD2o | 6: FMD3o |
// +----------+----------+----------+
//
fBody->Divide(fLandscape ? 3 : 2, fLandscape ? 2 : 3,
commonX ? 0 : 0.01, commonY ? 0 : 0.01);
fRingMap[0] = fBody->GetPad(1); // FMD1i;
fRingMap[1] = fBody->GetPad(fLandscape ? 2 : 3); // FMD2i;
fRingMap[2] = fBody->GetPad(fLandscape ? 5 : 4); // FMD2o;
fRingMap[3] = fBody->GetPad(fLandscape ? 3 : 5); // FMD3i;
fRingMap[4] = fBody->GetPad(6); // FMD3o;
fRingMap[5] = fBody->GetPad(fLandscape ? 4 : 2); // Free
}
else if (commonX && !commonY) {
// Divide into two - left/right
// Portrait:
// +----------++----------+
// | 1: FMD1i || 1: Free |
// +----------++----------+
// | 2: FMD2i || 2: FMD2o |
// +----------++----------+
// | 3: FMD3i || 3: FMD3o |
// +----------++----------+
//
// Landscape:
// +----------++----------++----------+
// | 1: FMD1i || 1: FMD2i || 1: FMD3i |
// +----------++----------++----------+
// | 2: Free || 2: FMD2o || 2: FMD3o |
// +----------++----------++----------+
//
fBody->Divide(fLandscape ? 3 : 2, 1);
TVirtualPad* left = fBody->cd(1);
left->Divide(fLandscape ? 2 : 3);
TVirtualPad* middle = fBody->cd(2);
middle->Divide(fLandscape ? 2 : 3);
Info("left","%p",left); left->ls();
Info("middle","%p",middle); middle->ls();
fRingMap[0] = left->GetPad(1); // FMD1i;
if (!fLandscape) {
fRingMap[1] = left->GetPad(2); // FMD2i
fRingMap[2] = middle->GetPad(2); // FMD2o
fRingMap[3] = left->GetPad(3); // FMD3i
fRingMap[4] = middle->GetPad(3); // FMD3o
fRingMap[5] = middle->GetPad(1); // Free
}
else {
TVirtualPad* right = fBody->cd(3);
right->Divide(fLandscape ? 2 : 3);
fRingMap[1] = middle->GetPad(1); // FMD2i
fRingMap[2] = middle->GetPad(2); // FMD2o
fRingMap[3] = right->GetPad(1); // FMD3i
fRingMap[4] = right->GetPad(2); // FMD3o
fRingMap[5] = left->GetPad(2); // Free
}
}
else {
// Divide into two - left/right
// Portrait:
// +----------+----------+
// | 1: FMD1i | 2: Free |
// +----------+----------+
// +----------+----------+
// | 1: FMD2i | 2: FMD2o |
// +----------+----------+
// +----------+----------+
// | 1: FMD3i | 2: FMD3o |
// +----------+----------+
//
// Landscape:
// +----------+----------+----------+
// | 1: FMD1i | 2: FMD2i | 3: FMD3i |
// +----------+----------+----------+
// +----------+----------+----------+
// | 1: Free | 2: FMD2o | 3: FMD3o |
// +----------+----------+----------+
//
fBody->Divide(1, fLandscape ? 2 : 3);
TVirtualPad* top = fBody->cd(1);
top->Divide(fLandscape ? 3 : 2);
TVirtualPad* middle = fBody->cd(2);
middle->Divide(fLandscape ? 3 : 2);
fRingMap[0] = top->GetPad(1); // FMD1i;
if (!fLandscape) {
TVirtualPad* bottom = fBody->cd(2);
bottom->Divide(2);
fRingMap[1] = middle->GetPad(1); // FMD2i
fRingMap[2] = middle->GetPad(2); // FMD2o
fRingMap[3] = bottom->GetPad(1); // FMD3i
fRingMap[4] = bottom->GetPad(2); // FMD3o
fRingMap[5] = top->GetPad(2); // Free
}
else {
fRingMap[1] = top->GetPad(2); // FMD2i
fRingMap[2] = middle->GetPad(2); // FMD2o
fRingMap[3] = top->GetPad(3); // FMD3i
fRingMap[4] = middle->GetPad(3); // FMD3o
fRingMap[5] = middle->GetPad(1); // Free
}
}
if (fRingMap[0]) fRingMap[0]->SetTitle("FMD1i");
if (fRingMap[1]) fRingMap[1]->SetTitle("FMD2i");
if (fRingMap[2]) fRingMap[2]->SetTitle("FMD2o");
if (fRingMap[3]) fRingMap[3]->SetTitle("FMD3i");
if (fRingMap[4]) fRingMap[4]->SetTitle("FMD3o");
if (fRingMap[5]) fRingMap[5]->SetTitle("Other");
}
//__________________________________________________________________
TVirtualPad* RingPad(UShort_t d, Char_t r) const
{
Int_t idx = 0;
switch (d) {
case 0: idx = 5; break;
case 1: idx = 0; break;
case 2: idx = 1 + ((r == 'I' || r == 'i') ? 0 : 1); break;
case 3: idx = 3 + ((r == 'I' || r == 'i') ? 0 : 1); break;
default: return 0;
}
return fRingMap[idx];
// return fBody->GetPad(no);
}
//__________________________________________________________________
TVirtualPad* RingPad(const char* name) const
{
TString n(name);
Int_t idx = n.Index("FMD");
if (n == kNPOS) return 0;
n.Remove(0, idx+3);
Int_t det = n.Atoi();
n.Remove(0,1);
Char_t rng = n[0];
return RingPad(det, rng);
}
//__________________________________________________________________
/**
* Draw an object in pad
*
* @param d Detector
* @param r Ring
* @param h Object to draw
* @param opts Options
* @param flags Flags
* @param title Title on plot
*/
void DrawInRingPad(UShort_t d,
Char_t r,
TObject* h,
Option_t* opts="",
UShort_t flags=0x0,
const char* title="")
{
TVirtualPad* p = RingPad(d, r);
if (!p) {
Warning("DrawInRingPad", "No pad found for FMD%d%c", d, r);
return;
}
DrawInPad(p, h, opts, flags, title);
}
/**
* Draw object in a ring pad
*
* @param name Name of ring
* @param h Object to draw
* @param opts Options
* @param flags Flags
* @param title Possible new title
*/
void DrawInRingPad(const char* name,
TObject* h,
Option_t* opts="",
UShort_t flags=0x0,
const char* title="")
{
TVirtualPad* p = RingPad(name);
if (!p) {
Warning("DrawInRingPad", "No pad found for \"%s\"", name);
return;
}
DrawInPad(p, h, opts, flags, title);
}
/**
* Draw object in a ring pad. Which pad to draw in depends on the
* name or title of the drawn object (must contain the ring name as
* a sub-string).
*
* @param h Object to draw
* @param opts Options
* @param flags Flags
* @param title Possible new title
*/
void DrawInRingPad(TObject* h,
Option_t* opts="",
UShort_t flags=0x0,
const char* title="")
{
if (!h) return;
TVirtualPad* p = RingPad(h->GetName());
if (!p) {
p = RingPad(h->GetTitle());
if (!p) {
Warning("DrawInRingPad", "No pad found for %s/%s",
h->GetName(), h->GetTitle());
return;
}
}
DrawInPad(p, h, opts, flags, title);
}
//__________________________________________________________________
/**
* Pause after each plot
*
*/
void Pause()
{
if (!fPause) return;
printf("Press enter to continue");
std::cin.get();
}
static void CompileScript(const TString& name,
const TString& sub,
const TString& check,
Bool_t force)
{
if (!check.IsNull() && gROOT->GetClass(check)) return;
TString fwd =gSystem->ExpandPathName("$ALICE_ROOT/PWGLF/FORWARD/analysis2");
TString macPath(gROOT->GetMacroPath());
TString incPath(gSystem->GetIncludePath());
if (!macPath.Contains(fwd)) macPath.Append(Form(":%s", fwd.Data()));
if (!incPath.Contains(fwd)) gSystem->AddIncludePath(Form("-I%s",
fwd.Data()));
if (!sub.IsNull()) {
TObjArray* subs = sub.Tokenize(": ");
TObject* pSub = 0;
TIter iSub(subs);
while ((pSub = iSub())) {
TString subDir = gSystem->ConcatFileName(fwd, pSub->GetName());
if (!macPath.Contains(subDir))
macPath.Append(Form(":%s", subDir.Data()));
if (!incPath.Contains(subDir))
gSystem->AddIncludePath(Form("-I%s", subDir.Data()));
}
}
gROOT->SetMacroPath(macPath);
gROOT->LoadMacro(Form("%s%s", name.Data(), (force ? "++g" : "+")));
}
//____________________________________________________________________
virtual void DrawEventInspector(TCollection* parent)
{
Info("DrawEventInspector", "Drawing event inspector");
TCollection* c = GetCollection(parent, "fmdEventInspector");
if (!c) return;
UShort_t sys=0, sNN=0;
Int_t field=0;
ULong_t runNo=0;
Int_t lowFlux=0, nPileUp=0, ipMethod=0;
ULong_t aliRev=0, aliBra=0;
Bool_t v0and=false;
Double_t dPileUp=0.;
Double_t y = .8;
fBody->cd();
Double_t save = fParName->GetTextSize();
fParName->SetTextSize(0.03);
fParVal->SetTextSize(0.03);
GetParameter(c, "sys", sys);
GetParameter(c, "sNN", sNN);
GetParameter(c, "field", field);
GetParameter(c, "runNo", runNo);
GetParameter(c, "lowFlux", lowFlux);
GetParameter(c, "ipMethod", ipMethod, false);
GetParameter(c, "v0and", v0and);
GetParameter(c, "nPileUp", nPileUp);
GetParameter(c, "dPileup", dPileUp);
GetParameter(c, "alirootRev", aliRev);
GetParameter(c, "alirootBranch", aliBra);
TString tS; SysString(sys, tS); DrawParameter(y, "System", tS);
TString tE; SNNString(sNN, tE); DrawParameter(y, "#sqrt{s_{NN}}", tE);
DrawParameter(y, "L3 B field", Form("%+2dkG", field));
DrawParameter(y, "Run #", Form("%lu", runNo));
DrawParameter(y, "Low flux cut", Form("%d", lowFlux));
TString sIpMeth("unknown");
switch(ipMethod) {
case 0: sIpMeth = "Normal"; break;
case 1: sIpMeth = "pA in 2012"; break;
case 2: sIpMeth = "pA in 2013"; break;
case 3: sIpMeth = "PWG-UD"; break;
case 4: sIpMeth = "Satellite"; break;
}
DrawParameter(y, "Use PWG-UD vertex", sIpMeth);
DrawParameter(y, "Use V0AND for NSD", (v0and ? "yes" : "no"));
DrawParameter(y, "Least # of pile-up vertex", Form("%d", nPileUp));
DrawParameter(y, "Least distance of pile-up vertex",
Form("%fcm", dPileUp));
DrawParameter(y, "AliROOT", Form("%lu/0x%08lx", ULong_t(aliRev),
ULong_t(aliBra)));
TH1* triggers = GetH1(c, "triggers");
TH1* vertex = GetH1(c, "vertex", false);
Bool_t mc = (vertex != 0);
if (mc) {
Int_t nInelMC = vertex->GetEntries();
Int_t nInel = triggers->GetBinContent(1);
Int_t nNSDMC = triggers->GetBinContent(11);
Int_t nNSD = triggers->GetBinContent(4);
DrawParameter(y,
Form("#varepsilon_{INEL} = #bf{%d/%d}", nInel, nInelMC),
Form("%5.3f", float(nInel)/nInelMC));
DrawParameter(y,
Form("#varepsilon_{NSD} = #bf{%d/%d}", nNSD, nNSDMC),
Form("%5.3f", float(nNSD)/nNSDMC));
}
PrintCanvas("Event Inspector");
fParName->SetTextSize(save);
fParVal->SetTextSize(save);
if (fLandscape) fBody->Divide(4,2);
else fBody->Divide(2,4);
TH1* nEventsTr = GetH1(c, "nEventsTr");
TH1* nEventsTrVtx = GetH1(c, "nEventsTrVtx");
TH1* nEventsAcc = GetH1(c, "nEventsAccepted");
if (nEventsTr) nEventsTr->Rebin(2);
if (nEventsTrVtx) nEventsTrVtx->Rebin(2);
if (vertex) {
// vertex->Rebin(2);
vertex->SetFillColor(kMagenta+2);
}
DrawInPad(fBody, 1, nEventsTr, "", kLogy,
"Events w/trigger, trigger+vertex, accepted");
if (vertex) DrawInPad(fBody, 1, vertex, "same");
DrawInPad(fBody, 1, nEventsTrVtx, "same");
DrawInPad(fBody, 1, nEventsAcc, "same", kLegend);
DrawInPad(fBody, 2, GetH2(c, "nEventsAcceptedXY"), "colz", kLogz);
DrawInPad(fBody, 3, triggers, "hist text");
if (GetH1(c, "trgStatus"))
DrawInPad(fBody, 4, GetH1(c, "trgStatus"), "hist text");
else // Old one
DrawInPad(fBody, 4, GetH2(c, "triggerCorr"), "colz", kLogz);
DrawInPad(fBody, 5, GetH1(c, "status"), "hist text");
if (GetH1(c, "vtxStatus"))
DrawInPad(fBody, 6, GetH1(c, "vtxStatus"), "hist text");
else // old
DrawInPad(fBody, 6, GetH1(c, "type"), "hist text");
TH1* cent = GetH1(c, "cent");
if (cent) {
cent->Scale(1, "width");
DrawInPad(fBody, 7, cent, "", kLogy);
}
TH1* pileupStatus = GetH1(c, "pileupStatus", false);
if (pileupStatus) DrawInPad(fBody, 8, pileupStatus, "hist text30");
else {
TH2* centQual = GetH2(c, "centVsQuality");
if (centQual) {
centQual->Scale(1, "width");
DrawInPad(fBody, 8, centQual, "colz", kLogz);
}
}
PrintCanvas("EventInspector - Histograms");
if (!mc) return; // not MC
TH1* phiR = GetH1(c, "phiR");
TH1* b = GetH1(c, "b");
TH2* bVsNpart = GetH2(c, "bVsParticipants");
TH2* bVsNbin = GetH2(c, "bVsBinary");
TH2* bVsCent = GetH2(c, "bVsCentrality");
TH2* vzComparison = GetH2(c, "vzComparison");
TH2* centVsNpart = GetH2(c, "centralityVsParticipans");// Spelling!
TH2* centVsNbin = GetH2(c, "centralityVsBinary");
fBody->Divide(2,3);
DrawInPad(fBody, 1, phiR);
DrawInPad(fBody, 2, vzComparison, "colz", kLogz);
DrawInPad(fBody, 3, b);
TProfile* nPartB = bVsNpart->ProfileX("nPartB",1,-1,"s");
TProfile* nBinB = bVsNbin->ProfileX("nBinB",1,-1,"s");
nPartB->SetMarkerColor(kBlue+2);
nPartB->SetMarkerStyle(20);
nPartB->SetLineColor(kBlue+2);
nPartB->SetFillColor(kBlue-10);
nPartB->SetFillStyle(1001);
nPartB->SetMarkerSize(0.7);
nBinB->SetMarkerColor(kRed+2);
nBinB->SetMarkerStyle(21);
nBinB->SetLineColor(kRed+2);
nBinB->SetFillColor(kRed-10);
nBinB->SetMarkerSize(0.7);
nBinB->SetFillStyle(1001);
DrawTwoInPad(fBody, 4, nPartB, nBinB, "e3 p", kLegend);
DrawInPad(fBody, 5, bVsCent, "colz", kLogz);
TProfile* nPartC = centVsNpart->ProfileY("nPartC",1,-1,"s");
TProfile* nBinC = centVsNbin->ProfileY("nBinC",1,-1,"s");
nPartC->SetMarkerColor(kBlue+2);
nPartC->SetMarkerStyle(20);
nPartC->SetLineColor(kBlue+2);
nPartC->SetFillColor(kBlue-10);
nPartC->SetFillStyle(1001);
nPartC->SetMarkerSize(0.7);
nBinC->SetMarkerColor(kRed+2);
nBinC->SetMarkerStyle(21);
nBinC->SetLineColor(kRed+2);
nBinC->SetFillColor(kRed-10);
nBinC->SetMarkerSize(0.7);
nBinC->SetFillStyle(1001);
DrawTwoInPad(fBody, 6, nPartC, nBinC, "e3 p", kLegend);
PrintCanvas("EventInspector - Monte-Carlo");
}
//____________________________________________________________________
virtual void DrawESDFixer(TCollection* parent)
{
Info("DrawESDFixer", "Drawing ESD fixer");
TCollection* c = GetCollection(parent, "fmdESDFixer");
if (!c) return;
Int_t recoFactor = 0;
Bool_t recalcEta = false;
Bool_t invalidIsEmpty = false;
fBody->cd();
Double_t save = fParName->GetTextSize();
fParName->SetTextSize(0.05);
fParVal->SetTextSize(0.05);
fBody->Divide(2,2);
fBody->cd(1);
Double_t y = .8;
if (GetParameter(c, "recoFactor", recoFactor))
DrawParameter(y, "Noise factor used in reco",
Form("%d (assumed)", recoFactor));
if (GetParameter(c, "recalcEta", recalcEta))
DrawParameter(y, "Recalculate #eta",
Form("%s", (recalcEta ? "yes" : "no")));
if (GetParameter(c, "invalidIsEmpty", invalidIsEmpty))
DrawParameter(y, "Assume invalid strips are empty",
Form("%s", (invalidIsEmpty ? "yes" : "no")));
TCollection* xd = GetCollection(c, "extraDead");
if (xd)
DrawParameter(y, "# extra dead strips",
Form("%d", xd->GetEntries()));
DrawInPad(fBody, 2, GetH1(c, "noiseChange"), "", kLogy);
DrawInPad(fBody, 3, GetH1(c, "etaChange"), "", kLogy);
DrawInPad(fBody, 4, GetH1(c, "deadChange"), "", kLogy);
PrintCanvas("ESD Fixer");
fParName->SetTextSize(save);
fParVal->SetTextSize(save);
}
//____________________________________________________________________
void DrawTrackDensity(TCollection* parent,
const char* folderName="mcTrackDensity")
{
Info("DrawTrackDensity", "Drawing track density");
// --- MC --------------------------------------------------------
TCollection* mc = GetCollection(parent, folderName, false);
if (!mc) return; // Not MC
fBody->Divide(2,3);
DrawInPad(fBody, 1, GetH2(mc, "binFlow"), "colz", kLogz);
DrawInPad(fBody, 2, GetH2(mc, "binFlowEta"), "colz", kLogz);
DrawInPad(fBody, 3, GetH2(mc, "binFlowPhi"), "colz", kLogz);
DrawInPad(fBody, 4, GetH1(mc, "nRefs"), "", kLogy,
"# of references");
DrawInPad(fBody, 4, GetH1(mc, "clusterRefs", false), "same");
DrawInPad(fBody, 4, GetH1(mc, "clusterSize", false), "same");
DrawInPad(fBody, 4, GetH1(mc, "nClusters", false), "same", kLegend);
DrawInPad(fBody, 5, GetH2(mc, "clusterVsRefs", false),"colz", kLogz);
PrintCanvas("Track density");
}
//__________________________________________________________________
TCanvas* fCanvas; // Our canvas
TPad* fTop; // Top part
TPad* fBody; // Body part
TLatex* fHeader; // Header text
TLatex* fParName; // Parameter name
TLatex* fParVal; // Parameter value
Bool_t fPause; // Whether to pause after drawing a canvas
Bool_t fLandscape; // Landscape or Portrait orientation
TVirtualPad** fRingMap;
Bool_t fPDF;
TString fLastTitle;
};
#if 0
template <>
inline Bool_t
SummaryDrawer::DoGetParameter<Double_t>(TObject* o, const TObject* p,
Double_t& value)
{
TParameter<Double_t>* r = DoGetObject<TParameter<Double_t>(o, p);
UInt_t i = o->GetUniqueID();
Float_t v = *reinterpret_cast<Float_t*>(&i);
value = v;
return true;
}
#endif
inline Bool_t
SummaryDrawer::GetParameter(const TObject* c,
const TString& name,
Double_t& value,
Bool_t verb)
{
return DoGetParameter(GetObject(c, name, verb), c, value);
}
#endif
//
// EOF
//