Package reflectometry :: Package reduction :: Module fresnel

Source Code for Module reflectometry.reduction.fresnel

 1  # This code is public domain 
 2   
 3  """ 
 4  Pure python Fresnel reflectivity calculator. 
 5  """ 
 6   
 7  from numpy import sqrt, exp, real, conj, pi, log, abs, choose 
 8   
9 -class Fresnel:
10 """ 11 Function for computing the Fresnel reflectivity for a single interface. 12 13 rho,Vrho 14 scattering length density of substrate and vacuum 15 mu,Vmu 16 absorption of substrate and vacuum (note that we do not correct 17 for attenuation of the beam through the incident medium since we 18 do not know the path length). 19 sigma (angstrom) 20 interfacial roughness 21 """
22 - def __init__(self, rho=1e-6, mu=0, sigma=0, Vrho=0, Vmu=0):
23 self.rho,self.Vrho,self.mu,self.Vmu,self.sigma = rho,Vrho,mu,Vmu,sigma
24
25 - def reflectivity(self, Q, L=1):
26 """ 27 Compute the Fresnel reflectivity at the given Q/wavelength. 28 """ 29 # If Q < 0, then we are going from substrate into incident medium. 30 # In that case we must negate the change in scattering length density 31 # and ignore the absorption. 32 drho = self.rho-self.Vrho 33 S = 4*pi*choose(Q<0,(-drho,drho)) \ 34 + 2j*pi/L*choose(Q<0,(self.Vmu,self.mu)) 35 kz = abs(Q)/2 36 f = sqrt(kz**2 - S) # fresnel coefficient 37 38 # Compute reflectivity amplitude, with adjustment for roughness 39 amp = (kz-f)/(kz+f) * exp(-2*self.sigma**2*kz*f) 40 # Note: we do not need to check for a divide by zero. 41 # Qc^2 = 16 pi rho. Since rho is non-zero then Qc is non-zero. 42 # For mu = 0: 43 # * If |Qz| < Qc then f has an imaginary component, so |Qz|+f != 0. 44 # * If |Qz| > Qc then |Qz| > 0 and f > 0, so |Qz|+f != 0. 45 # * If |Qz| = Qc then |Qz| != 0 and f = 0, so |Qz|+f != 0. 46 # For mu != 0: 47 # * f has an imaginary component, so |Q|+f != 0. 48 49 R = real(amp*conj(amp)) 50 return R
51 52 # Make the reflectivity method the default 53 __call__ = reflectivity
54
55 -def test():
56 return #TODO: Skip this test until reflectivity.model1d is fixed 57 58 # Rough silicon with an anomolously large absorbtion 59 f = Fresnel(rho=2.07e-6, mu=1e-6, sigma=20) 60 61 import numpy 62 import reflectometry.model1d as reflfit 63 m = reflfit.Model() 64 m.incident('Air',rho=0,mu=0) 65 m.interface(sigma=f.sigma) 66 m.substrate('Si',rho=f.rho*1e6,mu=f.mu*1e6) 67 68 L = 4.75 # Angstrom 69 Q = numpy.linspace(0,0.1,11,'d') 70 Rf = f(Q,L) 71 Rm = m.reflectivity(Q,L,dz=0.01) 72 #print numpy.vstack((Q,Rf,Rm)).T 73 74 # This is failing because reflectometry.model1d is failing; why that 75 # is so has not yet been determined. 76 relerr = numpy.linalg.norm((Rf-Rm)/Rm) 77 assert relerr < 1e-10, "relative error is %g"%relerr
78 79 if __name__ == "__main__": test() 80