Package theia :: Package optics :: Module beam
[hide private]
[frames] | no frames]

Source Code for Module theia.optics.beam

  1  '''Defines the GaussianBeam class for theia.''' 
  2   
  3  # Provides: 
  4  #   class GaussianBeam 
  5  #       __init__ 
  6  #       __str__ 
  7  #       lines 
  8  #       Q 
  9  #       QParam 
 10  #       ROC 
 11  #       waistPos 
 12  #       rayleigh 
 13  #       width 
 14  #       waistSize 
 15  #       gouy 
 16  #       translate 
 17  #   userGaussianBeam 
 18   
 19  import numpy as np 
 20  from ..helpers import geometry 
 21  from ..helpers.tools import formatter 
 22  from ..helpers.units import pi, nm, deg, mm 
 23   
24 -class GaussianBeam(object):
25 ''' 26 27 GaussianBeam class. 28 29 This class represents general astigmatic Gaussian beams in 3D space. 30 These are the objects that are intended to interact with the optical 31 components during the ray tracing and that are rendered in 3D thanks to 32 FreeCAD. 33 34 *=== Attributes ===* 35 BeamCount: class attribute, counts beams. [integer] 36 Name: class attribute. [string] 37 QTens: general astigmatic complex curvature tensor at the origin. 38 [np. array of complex] 39 N: Refraction index of the medium in which the beam is placed. [float] 40 Wl: Wave-length in vacuum of the beam (frequency never changes). [float] 41 P: Power of the beam. [float] 42 Pos: Position in 3D space of the origin of the beam. [3D vector] 43 Dir: Normalized direction in 3D space of the beam axis. [3D vector] 44 U: A tuple of unitary vectors which along with Dir form a direct orthonormal 45 basis in which the Q tensor is expressed. [tuple of 3D vectors] 46 Ref: Reference to the beam. [string] 47 OptDist: Optical length. [float] 48 Length: Geometrical length of the beam. [float] 49 StrayOrder: Number representing the *strayness* of the beam. If the beams 50 results from a transmission on a HR surface or a reflection on a AR 51 surface, then its StrayOrder is the StrayOrder of the parent beam + 1. 52 [integer] 53 Optic: Ref of optic where the beam departs from (None if laser). [string] 54 Face: face of the optic where the beam departs from. [string] 55 56 ''' 57 BeamCount = 0 # counts beams 58 Name = "Beam" 59
60 - def __init__(self, Q, N, Wl, P, Pos, Dir, Ux, Uy, Ref, OptDist, 61 Length, StrayOrder, Optic, Face):
62 '''Beam initializer. 63 64 This is the initializer used internally for beam creation, for user 65 inputed beams, see class method userGaussianBeam. 66 67 Returns a Gaussian beam with attributes as the parameters. 68 69 ''' 70 71 # external params 72 self.N = N 73 self.Wl = Wl 74 self.P = P 75 self.OptDist = OptDist 76 self.Length = Length 77 self.StrayOrder = StrayOrder 78 79 self.Ref = Ref 80 81 self.Pos = Pos 82 self.Dir = Dir 83 84 # orthonormal basis in which Q is expressed 85 self.U = (Ux, Uy) 86 87 # Curvature tensor 88 self.QTens = np.array(Q, dtype = np.complex64) 89 90 #origin optics 91 self.Optic = Optic 92 self.Face = Face 93 94 self.__class__.BeamCount = self.__class__.BeamCount + 1
95
96 - def __str__(self):
97 '''String representation of the beam, when calling print(beam). 98 99 ''' 100 return formatter(self.lines())
101
102 - def lines(self):
103 '''Returns the list of lines necessary to print the object. 104 105 ''' 106 ans = [] 107 ans.append("Beam: " + self.Name + " (" + self.Ref + ") " + "{") 108 ans.append("Power: " + str(self.P) + "W/"\ 109 +"Index: " + str(self.N)\ 110 +"/Wavelength: "+str(self.Wl/nm)+"nm/Length: " + str(self.Length) + "m") 111 ans.append("Order: " + str(self.StrayOrder)) 112 ans.append("Origin: " + str(self.Pos)) 113 114 sph = geometry.rectToSph(self.Dir) 115 ans.append("Direction: (" + str(sph[0]/deg) + ', ' \ 116 + str(sph[1]/deg) + ')deg') 117 118 sphx = geometry.rectToSph(self.U[0]) 119 ans.append("Ux: (" + str(sphx[0]/deg) + ', ' \ 120 + str(sphx[1]/deg) + ')deg') 121 122 sphy = geometry.rectToSph(self.U[1]) 123 ans.append("Uy: (" + str(sphy[0]/deg) + ', ' \ 124 + str(sphy[1]/deg) + ')deg') 125 ans.append("Waist Pos: " + str(self.waistPos()) + 'm') 126 ans.append("Waist Size: (" \ 127 + str(self.waistSize()[0]/mm) + ', ' + str(self.waistSize()[1]/mm)\ 128 + ')mm') 129 ans.append("Rayleigh: " + str(self.rayleigh()) + "m") 130 ans.append("ROC: " + str(self.ROC())) 131 ans.append("}") 132 133 return ans
134
135 - def Q(self, d = 0.):
136 '''Return the Q tensor at a distance d of origin. 137 138 ''' 139 d = float(d) 140 I = np.array([[1., 0.], [0., 1.]], dtype=np.float64) 141 return np.matmul(np.linalg.inv(I + d * self.QTens),self.QTens)
142
143 - def QParam(self, d = 0.):
144 '''Compute the complex parameters q1 and q2 and theta of beam. 145 146 Returns a dictionary with keys: 147 '1': q1 [complex] 148 '2': q2 [complex] 149 'theta': theta [float] 150 ''' 151 d = float(d) 152 153 a = self.Q(d)[0][0] 154 b = self.Q(d)[0][1] 155 d = self.Q(d)[1][1] 156 157 q1inv = .5*(a + d + np.sqrt((a - d)**2. + 4.*b**2.)) 158 q2inv = .5*(a + d - np.sqrt((a - d)**2. + 4.*b**2.)) 159 160 if q1inv == q2inv: 161 theta = 0. 162 else: 163 theta = .5*np.arcsin(2.*b/(q1inv - q2inv)) 164 165 try: 166 a = 1/q1inv 167 except ZeroDivisionError: 168 a = np.inf 169 try: 170 b = 1/q2inv 171 except ZeroDivisionError: 172 b = np.inf 173 return {'1': a, '2': b, 'theta':theta}
174
175 - def ROC(self, dist = 0.):
176 '''Return the tuple of ROC of the beam. 177 178 ''' 179 dist = float(dist) 180 Q = self.QParam(dist) 181 try: 182 a = 1./np.real(1./Q['1']) 183 except FloatingPointError: 184 a = np.inf 185 try: 186 b = 1./np.real(1./Q['2']) 187 except FloatingPointError: 188 b = np.inf 189 190 return (a, b)
191
192 - def waistPos(self):
193 '''Return the tuple of positions of the waists of the beam along Dir. 194 195 ''' 196 Q = self.QParam(0.) 197 return (-np.real(Q['1']), -np.real(Q['2']))
198
199 - def rayleigh(self):
200 '''Return the tuple of Rayleigh ranges of the beam. 201 202 ''' 203 Q = self.QParam() 204 return (np.abs(np.imag(Q['1'])), np.abs(np.imag(Q['2'])))
205
206 - def width(self, d = 0.):
207 '''Return the tuple of beam widths. 208 209 ''' 210 d = float(d) 211 lam = self.Wl/self.N 212 zR = self.rayleigh() 213 D = self.waistPos() 214 215 return (np.sqrt((lam/pi)*((d - D[0])**2. + zR[0]**2.)/zR[0]) , 216 np.sqrt((lam/pi)*((d - D[1])**2. + zR[1]**2.)/zR[1]))
217
218 - def waistSize(self):
219 '''Return a tuple with the waist sizes in x and y. 220 221 ''' 222 pos = self.waistPos() 223 return (self.width(pos[0])[0], self.width(pos[1])[1] )
224
225 - def gouy(self, d = 0.):
226 '''Return the tuple of Gouy phases. 227 228 ''' 229 d = float(d) 230 zR = self.rayleigh() 231 WDist = self.waistPos() 232 return (np.arctan((d-WDist[0])/zR[0]), 233 np.arctan((d-WDist[1])/zR[1]))
234
235 - def translate(self, X = 0., Y = 0., Z = 0.):
236 '''Move the beam to (current position + (X, Y, Z)). 237 238 X, Y, Z: components of the translation vector. 239 240 No return value. 241 ''' 242 self.Pos = self.Pos + np.array([X, Y, Z], dtype = np.float64)
243
244 -def userGaussianBeam(Wx = 1.e-3, Wy = 1.e-3, WDistx = 0., WDisty = 0., 245 Wl = 1064.e-9, P = 1., X = 0., Y = 0., Z = 0., 246 Theta = pi/2., Phi = 0., Alpha = 0., 247 Ref = None):
248 '''Constructor used for user inputed beams, separated from the class 249 initializer because the internal state of a beam is very different from 250 the input of this user-defined beam. 251 252 Input parameters are processed to make arguments for the class 253 contructor and then the corresponding beam is returned. 254 ''' 255 256 #externs 257 P = float(P) 258 Pos = np.array([X, Y, Z], dtype = np.float64) 259 Dir = np.array([np.sin(Theta) * np.cos(Phi), 260 np.sin(Theta) * np.sin(Phi), 261 np.cos(Theta)], dtype = np.float64) 262 263 # basis for Q tensor 264 Alpha = float(Alpha) 265 (u1,v1) = geometry.basis(Dir) 266 v = np.cos(Alpha)*v1 - np.sin(Alpha)*u1 267 u = np.cos(Alpha)*u1 + np.sin(Alpha)*v1 268 269 # Q tensor for orthogonal beam 270 Wl = float(Wl) 271 Wx = float(Wx) 272 Wy = float(Wy) 273 qx = complex(- float(WDistx) + 1.j * pi*Wx**2./Wl ) 274 qy = complex(- float(WDisty) + 1.j * pi*Wy**2./Wl ) 275 QTens = np.array([[1./qx, 0.],[0., 1./qy]], 276 dtype = np.complex64) 277 278 if Ref is None: 279 Ref = "Beam" + str(GaussianBeam.BeamCount) 280 else: 281 Ref = Ref 282 283 return GaussianBeam(Q = QTens, N = 1., Wl = Wl, P = P, 284 Pos = Pos, Dir = Dir, 285 Ux = u, Uy = v, Ref = Ref, OptDist = 0., 286 Length = 0., StrayOrder = 0, Optic = 'Laser', Face = 'Out')
287