def traceHole(num, N, numholes, div, cda): a, p, d, e = conicsolve.woltparam(220., 8400.) #Pitch is 2*a halfang = arcsin(50. / 220.) - .009 holetheta = linspace(-halfang, halfang, numholes) CDAbeam(num, div, 2 * a, holetheta[N - 1], cda) return 2 * a, holetheta[N - 1]
def primMaskTrace(fold, primary, woltVignette=True, foldrot=0.): #Get Wolter parameters alpha, p, d, e = conicsolve.woltparam(220., 8400.) primfoc = conicsolve.primfocus(220., 8400.) #Trace to fold mirror #translate to center of fold mirror PT.transform(0., 85.12, primfoc - 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() ## pdb.set_trace() rt = conicsolve.primrad(8475., 220., 8400.) PT.transform(0, -rt, 75., 0, 0, 0) PT.transform(*primary) PT.transform(0, rt, -8475., 0, 0, 0) ## PT.wolterprimary(220.,8400.) PT.primaryLL(220., 8400., 8525., 8425., 30. * np.pi / 180., pcoeff, pax, paz) if woltVignette is True: ind = logical_and(PT.z < 8525., PT.z > 8425.) PT.vignette(ind=ind) PT.reflect() PT.transform(0, -rt, 8475., 0, 0, 0) PT.itransform(*primary) PT.transform(0, rt, -8475., 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
def evaluateShell(theta,alpha): """Compute vignetting factor and HPD as a function of pointing error. Supply pointing errors theta and intersection radius of shell. Assumption is 200 mm long segments. """ r0 = 10000.*np.tan(alpha) hpd = np.zeros(np.size(theta)) rms = np.copy(hpd) delta = np.copy(hpd) a,p,d,e = con.woltparam(r0,10000.) for t in theta: hpd[t==theta],rms[t==theta],delta[t==theta] = \ traceWSShell(10000,t,r0,10000.,11000.,\ 10000.,10000.,8000.,1000.,.5,\ chaseFocus=True) return hpd,rms,delta
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
def traceWSShell(num,theta,r0,z0,phigh,plow,shigh,slow,\ energy,rough,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 rays = PT.annulus(r1,r2,num) PT.transform(rays,0,0,0,np.pi,0,0) PT.transform(rays,0,0,z0,0,0,0) #Trace to primary PT.wsPrimary(rays,r0,z0,1.) #Handle vignetting ind = np.logical_and(rays[3]<phigh,rays[3]>plow) rays = PT.vignette(rays,ind=ind) #Vignette rays hitting backside of mirror dot = rays[4]*rays[7]+rays[5]*rays[8]+rays[6]*rays[9] ind = dot < 0. rays = PT.vignette(rays,ind=ind) #If all rays are vignetted, return if np.size(rays[1]) < 1: return 0.,0.,0. #Apply pointing error rays = [rays[0],rays[1],rays[2],rays[3],\ rays[4]+np.sin(theta),rays[5],-np.sqrt(1-np.sin(theta)**2),\ rays[7],rays[8],rays[9]] ## 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(rays[1]) #Trace to secondary PT.wsSecondary(r0,z0,1.) #Vignette anything outside the physical range of the mirror ind = np.logical_and(rays[3]>slow,rays[3]<shigh) rays = PT.vignette(rays,ind=ind) #Vignette anything hitting the backside dot = rays[4]*rays[7]+rays[5]*rays[8]+rays[6]*rays[9] ind = dot < 0. rays = PT.vignette(rays,ind=ind) if np.size(rays[1]) < 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 rays = PT.flat(rays) ## #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: ## tran.focusI(rays,weights= ## except: ## pdb.set_trace() ## PT.flat() return refl1*refl2,rays
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
def hartmannStart(N, numholes): global holetheta a, p, d, e = conicsolve.woltparam(220., 8400.) #Pitch is 2*a return 2 * a, holetheta[N - 1]
def hartmannStartFull(N): global holetheta a, p, d, e = conicsolve.woltparam(220., 8400.) #Pitch is 4*a return 4 * a, holetheta[N - 1]