Inconsistent behaviour from fit

Hi, I have a macro which fits more or less a custom error function/vertically reflected Fermi-Dirac distribution to data point from a threshold scan for all pixels on chip of 1024x512 pixels. In the case of most (99%) of pixels this works fine, with some curves being refit if the detected parameters seems unreasonable (though these tests are hard to perform as these ‘bad fits’ still return IsValid=TRUE), and due to their being thousands of bad fits it is impossible to go through on a case by case basis. However, 1% of pixels still have issues fitting, with the fit gradients being far steeper than true. What is stranger than this, however, is that when I extract these original threshold scan data from my tree and fit using exactly the same function, range, and initial parameters in a separate macro, the fit is perfect, but no matter how many times I try and refit within the original macro I cannot reproduce these correct fits. Example of the issue produced by the second macro, with the original fit parameters shown in red, and the correct fit in green.


Macro for reading data into tree and performing original hits:
AnalyseT2.C (6.6 KB)

Data file for reading which isn’t 1GB (think it should still contain some dubious fits)
row0.txt (1.5 MB)

Fit code used in secondary macro (which produces above figure):

 for(int j = 0 ;j<myHit.GetSize(); ++j){
	    
	    PlotHit->SetPoint(j,100-j,myHit[j]);
	  }
	  TCanvas *plotdodge=new TCanvas();
      //fit object to show fit from AnalyseT macro
	  TF1 *f2 = new TF1("f1","100/(1+exp(([0]-x)/[1]))",5,55);
      //fit obejct to refit graph
	  TF1 *f1 = new TF1("f1","100/(1+exp(([0]-x)/[1]))",5,55);
	  f2->SetParName(0,"Threshold");
	  f2->SetParName(1,"Response");
	  f2->SetParameters(*myThresh,0.5);
	  
      PlotHit->SetMarkerStyle(5);
      PlotHit->SetMarkerSize(2);
      //fix f1 to keep old parameters 
	  f1->FixParameter(0,*myThresh);
	  f1->FixParameter(1,*myResponse);

      //plot old and new fits on same canvas
	  plotdodge->cd();
	  PlotHit->Draw("AP");
      f2->SetLineColor(3);
	  PlotHit->Fit(f2);
	  f1->Draw("same");
	  plotdodge->Update();

Is it likely launching something like this second macro segment from the first would help? At present I am just ignoring results with seemingly bad gradients, but would ideally like to have a complete data set.

In AnalyseT2.C you do not need to use new to create the TGraph and TF1 the following with reduce your memory management:

TGraph plot(Npoints,PlsH,Hits);
...
TF1 f1("f1","100/(1+exp(([0]-x)/[1]))",fitstart,fitend);

Also, the values for the tree don’t seem to set the values if the fit is good?

if(f1->IsValid() && MaxGrad>300 && Response>ResponsERR && chisq<2 && Threshold>10){

   GoodFit=true;

   //Need to set vaules to be written to the tree!
   Threshold= f1->GetParameter(0);
   ThreshError= f1->GetParError(0);
   Response= f1->GetParameter(1);
   ResponsERR=f1->GetParError(1);
   MaxGrad=25/Response;
   GradERR=MaxGrad*(ResponsERR/Response);


   //delete graph objects to prevent memory leaks 
   PLOT->Delete();
   f1->Delete();

//fit again if above critera not met, still not perfect but helps a lot...
}else{
                    
   ...
}
//write current values of branch variables to TTree
tree->Fill();  

Hi, Cheers for the help- though it certainly didn’t stop the strange fit behavior. Also the constructor changes just lead to loads of pointer mess which is whole rabbit hole I don’t currently have time to go down- the code runs reasonably fast without crashing my computer so I’m satisfied for now on that front!
I’ve also noticed that (much neater and more efficient code) written for this same purpose by much better programmers than I also seems to ‘throw away’ quite a lot of values, I assume also from bad fits. Is this a known issue when performing thousands of fits rapidly compared to performing just one?

I’'m not sure what you mean here, but you will need to change the member access operator from -> to . . And then you will no longer need to worry about deleting the objects as the memory management will be performed automatically. Your solution is fine as well.

What do you mean by, “throw away values”? Do you have an example? It is possible that they were only interested in a subset of the data from the fitting?

After having another look at your code I see that you are indeed setting the branch values correctly, I missed it on the first pass. However, your fitting is missing the “R” option for fitting, “Use the Range specified in the function range”. This may help your situation.

In addition, you may try “M” (More. Improve fit results. It uses the IMPROVE command of TMinuit (see TMinuit::mnimpr). This algorithm attempts to improve the found local minimum by searching for a better one.), as well as “E” (Perform better Errors estimation using Minos technique) since you are interested in the errors.

I mean that in the Hitmaps produced by this other code, there is a random looking distribution of blank points, where the highest values produced (potentially from bad fits) are excluded.

Using “R” seems to cause all fits to fit to parameters outside of my initially specified range, I think M might help a little bit, however. My main source of confusion remains as to why an external macro has no issues whatsoever fitting correctly to data which could not be fit correctly in the initial macro despite using an identical fit function and settings.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.