Segmentation violation while drawing histograms

Hello,

I am having trouble drawing histograms with a piece of code that used to work before. I have signal + background data and I can no longer generate the pdf containing the histogram because of segmentation violation error. I get the error when creating a shared library in my workspace. I don’t know why it was working before and stopped working when I modified the signals I want to draw.

here’s the error I get :

[code]Starting hist_draw
root [0]
Processing hist_draw.C+…
Info in TUnixSystem::ACLiC: creating shared library /afs/cern.ch/user/a/aaitahme/common_analysis/process/analysis/./hist_draw_C.so

*** Break *** segmentation violation

===========================================================
There was a crash.
This is the entire stack trace of all threads:

#0 0x00007fc721a497be in waitpid () from /lib64/libc.so.6
#1 0x00007fc7219db5c9 in do_system () from /lib64/libc.so.6
#2 0x00007fc721fc506a in TUnixSystem::StackTrace() () from /cvmfs/cms.cern.ch/slc6_amd64_gcc493/lcg/root/6.02.12-kpegke4/lib/libCore.so
#3 0x00007fc721fc703c in TUnixSystem::DispatchSignals(ESignals) () from /cvmfs/cms.cern.ch/slc6_amd64_gcc493/lcg/root/6.02.12-kpegke4/lib/libCore.so
#4
#5 0x00007fc716265fbc in TH1D::operator=(TH1D const&) () from /cvmfs/cms.cern.ch/slc6_amd64_gcc493/lcg/root/6.02.12-kpegke4/lib/libHist.so
#6 0x00007fc70f7fca60 in hist_draw() () from /afs/cern.ch/user/a/aaitahme/common_analysis/process/analysis/hist_draw_C.so
#7 0x00007fc71de3b2e2 in ?? ()
#8 0x0000000000000015 in ?? ()
#9 0x00007ffc6ada38b0 in ?? ()
#10 0x0000000001fa13b0 in ?? ()
[/code]

As for the code I use, here it is :

[code]#if !defined(CINT) || defined(MAKECINT)

#include <TROOT.h> // -
#include <TSystem.h> // |
#include <TFile.h> // |
#include <TTree.h> // |
#include <TClonesArray.h> // |
#include <TChain.h> // |
#include <TCanvas.h> // |
#include <TStyle.h> // |
#include <TLegend.h> // - Include tools for root in general
#include <TH1.h> // |
#include <TF1.h>
#include <TH2.h> // |
#include // |
#include // |
#include // |
#include // |
#include <TString.h> // |
#include <TLorentzVector.h> // |
#include “TMath.h” // -
#include <TLatex.h>
#include <TPaveText.h>

#endif

using namespace TMath;
using namespace std;

//Main Function
void hist_draw(){

TString file = "ee_240_hist";
TString root = ".root";
TString name, histtype, filename;

std::map<TString, Int_t > histnames ={ // Defines which samples to process}
    { "signal_HZ", 1},
    { "backgd_WW", 1},
   	{ "backgd_Z", 1},
    { "backgd_ZZ", 1},
    { "backgd_bbbar", 1},
    { "data_obs", 2}
};

std::map<Int_t, TString> histtypes ={ // Defines which parameters to process {index, "_parameterHIST"}
    { 1, "_recoilmassHIST"}
};

std::map<TString, TString > titles ={ // Defines which samples to process and their corresponding cross sections {index, <"sample name", cross section>}
    { "_recoilmassHIST", "Missing Mass of Di-Muon System @ #sqrt{s} = 240 GeV With Cuts"}
};

std::map<TString, TString > xtitles ={ // Defines which samples to process and their corresponding cross sections {index, <"sample name", cross section>}
    { "_recoilmassHIST", "Missing Mass (GeV)"}
};

std::map<TString, TString > ytitles ={ // Defines which samples to process and their corresponding cross sections {index, <"sample name", cross section>}
    { "_recoilmassHIST", "Count"}
};


// Plots the signal and background di-jet mass and missing mass
TCanvas *can = new TCanvas(file, file, 1280, 720);
can->Divide(1, 1);

for (Int_t counter=1; counter<2; counter++){
    histtype = histtypes[counter];
    can->cd(counter);

    filename = file+root;
    TFile *f = new TFile(filename); // Specifies the root files which contain the generated histograms

    std::map<TString, TH1D*> histograms;
    std::map<TString, Int_t>::iterator names;
    for ( names = histnames.begin(); names != histnames.end(); names++){
        if (names->second == 1){
            name = names->first + histtype;
            histograms.insert ( std::pair<TString, TH1D*> (names->first, (TH1D*)f->Get(name)));
        }
    }

    Double_t largest=0;
    std::map<TString, TH1D*>::iterator hists;
    for ( hists = histograms.begin(); hists != histograms.end(); hists++){
        Double_t newlargest = hists->second->GetMaximum();
        if (newlargest > largest){
            largest = newlargest;
        }
    }
    largest = 1.1*largest;

    std::map<TString, TH1D*>::iterator histsit;
    for (histsit = histograms.begin(); histsit != histograms.end(); histsit++){
        name = histsit->first;
        (histograms)[name]->SetTitle(titles[histtype]);
        (histograms)[name]->GetXaxis()->SetTitle(xtitles[histtype]);
        (histograms)[name]->GetYaxis()->SetTitle(ytitles[histtype]);
        (histograms)[name]->SetMinimum(0);
        (histograms)[name]->SetMaximum(largest);
    }

    name = "signal_HZ";
    (histograms)[name]->SetLineColor(kRed);
    (histograms)[name]->SetFillStyle(3004);
    (histograms)[name]->SetFillColor(kRed);
    (histograms)[name]->SetStats(kFALSE);
    (histograms)[name]->Draw("hist same");

    name = "backgd_WW";
    (histograms)[name]->SetLineColor(kBlue);
    (histograms)[name]->SetFillStyle(3005);
    (histograms)[name]->SetFillColor(kBlue);
    (histograms)[name]->SetStats(kFALSE);
    (histograms)[name]->Draw("hist same");

    name = "backgd_Z";
    (histograms)[name]->SetLineColor(kGreen);
    (histograms)[name]->SetFillStyle(3006);
    (histograms)[name]->SetFillColor(kGreen);
    (histograms)[name]->SetStats(kFALSE);
    (histograms)[name]->Draw("hist same");

    name = "backgd_ZZ";
    (histograms)[name]->SetLineColor(kBlack);
    (histograms)[name]->SetFillStyle(3007);
    (histograms)[name]->SetFillColor(kBlack);
    (histograms)[name]->SetStats(kFALSE);
    (histograms)[name]->Draw("hist same");

    name = "backgd_bbbar";
    (histograms)[name]->SetLineColor(kYellow);
    (histograms)[name]->SetFillStyle(3008);
    (histograms)[name]->SetFillColor(kYellow);
    (histograms)[name]->SetStats(kFALSE);
    (histograms)[name]->Draw("hist same");

    TLegend* leg = new TLegend(0.13,0.69,0.25,0.89);
    std::map<TString, TH1D*>::iterator histdrawer;
    for (histdrawer = histograms.begin(); histdrawer != histograms.end(); histdrawer++){
        name = histdrawer->first;
        //(histograms)[name]->Draw("hist same");
        leg->AddEntry((histograms)[name],name,"f");
    }
    leg->Draw();

    TFile *g = new TFile(filename, "update"); // Specifies the root files which contain the generated histograms
        if (histnames["data_obs"]==2){
            histograms.insert ( std::pair<TString, TH1D*> ("data_obs", new TH1D("data_obs", "data_obs", 240/2, 0, 240)));
            *((histograms)["data_obs"]) = *((histograms)["signal"]);
            (histograms)["data_obs"]->SetName("data_obs");
            (histograms)["data_obs"]->Write();
        }
    g->Close();
}
    // Saves as PDF
can->Print("",".pdf");

}
[/code]

Thank you in advance for your help !

Aimane

to run your macro we would need the file ee_240_hist.root .

Without the root file I can’t reproduce. But my first advice would be to check all TFile operations.

Especially (TH1D *)f->Get(name) is potentially dangerous. Get can return nullptr or in case the root file has changed the result might be of a different type.

So instead use something like this:

auto object = f->Get(name); if (!object) { cerr << "object missing\n"; exit(1); } auto histo = dynamic_cast<TH1D*>(object); if (!histo) { cerr << "object is not a TH1D\n"; exit(1); }

Also it is probably wrong to open the same file twice at the same time (once for reading, once for updating). f is still open when you open g for update. And it is certainly wrong to open f inside the loop (and not closing it).