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()) fit2.fit() mdl.c1.thaw()
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 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 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
# 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()") report("res") report("mdl")