hi wang,
you can comment out the first two lines, or here is the util.C file
it is looking for.
--chris
Wang Xu wrote:
>Dear Chris,
> Sorry that I can not make for your talk.
> I try to view your talk. Somehow, I get an error message.
>Processing view_canvas.C...
>Error: Can't call TClass::GetMenuList() in current scope FILE:util.C
>LINE:446
>Possible candidates are...
>filename line:size busy function type and name (in TClass)
>filename line:size busy function type and name (in TDictionary)
>filename line:size busy function type and name (in TObject)
>Error: non class,struct,union object GetMenuList() used with . or ->
>FILE:util.C LINE:446
>*** Interpreter error recovered ***
>
> Can you help me run your code?
> Thanks,
> Wang
>
>On Thu, 10 Jul 2003, chris crawford wrote:
>
>
>
>>hi,
>> you can find the files for my presentation at
>>blast05:/home/blast/chris2/scr/archive/2003-07-10_summary.tgz
>>
>> the plots are as root files, but there is a macro for viewing them:
>>
>>root elas-eff.root view_canvas.C
>>
>>.etc.... you can then modify them and save them in any format.
>>--chris
>>
>>Chris Crawford
>> chris2@mitlns.mit.edu
>>MIT building 26-648 office: 617-253-7977
>>77 Massachusetts Ave. lab: 617-253-8208
>>Cambridge, MA 02139 fax: 617-258-5440
>>
>>
>>
>>
// $Id: util.C,v 1.20 2003/03/25 23:15:01 chris2 Exp $
// cbc 2002/09/05
// utilities for programs using 'init.C'
//
// This file contains support functions for drawing histograms
// with multiple datasets. The basic useful function defined is
// `Draw()', which mimics the TTree::Draw() method acting on each
// of the datasets in the TChain[] setup by `init.C'. Draw() makes
// use of the support functions PaseHist(), and DrawHist().
// The two functions Draw16() and Draw4() are generalizations
// for drawing multiple histograms on a separate canvas in one step.
// These make use of the support functions InitCanvas(), and ExpandNLR()
// which may also be used on their own.
//______________________________________________________________________
TPad* InitCanvas(TString name, TString title, int nx, int ny)
{
// Creates a new canvas with a title bar and mxn subpads.
// Returns the pad containing all subpads.
// Note: the title string can be overridden
// by the `-title' option in `init.C'.
// The option can include the default string by putting
// a `+' at beginning or end or the title string.
// Used by Draw16(), Draw4().
TCanvas *canvas;
if (name=="") canvas = new TCanvas();
else canvas = new TCanvas(name,name);
canvas->SetWindowPosition(413,42);
canvas->Update();
canvas->ToggleEventStatus();
if (canvas_title) {
int length = canvas_title->Length();
if (canvas_title(0)=='+') {
title += canvas_title(1,length-1);
} else if (canvas_title(length-1)=='+') {
title = canvas_title(0,length-1) + title;
} else {
title = *canvas_title;
}
}
ltmp = new TPaveLabel(0.05,0.86,0.95,0.95, title);
ltmp->SetTextSize(0.5);
ltmp->SetTextColor(1);
ltmp->Draw();
TPad *pad = new TPad("p", "", 0.05,0.05,0.95,0.85);
if (nx<6&&ny<6) {
pad->Divide(nx,ny);
} else {
TStyle* old=gStyle->Clone();
// gStyle->SetPadLeftMargin(0);
// gStyle->SetPadRightMargin(0);
// gStyle->SetPadBottomMargin(0);
// gStyle->SetPadTopMargin(0);
gStyle->SetPadBorderSize(1);
pad->Divide(nx,ny,0,0);
gStyle=old;
}
pad->Draw();
canvas->Update();
AddContextMenuItems();
return pad;
}
//______________________________________________________________________
TString ExpandNLR(char* in, int np, int side=0)
{
// expands special characters `#^!%$' in string
// to paddle number (np), or sector (side) values
// used by Draw16()
TString out;
char c;
while ((c=*in++)) {
switch (c) {
case '#': out += np; break;
case '^': out += side; break;
case '!': out += !side; break;
case '%': out += (!side?'l':'r'); break;
case '$': out += (!side?'r':'l'); break;
default: out += c;
}
}
return out.Copy();
}
int hist_ctr = 0; // histogram unique id
void ParseHist(char* hist_exp,
TString& histexp, TString& histname, TString& histrange)
{
// Parses hist_exp for `histexp>>histname(histrange)'
// Output:
// histexp: tree expression
// histname: histogram name
// histrange: optional range
// If `histname' is null, it returns "htemp_#" (# = ++hist_ctr),
// and then parentheses around `histrange' are optional.
// Used by Draw().
histexp = histname = histrange = "";
// extract histogram variables
char* hep=hist_exp;
while (*hep && (*hep!='>' || *(hep+1)!='>')) histexp+=*hep++;
if (*hep) {
hep+=2; // points after ">>"
char* hnp=hep;
// get histogram name
while (hnp && *hnp==' ') hnp++;
if (*hnp!='.' && *hnp!='-' && (*hnp<'0' || *hnp>'9')) {
while (*hnp && *hnp!='(') {
if (hnp!=' ') histname+=*hnp;
hnp++;
}
if (*hnp) hnp++;
}
// extract the range
if (*hnp) {
char* hrp = hnp;
// put range on to end of string
while(*hrp && *hrp!=')') {
if (*hrp!=' ') histrange+=*hrp;
hrp++;
}
if (histrange.Length()>0) histrange='('+histrange+')';
}
}
if (histname=="") {
histname = "htemp_";
histname += (++hist_ctr);
}
}
//______________________________________________________________________
void DrawHist(TH1 *hl[], TString opt="", float max=0, int* colors=0)
{
// Draws a single plot of `nsets' histgrams (datasets) superimposed.
// If the `init.C -norm' option is used, histograms are normalized
// (by integral) to the preceding nonzero histogram, if it exists.
// The optional parameter `max' sets the upper limit of the histogram,
// for displaying multiple histogram sets with the same range.
// Used by Draw16,8,4(), Draw(), or as a stand-alone low-level f'n.
// normalize subsequent datasets
int integral[maxsets];
for (int ds=0; ds<nsets; ds++) {
integral[ds]=hl[ds]->Integral();
if (normalize && integral[ds]) {
for (int sd=0; sd<ds; sd++) {
if (integral[sd]) {
hl[ds]->Scale(double(integral[sd])/integral[ds]);
break;
}
}
}
if (max) hl[ds]->SetMaximum(max);
hl[ds]->SetLineColor(colors?colors[ds]:ds+1);
hl[ds]->SetMarkerColor(colors?colors[ds]:ds+1);
hl[ds]->Draw((ds?"same":""));//+opt);
}
}
//______________________________________________________________________
TH1** Draw(TString hist_exp, TString cut_exp="", TString opt_exp="",
float max=0, int* colors=0)
{
// Draws a set of superimposed histograms, one for each dataset/cut
// specified in the command-line options of `init.C' (separated by `-d')
// The histogram expression is parsed for the histogram name and range,
// which is used for the first dataset, (or `htemp_#' if none given).
// Draw(...)[dataset#] = pointer to corresponding histogram
// Subsequent datasets histograms have the suffix `.#' (# = 1,2,3...).
// Used by Draw16(), Draw4(), or as a stand-alone function.
TString u, histexp,histname,histrange;
TH1** htmp = new TH1*[maxsets];
ParseHist(hist_exp, histexp,histname,histrange);
// loop over datasets and draw histograms
for (int ds=0;ds<nsets;ds++) {
TString hname = histname;
if (ds) hname = hname + "." + ds;
TString hexp = histexp+">>"+hname+histrange;
//cout<<"hist: "<<hexp<<endl;
chain[ds]->Draw(hexp, u+cut_exp+*cut[ds], "goff", nevents);
htmp[ds] = (TH1*)gDirectory->Get(hname);
cout<<"."<<flush;
}
DrawHist(htmp, opt_exp);
return htmp;
}
//______________________________________________________________________
TH1*** Draw4(TString hist_exp, TString cut_exp="", TString opt_exp="",
char* name="", float max=0, int* colors=0)
{
// Creates a new canvas w/4 pads, and draws a histogram in each,
// The histograms differ by substituting 0,1,2,3 for `#' in hist_exp.
// Draw4(...)[pad#][dataset#] = pointer to corresponding histogram
TH1*** htmp = new TH1**[4];
pad=InitCanvas(name,name,2,2);
for (int np=0;np<4;np++) {
pad->cd(np+1);
TString h_exp = ExpandNLR(hist_exp,np);
TString c_exp = ExpandNLR(cut_exp,np);
htmp[np]=Draw(h_exp, c_exp, opt_exp, max, colors);
cout<<":"<<flush;
}
cout<<endl;
return htmp;
}
TH1*** Draw8(TString hist_exp, TString cut_exp="", TString opt_exp="",
char* name="", float max=0, int* colors=0)
{
// Creates a new canvas w/4 pads, and draws a histogram in each,
// The histograms differ by substituting 0,1,2,3 for `#' in hist_exp.
// Draw8(...)[pad#][dataset#] = pointer to corresponding histogram
TH1*** htmp = new TH1**[8];
pad=InitCanvas(name,name,2,4);
for (int np=0;np<8;np++) {
pad->cd(np+1);
TString h_exp = ExpandNLR(hist_exp,np);
TString c_exp = ExpandNLR(cut_exp,np);
htmp[np]=Draw(h_exp, c_exp, opt_exp, max, colors);
cout<<":"<<flush;
}
cout<<endl;
return htmp;
}
TH1*** Draw16(TString hist_exp, TString cut_exp="", TString opt_exp="",
char* name="", float max=0, int* colors=0)
{
// Creates a new canvas w/16 pads, and draws a histogram in each,
// The histograms differ by substituting 0,1,2,... for `#' in hist_exp.
// Draw16(...)[pad#][dataset#] = pointer to corresponding histogram
TH1*** htmp = new TH1**[16];
pad=InitCanvas(name,name,4,4);
for (int np=0;np<16;np++) {
pad->cd(np+1);
TString h_exp = ExpandNLR(hist_exp,np);
TString c_exp = ExpandNLR(cut_exp,np);
htmp[np]=Draw(h_exp, c_exp, opt_exp, max, colors);
cout<<":"<<flush;
}
cout<<endl;
return htmp;
}
// TCut equivalents of above Draw() functions:
TH1** Draw(TString hist_exp, TCut cut_exp, TString opt_exp="",
float max=0, int* colors=0)
{
return Draw(hist_exp, (char*)cut_exp, opt_exp, max, colors);
}
TH1*** Draw4(TString hist_exp, TCut cut_exp="", TString opt_exp="",
char* name="", float max=0, int* colors=0)
{
return Draw4(hist_exp, (char*)cut_exp, opt_exp, max, colors);
}
TH1*** Draw8(TString hist_exp, TCut cut_exp="", TString opt_exp="",
char* name="", float max=0, int* colors=0)
{
return Draw8(hist_exp, (char*)cut_exp, opt_exp, max, colors);
}
TH1*** Draw16(TString hist_exp, TCut cut_exp="", TString opt_exp="",
char* name="", float max=0, int* colors=0)
{
return Draw16(hist_exp, (char*)cut_exp, opt_exp, max, colors);
}
//______________________________________________________________________
int cut_ctr = -1; // graphical cut number
void CutG(char* name=0, int ds=0)
{
// Sets up a graphical cut editor and waits for the user
// to click on each corner of the cut (double-click last vertex)
// Afterwards, adds a new dataset based on the `ds'th dataset,
// with the extra graphical cut "CUTG" (or `name', if given)
// Thus subsequent `Draw()' commands will superimpose a dataset
// cut by "CUTG" over top in a different color.
TString cut_name("cg"); // default name
if (!name) name = (char*) (cut_name + (++cut_ctr));
cout<<"Click on each corner of cut, double-click last ... "<<flush;
TCutG* cg = gPad->WaitPrimitive("CUTG","CutG");
//if ((cg = (TCutG*)gROOT->GetListOfSpecials()->FindObject("CUTG"))) {
if (cg && !strcmp(cg->IsA()->GetName(), "TCutG")) {
cg->SetName(name);
if (gDirectory->IsWritable()) cg->Write();
if (nsets+1<maxsets) {
chain[nsets]=chain[ds];
runlist[nsets]=runlist[ds];
cut[nsets][left] =cut[ds][left] + name;
cut[nsets][right]=cut[ds][right] + name;
cutname[nsets]=cutname[ds] + " && " + name;
nsets++;
}
cout<<name<<endl;
// todo: draw extra dataset
} else {
cout<<"none selected."<<endl;
}
}
void EventList(TString cut_exp="", TString file="ev.root")
{
if (cut_exp=="" && cut_ctr>-1) {
cut_exp="cg";
cut_exp+=cut_ctr;
}
TFile* f = new TFile(file, "recreate");
TEventList* el= new TEventList("el","el");
chain[0]->Draw(">>el", (char*)(cut_exp+*cut[0]));
el->Write();
f->Close();
}
//______________________________________________________________________
void SetColor(float hds, int color)
{
// Useful for displaying and hiding single datasets.
// Sets the color of `histogram.dataset' to `color' (-1 for default),
// where `histogram' is the integer in its name `htemp_#'.
// The float `.dataset' is a dataset in the latest histogram.
// Used by SetColor(), Show(), and Hide().
int hs = int(hds);
int ds = int(10*fabs(hds-int(hds))+.01);
TString u, htmp;
htmp = u+"htemp_"+(hs<1?hist_ctr:hs);
if (ds) htmp = htmp+"."+ds;
//cout<<htmp<<endl;
if (color==-1) color = ds+1;
((TH1*)gDirectory->FindObject(htmp))->SetLineColor(color);
((TH1*)gDirectory->FindObject(htmp))->SetMarkerColor(color);
gPad->Modified();
}
void SetColor(int hs, int color)
{
// Sets the color of all datasets in histogram `hs'.
// Normally used only by Show() and Hide().
for (int ds=0;ds<nsets;ds++) {
SetColor(hs+ds/10., color);
}
}
// These functions are aliases of `SetColor' with
// the color set to default (Show) or black (Hide).
void Show(float hds, int color=-1) {SetColor(hds,color);}
void Show(int hds=0, int color=-1) {SetColor(hds,color);}
void Hide(float hds, int color=0) {SetColor(hds,color);}
void Hide(int hds=0, int color=0) {SetColor(hds,color);}
//______________________________________________________________________
void GetAsymmetry(TH1* asym, TH1* h1, TH1* h2,
Float_t c1=1, Float_t c2=1,Float_t dc1=0, Float_t dc2=0){
// this function forms the asymmetry between the two histograms
// (can be any 1-D or 2-D histograms of the same size)
// and returns a histogram with asymmetries and errors. js 12.6.2
// clone the historgrams so top and bottom will have the
// correct dimensions:
TH1 *top = asym->Clone();
TH1 *bottom = asym->Clone();
// Sumw2 just makes sure the errors will be computed properly
// when we form sums and ratios below.
top->Sumw2();
bottom->Sumw2();
asym->Sumw2();
// form the top and bottom of the asymmetry, and then divide:
top->Add(h1,h2,c1,-1*c2);
bottom->Add(h1,h2,c1,c2);
asym->Divide(top,bottom);
Int_t xmax = asym->GetNbinsX();
Int_t ymax = asym->GetNbinsY();
Int_t zmax = asym->GetNbinsZ();
Float_t as, bot, error, a, b;
// now loop over bins to calculate the correct
// erors:
// the reason this error calculation looks so messy is because of the
// constants c1 and c2!
for(Int_t i=1; i<= xmax; i++){
for(Int_t j=1; j<= ymax; j++){
for(Int_t k=1; k<= zmax; k++){
a = h1->GetBinContent(i,j,k);
b = h2->GetBinContent(i,j,k);
as = asym->GetBinContent(i,j,k);
bot = bottom->GetBinContent(i,j,k);
// make sure there are some events, if not, let ROOT set the error=0
if(b < 1){}
else{
// remember: da = sqrt(a)
error = sqrt((1-as)*(1-as)*(c1*c1*a+a*a*dc1*dc1)
+(1+as)*(1+as)*(c2*c2*b+b*b*dc2*dc2))/bot;
asym->SetBinError(i,j,k,error);
}
}
}
}
}
//______________________________________________________________________
void AddContextMenuItems()
{
// add helpful entries to context menus
static bool context_menu_flag = false;
if (context_menu_flag) return;
context_menu_flag = true;
// get object in a variable
TClass* cl_obj;
gClassTable->Init();
while ((cl_obj=gROOT->GetClass(gClassTable->Next()))) {
cl_obj->GetMenuList()->AddFirst
(new TClassMenuItem(0,cl_obj, "Print", "PrintObj", 0,0,0));
cl_obj->GetMenuList()->AddFirst
(new TClassMenuItem(0,cl_obj, "List", "ListObj", 0,0,0));
cl_obj->GetMenuList()->AddFirst
(new TClassMenuItem(0,cl_obj, "Make Variable", "MakeVar", 0,0,0));
}
// enable pad popup menu item
char* cl_list[]={"TPad", "TH1F", "TH2F", "TH3F", "TProfile"};
for (int i=0;i<5;i++) {
TClass* cl_obj = gROOT->GetClass(cl_list[i]);
cl_obj->GetMenuList()->AddFirst
(new TClassMenuItem(0,cl_obj, "Make Event List", "MakeEvList", 0,0,0));
cl_obj->GetMenuList()->AddFirst
(new TClassMenuItem(0,cl_obj, "View Single", "ViewSingle", 0,0,0));
}
// need to click on pad behind histogram frames
gStyle->SetFrameFillStyle(0);
}
TCanvas* ViewSingle(TObject* obj)
{
// draw object in its very own canvas
// useful with InitCanvas grids with many divisions
TCanvas* c = new TCanvas();
TObject* clone = obj->Clone();
TPad* pad;
if (clone->InheritsFrom("TPad")) {
((TPad*)clone)->SetPad(0,0,1,1);
}
clone->UseCurrentStyle();
clone->Draw();
return c;
}
void MakeVar(TObject* obj)
{
// make a variable of the form mClassName
// useful to enter command on graphical objects
TString classname = obj->IsA()->GetName();
TString mclass = classname; mclass[0] = 'm';
TString command = mclass+"=("+classname+"*)"+(int)obj+";";
gROOT->ProcessLine( command );
cout<<"Created variable: "<<command<<endl;
}
void ListObj(TObject* obj)
{
// call ls() without any arguments
obj->ls();
}
void PrintObj(TObject* obj)
{
// call ls() without any arguments
obj->Print();
}
void MakeEvList(TObject* obj)
{
// change to pad and create gaphical cut
if (obj->InheritsFrom(TPad::Class())) obj->cd();
CutG();
EventList();
}
This archive was generated by hypermail 2.1.2 : Mon Feb 24 2014 - 14:07:29 EST