Multidimensional Array

Hi all,

Would someone please tell me how to include a n-dimensional array (n>3)?

It seems that I got “Cint internal error ary parameter dimension” while trying to do that.

I googled and found that CINT only supports n-D array with n<=3, but that topic was in 2006. Is it fixed now?

Thank you so much! :slight_smile:

root [0] int array[10][20][30][40][50];
root [1] 10*20*30*40*50
(const int)12000000
root [2] sizeof(array) / sizeof(int)
(const int)12000000

this is max.C

#define max_cxx
#include <iostream>
#include <stdlib.h>

using namespace std;

Float_t max(Float_t A[][8][7][12][9],int &m,int &n,int &o,int &p,int &q) {
Float_t temp=A[0][0][0][0][0];
for (Int_t a=0;a<6;a++) {
for (Int_t b=0;b<8;b++) {
for (Int_t c=0;c<7;c++) {
for (Int_t d=0;d<12;d++) {
for (Int_t e=0;e<9;e++) {
if (temp<A[a][b][c][d][e]) {
temp = A[a][b][c][d][e];
m = a;
n = b;
o = c;
p = d;
q = e;
}
}
}
}
}
}
return temp;
}

and this is runSimpleCode.C

{
gROOT->ProcessLine(".L simpleCode.C+");
gROOT->ProcessLine(".L max.C+");
vector<TString> rootfiles;
rootfiles.push_back("WH120");
rootfiles.push_back("top");
rootfiles.push_back("Wbb");

Float_t signal[6][8][7][12][9];
Float_t bkg[6][8][7][12][9];
Float_t sen[6][8][7][12][9];

TFile *file = new TFile ("AnalysisManager.data11_7TeV.p833_v0115_MC1.Full.Hists.root");
TTree *tree = (TTree*) file->Get(rootfiles[0]);
TTree *tree1 = (TTree*) file->Get(rootfiles[1]);
TTree *tree2 = (TTree*) file->Get(rootfiles[2]);
	simpleCode x(tree);
	simpleCode y(tree1);
	simpleCode z(tree2);
for (Int_t a=0;a<6;a++) {
for (Int_t b=0;b<8;b++) {
for (Int_t c=0;c<7;c++) {
for (Int_t d=0;d<12;d++) {
for (Int_t e=0;e<9;e++) {
	signal[a][b][c][d][e] = x.Loop(rootfiles[0],a,b,c,d,e);
	bkg[a][b][c][d][e] = y.Loop(rootfiles[1],a,b,c,d,e) + z.Loop(rootfiles[2],a,b,c,d,e);
	if (signal[a][b][c][d][e]<=0) {sen[a][b][c][d][e]=0;}
	if (bkg[a][b][c][d][e]<=0) {sen[a][c][b][d][e]=0;}
	if (signal[a][b][c][d][e]>0 && bkg[a][b][c][d][e]>0) {sen[a][b][c][d][e] = sqrt(2*((signal[a][b][c][d][e]+bkg[a][b][c][d][e]) * log(1+(signal[a][b][c][d][e]/bkg[a][b][c][d][e]))-signal[a][b][c][d][e]));}
	}
}
}
}
}
int m=0;
int n=0;
int o=0;
int p=0;
int q=0
Float_t maxS = max(sen,m,n,o,p,q); 

std::cerr << maxS << std::endl;
std::cerr << m << std::endl;
std::cerr << n << std::endl;
std::cerr << o << std::endl;
std::cerr << p << std::endl;
std::cerr << q << std::endl;

FILE *data1;
data1=fopen("data1.dat","w+");
for (Int_t a=0;a<6;a++) {
for (Int_t b=0;b<8;b++) {
for (Int_t c=0;c<7;c++) {
for (Int_t d=0;d<12;d++) {
for (Int_t e=0;e<9;e++) {
fprintf(data1, "%f	%d	%d	%d	\n",sen[a][b][c][d][e],a,b,c,d,e);}}}}}
}

while trying to run root -l runSimpleCode.C or root -l runSimpleCode.C+, I got this error message:

Info in <TUnixSystem::ACLiC>: creating shared library /home/minh/Mine/ROOT/higgs/./max_C.so
Cint internal error ary parameter dimension :0:
Warning: Error occurred during dictionary source generation
!!!Removing /home/minh/Mine/ROOT/higgs/max_C_ACLiC_dict.cxx /home/minh/Mine/ROOT/higgs/max_C_ACLiC_dict.h !!!
Error: /usr/local/bin/rootcint: error loading headers...
Error in <ACLiC>: Dictionary generation failed!
Info in <ACLiC>: Invoking compiler to check macro's validity
/home/minh/Mine/ROOT/higgs/./max.C:7:1: error: ‘Float_t’ does not name a type

and finally, here is the link to the old topic

CINT array limitation

  1. See: Float_t does not name a type
  2. Maybe Philippe knows a better way … I just know a brutal fix …
    replace:
    Float_t A[][8][7][12][9]
    with:
    Float_t *A
    and:
    A[0][0][0][0][0]
    with:
    A[0]
    and:
    A[a][b][c][d][e]
    with:
    A[(((((( a * 8 ) + b ) * 7 ) + c ) * 12 + d ) * 9 + e )]
    and:
    max(sen,m,n,o,p,q);
    with:
    max(&sen[0][0][0][0][0], m, n, o, p, q);

still waiting for the output but I think it works. Thank you very much, I really appreciate it. :smiley:

I think I have found a much neater brutal fix …
in your “max.C” add a:
typedef Float_t (*My5DArray)[8][7][12][9];
and replace:
Float_t A[][8][7][12][9]
with:
My5DArray A
(Nothing else needs to be changed.)
BTW. The “typedef” trick works in many cases in which CINT breaks on something (due to its limitations).

Thank you so much for your effort, mant! I’m trying your suggestion. :slight_smile:

okay so now I modified max.C to

#define max_cxx
#include <iostream>
#include <stdlib.h>
#if !defined (__CINT__) || defined (__MAKECINT__)
#include "Rtypes.h"
#endif

using namespace std;
typedef Float_t (*My5DArray)[8][7][10][9];
Float_t max(My5DArray A,int &m,int &n,int &o,int &p,int &q) {
Float_t temp=A[0][0][0][0][0];
for (Int_t a=0;a<6;a++) {
for (Int_t b=0;b<8;b++) {
for (Int_t c=0;c<7;c++) {
for (Int_t d=0;d<10;d++) {
for (Int_t e=0;e<9;e++) {
if (temp<A[a][b][c][d][e]) {
temp = A[a][b][c][d][e];
m = a;
n = b;
o = c;
p = d;
q = e;
}
}
}
}
}
}
return temp;
}

so I got

Error: Symbol q is not defined in current scope  runSimpleCode.C:56:
Error: assignment to 0 Float_t maxS runSimpleCode.C:56:
Error: Invalid type '0' in declaration of 'Float_t maxS' runSimpleCode.C:56:
*** Interpreter error recovered ***

Do I need to change the signal, bkg, and sen array in runSimpleCode.C to my5Darray type?
BTW, thanks for the typedef tip :smiley:

  1. add the missing “;” in the end of the line “int q=0” in your “runSimpleCode.C” file
  2. I noticed you changed “[8][7][12][9]” into “[8][7][10][9]” in your new “max.C” file -> I hope you did the same change in your “runSimpleCode.C” file ("signal", “bkg”, “sen”, 2 x “for (Int_t d=0;d<12;d++) {”)