Problem closing/passing TFile

Dear RootTalk,

I am currently trying to run a named macro code that repeatedly reads many histograms from a handful of root files. I decided to write a function which fetches a desired histogram and performs some desired manipulation. I have many histograms that require an identical treatment (for instance scaling the MC, or projecting a portion a 2D histogram), so this saves me copying my code. I then run into issues when my main macro opens too many files (where in fact it is mostly many instances of the same files).

The best way I can think of to mitigate this would be to initialize a TFile pointer and then to pass this as an argument to a function which fetches my histograms. This way I would only have one instance of each file. When I try to do so my macro crashes with a seg fault.

My next idea is to modify my existing function to close the file and then return the histogram. Once again adding in a line to delete or close the TFile produces a seg fault.

I have been browsing the help pages and am unsure of what I am doing wrong. I append here an example macro that fetches and plots a histogram with two versions of the fetcher function - neither of which work.

Many Thanks!

Robert

[code]
#include
#include<TCanvas.h>
#include<TFile.h>
#include<TH1D.h>

using namespace std;
//When I don’t include this line that deletes the TFile pointer this version works,
//but repeatedly opens redundant instances of the same TFile
TH1D* histMaker(TString hname, TString fname){
TFile f0 = new TFile(fname,“READONLY”);
f0->cd();
cout<<"Getting "<<hname<<endl;
TH1D hist = (TH1D)gDirectory->Get(hname);
double lumi=20216.6;
hist->Scale(lumi);
delete f0;
return hist;
}
//This version of the function simply crashes
TH1D
histMaker(TString hname, TFile* f0){
f0->cd();
cout<<"Getting "<<hname<<endl;
TH1D hist = (TH1D)gDirectory->Get(hname);
double lumi=20216.6;
hist->Scale(lumi);
delete f0;
return hist;
}
//This is just how I would go about calling either of these functions
draw(){
TFile f1 = new TFile(“histos.root”,“READONLY”);
TH1D
hist1 = histMaker(“hgaus”,f1);
TH1D* hist2 = histMaker(“hgaus”,“histos.root”);
TCanvas *c1 = new TCanvas(“c1”,“c1”,10,10,600,500);
hist1->Draw(“HIST”);
TCanvas *c2 = new TCanvas(“c2”,“c2”,10,10,600,500);
c2->cd();
hist2->Draw(“HIST”);
}[/code]

In your “histMaker” functions, after you retrieve the histogram, try to add:
hist->SetDirectory(0); // (0) or (gROOT)
and then, before you “delete f0;”, try to add:
gROOT->cd();

1 Like

Awesome - that works and makes sense, I suppose my function was trying to return a histogram that I had deleted as it was sitting in the open file.

Thanks a lot!

Robert