Combine Histograms Code Not Working

So I am writing code to combine histograms found within root files. I am running in ubuntu wsl, root is set up to work, the files are named after the following format “combined_run_13_DY.root”, the histogram names are correct (although I did also try with 1; and _ as seen in the image below), the files that I have been inputting are correct, their directory structure is also correct, the histograms are also filled, which is why I am posting this. It seems like it should work (it was actually working before), but it doesn’t. Attached is an image of the root browser looking at an example file structure.
Well, apparently I can’t attach links as a new user so here is the code:


#include <TFile.h>
#include <TH1F.h>
#include <TCanvas.h>
#include <TLegend.h>
#include
#include
#include

void combine_histograms(const char* file1_name, const char* file2_name, const char* file3_name, const char* file4_name, const char* file5_name, const char* file6_name, const char* file7_name, const char* file8_name, const char* output_file_name) {

TFile *file1 = TFile::Open(file1_name,"read");
TFile *file3 = TFile::Open(file3_name,"read");
TFile *file2 = TFile::Open(file2_name,"read");
TFile *file4 = TFile::Open(file4_name,"read");
TFile *file5 = TFile::Open(file5_name,"read");
TFile *file6 = TFile::Open(file6_name,"read");
TFile *file7 = TFile::Open(file7_name,"read");
TFile *file8 = TFile::Open(file8_name,"read");

//|| !file8

// Check if files are open
if (!file1 || !file2 || !file3 || !file4 || !file5 || !file6 || !file7 || !file8) {
    std::cerr << "Error: Unable to open one of the input files." << std::endl;
    return;
}

std::vector<std::string> variableArray = {"muonPt", "muonEta", "muonPhi", "muoniso", "muoniso_SEL", "muonVX", "muonVY", "muonVZ", "Nmuons_all", "Nmuons_mumuSEL", "MET_mumuSEL", "elecPt", "elecEta", "elecPhi", "eleciso", "elecVX", "elecVY", "elecVZ", "Nelectrons_all", "Nelectrons_eeSEL", "MET_eeSEL", "elec_muonPt", "elec_muonEta", "elec_muonPhi", "elec_muonVX", "elec_muonVY", "elec_muonVZ", "MET_emuSEL", "before_muonPt", "before_muonEta", "before_muonPhi", "before_muonVX", "before_muonVY", "before_muonVZ", "jetPt", "jetEta", "jetPhi", "jetVX", "jetVY", "jetVZ", "Njets_all_", "Njets_ee_", "Njets_mm_", "Njets_em_", "AK8_jetPt", "AK8_jetEta", "AK8_jetPhi", "AK8_jetVX", "AK8_jetVY", "AK8_jetVZ", "AK8_Njets_all_", "AK8_Njets_ee_", "AK8_Njets_mm_", "AK8_Njets_em_", "DeltaR_Elec", "DeltaR_Muon", "Generator_b", "MET_eeSel_Jet_", "MET_mumuSel_Jet_", "deltaRVal_mu1", "deltaRVal_mu2", "numMatched_mu1", "numMatched_mu2"};

// Create the output ROOT file
TFile *output_file = new TFile(output_file_name, "recreate");

// Using Index-Based For Loop
for (int i = 0; i<variableArray.size(); i++) {
    // Get the histograms
    std::string path = "analyzeBasicPat/" + variableArray[i];
    
    TH1F* hist1 = (TH1F*)file1->Get("analyzeBasicPat/Njets_all_");
    TH1F* hist2 = (TH1F*)file2->Get(path.c_str());
    TH1F* hist3 = (TH1F*)file3->Get(path.c_str());
    TH1F* hist4 = (TH1F*)file4->Get(path.c_str());
    TH1F* hist5 = (TH1F*)file5->Get(path.c_str());
    TH1F* hist6 = (TH1F*)file6->Get(path.c_str());
    TH1F* hist7 = (TH1F*)file7->Get(path.c_str());
    TH1F* hist8 = (TH1F*)file8->Get(path.c_str());

    // Check if histograms are retrieved successfully
    if (!hist1 || !hist2 || !hist3 || !hist4 || !hist5 || !hist6 || !hist7 || !hist8) {
        //|| !hist8
        std::cerr << "Error: Unable to retrieve histograms for " << variableArray[i] << " from input files." << std::endl;
        continue;
    }

    // Set histogram styles
    hist1->SetLineColor(kRed);
    hist2->SetLineColor(kOrange);
    hist3->SetLineColor(kYellow);
    hist4->SetLineColor(kGreen);
    hist5->SetLineColor(kBlue);
    hist6->SetLineColor(kCyan);
    hist7->SetLineColor(kGray);
    hist8->SetLineColor(kBlack);

    // Create a canvas
    TCanvas *canvas = new TCanvas(("canvas_" + variableArray[i]).c_str(), "Combined Histograms", 1000, 1000);

    Double_t factor = 1.;

    // Draw the histograms on the same canvas
    hist1->Scale(factor/hist1->GetEntries());
    hist1->Draw("HIST");
    hist2->Scale(factor/hist2->GetEntries());
    hist2->Draw("HIST SAME");
    hist3->Scale(factor/hist3->GetEntries());
    hist3->Draw("HIST SAME");
    hist4->Scale(factor/hist4->GetEntries());
    hist4->Draw("HIST SAME");
    hist5->Scale(factor/hist5->GetEntries());
    hist5->Draw("HIST SAME");
    hist6->Scale(factor/hist6->GetEntries());
    hist6->Draw("HIST SAME");
    hist7->Scale(factor/hist7->GetEntries());
    hist7->Draw("HIST SAME");
    hist8->Scale(factor/hist8->GetEntries());
    


    // Add a legend
    TLegend *legend = new TLegend(0.7, 0.7, 0.9, 0.9);
    legend->AddEntry(hist1, "DY", "l"); //Was DY
    legend->AddEntry(hist2, "WW", "l");
    legend->AddEntry(hist3, "WZ", "l");
    legend->AddEntry(hist4, "ZZ", "l");
    legend->AddEntry(hist5, "1100", "l");
    legend->AddEntry(hist6, "1400", "l");
    legend->AddEntry(hist7, "1800", "l");
    legend->AddEntry(hist8, "TT", "l");
    legend->Draw();

    // Save the canvas to a file
    canvas->SaveAs(("combined_histograms_" + variableArray[i] + ".png").c_str());

    // Write the histograms and canvas to the output file
    output_file->cd();
    hist1->Write();
    hist2->Write();
    hist3->Write();
    hist4->Write();
    hist5->Write();
    hist6->Write();
    hist7->Write();
    hist8->Write();
    canvas->Write();

    // Clean up
    delete canvas;
    delete legend;
}

// Close the files
output_file->Close();
file1->Close();
file2->Close();
file3->Close();
file4->Close();
file5->Close();
file6->Close();
file7->Close();
file8->Close();

// Clean up
delete output_file;
delete file1;
delete file2;
delete file3;
delete file4;
delete file5;
delete file6;
delete file7;
delete file8;

}

int main() {
// Call the function with the file names
std::string run = “13”;

// Call the function with the file names
combine_histograms(("combined_run_" + run + "_DY.root").c_str(), ("combined_run_" + run + "_WW.root").c_str(), ("combined_run_" + run + "_WZ.root").c_str(), ("combined_run_" + run + "_ZZ.root").c_str(), ("combined_run_" + run + "_SUSY_1100.root").c_str(), ("combined_run_" + run + "_SUSY_1400.root").c_str(), ("combined_run_" + run + "_SUSY_1800.root").c_str(), ("combined_run_" + run + "_TT.root").c_str(), ("combined_Run_" + run + ".root").c_str());

}

Hello,
Which error are you getting running your code?

Lorenzo

The error that triggers is the error when accessing histograms inside the root files. So where is says Error could not retrieve histograms for variableArray[i].

Then it means that the provided name and path of the histogram is not correct. I would check that these expected histograms are present in all those files

Lorenzo

Well, the path is correct. As for the name, that should also be correct, so in another file that creates the original root file with the histograms, this is the example code:

TH1F* muonPt_ = dir.make(“muonPt”, “pt”, 100, 0., 300.);

Now in the combine histograms code do I use muonPt_ or muonPt?

I tried both right now, and they both resulted in the same error as before. And the expected histograms are present in the root file.

If you get the error it means in one of the file the histogram is not present or th path is not correct. You can check the path by calling (for each file):

std::cout << variableArray[i] << std::endl;
file1->cd("analyzeBasicPat")
file1->ls();
//... and similar for the other files 

I did that and here is a sample what I got, and this is what happened for everything else in the for loop, and I tried to run again by adding on the ;1 to the variable name in the for loop, but it still didn’t work:

Error: Unable to retrieve histograms for muonPt from input files.
TFile** combined_run_14_DY.root
TFile* combined_run_14_DY.root
TDirectoryFile* analyzeBasicPat analyzeBasicPat
KEY: TH1F muonPt;1 pt
KEY: TH1F muonEta;1 eta
KEY: TH1F muonPhi;1 phi
KEY: TH1F muoniso;1 iso_
KEY: TH1F muoniso_SEL;1 iso
KEY: TH1F muonVX;1 vx
KEY: TH1F muonVY;1 vy
KEY: TH1F muonVZ;1 vz
KEY: TH1F Nmuons_all;1 N
KEY: TH1F Nmuons_mumuSEL;1 N
KEY: TH1F MET_mumuSEL;1 N
KEY: TH1F elecPt;1 pt
KEY: TH1F elecEta;1 eta
KEY: TH1F elecPhi;1 phi
KEY: TH1F eleciso;1 iso_
KEY: TH1F elecVX;1 vx
KEY: TH1F elecVY;1 vy
KEY: TH1F elecVZ;1 vz
KEY: TH1F Nelectrons_all;1 N
KEY: TH1F Nelectrons_eeSEL;1 N
KEY: TH1F MET_eeSEL;1 N
KEY: TH1F elec_muonPt;1 pt
KEY: TH1F elec_muonEta;1 eta
KEY: TH1F elec_muonPhi;1 phi
KEY: TH1F elec_muonVX;1 vx
KEY: TH1F elec_muonVY;1 vy
KEY: TH1F elec_muonVZ;1 vz
KEY: TH1F MET_emuSEL;1 N
KEY: TH1F deltaRVal_mu1;1 deltaR
KEY: TH1F deltaRVal_mu2;1 deltaR
KEY: TH1F numMatched_mu1;1 Matched deltaR 1
KEY: TH1F numMatched_mu2;1 Matched deltaR 2
KEY: TH1F before_muonPt;1 pt
KEY: TH1F before_muonEta;1 eta
KEY: TH1F before_muonPhi;1 phi
KEY: TH1F before_muonVX;1 vx
KEY: TH1F before_muonVY;1 vy
KEY: TH1F before_muonVZ;1 vz
KEY: TH1F jetPt;1 pt
KEY: TH1F jetEta;1 eta
KEY: TH1F jetPhi;1 phi
KEY: TH1F jetVX;1 vx
KEY: TH1F jetVY;1 vy
KEY: TH1F jetVZ;1 vz
KEY: TH1F Njets_all_;1 Njets
KEY: TH1F Njets_ee_;1 Njets_ee
KEY: TH1F Njets_mm_;1 Njets_mm
KEY: TH1F Njets_em_;1 Njets_em
KEY: TH1F AK8_jetPt;1 pt
KEY: TH1F AK8_jetEta;1 eta
KEY: TH1F AK8_jetPhi;1 phi
KEY: TH1F AK8_jetVX;1 vx
KEY: TH1F AK8_jetVY;1 vy
KEY: TH1F AK8_jetVZ;1 vz
KEY: TH1F AK8_Njets_all_;1 AK8_Njets
KEY: TH1F AK8_Njets_ee_;1 AK8_Njets_ee
KEY: TH1F AK8_Njets_mm_;1 AK8_Njets_mm
KEY: TH1F AK8_Njets_em_;1 AK8_Njets_em
KEY: TH1F DeltaR_Elec;1 R
KEY: TH1F DeltaR_Muon;1 R
KEY: TH1F Generator_b;1 number
KEY: TH2F MET_eeSel_Jet_;1 eeMET_Njets
KEY: TH2F MET_mumuSel_Jet_;1 mumuMET_Njets
KEY: TDirectoryFile analyzeBasicPat;1 analyzeBasicPat

Do this separately for each hist to find out which one/ones is/are not found, then check those files:

    if (!hist1 || !hist2 || !hist3 ...

Okay I did that, and there was an issue with one of the input files. I fixed it, and it half worked now, because now it is outputting:
(Prints a couple png created outputs) then

Error: Unable to open hist 1 for AK8_Njets_all

*** Break *** segmentation violation
Generating stack trace…
0x00007fdb2595d9d8 in TFile::WriteStreamerInfo() + 0x458 from /home/khusanjonb/root-6.30.06-install/lib/libRIO.so
0x00007fdb2595c473 in TFile::Close(char const*) + 0xb3 from /home/khusanjonb/root-6.30.06-install/lib/libRIO.so
0x00007fdb25e04bcd in from /home/khusanjonb/root-6.30.06-install/lib/libCore.so
0x00007fdb25e05420 in TROOT::CloseFiles() + 0x50 from /home/khusanjonb/root-6.30.06-install/lib/libCore.so
0x00007fdb25174495 in from /lib/x86_64-linux-gnu/libc.so.6
0x00007fdb25174610 in on_exit + 0x0 from /lib/x86_64-linux-gnu/libc.so.6
0x00007fdb25158d97 in from /lib/x86_64-linux-gnu/libc.so.6
0x00007fdb25158e40 in __libc_start_main + 0x80 from /lib/x86_64-linux-gnu/libc.so.6
0x0000559d71150685 in _start + 0x25 from ./combine_histograms
corrupted double-linked list
Aborted

But I checked the file, and the filename and the histogram were both there. Do you have any idea what issues I have to check for this time?

Nevermind, it was an underscore that was missing in the variable list, now everything works. Thanks!