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 test_user_stat_unit(): given_stat_error = [1.1, 2.2, 3.3] given_sys_error = [10.1, 10.2, 10.3] def calc_stat(data, _model, staterror, syserror=None, weight=None): # Make sure values are being injected correctly np.testing.assert_array_equal(given_stat_error, staterror) np.testing.assert_array_equal(given_sys_error, syserror) return 3.235, np.ones_like(data) xdata = [1, 2, 3] ydata = xdata ui.load_arrays(1, xdata, ydata, None, given_sys_error, Data1D) ui.set_model(1, 'polynom1d.p') ui.load_user_stat('customstat', calc_stat, lambda x: given_stat_error) ui.set_stat(eval('customstat')) try: ui.fit(1) except StatErr: pytest.fail("Call should not be throwing any exception (bug #341)") # Test the result is what we made the user stat return assert 3.235 == ui.get_fit_results().statval
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()
def test_user_model_stat_docs(): """ This test reproduces the documentation shown at: http://cxc.harvard.edu/sherpa4.4/statistics/#userstat and: http://cxc.harvard.edu/sherpa/threads/user_model/ I tried to be as faithful as possible to the original, although the examples in thedocs are not completely self-contained, so some changes were necessary. I changed the numpy reference, as it is imported as `np` here, and added a clean up of the environment before doing anything. For the model, the difference is that I am not importing the function from an external module, plus the dataset is different. Also, the stats docs do not perform a fit. """ def my_stat_func(data, model, staterror, syserror=None, weight=None): # A simple function to replicate χ2 fvec = ((data - model) / staterror)**2 stat = fvec.sum() return (stat, fvec) def my_staterr_func(data): # A simple staterror function return np.sqrt(data) def myline(pars, x): return pars[0]*x + pars[1] x = [1, 2, 3] y = [4, 5, 6.01] ui.clean() ui.load_arrays(1, x, y) ui.load_user_stat("mystat", my_stat_func, my_staterr_func) ui.set_stat(eval('mystat')) ui.load_user_model(myline, "myl") ui.add_user_pars("myl", ["m", "b"]) ui.set_model(eval('myl')) ui.fit() assert ui.get_par("myl.m").val == approx(1, abs=0.01) assert ui.get_par("myl.b").val == approx(3, abs=0.01)
def wfit(dataids=None): listids = () if dataids is None: listids = sau.list_data_ids() else: listids = dataids wstat = w_statistic(listids) sau.load_user_stat("mystat", wstat, wstat.CATstat_err_LV) sau.set_stat(mystat) sau.set_method("neldermead") # set_method("moncar") sau.set_conf_opt("max_rstat", 1000) # We don't use a specific maximum reduced statistic value # since we don't expect the cstat to be anywhere near the # large number limit sau.fit(*listids) sau.conf()
def wfit(dataids=None): listids = () if dataids is None: listids = sau.list_data_ids() else: listids = dataids wstat = w_statistic(listids) sau.load_user_stat("mystat", wstat, wstat.CATstat_err_LV) sau.set_stat(mystat) sau.set_method("neldermead") # set_method("moncar") sau.set_conf_opt( "max_rstat", 1000) # We don't use a specific maximum reduced statistic value # since we don't expect the cstat to be anywhere near the # large number limit sau.fit(*listids) sau.conf()
def load_chi2asym_stat(): """"Load and set the chi2asym statistic""" import sherpa.astro.ui as sau sau.load_user_stat("chi2asym", chi2asym_stat_func, chi2asym_err_func) sau.set_stat(chi2asym)
def test_341(): """ The original reporter of bug #341 had a special implementation that should be captured by this test. The implementation has a proxy model that takes care of updating the actual model when it is evaluated. During a recent refactoring of the Stat and Fit code (PR #287) a regression was introduced by short-circuiting the evaluation of the model. """ class ExampleModel(object): """ Class to define model """ def __init__(self, x, y): self.x = np.array(x) self.y = np.array(y) self.parvals = [1, 2] self.parnames = ("m", "b") def calc_stat(self): return float(np.sum(np.abs(self.y - self.model()))) def model(self): return self.parvals[0] * self.x + self.parvals[1] class CalcModel(object): """ Class to update model parameters """ def __init__(self, model): self.model = model def __call__(self, pars, x): self.model.parvals = pars return np.ones_like(x) class CalcStat(object): """ Class to determine fit statistic """ def __init__(self, model): self.model = model def __call__(self, _data, _model, *args, **kwargs): fit_stat = self.model.calc_stat() return fit_stat, np.ones(1) xdata = [1, 2, 3] ydata = [4, 5, 6] newmodel = ExampleModel(xdata, ydata) dummy_data = np.zeros(1) dummy_times = np.arange(1) ui.load_arrays(1, dummy_times, dummy_data) method = 'simplex' ui.set_method(method) ui.load_user_model(CalcModel(newmodel), 'simplemodel') ui.add_user_pars('simplemodel', newmodel.parnames) ui.set_model(1, 'simplemodel') calc_stat = CalcStat(newmodel) ui.load_user_stat('customstat', calc_stat, lambda x: np.ones_like(x)) ui.set_stat(eval('customstat')) ui.fit(1) assert ui.get_par("simplemodel.m").val == approx(1, abs=0.00001) assert ui.get_par("simplemodel.b").val == approx(3, abs=0.00001)
d = ui.get_bkg_model_plot(id=id) if bkg else ui.get_model_plot(id=id) e = d.xlo mask = logical_and(e >= elow, e <= ehigh) e = e[mask] model = d.y[mask].cumsum() last_stat = ui.get_stat() ui.set_stat(ksstat) ks = ui.calc_stat() ui.set_stat(cvmstat) cvm = ui.calc_stat() ui.set_stat(adstat) ad = ui.calc_stat() ui.set_stat(last_stat) ad = ui.calc_stat() ui.set_stat('chi2gehrels') chi2 = ui.calc_stat() ui.set_stat('cstat') cstat = ui.calc_stat() ui.set_stat(last_stat) stats = dict(ks=ks, cvm=cvm, ad=ad, cstat=cstat, chi2=chi2) numpy.savetxt(outfile, numpy.transpose([e, data, model])) json.dump(stats, open(outfile + '.json', 'w'), indent=4) if 'MAKESPHINXDOC' not in os.environ: ui.load_user_stat("ksstat", KSstat, fake_staterr_func) ui.load_user_stat("cvmstat", CvMstat, fake_staterr_func) ui.load_user_stat("adstat", ADstat, fake_staterr_func)
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.frozen = par.frozen par.min = -5 par.max = 5 ui.fit(1)
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.frozen = par.frozen par.min = -5 par.max = 5 ui.fit(1)