1
2 """
3 Optical matrix form of the reflectivity calculation.
4
5 O.S. Heavens, Optical Properties of Thin Solid Films
6 """
7 from numpy import *
8
9 -def refl(Qz,depth,rho,mu=0,wavelength=1,sigma=0):
10 """
11 Reflectometry as a function of Qz,wavelength.
12
13 Qz (inv angstrom)
14 Scattering vector 4*pi*sin(theta)/wavelength. This is an array.
15 wavelenth (angstrom)
16 Incident wavelength. If present this is a
17 rho,mu (uNb)
18 scattering length density and absorption of each layer
19 depth (angstrom)
20 thickness of each layer. The thickness of the incident medium
21 and substrate are ignored.
22 sigma (angstrom)
23 interfacial roughness. This is the roughness between a layer
24 and the subsequent layer. There is no interface associated
25 with the substrate. The sigma array should have at least n-1
26 entries, though it may have n with the last entry ignored.
27 method (parratt | abeles | opticalmatrix)
28 method used to compute the reflectivity
29 """
30 if isscalar(Qz): Qz = array([Qz], 'd')
31 n = len(rho)
32 nQ = len(Qz)
33
34
35 kz = array(Qz,'d')/2
36 depth = array(depth,'d')
37 rho = array(rho,'d')
38 mu = mu*ones(n,'d') if isscalar(mu) else array(mu,'d')
39 wavelength = wavelength*ones(nQ,'d') \
40 if isscalar(wavelength) else array(wavelength,'d')
41 sigma = sigma*ones(n-1,'d') if isscalar(sigma) else array(sigma,'d')
42
43
44 rho *= 1e-6
45 mu *= 1e-6
46
47
48
49
50
51
52 idx = (kz>=0)
53 r = empty(len(kz),'D')
54 r[idx] = calc(kz[idx], wavelength[idx], depth, rho, mu, sigma)
55 r[~idx] = calc(abs(kz[~idx]), wavelength[~idx],
56 depth[-1::-1], rho[-1::-1], mu[-1::-1],
57 sigma[n-2::-1])
58 return r
59
60
61 -def calc(kz,wavelength,depth,rho,mu,sigma):
62 """Parratt recursion"""
63 if len(kz) == 0: return kz
64
65
66
67
68 kz_sq = kz**2 + 4*pi*rho[0]
69 k = kz
70
71
72
73
74 B11 = 1
75 B22 = 1
76 B21 = 0
77 B12 = 0
78 print "kz",kz[-1]
79 for i in xrange(0,len(rho)-1):
80 k_next = sqrt(kz_sq - (4*pi*rho[i+1] + 2j*pi*mu[i+1]/wavelength))
81 F = (k - k_next) / (k + k_next)
82 F *= exp(-2*k*k_next*sigma[i]**2)
83 M11 = exp(1j*k*depth[i]) if i>0 else 1
84 print i, kz_sq[-1], rho[i], mu[i], rho[i+1], mu[i+1], wavelength
85 print i, " k",k[-1], " k_next",k_next[-1]
86 if i==0: print i, " F",F[-1], " M",1
87 if i>0:
88 print i, " F",F[-1], " M",M11[-1]
89 M22 = exp(-1j*k*depth[i]) if i>0 else 1
90 M21 = F*M11
91 M12 = F*M22
92 C1 = B11*M11 + B21*M12
93 C2 = B11*M21 + B21*M22
94 B11 = C1
95 B21 = C2
96 C1 = B12*M11 + B22*M12
97 C2 = B12*M21 + B22*M22
98 B12 = C1
99 B22 = C2
100 k = k_next
101
102 r = B12/B11
103 return r
104