Hello, I’m writing a program that should work equally both in ROOT5 and ROOT6. In this program, I find the minima of several histograms using the method TH1F::GetMinimumBin. In some histograms, the minima in ROOT5 and ROOT6 coincide, but in other histograms the minima differ by one bin. Why does this happen and can it be fixed?
Can you provide an example showing the problem ? It is strange it is working for some of them and not for some others. I would guess that if TH1F::GetMinimumBin
differs between version 5 and 6 then all results will be different. So a small reproducer will help.
It’s programm
//
// callib1.c
//
//
// Created by chipxipo on 8/15/16.
//
//
#include <stdio.h>
#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>
#include <TH1.h>
#include <TROOT.h>
#include <iostream>
#include <algorithm>
#include <TFile.h>
#include <TTree.h>
#include <TSpectrum.h>
#include <TMath.h>
#include <vector>
using namespace std;
Float_t rounding(Float_t a){
Int_t N=10; //Number of zeroz - number of decimal places after rounding
Float_t b =a*N;
int tmp=b+0.5;
b=(float)tmp/N;
return b;
}
void summaROOT65(){
cout<<"Please choose one size of the bin from three: 0.1 or 0.05 or 0.025 and enter it"<<endl;
cout<<"SizeBin=";
Float_t SizeBin;
cin>>SizeBin;
Float_t bin;
const Int_t nDet=16;
Int_t npeaks=0;
Double_t ADC4[nDet];
TH1F* spectra4[nDet];
TH1F* spectr[nDet];
Int_t SumAll[nDet];
Int_t SumAll_Bg[nDet];
TH1F* hMin[nDet];
TH1F* h[nDet];
TH1* h_removeBg[nDet];
TH1* spectraBg[nDet];
Float_t xLeft=3;
Float_t xRight=9;
// Int_t nBin=(Int_t)rounding((xRight-xLeft)/SizeBin); //ROOT5
Int_t nBin=(xRight-xLeft)/SizeBin; //ROOT6
TFile *ff_temp=new TFile("testRead.root","recreate");
ff_temp->Close();
TFile *f = new TFile("run0121.root");
TTree* tree;
f->GetObject("calib",tree);
cout<<"nBin="<<nBin<<endl;
for (Int_t j=0;j<nDet;j++)
{
tree->SetBranchAddress(Form("ADC4%d",j),&ADC4[j]);
spectra4[j]=new TH1F(Form("A%d",j),Form("A4%d",j),nBin,xLeft,xRight);
spectr[j]=new TH1F(Form("A%d_removeBg",j),Form("A4%d_removeBg",j),nBin,xLeft,xRight);
}
Int_t nentries=(Int_t)tree->GetEntries();
for (Int_t i=0;i<nentries;i++){
tree->GetEntry(i);
for (Int_t j=0;j<nDet;j++)
spectra4[j]->Fill(ADC4[j]);
}
Float_t* E_peak;
Float_t ** NumberBinMin = new Float_t *[nDet];
Int_t ** Sum = new Int_t *[nDet];
Int_t ** Sum_Bg = new Int_t *[nDet];
struct SumsPeak{
Int_t sum0,sum1,sum2,sum3,sum4,sum_all;
Int_t sum0_Bg,sum1_Bg,sum2_Bg,sum3_Bg,sum4_Bg,sum_all_Bg;
};
SumsPeak SumPeak;
TFile* outputTemp = new TFile("testSplit.root","recreate");
outputTemp->Close();
for (Int_t j=0;j<nDet;j++){
cout<<"spectrum"<<endl;
TSpectrum *s=new TSpectrum();
s->Search(spectra4[j]);
npeaks = s->GetNPeaks();
E_peak=new Float_t[npeaks];
NumberBinMin[j]=new Float_t[npeaks];
Sum[j]=new Int_t[npeaks];
Sum_Bg[j]=new Int_t[npeaks];
//Float_t *x=s->GetPositionX(); //ROOT 5
Double_t *x=s->GetPositionX(); //ROOT 6
// Int_t ind[5]; //ROOT5
Int_t ind[npeaks]; //ROOT6
TMath::Sort(npeaks,x,ind,kFALSE);
for (Int_t i=0;i<npeaks;i++){
E_peak[i]=x[ind[i]];
E_peak[i]=rounding(E_peak[i]);
cout<<" E_peak="<<E_peak[i];
}
cout<<endl;
spectraBg[j]=s->Background(spectra4[j],20,"nosmoothingsame");
spectr[j]->Add(spectraBg[j],spectra4[j],-1);
TFile *ff=new TFile("testRead.root","update");
spectra4[j]->Write();
spectraBg[j]->Write();
spectr[j]->Write();
ff->Close();
//Conctruction the histograms to search the mimimums
Float_t N=0;
Float_t binn=0;
for(Int_t np=0;np<npeaks;np++){
if (np==npeaks-1) E_peak[np+1]=xRight;
else E_peak[np+1]=E_peak[np+1];
N=(E_peak[np+1]-E_peak[np])/SizeBin;
binn=(E_peak[np+1]-E_peak[np])/N;
Int_t NN=(Int_t)rounding(N);
hMin[j]=new TH1F(Form("hMin%d",j),Form("hMin%d",j),NN,E_peak[np],E_peak[np+1]);
for (Int_t m=0;m<NN+1;m++){
Int_t binx=m+(E_peak[np]-xLeft)/SizeBin;
hMin[j]->SetBinContent(m,spectr[j]->GetBinContent(binx));
}
hMin[j]->Smooth(); // Histogram smoothing. You can not do or make with option 2,3, and so on.
NumberBinMin[j][np+1]=hMin[j]->GetMinimumBin();
cout<<"j="<<j<<", np="<<np+1<<", min="<<NumberBinMin[j][np+1]<<endl;
delete hMin[j];
}
//End minimums search
//Splitting the total histogram at several peaks
Float_t left,right;
Float_t binz;
NumberBinMin[j][0]=0;
for(Int_t pp=0;pp<npeaks;pp++){
if (pp==0)
left=xLeft;
else
left=E_peak[pp-1]+NumberBinMin[j][pp]*SizeBin;
right=E_peak[pp]+NumberBinMin[j][pp+1]*SizeBin;
N=(right-left)/SizeBin;
N=(Int_t)rounding(N);
bin=(right-left)/N;
h[j]=new TH1F(Form("h_%d_%d",j,pp),Form("h_%d_%d",j,pp),N,left,right);
h_removeBg[j]=new TH1F(Form("H_Bg_%d_%d",j,pp),Form("H_%d_%d",j,pp),N,left,right);
cout<<" left="<<left<<" right="<<right<<" N="<<N<<" bin="<<bin<<endl;
for (Int_t i=1;i<N+1;i++){
if (pp==0){
h[j]->SetBinContent(i,spectra4[j]->GetBinContent(i));
h_removeBg[j]->SetBinContent(i,spectr[j]->GetBinContent(i));
}
else
{
binz=i+E_peak[pp-1]/SizeBin+NumberBinMin[j][pp]-xLeft/SizeBin;
h[j]->SetBinContent(i,spectra4[j]->GetBinContent(binz));
h_removeBg[j]->SetBinContent(i,spectr[j]->GetBinContent(binz));
}
}
TFile fin("testSplit.root","update");
h[j]->Write();
h_removeBg[j]->Write();
Sum[j][pp]=h[j]->Integral(); //Sum search
Sum_Bg[j][pp]=h_removeBg[j]->Integral();
delete h[j];
delete h_removeBg[j];
fin.Close();
}
}
//End splitting and sums search
cout<<endl;
cout<<" The sum of the entries to the peaks"<<endl;
cout<<" S0 S0_Bg S1 S1_Bg S2 S2_Bg S3 S3_Bg S4 S4_Bg SAll SAll_Bg "<<endl;
cout<<endl;
for (Int_t j=0;j<nDet;j++)
{
for(Int_t i=0;i<npeaks;i++){
if (npeaks==4 && i==1) cout<<" ";
cout.width(6);
cout<<Sum[j][i]<<" ";
cout.width(6);
cout<<Sum_Bg[j][i]<<" ";}
cout.width(6);
SumAll[j]=spectra4[j]->Integral();
cout<<SumAll[j]<<" ";
SumAll_Bg[j]=spectr[j]->Integral();
cout.width(7);
cout<<SumAll_Bg[j];
cout<<endl;
}
//Construction the sum tree
TFile* output =new TFile("Sum.root","update");
TTree* treeSum = new TTree("tree_Sum","The Sum of the entries to the peaks");
treeSum->Branch("SumPeak",&SumPeak,"sum0/I:sum1:sum2:sum3:sum4:sum_all:sum0_Bg:sum1_Bg:sum2_Bg:sum3_Bg:sum4_Bg:sum_all_Bg");
for (Int_t j=0;j<nDet;j++){
SumPeak.sum0=Sum[j][0];
SumPeak.sum1=Sum[j][1];
SumPeak.sum2=Sum[j][2];
SumPeak.sum3=Sum[j][3];
SumPeak.sum4=Sum[j][4];
SumPeak.sum_all=SumAll[j];
SumPeak.sum0_Bg=Sum_Bg[j][0];
SumPeak.sum1_Bg=Sum_Bg[j][1];
SumPeak.sum2_Bg=Sum_Bg[j][2];
SumPeak.sum3_Bg=Sum_Bg[j][3];
SumPeak.sum4_Bg=Sum_Bg[j][4];
SumPeak.sum_all_Bg=SumAll_Bg[j];
treeSum->Fill();
}
treeSum->Write();
output->Close();
// End of construction the sum tree
}
It’ result (partial) in ROOT6
[tsolovyeva@ui1-hlit ~]$ root
-------------------------------------------------------------------------
| Welcome to ROOT 6.06/06 http://root.cern.ch |
| (c) 1995-2016, The ROOT Team |
| Built for linuxx8664gcc |
| From heads/v6-06-00-patches@v6-06-04-66-gb9c1d82, Jul 06 2016, 18:28:55 |
| Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
-------------------------------------------------------------------------
root [0] .x summaROOT65.C
Please choose one size of the bin from three: 0.1 or 0.05 or 0.025 and enter it
SizeBin=0.025
nBin=240
spectrum
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
E_peak=4.8 E_peak=5.3 E_peak=5.5 E_peak=6 E_peak=7.7
j=0, np=1, min=13
j=0, np=2, min=3
j=0, np=3, min=10
j=0, np=4, min=11
j=0, np=5, min=18
left=3 right=5.125 N=85 bin=0.025
left=5.125 right=5.375 N=10 bin=0.025
left=5.375 right=5.75 N=15 bin=0.025
left=5.75 right=6.275 N=21 bin=0.025
left=6.275 right=8.15 N=75 bin=0.025
spectrum
E_peak=4.8 E_peak=5.3 E_peak=5.5 E_peak=6 E_peak=7.7
j=1, np=1, min=13
j=1, np=2, min=4
j=1, np=3, min=10
j=1, np=4, min=13
j=1, np=5, min=11
left=3 right=5.125 N=85 bin=0.025
left=5.125 right=5.4 N=11 bin=0.025
left=5.4 right=5.75 N=14 bin=0.025
left=5.75 right=6.325 N=23 bin=0.025
left=6.325 right=7.975 N=66 bin=0.025
spectrum
E_peak=4.7 E_peak=5.2 E_peak=5.5 E_peak=6 E_peak=7.7
j=2, np=1, min=14
j=2, np=2, min=8
j=2, np=3, min=9
j=2, np=4, min=10
j=2, np=5, min=10
left=3 right=5.05 N=82 bin=0.025
left=5.05 right=5.4 N=14 bin=0.025
left=5.4 right=5.725 N=13 bin=0.025
left=5.725 right=6.25 N=21 bin=0.025
left=6.25 right=7.95 N=68 bin=0.025
spectrum
E_peak=4.8 E_peak=5.3 E_peak=5.5 E_peak=6 E_peak=7.7
j=3, np=1, min=14
j=3, np=2, min=4
j=3, np=3, min=11
j=3, np=4, min=12
j=3, np=5, min=9
left=3 right=5.15 N=86 bin=0.025
left=5.15 right=5.4 N=10 bin=0.025
left=5.4 right=5.775 N=15 bin=0.025
left=5.775 right=6.3 N=21 bin=0.025
left=6.3 right=7.925 N=65 bin=0.025
spectrum
Results (partial) ROOT5
[tsolovyeva@ui1-hlit ~]$ root
*******************************************
* *
* W E L C O M E to R O O T *
* *
* Version 5.34/36 5 April 2016 *
* *
* You are welcome to visit our Web site *
* http://root.cern.ch *
* *
*******************************************
ROOT 5.34/36 (v5-34-36@v5-34-36, Apr 05 2016, 10:25:45 on linuxx8664gcc)
CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] .x summaROOT65.C
Please choose one size of the bin from three: 0.1 or 0.05 or 0.025 and enter it
SizeBin=0.025
nBin=240
spectrum
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
E_peak=4.8 E_peak=5.3 E_peak=5.5 E_peak=6 E_peak=7.7
j=0, np=1, min=13
j=0, np=2, min=3
j=0, np=3, min=11
j=0, np=4, min=12
j=0, np=5, min=18
left=3 right=5.125 N=85 bin=0.025
left=5.125 right=5.375 N=10 bin=0.025
left=5.375 right=5.775 N=16 bin=0.025
left=5.775 right=6.3 N=21 bin=0.025
left=6.3 right=8.15 N=74 bin=0.025
spectrum
E_peak=4.8 E_peak=5.3 E_peak=5.5 E_peak=6 E_peak=7.7
j=1, np=1, min=13
j=1, np=2, min=4
j=1, np=3, min=11
j=1, np=4, min=14
j=1, np=5, min=11
left=3 right=5.125 N=85 bin=0.025
left=5.125 right=5.4 N=11 bin=0.025
left=5.4 right=5.775 N=15 bin=0.025
left=5.775 right=6.35 N=23 bin=0.025
left=6.35 right=7.975 N=65 bin=0.025
spectrum
E_peak=4.7 E_peak=5.2 E_peak=5.5 E_peak=6 E_peak=7.7
j=2, np=1, min=14
j=2, np=2, min=8
j=2, np=3, min=10
j=2, np=4, min=11
j=2, np=5, min=10
left=3 right=5.05 N=82 bin=0.025
left=5.05 right=5.4 N=14 bin=0.025
left=5.4 right=5.75 N=14 bin=0.025
left=5.75 right=6.275 N=21 bin=0.025
left=6.275 right=7.95 N=67 bin=0.025
spectrum
E_peak=4.8 E_peak=5.3 E_peak=5.5 E_peak=6 E_peak=7.7
j=3, np=1, min=14
j=3, np=2, min=4
j=3, np=3, min=12
j=3, np=4, min=13
j=3, np=5, min=9
left=3 right=5.15 N=86 bin=0.025
left=5.15 right=5.4 N=10 bin=0.025
left=5.4 right=5.8 N=16 bin=0.025
left=5.8 right=6.325 N=21 bin=0.025
left=6.325 right=7.925 N=64 bin=0.025
spectrum
It can be seen that the results from np=3 and np=4 do not match. I do not know yet how to attach .root file here. I’ll do it later
Sorry, I incorrectly inserted the code. Please remove it from the topic.
to run your example we need the root file.
run0121.root.zip (2.9 MB)
The original .root file was very large, and it did not turn out to download it. There are less entries in this file, so the values of the minima have changed, but nevertheless it is clear that they are different for ROOT5 and ROOT6.
[tsolovyeva@ui1-hlit ~]$ root
*******************************************
* *
* W E L C O M E to R O O T *
* *
* Version 5.34/36 5 April 2016 *
* *
* You are welcome to visit our Web site *
* http://root.cern.ch *
* *
*******************************************
ROOT 5.34/36 (v5-34-36@v5-34-36, Apr 05 2016, 10:25:45 on linuxx8664gcc)
CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] .x summaROOT65.C
Please choose one size of the bin from three: 0.1 or 0.05 or 0.025 and enter it
SizeBin=0.025
nBin=240
spectrum
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
E_peak=4.8 E_peak=5.5 E_peak=6 E_peak=7.7
j=0, np=1, min=12
j=0, np=2, min=11
j=0, np=3, min=7
j=0, np=4, min=8
left=3 right=5.1 N=84 bin=0.025
left=5.1 right=5.775 N=27 bin=0.025
left=5.775 right=6.175 N=16 bin=0.025
left=6.175 right=7.9 N=69 bin=0.025
spectrum
E_peak=4.8 E_peak=5.3 E_peak=5.5 E_peak=6 E_peak=7.7
j=1, np=1, min=15
j=1, np=2, min=4
j=1, np=3, min=12
j=1, np=4, min=11
j=1, np=5, min=10
left=3 right=5.175 N=87 bin=0.025
left=5.175 right=5.4 N=9 bin=0.025
left=5.4 right=5.8 N=16 bin=0.025
left=5.8 right=6.275 N=19 bin=0.025
left=6.275 right=7.95 N=67 bin=0.025
spectrum
E_peak=4.7 E_peak=5.2 E_peak=5.5 E_peak=6 E_peak=7.7
j=2, np=1, min=15
j=2, np=2, min=7
j=2, np=3, min=9
j=2, np=4, min=15
j=2, np=5, min=9
left=3 right=5.075 N=83 bin=0.025
left=5.075 right=5.375 N=12 bin=0.025
left=5.375 right=5.725 N=14 bin=0.025
left=5.725 right=6.375 N=26 bin=0.025
left=6.375 right=7.925 N=62 bin=0.025
spectrum
E_peak=4.8 E_peak=5.3 E_peak=5.5 E_peak=6 E_peak=7.7
j=3, np=1, min=12
j=3, np=2, min=4
j=3, np=3, min=11
j=3, np=4, min=12
j=3, np=5, min=9
left=3 right=5.1 N=84 bin=0.025
left=5.1 right=5.4 N=12 bin=0.025
left=5.4 right=5.775 N=15 bin=0.025
left=5.775 right=6.3 N=21 bin=0.025
left=6.3 right=7.925 N=65 bin=0.025
......
[tsolovyeva@ui1-hlit ~]$ root
-------------------------------------------------------------------------
| Welcome to ROOT 6.06/06 http://root.cern.ch |
| (c) 1995-2016, The ROOT Team |
| Built for linuxx8664gcc |
| From heads/v6-06-00-patches@v6-06-04-66-gb9c1d82, Jul 06 2016, 18:28:55 |
| Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
-------------------------------------------------------------------------
root [0] .x summaROOT65.C
Please choose one size of the bin from three: 0.1 or 0.05 or 0.025 and enter it
SizeBin=0.025
nBin=240
spectrum
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
E_peak=4.8 E_peak=5.5 E_peak=6 E_peak=7.7
j=0, np=1, min=12
j=0, np=2, min=10
j=0, np=3, min=6
j=0, np=4, min=8
left=3 right=5.1 N=84 bin=0.025
left=5.1 right=5.75 N=26 bin=0.025
left=5.75 right=6.15 N=16 bin=0.025
left=6.15 right=7.9 N=70 bin=0.025
spectrum
E_peak=4.8 E_peak=5.3 E_peak=5.5 E_peak=6 E_peak=7.7
j=1, np=1, min=15
j=1, np=2, min=4
j=1, np=3, min=11
j=1, np=4, min=10
j=1, np=5, min=10
left=3 right=5.175 N=87 bin=0.025
left=5.175 right=5.4 N=9 bin=0.025
left=5.4 right=5.775 N=15 bin=0.025
left=5.775 right=6.25 N=19 bin=0.025
left=6.25 right=7.95 N=68 bin=0.025
spectrum
E_peak=4.7 E_peak=5.2 E_peak=5.5 E_peak=6 E_peak=7.7
j=2, np=1, min=15
j=2, np=2, min=7
j=2, np=3, min=8
j=2, np=4, min=14
j=2, np=5, min=9
left=3 right=5.075 N=83 bin=0.025
left=5.075 right=5.375 N=12 bin=0.025
left=5.375 right=5.7 N=13 bin=0.025
left=5.7 right=6.35 N=26 bin=0.025
left=6.35 right=7.925 N=63 bin=0.025
spectrum
E_peak=4.8 E_peak=5.3 E_peak=5.5 E_peak=6 E_peak=7.7
j=3, np=1, min=12
j=3, np=2, min=4
j=3, np=3, min=10
j=3, np=4, min=11
j=3, np=5, min=9
left=3 right=5.1 N=84 bin=0.025
left=5.1 right=5.4 N=12 bin=0.025
left=5.4 right=5.75 N=14 bin=0.025
left=5.75 right=6.275 N=21 bin=0.025
left=6.275 right=7.925 N=66 bin=0.025
spectrum
I ran your macro… I enter 0.1 … and I get a segfault with ROOT 5 and ROOT 6.
What should I enter ? (I tried other values … same thing).
In macro 3 lines are different depending on the version of the ROOT. This is noted in the comments on the right. I.e
- If the ROOT 5 is started, then
Int_t nBin=(Int_t)rounding((xRight-xLeft)/SizeBin); //ROOT5
// Int_t nBin=(xRight-xLeft)/SizeBin; //ROOT6
If the ROOT6 is started, then
// Int_t nBin=(Int_t)rounding((xRight-xLeft)/SizeBin); //ROOT5
Int_t nBin=(xRight-xLeft)/SizeBin; //ROOT6
- If the ROOT5 is started, then
Float_t *x=s->GetPositionX(); //ROOT 5
// Double_t *x=s->GetPositionX(); //ROOT 6
If the ROOT6 is started, then
// Float_t *x=s->GetPositionX(); //ROOT 5
Double_t *x=s->GetPositionX(); //ROOT 6
- If the ROOT5 is started, then
Int_t ind[5]; //ROOT5
// Int_t ind[npeaks]; //ROOT6
If the ROOT6 is started, then
// Int_t ind[5]; //ROOT5
Int_t ind[npeaks]; //ROOT6
I find weird that you have two different versions one for ROOT5 and one for ROOT6 … That might explain why you get different results ? Before comparing the results I would first try to run exactly the same code with both versions.
// ...
npeaks = s->GetNPeaks();
if (npeaks < 1) { delete s; continue; } // just a precaution
// ...
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,00,00)
Double_t *x; // ROOT 6
#else
Float_t *x; // ROOT 5
#endif
x = s->GetPositionX();
Int_t *ind = new Int_t[npeaks];
// ...
delete [] ind; // no longer needed
// ...
Thank you for solving the problem with the different type of return value for the method x = s->GetPositionX() and the problem of the dimension of the array ind[] . As for the first difference in the macro, it is possible to use the line
Int_t nBin=(Int_t)rounding((xRight-xLeft)/SizeBin);
for ROOT5 and ROOT6, then the macro turns out to be absolutely identical for the two versions of the ROOT. But nevertheless, when I run this macro, I get different minimum values in some cases.
Fix problems reported by: valgrind --tool=memcheck --leak-check=full --suppressions=`root-config --etcdir`/valgrind-root.supp `root-config --bindir`/root.exe -l -q 'summaROOT65.C++g'
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.