示例#1
0
def traceSPO(R, L, F, N, M, span=pi / 12, d=.605, t=.775):
    """Trace SPO surfaces sequentially. Collect rays from
    each SPO shell and set them to the PT rays at the end.
    Start at the inner radius, use the wafer and pore thicknesses
    to vignette and compute the next radius, loop while
    radius is less than Rout.
    """
    #Ray bookkeeping arrays
    tx = np.zeros(M * N)
    ty = np.zeros(M * N)
    tz = np.zeros(M * N)
    tl = np.zeros(M * N)
    tm = np.zeros(M * N)
    tn = np.zeros(M * N)
    tux = np.zeros(M * N)
    tuy = np.zeros(M * N)
    tuz = np.zeros(M * N)

    #Loop through shell radii and collect rays
    for i in range(M):
        #Set up source annulus
        PT.subannulus(R[i], R[i] + d, span, N)
        #Transform rays to be above xy plane
        PT.n = -PT.n
        PT.transform(0, 0, -100., 0, 0, 0)
        #Trace to primary
        PT.spoPrimary(R[i], F)
        PT.reflect()
        #Vignette
        ind = np.logical_and(PT.z <= L[i], PT.z >= 0.)
        if np.sum(ind) < N:
            pdb.set_trace()
        PT.vignette(np.logical_and(PT.z <= L[i], PT.z >= 0.))
        #Trace to secondary
        PT.spoSecondary(R[i], F)
        PT.reflect()
        #Vignette
        ind = np.logical_and(PT.z <= 0., PT.z >= -L[i])
        if np.sum(ind) < N:
            pdb.set_trace()
        PT.vignette(ind)
        #Collect rays
        try:
            tx[i * N:(i + 1) * N] = PT.x
            ty[i * N:(i + 1) * N] = PT.y
            tz[i * N:(i + 1) * N] = PT.z
            tl[i * N:(i + 1) * N] = PT.l
            tm[i * N:(i + 1) * N] = PT.m
            tn[i * N:(i + 1) * N] = PT.n
            tux[i * N:(i + 1) * N] = PT.ux
            tuy[i * N:(i + 1) * N] = PT.uy
            tuz[i * N:(i + 1) * N] = PT.uz
        except:
            pdb.set_trace()

    #Set to PT rays
    try:
        PT.x = tx
        PT.y = ty
        PT.z = tz
        PT.l = tl
        PT.m = tm
        PT.n = tn
        PT.ux = tux
        PT.uy = tuy
        PT.uz = tuz
    except:
        pdb.set_trace()

    return
示例#2
0
def traceCyl(align):
    """Traces a cylindrical approximation to Wolter I geometry
    Assumes 1 m radius of curvature in accordance with OAB samples
    align is a 12 element array giving the transformations to be
    applied to each mirror
    Uses identical set of rays each run defined upon module import
    Adds a restraint such that any vignetting over 25% results in
    a huge merit function
    """

    #Set up source
    np.random.seed(5)
    a, p, d, e = con.woltparam(1000., 10000.)
    r0 = con.primrad(10025., 1000., 10000.)
    r1 = con.primrad(10125., 1000., 10000.)
    dphi = 100. / 1000.
    PT.subannulus(r0, r1, dphi, 10**4)
    PT.transform(0, 0, 0, np.pi, 0, 0)
    PT.transform(0, 0, -10500., 0, 0, 0)

    #Trace primary cylinder: go to tangent point at center
    #of mirror and then rotate to cone angle, then move
    #to new cylinder axis and tracecyl
    rt = con.primrad(10075., 1000., 10000.)
    PT.transform(rt, 0, 0, 0, a, 0)
    PT.transform(*align[:6])
    PT.transform(0, 0, 0, np.pi / 2, 0, 0)
    PT.transform(-1000., 0, 0, 0, 0, 0)
    PT.cyl(1000.)

    #Vignette rays missing physical surface
    ind = np.logical_and(abs(PT.z) < 50., abs(PT.y) < 50.)
    PT.vignette(ind=ind)

    #Reflect and reverse transformations
    PT.reflect()
    PT.transform(1000., 0, 0, 0, 0, 0)
    PT.itransform(0, 0, 0, np.pi / 2, 0, 0)
    PT.itransform(*align[:6])
    PT.itransform(rt, 0, 0, 0, a, 0)

    #Trace secondary cylinder: same principle as before
    rt = con.secrad(9925., 1000., 10000.)
    PT.transform(0, 0, -150., 0, 0, 0)
    PT.transform(rt, 0, 0, 0, 3 * a, 0)
    PT.transform(*align[6:])
    PT.transform(0, 0, 0, np.pi / 2, 0, 0)
    PT.transform(-1000., 0, 0, 0, 0, 0)
    PT.cyl(1000.)

    #Vignette rays missing physical surface
    ind = np.logical_and(abs(PT.z) < 50., abs(PT.y) < 50.)
    PT.vignette(ind=ind)

    #Reflect and reverse transformations
    PT.reflect()
    PT.transform(1000., 0, 0, 0, 0, 0)
    PT.itransform(0, 0, 0, np.pi / 2, 0, 0)
    PT.itransform(*align[6:])
    PT.itransform(rt, 0, 0, 0, 3 * a, 0)

    #Go down to nominal focus
    PT.transform(0, 0, -9925., 0, 0, 0)
    PT.flat()

    #Compute merit function
    nom = PT.rmsCentroid() / 10**4 * 180. / np.pi * 60**2
    nom = nom + max((9500. - np.size(PT.x)), 0.)

    return nom