1 '''Defines the Optic class for theia.'''
2
3
4
5
6
7
8
9
10
11
12 import numpy as np
13 from ..helpers import settings
14 from .component import SetupComponent
15
16 -class Optic(SetupComponent):
17 '''
18
19 Optic class.
20
21 This class is a base class for optics which may interact with Gaussian
22 beams and return transmitted and reflected beams (mirrors, lenses, etc.)
23
24
25 *=== Attributes ===*
26 SetupCount (inherited): class attribute, counts all setup components.
27 [integer]
28 OptCount: class attribute, counts optical components. [integer]
29 Name: class attribute. [string]
30 HRCenter (inherited): center of the 'chord' of the HR surface. [3D vector]
31 HRNorm (inherited): unitary normal to the 'chord' of the HR (always pointing
32 towards the outside of the component). [3D vector]
33 Thick (inherited): thickness of the optic, counted in opposite direction to
34 HRNorm. [float]
35 Dia (inherited): diameter of the component. [float]
36 Ref (inherited): reference string (for keeping track with the lab). [string]
37 ARCenter: center of the 'chord' of the AR surface. [3D vector]
38 ARNorm: unitary normal to the 'chord' of the AR (always pointing
39 towards the outside of the component). [3D vector]
40 N: refraction index of the material. [float]
41 HRK, ARK: curvature of the HR, AR surfaces. [float]
42 HRr, HRt, ARr, ARt: power reflectance and transmission coefficients of
43 the HR and AR surfaces. [float]
44 KeepI: whether of not to keep data of rays for interference calculations
45 on the HR. [boolean]
46
47 **Note**: the curvature of any surface is positive for a concave surface
48 (coating inside the sphere).
49 Thus kurv*HRNorm/|kurv| always points to the center
50 of the sphere of the surface, as is the convention for the lineSurfInter of
51 geometry module. Same for AR.
52
53 ******* HRK > 0 and ARK > 0 ******* HRK > 0 and ARK < 0
54 ***** ******** and |ARK| > |HRK|
55 H***A H*********A
56 ***** ********
57 ******* *******
58
59 '''
60
61 OptCount = 0
62 Name = "Optic"
63
64 - def __init__(self, ARCenter, ARNorm, N, HRK, ARK, ARr, ARt, HRr,
65 HRt, KeepI, HRCenter, HRNorm, Thickness, Diameter, Ref):
66 '''Optic base initializer.
67
68 Parameters are the attributes of the object to construct.
69
70 Returns an Optic.
71
72 '''
73
74 if Ref is None:
75 Ref = "Opt" + str(Optic.OptCount)
76
77
78 self.ARCenter = ARCenter
79 self.ARNorm = ARNorm
80 self.N = N
81 self.HRK = HRK
82 self.ARK = ARK
83 self.HRr = HRr
84 self.HRt = HRt
85 self.ARr = ARr
86 self.ARt = ARt
87 self.KeepI = KeepI
88
89
90 super(Optic, self).__init__(HRCenter = HRCenter, HRNorm = HRNorm,
91 Ref = Ref, Thickness = Thickness,
92 Diameter = Diameter)
93 Optic.OptCount = Optic.OptCount + 1
94
96 '''Compute the daughter beams after interaction on Side at point.
97
98 Generic function: all sides stop beams.
99
100 beam: incident beam. [GaussianBeam]
101
102 Returns {'t': None, 'r': None}
103
104 '''
105 if settings.info:
106 print ("theia: Info: Reached leaf of tree by interaction "\
107 +"(%s on %s, Side).") %(beam.Ref, self.Ref)
108 return {'t': None, 'r': None}
109
111 '''Returns the positions of the apexes of HR and AR as a tuple.'''
112 if self.HRK == 0.:
113 apex1 = self.HRCenter
114 else:
115 try:
116 theta1 = np.arcsin(self.Dia * self.HRK/2.)
117 except FloatingPointError:
118
119
120 theta1 = np.pi/2.
121 apex1 = self.HRCenter - (1-np.cos(theta1))*self.HRNorm/self.HRK
122
123 if self.ARK == 0.:
124 apex2 = self.ARCenter
125 else:
126 if self.Name == 'Mirror':
127
128 wedge = self.Wedge
129 else:
130 wedge = 0.
131 try:
132 theta2 = np.arcsin(self.Dia * self.ARK/(2.*np.cos(wedge)))
133 except FloatingPointError:
134 theta2 = np.pi/2.
135 apex2 = self.ARCenter - (1-np.cos(theta2))*self.ARNorm/self.ARK
136
137 return apex1, apex2
138
140 '''Determine whether the HR and AR surfaces intersect.
141
142 Returns True if there is an intersection, False if not.
143
144 '''
145
146 if self.ARK <= 0. and self.HRK <= 0.:
147
148 return False
149
150 apex = self.apexes()
151
152
153 vec = apex[1] - apex[0]
154
155 return np.dot(vec, self.HRNorm) > 0.
156
158 '''Makes geometrical checks on surfaces and warns when necessary.'''
159
160 if self.HRt + self.HRr > 1.:
161 print "theia: Warning: In %s %s on HR, R + T > 1." %(word, self.Ref)
162
163 if self.ARt + self.ARr > 1.:
164 print "theia: Warning: In %s %s on AR, R + T > 1." %(word, self.Ref)
165
166 if self.N < 1.:
167 print "theia: Warning: In %s %s, optical index < 1."\
168 %(word, self.Ref)
169
170 if self.HRK != 0. and np.abs(1./self.HRK) < self.Dia/2.:
171 print ("theia: Warning: In %s, the diameter of the %s exceeds the"\
172 + " diameter of the HR surface.") %( self.Ref, word)
173
174 if self.ARK != 0. and np.abs(1./self.ARK) < self.Dia/2.:
175 print ("theia: Warning: In %s, the diameter of the %s exceeds the"\
176 + " diameter of the AR surface.") %(self.Ref, word)
177
178 if self.collision():
179 print "theia: Warning: In %s, HR and AR surfaces intersect."\
180 %self.Ref
181
182 - def translate(self, X = 0., Y = 0., Z = 0.):
183 '''Move the optic to (current position + (X, Y, Z)).
184
185 This version takes care of HRcenter and ARCenter and overwrites the
186 SetupComponent version.
187
188 X, Y, Z: components of the translation vector.
189
190 No return value.
191 '''
192 self.HRCenter = self.HRCenter + np.array([X, Y, Z], dtype = np.float64)
193 self.ARCenter = self.ARCenter + np.array([X, Y, Z], dtype = np.float64)
194