def __init__( self, model, data, lnsigma=None, use_weights=True, transform=None, logp_extra=None, name=None, ): self.model = model # should be a Data1D instance if isinstance(data, Data1D): self.data = data else: self.data = Data1D(data=data) self.lnsigma = lnsigma if lnsigma is not None: self.lnsigma = possibly_create_parameter(lnsigma, "lnsigma") self._use_weights = use_weights self.transform = transform self.logp_extra = logp_extra self.name = name if name is None: self.name = id(self)
def setup(self): # Reproducible results! np.random.seed(123) m_true = -0.9594 b_true = 4.294 f_true = 0.534 m_ls = -1.1040757010910947 b_ls = 5.4405552502319505 # Generate some synthetic data from the model. N = 50 x = np.sort(10 * np.random.rand(N)) y_err = 0.1 + 0.5 * np.random.rand(N) y = m_true * x + b_true y += np.abs(f_true * y) * np.random.randn(N) y += y_err * np.random.randn(N) data = Data1D(data=(x, y, y_err)) p = Parameter(b_ls, 'b', vary=True, bounds=(-100, 100)) p |= Parameter(m_ls, 'm', vary=True, bounds=(-100, 100)) model = Model(p, fitfunc=line) self.objective = Objective(model, data) self.mcfitter = CurveFitter(self.objective) self.mcfitter_t = CurveFitter(self.objective, ntemps=20) self.mcfitter.initialise('prior') self.mcfitter_t.initialise('prior')
def test_2D_data(self): # despite the class being called Data1D it should be possible to # store ND data in it # try with multidimensional x data x = np.linspace(0.01, 0.5, 100).reshape(50, 2) y = np.arange(50, dtype=float) data = Data1D((x, y)) assert len(data) == 50 assert_equal(data.x, x) assert_equal(data.y, y) mask = np.ones_like(y, bool) mask[1] = False data.mask = mask assert len(data) == 49 assert_equal(data.y, np.r_[y[0], y[2:]]) assert_equal(data.x, np.concatenate((x[0][np.newaxis, :], x[2:]))) # try with storing multiple channels for y as well # this might happen with something like ellipsometry data where you'd # have (delta, xsi) as the y data, and (lambda, aoi) as the x data # NOTE THAT MASKING WON'T WORK, FOR ND YDATA. This is because the class # is using fancy indexing with booleans to remove entries that are # unwanted. Could mark as NaN instead? x = np.linspace(0.01, 0.5, 50).reshape(50) y = np.arange(100, dtype=float).reshape(50, 2) data = Data1D((x, y)) assert len(data) == 100 assert_equal(data.x, x) assert_equal(data.y, y) x = np.linspace(0.01, 0.5, 100).reshape(50, 2) data = Data1D((x, y)) assert len(data) == 100 assert_equal(data.x, x) assert_equal(data.y, y)
def test_data_setter(self): # check that setting a Data1D's data from a tuple works correctly # this is the approach used in Data1D.synthesise. new_dataset = Data1D() new_dataset.data = self.data.data assert_equal(new_dataset.y_err, self.data.y_err) assert_equal(new_dataset.x_err, self.data.x_err) assert_equal(new_dataset.y, self.data.y) assert_equal(new_dataset.x, self.data.x) assert_equal(new_dataset.weighted, self.data.weighted)
def test_repr(self): a = Data1D(os.path.join(self.pth, "c_PLP0033831.txt")) b = eval(repr(a)) assert_equal(len(a), 166) assert_equal(len(b), 166) # load dataset from XML, via string a = ReflectDataset(os.path.join(self.pth, "c_PLP0000708.xml")) b = eval(repr(a)) assert_equal(len(b), len(a)) assert_equal(len(b), len(a))
def setup_method(self, tmpdir): self.path = os.path.dirname(os.path.abspath(__file__)) self.tmpdir = tmpdir.strpath theoretical = np.loadtxt(os.path.join(self.path, "gauss_data.txt")) xvals, yvals, evals = np.hsplit(theoretical, 3) xvals = xvals.flatten() yvals = yvals.flatten() evals = evals.flatten() # these best weighted values and uncertainties obtained with Igor self.best_weighted = [-0.00246095, 19.5299, -8.28446e-2, 1.24692] self.best_weighted_errors = [ 0.0220313708486, 1.12879436221, 0.0447659158681, 0.0412022938883, ] self.best_weighted_chisqr = 77.6040960351 self.best_unweighted = [ -0.10584111872702096, 19.240347049328989, 0.0092623066070940396, 1.501362314145845, ] self.best_unweighted_errors = [ 0.34246565477, 0.689820935208, 0.0411243173041, 0.0693429375282, ] self.best_unweighted_chisqr = 497.102084956 self.p0 = np.array([0.1, 20.0, 0.1, 0.1]) self.names = ["bkg", "A", "x0", "width"] self.bounds = [(-1, 1), (0, 30), (-5.0, 5.0), (0.001, 2)] self.params = Parameters(name="gauss_params") for p, name, bound in zip(self.p0, self.names, self.bounds): param = Parameter(p, name=name) param.range(*bound) param.vary = True self.params.append(param) self.model = Model(self.params, fitfunc=gauss) self.data = Data1D((xvals, yvals, evals)) self.objective = Objective(self.model, self.data) return 0
def test_add_non_overlapping(self): # check that splicing of non-overlapping datasets raises ValueError x1 = np.linspace(0, 10, 11) y1 = 2 * x1 data = Data1D((x1, y1)) x2 = np.linspace(11, 20, 10) y2 = 2 * x2 + 2 from pytest import raises with raises(ValueError): data.add_data((x2, y2), requires_splice=True)
def test_run(): print("\n\n\n") from refnx.dataset import Data1D from refnx.dataset import ReflectDataset import refnx import data_in data = data_in.data_in('d2o/29553_54.dat') # dataset = data # ... data = Data1D(data) from make_egg import bsla_thesis # air = SLD(0) # air = air(0,0) bt = bsla_thesis() bt.interface_protein_solvent.setp(vary=True, bounds=(11, 40)) bt.protein_length.setp(vary=True, bounds=(25, 55)) bt.number_of_water_molecules.setp(vary=True, bounds=(1, 10000)) bt.interface_width_air_solvent.setp(vary=True, bounds=(0.001, 30)) #bt.interface_width_protein_solvent.setp(vary=True, bounds=(0, 5)) bt.sld_of_protein.setp(vary=True, bounds=(1.92, 6.21)) # *(10**(-6)) bt.d2o_to_h2o_ratio.setp(vary=True, bounds=(0, 1)) # if isinstance(bt, Component): # print("it is comp") # if isinstance(bt, Structure): # print("it is") #print(bt.parameters) # d2o = 1.9185/0.3 # h2o = -0.1635/0.3 # solvent = SLD((bt.d2o_to_h2o_ratio.value*d2o + (1-bt.d2o_to_h2o_ratio.value)*h2o)) # solvent = solvent(0,0) # from refnx.reflect import Structure # structure = air|bt|solvent # structure.name = "bsla" from refnx.reflect import ReflectModel model = ReflectModel(bt) #structure) from refnx.analysis import Transform, CurveFitter, Objective objective = Objective(model, data) fitter = CurveFitter(objective) fitter.fit('differential_evolution') import matplotlib.pyplot as plt #%matplotlib notebook # plt.plot(*bt.sld_profile()) objective.plot() plt.yscale('log') plt.xscale('log') plt.xlabel('Q') plt.ylabel('Reflectivity') plt.legend() print(bt) plt.show()
def setup_method(self): # Choose the "true" parameters. # Reproducible results! np.random.seed(123) self.m_true = -0.9594 self.b_true = 4.294 self.f_true = 0.534 self.m_ls = -1.1040757010910947 self.b_ls = 5.4405552502319505 # Generate some synthetic data from the model. N = 50 x = np.sort(10 * np.random.rand(N)) y_err = 0.1 + 0.5 * np.random.rand(N) y = self.m_true * x + self.b_true y += np.abs(self.f_true * y) * np.random.randn(N) y += y_err * np.random.randn(N) self.data = Data1D(data=(x, y, y_err)) self.p = Parameter(self.b_ls, 'b') | Parameter(self.m_ls, 'm') self.model = Model(self.p, fitfunc=line) self.objective = Objective(self.model, self.data) # want b and m self.p[0].vary = True self.p[1].vary = True mod = np.array([4.78166609, 4.42364699, 4.16404064, 3.50343504, 3.4257084, 2.93594347, 2.92035638, 2.67533842, 2.28136038, 2.19772983, 1.99295496, 1.93748334, 1.87484436, 1.65161016, 1.44613461, 1.11128101, 1.04584535, 0.86055984, 0.76913963, 0.73906649, 0.73331407, 0.68350418, 0.65216599, 0.59838566, 0.13070299, 0.10749131, -0.01010195, -0.10010155, -0.29495372, -0.42817431, -0.43122391, -0.64637715, -1.30560686, -1.32626428, -1.44835768, -1.52589881, -1.56371158, -2.12048349, -2.24899179, -2.50292682, -2.53576659, -2.55797996, -2.60870542, -2.7074727, -3.93781479, -4.12415366, -4.42313742, -4.98368609, -5.38782395, -5.44077086]) self.mod = mod
def test_multidimensionality(self): # Check that ND data can be used with an objective/model/data # (or at least it doesn't stand in the way) rng = np.random.default_rng() x = rng.uniform(size=100).reshape(50, 2) desired = line_ND(x, self.p) assert desired.shape == (50, 2) data = Data1D((x, desired)) model = Model(self.p, fitfunc=line_ND) y = model(x) assert_allclose(y, desired) objective = Objective(model, data) assert_allclose(objective.chisqr(), 0) assert_allclose(objective.generative(), desired) assert_allclose(objective.residuals(), 0) assert objective.residuals().shape == (50, 2) objective.logl() objective.logpost() covar = objective.covar() assert covar.shape == (2, 2)
print("a") if __name__ == "__main__": import numpy as np max_thickness = 350 structs = [] fitrs = [] ln_posts = [] fig_i = 0 import data_in as di data = di.data_in("29553_54.dat") q, R, sim_dR = data[0], data[1], data[2] #print(q, R, sim_dR) from refnx.dataset import Data1D data = Data1D(data=(q, R, sim_dR)) import make_model as mm for i in range(1, 2): thick = round(max_thickness / (i + 1.)) names = [] bs = [] thicks = [] roughs = [] for j in range(i + 1): names.append('layers' + str(j)) bs.append(5) thicks.append(thick) roughs.append(0) print(names, bs, thicks, roughs) structure, fitter, objective, fig_i = mm.make_model( names, bs, thicks, roughs, fig_i, data)
def test_covar(self): # checks objective.covar against optimize.least_squares covariance. path = os.path.dirname(os.path.abspath(__file__)) theoretical = np.loadtxt(os.path.join(path, 'gauss_data.txt')) xvals, yvals, evals = np.hsplit(theoretical, 3) xvals = xvals.flatten() yvals = yvals.flatten() evals = evals.flatten() p0 = np.array([0.1, 20., 0.1, 0.1]) names = ['bkg', 'A', 'x0', 'width'] bounds = [(-1, 1), (0, 30), (-5., 5.), (0.001, 2)] params = Parameters(name="gauss_params") for p, name, bound in zip(p0, names, bounds): param = Parameter(p, name=name) param.range(*bound) param.vary = True params.append(param) model = Model(params, fitfunc=gauss) data = Data1D((xvals, yvals, evals)) objective = Objective(model, data) # first calculate least_squares jac/hess/covariance matrices res = least_squares(objective.residuals, np.array(params), jac='3-point') hess_least_squares = np.matmul(res.jac.T, res.jac) covar_least_squares = np.linalg.inv(hess_least_squares) # now calculate corresponding matrices by hand, to see if the approach # concurs with least_squares objective.setp(res.x) _pvals = np.array(res.x) def residuals_scaler(vals): return np.squeeze(objective.residuals(_pvals * vals)) jac = approx_derivative(residuals_scaler, np.ones_like(_pvals)) hess = np.matmul(jac.T, jac) covar = np.linalg.inv(hess) covar = covar * np.atleast_2d(_pvals) * np.atleast_2d(_pvals).T assert_allclose(covar, covar_least_squares) # check that objective.covar corresponds to the least_squares # covariance matrix objective.setp(res.x) _pvals = np.array(res.x) covar_objective = objective.covar() assert_allclose(covar_objective, covar_least_squares) # now see what happens with a parameter that has no effect on residuals param = Parameter(1.234, name='dummy') param.vary = True params.append(param) from pytest import raises with raises(LinAlgError): objective.covar()
def test_add_data(self): # test we can add data to the dataset # 2 columns data = Data1D() x1 = np.linspace(0, 10, 5) y1 = 2 * x1 data.add_data((x1, y1)) x2 = np.linspace(7, 20, 10) y2 = 2 * x2 + 2 data.add_data((x2, y2), requires_splice=True) assert_(len(data) == 13) # 3 columns data = Data1D() x1 = np.linspace(0, 10, 5) y1 = 2 * x1 e1 = np.ones_like(x1) data.add_data((x1, y1, e1)) x2 = np.linspace(7, 20, 10) y2 = 2 * x2 + 2 e2 = np.ones_like(x2) data.add_data((x2, y2, e2), requires_splice=True) assert_(len(data) == 13) # 4 columns data = Data1D() x1 = np.linspace(0, 10, 5) y1 = 2 * x1 e1 = np.ones_like(x1) dx1 = np.ones_like(x1) data.add_data((x1, y1, e1, dx1)) x2 = np.linspace(7, 20, 10) y2 = 2 * x2 + 2 e2 = np.ones_like(x2) dx2 = np.ones_like(x2) data.add_data((x2, y2, e2, dx2), requires_splice=True) assert_(len(data) == 13) # test addition of datasets. x1 = np.linspace(0, 10, 5) y1 = 2 * x1 e1 = np.ones_like(x1) dx1 = np.ones_like(x1) data = Data1D((x1, y1, e1, dx1)) x2 = np.linspace(7, 20, 10) y2 = 2 * x2 + 2 e2 = np.ones_like(x2) dx2 = np.ones_like(x2) data2 = Data1D((x2, y2, e2, dx2)) data3 = data + data2 assert_(len(data3) == 13) # test iadd of datasets data += data2 assert_(len(data) == 13)
def test_init_with_data1d(self): # test we can construct a dataset from a dataset (i.e. a copy) dataset = Data1D(self.data) assert_equal(dataset.y, self.data.y)