Esempio n. 1
0
def fit_ellipse_for_source(
    friendid=None,
    detectid=None,
    coords=None,
    shotid=None,
    subcont=True,
    convolve_image=False,
    pixscale=pixscale,
    imsize=imsize,
    wave_range=None,
):

    if detectid is not None:

        global deth5

        detectid_obj = detectid

        if detectid_obj <= 2190000000:
            det_info = deth5.root.Detections.read_where("detectid == detectid_obj")[0]
            linewidth = det_info["linewidth"]
            wave_obj = det_info["wave"]
            redshift = wave_obj / (1216) - 1
        else:
            det_info = conth5.root.Detections.read_where("detectid == detectid_obj")[0]
            redshift = 0
            wave_obj = 4500

        coords_obj = SkyCoord(det_info["ra"], det_info["dec"], unit="deg")

        shotid_obj = det_info["shotid"]
        fwhm = surveyh5.root.Survey.read_where("shotid == shotid_obj")["fwhm_virus"][0]
        amp = det_info["multiframe"]

        if wave_range is not None:
            wave_range_obj = wave_range
        else:
            if detectid_obj <= 2190000000:
                wave_range_obj = [wave_obj - 2 * linewidth, wave_obj + 2 * linewidth]
            else:
                wave_range_obj = [4100, 4200]

        if coords is not None:
            coords_obj = coords

        if shotid is not None:
            shotid_obj = shotid
            fwhm = surveyh5.root.Survey.read_where("shotid == shotid_obj")[
                "fwhm_virus"
            ][0]

        try:
            hdu = make_narrowband_image(
                coords=coords_obj,
                shotid=shotid_obj,
                wave_range=wave_range_obj,
                imsize=imsize * u.arcsec,
                pixscale=pixscale * u.arcsec,
                subcont=subcont,
                convolve_image=convolve_image,
                include_error=True,
            )

        except:
            print("Could not make narrowband image for {}".format(detectid))
            return np.nan, np.nan

    elif friendid is not None:

        global friend_cat

        sel = friend_cat["friendid"] == friendid
        group = friend_cat[sel]
        coords_obj = SkyCoord(ra=group["icx"][0] * u.deg, dec=group["icy"][0] * u.deg)
        wave_obj = group["icz"][0]
        redshift = wave_obj / (1216) - 1
        linewidth = group["linewidth"][0]
        shotid_obj = group["shotid"][0]
        fwhm = group["fwhm"][0]
        amp = group["multiframe"][0]

        if wave_range is not None:
            wave_range_obj = wave_range
        else:
            wave_range_obj = [wave_obj - 2 * linewidth, wave_obj + 2 * linewidth]

        if shotid is not None:
            shotid_obj = shotid
            fwhm = surveyh5.root.Survey.read_where("shotid == shotid_obj")[
                "fwhm_virus"
            ][0]

        try:
            hdu = make_narrowband_image(
                coords=coords_obj,
                shotid=shotid_obj,
                wave_range=wave_range_obj,
                imsize=imsize * u.arcsec,
                pixscale=pixscale * u.arcsec,
                subcont=subcont,
                convolve_image=convolve_image,
                include_error=True,
            )
        except:
            print("Could not make narrowband image for {}".format(friendid))
            return None

    elif coords is not None:
        coords_obj = coords

        if wave_range is not None:
            wave_range_obj = wave_range
        else:
            print(
                "You need to supply wave_range=[wave_start, wave_end] for collapsed image"
            )

        if shotid is not None:
            shotid_obj = shotid
            fwhm = surveyh5.root.Survey.read_where("shotid == shotid_obj")[
                "fwhm_virus"
            ][0]
        else:
            print("Enter the shotid to use (eg. 20200123003)")

        hdu = make_narrowband_image(
            coords=coords_obj,
            shotid=shotid_obj,
            wave_range=wave_range_obj,
            imsize=imsize * u.arcsec,
            pixscale=pixscale * u.arcsec,
            subcont=subcont,
            convolve_image=convolve_image,
            include_error=True,
        )
    else:
        print("You must provide a detectid, friendid or coords/wave_range/shotid")
        return np.nan, np.nan

    w = wcs.WCS(hdu[0].header)

    if friendid is not None:

        sel_friend_group = friend_cat["friendid"] == friendid
        group = friend_cat[sel_friend_group]
        eps = 1 - group["a2"][0] / group["b2"][0]
        pa = group["pa"][0] * np.pi / 180.0 - 90
        sma = group["a"][0] * 3600 / pixscale

        coords = SkyCoord(ra=group["icx"][0] * u.deg, dec=group["icy"][0] * u.deg)
        wave_obj = group["icz"][0]
        redshift = wave_obj / (1216) - 1
        linewidth = np.nanmedian(group["linewidth"])
        shotid_obj = group["shotid"][0]
        fwhm = group["fwhm"][0]

        geometry = EllipseGeometry(
            x0=w.wcs.crpix[0], y0=w.wcs.crpix[0], sma=sma, eps=eps, pa=pa
        )
    else:
        geometry = EllipseGeometry(
            x0=w.wcs.crpix[0], y0=w.wcs.crpix[0], sma=20, eps=0.2, pa=20.0
        )

    geometry = EllipseGeometry(
        x0=w.wcs.crpix[0], y0=w.wcs.crpix[0], sma=20, eps=0.2, pa=20.0
    )
    # geometry.find_center(hdu.data)
    # aper = EllipticalAperture((geometry.x0, geometry.y0), geometry.sma,
    #                          geometry.sma*(1 - geometry.eps), geometry.pa)

    # plt.imshow(hdu.data, origin='lower')
    # aper.plot(color='white')

    ellipse = Ellipse(hdu[0].data)
    isolist = ellipse.fit_image()
    iso_tab = isolist.to_table()

    if len(iso_tab) == 0:
        geometry.find_center(hdu[0].data, verbose=False, threshold=0.5)
        ellipse = Ellipse(hdu[0].data, geometry)
        isolist = ellipse.fit_image()
        iso_tab = isolist.to_table()

    if len(iso_tab) == 0:
        return np.nan, np.nan, np.nan

        try:
            # compute iso's manually in steps of 3 pixels
            ellipse = Ellipse(hdu[0].data)  # reset ellipse
            iso_list = []
            for sma in np.arange(1, 60, 2):
                iso = ellipse.fit_isophote(sma)
                if np.isnan(iso.intens):
                    # print('break at {}'.format(sma))
                    break
                else:
                    iso_list.append(iso)
            isolist = IsophoteList(iso_list)
            iso_tab = isolist.to_table()
        except:
            return np.nan, np.nan, np.nan

    try:
        model_image = build_ellipse_model(hdu[0].data.shape, isolist)
        residual = hdu[0].data - model_image
    except:
        return np.nan, np.nan, np.nan

    sma = iso_tab["sma"] * pixscale
    const_arcsec_to_kpc = cosmo.kpc_proper_per_arcmin(redshift).value / 60.0

    def arcsec_to_kpc(sma):
        dist = const_arcsec_to_kpc * sma
        return dist

    def kpc_to_arcsec(dist):
        sma = dist / const_arcsec_to_kpc
        return sma

    dist_kpc = (
        sma * u.arcsec.to(u.arcmin) * u.arcmin * cosmo.kpc_proper_per_arcmin(redshift)
    )
    dist_arcsec = kpc_to_arcsec(dist_kpc)

    # print(shotid_obj, fwhm)
    # s_exp1d = models.Exponential1D(amplitude=0.2, tau=-50)

    alpha = 3.5
    s_moffat = models.Moffat1D(
        amplitude=1,
        gamma=(0.5 * fwhm) / np.sqrt(2 ** (1.0 / alpha) - 1.0),
        x_0=0.0,
        alpha=alpha,
        fixed={"amplitude": False, "x_0": True, "gamma": True, "alpha": True},
    )

    s_init = models.Exponential1D(amplitude=0.2, tau=-50)

    fit = fitting.LevMarLSQFitter()
    s_r = fit(s_init, dist_kpc, iso_tab["intens"])

    # Fitting can be done using the uncertainties as weights.
    # To get the standard weighting of 1/unc^2 for the case of
    # Gaussian errors, the weights to pass to the fitting are 1/unc.
    # fitted_line = fit(line_init, x, y, weights=1.0/yunc)

    # s_r = fit(s_init, dist_kpc, iso_tab['intens'])#, weights=iso_tab['intens']/iso_tab['intens_err'] )

    print(s_r)
    try:
        r_n = -1.0 * s_r.tau  # _0 #* const_arcsec_to_kpc
    except:
        r_n = np.nan  # r_n = -1. * s_r.tau_0
    try:
        sel_iso = np.where(dist_kpc >= 2 * r_n)[0][0]
    except:
        sel_iso = -1

    aper = EllipticalAperture(
        (isolist.x0[sel_iso], isolist.y0[sel_iso]),
        isolist.sma[sel_iso],
        isolist.sma[sel_iso] * (1 - isolist.eps[sel_iso]),
        isolist.pa[sel_iso],
    )

    phottable = aperture_photometry(hdu[0].data, aper, error=hdu[1].data)
    flux = phottable["aperture_sum"][0] * 10 ** -17 * u.erg / (u.cm ** 2 * u.s)
    flux_err = phottable["aperture_sum_err"][0] * 10 ** -17 * u.erg / (u.cm ** 2 * u.s)

    lum_dist = cosmo.luminosity_distance(redshift).to(u.cm)
    lum = flux * 4.0 * np.pi * lum_dist ** 2
    lum_err = flux_err * 4.0 * np.pi * lum_dist ** 2

    if detectid:
        name = detectid
    elif friendid:
        name = friendid

    # Get Image data from Elixer
    catlib = catalogs.CatalogLibrary()
    try:
        cutout = catlib.get_cutouts(
            position=coords_obj,
            side=imsize,
            aperture=None,
            dynamic=False,
            filter=["r", "g", "f606W"],
            first=True,
            allow_bad_image=False,
            allow_web=True,
        )[0]
    except:
        print("Could not get imaging for " + str(name))

    zscale = ZScaleInterval(contrast=0.5, krej=1.5)
    vmin, vmax = zscale.get_limits(values=hdu[0].data)

    fig = plt.figure(figsize=(20, 12))
    fig.suptitle(
        "{}  ra={:3.2f}, dec={:3.2f}, wave={:5.2f}, z={:3.2f}, mf={}".format(
            name, coords_obj.ra.value, coords_obj.dec.value, wave_obj, redshift, amp
        ),
        fontsize=22,
    )

    ax1 = fig.add_subplot(231, projection=w)
    plt.imshow(hdu[0].data, vmin=vmin, vmax=vmax)
    plt.xlabel("RA")
    plt.ylabel("Dec")
    plt.colorbar()
    plt.title("Image summed across 4*linewidth")

    ax2 = fig.add_subplot(232, projection=w)
    plt.imshow(model_image, vmin=vmin, vmax=vmax)
    plt.xlabel("RA")
    plt.ylabel("Dec")
    plt.colorbar()
    plt.title("model")

    ax3 = fig.add_subplot(233, projection=w)
    plt.imshow(residual, vmin=vmin, vmax=vmax)
    plt.xlabel("RA")
    plt.ylabel("Dec")
    plt.colorbar()
    plt.title("residuals (image-model)")
    # fig = plt.figure(figsize=(10,5))

    im_zscale = ZScaleInterval(contrast=0.5, krej=2.5)
    im_vmin, im_vmax = im_zscale.get_limits(values=cutout["cutout"].data)

    ax4 = fig.add_subplot(234, projection=cutout["cutout"].wcs)

    plt.imshow(
        cutout["cutout"].data,
        vmin=im_vmin,
        vmax=im_vmax,
        origin="lower",
        cmap=plt.get_cmap("gray"),
        interpolation="none",
    )

    plt.text(
        0.8,
        0.9,
        cutout["instrument"] + cutout["filter"],
        transform=ax4.transAxes,
        fontsize=20,
        color="w",
    )
    plt.contour(hdu[0].data, transform=ax4.get_transform(w))
    plt.xlabel("RA")
    plt.ylabel("Dec")
    aper.plot(
        color="white", linestyle="dashed", linewidth=2, transform=ax4.get_transform(w)
    )

    ax5 = fig.add_subplot(235)
    plt.errorbar(
        dist_kpc.value,
        iso_tab["intens"],
        yerr=iso_tab["intens_err"] * iso_tab["intens"],
        linestyle="none",
        marker="o",
        label="Lya SB profile",
    )

    plt.plot(dist_kpc, s_r(dist_kpc), color="r", label="Lya exp SB model", linewidth=2)

    plt.xlabel("Semi-major axis (kpc)")
    # plt.xlabel('Semi-major axis (arcsec)')
    plt.ylabel("Flux ({})".format(10 ** -17 * (u.erg / (u.s * u.cm ** 2))))
    plt.text(0.4, 0.7, "r_n={:3.2f}".format(r_n), transform=ax5.transAxes, fontsize=16)
    plt.text(
        0.4, 0.6, "L_lya={:3.2e}".format(lum), transform=ax5.transAxes, fontsize=16
    )
    secax = ax5.secondary_xaxis("top", functions=(kpc_to_arcsec, kpc_to_arcsec))
    secax.set_xlabel("Semi-major axis (arcsec)")
    # secax.set_xlabel('Semi-major axis (kpc)')
    plt.xlim(0, 100)

    # plt.plot(sma, s_r(sma), label='moffat psf')

    # plt.plot(dist_kpc.value, s1(kpc_to_arcsec(dist_kpc.value)),
    #        linestyle='dashed', linewidth=2,
    #         color='green', label='PSF seeing:{:3.2f}'.format(fwhm))

    # These two are the exact same
    # s1 = models.Moffat1D()
    # s1.amplitude = iso_tab['intens'][0]
    # alpha=3.5
    # s1.gamma = 0.5*(fwhm*const_arcsec_to_kpc)/ np.sqrt(2 ** (1.0 / alpha) - 1.0)
    # s1.alpha = alpha
    # plt.plot(r_1d, moffat_1d, color='orange')

    #    plt.plot(dist_kpc.value, (s1(dist_kpc.value)),
    #            linestyle='dashed', linewidth=2,
    #             color='blue', label='PSF seeing:{:3.2f}'.format(fwhm))

    E = Extract()
    E.load_shot(shotid_obj)
    moffat_psf = E.moffat_psf(seeing=fwhm, boxsize=imsize, scale=pixscale)
    moffat_shape = np.shape(moffat_psf)
    xcen = int(moffat_shape[1] / 2)
    ycen = int(moffat_shape[2] / 2)
    moffat_1d = (
        moffat_psf[0, xcen:-1, ycen] / moffat_psf[0, xcen, ycen] * iso_tab["intens"][0]
    )
    r_1d = moffat_psf[1, xcen:-1, ycen]
    E.close()

    plt.plot(
        arcsec_to_kpc(pixscale * np.arange(80)),
        iso_tab["intens"][0] * (moffat_psf[0, 80:-1, 80] / moffat_psf[0, 80, 80]),
        linestyle="dashed",
        color="green",
        label="PSF seeing:{:3.2f}".format(fwhm),
    )
    plt.legend()

    if friendid is not None:
        ax6 = fig.add_subplot(236, projection=cutout["cutout"].wcs)
        plot_friends(friendid, friend_cat, cutout, ax=ax6, label=False)
    plt.savefig("fit2d_{}.png".format(name))

    # filename = 'param_{}.txt'.format(name)
    # np.savetxt(filename, (r_n.value, lum.value))

    return r_n, lum, lum_err
Esempio n. 2
0
def main(argv=None):
    """ Main Function """

    parser = get_parser()
    args = parser.parse_args(argv)
    args.log = setup_logging()

    args.log.info(args)

    class FiberImage2D(tb.IsDescription):
        detectid = tb.Int64Col(pos=0)
        im_wave = tb.Float32Col(args.width, pos=1)
        im_sum = tb.Float32Col((args.height, args.width), pos=2)
        im_array = tb.Float32Col((4, args.height, args.width), pos=3)

    if args.merge:
        fileh = tb.open_file("merged_im2D.h5", "w")

        fibim2D_table = fileh.create_table(fileh.root,
                                           "FiberImages",
                                           FiberImage2D,
                                           "Fiber Cutout Images",
                                           expectedrows=1000000)
        phot_table = fileh.create_table(fileh.root,
                                        "PhotImages",
                                        PhotImage,
                                        "Photometric Images",
                                        expectedrows=1000000)
        spec_table = fileh.create_table(fileh.root,
                                        "Spec1D",
                                        Spec1D,
                                        "Aperture Summed Spectrum",
                                        expectedrows=1000000)

        files = sorted(glob.glob("im2D*.h5"))

        for file in files:
            args.log.info('Ingesting %s' % file)
            fileh_i = tb.open_file(file, "r")
            fibim2D_table_i = fileh_i.root.FiberImages.read()
            phot_table_i = fileh_i.root.PhotImages.read()
            spec_table_i = fileh_i.root.Spec1D.read()

            fibim2D_table.append(fibim2D_table_i)
            phot_table.append(phot_table_i)
            spec_table.append(spec_table_i)

            fileh_i.close()

        fibim2D_table.flush()
        phot_table.flush()
        spec_table.flush()

        fibim2D_table.cols.detectid.create_csindex()
        phot_table.cols.detectid.create_csindex()
        spec_table.cols.detectid.create_csindex()

        fibim2D_table.flush()
        phot_table.flush()
        spec_table.flush()

        fileh.close()
        sys.exit("Merged h5 files in current directory. Exiting")

    shotid_i = args.shotid

    detects = Detections(args.survey, loadtable=False)

    if args.infile:

        try:
            catalog = Table.read(args.infile, format="ascii")
        except:
            catalog = Table.read(args.infile)

        selcat = catalog["shotid"] == args.shotid

        detectlist = np.array(catalog["detectid"][selcat])

    elif args.dets:
        if op.exists(args.dets):
            try:
                catalog = Table.read(args.dets, format="ascii")
                selcat = catalog["shotid"] == int(shotid_i)
                detectlist = np.array(catalog["detectid"][selcat])
            except:
                detectlist = np.loadtxt(args.dets, dtype=int)
        else:
            args.log.warning('No dets for ' + str(shotid_i))
            sys.exit()

    if len(detectlist) == 0:
        sys.exit()

    # open up catalog library from elixer
    catlib = catalogs.CatalogLibrary()

    args.log.info("Opening shot: " + str(shotid_i))

    fibers = Fibers(args.shotid, survey=args.survey)

    if args.h5file:

        fileh = tb.open_file("im2D_" + str(args.shotid) + ".h5", "w")

        fibim2D_table = fileh.create_table(fileh.root, "FiberImages",
                                           FiberImage2D, "Fiber Cutout Images")

        phot_table = fileh.create_table(fileh.root, "PhotImages", PhotImage,
                                        "Photometric Images")
        spec_table = fileh.create_table(fileh.root, "Spec1D", Spec1D,
                                        "Aperture Summed Spectrum")

        for detectid_i in detectlist:

            # add data to HDF5 file
            row = fibim2D_table.row
            row["detectid"] = detectid_i
            sel = detects.detectid == detectid_i

            try:
                row["im_wave"] = get_2Dimage_wave(detectid_i,
                                                  detects,
                                                  fibers,
                                                  width=args.width,
                                                  height=args.height)
            except:
                args.log.error("Could not get wave array for %s" % detectid_i)

            try:
                row["im_sum"] = get_2Dimage(detectid_i,
                                            detects,
                                            fibers,
                                            width=args.width,
                                            height=args.height)
            except:
                args.log.error("Could not get Fiber sum for %s" % detectid_i)
            try:
                im_arr, fiber_table = get_2Dimage_array(detectid_i,
                                                        detects,
                                                        fibers,
                                                        width=args.width,
                                                        height=args.height)

                row["im_array"] = im_arr
            except:
                args.log.error("Could not get 4 Fiber info for %s" %
                               detectid_i)

            row.append()

            row_spec = spec_table.row
            spec_tab = detects.get_spectrum(detectid_i)
            row_spec["detectid"] = detectid_i
            row_spec["spec1D"] = spec_tab["spec1d"]
            row_spec["spec1D_err"] = spec_tab["spec1d_err"]
            row_spec.append()

            row_phot = phot_table.row

            # add in phot image, need RA/DEC from catalog
            # sel_det = detects.detectid == detectid_i
            # coord = detects.coords[sel_det]

            det_row = detects.hdfile.root.Detections.read_where(
                'detectid == detectid_i')

            coord = SkyCoord(ra=det_row["ra"] * u.deg,
                             dec=det_row["dec"] * u.deg)

            row_phot["detectid"] = detectid_i

            # ignore the Fall data for now
            if coord.dec.value > 10:
                try:
                    cutout = catlib.get_cutouts(
                        position=coord,
                        radius=5,
                        aperture=None,
                        dynamic=False,
                        filter="r",
                        first=True,
                    )[0]
                    if cutout["instrument"] == "HSC":
                        # get shape to ensure slicing on cropped images
                        phot = np.shape(cutout["cutout"].data)

                        row_phot["im_phot"] = cutout["cutout"].data
                        header = cutout["cutout"].wcs.to_header()
                        row_phot["im_phot_hdr"] = header.tostring()

                except:
                    pass
                    #args.log.warning("No imaging available for source")
            else:
                pass

            row_phot.append()

        spec_table.flush()
        phot_table.flush()
        fibim2D_table.flush()
        fileh.close()

    else:
        for detectid_i in detectlist:

            save_2Dimage(
                detectid_i,
                detects,
                fibers,
                width=args.width,
                height=args.height,
                path=args.path,
            )

    if args.ra and args.dec:
        # NOTE this has not been updated yet.. will build functionality soon
        obj_coords = SkyCoord(args.ra * u.deg, args.dec * u.deg, frame="icrs")
        idx = fibers.query_region_idx(obj_coords, radius=(args.rad / 3600.0))

        output = Table()
        output["ra"] = fibers.coords.ra[idx] * u.deg
        output["dec"] = fibers.coords.dec[idx] * u.deg
        filenames = []

        fileidx = 101
        for i in idx:
            filename = "tmp" + str(fileidx) + ".dat"
            filenames.append(filename)
            save_rsp_spectrum(
                fibers,
                i,
                file=filename,
            )
            fileidx += 1

        output["filename"] = np.array(filenames)
        ascii.write(output, "fib_coords.dat", overwrite=True)

    fibers.close()
    detects.close()
    tb.file._open_files.close_all()
Esempio n. 3
0
from regions import LineSkyRegion, PixCoord, LinePixelRegion

from hetdex_api.config import HDRconfig
from hetdex_api.survey import Survey
from hetdex_api.detections import Detections
import hetdex_tools.fof_kdtree as fof

from hetdex_api.elixer_widget_cls import ElixerWidget
from hetdex_api.flux_limits.hdf5_sensitivity_cubes import SensitivityCubeHDF5Container

from elixer import catalogs

from hetdex_api.extinction import *
import extinction

catlib = catalogs.CatalogLibrary()
config = HDRconfig()

agn_tab = None
cont_gals = None
cont_stars = None

wavelya = 1215.67
waveoii = 3727.8

deth5 = None
conth5 = None


def return_fiber_ratio(det, det_type):
Esempio n. 4
0
    def __init__(
        self,
        coords=None,
        detectid=None,
        survey="hdr2.1",
        aperture=3.0 * u.arcsec,
        cutout_size=5.0 * u.arcmin,
        zoom=3,
    ):

        self.survey = survey.lower()

        self.detectid = detectid
        self.aperture = aperture
        self.cutout_size = cutout_size
        self.zoom = zoom

        config = HDRconfig(survey=survey)

        self.fileh5dets = tb.open_file(config.detecth5, "r")
        self.catlib = catalogs.CatalogLibrary()

        if coords:
            self.coords = coords
            self.detectid = 1000000000
        elif detectid:
            self.detectid = detectid
            self.update_det_coords()
        else:
            self.coords = SkyCoord(191.663132 * u.deg,
                                   50.712696 * u.deg,
                                   frame="icrs")
            self.detectid = 2101848640

        # initialize the image widget from astrowidgets
        self.imw = ImageWidget(image_width=600, image_height=600)

        self.survey_widget = widgets.Dropdown(
            options=["HDR1", "HDR2", "HDR2.1"],
            value=self.survey.upper(),
            layout=Layout(width="10%"),
        )

        self.detectbox = widgets.BoundedIntText(
            value=self.detectid,
            min=1000000000,
            max=3000000000,
            step=1,
            description="DetectID:",
            disabled=False,
        )
        self.im_ra = widgets.FloatText(
            value=self.coords.ra.value,
            description="RA (deg):",
            layout=Layout(width="20%"),
        )
        self.im_dec = widgets.FloatText(
            value=self.coords.dec.value,
            description="DEC (deg):",
            layout=Layout(width="20%"),
        )

        self.pan_to_coords = widgets.Button(description="Pan to coords",
                                            disabled=False,
                                            button_style="success")
        self.marking_button = widgets.Button(description="Mark Sources",
                                             button_style="success")
        self.reset_marking_button = widgets.Button(description="Reset",
                                                   button_style="success")
        self.extract_button = widgets.Button(description="Extract Object",
                                             button_style="success")

        self.marker_table_output = widgets.Output(
            layout={"border": "1px solid black"})
        #        self.spec_output = widgets.Output(layout={'border': '1px solid black'})

        self.spec_output = widgets.Tab(description="Extracted Spectra:",
                                       layout={"border": "1px solid black"})
        self.textimpath = widgets.Text(description="Source: ",
                                       value="",
                                       layout=Layout(width="90%"))

        self.topbox = widgets.HBox([
            self.survey_widget,
            self.detectbox,
            self.im_ra,
            self.im_dec,
            self.pan_to_coords,
        ])
        self.leftbox = widgets.VBox([self.imw, self.textimpath],
                                    layout=Layout(width="800px"))
        self.rightbox = widgets.VBox(
            [
                widgets.HBox([
                    self.marking_button,
                    self.reset_marking_button,
                    self.extract_button,
                ]),
                self.marker_table_output,
                self.spec_output,
            ],
            layout=Layout(width="800px"),
        )

        self.bottombox = widgets.Output(layout={"border": "1px solid black"})

        self.load_image()

        self.all_box = widgets.VBox([
            self.topbox,
            widgets.HBox([self.leftbox, self.rightbox]),
            #self.spec_output,
            self.bottombox
        ])
        display(self.all_box)
        self.detectbox.observe(self.on_det_change)
        self.pan_to_coords.on_click(self.pan_to_coords_click)
        self.marking_button.on_click(self.marking_on_click)
        self.reset_marking_button.on_click(self.reset_marking_on_click)
        self.extract_button.on_click(self.extract_on_click)
        self.survey_widget.observe(self.on_survey_change)