Example #1
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 #2
0
def rxPlot():
    #Get Rx
    rx = np.transpose(np.genfromtxt('/home/rallured/Dropbox/AXRO/WSTracing/'
                                    '150528_Pauls_Rx.csv',delimiter=','))
    geo = np.transpose(np.genfromtxt('/home/rallured/Dropbox/AXRO/WSTracing/'
                                     'geometric_transmission_102711.txt'))
    rx = rx[:,geo[1]>0]
    geo = geo[1][geo[1]>0]
    f = np.sqrt(rx[1][-1]**2+10000.**2)
    z = np.sqrt(f**2-rx[1]**2) #spherical

    #Make plot
    plt.figure('SX')
    plt.clf()
    for i in np.arange(0,len(geo),3):
        rp1 = con.primrad(z[i]+50.,rx[1][i],1e4)
        rp2 = con.primrad(z[i]+250.,rx[1][i],1e4)
        rh1 = con.secrad(z[i]-50.,rx[1][i],1e4)
        rh2 = con.secrad(z[i]-250.,rx[1][i],1e4)
        uplt.isoplot([rp1,rp2],[z[i]+50.-1e4,z[i]+250.-1e4],'b')
        uplt.isoplot([rh1,rh2],[z[i]-50.-1e4,z[i]-250.-1e4],'b')

    return rx,geo
Example #3
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
Example #4
0
def fullFromMask(N, cda, fold, retro, prim, sec, foldrot=0., retrorot=0.):
    ##    pdb.set_trace()
    #Vignette at proper hole
    h = hartmannMask()
    ind = h == N
    PT.vignette(ind=ind)

    #Continue trace up to retro and back to CDA
    PT.transform(0, -123.41, 1156.48 - 651.57 - 134.18, 0, 0, 0)
    PT.flat()
    PT.transform(0, 0, 0, pi, 0, 0)
    PT.transform(*retro)
    PT.zernsurfrot(retrosag, retrofig, 378. / 2, -8.993 * pi / 180 + retrorot)
    PT.itransform(*retro)
    PT.reflect()
    PT.transform(0, 0, 0, -pi, 0, 0)

    #Back to mask
    PT.transform(0, 123.41, -1156.48 + 651.57 + 134.18, 0, 0, 0)
    PT.flat()
    h = hartmannMask()
    ind = h == N
    PT.vignette(ind=ind)

    #Place Wolter surfaces
    PT.transform(0, 0, -134.18 - 8400., 0, 0, 0)
    PT.transform(0, -conicsolve.primrad(8425., 220., 8400.), 8425., 0, 0, 0)
    PT.transform(*prim)
    PT.itransform(0, -conicsolve.primrad(8425., 220., 8400.), 8425., 0, 0, 0)
    ##    PT.wolterprimary(220.,8400.)
    PT.primaryLL(220., 8400., 8525., 8425., 30. * np.pi / 180., pcoeff, pax,
                 paz)
    pdb.set_trace()
    ind = logical_and(PT.z < 8525., PT.z > 8425.)
    PT.vignette(ind=ind)
    PT.transform(0, -conicsolve.primrad(8425., 220., 8400.), 8425., 0, 0, 0)
    PT.itransform(*prim)
    PT.itransform(0, -conicsolve.primrad(8425., 220., 8400.), 8425., 0, 0, 0)
    PT.reflect()

    #Wolter secondary
    PT.transform(0, -conicsolve.secrad(8325., 220., 8400.), 8325., 0, 0, 0)
    PT.transform(*sec)
    PT.itransform(0, -conicsolve.secrad(8325., 220., 8400.), 8325., 0, 0, 0)
    PT.woltersecondary(220., 8400.)
    ind = logical_and(PT.z < 8375., PT.z > 8275.)
    PT.vignette(ind=ind)
    PT.reflect()
    PT.transform(0, -conicsolve.secrad(8325., 220., 8400.), 8325., 0, 0, 0)
    PT.itransform(*sec)
    PT.itransform(0, -conicsolve.secrad(8325., 220., 8400.), 8325., 0, 0, 0)

    ##    PT.woltersecondary(220.,8400.)
    ##    ind = logical_and(PT.z<8375.,PT.z>8275.)
    ##    PT.vignette(ind=ind)
    ##    PT.reflect()

    #Back to fold
    PT.transform(0,-85.12,8400.-651.57+85.12\
                 ,0,0,0)
    PT.transform(0, 0, 0, -pi / 4, 0, 0)
    PT.transform(0, 0, 0, 0, 0, pi)
    PT.flat()
    PT.transform(*fold)
    PT.zernsurfrot(foldsag, foldfig, 406. / 2, -174.659 * pi / 180 + foldrot)
    PT.itransform(*fold)
    PT.reflect()
    PT.transform(0, 0, 0, 0, 0, -pi)

    #Back to CDA
    PT.transform(0, 0, 0, 3 * pi / 4, 0, 0)
    PT.transform(0,-85.12,-85.12-8400.+651.57\
                 ,0,0,0)
    PT.transform(*cda)
    PT.flat()

    return
Example #5
0
def fullMaskTrace(fold, prim, sec, woltVignette=True, foldrot=0.):
    #Get Wolter parameters
    alpha, p, d, e = conicsolve.woltparam(220., 8400.)
    foc = 8400.

    #Trace to fold mirror
    #translate to center of fold mirror
    PT.transform(0., 85.12, foc - 651.57 + 85.12, 0, 0, 0)
    #rotate so surface normal points in correct direction
    PT.transform(0, 0, 0, -3 * pi / 4, 0, 0)
    PT.transform(0, 0, 0, 0, 0, pi)
    #trace to fold flat
    PT.flat()
    #Introduce fold misalignment
    PT.transform(*fold)
    PT.zernsurfrot(foldsag, foldfig, 406. / 2, -174.659 * pi / 180 + foldrot)
    PT.itransform(*fold)
    PT.reflect()
    PT.transform(0, 0, 0, 0, 0, -pi)
    PT.transform(0, 0, 0, pi / 4, 0, 0)

    #Translate to optical axis mid-plane, then down to image of
    #primary focus, place primary mirror and trace
    PT.transform(0, 85.12, 651.57 - 85.12, 0, 0, 0)
    PT.flat()
    PT.transform(0, 0, -8400., 0, 0, 0)

    #Place secondary
    #Go to tangent point, apply misalignment, place mirror, and reverse
    PT.transform(0, -conicsolve.secrad(8325., 220., 8400.), 8325., 0, 0, 0)
    PT.transform(*sec)
    PT.itransform(0, -conicsolve.secrad(8325., 220., 8400.), 8325., 0, 0, 0)
    PT.woltersecondary(220., 8400.)
    if woltVignette is True:
        ind = logical_and(PT.z < 8375., PT.z > 8275.)
        PT.vignette(ind=ind)
    PT.reflect()
    PT.transform(0, -conicsolve.secrad(8325., 220., 8400.), 8325., 0, 0, 0)
    PT.itransform(*sec)  #Back at nominal secondary tangent point
    PT.itransform(0, -conicsolve.secrad(8325., 220., 8400.), 8325., 0, 0, 0)

    #Place primary
    #Go to tangent point, apply misalignment, place mirror, and reverse
    PT.transform(0, -conicsolve.primrad(8425., 220., 8400.), 8425., 0, 0, 0)
    PT.transform(*prim)
    PT.itransform(0, -conicsolve.primrad(8425., 220., 8400.), 8425., 0, 0, 0)
    ##    PT.transform(0,0,8475.,0,0,0)
    ##    PT.flat()
    ##    PT.itransform(0,0,8475.,0,0,0)
    ##    PT.wolterprimary(220.,8400.)
    PT.primaryLL(220., 8400., 8525., 8425., 30. * np.pi / 180., pcoeff, pax,
                 paz)
    ##    pdb.set_trace()
    if woltVignette is True:
        ind = logical_and(PT.z < 8525., PT.z > 8425.)
        PT.vignette(ind=ind)
    PT.reflect()
    PT.transform(0, -conicsolve.primrad(8425., 220., 8400.), 8425., 0, 0, 0)
    PT.itransform(*prim)
    PT.itransform(0, -conicsolve.primrad(8425., 220., 8400.), 8425., 0, 0, 0)

    #Move back up to mask plane and trace flat
    PT.transform(0, 0, 8400. + 134.18, 0, 0, 0)
    PT.flat()
    ##    pdb.set_trace()

    #Rays should now be at Hartmann mask plane

    return
Example #6
0
def traceThroughPair(rays,mask,primalign=np.zeros(6),\
                        detalign=np.zeros(6),cenSig=0.,\
                     primCoeffs=None,secCoeffs=None,\
                     secalign=np.zeros(6)):
    """
    Trace rays through the primary mirror and then down to a focus.
    Need to simulate an initial misalignment and then applying
    an optimization algorithm to align primary to beam.
    Merit function should include the random error in spot centroiding
    primCoeffs is a list of coefficients, axial orders, and azimuthal orders
    Use global coordinate systems to determine sign conventions
    """
    #Move to primary reference frame - rays 200 mm above node
    tran.transform(rays, 0, 0, -200., 0, 0, 0)
    glo = [tran.tr.identity_matrix()] * 4
    #Move to mirror tangent point and apply misalignment
    tran.transform(rays,
                   conic.primrad(8450., 220., 8400.),
                   0,
                   50,
                   0,
                   0,
                   0,
                   coords=glo)
    tran.transform(rays, 0, 0, 0, *primalign[3:], coords=glo)
    tran.itransform(rays,
                    conic.primrad(8450., 220., 8400.),
                    0,
                    50,
                    0,
                    0,
                    0,
                    coords=glo)
    tran.transform(rays, 0, 0, -8400., 0, 0, 0, coords=glo)
    #Trace to Wolter surface
    if primCoeffs is None:
        surf.wolterprimary(rays, 220., 8400.)
    else:
        surf.primaryLL(rays,220.,8400.,8500.,8400.,100./220.,\
                       *primCoeffs)
    tran.reflect(rays)
    #Place secondary in primary reference frame
    tran.transform(rays,conic.secrad(8350.,220.,8400.),0,8350.,0,0,0,\
                   coords=glo)
    tran.transform(rays, *secalign, coords=glo)
    tran.itransform(rays,conic.secrad(8350.,220.,8400.),0,8350.,0,0,0,\
                    coords=glo)
    if secCoeffs is None:
        surf.woltersecondary(rays, 220., 8400.)
    else:
        surf.secondaryLL(rays,220.,8400.,8400.,8300.,100./220.,\
                         *secCoeffs)
    rays = tran.applyT(rays, glo, inverse=True)
    #Rays are now at secondary in global coordinate system
    #(origin on optical axis and at nominal node height)
    #Now reflect and go to detector
    tran.reflect(rays)
    tran.transform(rays, 0, 0, -8400., 0, 0, 0)
    tran.transform(rays, *detalign)
    surf.flat(rays)

    #Pick out spot centroids
    cen = [anal.centroid(rays, weights=mask == i) for i in range(mask[-1] + 1)]
    cen = np.transpose(np.array(cen))
    #Add centroiding error
    if cenSig > 0:
        cen = cen + np.random.normal(scale=cenSig, size=np.shape(cen))

    return cen