MakeClass and AddFriend

Dear rooters,

I am trying to use MakeClass on different trees in the same file. So far, I searched and found different old forum entries discussing the subject:

root.cern.ch/root/roottalk/roottalk01/3482.html

This seems too old and maybe a new (easier?) way of doing so is possible now?

Also,
osdir.com/ml/lang.c++.root/2004-06/msg00162.html

Seems to imply that some progress was on the way in 2004.

I tried to do the following in 5.18/00d:

root [0] 
Attaching file Jpsiee_output_1.root as _file0...
Warning in <TClass::TClass>: no dictionary for class AttributeListLayout is available
root [1] TTree* treeA = (TTree*)(_file0 -> Get("Electron"));      
root [2] TTree* treeB = (TTree*)(_file0 -> Get("Muon"));    
root [3] treeA -> AddFriend(treeB);                   
root [4] treeA->MakeClass()

It didn’t work the way I expected it to, i.e. only branches from treeA where included in the class. Is it now possible to have branches from the friend tree as well in the class from MakeClass or am I doing something wrong here?

Cheers,

Andrée

Hi,

MakeClass has not yet been upgraded to support friend. You still need to create a MakeClass for each TTree separately and connect them ‘by hand’.

Cheers,
Philippe.

Hi,

That’s a long shot, but I’m trying now to use this by hand and I have some trouble. So far, I could only find this forum entry to obtain some info on how to do this:

root.cern.ch/root/roottalk/roottalk07/1249.html

I tried following it carefully and I failed to get it to work. Would it be possible for you to post an complete example that I could base myself on to get this to work?

Thanks in advance,

Andrée

Hi Andrée,

Can you post your tries? How did they fail?

Cheers,
Philippe.

So, I have two trees which are part of the same root file, Electron and Photon. I created the two classes separately. Then I made the modifications in Electron.h to include the Photon class and I obtained the files attached. I am not sure I am doing the "constructor’ part correctly (at least I don’t understand how it works!). I also made sure to read variables from both trees in Electron.C. When I try to run this file, I get the following:

root [0] .L Electron.C
root [1] Electron t;t.Loop();
Warning in <TClass::TClass>: no dictionary for class AttributeListLayout is available
Error: Photon() declared but not defined Electron.h:354:
*** Interpreter error recovered ***

What am I doing wrong?

Also, another issue in my case is that I will need to be able to compile my code using the ACLiC libs. The files I share here are only a toy example, but they exhibit the same compilation error I get when I use my original code, which is:

root [0] .L Electron.C+      
Info in <TUnixSystem::ACLiC>: creating shared library /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron_C.so
In file included from /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron_C_ACLiC_dict.h:33,
                 from /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron_C_ACLiC_dict.cxx:16:
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C: In member function `virtual void Electron::Loop()':
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:44: error: `photon_nParticle' was not declared in this scope
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:43: warning: unused variable 'nelec'
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:44: warning: unused variable 'nphot'
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:44: warning: unused variable 'photon_nParticle'
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:36: warning: unused variable 'nbytes'
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:36: warning: unused variable 'nb'
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.h: At global scope:
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.h:708: warning: unused parameter 'entry'
g++: /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron_C_ACLiC_dict.o: No such file or directory
Error in <ACLiC>: Compilation failed!

Thanks a lot for you help,

Andrée
Photon.h (28.7 KB)
Electron.h (28.6 KB)
Electron.C (1.46 KB)
AnalysisSkeleton.aan.root (321 KB)

[quote]Error: Photon() declared but not defined Electron.h:354[/quote]You never include/load Photon.C which is absolutely necessary due to the way the .h is written (see the #ifdef Photon_cxx). Doing the following should fix that issue:root [] .L Photon.C root [] .L Electron.CNote that the order is important.

To Fix:/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:44: error: `photon_nParticle' was not declared in this scope you need to replace int nphot = photon_nParticle;with int nphot = fOther->photon_nParticle;

Also, if and only if the 2 TTrees are ‘Friend’ the call to ‘fOther->GetEntry(jentry)’ is uncessary and could be harmful if the entries are not in the same order in both TTree (i.e. you are relying on the TTreeIndex (constructed via TTree::BuildIndex).

Cheers,
Philippe.

Hi Philippe,

Thanks for this, it works fine with your fixes! There is only one remaining issue: the compilation with ACLiC. I tried to compile the files in the order you mentionned, both with ACLiC, and it crashed.

root [0] .L Photon.C+        
Info in <TUnixSystem::ACLiC>: creating shared library /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Photon_C.so
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Photon.h:670: warning: unused parameter 'entry'
root [1] .L Electron.C+      
Info in <TUnixSystem::ACLiC>: creating shared library /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron_C.so
In file included from /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron_C_ACLiC_dict.h:33,
                 from /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron_C_ACLiC_dict.cxx:16:
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C: In member function `virtual void Electron::Loop()':
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:43: warning: unused variable 'nelec'
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:44: warning: unused variable 'nphot'
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:36: warning: unused variable 'nbytes'
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.C:36: warning: unused variable 'nb'
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.h: At global scope:
/atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron.h:708: warning: unused parameter 'entry'
root [2] Electron t;t.Loop();
Warning in <TClass::TClass>: no dictionary for class AttributeListLayout is available

 *** Break *** segmentation violation
(no debugging symbols found)
Using host libthread_db library "/lib64/tls/libthread_db.so.1".
Attaching to program: /proc/13248/exe, process 13248
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 4144084672 (LWP 13248)]
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
0xffffe405 in __kernel_vsyscall ()
#1  0x006ae4b3 in __waitpid_nocancel () from /lib/tls/libc.so.6
#2  0x00657779 in do_system () from /lib/tls/libc.so.6
#3  0x0078a98d in system () from /lib/tls/libpthread.so.0
#4  0xf7b91387 in TUnixSystem::Exec ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#5  0xf7b9701f in TUnixSystem::StackTrace ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#6  0xf7b93a1a in TUnixSystem::DispatchSignals ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#7  0xf7b93aa8 in SigHandler ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#8  0xf7b92d25 in sighandler ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#9  <signal handler called>
#10 0xf496fc63 in Photon::Init ()
   from /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Photon_C.so
#11 0xf497214b in Photon::Photon ()
   from /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Photon_C.so
#12 0xf494ff5b in Electron::Electron ()
   from /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron_C.so
#13 0xf49504a3 in G__Electron_C_ACLiC_dict_14374_0_1 ()
   from /atlas/data2/userdata/arobic/Jpsi/15.3.0.1/PhysicsAnalysis/BPhys/BPhysExamples/run/root_test/./Electron_C.so
#14 0xf7310bd7 in Cint::G__ExceptionWrapper ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCint.so
#15 0xf73a5adc in G__execute_call ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCint.so
#16 0xf73a5dee in G__call_cppfunc ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCint.so
#17 0xf7386a1f in G__interpret_func ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCint.so
#18 0xf7375410 in G__getfunction ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCint.so
#19 0xf734e981 in G__define_var ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCint.so
#20 0xf73d1666 in G__exec_statement ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCint.so
#21 0xf734752c in G__exec_tempfile_core ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCint.so
#22 0xf7348867 in G__exec_tempfile_fp ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCint.so
#23 0xf73e195c in G__process_cmd ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCint.so
#24 0xf7b7f5ff in TCint::ProcessLine ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#25 0xf7ab8262 in TApplication::ProcessLine ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#26 0xf71371b3 in TRint::HandleTermInput ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libRint.so
#27 0xf7135684 in TTermInputHandler::Notify ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libRint.so
#28 0xf7137ad2 in TTermInputHandler::ReadNotify ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libRint.so
#29 0xf7b8fd12 in TUnixSystem::CheckDescriptors ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#30 0xf7b93ef8 in TUnixSystem::DispatchOneEvent ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#31 0xf7b10b20 in TSystem::InnerLoop ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#32 0xf7b108e7 in TSystem::Run ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#33 0xf7ab83e2 in TApplication::Run ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libCore.so
#34 0xf7135f6a in TRint::Run ()
   from /atlas/software/releases/15.3.0_i686slc4/sw/lcg/app/releases/ROOT/5.22.00b/slc4_ia32_gcc34/root/lib/libRint.so
#35 0x08048d46 in main ()
Root > 

Any idea why this is?

Cheers,

Andrée

Hi,

Note that the compilation did succeeds. The problem is that in Electron::Electron you use tree2 before it is ever initialized hence using a random value. Your code should simply look like:[code]Electron::Electron(TTree tree)
{
// if parameter tree is not specified (or zero), connect the file
// used to generate this class and read the Tree.
if (tree == 0) {
TFile f = (TFile)gROOT->GetListOfFiles()->FindObject(“AnalysisSkeleton.aan.root”);
if (!f) {
f = new TFile(“AnalysisSkeleton.aan.root”);
}
tree = (TTree
)gDirectory->Get(“Electron”);

}
Init(tree);

TFile f = (TFile)gROOT->GetListOfFiles()->FindObject(“AnalysisSkeleton.aan.root”);
if (!f) {
f = new TFile(“AnalysisSkeleton.aan.root”);
}
tree2 = (TTree*)gDirectory->Get(“Photon”);

fOther = new Photon( tree2 );
}
[/code]

Hi,

Sorry about that, this was badly formulated, you are right, it compiled ok, this was a runtime error :unamused:

Now it works perfectly!! Thanks a bunch for all your help!

Cheers,

Andrée

Hi,

I wonder what was the final outcome of this thread, the exact way the things were done.

I am now doing MakeClass for the two trees separately. Then adding the one tree to the first, like suggested earlier in this thread. I want the two trees to be friends, but have not succeeded in setting this correctly. The “mother” class is CollectionLooper.

At the moment I cannot access the variables from the second tree I try to include, and I also get lots of error messages like this:
Error in TTree::SetBranchAddress: unknown branch -> mboyseg_nHits
but these branches are actually in the “mother-tree”, not the added tree.

I attach the relevant files, and maybe you can spot where the changes need to be made. Relevant lines are in beginning of CollectionTree.h and in the Init() functions.

Thank you very much!
CollectionLooper.C (1.67 KB)
thephysics.h (236 KB)
thephysics.C (1.43 KB)
miniloopMacro.C (428 Bytes)
CollectionLooper.h (449 KB)
CollectionLooper.C (1.68 KB)

Hi,

The problem is the line 4380 of your CollectionLooper.h:[code] physicsChain = (TTree*)gDirectory->Get(“physics”);
physicsObject = new thephysics( physicsChain );

Init(physicsChain);[/code]where the last line (the line 4380) should actually induces the execution of thephysics::Init
i.e. assuming you added a thephysics * fThephysics_mc;data member to CollectionLooper.h, the line above should read:[code] physicsChain = (TTree*)gDirectory->Get(“physics”);
physicsObject = new thephysics( physicsChain );

fThephysics_mc = new thephysics( physicsChain );[/code]

Cheers,
Philippe.

Hi, I guess you mean I should do:

physicsChain = (TTree*)gDirectory->Get("physics");
 physicsObject = new thephysics( physicsChain ); 

since I in CollectionLooper.h do
thephysics *physicsObject;

If I just do this, I get a segmentation violation when I try to run. If I include the line

Init(physicsChain);

then I do not get segmentationviolation, but I do still not manage to read the branches in the second tree.

That is why I thought I needed to add the second tree as friend, but did not succeed.

you can test by trying cout in CollectionTree.C with a variable from the “mother” tree CollectionTree

stacomu_nTrack

and one from the added physics tree

jet_n

Any other suggestions what I might be doing wrong? Did you try to run it?

Thanks!
Maiken

Hi again,

sorry I did not notice that my previous attempt to upload also the ntuple did not suceed. It is too big to be attached.

The file can be found on lxplus:

/afs/cern.ch/user/m/maikenp/public/physics.root

Thanks
Maiken

[quote]Hi, I guess you mean I should do: [/quote]yes, indeed, I misread. CollectionLooper::Init must be passed a pointer to a TTree or TChain that hold a ‘CollectionLooper’ tree.

[quote]If I just do this, I get a segmentation violation when I try to run[/quote]What is the stack trace? What does valgrind says about this crash?

Cheers,
Philippe.

Hi,

so you agree that I did it correct by doing this?:

 physicsChain = (TTree*)gDirectory->Get("physics");
 physicsObject = new thephysics( physicsChain ); 

If so, then I get seg.violation when in CollectionTree.C doing:

 Long64_t nentries = fChain->GetEntriesFast();

The message from ROOT is:

I have never managed to successfully use Valgrind with ROOT… but this should shows that the problem lies when trying to access the branches.

Maiken
[/code]

Hi,

the problem is that your file physics does not have a TTree named ‘CollectionLooper’ but you are trying to read it from that file: tree = (TTree*)gDirectory->Get("CollectionLooper");and hence fChain later on is still 0.

Philippe.

Cheers,
Philippe.

Hi,

thanks

But I am getting a bit confused. I am using “CollectionLopper” as my main file. Not “thephysics”. And it is in CollectionLooper.C I am getting the problem. Exactly where do you mean I should add the line you suggest?

To remind you: I am in CollectionLooper.h adding

Thanks
Maiken

Hi,

What is the name of the .root file in which you have a TTree named ‘CollectionLooper’? Is this file open in the beginning of the CollectionLooper constructor? I see (path removed):[code]CollectionLooper::CollectionLooper(TTree tree)
{
// if parameter tree is not specified (or zero), connect the file
// used to generate this class and read the Tree.
if (tree == 0) {
TFile f = (TFile)gROOT->GetListOfFiles()->FindObject(“physics.root”);
if (!f) {
f = new TFile(“physics.root”);
}
tree = (TTree
)gDirectory->Get(“CollectionLooper”);

}
Init(tree);[/code]

Philippe.

Well, I thought that these automatically created lines

took care of opening the file?

Both CollectionTree and physics trees are in physics.root

Maiken