RE: Creating a vector of pointers to histograms - problem.

From: Fine, Valeri <fine_at_bnl.gov>
Date: Tue, 13 Nov 2007 21:36:21 -0500


Hello Eddy,
The histogram objects are own by ROOT file "by default". This means your solution will not work. Because all histograms are to be destroyed as soon as the ROOT file the "belong to" is closed.

Anyway, the invocation of the f.Close() is redundant, because the "f" objects is to be destroyed anyway.

My guess the correct code should be:

 vector<TH1I*> groupA;
 vector<TH1I*> groupB;

 while ((chEl=(TChainElement*)next() )) {

     TFile f(chEl->GetTitle());  

     TH1D *histoA = (TH1D *) f.Get("hA"); // break ownerships to keep the histogram alive

     histoA->SetDirectory(0);  
     histoA->SetName("newhA);
     groupA.push_back(histoA);
 
     TH1D *histoB = (TH1D *) f.Get("hB");
// break ownerships to keep the histogram alive
     histoB->SetDirectory(0);
     histoB->SetName("newhB);
     groupB.push_back(histoB);

    }
 }

Without histoB->SetDirectory(0); trhe code will be failed randomly, because the groupA and groupB are the containers of the died pointers.  

Best Regards

                         Valeri Fine


Brookhaven National Laboratory
Upton, NY 11973, USA
Phone: +1 631 344 7806
Fax: +1 631 344 4206
E-mail: fine_at_bnl.gov

> -----Original Message-----
> From: owner-roottalk_at_root.cern.ch [mailto:owner-roottalk_at_root.cern.ch]
On
> Behalf Of Edmond Offermann
> Sent: Tuesday, November 13, 2007 6:25 PM
> To: Thiago Tomei; roottalk_at_cern.ch
> Subject: Re: [ROOT] Creating a vector of pointers to histograms -
problem.
>
> Hi Thiago,
>
> Inside your loop you have a variable histoA which will be destroyed
> after each iteration . Replace you stuff by :
>
> vector<TH1I*> groupA;
> vector<TH1I*> groupB;
>
> while ((chEl=(TChainElement*)next() )) {
> TFile f(chEl->GetTitle());
>
> TH1D *histoA = (TH1D *) f.Get("hA");
> histoA->SetName("newhA);
> groupA.push_back(histoA);
>
> TH1D *histoB = (TH1D *) f.Get("hB");
> histoB->SetName("newhB);
> groupB.push_back(histoB);
>
> f.Close();
> }
> }
>
> Eddy
>
> --- Thiago Tomei <Thiago.Tomei_at_cern.ch> wrote:
>
> > Dear ROOTers
> >
> > The solution from Philippe worked perfectly (by the way, many
thanks.
> > :) , but still it will not quite solve my problems. What I want to
do
> > is:
> >
> > 1) Open a file, with a name given by a string constructed in run
time
> > (so I can loop over files)
> > 2) Get all the histograms that exist in that file, according to
their
> > categories (for instance, the histogram of momenta, the histogram of
> > energies, etc.), and copy them in containers (could be std::vectors,
> > TObjArrays, whatever works best). So, I would have a container of
> > momenta histograms, a container of energies histogram, etc...
> > 3) Close the file and go back to 1). Loop over all the files.
> >
> > I want to access the histograms, which were (hopefully) saved in the
> > containers, after the loop is done. I came up with the following
> > code:
> >
> > void group() {
> >
> > TChain ch("anything");
> > string files; // I will construct this string during runtime.
> > // ... constructs the string...
> > ch.Add(files.c_str());
> >
> > TObjArray* fileElements = ch.GetListOfFiles();
> > TIter next(fileElements);
> > TChainElement* chEl = 0;
> >
> > vector<TH1I> groupA;
> > vector<TH1I> groupB;
> >
> > while ((chEl=(TChainElement*)next() )) {
> > TFile f(chEl->GetTitle());
> >
> > TH1D histoA;
> > f.Get("hA")->Copy(histoA);
> > histoA.SetName("newhA);
> > groupA.push_back(histoA);
> >
> > TH1D histoB;
> > f.Get("hB")->Copy(histoB);
> > histoB.SetName("newhB);
> > groupB.push_back(histoB);
> >
> > f.Close();
> > }
> > }
> >
> > and the strange thing is: the first trip through the loop,
everything
> > works fine! However, during the second trip, it crashes just before
I
> > push histoA to the groupA. The macro compiles with no problems, but
> > segfaults with the following backtrace:
> >
> > #0 0xb695b360 in TH1D::TH1D () from /usr/lib/root/5.17/libHist.so
> > #1 0xb5f3d289 in std::vector<TH1D, std::allocator<TH1D>
> > >::_M_insert_aux ()
> > from /home/trtomei/Desktop/WZjets/scanning_old/./teste2_C.so
> > #2 0xb5f3c3c3 in teste2 ()
> > from /home/trtomei/Desktop/WZjets/scanning_old/./teste2_C.so
> > #3 0xb5f3cd47 in G__fileCn2kaN__0_1198 ()
> > from /home/trtomei/Desktop/WZjets/scanning_old/./teste2_C.so
> > #4 0xb727a4e7 in Cint::G__ExceptionWrapper ()
> > from /usr/lib/root/libCint.so.5.17
> > #5 0xb73636e0 in G__call_cppfunc () from
> > /usr/lib/root/libCint.so.5.17
> > #6 0xb733cba5 in G__interpret_func () from
> > /usr/lib/root/libCint.so.5.17
> > #7 0xb732b6b7 in G__getfunction () from
> > /usr/lib/root/libCint.so.5.17
> > #8 0xb72ffdf2 in G__getitem () from /usr/lib/root/libCint.so.5.17
> > #9 0xb7306865 in G__getexpr () from /usr/lib/root/libCint.so.5.17
> > #10 0xb731217a in G__calc_internal () from
> > /usr/lib/root/libCint.so.5.17
> > #11 0xb739b441 in G__process_cmd () from
> > /usr/lib/root/libCint.so.5.17
> > #12 0xb79c4275 in TCint::ProcessLine () from
> > /usr/lib/root/libCore.so.5.17
> > #13 0xb79be086 in TCint::ProcessLineSynch () from
> > /usr/lib/root/libCore.so.5.17
> > #14 0xb792647b in TApplication::ExecuteFile ()
> > from /usr/lib/root/libCore.so.5.17
> > #15 0xb79267b4 in TApplication::ProcessFile ()
> > from /usr/lib/root/libCore.so.5.17
> > #16 0xb7923ddb in TApplication::ProcessLine ()
> > ---Type <return> to continue, or q <return> to quit---
> > from /usr/lib/root/libCore.so.5.17
> > #17 0xb7213a89 in TRint::HandleTermInput () from
> > /usr/lib/root/libRint.so.5.17
> > #18 0xb7211f75 in TTermInputHandler::Notify ()
> > from /usr/lib/root/libRint.so.5.17
> > #19 0xb72143e4 in TTermInputHandler::ReadNotify ()
> > from /usr/lib/root/libRint.so.5.17
> > #20 0xb79f059b in TUnixSystem::CheckDescriptors ()
> > from /usr/lib/root/libCore.so.5.17
> > #21 0xb79f098e in TUnixSystem::DispatchOneEvent ()
> > from /usr/lib/root/libCore.so.5.17
> > #22 0xb797bce1 in TSystem::InnerLoop () from
> > /usr/lib/root/libCore.so.5.17
> > #23 0xb797d631 in TSystem::Run () from /usr/lib/root/libCore.so.5.17
> > #24 0xb7922858 in TApplication::Run () from
> > /usr/lib/root/libCore.so.5.17
> > #25 0xb721401e in TRint::Run () from /usr/lib/root/libRint.so.5.17
> > #26 0x08048ea3 in main ()
> >
> > Regards,
> > Thiago
> >
> > On Nov 12, 2007 4:17 AM, Philippe Canal <pcanal_at_fnal.gov> wrote:
> > > Hi Thiago,
> > >
> > > This is a problem with the bytecode compiler. You can work around
> > > it by issuing the CINT command .O 0
> > > which disables the byte code compilation or better yet, you can
> > > simply compile your code via ACLiC (which will lead you to correct
> > > a few mistake including the wrong placement of the declaration of
> > f).
> > >
> > > Cheers,
> > > Philippe
> > >
> > >
> > > -----Original Message-----
> > > From: owner-roottalk_at_root.cern.ch
> > [mailto:owner-roottalk_at_root.cern.ch] On
> > > Behalf Of Thiago Tomei
> > > Sent: Saturday, November 10, 2007 6:06 AM
> > > To: roottalk_at_cern.ch
> > > Subject: [ROOT] Creating a vector of pointers to histograms -
> > problem.
> > >
> > > (I have already sent this message to roottalk_at_root.cern.ch, but it
> > > didn't appear anywhere - I take it that roottalk_at_root.cern.ch is
> > NOT
> > > an alias to roottalk_at_cern.ch. If another copy of this message
> > appears
> > > floating around, my apologies.)
> > >
> > > Dear ROOTers.
> > >
> > > I am trying to declare a vector of pointers to histograms, adding
> > > histograms inside the loop, and accessing the histograms after the
> > > loop is done. However, I am not able to do it, and I cannot figure
> > out
> > > why. Here's the relevant code:
> > >
> > > #include <iostream>
> > > #include <vector>
> > > #include "TFile"
> > > #include "TH1"
> > >
> > > int test() {
> > >
> > > using namespace std;
> > >
> > > vector <TH1I*> vechist;
> > >
> > > do {
> > > cout << "in the loop..." << endl;
> > > TFile* f = new TFile("rootfile.root");
> > > TH1I* temphist = (TH1I*) f->Get("histogram");
> > > vechist.push_back(temphist);
> > > cout << "off the loop..." << endl;
> > > } while(0);
> > > cout << vechist[0]->GetEntries() << endl;
> > > f->Close();
> > >
> > > return 0;
> > > }
> > >
> > > It crashes just before the third cout. I thought it was a scope
> > > problem, but removing the do and the while(0), while still keeping
> > the
> > > curly braces (thus defining a scope inside) makes the problem
> > > disappear. What am I doing wrong? What can I do to solve my
> > problem?
> > >
> > > I am using ROOT 5.17/04, in an Ubuntu 7.10 machine.
> > >
> > > The output from bt command from the debugger:
> > >
> > > #0 0x53e58955 in ?? ()
> > > #1 0xb68bcd1d in ?? () from /usr/lib/root/5.17/libHist.so
> > > #2 0xb72d54e7 in Cint::G__ExceptionWrapper ()
> > > from /usr/lib/root/libCint.so.5.17
> > > #3 0xb73be6e0 in G__call_cppfunc () from
> > /usr/lib/root/libCint.so.5.17
> > > #4 0xb7397ba5 in G__interpret_func () from
> > /usr/lib/root/libCint.so.5.17
> > > #5 0xb7386651 in G__getfunction () from
> > /usr/lib/root/libCint.so.5.17
> > > #6 0xb74569b8 in G__getstructmem () from
> > /usr/lib/root/libCint.so.5.17
> > > #7 0xb744d802 in G__getvariable () from
> > /usr/lib/root/libCint.so.5.17
> > > #8 0xb735ad11 in G__getitem () from /usr/lib/root/libCint.so.5.17
> > > #9 0xb736a79f in G__getexpr () from /usr/lib/root/libCint.so.5.17
> > > #10 0xb73e2151 in G__exec_statement () from
> > /usr/lib/root/libCint.so.5.17
> > > #11 0xb7398f1b in G__interpret_func () from
> > /usr/lib/root/libCint.so.5.17
> >
> === message truncated ===
Received on Wed Nov 14 2007 - 03:36:56 CET

This archive was generated by hypermail 2.2.0 : Wed Nov 14 2007 - 05:50:02 CET