def test_custom_independentvar(): """Tests using a non-trivial object as an independent variable.""" npts = 501 xmin = 1 xmax = 21 cen = 8 obj = Stepper(xmin, xmax, npts) y = gaussian(obj.get_x(), amplitude=3.0, center=cen, sigma=2.5) y += np.random.normal(scale=0.2, size=npts) gmod = Model(gaussian_mod) params = gmod.make_params(amplitude=2, center=5, sigma=8) out = gmod.fit(y, params, obj=obj) assert(out.nvarys == 3) assert(out.nfev > 10) assert(out.chisqr > 1) assert(out.chisqr < 100) assert(out.params['sigma'].value < 3) assert(out.params['sigma'].value > 2) assert(out.params['center'].value > xmin) assert(out.params['center'].value < xmax) assert(out.params['amplitude'].value > 1) assert(out.params['amplitude'].value < 5)
def fitGompertz(x, y, dias): # fit a logistic function~ def Gompertz(a, b, c, x): return a * np.exp(-1 * np.exp(-b * (x - c))) model = Model(Gompertz, independent_vars=["x"]) params = model.make_params() params["a"].value = 10000 params["b"].value = 0.05 params["c"].value = 100 output = model.fit(y, params, x=x) amplitude = output.params["a"].value amplitude = math.floor(amplitude) center = output.params["c"].value sigma = output.params["b"].value fit = [] xfit = [] cumulative = [] for i in range(61, dias): if i == 61: xfit.append(i) value = amplitude * np.exp(-1 * np.exp(-sigma * (i - center))) fit.append(value) cumulative.append(0) else: xfit.append(i) value = amplitude * np.exp(-1 * np.exp(-sigma * (i - center))) fit.append(value) c = value - fit[i - 62] cumulative.append(c) return amplitude, center, sigma, xfit, fit, cumulative, output.fit_report()
def make_bareexponentialdecay_model(self): """ This method creates a model of bare exponential decay. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. """ def bareexponentialdecay_function(x, lifetime): """ Function of a bare exponential decay. @param x: variable variable - e.g. time @param lifetime: lifetime @return: bare exponential decay function: in order to use it as a model """ return np.exp(-x / lifetime) model = Model(bareexponentialdecay_function) params = model.make_params() return model, params
def make_twoDgaussian_model(self): """ This method creates a model of the 2D gaussian function. The parameters are: 'amplitude', 'center', 'sigm, 'fwhm' and offset 'c'. For function see: @return lmfit.model.CompositeModel model: Returns an object of the class CompositeModel @return lmfit.parameter.Parameters params: Returns an object of the class Parameters with all parameters for the gaussian model. """ def twoDgaussian_function(x, amplitude, x_zero, y_zero, sigma_x, sigma_y, theta, offset): # FIXME: x_data_tuple: dimension of arrays """ This method provides a two dimensional gaussian function. Function taken from: http://stackoverflow.com/questions/21566379/fitting-a-2d-gaussian-function-using-scipy-optimize-curve-fit-valueerror-and-m/21566831 Question from: http://stackoverflow.com/users/2097737/bland & http://stackoverflow.com/users/3273102/kokomoking & http://stackoverflow.com/users/2767207/jojodmo Answer: http://stackoverflow.com/users/1461210/ali-m & http://stackoverflow.com/users/5234/mrjrdnthms @param array[k][M] x_data_tuple: array which is (k,M)-shaped, x and y values @param float or int amplitude: Amplitude of gaussian @param float or int x_zero: x value of maximum @param float or int y_zero: y value of maximum @param float or int sigma_x: standard deviation in x direction @param float or int sigma_y: standard deviation in y direction @param float or int theta: angle for eliptical gaussians @param float or int offset: offset @return callable function: returns the function """ (u, v) = x x_zero = float(x_zero) y_zero = float(y_zero) a = (np.cos(theta) ** 2) / (2 * sigma_x ** 2) \ + (np.sin(theta) ** 2) / (2 * sigma_y ** 2) b = -(np.sin(2 * theta)) / (4 * sigma_x ** 2) \ + (np.sin(2 * theta)) / (4 * sigma_y ** 2) c = (np.sin(theta) ** 2) / (2 * sigma_x ** 2) \ + (np.cos(theta) ** 2) / (2 * sigma_y ** 2) g = offset + amplitude * np.exp(- (a * ((u - x_zero) ** 2) \ + 2 * b * (u - x_zero) * (v - y_zero) \ + c * ((v - y_zero) ** 2))) return g.ravel() model = Model(twoDgaussian_function) params = model.make_params() return model, params
def make_slope_model(self): """ This method creates a model of a slope model. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. For further information have a look in: http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html#models.GaussianModel """ def slope_function(x, slope): """ Function of a constant value. @param x: variable variable @param slope: independent variable - slope @return: slope function: in order to use it as a model """ return slope + 0.0 * x model = Model(slope_function) params = model.make_params() return model, params
def test_custom_independentvar(): """Tests using a non-trivial object as an independent variable.""" npts = 501 xmin = 1 xmax = 21 cen = 8 obj = Stepper(xmin, xmax, npts) y = gaussian(obj.get_x(), amplitude=3.0, center=cen, sigma=2.5) y += np.random.normal(scale=0.2, size=npts) gmod = Model(gaussian_mod) params = gmod.make_params(amplitude=2, center=5, sigma=8) out = gmod.fit(y, params, obj=obj) assert (out.nvarys == 3) assert (out.nfev > 10) assert (out.chisqr > 1) assert (out.chisqr < 100) assert (out.params['sigma'].value < 3) assert (out.params['sigma'].value > 2) assert (out.params['center'].value > xmin) assert (out.params['center'].value < xmax) assert (out.params['amplitude'].value > 1) assert (out.params['amplitude'].value < 5)
def make_amplitude_model(self, prefix=None): """ Create a constant model. @param str prefix: optional string, which serves as a prefix for all parameters used in this model. That will prevent name collisions if this model is used in a composite way. @return tuple: (object model, object params), for more description see in the method make_constant_model. """ def amplitude_function(x, amplitude): """ Function of a constant value. @param numpy.array x: 1D array as the independent variable - e.g. time @param float amplitude: constant offset @return: constant function, in order to use it as a model """ return amplitude if not isinstance(prefix, str) and prefix is not None: self.log.error( 'The passed prefix <{0}> of type {1} is not a string and cannot be used as ' 'a prefix and will be ignored for now. Correct that!'.format( prefix, type(prefix))) model = Model(amplitude_function, independent_vars='x') else: model = Model(amplitude_function, independent_vars='x', prefix=prefix) params = model.make_params() return model, params
def make_amplitude_model(self, prefix=None): """ Create a constant model. @param str prefix: optional string, which serves as a prefix for all parameters used in this model. That will prevent name collisions if this model is used in a composite way. @return tuple: (object model, object params), for more description see in the method make_constant_model. """ def amplitude_function(x, amplitude): """ Function of a constant value. @param numpy.array x: 1D array as the independent variable - e.g. time @param float amplitude: constant offset @return: constant function, in order to use it as a model """ return amplitude if not isinstance(prefix, str) and prefix is not None: self.log.error('The passed prefix <{0}> of type {1} is not a string and cannot be used as ' 'a prefix and will be ignored for now. Correct that!'.format(prefix, type(prefix))) model = Model(amplitude_function, independent_vars='x') else: model = Model(amplitude_function, independent_vars='x', prefix=prefix) params = model.make_params() return model, params
def make_gaussianwithoutoffset_model(self, prefix=None): """ Create a model of a gaussian with specified amplitude. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. For further information have a look in: http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html """ def physical_gauss(x, center, sigma): """ Function of a bare Gaussian with unit height at center. @param numpy.array x: independent variable - e.g. frequency @param float center: center around which the distributions (expectation value). @param float sigma: standard deviation of the gaussian @return: numpy.array with length equals to input x and with the values of a bare Gaussian. """ return np.exp(-np.power((center - x), 2) / (2 * np.power(sigma, 2))) amplitude_model, params = self.make_amplitude_model(prefix=prefix) if not isinstance(prefix, str) and prefix is not None: self.log.error( 'The passed prefix <{0}> of type {1} is not a string and' 'cannot be used as a prefix and will be ignored for now.' 'Correct that!'.format(prefix, type(prefix))) gaussian_model = Model(physical_gauss, independent_vars='x') else: gaussian_model = Model(physical_gauss, independent_vars='x', prefix=prefix) full_gaussian_model = amplitude_model * gaussian_model if prefix is None: prefix = '' full_gaussian_model.set_param_hint( '{0!s}fwhm'.format(prefix), expr="2.3548200450309493*{0}sigma".format(prefix)) params = full_gaussian_model.make_params() return full_gaussian_model, params
def poly_gaussian(): gauss1 = Model(gaussian, independent_vars=['x'], prefix='gauss1_') gauss2 = Model(gaussian, independent_vars=['x'], prefix='gauss2_') gauss3 = Model(gaussian, independent_vars=['x'], prefix='gauss3_') gauss4 = Model(gaussian, independent_vars=['x'], prefix='gauss4_') linear1 = LinearModel(independent_vars=['x'], prefix='linear1_') linear2 = LinearModel(independent_vars=['x'], prefix='linear2_') model = gauss1 + gauss2 + linear1 + gauss3 + linear2 + gauss4 return model
def _fit_echo(self): fit_start, fit_end = self._get_region() df = self.data_in_range[(self.data_in_range.index > fit_start) & (self.data_in_range.index < fit_end)] # Fit arrays fit_variable = self._graph_select.currentText() + '_mean' x = np.array(df.index.get_values()) if self._fit_res_checkbox.isChecked(): y = df['peak_fit_res'] + self.c.best_val else: y = df[fit_variable] params = Parameters() params.add_many( ('y0', self.y0.param.value, self.y0.param.vary, self.y0.param.min, self.y0.param.max), ('A', self.A.param.value, self.A.param.vary, self.A.param.min, self.center.param.max), ('t2', self.t2.param.value, self.t2.param.vary, self.t2.param.min, self.t2.param.max), ) model = Model(echo_decay_curve, independent_vars=['x']) result = model.fit(y, x=x, params=params) all_time = np.linspace(0.1, self.data_in_range.index.get_values().max(), 2000) # plot data self.echo_fit_line.set_data(x, echo_decay_curve(x=x, **result.values)) self.echo_fit_extended_line.set_data( all_time, echo_decay_curve(x=all_time, **result.values)) # Подсчитываем данные t2 = result.values['t2'] t2_stderr = result.params.get('t2').stderr # Ширина линии в MHz delta_f = 10**6 / (np.pi * result.values['t2']) delta_f_stderr = delta_f * t2_stderr / t2 self._ax.set_title( "$T_2$: {:0.2f} $\pm$ {:0.2f} $ps$ ({:0.2f} $\pm$ {:0.2f} $MHz$ )". format(t2, t2_stderr, delta_f, delta_f_stderr)) # refresh canvas and rescale self._ax.relim() self._ax.autoscale_view() # update plot self._fitting_figure.canvas.draw() self._fitting_figure.canvas.flush_events() # Populating report self.fit_report_text.append(result.fit_report()) # Populating spinboxes self.y0.from_res(result) self.A.from_res(result) self.t2.from_res(result)
def poly_lorentzian(number_unique_lorentzians=None): model = Model(lorentzian, independent_vars=['x'], prefix='lorentzian1_') model += LinearModel(independent_vars=['x'], prefix='linear1_') if number_unique_lorentzians is None: raise UserWarning('number_unique_lorentzians need to be given') for i in range(2, number_unique_lorentzians + 1): model += Model(lorentzian, independent_vars=['x'], prefix='lorentzian{}_'.format(i)) return model
def make_poissonian_model(self, prefix=None): """ Create a model of a single poissonian with an offset. param str prefix: optional string, which serves as a prefix for all parameters used in this model. That will prevent name collisions if this model is used in a composite way. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. """ def poisson_function(x, mu): """ Function of a poisson distribution. @param numpy.array x: 1D array as the independent variable - e.g. occurences @param float mu: expectation value @return: poisson function: in order to use it as a model """ return self.poisson(x, mu) amplitude_model, params = self.make_amplitude_model(prefix=prefix) if not isinstance(prefix, str) and prefix is not None: self.log.error( 'The passed prefix <{0}> of type {1} is not a string and' 'cannot be used as a prefix and will be ignored for now.' 'Correct that!'.format(prefix, type(prefix))) poissonian_model = Model(poisson_function, independent_vars='x') else: poissonian_model = Model(poisson_function, independent_vars='x', prefix=prefix) poissonian_ampl_model = amplitude_model * poissonian_model params = poissonian_ampl_model.make_params() return poissonian_ampl_model, params
def make_barestretchedexponentialdecay_model(self, prefix=None): """ Create a general bare exponential decay model. @param str prefix: optional string, which serves as a prefix for all parameters used in this model. That will prevent name collisions if this model is used in a composite way. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. """ def barestretchedexponentialdecay_function(x, beta, lifetime): """ Function of a bare exponential decay. @param numpy.array x: 1D array as the independent variable - e.g. time @param float lifetime: constant lifetime @return: bare exponential decay function: in order to use it as a model """ return np.exp(-np.power(x / lifetime, beta)) if not isinstance(prefix, str) and prefix is not None: self.log.error( 'The passed prefix <{0}> of type {1} is not a string and' 'cannot be used as a prefix and will be ignored for now.' 'Correct that!'.format(prefix, type(prefix))) model = Model(barestretchedexponentialdecay_function, independent_vars='x') else: model = Model(barestretchedexponentialdecay_function, independent_vars='x', prefix=prefix) params = model.make_params() return model, params
def make_hyperbolicsaturation_model(self, prefix=None): """ Create a model of the fluorescence depending on excitation power with linear offset. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. """ def hyperbolicsaturation_function(x, I_sat, P_sat): """ Fluorescence depending excitation power function @param numpy.array x: 1D array as the independent variable e.g. power @param float I_sat: Saturation Intensity @param float P_sat: Saturation power @return: hyperbolicsaturation function: for using it as a model """ return I_sat * (x / (x + P_sat)) if not isinstance(prefix, str) and prefix is not None: self.log.error( 'The passed prefix <{0}> of type {1} is not a string and' 'cannot be used as a prefix and will be ignored for now.' 'Correct that!'.format(prefix, type(prefix))) mod_sat = Model(hyperbolicsaturation_function, independent_vars='x') else: mod_sat = Model(hyperbolicsaturation_function, independent_vars='x', prefix=prefix) linear_model, params = self.make_linear_model(prefix=prefix) complete_model = mod_sat + linear_model params = complete_model.make_params() return complete_model, params
def fitgaussian_lmfit(x, y, weights, return_fit=True, return_uncertainties=False): try: # noinspection PyUnresolvedReferences from lmfit.models import Model, GaussianModel except ImportError: print(' Need module lmfit to use fitgauss_lmfit') # calculate guess mod = GaussianModel() params = mod.guess(y, x=x) guess = np.array([ params['height'].value, params['center'].value, params['sigma'].value, 0.0 ]) # set up model fit gmodel = Model(gauss_function) # run model fit out = gmodel.fit(y, x=x, a=guess[0], x0=guess[1], sigma=guess[2], dc=guess[3], params=None, weights=weights) # extract out parameters pfit = [ out.values['a'], out.values['x0'], out.values['sigma'], out.values['dc'] ] # extract out standard errors siga = [ out.params['a'].stderr, out.params['x0'].stderr, out.params['sigma'].stderr, out.params['dc'].stderr ] # return if return_fit and return_uncertainties: return np.array(pfit), np.array(siga), out.best_fit elif return_uncertainties: return np.array(pfit), np.array(siga) elif return_fit: return np.array(pfit), out.best_fit else: return np.array(pfit)
def make_barestretchedexponentialdecay_model(self, prefix=None): """ Create a general bare exponential decay model. @param str prefix: optional string, which serves as a prefix for all parameters used in this model. That will prevent name collisions if this model is used in a composite way. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. """ def barestretchedexponentialdecay_function(x, beta, lifetime): """ Function of a bare exponential decay. @param numpy.array x: 1D array as the independent variable - e.g. time @param float lifetime: constant lifetime @return: bare exponential decay function: in order to use it as a model """ return np.exp(-np.power(x/lifetime, beta)) if not isinstance(prefix, str) and prefix is not None: self.log.error('The passed prefix <{0}> of type {1} is not a string and' 'cannot be used as a prefix and will be ignored for now.' 'Correct that!'.format(prefix, type(prefix))) model = Model(barestretchedexponentialdecay_function, independent_vars='x') else: model = Model(barestretchedexponentialdecay_function, independent_vars='x', prefix=prefix) params = model.make_params() return model, params
def make_constant_model(self, prefix=None): """ Create constant model. @param str prefix: optional string, which serves as a prefix for all parameters used in this model. That will prevent name collisions if this model is used in a composite way. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. For further information have a look in: http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html#models.GaussianModel """ def constant_function(x, offset): """ Function of a constant value. @param numpy.array x: 1D array as the independent variable - e.g. time @param float offset: constant offset @return: constant function, in order to use it as a model """ return offset if not isinstance(prefix, str) and prefix is not None: self.log.error( 'The passed prefix <{0}> of type {1} is not a string and cannot be used as ' 'a prefix and will be ignored for now. Correct that!'.format( prefix, type(prefix))) model = Model(constant_function, independent_vars='x') else: model = Model(constant_function, independent_vars='x', prefix=prefix) params = model.make_params() return model, params
def make_constant_model(self, prefix=None): """ Create constant model. @param str prefix: optional string, which serves as a prefix for all parameters used in this model. That will prevent name collisions if this model is used in a composite way. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. For further information have a look in: http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html#models.GaussianModel """ def constant_function(x, offset): """ Function of a constant value. @param numpy.array x: 1D array as the independent variable - e.g. time @param float offset: constant offset @return: constant function, in order to use it as a model """ return offset if not isinstance(prefix, str) and prefix is not None: self.log.error('The passed prefix <{0}> of type {1} is not a string and cannot be used as ' 'a prefix and will be ignored for now. Correct that!'.format(prefix, type(prefix))) model = Model(constant_function, independent_vars='x') else: model = Model(constant_function, independent_vars='x', prefix=prefix) params = model.make_params() return model, params
def _calc_fit_start_dep_curve(self): t2_array = [] t2_var_array = [] x_array = [] # Fit value fit_variable_name = self._graph_select.currentText() for start_fit_from in self.means[DELAY_TITLE]: start_fit_from = float(start_fit_from) fit_means = self.means[start_fit_from < self.means[DELAY_TITLE]] fit_std = self.std[start_fit_from < self.std[DELAY_TITLE]] params = self._init_params() model = Model(echo_decay_curve, independent_vars=['x']) try: result = model.fit(fit_means[fit_variable_name], x=fit_means[DELAY_TITLE], params=params, weights=1 / fit_std[LASER_TITLE]**2) t2_array.append(result.params.get('t2').value) t2_var_array.append(result.params.get('t2').stderr) x_array.append(start_fit_from) except TypeError: break ax = self._fitting_stats_figure.add_subplot(111) ax.errorbar(x_array, t2_array, yerr=t2_var_array, fmt='--bo', capthick=2, ecolor='b', alpha=0.9) ax.set_xlim([-10, 100]) ax.set_ylim([0, 2000]) ax.set_title("Зависимость $T_2$ от точки старта фитирования") # refresh canvas and tight layout self._fitting_stats_canvas.draw() self._fitting_stats_figure.tight_layout() self._fit_stats = True # Adding to fit report self.fit_report_text.append( "Зависимость t2 от точки старта фитирования:\n") self.fit_report_text.append(" ".join( "{:.4f}: {:.2f}".format(x, y) for x, y in zip(x_array, t2_array))) self.fit_report_text.append("\n")
def _make_model(fct, number_unique_lorentzians=None): if not fct == poly_gaussian and not fct == double_gaussian and not fct == poly_lorentzian: return Model(fct, independent_vars=['x']) elif not fct == poly_lorentzian: return fct() else: return poly_lorentzian( number_unique_lorentzians=number_unique_lorentzians)
def fit_signal(signal,l): x1=np.linspace(0,1,len(signal)) piecewiseModel=Model(piecewise_prob) piecewiseModel.set_param_hint('l', value=1,vary=False) piecewiseModel.set_param_hint('C', vary=True, value=.1,min=0,max=1) piecewiseModel.make_params() res=piecewiseModel.fit(signal,x=x1,weights=np.sin(1.5*x1)+1.5) return res
def fit_residuals(df, start_fit_from=0.4, fit_field='fit_lorenz_res', init_params=None): """ Fits residuals with EchoDecay curve """ x = np.array(df[df.index > start_fit_from].index.get_values()) y = np.array(df[df.index > start_fit_from][fit_field].values) echo_model = Model(echo_decay_curve, independent_vars=['x']) if init_params: params = init_params else: params = _init_echo_params(0, 500, 50) result = echo_model.fit(y, x=x, params=params) full_x = np.array(df.index.get_values()) res_fit_eval = result.eval(x=full_x) df['res_echo_fit'] = pd.Series(res_fit_eval, index=df.index) return df, result
def make_baresine_model(self, prefix=None): """ This method creates a model of bare sine without amplitude and offset. @param string prefix: variable prefix @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. For further information have a look in: http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html#models.GaussianModel """ def sine_function(x, frequency, phase): """ Function of a sine. @param x: variable variable - e.g. time @param frequency: frequency @param phase: phase @return: sine function: in order to use it as a model """ return np.sin(2 * np.pi * frequency * x + phase) if prefix is not None: model = Model(sine_function, prefix=prefix) else: model = Model(sine_function) params = model.make_params() return model, params
def make_linear_model(self, prefix=None): """ Create linear model. @param str prefix: optional string, which serves as a prefix for all parameters used in this model. That will prevent name collisions if this model is used in a composite way. @return tuple: (object model, object params), for more description see in the method make_constant_model. """ def linear_function(x): """ Function of a linear model. @param numpy.array x: 1D array as the independent variable - e.g. time @return: linear function, in order to use it as a model """ return x if not isinstance(prefix, str) and prefix is not None: self.log.error( 'The passed prefix <{0}> of type {1} is not a string and cannot be used as ' 'a prefix and will be ignored for now. Correct that!'.format( prefix, type(prefix))) linear_mod = Model(linear_function, independent_vars='x') else: linear_mod = Model(linear_function, independent_vars='x', prefix=prefix) slope, slope_param = self.make_slope_model(prefix=prefix) constant, constant_param = self.make_constant_model(prefix=prefix) model = slope * linear_mod + constant params = model.make_params() return model, params
def make_poissonian_model(self, no_of_functions=None): """ This method creates a model of a poissonian with an offset. @param no_of_functions: if None or 1 there is one poissonian, else more functions are added @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. The used model has the Parameter with the meaning: 'mu' : expected value mu """ def poisson_function(x, mu): """ Function of a poisson distribution. @param x: occurences @param mu: expected value @return: poisson function: in order to use it as a model """ return self.poisson(x, mu) def amplitude_function(x, amplitude): """ Function of a amplitude value. @param x: variable variable @param offset: independent variable - amplitude @return: amplitude function: in order to use it as a model """ return amplitude + 0.0 * x if no_of_functions is None or no_of_functions == 1: model = (Model(poisson_function, prefix='poissonian_') * Model(amplitude_function, prefix='poissonian_')) else: model = ( Model(poisson_function, prefix='poissonian{0}_'.format('0')) * Model(amplitude_function, prefix='poissonian{0}_'.format('0'))) for ii in range(no_of_functions - 1): model += (Model(poisson_function, prefix='poissonian{0}_'.format(ii + 1)) * Model(amplitude_function, prefix='poissonian{0}_'.format(ii + 1))) params = model.make_params() return model, params
def make_amplitude_model(self, prefix=None): """ This method creates a model of a constant model. @param string prefix: variable prefix @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. For further information have a look in: http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html#models.GaussianModel """ def amplitude_function(x, amplitude): """ Function of a constant value. @param x: variable variable @param amplitude: independent variable - e.g. amplitude @return: constant function: in order to use it as a model """ return amplitude + 0.0 * x if prefix is None: model = Model(amplitude_function) else: if not isinstance(prefix, str): logger.error('Given prefix in constant model is no string. ' 'Deleting prefix.') try: model = Model(amplitude_function, prefix=prefix) except: logger.error('Creating the constant model failed. ' 'The prefix might not be a valid string. ' 'The prefix was deleted.') model = Model(amplitude_function) params = model.make_params() return model, params
def make_powerfluorescence_model(self): """ This method creates a model of the fluorescence depending on excitation power with an linear offset. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. For further information have a look in: http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html#models.GaussianModel """ def powerfluorescence_function(x, I_saturation, P_saturation): """ Function to describe the fluorescence depending on excitation power @param x: variable variable - Excitation pwer @param I_saturation: Saturation Intensity @param P_saturation: Saturation power @return: powerfluorescence function: for using it as a model """ return I_saturation * (x / (x + P_saturation)) mod_sat = Model(powerfluorescence_function) model = mod_sat + LinearModel() params = model.make_params() return model, params
def make_stretchedexponentialdecay_model(self): """ This method creates a model of stretched exponential decay. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. """ def stretched_exponentialdecay_function(x, lifetime, beta): """ Function of a stretched exponential decay. @param x: variable variable - e.g. time @param amplitude: amplitude @param beta: stretch exponent @param offset: offset @return: streched exponential decay function: in order to use it as a model """ return np.exp(-np.power(x / lifetime, beta)) constant_model, params = self.make_constant_model() amplitude_model, params = self.make_amplitude_model() model = amplitude_model * Model( stretched_exponentialdecay_function) + constant_model params = model.make_params() return model, params
def UserDefinedFunctionFit(self): userDefinedFunctionList = [s for s in dir(UserDefinedFunction) if s[0].isupper()] d = QtGui.QInputDialog() func_name, ok = d.getItem( self, 'User Defined Function', 'Choose a function', userDefinedFunctionList) if ok: try: fun = getattr(UserDefinedFunction, str(func_name)) # print fun except AttributeError: QtGui.QMessageBox.warning( self, 'Warning', 'No such a function,\nplease check the name.') return else: return fun_model = Model(fun) self.Fitting(False, fun_model)
y1=smooth_signal(y1,10**3) y1=np.real(sharpen_filter(y1)) plt.clf() plt.plot(y1,'b') plt.savefig("".join([sys.argv[1],"blak"])+".png") print(sys.argv[1]+": Coverage OK ("+str(coveragePercentage)+" x).") x1=np.linspace(0,genomeLen-1,len(y1)) ### Korem fit # fit piecewise using least squares (LM) piecewiseModel=Model(piecewiseLinear) piecewiseModel.set_param_hint('Ol', value=0.5*genomeLen,vary=True,min=0,max=genomeLen) #piecewiseModel.set_param_hint('Tl', value=0.6*genomeLen,vary=True,min=0,max=genomeLen) piecewiseModel.set_param_hint('Tc', value = np.median(np.log2(y1)), vary=True) piecewiseModel.set_param_hint('Oc', value = np.median(np.log2(y1)), vary=True) piecewiseModel.set_param_hint('delta', value = 0.545*genomeLen, min=0.45*genomeLen, max=0.55*genomeLen, vary=True)#,expr='Tl-Ol if Tl-Ol > 0 else Ol-Tl') #piecewiseModel.set_param_hint('Tl', value=0.6*genomeLen,vary=True,min=0,max=genomeLen,expr='mod(Ol+delta,genLen)') piecewiseModel.set_param_hint('genLen', vary=False, value=genomeLen) piecewiseModel.make_params() result=piecewiseModel.fit(np.log2(y1),x=x1) resR2=R2(result.best_fit,y1) # var=np.var(abs(np.log2(y1)-result.best_fit), dtype=np.float64) #med=np.median(np.log2(y1))
def make_twoDgaussian_model(self, prefix=None): """ Creates a model of the 2D gaussian function. @param str prefix: optional, if multiple models should be used in a composite way and the parameters of each model should be distinguished from each other to prevent name collisions. @return tuple: (object model, object params), for more description see in the method make_gaussianwithoutoffset_model. """ def twoDgaussian_function(x, amplitude, center_x, center_y, sigma_x, sigma_y, theta, offset): """ Provide a two dimensional gaussian function. @param float amplitude: Amplitude of gaussian @param float center_x: x value of maximum @param float center_y: y value of maximum @param float sigma_x: standard deviation in x direction @param float sigma_y: standard deviation in y direction @param float theta: angle for eliptical gaussians @param float offset: offset @return callable function: returns the reference to the function Function taken from: http://stackoverflow.com/questions/21566379/fitting-a-2d-gaussian-function-using-scipy-optimize-curve-fit-valueerror-and-m/21566831 Question from: http://stackoverflow.com/users/2097737/bland http://stackoverflow.com/users/3273102/kokomoking http://stackoverflow.com/users/2767207/jojodmo Answer: http://stackoverflow.com/users/1461210/ali-m http://stackoverflow.com/users/5234/mrjrdnthms """ # FIXME: x_data_tuple: dimension of arrays # @param np.arra[k][M] x_data_tuple: array which is (k,M)-shaped, # x and y values (u, v) = x center_x = float(center_x) center_y = float(center_y) a = (np.cos(theta) ** 2) / (2 * sigma_x ** 2) \ + (np.sin(theta) ** 2) / (2 * sigma_y ** 2) b = -(np.sin(2 * theta)) / (4 * sigma_x ** 2) \ + (np.sin(2 * theta)) / (4 * sigma_y ** 2) c = (np.sin(theta) ** 2) / (2 * sigma_x ** 2) \ + (np.cos(theta) ** 2) / (2 * sigma_y ** 2) g = offset + amplitude * np.exp(- (a * ((u - center_x) ** 2) + 2 * b * (u - center_x) * (v - center_y) + c * ((v - center_y) ** 2))) return g.ravel() if not isinstance(prefix, str) and prefix is not None: self.log.error('The passed prefix <{0}> of type {1} is not a string and' 'cannot be used as a prefix and will be ignored for now.' 'Correct that!'.format(prefix, type(prefix))) gaussian_2d_model = Model(twoDgaussian_function, independent_vars='x') else: gaussian_2d_model = Model(twoDgaussian_function, independent_vars='x', prefix=prefix) params = gaussian_2d_model.make_params() return gaussian_2d_model, params
# ----------------------- Observed frame flux_voxel_norm = flux_voxel / norm_flux err_voxel_norm = flux_err / norm_flux obsLineWaves = wave_regions * (1 + z_objs[i]) idcsEmis, idcsCont = obsLm.define_masks(wave, flux_voxel_norm, obsLineWaves) emisWave, emisFlux = wave[idcsEmis], flux_voxel_norm[idcsEmis] contWave, contFlux = wave[idcsCont], flux_voxel_norm[idcsCont] obsLm.line_properties(emisWave, emisFlux, contWave, contFlux, bootstrap_size=5000) fit_model = Model(linear_model, prefix=f'{lineLabel}_cont_') fit_model.set_param_hint(f'{lineLabel}_cont_slope', **{ 'value': obsLm.m_cont, 'vary': False }) fit_model.set_param_hint(f'{lineLabel}_cont_intercept', **{ 'value': obsLm.n_cont, 'vary': False }) fit_model += Model(gaussian_model, prefix=f'{lineLabel}_') fit_model.set_param_hint(f'{lineLabel}_amplitude', value=obsLm.peak_flux - obsLm.cont) fit_model.set_param_hint(f'{lineLabel}_center', value=obsLm.peak_wave) fit_model.set_param_hint(f'{lineLabel}_sigma', value=1.0)
def lmfit_gaussian(x_array, y_array, err_array, x_boundarys): # Find indeces for six points in spectrum idcsW = np.searchsorted(x_array, x_boundarys) # Emission region idcsEmis = (x_array[idcsW[2]] <= x_array) & (x_array <= x_array[idcsW[3]]) # Return left and right continua merged in one array idcsCont = (((x_array[idcsW[0]] <= x_array) & (x_array <= x_array[idcsW[1]])) | ((x_array[idcsW[4]] <= x_array) & (x_array <= x_array[idcsW[5]]))).squeeze() emisWave, emisFlux = x_array[idcsEmis], y_array[idcsEmis] contWave, contFlux = x_array[idcsCont], y_array[idcsCont] idx_peak = np.argmax(emisFlux) fit_model = Model(linear_model, prefix=f'{lineLabel}_cont_') fit_model.set_param_hint(f'{lineLabel}_cont_slope', **{ 'value': 0, 'vary': False }) fit_model.set_param_hint(f'{lineLabel}_cont_intercept', **{ 'value': contFlux.mean(), 'vary': False }) fit_model += Model(gaussian_model, prefix=f'{lineLabel}_') fit_model.set_param_hint(f'{lineLabel}_amp', value=emisFlux[idx_peak] - contFlux.mean()) fit_model.set_param_hint(f'{lineLabel}_center', value=emisWave[idx_peak]) fit_model.set_param_hint(f'{lineLabel}_sigma', value=1.0) x_fit = x_array[idcsEmis + idcsCont] y_fit = y_array[idcsEmis + idcsCont] w_fit = 1.0 / err_array[idcsEmis + idcsCont] fit_params = fit_model.make_params() obs_fit_output = fit_model.fit(y_fit, fit_params, x=x_fit, weights=w_fit) # amp = obs_fit_output.params[f"{lineLabel}_amp"].value mu = obs_fit_output.params[f"{lineLabel}_center"].value sigma = obs_fit_output.params[f"{lineLabel}_sigma"].value mu_err = obs_fit_output.params[f"{lineLabel}_center"].stderr sigma_err = obs_fit_output.params[f"{lineLabel}_sigma"].stderr x_obs, y_obs = obs_fit_output.userkws['x'], obs_fit_output.data wave_obs = np.linspace(x_obs[0], x_obs[-1], 500) flux_comps_obs = obs_fit_output.eval_components(x=wave_obs) flux_obs = flux_comps_obs.get(f'{lineLabel}_cont_', 0.0) + flux_comps_obs[f'{lineLabel}_'] return x_fit, y_fit, wave_obs, flux_obs, mu, sigma, mu_err, sigma_err
def make_lorentzianwithoutoffset_model(self, prefix=None): """ Create a model of a bare physical Lorentzian with an amplitude. @param str prefix: optional, if multiple models should be used in a composite way and the parameters of each model should be distinguished from each other to prevent name collisions. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. For further information have a look in: http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html#models.LorentzianModel """ def physical_lorentzian(x, center, sigma): """ Function of a Lorentzian with unit height at center. @param numpy.array x: independent variable - e.g. frequency @param float center: center around which the distributions will be @param float sigma: half length at half maximum @return: numpy.array with length equals to input x and with the values of a lorentzian. """ return np.power(sigma, 2) / (np.power( (center - x), 2) + np.power(sigma, 2)) amplitude_model, params = self.make_amplitude_model(prefix=prefix) if not isinstance(prefix, str) and prefix is not None: self.log.error( 'The passed prefix <{0}> of type {1} is not a string and' 'cannot be used as a prefix and will be ignored for now.' 'Correct that!'.format(prefix, type(prefix))) lorentz_model = Model(physical_lorentzian, independent_vars='x') else: lorentz_model = Model(physical_lorentzian, independent_vars='x', prefix=prefix) full_lorentz_model = amplitude_model * lorentz_model params = full_lorentz_model.make_params() # introduces a new parameter, which is solely depending on others and which # will be not optimized: if prefix is None: prefix = '' full_lorentz_model.set_param_hint('{0!s}fwhm'.format(prefix), expr="2*{0!s}sigma".format(prefix)) # full_lorentz_model.set_param_hint('{0}contrast'.format(prefix), # expr='(-100.0)') # expr='({0!s}amplitude/offset)*100'.format(prefix)) # params.add('{0}contrast'.format(prefix), expr='({0!s}amplitude/offset)*100'.format(prefix)) return full_lorentz_model, params
def make_twoDgaussian_model(self, prefix=None): """ Creates a model of the 2D gaussian function. @param str prefix: optional, if multiple models should be used in a composite way and the parameters of each model should be distinguished from each other to prevent name collisions. @return tuple: (object model, object params), for more description see in the method make_gaussianwithoutoffset_model. """ def twoDgaussian_function(x, amplitude, center_x, center_y, sigma_x, sigma_y, theta, offset): """ Provide a two dimensional gaussian function. @param float amplitude: Amplitude of gaussian @param float center_x: x value of maximum @param float center_y: y value of maximum @param float sigma_x: standard deviation in x direction @param float sigma_y: standard deviation in y direction @param float theta: angle for eliptical gaussians @param float offset: offset @return callable function: returns the reference to the function Function taken from: http://stackoverflow.com/questions/21566379/fitting-a-2d-gaussian-function-using-scipy-optimize-curve-fit-valueerror-and-m/21566831 Question from: http://stackoverflow.com/users/2097737/bland http://stackoverflow.com/users/3273102/kokomoking http://stackoverflow.com/users/2767207/jojodmo Answer: http://stackoverflow.com/users/1461210/ali-m http://stackoverflow.com/users/5234/mrjrdnthms """ # FIXME: x_data_tuple: dimension of arrays # @param np.arra[k][M] x_data_tuple: array which is (k,M)-shaped, # x and y values (u, v) = x center_x = float(center_x) center_y = float(center_y) a = (np.cos(theta) ** 2) / (2 * sigma_x ** 2) \ + (np.sin(theta) ** 2) / (2 * sigma_y ** 2) b = -(np.sin(2 * theta)) / (4 * sigma_x ** 2) \ + (np.sin(2 * theta)) / (4 * sigma_y ** 2) c = (np.sin(theta) ** 2) / (2 * sigma_x ** 2) \ + (np.cos(theta) ** 2) / (2 * sigma_y ** 2) g = offset + amplitude * np.exp(-(a * ((u - center_x)**2) + 2 * b * (u - center_x) * (v - center_y) + c * ((v - center_y)**2))) return g.ravel() if not isinstance(prefix, str) and prefix is not None: self.log.error( 'The passed prefix <{0}> of type {1} is not a string and' 'cannot be used as a prefix and will be ignored for now.' 'Correct that!'.format(prefix, type(prefix))) gaussian_2d_model = Model(twoDgaussian_function, independent_vars='x') else: gaussian_2d_model = Model(twoDgaussian_function, independent_vars='x', prefix=prefix) params = gaussian_2d_model.make_params() return gaussian_2d_model, params
def double_gaussian(): gauss1 = Model(gaussian, independent_vars=['x'], prefix='gauss1_') gauss2 = Model(gaussian, independent_vars=['x'], prefix='gauss2_') linear1 = LinearModel(independent_vars=['x'], prefix='linear1_') model = gauss1 + linear1 + gauss2 return model