def init(self, theta1, clen, lambda0, center, angle, extras):
		grating_offset=-0.075
		exit_height=-1.0*inch
		exit_z=-0.275
		my=blue_compressor
		basebeam=beam((0,0,-1.0), qtens(lambda0, w=0.001, r=Infinity))
		optics=self.setup_reflectors_blue(basebeam, theta1, clen, grating_offset, lam0=lambda0, inside_retro_err=0.0)
					
		cs=Numeric.array((0, exit_height, -0.44)) #entrance to compressor, before rotation
	
		optics[my.IPERI1]=reflector("input peri bot", angle=0, center=cs, width=.025)
		optics[my.IPERI2]=reflector("input peri top", angle=0, center=cs+(0.0,-exit_height, 0), width=.025)
	
		optics[my.EXP1]=lens("expander diverge", f=-.15).place_between(cs+(-.1,0,0), optics[my.IPERI1], -0.09)
		optics[my.EXP2]=lens("expander re-coll", f=0.3).place_between(optics[my.IPERI2], (0,0,0), 0.037)	
		#optics[my.EXP2]=lens("expander re-coll", f=0.3).place_between(optics[my.IPERI2], (0,0,0), 0.0357)	
	
		optics[my.IPERI1].set_direction(optics[my.EXP1], optics[my.IPERI2])
		optics[my.IPERI2].set_direction(optics[my.IPERI1], optics[my.EXP2])
	
		optics[my.OPERI1]=reflector("output peri top", angle=0, center=(0,my.y_offset,exit_z), width=.025)
		optics[my.OPERI2]=reflector("output peri bot", angle=0, center=(0,exit_height,exit_z), width=.025)

		optics[my.TM1]=reflector("output turn 1", angle=90, center=(0.30, exit_height,exit_z), width=.025)
	
		optics[my.OPERI1].set_direction((0,my.y_offset,0), optics[my.OPERI2])
		optics[my.OPERI2].set_direction(optics[my.OPERI1], optics[my.TM1])
				
		comp_order=(my.EXP1, my.IPERI1, my.IPERI2, my.EXP2, my.GRATE, 
				my.IR2, my.IR1, my.GRATE, my.VR1, my.VR2, my.GRATE, my.IR1, my.IR2, 
				my.GRATE, my.OPERI1, my.OPERI2, my.TM1)
					
		composite_optic.init(self, "compressor", optics, comp_order, None, center=center, angle=angle, extras=extras )		
	def init(self, theta1, clen, lambda0, center, angle, extras):
		my=ir_compressor
		input_height=18*inch
		output_height=12*inch
		center_height=(input_height+output_height)/2.0
		
		basebeam=beam((0,input_height,-1.0), qtens(lambda0, w=0.005, r=Infinity))		
		optics={}
					
		optics[my.INPUT]=m1=reflector("input mirror", center=(0, input_height, 0), width=8*inch, angle=-45)
		
		optics[my.G1]=g1=grating("g1", angle=theta1+90, center=(52*inch,center_height, 0), 
				pitch=1740e3, order=1, width=16*inch, thickness=2.0*inch)
		mybeam=basebeam.clone()
		m1.transport_to_here(mybeam)
		m1.transform(mybeam)	
		g1.transport_to_here(mybeam)
		g1.transform(mybeam)
		mybeam.free_drift(clen) #this is where grating 2 should be
		optics[my.G2]=g2=grating("g2", angle=theta1-90, center=mybeam.x0+(0,0,1e-8), 
				pitch=1740e3, order=1, width=16*inch, thickness=2.0*inch)
		
		optics[my.VR1]=reflector("retro", center=(40*inch, center_height, g2.center[2]),  angle=90.0, width=8*inch, thickness=1.0*inch)
		
		out=optics[my.OUTPUT]=reflector("output mirror", center=(8*inch, output_height, 0.0), 
				width=8.0*inch, thickness=1.0*inch)
		focus=optics[my.FOCUS]=lens("output focus", center=out.center+(35*inch, 0, 7*inch), 
				angle=90-math.atan(0.2)/deg, f=2.0, width=8.0*inch, 
				height=8.0*inch, thickness=1.0*inch).tilt_off_axis(0)
		out.set_direction(g1.center-(0, center_height-output_height, 0), focus)
		
		comp_order=(my.INPUT, my.G1, my.G2, my.VR1, my.G2, my.G1, my.OUTPUT, my.FOCUS)
		
		composite_optic.init(self, "ir compressor", optics, comp_order, None, center=center, angle=0, extras=extras )		

		#prepare to handle to downslope in the beam through the compressor while we are still
		#not rotated to the funny beam axis
		m1label=self.mark_label(my.INPUT)
		g1label=self.mark_label(my.G1)
		m2label=self.mark_label(my.OUTPUT)
		ir_trace=trace_path(self, basebeam.clone())
		path_len=(ir_trace[(m2label,0)].total_drift-ir_trace[(m1label,0)].total_drift)
		slope=(output_height-input_height)/path_len
		
		#distance from entrance to first g1 hit
		g1_first_distance=(ir_trace[(g1label,0)].total_drift-ir_trace[(m1label,0)].total_drift) 
		#distance from entrance to second g1 hit
		g1_second_distance=(ir_trace[(g1label,1)].total_drift-ir_trace[(m1label,0)].total_drift) 
		
		#now, rotate us to the real beam direction
		self.update_coordinates(self.center, self.center, general_optics.eulermat(angle, 0, 0))	
		
		#and set up the aiming points
		self.g1target1=g1.center+(0, (input_height-center_height)+g1_first_distance*slope, 0)		
		self.g1target2=g1.center+(0, (input_height-center_height)+g1_second_distance*slope, 0)	
		out.set_direction(self.g1target2, focus)
Example #3
0
def show_table():
    inch = 0.0254
    lambda0 = 1.054e-6
    spitfire_exit = Numeric.array((2 * inch, 5 * inch, -0.65))
    compressor_entrance = Numeric.array((45.5 * inch, 2.5 * inch, 46.5 * inch))

    optics = {}
    BLUELINE = 'bl'
    SPLIT = 'split'
    START = 'start'
    COMP = 'compressor'
    QUAD = 'quadrupler'
    IR = 'ir'
    IR_COMP = 'ir compressor'
    BE_TURN = 'be_turn'
    IZ_SCREEN = 'iz'

    optics[START] = null_optic("start", spitfire_exit)
    optics[BLUELINE] = blueline = blue_through_ylf()
    optics[SPLIT] = split1 = reflector("splitter1",
                                       center=(2 * inch, 5 * inch, 3 * inch))
    optics[IR] = irline = ir_line()

    comp = optics[COMP] = blue_compressor(38.5,
                                          1.28,
                                          lambda0,
                                          center=compressor_entrance,
                                          angle=270)
    mainbeam = beam(spitfire_exit, qtens(lambda0, spitfire.q0), lambda0)
    # print mainbeam.q
    split1.set_direction(spitfire_exit, blueline)
    blueline.set_entrance_direction(split1)
    blueline.set_exit_direction(comp)
    comp.rotate_to_axis(blueline)
    q = optics[QUAD] = quadrupler(center=(40 * inch, 2.5 * inch, 34.5 * inch),
                                  from_optic=comp[blue_compressor.TM1])
    comp.set_exit_direction(q)
    q.set_entrance_direction(comp)
    blue_sys = composite_optic("blue_sys", optics,
                               [START, SPLIT, BLUELINE, COMP, QUAD], (0, 0, 0),
                               (0, 0, 0), 0)
    irline.set_entrance_direction(spitfire_exit)

    # align compressor table to output of main IR line
    ir_sys = composite_optic("ir_sys", optics, [START, IR], (0, 0, 0),
                             (0, 0, 0), 0).clone()
    pointer = trace_path(ir_sys, mainbeam.clone())[-1]
    pointer.free_drift(1.0)
    optics[IR_COMP] = ircomp = ir_compressor(center=pointer.x0,
                                             angle=math.atan(0.2) / deg)
    ircomp.set_entrance_direction(irline)

    # now, align IZ
    ir_sys = composite_optic("ir_sys", optics, [START, IR, IR_COMP], (0, 0, 0),
                             (0, 0, 0), 0).clone()
    pointer = trace_path(ir_sys, mainbeam.clone())[-1]
    pointer.free_drift(1.0)
    bemir = optics[BE_TURN] = reflector("be turn mirror",
                                        center=pointer.x0,
                                        angle=45.0)
    bemir.transport_to_here(pointer).transform(pointer)
    pointer.free_drift(0.1)
    dz = pointer.q.next_waist()
    pointer.free_drift(dz)
    optics[IZ_SCREEN] = null_optic("IZ", pointer.x0)
    ir_sys = composite_optic("ir_sys", optics,
                             [START, IR, IR_COMP, BE_TURN, IZ_SCREEN],
                             (0, 0, 0), (0, 0, 0), 0)

    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)

    ir_trace = trace_path(ir_sys, mainbeam.clone())
    ir_trace.color = graphite.red
    blue_trace = trace_path(blue_sys, mainbeam.clone())
    blue_trace.color = graphite.blue

    if table_layout:
        g = draw_everything({"sys": whole_table},
                            ir_trace, (-.25, 5), (0, 2.5),
                            three_d=0)
        draw_trace(g, blue_trace)

        #g=draw_everything({"sys":sys}, trace, (0.5,1.1), (0.8,1.1), three_d=0)
        #g=draw_everything({"sys":sys}, trace, (0.7,1.3), (0.9,1.2), three_d=0)
        if show_qd:
            graphite.genOutput(g,
                               'QD',
                               canvasname="Compressor layout",
                               size=(900, 500))
        if show_pdf:
            graphite.genOutput(g,
                               'PDF',
                               canvasname="Tablelayout",
                               size=(900, 500))
    # print trace[0]
    plotq(blue_trace)

    if 0:
        glabel = ircomp.mark_label(ircomp.INPUT)
        m = ir_trace[(glabel, 0)]
        print("\n\n**start**\n\n")
        print(m.incoming_direction, m.direction())
        print(m.incoming_q)
        print(m.incoming_q.qi_moments()[1:3])
        print(m.incoming_q.q_moments()[1:3])
        print(m.incoming_q.qit, "\n")
        print(m.localize_transform_tensor)
        print(m.footprint_q)
        print(m.footprint_q.qi_moments()[1:3])
        print(m.footprint_q.q_moments()[1:3])
        print(m.footprint_q.qit, "\n")
        print(m.globalize_transform_tensor)
        print(m.q)
        print(m.q.qi_moments()[1:3])
        print(m.q.q_moments()[1:3])
        print(m.q.qit, "\n")

    glabel = ircomp.mark_label(ircomp.INPUT)
    # endpoint=ir_trace[(glabel,0)]  #get first hit on optic <glabel>
    endpoint = ir_trace[-1]
    q = endpoint.q

    t, qx0, qy0 = q.qi_moments()
    theta = math.atan2(t[0, 1].real, t[0, 0].real) / deg
    qxx, qyy = endpoint.transform_q_to_table(q)
    dzx, dzy = (1e6 / qxx).real, (1e6 / qyy).real
    print((
        "qxx = %.1f, dzx = %.0f, qyy=%.1f, dzy=%.0f, (in um), theta=%.1f deg" %
        (q.rw(qxx)[1] * 1e6, dzx, q.rw(qyy)[1] * 1e6, dzy, theta)))
Example #4
0
def doit_bc(theta1, clen, lambda0, drawit=0):

    print("\n\n***start blue line trace***\n")
    grating_offset = -0.075
    exit_height = 0
    exit_z = -0.3
    eta1 = 0.0

    optics = {}

    END = 'end'
    optics[END] = null_optic("end", (0.15, exit_height, 0), 0)
    START = 'start'
    optics[START] = null_optic("start", (0, 0, -0.85))

    tracebeam = basebeam.clone()
    system_center = Numeric.array((-0.1, 0, -0.85))

    basebeam = beam(system_center, qtens(lambda0, q=spitfire.q0), lambda0)
    tracebeam.free_drift(-0.2)

    COMP = 'comp'
    comp = optics[COMP] = blue_compressor(theta1,
                                          clen,
                                          lambda0,
                                          center=system_center,
                                          angle=rotation)
    TM2 = 'turn2'
    optics[TM2] = reflector("output turn 2",
                            angle=0,
                            center=(0.15, exit_height, -0.6),
                            width=.025)

    optics[COMP].set_exit_direction(optics[TM2])
    optics[TM2].set_direction(optics[COMP], optics[END])

    sys_order = (START, COMP, TM2, DEMAG1, DEMAG2, END)

    GRATE = comp.mark_label(blue_compressor.GRATE)
    IR1 = comp.mark_label(blue_compressor.IR1)
    IR2 = comp.mark_label(blue_compressor.IR2)

    optic_sys = composite_optic("system",
                                optics,
                                sys_order,
                                center=optics[START].center)

    trace0 = trace_path(optic_sys, tracebeam.shift_lambda(0))
    trace0.color = graphite.green
    trace1 = trace_path(optic_sys, tracebeam.shift_lambda(-0.5e-9))
    trace1.color = graphite.blue
    trace2 = trace_path(optic_sys, tracebeam.shift_lambda(+0.5e-9))
    trace2.color = graphite.red

    try:  # if one of the traces failed, this may not work
        print("Theta1=%.3f eta=%.3f len=%.3f lambda=%.4f" %
              (theta1, eta1, clen, lambda0 * 1e6))
        d0 = trace0[-1]['total_drift']
        d1 = trace1[-1]['total_drift']
        d2 = trace2[-1]['total_drift']
        print((
            "d(lambda0-0.5nm)=%.3f m, d(lambda0+0.5nm)=%.3f m, dt/dl=%.0f ps/nm, "
            % (d1, d2, (d2 - d1) * 1e12 / clight)),
              end=' ')
        print("d2t/dl2 = %.2f ps/nm^2" % ((d2 + d1 - 2.0 * d0) *
                                          (1e12 / clight) * 4))
        spot1info = trace0[(GRATE, 0)]
        spot2info = trace0[(GRATE, 1)]
        ir1info = trace0[(IR1, 0)]
        ir2info = trace0[(IR2, 0)]
        spot_offset = spot2info['position'] - spot1info['position']
        retro_offset = ir2info['position'] - ir1info['position']
        print("Grating offset = %.3f, retro_offset=%.3f" %
              (vec_mag(spot_offset), vec_mag(retro_offset)))
        print("measured vertex length = %.3f" %
              vec_mag(comp[GRATE].center - comp[IR1].center))
        print("dispersion offset on grating = %.3f m / nm" %
              vec_mag(trace2[(GRATE, 1)]['position'] -
                      trace1[(GRATE, 1)]['position']))
        print("final q = ", trace0[-1]['q'])
    except:
        traceback.print_exc()
        pass

    if drawit:
        g = draw_everything({"sys": optic_sys},
                            trace0, (-.9, .1), (-.5, .5),
                            three_d=0)
        #g=draw_everything(optics, trace0, (-2, 2), (-2, 2))
        draw_trace(g, trace1)
        draw_trace(g, trace2)
        graphite.genOutput(g,
                           'QD',
                           canvasname="Compressor layout",
                           size=(600, 500))
Example #5
0
    def init(self, theta1, clen, lambda0, center, angle, extras):
        grating_offset = -0.075
        exit_height = -1.0 * inch
        exit_z = -0.275
        my = blue_compressor
        basebeam = beam((0, 0, -1.0), qtens(lambda0, w=0.001, r=Infinity))
        optics = self.setup_reflectors_blue(basebeam,
                                            theta1,
                                            clen,
                                            grating_offset,
                                            lam0=lambda0,
                                            inside_retro_err=0.0)

        # entrance to compressor, before rotation
        cs = Numeric.array((0, exit_height, -0.44))

        optics[my.IPERI1] = reflector("input peri bot",
                                      angle=0,
                                      center=cs,
                                      width=.025)
        optics[my.IPERI2] = reflector("input peri top",
                                      angle=0,
                                      center=cs + (0.0, -exit_height, 0),
                                      width=.025)

        optics[my.EXP1] = lens("expander diverge",
                               f=-.15).place_between(cs + (-.1, 0, 0),
                                                     optics[my.IPERI1], -0.09)
        optics[my.EXP2] = lens("expander re-coll",
                               f=0.3).place_between(optics[my.IPERI2],
                                                    (0, 0, 0), 0.037)
        #optics[my.EXP2]=lens("expander re-coll", f=0.3).place_between(optics[my.IPERI2], (0,0,0), 0.0357)

        optics[my.IPERI1].set_direction(optics[my.EXP1], optics[my.IPERI2])
        optics[my.IPERI2].set_direction(optics[my.IPERI1], optics[my.EXP2])

        optics[my.OPERI1] = reflector("output peri top",
                                      angle=0,
                                      center=(0, my.y_offset, exit_z),
                                      width=.025)
        optics[my.OPERI2] = reflector("output peri bot",
                                      angle=0,
                                      center=(0, exit_height, exit_z),
                                      width=.025)

        optics[my.TM1] = reflector("output turn 1",
                                   angle=90,
                                   center=(0.30, exit_height, exit_z),
                                   width=.025)

        optics[my.OPERI1].set_direction((0, my.y_offset, 0), optics[my.OPERI2])
        optics[my.OPERI2].set_direction(optics[my.OPERI1], optics[my.TM1])

        comp_order = (my.EXP1, my.IPERI1, my.IPERI2, my.EXP2, my.GRATE, my.IR2,
                      my.IR1, my.GRATE, my.VR1, my.VR2, my.GRATE, my.IR1,
                      my.IR2, my.GRATE, my.OPERI1, my.OPERI2, my.TM1)

        composite_optic.init(self,
                             "compressor",
                             optics,
                             comp_order,
                             None,
                             center=center,
                             angle=angle,
                             extras=extras)
Example #6
0
    def init(self, theta1, clen, lambda0, center, angle, extras):
        my = ir_compressor
        input_height = 18 * inch
        output_height = 12 * inch
        center_height = (input_height + output_height) / 2.0

        basebeam = beam((0, input_height, -1.0),
                        qtens(lambda0, w=0.005, r=Infinity))
        optics = {}

        optics[my.INPUT] = m1 = reflector("input mirror",
                                          center=(0, input_height, 0),
                                          width=8 * inch,
                                          angle=-45)

        optics[my.G1] = g1 = grating("g1",
                                     angle=theta1 + 90,
                                     center=(52 * inch, center_height, 0),
                                     pitch=1740e3,
                                     order=1,
                                     width=16 * inch,
                                     thickness=2.0 * inch)
        mybeam = basebeam.clone()
        m1.transport_to_here(mybeam)
        m1.transform(mybeam)
        g1.transport_to_here(mybeam)
        g1.transform(mybeam)
        mybeam.free_drift(clen)  # this is where grating 2 should be
        optics[my.G2] = g2 = grating("g2",
                                     angle=theta1 - 90,
                                     center=mybeam.x0 + (0, 0, 1e-8),
                                     pitch=1740e3,
                                     order=1,
                                     width=16 * inch,
                                     thickness=2.0 * inch)

        optics[my.VR1] = reflector("retro",
                                   center=(40 * inch, center_height,
                                           g2.center[2]),
                                   angle=90.0,
                                   width=8 * inch,
                                   thickness=1.0 * inch)

        out = optics[my.OUTPUT] = reflector("output mirror",
                                            center=(8 * inch, output_height,
                                                    0.0),
                                            width=8.0 * inch,
                                            thickness=1.0 * inch)
        focus = optics[my.FOCUS] = lens("output focus",
                                        center=out.center +
                                        (35 * inch, 0, 7 * inch),
                                        angle=90 - math.atan(0.2) / deg,
                                        f=2.0,
                                        width=8.0 * inch,
                                        height=8.0 * inch,
                                        thickness=1.0 * inch).tilt_off_axis(0)
        out.set_direction(g1.center - (0, center_height - output_height, 0),
                          focus)

        comp_order = (my.INPUT, my.G1, my.G2, my.VR1, my.G2, my.G1, my.OUTPUT,
                      my.FOCUS)

        composite_optic.init(self,
                             "ir compressor",
                             optics,
                             comp_order,
                             None,
                             center=center,
                             angle=0,
                             extras=extras)

        # prepare to handle to downslope in the beam through the compressor while we are still
        # not rotated to the funny beam axis
        m1label = self.mark_label(my.INPUT)
        g1label = self.mark_label(my.G1)
        m2label = self.mark_label(my.OUTPUT)
        ir_trace = trace_path(self, basebeam.clone())
        path_len = (ir_trace[(m2label, 0)].total_drift -
                    ir_trace[(m1label, 0)].total_drift)
        slope = (output_height - input_height) / path_len

        # distance from entrance to first g1 hit
        g1_first_distance = (ir_trace[(g1label, 0)].total_drift -
                             ir_trace[(m1label, 0)].total_drift)
        # distance from entrance to second g1 hit
        g1_second_distance = (ir_trace[(g1label, 1)].total_drift -
                              ir_trace[(m1label, 0)].total_drift)

        # now, rotate us to the real beam direction
        self.update_coordinates(self.center, self.center,
                                general_optics.eulermat(angle, 0, 0))

        # and set up the aiming points
        self.g1target1 = g1.center + (0, (input_height - center_height) +
                                      g1_first_distance * slope, 0)
        self.g1target2 = g1.center + (0, (input_height - center_height) +
                                      g1_second_distance * slope, 0)
        out.set_direction(self.g1target2, focus)
def show_table():
	inch=0.0254
	lambda0=1.054e-6
	spitfire_exit=Numeric.array((2*inch, 5*inch, -0.65))
	compressor_entrance=Numeric.array((45.5*inch, 2.5*inch, 46.5*inch))
	
	optics={}
	BLUELINE='bl'
	SPLIT='split'
	START='start'
	COMP='compressor'
	QUAD='quadrupler'
	IR='ir'
	IR_COMP='ir compressor'
	BE_TURN='be_turn'
	IZ_SCREEN='iz'
	
	optics[START]=null_optic("start", spitfire_exit)
	optics[BLUELINE]=blueline=blue_through_ylf()	
	optics[SPLIT]=split1=reflector("splitter1", center=(2*inch, 5*inch, 3*inch))
	optics[IR]=irline=ir_line()
	
	comp=optics[COMP]=blue_compressor(38.5, 1.28, lambda0, center=compressor_entrance, angle=270)
	mainbeam=beam( spitfire_exit, qtens(lambda0, spitfire.q0), lambda0)
	#print mainbeam.q
	split1.set_direction(spitfire_exit, blueline)
	blueline.set_entrance_direction(split1)
	blueline.set_exit_direction(comp)
	comp.rotate_to_axis(blueline)
	q=optics[QUAD]=quadrupler(center=(40*inch, 2.5*inch, 34.5*inch), from_optic=comp[blue_compressor.TM1])
	comp.set_exit_direction(q)
	q.set_entrance_direction(comp)
	blue_sys=composite_optic("blue_sys", optics, [START, SPLIT, BLUELINE, COMP, QUAD], (0,0,0), (0,0,0), 0)
	irline.set_entrance_direction(spitfire_exit)
	
	#align compressor table to output of main IR line
	ir_sys=composite_optic("ir_sys", optics, [START, IR], (0,0,0), (0,0,0), 0).clone()
	pointer=trace_path(ir_sys, mainbeam.clone())[-1]
	pointer.free_drift(1.0)
	optics[IR_COMP]=ircomp=ir_compressor(center=pointer.x0, angle=math.atan(0.2)/deg)
	ircomp.set_entrance_direction(irline)

	#now, align IZ
	ir_sys=composite_optic("ir_sys", optics, [START, IR, IR_COMP], (0,0,0), (0,0,0), 0).clone()
	pointer=trace_path(ir_sys, mainbeam.clone())[-1]
	pointer.free_drift(1.0)
	bemir=optics[BE_TURN]=reflector("be turn mirror", center=pointer.x0, angle=45.0)
	bemir.transport_to_here(pointer).transform(pointer)
	pointer.free_drift(0.1)
	dz=pointer.q.next_waist()
	pointer.free_drift(dz)
	optics[IZ_SCREEN]=null_optic("IZ", pointer.x0)
	ir_sys=composite_optic("ir_sys", optics, [START, IR, IR_COMP, BE_TURN, IZ_SCREEN], (0,0,0), (0,0,0), 0)
	
	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)
	
	
	ir_trace=trace_path(ir_sys, mainbeam.clone())
	ir_trace.color=graphite.red
	blue_trace=trace_path(blue_sys, mainbeam.clone())
	blue_trace.color=graphite.blue
	
	if table_layout:
		g=draw_everything({"sys":whole_table}, ir_trace, (-.25,5), (0,2.5), three_d=0)
		draw_trace(g, blue_trace)
		
		#g=draw_everything({"sys":sys}, trace, (0.5,1.1), (0.8,1.1), three_d=0)
		#g=draw_everything({"sys":sys}, trace, (0.7,1.3), (0.9,1.2), three_d=0)
		if show_qd:
			graphite.genOutput(g,'QD',canvasname="Compressor layout", size=(900,500))
		if show_pdf:
			graphite.genOutput(g,'PDF',canvasname="Tablelayout", size=(900,500))
	#print trace[0]
	plotq(blue_trace)
	
	if 0:
		glabel=ircomp.mark_label(ircomp.INPUT)
		m=ir_trace[(glabel,0)]
		print "\n\n**start**\n\n"
		print m.incoming_direction, m.direction()
		print m.incoming_q
		print m.incoming_q.qi_moments()[1:3]
		print m.incoming_q.q_moments()[1:3]
		print m.incoming_q.qit, "\n"
		print m.localize_transform_tensor
		print m.footprint_q
		print m.footprint_q.qi_moments()[1:3]
		print m.footprint_q.q_moments()[1:3]
		print m.footprint_q.qit, "\n"
		print m.globalize_transform_tensor
		print m.q
		print m.q.qi_moments()[1:3]
		print m.q.q_moments()[1:3]
		print m.q.qit, "\n"

	glabel=ircomp.mark_label(ircomp.INPUT)
	#endpoint=ir_trace[(glabel,0)]  #get first hit on optic <glabel>
	endpoint=ir_trace[-1]
	q=endpoint.q
	
	t, qx0, qy0=q.qi_moments()
	theta=math.atan2(t[0,1].real, t[0,0].real)/deg
	qxx, qyy = endpoint.transform_q_to_table(q)
	dzx, dzy = (1e6/qxx).real, (1e6/qyy).real
	print ("qxx = %.1f, dzx = %.0f, qyy=%.1f, dzy=%.0f, (in um), theta=%.1f deg" % 
			(q.rw(qxx)[1]*1e6, dzx, q.rw(qyy)[1]*1e6, dzy, theta ) )
def doit_bc(theta1, clen, lambda0, drawit=0):
	
	print "\n\n***start blue line trace***\n"
	grating_offset=-0.075
	exit_height=0
	exit_z=-0.3
	eta1=0.0
	
	optics={}
	
	END='end'
	optics[END]=null_optic("end", (0.15,exit_height,0), 0)
	START='start'
	optics[START]=null_optic("start", (0,0,-0.85))

	
	tracebeam=basebeam.clone()
	system_center=Numeric.array((-0.1, 0, -0.85))
	
	basebeam=beam(system_center, qtens(lambda0, q=spitfire.q0), lambda0)
	tracebeam.free_drift(-0.2)
		
	COMP='comp'
	comp=optics[COMP]=blue_compressor(theta1, clen, lambda0, center=system_center, angle=rotation)
	TM2='turn2'
	optics[TM2]=reflector("output turn 2", angle=0, center=(0.15,exit_height,-0.6), width=.025)

	optics[COMP].set_exit_direction(optics[TM2])
	optics[TM2].set_direction(optics[COMP], optics[END])

	sys_order=(START, COMP, TM2, DEMAG1, DEMAG2, END)

	GRATE=comp.mark_label(blue_compressor.GRATE)
	IR1=comp.mark_label(blue_compressor.IR1)
	IR2=comp.mark_label(blue_compressor.IR2)
	
	optic_sys=composite_optic("system", optics, sys_order, center=optics[START].center)
	
	trace0=trace_path(optic_sys, tracebeam.shift_lambda(0))
	trace0.color=graphite.green
	trace1=trace_path(optic_sys, tracebeam.shift_lambda(-0.5e-9))
	trace1.color=graphite.blue
	trace2=trace_path(optic_sys, tracebeam.shift_lambda(+0.5e-9))
	trace2.color=graphite.red
			
	try: #if one of the traces failed, this may not work
		print "Theta1=%.3f eta=%.3f len=%.3f lambda=%.4f" % (theta1, eta1, clen, lambda0*1e6)
		d0=trace0[-1]['total_drift']
		d1=trace1[-1]['total_drift']
		d2=trace2[-1]['total_drift']
		print ("d(lambda0-0.5nm)=%.3f m, d(lambda0+0.5nm)=%.3f m, dt/dl=%.0f ps/nm, " % (d1, d2, (d2-d1)*1e12/clight)), 
		print "d2t/dl2 = %.2f ps/nm^2" % ((d2+d1-2.0*d0)*(1e12/clight)*4)
		spot1info=trace0[(GRATE,0)] 
		spot2info=trace0[(GRATE,1)] 
		ir1info=trace0[(IR1,0)]
		ir2info=trace0[(IR2,0)]
		spot_offset=spot2info['position']-spot1info['position']
		retro_offset=ir2info['position']-ir1info['position']
		print "Grating offset = %.3f, retro_offset=%.3f" % (vec_mag(spot_offset), vec_mag(retro_offset))
		print "measured vertex length = %.3f" % vec_mag(comp[GRATE].center-comp[IR1].center)
		print "dispersion offset on grating = %.3f m / nm" % vec_mag(trace2[(GRATE,1)]['position']-trace1[(GRATE,1)]['position'])
		print "final q = ", trace0[-1]['q']
	except:
		traceback.print_exc()
		pass
				
	if drawit:
		g=draw_everything({"sys":optic_sys}, trace0, (-.9, .1), (-.5, .5), three_d=0)
		#g=draw_everything(optics, trace0, (-2, 2), (-2, 2))
		draw_trace(g, trace1)
		draw_trace(g, trace2)
		graphite.genOutput(g,'QD',canvasname="Compressor layout", size=(600,500))