I am trying the following function as part of a bigger code. I copy it here hoping that it has all the necessary information to find the source of the problem. It gets the integral from different histograms (at different cut levels) and produces plots like the attached one. When I try to change the axis label (see the commented line) it crashes with the associated (bad_alloc) comment.
I have done several tests. For example, if I set by hand the label of all minus one bins, it works.
Thanks,
Jonatan
void HistogramReader::Evolution(TFile* file,
TString analysis,
TString hname)
{
TH1D* test_hist = (TH1D*)file->Get(analysis + "/" + hname + "_evolution");
if (test_hist) return;
file->cd();
file->cd(analysis);
Int_t nbins = 0;
for (Int_t i=0; i<ncut; i++)
{
if (!scut[i].Contains(analysis + "/")) continue;
nbins++;
}
TH1D* hist = new TH1D(hname + "_evolution", "", nbins, -0.5, nbins-0.5);
for (Int_t i=0, bin=0; i<ncut; i++)
{
if (!scut[i].Contains(analysis + "/")) continue;
TH1D* dummy = (TH1D*)file->Get(scut[i] + "/" + hname);
hist->SetBinContent(++bin, Yield(dummy));
// terminate called after throwing an instance of 'std::bad_alloc'
// hist->GetXaxis()->SetBinLabel(bin, scut[i].Data());
}
hist->Write();
}
Dear ROOT experts, I have tried to make the code more clear / robust. Unfortunately it continues failing Please let me know how can I check / fix this problem.
void HistogramReader::Evolution(TFile* file,
TString analysis,
TString hname)
{
// Check if the evolution histogram already exists
TH1D* test_hist = (TH1D*)file->Get(analysis + "/" + hname + "_evolution");
if (test_hist) return;
// Get the number of bins
file->cd(analysis);
Int_t nbins = 0;
for (Int_t i=0; i<ncut; i++)
{
if (!scut[i].Contains(analysis + "/")) continue;
nbins++;
}
// Create and fill the evolution histogram
TH1D* hist = new TH1D(hname + "_evolution", "", nbins, -0.5, nbins-0.5);
for (Int_t i=0, bin=0; i<ncut; i++)
{
if (!scut[i].Contains(analysis + "/")) continue;
TH1D* dummy = (TH1D*)file->Get(scut[i] + "/" + hname);
hist->SetBinContent(++bin, Yield(dummy));
}
// Change the evolution histogram x-axis labels
TAxis* xaxis = (TAxis*)hist->GetXaxis();
for (Int_t i=0, bin=0; i<ncut; i++)
{
if (!scut[i].Contains(analysis + "/")) continue;
TString tok, icut;
Ssiz_t from = 0;
while (scut[i].Tokenize(tok, from, "_")) icut = tok;
if (++bin < nbins) xaxis->SetBinLabel(bin, icut);
// terminate called after throwing an instance of 'std::bad_alloc'
// xaxis->SetBinLabel(bin, icut);
}
// Write the evolution histogram
hist->Write();
}
There you are! That’s why I was reading the nbin+1 element, to get the overflow bin. Then, as I wrote, if I try to do it with a histogram in which I have changed the label, it crashes
I admit that there might be something else going on, but the fact is that not getting the overflow bin (which I should) allows me to read without crash the relabelled histograms.