00001 "a sample system using general_optics.py to model a 10 Joule Nd:Glass CPA laser system"
00002 _rcsid="$Id: general_optics_example.py,v 1.3 2003/05/30 13:31:55 mendenhall Release-20030716 $"
00003
00004 from math import *
00005 import math
00006 import Numeric
00007 import types
00008 import traceback
00009
00010 import general_optics
00011 from general_optics import composite_optic, grating, lens, reflector, null_optic, beam, qtens, Infinity, euler, trace_path, vec_mag
00012 from general_optics import phase_plate, halfwave_plate, faraday_rotator
00013
00014 import copy
00015
00016 import abcd_optics
00017
00018 class spitfire:
00019 optics=abcd_optics
00020 mm=1e-3
00021 inch=25.4*mm
00022 lambda0=1.054e-6
00023 spitfire_thermal=optics.lens(500.0*mm)
00024 spitfire_abcd=(optics. mirror(1000.0*mm)*optics.space(19.0*inch)*optics.mirror(500.0*mm)*optics.space(9.5*inch)*spitfire_thermal*
00025 optics.space(9.5*inch)*optics.mirror(500.0*mm)* optics.space(19.0*inch)*optics.mirror(1000.0*mm)*
00026 optics.space(19.0*inch)*optics.mirror(500.0*mm)*optics.space(9.5*inch)*spitfire_thermal*optics.space(9.5*inch)*
00027 optics.mirror(500.0*mm)*optics.space(19.0*inch) )
00028
00029 resonator=optics.abcd_resonator(spitfire_abcd, lambda0)
00030 exit_window=resonator.qw(optics.space(900.0*mm))
00031 q0=exit_window.q
00032
00033
00034 clight=299792458.
00035 deg=pi/180.0
00036 inch = 0.0254
00037
00038 import graphite
00039
00040 show_qd=0
00041 show_pdf=1
00042
00043 def draw_layout(graph, optics):
00044 if optics is None:
00045 return
00046
00047 colorline = graphite.PointPlot()
00048 colorline.lineStyle = graphite.LineStyle(width=1, color=graphite.orange, kind=graphite.SOLID)
00049 colorline.symbol = None
00050 for i in optics.keys():
00051 olist=optics[i].polygon_list()
00052 for o in olist:
00053 if o is not None:
00054 d=graphite.Dataset()
00055 d.x=o[:,2]
00056 d.y=o[:,0]
00057 d.z=o[:,1]
00058
00059 graph.datasets.append(d)
00060 graph.formats.append(colorline)
00061
00062 def draw_trace(graph, optics_trace):
00063 if optics_trace is None:
00064 return
00065
00066 colorline = graphite.PointPlot()
00067 if optics_trace.color is None:
00068 color=graphite.black
00069 else:
00070 color=optics_trace.color
00071
00072 colorline.lineStyle = graphite.LineStyle(width=1, color=color, kind=graphite.SOLID)
00073 colorline.symbol = None
00074
00075 count=len(optics_trace)
00076 coords=Numeric.zeros((count,3), Numeric.Float)
00077 for i in range(count):
00078 xy=optics_trace[i].x0
00079 coords[i]=(xy[2],xy[0], xy[1])
00080
00081 graph.datasets.append(graphite.Dataset(coords))
00082 graph.formats.append(colorline)
00083
00084 def draw_everything(optics, trace, xrange, yrange, three_d=None):
00085
00086 g=graphite.Graph()
00087 g.top=10
00088 g.left=100
00089 g.right=g.left+700
00090 g.bottom=g.top+300
00091 g.axes[graphite.X].range=xrange
00092 g.axes[graphite.Y].range=yrange
00093 g.formats=[]
00094 if three_d:
00095 g.axes[graphite.Z].range=(-0.5, 0.5)
00096 g.lookAt=(-.25,-1.0,0)
00097 g.eyePosition=(-.75,-2,0.25)
00098
00099 draw_layout(g, optics)
00100 draw_trace(g, trace)
00101
00102 g.axes[graphite.Y].tickMarks[0].labels = "%+.1f"
00103 g.axes[graphite.Y].label.text = "meters"
00104 g.axes[graphite.Y].tickMarks[0].inextent= 0.02
00105 g.axes[graphite.Y].tickMarks[0].labelStyle=graphite.TextStyle(hjust=graphite.RIGHT, vjust=graphite.CENTER,
00106 font=graphite.Font(10,0,0,0,None),
00107 color=graphite.Color(0.00,0.00,0.00))
00108 g.axes[graphite.Y].tickMarks[0].labeldist=-0.01
00109
00110 g.axes[graphite.X].tickMarks[0].labels = "%+.1f"
00111 g.axes[graphite.X].label.text = "meters"
00112 g.axes[graphite.X].tickMarks[0].inextent= 0.02
00113 g.axes[graphite.X].tickMarks[0].labelStyle=graphite.TextStyle(hjust=graphite.CENTER, vjust=graphite.TOP,
00114 font=graphite.Font(10,0,0,0,None),
00115 color=graphite.Color(0.00,0.00,0.00))
00116 g.axes[graphite.X].tickMarks[0].labeldist=-0.01
00117
00118 return g
00119
00120 class mir(reflector):
00121 "a one inch mirror"
00122 def post_init(self):
00123 self.width=0.0254
00124 self.thickness=0.005
00125 reflector.post_init(self)
00126
00127 class serrated_aperture(null_optic):
00128 pass
00129
00130 class plain_aperture(null_optic):
00131 pass
00132
00133 class alignment_aperture(null_optic):
00134 pass
00135
00136 class laser_head(null_optic):
00137 "an optic with both an inner box (rod) and outer box (case)"
00138 def inner_polygon(self):
00139 savew, savet = self.width, self.thickness
00140 self.width=self.rodsize
00141 self.thickness=self.thickness*0.75
00142 try:
00143 p=self.polygon()
00144 finally:
00145 self.width=savew
00146 self.thickness=savet
00147 return p
00148 def polygon_list(self):
00149 return [self.polygon(), self.inner_polygon()]
00150
00151 class PL_brewster_filter(reflector):
00152 def post_init(self):
00153 self.width=5.0*inch
00154 self.height=2.0*inch
00155 self.thickness=0.125*inch
00156 self.brewster_angle=56.0
00157 if not self.__dict__.has_key("transmit"):
00158 self.transmit=0
00159 if not self.__dict__.has_key("reversed"):
00160 self.eta=0
00161 else:
00162 self.eta=180
00163
00164 def outer_polygon(self):
00165 savew, savet = self.width, self.thickness
00166 self.width=4*inch
00167 self.thickness=6*inch
00168 myrot=general_optics.eulermat(-self.brewster_angle,self.eta,0)
00169 self.rotate_in_local_frame(myrot)
00170 try:
00171 p=self.polygon()
00172 finally:
00173 self.width=savew
00174 self.thickness=savet
00175 self.rotate_in_local_frame(Numeric.transpose(myrot))
00176 return p
00177
00178 def local_transform(self):
00179 if not self.transmit:
00180 reflector.local_transform(self)
00181
00182 def q_transform(self):
00183 if not self.transmit:
00184 reflector.q_transform(self)
00185
00186 def place_between(self, from_obj, to_obj, distance):
00187 reflector.place_between(self, from_obj, to_obj, distance)
00188 self.rotate_in_local_frame(general_optics.eulermat(self.brewster_angle,0,0))
00189 return self
00190
00191 def rotate_axis(self, axis_theta):
00192 self.rotate_in_local_frame(general_optics.eulermat(-self.brewster_angle,0,0))
00193 self.rotate_in_local_frame(general_optics.eulermat(0,0,axis_theta))
00194 self.rotate_in_local_frame(general_optics.eulermat(self.brewster_angle,0,0))
00195 return self
00196
00197 def polygon_list(self):
00198 return [self.polygon(), self.outer_polygon()]
00199
00200 class vacuum_spatial_filter(null_optic):
00201 "an optic with both an inner box (aperture) and outer box (tube)"
00202 def inner_polygon(self):
00203 savew, savet = self.width, self.thickness
00204 self.thickness=0.01
00205 try:
00206 p=self.polygon()
00207 finally:
00208 self.width=savew
00209 self.thickness=savet
00210 return p
00211 def polygon_list(self):
00212 return [self.polygon(), self.inner_polygon()]
00213
00214 class blue_through_ylf(composite_optic):
00215
00216
00217
00218 UVM1, UVM2, UVM3, UVM4, UVM5, UVM6, UVM7, UVM8, UVM9, UVM10, UVM11, UVM12= range(12)
00219 PS1u, PS1d='ps1u', 'ps1d'
00220 UVL1, UVL2, DEMAG1, DEMAG2=range(20,24)
00221 YLF_SPLIT='ylf_split'
00222 SERR='serr'
00223 FILTER='filt'
00224
00225 def __init__(self, **extras):
00226 inch=0.0254
00227 entrance_y=5.0*inch
00228 y0=2.5*inch
00229 my=blue_through_ylf
00230 optics={}
00231
00232
00233 optics[my.UVM1]=mir("UVM1", (13*inch, entrance_y, 7.5*inch))
00234 optics[my.UVM2]=mir("UVM2", (7.5*inch, entrance_y, 7.5*inch))
00235 optics[my.PS1u]=mir("Blue Peri 1 upper", (8*inch, entrance_y, 37*inch))
00236 optics[my.PS1d]=mir("Blue Peri 1 lower", (8*inch, y0, 37*inch))
00237 optics[my.UVM3]=mir("UVM3", (36*inch, y0, 38*inch))
00238 optics[my.UVM4]=mir("UVM4", (36*inch, y0, 137.5*inch))
00239 optics[my.UVM5]=mir("UVM5", (43.5*inch, y0, 49.5*inch))
00240 optics[my.UVM6]=mir("UVM6", (46.5*inch, y0, 137.5*inch))
00241 optics[my.UVM7]=mir("UVM7", (38*inch, y0, 38*inch))
00242 optics[my.UVM8]=mir("UVM8", (41.5*inch, y0, 136*inch))
00243 optics[my.UVM9]=mir("UVM9", (53*inch, y0, 136*inch))
00244 optics[my.UVM10]=mir("UVM10", (53*inch, y0, 41*inch))
00245 optics[my.UVM11]=mir("UVM11", (48*inch, y0, 41*inch))
00246 optics[my.UVM12]=mir("YLF retro", (48*inch, y0,80.5*inch))
00247 optics[my.YLF_SPLIT]=mir("YLF exit splitter", (48*inch, y0, 47.8*inch))
00248
00249 optics[my.UVL1]=lens("UVL1", f=+0.75).place_between(optics[my.UVM3], optics[my.UVM4], 4.0*inch)
00250 optics[my.UVL2]=lens("UVL2", f=+1.00).place_between(optics[my.UVL1], optics[my.UVM4], 83*inch-0.0*inch)
00251
00252 optics[my.DEMAG1]=lens("UVL3", f=+0.75).place_between(optics[my.UVM9], optics[my.UVM10], 23.0*inch)
00253 optics[my.DEMAG2]=lens("UVL4", f=+1.00).place_between(optics[my.DEMAG1], optics[my.UVM10], 1.7+5.0*inch)
00254
00255 optics[my.SERR]=null_optic("Serr. Aperture", width=1.0*inch, thickness=0.1*inch).place_between(optics[my.DEMAG1], optics[my.DEMAG2], 3*inch)
00256 optics[my.FILTER]=null_optic("Filter Aperture", width=1.0*inch, thickness=0.1*inch).place_between(optics[my.DEMAG1], optics[my.DEMAG2], 0.75)
00257
00258 looks=[my.UVM1, my.UVM2, my.PS1u, my.PS1d, my.UVM3, my.UVM4, my.UVM5, my.UVM6, my.UVM7,
00259 my.UVM8, my.UVM9, my.UVM10, my.UVM11, my.UVM12, my.YLF_SPLIT]
00260
00261 for i in range(1, len(looks)-1):
00262 optics[looks[i]].set_direction(optics[looks[i-1]], optics[looks[i+1]])
00263
00264 order=[my.UVM1, my.UVM2, my.PS1u, my.PS1d, my.UVM3, my.UVL1, my.UVL2, my.UVM4, my.UVM5, my.UVM6, my.UVM7,
00265 my.UVM8, my.UVM9, my.DEMAG1, my.SERR, my.FILTER, my.DEMAG2, my.UVM10, my.UVM11, my.UVM12, my.YLF_SPLIT]
00266
00267
00268 composite_optic.init(self, "blue line", optics, order, (0,0,0), (0,0,0), 0, extras=extras )
00269
00270 class ir_line(composite_optic):
00271 M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15= range(15)
00272 L1, L2, L3, L4, L5, L6, L7, L8, L7a=range(20,29)
00273 VSF1, VSF2, VSF3=range(30,33)
00274 SERR1='Serr1'
00275 SF1='SF1'
00276 FR12, FR25 = 'fr12', 'fr25'
00277 A1, A2, A3, A4, A5 = range(40,45)
00278 G9a, G9b, G25a, G25b, G50 = range(50,55)
00279 TrM1, TrM2, TrM3, TrM4 = range(60,64)
00280 BP2, BP3, BP4 = range(70,73)
00281 QR1, QR2, QR3, QR4 =range(80,84)
00282 EXIT='exit'
00283
00284 def __init__(self, **extras):
00285 inch=0.0254
00286 entrance_y=5.0*inch
00287 exit_y=13.5*inch
00288 my=ir_line
00289 optics={}
00290
00291
00292 optics[my.M1]=mir("M1", (2*inch, entrance_y, 10*inch))
00293 optics[my.M2]=mir("M2", (4*inch, entrance_y, 10*inch))
00294 optics[my.TrM1]=mir("TrM1", (4*inch, entrance_y, 96*inch))
00295 optics[my.TrM2]=mir("TrM2", (6*inch, entrance_y, 96*inch))
00296 optics[my.TrM3]=mir("TrM3", (6*inch, entrance_y, 82.5*inch))
00297 optics[my.TrM4]=mir("TrM4", (2*inch, entrance_y, 82.5*inch))
00298 optics[my.M3]=mir("M3", (4*inch, entrance_y, 135*inch))
00299 optics[my.M4]=mir("M4", (12*inch, entrance_y, 135*inch))
00300 optics[my.M5]=mir("M5", (13*inch, entrance_y, 105*inch))
00301 optics[my.M6]=mir("M6", (14*inch, entrance_y, 105*inch))
00302 optics[my.M7]=mir("M7", (16.5*inch, entrance_y, 3*inch))
00303 optics[my.M8]=mir("M8", (24*inch, entrance_y, 3*inch))
00304 optics[my.M9]=mir("M9", (23*inch, entrance_y, 135*inch))
00305 optics[my.M10]=mir("M10", (33*inch, entrance_y, 134.5*inch))
00306 optics[my.M11]=mir("M11", (33*inch, entrance_y, -6*inch))
00307 optics[my.BP4]=PL_brewster_filter("BP4", (33*inch, entrance_y, 27*inch), reversed=1)
00308 optics[my.M12]=mir("M12", (20*inch, entrance_y, 33*inch))
00309 optics[my.M13]=mir("M13", (20*inch, entrance_y, 12*inch))
00310 optics[my.M14]=mir("M14", (8.5*inch, entrance_y, 11.5*inch))
00311 optics[my.M15]=mir("M15", (8.5*inch, exit_y, 11.5*inch))
00312
00313 optics[my.EXIT]=sys_exit=null_optic("exit", (10.0*inch, exit_y, 142.0*inch))
00314
00315 optics[my.L1]=lens("L1", f=+0.400).place_between(optics[my.M2], optics[my.TrM1], 12.0*inch)
00316 optics[my.L2]=lens("L2", f=+0.800).place_between(optics[my.L1], optics[my.TrM1], 1.30)
00317 optics[my.L3]=lens("L3", f=+0.750).place_between(optics[my.M6], optics[my.M7], 10*inch)
00318 optics[my.L4]=lens("L4", f=+1.500).place_between(optics[my.L3], optics[my.M7], 2.25)
00319 optics[my.L5]=lens("L5", f=+0.750).place_between(optics[my.M10], optics[my.M11], 5*inch)
00320 optics[my.L6]=lens("L6", f=+1.500).place_between(optics[my.L5], optics[my.M11], 95.5*inch)
00321 optics[my.L7]=lens("L7", f=+0.750).place_between(optics[my.M15], sys_exit, 4.5*inch)
00322 optics[my.L8]=lens("L8", f=+2.500, width=6*inch, thickness=0.25*inch).\
00323 place_between(optics[my.M15], sys_exit, -1*inch).tilt_off_axis((0,45,0))
00324
00325 optics[my.G9a]=laser_head("9mm-1", width=2.0*inch, thickness=6.0*inch, rodsize=0.009).\
00326 place_between(optics[my.M4], optics[my.M5], 9*inch)
00327 optics[my.G9b]=laser_head("9mm-2", width=2.0*inch, thickness=6.0*inch, rodsize=0.009).\
00328 place_between(optics[my.M4], optics[my.M5], 23*inch)
00329
00330 optics[my.G25a]=laser_head("25mm-1", width=6.0*inch, thickness=12.0*inch, rodsize=0.025).\
00331 place_between(optics[my.M8], optics[my.M9], 74*inch)
00332 optics[my.G25b]=laser_head("25mm-2", width=6.0*inch, thickness=12.0*inch, rodsize=0.025).\
00333 place_between(optics[my.M8], optics[my.M9], 94*inch)
00334
00335 optics[my.G50]=laser_head("50mm", width=9.0*inch, thickness=15.0*inch, rodsize=0.050).\
00336 place_between(optics[my.M10], optics[my.M11], -19*inch)
00337
00338 optics[my.SERR1]=serrated_aperture("serrated aperture", diameter=0.003).\
00339 place_between(optics[my.M2], optics[my.TrM1], 10*inch)
00340 optics[my.SF1]=plain_aperture("spatial filter 1", diameter=0.001).\
00341 place_between(optics[my.M2], optics[my.TrM1], 35*inch)
00342
00343 optics[my.QR1]=halfwave_plate("QR1", width=1*inch, thickness=0.5*inch).\
00344 place_between(optics[my.G9a], optics[my.G9b], 8*inch).rotate_axis(22.5)
00345 optics[my.FR12]=faraday_rotator("FR12", width=0.5*inch, thickness=6*inch, rotation=45).\
00346 place_between(optics[my.M6], optics[my.M7], 5*inch)
00347 optics[my.VSF1]=vacuum_spatial_filter("VSF1", thickness=24*inch, width=2*inch).\
00348 place_between(optics[my.L3], optics[my.L4], 0.750)
00349
00350 optics[my.QR2]=halfwave_plate("QR2", width=1*inch, thickness=0.5*inch).\
00351 place_between(optics[my.G25a], optics[my.G25b], 8*inch).rotate_axis(22.5)
00352
00353 optics[my.BP2]=PL_brewster_filter("BP2", transmit=1).\
00354 place_between(optics[my.G25b], optics[my.M9], 13*inch).rotate_axis(90)
00355 optics[my.QR3]=halfwave_plate("QR3", width=1*inch, thickness=0.5*inch).\
00356 place_between(optics[my.G25b], optics[my.M9], 19*inch).rotate_axis(22.5)
00357 optics[my.FR25]=faraday_rotator("FR25", width=1.0*inch, thickness=6.0*inch, rotation=45).\
00358 place_between(optics[my.G25b], optics[my.M9], 23*inch)
00359 optics[my.BP3]=PL_brewster_filter("BP3", transmit=1).\
00360 place_between(optics[my.G25b], optics[my.M9], 30*inch).rotate_axis(0)
00361
00362 looks=[my.M1, my.M2, my.TrM1, my.TrM2, my.TrM3, my.TrM4, my.M3, my.M4, my.M5,
00363 my.M6, my.M7, my.M8, my.M9,
00364 my.M10, my.M11, my.BP4, my.M12, my.M13, my.M14, my.M15, my.EXIT]
00365
00366 for i in range(1, len(looks)-1):
00367 optics[looks[i]].set_direction(optics[looks[i-1]], optics[looks[i+1]])
00368
00369 order=[my.M1, my.M2, my.SERR1, my.L1, my.SF1, my.L2, my.TrM1, my.TrM2, my.TrM3, my.TrM4, my.M3, my.M4, my.G9a,
00370 my.QR1, my.G9b, my.M5,
00371 my.M6, my.FR12, my.L3, my.VSF1, my.L4, my.M7, my.M8, my.G25a, my.QR2, my.G25b,
00372 my.BP2, my.QR3, my.FR25, my.BP3,
00373 my.M9, my.M10, my.L5, my.L6, my.G50, my.M11, my.BP4, my.M12,
00374 my.M13, my.M14, my.M15, my.L7, my.L8]
00375
00376
00377 composite_optic.init(self, "IR line", optics, order, (0,0,0), (0,0,0), 0, extras=extras )
00378
00379 class ir_compressor(composite_optic):
00380 INPUT='M1'
00381 OUTPUT='M2'
00382 FOCUS='L1'
00383 G1="grating 1"
00384 G2="grating 2"
00385 VR1='vert_retro_1'
00386 VR2='vert_retro_2'
00387 START='bc.start'
00388 END='bc.end'
00389
00390 def __init__(self, theta1=61.486, clen=1.02, lambda0=1.054e-6, center=(0,0,0), angle=0, **extras):
00391 self.init(theta1, clen, lambda0, center, angle, extras)
00392
00393 def init(self, theta1, clen, lambda0, center, angle, extras):
00394 my=ir_compressor
00395 input_height=18*inch
00396 output_height=12*inch
00397 center_height=(input_height+output_height)/2.0
00398
00399 basebeam=beam((0,input_height,-1.0), qtens(lambda0, w=0.005, r=Infinity))
00400 optics={}
00401
00402 optics[my.INPUT]=m1=reflector("input mirror", center=(0, input_height, 0), width=8*inch, angle=-45)
00403
00404 optics[my.G1]=g1=grating("g1", angle=theta1+90, center=(52*inch,center_height, 0),
00405 pitch=1740e3, order=1, width=16*inch, thickness=2.0*inch)
00406 mybeam=basebeam.clone()
00407 m1.transport_to_here(mybeam)
00408 m1.transform(mybeam)
00409 g1.transport_to_here(mybeam)
00410 g1.transform(mybeam)
00411 mybeam.free_drift(clen)
00412 optics[my.G2]=g2=grating("g2", angle=theta1-90, center=mybeam.x0+(0,0,1e-8),
00413 pitch=1740e3, order=1, width=16*inch, thickness=2.0*inch)
00414
00415 optics[my.VR1]=reflector("retro", center=(40*inch, center_height, g2.center[2]), angle=90.0, width=8*inch, thickness=1.0*inch)
00416
00417 out=optics[my.OUTPUT]=reflector("output mirror", center=(8*inch, output_height, 0.0),
00418 width=8.0*inch, thickness=1.0*inch)
00419 focus=optics[my.FOCUS]=lens("output focus", center=out.center+(35*inch, 0, 7*inch),
00420 angle=90-math.atan(0.2)/deg, f=2.0, width=8.0*inch,
00421 height=8.0*inch, thickness=1.0*inch).tilt_off_axis(0)
00422 out.set_direction(g1.center-(0, center_height-output_height, 0), focus)
00423
00424 comp_order=(my.INPUT, my.G1, my.G2, my.VR1, my.G2, my.G1, my.OUTPUT, my.FOCUS)
00425
00426 composite_optic.init(self, "ir compressor", optics, comp_order, None, center=center, angle=0, extras=extras )
00427
00428
00429
00430 m1label=self.mark_label(my.INPUT)
00431 g1label=self.mark_label(my.G1)
00432 m2label=self.mark_label(my.OUTPUT)
00433 ir_trace=trace_path(self, basebeam.clone())
00434 path_len=(ir_trace[(m2label,0)].total_drift-ir_trace[(m1label,0)].total_drift)
00435 slope=(output_height-input_height)/path_len
00436
00437
00438 g1_first_distance=(ir_trace[(g1label,0)].total_drift-ir_trace[(m1label,0)].total_drift)
00439
00440 g1_second_distance=(ir_trace[(g1label,1)].total_drift-ir_trace[(m1label,0)].total_drift)
00441
00442
00443 self.update_coordinates(self.center, self.center, general_optics.eulermat(angle, 0, 0))
00444
00445
00446 self.g1target1=g1.center+(0, (input_height-center_height)+g1_first_distance*slope, 0)
00447 self.g1target2=g1.center+(0, (input_height-center_height)+g1_second_distance*slope, 0)
00448 out.set_direction(self.g1target2, focus)
00449
00450 def set_entrance_direction(self, look_to):
00451 my=ir_compressor
00452 self.optics_dict[my.INPUT].set_direction(look_to, self.g1target1)
00453
00454 class blue_compressor(composite_optic):
00455 IR1="bc.ir1"
00456 IR2="bc.ir2"
00457 OR1="bc.or1"
00458 GRATE="bc.grating"
00459 VR1='bc.vert_retro_1'
00460 VR2='vbc.ert_retro_2'
00461 IPERI1='bc.ip1'
00462 IPERI2='bc.ip2'
00463 EXP1='bc.exp1'
00464 EXP2='bc.exp2'
00465 OPERI1='bc.op1'
00466 OPERI2='bc.op2'
00467 TM1='bc.turn1'
00468 TM2='bc.turn2'
00469 DEMAG1='bc.dmg1'
00470 DEMAG2='bc.dmg2'
00471 START='bc.start'
00472 END='bc.end'
00473 y_offset=0.5*inch
00474
00475 def setup_retro_standard(self, beam, vertex_distance, retro_beam_offset, retro_err, y_center):
00476 """setup_retro_standard(diffracted_beam, vertex_distance, grating_beta, grating_spot_offset, retro_err) ->
00477 (retro_mirror_1, retro_mirror_2)"""
00478 my=blue_compressor
00479 c,s = beam.direction()[2], beam.direction()[0]
00480 vz, vx = c*vertex_distance, s*vertex_distance
00481 vz, vx = vz - s*retro_beam_offset, vx + c*retro_beam_offset
00482 beam_angle=math.atan2(s,c)/deg
00483 ir1=reflector(my.IR1, angle=(beam_angle-45-retro_err/2), center=(vx,y_center,vz), justify="left", width=0.05)
00484 ir2=reflector(my.IR2, angle=(beam_angle+45+retro_err/2), center=(vx,y_center,vz), justify="right", width=0.05)
00485
00486 return ir1, ir2
00487
00488 def setup_reflectors_blue(self, basebeam, theta1, clen, grating_spot_offset, pitch=1.5e6, lam0=1.053e-6, inside_retro_err=0, zeta=0):
00489 my=blue_compressor
00490 y_offset=my.y_offset
00491 grate=grating(my.GRATE, angle=theta1, center=(0,y_offset/2, 0), pitch=pitch, order=1, justify=-.8, height=0.05, width=0.1)
00492 littrow, beta=grate.degree_angles(theta1, lam0)
00493 vertex_dist=(clen-grating_spot_offset*sin(beta*deg))*0.5
00494 retro_beam_offset=grating_spot_offset*math.cos(beta*deg)*0.5
00495 beam=basebeam.clone().set_lambda(lam0)
00496 grate.transport_to_here(beam)
00497 grate.transform(beam)
00498 return_x=-grating_spot_offset*math.cos(theta1*deg)
00499 vretvertex=Numeric.array((return_x, y_offset/2, -0.22))
00500 yvec=Numeric.array((0.,y_offset,0.))
00501 ir1, ir2 = self.setup_retro_standard(beam, vertex_dist, retro_beam_offset, inside_retro_err, y_offset/2)
00502 vr1=reflector('vert retro 1', angle=0, center=vretvertex-yvec/2, width=0.025, height=0.05, thickness=0.01)
00503 vr2=reflector('vert retro 2', angle=0, center=vretvertex+yvec/2, width=0.025, height=0.05)
00504 vr1.set_direction((return_x,0,0), vr2)
00505 vr2.set_direction(vr1, (return_x, y_offset, 0))
00506 return {my.GRATE:grate, my.IR1:ir1, my.IR2:ir2, my.VR1:vr1, my.VR2:vr2 }
00507
00508 def __init__(self, theta1, clen, lambda0, center=(0,0,0), angle=0, **extras):
00509 self.init(theta1, clen, lambda0, center, angle, extras)
00510
00511 def init(self, theta1, clen, lambda0, center, angle, extras):
00512 grating_offset=-0.075
00513 exit_height=-1.0*inch
00514 exit_z=-0.275
00515 my=blue_compressor
00516 basebeam=beam((0,0,-1.0), qtens(lambda0, w=0.001, r=Infinity))
00517 optics=self.setup_reflectors_blue(basebeam, theta1, clen, grating_offset, lam0=lambda0, inside_retro_err=0.0)
00518
00519 cs=Numeric.array((0, exit_height, -0.44))
00520
00521 optics[my.IPERI1]=reflector("input peri bot", angle=0, center=cs, width=.025)
00522 optics[my.IPERI2]=reflector("input peri top", angle=0, center=cs+(0.0,-exit_height, 0), width=.025)
00523
00524 optics[my.EXP1]=lens("expander diverge", f=-.15).place_between(cs+(-.1,0,0), optics[my.IPERI1], -0.09)
00525 optics[my.EXP2]=lens("expander re-coll", f=0.3).place_between(optics[my.IPERI2], (0,0,0), 0.037)
00526
00527
00528 optics[my.IPERI1].set_direction(optics[my.EXP1], optics[my.IPERI2])
00529 optics[my.IPERI2].set_direction(optics[my.IPERI1], optics[my.EXP2])
00530
00531 optics[my.OPERI1]=reflector("output peri top", angle=0, center=(0,my.y_offset,exit_z), width=.025)
00532 optics[my.OPERI2]=reflector("output peri bot", angle=0, center=(0,exit_height,exit_z), width=.025)
00533
00534 optics[my.TM1]=reflector("output turn 1", angle=90, center=(0.30, exit_height,exit_z), width=.025)
00535
00536 optics[my.OPERI1].set_direction((0,my.y_offset,0), optics[my.OPERI2])
00537 optics[my.OPERI2].set_direction(optics[my.OPERI1], optics[my.TM1])
00538
00539 comp_order=(my.EXP1, my.IPERI1, my.IPERI2, my.EXP2, my.GRATE,
00540 my.IR2, my.IR1, my.GRATE, my.VR1, my.VR2, my.GRATE, my.IR1, my.IR2,
00541 my.GRATE, my.OPERI1, my.OPERI2, my.TM1)
00542
00543 composite_optic.init(self, "compressor", optics, comp_order, None, center=center, angle=angle, extras=extras )
00544
00545
00546 def doit_bc(theta1, clen, lambda0, drawit=0):
00547
00548 print "\n\n***start blue line trace***\n"
00549 grating_offset=-0.075
00550 exit_height=0
00551 exit_z=-0.3
00552 eta1=0.0
00553
00554 optics={}
00555
00556 END='end'
00557 optics[END]=null_optic("end", (0.15,exit_height,0), 0)
00558 START='start'
00559 optics[START]=null_optic("start", (0,0,-0.85))
00560
00561
00562 tracebeam=basebeam.clone()
00563 system_center=Numeric.array((-0.1, 0, -0.85))
00564
00565 basebeam=beam(system_center, qtens(lambda0, q=spitfire.q0), lambda0)
00566 tracebeam.free_drift(-0.2)
00567
00568 COMP='comp'
00569 comp=optics[COMP]=blue_compressor(theta1, clen, lambda0, center=system_center, angle=rotation)
00570 TM2='turn2'
00571 optics[TM2]=reflector("output turn 2", angle=0, center=(0.15,exit_height,-0.6), width=.025)
00572
00573 optics[COMP].set_exit_direction(optics[TM2])
00574 optics[TM2].set_direction(optics[COMP], optics[END])
00575
00576 sys_order=(START, COMP, TM2, DEMAG1, DEMAG2, END)
00577
00578 GRATE=comp.mark_label(blue_compressor.GRATE)
00579 IR1=comp.mark_label(blue_compressor.IR1)
00580 IR2=comp.mark_label(blue_compressor.IR2)
00581
00582 optic_sys=composite_optic("system", optics, sys_order, center=optics[START].center)
00583
00584 trace0=trace_path(optic_sys, tracebeam.shift_lambda(0))
00585 trace0.color=graphite.green
00586 trace1=trace_path(optic_sys, tracebeam.shift_lambda(-0.5e-9))
00587 trace1.color=graphite.blue
00588 trace2=trace_path(optic_sys, tracebeam.shift_lambda(+0.5e-9))
00589 trace2.color=graphite.red
00590
00591 try:
00592 print "Theta1=%.3f eta=%.3f len=%.3f lambda=%.4f" % (theta1, eta1, clen, lambda0*1e6)
00593 d0=trace0[-1]['total_drift']
00594 d1=trace1[-1]['total_drift']
00595 d2=trace2[-1]['total_drift']
00596 print ("d(lambda0-0.5nm)=%.3f m, d(lambda0+0.5nm)=%.3f m, dt/dl=%.0f ps/nm, " % (d1, d2, (d2-d1)*1e12/clight)),
00597 print "d2t/dl2 = %.2f ps/nm^2" % ((d2+d1-2.0*d0)*(1e12/clight)*4)
00598 spot1info=trace0[(GRATE,0)]
00599 spot2info=trace0[(GRATE,1)]
00600 ir1info=trace0[(IR1,0)]
00601 ir2info=trace0[(IR2,0)]
00602 spot_offset=spot2info['position']-spot1info['position']
00603 retro_offset=ir2info['position']-ir1info['position']
00604 print "Grating offset = %.3f, retro_offset=%.3f" % (vec_mag(spot_offset), vec_mag(retro_offset))
00605 print "measured vertex length = %.3f" % vec_mag(comp[GRATE].center-comp[IR1].center)
00606 print "dispersion offset on grating = %.3f m / nm" % vec_mag(trace2[(GRATE,1)]['position']-trace1[(GRATE,1)]['position'])
00607 print "final q = ", trace0[-1]['q']
00608 except:
00609 traceback.print_exc()
00610 pass
00611
00612 if drawit:
00613 g=draw_everything({"sys":optic_sys}, trace0, (-.9, .1), (-.5, .5), three_d=0)
00614
00615 draw_trace(g, trace1)
00616 draw_trace(g, trace2)
00617 graphite.genOutput(g,'QD',canvasname="Compressor layout", size=(600,500))
00618
00619
00620 class quadrupler(composite_optic):
00621 L1, ENTRANCE, L2, DOUBLE, QUADRUPLE, EXIT = range(6)
00622
00623 def __init__(self, center, from_optic, **extras):
00624 my=quadrupler
00625 optics={}
00626 ent=optics[my.ENTRANCE]=mir("quadrupler entrance")
00627 exit=optics[my.EXIT]=null_optic("quadrupler exit", (0,0,-1.0))
00628 l1=optics[my.L1]=lens("quadrupler telescope 1", f=+0.300)
00629 l2=optics[my.L2]=lens("quadrupler telescope 2", f=-0.150).place_between(ent, exit, 0.111).tilt_off_axis(4.0)
00630
00631 green=optics[my.DOUBLE]=null_optic("green crystal").place_between(l2, exit, 0.1)
00632 optics[my.QUADRUPLE]=null_optic("UV crystal").place_between(green, exit, 0.1)
00633
00634 order=(my.L1, my.ENTRANCE, my.L2, my.DOUBLE, my.QUADRUPLE, my.EXIT)
00635 composite_optic.init(self, "quadrupler", optics, order, (0,0,0), center, 0, extras=extras )
00636 l1.place_between(from_optic, ent, -0.04)
00637
00638 def entrance_optics_tags(self):
00639
00640 return quadrupler.ENTRANCE, quadrupler.EXIT
00641
00642 def plotq(trace):
00643 qxl=[]
00644 qyl=[]
00645 zl=[]
00646 for i in trace:
00647 zl.append(i.total_drift)
00648 qi=i.incoming_q
00649 qix, qiy=i.transform_q_to_table(qi)
00650
00651 qxl.append(qi.rw(qix)[1])
00652 qyl.append(qi.rw(qiy)[1])
00653 zl.append(i.total_drift)
00654 qi=i.q
00655 qix, qiy=i.transform_q_to_table(qi)
00656
00657 qxl.append(qi.rw(qix)[1])
00658 qyl.append(qi.rw(qiy)[1])
00659
00660
00661 g=graphite.Graph()
00662 g.top=10
00663 g.left=100
00664 g.right=g.left+700
00665 g.bottom=g.top+300
00666
00667
00668 g.formats=[]
00669
00670 dsx=graphite.Dataset()
00671 dsx.x=zl
00672 dsx.y=qxl
00673 g.datasets.append(dsx)
00674 colorline = graphite.PointPlot()
00675 colorline.lineStyle = graphite.LineStyle(width=1, color=graphite.red, kind=graphite.SOLID)
00676 colorline.symbol = None
00677 g.formats.append(colorline)
00678
00679 dsy=graphite.Dataset()
00680 dsy.x=zl
00681 dsy.y=qyl
00682 g.datasets.append(dsy)
00683 colorline = graphite.PointPlot()
00684 colorline.lineStyle = graphite.LineStyle(width=1, color=graphite.blue, kind=graphite.SOLID)
00685 colorline.symbol = None
00686 g.formats.append(colorline)
00687
00688 g.axes[graphite.Y].tickMarks[0].labels = "%+.3f"
00689 g.axes[graphite.Y].label.text = "meters"
00690 g.axes[graphite.Y].tickMarks[0].inextent= 0.02
00691 g.axes[graphite.Y].tickMarks[0].labelStyle=graphite.TextStyle(hjust=graphite.RIGHT, vjust=graphite.CENTER,
00692 font=graphite.Font(10,0,0,0,None),
00693 color=graphite.Color(0.00,0.00,0.00))
00694 g.axes[graphite.Y].tickMarks[0].labeldist=-0.01
00695
00696 g.axes[graphite.X].tickMarks[0].labels = "%+.0f"
00697 g.axes[graphite.X].label.text = "meters"
00698 g.axes[graphite.X].tickMarks[0].inextent= 0.02
00699 g.axes[graphite.X].tickMarks[0].labelStyle=graphite.TextStyle(hjust=graphite.CENTER, vjust=graphite.TOP,
00700 font=graphite.Font(10,0,0,0,None),
00701 color=graphite.Color(0.00,0.00,0.00))
00702 g.axes[graphite.X].tickMarks[0].labeldist=-0.01
00703
00704 if show_qd:
00705 graphite.genOutput(g,'QD',canvasname="Beam size", size=(900,500))
00706 if show_pdf:
00707 graphite.genOutput(g,'PDF',canvasname="Q_plot", size=(900,500))
00708
00709 def show_table():
00710 inch=0.0254
00711 lambda0=1.054e-6
00712 spitfire_exit=Numeric.array((2*inch, 5*inch, -0.65))
00713 compressor_entrance=Numeric.array((45.5*inch, 2.5*inch, 46.5*inch))
00714
00715 optics={}
00716 BLUELINE='bl'
00717 SPLIT='split'
00718 START='start'
00719 COMP='compressor'
00720 QUAD='quadrupler'
00721 IR='ir'
00722 IR_COMP='ir compressor'
00723 BE_TURN='be_turn'
00724 IZ_SCREEN='iz'
00725
00726 optics[START]=null_optic("start", spitfire_exit)
00727 optics[BLUELINE]=blueline=blue_through_ylf()
00728 optics[SPLIT]=split1=reflector("splitter1", center=(2*inch, 5*inch, 3*inch))
00729 optics[IR]=irline=ir_line()
00730
00731 comp=optics[COMP]=blue_compressor(38.5, 1.28, lambda0, center=compressor_entrance, angle=270)
00732 mainbeam=beam( spitfire_exit, qtens(lambda0, spitfire.q0), lambda0)
00733
00734 split1.set_direction(spitfire_exit, blueline)
00735 blueline.set_entrance_direction(split1)
00736 blueline.set_exit_direction(comp)
00737 comp.rotate_to_axis(blueline)
00738 q=optics[QUAD]=quadrupler(center=(40*inch, 2.5*inch, 34.5*inch), from_optic=comp[blue_compressor.TM1])
00739 comp.set_exit_direction(q)
00740 q.set_entrance_direction(comp)
00741 blue_sys=composite_optic("blue_sys", optics, [START, SPLIT, BLUELINE, COMP, QUAD], (0,0,0), (0,0,0), 0)
00742 irline.set_entrance_direction(spitfire_exit)
00743
00744
00745 ir_sys=composite_optic("ir_sys", optics, [START, IR], (0,0,0), (0,0,0), 0).clone()
00746 pointer=trace_path(ir_sys, mainbeam.clone())[-1]
00747 pointer.free_drift(1.0)
00748 optics[IR_COMP]=ircomp=ir_compressor(center=pointer.x0, angle=math.atan(0.2)/deg)
00749 ircomp.set_entrance_direction(irline)
00750
00751
00752 ir_sys=composite_optic("ir_sys", optics, [START, IR, IR_COMP], (0,0,0), (0,0,0), 0).clone()
00753 pointer=trace_path(ir_sys, mainbeam.clone())[-1]
00754 pointer.free_drift(1.0)
00755 bemir=optics[BE_TURN]=reflector("be turn mirror", center=pointer.x0, angle=45.0)
00756 bemir.transport_to_here(pointer).transform(pointer)
00757 pointer.free_drift(0.1)
00758 dz=pointer.q.next_waist()
00759 pointer.free_drift(dz)
00760 optics[IZ_SCREEN]=null_optic("IZ", pointer.x0)
00761 ir_sys=composite_optic("ir_sys", optics, [START, IR, IR_COMP, BE_TURN, IZ_SCREEN], (0,0,0), (0,0,0), 0)
00762
00763 whole_table=composite_optic("whole table", optics, [START, SPLIT, BLUELINE, COMP, QUAD, IR, IR_COMP, BE_TURN, IZ_SCREEN], (0,0,0), (0,0,0), 0)
00764
00765
00766 ir_trace=trace_path(ir_sys, mainbeam.clone())
00767 ir_trace.color=graphite.red
00768 blue_trace=trace_path(blue_sys, mainbeam.clone())
00769 blue_trace.color=graphite.blue
00770
00771 if table_layout:
00772 g=draw_everything({"sys":whole_table}, ir_trace, (-.25,5), (0,2.5), three_d=0)
00773 draw_trace(g, blue_trace)
00774
00775
00776
00777 if show_qd:
00778 graphite.genOutput(g,'QD',canvasname="Compressor layout", size=(900,500))
00779 if show_pdf:
00780 graphite.genOutput(g,'PDF',canvasname="Tablelayout", size=(900,500))
00781
00782 plotq(blue_trace)
00783
00784 if 0:
00785 glabel=ircomp.mark_label(ircomp.INPUT)
00786 m=ir_trace[(glabel,0)]
00787 print "\n\n**start**\n\n"
00788 print m.incoming_direction, m.direction()
00789 print m.incoming_q
00790 print m.incoming_q.qi_moments()[1:3]
00791 print m.incoming_q.q_moments()[1:3]
00792 print m.incoming_q.qit, "\n"
00793 print m.localize_transform_tensor
00794 print m.footprint_q
00795 print m.footprint_q.qi_moments()[1:3]
00796 print m.footprint_q.q_moments()[1:3]
00797 print m.footprint_q.qit, "\n"
00798 print m.globalize_transform_tensor
00799 print m.q
00800 print m.q.qi_moments()[1:3]
00801 print m.q.q_moments()[1:3]
00802 print m.q.qit, "\n"
00803
00804 glabel=ircomp.mark_label(ircomp.INPUT)
00805
00806 endpoint=ir_trace[-1]
00807 q=endpoint.q
00808
00809 t, qx0, qy0=q.qi_moments()
00810 theta=math.atan2(t[0,1].real, t[0,0].real)/deg
00811 qxx, qyy = endpoint.transform_q_to_table(q)
00812 dzx, dzy = (1e6/qxx).real, (1e6/qyy).real
00813 print ("qxx = %.1f, dzx = %.0f, qyy=%.1f, dzy=%.0f, (in um), theta=%.1f deg" %
00814 (q.rw(qxx)[1]*1e6, dzx, q.rw(qyy)[1]*1e6, dzy, theta ) )
00815
00816 show_pdf=0
00817 show_qd=1
00818 table_layout=1
00819
00820 show_table()
00821
00822