Using ROOT as API

Hi,

I would like to know what is the best way to use ROOT objects within an c++ application. For example, I would like to create a canvas and histogram from one of my class, pop it on the screen and update the display periodically. Shoud I use the CINT API, derive from ROOT classes , use the ROOT GUI classes or something else?

Thanks,

Philippe

Hi Philippe,
the best way to do this is by coming up with your own source file, that gets compiled as a library by root, and which you can just “start”:root [0] .L myClass.cxx+ root [1] MyClass* mc=new MyClass(); root [2] mc->Run()Not only can you use all of root’s classes this way - you don’t even have to figure out what root libraries to use, and it will run on all systems that root supports (as long as you don’t include functions that are not portable).

Another, much more painful option is to write your own Makefile (or solution, if you’re working under windows). Example Makefiles are in $ROOTSYS/test. This will give you a binary in the end - but you will still need a root installation on any computer you run this binary.

Either way, you should write your own code, and just call root methods - there is no reason to derive from root’s classes if you don’t want to fundamentally change their behaviour. Just look at the $ROOTSYS/tutorials directory (and $ROOTSYS/test) to see some examples. For GUI related applications, tutorials/hsumTimer.C might be a good start.
Axel.

Hi Axel,

thank you for the answer. It looks like ROOT is very powerful but that it relies mostly on the CINT interpreter to work, and it is my main concern. Ideally, I would like to avoid the interpreter. Right now, I create histograms in a ROOT file while running a GEANT4 application. The ROOT operations are compiled with my GEANT project and all is working properly, without any requirement for CINT. I can look at and manipulate histograms after the run with a root session. However, I wonder if it is possible to see them online, i.e. registering a ROOT graphic window and control it from my GEANT4 code. At this point, I thought that a pipe to a CINT process could do the job but apparently CINT does not support pipes. Maybe the client-server capabilities of ROOT are pertinent here? If I understand correctly, you suggested to compile my entire application within a ROOT session? That sounds scary to me. How can I control the optimization, flags, etc? ROOT is written in C++ and all seems to be there to use it as an API. But unfortunately, I seems that I always end into CINT somewhere… Good for prototyping but when it’s not your goal…Maybe I missed something? Thanks again,
Philippe

Hi Philippe,
if you want separate programs for histo creation (GEANT) and monitoring you could use a TMapFile, see tutorials/hprod.C, hcons.C. Another way to get this done is by using threads; one for Geant and one for the histogram updates. You could just use the regular root threads: update the histograms in your program using TCanvas::Update(), and call gSystem->ProcessEvents() regularely to allow the user to interact with it, and to allow root to re-draw the histogram if necessary.

And you don’t have to let cint interpret your code - as I said, you can compile it, e.g. within root/cint. You can manipulate the build settings using gSystem->Get/SetMakeSharedLib. This is just a suggestion; if you prefer, you can always use a Makefile.
Axel.

Hi Axel,

I tried to implement the TMapFile approach. I was succesful at running the tutorial hproc.C and hcons.C yesterday but it is not working anymore…

[color=green]root [0] .x hprod.C
Memory mapped file: hsimple.map
Title: Demo memory mapped file with histograms
Option: CREATE
Mapped Memory region: 0x41b95000 - 0x41bae000 (0.10 MB)
Current breakval: 0x41b9d000
Object Class Size
hpx TH1F 1024
hpxpy TH2F 8939
hprof TProfile 8552

[/color]

then in another terminal window:

[color=green]root [0] .x hcons.C
Memory mapped file: hsimple.map
Title: Demo memory mapped file with histograms
Option: READ
Mapped Memory region: 0x41b95000 - 0x41c7c000 (0.90 MB)
Current breakval: 0x41c7c000
Object Class Size
hpx TH1F 1024
hpxpy TH2F 8939
hprof TProfile 8552

*** Break *** segmentation violation
Generating stack trace…
/usr/bin/addr2line: ‘rootn.exe’: No such file
/usr/bin/addr2line: ‘rootn.exe’: No such file
0x400060da in from /lib/ld-linux.so.2
0x41378ee4 in from /lib/tls/libc.so.6
0x4000ae66 in from /lib/ld-linux.so.2
0x41379a70 in _dl_open + 0x70 from /lib/tls/libc.so.6
0x41179c71 in from /lib/libdl.so.2
0x4000ae66 in from /lib/ld-linux.so.2
0x41179423 in from /lib/libdl.so.2
0x41179c2b in dlopen + 0x3b from /lib/libdl.so.2
0x407af0fc in G__dlopen + 0x22 from /usr/local/lib/root/libCint.so
0x407af75d in G__shl_load + 0x7e from /usr/local/lib/root/libCint.so
0x4076b553 in G__loadfile + 0x14c5 from /usr/local/lib/root/libCint.so
0x407af096 in G__loadsystemfile + 0x1e1 from /usr/local/lib/root/libCint.so
0x401d5872 in TCint::Load(char const*, bool) + 0x6a from /usr/local/lib/root/libCore.so
0x401980e8 in TSystem::Load(char const*, char const*, bool) + 0x53e from /usr/local/lib/root/libCore.so
0x4027de34 in TUnixSystem::Load(char const*, char const*, bool) + 0x2a from /usr/local/lib/root/libCore.so
0x40185a84 in TROOT::LoadClass(char const*, char const*, bool) + 0xb6 from /usr/local/lib/root/libCore.so
0x4016e060 in TPluginHandler::LoadPlugin() + 0x68 from /usr/local/lib/root/libCore.so
0x409e7b8d in TVirtualHistPainter::HistPainter(TH1*) + 0x4d from /usr/local/lib/root/libHist.so
0x4097f4de in TH1::GetPainter() + 0x26 from /usr/local/lib/root/libHist.so
0x409838f7 in TH1::Paint(char const*) + 0x21 from /usr/local/lib/root/libHist.so
0x40e0751b in TPad::PaintModified() + 0x21f from /usr/local/lib/root/libGpad.so
0x40e074d0 in TPad::PaintModified() + 0x1d4 from /usr/local/lib/root/libGpad.so
0x40debe92 in TCanvas::Update() + 0xde from /usr/local/lib/root/libGpad.so
0x40e21b24 in from /usr/local/lib/root/libGpad.so
0x40770f3b in G__call_cppfunc + 0x284 from /usr/local/lib/root/libCint.so
0x4075f4b0 in G__interpret_func + 0x7fb from /usr/local/lib/root/libCint.so
0x4073f0d3 in G__getfunction + 0x162f from /usr/local/lib/root/libCint.so
0x407dba61 in G__getstructmem + 0x9ae from /usr/local/lib/root/libCint.so
0x407d35a6 in G__getvariable + 0x5a2 from /usr/local/lib/root/libCint.so
0x407350a6 in G__getitem + 0x762 from /usr/local/lib/root/libCint.so
0x40733612 in G__getexpr + 0x9fe6 from /usr/local/lib/root/libCint.so
0x407883e4 in G__exec_function + 0xd0 from /usr/local/lib/root/libCint.so
0x4079182c in G__exec_statement + 0x3e23 from /usr/local/lib/root/libCint.so
0x4078c509 in G__exec_if + 0x1ef from /usr/local/lib/root/libCint.so
0x4079125b in G__exec_statement + 0x3852 from /usr/local/lib/root/libCint.so
0x4078cd53 in G__exec_loop + 0x292 from /usr/local/lib/root/libCint.so
0x4078d350 in G__exec_while + 0x7a from /usr/local/lib/root/libCint.so
0x407913c0 in G__exec_statement + 0x39b7 from /usr/local/lib/root/libCint.so
0x40718698 in G__exec_tempfile_core + 0x327 from /usr/local/lib/root/libCint.so
0x407188ec in G__exec_tempfile + 0x22 from /usr/local/lib/root/libCint.so
0x4079a206 in G__process_cmd + 0x479d from /usr/local/lib/root/libCint.so
0x401d59d1 in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) + 0xaf from /usr/local/lib/root/libCore.so
0x401d5b00 in TCint::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) + 0x46 from /usr/local/lib/root/libCore.so
0x4012c26d in TApplication::ProcessFile(char const*, int*) + 0x6d9 from /usr/local/lib/root/libCore.so
0x4012bb19 in TApplication::ProcessLine(char const*, bool, int*) + 0x625 from /usr/local/lib/root/libCore.so
0x4115de42 in TRint::HandleTermInput() + 0x1f8 from /usr/local/lib/root/libRint.so
0x4115cb22 in TTermInputHandler::Notify() + 0x24 from /usr/local/lib/root/libRint.so
0x4115e2c8 in TTermInputHandler::ReadNotify() + 0x12 from /usr/local/lib/root/libRint.so
0x4027bf00 in TUnixSystem::CheckDescriptors() + 0x152 from /usr/local/lib/root/libCore.so
0x4027adbf in TUnixSystem::DispatchOneEvent(bool) + 0x18f from /usr/local/lib/root/libCore.so
0x40195558 in TSystem::InnerLoop() + 0x18 from /usr/local/lib/root/libCore.so
0x401954f8 in TSystem::Run() + 0x7a from /usr/local/lib/root/libCore.so
0x4012c3d8 in TApplication::Run(bool) + 0x32 from /usr/local/lib/root/libCore.so
0x4115d8d6 in TRint::Run(bool) + 0x368 from /usr/local/lib/root/libRint.so
0x08048de3 in main + 0x67 from rootn.exe
0x4129dea0 in __libc_start_main + 0xe0 from /lib/tls/libc.so.6
0x08048cf1 in TApplicationImp::ShowMembers(TMemberInspector&, char*) + 0x3d from rootn.exe
Root > Segmentation fault
[/color]

I really have no clue on what’s going on. I compiled 4.03/02 on linux (gcc).

I also tried to implement TMapFile in my GEANT application. The mapfile is created but the consumer cannot find it back…
According to the SetMapAddress method, it seems that there’s some issues with TMapFile
http://root.cern.ch/root/htmldoc/TMapFile.html#TMapFile:SetMapAddress

Thank you

Philippe

Can you climb your program call stack up from the crash point by the point

to see what is the name of the file (the first “const char*” parameter) with the shared library the Load method tried to load and failed.

This might have given you and us some clue.
Of course some simplest example that one can run to reproduce your problem would have helped also.

Hi,

if it can help you, here is a backtrace from gdb:

root [0] .x hcons.C
Memory mapped file: hsimple.map
Title: Demo memory mapped file with histograms
Option: READ
Mapped Memory region: 0x41b95000 - 0x41c7c000 (0.90 MB)
Current breakval: 0x41c7c000
Object Class Size
hpx TH1F 1024
hpxpy TH2F 8939
hprof TProfile 8552

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1095786016 (LWP 16501)]
strcmp (p1=0x408d5d2a “/usr/local/lib/root/libHistPainter.so”, p2=0xd <Address 0xd out of bounds>)
at …/sysdeps/generic/strcmp.c:39
39 …/sysdeps/generic/strcmp.c: No such file or directory.
in …/sysdeps/generic/strcmp.c
(gdb) bt
#0 strcmp (p1=0x408d5d2a “/usr/local/lib/root/libHistPainter.so”, p2=0xd <Address 0xd out of bounds>)
at …/sysdeps/generic/strcmp.c:39
#1 0x400060da in _dl_map_object (loader=0x0,
name=0x408d5d2a “/usr/local/lib/root/libHistPainter.so”, preloaded=0, type=2, trace_mode=0,
mode=-1879047935) at dl-load.c:1768
#2 0x41378ee4 in getutmpx () from /lib/tls/libc.so.6
#3 0x4000ae66 in _dl_catch_error (objname=0xbffe4628, errstring=0xbffe462c,
operate=0x41378e00 <getutmpx+64>, args=0xbffe4630) at dl-error.c:161
#4 0x41379a70 in _dl_open () from /lib/tls/libc.so.6
#5 0x41179c71 in dlopen () from /lib/libdl.so.2
#6 0x4000ae66 in _dl_catch_error (objname=0x8848198, errstring=0x884819c,
operate=0x41179c40 <dlopen+80>, args=0xbffe47b0) at dl-error.c:161
#7 0x41179423 in dlerror () from /lib/libdl.so.2
#8 0x41179c2b in dlopen () from /lib/libdl.so.2
#9 0x407af0fc in G__dlopen () from /usr/local/lib/root/libCint.so
#10 0x407af75d in G__shl_load () from /usr/local/lib/root/libCint.so
#11 0x4076b553 in G__loadfile () from /usr/local/lib/root/libCint.so
—Type to continue, or q to quit—
#12 0x407af096 in G__loadsystemfile () from /usr/local/lib/root/libCint.so
#13 0x401d5872 in TCint::Load () from /usr/local/lib/root/libCore.so
#14 0x401980e8 in TSystem::Load () from /usr/local/lib/root/libCore.so
#15 0x4027de34 in TUnixSystem::Load () from /usr/local/lib/root/libCore.so
#16 0x40185a84 in TROOT::LoadClass () from /usr/local/lib/root/libCore.so
#17 0x4016e060 in TPluginHandler::LoadPlugin () from /usr/local/lib/root/libCore.so
#18 0x409e7b8d in TVirtualHistPainter::HistPainter () from /usr/local/lib/root/libHist.so
#19 0x4097f4de in TH1::GetPainter () from /usr/local/lib/root/libHist.so
#20 0x409838f7 in TH1::Paint () from /usr/local/lib/root/libHist.so
#21 0x40e0751b in TPad::PaintModified () from /usr/local/lib/root/libGpad.so
#22 0x40e074d0 in TPad::PaintModified () from /usr/local/lib/root/libGpad.so
#23 0x40debe92 in TCanvas::Update () from /usr/local/lib/root/libGpad.so
#24 0x40e21b24 in G__G__GPad_201_3_10 () from /usr/local/lib/root/libGpad.so
#25 0x40770f3b in G__call_cppfunc () from /usr/local/lib/root/libCint.so
#26 0x4075f4b0 in G__interpret_func () from /usr/local/lib/root/libCint.so
#27 0x4073f0d3 in G__getfunction () from /usr/local/lib/root/libCint.so
#28 0x407dba61 in G__getstructmem () from /usr/local/lib/root/libCint.so
—Type to continue, or q to quit—
#29 0x407d35a6 in G__getvariable () from /usr/local/lib/root/libCint.so
#30 0x407350a6 in G__getitem () from /usr/local/lib/root/libCint.so
#31 0x40733612 in G__getexpr () from /usr/local/lib/root/libCint.so
#32 0x407883e4 in G__exec_function () from /usr/local/lib/root/libCint.so
#33 0x4079182c in G__exec_statement () from /usr/local/lib/root/libCint.so
#34 0x4078c509 in G__exec_if () from /usr/local/lib/root/libCint.so
#35 0x4079125b in G__exec_statement () from /usr/local/lib/root/libCint.so
#36 0x4078cd53 in G__exec_loop () from /usr/local/lib/root/libCint.so
#37 0x4078d350 in G__exec_while () from /usr/local/lib/root/libCint.so
#38 0x407913c0 in G__exec_statement () from /usr/local/lib/root/libCint.so
#39 0x40718698 in G__exec_tempfile_core () from /usr/local/lib/root/libCint.so
#40 0x407188ec in G__exec_tempfile () from /usr/local/lib/root/libCint.so
#41 0x4079a206 in G__process_cmd () from /usr/local/lib/root/libCint.so
#42 0x401d59d1 in TCint::ProcessLine () from /usr/local/lib/root/libCore.so
#43 0x401d5b00 in TCint::ProcessLineSynch () from /usr/local/lib/root/libCore.so
#44 0x4012c26d in TApplication::ProcessFile () from /usr/local/lib/root/libCore.so
#45 0x4012bb19 in TApplication::ProcessLine () from /usr/local/lib/root/libCore.so
—Type to continue, or q to quit—
#46 0x4115de42 in TRint::HandleTermInput () from /usr/local/lib/root/libRint.so
#47 0x4115cb22 in TTermInputHandler::Notify () from /usr/local/lib/root/libRint.so
#48 0x4115e2c8 in TTermInputHandler::ReadNotify () from /usr/local/lib/root/libRint.so
#49 0x4027bf00 in TUnixSystem::CheckDescriptors () from /usr/local/lib/root/libCore.so
#50 0x4027adbf in TUnixSystem::DispatchOneEvent () from /usr/local/lib/root/libCore.so
#51 0x40195558 in TSystem::InnerLoop () from /usr/local/lib/root/libCore.so
#52 0x401954f8 in TSystem::Run () from /usr/local/lib/root/libCore.so
#53 0x4012c3d8 in TApplication::Run () from /usr/local/lib/root/libCore.so
#54 0x4115d8d6 in TRint::Run () from /usr/local/lib/root/libRint.so
#55 0x08048de3 in main ()
(gdb)