Accesing Char Array from a TTree with TTreeReader

Hi Everyone,

One of my branches in my TTree has the following format fDate/C and I’m using TTreeReaderArray<char> fDt(fReader,"fDate"); (i.e I have access to its elements through fDt[n]) I wonder if there is a way to get this char array as a TString without using a loop, as the name suggest it is a date and I need to convert this to a TDatime object but first I have to append “00:00:00” as the info about the hour is not relevant.

Aside question: Is there a way to store a TString/TDatime object in a TTree Branch?

Any help would be appreciated :wink:

Hi,
fDt.GetAddress() and fDt.GetSize() should give you all the information needed to construct a string from the TTreeReaderArray<char> (namely, char * to the beginning of the string and size of the string).
A TString can be constructed with precisely those arguments if I’m not mistaken.

Let me know if you try it out and something breaks.
Cheers,
Enrico

Thank you @eguiraud, I tried:

`fDate = TString(fDt.GetAddress(),fDt.GetSize());`

Without success:

            ^       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/TString.h:257:4: note: candidate constructor not viable: cannot convert argument of incomplete type 'void *' to 'const char *' for 1st argument
   TString(const char *s, Ssiz_t n);    // Copy past any embedded nulls
   ^
/TString.h:260:4: note: candidate constructor not viable: cannot convert argument of incomplete type 'void *' to 'char' for 1st argument
   TString(char c, Ssiz_t s);
   ^

From the error message GetAddress returns a void* that you need to convert to char*:
fDate = TString(static_cast<char*>(fDt.GetAddress()), fDt.GetSize());

It prints out just the first character. For some reason, fDt.GetSize() is returning 1 when it is 10: 2017-01-01

My guess is this is a bug in TTreeReaderArray<char>::GetSize (it stops counting when it sees a 0 character).
I’ll try to reproduce it and confirm it and let you know soon. Pinging @Axel in case he knows right away.

I don’t know what this is. That said, I bet it’s not the 0, but the size gets determined incorrectly. An example file / reproducer would indeed be most helpful.

1 Like

Here is a script and a set of data to reproduce the issue:

int Analyzer() {

  TFile *f = new TFile("Test.root","OPEN");

  TTreeReader fReader("SOXL", f);
  TTreeReaderArray<char> fDt(fReader,"fDate");

  TString fDate;
  
  while(fReader.Next()){

    fDate = TString(static_cast<char*>(fDt.GetAddress()),fDt.GetSize());
    cout << "Size: " << fDt.GetSize() << endl;
 
  }
  return 0;
}

Let me know if it works for you, I’m using ROOT 6.11/01

Test.root (6.3 KB)
Analyzer.C (332 Bytes)

1 Like

Well, fDate/C means “a character string terminated by the 0 character”. So, it should work fine with any of:

fDate = static_cast<char*>(fDt.GetAddress());
fDate = &(fDt.At(0));
fDate = &(fDt[0]);

BTW. fDt.GetSize() should return strlen(&(fDt[0]))+1 (i.e. including the terminating 0 character).

Thanks @Wile_E_Coyote, it works!.

{
  TString st;
  TDatime dt; // not portable
  TTimeStamp ts; // better than TDatime
  TTree *t = new TTree("t", "t");
  t->Branch("st", &st);
  t->Branch("dt", &dt);
  t->Branch("ts", &ts);
  t->Print();
  delete t; // cleanup
}

FYI @amvargash I haven’t forgotten this issue, I simply didn’t get around to debug it yet. I’ll let you know once it’s fixed!

1 Like

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