Creating a class and reading to a Ttree

I don’t know what “_Attributes” and “_Dimensions” are.
Maybe you should say:

#pragma link C++ class _Attributes+;
#pragma link C++ class _Dimensions+;
#pragma link C++ class std::vector<_Attributes>+;
#pragma link C++ class std::vector<_Dimensions>+;

or:

#pragma link C++ typedef _Attributes;
#pragma link C++ typedef _Dimensions;
#pragma link C++ class std::vector<_Attributes>+;
#pragma link C++ class std::vector<_Dimensions>+;

or:

#pragma link C++ enum _Attributes;
#pragma link C++ enum _Dimensions;
#pragma link C++ class std::vector<_Attributes>+;
#pragma link C++ class std::vector<_Dimensions>+;

[quote]I used a similar procedure to make a vector of the _Attributes. I get it to compile but ROOT gives a warning that it is unknown.[/quote]What error message do you actually get?

Philippe.

I eventually discovered that I had written t2.Branch(“dims”. &dims) mistyping a . instead of a ,. Using typedef in the LinkDef.h I was able to put dims and atts into the TTree. But it was the same problem as when trying to put ncData into a Ttree: ROOT did not know the size of the arrays so it didn’t work.

I have read that ROOT understands std::map, and have now decided that what I need to do is to put the dim information into maps, comprized of int (equal to the dim number) and int (dim length) or std::string (dim name). Does ROOT understand multimap? If so, I can then easily get the information from a dim based on dimid. A similar thing should be possible for attributes.

I have put the data of three variables into a TTree that can be seen using TBrowser using std::vector and two are . I fill them from ncData using varname.push_back(data->variable[16]->double_data) and a for loop of the variable length. ROOT understands the length of those “arrays”. Does ROOT understand a struct/class containing vectors? That is, if I create a second struct/class of dim2, att2, var2 and fill them from ncData? Something like
class dim2 : public TObject
{
int dimid;
std::string dimname;
int dimlength
};
and fill that from ncData and then create std::vector newdim; putting it into a Ttree with
t2.Branch(“newdim”, &newdim)?

Can a branch be writting using a C++ variable name?
std::string newname;
newname data->variables->varname;
t2.Branch(newname, &newname)
so that I can for loop over the variables?

Thank you for your help. I think I can finally get this accomplished.

Hi,

[quote]Can a branch be writting using a C++ variable name?[/quote]No, if I correctly understood your idea.

[quote]so that I can for loop over the variables?[/quote]Well, you could do that my looking at the content of the TClass object that describe your class … but why do it yourself when it is done automatically for you?

[quote]I have read that ROOT understands std::map[/quote]Yes, it does.

[quote]Does ROOT understand multimap?[/quote]Yes, it does.

[quote]I have read that ROOT understands std::map, and have now decided that what I need to do is to put the dim information into maps,[/quote]Why? Will the list of dimensions and their name change from run to run?

[quote]But it was the same problem as when trying to put ncData into a Ttree: ROOT did not know the size of the arrays so it didn’t work.[/quote]I am confused, I thought you had decided to go with vectors, why do you still have arrays?

[quote]Does ROOT understand a struct/class containing vectors? [/quote]Of course! You just need to generate the dictionary for this class.

Cheers,
Philippe.

PS. You may want to re-read the User’s Chapter on TTree in particular the part on objects.

Hi.

I have the same problem as was posted in this topic above. I create a dictionary of some class. It has lines like:

class MyClass {
  void* fData;
};

The dictionary was generated, but when I run I get this:

Error in <TStreamerInfo::Build>: MyClass, discarding: void* fData, no [dimension]

As far as I understood I should specify the size of this variable like

  void* fData; //[fSize]

but this is not an array. If this is an error, how can I fix this?

Thanks,
Alex.

See the discussion on “Streamers” and “Pointers and References in Persistency” in the “Input/Output” chapter of the ROOT User’s Guide:
http://root.cern.ch/download/doc/11InputOutput.pdf
In particular, see the “Transient Data Members”, “Variable Length Array” and “Streaming C++ Pointers” paragraphs therein.
Note, you must initialize all your “Transient Data Members” in the default constructor of your class (they will NOT be saved when your “object” is written to a ROOT file and so, they will NOT be “retrieved” when your “object” is read back hence, they need to be initialized by the default constructor which will automatically be called when retrieving an “object” from a ROOT file).

Hi,

The ROOT I/O can not (know out to) store a void* (no clue what the ‘size’ of the data to be stored would be). If you class need I/O you will need to be more specific in the underlying type or write a custom streamer. If you do not need the I/O then you need to disable the I/O by either setting the class version to zero or adding/using:#pragma link C++ class MyData-;

Cheers,
Philippe.