-2

I am newbie in python I have this code i want to use subclass lmfit.models and implement a guess method,

class DecayingSineModel():

     def __init__(self, *args, **kwargs):

        def decaying_sine(self, x, ampl, offset, freq, x0, tau):
            return ampl * np.sin((x - x0)*freq) * np.exp(-x/tau) + offset

        super(DecayingSineModel, self).__init__(decaying_sine, *args, **kwargs)

    def pset(param, value):
        params["%s%s" % (self.prefix, param)].set(value=value)

    def guess(self, data, **kwargs):         
        params = self.make_params()
        pset("ampl", np.max(data) - np.min(data))
        pset("offset", np.mean(data))
        pset("freq", 1)
        pset("x0", 0)
        pset("tau", 1)
        return lmfit.models.update_param_vals(params, self.prefix, **kwargs)

sp = DecayingSineModel()
params = sp.guess(y, x=x)
fit = sp.fit(y, params, x=x)

and i am recieving following error the error that i am recieving the image of error that i recieved is in this address

somaye
  • 3
  • 5
  • Is this how you indented your code, because this can explain it. – Willem Van Onsem Oct 29 '17 at 15:58
  • 1
    Please post an exact copy of your code, since it is very weird right now... – Willem Van Onsem Oct 29 '17 at 16:01
  • Is the call to `super` inside your `__init__` method? With the broken indentation it's impossible to tell. Similarly, is `sp = DecayingSineModel()` inside the class body? Or is it outside of the class? – Tom Karzes Oct 29 '17 at 16:04
  • 1
    Voting to close. Without knowing the exact indentation that OP is using, we can only guess at where the error is coming from. – Tom Karzes Oct 29 '17 at 16:08
  • You say you want to 'subclass lmfit.models' but your `class` declaration doesn't mention lmfit. I also wonder why you don't use the simple pattern for describing models, in the introduction for this software. – Bill Bell Oct 29 '17 at 16:32

1 Answers1

0

You almost certainly want your DecayingSineWave to inherit from lmfit.Model. As others have pointed out there are a number of other problems with your code, including the fact that your pset references self but doesn't have it passed in and yet you call pset, not self.pset. Your model function decaying_sine should not have self.

A cleaned-up version:

import numpy as np
import lmfit
import matplotlib.pyplot as plt

class DecayingSineModel(lmfit.Model):
    def __init__(self, *args, **kwargs):
        def decaying_sine(x, ampl, offset, freq, x0, tau):
            return ampl * np.sin((x - x0)*freq) * np.exp(-x/tau) + offset
        super(DecayingSineModel, self).__init__(decaying_sine, *args, **kwargs)

    def guess(self, data, x=None, **kwargs):
        ampl = np.max(data) - np.min(data)
        offset = np.mean(data)
        params = self.make_params(ampl=ampl, offset=offset, freq=1, x0=0, tau=1)
        return lmfit.models.update_param_vals(params, self.prefix, **kwargs)

sp = DecayingSineModel()

x = np.linspace(0, 25, 201)
noise = np.random.normal(size=len(x), scale=0.25)
y = 2 + 7*np.sin(1.6*(x-0.2)) * np.exp(-x/18) + noise

params = sp.guess(y, x=x)
result = sp.fit(y, params, x=x)
print(result.fit_report())

plt.plot(x, y, 'bo')
plt.plot(x, result.best_fit, 'r-')
plt.show()

gives a report of:

[[Model]]
    Model(decaying_sine)
[[Fit Statistics]]
    # function evals   = 83
    # data points      = 201
    # variables        = 5
    chi-square         = 39.266
    reduced chi-square = 0.200
    Akaike info crit   = -318.220
    Bayesian info crit = -301.703
[[Variables]]
    ampl:     6.92483967 +/- 0.123863 (1.79%) (init= 12.59529)
    offset:   1.96307863 +/- 0.031684 (1.61%) (init= 2.139916)
    freq:     1.60060819 +/- 0.001775 (0.11%) (init= 1)
    x0:       0.19650313 +/- 0.010267 (5.23%) (init= 0)
    tau:      18.3528781 +/- 0.614576 (3.35%) (init= 1)
[[Correlations]] (unreported correlations are <  0.100)
    C(ampl, tau)                 = -0.781 
    C(freq, x0)                  =  0.750

and enter image description here

M Newville
  • 7,486
  • 2
  • 16
  • 29
  • Yeah, Thanks but after do this i recieved this error again. – somaye Oct 30 '17 at 05:25
  • Hm, I doubt that: when I try your code I do not get the NameError error. But, as others have pointed out, there are several other problems with your code. I updated my answer to give a working version. – M Newville Oct 30 '17 at 11:51
  • @M Newville thanks for your reply i dont know why i am recieving this error even with your working version, maybe there is another problem, i am using Python 2.7.14 in widows 7, is it possible that because of this i have this problems. – somaye Oct 30 '17 at 17:38
  • post full, exact code that shows the problem and full, exact error messages. – M Newville Oct 30 '17 at 22:28
  • i am using just your working version, and i updated my error image in question – somaye Oct 31 '17 at 10:48
  • try again... `super(DecayingSineWave, ...` needs to be indented properly, to be within `def __init__()`. – M Newville Oct 31 '17 at 12:34