Example #1
0
def placeWolterPair(rays, misalign=np.zeros(6)):
    """
    Place the X-ray test mirror pair in the beam path.
    Assume rays are at XY plane with -z mean direction
    Nominal position of intersection plane is 1.5 m
    past chamber entrance with mirror optical axis
    coincident with chamber optical axis.
    Can supply misalignment about X=0,Y=0 in intersection plane.
    """
    #Go to nominal intersection plane
    tran.transform(rays, 0, 0, -1500., 0, 0, 0)
    #Apply misalignments
    tran.transform(rays, *misalign)
    #Go to focus and place primary
    tran.transform(rays, 0, 0, -8400, 0, 0, 0)
    pdb.set_trace()
    surf.wolterprimary(rays, 220., 8400.)
    tran.reflect(rays)
    pdb.set_trace()
    #Vignette rays not landing in active mirror area
    indz = np.logical_and(rays[3] > 8426., rays[3] < 8526.)
    ind = np.logical_and(np.abs(rays[2]) < 50., indz)
    rays = tran.vignette(rays, ind=ind)
    #Place secondary
    pdb.set_trace()
    surf.woltersecondary(rays, 220., 8400.)
    tran.reflect(rays)
    #Vignette rays not landing in active mirror area
    indz = np.logical_and(rays[3] > 8276., rays[3] < 8376.)
    ind = np.logical_and(np.abs(rays[2]) < 50., indz)
    rays = tran.vignette(rays, ind=ind)
    #Go back up to nominal intersection plane
    tran.transform(rays, 0, 0, 8400, 0, 0, 0)
    tran.itransform(rays, *misalign)
    return rays
Example #2
0
def distortTrace(cone1,sag1,roc1,cone2,sag2,roc2,despace=0.,secondaryTilt=0.,\
                 nominal=True):
    """
    Trace rays through a Wolter mirror pair with low
    order distortions. Distortions can be applied to
    either primary or secondary or both.
    axial sag, azimuthal sag, and cone angle are included.
    
    """
    #Define ray subannulus
    r1 = surf.con.primrad(8600., 1000., 8400.)
    ang = 260. / 1000.  #arc length over radius is angular extent
    rays = sources.subannulus(1000., r1, ang, 10**3)
    tran.transform(rays, 0, 0, 0, np.pi, 0, 0)  #Point in -z
    tran.transform(rays, 0, 0, -10000, 0, 0, 0)  #Converge from above

    #Trace to primary
    surf.primaryLL(rays,1000.,8400.,8600,8400,ang,[cone1,sag1,roc1],\
                   [1,2,0],[0,0,2])
    #Vignette rays missing
    ind = np.logical_and(rays[3] < 8600., rays[3] > 8400.)
    rays = tran.vignette(rays, ind)
    numin = float(len(rays[1]))
    #Reflect
    tran.reflect(rays)

    #Apply secondary misalignment
    tran.transform(rays, surf.con.secrad(8300., 1000., 8400.), 0, 8300, 0, 0,
                   0)
    tran.transform(rays, 0, 0, despace, 0, secondaryTilt, 0)
    tran.itransform(rays, surf.con.secrad(8300., 1000., 8400.), 0, 8300, 0, 0,
                    0)
    #Trace to secondary
    surf.secondaryLL(rays,1000.,8400.,8400.,8200.,ang,[cone2,sag2,roc2],\
                     [1,2,0],[0,0,2])
    #Vignette rays missing
    ind = np.logical_and(rays[3] < 8400., rays[3] > 8200.)
    rays = tran.vignette(rays, ind)
    numout = float(len(rays[1]))
    #Reflect
    tran.reflect(rays)
    #Reverse secondary misalignment
    tran.transform(rays, surf.con.secrad(8300., 1000., 8400.), 0, 8300, 0, 0,
                   0)
    tran.itransform(rays, 0, 0, despace, 0, secondaryTilt, 0)
    tran.itransform(rays, surf.con.secrad(8300., 1000., 8400.), 0, 8300, 0, 0,
                    0)

    #Go to focus
    if nominal is True:
        surf.flat(rays)
    else:
        surf.focusI(rays)

    #Return merit function
    return rays  #anal.hpd(rays)/8400.,numout/numin
Example #3
0
def mirrorPair(N,srcdist=89.61e3+1.5e3,primalign=np.zeros(6),\
               secalign=np.zeros(6),rrays=False,f=None,\
               plist=[[0],[0],[0]],hlist=[[0],[0],[0]]):
    """
    SLF finite source trace
    """
    #Establish subannulus of rays
    rays = sources.subannulus(220., 221., 100. / 220., N, zhat=-1.)
    #Transform to node position
    tran.transform(rays, 220, 0, 0, 0, 0, 0)
    #Set up finite source distance
    raydist = sqrt(srcdist**2 + rays[1]**2 + rays[2]**2)
    rays[4] = rays[1] / raydist
    rays[5] = rays[2] / raydist
    rays[6] = -sqrt(1. - rays[4]**2 - rays[5]**2)

    #Place mirror pair
    coords = [tran.tr.identity_matrix()] * 4
    tran.transform(rays,-220+conic.primrad(8450.,220.,8400.),0,50.,0,0,0,\
                   coords=coords)
    tran.transform(rays, *primalign, coords=coords)
    tran.transform(rays,-conic.primrad(8450.,220.,8400.),0,-8450.,0,0,0,\
                   coords=coords)
    ##    surf.wolterprimary(rays,220.,8400.)
    surf.primaryLL(rays, 220., 8400., 8500., 8400., 100. / 220, *plist)
    rays = tran.vignette(rays,ind=np.logical_and(rays[3]<8500.,\
                                                 rays[3]>8400.))
    tran.reflect(rays)
    #Place secondary in primary's reference frame
    tran.transform(rays,conic.secrad(8350.,220.,8400.),0,8350.,0,0,0,\
                   coords=coords)
    tran.transform(rays, *secalign, coords=coords)
    tran.itransform(rays,conic.secrad(8350.,220.,8400.),0,8350.,0,0,0,\
                   coords=coords)
    ##    surf.woltersecondary(rays,220.,8400.)
    surf.secondaryLL(rays, 220., 8400., 1., 8400., 8300., 100. / 220, *hlist)
    rays = tran.vignette(rays,ind=np.logical_and(rays[3]<8400.,\
                                                 rays[3]>8300.))
    tran.reflect(rays)

    #Go back to nominal node reference frame and down to focus
    rays = tran.applyT(rays, coords, inverse=True)

    if f is None:
        f = -surf.focusI(rays)
        print f
    else:
        tran.transform(rays, 0, 0, -f, 0, 0, 0)
        surf.flat(rays)

    if rrays is True:
        return rays

    return anal.hpd(rays)/f * 180/np.pi * 60.**2, \
           airnp.mean(rays[1]), np.mean(rays[2])
Example #4
0
def sourceToChamber(N, misalign=np.zeros(6)):
    """
    Trace randomly sampled rays from the TruFocus X-ray source
    to the 1.22 m diameter entrance to the test chamber.
    A-B from Jeff K.'s memo is 89.61
    Use oversized sub-apertured annulus, applying translations
    """
    #Define some Wolter parameters
    r1 = conic.primrad(8600., 220., 8400.)
    dphi = 100. / 220. / 2
    #Set up subannulus
    rays = sources.subannulus(220., r1, dphi * 1.25, N)
    #Set direction cosines
    srcdist = 89.61e3 + (1.5e3 - misalign[2])
    raydist = sqrt(srcdist**2+\
                   (rays[1]-misalign[0])**2+\
                   (rays[2]-misalign[1])**2)
    l = (rays[1] - misalign[0]) / raydist
    m = (rays[2] - misalign[1]) / raydist
    n = -sqrt(1. - l**2 - m**2)
    rays = [
        rays[0], rays[1], rays[2], rays[3], l, m, n, rays[7], rays[8], rays[9]
    ]
    #Go to mirror node and apply rotational misalignment
    tran.transform(rays, 220., 0, 0, misalign[3], misalign[4], misalign[5])
    tran.transform(rays, -220., 0, 0, 0, 0, 0)
    #Place Wolter surfaces
    tran.transform(rays, 0, 0, -8400., 0, 0, 0)
    surf.wolterprimary(rays, 220., 8400.)
    tran.reflect(rays)
    #Vignette rays not landing in active mirror area
    indz = np.logical_and(rays[3] > 8426., rays[3] < 8526.)
    ind = np.logical_and(np.abs(rays[2]) < 50., indz)
    rays = tran.vignette(rays, ind=ind)
    #Place secondary
    surf.woltersecondary(rays, 220., 8400.)
    tran.reflect(rays)
    #Vignette rays not landing in active mirror area
    indz = np.logical_and(rays[3] > 8276., rays[3] < 8376.)
    ind = np.logical_and(np.abs(rays[2]) < 50., indz)
    rays = tran.vignette(rays, ind=ind)
    #Go back up to intersection plane
    tran.transform(rays, 0, 0, 8400, 0, 0, 0)
    #Reverse misalignments
    tran.itransform(rays, -220., 0, 0, 0, 0, 0)
    tran.itransform(rays, 0, 0, 0, misalign[3], misalign[4], misalign[5])
    tran.itransform(rays, 220, 0, 0, 0, 0, 0)
    #Now back in nominal intersection coordinate system
    #Go to focus
    f = -9253.3858232
    tran.transform(rays, 0, 0, f, 0, 0, 0)
    surf.flat(rays)

    return rays  #anal.hpd(rays)/abs(f)*60**2*180/pi
Example #5
0
def pairRaytrace(secondaryTilt, despace):
    """Trace the distorted mirror pair. Assume no gap for now.
    Vignette rays that land outside active mirror areas."""
    #Define ray subannulus
    r1 = surf.con.primrad(8600., 1000., 8400.)
    ang = 260. / 1000.  #arc length over radius is angular extent
    rays = sources.subannulus(1000., r1, ang, 10**3)
    tran.transform(rays, 0, 0, 0, np.pi, 0, 0)  #Point in -z
    tran.transform(rays, 0, 0, -10000, 0, 0, 0)  #Converge from above

    #Trace to primary
    surf.primaryLL(rays, 1000., 8400., 8600, 8400, ang, res[0], res[2], res[1])
    #Vignette rays missing
    ind = np.logical_and(rays[3] < 8600., rays[3] > 8400.)
    rays = tran.vignette(rays, ind)
    numin = float(len(rays[1]))
    #Reflect
    tran.reflect(rays)
    #Bring to midplane of despaced secondary

    #Apply secondary misalignment
    tran.transform(rays, surf.con.secrad(8300., 1000., 8400.), 0, 8300, 0, 0,
                   0)
    tran.transform(rays, 0, 0, despace, 0, secondaryTilt, 0)
    tran.itransform(rays, surf.con.secrad(8300., 1000., 8400.), 0, 8300, 0, 0,
                    0)
    #Trace to secondary
    surf.secondaryLL(rays, 1000., 8400., 8400., 8200., ang, res2[0], res2[2],
                     res2[1])
    #Vignette rays missing
    ind = np.logical_and(rays[3] < 8400., rays[3] > 8200.)
    rays = tran.vignette(rays, ind)
    numout = float(len(rays[1]))
    #Reflect
    tran.reflect(rays)
    #Reverse secondary misalignment
    tran.transform(rays, surf.con.secrad(8300., 1000., 8400.), 0, 8300, 0, 0,
                   0)
    tran.itransform(rays, 0, 0, despace, 0, secondaryTilt, 0)
    tran.itransform(rays, surf.con.secrad(8300., 1000., 8400.), 0, 8300, 0, 0,
                    0)

    #Go to focus
    surf.focusI(rays)

    #Get centroid
    cx, cy = anal.centroid(rays)

    #Return merit function
    return anal.rmsCentroid(
        rays) / 8400. * 180 / np.pi * 60**2, numout / numin, cx, cy
Example #6
0
def singleOptic2(n,misalign=np.zeros(6),srcdist=89.61e3+1.5e3,az=100.,\
                 returnRays=False,f=None,\
                 plist=[[0],[0],[0]],\
                 ax=100.):
    """Alternative SLF finite source trace"""
    #Establish subannulus of rays
    r0 = conic.primrad(8426., 220., 8400.)
    r1 = conic.primrad(8426. + ax, 220., 8400.)
    rays = sources.subannulus(r0, r1, az / 220., n, zhat=-1.)
    #Transform to node position
    tran.transform(rays, 220, 0, 0, 0, 0, 0)
    #Set up finite source distance
    raydist = sqrt(srcdist**2 + rays[1]**2 + rays[2]**2)
    l = rays[1] / raydist
    m = rays[2] / raydist
    n = -sqrt(1. - l**2 - m**2)
    rays = [
        raydist, rays[1], rays[2], rays[3], l, m, n, rays[7], rays[8], rays[9]
    ]
    #Align perfectly to beam
    tran.steerX(rays)
    #Apply misalignment
    tran.transform(rays, *misalign)
    #Place mirror
    tran.transform(rays, -220., 0, -8400., 0, 0, 0)
    ##    surf.wolterprimarynode(rays,220,8400.)
    surf.primaryLL(rays, 220., 8400., 8426. + ax, 8426., az / 220., *plist)
    rays = tran.vignette(rays,ind=np.logical_and(rays[3]<8400.+ax,\
                                                 rays[3]>8400.))
    tran.itransform(rays, -220., 0., -8400., 0, 0, 0)
    #Vignette rays not landing in active mirror area
    ind = np.logical_and(rays[3] > 26., rays[3] < (26. + ax))
    ##    ind = np.logical_and(np.abs(rays[2])<az/2.,indz)
    rays = tran.vignette(rays, ind=ind)
    #Reverse misalignment
    tran.itransform(rays, *misalign)
    #Reflect and go to surface
    tran.reflect(rays)
    if f is None:
        f = surf.focusI(rays)
    else:
        tran.transform(rays, 0, 0, f, 0, 0, 0)
        surf.flat(rays)
    #Get centroid
    cx, cy = anal.centroid(rays)

    if returnRays is True:
        return rays

    return anal.hpd(rays) / abs(f) * 180 / pi * 60**2, f, cx
Example #7
0
def tracePrimary(primCoeffs=None, primalign=np.zeros(6)):
    """
    Trace rays from focus to primary, off retroreflector,
    then back to focus. Return spot centroids.
    """
    #Set up source
    primfoc = conic.primfocus(220., 8400.)
    r1 = conic.primrad(8500., 220., 8400.)
    rays = sources.subannulus(220., r1, 100. / 220, 100000, zhat=1.)
    tran.pointTo(rays, 0., 0., -primfoc, reverse=1.)
    theta = np.arctan2(rays[2], rays[1])

    #Trace to primary
    tran.transform(rays, *primalign)
    tran.transform(rays, 0., 0, -8400., 0, 0, 0)
    if primCoeffs is None:
        surf.wolterprimary(rays, 220., 8400.)
    else:
        surf.primaryLL(rays,220.,8400.,8500.,8400.,100./220.,\
                       *primCoeffs)
    tran.transform(rays, 0, 0, 8400., 0, 0, 0)
    tran.itransform(rays, *primalign)
    tran.reflect(rays)

    #Reflect and come back
    tran.transform(rays, 0, 0, 400., 0, 0, 0)
    surf.flat(rays)
    tran.reflect(rays)
    tran.transform(rays, 0, 0, -400., 0, 0, 0)

    #Trace to primary
    tran.transform(rays, *primalign)
    tran.transform(rays, 0., 0, -8400., 0, 0, 0)
    if primCoeffs is None:
        surf.wolterprimary(rays, 220., 8400.)
    else:
        surf.primaryLL(rays,220.,8400.,8500.,8400.,100./220.,\
                       *primCoeffs)
    ind = np.logical_and(rays[3] > 8400., rays[3] < 8500.)
    tran.vignette(rays, ind=ind)
    tran.transform(rays, 0, 0, 8400., 0, 0, 0)
    tran.itransform(rays, *primalign)
    tran.reflect(rays)

    #Go to primary focus
    tran.transform(rays, 0, 0, -primfoc, 0, 0, 0)
    surf.flat(rays)

    return rays, theta
Example #8
0
def singleOptic(N, misalign=np.zeros(6)):
    """Trace single primary mirror from SLF finite
    source distance.
    """
    #Define some Wolter parameters
    r1 = conic.primrad(8600., 220., 8400.)
    dphi = 100. / 220. / 2
    #Set up subannulus
    rays = sources.subannulus(220., r1, dphi * 1.25, N)
    ##    #Set direction cosines
    ##    srcdist = 89.61e3+(1.5e3-misalign[2])
    ##    raydist = sqrt(srcdist**2+\
    ##                   (rays[1]-misalign[0])**2+\
    ##                   (rays[2]-misalign[1])**2)
    ##    l = (rays[1]-misalign[0])/raydist
    ##    m = (rays[2]-misalign[1])/raydist
    ##    n = -sqrt(1. - l**2 - m**2)
    ##    rays = [rays[0],rays[1],rays[2],rays[3],l,m,n,rays[7],rays[8],rays[9]]
    #Go to mirror node and apply rotational misalignment
    tran.transform(rays, 220., 0, 0, misalign[3], misalign[4], misalign[5])
    tran.transform(rays, -220., 0, 0, 0, 0, 0)
    #Place Wolter surfaces
    tran.transform(rays, 0, 0, -8400., 0, 0, 0)
    surf.wolterprimary(rays, 220., 8400.)
    tran.reflect(rays)
    #Vignette rays not landing in active mirror area
    indz = np.logical_and(rays[3] > 8426., rays[3] < 8526.)
    ind = np.logical_and(np.abs(rays[2]) < 50., indz)
    rays = tran.vignette(rays, ind=ind)
    #Go to focus
    surf.flat(rays)
    f = surf.focusI(rays) - 8400.

    return rays  #anal.hpd(rays)/abs(f)*180/pi*60**2,abs(f)
Example #9
0
def singleEllipse(n,misalign=np.zeros(6),srcdist=89.61e3+1.5e3,az=100.,\
                 returnRays=False,f=None,\
                 plist=[[0],[0],[0]],\
                 ax=100.,psi=psiE):
    """Alternative SLF finite source trace"""
    #Establish subannulus of rays
    r0 = conic.primrad(8426., 220., 8400.)
    r1 = conic.primrad(8426. + ax, 220., 8400.)
    rays = sources.subannulus(r0, r1, az / 220., n, zhat=-1.)
    tran.pointTo(rays, 0., 0., srcdist, reverse=1.)
    #Transform to node position
    tran.transform(rays, 220, 0, 0, 0, 0, 0)
    #Apply misalignment
    tran.transform(rays, *misalign)
    #Place mirror
    tran.transform(rays, -220., 0, -8400., 0, 0, 0)
    ##    surf.wolterprimarynode(rays,220,8400.)
    surf.ellipsoidPrimaryLL(rays,220.,8400.,srcdist,psi,8426.+ax,8426.,\
                            az/220.,*plist)
    tran.itransform(rays, -220., 0., -8400., 0, 0, 0)
    #Vignette rays not landing in active mirror area
    ind = np.logical_and(rays[3] > 26., rays[3] < (26. + ax))
    ##    ind = np.logical_and(np.abs(rays[2])<az/2.,indz)
    rays = tran.vignette(rays, ind=ind)
    #Reverse misalignment
    tran.itransform(rays, *misalign)
    #Reflect and go to surface
    tran.reflect(rays)
    if f is None:
        f = surf.focusI(rays)
    else:
        tran.transform(rays, 0, 0, f, 0, 0, 0)
        surf.flat(rays)
    #Get centroid
    cx, cy = anal.centroid(rays)

    if returnRays is True:
        return rays

    return anal.hpd(rays) / abs(f) * 180 / pi * 60**2  #,f,cx
Example #10
0
def turnoffChannels(rays, weights, flags, off):
    """
    Create vector to turn off certain channels. Figure out
    new resolution and area.
    """
    #Compute original RMS and sum of weights
    area0 = np.sum(weights)
    rms0 = np.sqrt(np.average(rays[2]**2, weights=weights))

    if off is None:
        return area0, rms0 * 2.35 * 180 / np.pi * 60**2 / 12e3

    #And all of the booleans
    tf = (flags != off[0])
    for o in off[1:]:
        tf = (tf) & (flags != o)
    rays = tran.vignette(rays, ind=tf)
    weights = weights[tf]

    #Return RMS and sum of weights
    return np.sum(weights),np.sqrt(np.average(rays[2]**2,\
                            weights=weights))/12e3*180/np.pi*60**2*2.35
Example #11
0
def ellipsoidPair(N,srcdist=89.61e3+1.5e3,primalign=np.zeros(6),\
               secalign=np.zeros(6),rrays=False,f=None,\
                  plist=[[0],[0],[0]],hlist=[[0],[0],[0]]):
    """
    Trace an ellipsoid-hyperboloid telescope in SLF geometry.
    plist is [pcoeff,pax,paz]
    """
    #Establish subannulus of rays
    r1 = conic.ellipsoidRad(srcdist, 1., 220., 8400., 8500.)
    rays = sources.subannulus(220., r1, 100. / 220., N, zhat=-1.)
    tran.pointTo(rays, 0, 0, srcdist, reverse=1.)
    ##    #Transform to node position
    ##    tran.transform(rays,220,0,0,0,0,0)
    ##    #Set up finite source distance
    ##    raydist = sqrt(srcdist**2+rays[1]**2+rays[2]**2)
    ##    rays[4] = rays[1]/raydist
    ##    rays[5] = rays[2]/raydist
    ##    rays[6] = -sqrt(1.-rays[4]**2-rays[5]**2)

    #Place mirror pair
    coords = [tran.tr.identity_matrix()] * 4
    prad = conic.ellipsoidRad(srcdist, 1., 220., 8400., 8450.)
    tran.transform(rays,prad,0,50.,0,0,0,\
                   coords=coords)
    tran.transform(rays, *primalign, coords=coords)
    tran.transform(rays,-prad,0,-8450.,0,0,0,\
                   coords=coords)
    surf.ellipsoidPrimaryLL(rays,220.,8400.,srcdist,1.,8500.,8400.,100./220,\
                            *plist)
    #Vignette any rays outside of active area
    rays = tran.vignette(rays,ind=np.logical_and(rays[3]<8500.,\
                                                 rays[3]>8400.))
    ##    surf.ellipsoidPrimary(rays,220.,8400.,srcdist,1.)
    tran.reflect(rays)
    #Place secondary in primary's reference frame
    srad = conic.ehSecRad(srcdist, 1., 220., 8400., 8350.)
    tran.transform(rays,srad,0,8350.,0,0,0,\
                   coords=coords)
    tran.transform(rays, *secalign, coords=coords)
    tran.itransform(rays,srad,0,8350.,0,0,0,\
                   coords=coords)
    ##    surf.ellipsoidSecondary(rays,220.,8400.,srcdist,1.)
    surf.ellipsoidSecondaryLL(rays,220.,8400.,srcdist,1.,8400.,8300.,100./220,\
                              *hlist)
    rays = tran.vignette(rays,ind=np.logical_and(rays[3]<8400.,\
                                                 rays[3]>8300.))
    ang = anal.grazeAngle(rays)
    tran.reflect(rays)

    #Go back to nominal node reference frame and down to focus
    rays = tran.applyT(rays, coords, inverse=True)

    if f is None:
        f = -surf.focusI(rays)
        print f
    else:
        tran.transform(rays, 0, 0, -f, 0, 0, 0)
        surf.flat(rays)

    if rrays is True:
        return rays

    return anal.hpd(rays) / f * 180 / np.pi * 60.**2
Example #12
0
def reproduceChevron(num,rin=220.,axlength=100.,azwidth=50.,F=8.4e3,\
                     hubdist=8e3,radapprox=False,order=1,wave=.83,f=None,\
                     autofocus=False,returnMet=False,yaw=0.,N=1,\
                     gratalign=np.zeros(6)):
    #Create Wolter beam
    rout = conic.primrad(F+axlength,rin,F)
    rays = source.subannulus(rin,rout,azwidth/rin,num,zhat=-1.)
    surf.wolterprimary(rays,rin,F)
    tran.reflect(rays)
    surf.woltersecondary(rays,rin,F)
    tran.reflect(rays)
    tran.transform(rays,0,0,0,0,0,np.pi/2)

    #Go to focus
    surf.focusI(rays)
    #Steer beam
    coords = [tran.tr.identity_matrix()]*4
    tran.transform(rays,0,0,0,np.mean(rays[5]),-np.mean(rays[4]),0)
    pdb.set_trace()
    #Go up to grating
    tran.transform(rays,0,0,hubdist/np.cos(1.5*np.pi/180),0,0,0)
    #Go to incidence angle
    tran.transform(rays,0,0,0,91.5*np.pi/180,0,0)
    tran.transform(rays,0,0,0,0,0,yaw)
    #Apply grating misalignment
    tran.transform(rays,*gratalign)
    surf.flat(rays)
    #Get rid of rays outside grating
    ind = np.logical_and(np.abs(rays[2])<16,np.abs(rays[1])<25/2.)
    rays = tran.vignette(rays,ind=ind)

    plt.figure('grat')
    plt.clf()
    plt.plot(rays[1],rays[2],'.')
    plt.title('Beam Footprint')

    #Place grating
    if radapprox is False:
        tran.reflect(rays)
        tran.transform(rays,0,-hubdist,0,0,0,0)
        tran.radgrat(rays,160./hubdist,order,wave)
        tran.transform(rays,0,hubdist,0,0,0,0)
    else:
        tran.reflect(rays)
        gratedges = np.linspace(-16.,16.,N+1)
        for i in range(N):
            ind = np.logical_and(rays[2]>gratedges[i],\
                             rays[2]<gratedges[i+1])
            d = (hubdist+np.mean(gratedges[i:i+2]))/hubdist*160.
            if np.sum(ind)>0:
                tran.grat(rays,d,-order,wave,ind=ind)


    #Go to focal plane
    tran.transform(rays,*gratalign)
    tran.transform(rays,0,0,0,0,0,-yaw)
    tran.transform(rays,0,0,0,-91.5*np.pi/180.,0,0)
    tran.transform(rays,0,0,0,0,0,np.pi/2)

    if f is not None:
        try:
            tran.transform(rays,0,0,-f,0,0,0)
            surf.flat(rays)
        except:
            pdb.set_trace()

    if autofocus is True:
        surf.focusY(rays)

    if returnMet is True:
        return anal.hpdY(rays)/F*180/np.pi*60**2

    plt.figure('LSF')
    plt.clf()
    plt.plot(rays[1],rays[2],'.')
    plt.title('LSF')
    
    return rays
Example #13
0
def test(N,rin=700.,rout=737.,azwidth=66.,srcdist=89.61e3+1.5e3,\
         hubdist=11832.911,yaw=0.,wave=6.,order=1,\
         opgalign=[0,0,0,0,0,0],f=None,\
         rrays=False,glob=False,rcen=False,\
         groll=0.,gyaw=0.,gpitch=0.,\
         scatter=False,coordin=None,\
         radapprox=False):
    """
    Trace through the SPO module, then place the OPG module
    at its nominal position, allowing for misalignments about the
    center of the OPG module. The module tolerances can be
    investigated by a coordinate transformation around the
    OPG module placement.
    """
    #Trace through SPO module
    rays = traceSPO(N,rin=rin,rout=rout,azwidth=azwidth,srcdist=srcdist,\
                    scatter=scatter)

    #Find the nominal OPG module location using formalism
    #from Flanagan's SPIE paper
    #Go to focus, steer out X and Y, then go up a distance
    #defined using Flangan formula, this should leave you
    #at the center of the beam, therefore the center of the
    #OPG module
    if coordin is None:
        coords = [tran.tr.identity_matrix()]*4
        tran.transform(rays,0,0,0,0,-np.mean(rays[4]),0,coords=coords)
        #tran.steerX(rays,coords=coords)
        #tran.steerY(rays,coords=coords)
        tran.transform(rays,0,0,0,pi-np.mean(rays[5]),0,0,coords=coords)
        f0 = surf.focusI(rays,coords=coords)
        tran.transform(rays,np.mean(rays[1]),np.mean(rays[2]),0,0,0,0,\
                       coords=coords)
        tran.transform(rays,0,0,0,0,pi,0,coords=coords)
        tran.transform(rays,0,0,11832.911*np.cos(1.5*np.pi/180),0,0,0,coords=coords)
        tran.transform(rays,0,0,0,0,1.5*np.pi/180,0,coords=coords)
    else:
        rays = tran.applyT(rays,coordin)
        coords = np.copy(coordin)
    surf.flat(rays)
    #Now at center of central grating, with -z pointing toward hub
    tran.transform(rays,*opgalign,coords=coords)
    rays,record = traceOPG(rays,hubdist=hubdist,yaw=yaw,wave=wave,order=order,\
                           gyaw=gyaw,groll=groll,gpitch=gpitch,\
                           radapprox=radapprox)
    tran.itransform(rays,*opgalign,coords=coords)
    #Should be at same reference frame, with rays now diffracted
    if np.sum(record)==0:
        pdb.set_trace()
    rays = tran.vignette(rays,ind=record>0)
    record = record[record>0]

    #Trace to detector and determine LSF
    rays = tran.applyT(rays,coords,inverse=True)
    #surf.focusI(rays)
    if f is not None:
        try:
            tran.transform(rays,0,0,-f,0,0,0)
            surf.flat(rays)
        except:
            pdb.set_trace()

    if rcen is True:
        return anal.centroid(rays)

    if rrays is True:
        if glob is True:
            tran.transform(rays,0,0,f,0,0,0)
        return rays,record

    #Return LSF in arcseconds
    return anal.hpdY(rays)/12e3*180/pi*60**2