Usage of TChainIndex

Dear experts,

in my analysis framework (using ROOT 5.34/25) I have created an object (selfmade class, let’s call it MyObject) that I’d like to store in additional files somewhere. The plan is to read in these files, check if MyObject corresponding to the current event is already stored in a TTree in this file, and use this object. If MyObject is not available yet, it is created and stored in a new file containing a TTree with the same name. Thus, each time I run my code, I get a new file, which I store and then add to the TChain the next time I run my code.

In this approach it is quite natural that the entries within each individual TTree are perfectly sorted, but the range of the TTrees might overlap (e.g. because one job crashed during production, or one individual event is added at a later point, etc.). Thus, I am not able to use TChainIndex to build an index and retrieve the appropriate MyObject.

I have attached the corresponding class. The problematic part is in MyObjectStorage::LoadTree(), where the call to BuildIndex(…) returns a positive value (indicating everything is fine), but the code produces Error messages:

Error in TChainIndex::TChainIndex: The indices in files of this chain aren’t sorted.
Error in TTreePlayer::BuildIndex: Creating a TChainIndex unsuccessfull - switching to TTreeIndex

Am I right to assume that the returned values are not to be trusted, because they are obtained using the index values in the individual TTree? Or can I just ignore these errors and go on? (The code does compile and run, but I’m not sure if it is returning the correct values.)
Is there a way of creating a TChainIndex which is not embedded in the TChain, but a standalone object? This might solve my problem, but I did not succeed in doing so.
Please also let me know if you have any other ideas.

Thanks a lot in advance!
Cheers,
Bastian
myObjectStorage.h (1.11 KB)
myObjectStorage.cxx (6 KB)

[quote]Or can I just ignore these errors and go on? [/quote]You probably should not ignore the error as they indicates that the index has to be recreated the first time you use the chain in a process (i.e. performance slow-down) … but the result should be correct.

You can indeed save the TTreeIndex (retrieved by calling GetTreeIndex on the chain after the message or after building it explicitly) individual and attach it to a TChani (SetTreeIndex).

Cheers,
Philippe.

Hi Philippe,

thanks for your help.
I am not sure I understand. I don’t care too much about performance issues: If recreating the index takes a few seconds, that’s fine. That’s what I meant with “ignore the errors”. If it is just a performance issues, would it be more correct to give a Warning rather than an Error?
Is there a way to tell ROOT to not even try the stored Index, and produce a new one right away?

Cheers,
Bastian

Hi Bastian,

[quote]Is there a way to tell ROOT to not even try the stored Index, and produce a new one right away?[/quote]Yes, call BuildIndex on the TChain at the beginning.

[quote] If it is just a performance issues, would it be more correct to give a Warning rather than an Error?[/quote]In some cases (chains with many very large files for example) this is not a minor performance issues.

Cheers,
Philippe.

Hi Philippe,

calling it at the beginning is what I do:

 TChain *intree_;
intree_ = new TChain("my chain", "my chain");
intree_->Add("file1.root");
intree_->Add("file2.root");
intree_->SetBranchAddress("RunNumber", &RunNumber_, &b_RunNumber_);
intree_->SetBranchAddress("LumiNumber", &LumiNumber_, &b_LumiNumber_);
intree_->SetBranchAddress("EventNumber", &EventNumber_, &b_EventNumber_);
intree_->SetBranchAddress("object", &myObject_, &b_object_);
intree_->BuildIndex("(RunNumber<<13) + LumiNumber", "EventNumber");

I don’t see how I could call it earlier. It still gives the two error messages. Is there anything else I could do?

Cheers,
Bastian

Hi Bastian,

UseTTreeIndex *index = new TTreeIndex(intree_,"(RunNumber<<13) + LumiNumber", "EventNumber"); intree_->SetTreeIndex(index);

Cheers,
Philippe.

Hi Philippe,

this works well. Thanks a lot!

Cheers,
Bastian