1

I have tried to best fit my data set for more than 700 txt files with a single run. And I want the output parameter obtained from all files into a tabular format.I have tried in this way

def resid(params, x, ydata):
   decay = params['decay'].value
   phase = params['phase'].value
   omega = params['omega'].value
   amp = params['amp'].value
   ampb=params['ampb'].value
   phaseb=params['phaseb'].value
   #omegab = params['omegab'].value
   
   y_model =  (amp * np.sin(x*2*np.pi*omega+phase)+ ampb*np.sin(x*4*np.pi*omega+phaseb)) * np.exp(-x*decay)
   return y_model - ydata


filelist = glob.glob("C:/Users/USER/Desktop/B3/*.txt") 
#print(filelist)
for file in filelist:
   data = np.loadtxt(file)
   x = data[:,0]
   y = data[:,1]
   params = lmfit.Parameters()
   params.add('phase', 0.0,   min=-np.pi, max=np.pi)
   params.add('omega',  10,   min=7, max=12)
   params.add('amp',     7,   min=0, max=10.0)
   params.add('decay', 0.05,  min=0, max=10.0)
   params.add('ampb',     3,  min=0, max=8.0)
   params.add('phaseb', 0.0,  min=-np.pi, max=np.pi)
   #params.add('omegab', 18, min=16, max=20)   
   
   fit = lmfit.minimize(resid, params, args=(x, y), method='differential_evolution')
   #print("\n\n# Fit using differential_evolution:")
   #print(lmfit.report_fit(fit))
   for name, param in fit.params.items():
           if name=='phase':
               print('phase',' ' , param.value,' ',param.stderr, ) 
           elif name=='amp ':
               print('amp', '   ',param.value,'  ',param.stderr )
           elif name=='omega':
               print('omega', '  ',param.value,'  ',param.stderr)
           elif name=='decay':
               print('decay', '  ',param.value,'  ',param.stderr)
           elif name=='ampb':
               print('ampb', '   ',param.value,'  ',param.stderr)
           else: 
               print('phaseb','  ',param.value,'  ',param.stderr)
   print(fit.success)

I expect the output in this format enter image description here

but I have got values of each output separately like this enter image description here

1 Answers1

0

You can create an empty dict before the inner for loop, make the loop fill that dict with the params, and then print them all on 1 line after the for loop is done. The below example will print the values next to each other, separated with the TAB character, which should be readable enough but the "table" might not be perfectly aligned. If you want it to look better in terminal, there are some solutions mentioned here. Alternatively you could dump the TAB- or comma-separated values to a file, then open that file e.g. with Excel.

    ...
    params = {}
    for name, param in fit.params.items():
        if name == 'phase':
            params['phase'] = param.value
            params['phase_stderr'] = param.stderr
        elif name == 'amp':
            params['amp'] = param.value
            params['amp_stderr'] = param.stderr
        elif name == 'omega':
            params['omega'] = param.value
            params['omega_stderr'] = param.stderr
        elif name == 'decay':
            params['decay'] = param.value
            params['decay_stderr'] = param.stderr
        elif name == 'ampb':
            params['ampb'] = param.value
            params['ampb_stderr'] = param.stderr
        else: 
            params['phaseb'] = param.value
            params['phaseb_stderr'] = param.stderr
    print(
        params['phase'],
        params['amp'],
        params['omega'],
        params['decay'],
        params['ampb'],
        params['phaseb'],
        params['phase_stderr'],
        params['amp_stderr'],
        params['omega_stderr'],
        params['decay_stderr'],
        params['ampb_stderr'],
        params['phaseb_stderr'],
        sep="\t"
    )
Czaporka
  • 2,190
  • 3
  • 10
  • 23
  • @PrakashGyawali no need to thank me :) please just upvote the answer if you think it's useful, and if it solves your problem - mark it as accepted. Thanks! – Czaporka Nov 15 '20 at 20:28