2D arrays - basic mistake?

Hi,
For the life of me I can’t get a 2D array written to a branch when it has both indicies specified by other items in the tree (“for the life of me” == some number of hours which is too embarassing to admit). I’m using 5.24/04 for this test. Here is the code:

[code]void test3(int nEvents)
{
TFile *f = new TFile("…/test3.root", “RECREATE”);

TTree *t = new TTree ("testTree", "Test of the tree");
Int_t nx = 0, ny = 0;
Double_t info[maxArraySize2D][maxArraySize2D];
for (int ix = 0; ix < maxArraySize2D; ix++) {
	for (int iy = 0; iy < maxArraySize2D; iy++) {
		info[ix][iy] = 0.0;
	}
}

t->Branch("nx", &nx, "nx/I");
t->Branch("ny", &ny, "ny/I");
t->Branch("info", info, "info[nx][ny]/D");

for (int i = 0; i < nEvents; i++) {
	nx = (int) gRandom->Uniform(maxArraySize2D);
	ny = (int) gRandom->Uniform(maxArraySize2D);

	/// Zero it out

	for (int ix = 0; ix < nx; ix++) {
		for (int iy = 0; iy < ny; iy++) {
			info[ix][iy] = 0.0;
		}
	}

	/// Now fill it all in!
	for (int ix = 0; ix < nx; ix++) {
		int nyToFill = (int) gRandom->Uniform(ny);
		for (int iy = 0; iy < nyToFill; iy++) {
			info[ix][iy] = gRandom->Gaus(0.0, 1000.0);
		}
	}

	//std::cout << i << ": nx=" << nx << " ny=" << ny << " info[1][1]=" << info[1][1] << std::endl;

	t->Fill();
}

t->Write();
f->Write();
f->Close();
delete f;

}[/code]
If i just use one index in the Branch specification (i.e. “info[nx][10]/D”) then it works. It doesn’t matter which index - so long as there aren’t two. I’ve looked through the docs and I don’t see mention of this limitation and I see it used in code I’ve played with. Am I doing something dumb above?

[quote]t->Branch(“info”, info, “info[nx][ny]/D”);[/quote]Is not supported :slight_smile:

[quote]and I see it used in code I’ve played with[/quote]Really! Do you have a link to it?

Anyway the best way is:std::vector<std::vector<double> > info; t->Branch("info", &info);where you also need to create the dictionary with:// loader.C #include <vector> #ifdef __MAKECINT__ #pragma link C++ class vector<vector<double> >+; #endifandgROOT->ProcessLine(".L loader.C+");

Cheers,
Philippe.

Thanks!

Now that you say that I have looked at the code more carefully and you are right - only one of the array sizes has variable length. The other one is fixed. I missed exactly how this was working becuase ostringstream was being used to construct the actual name. :frowning:

My bad.

One more question. I’m guessing that declaring a branch “info[40][ny]” is not legal but doing it “info[nx][40]” is - due to memory layout. Is that true on all platforms and compilers? Or is how the memory is layed out varry? :slight_smile: Thanks!

Hi Gordon,

[quote] but doing it “info[nx][40]” is - due to memory layout. I Is that true on all platforms and compilers?[/quote]Yes (the 2 orders are only different from language to language (C++ vs Fortran).

Cheers,
Philippe.