[quote=“wiso”]I’ve never understand why accessing to TTree it’s so intricated.
I don’t like it. Better would be:
for(i=0;...............) {
t.Get("Brach1")[i];
t.Get("Brach2")[i];
}
[/quote]
You can do things like this if you really wanted to. But there is a reason it’s not done like that. When you are looping over millions of events, the cost of calling a function like ‘get’ and the [i] operator would be enough to slow the process down significantly. Much more efficient is if you tell the tree where you want to put the value, then within the loop just do one ‘GetEntry’ which fetches all of the values into memory in the most efficient way possible. Then within the loop, you just specify the variable where you want to use it. No function calls and lookups each time you you want to do something with the value in Branch1.
You can do things like what you want to do, anyway, but a) they are not the most efficient and b) they are not very elegant.
for ( Long64_t i... )
t.GetEntry(i)
t.GetLeaf("Branch1").GetValue()
In short, there are multiple parts to it: Reading the data from the tree into memory (which is done in GetEntry), then fetching the value from the memory address (.GetValue()). Alternatively, you could just tell the tree beforehand where to put the value (With SetBranchAddress), and use GetEntry(). No messing around with fetching values from the relevant place, just physics logic.
[quote]and why don’t use iterators? Or iterators that can filter data (like generators in python)?
TCut cut = "Brach1 > 10 && Branch2<100";
TTree t;
i = t.GetIterator(cut);
for (i=t.begin();i!=t.end();++i)
{
cout << i.Get("Branch1"); //only when the condition cut is true they are printed
cout << i.Get("Branch2");
}
[/quote]
Again, speed and elegance. You can do what you want to do, though:
Consider this snippet, which just loops over the events that match your cut:
[code]
TTree t…;
Double_t Branch1;
t.SetBranchAddress( “Branch1”, &Branch1 );
t.Draw(“>>MyEventList”, “Brach1 > 10 && Branch2<100”);
TEventList *MyEventList;
gDirectory->GetObject(“MyEventList”, MyEventList);
for ( Long64_t i = 0; i < MyEventList->GetN(); i++ )
{
t.GetEntry( MyEventList->GetEntry( i ) );
cout << Branch1 << endl;
}[/code]
This is a matter of taste and just the way the framework evolved. You could probably find a way of doing things like that if you really wanted to, but you would be turning your project into a programming exercise than a physics (or whatever else you are doing) one. (If it’s not already possible to do exactly this)
Why would one want the complexities associated with a fully SQL compatible database? You just need access to numbers efficiently. That’s what a TTree is about. If you want a relational database and associated detritus, then find some other way of doing what you want. More likely is that the only time you need a feature present in an SQL database, you would be able to implement it easily with what is available in ROOT anyway.
IANARD (I am not a ROOT developer). I am not speaking on behalf of them, or anything like that. But in my experience, things are the way they are for a good reason, especially in cases like this. ROOT can be a bit complex to get your head around sometimes, but if you want to do something efficiently, there is usually a good way to do it - and it will usually be faster for you to put up with the way it is done than to try to reinvent the wheel.
If you like Python, try PyROOT. It is easier to implement some constructs which are like what you are after - but you will always take a big speed hit when doing things like looping over events.