Example #1
0
 def initialize_spectrum(self):
     # GET WAVELENGTHS INTO RIGHT UNITS
     if self.factor:
         log.info("Multiplying input wavelengths by factor %s.", self.factor)
         wavelengths = self.source_spectrum[0] * self.factor
     # REDSHIFT SPECTRA
     wavelengths = physics.redshift(self.source_spectrum[0]*1.e-9, self.rv) * 1.e9
     flux = self.source_spectrum[1]
     # ADD TELLURIC LINES
     if self.telluric and self.FITS_SOURCE == "STAR":
         flux = wf.convolve_telluric_lines(self.telluric, wavelengths, flux)
     # CONVERT FLUX TO NUMBER DENSITY
     if self.FITS_SOURCE == "STAR":
         pdf = physics.energy2counts(wavelengths, flux)
     else:
         pdf = flux
     # TRUNCATE TO SPECTROGRAPH LIMIT WITH A SMALL BUFFER AS CUSHION
     self.source_spectrum = wf.truncate_spectrum(self, wavelengths, pdf)
Example #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