Reading a TString TBranch from a TTree


ROOT Version: 6.18/04
Platform: Ubuntu 18.04
Compiler: gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)


Dear co-rooters,

I’ve got a TTree which has a couple TString TBranches. That’s the Print() from the TTree with the relevant TBranches and a Scan() of the first 5 entries

******************************************************************************
*Tree    :DICER     : A test TTree for DICER                                 *
*Entries :  5563134 : Total =       452144078 bytes  File  Size =  417002919 *
*        :          : Tree compression factor =   1.08                       *
*............................................................................*
*Br    8 :paddle    : TString                                                *
*Entries :  5563134 : Total  Size=   39137774 bytes  File Size  =   39099132 *
*Baskets :     1917 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br    9 :beam_blocker : TString                                             *
*Entries :  5563134 : Total  Size=   78223106 bytes  File Size  =   78160020 *
*Baskets :     3138 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*

************************************************************************************************************************************************************************
*    Row   * ntof.ntof * detn.detn * event_ID. * Q_short.Q * Q_long.Q_ * RunNumber * ntof0.nto *       PSD *    paddle * beam_bloc * baseline. * std_basel *    dt_min *
************************************************************************************************************************************************************************
*        0 * 1890288.6 *       200 *       322 *      2150 *     65535 *     40019 * 1890288.6 * 0.9671931 *        Cd * both_open * 11343.299 * 27.544561 *    -2e+12 *
*        1 * 762.66200 *         5 *        23 *     32767 *       182 *     40019 * 1890288.6 * -179.0384 *        Cd * both_open * 14856.400 * 1.2608654 *    -5e+10 *
*        2 * 846.82607 *         6 *        46 *       107 *       325 *     40019 * 1890288.6 * 0.6707692 *        Cd * both_open * 14938.599 * 0.8239548 *      1000 *
*        3 * 4871.6034 *         4 *        24 *      5003 *     12836 *     40019 * 1890288.6 * 0.6102368 *        Cd * both_open * 14910.900 * 0.0881507 *    -4e+10 *
*        4 * 4876.4667 *         3 *         0 *      9961 *     24830 *     40019 * 1890288.6 * 0.5988320 *        Cd * both_open *     14756 * 0.0367038 * -4.273437 *

I’m trying to read the TString TBranches but I’m having the following issues.

  1. If I declare my parsing variables as TString, I’m able to compile my code.

    TString  paddle, beam_blocker;
    TTree *t      = (TTree*)f_root->Get("DICER");
    t->SetBranchAddress("paddle"      , &paddle);
    t->SetBranchAddress("beam_blocker", &beam_blocker);
    

    However, when I’m executing it, I get the following error

    Error in <TTree::SetBranchAddress>: The address for "paddle" should be the address of a pointer!
    Error in <TTree::SetBranchAddress>: The address for "beam_blocker" should be the address of a pointer!
    
  2. If I declare the parsing variables as pointers, I’m able to successfully compile, but once it reads the first entry, root crashes without any error message apart from “Break segmentation violation”

    TString  *paddle, *beam_blocker;
    TTree *t      = (TTree*)f_root->Get("DICER");
    t->SetBranchAddress("paddle"      , &paddle);
    t->SetBranchAddress("beam_blocker", &beam_blocker);
    
  3. I tried declaring my parsing variable as TString, but when getting the TBRanchAddress I used the GetPointer() function.

    TString  paddle, beam_blocker;
    TTree *t      = (TTree*)f_root->Get("DICER");
    t->SetBranchAddress("paddle"      , paddle.GetPointer() );
    t->SetBranchAddress("beam_blocker", beam_blocker.GetPointer() );
    

    The code compiles, but when I run it, I get the following error

    Error in <TTree::SetBranchAddress>: The pointer type given "Char_t" (1) does not correspond to the type needed "TString" by the branch: paddle
    Error in <TTree::SetBranchAddress>: The pointer type given "Char_t" (1) does not correspond to the type needed "TString" by the branch: beam_blocker
    

Any idea on how to parse the TBranches?

Thanks in advance!

In principle, this should be the right way:

TString *paddle = nullptr;
TString *beam_blocker = nullptr;
TTree *t = (TTree*)f_root->Get("DICER");
if (t) {
   t->SetBranchAddress("paddle"      , &paddle);
   t->SetBranchAddress("beam_blocker", &beam_blocker);
}

[edited to add the required pointer initialization]

TString *paddle = 0, *beam_blocker = 0;

1 Like

I tried both but I get the same thing

Error in <TTree::SetBranchAddress>: The address for "paddle" should be the address of a pointer!
Error in <TTree::SetBranchAddress>: The address for "beam_blocker" should be the address of a pointer!

I event tried to print the values by using


t->GetEntry(i);
cout << beam_blocker << endl;

But I get 0 values…

Maybe it’s more useful if I post some code and a sample file?

#include "TString.h"
#include "TTree.h"
#include "TFile.h"

#include <iostream>



void reduce_data(TString filename_in){

//_____________________________________________________________________________________________________________________	
//(1) Open the root file and loop over the TTree

	//(a) Variables to read the tree
	UShort_t Q_short, Q_long;
	double   ntof, ntof0, dt_min;
	float    PSD;
	int      detn, RunNumber, event_ID;
	TString  *paddle, *beam_blocker;
	
	//(b) Open the root file and get the TTree
	TFile *f_root;
	f_root = TFile::Open(filename_in);
	
	std::cout << std::endl;
	std::cout << "Reading file " << filename_in << std::endl;
	std::cout << std::endl;
	
	TTree *t      = (TTree*)f_root->Get("DICER");
	
	//(c) Set the branch addresses to read the TBranches
	std::cout << "Reading TTree and TBranches" << std::endl;
	t->SetBranchAddress("PSD"         , &PSD);
	t->SetBranchAddress("detn"        , &detn);
	t->SetBranchAddress("ntof"        , &ntof);
	t->SetBranchAddress("ntof0"       , &ntof0);
	t->SetBranchAddress("dt_min"      , &dt_min);
	t->SetBranchAddress("paddle"      , paddle);
	t->SetBranchAddress("Q_long"      , &Q_long);
	t->SetBranchAddress("Q_short"     , &Q_short);
	t->SetBranchAddress("event_ID"    , &event_ID);
	t->SetBranchAddress("RunNumber"   , &RunNumber);
	t->SetBranchAddress("beam_blocker", beam_blocker);
	
	//(d) Calculate the entries and prepare for the progress bar
	Long64_t entries = t->GetEntries();
	std::cout << "Total entries found: " << entries << std::endl;
	
	
//_____________________________________________________________________________________________________________________
// (2) Loop over the tree

	for (Long64_t i=0; i<20; ++i){
		t->GetEntry(i);
		std::cout << i << ". Paddle = " << paddle << ", beam blocker = " << beam_blocker << std::endl;
		//if (beam_blocker=="Undefined")   continue;	
	}

}

A sample file can be found here

https://cernbox.cern.ch/index.php/s/TtsgHanoyaPb3WP

	TString  *paddle = nullptr, *beam_blocker = nullptr;

and

	t->SetBranchAddress("paddle"      , &paddle);
	t->SetBranchAddress("beam_blocker", &beam_blocker);

I get exactly the same…


Reading TTree and TBranches
Error in <TTree::SetBranchAddress>: The address for "paddle" should be the address of a pointer!
Error in <TTree::SetBranchAddress>: The address for "beam_blocker" should be the address of a pointer!
Total entries found: 5563134
0. Paddle = 0, beam blocker = 0
1. Paddle = 0, beam blocker = 0
2. Paddle = 0, beam blocker = 0
3. Paddle = 0, beam blocker = 0
4. Paddle = 0, beam blocker = 0
5. Paddle = 0, beam blocker = 0
6. Paddle = 0, beam blocker = 0
7. Paddle = 0, beam blocker = 0
8. Paddle = 0, beam blocker = 0
9. Paddle = 0, beam blocker = 0
10. Paddle = 0, beam blocker = 0
11. Paddle = 0, beam blocker = 0
12. Paddle = 0, beam blocker = 0
13. Paddle = 0, beam blocker = 0
14. Paddle = 0, beam blocker = 0
15. Paddle = 0, beam blocker = 0
16. Paddle = 0, beam blocker = 0
17. Paddle = 0, beam blocker = 0
18. Paddle = 0, beam blocker = 0
19. Paddle = 0, beam blocker = 0

Please read carefully my answer, it has been edited

That’s perfect!!! Thanks!!
I guess I can de-reference with *(paddle) to read the actual values and use them in my analysis, right?
Printing seems to work!

(BTW, that was my first answer, despite the fact that I forgot to initialize the values to nullptr)

Also why a TString has to be declared a pointer whereas an int doesn’t have to?

Why? those are pointers, you can just use them as any pointer, e.g. std::cout << paddle->Data() << std::endl;

@pcanal can give more technical details, but for complex data types (classes), a constructor has to be called (with operator new) and then its pointer is returned. Not for simple data types

Duh!
I didn’t think about that! Thanks so much for the help!

1 Like

You’re very welcome

1 Like

You are right.
I was mistakenly using strings assuming they’re data types, but actually they’re not.
I’ve to be more careful!

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