Class TChain : public TTree

If TChain is a TTres’ subtype and even overrides some methods, why they have different behaviour? #-o

Concretely, I want to speedup program by loading only selected branches.
But I can’t just call TChain::GetBranch(), I need to take special care and check whether file with TTree changed. #-o
And even then it seem to invalidate the effect of TChain::SetBranchAddress()… #-o

[color=#FF0000]IF TCHAIN IS TTREE SUBTYPE, WHY CAN’T I JUST PASS IT INTO THE FUNCTION WHICH EXPECTS TTREE?!![/color] #-o

The only hope that I still have in this world is that ROOT7 developers won’t repeat such rough design flaws… [-o<

[quote]And even then it seem to invalidate the effect of TChain::SetBranchAddress()…[/quote]For TChain, you should use the 3 parameters version of SetBranchAddress which will update a TBranch pointer.

Cheers,
Philippe.

[quote]IF TCHAIN IS TTREE SUBTYPE, WHY CAN’T I JUST PASS IT INTO THE FUNCTION WHICH EXPECTS TTREE?!!
[/quote]

PS. For all intent and purpose (weirdly enough) if you write the function expecting (from the TTree*) the behavior of TChain it will then work for both a TTree and TChain.

Let me explain more clearly.
Suppose I have a function with type void(TTree*) and I see that class TChain : public TTree, then I [color=#FF0000]DON’T[/color] expect segfault because I’ve passed TChain into the function.

[quote]Let me explain more clearly[/quote]My bad I was not clear :slight_smile:. We already agree with your point that the TChain inheritance is sub-optimal and require user knowledge (of what not to use in the TTree interface) to properly support it in user code. This is indeed one of the thing to be simplified in v7.

Cheers,
Philippe.

Now it doesn’t segfault, but I again have a dozen of giant peaks ontop of proper distribution in p_T histogram.
It seems that TChain, when it changes file, stops reading values into variable I told him to read into. And I fill histogram 50 mln. times with the same p_T’s left from the last record of the first file.

[quote=“Pepe Le Pew”]How are multiple TTree->Draw()s done?
My dear friend!
What are you trying to say by posting this link?

Start with (note: you need to generate it for your TChain, not for your single TTrree):

[quote]It seems that TChain, when it changes file, stops reading values into variable I told him to read into. [/quote]This is unusual and surprising. I would need to see the actual code to diagnose this any further.

Cheers,
Philippe.

Here it is

And excerpt from its’ output. At first, some "Aha"s about the first file: it is possible to have several records with same value in a row, isn’t it? So it is ok. But then we see that file has changed, branch address has changed, but the value doesn’t change anymore!

Aha! 0  input/lhc10d/result_00.root
Aha! 6  input/lhc10d/result_00.root
Aha! 0  input/lhc10d/result_00.root
Aha! 11  input/lhc10d/result_00.root
Aha! 0  input/lhc10d/result_00.root
Wow! 0x21cb830
Current notr 2
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
<billion of identical messages...>

If I call ->GetEntry() on the chain and not on the branch, I have

Aha! 0  input/lhc10d/result_00.root
Aha! 0  input/lhc10d/result_00.root
Aha! 0  input/lhc10d/result_00.root
Aha! 6  input/lhc10d/result_00.root
Aha! 0  input/lhc10d/result_00.root
Aha! 11  input/lhc10d/result_00.root
Aha! 0  input/lhc10d/result_00.root
Wow! 0x232f450
Current notr 2
Aha! 0  input/lhc10d/result_01.root
Aha! 0  input/lhc10d/result_01.root
Aha! 0  input/lhc10d/result_01.root
Aha! 0  input/lhc10d/result_01.root
Aha! 0  input/lhc10d/result_01.root
Aha! 2  input/lhc10d/result_01.root
Aha! 0  input/lhc10d/result_01.root
Aha! 0  input/lhc10d/result_01.root
Aha! 0  input/lhc10d/result_01.root

So we can see that the value changes!
one.C (973 Bytes)

Hi,

The problem is fChain->LoadTree(ev); ... br->GetEntry(ev);which should read

Long64_t localEntry = fChain->LoadTree(ev); ... br->GetEntry(localEntry);
The previous code is requesting a ‘out-of-bound’ entry from the branch after the first file … [Note the 2nd code will work whether fChain is a chain or tree, in the later case localEntry will always be ev).

Cheers,
Philippe.

It seem working now, thanks!

But still, I’m really shocked how easily ROOT breaks basic rules of software design.

Why nobody did introduce

and made TChain::GetBranch() return pointer to TChainBranch? As you know, It is perfectly OK and called return type covariance paradigm.
TChainBranch class could have served as a “proxy” to TChain from which it originated from and translate “global” entry numbers to local ones…

and made TChain::GetBranch() return pointer to TChainBranch? As you know, It is perfectly OK and called return type covariance paradigm. TChainBranch class could have served as a "proxy" to TChain from which it originated from and translate "global" entry numbers to local ones...Because, for better or worse, this is only the beginning of the story. For historical reasons (code started being written in 1990) we have a lot of code (even outside of the TTree/TChain) that triggers on the type actual type of the branch, this would have to be carefully look at and tested. I.e. it is much more work than it looks at first … (Not even counting that it might break existing user code for the same reasons …)

Cheers,
Philippe.