Double_32 support without need for dictionary generation?

Dear ROOT experts,

I find the functionality offered by Double32_t imperative
for high performance IO on ROOT files and disk storage considerations.

However, these features (as I understand from https://root.cern.ch/root/html/tutorials/io/double32.C.html) can be used only if Double32_t is a member of a user defined class
and that implies the need of dictionary generation e.g., using genreflex.

I was wondering if there is any trick to use a Double32_t as a pseudo
basic data type over a “flat” tree, without need of a dictionary.

e.g.,

Double32_t var; //[0, 4096, 13]
myTree->Branch("var", &var, "var/D32");

The code above doesn’t work, because there is no leaflist of D32
since Double32_t is not a supported data type as Float_t or
Double_t are, but I just give it as an example of what I would
like/wish to have.

Is there any trick to do this work without defining class and generating
dictionary ? If not, is there any chance to get this feature supported
by next version of ROOT ?

thanks
-Kostas

Hi Kostas,

Indeed this is not directly supported. The following might work though (especially in v6):

gROOT->ProcessLine("struct D32Holder { Double32_t var; //[0, 4096, 13] };"); myTree->Branch("var", TClass::GetClass("D32Holder"), &var);

Cheers,
Philippe.

Dear Philippe,

Thank you very much for your prompt reply.

I tried it, but didn’t succeed, I believe I am missing something obvious due
to my lack of experience with this dataformat.

Here is my code:

// compile this with: g++ main.C -o main.exec `root-config --glibs --cflags`
#include "TTree.h"
#include "TFile.h"
#include "TROOT.h"

TTree *myTree;
TFile *fp;

Double32_t var; //[0, 4096, 13]

int main()
{
  fp = new TFile("output.root","RECREATE");
  myTree = new TTree("myTree","myTree");

  gROOT->ProcessLine("struct D32Holder { Double32_t var; //[0, 4096, 13] };");
  myTree->Branch("var", TClass::GetClass("D32Holder"), &var);  // doesn't work

  var = 3.14159265359; // random value
  myTree->Fill();

  fp->Write();
  return 0; 
}

I tried it on CINT, on ACliC but also tried to compile this with g++, none of it
gave me what I was hoping. I used ROOT 6.02/05 built for macosx64 but for
my project I will need eventually a solution that compiles with g++ and can
go inside CMSSW. I am not completely sure where the “var” should be declared
and if the declaration in gROOT->ProcessLine(…) would be sufficient for the
compiler or if a global scope “Double32_t var; //[0, 4096, 13]” should be also
given.

The error message:

pb-d-128-141-140-92:data32 theofil$ g++ main.C -o main.exec `root-config --glibs --cflags`
main.C:17:11: error: no matching member function for call to 'Branch'
  myTree->Branch("var", TClass::GetClass("D32Holder"), &var);  // doesn't work
  ~~~~~~~~^~~~~~
/Users/theofil/root/include/TTree.h:333:32: note: candidate function [with T = TClass] not viable: no known conversion from 'Double32_t *' (aka 'double *') to 'Int_t' (aka 'int')
      for 3rd argument; remove &
   template <class T> TBranch *Branch(const char* name, T* obj, Int_t bufsize = 32000, Int_t splitlevel = 99)
                               ^
/Users/theofil/root/include/TTree.h:299:28: note: candidate function not viable: no known conversion from 'Double32_t *' (aka 'double *') to 'const char *' for 3rd argument
   virtual TBranch        *Branch(const char* name, void* address, const char* leaflist, Int_t bufsize = 32000);
                           ^
/Users/theofil/root/include/TTree.h:318:32: note: candidate function [with T = double] not viable: no known conversion from 'TClass *' to 'const char *' for 2nd argument
   template <class T> TBranch *Branch(const char* name, const char* classname, T* obj, Int_t bufsize = 32000, Int_t splitlevel = 99)
                               ^
/Users/theofil/root/include/TTree.h:316:28: note: candidate function not viable: no known conversion from 'TClass *' to 'const char *' for 2nd argument
   virtual TBranch        *Branch(const char* name, const char* classname, void* addobj, Int_t bufsize = 32000, Int_t splitlevel = 99);
                           ^
/Users/theofil/root/include/TTree.h:298:28: note: candidate function not viable: no known conversion from 'TClass *' to 'Int_t' (aka 'int') for 2nd argument
   virtual Int_t           Branch(const char* folder, Int_t bufsize = 32000, Int_t splitlevel = 99);
                           ^
/Users/theofil/root/include/TTree.h:300:28: note: candidate function not viable: no known conversion from 'TClass *' to 'char *' for 2nd argument
           TBranch        *Branch(const char* name, char* address, const char* leaflist, Int_t bufsize = 32000)
                           ^
/Users/theofil/root/include/TTree.h:305:20: note: candidate function not viable: no known conversion from 'TClass *' to 'Long_t' (aka 'long') for 2nd argument
   TBranch        *Branch(const char* name, Long_t address, const char* leaflist, Int_t bufsize = 32000)
                   ^
/Users/theofil/root/include/TTree.h:310:20: note: candidate function not viable: no known conversion from 'TClass *' to 'int' for 2nd argument
   TBranch        *Branch(const char* name, int address, const char* leaflist, Int_t bufsize = 32000)
                   ^
/Users/theofil/root/include/TTree.h:296:28: note: candidate function not viable: no known conversion from 'const char [4]' to 'TCollection *' for 1st argument
   virtual Int_t           Branch(TCollection* list, Int_t bufsize = 32000, Int_t splitlevel = 99, const char* name = "");
                           ^
/Users/theofil/root/include/TTree.h:297:28: note: candidate function not viable: no known conversion from 'const char [4]' to 'TList *' for 1st argument
   virtual Int_t           Branch(TList* list, Int_t bufsize = 32000, Int_t splitlevel = 99);
                           ^
/Users/theofil/root/include/TTree.h:323:32: note: candidate template ignored: could not match 'type-parameter-0-0 *' against 'double'
   template <class T> TBranch *Branch(const char* name, const char* classname, T** addobj, Int_t bufsize = 32000, Int_t splitlevel = 99)
                               ^
/Users/theofil/root/include/TTree.h:328:32: note: candidate template ignored: could not match 'type-parameter-0-0 *' against 'TClass'
   template <class T> TBranch *Branch(const char* name, T** addobj, Int_t bufsize = 32000, Int_t splitlevel = 99)
                               ^
1 error generated.

thanks for any tip,
-Kostas

Hi Kosta,

Indeed, I meant to typemyTree->Branch("var", "D32Holder", (void*)&var);

Cheers,
Philippe.

Dear Philippe,

I successfully compiled the code below:

#include "TTree.h"
#include "TFile.h"
#include "TROOT.h"

TTree *myTree;
TFile *fp;

Double32_t var; //[0, 4096, 13]

int main()
{
  fp = new TFile("output.root","RECREATE");
  myTree = new TTree("myTree","myTree");

  gROOT->ProcessLine("struct D32Holder { Double32_t var; //[0, 4096, 13] };");
  myTree->Branch("var", "D32Holder", (void*)&var);

  var = 3.14159265359; // random value
  myTree->Fill();

  fp->Write();
  return 0;
}

using g++ main.C -o main.exec root-config --glibs --cflags

but unfortunately I get an error upon executing the compiled file:
Error in TTree::Bronch: Cannot find class:D32Holder

I guess the above error is probably underlining the void of my understanding
regarding the data type of “var” and how to make the TTree recognize
it, any further input will be greatly appreciated.

thanks
-Kostas

Hi,

The following tweaks on your code:[code]#include “TTree.h”
#include “TFile.h”
#include “TROOT.h”
#include “TInterpreter.h”

TTree *myTree;
TFile *fp;

Double32_t var; //[0, 4096, 13]

int bb()
{
fp = new TFile(“output.root”,“RECREATE”);
myTree = new TTree(“myTree”,“myTree”);

gInterpreter->Declare(“struct D32Holder { Double32_t var; //[0, 4096, 13]\n};”);
void p = (void)&var;
myTree->Branch(“var”, “D32Holder”, (void*)&p);

var = 3.14159265359; // random value
myTree->Fill();
//myTree->Scan(“var.var”);

fp->Write();
return 0;
}[/code]works for me (note in particular the addition ‘\n’ in the declaration and the switch to gInterpreter->Declare.

Cheers,
Philippe.

Dear Philippe,

The code you’ve sent to me works.

I am gonna try now to push up this local implementation on where I need to,
I hope I don’t bother you again with this.

thanks a lot for all your help!
-Kostas