예제 #1
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
예제 #2
0
def traceChaseParam(num,
                    psi,
                    theta,
                    alpha,
                    L1,
                    z0,
                    bestFocus=False,
                    chaseFocus=False):
    """Trace a WS mirror pair using the parameters in Eq. 13
    of Chase & VanSpeybroeck
    Return the RMS radius of the focus
    Can specify whether to find the best focus or not
    """
    #Define annulus of source rays
    r0 = np.tan(4 * alpha) * z0
    alphap = 2 * alpha / (1 + 1 / psi)
    r1 = PT.wsPrimRad(z0 + L1, 1., r0, z0)  #np.tan(alphap/2.)*L1 + r0
    PT.annulus(r0, r1, num)
    PT.transform(0, 0, 0, np.pi, 0, 0)
    PT.transform(0, 0, -10000., 0, 0, 0)

    pdb.set_trace()

    #Trace to primary
    PT.wsPrimary(r0, z0, psi)
    #Handle vignetting
    PT.vignette()
    ind = np.logical_and(PT.z < z0 + L1, PT.z > z0)
    PT.vignette(ind=ind)
    ##    pdb.set_trace()
    #Apply pointing error
    PT.l = PT.l + np.sin(theta)
    PT.n = -np.sqrt(1 - PT.l**2)
    #Anything hitting backside goes away
    dot = PT.l * PT.ux + PT.m * PT.uy + PT.n * PT.uz
    ind = dot < 0.
    PT.vignette(ind=ind)
    if np.size(PT.x) < 1:
        return 0., 0., 0.
    #Reflect
    PT.reflect()

    N1 = np.size(PT.x)

    #Trace to secondary
    PT.wsSecondary(r0, z0, psi)
    #Vignette anything that did not converge
    PT.vignette()
    #Vignette anything hitting the backside
    dot = PT.l * PT.ux + PT.m * PT.uy + PT.n * PT.uz
    ind = dot < 0.
    PT.vignette(ind=ind)
    ##    #Vignette anything outside the physical range of the mirror
    ##    ind = np.logical_and(PT.z>z0-L1,PT.z<z0)
    ##    PT.vignette(ind=ind)
    if np.size(PT.x) < 1:
        return 0., 0., 0.
    PT.reflect()

    #Trace to focal plane
    PT.flat()
    cx, cy = PT.centroid()
    r = np.sqrt(cx**2 + cy**2)

    #Find best focus
    delta = 0.
    if chaseFocus or bestFocus:
        delta = .0625 * (psi + 1) * (r**2 * L1 / z0**2) * (1 /
                                                           np.tan(alpha))**2
        PT.transform(0, 0, delta, 0, 0, 0)
        PT.flat()

    delta2 = 0.
    delta3 = 0.
    if bestFocus:
        try:
            delta2 = PT.findimageplane(20., 100)
            PT.transform(0, 0, delta2, 0, 0, 0)
            delta3 = PT.findimageplane(1., 100)
            PT.transform(0, 0, delta3, 0, 0, 0)
        except:
            pdb.set_trace()
        PT.flat()

    return PT.rmsCentroid() / z0, delta + delta2 + delta3, r
예제 #3
0
def SXperformance(theta,energy,rough,bestsurface=False,optsurface=False):
    """Go through a SMART-X prescription file and compute
    area weighted performance for a flat focal plane
    """
    #Load in rx data
##    rx = np.transpose(np.genfromtxt('/home/rallured/Dropbox/AXRO/WSTracing/'
##        'mirror-design-260sh-200mmlong-040mmthick'
##        '-3mdiam-10mfl-10arcmin-fov-planarIntersept032713.csv',\
##                       delimiter=','))
    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'))
    therm = np.transpose(np.genfromtxt('/home/rallured/Dropbox/AXRO/'
                                       'WSTracing/thermal_shield_transmission_102711.txt'))
    
    f = np.sqrt(rx[1][-1]**2+10000.**2)
    z = np.sqrt(f**2-rx[1]**2) #spherical
##    z = np.repeat(10000.,np.size(rx[1]))
##    ind = rx[0] > 210.
##    rx = rx[:,ind]
    Ns = np.shape(rx)[1]

    #Loop through and compute a resolution and a weight for each shell
    hpdTelescope = np.zeros(np.size(theta))
    rmsTelescope = np.zeros(np.size(theta))
    delta = np.zeros(np.size(theta))
    cent = np.zeros(np.size(theta))
    platefrac =  np.zeros(np.size(theta))
    #fig = plt.figure()
    for t in theta[:]:
        xi = np.array([])
        yi = np.array([])
        l = np.array([])
        m = np.array([])
        n = np.array([])
        weights = np.array([])
        #plt.clf()
        tstart = time.time()
        plate = np.zeros(Ns)
        for s in np.arange(0,Ns):
            if geo[1][s] > 0.:
                sys.stdout.write('Shell: %03i \r' % s)
                sys.stdout.flush()
                r,rays = traceWSShell(1000,t,rx[1][s],z[s],z[s]+225.,z[s]+25.,\
                                     z[s]-25.,z[s]-225.,energy,rough)
                r = r*geo[1][s]*rx[9][s] #Reflectivity*area*alignmentbars*vign
                #Account for thermal shield in shells 220-321
                if s > 219:
                    r = r * therm[1][np.abs(energy/1000.-therm[0]).argmin()]
                r = np.repeat(r,np.size(rays[1]))
                weights = np.append(weights,r)
                PT.conic(1107.799202,-1.)
                xi = np.append(xi,rays[1])
                yi = np.append(yi,rays[2])
                l = np.append(l,rays[4])
                m = np.append(m,rays[5])
                n = np.append(n,rays[6])
                if s%10==0:
                    plt.plot(rays[1][:100],rays[2][:100],'.')
                plate[s] = anal.centroid(rays,weights=r)[0]
        print time.time()-tstart

        #Have list of photon positions and weights
        #Need to compute centroid and then FoM
        #Normalize weights
        weights = weights/np.sum(weights)
        xi = np.array(xi,order='F')
        yi = np.array(yi,order='F')
        zi = np.zeros(np.size(xi)).astype('float')
        li = np.array(l,order='F')
        mi = np.array(m,order='F')
        ni = np.array(n,order='F')
        uxi = np.zeros(np.size(xi)).astype('float')
        uyi = np.zeros(np.size(xi)).astype('float')
        uzi = np.zeros(np.size(xi)).astype('float')
        rays = [np.zeros(np.size(xi)).astype('float'),\
                xi,yi,zi,\
                li,mi,ni,\
                uxi,uyi,uzi]
        if bestsurface:
            rays = tran.transform(rays,0,0,.25,0,0,0)
            surf.focusI(rays,weights=weights)
        if optsurface:
            PT.conic(1107.799202,-1.) #Emprically found best surface 1128.058314
        
        #Compute FoM
        rmsTelescope[t==theta] = PT.rmsCentroid(weights=weights)/10000.
        hpdTelescope[t==theta] = PT.hpd(weights=weights)/10000.
        cx,cy = PT.centroid()
        cent[t==theta] = cx
        ind = geo[1] > 0.
        platefrac[t==theta] = np.std(plate[ind]/1e4)/rmsTelescope[t==theta]
        
        print hpdTelescope[t==theta],rmsTelescope[t==theta]

    return hpdTelescope,rmsTelescope,delta,cent,plate
예제 #4
0
def traceWSShell(num,theta,r0,z0,phigh,plow,shigh,slow,\
                 chaseFocus=False,bestFocus=False):
    """Trace a WS mirror pair with 10 m focal length and
    mirror axial cutoffs defined by phigh,plow
    """
    #Define annulus of source rays
    a, p, d, e = con.woltparam(r0, z0)
    r1 = PT.wsPrimRad(plow, 1., r0, z0)  #np.tan(a/2.)*(plow-10000.) + r0
    r2 = PT.wsPrimRad(phigh, 1., r0, z0)  #np.tan(a/2.)*(phigh-10000.) + r0
    ##    r2 = np.mean([r1,r2])
    PT.annulus(r1, r2, num)
    PT.transform(0, 0, 0, np.pi, 0, 0)
    PT.transform(0, 0, z0, 0, 0, 0)
    ##    pdb.set_trace()

    #Trace to primary
    PT.wsPrimary(r0, z0, 1.)
    #Handle vignetting
    PT.vignette()
    ind = np.logical_and(PT.z < phigh, PT.z > plow)
    PT.vignette(ind=ind)
    #Vignette rays hitting backside of mirror
    dot = PT.l * PT.ux + PT.m * PT.uy + PT.n * PT.uz
    ind = dot < 0.
    PT.vignette(ind=ind)
    #If all rays are vignetted, return
    if np.size(PT.x) < 1:
        return 0., 0., 0.
    #Apply pointing error
    PT.l = PT.l + np.sin(theta)
    PT.n = -np.sqrt(1 - PT.l**2)
    #Reflect
    PT.reflect()
    #Compute mean incidence angle for reflectivity
    ##    ang = np.abs(np.mean(np.arcsin(dot))) #radians
    ##    refl1 = CXCreflIr(ang,energy,rough)
    #Total rays entering primary aperture
    N1 = np.size(PT.x)

    #Trace to secondary
    PT.wsSecondary(r0, z0, 1.)
    #Vignette anything that did not converge
    PT.vignette()
    #Vignette anything outside the physical range of the mirror
    ind = np.logical_and(PT.z > slow, PT.z < shigh)
    PT.vignette(ind=ind)
    #Vignette anything hitting the backside
    dot = PT.l * PT.ux + PT.m * PT.uy + PT.n * PT.uz
    ind = dot < 0.
    PT.vignette(ind=ind)
    if np.size(PT.x) < 1:
        return 0., 0., 0.
    PT.reflect()
    #Compute mean incidence angle for reflectivity
    ##    ang = np.abs(np.mean(np.arcsin(dot))) #radians
    ##    refl2 = CXCreflIr(ang,energy,rough)

    #Trace to focal plane
    PT.flat()

    #Find Chase focus
    delta = 0.
    if chaseFocus or bestFocus:
        cx, cy = PT.centroid()
        r = np.sqrt(cx**2 + cy**2)
        delta = .0625*(1.+1)*(r**2*(phigh-plow)/10000.**2)\
                *(1/np.tan(a))**2
        PT.transform(0, 0, delta, 0, 0, 0)
        PT.flat()

    #Find best focus
    delta2 = 0.
    delta3 = 0.
    if bestFocus:
        try:
            delta2 = PT.findimageplane(20., 100)
            PT.transform(0, 0, delta2, 0, 0, 0)
            delta3 = PT.findimageplane(1., 100)
            PT.transform(0, 0, delta3, 0, 0, 0)
        except:
            pdb.set_trace()
        PT.flat()

    #return refl1*refl2
    return PT.hpd(), PT.rmsCentroid(), delta