-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpyABCDobj.py
More file actions
145 lines (124 loc) · 5.24 KB
/
pyABCDobj.py
File metadata and controls
145 lines (124 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
CONST_PI=3.14159265359
class GaussianBeam(object):
initsuccess = False
def __init__(self, wavelength, mode, arg):
self.wavelength = wavelength
if mode.lower() == "q":
self.q = arg
self.r = abs(self.q)**2 / self.q.real
self.w = abs(self.wavelength / CONST_PI * abs(self.q)**2 / self.q.imag)**0.5
self.divergence = ( self.wavelength/CONST_PI / abs( self.q.imag )) ** 0.5
self.initsuccess = True
elif mode.lower() =="rw":
self.r = arg[0]
self.w = arg[1]
self.q = 1.0 / ( 1.0/self.r + 1.0j * self.wavelength / (CONST_PI * self.w**2))
self.divergence = ( self.wavelength/CONST_PI / abs( self.q.imag )) ** 0.5
self.initsuccess = True
else:
print "Please use GaussianBeam('q', wavelength, qVal) or GaussianBeam('rw',wavelength, [R,w])"
def print_params(self):
if self.initsuccess:
print "q = %.8f + %.8fj"%(self.q.real,self.q.imag)
print "w = %.5f mm"%(self.w / 1e-3)
print "R = %.5f m "%self.r
print "div = %.5f mrad (divergence far field)"%(self.divergence/1e-3)
else:
print "Error: GaussianBeam not properly initialzed. Can not print beam"
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
class LensSystem( object ):
verbose = False
def __init__(self, wavelength):
self.wavelength=wavelength
if self.verbose:
print "empty LensSystem created at wavelength of %.2f nm."%(wavelength / 1e-9)
self.Lelements = []
def add_beam(self, mode, params):
self.beamZ0 = GaussianBeam( self.wavelength, mode, params)
def add_element(self, Mtype, z, params):
if Mtype.lower()=="lens":
newEle = {"z": z, "matrix": self.__matrix_lens(params[0]),'type':'lens'}
if self.verbose :
print "... appended a lens (f=%.5f m) at z=%.5f m to the system"%(params[0],z)
self.Lelements.append(newEle)
elif Mtype.lower()=="curvedmirror":
newEle= {"z":z,"matrix": self.__matrix_curved_mirror(params[0]),'type':'curved mirror'}
if self.verbose :
print "... appended a curved mirror (R=%.5f m) at z=%.5f m to the system"%(params[0],z)
self.Lelements.append(newEle)
else:
print "unknown element :("
def calc_beam( self, zend,points):
dz = zend / 1.0 / points
qlist = []
zl = []
for i in range(points):
z = i * dz
M = self.calc_propmatrix_until_z(z)
qs = (self.beamZ0.q * M[0] + M[1]) / (self.beamZ0.q * M[2] + M[3])
qlist.append( GaussianBeam( self.wavelength, 'q', qs))
if self.verbose:
qlist[i].print_params()
zl.append(z)
ws = [x.w for x in qlist]
rs = [x.r for x in qlist]
ds = [x.divergence for x in qlist]
# z = [x*dz for x in range(points)]
return ws,rs,ds,zl,[x.q for x in qlist]
def clone(self):
LSclone = LensSystem(self.wavelength)
LSclone.Lelements = self.Lelements
return LSclone
def __matrix_lens(self,f):
return [1,0,-1.0/f,1]
def __matrix_free_space(self, L,n):
return [1,n*L,0,1]
def __matrix_curved_mirror(self, R):
return [1.0,0.0, -2.0/R,1.0]
def __matrix_multiplication(self, A, B):
result = [0,0,0,0]
result[0] = A[0]*B[0] + A[1]*B[2]
result[1] = A[0]*B[1] + A[1]*B[3]
result[2] = A[2]*B[0] + A[3]*B[2]
result[3] = A[2]*B[1] + A[3]*B[3]
return result
def __get_list_order(self):
zind = sorted(enumerate([ele['z'] for ele in self.Lelements]),key=lambda x:x[1])
return zind
def print_positions(self):
zind = self.__get_list_order()
for i in range(len(zind)):
print "At z = %.3f is the element with number %d"%(zind[i][1],zind[i][0])
def calc_propmatrix_until_z(self,z_end):
#get elements before z_end
zind = self.__get_list_order()
#find elements that are before z:
ElementList = [ x for x in zind if x[1]<z_end]
M = []
aktz = 0
if self.verbose:
print "Z_end = ",z_end
print "number of elements before: ",len(ElementList)
for i in range(len(ElementList)):
zwert = ElementList[i][1]
index = ElementList[i][0]
zdiff = zwert-aktz
aktz = zwert
if self.verbose:
print "air: %.4f m, then element number %d"%(zdiff,index)
M.append(self.__matrix_free_space(zdiff,1.0))
M.append(self.Lelements[index]['matrix'])
zdiff = z_end - aktz
if self.verbose:
print "after last element: %.4f m of air"%(zdiff)
M.append(self.__matrix_free_space(zdiff,1.0))
Mtot = [1,0,0,1]
if self.verbose:
print "Matrices including free space in reverse order:"
for i in range(len(M)-1,-1,-1):
Mtot = self.__matrix_multiplication(Mtot,M[i])
if self.verbose:
print M[i]
if self.verbose:
print "Total propagation matrix : ",Mtot
return Mtot