The leaflist technique to add branch does NOT support array of struct (but it support struct of arrays).[code]
TTree* testTree = new Tree(“something”,“TestTree”);
struct {
int test2[20][30]
double test3[20][30]
} test1;
I strongly suggest that you move to using the object based technique to add branch:[code]// Script.C
class test1 {
public:
test1() : test2(0), test3(0) []
int test2;
double test3;
};
class Holder {
public:
test1 values[20][30];
};
TTree createTree() {
TTree testTree = new Tree(“something”,“TestTree”);
Holder holder;
testTree->Branch(“event.”,&holder);
testTree->Fill();
testTree->ResetBranchAddresses();
return testTree;
}[/code]and use with ACLiCroot [] .L Script.C+
Thank’s so far.
If I am using an external compiler (gcc) I will have to generate a dictionary with rootcint to make the object based technique work, I guess. Am I right?
[quote]Please say yes.[/quote]Well actually the answer is no (in particular because the 2 declared sizes do not match) but the first code example I gave does not require a dictionary (so I do not see why you would need to use or prefer the code in your last question).
The thing is that I have a lot of structs with also a lot of internal arrays and I wonder now if I have to read in and write out all of these internal arrays seperately, because I am exchanging data between my classes with Trees.
I cant do this either?
[code]TTree* testTree = new Tree(“something”,“TestTree”);
struct {
int test2[20][30]
double test3[20][30]
} test1;
testTree->Branch(“test2”,&test1, “test2[20][30]/I:test3[20][30]/D”);
testTree->Fill();[/code]
And I guess it is also not possible to read the data out of the Tree, which is generated in your first code example, like this:
[code]struct {
int test2[20][30]
double test3[20][30]
} test4;
[quote]The thing is that I have a lot of structs with also a lot of internal arrays[/quote]Then it would be simplier and less error-prone to simply create dictionaries for those structs. This is as simple as writing a linkdef.h file://struct_linkdef.h
#ifdef __MAKECINT__
#pragma link C++ class test1+;
#pragma link C++ class test2+;
etc.
#endifand adding to your Makefile something like:[code]MyDict.cxx: $(HEADERS) struct_linkdef.h
[TAB] rootcint -f $@ -c $(CXXFLAGS) -p $^
PS. [quote]And I guess it is also not possible to read the data out of the Tree, which is generated in your first code example, like this:[/quote]that’s right you can not.
[quote]I cant do this either? … “test2[20][30]/I:test3[20][30]/D”[/quote]It will probably work but I do not recommend it.
Thank you very much. Some question remain not crystal clear. I am sorry to bug you even more but I am kind of brain dead today.
So I only have to create the header file and add it to my make file?
Do I also have to create a mydict.cxx file and add it to the make file?
Where should the linkdef.h be included?
Could you please give me again one code example on how I will use the Trees afterwards?
Did I understand it right that when this dictionary is created that I can use the struct as a single object but it is still not possible to add an array of this object to a Tree?
[quote]So I only have to create the header file and add it to my make file?[/quote]Yes.
[quote]Do I also have to create a mydict.cxx file and add it to the make file?[/quote]Yes for example using a variation of the Makefile code snippet I provided.
[quote]Where should the linkdef.h be included?[/quote]It should only be used as an argument to the rootcint command.
[quote]Could you please give me again one code example on how I will use the Trees afterwards?
[/quote]
[quote]Did I understand it right that when this dictionary is created that I can use the struct as a single object but it is still not possible to add an array of this object to a Tree?[/quote]Correct. But you can add a collection of those objects (either a TClonesArray if you inherit from TObject or std::vector if you generate the dictionary for the vector class).
Hmmm. Regretfully some problems again. When I try to generate the dictionary I get those errors.
$ rootcint -f Dict.cpp -c TDummy1.h TDummy2.h linkDef.h
Error: link requested for unknown class teststruct1 linkDef.h:3:
Error: link requested for unknown class teststruct2 linkDef.h:4:
Error: link requested for unknown class linkDef G__auto4142LinkDef.h:9:
Warning: Error occurred during reading source files
Warning: Error occurred during dictionary source generation
!!!Removing Dict.cpp Dict.h !!!
Error: rootcint: error loading headers...
The TDummy1.h file looks like this:
[code]#ifndef TDUMMY1_H #define TDUMMY1_H
#include #include
#include <TTree.h>
class TDummy1
{
public:
typedef struct {
int testint1;
int testintarray1D1[40];
int testintarray2D1[40][40];
} teststruct1;
#endif // TDUMMY1_H[/code]
The TDummy2.h the same but instead of teststruct1 it is teststruct2.
The linkDef.h:
//linkDef.h
#ifdef __MAKECINT__
#pragma link C++ class teststruct1+;
#pragma link C++ class teststruct2+;
#pragma link C++ class vector<teststruct1>+;
#pragma link C++ class vector<vector<teststruct1> >+;
#pragma link C++ class vector<teststruct2>+;
#pragma link C++ class vector<vector<teststruct2> >+;
#endif
[quote]Error: link requested for unknown class teststruct1 linkDef.h:3:[/quote]Is an accurate error isn’t it? Didn’t you mean to talk about ‘TDummy1::teststruct1’ ?
Thank you. Slowly it is getting more and more clear. But I get a different error now.
My linkDef.h no reads like this,
//linkDef.h
#ifdef __MAKECINT__
#pragma link C++ class TDummy1::teststruct1+;
#pragma link C++ class TDummy2::teststruct2+;
#pragma link C++ class vector<TDummy1::teststruct1>+;
#pragma link C++ class vector<vector<TDummy1::teststruct1> >+;
#pragma link C++ class vector<TDummy2::teststruct2>+;
#pragma link C++ class vector<vector<TDummy2::teststruct2> >+;
#endif
and I get …
$ rootcint -f Dict.cpp -c TDummy1.h TDummy2.h linkDef.h
Error: link requested for unknown class linkDef G__auto4172LinkDef.h:9:
Warning: Error occurred during reading source files
Warning: Error occurred during dictionary source generation
!!!Removing Dict.cpp Dict.h !!!
Error: rootcint: error loading headers...
Never mind. In this case I found the answer myself. It is a wonder .
One has to name the definition header file LinkDef.h. It is case sensitive.
But if I try to compile the whole thing (added Dict.cpp to my make file). I get a bunch of errors.
$ make
[ 25%] Building CXX object CMakeFiles/dictionary_test.dir/Dict.cpp.o
/home/adonai/projects/dictionary_test/Dict.cpp: In function ‘ROOT::TGenericClassInfo* ROOT::GenerateInitInstanceLocal(const TDummy1::teststruct1*)’:
/home/adonai/projects/dictionary_test/Dict.cpp:52: error: ‘ROOT::Shadow::TDummy1’ has not been declared
/home/adonai/projects/dictionary_test/Dict.cpp: In function ‘ROOT::TGenericClassInfo* ROOT::GenerateInitInstanceLocal(const TDummy2::teststruct2*)’:
/home/adonai/projects/dictionary_test/Dict.cpp:94: error: ‘ROOT::Shadow::TDummy2’ has not been declared
/home/adonai/projects/dictionary_test/Dict.cpp: In function ‘void ROOT::TDummy1cLcLteststruct1_ShowMembers(void*, TMemberInspector&)’:
/home/adonai/projects/dictionary_test/Dict.cpp:128: error: ‘ROOT::Shadow::TDummy1’ has not been declared
/home/adonai/projects/dictionary_test/Dict.cpp:128: error: expected initializer before ‘ShadowClass’
/home/adonai/projects/dictionary_test/Dict.cpp:129: error: ‘ShadowClass’ was not declared in this scope
/home/adonai/projects/dictionary_test/Dict.cpp:129: error: ‘sobj’ was not declared in this scope
/home/adonai/projects/dictionary_test/Dict.cpp:129: error: expected primary-expression before ‘)’ token
/home/adonai/projects/dictionary_test/Dict.cpp:129: error: expected ‘;’ before ‘obj’
/home/adonai/projects/dictionary_test/Dict.cpp: In function ‘void ROOT::TDummy2cLcLteststruct2_ShowMembers(void*, TMemberInspector&)’:
/home/adonai/projects/dictionary_test/Dict.cpp:167: error: ‘ROOT::Shadow::TDummy2’ has not been declared
/home/adonai/projects/dictionary_test/Dict.cpp:167: error: expected initializer before ‘ShadowClass’
/home/adonai/projects/dictionary_test/Dict.cpp:168: error: ‘ShadowClass’ was not declared in this scope
/home/adonai/projects/dictionary_test/Dict.cpp:168: error: ‘sobj’ was not declared in this scope
/home/adonai/projects/dictionary_test/Dict.cpp:168: error: expected primary-expression before ‘)’ token
/home/adonai/projects/dictionary_test/Dict.cpp:168: error: expected ‘;’ before ‘obj’
make[2]: *** [CMakeFiles/dictionary_test.dir/Dict.cpp.o] Fehler 1
make[1]: *** [CMakeFiles/dictionary_test.dir/all] Fehler 2
make: *** [all] Fehler 2
You need to either add#pragma link C++ class TDummy1+; to the linkdef file or add ClassDef(teststruct1,2); inside the declaration of the class teststruct1.
Thank you very much again. Just a moment before you posted, I was to post that it compiled now. I modified my LinkDef.h file:
//linkDef.h
#ifdef __MAKECINT__
#pragma link C++ class TDummy1+;
#pragma link C++ class TDummy2+;
#pragma link C++ class TDummy1::teststruct1+;
#pragma link C++ class TDummy2::teststruct2+;
#pragma link C++ class vector<teststruct1>+;
#pragma link C++ class vector<vector<teststruct1> >+;
#pragma link C++ class vector<teststruct2>+;
#pragma link C++ class vector<vector<teststruct2> >+;
#endif
and also the TDummy classes (added ClassDef and ClassImp) EDIT: as well as #include "RTypes.h"
TDummy1.h:
[code]#ifndef TDUMMY1_H #define TDUMMY1_H
#include #include
#include “Rtypes.h” #include “TTree.h”
class TDummy1
{
public:
typedef struct teststruct1 {
int testint1;
int testintarray1D1[40];
int testintarray2D1[40][40];
} teststruct1;
[quote]Does this look correct?[/quote]Not quite yet.
I think you need to use:#pragma link C++ class vector<TDummy1::teststruct1>+;
#pragma link C++ class vector<vector<TDummy1::teststruct1> >+;
#pragma link C++ class vector<TDummy2::teststruct2>+;
#pragma link C++ class vector<vector<TDummy2::teststruct2> >+;