How to read a struct from a TTree

I used a structure to save some data in a TTree branch. I had to declare the structure both in the macro I created the TTree in, and in the macro I read the TTree in. This worked, but it was messy, so I decided to put the structure declaration in its own macro. However, when I try to load the branch in the second macro, I get a type error.

//I declared the structure in the macro MakeList.c
struct constant_list {
  long evts;
  double eMin;
  double eMax;
  double SiPM_pde;
  double light_cov;
  int tpbOnOff;
  char recoil;
};

//In the macro RunMC.c, I created a TTree called SiPMmc. 
//I used MakeList.c to create a structure called this_run
// and I saved it in a branch.
SiPMmc->Branch("constants", &this_run, "evt_max/L:energy_min/D:energy_max/D:pde/D:coll_eff/D:tpb/I:evt_type:C");

//In the macro ReadOutput1.c, I'm trying to read in the TTree
#include "MakeList.c"
TFile *fileIN = TFile::Open(filename);
TTree *SiPMmc = (TTree*)fileIN->Get("SiPMmc");
constant_list constants;
SiPMmc->SetBranchAddress("constants", &constants);

I get this error:
Error in TTree::SetBranchAddress: The pointer type given “constant_list” does not correspond to the type needed “Long64_t” (16) by the branch: constants
I don’t know why it wants me to use the type of the first item in the structure, but it doesn’t work if I do Long64_t constants instead.

Thanks in advance for your help!


ROOT Version: 6.10/04
Platform: Ubuntu 18.04 on Windows
Compiler: Cling?


Try:

SiPMmc->SetBranchAddress("constants", &constants.evts);

Thanks for the reply!
When I try
SiPMmc->SetBranchAddress("constants", &constants.evts);
I get the same error as before.
If I try to declare it as
Long_t constants.evts;
it says, “error: expected ‘;’ at end of declaration”.

SiPMmc->Branch("constants", &this_run, "evt_max/L:energy_min/D:energy_max/D:pde/D:coll_eff/D:tpb/I:evt_type/B");

I think, you should simply use (let ROOT discover what “this_run” is, so that you will not face “structure padding” problems):

SiPMmc->Branch("constants", &this_run);

Now it says:
Error in <TTree::SetBranchAddress>: The address for "constants" should be the address of a pointer!

This is a strange error given the information in the post. There is seemingly no Long64_t in the tree at all … Can you give us the output of SiPMmc->Print() ?

There’s some other stuff here, but constants is at the bottom.

******************************************************************************
*Tree    :SiPMmc    : SiPM LAr Simulation                                    *
*Entries :        0 : Total =            8131 bytes  File  Size =          0 *
*        :          : Tree compression factor =   1.00                       *
******************************************************************************
*Br    0 :ievt      : ievt/I                                                 *
*Entries :        0 : Total  Size=        470 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    1 :tru_psd   : tru_psd/D                                              *
*Entries :        0 : Total  Size=        490 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    2 :rec_psd   : rec_psd/D                                              *
*Entries :        0 : Total  Size=        490 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    3 :u_pr      : u_pr/D                                                 *
*Entries :        0 : Total  Size=        478 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    4 :erecoil   : erecoil/D                                              *
*Entries :        0 : Total  Size=        490 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    5 :n_scint_p : n_scint_p/I                                            *
*Entries :        0 : Total  Size=        490 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    6 :n_coll_p  : n_coll_p/I                                             *
*Entries :        0 : Total  Size=        486 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Branch  :constants                                                          *
*Entries :        0 : BranchElement (see below)                              *
*............................................................................*
*Br    7 :evts      : Long_t                                                 *
*Entries :        0 : Total  Size=        474 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    8 :eMin      : Double_t                                               *
*Entries :        0 : Total  Size=        474 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    9 :eMax      : Double_t                                               *
*Entries :        0 : Total  Size=        474 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br   10 :SiPM_pde  : Double_t                                               *
*Entries :        0 : Total  Size=        490 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br   11 :light_cov : Double_t                                               *
*Entries :        0 : Total  Size=        494 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br   12 :tpbOnOff  : Int_t                                                  *
*Entries :        0 : Total  Size=        490 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br   13 :recoil    : Char_t                                                 *
*Entries :        0 : Total  Size=        482 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*

The issue is that in your structure, you use

 long evts;

but when you save the branch, “evt_max/L” saves it as a Long64_t, and when you try to read it with a “long” it doesn’t work. So, to avoid inconsistencies you’re better off using only ROOT variables:

struct constant_list {
  Long64_t evts;
  Double_t eMin;
  Double_t eMax;
  Double_t SiPM_pde;
  Double_t light_cov;
  Int_t tpbOnOff;
  Char_t recoil;
};

As a side note, your tree printout looks a bit strange to me; the variables in the structure appear as separate branches (although the “BranchElement” comment somewhat explains this), but to me they always look like one branch (maybe it’s some option you are using in your config?):

*Tree    :t         : t                                                      *
*Entries :       10 : Total =            2089 bytes  File  Size =        855 *
*        :          : Tree compression factor =   2.33                       *
******************************************************************************
*Br    0 :constants : evt_max/L:energy_min/D:energy_max/D:pde/D:coll_eff/D:  *
*         | tpb/I:evt_type:C
*Entries :       10 : Total  Size=       1736 bytes  File Size  =        254 *
*Baskets :        1 : Basket Size=      32000 bytes  Compression=   2.33     *
*............................................................................*

Hi,

maybe a more high-level solution could help?
For example, with RDataFrame, the code to make an histogram out of one of your leaves would look like:

ROOT::RDataFrame df("SiPMmc","myfile.root");
auto h = df.Histo1D("constants.evt_max");
h->Draw();

Cheers,
H

@dastudillo, I tried your solution, but I got the same error again: Error in <TTree::SetBranchAddress>: The pointer type given "constant_list" does not correspond to the type needed "Long64_t" (16) by the branch: constants

@Guisan, I’ll try to use RDataFrame and see if that works.

RDataFrame isn’t working because my ROOT version is too old :disappointed_relieved:

If using:

struct constant_list {
  Long64_t evts;
  Double_t eMin;
  Double_t eMax;
  Double_t SiPM_pde;
  Double_t light_cov;
  Int_t tpbOnOff;
  Char_t recoil;
};

does not work. You can try (but verify carefully that the data is read correctly):

SiPMmc->SetBranchAddress("constants", (Long64_t*)(&constants));

Thank you so much @pcanal! That worked, and the graphs look the same as they did before I started messing around with this macro. I am eternally grateful.

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