TClonesArrays, split and file reading

Hi,

I have an object which basically contains as data members:

TClonesArray *fPABlocks; //->
static TClonesArray *fgPABlocks;

where fPABlocks points to fgPABlocks, which is a TClonesArray of an object containing:

Int_t fBlockNb;
Int_t fNPulse; //Number of pulses
TClonesArray *fEnergy; //-> Energies

and fEnergy is a TClonesArray of an object containing:

Double_t fValue;

Somehow, when writing the main object to a branch in a tree with split 99, the reading of the file give errors in some events (only a few out of the total) :

TClonesArray::Streamer expecting class
TClonesArray::Streamer expecting class
TClonesArray::Streamer expecting class �
TClonesArray::Streamer expecting class
Error in TBuffer::CheckByteCount: object of class TClonesArray read too many bytes: 14 instead of -1151401488
Warning in TBuffer::CheckByteCount: TClonesArray::Streamer() not in sync with data on file /work/halla/dvcs/disk4/kin3/dvcs_4435_0.root, fix Streamer()
Error in TBuffer::CheckByteCount: Byte count probably corrupted around buffer position 28905:
-1151401488 for a possible maximum of -92

I found a solution to the problem: when setting the split of the branch to 2, this does not happen anymore. However, it is too late for me to do that and I woundn’t like to process all my files (about 3000) again. I noticed that TTree::Draw actually manage to loop over the data member I’m interested in (fBlockNb) without problems.

My question is: can we somehow emulate the way TTree::Draw reads the branch to use it in a loop, as the usual method with SetBranchAddress, etc fails giving the above mentioned errors?

Thank you very much for your help,

Carlos

PS: This is ROOT 4.00/08 under Linux

[quote]My question is: can we somehow emulate the way TTree::Draw reads the branch to use it in a loop, as the usual method with SetBranchAddress, etc fails giving the above mentioned errors?
[/quote]You just need to disable the branch(es) corresponding to “fEnergy”. (call SetBranchStatus).
The problem that you have encountered has been fixed in laster relase of ROOT.

Cheers,
Philippe.

A strange behaviour happens when I try to do that. The branch seems present when I do a tree->Print() before calling SetBranchStatus:


*Br 7 :event_pa.fPABlocks.fEnergy : fEnergy[event_pa.fPABlocks_] *
*Entries : 67625 : Total Size= 277517543 bytes File Size = 3852740 *
*Baskets : 9632 : Basket Size= 32000 bytes Compression= 71.98 *

then I do

root [7] tree->SetBranchStatus(“event_pa.fPABlocks.fEnergy”,0);
root [8] Int_t nev=tree->GetEntry();
Error in TTree::SetBranchStatus: unknown branch -> event_pa.fPABlocks.fEnergy

The only way I found to get around that is to do

tree->SetBranchStatus("*",0);
tree->SetBranchStatus(“event_pa.fPABlocks.fBlockNb”,1);

but when doing that, and looping over the file, I still get the error message I mentioned, as if I had not desactivate any branches at all. TTree::Draw on event_pa.fPABlocks.fBlockNb works, so somehow it does differently than TTree::GetEntry.

Any clues?

And since you said this problem was fixed, do you have an idea where it comes from?

Thanks!

[quote]root [7] tree->SetBranchStatus(“event_pa.fPABlocks.fEnergy”,0);
root [8] Int_t nev=tree->GetEntry();
Error in TTree::SetBranchStatus: unknown branch -> event_pa.fPABlocks.fEnergy [/quote]
The order of the error message compare to your command is interesting. It sounds like tree point to a TChain object and that the branch may not be present in some the files. If this is not the case, I can not reproduce the problem (at least not with a recent version of ROOT).

TTree::Draw does not use TTree::SetBranchStatus nor TTree::GetEntry, instead it call GetEntry on the branches that it needs.

[quote]And since you said this problem was fixed, do you have an idea where it comes from?[/quote]They have been several issues related to attempting to split TClonesArray within TClonesArray. What you see might or might not (:() be related. If you try with ROOT 4.03/02 and
can still reproduce the problem, please send me the example.

Cheers,
Philippe.

Can we call GetEntry only on a certain branch of a TChain, not a TTree? If yes, how? I don’t get the usual method with GetBranch and SetAddress which works with TTree, to work with a TChain.

[quote]Can we call GetEntry only on a certain branch of a TChain, not a TTree? [/quote]Yes you can be it is requires a little infrastructure. For a working example see the result of MakeSelector or MakeClass. The b_xyz
are maintain such that you can call GetEntry on them.

Cheers,
Philippe.