Warning in <Fit>: Fit data is empty

I have written a C++ code that I compile with g++, and I am using ROOT libraries.

I have a code that looks at data files, does a simple curve fit, and outputs the parameters.

The code works fine for 1,000 sequential files without any errors.

If I try to do randomly addressed data files though, the code crashes around 350 files. I get the error

“Warning in : Fit data is empty”

after about 350 data files. Remember these are randomly selected data files, and it consistently generates this error around 350 files, so I think this is some kind of memory error.

What are the causes of that kind of error? How can I make sure there are no memory issues with TF1?

Here is the sub-loop. There is more code around this, but I think the memory management might be coming from in here:


        for(int n = 0; n < length; n++) {
          t1->GetEntry(n);
          double fitpar[3];
          TH1F* Leakage = new TH1F("Leakage","Leakage", 12, -0.5, 11.5);
          for(int tbin = 0; tbin < 12; tbin++) {
            double sigsum = 0;
            double sigave = 0;
            for(int det = 0; det < ndets; det++) {
              double signal = detector[det]->EvalInstance(tbin);
              sigsum += signal;        
            } // loop over detectors
            sigave = sigsum/ndets;
            Leakage->Fill(tbin,sigave);
          }
          TF1 *polyfit = new TF1("polyfit","pol3",0,11);
          TCanvas* LCanvas=new TCanvas("Leakage","",1440,900);
          Leakage->Fit("polyfit","q");
          delete LCanvas; 
          polyfit->GetParameters(fitpar);
          Poly0->Fill(fitpar[0]);
          Poly1->Fill(fitpar[1]);
          Poly2->Fill(fitpar[2]);
          Poly3->Fill(fitpar[3]);
          delete Leakage;
          delete polyfit;
        }

What could be causing this?

Hi,
Difficult to say. It seems that one of the histogram you are trying to fit is all empty (has zero bin content).
If this is not the case, and you get the error fitting that histogram, I would need to have your running code to understand your problem

Cheers

Lorenzo

[quote=“moneta”]Hi,
Difficult to say. It seems that one of the histogram you are trying to fit is all empty (has zero bin content).
If this is not the case, and you get the error fitting that histogram, I would need to have your running code to understand your problem

Cheers

Lorenzo[/quote]

Hello,

I posted the code above. Here is latest version, with the same error.

int lcheck(int r, int leak[]) { for(int k=0;k<2500;k++) { leak[k] = 0; } TTree* t1=new TTreeRaw(r); int length = t1->GetEntries(); const int ndets = 48; TTreeFormula** detector=new TTreeFormula*[ndets]; for(int j = 0; j < ndets; j++) { detector[j] = new TTreeFormula("",Form("det[][%i]",j),t1); } double fitpar[3]; for(int n = 0; n < length; n++) { t1->GetEntry(n); TH1F* Leakage = new TH1F("Leakage","Leakage", 12, -0.5, 11.5); for(int tbin = 0; tbin < 12; tbin++) { double sigsum = 0; double sigave = 0; for(int det = 0; det < ndets; det++) { double signal = detector[det]->EvalInstance(tbin); sigsum += signal; } sigave = sigsum/ndets; Leakage->Fill(tbin,sigave); } TF1 *polyfit = new TF1("polyfit","pol3",0.,11.); Leakage->Fit("polyfit","q","",0,11); polyfit->GetParameters(fitpar); if(fitpar[0] < -.67 && fitpar[0] > -.88) { if(fitpar[1] > .24 && fitpar[1] < .31) { if(fitpar[2] < -.039 && fitpar[2] > -.052) { if(fitpar[3] > .0013 && fitpar[3] < .0018) { leak[n] = 1; } } } } delete Leakage; delete polyfit; } delete t1; delete [] detector; return 0; }

The code works and fits perfectly up until a certain number of calls, after which it gives the empty fit error every time.

Hi,

Thank you for the code, but I would need to run the code to reproduce the problem and understand it. Just looking at the code it is difficult to find the problem.
You create in the macro a TTreeRaw object. What is it ?

Best Regards

Lorenzo

[quote=“moneta”]Hi,

Thank you for the code, but I would need to run the code to reproduce the problem and understand it. Just looking at the code it is difficult to find the problem.
You create in the macro a TTreeRaw object. What is it ?

Best Regards

Lorenzo[/quote]

Hello,

I am creating it so I can read entries into it from a root tree with data. It is an array of signal data over a period of time for different detectors, with additional header data.

The part that is confusing is that this code works perfectly up to about 350 runs. What kind of memory leak could I be having by using the ROOT calls?

Hi,

Try maybe to run the code with Valgrind. But if the message says the data is empty it means the histogram is empty.
Looking better at your code I see a potential problem here:

 for(int det = 0; det < ndets; det++) {
        double signal = detector[det]->EvalInstance(tbin);
        sigsum += signal;        
      }
      sigave = sigsum/ndets;
      Leakage->Fill(tbin,sigave);

Are you sure sigsum is not zero ? Because if the histogram is filled with all zero then you will get such message. So maybe you want to skip those histograms with all zero. You can check it using TH1::Integral or TH1::GetSumOfWeights.
If for you zero is a valid value (i.e. you don’t want to esclude bins with zero), then you should use the fit option “WW”. I think also using the square root of the bin content as error in the fit is really correct in your case.
Also , I would create a TGraph instead of a TH1F and fit that object. It is more appropriate for your case.

Regards
Lorenzo

[quote=“moneta”]Hi,

Try maybe to run the code with Valgrind. But if the message says the data is empty it means the histogram is empty.
Looking better at your code I see a potential problem here:

 for(int det = 0; det < ndets; det++) {
        double signal = detector[det]->EvalInstance(tbin);
        sigsum += signal;        
      }
      sigave = sigsum/ndets;
      Leakage->Fill(tbin,sigave);

Are you sure sigsum is not zero ? Because if the histogram is filled with all zero then you will get such message. So maybe you want to skip those histograms with all zero. You can check it using TH1::Integral or TH1::GetSumOfWeights.
If for you zero is a valid value (i.e. you don’t want to esclude bins with zero), then you should use the fit option “WW”. I think also using the square root of the bin content as error in the fit is really correct in your case.
Also , I would create a TGraph instead of a TH1F and fit that object. It is more appropriate for your case.

Regards
Lorenzo[/quote]

Yes, I am sure the data are non-zero. There is no problem with the data. That is why this error is puzzling.

Let me give an example: I can start my data analysis anywhere in the data library, and regardless of where I start, I always encounter this same fit error about 2-300 files in. If I start closer to those files, it correctly reads them and there is no problem. But I always get these errors after a few hundred runs, and then they trigger for every single run after that. Once I start getting the error, I always get it.

What does this mean?

I wonder how CINT is being used behind the scenes; I’ve seen that CINT handles certain things in a way that in some cases it will just refuse to function after enough “operations” resulting to exactly the same symptoms as described here: everything works for a while and after that it breaks and won’t recover resulting to, perhaps puzzling, error messages thereafter.

I have this exact same question. I wish I knew what was going on! I am happy to write new subroutines, but I have no idea what to do differently.

Hi,
Can you not simplify your code, so it can be run by other people to reproduce this problem? Otherwise it is dufficult to progress on this…

Cheers

Lorenzo

Some quick ideas:
-If the problem is the same what I’ve seen, it might be detectable by looking at the (number of) temp files ROOT produces while running the program.
-If not, commenting out e.g. the fitting part and seeing whether it affects the “350 limit” might give a hint of the culprit.
-Can you run the program in a debugger to see what’s going on? If that’s not possible, providing a test case might help someone else to do it.

[quote=“tc3t”]Some quick ideas:
-If the problem is the same what I’ve seen, it might be detectable by looking at the (number of) temp files ROOT produces while running the program.
-If not, commenting out e.g. the fitting part and seeing whether it affects the “350 limit” might give a hint of the culprit.
-Can you run the program in a debugger to see what’s going on? If that’s not possible, providing a test case might help someone else to do it.[/quote]

The problem is that the code keeps running, but this subroutine stops functioning. It never actually crashes.

How do you monitor ROOT temp files?

I later realised that the temp file thing might not help, sorry. Anyway the idea was to simply look at the system temp-folder where ROOT produces the temp files. The program does not need to crash in order to use debugger: e.g. setting breakpoint to line producing “Warning in : Fit data is empty” might be a good starting point.

FYI, this can happen even if the bin contents are not all zero; it will also happen if all bin errors are zero, regardless of the bin contents. This won’t normally happen if you’re using TH1 as intended.