Home | News | Documentation | Download

TTree with a "fixed" branch


#1

Dear ROOTers,

I have a stupid but very practical question…

I would like to have a “fixed” branch in a TTree…
I have to produce a very short and compact tree to let the users make a first, quick, pre-selection of the events before starting to analyze the interesting events in the complete data rootuple. Some variables, in each compact-tree, have always the same value (for example the run number of a data taking…) but would be nice to have it accessible as a “standard” branch. On the other hand is stupid to write N times the same identical value…

There’s a smart way to do this?

Thanks,
Matteo


#2

Hi,

The alternative is to store the data that vary ‘less’ in a friend tree (however you would still have at least one slow varying value (for example the run number :slight_smile: to hold the connection between the 2 trees).

Cheers,
Philippe.


#3

Thanks a lot!

I didn’t understand that with the TTreeFriend there’s the possibility of make the “friend” tree running slower than the main tree…

I will try!

Thanks a lot!
Matteo


#4

Hi,

is working! If I well understand, however, is a sort of “unwanted feature”: the “slower” tree (friend of the “faster” one) arrives at the end and always the same (last) entry continues of being read.
In my case I would have a 1 single entry tree (with the run number…) and the “standard” tree. Looping all over thee tree (the fast one) will give me the normal things and, as wanted, always the same value for the run number…

If I would like to have really a “slower” (and not “static”) friend (“changing” every N entries of the faster one) I didnìt understand how to do…

Thanks!
Matteo


#5

Hi Matteo,

This is supported by creating an index (see TTree::BuildIndex) on the friend tree which tells the main tree which entry in the friend to read.

Cheers,
Philippe.


#6

Thanks a lot again!

Sorry if I’m bothering you so much but there’s something not clear for me, yet…

I have N (for the following exercise let’s this N being 2) files with, each, one “normal” tree (“fast”) with a lot of entries and one tree (“slow”) with just one entry.

I put “slow” trees into a chain (the pointer is “slow”) (for the “fast” ones is the same in a chain with the pointer “slow”) and I have:

[code]root [37] slow->Scan(“Entry$:This->GetTreeNumber()”)


  • Row * Entry$ * This->Get *

  •    0 *         0 *         0 *
    
  •    1 *         1 *         1 *
    

(Long64_t)2[/code]

Then I try to Build the Index based on TreeNumber since then I would like Add this as Friend of the “fast” chain and getting the entry trough the GetTreeNumber(): when the “fast” chain changes file and so tree I want also the “slow” one changing tree and then giving back always its “fixed” values.

root [38] slow->BuildIndex("This->GetTreeNumber()") (Int_t)2 root [39] slow->GetEntryNumberWithIndex(0) (const Long64_t)1 root [40] slow->GetEntryNumberWithIndex(1) (const Long64_t)0 root [41] slow->GetEntryNumberWithIndex(2) (const Long64_t)0

I’m failing in understanding the result or the entry number I get back are wrong?! I should obtain 0, 1 and then always 0 or 1 or, better some “error” number (like -1…), isn’t it?

Ciao,
Matteo


#7

[quote]I’m failing in understanding the result or the entry number I get back are wrong?! I should obtain 0, 1 and then always 0 or 1 or, better some “error” number (like -1…), isn’t it?[/quote]The return value should have -1 in those case … I updated the code in the trunk (revision 43390) and in the v5.32 patch branch to correct the behavior (i.e. it now properly returns -1).slow->BuildIndex("This->GetTreeNumber()")‘This->GetTreeNumber()’ is an unfortunate choice as it is a property of the position of the tree in the chain and not a property of the TTree ('s data). Since the implementation turns around and ask the TTree to directly build the index for its part of the data/chain, the value (as far as the index building is concerned) is always 0.

Cheers,
Philippe.


#8

Thanks a lot for your replies but I have to bother you again…

If the “BuildIndex” is TTree-based and not TChain-based, I fail to understand how I can obtain an Index (and then to use a GetEntryNumberWithIndex()…) that “connects” tree_fast_0 with tree_slow_0 in fileA, tree_fast_1 with tree_slow_1 in fileB, etc…

In addition maybe I didn’t understand correctly the philosophy behind the combination of TTreeFriend + BuildIndex. If I understood correctly the idea is:

  • create the INDEX IN THE FRIEND BASED ON MAJOR AND MINOR (THEY ARE EVALUATED ON THE FRIEND ITSELF)
  • call “normally” (a simple GetEvent()) the “main” tree; this will computes the major<<31+minor BASED ON THE MAIN TREE VARIABLES and then will call GetEntryNumberWithIndex(major, minor), ON THE FRIEND, that will be NOW REFERRED TO THE INDEX computed in the previous step WITH THE FRIEND VARIABLES
    Is it correct?!

Thanks again,
Matteo


#9

[quote]If the “BuildIndex” is TTree-based and not TChain-based, I fail to understand how I can obtain an Index (and then to use a GetEntryNumberWithIndex()…) that “connects” tree_fast_0 with tree_slow_0 in fileA, tree_fast_1 with tree_slow_1 in fileB, etc…[/quote]TChain::BuildIndex is a two stage process. First build the index for the individual TTree, then (well at the same time but that’s a detail) record the min and max values for each TTree’s index. The search is also a 2 stages process, first find the TTree to which the value belongs … assuming that the TTree are sorted in increasing order of the index value (The index building of the chain fails otherwise).

[quote]Is it correct?![/quote]Yes this is the semantic.

Cheers,
Philippe.


#10

Hi!

At the end I found the way to do what I had in mind… Since “fast” and “slow” trees are “synchronized” by belonging to the same file (in the example below I have two pairs of trees in two files: tree_prova_1.root and tree_prova_2.root) I wanted to use the namefile as major. Since is not possible a char-ordering I’m using the Hash() of the file name (that fortunately is an available method of TFile! Doing it passing trough TString was almost impossible…):

  TChain* fast = new TChain("fast");
  TChain* slow = new TChain("slow");
  fast->Add("./tree_prova*.root");
  slow->Add("./tree_prova*.root");
  printf("fast: %lld\n", fast->GetEntries());
  printf("slow: %lld\n", slow->GetEntries());
  fast->Scan("pippo:This->GetCurrentFile()->GetName():This->GetCurrentFile()->Hash()", "", "", 10);
  slow->Scan("pluto:This->GetCurrentFile()->GetName():This->GetCurrentFile()->Hash()", "", "", 10);
  slow->BuildIndex("This->GetCurrentFile()->Hash()");
  int pippo=0;
  int pluto=0;
  fast->AddFriend(slow);
  fast->SetBranchAddress("pippo", &pippo);
  fast->SetBranchAddress("pluto", &pluto);
  for (int ii=0; ii<102; ii++) {
    fast->GetEntry(ii);
    printf("%d) pippo = %d, pluto = %d, filename = %s (%lu)\n", ii, pippo, pluto, fast->GetCurrentFile()->GetName(), fast->GetCurrentFile()->Hash());
  }
  fast->Scan("pippo:pluto");

that gives, as wanted, as result:

fast: 1124
slow: 2
************************************************
*    Row   *     pippo * This->Get * This->Get *
************************************************
*        0 *         0 * ./tree_pr * 1.403e+09 *
*        1 *         2 * ./tree_pr * 1.403e+09 *
*        2 *         4 * ./tree_pr * 1.403e+09 *
*        3 *         6 * ./tree_pr * 1.403e+09 *
*        4 *         8 * ./tree_pr * 1.403e+09 *
*        5 *        10 * ./tree_pr * 1.403e+09 *
*        6 *        12 * ./tree_pr * 1.403e+09 *
*        7 *        14 * ./tree_pr * 1.403e+09 *
*        8 *        16 * ./tree_pr * 1.403e+09 *
*        9 *        18 * ./tree_pr * 1.403e+09 *
************************************************
************************************************
*    Row   *     pluto * This->Get * This->Get *
************************************************
*        0 *        12 * ./tree_pr * 1.403e+09 *
*        1 *        25 * ./tree_pr * 1.403e+09 *
************************************************
0) pippo = 0, pluto = 12, filename = ./tree_prova1.root (1403912113)
1) pippo = 2, pluto = 12, filename = ./tree_prova1.root (1403912113)
...
99) pippo = 198, pluto = 12, filename = ./tree_prova1.root (1403912113)
100) pippo = 2000, pluto = 25, filename = ./tree_prova2.root (1403912145)
101) pippo = 2002, pluto = 25, filename = ./tree_prova2.root (1403912145)
************************************
*    Row   *     pippo *     pluto *
************************************
*        0 *         0 *        12 *
*        1 *         2 *        12 *
*        2 *         4 *        12 *
...
*       99 *       198 *        12 *
Type <CR> to continue or q to quit ==> 
*      100 *      2000 *        25 *
*      101 *      2002 *        25 *
...

Thanks for your help. I hope my “tricky” solution can be useful to someone else…
Matteo