Esempio n. 1
0
def wolterprimarynode(rays,r0,z0,psi=1.):
    """Place Wolter node at current origin,
    focus at (-r0,0,-z0)
    """
    tran.transform(rays,-r0,0,-z0,0,0,0)
    wolterprimary(rays,r0,z0,psi)
    tran.itransform(rays,-r0,0,-z0,0,0,0)
    return
Esempio n. 2
0
def ellipsoidPrimary(rays,R0,F,S,psi):
    """
    Trace rays to the primary of an ellipsoid-hyperboloid
    telescope.
    Call at focus, just like with Wolter-I
    """
    #Compute ellipsoid parameters
    P,a,b,e,f = con.ellipsoidFunction(S,psi,R0,F)
    R = b**2/a

    #Move to vertex
    tran.transform(rays,0,0,F+f-P-a,0,0,0)
    #Call conic
    conic(rays,R,-e**2)
    #Go back to focus
    tran.itransform(rays,0,0,F+f-P-a,0,0,0)

    return
def ogre_simulation_one_channel(waves,
                                orders,
                                j=j,
                                oa_misalign=oa_misalign,
                                g_misalign=g_misalign,
                                s_misalign=s_misalign,
                                m_misalign=m_misalign,
                                cen_width=5 * u.mm,
                                rib_width=2 * u.mm,
                                rib_num=3,
                                edge_width=5. * u.mm,
                                mod_width=150 * u.mm):
    '''
    Simulate rays going through the OGRE spectrometer. This function will
    just simulate rays passing through the spectrometer with
    misalignments, but will not take throughput into consideration. A
    seperate function is needed to correct this output for throughput.

    Parameters
    ----------
    waves : Quantity
        Array of wavelengths to simulate. Each wavelength in the array
        will be associated with one ray (100 wavelengths = 100 rays).
    orders : numpy.ndarray
        Diffraction orders associated with wavelengths passed.
    j : Quantity
        FWHM of the jitter throughout the observation.
    oa_misalign : 
    g_misalign : 
    s_misalign : 
    m_misalign : 

    Returns
    -------
    rays : [opd, x, y, z, l, m, n, nx, ny, nz]
        Rays on the focal plane of the OGRE spectrometer.
    waves : Quantity
        Wavelengths corresponding to each simulated ray.
    orders : array
        Diffracted order of each simulated ray.

    '''

    # Define initial rays.
    n = len(waves)
    rays = ogre.create_rays(10 * n)

    # Translate rays to center of optic assembly.
    rays[3] = np.ones(len(rays[1])) * oa_z_cen
    surfaces.flat(rays)

    # Misalign rays relative to optic assembly.
    trans.transform(rays, 0, 0, 0, oa_pitch, oa_yaw, 0)

    # Move rays to R_INT position. This is just a global offset.
    rays[3] = np.ones(len(rays[1])) * 3500.

    # Add jitter.
    xj = np.random.normal(0, j.to('rad').value, size=len(rays[4]))
    yj = np.random.normal(0, j.to('rad').value, size=len(rays[4]))

    rays[4] += xj
    rays[5] += yj
    rays[6] = np.sqrt(1 - rays[4]**2 - rays[5]**2)

    # Pass rays through optic.
    rays = ogre.ogre_mirror_module(rays, scatter='bg')

    # Randomly select indicies to keep based on count rate analysis.
    n_rays = len(rays[0])
    rand_inds = np.random.choice(np.arange(n_rays, dtype=int),
                                 len(waves),
                                 replace=False)

    # Keep only those selected indicies.
    rays = [r[rand_inds] for r in rays]

    # Add random period error effect.
    rand_fact = np.random.normal(1, 0.000094, size=len(waves))

    # Pass through grating moudle.
    rays, diff_ind = ogre.ogre_grating_module(rays,
                                              waves=waves * orders / rand_fact,
                                              g_misalign=g_misalign,
                                              s_misalign=s_misalign,
                                              m_misalign=m_misalign,
                                              return_diff_ind=True)

    # Keep only wavelength/orders that make it through grating module.
    waves = waves[diff_ind]
    orders = orders[diff_ind]

    # Occult rays that will hit ribs.
    rays, waves, orders = ogre.grating_rib_occultation(rays,
                                                       waves=waves,
                                                       orders=orders)

    # Transform coordinate system to be at center of rotation.
    trans.transform(rays, 0, 0, oa_z_cen, 0, 0, 0)

    # Propagate rays to misaligned plane, simulating center plane of optic assembly.
    surfaces.flat(rays)

    # Transform the rays back by the pitch angle to the optical axis coordinate system.
    trans.itransform(rays, 0, 0, 0, oa_pitch, oa_yaw, 0)

    # Put the rays back at the intersection plane of the ideal optic.
    rays[3] = np.ones(len(rays[3])) * oa_z_cen

    # Misalign in z-hat.
    trans.transform(rays, 0, 0, oa_z, 0, 0, 0)

    # Propagate to the focal plane.
    rays = ogre.ogre_focal_plane(rays,
                                 det_misalignments=[0, 0, 0, 0, 0, -det_z])

    return rays, waves, orders