def test_mixed_reflectivity_model(self): # test that mixed area model works ok. # should be same as data generated from Motofit sio2 = SLD(3.47, name='SiO2') air = SLD(0, name='air') si = SLD(2.07, name='Si') s1 = air | sio2(100, 2) | si(0, 3) s2 = air | sio2(100, 2) | si(0, 3) mixed_model = MixedReflectModel([s1, s2], [0.4, 0.3], dq=0) assert_almost_equal(mixed_model(self.qvals), self.rvals * 0.7) # now try out the mixed model compared to sum of individual models # with smearing, but no background. s1 = air | sio2(100, 2) | si(0, 2) s2 = air | sio2(50, 3) | si(0, 1) mixed_model = MixedReflectModel([s1, s2], [0.4, 0.3], dq=5, bkg=0) indiv1 = ReflectModel(s1, bkg=0) indiv2 = ReflectModel(s2, bkg=0) assert_almost_equal(mixed_model(self.qvals), (0.4 * indiv1(self.qvals) + 0.3 * indiv2(self.qvals))) # now try out the mixed model compared to sum of individual models # with smearing, and background. mixed_model.bkg.value = 1e-7 assert_almost_equal(mixed_model(self.qvals), (0.4 * indiv1(self.qvals) + 0.3 * indiv2(self.qvals) + 1e-7))
def setup(): # load the data. DATASET_NAME = os.path.join(refnx.__path__[0], 'analysis', 'test', 'c_PLP0011859_q.txt') # load the data data = ReflectDataset(DATASET_NAME) # the materials we're using si = SLD(2.07, name='Si') sio2 = SLD(3.47, name='SiO2') film = SLD(2, name='film') d2o = SLD(6.36, name='d2o') structure = si | sio2(30, 3) | film(250, 3) | d2o(0, 3) structure[1].thick.setp(vary=True, bounds=(15., 50.)) structure[1].rough.setp(vary=True, bounds=(1., 6.)) structure[2].thick.setp(vary=True, bounds=(200, 300)) structure[2].sld.real.setp(vary=True, bounds=(0.1, 3)) structure[2].rough.setp(vary=True, bounds=(1, 6)) model = ReflectModel(structure, bkg=9e-6, scale=1.) model.bkg.setp(vary=True, bounds=(1e-8, 1e-5)) model.scale.setp(vary=True, bounds=(0.9, 1.1)) model.threads = 1 # fit on a logR scale, but use weighting objective = Objective(model, data, transform=Transform('logY'), use_weights=True) return objective
def setup(self): pth = os.path.dirname(os.path.abspath(refnx.reflect.__file__)) e361 = RD(os.path.join(pth, 'test', 'e361r.txt')) sio2 = SLD(3.47, name='SiO2') si = SLD(2.07, name='Si') d2o = SLD(6.36, name='D2O') polymer = SLD(1, name='polymer') # e361 is an older dataset, but well characterised structure361 = si | sio2(10, 4) | polymer(200, 3) | d2o(0, 3) model361 = ReflectModel(structure361, bkg=2e-5) model361.scale.vary = True model361.bkg.vary = True model361.scale.range(0.1, 2) model361.bkg.range(0, 5e-5) model361.dq = 5. # d2o structure361[-1].sld.real.vary = True structure361[-1].sld.real.range(6, 6.36) structure361[1].thick.vary = True structure361[1].thick.range(5, 20) structure361[2].thick.vary = True structure361[2].thick.range(100, 220) structure361[2].sld.real.vary = True structure361[2].sld.real.range(0.2, 1.5) e361.x_err = None objective = Objective(model361, e361) self.fitter = CurveFitter(objective, nwalkers=200) self.fitter.initialise('jitter')
def test_q_offset(self): p = SLD(0.0) q = SLD(2.07) s = p(0, 0) | q(0, 3) model = ReflectModel(s, scale=0.99, bkg=1e-8, q_offset=0.002) model2 = ReflectModel(s, scale=0.99, bkg=1e-8, q_offset=0.0) x = np.linspace(0.01, 0.2, 3) assert_equal(model(x - 0.002), model2(x))
def test_reflectivity_model(self): # test reflectivity calculation with values generated from Motofit rff = ReflectModel(self.structure, dq=0) # the default for number of threads should be -1 assert rff.threads == -1 model = rff.model(self.qvals) assert_almost_equal(model, self.rvals)
def test_constant_smearing(self): # check that constant dq/q smearing is the same as point by point dqvals = 0.05 * self.qvals rff = ReflectModel(self.structure, quad_order="ultimate") calc = rff.model(self.qvals, x_err=dqvals) rff.dq = 5.0 calc2 = rff.model(self.qvals) assert_allclose(calc, calc2, rtol=0.011)
def resolution_test(slabs, data, backend): structure = Structure() for i, slab in enumerate(slabs): m = SLD(complex(slab[1], slab[2])) structure |= m(slab[0], slab[-1]) with use_reflect_backend(backend): model = ReflectModel(structure, bkg=0.0) model.quad_order = 17 R = model.model(data[:, 0], x_err=data[:, -1] * 2 * np.sqrt(2 * np.log(2))) np.testing.assert_allclose(R, data[:, 1], rtol=0.03)
def test_smearedabeles(self): # test smeared reflectivity calculation with values generated from # Motofit (quadrature precsion order = 13) theoretical = np.loadtxt( os.path.join(self.pth, "smeared_theoretical.txt")) qvals, rvals, dqvals = np.hsplit(theoretical, 3) """ the order of the quadrature precision used to create these smeared values in Motofit was 13. Do the same here """ rff = ReflectModel(self.structure, quad_order=13) calc = rff.model(qvals.flatten(), x_err=dqvals.flatten()) assert_almost_equal(rvals.flatten(), calc)
def __init__(self): super(DataStore, self).__init__() self.data_objects = OrderedDict() # create the default theoretical dataset q = np.linspace(0.005, 0.5, 1000) r = np.empty_like(q) dataset = ReflectDataset() dataset.data = (q, r) dataset.name = "theoretical" air = SLD(0, name="fronting") sio2 = SLD(3.47, name="1") si = SLD(2.07, name="backing") structure = air(0, 0) | sio2(15, 3.0) | si(0, 3.0) structure[1].name = "slab" structure[1].thick.name = "thick" structure[1].rough.name = "rough" structure[1].sld.real.name = "sld" structure[1].sld.imag.name = "isld" structure[1].vfsolv.name = "vfsolv" model = ReflectModel(structure, name="theoretical") self.add(dataset) self["theoretical"].model = model
def setup_method(self): self.pth = os.path.dirname(os.path.abspath(__file__)) self.si = SLD(2.07, name='Si') self.sio2 = SLD(3.47, name='SiO2') self.d2o = SLD(6.36, name='d2o') self.h2o = SLD(-0.56, name='h2o') self.cm3 = SLD(3.5, name='cm3') self.polymer = SLD(2, name='polymer') self.sio2_l = self.sio2(40, 3) self.polymer_l = self.polymer(200, 3) self.structure = (self.si | self.sio2_l | self.polymer_l | self.d2o(0, 3)) fname = os.path.join(self.pth, 'c_PLP0011859_q.txt') self.dataset = ReflectDataset(fname) self.model = ReflectModel(self.structure, bkg=2e-7) self.objective = Objective(self.model, self.dataset, use_weights=False, transform=Transform('logY')) self.global_objective = GlobalObjective([self.objective])
def __init__(self): super(DataStore, self).__init__() self.data_objects = OrderedDict() # create the default theoretical dataset q = np.linspace(0.005, 0.5, 1000) r = np.empty_like(q) dataset = ReflectDataset() dataset.data = (q, r) dataset.name = 'theoretical' air = SLD(0, name='fronting') sio2 = SLD(3.47, name='1') si = SLD(2.07, name='backing') structure = air(0, 0) | sio2(15, 3.) | si(0, 3.) structure[1].name = 'slab' structure[1].thick.name = 'thick' structure[1].rough.name = 'rough' structure[1].sld.real.name = 'sld' structure[1].sld.imag.name = 'isld' structure[1].vfsolv.name = 'vfsolv' model = ReflectModel(structure, name='theoretical') self.add(dataset) self['theoretical'].model = model
def remove_structure(self, row): # don't remove the last structure if row < STRUCT_OFFSET or len(self.structures) < 2: return # you have to be a mixedreflectmodel because there's more than one # structure data_object_node = find_data_object(self.index) data_object = data_object_node.data_object orig_model = data_object.model structures = orig_model.structures scales = orig_model.scales # going down to a single reflectmodel if len(structures) == 2: self._model.beginRemoveRows(self.index, row, row) # remove all dependent parameters (either in this dataset or # elsewhere) # do this before the Structure is popped. self._model.unlink_dependent_parameters(self.child(row)) structures.pop(row - STRUCT_OFFSET) scales.pop(row - STRUCT_OFFSET) sf = possibly_create_parameter(scales[0], name="scale") new_model = ReflectModel(structures[0], scale=sf, bkg=orig_model.bkg, dq=orig_model.dq) data_object.model = new_model self.popChild(row) self._model.endRemoveRows() n = ParNode(sf, self._model, self) self._model.beginInsertRows(self.index, 0, 0) self.insertChild(0, n) self._model.endInsertRows() self._model.beginRemoveRows(self.index, 1, 1) self.popChild(1) self._model.endRemoveRows() # data_object_node.set_reflect_model(new_model) return # you're not down to a single structure, so there must have been more # than 2 structures self._model.beginRemoveRows(self.index, row, row) # remove all dependent parameters (either in this dataset or elsewhere) # do this before the Structure is popped. self._model.unlink_dependent_parameters(self.child(row)) # pop the structure and scale factor nodes self.popChild(row) structures.pop(row - STRUCT_OFFSET) scales.pop(row - STRUCT_OFFSET) self._model.endRemoveRows() self._model.beginRemoveRows( self.child(0).index, row - STRUCT_OFFSET, row - STRUCT_OFFSET) self.child(0).popChild(row - STRUCT_OFFSET) self._model.endRemoveRows()
def test_resolution_speed_comparator(self): fname = os.path.join(self.pth, "c_PLP0011859_q.txt") dataset = ReflectDataset(fname) sio2 = SLD(3.47, name="SiO2") si = SLD(2.07, name="Si") d2o = SLD(6.36, name="D2O") polymer = SLD(2.0, name="polymer") sio2_l = sio2(30, 3) polymer_l = polymer(125, 3) dx = dataset.x_err structure = si | sio2_l | polymer_l | polymer_l | d2o(0, 3) model = ReflectModel(structure, bkg=2e-6, dq_type="constant") objective = Objective(model, dataset, use_weights=False, transform=Transform("logY")) # check that choose_resolution_approach doesn't change state # of model fastest_method = choose_dq_type(objective) assert model.dq_type == "constant" assert_equal(dx, objective.data.x_err) # check that the comparison worked const_time = time.time() for i in range(1000): objective.generative() const_time = time.time() - const_time model.dq_type = "pointwise" point_time = time.time() for i in range(1000): objective.generative() point_time = time.time() - point_time if fastest_method == "pointwise": assert point_time < const_time elif fastest_method == "constant": assert const_time < point_time # check that we could use the function to setup a reflectmodel ReflectModel(structure, bkg=2e-6, dq_type=choose_dq_type(objective))
def test_sld_profile(self): # test SLD profile with SLD profile from Motofit. np.seterr(invalid="raise") profile = np.loadtxt(os.path.join(self.pth, "sld_theoretical_R.txt")) z, rho = np.split(profile, 2) rff = ReflectModel(self.structure) z, myrho = rff.structure.sld_profile(z.flatten()) assert_almost_equal(myrho, rho.flatten())
def test_repr_reflect_model(self): p = SLD(0.0) q = SLD(2.07) s = p(0, 0) | q(0, 3) model = ReflectModel(s, scale=0.99, bkg=1e-8) r = eval(repr(model)) x = np.linspace(0.005, 0.3, 1000) assert_equal(r(x), model(x))
def phase_problem_plot(flag): if flag != "SLD" and flag != "ACF": raise Exception("Invalid flag to plot") qvals = np.linspace(0,0.2,1025)[1:] sld1 = SLD(0, 0) sld3 = SLD(2.074, 0) layer1 = sld1(0, 0) layer3 = sld3(0, 0) fig = plt.figure(figsize=(15, 10)) gs = gridspec.GridSpec(2, 2) ax1 = plt.subplot(gs[0,0]) ax2 = plt.subplot(gs[1,0]) for i, style in zip([0,1.0], ['k-', 'r:']): sld20 = SLD(6.335 - i, 0) sld21 = SLD(6.335 + i, 0) layer20 = sld20(100, 0) layer21 = sld21(100, 0) structure = Structure(layer1 | layer20 | layer21 | layer3) z, rho = structure.sld_profile() drho = (rho[1:] - rho[:-1]) / (z[1:] - z[:-1]) z_ = 0.5 * (z[:-1] + z[1:]) acf = autocorr(drho) z_acf = z_ - z_.min() z_acf = np.hstack((-np.flip(z_acf)[:-1], z_acf)) if flag == 'SLD': ax1.plot(z, rho, style) ax2.semilogy(qvals, ReflectModel(structure, dq=0.0).model(qvals), style) else: ax1.stem(z_, drho, style, markerfmt=' ', basefmt=style, use_line_collection=True) ax2.stem(z_acf, acf, style, markerfmt=' ', basefmt=style, use_line_collection=True) if flag == 'SLD': ax1.set_xlabel(r'$z$/Å') ax1.set_ylabel(r'$\rho(z)$/Å$^{-2}$') ax2.set_xlabel(r'$q$/Å') ax2.set_ylabel(r'$R(q)$') else: ax1.set_xlabel(r'$z$/Å') ax1.set_ylabel(r'$\rho\'(z)$/Å$^{-3}$') ax2.set_xlabel(r'$z$/Å') ax2.set_ylabel("$ \\rm{ACF}_{\\rho'}(z)/ \\AA^{-5}$") plt.tight_layout() figfilename = f"phase_problem_{flag}.pdf" plt.savefig(figfilename) print(f"Figure saved as {figfilename}") plt.close()
def save(save_path, name, structures, noisy=False): """Saves a list of Structure objects in the HDF5 format. Args: save_path (string): the file path to save the HDF5 file to. name (string): the name of the HDF5 file. structures (list): a list of refnx Structure objects to save. noisy (Boolean): whether to add background and sample noise when saving. """ save_path = save_path + "/" + name if not os.path.exists(save_path): #Create directories if not present. os.makedirs(save_path) #Space q points in equal log bins. q = np.logspace(np.log10(CurveGenerator.qMin), np.log10(CurveGenerator.qMax), CurveGenerator.points) parameters = [] data = [] for structure in structures: model = ReflectModel(structure, bkg=XRayGenerator.bkg, scale=CurveGenerator.scale, dq=CurveGenerator.dq) r = model(q) #Generate r values. if noisy: #Add background and sample noise if specified. r_noisy = CurveGenerator.background_noise( r, bkg_rate=CurveGenerator.bkg_rate) r = CurveGenerator.sample_noise( q, r_noisy, constant=CurveGenerator.noise_constant) data.append(list(zip( q, r))) #Add (q, r) pairs as a list to the data to store. #CurveGenerator.plot_reflectivity(q, r) temp = [0, 0, 0, 0, 0, 0] #Designed for parameter for up to 3 layers. for i, component in enumerate( structure.components[1:-1]): #Exclude air and substrate temp[2 * i] = component.thick.value temp[ 2 * i + 1] = component.sld.density.value * XRayGenerator.density_constant #Convert density to SLD parameters.append(temp) with h5py.File(save_path + "/{}-Layer.h5".format(name), 'w') as file: file.create_dataset("SLD_NUMS", data=parameters, chunks=(len(structures), 6)) file.create_dataset("DATA", data=data, chunks=(len(structures), CurveGenerator.points, 2))
def test_smearedabeles_reshape(self): # test smeared reflectivity calculation with values generated from # Motofit (quadrature precsion order = 13) theoretical = np.loadtxt(os.path.join(self.pth, 'smeared_theoretical.txt')) qvals, rvals, dqvals = np.hsplit(theoretical, 3) ''' the order of the quadrature precision used to create these smeared values in Motofit was 13. Do the same here ''' reshaped_q = np.reshape(qvals, (2, 250)) reshaped_r = np.reshape(rvals, (2, 250)) reshaped_dq = np.reshape(dqvals, (2, 250)) rff = ReflectModel(self.structure, quad_order=13) calc = rff.model(reshaped_q, x_err=reshaped_dq) assert_almost_equal(calc, reshaped_r)
def test_mcmc_fit_and_reprocess(qtbot, tmpdir): # test if we can add a spline to a model and save an experiment myapp, model = mysetup(qtbot) # load a dataset pth = os.path.dirname(os.path.abspath(refnx.analysis.__file__)) f_data = pjoin(pth, "test", "e361r.txt") myapp.load_data([f_data]) fit_list = myapp.currently_fitting_model fit_list.addItems(["e361r"]) # make a model and save it to pkl so we can load it si = SLD(2.07) sio2 = SLD(3.47) polymer = SLD(1.0) d2o = SLD(6.36) s = si | sio2(15, 3) | polymer(210, 3) | d2o(0, 3) rmodel = ReflectModel(s) rmodel.name = "e361r" rmodel.bkg.setp(vary=True, bounds=(1.0e-6, 5e-6)) s[-2].thick.setp(vary=True, bounds=(200, 300)) s[-2].sld.real.setp(vary=True, bounds=(0.0, 2.0)) mod_file_name = pjoin(tmpdir, "model.pkl") with open(mod_file_name, "wb") as f: pickle.dump(rmodel, f) # load the model myapp.load_model(mod_file_name) # do an MCMC myapp.select_fitting_algorithm("MCMC") names_to_fit = myapp.currently_fitting_model.datasets datastore = model.datastore data_objects = [datastore[name] for name in names_to_fit] kwds = {"nsteps": 5, "folder": tmpdir, "nplot": 20} myapp.fit_data_objects(data_objects, mcmc_kws=kwds) assert os.path.isfile(pjoin(tmpdir, "steps_corner.png"))
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 generate(self): """Generates a series of datasets simulating an experiment with a layer whose thickness changes over time.""" print("---------------- Generating ----------------") q = np.logspace(np.log10(CurveGenerator.qMin), np.log10(NeutronGenerator.qMax), self.points) for thickness in self.thick_range: #Iterate over each thickness the top layer will take. #The structure consists of air followed by each layer and then finally the substrate. air = SLD(0, name="Air") layer1 = SLD(self.layer1_sld, name="Layer 1")(thick=thickness, rough=self.roughness) layer2 = SLD(self.layer2_sld, name="Layer 2")(thick=self.layer2_thick, rough=self.roughness) substrate = SLD(NeutronGenerator.substrate_sld, name="Si Substrate")(thick=0, rough=self.roughness) structure = air | layer1 | layer2 | substrate model = ReflectModel(structure, bkg=NeutronGenerator.bkg, scale=CurveGenerator.scale, dq=CurveGenerator.dq) r = model(q) #Add simulated noise to the data. r_noisy_bkg = CurveGenerator.background_noise( r, bkg_rate=CurveGenerator.bkg_rate) r_noisy_sample = CurveGenerator.sample_noise( q, r_noisy_bkg, constant=CurveGenerator.noise_constant) #CurveGenerator.plot_reflectivity(q, r_noisy_sample) data = np.zeros((self.points, 3)) data[:, 0] = q data[:, 1] = r_noisy_sample data[:, 2] = 1e-10 #Error is set to be (near) zero as it is not used by the networks. This could be improved. np.savetxt(self.path + "/{}.dat".format(thickness), data, delimiter=" ") print("Layer 1 - Depth: [{0},{1}] | SLD: {2:1.3f}".format( self.thick_min, self.thick_max - self.thick_step, self.layer1_sld)) print("Layer 2 - Depth: {0} | SLD: {1:1.3f}".format( self.layer2_thick, self.layer2_sld))
def test_code_fragment(self): e361 = ReflectDataset(os.path.join(self.pth, "e361r.txt")) si = SLD(2.07, name="Si") sio2 = SLD(3.47, name="SiO2") d2o = SLD(6.36, name="D2O") polymer = SLD(1, name="polymer") # e361 is an older dataset, but well characterised self.structure361 = si | sio2(10, 4) | polymer(200, 3) | d2o(0, 3) self.model361 = ReflectModel(self.structure361, bkg=2e-5) self.model361.scale.vary = True self.model361.bkg.vary = True self.model361.scale.range(0.1, 2) self.model361.bkg.range(0, 5e-5) # d2o self.structure361[-1].sld.real.vary = True self.structure361[-1].sld.real.range(6, 6.36) self.structure361[1].thick.vary = True self.structure361[1].thick.range(5, 20) self.structure361[2].thick.vary = True self.structure361[2].thick.range(100, 220) self.structure361[2].sld.real.vary = True self.structure361[2].sld.real.range(0.2, 1.5) objective = Objective(self.model361, e361, transform=Transform("logY")) objective2 = eval(repr(objective)) assert_allclose(objective2.chisqr(), objective.chisqr()) exec(repr(objective)) exec(code_fragment(objective)) # artificially link the two thicknesses together # check that we can reproduce the objective from the repr self.structure361[2].thick.constraint = self.structure361[1].thick fragment = code_fragment(objective) fragment = fragment + "\nobj = objective()\nresult = obj.chisqr()" d = {} # need to provide the globals dictionary to exec, so it can see imports # e.g. https://bit.ly/2RFOF7i (from stackoverflow) exec(fragment, globals(), d) assert_allclose(d["result"], objective.chisqr())
def setup_method(self): self.pth = os.path.dirname(os.path.abspath(__file__)) sio2 = SLD(3.47, name="SiO2") air = SLD(0, name="air") si = SLD(2.07, name="Si") d2o = SLD(6.36, name="D2O") polymer = SLD(1, name="polymer") self.structure = air | sio2(100, 2) | si(0, 3) theoretical = np.loadtxt(os.path.join(self.pth, "theoretical.txt")) qvals, rvals = np.hsplit(theoretical, 2) self.qvals = qvals.flatten() self.rvals = rvals.flatten() # e361 is an older dataset, but well characterised self.structure361 = si | sio2(10, 4) | polymer(200, 3) | d2o(0, 3) self.model361 = ReflectModel(self.structure361, bkg=2e-5) self.model361.scale.vary = True self.model361.bkg.vary = True self.model361.scale.range(0.1, 2) self.model361.bkg.range(0, 5e-5) # d2o self.structure361[-1].sld.real.vary = True self.structure361[-1].sld.real.range(6, 6.36) self.structure361[1].thick.vary = True self.structure361[1].thick.range(5, 20) self.structure361[2].thick.vary = True self.structure361[2].thick.range(100, 220) self.structure361[2].sld.real.vary = True self.structure361[2].sld.real.range(0.2, 1.5) self.e361 = ReflectDataset(os.path.join(self.pth, "e361r.txt")) self.qvals361, self.rvals361, self.evals361 = ( self.e361.x, self.e361.y, self.e361.y_err, ) self.app = Motofit() self.app(self.e361, model=self.model361)
def __init__(self, file_path, layers, predicted_slds, predicted_depths, xray): """Initialises the Model class by creating a refnx model with given predicted values. Args: file_path (string): a path to the file with the data to construct the model for. layers (int): the number of layers for the model predicted by the classifier. predicted_slds (ndarray): an array of predicted SLDs for each layer. predicted_depths (ndarray): an array of predicted depths for each layer. xray (Boolean): whether the model should use a neutron or x-ray probe. """ self.structure = SLD(0, name='Air') #Model starts with air. if xray: #Use x-ray probe for i in range(layers): density = predicted_slds[i] / XRayGenerator.density_constant SLD_layer = MaterialSLD(XRayGenerator.material, density, probe='x-ray', wavelength=XRayGenerator.wavelength, name='Layer {}'.format(i+1)) layer = SLD_layer(thick=predicted_depths[i], rough=Model.roughness) layer.density.setp(bounds=XRayGenerator.density_bounds, vary=True) layer.thick.setp(bounds=ImageGenerator.depth_bounds, vary=True) layer.rough.setp(bounds=Model.rough_bounds, vary=True) self.structure = self.structure | layer #Next comes each layer. #Then substrate si_substrate = MaterialSLD(XRayGenerator.material, XRayGenerator.substrate_density, probe='x-ray', name='Si Substrate')(thick=0, rough=Model.roughness) else: #Use neutron probe for i in range(layers): layer = SLD(predicted_slds[i], name='Layer {}'.format(i+1))(thick=predicted_depths[i], rough=Model.roughness) layer.sld.real.setp(bounds=ImageGenerator.sld_neutron_bounds, vary=True) layer.thick.setp(bounds=ImageGenerator.depth_bounds, vary=True) layer.rough.setp(bounds=Model.rough_bounds, vary=True) self.structure = self.structure | layer #Next comes each layer. #Then substrate si_substrate = SLD(Model.si_sld, name='Si Substrate')(thick=0, rough=Model.roughness) si_substrate.rough.setp(bounds=Model.rough_bounds, vary=True) self.structure = self.structure | si_substrate data = self.__load_data(file_path) #Pre-process and load given dataset. self.model = ReflectModel(self.structure, scale=Model.scale, dq=Model.dq, bkg=Model.bkg) self.objective = Objective(self.model, data)
def test_modelvals_degenerate_layers(self): # try fitting dataset with a deposited layer split into two degenerate # layers fname = os.path.join(self.pth, "c_PLP0011859_q.txt") dataset = ReflectDataset(fname) sio2 = SLD(3.47, name="SiO2") si = SLD(2.07, name="Si") d2o = SLD(6.36, name="D2O") polymer = SLD(2.0, name="polymer") sio2_l = sio2(30, 3) polymer_l = polymer(125, 3) structure = si | sio2_l | polymer_l | polymer_l | d2o(0, 3) polymer_l.thick.setp(value=125, vary=True, bounds=(0, 250)) polymer_l.rough.setp(value=4, vary=True, bounds=(0, 8)) structure[-1].rough.setp(vary=True, bounds=(0, 6)) sio2_l.rough.setp(value=3.16, vary=True, bounds=(0, 8)) model = ReflectModel(structure, bkg=2e-6) objective = Objective(model, dataset, use_weights=False, transform=Transform("logY")) model.scale.setp(vary=True, bounds=(0, 2)) model.bkg.setp(vary=True, bounds=(0, 8e-6)) slabs = structure.slabs() assert_equal(slabs[2, 0:2], slabs[3, 0:2]) assert_equal(slabs[2, 3], slabs[3, 3]) assert_equal(slabs[1, 3], sio2_l.rough.value) f = CurveFitter(objective) f.fit(method="differential_evolution", seed=1, maxiter=3) slabs = structure.slabs() assert_equal(slabs[2, 0:2], slabs[3, 0:2]) assert_equal(slabs[2, 3], slabs[3, 3])
def make_model(names, bs, thicks, roughs, fig_i, data, show=False, mcmc=False): no_layers = len(bs) layers = [] for i in range(no_layers): names.append('layer' + str(i)) for i in range(no_layers): sld = SLD(bs[i], name=names[i]) layers.append(sld(thicks[i], roughs[i])) layers[0].thick.setp(vary=True, bounds=(thicks[i] - 1, thicks[i] + 1)) layers[0].sld.real.setp(vary=True, bounds=(bs[i] - 1, bs[i] + 1)) for layer in layers[1:]: layer.thick.setp(vary=True, bounds=(thicks[i] - 1, thicks[i] + 1)) layer.sld.real.setp(vary=True, bounds=(bs[i] - 1, bs[i] + 1)) layer.rough.setp(vary=True, bounds=(0, 5)) structure = layers[0] for layer in layers[1:]: structure |= layer print(structure) model = ReflectModel(structure, bkg=3e-6, dq=5.0) #model.scale.setp(bounds=(0.6, 1.2), vary=True) #model.bkg.setp(bounds=(1e-9, 9e-6), vary=True) objective = Objective(model, data, transform=Transform('logY')) fitter = CurveFitter(objective) if mcmc: fitter.sample(1000) process_chain(objective, fitter.chain, nburn=300, nthin=100) else: fitter.fit('differential_evolution') print(objective.parameters) if show: plt.figure(fig_i) plt.plot(*structure.sld_profile()) plt.ylabel('SLD /$10^{-6} \AA^{-2}$') plt.xlabel('distance / $\AA$') return structure, fitter, objective, fig_i + 1
def make_model(names, bs, thicks, roughs, fig_i, data, show=False, mcmc=False): extent = sum( thicks[:, 0]) # (float or Parameter) – Total extent of spline region vs = array( bs )[:, 0] #(Sequence of float/Parameter) – the real part of the SLD values of each of the knots. dz = cum_sum( array(thicks[:, 0]) ) #(Sequence of float/Parameter) – the lateral offset between successive knots. print(dz) name = "number of nots " + str(len(names)) #(str) – Name of component component = Spline(extent, vs, dz, name) front = SLD(0) front = front(0, 0) back = SLD(0) back = back(0, 0) structure = front | component | back model = ReflectModel(structure, bkg=3e-6, dq=5.0) objective = Objective(model, data, transform=Transform('logY')) fitter = CurveFitter(objective) fitter.fit('differential_evolution') return structure, fitter, objective, fig_i + 1
layers_to_cut = int(co / lt) + 1 timesteps += sim.layers.shape[0] l = np.append(l, sim.layers[:, :-layers_to_cut, :]) n = l.reshape(timesteps, sim.layers.shape[1]-layers_to_cut, sim.layers.shape[2]) data_dir = '../data/reflectometry2/dspc_{}/'.format(surface_pressure) dataset = ReflectDataset(os.path.join(data_dir, '{}{}.dat'.format(contrast, surface_pressure))) refy = np.zeros((n.shape[0], dataset.x.size)) sldy = [] chi = np.zeros((n.shape[0])) print(n.shape[0]) for i in range(n.shape[0]): sim.av_layers = n[i, :, :] model = ReflectModel(sim) model.scale.setp(1, vary=True, bounds=(0.00000001, np.inf)) model.bkg.setp(dataset.y[-1], vary=False) objective = Objective(model, dataset, transform=Transform('YX4')) fitter = CurveFitter(objective) res = fitter.fit() refy[i] = model(dataset.x, x_err=dataset.x_err)*(dataset.x)**4 sldy.append(sim.sld_profile()[1]) chi[i] = objective.chisqr() all_chi = np.append(all_chi, objective.chisqr()) if i == 0: ax1.errorbar(dataset.x, dataset.y*(dataset.x)**4 * 10**(ci-1), yerr=dataset.y_err*( dataset.x)**4 * 10**(ci-1), linestyle='', marker='o',
def test_multipledataset_corefinement(self): # test corefinement of three datasets data361 = ReflectDataset(os.path.join(self.pth, 'e361r.txt')) data365 = ReflectDataset(os.path.join(self.pth, 'e365r.txt')) data366 = ReflectDataset(os.path.join(self.pth, 'e366r.txt')) si = SLD(2.07, name='Si') sio2 = SLD(3.47, name='SiO2') d2o = SLD(6.36, name='d2o') h2o = SLD(-0.56, name='h2o') cm3 = SLD(3.47, name='cm3') polymer = SLD(1, name='polymer') structure361 = si | sio2(10, 4) | polymer(200, 3) | d2o(0, 3) structure365 = si | structure361[1] | structure361[2] | cm3(0, 3) structure366 = si | structure361[1] | structure361[2] | h2o(0, 3) structure365[-1].rough = structure361[-1].rough structure366[-1].rough = structure361[-1].rough structure361[1].thick.setp(vary=True, bounds=(0, 20)) structure361[2].thick.setp(value=200., bounds=(200., 250.), vary=True) structure361[2].sld.real.setp(vary=True, bounds=(0, 2)) structure361[2].vfsolv.setp(value=5., bounds=(0., 100.), vary=True) model361 = ReflectModel(structure361, bkg=2e-5) model365 = ReflectModel(structure365, bkg=2e-5) model366 = ReflectModel(structure366, bkg=2e-5) model361.bkg.setp(vary=True, bounds=(1e-6, 5e-5)) model365.bkg.setp(vary=True, bounds=(1e-6, 5e-5)) model366.bkg.setp(vary=True, bounds=(1e-6, 5e-5)) objective361 = Objective(model361, data361) objective365 = Objective(model365, data365) objective366 = Objective(model366, data366) global_objective = GlobalObjective( [objective361, objective365, objective366]) # are the right numbers of parameters varying? assert_equal(len(global_objective.varying_parameters()), 7) # can we set the parameters? global_objective.setp(np.array([1e-5, 10, 212, 1, 10, 1e-5, 1e-5])) f = CurveFitter(global_objective) f.fit() indiv_chisqr = np.sum( [objective.chisqr() for objective in global_objective.objectives]) # the overall chi2 should be sum of individual chi2 global_chisqr = global_objective.chisqr() assert_almost_equal(global_chisqr, indiv_chisqr) # now check that the parameters were held in common correctly. slabs361 = structure361.slabs() slabs365 = structure365.slabs() slabs366 = structure366.slabs() assert_equal(slabs365[0:2, 0:5], slabs361[0:2, 0:5]) assert_equal(slabs366[0:2, 0:5], slabs361[0:2, 0:5]) assert_equal(slabs365[-1, 3], slabs361[-1, 3]) assert_equal(slabs366[-1, 3], slabs361[-1, 3]) # check that the residuals are the correct lengths res361 = objective361.residuals() res365 = objective365.residuals() res366 = objective366.residuals() res_global = global_objective.residuals() assert_allclose(res_global[0:len(res361)], res361, rtol=1e-5) assert_allclose(res_global[len(res361):len(res361) + len(res365)], res365, rtol=1e-5) assert_allclose(res_global[len(res361) + len(res365):], res366, rtol=1e-5) repr(global_objective)
def getObjective(data, nLayers, bs_contrast_layer=None, contrast_layer=None, limits = None, doMCMC=False, logpExtra=None, onlyStructure=False, both=False, globalObjective=False): if globalObjective: if bs_contrast_layer is None: bs_contrast_layer = 6 if contrast_layer is None: contrast_layer = 1 # print("data, nLayers, bs_contrast_layer=None,\n contrast_layer=None,\nlimits = None, doMCMC=False,\nlogpExtra=None, onlyStructure=False,\nboth=False, globalObjective=False: ", # data, nLayers, bs_contrast_layer, # contrast_layer, # limits, doMCMC, # logpExtra, onlyStructure, # both, globalObjective) air = SLD(0,name="air layer") airSlab = air(10,0) sio2 = SLD(10,name="bottem layer") sio2Slab = sio2(10,0) if limits is None: limits = [350,50,4,6] # maxThick = 350 # lowerThick = 50 # upperThick = maxThick - nLayers*lowerThick # lowerB = 4 # upperB = 6 maxThick = float(limits[0]) lowerThick = limits[1] upperThick = maxThick - nLayers*lowerThick lowerB = limits[2] upperB = limits[3] if globalObjective: thick_contrast_layer=Parameter(maxThick/nLayers, "layer1 thickness") rough_contrast_layer=Parameter(0, "layer0/contrast roughness") sldcontrastA=SLD(5,name="contrast A layer") sldcontrastASlab= sldcontrastA(thick_contrast_layer,rough_contrast_layer) sldcontrastASlab.thick.setp(vary=True, bounds=(lowerThick,upperThick)) sldcontrastASlab.sld.real.setp(vary=True, bounds=(lowerB,upperB)) sldcontrastB=SLD(5,name="contrast B layer") sldcontrastBSlab = sldcontrastB(thick_contrast_layer,rough_contrast_layer) sldcontrastBSlab.thick.setp(vary=True, bounds=(lowerThick,upperThick)) sldcontrastBSlab.sld.real.setp(vary=True, bounds=(lowerB,upperB)) if nLayers>=1 and not globalObjective: sld1 = SLD(5,name="first layer") sld1Slab = sld1(maxThick/nLayers,0) sld1Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick)) sld1Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB)) if nLayers>=2: sld2 = SLD(5,name="second layer") sld2Slab = sld2(maxThick/nLayers,0) sld2Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick)) sld2Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB)) if nLayers>=3: sld3 = SLD(5,name="third layer") sld3Slab = sld3(maxThick/nLayers,0) sld3Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick)) sld3Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB)) if nLayers>=4: sld4 = SLD(5,name="forth layer") sld4Slab = sld4(maxThick/nLayers,0) sld4Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick)) sld4Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB)) # if nLayers>=1: # sld1Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick)) # sld1Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB)) # if nLayers>=2: # sld2Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick)) # sld2Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB)) # if nLayers>=3: # sld3Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick)) # sld3Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB)) # if nLayers>=4: # sld4Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick)) # sld4Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB)) if globalObjective and contrast_layer==1: if nLayers==1: structure1 = airSlab|sldcontrastASlab|sio2Slab structure2 = airSlab|sldcontrastBSlab|sio2Slab if nLayers==2: structure1 = airSlab|sldcontrastASlab|sld2Slab|sio2Slab structure2 = airSlab|sldcontrastBSlab|sld2Slab|sio2Slab if nLayers==3: structure1 = airSlab|sldcontrastASlab|sld2Slab|sld3Slab|sio2Slab structure2 = airSlab|sldcontrastBSlab|sld2Slab|sld3Slab|sio2Slab if nLayers==4: structure1 = airSlab|sldcontrastASlab|sld2Slab|sld3Slab|sld4Slab|sio2Slab structure2 = airSlab|sldcontrastBSlab|sld2Slab|sld3Slab|sld4Slab|sio2Slab if onlyStructure: returns = structure1,structure2 elif both: model1 = ReflectModel(structure1, bkg=3e-6, dq=5.0) model1.scale.setp(bounds=(0.85, 1.2), vary=True) model1.bkg.setp(bounds=(1e-9, 9e-6), vary=True) objective1 = Objective(model1, data[0], transform=Transform('logY'), logp_extra=logpExtra) model2 = ReflectModel(structure2, bkg=3e-6, dq=5.0) model2.scale.setp(bounds=(0.85, 1.2), vary=True) model2.bkg.setp(bounds=(1e-9, 9e-6), vary=True) objective2 = Objective(model2, data[1], transform=Transform('logY'), logp_extra=logpExtra) returns = GlobalObjective([objective1, objective2]), structure1, structure2 print("GlobalObjective and 2 structures") else: model1 = ReflectModel(structure1, bkg=3e-6, dq=5.0) model1.scale.setp(bounds=(0.85, 1.2), vary=True) model1.bkg.setp(bounds=(1e-9, 9e-6), vary=True) objective1 = Objective(model1, data[0], transform=Transform('logY'), logp_extra=logpExtra) model2 = ReflectModel(structure2, bkg=3e-6, dq=5.0) model2.scale.setp(bounds=(0.85, 1.2), vary=True) model2.bkg.setp(bounds=(1e-9, 9e-6), vary=True) objective2 = Objective(model2, data[1], transform=Transform('logY'), logp_extra=logpExtra) returns = GlobalObjective([objective1, objective2]) elif not globalObjective: if nLayers==1: structure = airSlab|sld1Slab|sio2Slab if nLayers==2: structure = airSlab|sld1Slab|sld2Slab|sio2Slab if nLayers==3: structure = airSlab|sld1Slab|sld2Slab|sld3Slab|sio2Slab if nLayers==4: structure = airSlab|sld1Slab|sld2Slab|sld3Slab|sld4Slab|sio2Slab if onlyStructure: returns = structure elif both: model = ReflectModel(structure, bkg=3e-6, dq=5.0) objective = Objective(model, data, transform=Transform('logY'), logp_extra=logpExtra) returns = objective, structure else: model = ReflectModel(structure, bkg=3e-6, dq=5.0) objective = Objective(model, data, transform=Transform('logY'),logp_extra=logpExtra) returns = objective else: print("error contrast layer not at sld1Slab ie contrast_layer!=0") # print(returns) return returns