def slabs(self, structure=None): layers = super(LipidLeafletTest, self).slabs(structure=structure) if self.reverse_monolayer: layers = np.flipud(layers) layers[:, 3] = layers[::-1, 3] # tail region volfrac = self.vm_tails.value / (self.apm.value * self.thickness_tails.value) layers[0, 4] = 1 - volfrac if self.head_solvent is not None: # we do the solvation here, not in Structure.slabs layers[0] = Structure.overall_sld(layers[0], self.head_solvent) layers[0, 4] = 0 # tail region volfrac = self.vm_tails.value / (self.apm.value * self.thickness_tails.value) layers[1, 4] = 1 - volfrac if self.tail_solvent is not None: # we do the solvation here, not in Structure.slabs layers[1] = Structure.overall_sld(layers[1], self.tail_solvent) layers[1, 4] = 0 if self.reverse_monolayer: layers = np.flipud(layers) layers[:, 3] = layers[::-1, 3]
def slabs(self, structure=None): """ Slab representation of monolayer, as an array Parameters ---------- structure : refnx.reflect.Structure The Structure hosting this Component """ layers = np.zeros((2, 5)) # thicknesses layers[0, 0] = float(self.thickness_heads) layers[1, 0] = float(self.thickness_tails) # real and imag SLD's head_sld_real, tail_sld_real = self.sld_( self.b_heads_real, #real self.b_tails_real, self.b_mscl_real) head_sld_imag, tail_sld_imag = self.sld_( self.b_heads_imag, #imaginary self.b_tails_imag, self.b_mscl_imag) layers[0, 1] = head_sld_real layers[0, 2] = head_sld_imag layers[1, 1] = tail_sld_real layers[1, 2] = tail_sld_imag # roughnesses layers[0, 3] = float(self.rough_preceding_mono) layers[1, 3] = float(self.rough_head_tail) # volume fractions # head region volfrac = self.vm_head() / (self.apm.value * self.thickness_heads.value) layers[0, 4] = 1 - volfrac if self.head_solvent is not None: # we do the solvation here, not in Structure.slabs layers[0] = Structure.overall_sld(layers[0], self.head_solvent) layers[0, 4] = 0 # tail region volfrac = self.vm_tail() / (self.apm.value * self.thickness_tails.value) layers[1, 4] = 1 - volfrac if self.tail_solvent is not None: # we do the solvation here, not in Structure.slabs layers[1] = Structure.overall_sld(layers[1], self.tail_solvent) layers[1, 4] = 0 if self.reverse_monolayer: layers = np.flipud(layers) layers[:, 3] = layers[::-1, 3] return layers
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 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_left_right_influence(self): # make sure that if the left and right components change, so does the # spline a = Spline(100, [2], [0.5], zgrad=False, microslab_max_thickness=1) s = self.left | a | self.right | self.solvent # change the SLD of the left component, spline should respond self.left.sld.real.value = 2.0 assert_almost_equal(a(0, s), 2) # check that the spline responds if it's a vfsolv that changes self.left.vfsolv.value = 0.5 assert_almost_equal( Structure.overall_sld(self.left.slabs(), self.solvent)[0, 1], 6.0) assert_almost_equal(a(0, s), 6.0) # check that the right side responds. self.right.sld.real.value = 5.0 assert_almost_equal(a(100, s), 5.0) # the spline should respond if the knot SLD's are changed a.vs[0].value = 3.0 assert_almost_equal(a(50, s), 3.0) # spline responds if the interval knot spacing is changed a.dz[0].value = 0.9 assert_almost_equal(a(90, s), 3.0)
def slabs(self, structure=None): """ Slab representation of monolayer, as an array Parameters ---------- structure : refnx.reflect.Structure The Structure hosting this Component """ layers = super(LipidLeafletWithProtien, self).slabs(structure=structure) if self.reverse_monolayer: layers = np.flipud(layers) layers[:, 3] = layers[::-1, 3] # volume fractions # head region # volfrac = self.vm_heads.value / (self.apm.value * # self.thickness_heads.value) layers[0, 4] = (1 - self.PLRatio.value ) * self.thickness_heads.value / self.total_thickness() if self.protein_head_SLD() is not None: # we do the solvation here, not in Structure.slabs layers[0] = Structure.overall_sld(layers[0], self.protein_head_SLD()) layers[0, 4] = 0 # tail region # volfrac = self.vm_tails.value / (self.apm.value * # self.thickness_tails.value) layers[1, 4] = (1 - self.PLRatio.value ) * self.thickness_heads.value / self.total_thickness() if self.protein_tail_SLD() is not None: # we do the solvation here, not in Structure.slabs layers[1] = Structure.overall_sld(layers[1], self.protein_tail_SLD()) layers[1, 4] = 0 if self.reverse_monolayer: layers = np.flipud(layers) layers[:, 3] = layers[::-1, 3] return layers
def slabs(self): """ Slab representation of monolayer, as an array """ layers = np.zeros((2, 5)) # thicknesses layers[0, 0] = float(self.thickness_heads) layers[1, 0] = float(self.thickness_tails) # real and imag SLD's layers[0, 1] = float(self.b_heads_real) / float(self.vm_heads) * 1.e6 layers[0, 2] = float(self.b_heads_imag) / float(self.vm_heads) * 1.e6 layers[1, 1] = float(self.b_tails_real) / float(self.vm_tails) * 1.e6 layers[1, 2] = float(self.b_tails_imag) / float(self.vm_tails) * 1.e6 # roughnesses layers[0, 3] = float(self.rough_preceding_mono) layers[1, 3] = float(self.rough_head_tail) # volume fractions # head region volfrac = self.vm_heads.value / (self.apm.value * self.thickness_heads.value) layers[0, 4] = 1 - volfrac if self.head_solvent is not None: # we do the solvation here, not in Structure.slabs layers[0] = Structure.overall_sld(layers[0], self.head_solvent) layers[0, 4] = 0 # tail region volfrac = self.vm_tails.value / (self.apm.value * self.thickness_tails.value) layers[1, 4] = 1 - volfrac if self.tail_solvent is not None: # we do the solvation here, not in Structure.slabs layers[1] = Structure.overall_sld(layers[1], self.tail_solvent) layers[1, 4] = 0 if self.reverse_monolayer: layers = np.flipud(layers) layers[:, 3] = layers[::-1, 3] return layers
def _interpolator(self): dz = np.array(self.dz) zeds = np.cumsum(dz) # if dz's sum to more than 1, then normalise to unit interval. if zeds[-1] > 1: zeds /= zeds[-1] zeds = np.clip(zeds, 0, 1) vs = np.array(self.vs) left_sld = Structure.overall_sld( np.atleast_2d(self.left_slab.slabs[-1]), self.solvent)[..., 1] right_sld = Structure.overall_sld( np.atleast_2d(self.right_slab.slabs[0]), self.solvent)[..., 1] if self.zgrad: zeds = np.concatenate([[-1.1, 0 - EPS], zeds, [1 + EPS, 2.1]]) vs = np.concatenate([left_sld, left_sld, vs, right_sld, right_sld]) else: zeds = np.concatenate([[0 - EPS], zeds, [1 + EPS]]) vs = np.concatenate([left_sld, vs, right_sld]) # cache the interpolator cache_zeds = self.__cached_interpolator['zeds'] cache_vs = self.__cached_interpolator['vs'] cache_extent = self.__cached_interpolator['extent'] # you don't need to recreate the interpolator if (np.array_equal(zeds, cache_zeds) and np.array_equal(vs, cache_vs) and np.equal(self.extent, cache_extent)): return self.__cached_interpolator['interp'] else: self.__cached_interpolator['zeds'] = zeds self.__cached_interpolator['vs'] = vs self.__cached_interpolator['extent'] = float(self.extent) # TODO make vfp zero for z > self.extent interpolator = self.interpolator(zeds, vs) self.__cached_interpolator['interp'] = interpolator return interpolator
def roughness(): sld1 = SLD(0, 0) sld2 = SLD(6.335, 0) sld3 = SLD(2.074, 0) layer1 = sld1(0, 0) layer3 = sld3(10, 0) fig = plt.figure(figsize=(10, 7.5 / 2)) gs = gridspec.GridSpec(1, 3) ax1 = plt.subplot(gs[0:2]) ax2 = plt.subplot(gs[2]) for i in range(3, 9, 2): layer2 = sld2(10, i) structure = Structure(layer1 | layer2 | layer3) ax1.plot(*structure.sld_profile()) ax2.plot(*structure.sld_profile()) ax2.set_ylim(1.6, 2.6) ax2.set_xlim(5, 15) ax1.axhline(sld3.real, color='k', alpha=0.3) ax2.axhline(sld3.real, color='k', alpha=0.3) ax1.set_xlabel(r'$z$/Å') ax1.set_ylabel(r'$\rho(z)$/Å$^{-2}$') ax1.text(0.025, 0.95, '(a)', horizontalalignment='left', verticalalignment='top', transform=ax1.transAxes) ax2.set_xlabel(r'$z$/Å') ax2.set_ylabel(r'$\rho(z)$/Å$^{-2}$') ax2.text(0.025, 0.95, '(b)', horizontalalignment='left', verticalalignment='top', transform=ax2.transAxes) plt.tight_layout() plt.savefig("roughness.pdf") plt.close()
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_stack(self): stk = Stack() slabs = stk.slabs(None) assert (slabs is None) si = SLD(2.07) sio2 = SLD(3.47) polymer = SLD(1.0) d2o = SLD(6.36) # check some initial stack properties stk.append(sio2(55, 4)) slabs = stk.slabs(None) assert (slabs.shape == (1, 5)) assert_equal(np.sum(slabs[:, 0]), 55) assert_equal(slabs[0, 1], 3.47) stk.repeats.value = 3.2 slabs = stk.slabs(None) assert (slabs.shape == (3, 5)) assert_equal(np.sum(slabs[:, 0]), 165) # ior a Stack and a Component stk |= polymer(110, 3.5) assert_equal(len(stk), 2) assert (isinstance(stk, Stack)) assert_almost_equal(stk.repeats, 3.2) slabs = stk.slabs() assert (slabs.shape == (6, 5)) assert_equal(np.sum(slabs[:, 0]), 495) # place a stack into a structure s = si | d2o(10, 3) | stk | d2o assert (isinstance(s, Structure)) slabs = s.slabs() assert_equal(slabs[:, 0], [0, 10, 55, 110, 55, 110, 55, 110, 0]) assert_equal(slabs[:, 1], [2.07, 6.36, 3.47, 1.0, 3.47, 1.0, 3.47, 1.0, 6.36]) assert_equal(slabs[:, 3], [0, 3, 4, 3.5, 4, 3.5, 4, 3.5, 0]) # what are the interfaces of the Stack assert_equal(len(stk.interfaces), len(stk.slabs())) assert_equal(len(list(flatten(s.interfaces))), len(s.slabs())) # ior a Structure and a Stack s = Structure(components=[si(), d2o(10, 3)]) s |= stk s |= d2o assert (isinstance(s, Structure)) assert_equal(s.slabs()[:, 0], [0, 10, 55, 110, 55, 110, 55, 110, 0]) assert_equal(s.slabs()[:, 1], [2.07, 6.36, 3.47, 1.0, 3.47, 1.0, 3.47, 1.0, 6.36]) q = repr(s) r = eval(q) assert_equal(r.slabs()[:, 0], [0, 10, 55, 110, 55, 110, 55, 110, 0]) assert_equal(r.slabs()[:, 1], [2.07, 6.36, 3.47, 1.0, 3.47, 1.0, 3.47, 1.0, 6.36]) s |= stk assert (isinstance(s.components[-1], Stack)) import pytest with pytest.raises(ValueError): s.slabs()
def slabs(self, structure=None): """ Slab representation of monolayer, as an array Parameters ---------- structure : refnx.reflect.Structure The Structure hosting this Component """ layers = np.zeros((2, 5)) # thicknesses layers[0, 0] = float(self.thickness_heads) layers[1, 0] = float(self.thickness_tails) # real and imag SLD's head_sld_r, tail_sld_r = self.sld_r() head_sld_i, tail_sld_i = self.sld_i() layers[0, 1] = head_sld_r layers[0, 2] = head_sld_i layers[1, 1] = tail_sld_r layers[1, 2] = tail_sld_i # roughnesses layers[0, 3] = float(self.rough_preceding_mono) layers[1, 3] = float(self.rough_head_tail) # volume fractions # head region apm = self.total_vm()/self.total_thickness() self.apm.value = apm volfrac = self.vm_head() / (self.apm.value * self.thickness_heads.value) layers[0, 4] = 1 - volfrac # print("volfrac h", volfrac) # print(layers[0]) if self.head_solvent is not None: # we do the solvation here, not in Structure.slabs layers[0] = Structure.overall_sld(layers[0], self.head_solvent_true()) layers[0, 4] = 0 # print(layers[0]) # tail region volfrac = self.vm_tail() / (self.apm.value * self.thickness_tails.value) layers[1, 4] = 1 - volfrac # print("volfrac t", volfrac) if self.tail_solvent is not None: # we do the solvation here, not in Structure.slabs layers[1] = Structure.overall_sld(layers[1], self.tail_solvent_true()) layers[1, 4] = 0 if self.reverse_monolayer: layers = np.flipud(layers) layers[:, 3] = layers[::-1, 3] # print("layers",layers) return layers
from refnx.reflect import Structure, SLD sld1 = SLD(0, 0) sld2 = SLD(6.335, 0) sld3 = SLD(2.074, 0) layer1 = sld1(0, 0) layer3 = sld3(10, 0) fig = plt.figure(figsize=(10, 7.5 / 2)) gs = gridspec.GridSpec(1, 3) ax1 = plt.subplot(gs[0:2]) ax2 = plt.subplot(gs[2]) for i in range(3, 9, 2): layer2 = sld2(10, i) structure = Structure(layer1 | layer2 | layer3) ax1.plot(*structure.sld_profile()) ax2.plot(*structure.sld_profile()) ax2.set_ylim(1.6, 2.6) ax2.set_xlim(5, 15) ax1.axhline(sld3.real, color='k', alpha=0.3) ax2.axhline(sld3.real, color='k', alpha=0.3) ax1.set_xlabel(r'$z$/Å') ax1.set_ylabel(r'$\rho(z)$/Å$^{-2}$') ax1.text(0.025, 0.95, '(a)', horizontalalignment='left', verticalalignment='top', transform=ax1.transAxes)
def _interpolator(self, structure): dz = np.array(self.dz) zeds = np.cumsum(dz) # if dz's sum to more than 1, then normalise to unit interval. if len(zeds) and zeds[-1] > 1: # there may be no knots zeds /= zeds[-1] zeds = np.clip(zeds, 0, 1) # note - this means you shouldn't use the same Spline more than once in # a Component, because only the first use will be detected. try: loc = structure.index(self) # figure out SLDs for the bracketing Components. # note the use of the modulus operator. This means that if the # Spline is at the end, then the right most Component will be # assumed to be the first Component. This is to aid the use of # Spline in a Stack. left_component = structure[loc - 1] right_component = structure[(loc + 1) % len(structure)] except ValueError: raise ValueError("Spline didn't appear to be part of a super" " Structure") if (isinstance(left_component, Spline) or isinstance(right_component, Spline)): raise ValueError("Spline must be bracketed by Components that" " aren't Splines.") vs = np.array(self.vs) left_sld = Structure.overall_sld( np.atleast_2d(left_component.slabs(structure)[-1]), structure.solvent)[..., 1] right_sld = Structure.overall_sld( np.atleast_2d(right_component.slabs(structure)[0]), structure.solvent)[..., 1] if self.zgrad: zeds = np.concatenate([[-1.1, 0 - EPS], zeds, [1 + EPS, 2.1]]) vs = np.concatenate([left_sld, left_sld, vs, right_sld, right_sld]) else: zeds = np.concatenate([[0 - EPS], zeds, [1 + EPS]]) vs = np.concatenate([left_sld, vs, right_sld]) # cache the interpolator cache_zeds = self.__cached_interpolator['zeds'] cache_vs = self.__cached_interpolator['vs'] cache_extent = self.__cached_interpolator['extent'] # you don't need to recreate the interpolator if (np.array_equal(zeds, cache_zeds) and np.array_equal(vs, cache_vs) and np.equal(self.extent, cache_extent)): return self.__cached_interpolator['interp'] else: self.__cached_interpolator['zeds'] = zeds self.__cached_interpolator['vs'] = vs self.__cached_interpolator['extent'] = float(self.extent) # TODO make vfp zero for z > self.extent interpolator = self.interpolator(zeds, vs) self.__cached_interpolator['interp'] = interpolator return interpolator
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=(10, 7.5)) gs = gridspec.GridSpec(2, 1) ax1 = plt.subplot(gs[0, 0]) ax2 = plt.subplot(gs[1, 0]) colors = [_fig_params.colors[0], _fig_params.colors[1]] ls = ['-', ':'] for i in [0, 1]: 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, color=colors[i], ls=ls[i]) ax2.semilogy(qvals, ReflectModel(structure, dq=0.0).model(qvals), color=colors[i], ls=ls[i]) else: ax1.stem(z_, drho, linefmt='C{}'.format(i) + ls[i], basefmt='C{}'.format(i) + ls[i], markerfmt=' ', use_line_collection=True) ax2.stem(z_acf, acf, linefmt='C{}'.format(i) + ls[i], basefmt='C{}'.format(i) + ls[i], markerfmt=' ', 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)$') ax1.text(0.025, 0.95, '(a)', horizontalalignment='left', verticalalignment='top', transform=ax1.transAxes) 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}$") ax1.text(0.975, 0.95, '(a)', horizontalalignment='right', verticalalignment='top', transform=ax1.transAxes) ax2.text(0.975, 0.95, '(b)', horizontalalignment='right', verticalalignment='top', transform=ax2.transAxes) plt.tight_layout() figfilename = f"phase_problem_{flag}.pdf" plt.savefig(figfilename) print(f"Figure saved as {figfilename}") plt.close()