the following macro will yield the correct (well, expected) histogram only on the left but not on the right pad:
int branch()
{
UChar_t njt;
Float_t jtpt[10][1];
TTree* tree = new TTree("t","t");
TBranch* b_njt = tree->Branch("njt", &njt,"njt/b");
TBranch* b_jtpt = tree->Branch("jtpt",jtpt,"jtpt[njt][1]/F");
for (unsigned ievt=0;ievt<1000;ievt++) {
njt = gRandom->Integer(9);
for (unsigned ijt=0;ijt<njt;ijt++) {
jtpt[ijt][0] = 50.*gRandom->Exp(1.0);
}
tree->Fill();
}
gStyle->SetOptStat(1111);
TCanvas* c = new TCanvas("c","c",0,500,1000,400);
c->Divide(2,1);
c->cd(1);
tree->Draw("jtpt[][0]");
c->cd(2);
tree->Draw("jtpt");
return 0;
}
Why? Is the ‘draw all’ not supported for two-dimensional branches?
I have browsed the forum for related posts and while I couldn’t find anything, I found a post which claimed that the array counter (njt above) must be Int_t?! Is that true, and also that it doesn’t save space to save it e.g. as an UChar_t? I have done that for a long time and didn’t experience problems.
One more thing (I suspect this is about C++ not ROOT): why can I not pass a two dimensional array (Float_t jtpt[10][1]) to a branch defined as “jtpt[njt]/F”, or in other words what is the difference between a 2D array with one of its dimension 1 and a 1D array?
This is indeed a bug in the ’ tree->Draw(“jtpt”);’ which because of the size [1] is actually plotting only half the elements. If you have a size of 2 or more it works as expected.
[quote]I have browsed the forum for related posts and while I couldn’t find anything, I found a post which claimed that the array counter (njt above) must be Int_t?! Is that true, and also that it doesn’t save space to save it e.g. as an UChar_t? I have done that for a long time and didn’t experience problems. [/quote]This is correct the code assume that the index is an Int_t. However on little endian processors, the correct number is found ; the same code will fail on big endian processors.
why can I not pass a two dimensional array (Float_t jtpt[10][1]) to a branch defined as "jtpt[njt]/F", In my test this works as you would expect.
[quote] or in other words what is the difference between a 2D array with one of its dimension 1 and a 1D array? [/quote]The C++ type is different by the in-memory representation is the same.
thank you for the clarification, the [1] case doesn’t make that much sense anyway. I concluded that there would be a general problem in this respect with two-dimensional arrays, good to know there is not!
You are right, the Float_t jtpt[10][1] works indeed with “jtptp[10]/F” as you say!
However, what doesn’t work is:
Float_t** jtpt = new Float_t*[10];
for (Int_t i=0;i<10;i++) jtpt[i] = new Float_t[1];
which I hoped to be equivalent to Float_t jtpt[10][1], but it is not. What I am trying to do is to dynamically decide wether a branch represents a one- or two-dimensional array, using the Float_t**. Is there any way to resolve this?
[quote]which I hoped to be equivalent to Float_t jtpt[10][1][/quote]Even-though both can be used using the C++ code, their memory layout is very different, and indeed ‘tptp[10]/F’ can not handle the array of pointers to arrays. If you need a flexible construct I recommend that you use a vector<vector > (for which you will need to generate a dictionary).