def test_fit_plot_see_errorbar_warnings(caplog, statClass, flag): """Do we see the warning when expected - fit plot? This looks for the 'The displayed errorbars have been supplied with the data or calculated using chi2xspecvar; the errors are not used in fits with <>' message. These are messages displayed to the Sherpa logger at the warning level, rather than using the warnings module, so the Sherpa capture_all_warnings test fixture does not come into play. Parameters ---------- stat : sherpa.stats.Stat instance flag : bool True if the warning should be created, False otherwise """ d = example_data() m = example_model() dplot = DataPlot() mplot = ModelPlot() fplot = FitPlot() # Internal check: this test requires that either yerrorbars is set # to True, or not included, in the plot preferences. So check this # assumption. # # I am skipping model plot here, since it is assumed that there # are no errors on the model. # prefname = 'yerrorbars' for plot in [dplot, fplot]: prefs = plot.plot_prefs assert (prefname not in prefs) or prefs[prefname] stat = statClass() # Ensure that the logging is set to WARNING since there # appears to be some test that changes it to ERROR. # with caplog.at_level(logging.INFO, logger='sherpa'): dplot.prepare(d, stat) mplot.prepare(d, m, stat) fplot.prepare(dplot, mplot) if flag: nwarn = 1 else: nwarn = 0 check_for_warning(caplog, nwarn, stat.name)
def test_fit_residstyle_plot_no_errors_no_errorbar_warnings( caplog, plotClass, statClass): """Should not see warnings when no error bars are drawn (See #621). This is a copy of test_fit_residstyle_plot_see_errorbar_warnings except that the 'yerrorbars' preference setting for all plots is 'False'. Parameters ---------- plotClass : {sherpa.plot.ResidPlot, sherpa.plot.RatioPlot} The plot to test. statClass : sherpa.stats.Stat instance Notes ----- Is this an accurate example of how 'plot_fit_resid' is created? """ d = example_data() m = example_model() dplot = DataPlot() mplot = ModelPlot() fplot = FitPlot() rplot = plotClass() jplot = JointPlot() prefname = 'yerrorbars' for plot in [dplot, rplot]: prefs = plot.plot_prefs prefs[prefname] = False stat = statClass() # Ensure that the logging is set to WARNING since there # appears to be some test that changes it to ERROR. # with caplog.at_level(logging.INFO, logger='sherpa'): dplot.prepare(d, stat) mplot.prepare(d, m, stat) fplot.prepare(dplot, mplot) rplot.prepare(d, m, stat) jplot.plottop(fplot) jplot.plotbot(rplot) check_for_warning(caplog, 0, stat.name)
def __init__(self): ModelPlot.__init__(self) self.title = 'Background Model Contribution'
sinfo2 = f.calc_stat_info() d.notice() dump("sinfo1.numpoints") dump("sinfo2.numpoints") res = f.fit() if res.succeeded: print("Fit succeeded") if not res.succeeded: print("**** ERRRR, the fit failed folks") report("res.format()") report("res") from sherpa.plot import DataPlot, ModelPlot dplot = DataPlot() dplot.prepare(f.data) mplot = ModelPlot() mplot.prepare(f.data, f.model) dplot.plot() mplot.overplot() savefig("data_model_c0_c2.png") dump("f.method.name") original_method = f.method from sherpa.optmethods import NelderMead f.method = NelderMead() resn = f.fit() print("Change in statistic: {}".format(resn.dstatval)) fit2 = Fit(d, mdl, method=NelderMead())
hdul.close() #normalize spliced intensities & invert y = -1.0 * (y_raw - min(y_raw)) / norm_factor + 1.0 #Set data and model for fits icorr = 0 G1 = Gauss1D('G1') d = Data1D('He 1083', x, y, staterror=sd) #guess parameters, this is important or sherpa won't know where to start looking G1.fwhm = .05 G1.pos = 1083.03 + ref_value * 5 mdl = G1 mplot = ModelPlot() mplot.prepare(d, mdl) dplot = DataPlot() dplot.prepare(d) mplot.overplot() #set error methods, ChiSq() or LeastSq() #Chi square is a way to compare which profile best describes data, ie: is it more gaussian or lorentzian #Least Square says how good the data fits the particular model instance #opt - optimizers improve the fit. Monte Carlo is what I used, it is slow but it is most robust. Many options on sherpas site ustat = LeastSq() opt = MonCar() #LevMar() #NelderMead() # #apply actual Fit f = Fit(d, mdl, stat=ustat, method=opt) res = f.fit()
plt.plot(xmid, y2 / (xhi - xlo) / pha.exposure) plt.xlabel('Energy (keV)') plt.ylabel('Counts/sec/keV') savefig('pha_eval_model_to_fit.png') from sherpa.astro.plot import ModelHistogram mplot = ModelHistogram() mplot.prepare(pha, full) mplot.plot() savefig('pha_fullmodel_model.png') from sherpa.fit import Fit fit = Fit(pha, full) res = fit.fit() report('res.format()') from sherpa.plot import ModelPlot dplot.prepare(pha) dplot.plot(xlog=True) mplot2 = ModelPlot() mplot2.prepare(pha, full) mplot2.overplot() savefig('pha_fullmodel_fit.png')
def prepare_spectra(group, nH, add_gal, redshift): pha = read_pha("core_spectrum.pi") pha.set_analysis("energy") pha.notice(0.5, 7.0) tabs = ~pha.mask pha.group_counts(group, tabStops=tabs) x = pha.get_x() x = pha.apply_filter(x, pha._middle) y = pha.get_y(filter=True) pha.set_analysis("energy") model = xsphabs.abs1 * powlaw1d.srcp1 print("Fitting the spectrum") zFlag = False if (nH is not None) and (nH > 0.0): if add_gal == 1: model = xsphabs.gal * xszphabs.abs1 * powlaw1d.srcp gal.nH = nH freeze(gal.nH) zFlag = True else: model = xsphabs.abs1 * powlaw1d.srcp1 abs1.nH = nH freeze(abs1.nH) else: model = xszphabs.abs1 * powlaw1d.srcp1 zFlag = True if zFlag is True and add_gal == 1: # print('REDSHIFT',redshift) abs1.redshift = redshift freeze(abs1.redshift) full_model = RSPModelPHA(pha.get_arf(), pha.get_rmf(), pha, pha.exposure * model) print(full_model) fit = Fit(pha, full_model, method=MonCar(), stat=WStat()) res = fit.fit() print(res.format()) print(fit.est_errors()) # calculate the p-value for wstat mplot2 = ModelPlot() mplot2.prepare(pha, full_model) miu = mplot2.y * pha.exposure * 0.0146 obs = y * pha.exposure * 0.0146 c, ce, cv = gof_cstat(miu, obs) print(f"C0={c},C_e={ce},C_v={cv}") zval = (fit.calc_stat() - ce) / np.sqrt(cv) if zval > 0: pval = special.erfc(zval / np.sqrt(2)) else: pval = special.erf(abs(zval) / np.sqrt(2)) print(f"p-value for wstat = {pval}") set_data(pha) set_model(model) save_chart_spectrum("core_flux_chart.dat", elow=0.5, ehigh=7.0) # save_chart_spectrum("core_flux_chart.rdb",format='text/tsv', elow=0.5, ehigh=7.0) save_spectrum_rdb("core_flux_chart.dat")
def fit(star_name, data, model, silent=False, breakdown=False): """A function that will fit a given multi-part model to a given spectrum. :param star_name: Name of the target star :type star_name: str :param data: Spectrum data in the form (wave, flux) :type data: tuple :param model: An unfit spectrum model :type model: object :param silent: If true, no plots will generate, defaults to False :type silent: bool :return: model that is fit to the data :rtype: object """ wave, flux = data # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% d = Data1D(star_name, wave, flux) # ========================================== # Initial guesses # Dataset 1 dplot = DataPlot() dplot.prepare(d) if silent is False: dplot.plot() mplot = ModelPlot() mplot.prepare(d, model) if silent is False: dplot.plot() mplot.overplot() plt.show() # ========================================= # Fitting happens here - don't break please start = time.time() stat = LeastSq() opt = LevMar() opt.verbose = 0 opt.ftol = 1e-15 opt.xtol = 1e-15 opt.gtol = 1e-15 opt.epsfcn = 1e-15 if silent is False: print(opt) vfit = Fit(d, model, stat=stat, method=opt) if silent is False: print(vfit) vres = vfit.fit() if silent is False: print() print() print(vres.format()) # ========================================= # Plotting after fit # Dataset 1 if silent is False: fplot = FitPlot() mplot.prepare(d, model) fplot.prepare(dplot, mplot) fplot.plot() # residual plt.title(star_name) plt.plot(wave, flux - model(wave)) # plt.xaxis(fontsize = ) plt.xlabel("Wavelength (AA)", fontsize=12) plt.ylabel("Flux", fontsize=12) plt.tick_params(axis="both", labelsize=12) if silent is False: duration = time.time() - start print() print("Time taken: " + str(duration)) print() plt.show() if breakdown is True: params = [] cont = model[0] if silent is False: plt.scatter(wave, flux, marker=".", c="black") plt.plot(wave, model(wave), c="C1") for line in model: if line.name[0] != "(": if line.name == "Cont_flux": if silent is False: print(line) plt.plot(wave, line(wave), linestyle="--") else: params.append(line) if silent is False: print() print(line) plt.plot(wave, line(wave) * cont(wave), linestyle="--") plt.show() return model, params return model
def multifit(star_name, data_list, model_list, silent=False): """A function that will fit 2 models to 2 spectra simultaneously. This was created to fit the NaI doublets at ~3300 and ~5890 Angstroms. :param star_name: Name of the target star :type star_name: str :param data_list: List of spectrum data in the form [(wave, flux), (wave, flux),...] :type data_list: tuple :param model_list: A list of unfit spectrum models :type model_list: list :param silent: If true, no plots will generate, defaults to False :type silent: bool :return: models that are fit to the data :rtype: list """ wave1, flux1 = data_list[0] wave2, flux2 = data_list[1] model1 = model_list[0] model2 = model_list[1] name_1 = star_name + " 1" name_2 = star_name + " 2" d1 = Data1D(name_1, wave1, flux1) d2 = Data1D(name_2, wave2, flux2) dall = DataSimulFit("combined", (d1, d2)) mall = SimulFitModel("combined", (model1, model2)) # # ========================================== # # Initial guesses # Dataset 1 dplot1 = DataPlot() dplot1.prepare(d1) if silent is False: dplot1.plot() mplot1 = ModelPlot() mplot1.prepare(d1, model1) if silent is False: dplot1.plot() mplot1.overplot() plt.show() # Dataset 2 dplot2 = DataPlot() dplot2.prepare(d2) if silent is False: dplot2.plot() mplot2 = ModelPlot() mplot2.prepare(d2, model2) if silent is False: dplot2.plot() mplot2.overplot() plt.show() # # ========================================= # # Fitting happens here - don't break please stat = LeastSq() opt = LevMar() opt.verbose = 0 opt.ftol = 1e-15 opt.xtol = 1e-15 opt.gtol = 1e-15 opt.epsfcn = 1e-15 print(opt) vfit = Fit(dall, mall, stat=stat, method=opt) print(vfit) vres = vfit.fit() print() print() print("Did the fit succeed? [bool]") print(vres.succeeded) print() print() print(vres.format()) # # ========================================= # # Plotting after fit if silent is False: # Dataset 1 fplot1 = FitPlot() mplot1.prepare(d1, model1) fplot1.prepare(dplot1, mplot1) fplot1.plot() # residual title = "Data 1" plt.title(title) plt.plot(wave1, flux1 - model1(wave1)) plt.show() # Dataset 2 fplot2 = FitPlot() mplot2.prepare(d2, model2) fplot2.prepare(dplot2, mplot2) fplot2.plot() # residual title = "Data 2" plt.title(title) plt.plot(wave2, flux2 - model2(wave2)) plt.show() # both datasets - no residuals splot = SplitPlot() splot.addplot(fplot1) splot.addplot(fplot2) plt.tight_layout() plt.show() return model_list
def prepare_spectra(nH: float, group: int = 1, add_gal: bool = False, redshift: Optional[float] = None, **kwargs) -> float: """ Fit the spectra using an absorbed powerlaw model using the Wstat statistic. The function also returns a p-value for the gof. :param nH: The galactic absorption column density in units of 10^22 /cm3 :param group: The number of counts per energy bin :param add_gal: Setting this to True would add an intrinsic abrosption column density along side the galactic one :param redshift: The redshift to use in the fit. Only takes effect if add_gal is set to True ... :return: Returns the p-value of the gof. The null hypothesis states that the model and the observation differ while alternate says that the model explains the data """ pha = read_pha("core_spectrum.pi") pha.set_analysis("energy") pha.notice(0.5, 7.0) tabs = ~pha.mask pha.group_counts(group, tabStops=tabs) x = pha.get_x() x = pha.apply_filter(x, pha._middle) y = pha.get_y(filter=True) pha.set_analysis("energy") model = xsphabs.abs1 * powlaw1d.srcp1 print("Fitting the spectrum") zFlag = False if (nH is not None) and (nH > 0.0): if add_gal == 1: model = xsphabs.gal * xszphabs.abs1 * powlaw1d.srcp gal.nH = nH freeze(gal.nH) zFlag = True else: model = xsphabs.abs1 * powlaw1d.srcp1 abs1.nH = nH freeze(abs1.nH) else: model = xszphabs.abs1 * powlaw1d.srcp1 zFlag = True if zFlag is True and add_gal == 1: # print('REDSHIFT',redshift) abs1.redshift = redshift freeze(abs1.redshift) full_model = RSPModelPHA(pha.get_arf(), pha.get_rmf(), pha, pha.exposure * model) print(full_model) fit = Fit(pha, full_model, method=MonCar(), stat=WStat()) res = fit.fit() print(res.format()) print(fit.est_errors()) # calculate the p-value for wstat mplot2 = ModelPlot() mplot2.prepare(pha, full_model) miu = mplot2.y * pha.exposure * 0.0146 obs = y * pha.exposure * 0.0146 c, ce, cv = SpecUtils.estimate_gof_cstat(miu, obs) #print(f"C0={c},C_e={ce},C_v={cv}") zval = (fit.calc_stat() - ce) / np.sqrt(cv) if zval > 0: pval = special.erfc(zval / np.sqrt(2)) else: pval = special.erf(abs(zval) / np.sqrt(2)) print(f"p-value for wstat = {pval}") set_data(pha) set_model(model) save_chart_spectrum("core_flux_chart.dat", elow=0.5, ehigh=7.0) # save_chart_spectrum("core_flux_chart.rdb",format='text/tsv', elow=0.5, ehigh=7.0) SAOTraceUtils.save_spectrum_rdb("core_flux_chart.dat") return pval
from sherpa.plot import Histogram hplot = Histogram() hplot.overplot(d.xlo, d.xhi, d.y) savefig('dataplot_histogram_overplot.png') from sherpa.models.basic import Const1D, Gauss1D mdl = Const1D('base') - Gauss1D('line') mdl.pars[0].val = 10 mdl.pars[1].val = 25 mdl.pars[2].val = 22 mdl.pars[3].val = 10 report("mdl") from sherpa.plot import ModelPlot mplot = ModelPlot() mplot.prepare(d, mdl) mplot.plot() dplot.overplot() savefig('modelplot_histogram_overplot.png') from sherpa.plot import FitPlot fplot = FitPlot() fplot.prepare(dplot, mplot) fplot.plot() savefig('fitplot_histogram.png') # settings
dplot.prepare(d) dplot.plot() savefig('data.png') # Note: can not print(dplot) as there is a problem with the fact # the input to the data object is a list, not ndarray # Sherpa 4.10.0 from sherpa.models.basic import Polynom1D mdl = Polynom1D() report("print(mdl)") mdl.c2.thaw() from sherpa.plot import ModelPlot mplot = ModelPlot() mplot.prepare(d, mdl) dplot.plot() mplot.overplot() savefig("data_model_initial.png") from sherpa.stats import LeastSq from sherpa.optmethods import NelderMead from sherpa.fit import Fit f = Fit(d, mdl, stat=LeastSq(), method=NelderMead()) report("print(f)") res = f.fit() dump("res.succeeded") report("res.format()")
dump("d.get_filter(format='%d')") dplot.prepare(d) from sherpa.models.basic import Const1D, Exp plateau = Const1D('plateau') rise = Exp('rise') mdl = plateau / (1 + rise) report("mdl") rise.ampl.freeze() report("mdl") from sherpa.plot import ModelPlot mplot = ModelPlot() mplot.prepare(d, mdl) plt.subplot(2, 1, 1) mplot.plot(clearwindow=False) plt.subplot(2, 1, 2) dplot.plot(clearwindow=False) plt.title('') savefig("model_data_before_fit.png") from sherpa.stats import Chi2 from sherpa.fit import Fit f = Fit(d, mdl, stat=Chi2()) report("f") print("Starting statistic: {}".format(f.calc_stat()))