I wrote up a tree structure that stores objects of a class I defined in an STL vector:
In the LinkDef I added a pragma for
#pragma link C++ class std::vector< StChargedPionJetParticle >;
and I filled the tree after calling
If I try to read this tree without loading the library containing the class definitions for StChargedPionJetParticle (which inherits from TLorentzVector), I get warnings of the form
Error in <TBuffer::CheckByteCount>: object of class TLorentzVector read too many bytes: 60 instead of 50
Warning in <TBuffer::CheckByteCount>: TLorentzVector::Streamer() not in sync with data on file /Users/kocolosk/work/charged-pion-event/chargedPions_6168083.tree.root, fix Streamer()
These warnings occur once for each StChargedPionJetParticle in the tree. My other classes (StChargedPionEvent, StChargedPionTrack, etc.) are also written using ::Class()->IgnoreTObjectStreamer(), but they’re not stored in STL vectors, and they don’t generate any warnings. I can suppress the warnings only by loading the class library AND calling IgnoreTObjectStreamer for StChargedPionJetParticle again.
This isn’t really a problem, as a) I’ll always be loading the class library for real work, and b) the file size only increases by 1-2% if I enable the TObject Streamer. I’m just curious if there’s some hidden interplay between STL vectors and TObject streamers that I should be aware of. Even when the warnings are emitted I’m able to TTree::Draw data members of StChargedPionJetParticle just fine. Regards,
(edit: sorry, meant to post in Discussion, not Support)
I can reproduce the problem in some cases. [… inaccurate observation removed … ].
I get the error message both for vector and for
StChargedPionJetParticle if I stored them directly in a TFile.
I do not see the error if I store them in a tree (in split mode).
So I assume that you are seeing them in your case when the object is not split (and hence streamed the same way it would be when it is stored directly in the TDirectory).
With the current code implementation, in non-split mode, you indeed MUST have the library load in order to properly read the object with
the IgnoreTObjectStreamer bit set.
Thanks for the response. The situation with the splitting is a little … complicated (at least to me). The class I’m storing in the tree is an StChargedPionEvent which has a TClonesArray* of StChargedPionJet* objects. Each jet has a vector of StChargedPionJetParticle objects.
I had initially written the StChargedPionJet to store a TClonesArray* of StChargedPionJetParticle* objects, but I realized that a nested TClonesArray* inside another TClonesArray* is not split, and its elements can’t be examined in a TBrowser. I tried switching to vector and found that the TBrowser could now examine the elements in the vector and draw them out. I still can’t see the StChargedPionJetParticles using e.g. TTree::Show. I’m not sure exactly what this means w.r.t. to the splitting of the vector.
Incidentally, after some thought I realized that this would be a nice opportunity to try out the LorentzVector class from ROOT::Math and get the benefits of Double32_t. I switched StChargedPionJetParticle’s base class and all seems well at first glance. I save about 15% in compressed tree size (30% in the StChargedPionJet branch) and don’t appear to lose any functionality that I care about. Thanks! Best,
[quote] I’m not sure exactly what this means w.r.t. to the splitting of the vector. [/quote]It does indeed mean that the vector was not split (hence the error message).