Problem with TH1D

Hi all,

I have a macro that give me problems when I use TH1D. In particular I fill using a TTree several TH1D, and it works for many of them but not all. I do not understand why since I manage (or I think to do it) all TH1D in the same way

here in attach the code (simply based on a tutorial):

[code]#include “TROOT.h”
#include “TFile.h”
#include “TTree.h”
#include “TBrowser.h”
#include “TH2.h”
#include “TRandom.h”
#include “stdio.h”
#include “iostream”
#include “fstream”
#include “TCanvas.h”

using namespace std;

// based on: This example is a variant of hsimple.C but using a TTree instead
// of a TNtuple. It shows :
// -how to fill a Tree with a few simple variables.
// -how to read this Tree
// -how to browse and analyze the Tree via the TBrowser and TTreeViewer
// This example can be run in many different ways:
// way1: .x tree1.C using the CINT interpreter
// way2: .x tree1.C++ using the automatic compiler interface
// way3: .L tree1.C or .L tree1.C++
// tree1()
// One can also run the write and read parts in two separate sessions.
// For example following one of the sessions above, one can start the session:
// .L tree1.C
// tree1r();
//
// Author: Rene Brun

Int_t WriteAscii(TH1D *Spectrum, TString SpectrumName);

void tree1r(TString run_name, TString output_name)
{
//read the Tree generated by tree1w and fill two histograms

//note that we use “new” to create the TFile and TTree objects !
//because we want to keep these objects alive when we leave this function.
TFile *f = new TFile(run_name.Data());
TTree rawEvents = (TTree)f->Get(“coincidenceEvents”);

// Definizione variabili del TTree
Double_t energyBGO1, energyBGO2, energyBGO3, energyBGO4, energyBGO5, energyBGO6, energyPulserOnly;
ULong64_t timeStamp;
UChar_t nBGO1, nBGO2, nBGO3, nBGO4, nBGO5, nBGO6, nPulserOnly;
UInt_t extrasBGO1, extrasBGO2, extrasBGO3, extrasBGO4, extrasBGO5, extrasBGO6, extrasPulserOnly;
Bool_t isPulser;

Int_t channel;

FILE *ascii;

// struttura del TTree
rawEvents->SetBranchAddress(“timeStamp”,&timeStamp);
rawEvents->SetBranchAddress(“nBGO1”,&nBGO1);
rawEvents->SetBranchAddress(“energyBGO1”,&energyBGO1);
rawEvents->SetBranchAddress(“extrasBGO1”,&extrasBGO1);
rawEvents->SetBranchAddress(“nBGO2”,&nBGO2);
rawEvents->SetBranchAddress(“energyBGO2”,&energyBGO2);
rawEvents->SetBranchAddress(“extrasBGO2”,&extrasBGO2);
rawEvents->SetBranchAddress(“nBGO3”,&nBGO3);
rawEvents->SetBranchAddress(“energyBGO3”,&energyBGO3);
rawEvents->SetBranchAddress(“extrasBGO3”,&extrasBGO3);
rawEvents->SetBranchAddress(“nBGO4”,&nBGO4);
rawEvents->SetBranchAddress(“energyBGO4”,&energyBGO4);
rawEvents->SetBranchAddress(“extrasBGO4”,&extrasBGO4);
rawEvents->SetBranchAddress(“nBGO5”,&nBGO5);
rawEvents->SetBranchAddress(“energyBGO5”,&energyBGO5);
rawEvents->SetBranchAddress(“extrasBGO5”,&extrasBGO5);
rawEvents->SetBranchAddress(“nBGO6”,&nBGO6);
rawEvents->SetBranchAddress(“energyBGO6”,&energyBGO6);
rawEvents->SetBranchAddress(“extrasBGO6”,&extrasBGO6);
rawEvents->SetBranchAddress(“nPulserOnly”,&nPulserOnly);
rawEvents->SetBranchAddress(“energyPulserOnly”,&energyPulserOnly);
rawEvents->SetBranchAddress(“extrasPulserOnly”,&extrasPulserOnly);
rawEvents->SetBranchAddress(“isPulser”,&isPulser);

// definire spettri
//
TH1D *BGO_single[6];
for(Int_t i = 0 ; i < 6 ; i++)
BGO_single[i] = new TH1D(Form(“BGO_single”),Form(“Single Spectrum BGO%d”,i),2000,0,20000);

TH1D *BGO_Sum = new TH1D(“BGO_Sum”,“Sum_Spectrum”,2000,0,20000);

TH1D *MultSpectra[6];
for(Int_t i = 0 ; i < 6 ; i++)
MultSpectra[i] = new TH1D(Form(“MultSpectra”),Form(“Spectrum with Multiplicity %d”,i),2000,0,20000);

TH1D *BGO1_file = (TH1D *)f->Get(“EnergySpectra/BGO1”);
//
// fine definizione spettri

//Definizioni variabili
Double_t Time0 = 0.;
Double_t Energy_SUM = 0.;
Int_t multiplicity = 0;
Double_t Sum_Energy = 0.;

//loop over the TTree
Long64_t nentries = rawEvents->GetEntries();
cout << nentries << endl;
for (Long64_t i=0;i<nentries/10;i++) {
rawEvents->GetEntry(i);
// cut su spettro somma
Sum_Energy = energyBGO1 + energyBGO2 + energyBGO3 + energyBGO4 + energyBGO5 + energyBGO6;
multiplicity = nBGO1 + nBGO2 + nBGO3 + nBGO4 + nBGO5 + nBGO6;
if(Sum_Energy > 7000 && Sum_Energy < 8700){
if(nBGO1 != 0)
BGO_single[0]->Fill(energyBGO1);
if(nBGO2 != 0)
BGO_single[1]->Fill(energyBGO2);
if(nBGO3 != 0)
BGO_single[2]->Fill(energyBGO3);
if(nBGO4 != 0)
BGO_single[3]->Fill(energyBGO4);
if(nBGO5 != 0)
BGO_single[4]->Fill(energyBGO5);
if(nBGO6 != 0)
BGO_single[5]->Fill(energyBGO6);

		MultSpectra[multiplicity-1]->Fill(Sum_Energy);
		BGO_Sum->Fill(Sum_Energy);
	}
		
 	
 }
 	
 	
 TCanvas *c1 = new TCanvas("c1","canvas",800,600);
 c1->cd(1);	
BGO_Sum->Draw();

TCanvas *c2 = new TCanvas(“c2”,“Single Spectra”,800,600);
c2->Divide(2,3);
for(Int_t i = 0 ; i < 6 ; i++){
c2->cd(i+1);
BGO_single[i]->Draw();
}
TCanvas *c3 = new TCanvas(“c3”,“Single Spectra”,800,600);
c3->Divide(2,3);
for(Int_t i = 0 ; i < 6 ; i++){
c3->cd(i+1);
MultSpectra[i]->Draw();
}
f->Close();

TFile *output = new TFile(output_name.Data(),“RECREATE”);
if (output->IsZombie()) {
cout << “Error opening file” << endl;
exit(-1);
}
/for(Int_t i = 0 ; i < 6 ; i++){
BGO_single[i]->Write();
MultSpectra[i]->Write();
}
/
BGO_single[2]->Write(“spettro_somma”,TObject::kOverwrite);
//output->Write();
output->Close();

for(Int_t i = 0 ; i < 6 ; i++){
	WriteAscii(BGO_single[i], Form("BGO_%d_Single.asc",i+1));
	WriteAscii(MultSpectra[i], Form("MultSpectra_%d.asc",i+1));
}
//WriteAscii(BGO_Sum, "BGO_SUM.asc");


return;

}

Int_t WriteAscii(TH1D *Spectrum, TString SpectrumName){

ofstream ascii(SpectrumName.Data()); //se il file non esiste lo crea, altrimenti lo sovrascrive!
if(!ascii) {
    cout << "Errore nella creazione del file!";
    return -1;
}	

Int_t NumberBins = Spectrum->GetNbinsX();

for(Int_t i = 0 ; i < NumberBins + 1 ; i++){
	ascii << Spectrum->GetBinContent(i) << endl;	
}
ascii.close();
return 0;

}

[/code]

when I draw the TH1D I cannot draw the BGO_single[5], the MultSpectra[5] and BGO_Sum but I can draw the others and I am sure that in the TTree the data of BGO6 are good.

when I use the method Write() I can save on file all spectra except them and the same when I use the function WriteAscii

it crashes with this log:

[code]root [5] tree1r("…/run0137_ttreeCoinc.root",“run0137_Anto.root”)
Warning in TFile::Append: Replacing existing TH1: BGO_single (Potential memory leak).
Warning in TFile::Append: Replacing existing TH1: BGO_single (Potential memory leak).
Warning in TFile::Append: Replacing existing TH1: BGO_single (Potential memory leak).
Warning in TFile::Append: Replacing existing TH1: BGO_single (Potential memory leak).
Warning in TFile::Append: Replacing existing TH1: BGO_single (Potential memory leak).
Warning in TFile::Append: Replacing existing TH1: MultSpectra (Potential memory leak).
Warning in TFile::Append: Replacing existing TH1: MultSpectra (Potential memory leak).
Warning in TFile::Append: Replacing existing TH1: MultSpectra (Potential memory leak).
Warning in TFile::Append: Replacing existing TH1: MultSpectra (Potential memory leak).
Warning in TFile::Append: Replacing existing TH1: MultSpectra (Potential memory leak).
31499118
Warning in TCanvas::Constructor: Deleting canvas with same name: c1
Warning in TCanvas::Constructor: Deleting canvas with same name: c2
Warning in TCanvas::Constructor: Deleting canvas with same name: c3

*** Break *** segmentation violation

Thread 6 (Thread 0x1503 of process 15004):
#0 0x00007fff8e6f694a in ?? ()
#1 0x00007fff8e6126c3 in ?? ()
#2 0x0000000002000170 in ?? ()
#3 0x0000000000000000 in ?? ()

Thread 5 (Thread 0x1403 of process 15004):
#0 0x00007fff8e6f694a in ?? ()
#1 0x00007fff8e6126c3 in ?? ()
#2 0x0000000002000170 in ?? ()
#3 0x0000000000000000 in ?? ()

Thread 4 (Thread 0x1303 of process 15004):
#0 0x00007fff8e6f694a in ?? ()
#1 0x00007fff8e6126c3 in ?? ()
#2 0x0000000002000170 in ?? ()
#3 0x0000000000000000 in ?? ()

Thread 3 (Thread 0x1203 of process 15004):
#0 0x00007fff8e6f14de in ?? ()
#1 0x00007fff8e6f064f in ?? ()
#2 0x00007fff00000000 in ?? ()
#3 0x0000000000000000 in ?? ()

Thread 2 (Thread 0x1103 of process 15004):
#0 0x00007fff8e6f7232 in ?? ()
#1 0x00007fff8e7cad91 in ?? ()
#2 0x0000000000000000 in ?? ()

Thread 1 (Thread 0x1003 of process 15004):
#0 0x00007fff8e6f691a in ?? ()
#1 0x00007fff8ea10228 in ?? ()
#2 0x0000000000000000 in ?? ()[/code]

In ROOT objects are identified by name, and they must have unique names. In your code they don’t. Modify it in following way

[code] for(Int_t i = 0 ; i < 6 ; i++)
BGO_single[i] = new TH1D(Form(“BGO_single_%d”, i),Form(“Single Spectrum BGO%d”,i),2000,0,20000);

for(Int_t i = 0 ; i < 6 ; i++)
MultSpectra[i] = new TH1D(Form(“MultSpectra_%d”, i),Form(“Spectrum with Multiplicity %d”,i),2000,0,20000);[/code]

I don’t understand why you have problems with BGO_sum, it should works fine.

Hi rlalik,

I did remove your modification since with that the program does not draw any spectrum.

with this change it does not crash but it seems that the spectra are empty since also the ascii files are completely empty (while in the previous versione if I did not use the function on problematic spectra the .asc files where full of numbers

ciao
Antonio

Can you provide input file with root tree for tests?

here you are
thanks a lot
ciao
Antonio

dl.dropboxusercontent.com/u/164 … t_run.root

Your script is working perfect, with one but… You are closing file f to early:

Move this line to the last before return keyword and will work OK. And apply also my changes I suggested in my first reply, you need unique names for objects.

hi,

thanks a lot, now it save the spectra in the File and also it produce the .asc files correctly. Still it opens empty canvas … but I do not understand why

PS: I also do not understand why the file should be close a the end while the spectra where already created and filled

The histograms you are plotting belong to the file you close.
If you close the file they disappear.
I you want to close the file and see the plots, you can modify the plotting part of your code as follow :

   TCanvas *c1 = new TCanvas("c1","canvas",0,0,800,600);
   c1->cd(1);
   BGO_Sum->SetDirectory(0);
   BGO_Sum->Draw();

   TCanvas *c2 = new TCanvas("c2","Single Spectra",0,0,800,600);
   c2->Divide(2,3);
   for (Int_t i = 0 ; i < 6 ; i++) {
      c2->cd(i+1);
      BGO_single[i]->SetDirectory(0);
      BGO_single[i]->Draw();
   }


   TCanvas *c3 = new TCanvas("c3","Single Spectra",0,0,800,600);
   c3->Divide(2,3);
   for(Int_t i = 0 ; i < 6 ; i++){
      c3->cd(i+1);
      MultSpectra[i]->SetDirectory(0);
      MultSpectra[i]->Draw();
   }

thank you all of you!

ciao
Antonio