Tree, branch, subbranch

Hello!

I have somehow a basic question for people used to work with trees.
I have something like 200 leaves in my tree something like this:

MyTree:

  • var1_x1
  • var1_x2
  • var1_x3
  • var2_x1
  • var2_x2
  • var2_x3
  • varN_x1
  • varN_x2
  • varN_x3

I tried to play with structures
So I created an exemple to hold some kind of structure in my tree. So as second step, I have this structure.

MyTree.var1.x1
MyTree.var2.x2

MyTree.varN.x3

That sounds good to me and using TBrowser I can open my tree with a second level.
But can someone explain me of should I do to properly create a tree structure with a third level in the architecture of my tree?

I would like to access something like this : “MyTree.level1.level2.level3”

Here is an running example creating a test.root file, but I am using a specifif leaflist in order to avoid dictionary issues:

struct Projection
{
      Float_t x,y;
};

Bool_t test()
{
        TFile *f = TFile::Open("test.root", "RECREATE");
        TTree *t = new TTree("t", "t");

        struct Projection p;
        t->Branch("projections", &p, "x/F:y/F");

        t->Fill();
        f->Write();
        f->Close();

        return 1;
}

And what I would like to do is using the following structure :

struct Projection
{
      struct Position { Float_t x,y; };
      struct Position var1;
      struct Position var2;
};

Maybe should I create subbranch directly to hold my leaf ?
I tried but I could not find a way to do that… Has someone an example to show me maybe ?
That would be wonderful.

Anyway, thanks a lot !!

I though also about this by playing with leaflist :

struct Projection
{
        struct Position { Float_t x,y; };
        struct Position var1;
        struct Position var2;
};

Bool_t test()
{
        TFile *f = TFile::Open("test.root", "RECREATE");
        TTree *t = new TTree("t", "t");

        struct Projection p;
        t->Branch("projections", &p, "var1.x/F:var1.y/F:var2.x/F:var2.y/F");

        t->Fill();
        f->Write();
        f->Close();

        return 1;
}

But it’s staying at the same level ! :frowning:

Search for “split” and “dot” in the TTree Class Reference.

Wonderful thank you.

Here is the second try.

using namespace std;
struct Projection
{
	struct Position { Float_t x,y; };

	Position var1;
	Position var2;

	TLorentzVector v;
};

Bool_t test()
{

	TFile *f = new TFile("test.root", "UPDATE");
      	TTree T("T","test list");

	struct Projection p;
	struct Projection p2;

	T.Branch("var1.","Projection",&p, 32000, 1);
	p.var1.x = 1;
        p.var2.x = 1;
        p.var1.y = 2;
        p.var2.y = 2;
	p.v.SetPxPyPzE(0,0,1,-1);
	T.Fill();

        p.var1.x = 10;
        p.var2.x = 10;
        p.var1.y = 20;
        p.var2.y = 20;
        p.v.SetPxPyPzE(0,0,100,-100);
	T.Fill();

      	T.Print();
      	T.Write();

	f->Close();
	return 1;
}

From now this test.C script is generating warning messages, because of dictionary. This I understand.
It doesn’t know about my structure obviously.

But why do I get the following warning, when my file doesn’t exists ? And not if my test.root already exists ?

> root -l test.C
root [0] 
Processing test.C...
Warning in <TStreamerInfo::Build>: Projection: Projection::Position has no streamer or dictionary, data member "var1" will not be saved
Warning in <TStreamerInfo::Build>: Projection: Projection::Position has no streamer or dictionary, data member "var2" will not be saved
******************************************************************************
*Tree    :T         : test list                                              *
*Entries :        2 : Total =            3175 bytes  File  Size =          0 *
*        :          : Tree compression factor =   1.00                       *
******************************************************************************
*Branch  :p1.                                                                *
*Entries :        2 : BranchElement (see below)                              *
*............................................................................*
*Br    0 :p1.var1   : Projection::Position                                   *
*Entries :        2 : Total  Size=        703 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    1 :p1.var2   : Projection::Position                                   *
*Entries :        2 : Total  Size=        703 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    2 :p1.v      : TLorentzVector                                         *
*Entries :        2 : Total  Size=        777 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
> root -l test.C
root [0] 
Processing test.C...
******************************************************************************
*Tree    :T         : test list                                              *
*Entries :        2 : Total =            3219 bytes  File  Size =        690 *
*        :          : Tree compression factor =   1.00                       *
******************************************************************************
*Branch  :p1.                                                                *
*Entries :        2 : BranchElement (see below)                              *
*............................................................................*
*Br    0 :p1.var1   : Projection::Position                                   *
*Entries :        2 : Total  Size=        703 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    1 :p1.var2   : Projection::Position                                   *
*Entries :        2 : Total  Size=        703 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    2 :p1.v      : TLorentzVector                                         *
*Entries :        2 : Total  Size=        777 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*

Futhermore, it seems to have some issues with the substructure I defined (Projection::Position). But in fact, data members are saved…
So is those messages harmless ?

Since my tree knows the structure when I read my test.root, is it possible to remove the following error messages ?

> root -l test.root
root [0] 
Attaching file test.root as _file0...
Warning in <TClass::Init>: no dictionary for class Projection is available
Warning in <TClass::Init>: no dictionary for class Projection::Position is available
(TFile *) 0x563113728750

Thank you for your help !

Create a “Projection.hxx” file:

#if !defined(__Projection_hxx__)
#define __Projection_hxx__

#include "TLorentzVector.h"

struct Projection {
  struct Position { Float_t x, y; };
  
  struct Position var1;
  struct Position var2;
  
  TLorentzVector v;
};

# endif /* !defined(__Projection_hxx__) */

and then load it:

root [0] .L Projection.hxx++

Yep of course, that’s what I wrote. I am aware of this.
But what about those warning messages are they harmless ? why it’s showing up only the first time ?

Create a “rootlogon.C” file:

{
  gROOT->LoadMacro("Projection.hxx+");
}

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