Пример #1
0
def _solve_wavelengths(arm, fiber, wave_trace=True, write=True):
    """
    Finds wavelength solutions using a point source slit function.
    """
    solution_file = 'DATA/%s_wavelength_solutions_fiber_%s.txt' % (arm.ARM.lower(), arm.fib_char[fiber].lower())

    if arm.fib_char[fiber] in ['A', 'B']: #@MZ
        offset = arm.fib_OFFSET[fiber]

    # CREATE POINT SOURCE SLIT FUNCTION
    slitx, slity = point_source(arm, offset=offset)
    nslit = slitx.size
    wavelengths = wavefuncs.calculate_wavelengths(arm, mode="wavetrace", nwaves=arm.dwt) # reminder: wavelengths is 2d array in this case
    intensities = np.ones(wavelengths.shape) # SET ALL INTENSITIES TO 1
    orders = arm.OSET
    norders = arm.NOSET

    # INITIALIZE IMAGE ARRAYS
    image = np.zeros(arm.CCD_DIMS)
    counts = np.zeros(arm.CCD_DIMS, dtype=np.uint)
    m_list = np.zeros(arm.CCD_DIMS, dtype=np.uint) # records order of each pixel

    # OTHER INITIALIZATIONS
    returnx = np.empty(0)
    returny = np.empty(0)
    LOC_FLAG = 0
    BLAZE_FLAG = 0

    for i,m in enumerate(orders):
        waves, _weights = wavefuncs.feed_wavelengths(arm, m, wavelengths=wavelengths, intensities=intensities)
        nwaves = waves.size
        n_g_sell = n_sell(arm.ARM, waves)

        cfunctions.compute(arm.ARM_FLAG,
                           BLAZE_FLAG,
                           LOC_FLAG,
                           nwaves,
                           nslit,
                           m,
                           arm.XD_0,
                           arm.YD_0,
                           np.ascontiguousarray(n_g_sell, dtype=np.float64),
                           np.ascontiguousarray(slitx, dtype=np.float64),
                           np.ascontiguousarray(slity, dtype=np.float64),
                           np.ascontiguousarray(waves, dtype=np.float64),
                           np.ascontiguousarray(waves, dtype=np.float64),
                           image,
                           np.ascontiguousarray(counts),
                           np.ascontiguousarray(m_list),
                           returnx,
                           returny)
        output = '  * Wavetrace order %i (%i of %i), %.2f%% complete.' % (m, i+1, norders, ((i+1.) * 100.0 / norders))
        Printer(output)
    print '\n'
    inds = np.where(counts != 0)
    image[inds] *= 1.0e7 / counts[inds] # average each pixel, convert mm to Angstrom

    # saves solutions to disk
    if write:
        newimage = image[inds]
        m_list = m_list[inds]
        y = inds[0]
        x = inds[1]
        n = x.size
        print "  * Saving wavelength solutions to '%s'" % solution_file
        filename = open(solution_file, 'w')
        for i,lamb in enumerate(newimage):
            filename.write( '%s %s %s %s\n' % (m_list[i], lamb, x[i], y[i]) )
            output1 = '  * %0.2f%% Complete. point %s of %s.' % \
                      (100.0 * float(i) / n, i+1, n)
            Printer(output1)
        print "\n"
        filename.close()
        return m_list, newimage, x, y
    return 0
Пример #2
0
def sim_general(arm, fiber, wavelengths=None, intensities=None,
    fiber_description=None, wavemap=None):
    """
    General simulation function.

    Parameters
    ----------
    arm : SpectralArm object
        Container object of spectrograph and simulation parameters.
    fiber : int {0,1}
        Fiber to simulate. 1 = A and 2 = B.

    """
    if wavelengths is None: wavelengths = arm.wavelengths
    if intensities is None: intensities = arm.intensities
    #if fiber_description is None: fiber_description = arm.fiber_description
    if wavemap is None: wavemap = arm.wavemap

    print "Fiber %s - %s" % (arm.fib_char[fiber], arm.fiber_description)
    t1 = time.time()    # start time

    orders = arm.OSET
    norders = arm.NOSET

    if arm.fib_char[fiber] in ['A', 'B']: #@MZ
        offset = arm.fib_OFFSET[fiber]

    # output arrays
    image = arm.zero_images[fiber] # initialize image CCD array
    if arm.SAMPLING == "mc":
        image = np.array(image, dtype=np.uint)
    if arm.SAMPLING == "grid":
        wavemap_arr = np.zeros(arm.CCD_DIMS, dtype=np.uint)
    elif arm.SAMPLING == "mc":
        wavemap_arr = np.zeros(arm.CCD_DIMS)

        # m_list = np.zeros((0,0), dtype=np.uint)

    # CREATE SLIT ?
    if arm.SAMPLING == "grid":
        ns = arm.ns # input slit samples
        if arm.slit is '0':
            slitx, slity = point_source(arm, offset=offset)
        else:
            slitx, slity = slit_image(arm, offset=offset)
        nslit = slitx.size # effective slit samples
        perturb = arm.slitperturb
    elif arm.SAMPLING == "mc":
        ns = False
        slitx = False
        slity = False
        perturb = False
        if arm.slit[0] in '0 1 2'.split():
            arm.slittyp = 'uniform'
            SLIT_FLAG = 0
            arm.slit_locx = 0.0
            arm.slit_locy = 0.0
            arm.slit_scalex = 0.0
            arm.slit_scaley = 0.0
        elif arm.slit[0] == '3':
            arm.slittyp = 'gaussian'
            SLIT_FLAG = 1
            if len(arm.slit) == 1:
                arm.slit_locx = 0.0
                arm.slit_locy = 0.0
                arm.slit_scalex = 1.0
                arm.slit_scaley = 1.0
            elif len(arm.slit) == 2:
                arm.slit_locx = 0.0
                arm.slit_locy = 0.0
                arm.slit_scalex = float(arm.slit[1])
                arm.slit_scaley = float(arm.slit[1])
            elif len(arm.slit) == 3:
                arm.slit_locx = float(arm.slit[1])
                arm.slit_locy = float(arm.slit[1])
                arm.slit_scalex = float(arm.slit[2])
                arm.slit_scaley = float(arm.slit[2])
            elif len(arm.slit) == 4:
                arm.slit_locx = float(arm.slit[1])
                arm.slit_locy = float(arm.slit[2])
                arm.slit_scalex = float(arm.slit[3])
                arm.slit_scaley = float(arm.slit[3])
            elif len(arm.slit) == 5:
                arm.slit_locx = float(arm.slit[1])
                arm.slit_locy = float(arm.slit[2])
                arm.slit_scalex = float(arm.slit[3])
                arm.slit_scaley = float(arm.slit[4])

    # set simulation flags
    if arm.blaze:
        BLAZE_FLAG = 1
    else:
        BLAZE_FLAG = 0
    LOC_FLAG = 0

    # CDF interpolation flag
    for word in 'flatfield line'.split():
        if word in arm.fiber_description:
            interp_flag = 0 # do not interpolate (for line lists)
        else:
            interp_flag = 3 # interpolate
    if arm.interp_flag:
        interp_flag = arm.interp_flag

    if arm.ARM == "NIR" and arm.gap:
        print "Creating NIR detector gap of %s mm at x=%s mm" % (arm.gap, arm.gapoffset)

    # SOLUTION/COMPUTATION BLOCK
    # =========================================================================
    if arm.SAMPLING == "mc":
        print "Sampling method: Monte Carlo"
        print "Wavelength samping: %s" % arm.sm
        print "Fiber sampling distribution: %s" % arm.slittyp
        counts_tot = np.trapz(energy2counts(wavelengths, intensities), wavelengths) # total counts
        wave_range = 0.0 # wavelength coverage of each spectral order
        for i,m in enumerate(orders):
            waves, weights = wavefuncs.feed_wavelengths(arm, m)
            counts = energy2counts(waves, weights) # flux to photon counts
            wave_range = np.trapz(counts, waves) / counts_tot
            nwaves = waves.size
            nrays = int(arm.nr[fiber] * wave_range)
            output = '  * Calculating order %i (%i of %i), total %.2f%% complete.' % (m, i+1, norders, ((i+1.) * 100.0 / norders))
            if arm.sm == "cdf":
                nrays_org = nrays   # @MZ
                irays = 1e8     # @MZ
                nloop = np.int((nrays_org - 1) / irays) + 1    # @MZ
                for loop in xrange(nloop):  # @MZ
                    nrays = np.int(min(irays, nrays_org-loop*irays))   # @MZ
                    print 'Memory block loop {}/{}, nrays {}/{}'.format(loop+1, nloop, nrays, nrays_org)   # @MZ
                    waves_inp = np.zeros(nrays)
                    print "  * Sampling wavelengths using Cumulative Distribution Function (CDF)..."
                    cfunctions.random_wave_cdf(
                        waves,
                        counts,
                        nwaves,
                        interp_flag,
                        waves_inp,
                        nrays)
                    print output
                    print "  * wavelength coverage = %.2f%%" % (wave_range * 100.0)
                    print "  * nrays = %s" % nrays
                    cfunctions.compute_mc_cdf(
                        arm.ARM_FLAG,
                        BLAZE_FLAG,
                        arm.GAP_FLAG,
                        SLIT_FLAG,
                        nrays,
                        m,
                        arm.gap,
                        arm.gapoffset,
                        arm.XD_0,
                        arm.YD_0,
                        offset,
                        arm.slit_locx,
                        arm.slit_locy,
                        arm.slit_scalex,
                        arm.slit_scaley,
                        np.ascontiguousarray(waves_inp, dtype=np.float64),
                        image,
                        wavemap_arr)
                nrays = nrays_org
            elif arm.sm == "rej":
                print output
                print "  * wavelength coverage = %.2f%%" % (wave_range * 100.0)
                print "  * nrays = %s" % nrays
                cfunctions.compute_mc_rejsamp(
                    arm.ARM_FLAG,
                    BLAZE_FLAG,
                    arm.GAP_FLAG,
                    SLIT_FLAG,
                    nwaves,
                    nrays,
                    m,
                    arm.gap,
                    arm.gapoffset,
                    arm.XD_0,
                    arm.YD_0,
                    weights.max(),
                    offset,
                    arm.slit_locx,
                    arm.slit_locy,
                    arm.slit_scalex,
                    arm.slit_scaley,
                    np.ascontiguousarray(waves, dtype=np.float64),
                    np.ascontiguousarray(weights, dtype=np.float64),
                    image,
                    wavemap_arr)
            arm.fib_nrays[fiber].append(nrays)
        inds = np.where(image != 0.0)
        arm.fib_mean_rays_per_pixel[fiber] = np.mean(image[inds])
        arm.fib_min_rays_per_pixel[fiber] = np.min(image[inds])
        arm.fib_max_rays_per_pixel[fiber] = np.max(image[inds])
        arm.fib_nrays_tot[fiber] = np.sum(image)

    elif arm.SAMPLING == "grid":
        print "Sampling method: Grid"
        print "Fiber location perturbation: %s" % arm.perturb
        for i,m in enumerate(orders):
            output = '  * Calculating order %i (%i of %i), total %.2f%% complete.' % (m, i+1, norders, ((i+1.) * 100.0 / norders))
            print output
            if arm.perturb:
                waves, weights = wavefuncs.feed_wavelengths(arm, m)
                n_g_sell = n_sell(arm.ARM, waves)
                nwaves = waves.size
                cfunctions.compute_grid_perturb(
                    arm.ARM_FLAG,
                    BLAZE_FLAG,
                    arm.GAP_FLAG,
                    nwaves,
                    nslit,
                    m,
                    arm.gap,
                    arm.gapoffset,
                    arm.XD_0,
                    arm.YD_0,
                    arm.slitperturb,
                    np.ascontiguousarray(n_g_sell, dtype=np.float64),
                    np.ascontiguousarray(slitx, dtype=np.float64),
                    np.ascontiguousarray(slity, dtype=np.float64),
                    np.ascontiguousarray(waves, dtype=np.float64),
                    np.ascontiguousarray(weights, dtype=np.float64),
                    image,
                    wavemap_arr)
            else:
                waves, weights = wavefuncs.feed_wavelengths(arm, m)
                n_g_sell = n_sell(arm.ARM, waves)
                nwaves = waves.size
                returnx = np.empty(nwaves*nslit)
                returny = np.empty(nwaves*nslit)
                cfunctions.compute_grid(
                    arm.ARM_FLAG,
                    BLAZE_FLAG,
                    arm.GAP_FLAG,
                    nwaves,
                    nslit,
                    m,
                    arm.gap,
                    arm.gapoffset,
                    arm.XD_0,
                    arm.YD_0,
                    np.ascontiguousarray(n_g_sell, dtype=np.float64),
                    np.ascontiguousarray(slitx, dtype=np.float64),
                    np.ascontiguousarray(slity, dtype=np.float64),
                    np.ascontiguousarray(waves, dtype=np.float64),
                    np.ascontiguousarray(weights, dtype=np.float64),
                    image,
                    wavemap_arr)
        if wavemap:
            inds = np.where(wavemap_arr != 0)
            image[inds] *= 1.0e7 / wavemap_arr[inds] # average each pixel and convert mm to Angstrom
        else:
            image *= (arm.MAX_SNR**2) / image.max()
            print "Normalizing image array to a max of %s SNR." % arm.MAX_SNR

        arm.fib_nslit[fiber] = nslit
    arm.add_image(image)
    arm.fib_sim_time[fiber] = time.time() - t1
    return 0
Пример #3
0
def _write_region_solve(arm, fiber, m_solutions=None, lamb_solutions=None, x=None,
    y=None):
    """
    Writes .reg file using regions from a pre-written wavelength solution file.

    lamb_solutions are in Ang
    NOTE possibly other functions in this module can be deprecated in favor of
    this one.
    """
    solution_file = 'DATA/%s_wavelength_solutions_fiber_%s.txt' % \
        (arm.ARM.lower(), arm.fib_char[fiber].lower())
    print "  * Writing region file to '%s.reg'" % arm.outfile
    dlamb = arm.dwt         # Ang
    wtlist = arm.wtlist     # Ang
    if arm.WT_FLAG:
        outfile = open('%s.reg' % arm.outfile, 'a')
    elif not arm.WT_FLAG:
        outfile = open('%s.reg' % arm.outfile, 'w')
        outfile.write('# Region file format: DS9 version 4.0\n')
        outfile.write('# Filename: %s.fits\n' % arm.outfile.replace('FITS/', ''))
        outfile.write('global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source\n')
        outfile.write('physical\n')

    # INITIALIZATIONS
    if arm.fib_char[fiber] in ['A', 'B']: #@MZ
        offset = arm.fib_OFFSET[fiber]
    slitx, slity = point_source(arm, offset=offset)
    nslit = slitx.size
    # import wavelist, or create a wavelist using the ccd limits, ang -> mm
    if wtlist:
        input_waves = np.loadtxt(wtlist, unpack=True) * 1.e-7
    else:
        input_waves = np.arange(arm.wmin*1.e7, arm.wmax*1.e7, dlamb) * 1.e-7# step size of dlamb in Angstrom
    _weights = np.zeros(input_waves.size) # dummy variable for feed_wavelengths()
    orders = arm.OSET
    norders = arm.NOSET
    # INITIALIZE IMAGE ARRAYS
    image = np.zeros(arm.CCD_DIMS)
    counts = np.zeros(arm.CCD_DIMS, dtype=np.uint)
    m_list = np.zeros(arm.CCD_DIMS, dtype=np.uint) # records order of each pixel

    # OTHER INITIALIZATIONS
    LOC_FLAG = 2
    BLAZE_FLAG = 0

    # find wavelengths for each order
    for i,m in enumerate(orders):
        waves, _intensities = wavefuncs.feed_wavelengths(arm, m,
            wavelengths=input_waves, intensities=_weights)
        nwaves = waves.size
        n_g_sell = n_sell(arm.ARM, waves)
        returnx = np.empty(nwaves)
        returny = np.empty(nwaves)
        cfunctions.compute(arm.ARM_FLAG,
                           BLAZE_FLAG,
                           LOC_FLAG,
                           nwaves,
                           nslit,
                           m,
                           arm.XD_0,
                           arm.YD_0,
                           np.ascontiguousarray(n_g_sell, dtype=np.float64),
                           np.ascontiguousarray(slitx, dtype=np.float64),
                           np.ascontiguousarray(slity, dtype=np.float64),
                           np.ascontiguousarray(waves, dtype=np.float64),
                           np.ascontiguousarray(waves, dtype=np.float64),
                           image,
                           np.ascontiguousarray(counts),
                           np.ascontiguousarray(m_list),
                           returnx,
                           returny)
        x = returnx
        y = returny
        print x
        print y
        # FITS indices start at 1, not 0
        outfile.write("".join(['point(%i,%i) # point=cross text={%.0f}\n' % \
            tup for tup in zip(x+1, y+1, waves*1.e7)]))  # ds9 has 1-based indexing ? @CM yes, I believe so
        output = '  * Region order %s (%s of %s), %.2f%% complete.' % \
            (m, i+1, norders, ((i+1.) * 100.0 / norders))
        Printer(output)
    print "\n"
    outfile.close()
    arm.set_wt_flag(True) # set flag to enable appending for region file
    return 0