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: %s {" %self.Ref ) 108 ans.append("Power: %sW/Index: %s/Wavelength: %snm/Length: %sm" \ 109 %(str(self.P), str(self.N), str(self.Wl/nm), str(self.Length))) 110 ans.append("Order: %s" %str(self.StrayOrder)) 111 ans.append("Origin: %s" %str(self.Pos)) 112 113 sph = geometry.rectToSph(self.Dir) 114 ans.append("Direction: (%s, %s)deg" %(str(sph[0]/deg), str(sph[1]/deg))) 115 116 sphx = geometry.rectToSph(self.U[0]) 117 ans.append("Ux: (%s, %s)deg" %(str(sphx[0]/deg), str(sphx[1]/deg) )) 118 119 sphy = geometry.rectToSph(self.U[1]) 120 ans.append("Uy: (%s, %s)deg" %(str(sphy[0]/deg), str(sphy[1]/deg))) 121 ans.append("Waist Pos: %sm" % str(self.waistPos()) ) 122 ans.append("Waist Size: (%s, %s)mm" \ 123 %(str(self.waistSize()[0]/mm), str(self.waistSize()[1]/mm))) 124 ans.append("Rayleigh: %sm" % str(self.rayleigh()) ) 125 ans.append("ROC: " + str(self.ROC())) 126 ans.append("}") 127 128 return ans
129
130 - def Q(self, d = 0.):
131 '''Return the Q tensor at a distance d of origin. 132 133 ''' 134 d = float(d) 135 I = np.array([[1., 0.], [0., 1.]], dtype=np.float64) 136 return np.dot(np.linalg.inv(I + d * self.QTens), self.QTens)
137
138 - def QParam(self, d = 0.):
139 '''Compute the complex parameters q1 and q2 and theta of beam. 140 141 Returns a dictionary with keys: 142 '1': q1 [complex] 143 '2': q2 [complex] 144 'theta': theta [float] 145 ''' 146 d = float(d) 147 148 a = self.Q(d)[0][0] 149 b = self.Q(d)[0][1] 150 d = self.Q(d)[1][1] 151 152 q1inv = .5*(a + d + np.sqrt((a - d)**2. + 4.*b**2.)) 153 q2inv = .5*(a + d - np.sqrt((a - d)**2. + 4.*b**2.)) 154 155 if q1inv == q2inv: 156 theta = 0. 157 else: 158 theta = .5*np.arcsin(2.*b/(q1inv - q2inv)) 159 160 try: 161 a = 1/q1inv 162 except ZeroDivisionError: 163 a = np.inf 164 try: 165 b = 1/q2inv 166 except ZeroDivisionError: 167 b = np.inf 168 return {'1': a, '2': b, 'theta':theta}
169
170 - def ROC(self, dist = 0.):
171 '''Return the tuple of ROC of the beam. 172 173 ''' 174 dist = float(dist) 175 Q = self.QParam(dist) 176 try: 177 a = 1./np.real(1./Q['1']) 178 except FloatingPointError: 179 a = np.inf 180 try: 181 b = 1./np.real(1./Q['2']) 182 except FloatingPointError: 183 b = np.inf 184 185 return (a, b)
186
187 - def waistPos(self):
188 '''Return the tuple of positions of the waists of the beam along Dir. 189 190 ''' 191 Q = self.QParam(0.) 192 return (-np.real(Q['1']), -np.real(Q['2']))
193
194 - def rayleigh(self):
195 '''Return the tuple of Rayleigh ranges of the beam. 196 197 ''' 198 Q = self.QParam() 199 return (np.abs(np.imag(Q['1'])), np.abs(np.imag(Q['2'])))
200
201 - def width(self, d = 0.):
202 '''Return the tuple of beam widths. 203 204 ''' 205 d = float(d) 206 lam = self.Wl/self.N 207 zR = self.rayleigh() 208 D = self.waistPos() 209 210 return (np.sqrt((lam/pi)*((d - D[0])**2. + zR[0]**2.)/zR[0]) , 211 np.sqrt((lam/pi)*((d - D[1])**2. + zR[1]**2.)/zR[1]))
212
213 - def waistSize(self):
214 '''Return a tuple with the waist sizes in x and y. 215 216 ''' 217 pos = self.waistPos() 218 return (self.width(pos[0])[0], self.width(pos[1])[1] )
219
220 - def gouy(self, d = 0.):
221 '''Return the tuple of Gouy phases. 222 223 ''' 224 d = float(d) 225 zR = self.rayleigh() 226 WDist = self.waistPos() 227 return (np.arctan((d-WDist[0])/zR[0]), 228 np.arctan((d-WDist[1])/zR[1]))
229
230 - def translate(self, X = 0., Y = 0., Z = 0.):
231 '''Move the beam to (current position + (X, Y, Z)). 232 233 X, Y, Z: components of the translation vector. 234 235 No return value. 236 ''' 237 self.Pos = self.Pos + np.array([X, Y, Z], dtype = np.float64)
238
239 -def userGaussianBeam(Wx = 1.e-3, Wy = 1.e-3, WDistx = 0., WDisty = 0., 240 Wl = 1064.e-9, P = 1., X = 0., Y = 0., Z = 0., 241 Theta = pi/2., Phi = 0., Alpha = 0., 242 Ref = None):
243 '''Constructor used for user inputed beams, separated from the class 244 initializer because the internal state of a beam is very different from 245 the input of this user-defined beam. 246 247 Input parameters are processed to make arguments for the class 248 contructor and then the corresponding beam is returned. 249 ''' 250 251 #externs 252 P = float(P) 253 Pos = np.array([X, Y, Z], dtype = np.float64) 254 Dir = np.array([np.sin(Theta) * np.cos(Phi), 255 np.sin(Theta) * np.sin(Phi), 256 np.cos(Theta)], dtype = np.float64) 257 258 # basis for Q tensor 259 Alpha = float(Alpha) 260 (u1,v1) = geometry.basis(Dir) 261 v = np.cos(Alpha)*v1 - np.sin(Alpha)*u1 262 u = np.cos(Alpha)*u1 + np.sin(Alpha)*v1 263 264 # Q tensor for orthogonal beam 265 Wl = float(Wl) 266 Wx = float(Wx) 267 Wy = float(Wy) 268 qx = complex(- float(WDistx) + 1.j * pi*Wx**2./Wl ) 269 qy = complex(- float(WDisty) + 1.j * pi*Wy**2./Wl ) 270 QTens = np.array([[1./qx, 0.],[0., 1./qy]], 271 dtype = np.complex64) 272 273 if Ref is None: 274 Ref = "Beam" + str(GaussianBeam.BeamCount) 275 else: 276 Ref = Ref 277 278 return GaussianBeam(Q = QTens, N = 1., Wl = Wl, P = P, 279 Pos = Pos, Dir = Dir, 280 Ux = u, Uy = v, Ref = Ref, OptDist = 0., 281 Length = 0., StrayOrder = 0, Optic = 'Laser', Face = 'Out')
282