How to get a histogram from a ROOT file with ROOT 6.10?

I get a crash when I do

$ root -l $ROOTSYS/tutorials/hsimple.root 
OBJ: TStyle     ildStyle        ILD Style : 0 at: 0x279cec0
root [0] 
Attaching file /opt/root/tutorials/hsimple.root as _file0...
(TFile *) 0x31af890
root [1] TH1F *h = (TH1F*)(_file0->GetListOfKeys()->At(0)->Clone())
(TH1F *) 0x37bb510
root [2] h->GetTitle()
(const char *) "This is the px distribution"
root [3] h->GetMean()

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007fb5f3fc9dfa in __libc_waitpid (pid=31101, stat_loc=stat_loc
entry=0x7fffccd03dd0, options=options
entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:31
#1  0x00007fb5f3f4bfbc in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:148
#2  0x00007fb5f4feb174 in Exec (shellcmd=<optimized out>, this=<optimized out>) at /home/pamputt/root-6.10.00/core/unix/src/TUnixSystem.cxx:2118
#3  TUnixSystem::StackTrace (this=0x1e0f8e0) at /home/pamputt/root-6.10.00/core/unix/src/TUnixSystem.cxx:2412
#4  0x00007fb5f4fed5fc in TUnixSystem::DispatchSignals (this=0x1e0f8e0, sig=kSigSegmentationViolation) at /home/pamputt/root-6.10.00/core/unix/src/TUnixSystem.cxx:3643
#5  <signal handler called>
#6  0x0000000000000000 in ?? ()
#7  0x00007fb5f56db04b in ?? ()
#8  0x00007fffccd06920 in ?? ()
#9  0x00007fb5f56db000 in ?? ()
#10 0x00007fffccd06550 in ?? ()
#11 0x00007fb5ef9b120e in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) () from /opt/root/lib/libCling.so
#12 0x00007fb5ef9b252d in cling::Interpreter::EvaluateInternal(std::string const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) () from /opt/root/lib/libCling.so
#13 0x00007fb5ef9b273b in cling::Interpreter::process(std::string const&, cling::Value*, cling::Transaction**, bool) () from /opt/root/lib/libCling.so
#14 0x00007fb5efa4273e in cling::MetaProcessor::process(char const*, cling::Interpreter::CompilationResult&, cling::Value*, bool) () from /opt/root/lib/libCling.so
#15 0x00007fb5ef937099 in HandleInterpreterException (metaProcessor=<optimized out>, input_line=<optimized out>, compRes=
0x7fffccd0681c: cling::Interpreter::kSuccess, result=result
entry=0x7fffccd06920) at /home/pamputt/root-6.10.00/core/metacling/src/TCling.cxx:1887
#16 0x00007fb5ef9479d8 in TCling::ProcessLine (this=0x1e6fe50, line=<optimized out>, error=0x7fffccd06d0c) at /home/pamputt/root-6.10.00/core/metacling/src/TCling.cxx:2050
#17 0x00007fb5f4ecfb00 in TApplication::ProcessLine (this=this
entry=0x1e5f110, line=<optimized out>, sync=sync
entry=false, err=err
entry=0x7fffccd06d0c) at /home/pamputt/root-6.10.00/core/base/src/TApplication.cxx:1001
#18 0x00007fb5f5313b9f in TRint::ProcessLineNr (this=this
entry=0x1e5f110, filestem=filestem
entry=0x7fb5f5324f43 "ROOT_prompt_", line=0x7fffccd06dc9 "h->GetMean()", error=0x7fffccd06d0c, error
entry=0x0) at /home/pamputt/root-6.10.00/core/rint/src/TRint.cxx:741
#19 0x00007fb5f5313efb in TRint::HandleTermInput (this=0x1e5f110) at /home/pamputt/root-6.10.00/core/rint/src/TRint.cxx:602
#20 0x00007fb5f4fecbfd in TUnixSystem::CheckDescriptors (this=this
entry=0x1e0f8e0) at /home/pamputt/root-6.10.00/core/unix/src/TUnixSystem.cxx:1321
#21 0x00007fb5f4fede9a in TUnixSystem::DispatchOneEvent (this=0x1e0f8e0, pendingOnly=<optimized out>) at /home/pamputt/root-6.10.00/core/unix/src/TUnixSystem.cxx:1076
#22 0x00007fb5f4f33804 in TSystem::InnerLoop (this=0x1e0f8e0) at /home/pamputt/root-6.10.00/core/base/src/TSystem.cxx:410
#23 0x00007fb5f4f32511 in TSystem::Run (this=0x1e0f8e0) at /home/pamputt/root-6.10.00/core/base/src/TSystem.cxx:360
#24 0x00007fb5f4ecd0ef in TApplication::Run (this=this
entry=0x1e5f110, retrn=retrn
entry=false) at /home/pamputt/root-6.10.00/core/base/src/TApplication.cxx:1153
#25 0x00007fb5f53154bf in TRint::Run (this=0x1e5f110, retrn=<optimized out>) at /home/pamputt/root-6.10.00/core/rint/src/TRint.cxx:455
#26 0x0000000000400c00 in main (argc=1, argv=0x7fffccd09158) at /home/pamputt/root-6.10.00/main/src/rmain.cxx:30
===========================================================


The lines below might hint at the cause of the crash.
You may get help by asking at the ROOT forum http://root.cern.ch/forum.
Only if you are really convinced it is a bug in ROOT then please submit a
report at http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#6  0x0000000000000000 in ?? ()
#7  0x00007fb5f56db04b in ?? ()
#8  0x00007fffccd06920 in ?? ()
#9  0x00007fb5f56db000 in ?? ()
#10 0x00007fffccd06550 in ?? ()
#11 0x00007fb5ef9b120e in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) () from /opt/root/lib/libCling.so
#12 0x00007fb5ef9b252d in cling::Interpreter::EvaluateInternal(std::string const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) () from /opt/root/lib/libCling.so
#13 0x00007fb5ef9b273b in cling::Interpreter::process(std::string const&, cling::Value*, cling::Transaction**, bool) () from /opt/root/lib/libCling.so
#14 0x00007fb5efa4273e in cling::MetaProcessor::process(char const*, cling::Interpreter::CompilationResult&, cling::Value*, bool) () from /opt/root/lib/libCling.so
#15 0x00007fb5ef937099 in HandleInterpreterException (metaProcessor=<optimized out>, input_line=<optimized out>, compRes=
0x7fffccd0681c: cling::Interpreter::kSuccess, result=result
entry=0x7fffccd06920) at /home/pamputt/root-6.10.00/core/metacling/src/TCling.cxx:1887
===========================================================

It happens with ROOT 6.10. I think I remember it was the way I used to get an object within a ROOT file in the previous ROOT versions.

You can do:

$ root -l $ROOTSYS/tutorials/hsimple.root
root [0] 
Attaching file /Users/couet/git/roottrunk-bin/tutorials/hsimple.root as _file0...
(TFile *) 0x7fbab0ba4ba0
root [1] TH1F *h = (TH1F*)(_file0->Get("hpx"));
root [2] h->GetMean()
(double) -0.004011
root [3] 

Indeed, I can do this for this case. However, for my real case, I do not know the name of the histograms before. That’s why I want to get the histogram from its key. We agree that this crash is not expected?

I see. May be what is suggested here can help:

Thanks, I will have a look. Actually, it crashes also on previous versions (at least with ROOT 6.08/02).

Yes it seems this way is not “legal” but I do not know why … it is weird that the title is returned correctly but not the Mean… note that Draw produces a white Pad … but no crash … so, some how something is wrong but I have no immediate clear answer…

Try (well, I knew I was missing “ReadObj” somewhere, and ksmith pointed out the missing “(TKey *)” cast): TH1F *h = new TH1F(*(TH1F *)((TKey *)_file0->GetListOfKeys()->At(0))->ReadObj());

it does not seem any better:

root [1] TH1F *h = new TH1F(*(TH1F *)(_file0->GetListOfKeys()->At(0)));
root [2] h->GetMean()
(double) 0.000000
root [3] h->Draw()
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1

 *** Break *** segmentation violation

Here is a clue, the values returned for the pointers are not the same:

$ root -l $ROOTSYS/tutorials/hsimple.root
root [0]
Attaching file /opt/root/root-6.08.06/tutorials/hsimple.root as _file0...
(TFile *) 0x7f9bf9ee2f20
root [1] TH1F* h = (TH1F*)_file0->GetListOfKeys()->At(0)
(TH1F *) 0x7f9bf9eebc20
root [2] TH1F* h2 = (TH1F*)_file0->Get("hpx")
(TH1F *) 0x7f9bf9f0b1c0
root [3]

This was bothering me and I realized I had run into it before. It is an issue with using static casts and not realizing what we are casting. GetListOfKeys gives a list of TKey objects! You were casting them to TH1F. The GetName method works as they both inherit from TObject, but there is no GetMean method in TKey.

A dynamic cast would have caught this sooner. The solution is to cast to TKey and then use TKey::ReadObj:

$ root -l $ROOTSYS/tutorials/hsimple.root
root [0]
Attaching file /opt/root/root-6.08.06/tutorials/hsimple.root as _file0...
(TFile *) 0x7febe9a6b140
root [1] TH1F *h = dynamic_cast<TH1F*>(_file0->GetListOfKeys()->At(0))
(TH1F *) nullptr
root [2] _file0->GetListOfKeys()->At(0)->IsA()->GetName()
(const char *) "TKey"
root [3] h = (TH1F*) ((TKey*)_file0->GetListOfKeys()->At(0))->ReadObj()
(TH1F *) 0x7febe4edf770
root [4] h->GetMean()
(Double_t) -0.00401052
root [5]

(I used static casts as the issue originally contained them.)

While I’m at it, here is the code I’ve used in the past:

#include <vector>

#include <TH1.h>
#include <TFile.h>
#include <TKey.h>

std::vector<TH1*> GetHistograms(TFile *f) {
   std::vector<TH1*> hists;

   //Get an iterator to and loop over the list of keys in the file.
   TIter keyIter(f->GetListOfKeys());
   TKey *key;
   while ((key = (TKey*)keyIter())) {
      //Get the objects name.
      std::string name = key->GetName();

      //Try to cast the object to a TTree.
      TH1* hist = dynamic_cast<TH1*>(key->ReadObj());
      if (hist) hists.push_back(hist);
   }

   return hists;
}
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.