Trouble in getting a histogram with FIndObjectAny()

Dear co-rooters!

I am facing this rather strange, for me, issue. The story is to get a root file and reconstruct from the TTrees a signal shape. So the code loops over many histograms and then stores them in another root file. Later this new file is opened, to do some processing. But I can’t parse the histograms…

My code is the following

[code]

double exclude(Double_t *x, Double_t *par){//Exclusion fit
//bool reject;
if (x[0] > par[2]-par[3] && x[0] < par[2]+par[3]){
TF1::RejectPoint();
return 0;
}
return par[0] + par[1]*x[0];
}

void pulse_shape(int run, int movie, int det){

// (0) global variable definitions
std::vector<TH1F*> hists;//Raw signals - input to stac

double x, x_start, x_end, baseline;// x-values of the signal
float  y;// y-values of the signal

int    entries, minimum, minimumBin;

bool reject;

// (1) Get the signals from the TTree and store them individually in a root file as histograms
for (int mov=0; mov<=movie; mov++){

// (1a) Read the file
	TFile *fin = new TFile(TString::Format("FIMG-%d_%d-0-s1_1-%d.root", det, run, mov));
	if ( !fin->IsOpen() || fin->IsZombie() ) continue;

// (1b) Get TTree
	TTree *data  = (TTree*)fin->Get("Data");
	entries = data->GetEntries();
	data->SetBranchStatus("*",0);
	data->SetBranchStatus("signal_x",1); data->SetBranchAddress("signal_x",&x);
	data->SetBranchStatus("signal_y",1); data->SetBranchAddress("signal_y",&y);

// (1c) Create the histogram to store the movie
	TH1F *h = new TH1F("h", TString::Format("h%d", mov), 2500, 0, 2500);
	for (int i=0; i<entries; i++){
		data->GetEntry(i);
		h->Fill(i,y);
	}

// (1g) Save the histograms in a root file
	TFile fout(TString::Format("movies_%d_%d.root", run, det), "UPDATE");
	//cout << "Saving File " << fout.GetName() << endl;
	if (h) {h->SetName(TString::Format("h%d", mov)); h->Write(); fout.Close();}

}

// (2) Process the recorded signals
for (int mov=0; mov<=movie; mov++){

// (2a) Open the root file containg the signals
	TFile *fsignals = new TFile(TString::Format("movies_%d_%d.root",run, det));
	if ( !fsignals->IsOpen() || fsignals->IsZombie() ) continue;
	cout << "File " << fsignals->GetName() << " opened successfully" << endl;

// (2b) Get the Signal histogram
	TH1F *hIndv = (TH1F*)fsignals->FindObjectAny(TString::Format("h%d;1",mov));	
	if (hIndv) cout << hIndv->GetName() << endl;

// (2c) Find the constant baseline and move the signal to 0
	minimum = hIndv->GetMinimum(0);
	hIndv->GetBinWithContent(minimum,minimumBin,0);
	TF1 *baselineFit = new TF1("baselineFit",exclude,0,2000,4);
	baselineFit->SetParameters(0,0);
	baselineFit->FixParameter(2, minimumBin);
	baselineFit->FixParameter(3, 300);
	hIndv->Fit("baselineFit","WNCQ");
	baseline = baselineFit->GetParameter(0);
	for (int bin = 0; bin<hIndv->GetNbinsX(); bin++){
		hIndv->SetBinContent(bin+1, hIndv->GetBinContent(bin+1)-baseline);
	}
	
// (2d) Normalize the signal to its maximum value
	hIndv->Scale(1./minimum);

// (2e) Align the signal in time - maximum point
	for (int bin=1; bin<=2500-minimumBin; bin++){//Start shifting the pulse to the left
		hIndv->SetBinContent(bin, hIndv->GetBinContent(bin+minimumBin));
		for (bin=2500-minimumBin; bin<=2500; bin++){
			hIndv->SetBinContent(bin,0);//End shifting
		}
	}

	hists.push_back(hIndv);

}



cout << "Hist size is : " << sizeof(hists)/sizeof(hists[0]) << endl;

}[/code]

I’ve put a cout command to let me know the name of the parsed histogram, but there is nothing printed…
Any idea on what might be the problem?

P.S.1: If needed to be run, load the code .L code.C++ and then execute pulse_shape(205837, 1, 1)
P.S.2: I am also attaching the initial root file
FIMG-1_205837-0-s1_1-1.root (55.2 KB)

It works for me. Find here a slightly modified version of your code:

#include "TF1.h"
#include "TH1F.h"
#include "TFile.h"
#include "TTree.h"

double exclude(Double_t *x, Double_t *par){//Exclusion fit
   //bool reject;
   if (x[0] > par[2]-par[3] && x[0] < par[2]+par[3]){
      TF1::RejectPoint();
      return 0;
   }
   return par[0] + par[1]*x[0];
}

void pulse_shape(int run, int movie, int det){

// (0) global variable definitions
   std::vector<TH1F*> hists;//Raw signals - input to stac

   double x, x_start, x_end, baseline;// x-values of the signal
   float  y;// y-values of the signal

   int    entries, minimum, minimumBin;

   bool reject;
   

// (1) Get the signals from the TTree and store them individually in a root file as histograms
   for (int mov=0; mov<=movie; mov++){

   // (1a) Read the file
      TFile *fin = new TFile(TString::Format("FIMG-%d_%d-0-s1_1-%d.root", det, run, mov));
      if(!fin) continue;
      if ( !fin->IsOpen() || fin->IsZombie() ) continue;

   // (1b) Get TTree
      TTree *data  = (TTree*)fin->Get("Data");
      if(!data) continue;
      entries = data->GetEntries();
      data->SetBranchStatus("*",0);
      data->SetBranchStatus("signal_x",1); data->SetBranchAddress("signal_x",&x);
      data->SetBranchStatus("signal_y",1); data->SetBranchAddress("signal_y",&y);

   // (1c) Create the histogram to store the movie
      TH1F *h = new TH1F("h", TString::Format("h%d", mov), 2500, 0, 2500);
      for (int i=0; i<entries; i++){
         data->GetEntry(i);
         h->Fill(i,y);
      }

   // (1g) Save the histograms in a root file
      TFile fout(TString::Format("movies_%d_%d.root", run, det), "UPDATE");
      //cout << "Saving File " << fout.GetName() << endl;
      if (h) {h->SetName(TString::Format("h%d", mov)); h->Write(); fout.Close();}

   }

// (2) Process the recorded signals
   for (int mov=0; mov<=movie; mov++){

   // (2a) Open the root file containg the signals
      TFile *fsignals = new TFile(TString::Format("movies_%d_%d.root",run, det));
      if(!fsignals) continue;
      if ( !fsignals->IsOpen() || fsignals->IsZombie() ) continue;
      cout << "File " << fsignals->GetName() << " opened successfully" << endl;

   // (2b) Get the Signal histogram
      TH1F *hIndv = (TH1F*)fsignals->FindObjectAny(TString::Format("h%d;1",mov));   
      if(!hIndv)
      {
		  cout << "hist " << TString::Format("h%d;1",mov) << " does not exist in this file." << endl;
		  fsignals->ls();
		  continue;
	  }
      if (hIndv) cout << "hIndv: " << hIndv->GetName() << " correctly opened." << endl;
      
   // (2c) Find the constant baseline and move the signal to 0
      minimum = hIndv->GetMinimum(0);
      hIndv->GetBinWithContent(minimum,minimumBin,0);
      TF1 *baselineFit = new TF1("baselineFit",exclude,0,2000,4);
      baselineFit->SetParameters(0,0);
      baselineFit->FixParameter(2, minimumBin);
      baselineFit->FixParameter(3, 300);
      hIndv->Fit("baselineFit","WNCQ");
      baseline = baselineFit->GetParameter(0);
      for (int bin = 0; bin<hIndv->GetNbinsX(); bin++){
         hIndv->SetBinContent(bin+1, hIndv->GetBinContent(bin+1)-baseline);
      }
      
   // (2d) Normalize the signal to its maximum value
      hIndv->Scale(1./minimum);

   // (2e) Align the signal in time - maximum point
      for (int bin=1; bin<=2500-minimumBin; bin++){//Start shifting the pulse to the left
         hIndv->SetBinContent(bin, hIndv->GetBinContent(bin+minimumBin));
            for (bin=2500-minimumBin; bin<=2500; bin++){
            hIndv->SetBinContent(bin,0);//End shifting
         }
      }

      hists.push_back(hIndv);

   }

   

   cout << "Hist size is : " << hists.size() << endl;

}

And the output:

root -l
root [0] .L code.C+
Info in <TUnixSystem::ACLiC>: creating shared library /tmp/./code_C.so
root [1] pulse_shape(205837, 1, 1)
Error in <TFile::TFile>: file FIMG-1_205837-0-s1_1-0.root does not exist
File movies_205837_1.root opened successfully
hist h0;1 does not exist in this file.
TFile**		movies_205837_1.root	
 TFile*		movies_205837_1.root	
  KEY: TH1F	h1;2	h1
  KEY: TH1F	h1;1	h1
File movies_205837_1.root opened successfully
hIndv: h1 correctly opened.
Hist size is : 1

It works for you? As is?
I am surprised…
Btw, I am using the standard version in lxplus, 5.34 that is.

I tried your version and it’s working…
But I don’t get why…
I can’t see any big difference.

You were trying to access a NULL pointer. You need to add the else clause as shown below.

if (hIndv) cout << hIndv->GetName() << endl;
else continue;