I have a Event (TTree with at least 40 Branches, of double, int, XYZVectors or LorentzVectors), when I loop over this events, I have to do the following:
1.) define the TBranch: TBranch *b_xyz;
2.) define the content: std::vector *xyz = new std::vector
3.) get the TBranch: b_xyz = TTree->GetBranch(“xyz”);
4.) set the Address: b_xyz->SetAddress(&xyz);
within the loop over the event (evt)
5.) get the event: b_xyz->GetEntry(evt);
then I can access the values.
Everything works fine like that, but I have at leas 40 branches and doing the same thing 40 times, is not much fun. I’m sure there must be an easy way to do that. But how? Can I define a class or so?
Then sometime I add a new TBranch to my TTree, for that I have to add in each step 1-5 this line or more line for more TBranchs.
You could use some like:[code]TTree *tree; myfile->GetObject(“tree”,tree);
if (!tree) return;
TIter next( tree->GetListOfBranches() );
TBranch branch = 0;
std::vector< std::vector > objs;
while ( (branch = (TBranch)next()) ) {
objs.push_back( std::vector() );
tree->SetBranchAddress( branch->GetName(), &( objs.back() );
}
tree->GetEntry(evt);[/code] or something like [code]std::vector< std::pair<std::string, std::vector > objs;
objs.push_back( std::make_pair(“abc”,std::vector() );
objs.push_back( std::make_pair(“xyz”,std::vector() );
for( iter = objs.begin(); iter != objs.end(); ++iter) {
tree->SetBranchAddress( iter->first.c_str(), *(iter->second) );
}
tree->GetEntry(evt);[/code]
You could also use a class containing a TBranch pointer, a string and a vector of LorentzVector and usetree->SetBranchAddress( myobj.branchname, &myobj.vectorofvector, &myobj.ptrToBranch);
When using:std::vector< std::vector<LorentzVector> > objs;
...
objs.push_back( std::vector<LorentzVector>() );
tree->SetBranchAddress( branch->GetName(), &( objs.back() ); you must make absolutely sure that the vector is not resized (in which the object would move without the TTree knowing). So use something like:std::vector< std::vector<LorentzVector> > objs;
objs.reserve( tree->GetListOfBranches()->GetEntries() );
...
objs.push_back( std::vector<LorentzVector>() );
tree->SetBranchAddress( branch->GetName(), &( objs.back() );
[quote]But this still does not solve my problem! [/quote]Indeed It was not intended to, instead it was a needed correction in case anybody else might want to use this recipe;
I will answer your question in a later post .
[quote]The problem that I still have, is, that not all are vector but also vector, and
[/quote]Technically you could probably adapt to use a generic adapter like Reflex::Any to hold in the vector.
However you may also just want to create a collection class (let’s call it ‘Event’ ): class Event {
public:
std::vector<LorentzVector> xyz;
std::vector<double> name_of_double_branch;
std::vector<XYZVector> name_of_branch;
}; and simply generate, compile and load the dictionary for Event and use it as in:[code]// To Write
Event e;
mytree->Branch(“event”,&e);
// To Read
Event *e = 0;
mytree->SetBranchAddress(“event”,&e);[/code]