I have a .root file (attached), which contains a TTree that contains an object called BTagNtup. After opening the file I get the usual “no dictionary” messages (as expected). But what suprised me what that ROOT dosen’t seem to re-construct the full object graph on its own. So, I get “0” for the following:
C:\Users\gwatts\Documents\ATLAS\Projects\LINQToROOT>root -l output.root
Attaching file output.root as _file0...
Warning in <TClass::TClass>: no dictionary for class BTagJet is available
Warning in <TClass::TClass>: no dictionary for class MuonInBJet is available
root  c = TClass::GetClass("BTagJet")
root  b = c->GetListOfBases()
The actual object does not have no base classes:
[code]class BTagJet : public TLorentzVector
Further (and perhaps worse) I can’t plot any jets in this guy b/c ROOT doesn’t seem to have saved enough info in its dictoinary.
The file was written with a production version of 5.26 (not sure exactly which one), and is being read with a version of 5.27 from about the beginning of November from svn head (I think - could be a little earlier than that!!).
Is this behavior expected?
output.root (899 KB)
I just noticed that TBrowser knows that this BTagJet inherrits from TLorentzVector (i.e. Gamma and other things show up in there). So that information must be around somewhere (though I I double click on Gamma in the TBrowser I get the usual “root  Error in TTreeFormula::DefinedVariable: Can not call method Gamma().)
on class without dictionary (BTagJet)!”).
Everything that comes back in TClass is bogus - for example, the list of data members! So this TClass that root creates really is quite minimal!
I’ve done some quick testing in 5.28 - it would seem all the same behavior exists in that version to.
we’re listening, just not answering yet (Philippe is on vacation) Stay tuned, please…
No worries! Thanks for listening.
we don’t create a properly filled TClass object for classes emulated from the TStreamerInfo. I.e. this is expected, but not as optimal as it could be
For now you’ll have to ask the TStreamerInfo, just like the TVirtualBranchBrowsable-derived classes do, to query the reflection data of objects / collections of objects without dictionary that are stored in a TTree. You can use TClass::IsLoaded() to check whether the TClass is complete or whether you need to talk to the TStreamerInfo.
Ahhh, the IsLoaded will be very useful.
Is it also correct that when IsLoaded is false you can’t really read the data correctly even though the streamer info is high enough fidelity?
I’ll put this on the list of things to do.
well, ROOT can read the data for !IsLoaded() - that’s what the emulated class is for. ROOT can even generate a header file containing the class definition (TTree::MakeProject()). I can’t tell whether you can read the data for !IsLoaded() - that depends on your code
Thanks. What I meant was that TTree::Draw can’t read the root-tuple w/out the classes loaded. I had thought that the new streamer definition meant the data was fully described. So while I understand why ROOT Might not be able to fully interpret the bits in the unknown classes, I was a bit surpised that it couldn’t read correctly the ones it knows (i.e. a class derived from a TLorentzVector).
seriously - it depends on how you read it. You can draw e.g. btag’s jets.fP.fX - i.e. by definition ROOT can read the data. What you are reporting is that the base class part of an emulated class is inaccessible through TTree::Draw(). I can reproduce that, and we should fix it. E.g. btag->Draw(“jets.fP.Mag2()”) does work, so it’s really only the base class.
I will suggest that to Philippe when he’s back.