def inverse_coordinate(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z): """ TODO """ dec_x = 100. * (2. * dec_x - 1.) dec_y = 100. * (2. * dec_y - 1.) dec_z = 100. * (2. * dec_z - 1.) tilt_x = 2. * math.pi * tilt_x tilt_y = 2. * math.pi * tilt_y tilt_z = 2. * math.pi * tilt_z system1 = LocalCoordinates.p(name="1") system2 = system1.addChild(LocalCoordinates.p(name="2")) system3 = system2.addChild( LocalCoordinates.p(name="3", decx=dec_x, decy=dec_y, decz=dec_z, tiltx=tilt_x, tilty=tilt_y, tiltz=tilt_z, tiltThenDecenter=0)) system4 = system3.addChild( LocalCoordinates.p(name="4", decx=-dec_x, decy=-dec_y, decz=-dec_z, tiltx=-tilt_x, tilty=-tilt_y, tiltz=-tilt_z, tiltThenDecenter=1)) assert np.allclose(system4.globalcoordinates, 0)
def create(): lc = LocalCoordinates.p(name="----LCglobal----") lc2 = LocalCoordinates.p(name="----LCap----", tiltx=0.1, decx=0.2) lc3 = LocalCoordinates.p(name="----LCsh----", tiltx=-0.1, decx=-0.2) lc4 = LocalCoordinates.p(name="----LCnext----", tiltx=-0.05, decz=5.0) lc.addChild(lc2) lc.addChild(lc3) lc2.addChild(lc4) return lc
def conic_grad(test_vector): """ Computation of conic grad equals explicit calculation. """ coordinate_system = LocalCoordinates.p(name="root") radius = 10.0 conic_constant = -1.5 curvature = 1./radius maxradius = (math.sqrt(1./((1+conic_constant)*curvature**2)) if conic_constant > -1 else abs(radius)) values = (2*test_vector-1.)*maxradius x = values[0] y = values[1] shape = Conic.p(coordinate_system, curv=curvature, cc=conic_constant) gradient = shape.getGrad(x, y) comparison = np.zeros_like(gradient) comparison[2, :] = 1. comparison[0] = (-curvature**3*x*(conic_constant + 1)*(x**2 + y**2)/ (np.sqrt(-curvature**2*(conic_constant + 1)*(x**2 + y**2) + 1)* (np.sqrt(-curvature**2*(conic_constant + 1)*(x**2 + y**2) + 1) + 1)**2) - 2*curvature*x/(np.sqrt(-curvature**2*(conic_constant + 1)*(x**2 + y**2) + 1) + 1)) comparison[1] = (-curvature**3*y*(conic_constant + 1)*(x**2 + y**2)/ (np.sqrt(-curvature**2*(conic_constant + 1)*(x**2 + y**2) + 1)* (np.sqrt(-curvature**2*(conic_constant + 1)*(x**2 + y**2) + 1) + 1)**2) - 2*curvature*y/(np.sqrt(-curvature**2*(conic_constant + 1)*(x**2 + y**2) + 1) + 1)) comparison = comparison*gradient[2] # comparison and gradient are calculated differently assert np.allclose(gradient, comparison)
def test_anisotropic_xi_determinants(rnd_data1, rnd_data2, rnd_data3, rnd_data4, rnd_data5): """ Check whether xi zeros from polynomial fulfill the QEVP and the associated GLEVP. This also verifies whether A6x6 and B6x6 are constructed correctly. """ lc = LocalCoordinates.p("1") myeps = rnd_data1 + complex(0, 1) * rnd_data2 # ((epsxx, epsxy, epsxz), (epsyx, epsyy, epsyz), (epszx, epszy, epszz)) = \ # tuple(myeps) m = AnisotropicMaterial.p(lc, myeps) n = rnd_data3 n = n / np.sqrt(np.sum(n * n, axis=0)) x = np.zeros((3, 5)) k = rnd_data4 + complex(0, 1) * rnd_data5 kpa = k - np.sum(n * k, axis=0) * n xiarray = m.calcXiNormZeros(x, n, kpa) ((Amatrix6x6, Bmatrix6x6), (Mmatrix, Cmatrix, Kmatrix)) \ = m.calcXiQEVMatricesNorm(x, n, kpa) should_be_zero_1 = np.ones((4, 5), dtype=complex) should_be_zero_2 = np.ones((4, 5), dtype=complex) for j in range(5): for xi_num in range(4): should_be_zero_1[xi_num, j] = np.linalg.det( (Mmatrix[:, :, j] * xiarray[xi_num, j]**2 + Cmatrix[:, :, j] * xiarray[xi_num, j] + Kmatrix[:, :, j])) should_be_zero_2[xi_num, j] = np.linalg.det( (Amatrix6x6[:, :, j] - Bmatrix6x6[:, :, j] * xiarray[xi_num, j])) assert np.allclose(should_be_zero_1, 0) assert np.allclose(should_be_zero_2, 0)
def xypolynomials_grad(test_vector): """ Computation of xy grad equals explicit calculation """ coordinate_system = LocalCoordinates.p(name="root") maxradius = 1e6 # arbitrary choice values = (2*test_vector - 1)*maxradius x_coordinate = values[0] y_coordinate = values[1] coefficients_list = [(0, 2, 1.), (4, 5, -1.), (3, 2, 0.1)] shape = XYPolynomials.p(coordinate_system, normradius=1., coefficients=coefficients_list) gradient = shape.getGrad(x_coordinate, y_coordinate) comparison = np.zeros_like(gradient) for (powx, powy, alpha) in coefficients_list: xpm1 = np.where(powx >= 1, x_coordinate**(powx - 1), np.zeros_like(x_coordinate)) ypm1 = np.where(powy >= 1, y_coordinate**(powy - 1), np.zeros_like(y_coordinate)) comparison[0] += -alpha*powx*xpm1*y_coordinate**powy comparison[1] += -alpha*powy*x_coordinate**powx*ypm1 comparison[2, :] = 1. assert np.allclose(gradient, comparison)
def asphere_sag(test_vector): """ Computation of asphere sag equals explicit calculation. """ coordinate_system = LocalCoordinates.p(name="root") radius = 10.0 conic_constant = -1.5 curvature = 1./radius alpha2 = 1e-3 alpha4 = -1e-6 alpha6 = 1e-8 maxradius = (math.sqrt(1./((1+conic_constant)*curvature**2)) if conic_constant > -1 else abs(radius)) values = (2*test_vector-1.)*maxradius x_coordinate = values[0] y_coordinate = values[1] shape = Asphere.p(coordinate_system, curv=curvature, cc=conic_constant, coefficients=[alpha2, alpha4, alpha6]) sag = shape.getSag(x_coordinate, y_coordinate) # comparison with explicitly entered formula comparison = (curvature*(x_coordinate**2+y_coordinate**2)/ (1.+ np.sqrt(1.-(1.+conic_constant) *curvature**2 *(x_coordinate**2+y_coordinate**2))) +alpha2*(x_coordinate**2+y_coordinate**2) +alpha4*(x_coordinate**2+y_coordinate**2)**2 +alpha6*(x_coordinate**2+y_coordinate**2)**3) assert np.allclose(sag, comparison)
def xypolynomials_sag(test_vector): """ Computation of xy sag equals explicit calculation """ coordinate_system = LocalCoordinates.p(name="root") maxradius = 1e6 # arbitrary choice values = (2*test_vector - 1)*maxradius x_coordinate = values[0] y_coordinate = values[1] coefficients_list = [(0, 2, 1.), (4, 5, -1.), (3, 2, 0.1)] shape = XYPolynomials.p(coordinate_system, normradius=1., coefficients=coefficients_list) sag = shape.getSag(x_coordinate, y_coordinate) comparison = np.zeros_like(x_coordinate) for (powx, powy, alpha) in coefficients_list: comparison += alpha * \ np.where(powx == 0, np.ones_like(x_coordinate), x_coordinate**powx) * \ np.where(powy == 0, np.ones_like(y_coordinate), y_coordinate**powy) assert np.allclose(sag, comparison)
def test_anisotropic_xi_eigenvectors(rnd_data1, rnd_data2, rnd_data3, rnd_data4, rnd_data5): """ Check whether eigenvectors fulfill the QEVP. """ lc = LocalCoordinates.p("1") myeps = rnd_data1 + complex(0, 1) * rnd_data2 # ((epsxx, epsxy, epsxz), (epsyx, epsyy, epsyz), (epszx, epszy, epszz)) = \ # tuple(myeps) m = AnisotropicMaterial.p(lc, myeps) n = rnd_data3 n = n / np.sqrt(np.sum(n * n, axis=0)) x = np.zeros((3, 5)) k = rnd_data4 + complex(0, 1) * rnd_data5 kpa = k - np.sum(n * k, axis=0) * n ((_, _), (Mmatrix, Cmatrix, Kmatrix)) \ = m.calcXiQEVMatricesNorm(x, n, kpa) (eigenvalues, eigenvectors) = m.calcXiEigenvectorsNorm(x, n, kpa) should_be_zero = np.ones((4, 3, 5), dtype=complex) for j in range(5): for k in range(4): should_be_zero[k, :, j] = np.dot( (Mmatrix[:, :, j] * eigenvalues[k, j]**2 + Cmatrix[:, :, j] * eigenvalues[k, j] + Kmatrix[:, :, j]), eigenvectors[k, :, j]) assert np.allclose(should_be_zero, 0)
def create(): from pyrateoptics.raytracer.surface_shape import GridSag lc = LocalCoordinates.p(name="global") x = np.linspace(-1, 1, 100) (X, Y) = np.meshgrid(x, x) Z = X**2 + Y**2 g = GridSag.p(lc, (x, x, Z)) return g
def create(): from pyrateoptics.raytracer.surface_shape import ZernikeANSI lc = LocalCoordinates.p(name="global") x = np.linspace(-1, 1, 100) (X, Y) = np.meshgrid(x, x) Z = ZernikeANSI.p(lc, normradius=1.0, coefficients=[1., 2., 3., 4., 5., 6., 7., 8.]) return Z
def create(): from pyrateoptics.raytracer.surface_shape import Conic from pyrateoptics.raytracer.surface import Surface from pyrateoptics.raytracer.aperture import CircularAperture lc = LocalCoordinates.p(name="----LCglobal----") lc2 = LocalCoordinates.p(name="----LCap----", tiltx=0.1, decx=0.2) lc3 = LocalCoordinates.p(name="----LCsh----", tiltx=-0.1, decx=-0.2) lc.addChild(lc2) lc.addChild(lc3) ap = CircularAperture.p(lc2) sh = Conic.p(lc3, curv=0.01, cc=-1) su = Surface.p(lc, sh, ap, name="mysurface") return su
def biconic_grad(test_vector): """ Computation of biconic gradient equals explicit calculation """ coordinate_system = LocalCoordinates.p(name="root") radiusx = 100.0 radiusy = 120.0 conic_constantx = -0.5 conic_constanty = -1.7 cx = 1./radiusx cy = 1./radiusy alpha2 = 1e-3 alpha4 = -1e-6 alpha6 = 1e-8 beta2 = 0.1 beta4 = -0.6 beta6 = 0.2 maxradiusx = (math.sqrt(1./((1+conic_constantx)*cx**2)) if conic_constantx > -1 else abs(radiusx)) maxradiusy = (math.sqrt(1./((1+conic_constanty)*cy**2)) if conic_constanty > -1 else abs(radiusy)) maxradius = min([maxradiusx, maxradiusy]) # choose minimal radius values = (2*test_vector - 1)*maxradius x = values[0] y = values[1] shape = Biconic.p(coordinate_system, curvx=cx, curvy=cy, ccx=conic_constantx, ccy=conic_constanty, coefficients=[(alpha2, beta2), (alpha4, beta4), (alpha6, beta6)]) gradient = shape.getGrad(x, y) comparison = np.zeros_like(gradient) comparison[2, :] = 1. comparison[0, :] = ( -alpha2*(-2*beta2*x + 2*x) - alpha4*(-4*beta4*x + 4*x)*(-beta4*(x**2 - y**2) + x**2 + y**2) - alpha6*(-6*beta6*x + 6*x)*(-beta6*(x**2 - y**2) + x**2 + y**2)**2 - cx**2*x*(conic_constantx + 1)*(cx*x**2 + cy*y**2)/((np.sqrt(-cx**2*x**2*(conic_constantx + 1) - cy**2*y**2*(conic_constanty + 1) + 1) + 1)**2*np.sqrt(-cx**2*x**2*(conic_constantx + 1) - cy**2*y**2*(conic_constanty + 1) + 1)) - 2*cx*x/(np.sqrt(-cx**2*x**2*(conic_constantx + 1) - cy**2*y**2*(conic_constanty + 1) + 1) + 1)) comparison[1, :] = ( -alpha2*(2*beta2*y + 2*y) - alpha4*(4*beta4*y + 4*y)*(-beta4*(x**2 - y**2) + x**2 + y**2) - alpha6*(6*beta6*y + 6*y)*(-beta6*(x**2 - y**2) + x**2 + y**2)**2 - cy**2*y*(conic_constanty + 1)*(cx*x**2 + cy*y**2)/((np.sqrt(-cx**2*x**2*(conic_constantx + 1) - cy**2*y**2*(conic_constanty + 1) + 1) + 1)**2*np.sqrt(-cx**2*x**2*(conic_constantx + 1) - cy**2*y**2*(conic_constanty + 1) + 1)) - 2*cy*y/(np.sqrt(-cx**2*x**2*(conic_constantx + 1) - cy**2*y**2*(conic_constanty + 1) + 1) + 1) ) assert np.allclose(gradient, comparison)
def biconic_sag(test_vector): """ Computation of biconic sag equals explicit calculation """ coordinate_system = LocalCoordinates.p(name="root") radiusx = 100.0 radiusy = 120.0 conic_constantx = -0.5 conic_constanty = -1.7 cx = 1. / radiusx cy = 1. / radiusy alpha2 = 1e-3 alpha4 = -1e-6 alpha6 = 1e-8 beta2 = 0.1 beta4 = -0.6 beta6 = 0.2 maxradiusx = (math.sqrt(1. / ((1 + conic_constantx) * cx**2)) if conic_constantx > -1 else abs(radiusx)) maxradiusy = (math.sqrt(1. / ((1 + conic_constanty) * cy**2)) if conic_constanty > -1 else abs(radiusy)) maxradius = min([maxradiusx, maxradiusy]) # choose minimal radius values = (2 * test_vector - 1) * maxradius x_coordinate = values[0] y_coordinate = values[1] shape = Biconic.p(coordinate_system, curvx=cx, curvy=cy, ccx=conic_constantx, ccy=conic_constanty, coefficients=[(alpha2, beta2), (alpha4, beta4), (alpha6, beta6)]) sag = shape.getSag(x_coordinate, y_coordinate) # comparison with explicitly entered formula comparison = ( (cx * x_coordinate**2 + cy * y_coordinate**2) / (1. + np.sqrt(1. - (1. + conic_constantx) * cx**2 * x_coordinate**2 - (1. + conic_constanty) * cy**2 * y_coordinate**2)) + alpha2 * (x_coordinate**2 + y_coordinate**2 - beta2 * (x_coordinate**2 - y_coordinate**2)) + alpha4 * (x_coordinate**2 + y_coordinate**2 - beta4 * (x_coordinate**2 - y_coordinate**2))**2 + alpha6 * (x_coordinate**2 + y_coordinate**2 - beta6 * (x_coordinate**2 - y_coordinate**2))**3) assert np.allclose(sag, comparison)
def test_anisotropic_xi_calculation_polynomial(rnd_data1, rnd_data2, rnd_data3, rnd_data4): """ Random epsilon tensor, Random k vector and n unit vector in z direction. Polynomial coefficients for eigenvalue equation from the numerical calculations via np.einsum and the analytical expressions given below (p4a, ..., p0a) should be identical. The test should work for real and complex epsilon and k values. """ lc = LocalCoordinates.p("1") myeps = rnd_data1 + complex(0, 1) * rnd_data2 ((epsxx, epsxy, epsxz), (epsyx, epsyy, epsyz), (epszx, epszy, epszz)) = \ tuple(myeps) m = AnisotropicMaterial.p(lc, myeps) n = np.zeros((3, 5)) n[2, :] = 1. x = np.zeros((3, 5)) k = rnd_data3 + complex(0, 1) * rnd_data4 kpa = k - np.sum(n * k, axis=0) * n kx = kpa[0] ky = kpa[1] (p4v, p3v, p2v, p1v, p0v) = m.calcXiPolynomialNorm(x, n, kpa) # TODO: Maybe generalize to arbitrary n vectors p4a = epszz * np.ones_like(kx) p3a = (epsxz + epszx) * kx + (epsyz + epszy) * ky p2a = epsxz*epszx + epsyz*epszy - (epsxx + epsyy)*epszz \ + (epsxx + epszz)*kx**2 + (epsxy + epsyx)*kx*ky \ + (epsyy + epszz)*ky**2 p1a = (epsxz + epszx)*kx**3 \ + (epsxz*epsyx + epsxy*epszx - epsxx*(epsyz + epszy))*ky \ + (epsyz + epszy)*kx**2*ky + (epsyz + epszy)*ky**3 \ + kx*(-(epsxz*epsyy) + epsxy*epsyz - epsyy*epszx + epsyx*epszy + (epsxz + epszx)*ky**2) p0a = -(epsxz*epsyy*epszx) + epsxy*epsyz*epszx + epsxz*epsyx*epszy \ - epsxx*epsyz*epszy - epsxy*epsyx*epszz + epsxx*epsyy*epszz \ + epsxx*kx**4 + (epsxy + epsyx)*kx**3*ky \ + (epsxy*epsyx - epsxx*epsyy + epsyz*epszy - epsyy*epszz)*ky**2 \ + epsyy*ky**4 + kx**2*(epsxy*epsyx + epsxz*epszx - epsxx*(epsyy + epszz) \ + (epsxx + epsyy)*ky**2) + kx*(\ (epsyz*epszx + epsxz*epszy - (epsxy + epsyx)*epszz)*ky \ + (epsxy + epsyx)*ky**3) should_be_zero_4 = p4a - p4v assert np.allclose(should_be_zero_4, 0) should_be_zero_3 = p3a - p3v assert np.allclose(should_be_zero_3, 0) should_be_zero_2 = p2a - p2v assert np.allclose(should_be_zero_2, 0) should_be_zero_1 = p1a - p1v assert np.allclose(should_be_zero_1, 0) should_be_zero_0 = p0a - p0v assert np.allclose(should_be_zero_0, 0)
def test_anisotropic_xi_eigenvalues(rnd_data1, rnd_data2, rnd_data3, rnd_data4, rnd_data5, rnd_data6): """ Comparison of eigenvalue calculation for xi from random complex material data. Comparing polynomial calculation from determinant, from quadratic eigenvalue problem and analytical calculation from sympy. """ lc = LocalCoordinates.p("1") myeps = np.zeros((3, 3), dtype=complex) myeps[0:2, 0:2] = rnd_data1 + complex(0, 1) * rnd_data2 myeps[2, 2] = rnd_data3 + complex(0, 1) * rnd_data4 ((epsxx, epsxy, _), (epsyx, epsyy, _), (_, _, epszz)) = \ tuple(myeps) m = AnisotropicMaterial.p(lc, myeps) #n = n/np.sqrt(np.sum(n*n, axis=0)) n = np.zeros((3, 1)) n[2, :] = 1 x = np.zeros((3, 1)) k = rnd_data5 + complex(0, 1) * rnd_data6 kpa = k - np.sum(n * k, axis=0) * n (eigenvalues, _) = m.calcXiEigenvectorsNorm(x, n, kpa) xiarray = m.calcXiNormZeros(x, n, kpa) # sympy check with analytical solution kx, ky, xi = sympy.symbols('k_x k_y xi') exx, exy, _, eyx, eyy, _, _, _, ezz \ = sympy.symbols('e_xx e_xy e_xz e_yx e_yy e_yz e_zx e_zy e_zz') #eps = Matrix([[exx, exy, exz], [eyx, eyy, eyz], [ezx, ezy, ezz]]) eps = sympy.Matrix([[exx, exy, 0], [eyx, eyy, 0], [0, 0, ezz]]) v = sympy.Matrix([[kx, ky, xi]]) m = -(v * v.T)[0] * sympy.eye(3) + v.T * v + eps detm = m.det().collect(xi) soldetm = sympy.solve(detm, xi) subsdict = { kx: kpa[0, 0], ky: kpa[1, 0], exx: epsxx, exy: epsxy, eyx: epsyx, eyy: epsyy, ezz: epszz, sympy.I: complex(0, 1) } analytical_solution = np.sort_complex( np.array([sol.evalf(subs=subsdict) for sol in soldetm], dtype=complex)) numerical_solution1 = np.sort_complex(xiarray[:, 0]) numerical_solution2 = np.sort_complex(eigenvalues[:, 0]) assert np.allclose(analytical_solution - numerical_solution1, 0) assert np.allclose(analytical_solution - numerical_solution2, 0)
def asphere_grad(test_vector): """ Computation of asphere gradient equals explicit calculation. Notice grad is calculated in 3 dimensions by grad F = grad(z - f(x, y)) """ coordinate_system = LocalCoordinates.p(name="root") radius = 10.0 conic_constant = -1.5 curvature = 1. / radius alpha2 = 1e-3 alpha4 = -1e-6 alpha6 = 1e-8 maxradius = (math.sqrt(1. / ((1 + conic_constant) * curvature**2)) if conic_constant > -1 else abs(radius)) values = (2 * test_vector - 1.) * maxradius x = values[0] y = values[1] shape = Asphere.p(coordinate_system, curv=curvature, cc=conic_constant, coefficients=[alpha2, alpha4, alpha6]) gradient = shape.getGrad(x, y) comparison = np.zeros_like(gradient) comparison[0] = (-2 * alpha2 * x - 4 * alpha4 * x * (x**2 + y**2) - 6 * alpha6 * x * (x**2 + y**2)**2 - curvature**3 * x * (conic_constant + 1) * (x**2 + y**2) / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) * (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)**2) - 2 * curvature * x / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)) comparison[1] = (-2 * alpha2 * y - 4 * alpha4 * y * (x**2 + y**2) - 6 * alpha6 * y * (x**2 + y**2)**2 - curvature**3 * y * (conic_constant + 1) * (x**2 + y**2) / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) * (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)**2) - 2 * curvature * y / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)) comparison[2, :] = 1.0 assert np.allclose(gradient, comparison)
def transform_directions(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z, local_directions): """ Sequential local/global and back transformation yields original vector. """ system = LocalCoordinates.p(name="1", decx=100. * (2. * dec_x - 1.), decy=100. * (2. * dec_y - 1.), decz=100. * (2. * dec_z - 1.), tiltx=2. * math.pi * tilt_x, tilty=2. * math.pi * tilt_y, tiltz=2. * math.pi * tilt_z) global_directions = system.returnLocalToGlobalDirections(local_directions) local_directions2 = system.returnGlobalToLocalDirections(global_directions) assert np.allclose(local_directions2 - local_directions, 0)
def transform_points(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z, local_points): """ Sequential local/global and back transformation yields original point. """ coordinate_system = LocalCoordinates.p(name="1", decx=100. * (2. * dec_x - 1.), decy=100. * (2. * dec_y - 1.), decz=100. * (2. * dec_z - 1.), tiltx=2. * math.pi * tilt_x, tilty=2. * math.pi * tilt_y, tiltz=2. * math.pi * tilt_z) global_points = coordinate_system.returnLocalToGlobalPoints(local_points) local_points2 = coordinate_system.returnGlobalToLocalPoints(global_points) assert np.allclose(local_points2 - local_points, 0)
def create_coordinate_systems(self, optical_system): coordinate_systems = [] for i in range(self.surfaces.shape[0]): if (i == 0): refname_ = optical_system.rootcoordinatesystem.name else: refname_ = coordinate_systems[i - 1].name coordinate_systems.append(optical_system.\ addLocalCoordinateSystem(LocalCoordinates.p(\ name=self.get_sufval("name",i),\ decx=self.get_sufval("decx",i), decy=self.get_sufval("decy",i), \ decz=self.get_sufval("decz",i), tiltx=self.get_sufval("tiltx",i),\ tilty=self.get_sufval("tilty",i), tiltz=self.get_sufval("tiltz",i)),\ refname=refname_)) return coordinate_systems
def directions_scalarproduct(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z, local1, local2): """ Two vectors have same scalar product in two different coordinate systems. """ system = LocalCoordinates.p(name="1", decx=100. * (2. * dec_x - 1.), decy=100. * (2. * dec_y - 1.), decz=100. * (2. * dec_z - 1.), tiltx=2. * math.pi * tilt_x, tilty=2. * math.pi * tilt_y, tiltz=2. * math.pi * tilt_z) global1 = system.returnLocalToGlobalDirections(local1) global2 = system.returnLocalToGlobalDirections(local2) scalarproduct_local = np.einsum('i...,i...', local1, local2) scalarproduct_global = np.einsum('i...,i...', global1, global2) assert np.allclose(scalarproduct_local - scalarproduct_global, 0)
def test_anisotropic_xi_calculation_det(rnd_data1, rnd_data2, rnd_data3, rnd_data4, rnd_data5, rnd_data6): """ Random epsilon tensor, Random k vector and n unit vector in z direction. Determinant of the propagator from numerical calculations via np.einsum and from analytical expression given below should coincide. The test should work for real and complex epsilon and k values. """ lc = LocalCoordinates.p("1") myeps = rnd_data1 + complex(0, 1) * rnd_data2 ((epsxx, epsxy, epsxz), (epsyx, epsyy, epsyz), (epszx, epszy, epszz)) = \ tuple(myeps) m = AnisotropicMaterial.p(lc, myeps) n = np.zeros((3, 5)) n[2, :] = 1. x = np.zeros((3, 5)) k = rnd_data3 + complex(0, 1) * rnd_data4 xi = rnd_data5 + complex(0, 1) * rnd_data6 kpa = k - np.sum(n * k, axis=0) * n kx = kpa[0] ky = kpa[1] # TODO: Maybe generalize to arbitrary n vectors det_analytical = xi**4*epszz \ + xi**3*((epsxz + epszx)*kx + (epsyz + epszy)*ky)\ + xi**2*(epsxz*epszx + epsyz*epszy - (epsxx + epsyy)*epszz\ + (epsxx + epszz)*kx**2 + (epsxy + epsyx)*kx*ky\ + (epsyy + epszz)*ky**2)\ + xi*((epsxz + epszx)*kx**3\ + (epsxz*epsyx + epsxy*epszx - epsxx*(epsyz + epszy))*ky\ + (epsyz + epszy)*kx**2*ky + (epsyz + epszy)*ky**3\ + kx*(-(epsxz*epsyy) + epsxy*epsyz - epsyy*epszx\ + epsyx*epszy + (epsxz + epszx)*ky**2))\ -(epsxz*epsyy*epszx) + epsxy*epsyz*epszx\ + epsxz*epsyx*epszy - epsxx*epsyz*epszy\ - epsxy*epsyx*epszz + epsxx*epsyy*epszz + epsxx*kx**4\ + (epsxy + epsyx)*kx**3*ky \ + (epsxy*epsyx - epsxx*epsyy + epsyz*epszy - epsyy*epszz)*ky**2 \ + epsyy*ky**4 + kx**2*(epsxy*epsyx + epsxz*epszx \ - epsxx*(epsyy + epszz) + (epsxx + epsyy)*ky**2)\ + kx*((epsyz*epszx + epsxz*epszy \ - (epsxy + epsyx)*epszz)*ky + (epsxy + epsyx)*ky**3) should_be_zero = det_analytical - m.calcXiDetNorm(xi, x, n, kpa) assert np.allclose(should_be_zero, 0)
def tensors_scalarproduct(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z, directions1, directions2, tensor1, tensor2): """ Vectors/tensors have same contractions in different coordinate systems. """ system = LocalCoordinates.p(name="1", decx=100. * (2. * dec_x - 1.), decy=100. * (2. * dec_y - 1.), decz=100. * (2. * dec_z - 1.), tiltx=2. * math.pi * tilt_x, tilty=2. * math.pi * tilt_y, tiltz=2. * math.pi * tilt_z) global_directions1 = system.returnLocalToGlobalDirections(directions1) global_directions2 = system.returnLocalToGlobalDirections(directions2) global_tensor1 = system.returnLocalToGlobalTensors(tensor1) global_tensor2 = system.returnLocalToGlobalTensors(tensor2) # check whether a transformation between coordinate # systems changes indeed the components # assert np.any(t1glob - t1loc != 0) FIXME: currently breaks # assert np.any(t2glob - t2loc != 0) FIXME: currently breaks # assert np.any(v1glob - v1loc != 0) FIXME: currently breaks # assert np.any(v2glob - v2loc != 0) FIXME: currently breaks # test trace of tensor assert np.allclose((np.trace(global_tensor1, axis1=0, axis2=1) - np.trace(tensor1, axis1=0, axis2=1)), 0) # test t1 t2 tensor contraction assert np.allclose( (np.einsum('ij...,ij...', global_tensor1, global_tensor2) - np.einsum('ij...,ij...', tensor1, tensor2)), 0) # test v1 t1 v2 assert np.allclose( (np.einsum('i...,ij...,j...', global_directions1, global_tensor1, global_directions2) - np.einsum('i...,ij...,j...', directions1, tensor1, directions2)), 0) # test v1 t1 t2 v2 assert np.allclose( (np.einsum('i...,ij...,jk...,k...', global_directions1, global_tensor1, global_tensor2, global_directions2) - np.einsum('i...,ij...,jk...,k...', directions1, tensor1, tensor2, directions2)), 0)
def conic_sag(test_vector): """ Computation of conic sag equals explicit calculation. """ coordinate_system = LocalCoordinates.p(name="root") radius = 10.0 conic_constant = -1.5 curvature = 1. / radius maxradius = (math.sqrt(1. / ((1 + conic_constant) * curvature**2)) if conic_constant > -1 else abs(radius)) values = (2 * test_vector - 1.) * maxradius x_coordinate = values[0] y_coordinate = values[1] shape = Conic.p(coordinate_system, curv=curvature, cc=conic_constant) sag = shape.getSag(x_coordinate, y_coordinate) # comparison with explicitly entered formula assert np.allclose( sag, (curvature * (x_coordinate**2 + y_coordinate**2) / (1. + np.sqrt(1. - (1. + conic_constant) * curvature**2 * (x_coordinate**2 + y_coordinate**2)))))
def test_anisotropic_xi_calculation_polynomial_zeros(rnd_data1, rnd_data2, rnd_data3, rnd_data4, rnd_data5): """ Random epsilon tensor, random k vector and random n unit vector. Check whether the roots calculated give really zero for the determinant. The test should work for real and complex epsilon and k values. """ lc = LocalCoordinates.p("1") myeps = rnd_data1 + complex(0, 1) * rnd_data2 # ((epsxx, epsxy, epsxz), (epsyx, epsyy, epsyz), (epszx, epszy, epszz)) = \ # tuple(myeps) m = AnisotropicMaterial.p(lc, myeps) n = rnd_data3 n = n / np.sqrt(np.sum(n * n, axis=0)) x = np.zeros((3, 5)) k = rnd_data4 + complex(0, 1) * rnd_data5 kpa = k - np.sum(n * k, axis=0) * n should_be_zero = np.ones((4, 5), dtype=complex) xiarray = m.calcXiNormZeros(x, n, kpa) for i in range(4): should_be_zero[i, :] = m.calcXiDetNorm(xiarray[i], x, n, kpa) assert np.allclose(should_be_zero, 0)
from pyrateoptics import raytrace, draw logging.basicConfig(level=logging.DEBUG) wavelength = 0.5876e-3 wave_red = 0.700e-3 wave_blue = 0.470e-3 # definition of optical system s = OpticalSystem.p() dropletradius = 0.1 lc0 = s.addLocalCoordinateSystem( LocalCoordinates.p(name="stop", decz=0.0), refname=s.rootcoordinatesystem.name) lccomprism = s.addLocalCoordinateSystem( LocalCoordinates.p(name="dropletcenter", decz=2.*dropletradius), refname=lc0.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="surf1", decz=-dropletradius), refname=lccomprism.name) # objectDist lc2 = s.addLocalCoordinateSystem( LocalCoordinates.p(name="surf2", decz=dropletradius), refname=lccomprism.name) lc3 = s.addLocalCoordinateSystem( LocalCoordinates.p(name="surf3", decz=0), refname=lccomprism.name) lc4 = s.addLocalCoordinateSystem(
from pyrateoptics.raytracer.optical_system import OpticalSystem from pyrateoptics.raytracer.aperture import CircularAperture from pyrateoptics.raytracer.localcoordinates import LocalCoordinates from pyrateoptics import draw, raytrace logging.basicConfig(level=logging.DEBUG) wavelength = 0.5876e-3 # definition of optical system s = OpticalSystem.p() lc0 = s.addLocalCoordinateSystem( LocalCoordinates.p(name="stop", decz=0.0), refname=s.rootcoordinatesystem.name) lc1 = s.addLocalCoordinateSystem( LocalCoordinates.p(name="surf1", decz=-1.048), refname=lc0.name) # objectDist lc2 = s.addLocalCoordinateSystem( LocalCoordinates.p(name="surf2", decz=4.0), refname=lc1.name) lc3 = s.addLocalCoordinateSystem( LocalCoordinates.p(name="surf3", decz=2.5), refname=lc2.name) lc4 = s.addLocalCoordinateSystem( LocalCoordinates.p(name="image", decz=97.2), refname=lc3.name) stopsurf = Surface.p(lc0) frontsurf = Surface.p(lc1, shape=Conic.p(lc1, curv=1./62.8), aperture=CircularAperture.p(lc1, maxradius=12.7))
def addChild(self, name=""): ch = self.__lc.addChild(LocalCoordinates.p(name)) self.createSubgroupForChild(ch)
# TODO: add materials via command line show_spot = parsed.showspot file_to_read = parsed.file enpd = parsed.epd num_rays = parsed.numrays bundletype = parsed.bundletype anglex = parsed.anglex reverse = parsed.reverse surfaces_do_not_draw = parsed.do_not_draw_surfaces.split(",") raybundles_do_not_draw = [ int(s) for s in parsed.do_not_draw_raybundles.split(",") if s != '' ] p = ZMXParser(file_to_read, name='ZMXParser') lctmp = LocalCoordinates.p("tmp") matdict = { "BK7": ConstantIndexGlass.p(lctmp, 1.5168), "LAFN21": ConstantIndexGlass.p(lctmp, 1.788), "SF53": ConstantIndexGlass.p(lctmp, 1.72) } (s, seq) = p.create_optical_system(matdict) if s is None: sys.exit() initialbundles_dict = p.create_initial_bundle() osa = OpticalSystemAnalysis(s, seq, name="Analysis")
from pyrateoptics.raytracer.optical_system import OpticalSystem from pyrateoptics.raytracer.aperture import CircularAperture from pyrateoptics.raytracer.localcoordinates import LocalCoordinates from pyrateoptics.raytracer.globalconstants import degree from pyrateoptics import draw, raytrace logging.basicConfig(level=logging.DEBUG) wavelength = 0.5876e-3 # definition of optical system s = OpticalSystem.p(name='os') lc0 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="stop", decz=1.0), refname=s.rootcoordinatesystem.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="surf1", decz=10.0), refname=lc0.name) lc2 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="surf2", decz=5.0, tiltx=10 * math.pi / 180.0), refname=lc1.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="image", decz=-5.0, tiltx=-10 * math.pi / 180.0), refname=lc2.name) stopsurf = Surface.p(lc0)
from pyrateoptics.sampling2d.raster import RandomGrid from pyrateoptics.optimize.optimize import Optimizer from pyrateoptics.optimize.optimize_backends import (ScipyBackend, Newton1DBackend, ParticleSwarmBackend, SimulatedAnnealingBackend) wavelength = standard_wavelength logging.basicConfig(level=logging.DEBUG) # definition of optical system s = OpticalSystem.p() # objectDistance = 2.0 lc0 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="object", decz=0.0), refname=s.rootcoordinatesystem.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="surf1", decz=2.0), refname=lc0.name) # objectDist lc2 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="surf2", decz=3.0), refname=lc1.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="surf3", decz=5.0, tiltx=2.5 * degree), refname=lc2.name) lc4 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="surf4", decz=3.0), refname=lc3.name) lc5 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="surf5", decz=3.0), refname=lc4.name) lc6 = s.addLocalCoordinateSystem(LocalCoordinates.p(name="surf6", decz=2.0),