Get size of TObject or TH1

Is there a way to the the size of any object inheriting from a TObject? I have a program that uses PROOF and TSelectors to allow users to create histograms and trees from an input tree. If these histograms or trees get larger than 1 GB they can’t be sent from the workers back to the server and cause the workers to crash. I would like to generate a warning if that happens and to remove the object from the output list of the TSelector.

For a tree I can get it’s size using

TBufferFile b(TBuffer::kWrite, 10000);
 TTree::Class()->WriteBuffer(b, obj); 

and then b.Length() gives me the size of the tree in bytes. Does something similar exist for all TObjects or at least for all histograms? I tried using the same code as above (with TTree::Class() replaced by obj->Class()), but that does not work for histograms, as I get a size of 522 bytes for a TH2F with 10000x10000 bins.

I guess I can always resort to trying to get the total number of bins of the histogram and multiplying that by the size of the underlying storage type to get an approximation of the size, but I was wondering if a simpler method exists for this?

Hi,
What you have written it works for histograms, you should use TH2F::Class and not one of the base class.

Lorenzo

Okay, I figured out what I was doing wrong (after knowing that it should work). I tried using a general loop where I use obj->Class()->WriteBuffer(b, obj);, but in the case of the loop obj->Class() evaluated to TObject::Class(), so I had to use TClass::GetClass(obj->ClassName())->WriteBuffer(b, obj); instead. With that this code:

for(const auto&& obj : *fOutput) {
   TBufferFile b(TBuffer::kWrite, 10000);
   TClass::GetClass(obj->ClassName())->WriteBuffer(b, obj);
   if(b.Length() > SIZE_LIMIT) {
      std::cout<<DRED<<obj->ClassName()<<" '"<<obj->GetName()<<"' too large to send to server or write: "<<b.Length()<<" bytes = "<<b.Length()/1024./1024./1024.<<" GB, removing it!"<<RESET_COLOR<<std::endl;
      fOutput->Remove(obj);
   } else {
      std::cout<<GREEN<<obj->ClassName()<<" '"<<obj->GetName()<<"' okay to use: "<<b.Length()<<" bytes = "<<b.Length()/1024./1024./1024.<<" GB"<<RESET_COLOR<<std::endl;
   }
}

gives results like

TH2F 'test' okay to use: 400160586 bytes = 0.372679 GB

for a 10000x10000 bin histogram, and

TH2F 'test' too large to send to server or write: 1600320586 bytes = 1.49041 GB, removing it!

for a 20000x20000 bin histogram.

For now I simply hard-coded SIZE_LIMIT to be 1 GB, is this size already defined somewhere in ROOT?

Note if the object inherits from TObject you can replace

TClass::GetClass(obj->ClassName())->WriteBuffer(b, obj);

with

obj->IsA()->WriteBuffer(b, obj);

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.