I seem to have a problem reading a histogram from a TFile, or maybe its my creation of the histogram.
What I am trying to do is simple, as seen on pg. 17 of “Histograms” and pg 3 of “Fitting Hitograms”, is read a histogram and then draw it for analysis.
[quote]
TFile f(“histos.root”);
TH1F h = (TH1F)f.Get(“hgaus”);[/quote]
That correction worked for being able to draw the histogram,
However I am unable to use the histogram. For instance, if I now try to fit the histogram to the profile it was generated with (1./x), I get error message saying that the fit data is empty.
What I am trying to do it call a TFile that contains 66 histograms. Each histogram is a profile I wish to use for for a generation, therefore I must be able to use the histogram that is called from the TFile. Even with adding
lab_profile->SetDirectory(0);
I am unable to use the histogram.
To show this, I edited the previous code to
#include <TFile.h>
#include <TH1.h>
#include <TF1.h>
void gethisto()
{
//Open TFile and get histograms
TFile *fhist = new TFile("beam_Profile.root");
TH1D *lab_profile = (TH1D*)fhist->Get("Blab_smear");
lab_profile->SetDirectory(0);
lab_profile->Draw("ep");
TF1 * f2 = new TF1("f2","[0]/x",1.2,5.5);
lab_profile->Fit("f2","R");
fhist->Close();
}
The error says
[ul]Warning in : Fit data is empty [/ul]
Why is this difficult? I have re-read “Fitting Histograms” where the example listed on page 3 states
void fitexample() {
// open a file and get a histogram
TFile *f = new TFile("hsimple.root");
TH1F *hpx = (TH1F*)f->Get(*hpx);
// Create a TF1 object using the function defined above. The last three // parameters specify the number of parameters for the function.
TF1 *func = new TF1("fit",fitf,-3,3,3);
// set the parameters to the mean and RMS of the histogram func->SetParameters(500,hpx->GetMean(),hpx->GetRMS());
// give the parameters meaningful names
func->SetParNames ("Constant","Mean_value","Sigma");
// call TH1::Fit with the name of the TF1 object
hpx->Fit("fit");
}
Also, try to change the order of your actions. Execute “fhist->Close();” right after you “lab_profile->SetDirectory(0);”
Also, I believe, before you can use your “f2” function, you need to initialize the parameter “0”:
f2->SetParameter(0, SomeValue);
BTW. In future, try to use “GetObject” instead of “Get”: TH1F *hpx;
f->GetObject("File_Resident_TH1F_Name_Required_Here", hpx);
if (!hpx) { std::cout << "Histogram NOT found!" << std::endl; } See the “NOTE:” in http://root.cern.ch/root/html/TDirectoryFile.html#TDirectoryFile:Get
The only problem that I see in your macro is … I believe, before you can use your “f2” function, you need to initialize the parameter “0” (e.g. do it right after you create it using “new TF1”):
f2->SetParameter(0, SomeValue); // e.g. put SomeValue = 1
I get no problem with your code (I added “f2->SetParameter(0, 99);”): root [0] .x gethisto.cxx
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
FCN=2.73954e-05 FROM MIGRAD STATUS=CONVERGED 14 CALLS 15 TOTAL
EDM=2.72271e-17 STRATEGY= 1 ERROR MATRIX ACCURATE
EXT PARAMETER STEP FIRST
NO. NAME VALUE ERROR SIZE DERIVATIVE
1 p0 1.00046e+00 3.76929e-02 2.97000e-02 -1.95774e-07
P.S. The “fitexample” contains a line:
TH1F hpx = (TH1F)f->Get(*hpx);
which doesn’t seem to be correct to me … I thought you used the same construct somewhere in your code.
Are you sure you use exactly the same “beam_Profile.root” file that is attached to your first post?
Is this file present in the subdirectory in which you run the “gethisto.cxx” macro?
[quote=“Pepe Le Pew”]Are you sure you use exactly the same “beam_Profile.root” file that is attached to your first post?
Is this file present in the subdirectory in which you run the “gethisto.cxx” macro?[/quote]
#include <TFile.h>
#include <TH1.h>
#include <TF1.h>
void gethisto()
{
//Open TFile and get histograms
TFile *fhist = new TFile("beam_Profile.root");
TH1D *lab_profile;
fhist->GetObject("Blab_smear",lab_profile);
if (!lab_profile) { std::cout << "Histogram NOT found!" << std::endl; }
lab_profile->SetDirectory(0);
fhist->Close();
lab_profile->Draw("ep");
TF1 * f2 = new TF1("f2","[0]/x",1.2,5.5);
f2->SetParameter(0, 99);
lab_profile->Fit("f2","R");
//To draw a line with number fitted by Pep Le Pew
//TF1 * f3 = new TF1("f3"," 1.00046e+00/x",1.2,5.5);
//f3->Draw("same");
}
Again, I get no problem … root [0] .x gethisto.cxx
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
FCN=2.73954e-05 FROM MIGRAD STATUS=CONVERGED 14 CALLS 15 TOTAL
EDM=2.72271e-17 STRATEGY= 1 ERROR MATRIX ACCURATE
EXT PARAMETER STEP FIRST
NO. NAME VALUE ERROR SIZE DERIVATIVE
1 p0 1.00046e+00 3.76929e-02 2.97000e-02 -1.95774e-07
Maybe try:
TF1 *f2 = new TF1(“f2”, “[0]/x”, 1.5, 4.5);
If the problem is still there … can you try another version of ROOT (I tried 5.28 and 5.34)?
If the problem is “unsolved”, report a bug … give the details of your “Operating System” (version) and your compiler (version).
BTW. You should add “delete fhist;” (so that there’s no memory leak) after “fhist->Close();” or simply instead of it (no need to “Close” it, if you “delete” it).
By using Sumw2() you will use as errors the values stored in the histogram and not the square root of the bin content. For example a bin with zero content can have a non-zero error when using Sumw2().
This can cause a very different behaviour when fitting. In case of the zero bin, it will be for example excluded from the fit (in case of a default least square fit) if you are not using Sumw2()
As far as I know, calling “Sumw2()” may never change the contents of any bins of the histogram.
And as you say, “Sumw2()” may actually increase the number of bins that are used in the fit.
The error, after calling “Sumw2()”, was: “Warning in : Fit data is empty”. How come?
(P.S. The histogram present in the root file that’s attached to the first post in this thread contains no bins with zero contents and it nicely goes like “1/x”, like it was created by simply calling this function when filling. I don’t really understand how calling “Sumw2()” could make it misbehave.)
How ws created the bin with Sumw2() ? If you just call TH1::Sumw2() and then TH1::SetBinContent without calling also TH1::SetBinError, all the errors of the histograms are zero. In this case the histogram cannot be fitted and you get that error message, “Warning in : Fit data is empty”.