예제 #1
0
def test_update():
    import simcado as sim
    cmd = sim.UserCommands()
    cmd.update({'OBS_EXPTIME': 30})
    assert cmd.cmds['OBS_EXPTIME'] == 30
    with pytest.raises(KeyError):
        cmd.update({'NO_EXISTE': 30})
예제 #2
0
def main():
    '''Main function

    Define source components, commands, psf, detector, etc. here
    '''
    ## Commands to control the simulation
    #cmds = sim.UserCommands('spectro_HK.config')
    cmds = sim.UserCommands('spectro_IJ.config')

    # Optionally set some parameters explicitely.
    cmds['SPEC_ORDER_LAYOUT'] = "specorders-160904.fits"
    cmds['OBS_EXPTIME'] = 60
    cmds['FPA_LINEARITY_CURVE'] = 'none'

    cmds['SPEC_INTERPOLATION'] = 'spline'
    #cmds['SPEC_INTERPOLATION'] = 'nearest'

    ## Define the source(s)  -- Only point sources for the moment
    specfiles = ['GW_Ori+9mag.fits', 'GW_Ori+9mag.fits']
    sourcepos = [[-1, 0], [1, 0]]

    ## Background spectra - these fill the slit
    bgfiles = ['atmo_emission.fits']

    ## Create source object. The units of the spectra are
    ##         - ph / um  for source spectra
    ##         - erg / (um arcsec2) for background spectra
    srcobj = sc.SpectralSource(cmds, specfiles, sourcepos, bgfiles)

    ## Load the psf
    psfobj = sc.prepare_psf("PSF_SCAO_120.fits")

    # Create detector
    detector = sim.Detector(cmds, small_fov=False)

    # Create transmission curve.
    # Here we take the  transmission from the simcado optical train,
    # this includes atmospheric, telescope and instrumental
    # transmissivities.
    # You can create your own transmission by suitably defining
    # tc_lam (in microns) and tc_val (as numpy arrays).
    opttrain = sim.OpticalTrain(cmds)
    tc_lam = opttrain.tc_mirror.lam_orig
    tc_val = opttrain.tc_mirror.val_orig
    transmission = interp1d(tc_lam, tc_val, kind='linear',
                            bounds_error=False, fill_value=0.)

    ## Prepare the order descriptions
    tracelist = sc.layout.read_spec_order(cmds['SPEC_ORDER_LAYOUT'])

    #    tracelist = list()
    #for lfile in layoutlist:
    #    tracelist.append(sc.SpectralTrace(lfile))

    #sc.do_one_chip(detector.chips[3], srcobj, psfobj, tracelist, cmds,
    #            transmission)
    sc.do_all_chips(detector, srcobj, psfobj, tracelist, cmds, transmission)
예제 #3
0
def test_full_sim_with_single_star_double_corr_readout():
    cmd = sim.UserCommands()
    opt = sim.OpticalTrain(cmd)
    fpa = sim.Detector(cmd)
    
    src = sim.source.star(mag=20, filter_name="Ks")
    src.apply_optical_train(opt, fpa)
    hdu = fpa.read_out(read_out_type="non_destructive")
    
    # "It’s over nine thousand!" - Vegeta Breigh
    assert np.max(hdu[0].data) > 9000
예제 #4
0
def make_cluster_hdus(mass=2E4, half_light_radius=1, exptime=3600, show=False):

    cmd = sim.UserCommands()
    cmd["OBS_EXPTIME"] = exptime
    # cmd["SCOPE_PSF_FILE"] = "PSF_MAORY_SCAO_Ks_2.fits"
    cmd["SCOPE_PSF_FILE"] = "Default_PSF_SCAO.fits"
    cmd["INST_FILTER_TC"] = "Ks"
    cmd["FPA_LINEARITY_CURVE"] = "none"
    cmd["FPA_USE_NOISE"] = "no"
    cmd["FPA_CHIP_LAYOUT"] = "FPA_chip_layout_centre.dat"

    opt = sim.OpticalTrain(cmd)
    fpa = sim.Detector(cmd, small_fov=False)

    dist_orig = 1E3
    cluster = sim.source.cluster(mass=mass,
                                 distance=dist_orig,
                                 half_light_radius=half_light_radius)

    x_orig = deepcopy(cluster.x)
    y_orig = deepcopy(cluster.y)
    f_orig = deepcopy(cluster.weight)

    d = np.array([8.5E3, 20E3, 50E3, 200E3, 800E3])
    dist_mods = 5 * np.log10(d) - 5

    if show: plt.figure(figsize=(15, 5))

    for ii, dist_mod in enumerate(
            dist_mods):  # GC=14.5, LMC=18.5, Leo I=21.5, M31=24.5

        dist = 10**(1 + dist_mod / 5)
        cluster.x = x_orig * dist_orig / dist
        cluster.y = y_orig * dist_orig / dist
        scale = f_orig * (dist_orig / dist)**2
        threshold = 0.000003
        scale[scale > threshold] = threshold
        cluster.weight = scale

        cluster.apply_optical_train(opt, fpa)
        hdu = fpa.read_out(OBS_EXPTIME=exptime,
                           filename=f"{int(dist)}kpc_{int(mass)}Msun.fits")

        if show:
            plt.subplot(1, 5, ii + 1)
            plt.imshow(hdu[0].data, norm=LogNorm(), vmin=1.61E5, vmax=1.8E5)

    if show: plt.show()
예제 #5
0
def test_flux_from_non_destructive_is_same_as_superfast():

    cmd = sim.UserCommands()
    cmd["FPA_READ_OUT_SCHEME"] = "double_corr"
    opt = sim.OpticalTrain(cmd)
    fpa = sim.Detector(cmd)
    
    src = sim.source.star(mag=20, filter_name="Ks")
    src.apply_optical_train(opt, fpa)
    hdu_nd = fpa.read_out(read_out_type="non_destructive")
    hdu_sf = fpa.read_out(read_out_type="superfast")
    
    sig_nd = np.max(hdu_nd[0].data) - np.min(hdu_nd[0].data)
    sig_sf = np.max(hdu_sf[0].data) - np.min(hdu_sf[0].data)

    # is the difference between the signal part fo the two read-outs < 10%?   
    assert sig_nd - sig_sf < 0.1 * sig_sf 
예제 #6
0
def simulate_m4_raw_data(show_plots=False):

    random_extinction_factor = 0.9
    k = simcado.optics.get_filter_curve("Ks") * random_extinction_factor

    cmd = simcado.UserCommands("HAWK-I_config/hawki.config")

    cmd["INST_FILTER_TC"] = k
    cmd["ATMO_BG_MAGNITUDE"] = 13.6
    cmd["OBS_EXPTIME"] = 10
    cmd["FPA_CHIP_LAYOUT"] = "HAWK-I_config/FPA_hawki_layout_cen.dat"
    cmd["FPA_LINEARITY_CURVE"] = "HAWK-I_config/FPA_hawki_linearity_ext.dat"

    opt = simcado.OpticalTrain(cmd)
    fpa = simcado.Detector(cmd, small_fov=False)

    if show_plots:
        plt.plot(opt.tc_source)
        plt.show()

    hdu_tbls = []
    for i in range(4):
        hdu_tbls += [ascii.read("M4/M4_chip" + str(i) + "table.dat")]

    gain = np.array([1.87, 1.735, 1.705, 2.11])
    hdus = []

    for i in range(4):
        x = (hdu_tbls[i]["x_corr"] - 1024) * 0.106
        y = (hdu_tbls[i]["y_corr"] - 1024) * 0.106

        k_m = hdu_tbls[i]["k_m"]

        src = simcado.source.stars(mags=k_m, x=x, y=y)
        fpa.chips[0].gain = gain[i]

        src.apply_optical_train(opt, fpa)
        hdus += fpa.read_out()

    for i in range(1, 4):
        hdus[i] = fits.ImageHDU(data=hdus[i].data, header=hdus[i].header)

    hdus = fits.HDUList(hdus)
    hdus.writeto("M4/hawkado_test10.fits", clobber=True)
예제 #7
0
def show_limiting_mags_micado():
    filter_names = ["J", "H", "Ks", "Br-gamma"]
    bg_mags = [16.5, 14.4, 13.6, 13.6]
    exptimes = np.array([2.6, 10, 60, 600, 3600, 18000, 36000])
    mmins = [19, 19, 18, 16]

    etcs = []

    for i in range(4):
        cmd = simcado.UserCommands()
        cmd["FPA_LINEARITY_CURVE"] = None
        cmd["ATMO_BG_MAGNITUDE"] = bg_mags[i]
        cmd["INST_FILTER_TC"] = filter_names[i]

        opt = simcado.OpticalTrain(cmd)
        etcs += [ETC(cmds=cmd, opt_train=opt, mmin=mmins[i], mmax=30)]

    plt.figure(figsize=(15, 15))

    my_lim_mags = []
    for i in range(4):
        plt.subplot(2, 2, i + 1)

        my_snr = etcs[i]

        lim_mags = my_snr.limiting_magnitudes(exptimes=exptimes,
                                              plot=True,
                                              limiting_sigmas=[5, 10, 250])  #
        lim_mags = np.array(lim_mags).T

        my_lim_mags += [lim_mags]

        for lm, sig in zip(lim_mags, [5, 10, 250]):
            print(
                str(filter_names[i]) + " & " + str(sig) + r"\sig & " +
                str([str(np.round(m, 1))[:4] + r"\m  &  "
                     for m in lm])[1:-1].replace(",", "").replace("'", "") +
                r"\\")

    plt.savefig("images/MICADO_limiting_mags_JHKBrG.png", format="png")
    plt.savefig("images/MICADO_limiting_mags_JHKBrG.pdf", format="pdf")

    return my_lim_mags
예제 #8
0
def run_simcado():
    import simcado as sim
    import os
    cmd = sim.UserCommands()
    cmd["OBS_EXPTIME"] = 3600
    cmd["OBS_NDIT"] = 1
    cmd["INST_FILTER_TC"] = "J"

    src = sim.source.source_1E4_Msun_cluster()
    opt = sim.OpticalTrain(cmd)
    fpa = sim.Detector(cmd)

    src.apply_optical_train(opt, fpa)
    fpa.read_out("my_output.fits")

    is_there = os.path.exists("my_output.fits")
    os.remove("my_output.fits")

    return is_there
예제 #9
0
def background_increases_consistently_with_exptime():
    """
    Run an empty source for exposure time: (1,2,4,8,16,32,64) mins
    If true the background level increases linearly and the stdev increases as sqrt(exptime)
    """

    import numpy as np
    import simcado as sim

    cmd = sim.UserCommands()
    cmd["OBS_REMOVE_CONST_BG"] = "no"

    opt = sim.OpticalTrain(cmd)
    fpa = sim.Detector(cmd)

    stats = []

    for t in [2**i for i in range(7)]:
        src = sim.source.empty_sky()
        src.apply_optical_train(opt, fpa)
        hdu = fpa.read_out(OBS_EXPTIME=60 * t, FPA_LINEARITY_CURVE=None)
        im = hdu[0].data
        stats += [[t, np.sum(im), np.median(im), np.std(im)]]

    stats = np.array(stats)

    factors = stats / stats[0, :]
    bg_stats = [
        i == np.round(l**2) == np.round(j) == np.round(k)
        for i, j, k, l in factors
    ]

    return_val = np.all(bg_stats)
    if not return_val:
        print(factors)

    return return_val
예제 #10
0
def snr_curve(exptimes,
              mmin=20,
              mmax=30,
              filter_name="Ks",
              aperture_radius=4,
              cmds=None,
              **kwargs):
    """
    Get the signal to noise ratios for a series of magnitudes and exposure times

    This function "observes" a grid of 100 stars equally spaced in the range [``mmin``, ``mmax``]
    The stars are observed for all times given in ``exptime`` and the SNR for each star is returned
    for each exposure time.

    Parameters
    ----------
    exptimes : float, list
        [s] exposure times for the stars

    mmin, mmax
        [mag] minimum and maximum magnitudes tor the SNR curve

    filter_name : str
        The name of a filter installed in SimCADO - see ``:func:~simcado.optics.get_filter_set()``

    aperture_radius : int
        [pixels] The radius of the aperture places around each star

    cmds : UserCommands object
        Used to control the observation fo the grid of stars


    Optional Parameters
    -------------------
    **kwargs : Anything that you want to pass to a ``UserCommands`` object


    Returns
    -------
    snr_array : list of arrays
        The best fit to the Magnitude-SNR curve for each entry in ``exptimes``

    mags : np.ndarray
        [mag] The magnitudes that the SNR values correspond to. Generally 100 values
        in a np.linspace range between ``mmin`` and ``mmax``


    See Also
    --------
    ``:func:~simcado.optics.get_filter_set()``

    """

    if isinstance(exptimes, (float, int)):
        exptimes = [exptimes]

    paranal_bg = {"J": 16.5, "H": 14.4, "Ks": 13.6}

    default_cmds = sim.UserCommands()
    default_cmds["ATMO_EC"] = "none"
    default_cmds["FPA_USE_NOISE"] = "no"
    if filter_name in paranal_bg.keys():
        default_cmds["ATMO_BG_MAGNITUDE"] = paranal_bg[filter_name]

    if cmds is not None:
        default_cmds.update(cmds)

    default_cmds.update(kwargs)

    q = sim.simulation._make_snr_grid_fpas(filter_names=[filter_name],
                                           mmin=mmin,
                                           mmax=mmax,
                                           cmds=default_cmds)
    fpa, src = q[0][0], q[1]

    mags = np.linspace(mmin, mmax, 100)

    r = aperture_radius
    r_out = 48
    r_width = 5

    snr_array = []
    for exptime in exptimes:

        hdu = fpa.read_out(OBS_EXPTIME=exptime)
        data = hdu[0].data

        sq_aps = []
        bg_stats = []

        for i in range(len(src.x_pix)):

            x, y = int(src.x_pix[i]), int(src.y_pix[i])
            sq_ap = np.copy(data[y - r:y + r + 1, x - r:x + r + 1])
            sq_aps += [sq_ap]

            bg_ap = np.copy(data[y - r_out:y + r_out + 1,
                                 x - r_out:x + r_out + 1])
            bg_ap[r_width:-r_width, r_width:-r_width] = 0

            av, med, std = sigma_clipped_stats(bg_ap[bg_ap != 0])
            bg_stats += [[av, med, std]]

        RON = default_cmds["FPA_READOUT_MEDIAN"]
        bg_med = np.array([s[1] for s in bg_stats])
        bg_std = np.array([s[0] for s in bg_stats])
        n_pix = (r * 2 + 1)**2

        raw = np.array([np.sum(s) for s in sq_aps])
        sig = raw - bg_med * n_pix

        sig_shot = np.sqrt(sig)
        bg_shot = np.sqrt(bg_med * n_pix)
        bg_shot_std = np.sqrt(n_pix) * bg_std
        e_shot = np.sqrt(n_pix * RON**2)

        tot_err = np.sqrt(sig_shot**2 + bg_shot**2 + e_shot**2)

        snr_val = sig / tot_err
        mask = snr > 10

        log_snr = np.log10(snr_val[mask])
        p = np.polyfit(mags[mask], log_snr, 2)
        snr_fit = 10**np.polyval(p, mags)

        snr_array += [snr_fit]

    return snr_array, mags
예제 #11
0
def _make_snr_grid_fpas(filter_names=["J", "H", "Ks"],
                        mmin=22,
                        mmax=32,
                        cmds=None,
                        **kwargs):
    """
    Makes a series of :class:`.Detector` objects containing a grid of stars


    Parameters
    ----------
    filter_names : list
        Which filters to use for the images. See ``simcado.optices.get_filter_set()``

    mmin, mmax : float
        [mag] Minimum and maximum magnitudes to use for the grid of stars

    cmds : simcado.UserCommands
        A custom set of commands for building the optical train

    Optional Parameters
    -------------------
    Any Keyword-Value pairs accepted by a
    :class:`~simcado.commands.UserCommands` object

    Returns
    -------
    fpas : list
        A list of :class:`Detector` objects with the grid of stars for each filter
        len(fpas) == len(filter_names)
    grid : simcado.Source
        A :class:`Source` object containing the grids of stars

    See Also
    --------
    :class:`~simcado.commands.UserCommands`

    """

    if isinstance(filter_names, str):
        filter_names = [filter_names]

    if not isinstance(cmds, list):
        cmds = [cmds] * len(filter_names)

    fpas = []
    grids = []
    for filt, cmd in zip(filter_names, cmds):
        if cmd is None:
            cmd = sim.UserCommands()
        #cmd["FPA_USE_NOISE"] = "no"
        cmd["OBS_NDIT"] = 1
        cmd["FPA_LINEARITY_CURVE"] = "none"
        cmd["FPA_CHIP_LAYOUT"] = "small"
        cmd.update(kwargs)

        star_sep = cmd["SIM_DETECTOR_PIX_SCALE"] * 100

        grid = sim.source.star_grid(100,
                                    mmin,
                                    mmax,
                                    filter_name=filt,
                                    separation=star_sep)
        grids += [grid]

        hdus, (cmd, opt, fpa) = sim.run(grid,
                                        filter_name=filt,
                                        cmds=cmd,
                                        return_internals=True)
        fpas += [fpa]

    return fpas, grid
예제 #12
0
def run(src,
        mode="wide",
        cmds=None,
        opt_train=None,
        fpa=None,
        detector_layout="small",
        filename=None,
        return_internals=False,
        filter_name=None,
        exptime=None,
        sub_pixel=False,
        **kwargs):
    """
    Run a MICADO simulation with default parameters

    Parameters
    ----------
    src : simcado.Source
        The object of interest

    mode : str, optional
        ["wide", "zoom"] Default is "wide", for a 4mas FoV. "Zoom" -> 1.5mas

    cmds : simcado.UserCommands, optional
        A custom set of commands for the simulation. Default is None

    opt_train : simcado.OpticalTrain, optional
        A custom optical train for the simulation. Default is None

    fpa : simcado.Detector, optional
        A custom detector layout for the simulation. Default is None

    detector_layout : str, optional
        ["small", "centre", "full", "tiny"] Default is "small".
        "small"   - 1x 1k-detector centred in the FoV
        "tiny"    - 128 x 128 pixels centred in the FoV
        "centre"  - 1x 4k-detector centred in the FoV
        "full"    - 9x 4k-detectors

    filename : str, optional
        The filepath for where the FITS images should be saved.
        Default is None. If None, the output images are returned to the user as
        FITS format astropy.io.HDUList objects.

    return_internals : bool
        [False, True] Default is False. If True, the ``UserCommands``,
        ``OpticalTrain`` and ``Detector`` objects used in the simulation are
        returned in a tuple: ``return hdu, (cmds, opt_train, fpa)``

    filter_name : str, TransmissionCurve
        Analogous to passing INST_FILTER_TC as a keyword argument

    exptime : int, float
        [s] Analogous to passing OBS_EXPTIME as a keyword argument

    """

    if cmds is None:
        cmds = sim.UserCommands()
        cmds["INST_FILTER_TC"] = "Ks"

        if detector_layout.lower() in ("tiny", "small", "centre", "center"):
            cmds["FPA_CHIP_LAYOUT"] = detector_layout
        else:
            cmds["FPA_CHIP_LAYOUT"] = 'full'

        if mode == "wide":
            cmds["SIM_DETECTOR_PIX_SCALE"] = 0.004
            cmds["INST_NUM_MIRRORS"] = 11
        elif mode == "zoom":
            cmds["SIM_DETECTOR_PIX_SCALE"] = 0.0015
            cmds["INST_NUM_MIRRORS"] = 13
        else:
            raise ValueError("'mode' must be either 'wide' or ' zoom', not " +
                             mode)

    if filter_name is not None:
        cmds["INST_FILTER_TC"] = filter_name

    if exptime is not None:
        cmds["OBS_EXPTIME"] = exptime

    # update any remaining keywords
    cmds.update(kwargs)

    if opt_train is None:
        opt_train = sim.OpticalTrain(cmds)
    if fpa is None:
        fpa = sim.Detector(cmds, small_fov=False)

    print("Detector layout")
    print(fpa.layout)
    print("Creating", len(cmds.lam_bin_centers), "layer(s) per chip")
    print(len(fpa.chips), "chip(s) will be simulated")

    src.apply_optical_train(opt_train, fpa, sub_pixel=sub_pixel)

    if filename is not None:
        if cmds["OBS_SAVE_ALL_FRAMES"] == "yes":
            for n in cmds["OBS_NDIT"]:
                fname = filename.replace(".", str(n) + ".")
                hdu = fpa.read_out(filename=fname, to_disk=True, OBS_NDIT=1)
        else:
            hdu = fpa.read_out(filename=filename, to_disk=True)
    else:
        hdu = fpa.read_out()

    if return_internals:
        return hdu, (cmds, opt_train, fpa)
    else:
        return hdu
예제 #13
0
def plot_micado_rainbow(ab_mags=False):
    axs = [[0.1, 0.5, 0.4, 0.4], [0.5, 0.5, 0.4, 0.4], [0.1, 0.1, 0.4, 0.4],
           [0.5, 0.1, 0.4, 0.4], [0.1, 0.9, 0.8, 0.03]]

    text_heights = [
        np.array([28.3, 27.2, 25.7, 24.6, 22.9, 21.4]) + 1.6,
        np.array([28.2, 27.2, 25.7, 24.6, 22.9, 21.3]) + 1,
        np.array([28.3, 27.2, 25.7, 24.6, 22.9, 21.4]) + 0.3,
        np.array([28.3, 27.2, 25.7, 24.6, 22.9, 21.3]) - 0.9
    ]

    mmins = [19, 19, 18, 16]

    filter_names = ["J", "H", "Ks", "Br-gamma"]
    label_names = ["J", "H", "K$_S$", "Br$\gamma$"]

    ab = [0.9, 1.4, 1.85, 1.85] if ab_mags else [0] * 4
    bg_mags = [16.5, 14.4, 13.6, 13.6]

    exptimes = np.logspace(np.log10(60), np.log10(10 * 3600), 10)

    plt.figure(figsize=(12, 8))

    for i in range(4):
        filt_name = filter_names[i]
        cmd = simcado.UserCommands()
        cmd["FPA_LINEARITY_CURVE"] = None
        cmd["ATMO_BG_MAGNITUDE"] = 16.5
        cmd["INST_FILTER_TC"] = filt_name

        opt = simcado.OpticalTrain(cmd)
        micado_etc = ETC(cmds=cmd, opt_train=opt, mmin=mmins[i], mmax=32)

        map_ax = plt.axes(axs[i])

        snrs = micado_etc.snr(exptimes=exptimes, fitted=True)
        micado_etc.plot_snr_rainbow(exptimes / 3600,
                                    snrs,
                                    snr_levels=[1, 5, 10, 50, 250, 1000],
                                    text_heights=text_heights[i] + ab[i],
                                    text_center=5,
                                    use_colorbar=False)

        plt.ylim(18, 31.9)
        plt.xlim(0, 9.9)
        plt.ylabel(label_names[i], fontsize=14)
        if i in [1, 3]:
            plt.gca().yaxis.tick_right()
            plt.gca().yaxis.set_label_position("right")
        if i in [0, 1]:
            plt.gca().set_xticklabels("")

    plt.axes(axs[4])
    cb = plt.colorbar(cax=plt.gca(), orientation="horizontal")
    plt.gca().xaxis.tick_top()

    plt.text(0,
             48,
             "Signal to Noise Ratio ($\sigma$)",
             horizontalalignment="center",
             fontsize=14)
    plt.text(0,
             16,
             "Exposure time [hours]",
             horizontalalignment="center",
             fontsize=14)
    if ab_mags:
        plt.text(-11.5,
                 32,
                 "AB magnitudes",
                 rotation=90,
                 verticalalignment="center",
                 fontsize=14)
    else:
        plt.text(-11.5,
                 32,
                 "Vega magnitudes",
                 rotation=90,
                 verticalalignment="center",
                 fontsize=14)

    plt.savefig("images/MICADO_SNR_Rainbow_JHKBrG_ab.png", format="png")
    plt.savefig("images/MICADO_SNR_Rainbow_JHKBrG_ab.pdf", format="pdf")
            mags = imf.abs_mag_from_mass(masses) + dist_mod

            radius = 4
            n = len(lums)
            a = px_fov
            im = np.zeros((a, a))
            x, y = np.random.randint(radius, a - radius, (2, n))
            xs = 0.004 * (x - a // 2)
            ys = 0.004 * (y - a // 2)

            dist = 10**(1 + dist_mod / 5)
            dist = round(dist)
            star_density = round(mass)
            print("star_density", star_density, "dist", dist, "mass", mass)

            cmd = sim.UserCommands()
            cmd["OBS_EXPTIME"] = exptime
            cmd["SCOPE_PSF_FILE"] = psf_name
            cmd["INST_FILTER_TC"] = "Ks"
            cmd["FPA_LINEARITY_CURVE"] = "none"
            cmd["FPA_USE_NOISE"] = "no"
            cmd["FPA_CHIP_LAYOUT"] = "FPA_chip_layout_2as.dat"

            opt = sim.OpticalTrain(cmd)
            fpa = sim.Detector(cmd, small_fov=False)

            src = sim.source.stars(mags=mags, x=xs, y=ys)
            src.apply_optical_train(opt, fpa)

            hdu = fpa.read_out()
            im = hdu[0].data.T
예제 #15
0
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.colors import LogNorm

import simcado
from project.etc import ETC

filt_name = "J"
cmd = simcado.UserCommands("HAWK-I_config/hawki.config")
cmd["FPA_LINEARITY_CURVE"] = None
cmd["ATMO_BG_MAGNITUDE"] = 16.5
cmd["INST_FILTER_TC"] = filt_name

opt = simcado.OpticalTrain(cmd)
hawki_etc = ETC(cmds=cmd, opt_train=opt, mmin=16, mmax=26)

exptimes = np.logspace(0.3, 3.55, 10)
snrs = hawki_etc.snr(exptimes=exptimes, fitted=True)
hawki_etc.plot_snr_rainbow(
    exptimes / 60,
    snrs,
    snr_levels=[1, 5, 10, 50, 250, 1000],
    text_heights=np.array([21.3, 20, 18.8, 17.5, 15.8, 14.3]) + 3.5,
    text_center=30)

plt.savefig("images/HAWKI_rainbow_J.png", format="png")
plt.savefig("images/HAWKI_rainbow_J.pdf", format="pdf")
예제 #16
0
def plot_background_flux():

    #K band 44  photons cm-2 s-1 A-1  - average BG is 13.6
    #H band 93  photons cm-2 s-1 A-1  - average BG is 14.4
    #J band 193 photons cm-2 s-1 A-1  - average BG is 16.5

    # This works out to ~ 1700 ph/pix/dit for J-band and ~12500 ph/pix/dit in K-band
    # Old calculation was with 4500 and 15000, but this was based on filter widths of 0.26 and 0.4um.
    # The HAWKI filters are more like 0.15 and 0.35um for J and Ks

    # Depending on which images we use, J BG flux ranges from 700 to 4000 and K from 12000 to 15000
    # This is exactly what we see in the images

    f0 = np.array([193, 93, 44]) * 1E4 * u.Unit("m-2 s-1 AA-1")
    area = (4.1**2 - 0.6**2) * np.pi * u.m**2
    dlam = np.array([1500, 2900, 3400]) * u.AA
    exptime = 10 * u.s
    mag = np.array([16.5, 14.4, 13.6])
    mag_corr = 10**(-0.4 * mag) / (u.arcsec**2)
    pix_size = 0.106**2 * u.arcsec**2
    inst_eff = 0.5
    gain = 1.7

    bg_ph_hawki = f0 * dlam * mag_corr * area * exptime * pix_size * inst_eff * gain
    print("HAWKI JHK Sky BG: [ADU/pix/dit]", bg_ph_hawki)

    ### Test the SimCADO background levels for HAWKI - rough calcluation

    sim_f0 = np.array([
        simcado.source.zero_magnitude_photon_flux(i) for i in ["J", "H", "Ks"]
    ]) * u.Unit("ph/m2/s")
    print("BG flux JHK [ph/arcsec2/m2/s]", sim_f0 * mag_corr)
    print("BG flux JHK [ADU/pix/dit]",
          sim_f0 * mag_corr * area * exptime * pix_size * inst_eff * gain)
    print("Scale factor for system",
          area * exptime * pix_size * inst_eff * gain)

    # ## Create an optical train for the system
    # Use just the K=13.6 and J=16.5 and scaling a blank spectrum
    #
    # For K we get a background flux of ~18000 ph/pix/dit and J ~2500 ph/pix/dit. This is consistent with the upper and lower bounds set by the standard flux values given by theoretical values based on the ESO sky background values and empirical values from the HAWK-I ETC.
    #
    # The limits are  15000 < K < 28000 and 2000 < J < 2800 ph/pix/dit
    # This equates to 10000 < K < 16000 and 1200 < J < 1600 ADU/pix/dit

    cmd = simcado.UserCommands("HAWK-I_config/hawki.config")

    cmd["OBS_EXPTIME"] = 10
    cmd["INST_FILTER_TC"] = "J"
    cmd["ATMO_USE_ATMO_BG"] = "yes"
    cmd["ATMO_BG_MAGNITUDE"] = 16.5
    #cmd["ATMO_EC"] = None

    #cmd["SCOPE_USE_MIRROR_BG"] = "no"
    #cmd["FPA_USE_NOISE"] = "no"

    #cmd["FPA_LINEARITY_CURVE"] = None

    opt = simcado.OpticalTrain(cmd)
    fpa = simcado.Detector(cmd, small_fov=False)

    empty_sky = simcado.source.empty_sky()
    empty_sky.apply_optical_train(opt, fpa)

    myfits = fpa.read_out(OBS_EXPTIME=10)

    plt.imshow(myfits[0].data)
    plt.colorbar()
    plt.show()
예제 #17
0
def mimic_image(hdu,
                catalogue,
                cmds=None,
                hdu_ext=0,
                sim_chip_n=0,
                return_stamps=False,
                cat_ra_name="RA",
                cat_dec_name="DE",
                cat_filter_name="J",
                **kwargs):
    """
    Create a SimCADO image to mimic a real FITS file
    
    Parameters
    ----------
    hdu : str, astropy.HDUList
        The original FITS object- either a filename or an astropy.HDUList object
    
    catalogue : str, astropy.Table
        A catalogue of stars - either a filename or an astropy.Table object
    
    cmds : str, simcado.UserCommands
        Commands by which to simulate the image - a filename to a .config file or a UserCommands object
    
    hdu_ext : int
        The extension in the original FITS file which should be simulated
    
    sim_chip_n : int
        Which chip in the FPA_LAYOUT to simulate. Passed to apply_optical_train() and read_out()
    
    return_stamps : bool
        If True, returns two PostageStamps object for the original HDU and the generated HDU
   
    cat_ra_name, cat_dec_name, cat_filter_name : str
        The names of the column in catalogue which point to the RA, Dec and filter magnitudes for the stars
    
        
    Optional Parameters
    -------------------
    As passed to a PostageStamps object
    
    "dx"           : 0,
    "dy "          : 0,
    "bg_tile_size" : 24, 
    "stamp_width"  : 24, 
    "hot_pixel_threshold" : 3000 
    
    
    Returns
    -------
    hdu_sim, src [, post_real, post_sim]
        If return_stamps is True, post_real and post_sim are returned
        
        
    Examples
    --------
    ::
    
        >>> hdu_real = fits.open("HAWKI.2008-11-05T04_08_55.552.fits")
        >>> cat = ascii.read("ngc362_cohen.dat")    
        >>> 
        >>> dx, dy = -5, 15
        >>> 
        >>> cmd = sim.UserCommands("hawki_ngc362.config")
        >>> cmd["INST_FILTER_TC"] = "J"
        >>> cmd["OBS_EXPTIME"] = 10
        >>> 
        >>> out = mimic_image(hdu=hdu_real, catalogue=cat, cmds=cmd, hdu_ext=3, 
        ...                   sim_chip_n=3, return_stamps=True, 
        ...                   dx=dx, dy=dy)
        >>> hdu_sim, src, post_real, post_sim = out
        >>> len(out)
        4
        
    """

    if isinstance(hdu, str) and os.path.exists(hdu):
        hdu = fits.open(hdu)[hdu_ext]
    elif isinstance(hdu, fits.HDUList):
        hdu = hdu[hdu_ext]
    else:
        raise ValueError("hdu must be a filename or an astropy HDU object: " +
                         type(hdu))

    if isinstance(catalogue, str) and os.path.exists(catalogue):
        cat = ascii.read(catalogue)
    elif isinstance(catalogue, Table):
        cat = catalogue
    else:
        raise ValueError(
            "catalogue must be a filename or an astropy.Table object: " +
            type(catalogue))

    if isinstance(cmds, str) and os.path.exists(cmds):
        cmds = sim.UserCommands(cmds)
    elif isinstance(cmds, sim.UserCommands):
        pass
    else:
        raise ValueError(
            "cmds must be a filename or an simcado.UserCommands object: " +
            type(cmds))

    fig = plt.figure(figsize=(0.1, 0.1))
    apl_fig = aplpy.FITSFigure(hdu, figure=fig)

    # get the RA DEC position of the centre of the HAWKI FoV
    xc, yc = hdu.header["CRPIX1"], hdu.header["CRPIX2"]
    ra_cen, dec_cen = apl_fig.pixel2world(xc, yc)

    # get the x,y positions in arcsec from the HAWKI FoV centre
    y = (cat[cat_dec_name] - dec_cen) * 3600
    x = -(cat[cat_ra_name] - ra_cen) * 3600 * np.cos(cat[cat_dec_name] / 57.3)
    mag = cat[cat_filter_name]

    # make a Source object with the x,y positions in arcsec from the HAWKI FoV centre
    src = sim.source.stars(mags=mag, filter_name=cat_filter_name, x=x, y=y)

    opt = sim.OpticalTrain(cmds)
    fpa = sim.Detector(cmds, small_fov=False)

    print(sim_chip_n)

    src.apply_optical_train(opt, fpa, chips=sim_chip_n)
    hdu_sim = fpa.read_out(chips=sim_chip_n)

    ## Get the Postage Stamps
    if return_stamps:

        params = {
            "dx": 0,
            "dy ": 0,
            "bg_tile_size": 24,
            "stamp_width": 24,
            "hot_pixel_threshold": 3000
        }
        params.update(**kwargs)

        w, h = hdu_sim[0].data.shape
        mask = (src.x_pix > 0) * (src.x_pix < w) * (src.y_pix > 0) * (src.y_pix
                                                                      < h)

        xw = cat[cat_ra_name][mask]
        yw = cat[cat_dec_name][mask]
        mag = cat[cat_filter_name][mask]

        # get the x,y pixel positions of the stars in the simulated image
        xps = src.x_pix[mask]
        yps = src.y_pix[mask]

        # get the x,y pixel positions of the stars in the real image, include offset if needed
        xpr, ypr = apl_fig.world2pixel(xw, yw)
        xpr += params["dx"]
        ypr += params["dy"]

        # get the images from the FITS objects
        im_sim = np.copy(hdu_sim[0].data)
        im_sim -= np.median(im_sim)
        post_sim = PostageStamps(im_sim, x=xps, y=yps, **params)

        im_real = np.copy(hdu.data)
        im_real -= np.median(im_real)
        post_real = PostageStamps(im_real, x=xpr, y=ypr, **params)

        return hdu_sim, src, post_real, post_sim

    else:
        return hdu_sim, src
예제 #18
0
def test_load_UserCommands():
    import simcado as sim
    cmd = sim.UserCommands()
    assert type(cmd) == sim.commands.UserCommands