Retriveing Histogram from File, Cannot Draw After Closing FIle

Hi folks,
I’m trying to load a TH2D from a file, make a TH1D from some of the data stored in it, then use that second histogram.

This all has to be embedded in a loop and I need access the TH1D from outside the loop. Because there are lots of files to search through I want to close the file after I have retrieved the data I need from it.

I’ve tried two different ways to create the TH1D, one causes a seg fault whenever I try to do anything with it once the file is closed. The other mostly seems to work, except whenever I draw it I get a blank canvas.


#include "TH2D.h"
#include "TH1D.h"
#include "TFile.h"
#include "TCanvas.h"
#include "TMath.h"

void MinEx(){

  int i_E = 200;
  int i_a = 30;

  TFile *f_mc = nullptr;

  //find the MC prediction
  std::string mc_file = "proton_" + std::to_string(i_E) + "MeV_c.root"; 
  f_mc = TFile::Open(mc_file.c_str());

  TH2D *h_mc;
  std::string histname = "inel_" + std::to_string(i_E) + "_MeV";
  f_mc->GetObject(histname.c_str(), h_mc );


double angle_rad = 3.1415*i_a/180;

 //make the MC plot
   int nbins = 200;

   //if I use this version, attempting to draw h1_mc gives me a blank canvas
   TH1D h1_mc = TH1D("h_mc","h_mc",nbins,0,1000);

   for(int i=1;i<nbins+1;i++){
     
     h1_mc.SetBinContent(i,h_mc->GetBinContent( h_mc->FindBin( h1_mc.GetBinCenter(i) , angle_rad ))/(2*3.1415*TMath::Sin(angle_rad))    );

   }//i


   //if I use this version, I get a seg fault when trying to do anything with h1_mc after closing the file
   /*
  TH1D *h1_mc = new TH1D("h_mc","h_mc",nbins,0,1000);

   for(int i=1;i<nbins+1;i++){
     
     h1_mc->SetBinContent(i,h_mc->GetBinContent( h_mc->FindBin( h1_mc->GetBinCenter(i) , angle_rad ))/(2*3.1415*TMath::Sin(angle_rad))    );

   }//i
   */

   f_mc->Close();

   TCanvas *c = new TCanvas("c","c");
   h1_mc.Draw(); //drawing fails

   //but this works fine
   std::cout << h1_mc.Integral("width") << std::endl;


}

This is the root file containing the TH2D object.
proton_200MeV_c.root (60.1 KB)

ROOT Version: 6.18/04
Platform: Not Provided
Compiler: Not Provided


Right after “Open” add: gROOT->cd();

Hi,
the problem is that, by default, the current directory (i.e. gDirectory) at the point of histogram creation takes ownership of the histogram, and deletes it when the corresponding TFile is deleted. You can tell the TH1s that they should not be associated with a directory with hist->SetDirectory(nullptr) or TH1::AddDirectory(nullptr); (to set it once for all histograms), in which case you become responsible for the lifetime management of these objects.

The other piece of the puzzle is that TFile::Open implicitly changes gDirectory to the file you just opened.

I hope that clarifies what’s happening a little bit.
Cheers,
Enrico

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.