Dear rooters.
I’m trying to store instances of two classes, A and B, in nested TClonesArrays in a TTree. Each row in the tree contain a TClonesArray of class A, which in turn has a TClonesArray of class B as a member. I run into problems when I try to use B’s member functions in Draw() and Scan() commands.
The header file for class A:
#include <TObject.h>
#include <TClonesArray.h>
#include "B.h"
class A : public TObject {
private:
int nB; //!
public:
double varA;
TClonesArray *array_of_Bs;
A();
~A();
void Clear(Option_t * option = "");
char const * FunctionA();
void PushB(B &b);
ClassDef(A,1);
};
and for class B:
#include <TObject.h>
class B : public TObject {
public:
double varB;
B();
~B() = default;
void Clear(Option_t * option = "");
char const * FunctionB();
ClassDef(B,1);
};
I create a test-tree with the following macro:
#include <TFile.h>
#include <TTree.h>
#include <TClonesArray.h>
#include <TRandom3.h>
#include <TMath.h>
#include "A.h"
#include "B.h"
using namespace TMath;
void BuildTree()
{
TFile *outFile = new TFile("test.root","RECREATE");
TTree *outTree = new TTree("data","Tree with test data.");
TClonesArray a("A",10);
outTree->Branch("a", &a);
for(int i=0; i<10; i++){
TRandom3 rGen(0);
a.Clear("C");
int nA = Floor(rGen.Uniform(1,5)); //Between 1 and 4 instances of A per event.
for(int j=0; j<nA; j++){
A *aj = (A*)a.ConstructedAt(j);
aj->varA = rGen.Uniform(0,1);
int nB = Floor(rGen.Uniform(1,5)); //Same
for(int k=0; k<nB; k++){
B bk;
bk.varB = rGen.Uniform(0,1);
aj->PushB(bk);
}
}
outTree->Fill();
}
outTree->Write();
outFile->Close();
}
When I open the output file, I can use the member functions of class A in the Draw and Scan command all right, i.e. something like
root [3] data->Scan("varA:FunctionA()")
***********************************************
* Row * Instance * varA * FunctionA *
***********************************************
* 0 * 0 * 0.8405387 * A *
* 1 * 0 * 0.8260149 * A *
* 2 * 0 * 0.5822119 * A *
* 2 * 1 * 0.8680549 * A *
works just fine (FunctionA() just returns the character ‘A’). I can also access member variables of class B, i.e. the following also works
root [5] data->Scan("varA:FunctionA():array_of_Bs.varB")
***********************************************************
* Row * Instance * varA * FunctionA * array_of_ *
***********************************************************
* 0 * 0 * 0.8405387 * A * 0.8488560 *
* 1 * 0 * 0.8260149 * A * 0.0220859 *
* 1 * 1 * * * 0.6967885 *
* 1 * 2 * * * 0.7500650 *
* 1 * 3 * * * 0.7440082 *
however, when I try to use the member function of B, I get a segmentation error:
root [6] data->Scan("varA:FunctionA():array_of_Bs.varB:array_of_Bs.FunctionB()")
*** Break *** segmentation violation
===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0 0x00007efde35060cb in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007efde347efbb in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007efde414e823 in TUnixSystem::Exec (shellcmd=<optimized out>, this=0x1f36570) at /home/jonas/root-6.14.02/core/unix/src/TUnixSystem.cxx:2119
#3 TUnixSystem::StackTrace (this=0x1f36570) at /home/jonas/root-6.14.02/core/unix/src/TUnixSystem.cxx:2413
#4 0x00007efde4151214 in TUnixSystem::DispatchSignals (this=0x1f36570, sig=kSigSegmentationViolation) at /home/jonas/root-6.14.02/core/unix/src/TUnixSystem.cxx:3644
#5 <signal handler called>
#6 TTreeFormula::ParseWithLeaf (this=this
entry=0x3b3d6a0, leaf=0x37e2e40, subExpression=<optimized out>, final=<optimized out>, paran_level=0, castqueue=..., useLeafCollectionObject=<optimized out>, fullExpression=<optimized out>) at /home/jonas/root-6.14.02/tree/treeplayer/src/TTreeFormula.cxx:1321
#7 0x00007efdc86311bf in TTreeFormula::DefinedVariable (this=<optimized out>, name=..., action=
0x7ffd3b56af74: 150) at /home/jonas/root-6.14.02/tree/treeplayer/src/TTreeFormula.cxx:2960
#8 0x00007efdd62e1d08 in ROOT::v5::TFormula::Analyze (this=0x3b3d6a0, schain=0x39a2b80 "array_of_Bs.FunctionB()", err=
0x7ffd3b56b380: 0, offset=0) at /home/jonas/root-6.14.02/hist/hist/src/TFormula_v5.cxx:1381
#9 0x00007efdd62eaf2d in ROOT::v5::TFormula::Compile (this=0x3b3d6a0, expression=<optimized out>) at /home/jonas/root-6.14.02/hist/hist/src/TFormula_v5.cxx:2368
#10 0x00007efdc862c57a in TTreeFormula::Init (this=0x3b3d6a0, name=0x7efdc869091e "Var1", expression=0x3aeb120 "array_of_Bs.FunctionB()") at /home/jonas/root-6.14.02/tree/treeplayer/src/TTreeFormula.cxx:209
#11 0x00007efdc862ccf2 in TTreeFormula::TTreeFormula (this=0x3b3d6a0, name=0x7efdc869091e "Var1", expression=0x3aeb120 "array_of_Bs.FunctionB()", tree=<optimized out>) at /home/jonas/root-6.14.02/tree/treeplayer/src/TTreeFormula.cxx:162
#12 0x00007efdc864c45a in TTreePlayer::Scan (this=0x37363c0, varexp=<optimized out>, selection=<optimized out>, option=<optimized out>, nentries=10, firstentry=0) at /home/jonas/root-6.14.02/tree/treeplayer/src/TTreePlayer.cxx:2612
#13 0x00007efde48f90ae in ?? ()
#14 0x00007ffd3b56ba20 in ?? ()
#15 0x0000000001fb0f50 in ?? ()
#16 0x00000000039bc2d0 in ?? ()
#17 0x911129971ea07400 in ?? ()
#18 0x00007efde48f803a in ?? ()
#19 0x0000000001fa92a0 in ?? ()
#20 0x0000000003afa8d8 in ?? ()
#21 0x00007ffd3b56be30 in ?? ()
#22 0x0000000001fa92a0 in ?? ()
#23 0x00007ffd3b56be30 in ?? ()
#24 0x00007ffd3b56bac0 in ?? ()
#25 0x0000000001fb0f50 in ?? ()
#26 0x00007ffd3b56ba60 in ?? ()
#27 0x00007efddea1adc7 in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) [clone .part.303] () from /home/jonas/root-build/lib/libCling.so
#28 0x00007efddea1b21f in cling::Interpreter::EvaluateInternal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) () from /home/jonas/root-build/lib/libCling.so
#29 0x00007efddea1ba07 in cling::Interpreter::process(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*, cling::Transaction**, bool) () from /home/jonas/root-build/lib/libCling.so
#30 0x00007efddeacb9dd in cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) () from /home/jonas/root-build/lib/libCling.so
#31 0x00007efdde98dc5e in HandleInterpreterException (metaProcessor=0x258a890, input_line=<optimized out>, compRes=
0x7ffd3b56be1c: cling::Interpreter::kSuccess, result=result
entry=0x7ffd3b56be30) at /home/jonas/root-6.14.02/core/metacling/src/TCling.cxx:2060
#32 0x00007efdde9a30ed in TCling::ProcessLine (this=0x1fa8a00, line=<optimized out>, error=0x7ffd3b56c31c) at /home/jonas/root-6.14.02/core/metacling/src/TCling.cxx:2218
#33 0x00007efde401ee9d in TApplication::ProcessLine (this=0x1f70c30, line=<optimized out>, sync=<optimized out>, err=0x7ffd3b56c31c) at /home/jonas/root-6.14.02/core/base/src/TApplication.cxx:1021
#34 0x00007efde44d9a12 in TRint::ProcessLineNr (this=this
entry=0x1f70c30, filestem=filestem
entry=0x7efde44df552 "ROOT_prompt_", line=0x39a3150 "data->Scan(\"varA:FunctionA():array_of_Bs.varB:array_of_Bs.FunctionB()\")", error=0x7ffd3b56c31c, error
entry=0x0) at /home/jonas/root-6.14.02/core/rint/src/TRint.cxx:741
#35 0x00007efde44d9d84 in TRint::HandleTermInput (this=0x1f70c30) at /home/jonas/root-6.14.02/core/rint/src/TRint.cxx:602
#36 0x00007efde4150600 in TUnixSystem::CheckDescriptors (this=this
entry=0x1f36570) at /home/jonas/root-6.14.02/core/unix/src/TUnixSystem.cxx:1322
#37 0x00007efde4151f98 in TUnixSystem::DispatchOneEvent (this=0x1f36570, pendingOnly=<optimized out>) at /home/jonas/root-6.14.02/core/unix/src/TUnixSystem.cxx:1077
#38 0x00007efde4044701 in TSystem::InnerLoop (this=0x1f36570) at /home/jonas/root-6.14.02/core/base/src/TSystem.cxx:411
#39 TSystem::Run (this=0x1f36570) at /home/jonas/root-6.14.02/core/base/src/TSystem.cxx:361
#40 0x00007efde401ce8f in TApplication::Run (this=this
entry=0x1f70c30, retrn=retrn
entry=false) at /home/jonas/root-6.14.02/core/base/src/TApplication.cxx:1173
#41 0x00007efde44db473 in TRint::Run (this=this
entry=0x1f70c30, retrn=retrn
entry=false) at /home/jonas/root-6.14.02/core/rint/src/TRint.cxx:455
#42 0x000000000040095a in main (argc=<optimized out>, argv=0x7ffd3b56e778) at /home/jonas/root-6.14.02/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 TTreeFormula::ParseWithLeaf (this=this
entry=0x3b3d6a0, leaf=0x37e2e40, subExpression=<optimized out>, final=<optimized out>, paran_level=0, castqueue=..., useLeafCollectionObject=<optimized out>, fullExpression=<optimized out>) at /home/jonas/root-6.14.02/tree/treeplayer/src/TTreeFormula.cxx:1321
#7 0x00007efdc86311bf in TTreeFormula::DefinedVariable (this=<optimized out>, name=..., action=
0x7ffd3b56af74: 150) at /home/jonas/root-6.14.02/tree/treeplayer/src/TTreeFormula.cxx:2960
#8 0x00007efdd62e1d08 in ROOT::v5::TFormula::Analyze (this=0x3b3d6a0, schain=0x39a2b80 "array_of_Bs.FunctionB()", err=
0x7ffd3b56b380: 0, offset=0) at /home/jonas/root-6.14.02/hist/hist/src/TFormula_v5.cxx:1381
#9 0x00007efdd62eaf2d in ROOT::v5::TFormula::Compile (this=0x3b3d6a0, expression=<optimized out>) at /home/jonas/root-6.14.02/hist/hist/src/TFormula_v5.cxx:2368
#10 0x00007efdc862c57a in TTreeFormula::Init (this=0x3b3d6a0, name=0x7efdc869091e "Var1", expression=0x3aeb120 "array_of_Bs.FunctionB()") at /home/jonas/root-6.14.02/tree/treeplayer/src/TTreeFormula.cxx:209
#11 0x00007efdc862ccf2 in TTreeFormula::TTreeFormula (this=0x3b3d6a0, name=0x7efdc869091e "Var1", expression=0x3aeb120 "array_of_Bs.FunctionB()", tree=<optimized out>) at /home/jonas/root-6.14.02/tree/treeplayer/src/TTreeFormula.cxx:162
#12 0x00007efdc864c45a in TTreePlayer::Scan (this=0x37363c0, varexp=<optimized out>, selection=<optimized out>, option=<optimized out>, nentries=10, firstentry=0) at /home/jonas/root-6.14.02/tree/treeplayer/src/TTreePlayer.cxx:2612
#13 0x00007efde48f90ae in ?? ()
#14 0x00007ffd3b56ba20 in ?? ()
#15 0x0000000001fb0f50 in ?? ()
#16 0x00000000039bc2d0 in ?? ()
#17 0x911129971ea07400 in ?? ()
#18 0x00007efde48f803a in ?? ()
#19 0x0000000001fa92a0 in ?? ()
#20 0x0000000003afa8d8 in ?? ()
#21 0x00007ffd3b56be30 in ?? ()
#22 0x0000000001fa92a0 in ?? ()
#23 0x00007ffd3b56be30 in ?? ()
#24 0x00007ffd3b56bac0 in ?? ()
#25 0x0000000001fb0f50 in ?? ()
#26 0x00007ffd3b56ba60 in ?? ()
#27 0x00007efddea1adc7 in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) [clone .part.303] () from /home/jonas/root-build/lib/libCling.so
#28 0x00007efddea1b21f in cling::Interpreter::EvaluateInternal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) () from /home/jonas/root-build/lib/libCling.so
#29 0x00007efddea1ba07 in cling::Interpreter::process(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*, cling::Transaction**, bool) () from /home/jonas/root-build/lib/libCling.so
#30 0x00007efddeacb9dd in cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) () from /home/jonas/root-build/lib/libCling.so
#31 0x00007efdde98dc5e in HandleInterpreterException (metaProcessor=0x258a890, input_line=<optimized out>, compRes=
0x7ffd3b56be1c: cling::Interpreter::kSuccess, result=result
entry=0x7ffd3b56be30) at /home/jonas/root-6.14.02/core/metacling/src/TCling.cxx:2060
===========================================================
Am I trying to do the impossible, or have I just made a mistake? Any help is much appreciated. I have attached a minimal example, where I also show how I generate a dictionary and compile the classes into a shared library.
Cheers,
Jonas.
ROOT Version: 6.14/02
Platform: Ubuntu 16.04
Compiler: 7.5.0
___minimal.tar.gz (8.0 KB)