Home | News | Documentation | Download

How to improve exponential decay fit

Dear all,

Could anyone please suggest to me how I can improve this exponential decay fit?

Here is the input file I am reading from

2	3692
4	2356
6	1555
8	949
10	607
12	410
14	247
16	173
18	126
20	90
22	66
24	44
26	36
28	40
30	30
32	26
34	26
36	24
38	19
40	23
42	25
44	23
46	22
48	20
50	19
52	13
54	17
56	22
58	12
60	16
62	14
64	14
66	12
68	27
70	8
72	15
74	15
76	12
78	21
80	20
82	6
84	11
86	14
88	9
90	16
92	11
94	10
96	12
98	7
100	18

Here is my code that attempts to fit the data

// Plot C2_exponentialDecayOverlapping.dat

# include <iostream>
# include <fstream>
# include <math.h>
# include <iomanip>
# include <cmath>
# include <stdlib.h>
# include <cstdlib>
//# include <fstream.h>
# include <string.h>
# include <string>
//# include <dos.h> //For Sleep() 

# include "TROOT.h"
# include "TFile.h"
# include "TTree.h"
# include "TBrowser.h"
# include "TH1.h"
# include "TH2.h"
# include "TH3.h"
# include "TRandom.h"

int main(){
	
	// controls
	char inputFileName[50] = "C2_exponentialDecayOverlapping.dat";
	Int_t NumOfLines = 50;
	Int_t nArray = NumOfLines + 1;
	bool WantToFit = true; // switch for fitting
	
	char GraphTitle[10] = "C2";
	char GraphXLabel[10] = "X";
	char GraphYLabel[10] = "Y";
	
	char FitFunc[30] =  "expo"; // "[0] * exp ( t * [1] )";
	char DrawOption[10] = "AP" ; // see https://root.cern.ch/doc/master/classTGraphPainter.html
	int xmin = 0;
	int xmax = 100;
	
   // create the coordinate arrays
   Double_t x[nArray];
   Double_t y[nArray]; 
   
    // create the error arrays
  // Double_t dx[5] = {0};
 //  Double_t dy[nArray];
	
	ifstream inFile;
	inFile.open(inputFileName,ios::in);
	
	if(inFile.is_open()){
		cout<<"Input File was opened successfully"<<endl;
	}
	
	//Main loop filling arrays from file//
	inFile>>x[0]>>y[0];
	cout<<x[0]<<setw(20)<<y[0]<<endl;
	
	for(int i = 0; i < NumOfLines; i++){
		
		inFile>>x[i]>>y[i];
		//cout<<x[i]<<setw(20)<<y[i]<<endl;
		
	}
	
	inFile.close();
	
	cout << "Creating canvas" << endl;
	// create the canvas
   TCanvas *c1 = new TCanvas("c1",GraphTitle,200,10,700,500);
   c1->SetGrid();
   
   // create the TGraphErrors and draw it
   TGraphErrors *gr = new TGraphErrors(nArray,x,y);
   // change title and axes titles here
   gr->SetTitle("C2;X;Y");
   gr->SetMarkerColor(4);
   gr->SetMarkerStyle(21);
   TAxis *axis = gr->GetXaxis();
   axis->SetLimits(x[0],100);
   gr->Draw(DrawOption); 
   
      	// Define Fit Function
	if (WantToFit){
		TF1 *f = new TF1("f", FitFunc, xmin, xmax);
		//f->SetParNames("A0","A1","A2");
		f->SetParameters(100,-0.02);
			
		gr->Fit(f, "B");
		cout << "Fitting" << endl;
	}
	

   c1->Update();
   
	return 0;
}

I have attached the attempted plot. C2.pdf (14.5 KB)

You should just convert your script to C++ :wink:

  • use const char *, not fixed-size char arrays
  • use std::vector, not fixed-size double arrays
  • and most crucially, fix the ifstream reading loop.

Your issue was that you had 50 elements but only read 49 lines. That meant one bogus number, and that meant the fit didn’t converge. The attached version fit.C (1.8 KB) fixes that! It also makes the code simpler, more readable, and more stable: less magic buffer-size number etc. So there’s plenty of motivation to try out some more advanced C++ :slight_smile:

Cheers, Axel.