Exemplo n.º 1
0
def make_data_cube(
    detectid=None,
    coords=None,
    shotid=None,
    pixscale=0.25 * u.arcsec,
    imsize=30.0 * u.arcsec,
    wave_range=[3470, 5540],
    dwave=2.0,
    dcont=50.0,
    convolve_image=True,
    ffsky=True,
    subcont=False,
):
    """
    Function to make a datacube from either a detectid or from a
    coordinate/shotid combination.
    
    Paramaters
    ----------
    detectid: int
        detectid from the continuum or lines catalog. Default is
        None. Provide a coords/shotid combo if this isn't given
    coords: SkyCoords object
        coordinates to define the centre of the data cube
    pixscale: astropy angle quantity
        plate scale
    imsize: astropy angle quantity
        spatial length of cube (equal dims is only option)
    wave_range: list
        start and stop value for the wavelength range in Angstrom
    dwave
        step in wavelength range in Angstrom
    convolve_image: bool
         option to convolve image with shotid seeing
    ffsky: bool
        option to use full frame calibrated fibers. Default is
        True.
    subcont: bool
        option to subtract continuum. Default is False. This
        will measure the continuum 50AA below and above the
        input wave_range
    dcont
        width in angstrom to measure the continuum. Default is to
        measure 50 AA wide regions on either side of the line  

    Returns
    -------
    hdu: PrimaryHDU object
        the data cube 3D array and associated 3d header
        Units are '10^-17 erg cm-2 s-1 per spaxel'

    Examples
    --------

    Can either pass in a detectid:

    >>> detectid_obj=2101602788
    >>> hdu = make_data_cube( detectid=detectid_obj)
    >>> hdu.writeto( str(detectid_obj) + '.fits', overwrite=True)

    or can put in an SkyCoord object:

    >>> star_coords = SkyCoord(9.625181, -0.043587, unit='deg')
    >>> hdu = make_data_cube( coords=star_coords[0], shotid=20171016108, dwave=2.0)
    >>> hdu.writeto( 'star.fits', overwrite=True)
    
    """
    global config, detecth5, surveyh5

    if detectid is not None:
        detectid_obj = detectid
        det_info = detecth5.root.Detections.read_where(
            'detectid == detectid_obj')[0]
        shotid = det_info["shotid"]
        coords = SkyCoord(det_info["ra"], det_info["dec"], unit="deg")

        if coords is None or shotid is None:
            print("Provide a detectid or both a coords and shotid")

    E = Extract()
    E.load_shot(shotid, fibers=False)

    # get spatial dims:
    ndim = int(imsize / pixscale)
    center = int(ndim / 2)

    # get wave dims:
    nwave = int((wave_range[1] - wave_range[0]) / dwave + 1)

    w = wcs.WCS(naxis=3)
    w.wcs.crval = [coords.ra.deg, coords.dec.deg, wave_range[0]]
    w.wcs.crpix = [center, center, 1]
    w.wcs.ctype = ["RA---TAN", "DEC--TAN", "WAVE"]
    w.wcs.cdelt = [-pixscale.to(u.deg).value, pixscale.to(u.deg).value, dwave]

    rad = imsize.to(u.arcsec).value

    info_result = E.get_fiberinfo_for_coord(coords, radius=rad, ffsky=False)
    ifux, ifuy, xc, yc, ra, dec, data, error, mask = info_result

    # get ifu center:
    ifux_cen, ifuy_cen = E.convert_radec_to_ifux_ifuy(ifux, ifuy, ra, dec,
                                                      coords.ra.deg,
                                                      coords.dec.deg)

    # get FWHM and PA

    surveyh5 = tb.open_file(config.surveyh5, "r")
    shotid_obj = shotid

    pa = surveyh5.root.Survey.read_where("shotid == shotid_obj")["pa"][0]

    if convolve_image:
        fwhm = surveyh5.root.Survey.read_where(
            "shotid == shotid_obj")["fwhm_virus"][0]
    else:
        fwhm = 1.8  # just a dummy variable as convolve_image=False

    surveyh5.close()

    # add in rotation
    sys_rot = 1.55
    rot = 360. - (90. + pa + sys_rot)
    w.wcs.crota = [0, rot, 0]
    #    rrot = np.deg2rad(rot)
    #    w.wcs.pc = [[np.cos(rrot),
    #                 np.sin(rrot),0],
    #                [-1.0*np.sin(rrot),
    #                 np.cos(rrot),0], [0,0,0]]

    im_cube = np.zeros((nwave, ndim, ndim))

    wave_i = wave_range[0]
    i = 0

    while wave_i <= wave_range[1]:
        try:
            im_src = E.make_narrowband_image(
                ifux_cen,
                ifuy_cen,
                ifux,
                ifuy,
                data,
                mask,
                scale=pixscale.to(u.arcsec).value,
                wrange=[wave_i, wave_i + dwave],
                nchunks=1,
                seeing_fac=fwhm,
                convolve_image=convolve_image,
                boxsize=imsize.to(u.arcsec).value,
            )

            im_slice = im_src[0]

            if subcont:
                zarray_blue = E.make_narrowband_image(
                    ifux_cen,
                    ifuy_cen,
                    ifux,
                    ifuy,
                    data,
                    mask,
                    seeing_fac=fwhm,
                    scale=pixscale.to(u.arcsec).value,
                    boxsize=imsize.to(u.arcsec).value,
                    nchunks=2,
                    wrange=[wave_i - dcont, wave_i],
                    convolve_image=convolve_image,
                )
                zarray_red = E.make_narrowband_image(
                    ifux_cen,
                    ifuy_cen,
                    ifux,
                    ifuy,
                    data,
                    mask,
                    seeing_fac=fwhm,
                    nchunks=2,
                    scale=pixscale.to(u.arcsec).value,
                    boxsize=imsize.to(u.arcsec).value,
                    wrange=[wave_i + dwave, wave_i + dwave + dcont],
                    convolve_image=convolve_image,
                )

                im_cont = (zarray_blue[0] + zarray_red[0]) / (2 * dcont)
                im_slice = im_src[0] - dwave * im_cont

            im_cube[i, :, :] = im_slice

        except Exception:
            im_cube[i, :, :] = np.zeros((ndim, ndim))
        wave_i += dwave
        i += 1

    hdu = fits.PrimaryHDU(im_cube, header=w.to_header())

    E.close()

    return hdu
Exemplo n.º 2
0
def make_narrowband_image(
    detectid=None,
    coords=None,
    shotid=None,
    pixscale=0.25 * u.arcsec,
    imsize=30.0 * u.arcsec,
    wave_range=None,
    convolve_image=True,
    ffsky=True,
    subcont=False,
    dcont=50.,
    include_error=False,
):
    """
    Function to make narrowband image from either a detectid or from a
    coordinate/shotid combination.
    
    Paramaters
    ----------
    detectid: int
        detectid from the continuum or lines catalog. Default is
        None. Provide a coords/shotid combo if this isn't given
    coords: SkyCoords object
        coordinates to define the centre of the data cube
    pixscale: astropy angle quantity
         plate scale
    imsize: astropy angle quantity
        image size
    wave_range: list or None
        start and stop value for the wavelength range in Angstrom.
        If not given, the detectid linewidth is used
    convolve_image: bool
        option to convolve image with shotid seeing
    ffsky: bool
        option to use full frame calibrated fibers. Default is
        True.
    subcont: bool
        option to subtract continuum. Default is False. This
        will measure the continuum 50AA below and above the
        input wave_range
    dcont
        width in angstrom to measure the continuum. Default is to
        measure 50 AA wide regions on either side of the line
    include_error bool
        option to include error array

    Returns
    -------
    hdu: PrimaryHDU object
        the 2D summed data array and associated 2d header
        Units are '10^-17 erg cm-2 s-1'
        If include_error=True will include addiional hdu
    Examples
    --------

    For a specific detectid:
    >>> hdu = make_narrowband_image(detectid=2101046271)
    
    For a SkyCoords object. You must provide shotid and
    wavelength range

    >>> coords = SkyCoord(188.79312, 50.855747, unit='deg')
    >>> wave_obj = 4235.84 #in Angstrom
    >>> hdu = make_narrowband_image(coords=coords,
                                    shotid=20190524021,
                                    wave_range=[wave_obj-10, wave_obj+10])
    """
    global config, detecth5, surveyh5

    if detectid is not None:

        detectid_obj = detectid
        det_info = detecth5.root.Detections.read_where(
            'detectid == detectid_obj')[0]

        shotid_obj = det_info["shotid"]
        wave_obj = det_info["wave"]
        linewidth = det_info["linewidth"]
        wave_range = [wave_obj - 2.0 * linewidth, wave_obj + 2.0 * linewidth]
        coords = SkyCoord(det_info["ra"], det_info["dec"], unit="deg")
    elif coords is not None:
        if shotid is not None:
            shotid_obj = shotid
        else:
            print("Provide a shotid")
        if wave_range is None:
            print("Provide a wavelength range to collapse. \
            Example wave_range=[4500,4540]")
    else:
        print("Provide a detectid or both a coords and shotid")

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

    E = Extract()
    E.load_shot(shotid_obj, fibers=False)

    # get spatial dims:
    ndim = int(imsize / pixscale)
    center = int(ndim / 2)

    rad = imsize.to(u.arcsec).value  # convert to arcsec value, not quantity

    info_result = E.get_fiberinfo_for_coord(coords, radius=rad, ffsky=ffsky)
    ifux, ifuy, xc, yc, ra, dec, data, error, mask = info_result

    # get ifu center:
    ifux_cen, ifuy_cen = E.convert_radec_to_ifux_ifuy(ifux, ifuy, ra, dec,
                                                      coords.ra.deg,
                                                      coords.dec.deg)

    if include_error:
        zarray = E.make_narrowband_image(
            ifux_cen,
            ifuy_cen,
            ifux,
            ifuy,
            data,
            mask,
            error=error,
            seeing_fac=fwhm,
            scale=pixscale.to(u.arcsec).value,
            boxsize=imsize.to(u.arcsec).value,
            wrange=wave_range,
            convolve_image=convolve_image,
        )
        imslice = zarray[0]
        imerror = zarray[1]
    else:
        zarray = E.make_narrowband_image(
            ifux_cen,
            ifuy_cen,
            ifux,
            ifuy,
            data,
            mask,
            seeing_fac=fwhm,
            scale=pixscale.to(u.arcsec).value,
            boxsize=imsize.to(u.arcsec).value,
            wrange=wave_range,
            convolve_image=convolve_image,
        )

        imslice = zarray[0]

    if subcont:
        zarray_blue = E.make_narrowband_image(
            ifux_cen,
            ifuy_cen,
            ifux,
            ifuy,
            data,
            mask,
            seeing_fac=fwhm,
            scale=pixscale.to(u.arcsec).value,
            boxsize=imsize.to(u.arcsec).value,
            wrange=[wave_range[0] - dcont - 10, wave_range[0] - 10],
            convolve_image=convolve_image,
        )

        zarray_red = E.make_narrowband_image(
            ifux_cen,
            ifuy_cen,
            ifux,
            ifuy,
            data,
            mask,
            seeing_fac=fwhm,
            scale=pixscale.to(u.arcsec).value,
            boxsize=imsize.to(u.arcsec).value,
            wrange=[wave_range[1] + 10, wave_range[1] + dcont + 10],
            convolve_image=convolve_image,
        )

        dwave = wave_range[1] - wave_range[0]
        im_cont = (zarray_blue[0] + zarray_red[0]) / (2 * dcont)

        imslice = zarray[0] - dwave * im_cont

    w = wcs.WCS(naxis=2)
    imsize = imsize.to(u.arcsec).value
    w.wcs.crval = [coords.ra.deg, coords.dec.deg]
    w.wcs.crpix = [center, center]
    w.wcs.ctype = ["RA---TAN", "DEC--TAN"]
    w.wcs.cdelt = [-pixscale.to(u.deg).value, pixscale.to(u.deg).value]

    # get rotation:
    sys_rot = 1.55
    rot = 360. - (90. + pa + sys_rot)
    rrot = np.deg2rad(rot)

    #    w.wcs.crota = [ 0, rot]

    w.wcs.pc = [[np.cos(rrot), np.sin(rrot)],
                [-1.0 * np.sin(rrot), np.cos(rrot)]]

    hdu = fits.PrimaryHDU(imslice, header=w.to_header())
    E.close()
    if include_error:
        hdu_error = fits.ImageHDU(imerror, header=w.to_header())
        hdu_x = fits.ImageHDU(zarray[2], header=w.to_header())
        hdu_y = fits.ImageHDU(zarray[3], header=w.to_header())
        return fits.HDUList([hdu, hdu_error, hdu_x, hdu_y])
    else:
        return hdu
Exemplo n.º 3
0
def get_source_spectra_mp(source_dict, shotid, manager, args):

    E = Extract()
    FibIndex = FiberIndex(args.survey)

    if args.survey == "hdr1":
        source_num_switch = 20
    else:
        source_num_switch = 0

    if len(args.matched_sources[shotid]) > 0:
        args.log.info("Working on shot: %s" % shotid)
        if args.survey == "hdr1":
            fwhm = args.survey_class.fwhm_moffat[args.survey_class.shotid ==
                                                 shotid][0]
        else:
            fwhm = args.survey_class.fwhm_virus[args.survey_class.shotid ==
                                                shotid][0]

        moffat = E.moffat_psf(fwhm, 10.5, 0.25)

        if len(args.matched_sources[shotid]) > source_num_switch:
            E.load_shot(shotid, fibers=True, survey=args.survey)
        else:
            E.load_shot(shotid, fibers=False, survey=args.survey)

        for ind in args.matched_sources[shotid]:
            try:
                info_result = E.get_fiberinfo_for_coord(
                    args.coords[ind],
                    radius=args.rad,
                    ffsky=args.ffsky,
                    return_fiber_info=True,
                )
            except TypeError:
                info_result = E.get_fiberinfo_for_coord(
                    args.coords,
                    radius=args.rad,
                    ffsky=args.ffsky,
                    return_fiber_info=True,
                )
            if info_result is not None:
                if np.size(args.ID) > 1:
                    args.log.info("Extracting %s" % args.ID[ind])
                else:
                    args.log.info("Extracting %s" % args.ID)
                ifux, ifuy, xc, yc, ra, dec, data, error, mask, fiberid, \
                    multiframe = info_result

                weights = E.build_weights(xc, yc, ifux, ifuy, moffat)
                # added by EMC 20210609
                norm = np.sum(weights, axis=0)
                weights = weights / norm[np.newaxis, :]

                result = E.get_spectrum(data,
                                        error,
                                        mask,
                                        weights,
                                        remove_low_weights=False)

                spectrum_aper, spectrum_aper_error = [res for res in result]

                # apply aperture correction
                spectrum_aper /= norm
                spectrum_aper_error /= norm

                weights *= norm[np.newaxis, :]

                #add in the total weight of each fiber (as the sum of its weight per wavebin)
                if args.fiberweights:

                    try:
                        fiber_weights = np.array([
                            x for x in zip(ra, dec,
                                           np.sum(weights * mask, axis=1))
                        ])
                    except:
                        fiber_weights = []
                else:
                    fiber_weights = []

                # get fiber info no matter what so we can flag
                try:
                    fiber_info = np.array([
                        x for x in zip(fiberid, multiframe, ra, dec,
                                       np.sum(weights * mask, axis=1))
                    ])
                except:
                    args.log.warning(
                        'Could not get fiber info, no flagging created')
                    fiber_info = []

                if len(fiber_info) > 0:
                    try:
                        flags = FibIndex.get_fiber_flags(
                            coord=args.coords[ind], shotid=shotid)
                    except:
                        flags = FibIndex.get_fiber_flags(coord=args.coords,
                                                         shotid=shotid)
                else:
                    flags = None

                if np.size(args.ID) > 1:
                    if args.ID[ind] in source_dict:
                        source_dict[args.ID[ind]][shotid] = [
                            spectrum_aper,
                            spectrum_aper_error,
                            weights.sum(axis=0),
                            fiber_weights,
                            fiber_info,
                            flags,
                        ]
                    else:
                        source_dict[args.ID[ind]] = manager.dict()
                        source_dict[args.ID[ind]][shotid] = [
                            spectrum_aper,
                            spectrum_aper_error,
                            weights.sum(axis=0),
                            fiber_weights,
                            fiber_info,
                            flags,
                        ]
                else:
                    if args.ID in source_dict:
                        source_dict[args.ID][shotid] = [
                            spectrum_aper,
                            spectrum_aper_error,
                            weights.sum(axis=0),
                            fiber_weights,
                            fiber_info,
                            flags,
                        ]
                    else:
                        source_dict[args.ID] = manager.dict()
                        source_dict[args.ID][shotid] = [
                            spectrum_aper,
                            spectrum_aper_error,
                            weights.sum(axis=0),
                            fiber_weights,
                            fiber_info,
                            flags,
                        ]

        E.shoth5.close()
        FibIndex.close()

    return source_dict
Exemplo n.º 4
0
def get_flim_sig_erin(detectid=None, coord=None, wave=None, datevobs=None, shotid=None):
    """
    Script to grab flim_1sigma and sn_sig on demand from calibrated fiber extractions
    
    Parameters
    ----------
    detectid int
       detectid for source 
    coord
        astropy SkyCoord object
    wave
        central wavelength
    shotid 
        observation ID
    
    Returns
    -------
    flim_1sigma
        the 1 sigma sensitivity calculated over 7 pixels of the PSF-weighted extracted spectra
    """
    
    detectid_obj = detectid
    det_info = source_table[source_table['detectid'] == detectid][0]
    shotid = det_info['shotid']
    wave = det_info['wave']
    coord = SkyCoord(ra=det_info['ra'], dec=det_info['dec'], unit='deg')        
    fwhm = det_info['fwhm']
    
    if datevobs is None:
        datevobs = '{}v{}'.format( str(shotid)[0:8], str(shotid)[8:])
        
    if shotid is None:
        shotid_obj = int(datevobs[0:8] + datevobs[9:])
    else:
        shotid_obj = shotid
    
    try:
        E = Extract()
        E.load_shot(datevobs, fibers=False)
    
        info_result = E.get_fiberinfo_for_coord(coord, radius=3.5, fiber_lower_limit=2 )

        ifux, ifuy, xc, yc, ra, dec, data, error, mask = info_result

        #print(len(ifux))

        moffat = E.moffat_psf(fwhm, 10.5, 0.25)
   
        I = None
        fac = None

        weights, I, fac = E.build_weights(xc, yc, ifux, ifuy, moffat, 
                                            I=I, fac=fac, return_I_fac = True)

        norm = np.sum(weights, axis=0)

        weights = weights/norm   

        result = E.get_spectrum(data, error, mask, weights, 
                                remove_low_weights=False)


        spec, spec_err = [res for res in result]

        w_index = np.where(E.wave >= wave)[0][0]

        nfib = np.shape(weights)[0]

        flim_1sigma = 2 * np.sqrt( np.nansum( (spec_err[w_index-3:w_index+4])**2))

        sn_sig = 2 * np.sum( spec[w_index-3:w_index+4]) / flim_1sigma

        npix = np.sum(np.isfinite(spec[w_index-3:w_index+4]))

        apcor = np.sum( norm[w_index-3:w_index+4])/len( norm[w_index-3:w_index+4])  

        E.close()

        # XXX divide by apcor .... 
        return flim_1sigma/apcor, apcor
    except:
        return 999
Exemplo n.º 5
0
coords = SkyCoord(ra * u.deg, dec * u.deg)
L = []
kk = 0
for coord, S, xi in zip(coords, sp, xid):
    if coord.dec.deg > 0.:
        pn = '+'
    else:
        pn = '-'
    coord_tup = (coord.ra.hms.h, coord.ra.hms.m, coord.ra.hms.s, pn,
                 np.abs(coord.dec.dms.d), np.abs(coord.dec.dms.m),
                 np.abs(coord.dec.dms.s))
    coord_str = '%02dh%02dm%02ds%s%02dd%02dm%02ds' % coord_tup
    E.log.info('Working on coordinate: %s' % coord_str)
    E.log.info('Index: %i' % kk)
    kk +=1
    info_result = E.get_fiberinfo_for_coord(coord, radius=7.)
    if info_result is None:
        continue
    E.log.info('Found fibers for coordinate: %s' %
               coord.to_string(style='hmsdms'))
    ifux, ifuy, xc, yc, ra, dec, data, error, mask = info_result
    # Re-centroid? If so, do it here before building aperture (i.e., change xc, yc)
    image = E.make_collapsed_image(xc, yc, ifux, ifuy, data, mask,
                                   scale=0.25, seeing_fac=1.5, boxsize=10.75,
                                   wrange=[4900, 5300], nchunks=3,
                                   convolve_image=False)
    flam = 10**(-0.4 * (xi['g']-23.9)) * 1e-29 * 3e18 / 5000.**2
    weights = E.build_weights(xc, yc, ifux, ifuy, psf)
    result = E.get_spectrum(data, error, mask, weights)
    spectrum, spectrum_error = [res*1. for res in result]
Exemplo n.º 6
0
def get_source_spectra(shotid, args):
    E = Extract()
    source_dict = {}

    if args.survey == "hdr1":
        source_num_switch = 20
    else:
        source_num_switch = 0

    if len(args.matched_sources[shotid]) > 0:
        args.log.info("Working on shot: %s" % shotid)
        if args.survey == "hdr1":
            fwhm = args.survey_class.fwhm_moffat[args.survey_class.shotid == shotid][0]
        else:
            fwhm = args.survey_class.fwhm_virus[args.survey_class.shotid == shotid][0]

        moffat = E.moffat_psf(fwhm, 10.5, 0.25)

        if len(args.matched_sources[shotid]) > source_num_switch:
            E.load_shot(shotid, fibers=True, survey=args.survey)
        else:
            E.load_shot(shotid, fibers=False, survey=args.survey)

        for ind in args.matched_sources[shotid]:
            try:
                info_result = E.get_fiberinfo_for_coord(
                    args.coords[ind],
                    radius=args.rad,
                    ffsky=args.ffsky,
                    return_fiber_info=True,
                )
            except TypeError:
                info_result = E.get_fiberinfo_for_coord(
                    args.coords,
                    radius=args.rad,
                    ffsky=args.ffsky,
                    return_fiber_info=True,
                )
            if info_result is not None:
                try:
                    args.log.info("Extracting %s" % args.ID[ind])
                except:
                    args.log.info("Extracting %s" % args.ID)

                ifux, ifuy, xc, yc, ra, dec, data, error, mask, fiberid, \
                    multiframe = info_result

                weights = E.build_weights(xc, yc, ifux, ifuy, moffat)
                result = E.get_spectrum(data, error, mask, weights)
                spectrum_aper, spectrum_aper_error = [res for res in result]

                #add in the total weight of each fiber (as the sum of its weight per wavebin)
                if args.fiberweights:
                    try:
                        fiber_weights = np.array( [x for x in zip(ra, dec, np.sum(weights*mask, axis=1))])
                    except:
                        fiber_weights = []
                else:
                    fiber_weights = []

                # get fiber info no matter what so we can flag
                try:
                    fiber_info = np.array( [
                        x for x in zip(fiberid,
                                       multiframe,
                                       ra,
                                       dec,
                                       np.sum(weights*mask, axis=1))])
                except:
                    fiber_info = []

                if len(fiber_info) > 0:
                    flags = get_flags(fiber_info)
                else:
                    flags = None
                    
                if np.size(args.ID) > 1:
                    if args.ID[ind] in source_dict:
                        source_dict[args.ID[ind]][shotid] = [
                            spectrum_aper,
                            spectrum_aper_error,
                            weights.sum(axis=0),
                            fiber_weights,
                            fiber_info,
                            flags,
                        ]
                    else:
                        source_dict[args.ID[ind]] = dict()
                        source_dict[args.ID[ind]][shotid] = [
                            spectrum_aper,
                            spectrum_aper_error,
                            weights.sum(axis=0),
                            fiber_weights,
                            fiber_info,
                            flags,
                        ]
                else:
                    if args.ID in source_dict:
                        source_dict[args.ID][shotid] = [
                            spectrum_aper,
                            spectrum_aper_error,
                            weights.sum(axis=0),
                            fiber_weights,
                            fiber_info,
                            flags,
                        ]
                    else:
                        source_dict[args.ID] = dict()
                        source_dict[args.ID][shotid] = [
                            spectrum_aper,
                            spectrum_aper_error,
                            weights.sum(axis=0),
                            fiber_weights,
                            fiber_info,
                            flags,
                        ]

        E.shoth5.close()
        
    return source_dict