Class for Event Loop

Hi

I have the following situation:

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.

I would appreciate any help.

thx a lot.

cheers c.

Hi,

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);

Cheers,
Philippe.

hi pascal

thx very much.

This first part, is exactly, what I was looking for, since I use the same name as the TBranch.

The problem that I still have, is, that not all are vector but also vector, and

What can I do in these lines:

std::vector< std::vector<LorentzVector> > objs; 
...
   objs.push_back( std::vector<LorentzVector>() ); 

cheers c.

Hi,

An important note!

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() );

Cheers,
Philippe.

Thx

But this still does not solve my problem!

What do I do, if not all of my vectors are LorentzVectors?

cheers c.

[quote]But this still does not solve my problem! [/quote]Indeed :slight_smile: 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 :slight_smile:.

Cheers,
Philippe.

Hi,

[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’ :slight_smile:): 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]

Cheers,
Philippe.