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 test_FresnelTransform(self): t = FresnelTransform(2.07, 6.36, dq=5) slabs = np.array([[0, 2.07, 0, 0], [0, 6.36, 0, 0]]) q = np.linspace(0.01, 1.0, 1000) r = reflectivity(q, slabs, dq=5) rt, et = t(q, r) assert_almost_equal(rt, 1.0) # test errors are transformed rt, et = t(q, r, y_err=1.0) assert_almost_equal(et, 1.0 / r) # check that you can use an SLD object t = FresnelTransform(SLD(2.07), SLD(6.36), dq=5) rt, et = t(q, r) assert_almost_equal(rt, 1.0) # reconstitute a repr'd transform and check it works s = repr(t) st = eval(s) rt, et = st(q, r) assert_almost_equal(rt, 1.0)
def component(self): b_h_real = self.b_h_real.text() b_t_real = self.b_t_real.text() b_h_imag = self.b_h_imag.text() b_t_imag = self.b_t_imag.text() b_t = complex(float(b_t_real), float(b_t_imag)) b_h = complex(float(b_h_real), float(b_h_imag)) V_h = self.V_h.value() V_t = self.V_t.value() APM = self.APM.value() thick_h = self.thick_h.value() thick_t = self.thick_t.value() head_solvent = self.head_solvent.value() tail_solvent = self.tail_solvent.value() leaflet = LipidLeaflet( APM, b_h, V_h, thick_h, b_t, V_t, thick_t, 3, 3, head_solvent=SLD(head_solvent, name="head solvent"), tail_solvent=SLD(tail_solvent, name="tail solvent"), ) leaflet.name = "leaflet" return leaflet
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 __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 test_spline_solvation(self): a = Spline(100, [2], [0.5], zgrad=False, microslab_max_thickness=1) front = SLD(0.1) air = SLD(0.0) s = front | self.left | a | self.right | self.solvent # assign a solvent s.solvent = air self.left.vfsolv.value = 0.5 self.right.vfsolv.value = 0.5 assert_equal(s.slabs()[1, 1], 0.75) assert_equal(s.slabs()[-2, 1], 1.25) assert_almost_equal(a(0, s), 0.75) assert_almost_equal(a(100, s), 1.25) # remove solvent, should be solvated by backing medium s.solvent = None assert_equal(s.slabs()[1, 1], 5.75) assert_equal(s.slabs()[-2, 1], 6.25) assert_almost_equal(a(0, s), 5.75) assert_almost_equal(a(100, s), 6.25) # reverse structure, should be solvated by fronting medium s.reverse_structure = True assert_equal(s.slabs()[1, 1], 1.3) assert_equal(s.slabs()[-2, 1], 0.8) # note that a(0, s) end becomes the end when the structure is reversed assert_almost_equal(a(0, s), 0.8) assert_almost_equal(a(100, s), 1.3)
def test_slab_addition(self): # The slabs method for the main Structure component constructs # the overall slabs by concatenating Component slabs. This checks that # the slab concatenation is correct. si = SLD(2.07) sio2 = SLD(3.47) polymer = SLD(1.5) d2o = SLD(6.36) d2o_layer = d2o(0, 3) polymer_layer = polymer(20, 3) a = Spline(400, [4, 5.9], [0.2, .4], zgrad=True) film = si | sio2(10, 3) | polymer_layer | a | d2o_layer film.sld_profile() structure = si(0, 0) for i in range(200): p = SLD(i)(i, i) structure |= p structure |= d2o(0, 3) slabs = structure.slabs() assert_equal(slabs[1:-1, 0], np.arange(200)) assert_equal(slabs[1:-1, 1], np.arange(200)) assert_equal(slabs[1:-1, 3], np.arange(200)) assert_equal(slabs[-1, 1], 6.36) assert_equal(slabs[0, 1], 2.07) assert_equal(len(slabs), 202)
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 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 test_mixed_model(self): # test for MixedReflectModel air = SLD(0, name="air") sio2 = SLD(3.47, name="SiO2") si = SLD(2.07, name="Si") structure1 = air | sio2(100, 2) | si(0, 3) structure2 = air | sio2(50, 3) | si(0, 5) # this is out theoretical calculation mixed_model_y = 0.4 * structure1.reflectivity(self.qvals) mixed_model_y += 0.6 * structure2.reflectivity(self.qvals) mixed_model = MixedReflectModel([structure1, structure2], [0.4, 0.6], bkg=0, dq=0) assert_equal(mixed_model.scales, np.array([0.4, 0.6])) assert mixed_model.dq.value == 0 assert_allclose(mixed_model_y, mixed_model(self.qvals), atol=1e-13) # test repr of MixedReflectModel q = repr(mixed_model) r = eval(q) assert_equal(r.scales, np.array([0.4, 0.6])) assert r.dq.value == 0 assert_allclose(mixed_model_y, r(self.qvals), atol=1e-13)
def profile(self, extra=False): """ Calculates the volume fraction profile Returns ------- z, vfp : np.ndarray Distance from the interface, volume fraction profile """ s = Structure() s |= SLD(0) m = SLD(1.) for i, slab in enumerate(self.left_slabs): layer = m(slab.thick.value, slab.rough.value) if not i: layer.rough.value = 0 layer.vfsolv.value = slab.vfsolv.value s |= layer polymer_slabs = self.slabs() offset = np.sum(s.slabs()[:, 0]) if polymer_slabs is not None: for i in range(np.size(polymer_slabs, 0)): layer = m(polymer_slabs[i, 0], polymer_slabs[i, 3]) layer.vfsolv.value = polymer_slabs[i, -1] s |= layer for i, slab in enumerate(self.right_slabs): layer = m(slab.thick.value, slab.rough.value) layer.vfsolv.value = 1 - slab.vfsolv.value s |= layer s |= SLD(0, 0) # now calculate the VFP. total_thickness = np.sum(s.slabs()[:, 0]) zed = np.linspace(0, total_thickness, total_thickness + 1) # SLD profile puts a very small roughness on the interfaces with zero # roughness. zed[0] = 0.01 z, s = s.sld_profile(z=zed) s[0] = s[1] # perhaps you'd like to plot the knot locations zeds = np.cumsum(self.dz) if np.sum(self.dz) > 1: zeds /= np.sum(self.dz) zeds = np.clip(zeds, 0, 1) zed_knots = zeds * float(self.extent) + offset if extra: return z, s, zed_knots, np.array(self.vf) else: return z, s
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_initialisation_with_SLD(self): # we should be able to initialise with SLD objects heads = SLD(6.01e-4 + 0j) tails = SLD(-2.92e-4 + 0j) new_leaflet = LipidLeaflet(self.APM, heads, self.V_h, self.thick_h, tails, self.V_t, self.thick_t, 2, 3) slabs = self.leaflet.slabs() new_slabs = new_leaflet.slabs() assert_allclose(new_slabs, slabs)
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 test_reverse(self): # check that the structure reversal works. sio2 = SLD(3.47, name="SiO2") air = SLD(0, name="air") si = SLD(2.07, name="Si") structure = si | sio2(100, 3) | air(0, 2) structure.reverse_structure = True assert_equal(structure.slabs(), self.structure.slabs()) calc = structure.reflectivity(self.qvals) assert_almost_equal(calc, self.rvals)
def __repr__(self): d = {} d.update(self.__dict__) sld_bh = SLD([self.b_heads_real, self.b_heads_imag]) sld_bt = SLD([self.b_tails_real, self.b_tails_imag]) d['bh'] = sld_bh d['bt'] = sld_bt s = (" Monolayer({apm!r}, {bh!r}, {vm_heads!r}, {thickness_heads!r}," " {bt!r}, {vm_tails!r}, {thickness_tails!r}, {roughness!r}," " head_solvent={head_solvent!r}, solvfrac={solvfrac!r}" " reverse_monolayer={reverse_monolayer}, name={name!r})") return s.format(**d)
def __repr__(self): d = {} d.update(self.__dict__) sld_bh = SLD([self.b_heads_real, self.b_heads_imag]) sld_bt = SLD([self.b_tails_real, self.b_tails_imag]) d["bh"] = sld_bh d["bt"] = sld_bt s = ("LipidLeaflet({apm!r}, {bh!r}, {vm_heads!r}, {thickness_heads!r}," " {bt!r}, {vm_tails!r}, {thickness_tails!r}, {rough_head_tail!r}," " {rough_preceding_mono!r}, head_solvent={head_solvent!r}," " tail_solvent={tail_solvent!r}," " reverse_monolayer={reverse_monolayer}, name={name!r})") return s.format(**d)
def test_structure_construction(self): # structures are constructed by or-ing slabs # test that the slab representation is correct assert_equal( self.s.slabs(), np.array([[0, 0, 0, 0, 0], [100, 3.47, 0, 5, 0], [0, 6.36, 0, 4, 0]]), ) self.s[1] = SLD(3.47 + 1j, name="sio2")(100, 5) self.s[1].vfsolv.value = 0.9 oldpars = len(list(flatten(self.s.parameters))) # slabs have solvent penetration self.s.solvent = SLD(5 + 1.2j) sld = 5 * 0.9 + 0.1 * 3.47 sldi = 1 * 0.1 + 0.9 * 1.2 assert_almost_equal( self.s.slabs(), np.array([[0, 0, 0, 0, 0], [100, sld, sldi, 5, 0.9], [0, 6.36, 0, 4, 0]]), ) # when the structure._solvent is not None, but an SLD object, then # it's number of parameters should increase by 2. newpars = len(list(flatten(self.s.parameters))) assert_equal(newpars, oldpars + 2) # by default solvation is done by backing medium self.s.solvent = None sld = 6.36 * 0.9 + 0.1 * 3.47 sldi = 1 * 0.1 assert_almost_equal( self.s.slabs(), np.array([[0, 0, 0, 0, 0], [100, sld, sldi, 5, 0.9], [0, 6.36, 0, 4, 0]]), ) # by default solvation is done by backing medium, except when structure # is reversed self.s.reverse_structure = True sld = 0 * 0.9 + 0.1 * 3.47 sldi = 0 * 0.9 + 1 * 0.1 assert_almost_equal( self.s.slabs(), np.array([[0, 6.36, 0, 0, 0], [100, sld, sldi, 4, 0.9], [0, 0, 0, 5, 0]]), )
def test_sld(self): p = SLD(5 + 1j, name='pop') assert_equal(float(p.real), 5) assert_equal(float(p.imag), 1) # test that we can cast to complex assert_equal(complex(p), 5 + 1j) p = SLD(5) assert_equal(float(p.real), 5) q = Parameter(5) r = Parameter(1) p = SLD([q, r]) assert_equal(float(p.real), 5) assert_equal(float(p.imag), 1)
def __make_component(sld_range, thick_range, thick_probs, roughness, substrate=False): """Generates a single refnx component object representing a layer of the structure. Args: sld_range (ndarray): the discrete range of valid SLD values for generation. thick_range (ndarray): the range of valid thickness (depth) values for generation. thick_probs (list): the probabilities for each discrete thickness value. roughness (float): the given roughness for the layer. substrate (Boolean): whether the component is the substrate or not. Returns: A refnx Component object. """ if substrate: thickness = 0 #Substrate has 0 thickness in refnx. sld = NeutronGenerator.substrate_sld else: thickness = np.random.choice( thick_range, p=thick_probs) #Select a random thickness and SLD. sld = np.random.choice(sld_range) return SLD(sld)(thick=thickness, rough=roughness)
def __init__(self, apm, b_heads, vm_heads, thickness_heads, b_tails, vm_tails, thickness_tails, rough_head_tail, rough_preceding_mono, # water_vm, waters_per_head, waters_per_tail, # vm_mscl, protein_sld, PLRatio, head_solvent=None, tail_solvent=None, reverse_monolayer=False, name=''): super(LipidLeafletTest, self).__init__( apm, b_heads, vm_heads, thickness_heads, b_tails, vm_tails, thickness_tails, rough_head_tail, rough_preceding_mono, #water_vm, waters_per_head, waters_per_tail, head_solvent, tail_solvent, reverse_monolayer, name) self.PLRatio = possibly_create_parameter( PLRatio, name='%s - PLRatio, fraction lipid to protein' % name) self.protein_sld = possibly_create_parameter( protein_sld, name='%s - protein sld' % name) self.protein_sld = SLD(protein_sld, name="protein sld")
def __make_component(density_range, thick_range, thick_probs, roughness, substrate=False): """Generates a single refnx component object representing a layer of the structure. Args: density_range (ndarray): the discrete range of valid density values for generation. thick_range (ndarray): the range of valid thickness (depth) values for generation. thick_probs (list): the probabilities for each discrete thickness value. roughness (float): the given roughness for the component. substrate (Boolean): whether the component is the substrate or not. Returns: A refnx Component object. """ if substrate: thickness = 0 #Substrate has 0 thickness in refnx. density = XRayGenerator.substrate_density else: thickness = np.random.choice(thick_range, p=thick_probs) density = np.random.choice(density_range) SLD = MaterialSLD(XRayGenerator.material, density, probe='x-ray', wavelength=XRayGenerator.wavelength) return SLD(thick=thickness, rough=roughness)
def __random_structure(layers, density_range, thick_range, thick_probs): """Generates a single random refnx Structure object with desired parameters. Args: layers (int): the number of layers for each curve to be generated with. density_range (ndarray): the discrete range of valid density values for generation. thick_range (ndarray): the range of valid thickness (depth) values for generation. thick_probs (list): the probabilities for each discrete thickness value. Returns: A refnx Structure object. """ #The structure consists of air followed by each layer and then finally the substrate. roughness = np.random.choice( np.arange(*CurveGenerator.rough_bounds, 0.5) ) #Select a random roughness for the layers in this sample. structure = SLD(0, name="Air") for i in range(layers): component = XRayGenerator.__make_component(density_range, thick_range, thick_probs, roughness, substrate=False) structure = structure | component substrate = XRayGenerator.__make_component(density_range, thick_range, thick_probs, roughness, substrate=True) structure = structure | substrate return structure
def test_solvent_penetration(self): # check different types of solvation for heads/tails. self.leaflet.head_solvent = SLD(1.23) slabs = self.leaflet.slabs() assert_allclose( slabs[0, 1], 1.23 * self.phi_solv_h + (1 - self.phi_solv_h) * self.rho_h) assert_allclose(slabs[0, 4], 0) self.leaflet.head_solvent = None self.leaflet.tail_solvent = SLD(1.23) slabs = self.leaflet.slabs() assert_allclose( slabs[1, 1], 1.23 * self.phi_solv_t + (1 - self.phi_solv_t) * self.rho_t) assert_allclose(slabs[1, 4], 0)
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 __init__(self, extent, vf, dz, polymer_sld, name='', gamma=None, left_slabs=(), right_slabs=(), interpolator=Pchip, zgrad=True, monotonic_penalty=0, microslab_max_thickness=1): self.name = name if isinstance(polymer_sld, SLD): self.polymer_sld = polymer_sld else: self.polymer_sld = SLD(polymer_sld) # left and right slabs are other areas where the same polymer can # reside self.left_slabs = [slab for slab in left_slabs if isinstance(slab, Slab)] self.right_slabs = [slab for slab in right_slabs if isinstance(slab, Slab)] self.microslab_max_thickness = microslab_max_thickness self.extent = ( possibly_create_parameter(extent, name='%s - spline extent' % name)) # dz are the spatial spacings of the spline knots self.dz = Parameters(name='dz - spline') for i, z in enumerate(dz): p = possibly_create_parameter( z, name='%s - spline dz[%d]' % (name, i)) p.range(0, 1) self.dz.append(p) # vf are the volume fraction values of each of the spline knots self.vf = Parameters(name='vf - spline') for i, v in enumerate(vf): p = possibly_create_parameter( v, name='%s - spline vf[%d]' % (name, i)) p.range(0, 1) self.vf.append(p) if len(self.vf) != len(self.dz): raise ValueError("dz and vs must have same number of entries") self.monotonic_penalty = monotonic_penalty self.zgrad = zgrad self.interpolator = interpolator if gamma is not None: self.gamma = possibly_create_parameter(gamma, 'gamma') else: self.gamma = Parameter(0, 'gamma') self.__cached_interpolator = {'zeds': np.array([]), 'vf': np.array([]), 'interp': None, 'extent': -1}
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 test_repr_sld(self): p = SLD(5 + 1j, name='pop') assert_equal(float(p.real), 5) assert_equal(float(p.imag), 1) print(repr(p)) q = eval(repr(p)) assert_equal(float(q.real), 5) assert_equal(float(q.imag), 1)