Filling array of histograms in a function

Hi everyone,
first time here (and ever on a forum). I’m new to ROOT, sorry in advance if this will sound as a stupid question.

I’d like to fill multiple histograms in a function, so i created an array of pointers to histograms. When i run my code i get an error like:

error: member reference base type ‘TH1F *’ is not a structure or union
h[ind]->Fill(LHEPart_pt[ilept]); //fill histogram for pt

My source code is the following:

void Events::VarDef()
{
    TH1F **h[3]; //define array of histo pt for each particle
    *h[0] = new TH1F("h1", "electron pT", 80, 0.0, 250.0);

    *h[1] = new TH1F("h4", "muon pT", 80, 0.0, 250.0);

    *h[2] = new TH1F("h7", "tau pT", 80, 0.0, 250.0);


    TH1F *hR[6]; //array of histo, rct events
    hR[0] = new TH1F("hRee", "Electron pT, from rct electron event", 80, 0.0, 250.0); //hRee
    hR[1] = new TH1F("hRem", "Electron pT, from rct muon event", 80, 0.0, 250.0); //hRem
    
    hR[2] = new TH1F("hRme", "Muon pT, from rct electron event", 80, 0.0, 250.0); //hRme
    hR[3] = new TH1F("hRmm", "Muon pT, from rct muon event", 80, 0.0, 250.0); //hRmm
    
    hR[4] = new TH1F("hRte", "Tau pT, from rct electron event", 80, 0.0, 250.0); //hRte
    hR[5] = new TH1F("hRtm", "Tau pT, from rct muon event", 80, 0.0, 250.0); //hRtm
    
    
    TH1F *hRi[6]; //array of histo, reconstructed isolated events
    hRi[0] = new TH1F("hRiee", "Electron pT, from rct iso electron event", 80, 0.0, 250.0);
    hRi[1] = new TH1F("hRiem", "Electron pT, from rct iso muon event", 80, 0.0, 250.0);
    
    hRi[2] = new TH1F("hRime", "Muon pT, from rct iso electron event", 80, 0.0, 250.0);
    hRi[3] = new TH1F("hRimm", "Muon pT, from rct iso muon event", 80, 0.0, 250.0);
    
    hRi[4] = new TH1F("hRite", "Tau pT, from rct iso electron event", 80, 0.0, 250.0);
    hRi[5] = new TH1F("hRitm", "Tau pT, from rct iso muon event", 80, 0.0, 250.0);
    
return;
}


void Events::Filling(Int_t ind, Int_t ilept)
{
    h[ind]->Fill(LHEPart_pt[ilept]); //fill histogram for pt
    if(nElectron>0){ //if there is at least one reconstructed Electron
        hR[ind]->Fill(Electron_pt[0]); //store pT value of Electron
        if(Electron_pfRelIso03_all[0]<0.15) hRi[ind]->Fill(Electron_pt[0]);
    }
    if (nMuon>0){ //Muon
        hR[ind+1]->Fill(Muon_pt[0]);
        if(Muon_pfRelIso03_all[0]<0.15) hRi[ind+1]->Fill(Muon_pt[0]);
    }
    return;
}

Of course this is just a snippet of the code. I copy-pasted this example but i have other functions with the same problem (a similar one with THStack, but one at a time).

I need an array-like structure because in order functions i fill, color and write to a file my histograms with for loops.

As you can also see, i also have a reference class (automatically generated with MakeClass). Don’t know if this information could help.

Thanks in advance for the help.

_ROOT Version: 6.11/02


Hi,

Welcome to the forum :slight_smile:

If I understand correctly, this is an array of pointers to the pointers to the histograms…

TH1F **h[3]; //define array of histo pt for each particle

But what you probably need is just an array of pointers to the histograms.
Try to look how it is done in your example for hR array:

TH1F *hR[6]; //array of histo, rct events
    hR[0] = new TH1F("hRee", "Electron pT, from rct electron event", 80, 0.0, 250.0); 
    ....

and try to change the part with h array in the same way.

Basically, you don’t need extra * everywhere

or if you very very adventurous and want to use double pointers, then you can extract the histogram pointer as:

(*(h[ind]))->Fill(LHEPart_pt[ilept]); //fill histogram for pt

cheers,
Bohdan

1 Like

Hey Bohdan,
thank you very much for the quick reply. I tried the option you suggest (just the array of pointers), but i get the same error message. At frist I thought it was a parenthesis problem, so i tried

TH1F *h[3]; //define array of histo pt for each particle
    h[0] = new TH1F("h1", "electron pT", 80, 0.0, 250.0);
....
(h[ind])->Fill(LHEPart_pt[ilept]);

but the compiler still responds

error: member reference base type 'TH1F *' is not a structure or union
    (h[ind])->Fill(LHEPart_pt[ilept]); //fill histogram for pt
    ~~~~~~~~^ ~~~~

Following the very adventuros advice, I tried keeping the double pointer array and it compiles, hurray.
Now I just have a NULL problem, aka

Error in <HandleInterpreterException>: Trying to access a pointer that points to an invalid memory address..
Execution of your code was aborted.
In file included from input_line_71:1:
/Events.C:36:6: warning: invalid memory pointer passed to a callee:
    *h[0] = new TH1F("h1", "electron pT", 80, 0.0, 250.0);
     ^~~~

Don’t really know how to get away with it.

Cheers,
Zenith

Ok, then it is quite hard to locate the problem
Sharing the full code or small reproducible would probably help

1 Like

Tried to load my files or post my GitHub link here but apparently I don’t have the permissions.

You can find the source code on GitHub: my username is zenith378, the repository is Tesina and the branch I’m currently working on is FBC. The files are Events.C and Events.h.

Thanks a lot for the help, mate. Really appreciate it.

You probably need to make the histogram container a private member of the Events class or declare it in a scope accessible by multiple function calls.
You declare and initialize histograms in a method but you expect them to be filled from another method.aybe at run time the histograms go out of scope and you cannot access anymore them.

1 Like

Hey Renato,
thank you very much, that actually solved the problem. Just had to make the histogram and stack cointer a private member of the Events class and initialize them in the init method, with the rest of the tree.

Thanks everybody. You really helped me out here.

1 Like