Storing TTreeReaderValues in std::map

Hi All,

I have been trying to find a way to store branches that I want to access from my root file in a std::map<> format. My goal is to use this so that I can access different branches for each event that I need with a string and without using many if statements.
Thus far, I have tried the following (I haven’t seen anything like this on the forums, so I apologize if I missed something!):

[code]#include “TROOT.h”
#include “TFile.h”
#include “TTree.h”
#include “TH1.h”
#include “TSystem.h”
#include “TMath.h”
#include “TTreeReader.h”
#include “TTreeReaderValue.h”
#include “TTreeReaderArray.h”

#include
#include
#include <stdio.h>
#include
#include

// – Load ROOT File
auto file = TFile::Open(“data.root”); // simple root file

// – Create a TTreeReader for the “nominal” tree
TTreeReader myReader(“nominal”, file);

// – Create the map and load variables
std::vectorstd::string variables = {“ht”}; // variables I want to store in the map
std::map<std::string,TTreeReaderValue > branch_map;
branch_map[“ht”] = {myReader, “HT”}; // store “HT” in the map

TTreeReaderValue lepton_pt(myReader, “lepton_pt”);
TTreeReaderValue met(myReader, “met_met”);
// TTreeReaderValue met = {myReader, “met_met”}; // this also works

while (myReader.Next()) {

std::cout << " lepton pT = " << *met << std::endl;        // this works 
std::cout << " met       = " << *lepton_pt << std::endl;  // this works

for (auto variable : variables){
	std::cout << "   >>> Value = " << *branch_map.at(variable) << std::endl;
}

}[/code]

But, I get the following error:

[code]Error in <Get()>: Value reader not properly initialized, did you remember to call TTreeReader.Set(Next)Entry()?

*** Break *** segmentation violation

Value = Generating stack trace…[/code]

I hope this is a simple c++ issue I’m experiencing.
I’m using ROOT 6.04/14 and I execute this with:

$ g++ -o example example.cxx `root-config --cflags --glibs` -lTreePlayer $ ./example

Any help or tips would be greatly appreciated!

Dan

Hi Dan,

We need to look into this issue.

In the meantime, you should be able to work-around the issue by using the following container:

Cheers,
Philippe.

Hi Philippe,

Thank you very much for the suggestion, I was able to get my code working!
This did lead me to another problem that I can’t figure out.
I’m hoping (again) this is just a c++ problem.

If I want to use a branch, but it only exists for some files and not others, I can’t get everything working properly without crashing.
Here’s my example of code:

[code]// … same initial setup as my previous post
// – Create a TTreeReader for the tree
TTreeReader myReader(“nominal”, file);

// – Load the variables we need
bool some_bool(true); // this is set to true/false based on the root file
TTreeReaderValue met_met;
if (some_bool)
met_met = {myReader,“met_met”};

while (myReader.Next()) {
if (some_bool)
std::cout << " MET value = " << *met_met << std::endl;
} // end while loop
[/code]

Everything compiles without any problems, but when I try to access the variable met_met in my loop over the entries, I get the following error:

[code]Error in <Get()>: Value reader not properly initialized, did you remember to call TTreeReader.Set(Next)Entry()?

*** Break *** segmentation violation
MET value = Generating stack trace…
0x0000000000000001 in [/code]

Am I not properly setting something so that I can access that branch when “some_bool” is true?

Thanks,

Dan

Hi Dan,

This does not work for the same reason than your previous attempt. In this case also you will need to use a pointer to ReaderValue so that you can allocate/set it only once (and not rely on the copy constructor).

Cheers,
Philippe.

Hi Philippe,

Thanks again for your help!
Indeed, that was a simple error to fix on my part.

Thanks,

Dan

PS If anyone comes across the same problem, here is how I remedied the issue (everything compiles and appears to run correctly):

[code]#include “TROOT.h”
#include “TFile.h”
#include “TTree.h”
#include “TH1.h”
#include “TSystem.h”
#include “TMath.h”
#include “TTreeReader.h”
#include “TTreeReaderValue.h”
#include “TTreeReaderArray.h”

#include
#include
#include <stdio.h>
#include
#include

// – Load ROOT File
auto file = TFile::Open(“data.root”); // simple root file

// – Create a TTreeReader for the “nominal” tree
TTreeReader myReader(“nominal”, file);

// – Access/store branches with map
std::vectorstd::string variables = {“ht”};
TTreeReaderValue ht(myReader, “HT”);
std::map<std::string,TTreeReaderValue * > branch_map;
branch_map[“ht”] = &ht;

// – Access branches with if statement
bool some_bool(true); // this is set to true/false based on the root file
TTreeReaderValue * met_met = NULL;
if (some_bool)
met_met = new TTreeReaderValue(myReader, “met_met”);

// – Access branches in standard way
TTreeReaderValue lepton_pt(myReader, “lepton_pt”);

while (myReader.Next()) {

std::cout << " lepton pT = " << *lepton_pt << std::endl;     // nominal access
std::cout << " MET value = " << *(*met_met) << std::endl;  // if statement access

for (auto variable : variables){
std::cout << " >>> Variable " << variable << " = " << *(*branch_map.at(variable)) << std::endl;
}
}
delete met_met;[/code]

Hi,

…and TTreeReaderValue is now marked as “uncopyable”.

Cheers, Axel.