Re: [ROOT] Function busy flag cleared

From: Rene Brun (Rene.Brun@cern.ch)
Date: Thu Sep 20 2001 - 08:31:17 MEST


Hi Bob,

You are reading two branches only of your Tree. Probably, you have
more branches. Do you have objects in those branches?
Anyhow, I suggest the following simplification and changes in
your script.
 - use a local TH1F. It will be automatically deleted when leaving 
   the function
 - read only the two branches. Will be faster
 - Use the TH1::Integral instead of your loop. Your loop did not start
   at bin 1.

void weighthist(TTree *t, TString name, int nbins, double xmin, double xmax)
{
    double val, weight;
    double binwidth = (xmax-xmin)/nbins;
    int nentries = (int)t->GetEntries();
    int i;
    
    TH1F hist ("hist-" + name, name + " distribution", nbins, xmin, xmax);
    TBranch *bval = t->GetBranch(name);
    TBranch *bw   = t->GetBranch("weight");
    bval->SetAddress(&val);
    bw->SetAddress(&weight);
    for(i=0;i<nentries;i++) {
        bval->GetEntry(i);
        bw->GetEntry(i);
        hist->Fill(val,weight);
    }   
    cout << "Integral is: " << hist.Integral("width") << endl;
}   

About your second question. To execute a CINT command in a macro,
use gROOT->ProcessLine. Example
  gROOT->ProcessLine(".L ~/.root/weighthist.C");

Rene Brun


Bob McElrath wrote:
> 
> I'm having trouble running a couple of simple scripts to make hisograms
> from TTree data:
> 
> // Draws a weighted histogram.  The tree you pass must have a branch named "weight"
> // that will be applied.
> void weighthist(TTree *t, TString name, int nbins, double xmin, double xmax)
> {
>     TH1F *hist;
>     double val, weight;
>     double binwidth = (xmax-xmin)/nbins;
>     int nentries = (int)t->GetEntries();
>     int i;
>     double integral=0.0;
> 
>     if(hist = (TH1F*)gROOT->FindObject("hist-" + name)) delete hist;
>     hist = new TH1F("hist-" + name, name + " distribution", nbins, xmin, xmax);
>     if(!hist) {
>         cout << "new failed for TH1F!" << endl;
>         return;
>     }
>     t->SetBranchAddress(name, &val);
>     t->SetBranchAddress("weight", &weight);
>     for(i=0;i<nentries;i++) {
>         t->GetEntry(i);
>         hist->Fill(val,weight);
>     }
>     for(i=0;i<nbins;i++) {
>         integral += binwidth*hist->GetBinContent(i);
>     }
>     cout << "Integral is: " << integral << endl;
> }
> 
> I then run this script a couple of times:
>     root [1] .L ~/.root/weighthist.C
>     root [2]     TFile f("ppmumu.root", "UPDATE");
>     root [3]     TTree *t = (TTree*)f.Get("ppgammazmumu");
>     root [4]     TTree *st = (TTree*)f.Get("pphmumu");
>     root [5]     weighthist(t, "q", 50, 50, 200);
>     Integral is: 3.20927e+12
>     root [6]     weighthist(t, "ptl", 50, 0, 200);
>     Integral is: 4.28335e+12
>     root [7]     weighthist(t, "costheta", 50, -1, 1);
> 
>      *** Break *** segmentation violation
>      Root > Function weighthist() busy flag cleared
> 
> What does that mean?!?  And how do I fix it?  Note that the function ran
> successfully *twice* before bombing.  Turning on debug (gDebug=1) does
> not provide any more information than the above.  (about the segfault,
> anyway)
> 
> Lastly, where can I put commands like .L ~/.root/weighthist.C so I can
> load a set of often-used scripts at startup?  Scripts don't seem to like
> dot commands (.L) or I'd put it in login.C or something.
> 
> Thanks,
> -- Bob
> 
> Bob McElrath (rsmcelrath@students.wisc.edu)
> Univ. of Wisconsin at Madison, Department of Physics
> 
>   --------------------------------------------------------------------------------
> 
>    Part 1.2   Type: application/pgp-signature



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:51:00 MET