Re: [BLAST_ANAWARE] presentation

From: Chris Crawford (chris2@lns.mit.edu)
Date: Sat Jul 12 2003 - 19:19:44 EDT


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