def onePeakVoigtFit(self): try: nRow, nCol = self.dockedOpt.fileInfo() self.gausFit.binFitData = plab.zeros((nRow, 0)) self.gausFit.OnePkFitData = plab.zeros( (nCol, 6)) # Creates the empty 2D List for j in range(nCol): yy = self.dockedOpt.TT[:, j] xx = plab.arange(0, len(yy)) x1 = xx[0] x2 = xx[-1] y1 = yy[0] y2 = yy[-1] m = (y2 - y1) / (x2 - x1) b = y2 - m * x2 mod = VoigtModel() mod.guess(yy, x=xx) pars = mod.guess(yy, x=xx) mod = mod + LinearModel() pars.add('intercept', value=b, vary=True) pars.add('slope', value=m, vary=True) out = mod.fit(yy, pars, x=xx) amplitude = out.best_values['amplitude'] fitError = self.getFitError(out.fit_report(sort_pars=True), amplitude) self.gausFit.OnePkFitData[j, :] = (amplitude, 0, out.best_values['center'], 0, out.best_values['sigma'], 0) # Saves fitted data of each fit fitData = out.best_fit binFit = np.reshape(fitData, (len(fitData), 1)) self.gausFit.binFitData = np.concatenate( (self.gausFit.binFitData, binFit), axis=1) if self.gausFit.continueGraphingEachFit == True: self.gausFit.graphEachFitRawData(xx, yy, out.best_fit, 'V') return False except Exception as e: qtWidgets.QMessageBox.warning( self.myMainWindow, "Error", "There was an error \n\n Exception: " + str(e)) return True
def test_param_set(): np.random.seed(2015) x = np.arange(0, 20, 0.05) y = gaussian(x, amplitude=15.43, center=4.5, sigma=2.13) y = y + 0.05 - 0.01*x + np.random.normal(scale=0.03, size=len(x)) model = VoigtModel() params = model.guess(y, x=x) # test #1: gamma is constrained to equal sigma sigval = params['gamma'].value assert(params['gamma'].expr == 'sigma') assert_allclose(params['gamma'].value, sigval, 1e-4, 1e-4, '', True) # test #2: explicitly setting a param value should work, even when # it had been an expression. The value will be left as fixed gamval = 0.87543 params['gamma'].set(value=gamval) assert(params['gamma'].expr is None) assert(not params['gamma'].vary) assert_allclose(params['gamma'].value, gamval, 1e-4, 1e-4, '', True) # test #3: explicitly setting an expression should work params['gamma'].set(expr='sigma/2.0') assert(params['gamma'].expr is not None) assert(not params['gamma'].vary) assert_allclose(params['gamma'].value, sigval/2.0, 1e-4, 1e-4, '', True) # test #4: explicitly setting a param value WITH vary=True # will set it to be variable gamval = 0.7777 params['gamma'].set(value=gamval, vary=True) assert(params['gamma'].expr is None) assert(params['gamma'].vary) assert_allclose(params['gamma'].value, gamval, 1e-4, 1e-4, '', True)
def test_bounds_expression(): # load data to be fitted data = np.loadtxt(os.path.join(os.path.dirname(__file__), '..', 'examples', 'test_peak.dat')) x = data[:, 0] y = data[:, 1] # define the model and initialize parameters mod = VoigtModel() params = mod.guess(y, x=x) params['amplitude'].set(min=0, max=100) params['center'].set(min=5, max=10) # do fit, here with leastsq model result = mod.fit(y, params, x=x) # assert that stderr and correlations are correct [cf. lmfit v0.9.10] assert_almost_equal(result.params['sigma'].stderr, 0.00368468, decimal=6) assert_almost_equal(result.params['center'].stderr, 0.00505496, decimal=6) assert_almost_equal(result.params['amplitude'].stderr, 0.13861506, decimal=6) assert_almost_equal(result.params['gamma'].stderr, 0.00368468, decimal=6) assert_almost_equal(result.params['fwhm'].stderr, 0.00806917, decimal=6) assert_almost_equal(result.params['height'].stderr, 0.03009459, decimal=6) assert_almost_equal(result.params['sigma'].correl['center'], -4.6623973788006615e-05, decimal=6) assert_almost_equal(result.params['sigma'].correl['amplitude'], 0.651304091954038, decimal=6) assert_almost_equal(result.params['center'].correl['amplitude'], -4.390334984618851e-05, decimal=6)
def test_saveload_usersyms(): """Test save/load of modelresult with non-trivial user symbols, this example uses a VoigtModel, wheree `wofz()` is used in a constraint expression""" x = np.linspace(0, 20, 501) y = gaussian(x, 1.1, 8.5, 2) + lorentzian(x, 1.7, 8.5, 1.5) np.random.seed(20) y = y + np.random.normal(size=len(x), scale=0.025) model = VoigtModel() pars = model.guess(y, x=x) result = model.fit(y, pars, x=x) savefile = 'tmpvoigt_modelresult.sav' save_modelresult(result, savefile) assert_param_between(result.params['sigma'], 0.7, 2.1) assert_param_between(result.params['center'], 8.4, 8.6) assert_param_between(result.params['height'], 0.2, 1.0) time.sleep(0.25) result2 = load_modelresult(savefile) assert_param_between(result2.params['sigma'], 0.7, 2.1) assert_param_between(result2.params['center'], 8.4, 8.6) assert_param_between(result2.params['height'], 0.2, 1.0)
def voigt_response(self, sigma=None, gamma=None, weights=True): ''' Fit the background with a Voigt profile to determine the response of the spectrometer If you have a good, clear signal, set sigma and gamma to None (done by default) If your signal is poor, set sigma and gamma using a fit to a good signal, and then only the position of the central wavelength will be altered. ''' vm = VoigtModel() par_v = vm.guess(self.bkgd, x=self.lamb) par_v['center'].set(value=532e-9, vary=True) if sigma is not None: #if a width is provided, fix it. par_v['sigma'].set(value=sigma, vary=False) if gamma is not None: #if a width is provided, fix it. par_v['gamma'].set(value=gamma, vary=False, expr='') elif gamma is None: #vary gamma for better fit - this is not done by default par_v['gamma'].set(value=par_v['sigma'].value, vary=True, expr='') ##Fit the Voigt Model to the data if weights is True: weights = self.bkgd / self.bkgd_err if weights is False: weights = np.ones_like(self.bkgd) self.vm_fit = vm.fit(self.bkgd, par_v, x=self.lamb, weights=weights) self.l0 = self.vm_fit.best_values['center'] self.sigma = self.vm_fit.best_values['sigma']
def test_numdifftools_calc_covar_false(): pytest.importorskip("numdifftools") # load data to be fitted data = np.loadtxt( os.path.join(os.path.dirname(__file__), '..', 'examples', 'test_peak.dat')) x = data[:, 0] y = data[:, 1] # define the model and initialize parameters mod = VoigtModel() params = mod.guess(y, x=x) params['sigma'].set(min=-np.inf) # do fit, with leastsq and nelder result = mod.fit(y, params, x=x, method='leastsq') result_ndt = mod.fit(y, params, x=x, method='nelder', calc_covar=False) # assert that fit converged to the same result vals = [result.params[p].value for p in result.params.valuesdict()] vals_ndt = [ result_ndt.params[p].value for p in result_ndt.params.valuesdict() ] assert_allclose(vals_ndt, vals, rtol=5e-3) assert_allclose(result_ndt.chisqr, result.chisqr) assert result_ndt.covar is None assert result_ndt.errorbars is False
def test_numdifftools_calc_covar_false(): pytest.importorskip("numdifftools") # load data to be fitted data = np.loadtxt(os.path.join(os.path.dirname(__file__), '..', 'examples', 'test_peak.dat')) x = data[:, 0] y = data[:, 1] # define the model and initialize parameters mod = VoigtModel() params = mod.guess(y, x=x) params['sigma'].set(min=-np.inf) # do fit, with leastsq and nelder result = mod.fit(y, params, x=x, method='leastsq') result_ndt = mod.fit(y, params, x=x, method='nelder', calc_covar=False) # assert that fit converged to the same result vals = [result.params[p].value for p in result.params.valuesdict()] vals_ndt = [result_ndt.params[p].value for p in result_ndt.params.valuesdict()] assert_allclose(vals_ndt, vals, rtol=5e-3) assert_allclose(result_ndt.chisqr, result.chisqr) assert result_ndt.covar is None assert result_ndt.errorbars is False
def test_numdifftools_with_bounds(fit_method): pytest.importorskip("numdifftools") if fit_method in ['shgo', 'dual_annealing']: pytest.importorskip("scipy", minversion="1.2") # load data to be fitted data = np.loadtxt( os.path.join(os.path.dirname(__file__), '..', 'examples', 'test_peak.dat')) x = data[:, 0] y = data[:, 1] # define the model and initialize parameters mod = VoigtModel() params = mod.guess(y, x=x) params['amplitude'].set(min=25, max=70) params['sigma'].set(max=1) params['center'].set(min=5, max=15) # do fit, here with leastsq model result = mod.fit(y, params, x=x, method='leastsq') result_ndt = mod.fit(y, params, x=x, method=fit_method) # assert that fit converged to the same result vals = [result.params[p].value for p in result.params.valuesdict()] vals_ndt = [ result_ndt.params[p].value for p in result_ndt.params.valuesdict() ] assert_allclose(vals_ndt, vals, rtol=0.1) assert_allclose(result_ndt.chisqr, result.chisqr, rtol=1e-5) # assert that parameter uncertaintes from leastsq and calculated from # the covariance matrix using numdifftools are very similar stderr = [result.params[p].stderr for p in result.params.valuesdict()] stderr_ndt = [ result_ndt.params[p].stderr for p in result_ndt.params.valuesdict() ] perr = np.array(stderr) / np.array(vals) perr_ndt = np.array(stderr_ndt) / np.array(vals_ndt) assert_almost_equal(perr_ndt, perr, decimal=3) # assert that parameter correlatations from leastsq and calculated from # the covariance matrix using numdifftools are very similar for par1 in result.var_names: cor = [ result.params[par1].correl[par2] for par2 in result.params[par1].correl.keys() ] cor_ndt = [ result_ndt.params[par1].correl[par2] for par2 in result_ndt.params[par1].correl.keys() ] assert_almost_equal(cor_ndt, cor, decimal=2)
def curve_fitting_voigt(dref, pars=None): xdata = dref.index.to_numpy() ydata = dref.to_numpy() mod = VoigtModel() if pars is None: pars = mod.guess(ydata, x=xdata) out = mod.fit(ydata, pars, x=xdata) return out
def test_least_squares_solver_options(peakdata, capsys): """Test least_squares algorithm, pass options to solver.""" x = peakdata[0] y = peakdata[1] mod = VoigtModel() params = mod.guess(y, x=x) solver_kws = {'verbose': 2} mod.fit(y, params, x=x, method='least_squares', fit_kws=solver_kws) captured = capsys.readouterr() assert 'Iteration' in captured.out assert 'final cost' in captured.out
def VoigtCalc(x, y, x1, y1): y = removerBackground(y) y1 = removerBackground(y1) mod = VoigtModel() pars = mod.guess(y, x=x) pars['gamma'].set(value=0.7, vary=True, expr='') out = mod.fit(y, pars, x=x) mod = VoigtModel() pars1 = mod.guess(y1, x=x1) pars1['gamma'].set(value=0.7, vary=True, expr='') out1 = mod.fit(y1, pars1, x=x1) center = out.best_values['center'] sigma = Decon_Gau(out.best_values['sigma'], out1.best_values['sigma']) gamma = Decon_Lor(out.best_values['gamma'], out1.best_values['gamma']) return SingleLineEquation(sigma, gamma, center)
def singleline(x, y, tipo, arquivo): ## pdb.set_trace() mod = VoigtModel() pars = mod.guess(y, x=x) pars['gamma'].set(value=0.7, vary=True, expr='') ## pars['sigma'].set(value=0.7, vary=True, expr='') out = mod.fit(y, pars, x=x) gamma = out.best_values['gamma'] sigma = out.best_values['sigma'] center = out.best_values['center'] calcsingleline(gamma, sigma, center, tipo, arquivo)
def fit_peak_1d( xdata: np.ndarray, ydata: np.ndarray, engine: str = 'lmfit', ) -> np.ndarray: """ Description ----------- Perform 1D peak fitting using Voigt function Parameters ---------- xdata: np.ndarray independent var array ydata: np.ndarray dependent var array engien: str engine name, [lmfit, tomoproc] Returns ------- dict dictionary of peak parameters NOTE ---- Return dictionary have different entries. """ if engine.lower() in ['lmfit', 'external']: mod = VoigtModel() pars = mod.guess(ydata, x=xdata) out = mod.fit(ydata, pars, x=xdata) return out.best_values else: popt, pcov = curve_fit( voigt1d, xdata, ydata, maxfev=int(1e6), p0=[ydata.max(), xdata.mean(), 1, 1], bounds=([0, xdata.min(), 0, 0], [ ydata.max() * 10, xdata.max(), xdata.max() - xdata.min(), np.inf ]), ) return { 'amplitude': popt[0], 'center': popt[1], 'fwhm': popt[2], 'shape': popt[3], }
def test_numdifftools_no_bounds(): numdifftools = pytest.importorskip("numdifftools") # load data to be fitted data = np.loadtxt( os.path.join(os.path.dirname(__file__), '..', 'examples', 'test_peak.dat')) x = data[:, 0] y = data[:, 1] # define the model and initialize parameters mod = VoigtModel() params = mod.guess(y, x=x) params['sigma'].set(min=-np.inf) # do fit, here with leastsq model result = mod.fit(y, params, x=x, method='leastsq') for fit_method in ['nelder', 'basinhopping', 'ampgo']: result_ndt = mod.fit(y, params, x=x, method=fit_method) # assert that fit converged to the same result vals = [result.params[p].value for p in result.params.valuesdict()] vals_ndt = [ result_ndt.params[p].value for p in result_ndt.params.valuesdict() ] assert_allclose(vals_ndt, vals, rtol=5e-3) assert_allclose(result_ndt.chisqr, result.chisqr) # assert that parameter uncertaintes from leastsq and calculated from # the covariance matrix using numdifftools are very similar stderr = [result.params[p].stderr for p in result.params.valuesdict()] stderr_ndt = [ result_ndt.params[p].stderr for p in result_ndt.params.valuesdict() ] perr = np.array(stderr) / np.array(vals) perr_ndt = np.array(stderr_ndt) / np.array(vals_ndt) assert_almost_equal(perr_ndt, perr, decimal=4) # assert that parameter correlatations from leastsq and calculated from # the covariance matrix using numdifftools are very similar for par1 in result.var_names: cor = [ result.params[par1].correl[par2] for par2 in result.params[par1].correl.keys() ] cor_ndt = [ result_ndt.params[par1].correl[par2] for par2 in result_ndt.params[par1].correl.keys() ] assert_almost_equal(cor_ndt, cor, decimal=2)
def correlate_spectra(obs_flx, obs_wvl, ref_flx, ref_wvl): # convert spectra sampling to logspace obs_flux_res_log, _ = spectra_logspace(obs_flx, obs_wvl) ref_flux_sub_log, wvl_log = spectra_logspace(ref_flx, ref_wvl) wvl_step = ref_wvl[1] - ref_wvl[0] # correlate the two spectra min_flux = 0.95 ref_flux_sub_log[ref_flux_sub_log > min_flux] = 0. obs_flux_res_log[obs_flux_res_log > min_flux] = 0. corr_res = correlate(ref_flux_sub_log, obs_flux_res_log, mode='same', method='fft') # plt.plot(corr_res) # plt.show() # plt.close() # create a correlation subset that will actually be analysed corr_w_size = 100 corr_c_off = np.int64(len(corr_res) / 2.) corr_pos_min = corr_c_off - corr_w_size corr_pos_max = corr_c_off + corr_w_size # print corr_pos_min, corr_pos_max corr_res_sub = corr_res[corr_pos_min:corr_pos_max] corr_res_sub -= np.median(corr_res_sub) corr_res_sub_x = np.arange(len(corr_res_sub)) # analyze correlation function by fitting gaussian/voigt/lorentzian distribution to it fit_model = VoigtModel() parameters = fit_model.guess(corr_res_sub, x=corr_res_sub_x) corr_fit_res = fit_model.fit(corr_res_sub, parameters, x=corr_res_sub_x) corr_center = corr_fit_res.params['center'].value # plt.plot(corr_res_sub) # plt.axvline(corr_center) # plt.show() # plt.close() # determine the actual shift idx_no_shift = np.int32(len(corr_res) / 2.) idx_center = corr_c_off - corr_w_size + corr_center log_shift_px = idx_no_shift - idx_center log_shift_wvl = log_shift_px * wvl_step wvl_log_new = wvl_log - log_shift_wvl rv_shifts = (wvl_log_new[1:] - wvl_log_new[:-1]) / wvl_log_new[:-1] * 299792.458 * log_shift_px if log_shift_wvl < 2: return np.nanmedian(rv_shifts) else: # something went wrong return np.nan
def test_least_squares_cov_x(peakdata, bounds): """Test calculation of cov. matrix from Jacobian, with/without bounds.""" x = peakdata[0] y = peakdata[1] # define the model and initialize parameters mod = VoigtModel() params = mod.guess(y, x=x) if bounds: params['amplitude'].set(min=25, max=70) params['sigma'].set(min=0, max=1) params['center'].set(min=5, max=15) else: params['sigma'].set(min=-np.inf) # do fit with least_squares and leastsq algorithm result = mod.fit(y, params, x=x, method='least_squares') result_lsq = mod.fit(y, params, x=x, method='leastsq') # assert that fit converged to the same result vals = [result.params[p].value for p in result.params.valuesdict()] vals_lsq = [ result_lsq.params[p].value for p in result_lsq.params.valuesdict() ] assert_allclose(vals, vals_lsq, rtol=1e-5) assert_allclose(result.chisqr, result_lsq.chisqr) # assert that parameter uncertaintes obtained from the leastsq method and # those from the covariance matrix estimated from the Jacbian matrix in # least_squares are similar stderr = [result.params[p].stderr for p in result.params.valuesdict()] stderr_lsq = [ result_lsq.params[p].stderr for p in result_lsq.params.valuesdict() ] assert_allclose(stderr, stderr_lsq, rtol=1e-4) # assert that parameter correlations obtained from the leastsq method and # those from the covariance matrix estimated from the Jacbian matrix in # least_squares are similar for par1 in result.var_names: cor = [ result.params[par1].correl[par2] for par2 in result.params[par1].correl.keys() ] cor_lsq = [ result_lsq.params[par1].correl[par2] for par2 in result_lsq.params[par1].correl.keys() ] assert_allclose(cor, cor_lsq, rtol=1e-2)
def xrdCalculationProcessing(spectrumData, centerXValsList, heightList, axs, setupOptions): proposedUserSubstrateTwoTheta = centerXValsList[heightList.index(max(heightList))] substrateModel = VoigtModel() params = substrateModel.guess(spectrumData.bgSubIntensity, x=spectrumData.xVals, negative=False) out = substrateModel.fit(spectrumData.bgSubIntensity, params, x=spectrumData.xVals) fullModelSubstrateTwoTheta = out.best_values['center'] if abs(fullModelSubstrateTwoTheta - proposedUserSubstrateTwoTheta) <= 0.1: # looks like the user selected the substrate as a peak, use their value substrateTwoTheta = proposedUserSubstrateTwoTheta else: # Looks like the user did not select the substrate as a peak, use a global value from fitting all data substrateTwoTheta = fullModelSubstrateTwoTheta literatureSubstrateTwoTheta = calculateTwoTheta(snContentPercent=0) # Reusing Sn content to 2theta equation twoThetaOffset = substrateTwoTheta - literatureSubstrateTwoTheta offsetCorrectedCenterTwoThetaList = np.asarray(centerXValsList) - twoThetaOffset for centerTwoTheta in offsetCorrectedCenterTwoThetaList: michaelSnContent = round(calculateXRDSnContent(centerTwoTheta), 1) print("Michael Comp:", michaelSnContent) print("Zach Comp:", round(calculateXRDSnContent_Zach(centerTwoTheta), 1)) if abs(centerTwoTheta - literatureSubstrateTwoTheta) > 0.05: # Don't draw one for the substrate _, centerIndex = closestNumAndIndex(spectrumData.xVals, centerTwoTheta + twoThetaOffset) if setupOptions.isLogPlot: basePlot = spectrumData.lnIntensity subtractedPlot = spectrumData.lnBgSubIntensity else: basePlot = spectrumData.intensity subtractedPlot = spectrumData.bgSubIntensity if setupOptions.doBackgroundSubtraction: an0 = axs[0].annotate(str(abs(michaelSnContent)), xy=(centerTwoTheta + twoThetaOffset, basePlot[centerIndex]), xycoords='data', xytext=(0, 72), textcoords='offset points', arrowprops=dict(arrowstyle="->", shrinkA=10, shrinkB=5, patchA=None, patchB=None)) an0.draggable() an1 = axs[1].annotate(str(abs(michaelSnContent)), xy=( centerTwoTheta + twoThetaOffset, subtractedPlot[centerIndex]), xycoords='data', xytext=(0, 72), textcoords='offset points', arrowprops=dict(arrowstyle="->", shrinkA=10, shrinkB=5, patchA=None, patchB=None)) an1.draggable() else: an0 = axs.annotate(str(abs(michaelSnContent)), xy=(centerTwoTheta + twoThetaOffset, subtractedPlot[centerIndex]), xycoords='data', xytext=(0, 72), textcoords='offset points', arrowprops=dict(arrowstyle="->", shrinkA=10, shrinkB=5, patchA=None, patchB=None)) an0.draggable()
def voigtFit(filename, xloc=0, yloc=1, stats=False, plot=False): # Read Data df = pd.read_csv(filename, header=None) # Remove bad pixel df.drop(df.index[446], inplace=True) df.fillna(method='bfill', inplace=True) # Narrow region for later delays if 'd5' in filename: df = df[(df.iloc[:, xloc] > 287.75) & (df.iloc[:, xloc] < 288.6)] if 'd4' in filename and ('m1r' or 'm2' in filename): df = df[(df.iloc[:, xloc] > 287.75) & (df.iloc[:, xloc] < 288.6)] x = np.array(df.iloc[:, xloc]) y = np.array(df.iloc[:, yloc]) # Set Voigt fit parameters mod = VoigtModel() pars = mod.guess(y, x=x) pars['gamma'].set(value=0.7, vary=True, expr='') # Perform Voigt fit out = mod.fit(y, pars, x=x) # Print fit statistics if stats: print(out.fit_report(min_correl=0.25, show_correl=False)) # Plot Voigt fit if plot: plt.plot(x, y, 'o', markersize=2.0, c='blue') plt.plot(x, out.best_fit, 'r-') dely = out.eval_uncertainty(sigma=5) plt.fill_between(x, out.best_fit - dely, out.best_fit + dely, color="#bc8f8f") plt.xlabel = 'Wavelength (nm)' plt.ylabel = 'Intensity (a.u.)' plt.xlim((287, 289.5)) plt.show() # Save fit statistics for par_name, param in out.params.items(): if par_name == 'gamma': return pd.DataFrame({ 'fid': [filename], 'fwhm_L': [2 * param.value], 'error': [2 * param.stderr], 'R^2': [out.redchi] })
def test_cov_x_with_bounds(): # load data to be fitted data = np.loadtxt( os.path.join(os.path.dirname(__file__), '..', 'examples', 'test_peak.dat')) x = data[:, 0] y = data[:, 1] # define the model and initialize parameters mod = VoigtModel() params = mod.guess(y, x=x) params['amplitude'].set(min=25, max=70) params['sigma'].set(min=0, max=1) params['center'].set(min=5, max=15) # do fit, here with leastsq model result = mod.fit(y, params, x=x, method='least_squares') result_lsq = mod.fit(y, params, x=x, method='leastsq') # assert that fit converged to the same result vals = [result.params[p].value for p in result.params.valuesdict()] vals_lsq = [ result_lsq.params[p].value for p in result_lsq.params.valuesdict() ] assert_allclose(vals_lsq, vals, rtol=1e-5) assert_allclose(result_lsq.chisqr, result.chisqr) # assert that parameter uncertaintes obtained from the leastsq method and # those from the covariance matrix estimated from the Jacbian matrix in # least_squares are similar stderr = [result.params[p].stderr for p in result.params.valuesdict()] stderr_lsq = [ result_lsq.params[p].stderr for p in result_lsq.params.valuesdict() ] assert_almost_equal(stderr_lsq, stderr, decimal=6) # assert that parameter correlations obtained from the leastsq method and # those from the covariance matrix estimated from the Jacbian matrix in # least_squares are similar for par1 in result.var_names: cor = [ result.params[par1].correl[par2] for par2 in result.params[par1].correl.keys() ] cor_lsq = [ result_lsq.params[par1].correl[par2] for par2 in result_lsq.params[par1].correl.keys() ] assert_almost_equal(cor_lsq, cor, decimal=6)
def prepareFittingModels(roiCoordsList, modelType): modelList = [] paramList = [] index = 1 for region in roiCoordsList: individualModelsList = [] individualParamsList = [] if isinstance(region, dict): # If the region is just a single region, make it a list so the for loops pulls a dict rather than a dict entry region = [region] for entry in region: prefixName = 'v' + str(index) + '_' index += 1 # pull info out of region dict selectedXVals = entry['x'] selectedYVals = entry['y'] mod = None if modelType.lower() == 'voigt': mod = VoigtModel(prefix=prefixName) elif modelType.lower() == 'psuedovoigt': mod = PseudoVoigtModel(prefix=prefixName) elif modelType.lower() == 'lorentzian': mod = LorentzianModel(prefix=prefixName) elif modelType.lower() == 'gaussian': mod = GaussianModel(prefix=prefixName) elif modelType.lower() == 'pearsonvii': mod = Pearson7Model(prefix=prefixName) assert mod, "Entered model type is not supported" individualModelsList.append(mod) pars = mod.guess(selectedYVals, x=selectedXVals, negative=False) pars[prefixName + 'center'].set(min=min(selectedXVals), max=max(selectedXVals)) pars[prefixName + 'amplitude'].set(min=0) pars[prefixName + 'sigma'].set(min=0) if modelType.lower() == 'voigt': pars[prefixName + 'gamma'].set(value=0.3, vary=True, expr='', min=0) individualParamsList.append(pars) combinedModel = individualModelsList[0] combinedParams = individualParamsList[0] if len(individualModelsList) > 1: for model, params in zip(individualModelsList[1:], individualParamsList[1:]): combinedModel += model combinedParams += params modelList.append(combinedModel) paramList.append(combinedParams) return modelList, paramList
def test_numdifftools_with_bounds(fit_method): pytest.importorskip("numdifftools") if fit_method == 'shgo': pytest.importorskip("scipy", minversion="1.2") # load data to be fitted data = np.loadtxt(os.path.join(os.path.dirname(__file__), '..', 'examples', 'test_peak.dat')) x = data[:, 0] y = data[:, 1] # define the model and initialize parameters mod = VoigtModel() params = mod.guess(y, x=x) params['amplitude'].set(min=25, max=70) params['sigma'].set(max=1) params['center'].set(min=5, max=15) # do fit, here with leastsq model result = mod.fit(y, params, x=x, method='leastsq') result_ndt = mod.fit(y, params, x=x, method=fit_method) # assert that fit converged to the same result vals = [result.params[p].value for p in result.params.valuesdict()] vals_ndt = [result_ndt.params[p].value for p in result_ndt.params.valuesdict()] assert_allclose(vals_ndt, vals, rtol=0.1) assert_allclose(result_ndt.chisqr, result.chisqr, rtol=1e-5) # assert that parameter uncertaintes from leastsq and calculated from # the covariance matrix using numdifftools are very similar stderr = [result.params[p].stderr for p in result.params.valuesdict()] stderr_ndt = [result_ndt.params[p].stderr for p in result_ndt.params.valuesdict()] perr = np.array(stderr) / np.array(vals) perr_ndt = np.array(stderr_ndt) / np.array(vals_ndt) assert_almost_equal(perr_ndt, perr, decimal=3) # assert that parameter correlatations from leastsq and calculated from # the covariance matrix using numdifftools are very similar for par1 in result.var_names: cor = [result.params[par1].correl[par2] for par2 in result.params[par1].correl.keys()] cor_ndt = [result_ndt.params[par1].correl[par2] for par2 in result_ndt.params[par1].correl.keys()] assert_almost_equal(cor_ndt, cor, decimal=2)
def peakfit(xvals, yvals, yerrors=None): """ Fit peak to scans """ peak_mod = VoigtModel() # peak_mod = GaussianModel() bkg_mod = LinearModel() pars = peak_mod.guess(yvals, x=xvals) pars += bkg_mod.make_params(intercept=np.min(yvals), slope=0) # pars['gamma'].set(value=0.7, vary=True, expr='') # don't fix gamma mod = peak_mod + bkg_mod out = mod.fit(yvals, pars, x=xvals, weights=yerrors) return out
def fit(self): x = self.energies_eV y = self.intensities model = VoigtModel() init_parameters = model.guess(y, x=x) self.fit_results = model.fit(y, init_parameters, x=x) values = self.fit_results.params.valuesdict() self.fit_results_position_eV = values['center'] self.fit_results_fwhm_eV = values['fwhm'] self.fit_results_sigma_eV = values['sigma'] self.fit_results_gamma_eV = values['gamma'] self.fit_results_area = values['amplitude'] self.fit_results_height = values['height']
def test_least_squares_cov_x(peakdata, bounds): """Test calculation of cov. matrix from Jacobian, with/without bounds.""" x = peakdata[0] y = peakdata[1] # define the model and initialize parameters mod = VoigtModel() params = mod.guess(y, x=x) if bounds: params['amplitude'].set(min=25, max=70) params['sigma'].set(min=0, max=1) params['center'].set(min=5, max=15) else: params['sigma'].set(min=-np.inf) # do fit with least_squares and leastsq algorithm result = mod.fit(y, params, x=x, method='least_squares') result_lsq = mod.fit(y, params, x=x, method='leastsq') # assert that fit converged to the same result vals = [result.params[p].value for p in result.params.valuesdict()] vals_lsq = [result_lsq.params[p].value for p in result_lsq.params.valuesdict()] assert_allclose(vals, vals_lsq, rtol=1e-5) assert_allclose(result.chisqr, result_lsq.chisqr) # assert that parameter uncertaintes obtained from the leastsq method and # those from the covariance matrix estimated from the Jacbian matrix in # least_squares are similar stderr = [result.params[p].stderr for p in result.params.valuesdict()] stderr_lsq = [result_lsq.params[p].stderr for p in result_lsq.params.valuesdict()] assert_allclose(stderr, stderr_lsq, rtol=1e-4) # assert that parameter correlations obtained from the leastsq method and # those from the covariance matrix estimated from the Jacbian matrix in # least_squares are similar for par1 in result.var_names: cor = [result.params[par1].correl[par2] for par2 in result.params[par1].correl.keys()] cor_lsq = [result_lsq.params[par1].correl[par2] for par2 in result_lsq.params[par1].correl.keys()] assert_allclose(cor, cor_lsq, rtol=1e-2)
def voigt_response(self, sigma=None, gamma=None): ''' Fit the background with a Voigt profile to determine the response of the spectrometer If you have a good, clear signal, set sigma and gamma to None (done by default) If your signal is poor, set sigma and gamma using a fit to a good signal, and then only the position of the central wavelength will be altered. ''' vm = VoigtModel() par_v = vm.guess(self.bkgd, x=self.lamb) par_v['center'].set(value=532e-9, vary=True) err = (self.bkgd_ferr * self.shot) if sigma is not None: #if a width is provided, fix it. par_v['sigma'].set(value=sigma, vary=False) if gamma is not None: #if a width is provided, fix it. par_v['gamma'].set(value=gamma, vary=False, expr='') elif gamma is None: #vary gamma for better fit - this is not done by default par_v['gamma'].set(value=par_v['sigma'].value, vary=True, expr='') ##Fit the Voigt Model to the data vm_fit = vm.fit(self.bkgd, par_v, x=self.lamb) self.vm_fit = vm_fit #now crop the data so that the response is symmetric for the convolution to work l0 = vm_fit.best_values['center'] self.sigma = vm_fit.best_values['sigma'] self.l0 = l0 l0_i = find_nearest(self.lamb, l0) l_size = self.lamb.size take_l = min( l0_i, l_size - l0_i) #trim the shortest distance from the central wavelength low_i = l0_i - take_l high_i = l0_i + take_l self.lamb = self.lamb[low_i:high_i] self.bkgd = self.bkgd[low_i:high_i] self.shot = self.shot[low_i:high_i] self.shot_ferr = self.shot_ferr[low_i:high_i] self.bkgd_ferr = self.bkgd_ferr[low_i:high_i] #the response is taken from the model so it is nice and smooth self.response = vm_fit.best_fit[low_i:high_i] self.shift = self.lamb - l0 #this is useful for plotting data
def test_param_set(): np.random.seed(2015) x = np.arange(0, 20, 0.05) y = gaussian(x, amplitude=15.43, center=4.5, sigma=2.13) y = y + 0.05 - 0.01 * x + np.random.normal(scale=0.03, size=len(x)) model = VoigtModel() params = model.guess(y, x=x) # test #1: gamma is constrained to equal sigma assert (params['gamma'].expr == 'sigma') params.update_constraints() sigval = params['gamma'].value assert_allclose(params['gamma'].value, sigval, 1e-4, 1e-4, '', True) # test #2: explicitly setting a param value should work, even when # it had been an expression. The value will be left as fixed gamval = 0.87543 params['gamma'].set(value=gamval) assert (params['gamma'].expr is None) assert (not params['gamma'].vary) assert_allclose(params['gamma'].value, gamval, 1e-4, 1e-4, '', True) # test #3: explicitly setting an expression should work # Note, the only way to ensure that **ALL** constraints are up to date # is to call params.update_constraints(). This is because the constraint # may have multiple dependencies. params['gamma'].set(expr='sigma/2.0') assert (params['gamma'].expr is not None) assert (not params['gamma'].vary) params.update_constraints() assert_allclose(params['gamma'].value, sigval / 2.0, 1e-4, 1e-4, '', True) # test #4: explicitly setting a param value WITH vary=True # will set it to be variable gamval = 0.7777 params['gamma'].set(value=gamval, vary=True) assert (params['gamma'].expr is None) assert (params['gamma'].vary) assert_allclose(params['gamma'].value, gamval, 1e-4, 1e-4, '', True)
def test_param_set(): np.random.seed(2015) x = np.arange(0, 20, 0.05) y = gaussian(x, amplitude=15.43, center=4.5, sigma=2.13) y = y + 0.05 - 0.01*x + np.random.normal(scale=0.03, size=len(x)) model = VoigtModel() params = model.guess(y, x=x) # test #1: gamma is constrained to equal sigma assert(params['gamma'].expr == 'sigma') params.update_constraints() sigval = params['gamma'].value assert_allclose(params['gamma'].value, sigval, 1e-4, 1e-4, '', True) # test #2: explicitly setting a param value should work, even when # it had been an expression. The value will be left as fixed gamval = 0.87543 params['gamma'].set(value=gamval) assert(params['gamma'].expr is None) assert(not params['gamma'].vary) assert_allclose(params['gamma'].value, gamval, 1e-4, 1e-4, '', True) # test #3: explicitly setting an expression should work # Note, the only way to ensure that **ALL** constraints are up to date # is to call params.update_constraints(). This is because the constraint # may have multiple dependencies. params['gamma'].set(expr='sigma/2.0') assert(params['gamma'].expr is not None) assert(not params['gamma'].vary) params.update_constraints() assert_allclose(params['gamma'].value, sigval/2.0, 1e-4, 1e-4, '', True) # test #4: explicitly setting a param value WITH vary=True # will set it to be variable gamval = 0.7777 params['gamma'].set(value=gamval, vary=True) assert(params['gamma'].expr is None) assert(params['gamma'].vary) assert_allclose(params['gamma'].value, gamval, 1e-4, 1e-4, '', True)
def Plotar(): global x, y, K, E, v mod = VoigtModel() pars = mod.guess(y, x=x) pars['gamma'].set(value=0.7, vary=True, expr='') out = mod.fit(y, pars, x=x) K = E / (1 + v) K = K / 2 mult = np.tan(np.radians(out.best_values['center'] / 2)) mult = 1 / mult print 'multi: ', mult K = K * mult * (-1) print K print out.best_values try: plt.title('Amostra') plt.xlabel('2Theta') plt.ylabel("Intensity") plt.plot(x, out.best_fit, 'r-', label='bestfit') plt.plot(x, y, linestyle='-', marker='o', label='material') plt.grid() plt.legend() plt.show() except: print 'vazio'
def getcenter(x,y): mod=VoigtModel() pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) return out.best_values['center']
def voigtFit(df, delay, span, stats=False, plot=False): # Remove bad pixel df.drop(df.index[446], inplace=True) df.fillna(method='bfill', inplace=True) # Limit fitting region to selected span if (delay == 15) & (span == (545.4, 545.8)): span = (545.55, 545.8) if (delay == 30) & (span == (545.4, 545.8)): span = (545.45, 545.85) elif (delay == 500) & (span == (545.4, 545.8)): span = (545.5, 545.75) if span == span3: if delay == 15: span = (536.9, 537.5) elif delay == 30: span = (537.05, 537.45) elif delay == 500: span = (537.1, 537.4) df = df[(df.index >= span[0]) & (df.index <= span[1])] x = df.index.values y = df[str(delay)].values # Set Voigt fit parameters mod = VoigtModel() pars = mod.guess(y, x=x) pars['gamma'].set(value=0.7, vary=True, expr='') # Perform Voigt fit out = mod.fit(y, pars, x=x) # Print fit statistics if stats: print(out.fit_report(min_correl=0.25, show_correl=False)) # Plot Voigt fit if plot: if span == span1: plt.subplot(1, 2, 1) plt.title('Fe I 544.69, Delay: {} ns'.format(delay)) elif span == span2: plt.subplot(1, 2, 2) plt.title('Fe I 545.55, Delay: {} ns'.format(delay)) else: plt.title('Fe I 537.15, Delay: {} ns'.format(delay)) plt.plot(x, y, 'o', markersize=2.0, c='blue') plt.plot(x, out.best_fit, 'r-') try: dely = out.eval_uncertainty(sigma=5) except: dely = 0 plt.fill_between(x, out.best_fit - dely, out.best_fit + dely, color="#bc8f8f") plt.xlabel('Wavelength (nm)') plt.ylabel('Intensity (a.u.)') plt.xlim(span) # Save fit statistics for par_name, param in out.params.items(): if par_name == 'gamma': return pd.DataFrame({ 'delay': [delay], 'fwhm_L': [2 * param.value], 'error': [2 * param.stderr], 'R^2': [out.redchi] })
def get_wavelength_from_std_tth(x, y, d_spacings, ns, plot=False): """ Return the wavelength from a two theta scan of a standard Parameters ---------- x: ndarray the two theta coordinates y: ndarray the detector intensity d_spacings: ndarray the dspacings of the standard ns: ndarray the multiplicity of the reflection plot: bool If true plot some of the intermediate data Returns ------- float: The average wavelength float: The standard deviation of the wavelength """ l, r, c = find_peaks(y, sides=12) n_sym_peaks = len(c) // 2 lmfit_centers = [] for lidx, ridx, peak_center in zip(l, r, c): suby = y[lidx:ridx] subx = x[lidx:ridx] mod1 = VoigtModel() mod2 = LinearModel() pars1 = mod1.guess(suby, x=subx) pars2 = mod2.make_params(slope=0, intercept=0) mod = mod1 + mod2 pars = pars1 + pars2 out = mod.fit(suby, pars, x=subx) lmfit_centers.append(out.values['center']) if plot: plt.plot(subx, out.best_fit, '--') plt.plot(subx, suby - out.best_fit, '.') lmfit_centers = np.asarray(lmfit_centers) if plot: plt.plot(x, y, 'b') plt.plot(x[c], y[c], 'ro') plt.plot(x, np.zeros(x.shape), 'k.') plt.show() offset = [] for i in range(0, n_sym_peaks): o = (np.abs(lmfit_centers[i]) - np.abs(lmfit_centers[2 * n_sym_peaks - i - 1])) / 2. # print(o) offset.append(o) print('predicted offset {}'.format(np.median(offset))) lmfit_centers += np.median(offset) print(lmfit_centers) wavelengths = [] l_peaks = lmfit_centers[lmfit_centers < 0.] r_peaks = lmfit_centers[lmfit_centers > 0.] for peak_set in [r_peaks, l_peaks[::-1]]: for peak_center, d, n in zip(peak_set, d_spacings, ns): tth = np.deg2rad(np.abs(peak_center)) wavelengths.append(lamda_from_bragg(tth, d, n)) return np.average(wavelengths), np.std(wavelengths), np.median(offset)
def NewSingleLineDouble(): plt.close() print "Single Line" global x, y, xs, ys copyx = copy.copy(x) copyy = copy.copy(y) copyxs = copy.copy(xs) copyys = copy.copy(ys) mini, maxi = getminmax() minis, maxis = stgetminmax() x = x[mini:maxi] y = y[mini:maxi] xs = xs[minis:maxis] ys = ys[minis:maxis] #pdb.set_trace() #mod = methodfunciont((comboBox1.get())) #print mod mod = VoigtModel() pars = mod.guess(y, x=x) ## pars['gamma'].set(value=0.5, vary=True, expr='') ## pars['sigma'].set(value=0.5, vary=True, expr='') out = mod.fit(y, pars, x=x) pars1 = mod.guess(ys, x=xs) ## pars1['gamma'].set(value=0.5, vary=True, expr='') ## pars1['sigma'].set(value=0.5, vary=True, expr='') out1 = mod.fit(ys, pars1, x=xs) if out.best_values['gamma'] < out.best_values['gamma']: pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) pars1 = mod.guess(ys, x=xs) out1 = mod.fit(ys, pars1, x=xs) print(out.values) print(out1.values) try: G = np.sqrt( ((2.3548200 * 1.06446701943 * np.radians(out.best_values['sigma'])) **2 - (2.3548200 * 1.06446701943 * np.radians(out1.best_values['sigma']))**2)) padrao = (2.3548200 * 1.06446701943 * np.radians(out.best_values['sigma']))**2 amostra = (2.3548200 * 1.06446701943 * np.radians(out1.best_values['sigma']))**2 except: G = 0 L = np.radians(2 * out.best_values['gamma']) * 1.57079632679 - np.radians( 2 * out1.best_values['gamma']) * 1.57079632679 lambida = radiation(comboBoxrad.get()) #nm costheta = np.cos(np.radians(out.best_values['center'] / 2)) tantheta = np.tan(np.radians(out.best_values['center'] / 2)) RMSS = G / (4 * tantheta) RMSS = RMSS * 0.7978845608 D = (lambida) / (L * costheta) D = int(D) print 'D', D, 'RMSS', RMSS plt.figure(1) plt.subplot(121) plt.grid() plt.xlabel('$2\Theta$', size=15) plt.ylabel("Normalized(u.a)", size=15) plt.plot(x, y, 'k-+', label='Amostra') plt.plot(x, out.best_fit, 'k-', label='Best Fit') plt.legend() plt.subplot(122) plt.grid() plt.xlabel('$2\Theta$', size=15) plt.ylabel("Normalized(u.a)", size=15) plt.plot(xs, ys, 'k-+', label='Padrao') plt.plot(xs, out1.best_fit, 'k--', label='Best Fit') plt.legend() x = copyx xs = copyxs y = copyy ys = copyys plt.show()
def SingleLine(): plt.close() global x, y, Lv mini, maxi = getminmax() x = x[mini:maxi] y = y[mini:maxi] if str(comboBox.get()) == 'VoigtModel': mod = VoigtModel() pars = mod.guess(y, x=x) pars['gamma'].set(value=0.7, vary=True, expr='') out = mod.fit(y, pars, x=x) elif str(comboBox.get()) == 'PseudoVoigtModel': mod = PseudoVoigtModel() pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) print "Saida de dados" print(out.fit_report()) print "Melhores dados" print out.best_values plt.figure(1) plt.subplot(221) plt.plot(x, y, label='original data', linestyle='-', marker='o') plt.title('Amostra') plt.xlabel('$2\Theta$') plt.ylabel("Intensity") plt.grid() plt.legend() plt.subplot(222) plt.plot(x, out.best_fit, 'r-', label='best fit', linestyle='-', marker='o') plt.title('Amostra') plt.xlabel('$2\Theta$') plt.ylabel("Intensity") plt.grid() plt.legend() plt.subplot(212) plt.plot(x, y, linestyle='-', marker='o') plt.title(str(str(comboBox.get()))) lambida = radiation(comboBoxrad.get()) #D=(lambida)/( radians( out.best_values['sigma']*0.5*sqrt(pi/log1p(2))) *2*cos( radians( out.best_values['center']/2))) center = out.best_values['center'] / 2 center = radians(center) center = cos(center) tancenter = tan(center) sigmaL = out.best_values['gamma'] #*3.6013100 sigmaL = radians(sigmaL) * 0.5 * sqrt(pi / log1p(2)) D = lambida / (sigmaL * center) Lv = D E = (pi / sqrt(4 * log1p(2))) * ( (radians(out.best_values['sigma'] * pi / 2))) / (4 * tancenter) if E < 0: E *= -1 if D < 0: D *= -1 #t = plt.text(0.5, 0.5, '$L_V(nm)$: '+ str(D) + '\n$<e>$: '+ str(E), transform=plt.subplot(212).transAxes, fontsize=10) #t.set_bbox(dict(color='red', alpha=0.5, edgecolor='red')) plt.xlabel('$2\Theta$') plt.ylabel("Intensity") print D print E plt.plot(x, out.best_fit, 'r-', label='$L_V(nm)$: ' + str(int(D)) + '\n$ <e> $: ' + str(E), linestyle='-', marker='o') plt.plot(x, y - out.best_fit, label="residual") plt.legend() plt.grid() plt.show()
class gene_set(): def __init__(self, gene_id, cluster): self.cluster = cluster self.gene_id = gene_id self.norm_vals = [ float(y) for y in [x[1:] for x in reference if x[0] == gene_id][0] ] #TPM. self.get_model() self.def_peaks() self.model_resetting() self.half_life() #self.printing() self.saving() def get_model(self): self.x = np.array([0, 1, 2, 6, 12, 24]) self.y = np.array(self.norm_vals) # Compound model with Voigt curve. self.background = ExponentialModel(prefix='b_') self.pars = self.background.guess(self.y, x=self.x) self.peak = VoigtModel(prefix='p_') self.pars += self.peak.guess(self.y, x=self.x) self.comp_mod = self.peak + self.background self.init = self.comp_mod.eval(self.pars, x=self.x) self.comp_out = self.comp_mod.fit( self.y, x=self.x, fit_kws={'nan_policy': 'propagate' }) # instead of 'omit', it keeps up the zero vals. self.comp_list = self.comp_out.fit_report().split('\n') self.comp_chisq = float(self.comp_list[6][-5:]) self.out = self.comp_out self.chisq = float(self.comp_list[6][-5:]) self.usedmod = self.comp_mod self.model_flag = "composite (exponential+Voigt)" return self.comp_out, self.comp_chisq, self.out, self.chisq, self.usedmod, self.model_flag def def_peaks(self): self.bestfit = self.comp_out.best_fit self.idx = np.argmin(np.abs(self.bestfit - 0.5)) self.mysort = np.argsort(np.abs(self.bestfit - 0.5)) self.peak_flag = None if all(i > 0.5 for i in self.bestfit): # Meaning that it is never reaching the half-life, and we don't do extrapolation (not enough data points). self.min = 0 self.max = 0 self.peak_flag = "No predictable half-life" else: if self.bestfit[self.idx] == 0.5: # If by accident one time point hits the half-life. self.half_life_y = self.bestfit[self.idx] self.half_life_x = self.idx self.peak_flag = "Exact compound half-life" elif self.bestfit[0] > 0.5 and self.bestfit[1] < 0.5: self.min = self.x[0] self.max = self.x[1] self.peak_flag = "Compound" elif self.idx == 5 and self.bestfit[self.idx - 1] < 0.5: # Last value crosses only self.max = self.x[self.idx] self.min = self.x[self.idx - 1] self.peak_flag = "Compound" elif np.abs(self.idx - self.mysort[1]) == 1: if self.bestfit[self.idx] < 0.5: self.min = self.x[self.idx - 1] self.max = self.x[self.idx] self.peak_flag = "Compound" elif self.bestfit[self.idx] > 0.5: self.min = self.x[self.idx] self.max = self.x[self.idx + 1] self.peak_flag = "Compound" elif np.abs(self.idx - self.mysort[1]) > 1: # Meaning that the steps are not linear, there's a bump. if self.bestfit[self.idx] < 0.5: self.min = self.x[self.idx - 1] self.max = self.x[self.idx] self.peak_flag = "Compound" elif self.bestfit[self.idx] > 0.5 and self.bestfit[ self.mysort[1]] < 0.5: if self.bestfit[self.idx + 1] < 0.5: self.min = self.x[self.idx] self.max = self.x[self.idx + 1] self.peak_flag = "Compound" #resetting!! else: self.min = self.x[self.mysort[1] - 1] self.max = self.x[self.mysort[1]] self.peak_flag = "Resetting" elif self.bestfit[self.idx] > 0.5 and self.bestfit[ self.mysort[1]] > 0.5: if self.bestfit[self.idx + 1] < 0.5: self.min = self.x[self.idx] self.max = self.x[self.idx + 1] self.peak_flag = "Compound" #resetting!! elif self.bestfit[self.idx + 1] > 0.5 and self.bestfit[ self.mysort[1] + 1] < 0.5: self.min = self.x[self.mysort[1] - 1] self.max = self.x[self.mysort[1]] self.peak_flag = "Resetting" return self.min, self.max, self.peak_flag, self.bestfit def model_resetting(self): if self.peak_flag != "Resetting": #go for the previous method pass elif self.peak_flag == "Resetting": # mostly for plotting, half-life needs new zeros self.scnd_peak = np.sort(self.bestfit)[-2] self.scnd_idx = np.argsort(self.bestfit)[-2] self.newzero = self.x[self.scnd_idx] # Cutting the new time scale, reset to 0. self.x2 = np.array( [i - self.newzero for i in self.x[self.scnd_idx:]]) #x2 = np.array([i for i in x[scnd_idx:]]) # Re-normalized and cutted array self.y2 = np.array( [i / self.y[self.scnd_idx] for i in self.y[self.scnd_idx:]]) #newarray = myarray[scnd_idx:] self.exp_mod = ExponentialModel(prefix='e_') self.pars = self.exp_mod.guess(self.y2, x=self.x2) self.init = self.exp_mod.eval(self.pars, x=self.x2) self.exp_out = self.exp_mod.fit(self.y2, x=self.x2, missing='drop') self.exp_list = self.exp_out.fit_report().split('\n') self.exp_chisq = float(self.exp_list[6][-5:]) self.out = self.exp_out self.chisq = float(self.exp_list[6][-5:]) self.usedmod = self.exp_mod self.bestfit = self.exp_out.best_fit self.idx = np.argmin(np.abs(self.bestfit - 0.5)) self.mysort = np.argsort(np.abs(self.bestfit - 0.5)) self.peak_flag = None if self.bestfit[self.idx] < 0.5: self.min = self.x2[self.idx - 1] self.max = self.x2[self.idx] self.peak_flag = "Resetted exponential" elif self.bestfit[self.idx] > 0.5: self.min = self.x2[self.idx] self.max = self.x2[self.idx + 1] self.peak_flag = "Resetted exponential" # For printing. if len(self.bestfit) < 6: l = [self.bestfit[-1]] * (6 - len(self.bestfit)) self.bestfit = np.append(self.bestfit, l) self.x = self.x2 self.y = self.y2 self.model_flag = "exponential" return self.min, self.max, self.peak_flag, self.bestfit, self.x, self.out, self.chisq, self.usedmod, self.model_flag def half_life(self): self.new_x = np.array([0]) self.hl_eval = np.array([0]) self.hl_array = np.array([0]) self.hl_coord = np.array([0]) self.step = None if self.max == 0: self.half_life_y = 0 self.half_life_x = 0 self.peak_flag = "No predictable half-life" else: self.half_life_y = 0 self.half_life_x = 0 self.step = 0.1 self.max_allowed = 3 self.attempt = 0 #while self.attempt < 3 or self.half_life_y == 0: while self.half_life_y == 0 and self.attempt < 3: self.attempt += 1 self.step = self.step / 100 self.ranging = np.arange( self.min, self.max, self.step ) # normally it 0.001, but the slope is so radical, can't catxh half-life. for j in np.nditer(self.ranging): self.new_x = np.array([j]) #self.h = self.out.eval_components(self.out.params,x=self.new_x) #self.hl_eval = list(self.h.values())[-1] self.hl_eval = self.out.eval(self.out.params, x=self.new_x) if self.hl_eval >= 0.50 and self.hl_eval <= 0.51: self.hl_array = np.append(self.hl_array, self.hl_eval) self.hl_coord = np.append(self.hl_coord, self.new_x) self.half_life_id = np.argmin(np.abs(self.hl_array - 0.5)) self.half_life_y = self.hl_array[self.half_life_id] self.half_life_x = self.hl_coord[self.half_life_id] self.peak_flag = self.peak_flag if self.half_life_y == 0: self.peak_flag = "Above permitted interpolation iterations" return self.half_life_y, self.half_life_x, self.peak_flag def saving(self): with open('model_fit_c5_average_filtering_compound.txt', 'a') as f: f.write( "%s\t%s\t%s\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%s\n" % (self.gene_id, self.cluster, self.model_flag, self.chisq, self.half_life_y, self.half_life_x, self.norm_vals[0], self.norm_vals[1], self.norm_vals[2], self.norm_vals[3], self.norm_vals[4], self.norm_vals[5], self.bestfit[0], self.bestfit[1], self.bestfit[2], self.bestfit[3], self.bestfit[4], self.bestfit[5], self.peak_flag))
def test_param_set(): np.random.seed(2015) x = np.arange(0, 20, 0.05) y = gaussian(x, amplitude=15.43, center=4.5, sigma=2.13) y = y + 0.05 - 0.01*x + np.random.normal(scale=0.03, size=len(x)) model = VoigtModel() params = model.guess(y, x=x) # test #1: gamma is constrained to equal sigma assert(params['gamma'].expr == 'sigma') params.update_constraints() sigval = params['sigma'].value assert_allclose(params['gamma'].value, sigval, 1e-4, 1e-4, '', True) # test #2: explicitly setting a param value should work, even when # it had been an expression. The value will be left as fixed gamval = 0.87543 params['gamma'].set(value=gamval) assert(params['gamma'].expr is None) assert(not params['gamma'].vary) assert_allclose(params['gamma'].value, gamval, 1e-4, 1e-4, '', True) # test #3: explicitly setting an expression should work # Note, the only way to ensure that **ALL** constraints are up to date # is to call params.update_constraints(). This is because the constraint # may have multiple dependencies. params['gamma'].set(expr='sigma/2.0') assert(params['gamma'].expr is not None) assert(not params['gamma'].vary) params.update_constraints() assert_allclose(params['gamma'].value, sigval/2.0, 1e-4, 1e-4, '', True) # test #4: explicitly setting a param value WITH vary=True # will set it to be variable gamval = 0.7777 params['gamma'].set(value=gamval, vary=True) assert(params['gamma'].expr is None) assert(params['gamma'].vary) assert_allclose(params['gamma'].value, gamval, 1e-4, 1e-4, '', True) # test 5: make sure issue #389 is fixed: set boundaries and make sure # they are kept when changing the value amplitude_vary = params['amplitude'].vary amplitude_expr = params['amplitude'].expr params['amplitude'].set(min=0.0, max=100.0) params.update_constraints() assert_allclose(params['amplitude'].min, 0.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].max, 100.0, 1e-4, 1e-4, '', True) params['amplitude'].set(value=40.0) params.update_constraints() assert_allclose(params['amplitude'].value, 40.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].min, 0.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].max, 100.0, 1e-4, 1e-4, '', True) assert(params['amplitude'].expr == amplitude_expr) assert(params['amplitude'].vary == amplitude_vary) assert(not params['amplitude'].brute_step) # test for possible regressions of this fix (without 'expr'): # the set function should only change the requested attribute(s) params['amplitude'].set(value=35.0) params.update_constraints() assert_allclose(params['amplitude'].value, 35.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].min, 0.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].max, 100.0, 1e-4, 1e-4, '', True) assert(params['amplitude'].vary == amplitude_vary) assert(params['amplitude'].expr == amplitude_expr) assert(not params['amplitude'].brute_step) # set minimum params['amplitude'].set(min=10.0) params.update_constraints() assert_allclose(params['amplitude'].value, 35.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].min, 10.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].max, 100.0, 1e-4, 1e-4, '', True) assert(params['amplitude'].vary == amplitude_vary) assert(params['amplitude'].expr == amplitude_expr) assert(not params['amplitude'].brute_step) # set maximum params['amplitude'].set(max=110.0) params.update_constraints() assert_allclose(params['amplitude'].value, 35.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].min, 10.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].max, 110.0, 1e-4, 1e-4, '', True) assert(params['amplitude'].vary == amplitude_vary) assert(params['amplitude'].expr == amplitude_expr) assert(not params['amplitude'].brute_step) # set vary params['amplitude'].set(vary=False) params.update_constraints() assert_allclose(params['amplitude'].value, 35.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].min, 10.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].max, 110.0, 1e-4, 1e-4, '', True) assert(params['amplitude'].vary == False) assert(params['amplitude'].expr == amplitude_expr) assert(not params['amplitude'].brute_step) # set brute_step params['amplitude'].set(brute_step=0.1) params.update_constraints() assert_allclose(params['amplitude'].value, 35.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].min, 10.0, 1e-4, 1e-4, '', True) assert_allclose(params['amplitude'].max, 110.0, 1e-4, 1e-4, '', True) assert(params['amplitude'].vary == False) assert(params['amplitude'].expr == amplitude_expr) assert_allclose(params['amplitude'].brute_step, 0.1, 1e-4, 1e-4, '', True) # test for possible regressions of this fix for variables WITH 'expr': height_value = params['height'].value height_min = params['height'].min height_max = params['height'].max height_vary = params['height'].vary height_expr = params['height'].expr height_brute_step = params['height'].brute_step # set vary=True should remove expression params['height'].set(vary=True) params.update_constraints() assert_allclose(params['height'].value, height_value, 1e-4, 1e-4, '', True) assert_allclose(params['height'].min, height_min, 1e-4, 1e-4, '', True) assert_allclose(params['height'].max, height_max, 1e-4, 1e-4, '', True) assert(params['height'].vary == True) assert(params['height'].expr == None) assert(params['height'].brute_step == height_brute_step) # setting an expression should set vary=False params['height'].set(expr=height_expr) params.update_constraints() assert_allclose(params['height'].value, height_value, 1e-4, 1e-4, '', True) assert_allclose(params['height'].min, height_min, 1e-4, 1e-4, '', True) assert_allclose(params['height'].max, height_max, 1e-4, 1e-4, '', True) assert(params['height'].vary == False) assert(params['height'].expr == height_expr) assert(params['height'].brute_step == height_brute_step) # changing min/max should not remove expression params['height'].set(min=0) params.update_constraints() assert_allclose(params['height'].value, height_value, 1e-4, 1e-4, '', True) assert_allclose(params['height'].min, 0.0, 1e-4, 1e-4, '', True) assert_allclose(params['height'].max, height_max, 1e-4, 1e-4, '', True) assert(params['height'].vary == height_vary) assert(params['height'].expr == height_expr) assert(params['height'].brute_step == height_brute_step) # changing brute_step should not remove expression params['height'].set(brute_step=0.1) params.update_constraints() assert_allclose(params['height'].value, height_value, 1e-4, 1e-4, '', True) assert_allclose(params['height'].min, 0.0, 1e-4, 1e-4, '', True) assert_allclose(params['height'].max, height_max, 1e-4, 1e-4, '', True) assert(params['height'].vary == height_vary) assert(params['height'].expr == height_expr) assert_allclose(params['amplitude'].brute_step, 0.1, 1e-4, 1e-4, '', True) # changing the value should remove expression and keep vary=False params['height'].set(brute_step=0) params['height'].set(value=10.0) params.update_constraints() assert_allclose(params['height'].value, 10.0, 1e-4, 1e-4, '', True) assert_allclose(params['height'].min, 0.0, 1e-4, 1e-4, '', True) assert_allclose(params['height'].max, height_max, 1e-4, 1e-4, '', True) assert(params['height'].vary == False) assert(params['height'].expr == None) assert(params['height'].brute_step == height_brute_step) # passing expr='' should only remove the expression params['height'].set(expr=height_expr) # first restore the original expr params.update_constraints() params['height'].set(expr='') params.update_constraints() assert_allclose(params['height'].value, height_value, 1e-4, 1e-4, '', True) assert_allclose(params['height'].min, 0.0, 1e-4, 1e-4, '', True) assert_allclose(params['height'].max, height_max, 1e-4, 1e-4, '', True) assert(params['height'].vary == False) assert(params['height'].expr == None) assert(params['height'].brute_step == height_brute_step)