I have a TTree “waveformGraphTree” with a branches “cohGraphs[2]” and “deconvGraphs[2]” made with the lines
TGraph cohGraphs[2], deconvGraphs[2];
waveformGraphTree.Branch("cohGraphs[2]", "TGraph", & cohGraphs);
waveformGraphTree.Branch("deconvGraphs[2]", "TGraph", & deconvGraphs);
Later on, I would like to reference the TGraphs from these branches in another function with pointer to the TTree as input, and so I try
TGraph cohGraphs[2], deconvGraphs[2];
waveformGraphTree -> SetBranchAddress("cohGraphs[2]", & cohGraphs);
waveformGraphTree -> SetBranchAddress("deconvGraphs[2]", & deconvGraphs);
However, I then receive the following output:
Error in <TTree::SetBranchAddress>: Unable to determine the type given for the address for "cohGraphs[2]". This is probably due to a missing dictionary, the original data class for this branch is TGraph.
Error in <TTree::SetBranchAddress>: Unable to determine the type given for the address for "deconvGraphs[2]". This is probably due to a missing dictionary, the original data class for this branch is TGraph.
TTree::SetBranchAddress() is overloaded, am I supposed to have another input variable? I have also tried #include "TGraph.h" beforehand.
_ROOT Version:6.12/06
Platform: linuxx8664
Compiler: gcc
What do you get from waveformGraphTree->Print();
TGraph cohGraphs[2], deconvGraphs[2];
waveformGraphTree.Branch("cohGraphs[2]", "TGraph", & cohGraphs);
This will save only one of the 2 TGraph object. Use
std::vector<TGraph> cohGraphs, deconvGraphs;
waveformGraphTree.Branch("cohGraphs[2]", "TGraph", & cohGraphs);
SetBranchAddress expects the address of a pointer or the address a single object.
Hi Philippe,
Thanks for the informative response. I tried taking it a step further and tried
vector<TGraph> cohGraphs(2), deconvGraphs(2);
waveformGraphsTree.Branch("cohGraphs[2]", "TGraph", & cohGraphs);
waveformGraphsTree.Branch("deconvGraphs[2]", "TGraph", & deconvGraphs);
When I call cohGraphs, I get reference address inside of the vector, in contrast to when I try cohGraphs[2], where I get an empty vector of size 2.
However, with the above lines I get
Error in <TTree::Branch>: The class requested (TGraph) for "cohGraphs[2]" is different from the type of the object passed (vector<TGraph>)
Warning in <TTree::Bronch>: Using split mode on a class: TGraph with a custom Streamer
Error in <TTree::Branch>: The class requested (TGraph) for "deconvGraphs[2]" is different from the type of the object passed (vector<TGraph>)
Warning in <TTree::Bronch>: Using split mode on a class: TGraph with a custom Streamer
Even if I know what the size of the vectors should be beforehand, should I not assign sizes beforehand and a vector’s “push_back()” to add in the graphs later?
Hi!
Thank you for the response. I tried implementing Philippes’ suggestion below, so that will likely change what waveformGraphTree->Print(); returns. What it now returns is
******************************************************************************
*Tree :waveformGraphTree: TTree containing TGraphs of initial waveforms. *
*Entries : 189 : Total = 19026755 bytes File Size = 19019994 *
* : : Tree compression factor = 1.00 *
******************************************************************************
*Br 0 :run : run/I *
*Entries : 189 : Total Size= 1316 bytes File Size = 839 *
*Baskets : 1 : Basket Size= 32000 bytes Compression= 1.00 *
*............................................................................*
*Br 1 :eventNumber : eventNumber/i *
*Entries : 189 : Total Size= 1356 bytes File Size = 847 *
*Baskets : 1 : Basket Size= 32000 bytes Compression= 1.00 *
*............................................................................*
*Br 2 :cohGraphs[2] : vector<TGraph> *
*Entries : 189 : Total Size= 9513996 bytes File Size = 9509882 *
*Baskets : 189 : Basket Size= 32000 bytes Compression= 1.00 *
*............................................................................*
*Br 3 :deconvGraphs[2] : vector<TGraph> *
*Entries : 189 : Total Size= 9509503 bytes File Size = 9505377 *
*Baskets : 189 : Basket Size= 32000 bytes Compression= 1.00 *
*............................................................................*
Even if I know what the size of the vectors should be beforehand, should I not assign sizes beforehand and a vector’s “push_back()” to add in the graphs later?
Both will work.
Error in TTree::Branch: The class requested (TGraph) for “cohGraphs[2]” is different from the type of the object passed (vector)
The message is correct. You can just skip specifying the type.
waveformGraphsTree.Branch("cohGraphs[2]", & cohGraphs);
Cheers,
Philippe.
Thanks for the help, Philippe.
I looked into your comment
SetBranchAddress expects the address of a pointer or the address a single object.
and found a response you provided earlier
Vector in Branch - #5 by pcanal
So returning to the initial question, what I have tried now that the TGraphs are being properly stored is
vector<TGraph> * cohGraphs, * deconvGraphs;
waveformGraphTree -> SetBranchAddress("cohGraphs[2]", cohGraphs);
waveformGraphTree -> SetBranchAddress("deconvGraphs[2]", deconvGraphs);
Using TTree::SetBranchAddress() as above doesn’t throw any errors at this point, but now a function which I call later which referenced & cohGraphs[0] when I had
vector<TGraph> cohGraphs(2);
Now returns
error: cannot initialize a parameter of type 'const TGraph *' with an rvalue of type
'vector<TGraph> *'
Things appear to work if I do
vector<TGraph> * cohGraphs[2], * deconvGraphs[2];
and then provide the function with the argument cohGraphs[0] -> data(), but is that the correct thing to do? What if instead I did
vector<TGraph> * cohGraphs, * deconvGraphs;
and then passed as argument cohGraphs[0].data()? Both of these seem to work, but are they effectively doing the same thing?
Best,
John