Home | News | Documentation | Download

Curve-fitting in PYROOT showing very high chi-2 values

ROOT Version: root_v6.20.04.
I am using pyroot for curve-fitting and I am getting very high chi-2 values. The fit looks ok visually but the fitting results are very odd. Kindly let me know what might be the error. Regardless of what initial parameters I use I get very high Chi-2 values and sometimes the NDF value comes out to be zero. I am new to Root kindly help me with this.

Link to my data files

Here is my code

import numpy as np
import matplotlib.pyplot as plt
#Comment the line below if we are not using pyroot. Also comment the entire section for plotting light curve with pyroot towards the end of the code.
import ROOT as root

n4 = open("glg_tte_n4_bn190114873_v03_ascii_0.09_final.dat","r")
n8 = open("glg_tte_n8_bn190114873_v00_ascii_0.09_final.dat","r")
n3 = open("glg_tte_n3_bn190114873_v00_ascii_0.09_final.dat","r")
n7 = open("glg_tte_n7_bn190114873_v00_ascii_0.09_final.dat","r")
#line = f.readline()
alllinesn4 = n4.readlines()
alllinesn8 = n8.readlines()
alllinesn3 = n3.readlines()
alllinesn7 = n7.readlines()
#print alllines[9]  
#10th line (9th since python counting starts from 0) has number of energy channels and time bins.
nEchannelsn4=int(alllinesn4[9].split()[0])
nTimebinsn4=int(alllinesn4[9].split()[1])
nEchannelsn8=int(alllinesn8[9].split()[0])
nTimebinsn8=int(alllinesn8[9].split()[1])
nEchannelsn3=int(alllinesn3[9].split()[0])
nTimebinsn3=int(alllinesn3[9].split()[1])
nEchannelsn7=int(alllinesn7[9].split()[0])
nTimebinsn7=int(alllinesn7[9].split()[1])
print "Number of energy channels in n4= ",nEchannelsn4
print "Number of time bins in n4= ",nTimebinsn4
print "Number of energy channels in n8= ",nEchannelsn8
print "Number of time bins in n8= ",nTimebinsn8
print "Number of energy channels in n3= ",nEchannelsn3
print "Number of time bins in n3= ",nTimebinsn3
print "Number of energy channels in n7= ",nEchannelsn7
print "Number of time bins in n7= ",nTimebinsn7
##Below this line the starting and ending values of each energy channel are given. The starting value is in the left column and the ending value is in the right column. We call them Estart and Eend.

##Create empty numpy arrays for each energy channels Estart and Eend
Estartn4=np.zeros(nEchannelsn4)
Eendn4=np.zeros(nEchannelsn4)
Estartn8=np.zeros(nEchannelsn8)
Eendn8=np.zeros(nEchannelsn8)
Estartn3=np.zeros(nEchannelsn3)
Eendn3=np.zeros(nEchannelsn3)
Estartn7=np.zeros(nEchannelsn7)
Eendn7=np.zeros(nEchannelsn7)
#Fill Estart and Eend arrays
for ie in range(nEchannelsn4):
  il=11+ie
  Estartn4[ie]=(alllinesn4[il].split()[0])
  Eendn4[ie]=(alllinesn4[il].split()[1])
  print Estartn4
  print ie
  print alllinesn4[ie].split()[0]

for ie in range(nEchannelsn8):
  il=11+ie
  Estartn8[ie]=(alllinesn8[il].split()[0])
  Eendn8[ie]=(alllinesn8[il].split()[1])
  print ie
  print alllinesn8[ie].split()[0]
for ie in range(nEchannelsn3):
  il=11+ie
  Estartn3[ie]=(alllinesn3[il].split()[0])
  Eendn3[ie]=(alllinesn3[il].split()[1])
  print ie
  print alllinesn3[ie].split()[0]
for ie in range(nEchannelsn7):
  il=11+ie
  Estartn7[ie]=(alllinesn7[il].split()[0])
  Eendn7[ie]=(alllinesn7[il].split()[1])
  print ie
  print alllinesn7[ie].split()[0]
#print il
#print alllines[il+1]
#The line right after the energy channel Estart and End columns (with line number il+1), gives the formatting of the lines below this. ; Tstart(s), Tend(s), RateCh1(ct/s), ErrRateCh1(ct/s), BgdCh1(ct/s), ErrBgdCh1(ct/s), RateCh2(ct/s), ErrRateCh2(ct/s), BgdCh2(ct/s), ErrBgdCh2(ct/s), ... 
#This means that Each row has the following values at the beginning
#Tstart for that time bin
#Tstop for that time bin
#The rest of the columns have values for each energy channel as decribed below.
#The number of energy channels is 128 for all NaI and BGO detectors. For each of these channels, the following values are given.
#Rate in channel in counts per second.
#Error on rate in channel in counts per second
#Background in channel in counts per second
#Error on background in channel in counts per second.
#=> There should be 128*4 + 2 columns for each time bin =514. This is the second the number of columns in the numpy array (ssecond index).
#create empty array for Tstart, Tend and channel contents and their errors
Tstartn4=np.zeros(nTimebinsn4)
Tendn4=np.zeros(nTimebinsn4)
Countsn4=np.zeros((nTimebinsn4,nEchannelsn4))
Countserrn4=np.zeros((nTimebinsn4,nEchannelsn4))
Backgn4=np.zeros((nTimebinsn4,nEchannelsn4))
Backgerrn4=np.zeros((nTimebinsn4,nEchannelsn4))

Tstartn8=np.zeros(nTimebinsn8)
Tendn8=np.zeros(nTimebinsn8)
Countsn8=np.zeros((nTimebinsn8,nEchannelsn8))
Countserrn8=np.zeros((nTimebinsn8,nEchannelsn8))
Backgn8=np.zeros((nTimebinsn8,nEchannelsn8))
Backgerrn8=np.zeros((nTimebinsn8,nEchannelsn8))

Tstartn3=np.zeros(nTimebinsn3)
Tendn3=np.zeros(nTimebinsn3)
Countsn3=np.zeros((nTimebinsn3,nEchannelsn3))
Countserrn3=np.zeros((nTimebinsn3,nEchannelsn3))
Backgn3=np.zeros((nTimebinsn3,nEchannelsn3))
Backgerrn3=np.zeros((nTimebinsn3,nEchannelsn3))

Tstartn7=np.zeros(nTimebinsn7)
Tendn7=np.zeros(nTimebinsn7)
Countsn7=np.zeros((nTimebinsn7,nEchannelsn7))
Countserrn7=np.zeros((nTimebinsn7,nEchannelsn7))
Backgn7=np.zeros((nTimebinsn7,nEchannelsn7))
Backgerrn7=np.zeros((nTimebinsn7,nEchannelsn7))
#Channel data starts at line il+2
print alllinesn4[il+2]
print alllinesn8[il+2]
print alllinesn3[il+2]
print alllinesn7[il+2]
iligne_timedatabegin=il+2
#Fill Tstart and Tend as well as channel contents and their errors
for it in range(nTimebinsn4):
    il=iligne_timedatabegin+it
    Tstartn4[it]=float(alllinesn4[il].split()[0])
    Tendn4[it]=float(alllinesn4[il].split()[1])
    for ie in range(128):
        Countsn4[it][ie]=float(alllinesn4[il].split()[2+ie*4])
        Countserrn4[it][ie]=float(alllinesn4[il].split()[2+ie*4+1])
        Backgn4[it][ie]=float(alllinesn4[il].split()[2+ie*4+2])
        Backgerrn4[it][ie]=float(alllinesn4[il].split()[2+ie*4+3])
        
for it in range(nTimebinsn8):
    il=iligne_timedatabegin+it
    Tstartn8[it]=float(alllinesn8[il].split()[0])
    Tendn8[it]=float(alllinesn8[il].split()[1])
    for ie in range(128):
        Countsn8[it][ie]=float(alllinesn8[il].split()[2+ie*4])
        Countserrn8[it][ie]=float(alllinesn8[il].split()[2+ie*4+1])
        Backgn8[it][ie]=float(alllinesn8[il].split()[2+ie*4+2])
        Backgerrn8[it][ie]=float(alllinesn8[il].split()[2+ie*4+3])
for it in range(nTimebinsn3):
    il=iligne_timedatabegin+it
    Tstartn3[it]=float(alllinesn3[il].split()[0])
    Tendn3[it]=float(alllinesn3[il].split()[1])
    for ie in range(128):
        Countsn3[it][ie]=float(alllinesn3[il].split()[2+ie*4])
        Countserrn3[it][ie]=float(alllinesn3[il].split()[2+ie*4+1])
        Backgn3[it][ie]=float(alllinesn3[il].split()[2+ie*4+2])
        Backgerrn3[it][ie]=float(alllinesn3[il].split()[2+ie*4+3])       
for it in range(nTimebinsn7):
    il=iligne_timedatabegin+it
    Tstartn7[it]=float(alllinesn7[il].split()[0])
    Tendn7[it]=float(alllinesn7[il].split()[1])
    for ie in range(128):
        Countsn7[it][ie]=float(alllinesn7[il].split()[2+ie*4])
        Countserrn7[it][ie]=float(alllinesn7[il].split()[2+ie*4+1])
        Backgn7[it][ie]=float(alllinesn7[il].split()[2+ie*4+2])
        Backgerrn7[it][ie]=float(alllinesn7[il].split()[2+ie*4+3])
        #print ie
    #print alllines[ie].split()[0]

#print Tend-Tstart

#Determine time bin size and the size of the last time bin (which can be different).
Timebinsizen4=Tendn4[0]-Tstartn4[0]
lastTimebinsizen4=Tendn4[nTimebinsn4-1]-Tstartn4[nTimebinsn4-1]
print "Time bin size=",Timebinsizen4
print "Last iime bin size=",lastTimebinsizen4

Timebinsizen8=Tendn8[0]-Tstartn8[0]
lastTimebinsizen8=Tendn8[nTimebinsn8-1]-Tstartn8[nTimebinsn8-1]
print "Time bin size in n3=",Timebinsizen8
print "Last iime bin size in n3=",lastTimebinsizen8

Timebinsizen3=Tendn3[0]-Tstartn3[0]
lastTimebinsizen3=Tendn3[nTimebinsn3-1]-Tstartn3[nTimebinsn3-1]
print "Time bin size in n3=",Timebinsizen3
print "Last iime bin size in n3=",lastTimebinsizen3

Timebinsizen7=Tendn7[0]-Tstartn7[0]
lastTimebinsizen7=Tendn7[nTimebinsn7-1]-Tstartn7[nTimebinsn7-1]
print "Time bin size in n7=",Timebinsizen7
print "Last iime bin size in n7=",lastTimebinsizen7



#APPLY ENERGY RANGE CUTS
#=======================

#Lower and higher limit of energy range (energy is in keV)

#Note: typical range for NaI is from 8 keV to about 930 keV.
# For BGO, the typical range is from about 250 keV to less than 40 MeV.
#But these be chosen differently too.
Emin=[]
Emax=[]
Emin.append(524.)  #lower limit of the energy range
Emax.append(930.) #higher limit of the energy range

#For NaI, the 30 keV to 40 keV bins also need to be removed.
#if detectortype=NaI
#No bins are removed if detectortype=BGO. Therefore for a BGO detector, these should be put at some out of range value.
Eoutlow=30.
Eouthigh=40.
#Eoutlow=1.
#Eouthigh=2.


#Go through all the energy channels to determine the index for the first channels that corresponds to the range we want to keep and the index of the last channel of the range.
for ie in range (nEchannelsn4):
    if Emin[0] > Estartn4[ie] and Emin[0]<Estartn4[ie+1]:
        ifirstEbinn4=ie+1 #cut above just to be sure
    if Emax[0] > Eendn4[ie] and Emax[0]<Eendn4[ie+1]:
        ilastEbinn4=ie  # cut below just to be sure
        
for ie in range (nEchannelsn8):
    if Emin[0] > Estartn8[ie] and Emin[0]<Estartn8[ie+1]:
        ifirstEbinn8=ie+1 #cut above just to be sure
    if Emax[0] > Eendn8[ie] and Emax[0]<Eendn8[ie+1]:
        ilastEbinn8=ie  # cut below just to be sure 
        
for ie in range (nEchannelsn3):
    if Emin[0] > Estartn3[ie] and Emin[0]<Estartn3[ie+1]:
        ifirstEbinn3=ie+1 #cut above just to be sure
    if Emax[0] > Eendn3[ie] and Emax[0]<Eendn3[ie+1]:
        ilastEbinn3=ie  # cut below just to be sure  
        
for ie in range (nEchannelsn7):
    if Emin[0] > Estartn7[ie] and Emin[0]<Estartn7[ie+1]:
        ifirstEbinn7=ie+1 #cut above just to be sure
    if Emax[0] > Eendn7[ie] and Emax[0]<Eendn7[ie+1]:
        ilastEbinn7=ie  # cut below just to be sure  
        

#print ifirstEbin, ilastEbin
#print Estart[ifirstEbin[0]], Eend[ilastEbin[0]]
print "Energy range: for n4 ",Estartn4[ifirstEbinn4], "to", Eendn4[ilastEbinn4]
print "Also removed from this range for n4", Eoutlow , " to ", Eouthigh

print "Energy range: for n8 ",Estartn8[ifirstEbinn8], "to", Eendn8[ilastEbinn8]
print "Also removed from this range for n8", Eoutlow , " to ", Eouthigh

print "Energy range: for n3 ",Estartn3[ifirstEbinn3], "to", Eendn3[ilastEbinn3]
print "Also removed from this range for n3", Eoutlow , " to ", Eouthigh

print "Energy range: for n7 ",Estartn7[ifirstEbinn7], "to", Eendn7[ilastEbinn7]
print "Also removed from this range for n7", Eoutlow , " to ", Eouthigh

#Creating empty numpy arrays for counts, their errros, background counts and the error on background counts for the energy range that we want to work with
Countsinrangen4=np.zeros((nTimebinsn4))
Countsinrangeerrn4=np.zeros((nTimebinsn4))#squares of errors for propagation of error formula
Backginrangen4=np.zeros((nTimebinsn4))   
Backginrangeerrn4=np.zeros((nTimebinsn4))  #squares of errors for propagation of error formula

Countsinrangen8=np.zeros((nTimebinsn8))
Countsinrangeerrn8=np.zeros((nTimebinsn8))#squares of errors for propagation of error formula
Backginrangen8=np.zeros((nTimebinsn8))   
Backginrangeerrn8=np.zeros((nTimebinsn8))  #squares of errors for propagation of error formula

Countsinrangen3=np.zeros((nTimebinsn3))
Countsinrangeerrn3=np.zeros((nTimebinsn3))#squares of errors for propagation of error formula
Backginrangen3=np.zeros((nTimebinsn3))   
Backginrangeerrn3=np.zeros((nTimebinsn3))  #squares of errors for propagation of error formula

Countsinrangen7=np.zeros((nTimebinsn7))
Countsinrangeerrn7=np.zeros((nTimebinsn7))#squares of errors for propagation of error formula
Backginrangen7=np.zeros((nTimebinsn7))   
Backginrangeerrn7=np.zeros((nTimebinsn7))  #squares of errors for propagation of error formula
#Add the content for counts, their errors, background counts, and the error on backgrounds counts for the energy range we want to work with.
#for ier in range(nEchannels):
for it in range(nTimebinsn4):
    for ie in range(ifirstEbinn4,ilastEbinn4):
        #exclude channels we don't want
        if Estartn4[ie] >= Eoutlow and Eendn4[ie-1]<=Eouthigh:
            if it==0:
                print "Removed channel",ie, "range:",Estartn4[ie],"to",Eendn4[ie-1], "keV"
        else:
            Countsinrangen4[it]= Countsinrangen4[it]+Countsn4[it][ie]
            Countsinrangeerrn4[it]= Countsinrangeerrn4[it]+Countserrn4[it][ie]*Countserrn4[it][ie] #use propagation of error formula
            Backginrangen4[it]= Backginrangen4[it]+Backgn4[it][ie]
            Backginrangeerrn4[it]= Backginrangeerrn4[it]+Backgerrn4[it][ie]*Backgerrn4[it][ie] #use propagation of error formula
            #print "Kept"
            print it, ie, Countsinrangen4[it], Countsn4[it][ie]
            
for it in range(nTimebinsn8):
    for ie in range(ifirstEbinn8,ilastEbinn8):
        #exclude channels we don't want
        if Estartn8[ie] >= Eoutlow and Eendn8[ie-1]<=Eouthigh:
            if it==0:
                print "Removed channel",ie, "range:",Estartn8[ie],"to",Eendn8[ie-1], "keV"
        else:
            Countsinrangen8[it]= Countsinrangen8[it]+Countsn8[it][ie]
            Countsinrangeerrn8[it]= Countsinrangeerrn8[it]+Countserrn8[it][ie]*Countserrn8[it][ie] #use propagation of error formula
            Backginrangen8[it]= Backginrangen8[it]+Backgn8[it][ie]
            Backginrangeerrn8[it]= Backginrangeerrn8[it]+Backgerrn8[it][ie]*Backgerrn8[it][ie] #use propagation of error formula
            #print "Kept"
            print it, ie, Countsinrangen8[it], Countsn8[it][ie]            

for it in range(nTimebinsn3):
    for ie in range(ifirstEbinn3,ilastEbinn3):
        #exclude channels we don't want
        if Estartn3[ie] >= Eoutlow and Eendn3[ie-1]<=Eouthigh:
            if it==0:
                print "Removed channel",ie, "range:",Estartn3[ie],"to",Eendn3[ie-1], "keV"
        else:
            Countsinrangen3[it]= Countsinrangen3[it]+Countsn3[it][ie]
            Countsinrangeerrn3[it]= Countsinrangeerrn3[it]+Countserrn3[it][ie]*Countserrn3[it][ie] #use propagation of error formula
            Backginrangen3[it]= Backginrangen3[it]+Backgn3[it][ie]
            Backginrangeerrn3[it]= Backginrangeerrn3[it]+Backgerrn3[it][ie]*Backgerrn3[it][ie] #use propagation of error formula
            #print "Kept"
            print it, ie, Countsinrangen3[it], Countsn3[it][ie]            

for it in range(nTimebinsn7):
    for ie in range(ifirstEbinn7,ilastEbinn7):
        #exclude channels we don't want
        if Estartn7[ie] >= Eoutlow and Eendn7[ie-1]<=Eouthigh:
            if it==0:
                print "Removed channel",ie, "range:",Estartn7[ie],"to",Eendn7[ie-1], "keV"
        else:
            Countsinrangen7[it]= Countsinrangen7[it]+Countsn7[it][ie]
            Countsinrangeerrn7[it]= Countsinrangeerrn7[it]+Countserrn7[it][ie]*Countserrn7[it][ie] #use propagation of error formula
            Backginrangen7[it]= Backginrangen7[it]+Backgn7[it][ie]
            Backginrangeerrn7[it]= Backginrangeerrn7[it]+Backgerrn7[it][ie]*Backgerrn7[it][ie] #use propagation of error formula
            #print "Kept"
            print it, ie, Countsinrangen7[it], Countsn7[it][ie]            

#print ie

Countsinrangeerrn4=np.sqrt(Countsinrangeerrn4)
Backginrangeerrn4=np.sqrt(Backginrangeerrn4)

Countsinrangeerrn8=np.sqrt(Countsinrangeerrn8)
Backginrangeerrn8=np.sqrt(Backginrangeerrn8)

Countsinrangeerrn3=np.sqrt(Countsinrangeerrn3)
Backginrangeerrn3=np.sqrt(Backginrangeerrn3)

Countsinrangeerrn7=np.sqrt(Countsinrangeerrn7)
Backginrangeerrn7=np.sqrt(Backginrangeerrn7)

#To save count data in an output file

filenamen4='count_datan4.txt'
fn4=open(filenamen4,'w')

filenamen8='count_datan8.txt'
fn8=open(filenamen8,'w')

filenamen3='count_datan3.txt'
fn3=open(filenamen3,'w')

filenamen7='count_datan7.txt'
fn7=open(filenamen7,'w')

for it in range(nTimebinsn4):
    print >>fn4,"% 8.3f   % 8.3f   % 11.3f   % 11.3f"% (Tstartn4[it],Tendn4[it],Countsinrangen4[it],Countsinrangeerrn4[it])
for it in range(nTimebinsn8):
    print >>fn8,"% 8.3f   % 8.3f   % 11.3f   % 11.3f"% (Tstartn8[it],Tendn8[it],Countsinrangen8[it],Countsinrangeerrn8[it])
for it in range(nTimebinsn3):
    print >>fn3,"% 8.3f   % 8.3f   % 11.3f   % 11.3f"% (Tstartn3[it],Tendn3[it],Countsinrangen3[it],Countsinrangeerrn3[it])
for it in range(nTimebinsn7):
    print >>fn7,"% 8.7f   % 8.7f   % 11.7f   % 11.7f"% (Tstartn7[it],Tendn7[it],Countsinrangen7[it],Countsinrangeerrn7[it])
#Making plots for n4+n3
    
Countsinrange=Countsinrangen8+Countsinrangen4+Countsinrangen3+Countsinrangen7
Countsinrangeerr=Countsinrangeerrn8+Countsinrangeerrn4+Countsinrangeerrn3+Countsinrangeerrn7
Backginrange=Backginrangen8+Backginrangen4+Backginrangen3+Backginrangen7
Backginrangeer=Backginrangeerrn8+Backginrangeerrn4+Backginrangeerrn3+Backginrangeerrn7

#To plot the light curve with python
#===================================

fig, ax = plt.subplots(figsize=(8,4))
#fig.tight_layout() # Or equivalently,  "plt.tight_layout()"


#fig = plt.figure(figsize = plt.figaspect(1)*1.5)
NBINS=nTimebinsn3

ax.plot(Tstartn3, Countsinrange, lw = .9, color = 'blue',label='8-30Kev')
ax.legend(loc='best')
ax.set_xlim([-10.,36.])

#plt.hist(Countsinrange, NBINS, histtype='step',linewidth=1.,color="black")
ax.set_title('Summed light-curve of the NAI detectors')



#plt.xlabel('Low energy index')
#plt.ylabel('High energy index')


ax.set(xlabel=r'Time [seconds]',ylabel='Counts')

plt.savefig('Summed light-curve of the NAI detectors(0.09-tbin.(8-20kev)).png',bbox_inches='tight')
#plt.show()


#To plot the light curve with PYROOT and fit it
#==============================================
#Create canvas
cp = root.TCanvas( 'cp', 'LightCurve', 200, 10, 800, 300)
cp.SetGrid()
cp.SetLogy(0)
leg = root.TLegend(0.1,0.79,0.3,.99)
#Create graph for light curve
gr= root.TGraph( nTimebinsn3, Tstartn3.astype(np.double), Countsinrange.astype(np.double))
#Define the function, its limits (-4., 2.7 in this case) and the number of parameters (3 in this case). For instance, if we want to fit the function between -4. and 2.7 seconds, we do this in the following way.
#Note that there are three free parameters [0], [1] and [2]. That is why the last entry in the command below is 3.
Norris=root.TF1('myfit', '[0]*exp(2*(([1]/[2])**0.5))*exp(-[1]/(x-[3]))*exp(-(x-[3])/[2])',2,2.95,4)
#Give initial values to the three parameters
Norris.SetParameters(100000,14,1,1.8)
#Name the three parameters.
Norris.SetParNames("Amplitude","Rise_time","Decay_time","Pulse_start_time")
#polynomial functionss
poly = root.TF1( 'mypoly', '[3]*x*x*x+[2]*x*x+[1]*x+[0]', 0., 3., 4)
poly.SetParameters( 1., -1., 1. ,-3.)
poly.SetParNames("p3","p2","p1","p0")
#Carry out the fit
fit=gr.Fit(Norris, "R")
#fit2=gr.Fit(poly,"R")
gr.GetFunction('myfit').SetLineColor(4)
#Graph attributes
gr.SetTitle("")
gr.SetMarkerColor( root.kCyan+2 )
gr.SetLineColor( root.kCyan+2 )
gr.SetLineWidth(1)
gr.SetLineStyle(1)
#gr.GetXaxis().SetRangeUser(-10.,36.)
gr.GetXaxis().SetRangeUser(-10.,36.)
gr.GetXaxis().SetTitle( 'Time   (seconds)' )
gr.GetYaxis().SetTitle( 'Counts' )
gr.Draw('AL')

leg.AddEntry(gr,"524-930 keV ")
#leg.AddEntry("myfit","Norris-fit")
#Draw graph

#Axis titles, graph limits, Margin size, etc. The order can be important in setting these attributes.
leg.Draw()




#Get fit parameters, round them off to 4 digits and put them in variables
Amplitude=round(Norris.GetParameter(0),4)
Amplitude_err=round(Norris.GetParError(0),4)
Rise_time=round(Norris.GetParameter(1),4)
Rise_time_err=round(Norris.GetParError(1),4)
Decay_time=round(Norris.GetParameter(2),4)
Decay_time_err=round(Norris.GetParError(2),4)
Pulse_start_time=round(Norris.GetParameter(3),4)
Pulse_start_time_err=round(Norris.GetParError(3),4)
##Temporal properties formula's

#Width=Decay_time(1+4*((Rise_time/Decay_time)**0.5))
#Tpeak=Teff+((Rise_time*Decay_time)**0.5)
#K=Decay_time/w
#Rise_time=0.5*w*(1-k)
#Decay_time=0.5*w*(1+k)


#If one wants to print these values on the graph, we can put them in a Tlatex object in the following way. 
t1=root.TLatex(0.7,0.85,"Amplitude = " + str(Amplitude)+" +/- "+str(Amplitude_err) )
t2=root.TLatex(0.7,0.75,"Rise_time= "+ str(Rise_time)+" +/- "+str(Rise_time_err))
t3=root.TLatex(0.7,0.65,"Decay_time= "+ str(Decay_time)+" +/- "+str(Decay_time_err))
t4=root.TLatex(0.7,0.55,"Pulse_start_time= "+ str(Pulse_start_time)+" +/- "+str(Pulse_start_time_err))
#write on graph
t1.SetNDC()
t1.SetTextSize (0.04)
t1.Draw()
t2.SetNDC()
t2.SetTextSize (0.04)
t2.Draw()
t3.SetNDC()
t3.SetTextSize (0.04)
t3.Draw()
t4.SetNDC()
t4.SetTextSize (0.04)
t4.Draw()

cp.SetTopMargin(0.005)
cp.SetRightMargin(0.01)
cp.SaveAs('524_930_2a.pdf')

#End section of plotting  and fitting with PYROOT
#===================================
#fn3.close()
#fn7.close()
#fn4.close()
#fn8.close()

I don’t think this has to do with PyROOT itself, so asking @moneta to give a hand, thanks!