예제 #1
0
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)
예제 #2
0
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(name="1")
    system2 = system1.addChild(LocalCoordinates(name="2"))
    system3 = system2.addChild(LocalCoordinates(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(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)
예제 #3
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(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)
예제 #4
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
예제 #5
0
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(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)
예제 #6
0
def transform_tensors(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z,
                      local_tensor):
    """
    Sequential local/global and back transformation yields original tensor.
    """
    system = LocalCoordinates(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_tensor = system.returnLocalToGlobalTensors(local_tensor)
    local_tensor2 = system.returnGlobalToLocalTensors(global_tensor)
    assert np.allclose(local_tensor2-local_tensor, 0)
예제 #7
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(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)
예제 #8
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(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)
예제 #9
0
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)
예제 #10
0
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)
예제 #11
0
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)
예제 #12
0
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)
예제 #13
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)
예제 #14
0
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)
예제 #15
0
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(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)
예제 #16
0
 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
예제 #17
0
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(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)
예제 #18
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
예제 #19
0
    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
예제 #20
0
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)
예제 #21
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(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)
예제 #22
0
    def initDemoSystem(self):
        s = OpticalSystem()

        lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="object", decz=0.0), refname=s.rootcoordinatesystem.name)
        lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf1", decz=2.0), refname=lc0.name) # objectDist
        lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf2", decz=3.0), refname=lc1.name)
        lc3 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf3", decz=5.0, tiltx=0.0*math.pi/180.0), refname=lc2.name)
        lc4 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf4", decz=3.0), refname=lc3.name)
        lc5 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf5", decz=3.0), refname=lc4.name)
        lc6 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf6", decz=2.0), refname=lc5.name)
        lc7 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf7", decz=3.0), refname=lc6.name)
        lc8 = s.addLocalCoordinateSystem(LocalCoordinates(name="image", decz=19.0), refname=lc7.name)


        objectsurf = Surface(lc0)
        surf1 = Surface(lc1, shape=Conic(lc1, curv=1/-5.922))
        surf2 = Surface(lc2, shape=Conic(lc2, curv=1/-3.160))
        surf3 = Surface(lc3, shape=Conic(lc3, curv=1/15.884))
        surf4 = Surface(lc4, shape=Conic(lc4, curv=1/-12.756))
        stopsurf = Surface(lc5)
        surf6 = Surface(lc6, shape=Conic(lc6, curv=1/3.125))
        surf7 = Surface(lc7, shape=Conic(lc7, curv=1/1.479))
        image = Surface(lc8)


        elem = OpticalElement(lc0, label="lenssystem")

        glass = material_isotropic.ConstantIndexGlass(lc0, n=1.7)
        glass2 = material_isotropic.ConstantIndexGlass(lc0, n=1.5)

        elem.addMaterial("glass", glass)
        elem.addMaterial("glass2", glass2)

        elem.addSurface("object", objectsurf, (None, None))
        elem.addSurface("surf1", surf1, (None, "glass"))
        elem.addSurface("surf2", surf2, ("glass", None))
        elem.addSurface("surf3", surf3, (None, "glass"))
        elem.addSurface("surf4", surf4, ("glass", None))
        elem.addSurface("stop", stopsurf, (None, None))
        elem.addSurface("surf6", surf6, (None, "glass2"))
        elem.addSurface("surf7", surf7, ("glass2", None))
        elem.addSurface("image", image, (None, None))

        s.addElement("lenssys", elem)

        return s
예제 #23
0
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)
예제 #24
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)
예제 #25
0
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)
예제 #26
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)
예제 #27
0
def transform_tensors(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z,
                      local_tensor):
    """
    Sequential local/global and back transformation yields original tensor.
    """
    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_tensor = system.returnLocalToGlobalTensors(local_tensor)
    local_tensor2 = system.returnGlobalToLocalTensors(global_tensor)
    assert np.allclose(local_tensor2 - local_tensor, 0)
예제 #28
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
예제 #29
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)
예제 #30
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)))))
예제 #31
0
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)
예제 #32
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(
예제 #33
0
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)
예제 #34
0
from pyrateoptics.raytracer.aperture import CircularAperture
from pyrateoptics.raytracer.localcoordinates import LocalCoordinates
from pyrateoptics.raytracer.helpers import build_pilotbundle

from pyrateoptics import draw
from pyrateoptics.raytracer.globalconstants import degree

from pyrateoptics.analysis.optical_system_analysis import OpticalSystemAnalysis

logging.basicConfig(level=logging.DEBUG)

wavelength = 0.5876e-3

rnd_data1 = np.random.random((3, 3))  # np.eye(3)
rnd_data2 = np.random.random((3, 3))  # np.zeros((3, 3))#
lc = LocalCoordinates("1")
myeps = np.eye(3) + 0.1 * rnd_data1 + 0.01 * complex(0, 1) * rnd_data2
# aggressive complex choice of myeps
# myeps = np.eye(3) + 0.01*np.random.random((3, 3))
crystal = AnisotropicMaterial(lc, myeps)

# definition of optical system
s = OpticalSystem(matbackground=crystal)

lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="object", decz=0.0),
                                 refname=s.rootcoordinatesystem.name)
lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="m1",
                                                  decz=50.0,
                                                  tiltx=-math.pi / 8),
                                 refname=lc0.name)  # objectDist
lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="m2_stop",
예제 #35
0
# http://astro.dur.ac.uk/~rsharp/opticaldesign/
# some good demonstration of coordinate breaks is: FIELDROTATOR-LECT5.ZMX

if len(sys.argv) != 4:
    print("usage:")
    print("python -m demos.demo_zmx file.zmx entrance_pupil_diameter num_rays_for_yfan")
    print("only collimated light")
    print("file.zmx relative to local directory")
    exit()

file_to_read = sys.argv[1]
enpd = float(sys.argv[2])
num_rays = int(sys.argv[3])

p = ZMXParser(file_to_read, name='ZMXParser')
lctmp = LocalCoordinates("tmp")

#matdict = {}
matdict = {"BK7":ConstantIndexGlass(lctmp, 1.5168)}
#matdict = {"LAFN21":ConstantIndexGlass(lctmp, 1.788), "SF53":ConstantIndexGlass(lctmp, 1.72)}    

(s, seq) = p.createOpticalSystem(matdict)


rstobj = raster.MeridionalFan()
(px, py) = rstobj.getGrid(num_rays)

rpup = enpd*0.5 #7.5
o = np.vstack((rpup*px, rpup*py, -5.*np.ones_like(px)))

k = np.zeros_like(o)