Simplest Way to Write Numbers in a TFile

Hi, I can’t believe I am having trouble with this seemingly simple task. I want to store a small number of numerical values (like 5-10) directly in a TFile without having to make a TTree and create branches.

Is there any way to use existing ROOT classes that can be TObject::Write’n or with which I can use TFile::Add? Some way that would allow me to retrieve the values using TFile::Get?

Some things I have tried:

  • Tried using TArray, but hilariously this does not inherit from TObject, so you can’t write it to a TFile or put it in a TObjArray.
  • I tried creating a custom class that inherits from both TNamed and TArray, with the ClassDef macro, but I can’t seem to do it right and I get:
Warning in <TClass::TClass>: no dictionary for class MyNamedArrayI is available
Error in <TBufferFile::CheckByteCount>: object of class TNamed read too few bytes: 26 instead of 47
  • Looking into Roo* classes to see if they have something that behaves like an array but is an object, but I couldn’t find anything.
  • Using a TVector, but they are only available in double and float, but at least they inherit from TObject.

While I wait for people to answer this post, I am going to try:

  • store the values in a TVectorD, even the integer ones, and put checks so that the integers don’t get too big.
  • store the values’ string representation in a TObjString and use Atof after getting them out of the TFile.

My ideal solution would be some kind of container class that could contain N values of a specific type and inherit from TNamed so that I can Add it and Get it directly to/from a TFile without messing with dictionaries.

Jean-François

Hi,

Use a TArrayI or similar, or a TParameter.

Cheers, Axel.

Thanks, I didn’t know about TParameter. For now I have already worked around using a TVectorD, and my integers are small enough that casting them to/from double should not be a problem.

I thought TArrayI wouldn’t work because it doesn’t inherit from TObject? That was whole problem that I tried to solve with my “MyNamedArrayI” class that was basically a TNamed stapled to a TArrayI. How would you write/read a regular TArrayI to/from a TFile if it doesn’t have a Write method or a way of naming it?

Jean-François

Hi,

TFile can store also non-TObjects:

root [0] TFile* f = new TFile("arrayi.root","RECREATE");
root [1] TArrayI arr(2);
root [2] arr[0] = 17;
root [3] arr[1] = 42;
root [4] f->WriteObject(&arr, "arr");
root [5] delete f;
root [6] f = new TFile("arrayi.root");
root [7] f->ls()
TFile**		arrayi.root
 TFile*		arrayi.root
  KEY: TArrayI	arr;1	object title

Note that this does not work interactively with ROOT 5 (because it doesn’t know how to deal with the template), only with ROOT 6 or in compiled code. You can use one of the TDirectory:: WriteObjectAny() overloads in interactive ROOT 5.

Cheers, Axel.