def fit_coeffs(method='simplex'): method = method dummy_data = np.zeros(100) dummy_times = np.arange(100) ui.load_arrays(1, dummy_times, dummy_data) ui.set_method(method) ui.get_method().config.update(SHERPA_CONFIGS.get(method, {})) calc_model = CalcModel() ui.load_user_model(calc_model, 'axo_mod') # sets global axo_mod parnames = [] for row in range(N_ROWS): for col in range(N_COLS): parnames.append('adj_{}_{}'.format(row, col)) ui.add_user_pars('axo_mod', parnames) ui.set_model(1, 'axo_mod') calc_stat = CalcStat(axo_mod, M_2d, displ_x) ui.load_user_stat('axo_stat', calc_stat, lambda x: np.ones_like(x)) ui.set_stat(axo_stat) calc_model.set_calc_stat(calc_stat) # Set frozen, min, and max attributes for each axo_mod parameter for par in axo_mod.pars: par.val = 0.0 par.min = -5 par.max = 5 ui.fit(1) coeffs = np.array([(par.val) for pars in axo_mod.pars]) return coeffs
def fit_adjuster_set(coeffs, adj_idxs, method='simplex'): """ Find best fit parameters for an arbitrary subset of adjustors specified by the array ``adj_idxs``. The input ``coeffs`` are the best-fit adjustor coefficients for the last iteration. """ import sherpa.astro.ui as ui dummy_data = np.zeros(100) dummy_times = np.arange(100) ui.load_arrays(1, dummy_times, dummy_data) ui.set_method(method) ui.get_method().config.update(SHERPA_CONFIGS.get(method, {})) calc_model = CalcModel() ui.load_user_model(calc_model, 'axo_mod') # sets global axo_mod parnames = [] for adj_idx in adj_idxs: parnames.append('adj_{}'.format(adj_idx)) ui.add_user_pars('axo_mod', parnames) ui.set_model(1, 'axo_mod') coeffs = coeffs.copy() # Don't modify input coeffs coeffs[coeffs < 0] = 0 # Don't allow negative coeffs # Set frozen, min, and max attributes for each axo_mod parameter for adj_idx, par in zip(adj_idxs, axo_mod.pars): par.min = -1000 par.max = 1000 par.val = coeffs[adj_idx] print 'Setting {} to {}'.format(adj_idx, par.val) # Compute base adjusted displacements assuming all the fitted actuators # have zero drive level. coeffs[adj_idxs] = 0 base_adj_displ = M_2d.dot(coeffs) m_2d = M_2d[:, adj_idxs].copy() print m_2d.shape calc_stat = CalcStat(base_adj_displ, m_2d, DISPL_X) ui.load_user_stat('axo_stat', calc_stat, lambda x: np.ones_like(x)) ui.set_stat(axo_stat) calc_model.set_calc_stat(calc_stat) ui.fit(1) # Update coeffs with the values determined in fitting for adj_idx, par in zip(adj_idxs, axo_mod.pars): coeffs[adj_idx] = abs(par.val) return coeffs, ui.get_fit_results()
sh.load_table_model("bkg", "analysis_3d/background_2D.fits") sh.load_psf("psf", "analysis_3d/psf_2D.fits") # To speed up this tutorial, we change the fit optimazation method to Levenberg-Marquardt and fix a required tolerance. This can make the fitting less robust, and in practise, you can skip this step unless you understand what is going on. # In[ ]: sh.set_method("levmar") sh.set_method_opt("xtol", 1e-5) sh.set_method_opt("ftol", 1e-5) sh.set_method_opt("gtol", 1e-5) sh.set_method_opt("epsfcn", 1e-5) # In[ ]: print(sh.get_method()) # In principle one might first want to fit the background amplitude. However the background estimation method already yields the correct normalization, so we freeze the background amplitude to unity instead of adjusting it. The (smoothed) residuals from this background model are then computed and shown. # In[ ]: sh.set_full_model(bkg) bkg.ampl = 1 sh.freeze(bkg) # In[ ]: resid = Map.read("analysis_3d/counts_2D.fits") resid.data = sh.get_data_image().y - sh.get_model_image().y resid_smooth = resid.smooth(width=4) resid_smooth.plot(add_cbar=True)
if self.min_fit_stat is None or fit_stat < self.min_fit_stat: self.min_fit_stat = fit_stat self.min_parvals = self.parvals return fit_stat, np.ones_like(self.displ) # def fit(method='levmar'): method = "simplex" dummy_data = np.zeros(100) dummy_times = np.arange(100) ui.load_arrays(1, dummy_times, dummy_data) ui.set_method(method) ui.get_method().config.update(SHERPA_CONFIGS.get(method, {})) calc_model = CalcModel() ui.load_user_model(calc_model, "axo_mod") # sets global axo_mod parnames = [] for row in range(N_ROWS): for col in range(N_COLS): parnames.append("adj_{}_{}".format(row, col)) ui.add_user_pars("axo_mod", parnames) ui.set_model(1, "axo_mod") calc_stat = CalcStat(axo_mod, M_2d, displ_x) ui.load_user_stat("axo_stat", calc_stat, lambda x: np.ones_like(x)) ui.set_stat(axo_stat) calc_model.set_calc_stat(calc_stat)
if self.min_fit_stat is None or fit_stat < self.min_fit_stat: self.min_fit_stat = fit_stat self.min_parvals = self.parvals return fit_stat, np.ones_like(self.displ) # def fit(method='levmar'): method = 'simplex' dummy_data = np.zeros(100) dummy_times = np.arange(100) ui.load_arrays(1, dummy_times, dummy_data) ui.set_method(method) ui.get_method().config.update(SHERPA_CONFIGS.get(method, {})) calc_model = CalcModel() ui.load_user_model(calc_model, 'axo_mod') # sets global axo_mod parnames = [] for row in range(N_ROWS): for col in range(N_COLS): parnames.append('adj_{}_{}'.format(row, col)) ui.add_user_pars('axo_mod', parnames) ui.set_model(1, 'axo_mod') calc_stat = CalcStat(axo_mod, M_2d, displ_x) ui.load_user_stat('axo_stat', calc_stat, lambda x: np.ones_like(x)) ui.set_stat(axo_stat) calc_model.set_calc_stat(calc_stat)