Reading Histogram, Histogram drawing Empty

Greetings ROOT’rs

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]

My macro reads

[code]
#include <TFile.h>
#include <TH1.h>
void gethisto()

{
//Open TFile and get histograms

//TFile fhist(“beam_Profile.root”);
TFile *fhist = new TFile(“beam_Profile.root”);

// TH1D lab_profile = (TH1D)fhist.Get(“Blab_smear”);
TH1D lab_profile = (TH1D)fhist->Get(“Blab_smear”);
lab_profile->Draw(“ep”);

//fhist.Close();
fhist->Close();
}[/code]

where I have tried using and not using pointers.
Either case, I do not get an error, all I get is a blank canvas.

Howver is I open beam_Profile I have 2 KEYS

TFile**		beam_Profile.root	
 TFile*		beam_Profile.root	
  KEY: TH1D	B_smear;1	B_smear
  KEY: TH1D	Blab_smear;1	Blab_smear

and I can draw either TH1D from CINT.
What could I be doing wrong.

I have attached my macro and histogram file
Using ROOT 5.32/03

Thanks
Michael
beam_drawer.C (2.18 KB)
beam_Profile.root (33.1 KB)
gethisto.C (365 Bytes)

[url]Copying object from tfiles

[quote=“Pepe Le Pew”][url]Copying object from tfiles

Fantastic, thanks.
However I wonder why this isn’t documented in the reference manuals for Saving/Reading Histograms.

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");
}

TH1F hpx = (TH1F)f->Get(“File_Resident_TH1F_Name_Required_Here”);

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

[quote=“Pepe Le Pew”]TH1F hpx = (TH1F)f->Get(“File_Resident_TH1F_Name_Required_Here”);
[/quote]
How is this different than the syntax in my macro?

TH1D *lab_profile = (TH1D*)fhist->Get("Blab_smear");

I edited as you directed and still am unable to use the histogram, ie. fit the histogram.

[quote]TH1F *hpx;
f->GetObject(“File_Resident_TH1F_Name_Required_Here”, hpx);
if (!hpx) { std::cout << “Histogram NOT found!” << std::endl; }[/quote]

I also have edited to above prescription, and still cannot fit histogram.

EDIT: Since I provided a working macro, are you able to accomplish what I cannot?

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.

I added the “f2->SetParameter(0,1)” as prescribed

root [0] .x gethisto.C 
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
Warning in <Fit>: Fit data is empty

I cannot reproduce your result, and it seems you cannot reproduce mine. Which now leads me to the question as to why?

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]

Yes, and yes.

The histogram draws, just will not be fitted.

Can you repost your current “gethisto.cxx” (just to make sure that there’s no any typo and that I can run it, too)?


#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).

I have tried ROOT versions
5.26
5.30
5.32
5.34

and I get same error with them all.

I will have to report this

Thanks

See resolution at http://savannah.cern.ch/bugs/?97198

Philippe, could you please explain how calling “Sumw2()” may produce a histogram that misbehaves when fitting? And what’s “Sumw()”?

Hi,

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()

Best Regards

Lorenzo

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.)

Hi,

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”.

Lorenzo

O.K. That’s a good point. If he used “SetBinContent” then “Sumw2()” might have been lethal.

What is “Sumw()”? He mentions calling “Sumw()” instead of “Sumw2()”.