Re: [ROOT] Function busy flag cleared

From: Rene Brun (Rene.Brun@cern.ch)
Date: Mon Sep 24 2001 - 08:57:52 MEST


Hi Bob,

Bob McElrath wrote:
> 
> Rene Brun [Rene.Brun@cern.ch] wrote:
> > Hi Bob,
> >
> > You are reading two branches only of your Tree. Probably, you have
> > more branches. Do you have objects in those branches?
> 
> Yes, of course.  What does this have to do with this script?
>
When reading objects, your class constructors/destructors are called.
Many things may happen in these functions, such as non-initialized pointers,
double object deletion, etc.
 
> > Anyhow, I suggest the following simplification and changes in
> > your script.
> >  - use a local TH1F. It will be automatically deleted when leaving
> >    the function
> 
> I want the histogram to be saved so I may plot it.  (Using a TBrowser)
> The script you gave does not save the histograms.  In effect, all it
> does is compute the integral.
> 
> >  - read only the two branches. Will be faster
> 
> I thought it was?

 If you call TTree::GetEntry, all branches of your Tree will be read (unless
you have called TTree::setBranchStatus).
 If you call TBranch::GetEntry, only the corresponding branch is read.

> 
> >  - Use the TH1::Integral instead of your loop. Your loop did not start
> >    at bin 1.
> 
> Arg!  Bins start at 1!?!  I thought this was C++!?!  ;)

Bins are numbered from 0 to Nbins + 1 (see documentation), where bin 0 is the
underflow bin.

> 
> Why does my script crash in the first place?  I don't seem to be doing
> any memory nastiness (as far as I can see), and I don't see why it
> should crash...  Making the small modification to line 8 of your script:
>     TH1F* hist = new TH1F("hist-" + name, name + " distribution", nbins, xmin, xmax);
> Does not crash like my old one...

Difficult to figure out without executing your script. This simple change
should not make any difference.

Rene Brun

> 
> > 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
> -- 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