Ejemplo n.º 1
0
    def phot(self, image_path, x_coor, y_coor, aper_radius=3.0, gain=0.57):
        """
        Photometry of given coordinates.
        @param image_path: Path of FITS file.
        @type image_path: path
        @param x_coor: X coordinate of object
        @type x_coor: float
        @param y_coor: Y coordinate of object
        @type y_coor: float
        @param aper_radius: Aperture radius
        @type aper_radius: float
        @return: tuple
        """

        if image_path:
            hdu = fits.open(image_path)[0]
        else:
            print("FITS image has not been provided by the user!")
            raise SystemExit

        data = hdu.data.astype(float)

        bkg = sep.Background(data)
        # bkg_image = bkg.back()
        # bkg_rms = bkg.rms()
        data_sub = data - bkg

        flux, fluxerr, flag = sep.sum_circle(data_sub,
                                             x_coor,
                                             y_coor,
                                             aper_radius=aper_radius,
                                             err=bkg.globalrms,
                                             gain=gain)

        return ({"flag": flag, "flux": flux, "fluxerr": fluxerr})
Ejemplo n.º 2
0
def sep_phot(data, ap, th):
    """
    Preforms photometry by SEP, similar to source extractor
    """

    # Measure a spatially variable background of some image data (np array)
    try:
        bkg = sep.Background(data)  # , mask=mask, bw=64, bh=64, fw=3, fh=3) # optional parameters
    except ValueError:
        data = data.byteswap(True).newbyteorder()
        bkg = sep.Background(data)  # , mask=mask, bw=64, bh=64, fw=3, fh=3) # optional parameters

    # Directly subtract the background from the data in place
    bkg.subfrom(data)

    # for the background subtracted data, detect objects in data given some threshold
    thresh = th * bkg.globalrms  # ensure the threshold is high enough wrt background
    objs = sep.extract(data, thresh)
    # calculate the Kron radius for each object, then we perform elliptical aperture photometry within that radius
    kronrad, krflag = sep.kron_radius(data, objs['x'], objs['y'], objs['a'], objs['b'], objs['theta'], ap)
    flux, fluxerr, flag = sep.sum_ellipse(data, objs['x'], objs['y'], objs['a'], objs['b'], objs['theta'],
                                          2.5 * kronrad, subpix=1)
    flag |= krflag  # combine flags into 'flag'

    r_min = 1.75  # minimum diameter = 3.5
    use_circle = kronrad * np.sqrt(objs['a'] * objs['b']) < r_min
    x = objs['x']
    y = objs['y']
    cflux, cfluxerr, cflag = sep.sum_circle(data, x[use_circle], y[use_circle],
                                            r_min, subpix=1)
    flux[use_circle] = cflux
    fluxerr[use_circle] = cfluxerr
    flag[use_circle] = cflag

    return objs
Ejemplo n.º 3
0
 def photometry(self,
                file,
                x_coor,
                y_coor,
                zmag=25.0,
                aper_radius=15.0,
                gain=1.21):
     """Python photometry"""
     try:
         data = self.data(file)
         bkg = Background(data)
         data_sub = data - bkg
         flx, ferr, flag = sum_circle(data_sub,
                                      x_coor,
                                      y_coor,
                                      aper_radius,
                                      err=bkg.globalrms,
                                      gain=gain)
         mag, merr = self.sma.flux_to_mag(flx, ferr)
         return [
             str(x_coor),
             str(y_coor),
             str(float(flx)),
             str(float(ferr)),
             str(float(flag)),
             str(mag + zmag),
             str(merr)
         ]
     except Exception as e:
         self.logger.error(e)
Ejemplo n.º 4
0
    def AperaturePhoto(self,filter,objs):
        print 'Running Aperature Photometry on %s......'%filter
        kronrad, krflag = sep.kron_radius(self.dataList[filter],
                                          objs['x'], objs['y'],
                                          objs['a'], objs['b'],
                                          objs['theta'],
                                          6.0)

        flux, fluxerr, flag = sep.sum_ellipse(self.dataList[filter],
                                              objs['x'], objs['y'],
                                              objs['a'], objs['b'],
                                              objs['theta'],
                                              2.5*kronrad, subpix=1,
                                              err=self.bkgRMS[filter])
        #use circular aperature photometry if the kronradius is too small. see http://sep.readthedocs.org/en/v0.2.x/apertures.html
        r_min = 1.75 # minimum diameter = 3.5
        use_circle = kronrad * np.sqrt(objs['a']*objs['b']) < r_min
        cflux, cfluxerr, cflag = sep.sum_circle(self.dataList[filter],
                                                objs['x'][use_circle],
                                                objs['y'][use_circle],
                                                r_min, subpix=1,err=self.bkgRMS[filter])
        flux[use_circle] = cflux
        fluxerr[use_circle] = cfluxerr
        flag[use_circle] = cflag
        #convert flux to magnitudes using the appropriate zeropoint
        #absolute flux measurement (AB for Z-PEG)
        mag = -2.5*np.log10(flux)+self.zeroPoints[filter]
        #calculate magerr
        fluxdown = flux - fluxerr
        fluxup = flux + fluxerr
        magup = -2.5*np.log10(fluxdown) + self.zeroPoints[filter]
        magdown = -2.5*np.log10(fluxup) + self.zeroPoints[filter]
        magerr = ((magup - mag) + (mag-magdown))/2.

        return mag, magerr
Ejemplo n.º 5
0
Archivo: test.py Proyecto: cmccully/sep
def test_apertures_exact():
    """Test area as measured by exact aperture modes on array of ones"""

    theta = np.random.uniform(-np.pi/2., np.pi/2., naper)
    ratio = np.random.uniform(0.2, 1.0, naper)
    r = 3.

    for dt in SUPPORTED_IMAGE_DTYPES:
        data = np.ones(data_shape, dtype=dt)
        for r in [0.5, 1., 3.]:
            flux, fluxerr, flag = sep.sum_circle(data, x, y, r, subpix=0)
            assert_allclose(flux, np.pi*r**2)

            rout = r*1.1
            flux, fluxerr, flag = sep.sum_circann(data, x, y, r, rout,
                                                  subpix=0)
            assert_allclose(flux, np.pi*(rout**2 - r**2))

            flux, fluxerr, flag = sep.sum_ellipse(data, x, y, 1., ratio,
                                                  theta, r=r, subpix=0)
            assert_allclose(flux, np.pi*ratio*r**2)

            rout = r*1.1
            flux, fluxerr, flag = sep.sum_ellipann(data, x, y, 1., ratio,
                                                   theta, r, rout, subpix=0)
            assert_allclose(flux, np.pi*ratio*(rout**2 - r**2))
Ejemplo n.º 6
0
def aperture_photometry(image_data: np.ndarray,
                        background: sep.Background) -> List[Star]:
    """
    performs aperture photometry on an image

    :param image_data: data of the image
    :param background: background of the image
    :return: a list of extracted stars
    """

    # extract objects using source extractor
    objects = sep.extract(image_data,
                          AperturePhotometry.threshold,
                          err=background.globalrms)

    # perform aperture photometry
    aperture = sep.sum_circle(
        image_data,
        objects["x"],
        objects["y"],
        AperturePhotometry.radius,
        err=background.globalrms,
        gain=AperturePhotometry.gain,
    )

    # create and return a list of star objects
    return [
        Star(x, y, flux, fluxerr) for x, y, flux, fluxerr, _ in zip(
            objects["x"], objects["y"], *aperture)
    ]
Ejemplo n.º 7
0
def test_apertures_all():
    """Test that aperture subpixel sampling works"""

    data = np.random.rand(*data_shape)
    r = 3.
    rtol = 1.e-8

    for subpix in [0, 1, 5]:
        flux_ref, fluxerr_ref, flag_ref = sep.sum_circle(data,
                                                         x,
                                                         y,
                                                         r,
                                                         subpix=subpix)

        flux, fluxerr, flag = sep.sum_circann(data, x, y, 0., r, subpix=subpix)
        assert_allclose(flux, flux_ref, rtol=rtol)

        flux, fluxerr, flag = sep.sum_ellipse(data,
                                              x,
                                              y,
                                              r,
                                              r,
                                              0.,
                                              subpix=subpix)
        assert_allclose(flux, flux_ref, rtol=rtol)

        flux, fluxerr, flag = sep.sum_ellipse(data,
                                              x,
                                              y,
                                              1.,
                                              1.,
                                              0.,
                                              r=r,
                                              subpix=subpix)
        assert_allclose(flux, flux_ref, rtol=rtol)
Ejemplo n.º 8
0
def timeEvolveFITSNoDrift(data, coords, x_drift, y_drift, r, stars, x_length,
                          y_length, t):
    x = [coords[ind, 0] for ind in range(0, stars)]
    y = [coords[ind, 1] for ind in range(0, stars)]
    bkg = np.median(data) * np.pi * r * r
    fluxes = (sep.sum_circle(data, x, y, r)[0] - bkg).tolist()
    coords = zip(x, y, fluxes, [t] * len(x))
    return coords
Ejemplo n.º 9
0
def catalog(ccd, bgf, catf, db, config, logger):
    bg = fits.open(bgf)
    im = ccd.data - bg['background'].data
    ps = ccd.meta['SCALE'] * ccd.meta.get('REBIN', 1)

    bgrms = bg['background'].header['bgrms']
    objects = sep.extract(im, 2, err=bgrms, mask=ccd.mask)
    logger.info('Found {} sources.'.format(len(objects)))

    rap = max(ccd.meta['SEEING'] * 2, 5 / ps)
    flux, fluxerr, flag = sep.sum_circle(im,
                                         objects['x'],
                                         objects['y'],
                                         rap,
                                         err=bgrms)

    # avoid theta rounding error
    theta = np.maximum(np.minimum(objects['theta'], np.pi / 2.00001),
                       -np.pi / 2.00001)
    kronrad, krflag = sep.kron_radius(im, objects['x'], objects['y'],
                                      objects['a'], objects['b'], theta, 6.0)
    krflux, krfluxerr, _flag = sep.sum_ellipse(im,
                                               objects['x'],
                                               objects['y'],
                                               objects['a'],
                                               objects['b'],
                                               theta,
                                               2.5 * kronrad,
                                               subpix=1,
                                               err=bgrms)
    krflag |= _flag

    # an additional background estimate, which should help when there are
    # large extended sources in scene: IN TESTS, THIS DID NOT AFFECT RESULTS
    # for i in range(len(objects)):
    #    krflux[i], krfluxerr[i] = bg_subtract2(im, objects[i], krflux[i],
    #                                           krfluxerr[i])
    #    flux[i], fluxerr[i] = bg_subtract2(im, objects[i], flux[i],
    #                                       fluxerr[i], r=rap)

    if ccd.wcs.wcs.crval[0] == ccd.wcs.wcs.crval[1]:
        ra, dec = np.zeros((2, len(objects)))
    else:
        ra, dec = ccd.wcs.all_pix2world(objects['x'], objects['y'], 0)

    tab = Table(
        (objects['x'], objects['y'], ra, dec, flux, fluxerr, flag,
         objects['a'], objects['b'], theta, kronrad, krflux, krfluxerr,
         krflag),
        names=('x', 'y', 'ra', 'dec', 'flux', 'fluxerr', 'flag', 'a', 'b',
               'theta', 'kronrad', 'krflux', 'krfluxerr', 'krflag'))

    hdu = fits.HDUList()
    hdu.append(fits.BinTableHDU(tab, name='cat'))
    hdu['cat'].header['RADIUS'] = (rap * ps,
                                   'aperture photometry radius, arcsec')
    hdu.writeto(catf, overwrite=True)
Ejemplo n.º 10
0
    def photskycoord(self, image_path,
                     ra, dec,
                     aper_radius=3.0,
                     gain=0.57):

        """
        Photometry of given coordinates.
        @param image_path: Path of FITS file.
        @type image_path: path
        @param ra: RA coordinate of object
        @type ra: string
        @param dec: DEC coordinate of object
        @type dec: string
        @param aper_radius: Aperture radius
        @type aper_radius: float
        @param gain: gain value for the image expressed in electrons per adu.
        @type gain: float
        @return: tuple
        """
        
        if image_path:
            hdu = fits.open(image_path)[0]
        else:
            print("FITS image has not been provided by the user!")
            raise SystemExit

        data = hdu.data.astype(float)

        fo = FitsOps(image_path)
        header = hdu.header
        w = WCS(header)

        naxis1 = fo.get_header('naxis1')
        naxis2 = fo.get_header('naxis2')

        c = coordinates.SkyCoord('{0} {1}'.format(
                        ra, dec), unit=(u.hourangle, u.deg),
                                 frame='icrs')

        # object's X and Y coor
        a_x, a_y = w.wcs_world2pix(c.ra.degree, c.dec.degree, 1)

        if naxis1 < a_x or naxis2 < a_y or a_x < 0 or a_y < 0:
            print("Provided coordinates are out of frame!")
            return(False)
        else:
            bkg = sep.Background(data)
            data_sub = data - bkg
            flux, fluxerr, flag = sep.sum_circle(data_sub,
                                                 a_x,
                                                 a_y,
                                                 aper_radius=aper_radius,
                                                 err=bkg.globalrms,
                                                 gain=gain)
            return({"flag": flag,
                    "flux": flux,
                    "fluxerr": fluxerr})
Ejemplo n.º 11
0
    def do_stage(self, image):
        # identify emission feature (pixel, order) positions.
        # we use daofind (which is inside of identify_features) to get every feature with S/N > min_S/N - 1
        # Then later on in this do_stage, we will rigorously cut every feature with S/N < min_S/N (using
        # sep.sum_circle to rigorously estimate the Signal contained in the 2d feature.
        features = identify_features(image.data,
                                     image.uncertainty,
                                     image.mask,
                                     nsigma=self.nsigma - 1,
                                     fwhm=self.fwhm,
                                     sigma_radius=4)
        features = group_features_by_trace(features, image.traces)
        features = features[
            features['id'] !=
            0]  # throw out features that are outside of any trace.
        # get total flux in each emission feature. For now just sum_circle, although we should use sum_ellipse.
        features['flux'], features['fluxerr'], _ = sep.sum_circle(
            image.data,
            features['xcentroid'],
            features['ycentroid'],
            self.fwhm,
            gain=1.0,
            err=image.uncertainty,
            mask=image.mask)
        if image.blaze is not None:
            logger.info('Blaze correcting emission feature fluxes',
                        image=image)
            # blaze correct the emission features fluxes. This speeds up and improves overlap fitting in xwavecal.
            features['corrected_flux'] = features['flux']
            features['corrected_flux'] /= image.blaze['blaze'][
                np.array(features['id'], dtype=int) - 1,
                np.array(features['xcentroid'], dtype=int)]

        # cutting which lines to keep:
        # calculate the error in the centroids provided by identify_features()
        features['centroid_err'] = self.fwhm / np.sqrt(features['flux'])
        # Filter features that pass the signal to noise check.
        # only keep features with S/N > min S/N.
        valid_features = features['flux'] / features['fluxerr'] > self.nsigma
        features = features[valid_features]
        logger.info('{0} valid emission features found on this image'.format(
            len(features)),
                    image=image)
        features = self.limit_features_per_fiber(features,
                                                 self.num_features_max)
        # report statistics
        logger.info('{0} emission features on this image will be used'.format(
            len(features)),
                    image=image)
        if len(features) == 0:
            logger.error('No emission features found on this image!',
                         image=image)
        # save the features to the image.
        image.add_or_update(DataTable(features, name='FEATURES'))
        return image
def get_fluxes(object1, data1, iR, oR, G, rN):
    """
    Preconditions: Expects a sep extracted list of objects and the image data
    the objectlist is from. Can also take the inner radius, outer radius,
    gain, and read noise.
    Postcontions: Returns the flux and flux error for each object in the list.
    """

    flux, fluxerr, flag = sep.sum_circle(data1, object1["x"], object1["y"], 16.0, bkgann=(iR, oR), gain=G, err=rN)

    return flux, np.sqrt(fluxerr)
Ejemplo n.º 13
0
    def _measure(self, img, sources, mask=None):

        logger.info('measuring source parameters')

        # HACK: issues with numerical precision
        # must have pi/2 <= theta <= npi/2
        sources[np.abs(np.abs(sources['theta']) - np.pi/2) < 1e-6] = np.pi/2

        for p in ['x', 'y', 'a', 'b', 'theta']:
            sources = sources[~np.isnan(sources[p])]

        # calculate "AUTO" parameters
        kronrad, krflag = sep.kron_radius(
            img, sources['x'], sources['y'], sources['a'], sources['b'],
            sources['theta'], 6.0, mask=mask)
    
        flux, fluxerr, flag = sep.sum_ellipse(
            img, sources['x'], sources['y'], sources['a'], sources['b'],
            sources['theta'], 2.5*kronrad, subpix=5, mask=mask)
        flag |= krflag  # combine flags into 'flag'

        sources = sources[~np.isnan(flux)]
        flux = flux[~np.isnan(flux)]
        sources = sources[flux > 0]
        flux = flux[flux > 0]

        mag_auto = utils.zpt - 2.5*np.log10(flux)
        r, flag = sep.flux_radius(
            img, sources['x'], sources['y'], 6.*sources['a'], 0.5,
            normflux=flux, subpix=5, mask=mask)

        sources['mag_auto'] = mag_auto
        sources['flux_auto'] = flux
        sources['flux_radius'] = r * utils.pixscale

        # approximate fwhm 
        r_squared = sources['a']**2 + sources['b']**2
        sources['fwhm'] = 2 * np.sqrt(np.log(2) * r_squared) *  utils.pixscale
        
        q = sources['b'] / sources['a']
        area = np.pi * q * sources['flux_radius']**2
        sources['mu_ave_auto'] = sources['mag_auto']  + 2.5 * np.log10(2*area)
        
        area_arcsec = np.pi * (self.psf_fwhm/2)**2 * utils.pixscale**2
        flux, fluxerr, flag = sep.sum_circle(
            img, sources['x'], sources['y'], self.psf_fwhm/2, 
            subpix=5, mask=mask)
        flux[flux<=0] = np.nan
        mu_0 = utils.zpt - 2.5*np.log10(flux / area_arcsec)

        sources['mu_0_aper'] = mu_0

        return sources
Ejemplo n.º 14
0
Archivo: test.py Proyecto: cmccully/sep
def test_aperture_bkgann_overlapping():
    """Test bkgann functionality in circular & elliptical apertures."""

    # If bkgann overlaps aperture exactly, result should be zero
    # (with subpix=1)
    data = np.random.rand(*data_shape)
    r = 5.
    f, _, _ = sep.sum_circle(data, x, y, r, bkgann=(0., r), subpix=1)
    assert_allclose(f, 0., rtol=0., atol=1.e-13)

    f, _, _ = sep.sum_ellipse(data, x, y, 2., 1., np.pi/4., r=r,
                              bkgann=(0., r), subpix=1)
    assert_allclose(f, 0., rtol=0., atol=1.e-13)
Ejemplo n.º 15
0
def find_flux(tbdat_sub, objects, kronrad, kronflag):
	flux, fluxerr, flag = sep.sum_ellipse(tbdat_sub, objects['x'], objects['y'], objects['a'], objects['b'], objects['theta'], pho_auto_A = (2.5*kronrad), err = bkg.globalrms, subpix=1)
	flag |=kronflag #combines all flags
	r_min = 1.75 #minimum diameter = 3.5
	use_circle = kronrad * np.sqrt(a * b) < r_min
	cflux, cfluxerr, cflag = sep.sum_circle(tbdat_sub, objects['x'][use_circle], objects['y'][use_circle], r_min, subpix=1)
	flux[use_circle] = cflux
	fluxerr[use_circle] = cfluxerr
	flag[use_circle] = cflag
	r, rflag = sep.flux_radius(data, x, y, 6.0*objects['a'], rmax = 0.5, normflux = flux, subpix =5)
	sig = 2.0 / (2.35*r) # r from sep.flux_radius() above, with fluxfrac = 0.5
	xwin, ywin, wflag = sep.winpos(tbdat_sub, objects['x'], objects['y'], sig)
	return flux, fluxerr, flag, r, xwin, ywin
Ejemplo n.º 16
0
Archivo: test.py Proyecto: fred3m/sep
def test_aperture_bkgann_ones():
    """Test bkgann functionality with flat data"""

    data = np.ones(data_shape)
    r=5.
    bkgann=(6., 8.)

    # On flat data, result should be zero for any bkgann and subpix
    f, _, _ = sep.sum_circle(data, x, y, r, bkgann=bkgann)
    assert_allclose(f, 0., rtol=0., atol=1.e-13)
   
    f, _, _ = sep.sum_ellipse(data, x, y, 2., 1., np.pi/4., r, bkgann=bkgann)
    assert_allclose(f, 0., rtol=0., atol=1.e-13)
Ejemplo n.º 17
0
    def photskycoord(self, image_path, ra, dec, aper_radius=3.0, gain=0.57):
        """
        Photometry of given coordinates.
        @param image_path: Path of FITS file.
        @type image_path: path
        @param ra: RA coordinate of object
        @type ra: string
        @param dec: DEC coordinate of object
        @type dec: string
        @param aper_radius: Aperture radius
        @type aper_radius: float
        @param gain: gain value for the image expressed in electrons per adu.
        @type gain: float
        @return: tuple
        """

        if image_path:
            hdu = fits.open(image_path)[0]
        else:
            print("FITS image has not been provided by the user!")
            raise SystemExit

        data = hdu.data.astype(float)

        fo = FitsOps(image_path)
        header = hdu.header
        w = WCS(header)

        naxis1 = fo.get_header('naxis1')
        naxis2 = fo.get_header('naxis2')

        c = coordinates.SkyCoord('{0} {1}'.format(ra, dec),
                                 unit=(u.hourangle, u.deg),
                                 frame='icrs')

        # object's X and Y coor
        a_x, a_y = w.wcs_world2pix(c.ra.degree, c.dec.degree, 1)

        if naxis1 < a_x or naxis2 < a_y or a_x < 0 or a_y < 0:
            print("Provided coordinates are out of frame!")
            return (False)
        else:
            bkg = sep.Background(data)
            data_sub = data - bkg
            flux, fluxerr, flag = sep.sum_circle(data_sub,
                                                 a_x,
                                                 a_y,
                                                 aper_radius=aper_radius,
                                                 err=bkg.globalrms,
                                                 gain=gain)
            return ({"flag": flag, "flux": flux, "fluxerr": fluxerr})
Ejemplo n.º 18
0
Archivo: test.py Proyecto: cmccully/sep
def test_aperture_dtypes():
    """Ensure that all supported image dtypes work in sum_circle() and
    give the same answer"""

    r = 3.

    fluxes = []
    for dt in SUPPORTED_IMAGE_DTYPES:
        data = np.ones(data_shape, dtype=dt)
        flux, fluxerr, flag = sep.sum_circle(data, x, y, r)
        fluxes.append(flux)

    for i in range(1, len(fluxes)):
        assert_allclose(fluxes[0], fluxes[i])
Ejemplo n.º 19
0
def sextractor(im,err=None,mask=None,nsig=5.0,gain=1.0):

    # Check byte order, SEP needs little endian
    if im.dtype.byteorder == '>':
        data = im.byteswap().newbyteorder()
    else:
        data = im

    # Background estimation and subtraction
    bkg = sep.Background(data, mask, bw=256, bh=256, fw=3, fh=3)
    bkg_image = bkg.back()
    data_sub = data-bkg
    #data_sub[data>50000]=0.0
    # Detect and extract objects
    if err is None:
        objects = sep.extract(data_sub, nsig, err=bkg.globalrms, mask=mask)
    else:
        objects = sep.extract(data_sub, nsig, err=err, mask=mask)
        
    # Get mag_auto in 2 steps
    kronrad, krflag = sep.kron_radius(data_sub, objects['x'], objects['y'], objects['a'], objects['b'],
                                      objects['theta'], 6.0, mask=mask)
    flux, fluxerr, flag = sep.sum_ellipse(data_sub, objects['x'], objects['y'], objects['a'], objects['b'],
                                          objects['theta'], 2.5*kronrad, subpix=1, err=err, mask=mask, gain=gain)
    flag |= krflag  # combine flags into 'flag'

    # Use circular aperture if Kron radius is too small
    r_min = 1.75  # minimum diameter = 3.5
    use_circle = kronrad * np.sqrt(objects['a'] * objects['b']) < r_min
    if np.sum(use_circle)>0:
        cflux, cfluxerr, cflag = sep.sum_circle(data_sub, objects['x'][use_circle], objects['y'][use_circle],
                                                r_min, subpix=1, err=err, mask=mask, gain=gain)
        flux[use_circle] = cflux
        fluxerr[use_circle] = cfluxerr
        flag[use_circle] = cflag
    mag_auto = -2.5*np.log10(flux)+25.0
    magerr_auto = 1.0857*fluxerr/flux
    
    # Make the final catalog
    newdt = np.dtype([('kronrad',float),('flux_auto',float),('fluxerr_auto',float),('mag_auto',float),('magerr_auto',float)])
    cat = dln.addcatcols(objects,newdt)
    cat['flag'] |= flag
    cat['kronrad'] = kronrad
    cat['flux_auto'] = flux
    cat['fluxerr_auto'] = fluxerr
    cat['mag_auto'] = mag_auto
    cat['magerr_auto'] = magerr_auto
    
    return cat
Ejemplo n.º 20
0
def flux(path, aperture):

    import sep, numpy as np
    from astropy.io import fits

    # Reading the fits image alongwith its header
    galaxy = fits.open(path)
    data = galaxy[0].data

    # This step seems meaningless but it works. The issue is the change of byte order which will increase the computation time  so I had this workaround!
    data = data + 0

    # subtracting the background. It's a good idea to ckech the image of background!
    bkg = sep.Background(data)
    back = bkg.back()
    data2 = data - back

    # it will be really helpful if we see the image at this point. It is background subtracted so the difference should be noticable.

    # printing the global background as well as the  rms of background.

    #print(bkg.globalback)
    #print(bkg.globalrms)

    # defining the threshold, it is necessary for flux estimation.

    thresh = 10 * bkg.globalback
    #print(thresh)

    # finding out the objects, it will store all the objects found out in the frame determined by the threshold.

    objects = sep.extract(data2, thresh, err=bkg.globalrms)

    #The most important, flux and its error determination. This will take a given aperture and calculate the flux in that aperture around the centroid of the object.

    flux, fluxerr, flag = sep.sum_circle(data2,
                                         objects['x'],
                                         objects['y'],
                                         aperture,
                                         err=bkg.globalrms,
                                         gain=1.4)

    #printing the flux values.

    l = len(objects)
    flux = np.max(flux)
    fluxerr = np.max(fluxerr)
    return (l, flux, fluxerr)
Ejemplo n.º 21
0
def extract(data):
	bkg = sep.Background(data, bw=64, bh=64, fw=3, fh=3)
	bkg.subfrom(data)
	objs = sep.extract(data, 1.5*bkg.globalrms)
	flux, fluxerr, flag = sep.sum_circle(data, objs['x'], objs['y'], 5.,
                                         err=bkg.globalrms)
	kr, flag = sep.kron_radius(data, objs['x'], objs['y'], objs['a'],
                               			objs['b'], objs['theta'], 6.0)
	eflux, efluxerr, eflag = sep.sum_ellipse(data, objs['x'], objs['y'],
                                          objs['a'], objs['b'],
                                          objs['theta'], r=2.5 * kr,
                                          err=bkg.globalrms, subpix=1)
	retstr = ""
	for i in range(len(objs['x'])):
		retstr = retstr+(str(objs['x'][i])+"\t"+str(objs['y'][i])+"\t"+str(flux[i])+"\t"+str(fluxerr[i])+"\t"+str(kr[i])+"\t"+str(eflux[i])+"\t"+str(efluxerr[i])+"\t"+str(flag[i])+"\n")
	return retstr
Ejemplo n.º 22
0
 def do(self, data, x_coor, y_coor, aper_radius=10.0, gain=1.21):
     self.etc.log(
         "Starting Photometry for x({}), y({}) with aperture({}) and gain({})"
         .format(x_coor, y_coor, aper_radius, gain))
     try:
         bkg = Background(data)
         data_sub = data - bkg
         flux, fluxerr, flag = sum_circle(data_sub,
                                          x_coor,
                                          y_coor,
                                          aper_radius,
                                          err=bkg.globalrms,
                                          gain=gain)
         return (flux, fluxerr, flag)
     except Exception as e:
         self.eetc.log(e)
Ejemplo n.º 23
0
    def run(self, image):
        if self.fwhm_scale:
            r_in = self.annulus_inner_radius * image.fwhm
            r_out = self.annulus_outer_radius * image.fwhm
            r = self.apertures * image.fwhm
        else:
            r_in = self.annulus_inner_radius
            r_out = self.annulus_outer_radius
            r = self.apertures

        self.n_stars = len(image.stars_coords)
        image.fluxes = np.zeros((self.n_apertures, self.n_stars))

        data = image.data.copy().byteswap().newbyteorder()

        for i, _r in enumerate(r):
            image.fluxes[i, :], fluxerr, flag = sep.sum_circle(
                data,
                *image.stars_coords.T,
                _r,
                bkgann=(r_in, r_out),
                subpix=0)

        image.sky = 0
        image.apertures_area = np.pi * r**2
        image.annulus_area = np.pi * (r_out**2 - r_in**2)

        # fluxes = np.zeros((self.n_apertures, self.n_stars))
        # bkg = np.zeros((self.n_apertures, self.n_stars))

        # for i, _r in enumerate(r):
        #     fluxes[i, :], _, _ = sep.sum_circle(
        #         data,
        #         *image.stars_coords.T,
        #         _r, bkgann=(r_in, r_out), subpix=0)

        #     bkg[i, :], _, _ = sep.sum_circann(data, *image.stars_coords.T, r_in, r_out, subpix=0)

        #     image.fluxes = fluxes - bkg

        # image.sky = np.mean(bkg)
        # image.apertures_area = np.pi * r**2
        # image.annulus_area = np.pi * (r_out**2 - r_in**2)
        # image.header["sky"] = np.mean(image.sky)

        self.compute_error(image)
Ejemplo n.º 24
0
def timeEvolveFITS(data, coords, x_drift, y_drift, r, stars, x_length,
                   y_length, t):
    """ Adjusts aperture based on star drift and calculates flux in aperture"""

    x = [coords[ind, 0] + x_drift[ind] for ind in range(0, stars)]
    y = [coords[ind, 1] + y_drift[ind] for ind in range(0, stars)]
    inds = clipCutStars(x, y, x_length, y_length)
    inds = list(set(inds))
    inds.sort()
    xClip = np.delete(np.array(x), inds)
    yClip = np.delete(np.array(y), inds)
    bkg = np.median(data) * np.pi * r * r
    fluxes = (sep.sum_circle(data, xClip, yClip, r)[0] - bkg).tolist()
    for a in inds:
        fluxes.insert(a, 0)
    coords = zip(x, y, fluxes, [t] * len(x))
    return coords
def get_fluxes(object1, data1, iR, oR, G, rN):
    """
    Preconditions: Expects a sep extracted list of objects and the image data
    the objectlist is from. Can also take the inner radius, outer radius,
    gain, and read noise.
    Postcontions: Returns the flux and flux error for each object in the list.
    """

    flux, fluxerr, flag = sep.sum_circle(data1,
                                         object1['x'],
                                         object1['y'],
                                         16.0,
                                         bkgann=(iR, oR),
                                         gain=G,
                                         err=rN)

    return flux, np.sqrt(fluxerr)
Ejemplo n.º 26
0
    def AperPhot(self, r_aper=[1.5, 2.0, 4.0], write=True):

        ra, dec = self.wcs.all_pix2world(self.src['x'] + 1, self.src['y'] + 1,
                                         1)

        df = pd.DataFrame(
            data={
                'x': self.src['x'],
                'y': self.src['y'],
                'ra': ra,
                'dec': dec,
                'a': self.src['a'],
                'b': self.src['b'],
                'theta': self.src['theta']
            })

        for i in np.arange(len(r_aper)):
            flux, fluxerr, flag = sep.sum_circle(self.dat,
                                                 self.src['x'],
                                                 self.src['y'],
                                                 r_aper[i],
                                                 err=self.skysigma,
                                                 gain=self.gain,
                                                 subpix=0)
            mag = self.zmag - 2.5 * np.log10(flux)
            magerr = (2.5 / np.log(10.0)) * (fluxerr / flux)

            df['r' + f'{i+1:d}'] = r_aper[i]
            df['flux' + f'{i+1:d}'] = flux
            df['e_flux' + f'{i+1:d}'] = fluxerr
            df['mag' + f'{i+1:d}'] = mag
            df['e_mag' + f'{i+1:d}'] = magerr

        if write:
            df.to_csv(ip.tmp_dir + 'aper_' + self.img.split('.fits')[0] +
                      '.csv')

            f = open(ip.tmp_dir + 'src_' + self.img.split('.fits')[0] + '.reg',
                     'w')
            for i in np.arange(self.nsrc):
                f.write('{0:.3f}  {1:.3f}\n'.format(self.src['x'][i] + 1,
                                                    self.src['y'][i] + 1))
            f.close()

        return df
Ejemplo n.º 27
0
Archivo: test.py Proyecto: cmccully/sep
def test_aperture_bkgann_ones():
    """Test bkgann functionality with flat data"""

    data = np.ones(data_shape)
    r=5.
    bkgann=(6., 8.)

    # On flat data, result should be zero for any bkgann and subpix
    f, fe, _ = sep.sum_circle(data, x, y, r, bkgann=bkgann, gain=1.)
    assert_allclose(f, 0., rtol=0., atol=1.e-13)

    # for all ones data and no error array, error should be close to
    # sqrt(Npix_aper + Npix_ann * (Npix_aper**2 / Npix_ann**2))
    aper_area = np.pi * r**2
    bkg_area = np.pi * (bkgann[1]**2 - bkgann[0]**2)
    expected_error = np.sqrt(aper_area + bkg_area * (aper_area/bkg_area)**2)
    assert_allclose(fe, expected_error, rtol=0.1)

    f, _, _ = sep.sum_ellipse(data, x, y, 2., 1., np.pi/4., r, bkgann=bkgann)
    assert_allclose(f, 0., rtol=0., atol=1.e-13)
Ejemplo n.º 28
0
def findSpot(data, sigma):
    image=data
    #m, s = np.mean(image), np.std(image)
    bkg = sep.Background(image, bw=32, bh=32, fw=3, fh=3)
    objs = sep.extract(image-bkg, sigma, err=bkg.globalrms)
    aper_radius=3
    
    # Calculate the Kron Radius
    kronrad, krflag = sep.kron_radius(image, objs['x'], objs['y'], \
        objs['a'], objs['b'], objs['theta'], aper_radius)

    r_min = 3
    use_circle = kronrad * np.sqrt(objs['a'] * objs['b'])
    cinx=np.where(use_circle <= r_min)
    einx=np.where(use_circle > r_min)

    # Calculate the equivalent of FLUX_AUTO
    flux, fluxerr, flag = sep.sum_ellipse(image, objs['x'][einx], objs['y'][einx], \
        objs['a'][einx], objs['b'][einx], objs['theta'][einx], 2.5*kronrad[einx],subpix=1)		

    cflux, cfluxerr, cflag = sep.sum_circle(image, objs['x'][cinx], objs['y'][cinx],
                                    objs['a'][cinx], subpix=1)

    # Adding half pixel to measured coordinate.  
    objs['x'] =  objs['x']+0.5
    objs['y'] =  objs['y']+0.5

    objs['flux'][einx]=flux
    objs['flux'][cinx]=cflux


    r, flag = sep.flux_radius(image, objs['x'], objs['y'], \
        6*objs['a'], 0.3,normflux=objs['flux'], subpix=5)

    flag |= krflag
 
    objs=rfn.append_fields(objs, 'r', data=r, usemask=False)

    objects=objs[:]
    
    return objects
Ejemplo n.º 29
0
    def phot(self, image_path,
             x_coor, y_coor,
             aper_radius=3.0,
             gain=0.57):

        """
        Photometry of given coordinates.
        @param image_path: Path of FITS file.
        @type image_path: path
        @param x_coor: X coordinate of object
        @type x_coor: float
        @param y_coor: Y coordinate of object
        @type y_coor: float
        @param aper_radius: Aperture radius
        @type aper_radius: float
        @return: tuple
        """
        
        if image_path:
            hdu = fits.open(image_path)[0]
        else:
            print("FITS image has not been provided by the user!")
            raise SystemExit

        data = hdu.data.astype(float)

        bkg = sep.Background(data)
        # bkg_image = bkg.back()
        # bkg_rms = bkg.rms()
        data_sub = data - bkg

        flux, fluxerr, flag = sep.sum_circle(data_sub,
                                             x_coor,
                                             y_coor,
                                             aper_radius=aper_radius,
                                             err=bkg.globalrms,
                                             gain=gain)

        return({"flag": flag,
                "flux": flux,
                "fluxerr": fluxerr})
Ejemplo n.º 30
0
def sextract_magnitudes(
    data,
    aperture_radius,
    buffer_radius,
    background_radius,
    bkg=None,
    objects=None,
    sigma=3.0,
):
    aperture_area = np.pi * (aperture_radius**2)
    buffer_area = np.pi * (buffer_radius**2)
    background_area = (np.pi * (background_radius**2)) - buffer_area

    if bkg is None:
        data, bkg = sextract_bkg(data)
    if objects is None:
        objects = sextract_objects(data, sigma, bkg)

    aperture_list, _, _ = sep.sum_circle(data,
                                         objects["x"],
                                         objects["y"],
                                         aperture_radius,
                                         err=bkg.globalrms,
                                         gain=1.0)
    background_list, _, _ = sep.sum_circann(
        data,
        objects["x"],
        objects["y"],
        buffer_radius,
        background_radius,
        err=bkg.globalrms,
        gain=1.0,
    )
    background_densities = [
        annulus_sum / background_area for annulus_sum in background_list
    ]
    fluxes = np.array([
        aperture_list[i] - (aperture_area * background_densities[i])
        for i in range(len(aperture_list))
    ])
    return fluxes
Ejemplo n.º 31
0
Archivo: test.py Proyecto: cmccully/sep
def test_apertures_all():
    """Test that aperture subpixel sampling works"""

    data = np.random.rand(*data_shape)
    r = 3.
    rtol=1.e-8

    for subpix in [0, 1, 5]:
        flux_ref, fluxerr_ref, flag_ref = sep.sum_circle(data, x, y, r,
                                                         subpix=subpix)

        flux, fluxerr, flag = sep.sum_circann(data, x, y, 0., r,
                                              subpix=subpix)
        assert_allclose(flux, flux_ref, rtol=rtol)

        flux, fluxerr, flag = sep.sum_ellipse(data, x, y, r, r, 0.,
                                              subpix=subpix)
        assert_allclose(flux, flux_ref, rtol=rtol)

        flux, fluxerr, flag = sep.sum_ellipse(data, x, y, 1., 1., 0., r=r,
                                              subpix=subpix)
        assert_allclose(flux, flux_ref, rtol=rtol)
Ejemplo n.º 32
0
        def mphotometry(self,
                        file,
                        coors,
                        zmag=25.0,
                        apertures=[10.0, 15.0],
                        gain=1.21):
            """Python multiple photometry"""
            try:
                data = self.data(file)
                bkg = Background(data)
                data_sub = data - bkg
                ret = []
                for coor in coors:
                    try:
                        x_coor, y_coor = list(map(int, coor))
                        for aper in apertures:
                            flx, ferr, flag = sum_circle(data_sub,
                                                         x_coor,
                                                         y_coor,
                                                         aper,
                                                         err=bkg.globalrms,
                                                         gain=gain)

                            mag, merr = self.sma.flux_to_mag(flx, ferr)
                            ret.append([
                                str(x_coor),
                                str(y_coor),
                                str(aper),
                                str(float(flx)),
                                str(float(ferr)),
                                str(float(flag)),
                                str(mag + zmag),
                                str(merr)
                            ])
                    except Exception as e:
                        self.logger.error(e)
                return ret
            except Exception as e:
                self.logger.error(e)
Ejemplo n.º 33
0
def aperture_photometry(data, x, y, r, r_in, r_out,
                        elipse = False, abtheta = None,
                        rms = None,
                        *args, **kwargs):
    '''
    Do the aperture photometry with local sky subtraction.

    Parameters:
        data : ~numpy.ndarray~
            2D image data.
        x, y : list of list of float
            The list containing the pairs (x,y) of the objects.
        r : float
            The radius of the circular aperture to do the sum.
        r_in : float
            The internal radius of the sky annulus.
        r_out : float
            The external radius of the sky annulus.
        elipse : bool
            Tell the program if you want to do the photometry with eliptical
            aperture. If True, you have to pass the 'abtheta' argument, giving
            the elipse properties.
        **The kwargs will be passed integrally to the sep functions.

    Returns:
        flux, fluxerr, flags : ~numpy.ndarray~
            The sum of the aperture, with annulus sky subtraction, and its error.
    '''
    data = _fix_data(data)

    if elipse:
        if abtheta is None:
            raise ValueError("You must give the 'abtheta' argument if you want elipse photometry.")
        a, b, theta = _extract_abtheta(abtheta)
        return sep.sum_ellipse(data, x, y, a, b, theta, r, err=rms, bkgann=(r_in, r_out), **kwargs)
    else:
        return sep.sum_circle(data, x, y, r, err=rms, bkgann=(r_in, r_out), **kwargs)
Ejemplo n.º 34
0
def do_phot(data, x, y, r_aper=PHOT_RADIUS):
    """
    Extract photometry from the reference positions,
    altered by the shifts from donuts

    Parameters
    ----------
    data : array-like
        data array to extract photometry from
    x : array-like
        list of x positions to extract
    y : array-like
        list of y positions to extract
    r_aper : float
        radius used for the aperture photometry

    Returns
    -------
    new_fluxes : array-like
        new flux measurements at these positions

    Raises
    ------
    None
    """
    bkg = sep.Background(data)
    data_new = data - bkg
    flux_new = []
    for i, j in zip(x, y):
        flux, _, _ = sep.sum_circle(data_new,
                                    i,
                                    j,
                                    r_aper,
                                    subpix=0,
                                    gain=GAIN)
        flux_new.append(flux)
    return np.array(flux_new)
Ejemplo n.º 35
0
def forcephot(image,x,y,rad,skyreg=[10,20],show=False,mask=None):
    
    """

    Compute the photometry on a MUSE reconstructed image within an aperture 
    Treat limits as 2sigma

    x,y        -> position of the aperture in pixels
    radap      -> radius of the aperture in pixels
    skyreg     -> radius of inner/outer sky region in pixel
    mask       -> mask to avoid pixels
    
    show       -> if true, show what's appening


    """
    
    from astropy.io import fits
    import matplotlib.pyplot as plt
    import sep
    import numpy as np

    #open the image
    image=fits.open(image)
    data = image[1].data.byteswap().newbyteorder()
    var = image[2].data.byteswap().newbyteorder()

    #grab the zp
    zp=image[0].header['ZPAB']
    flux, err, flg = sep.sum_circle(data,x,y,rad,var=var,bkgann=skyreg,mask=mask)

    #compute magnitudes
    if(flux < 2*err):
        mag=-2.5*np.log10(2*err)+zp
        errmag=99
    else:
        mag=-2.5*np.log10(flux)+zp
        errmag=2.5*np.log10(1.+err/flux)     

    #if show
    if(show):
        

        #display field
        median=np.median(data)
        stddev=np.std(data)
        plt.imshow(data,clim=[median-0.2*stddev,median+stddev],origin='low')
        

        #now the aperture 
        circ=plt.Circle((x,y),radius=rad, color='red', fill=False)
        ax=plt.gca()
        ax.add_patch(circ)
    
        if(skyreg):
             circ1=plt.Circle((x,y),radius=skyreg[0], color='red', fill=False)
             circ2=plt.Circle((x,y),radius=skyreg[1], color='red', fill=False)
             ax.add_patch(circ1)
             ax.add_patch(circ2)

        

        plt.show()



    return mag, errmag
Ejemplo n.º 36
0
    def do_stage(self, images):
        for i, image in enumerate(images):
            try:
                # Set the number of source pixels to be 5% of the total. This keeps us safe from
                # satellites and airplanes.
                sep.set_extract_pixstack(int(image.nx * image.ny * 0.05))

                data = image.data.copy()
                error = (np.abs(data) + image.readnoise ** 2.0) ** 0.5
                mask = image.bpm > 0

                # Fits can be backwards byte order, so fix that if need be and subtract
                # the background
                try:
                    bkg = sep.Background(data, mask=mask, bw=32, bh=32, fw=3, fh=3)
                except ValueError:
                    data = data.byteswap(True).newbyteorder()
                    bkg = sep.Background(data, mask=mask, bw=32, bh=32, fw=3, fh=3)
                bkg.subfrom(data)

                # Do an initial source detection
                # TODO: Add back in masking after we are sure SEP works
                sources = sep.extract(data, self.threshold, minarea=self.min_area,
                                      err=error, deblend_cont=0.005)

                # Convert the detections into a table
                sources = Table(sources)

                # We remove anything with a detection flag >= 8
                # This includes memory overflows and objects that are too close the edge
                sources = sources[sources['flag'] < 8]

                sources = array_utils.prune_nans_from_table(sources)

                # Calculate the ellipticity
                sources['ellipticity'] = 1.0 - (sources['b'] / sources['a'])

                # Fix any value of theta that are invalid due to floating point rounding
                # -pi / 2 < theta < pi / 2
                sources['theta'][sources['theta'] > (np.pi / 2.0)] -= np.pi
                sources['theta'][sources['theta'] < (-np.pi / 2.0)] += np.pi

                # Calculate the kron radius
                kronrad, krflag = sep.kron_radius(data, sources['x'], sources['y'],
                                                  sources['a'], sources['b'],
                                                  sources['theta'], 6.0)
                sources['flag'] |= krflag
                sources['kronrad'] = kronrad

                # Calcuate the equivilent of flux_auto
                flux, fluxerr, flag = sep.sum_ellipse(data, sources['x'], sources['y'],
                                                      sources['a'], sources['b'],
                                                      np.pi / 2.0, 2.5 * kronrad,
                                                      subpix=1, err=error)
                sources['flux'] = flux
                sources['fluxerr'] = fluxerr
                sources['flag'] |= flag

                # Do circular aperture photometry for diameters of 1" to 6"
                for diameter in [1, 2, 3, 4, 5, 6]:
                    flux, fluxerr, flag = sep.sum_circle(data, sources['x'], sources['y'],
                                                         diameter / 2.0, gain=1.0, err=error)
                    sources['fluxaper{0}'.format(diameter)] = flux
                    sources['fluxerr{0}'.format(diameter)] = fluxerr
                    sources['flag'] |= flag

                # Calculate the FWHMs of the stars:
                fwhm = 2.0 * (np.log(2) * (sources['a'] ** 2.0 + sources['b'] ** 2.0)) ** 0.5
                sources['fwhm'] = fwhm

                # Cut individual bright pixels. Often cosmic rays
                sources = sources[fwhm > 1.0]

                # Measure the flux profile
                flux_radii, flag = sep.flux_radius(data, sources['x'], sources['y'],
                                                   6.0 * sources['a'], [0.25, 0.5, 0.75],
                                                   normflux=sources['flux'], subpix=5)
                sources['flag'] |= flag
                sources['fluxrad25'] = flux_radii[:, 0]
                sources['fluxrad50'] = flux_radii[:, 1]
                sources['fluxrad75'] = flux_radii[:, 2]

                # Calculate the windowed positions
                sig = 2.0 / 2.35 * sources['fluxrad50']
                xwin, ywin, flag = sep.winpos(data, sources['x'], sources['y'], sig)
                sources['flag'] |= flag
                sources['xwin'] = xwin
                sources['ywin'] = ywin

                # Calculate the average background at each source
                bkgflux, fluxerr, flag = sep.sum_ellipse(bkg.back(), sources['x'], sources['y'],
                                                         sources['a'], sources['b'], np.pi / 2.0,
                                                         2.5 * sources['kronrad'], subpix=1)
                #masksum, fluxerr, flag = sep.sum_ellipse(mask, sources['x'], sources['y'],
                #                                         sources['a'], sources['b'], np.pi / 2.0,
                #                                         2.5 * kronrad, subpix=1)

                background_area = (2.5 * sources['kronrad']) ** 2.0 * sources['a'] * sources['b'] * np.pi # - masksum
                sources['background'] = bkgflux
                sources['background'][background_area > 0] /= background_area[background_area > 0]
                # Update the catalog to match fits convention instead of python array convention
                sources['x'] += 1.0
                sources['y'] += 1.0

                sources['xpeak'] += 1
                sources['ypeak'] += 1

                sources['xwin'] += 1.0
                sources['ywin'] += 1.0

                sources['theta'] = np.degrees(sources['theta'])

                image.catalog = sources['x', 'y', 'xwin', 'ywin', 'xpeak', 'ypeak',
                                        'flux', 'fluxerr', 'peak', 'fluxaper1', 'fluxerr1',
                                        'fluxaper2', 'fluxerr2', 'fluxaper3', 'fluxerr3',
                                        'fluxaper4', 'fluxerr4', 'fluxaper5', 'fluxerr5',
                                        'fluxaper6', 'fluxerr6', 'background', 'fwhm',
                                        'a', 'b', 'theta', 'kronrad', 'ellipticity',
                                        'fluxrad25', 'fluxrad50', 'fluxrad75',
                                        'x2', 'y2', 'xy', 'flag']

                # Add the units and description to the catalogs
                image.catalog['x'].unit = 'pixel'
                image.catalog['x'].description = 'X coordinate of the object'
                image.catalog['y'].unit = 'pixel'
                image.catalog['y'].description = 'Y coordinate of the object'
                image.catalog['xwin'].unit = 'pixel'
                image.catalog['xwin'].description = 'Windowed X coordinate of the object'
                image.catalog['ywin'].unit = 'pixel'
                image.catalog['ywin'].description = 'Windowed Y coordinate of the object'
                image.catalog['xpeak'].unit = 'pixel'
                image.catalog['xpeak'].description = 'X coordinate of the peak'
                image.catalog['ypeak'].unit = 'pixel'
                image.catalog['ypeak'].description = 'Windowed Y coordinate of the peak'
                image.catalog['flux'].unit = 'counts'
                image.catalog['flux'].description = 'Flux within a Kron-like elliptical aperture'
                image.catalog['fluxerr'].unit = 'counts'
                image.catalog['fluxerr'].description = 'Error on the flux within Kron aperture'
                image.catalog['peak'].unit = 'counts'
                image.catalog['peak'].description = 'Peak flux (flux at xpeak, ypeak)'
                for diameter in [1, 2, 3, 4, 5, 6]:
                    image.catalog['fluxaper{0}'.format(diameter)].unit = 'counts'
                    image.catalog['fluxaper{0}'.format(diameter)].description = 'Flux from fixed circular aperture: {0}" diameter'.format(diameter)
                    image.catalog['fluxerr{0}'.format(diameter)].unit = 'counts'
                    image.catalog['fluxerr{0}'.format(diameter)].description = 'Error on Flux from circular aperture: {0}"'.format(diameter)

                image.catalog['background'].unit = 'counts'
                image.catalog['background'].description = 'Average background value in the aperture'
                image.catalog['fwhm'].unit = 'pixel'
                image.catalog['fwhm'].description = 'FWHM of the object'
                image.catalog['a'].unit = 'pixel'
                image.catalog['a'].description = 'Semi-major axis of the object'
                image.catalog['b'].unit = 'pixel'
                image.catalog['b'].description = 'Semi-minor axis of the object'
                image.catalog['theta'].unit = 'degrees'
                image.catalog['theta'].description = 'Position angle of the object'
                image.catalog['kronrad'].unit = 'pixel'
                image.catalog['kronrad'].description = 'Kron radius used for extraction'
                image.catalog['ellipticity'].description = 'Ellipticity'
                image.catalog['fluxrad25'].unit = 'pixel'
                image.catalog['fluxrad25'].description = 'Radius containing 25% of the flux'
                image.catalog['fluxrad50'].unit = 'pixel'
                image.catalog['fluxrad50'].description = 'Radius containing 50% of the flux'
                image.catalog['fluxrad75'].unit = 'pixel'
                image.catalog['fluxrad75'].description = 'Radius containing 75% of the flux'
                image.catalog['x2'].unit = 'pixel^2'
                image.catalog['x2'].description = 'Variance on X coordinate of the object'
                image.catalog['y2'].unit = 'pixel^2'
                image.catalog['y2'].description = 'Variance on Y coordinate of the object'
                image.catalog['xy'].unit = 'pixel^2'
                image.catalog['xy'].description = 'XY covariance of the object'
                image.catalog['flag'].description = 'Bit mask of extraction/photometry flags'

                image.catalog.sort('flux')
                image.catalog.reverse()

                logging_tags = logs.image_config_to_tags(image, self.group_by_keywords)
                logs.add_tag(logging_tags, 'filename', os.path.basename(image.filename))

                # Save some background statistics in the header
                mean_background = stats.sigma_clipped_mean(bkg.back(), 5.0)
                image.header['L1MEAN'] = (mean_background,
                                          '[counts] Sigma clipped mean of frame background')
                logs.add_tag(logging_tags, 'L1MEAN', float(mean_background))

                median_background = np.median(bkg.back())
                image.header['L1MEDIAN'] = (median_background,
                                            '[counts] Median of frame background')
                logs.add_tag(logging_tags, 'L1MEDIAN', float(median_background))

                std_background = stats.robust_standard_deviation(bkg.back())
                image.header['L1SIGMA'] = (std_background,
                                           '[counts] Robust std dev of frame background')
                logs.add_tag(logging_tags, 'L1SIGMA', float(std_background))

                # Save some image statistics to the header
                good_objects = image.catalog['flag'] == 0

                seeing = np.median(image.catalog['fwhm'][good_objects]) * image.pixel_scale
                image.header['L1FWHM'] = (seeing, '[arcsec] Frame FWHM in arcsec')
                logs.add_tag(logging_tags, 'L1FWHM', float(seeing))

                mean_ellipticity = stats.sigma_clipped_mean(sources['ellipticity'][good_objects],
                                                            3.0)
                image.header['L1ELLIP'] = (mean_ellipticity, 'Mean image ellipticity (1-B/A)')
                logs.add_tag(logging_tags, 'L1ELLIP', float(mean_ellipticity))

                mean_position_angle = stats.sigma_clipped_mean(sources['theta'][good_objects], 3.0)
                image.header['L1ELLIPA'] = (mean_position_angle,
                                            '[deg] PA of mean image ellipticity')
                logs.add_tag(logging_tags, 'L1ELLIPA', float(mean_position_angle))

                self.logger.info('Extracted sources', extra=logging_tags)

            except Exception as e:
                logging_tags = logs.image_config_to_tags(image, self.group_by_keywords)
                logs.add_tag(logging_tags, 'filename', os.path.basename(image.filename))
                self.logger.error(e, extra=logging_tags)
        return images
Ejemplo n.º 37
0
def aperture_photometry(data, objects, radii):
	#TODO aperture corrected flux: take the ratio of the Flux in the bigger to the flux in the smaller, average them to find the correction, then multiply each of the smaller fluxes to the correction. Do the same thing for errors. Depending on what you set your GAIN to be, this is either background only or background and Poisson. If GAIN is set to 0 its only background error. http://www.galex.caltech.edu/researcher/techdoc-ch5.html Or you could use the apertures in Figure 1... The value for the correction shouldn't change much for GALEX since the PSF doesn't change across the CCDs.
	flux_min, fluxerr_min, flag_min = sep.sum_circle(data, objects[0], objects[1], min(radii))
	flux_max, fluxerr_max, flag_max = sep.sum_circle(data, objects[0], objects[1], max(radii))
	return flux_min
Ejemplo n.º 38
0
def test_vs_sextractor():
    data = np.copy(image_data)  # make an explicit copy so we can 'subfrom'
    bkg = sep.Background(data, bw=64, bh=64, fw=3, fh=3)

    # Test that SExtractor background is same as SEP:
    bkgarr = bkg.back(dtype=np.float32)
    assert_allclose(bkgarr, image_refback, rtol=1.e-5)

    # Extract objects
    bkg.subfrom(data)
    objs = sep.extract(data, 1.5*bkg.globalrms)
    objs = np.sort(objs, order=['y'])

    # Read SExtractor result
    refobjs = np.loadtxt(IMAGECAT_FNAME, dtype=IMAGECAT_DTYPE)
    refobjs = np.sort(refobjs, order=['y'])

    # Found correct number of sources at the right locations?
    assert_allclose(objs['x'], refobjs['x'] - 1., atol=1.e-3)
    assert_allclose(objs['y'], refobjs['y'] - 1., atol=1.e-3)

    # Test aperture flux
    flux, fluxerr, flag = sep.sum_circle(data, objs['x'], objs['y'], 5.,
                                         err=bkg.globalrms)
    assert_allclose(flux, refobjs['flux_aper'], rtol=2.e-4)
    assert_allclose(fluxerr, refobjs['fluxerr_aper'], rtol=1.0e-5)

    # check if the flags work at all (comparison values 
    assert ((flag & sep.APER_TRUNC) != 0).sum() == 4
    assert ((flag & sep.APER_HASMASKED) != 0).sum() == 0

    # Test "flux_auto"
    kr, flag = sep.kron_radius(data, objs['x'], objs['y'], objs['a'],
                               objs['b'], objs['theta'], 6.0)

    flux, fluxerr, flag = sep.sum_ellipse(data, objs['x'], objs['y'],
                                          objs['a'], objs['b'],
                                          objs['theta'], r=2.5 * kr,
                                          err=bkg.globalrms, subpix=1)

    # For some reason, object at index 59 doesn't match. It's very small
    # and kron_radius is set to 0.0 in SExtractor, but 0.08 in sep.
    # Most of the other values are within 1e-4 except one which is only
    # within 0.01. This might be due to a change in SExtractor between
    # v2.8.6 (used to generate "truth" catalog) and v2.18.11.
    kr[59] = 0.0
    flux[59] = 0.0
    fluxerr[59] = 0.0
    assert_allclose(2.5*kr, refobjs['kron_radius'], rtol=0.01)
    assert_allclose(flux, refobjs['flux_auto'], rtol=0.01)
    assert_allclose(fluxerr, refobjs['fluxerr_auto'], rtol=0.01)

    # Test ellipse representation conversion
    cxx, cyy, cxy = sep.ellipse_coeffs(objs['a'], objs['b'], objs['theta'])
    assert_allclose(cxx, objs['cxx'], rtol=1.e-4)
    assert_allclose(cyy, objs['cyy'], rtol=1.e-4)
    assert_allclose(cxy, objs['cxy'], rtol=1.e-4)

    a, b, theta = sep.ellipse_axes(objs['cxx'], objs['cyy'], objs['cxy'])
    assert_allclose(a, objs['a'], rtol=1.e-4)
    assert_allclose(b, objs['b'], rtol=1.e-4)
    assert_allclose(theta, objs['theta'], rtol=1.e-4)

    #test round trip
    cxx, cyy, cxy = sep.ellipse_coeffs(a, b, theta)
    assert_allclose(cxx, objs['cxx'], rtol=1.e-4)
    assert_allclose(cyy, objs['cyy'], rtol=1.e-4)
    assert_allclose(cxy, objs['cxy'], rtol=1.e-4)

    # test flux_radius
    fr, flags = sep.flux_radius(data, objs['x'], objs['y'], 6.*refobjs['a'],
                                [0.1, 0.5, 0.6], normflux=refobjs['flux_auto'],
                                subpix=5)
    assert_allclose(fr, refobjs["flux_radius"], rtol=0.04, atol=0.01)

    # test winpos
    sig = 2. / 2.35 * fr[:, 1]  # flux_radius = 0.5
    xwin, ywin, flag = sep.winpos(data, objs['x'], objs['y'], sig)
    assert_allclose(xwin, refobjs["xwin"] - 1., rtol=0., atol=0.0025)
    assert_allclose(ywin, refobjs["ywin"] - 1., rtol=0., atol=0.0025)
Ejemplo n.º 39
0
def alma_source():
    """
    Model a source detected in alma
    """
    import grizli.utils

    # ALMA source
    if False:
        # zero-out nearby object
        ix = np.where(ids == 1019)[0][0]
        _xx = _x[0]
        _xx[Nbg + ix] = 0
        h_model2 = _Af.T.dot(_xx).reshape(h_sm.shape)

        full_model = irac_im.data * 0
        full_model[isly, islx] += h_model2
        pyfits.writeto('{0}-ch{1}_model.fits'.format(root, ch),
                       data=full_model,
                       header=irac_im.header,
                       overwrite=True)

        #########
        import sep
        rg, dg = 205.5360413, 9.478936196
        rq, dq = 205.5337798, 9.477328082
        rr, dd = rg, dg

        phot = grizli.utils.read_catalog(
            '{0}irac_phot_apcorr.fits'.format(root))

        irac_im = pyfits.open('{0}-ch{1}_drz_sci.fits'.format(root, ch))[0]
        irac_wht = pyfits.open('{0}-ch{1}_drz_wht.fits'.format(root,
                                                               ch))[0].data

        irac_wcs = pywcs.WCS(irac_im.header)
        full_model = pyfits.open('{0}-ch1_model.fits'.format(root))[0].data

        irac_psf, psf_nexp = irac.evaluate_irac_psf(ch=ch,
                                                    scale=0.1,
                                                    ra=rg,
                                                    dec=dg)

        xy_ap = irac_wcs.all_world2pix(np.array([[rg, dg]]), 0).T
        apers = np.append(4, np.arange(2, 10.1, 0.5))
        _res = sep.sum_circle(irac_im.data - full_model,
                              xy_ap[0],
                              xy_ap[1],
                              apers,
                              var=1 / irac_wht)

        sh_psf = irac_psf.shape
        _res_psf = sep.sum_circle(irac_psf, [sh_psf[1] // 2 - 1],
                                  [sh_psf[0] // 2 - 1],
                                  apers * 5,
                                  var=irac_psf * 0. + 1)

        ch1_flux = (_res[0] / _res_psf[0])[0]
        ch1_err = (_res[1] / _res_psf[0])[0]

        parent = ['ch1']
        wave = [3.6]
        fnu = [1.7927988]
        fnu_sum = [1.7927988]
        efnu = [0.2448046]
        pixscale = [0.5]

        parent += ['ch2']
        wave += [4.5]
        fnu += [3.060]
        fnu_sum += [3.06]
        efnu += [0.3203]
        pixscale += [0.5]
        width = [0.25] * 2

        alm = grizli.utils.read_catalog('alma.info', format='ascii')
        alm['wave'] = 2.99e8 / alm['CRVAL3'] / 1.e-6 * u.micron
        alm['wave'].format = '.1f'

        # ALMA images
        files = glob.glob('ALMA/*spw2?.mfs*fits')
        files += glob.glob('ALMA/*spw??_*fits')
        files.sort()
        for file in files:
            print(file)
            alma = pyfits.open(file)
            alma_wcs = pywcs.WCS(alma[0].header)
            pscale = np.abs(alma_wcs.wcs.cdelt[0] * 3600.)
            alma_xy = alma_wcs.all_world2pix(np.array([[rr, dd, 0, 0]]),
                                             0).flatten()
            yp, xp = np.indices(np.squeeze(alma[0].data).shape)
            R = np.sqrt((xp - alma_xy[0])**2 +
                        (yp - alma_xy[1])**2) < 1.3 / pscale
            R &= np.isfinite(np.squeeze(alma[0].data))
            fnu.append(np.squeeze(alma[0].data)[R].max() * 1.e6)
            fnu_sum.append(np.squeeze(alma[0].data)[R].sum() * 1.e6)
            wave.append(2.999e8 / alma[0].header['CRVAL3'] * 1.e6)
            width.append(alma[0].header['CDELT3'] / alma[0].header['CRVAL3'] *
                         wave[-1])
            parent.append(file)
            msk = np.isfinite(alma[0].data)
            efnu.append(grizli.utils.nmad(alma[0].data[msk]) * 1.e6)
            pixscale.append(pscale)

        plt.errorbar(wave,
                     fnu,
                     xerr=width,
                     yerr=efnu,
                     marker='o',
                     alpha=0.5,
                     linestyle='None',
                     color='k')
        #plt.scatter(wave, fnu, c=np.log10(np.array(width)/np.array(wave)), marker='o', alpha=0.8, zorder=100, cmap='plasma_r')

        #plt.errorbar(wave, fnu_sum, efnu, marker='o', alpha=0.1, linestyle='None')
        plt.xlabel(r'$\lambda_\mathrm{obs}$, $\mu\mathrm{m}$')
        plt.ylabel(r'flux, $\mu$Jy')
        plt.loglog()

        width_lim = [0.1] * 3
        wave_lim = [1.25, 1.05, 0.81]

        efnu_lim = [
            np.median(phot['f{0}w_etot_1'.format(b)][
                phot['f{0}w_etot_1'.format(b)] > 0])
            for b in ['125', '105', '814']
        ]
        np.random.seed(3)
        fnu_lim = list(np.random.normal(size=3) * np.array(efnu_lim))
        plt.errorbar(wlim,
                     fnu_lim,
                     efnu_lim,
                     marker='v',
                     alpha=0.5,
                     linestyle='None',
                     color='k')
        parent_lim = ['f125w_limit', 'f105w_limit', 'f814w_limit']

        tab = grizli.utils.GTable()
        tab['wave'] = wave + wave_lim
        tab['wave'].unit = u.micron
        tab['dw'] = width + width_lim
        tab['dw'].unit = u.micron
        tab['fnu'] = fnu + fnu_lim
        tab['fnu'].unit = u.microJansky
        tab['efnu'] = efnu + efnu_lim
        tab['efnu'].unit = u.microJansky
        tab['parent'] = parent + parent_lim
        tab.meta['RA'] = (rg, 'Target RA')
        tab.meta['DEC'] = (dg, 'Target Dec')
        tab.meta['TIME'] = (time.ctime(), 'Timestamp of file generation')
        tab['wave'].format = '.1f'
        tab['dw'].format = '.1f'
        for c in tab.colnames:
            if 'fnu' in c:
                tab[c].format = '.3f'

        jname = grizli.utils.radec_to_targname(
            ra=rg,
            dec=dg,
            round_arcsec=(0.01, 0.01 * 15),
            precision=2,
            targstr='j{rah}{ram}{ras}.{rass}{sign}{ded}{dem}{des}.{dess}',
            header=None)
        so = np.argsort(tab['wave'])

        tab[so].write('alma_serendip_{0}.fits'.format(jname), overwrite=True)
        tab[so].write('alma_serendip_{0}.ipac'.format(jname),
                      format='ascii.ipac',
                      overwrite=True)

        if False:
            plt.scatter(
                1.25,
                3 * np.median(phot['f125w_etot_1'][phot['f125w_etot_1'] > 0]),
                marker='v',
                color='k',
                alpha=0.8)
            plt.scatter(
                1.05,
                3 * np.median(phot['f105w_etot_1'][phot['f105w_etot_1'] > 0]),
                marker='v',
                color='k',
                alpha=0.8)
            plt.scatter(
                0.81,
                3 * np.median(phot['f814w_etot_1'][phot['f814w_etot_1'] > 0]),
                marker='v',
                color='k',
                alpha=0.8)

        plt.xlim(0.4, 5000)
        plt.ylim(01.e-5, 1.e4)
        plt.gca().set_yticks(10**np.arange(-5, 4.1))
        plt.grid()

        ### FSPS
        import fsps
        import astropy.constants as const
        import astropy.units as u
        from astropy.cosmology import Planck15

        try:
            print(sp.params['dust2'])
        except:
            sp = fsps.StellarPopulation(zcontinuous=True,
                                        dust_type=2,
                                        sfh=4,
                                        tau=0.1)
        dust2 = 6
        z = 1.5
        tage = 0.2

        sp.params['dust2'] = dust2
        sp.params['add_neb_emission'] = True
        wsp, flux = sp.get_spectrum(tage=tage, peraa=False)

        flux = (flux /
                (1 + z) * const.L_sun).to(u.erg / u.s).value * 1.e23 * 1.e6
        dL = Planck15.luminosity_distance(z).to(u.cm).value
        flux /= 4 * np.pi * dL**2

        yi = np.interp(3.6e4, wsp * (1 + z), flux)

        label = 'z={0:.1f} tage={1:.1f}'.format(
            z, tage) + '\n' + 'dust2={0:.1f}, logM={1:.1f} SFR={2:.1f}'.format(
                dust2, np.log10(sp.stellar_mass * fnu[0] / yi),
                sp.sfr_avg() * fnu[0] / yi)
        plt.plot(wsp * (1 + z) / 1.e4,
                 flux / yi * fnu[0],
                 alpha=0.6,
                 zorder=-1,
                 label=label)
        plt.legend()
        plt.tight_layout()
        plt.savefig('alma_serendip_{0}.pdf'.format(jname))

        # Cubes
        alma = pyfits.open(
            'ALMA/member.uid___A001_X1296_X96a.Pisco_sci.spw27.cube.I.pbcor.fits'
        )

        cube_files = glob.glob('ALMA/*cube*fits')
        cube_files.sort()
        alma = pyfits.open(cube_files[ci])
        alma_wcs = pywcs.WCS(alma[0].header)
        pscale = np.abs(alma_wcs.wcs.cdelt[0] * 3600.)
        alma_xy = alma_wcs.all_world2pix(np.array([[rr, dd, 0, 0]]),
                                         0).flatten()
        yp, xp = np.indices(alma[0].data[0, 0, :, :].shape)
        R = np.sqrt((xp - alma_xy[0])**2 + (yp - alma_xy[1])**2) < 0.5 / pscale
        fin = np.isfinite(alma[0].data)
        alma[0].data[~fin] = 0
        clip = alma[0].data[0, :, :] * R
        fnu_max = clip.max(axis=1).max(axis=1)

        freq = (np.arange(alma_wcs._naxis[2]) + 1 - alma_wcs.wcs.crpix[2]
                ) * alma_wcs.wcs.cdelt[2] + alma_wcs.wcs.crval[2]
        dv = np.gradient(freq) / freq * 3.e5
        ng = 20. / np.median(dv)
        sm = nd.gaussian_filter(fnu_max, ng)
        plt.plot(freq / 1.e9, sm)
        plt.plot(freq / 1.e9, fnu_max, color='k', alpha=0.1)

    if False:
        # candidate
        ix = ids == 588
        coeffs = _x[0] * (~ix)
        h_m2 = _A.T.dot(coeffs).reshape(h_sm.shape)
        ds9.frame(16)
        ds9.view(irac_im.data[isly, islx] - h_m2,
                 header=utils.get_wcs_slice_header(irac_wcs, islx, isly))
Ejemplo n.º 40
0
Archivo: test.py Proyecto: cmccully/sep
def test_vs_sextractor():
    """Test behavior of sep versus sextractor.

    Note: we turn deblending off for this test. This is because the
    deblending algorithm uses a random number generator. Since the sequence
    of random numbers is not the same between sextractor and sep or between
    different platforms, object member pixels (and even the number of objects)
    can differ when deblending is on.

    Deblending is turned off by setting DEBLEND_MINCONT=1.0 in the sextractor
    configuration file and by setting deblend_cont=1.0 in sep.extract().
    """

    data = np.copy(image_data)  # make an explicit copy so we can 'subfrom'
    bkg = sep.Background(data, bw=64, bh=64, fw=3, fh=3)

    # Test that SExtractor background is same as SEP:
    bkgarr = bkg.back(dtype=np.float32)
    assert_allclose(bkgarr, image_refback, rtol=1.e-5)

    # Extract objects (use deblend_cont=1.0 to disable deblending).
    bkg.subfrom(data)
    objs = sep.extract(data, 1.5*bkg.globalrms, deblend_cont=1.0)
    objs = np.sort(objs, order=['y'])

    # Read SExtractor result
    refobjs = np.loadtxt(IMAGECAT_FNAME, dtype=IMAGECAT_DTYPE)
    refobjs = np.sort(refobjs, order=['y'])

    # Found correct number of sources at the right locations?
    assert_allclose(objs['x'], refobjs['x'] - 1., atol=1.e-3)
    assert_allclose(objs['y'], refobjs['y'] - 1., atol=1.e-3)

    # Test aperture flux
    flux, fluxerr, flag = sep.sum_circle(data, objs['x'], objs['y'], 5.,
                                         err=bkg.globalrms)
    assert_allclose(flux, refobjs['flux_aper'], rtol=2.e-4)
    assert_allclose(fluxerr, refobjs['fluxerr_aper'], rtol=1.0e-5)

    # check if the flags work at all (comparison values 
    assert ((flag & sep.APER_TRUNC) != 0).sum() == 4
    assert ((flag & sep.APER_HASMASKED) != 0).sum() == 0

    # Test "flux_auto"
    kr, flag = sep.kron_radius(data, objs['x'], objs['y'], objs['a'],
                               objs['b'], objs['theta'], 6.0)

    flux, fluxerr, flag = sep.sum_ellipse(data, objs['x'], objs['y'],
                                          objs['a'], objs['b'],
                                          objs['theta'], r=2.5 * kr,
                                          err=bkg.globalrms, subpix=1)

    # For some reason, one object doesn't match. It's very small
    # and kron_radius is set to 0.0 in SExtractor, but 0.08 in sep.
    # Could be due to a change in SExtractor between v2.8.6 (used to
    # generate "truth" catalog) and v2.18.11 (from which sep was forked).
    i = 56  # index is 59 when deblending is on.
    kr[i] = 0.0
    flux[i] = 0.0
    fluxerr[i] = 0.0

    # We use atol for radius because it is reported to nearest 0.01 in
    # reference objects.
    assert_allclose(2.5*kr, refobjs['kron_radius'], atol=0.01, rtol=0.) 
    assert_allclose(flux, refobjs['flux_auto'], rtol=0.0005)
    assert_allclose(fluxerr, refobjs['fluxerr_auto'], rtol=0.0005)

    # Test ellipse representation conversion
    cxx, cyy, cxy = sep.ellipse_coeffs(objs['a'], objs['b'], objs['theta'])
    assert_allclose(cxx, objs['cxx'], rtol=1.e-4)
    assert_allclose(cyy, objs['cyy'], rtol=1.e-4)
    assert_allclose(cxy, objs['cxy'], rtol=1.e-4)

    a, b, theta = sep.ellipse_axes(objs['cxx'], objs['cyy'], objs['cxy'])
    assert_allclose(a, objs['a'], rtol=1.e-4)
    assert_allclose(b, objs['b'], rtol=1.e-4)
    assert_allclose(theta, objs['theta'], rtol=1.e-4)

    #test round trip
    cxx, cyy, cxy = sep.ellipse_coeffs(a, b, theta)
    assert_allclose(cxx, objs['cxx'], rtol=1.e-4)
    assert_allclose(cyy, objs['cyy'], rtol=1.e-4)
    assert_allclose(cxy, objs['cxy'], rtol=1.e-4)

    # test flux_radius
    fr, flags = sep.flux_radius(data, objs['x'], objs['y'], 6.*refobjs['a'],
                                [0.1, 0.5, 0.6], normflux=refobjs['flux_auto'],
                                subpix=5)
    assert_allclose(fr, refobjs["flux_radius"], rtol=0.04, atol=0.01)

    # test winpos
    sig = 2. / 2.35 * fr[:, 1]  # flux_radius = 0.5
    xwin, ywin, flag = sep.winpos(data, objs['x'], objs['y'], sig)
    assert_allclose(xwin, refobjs["xwin"] - 1., rtol=0., atol=0.0025)
    assert_allclose(ywin, refobjs["ywin"] - 1., rtol=0., atol=0.0025)
Ejemplo n.º 41
0
def get_sources(img_data, dqmask_data=None, wtmap_data=None, exptime=None, 
        sex_params={}, objects=None, subtract_bkg=False, gain=None, 
        wcs=None, aper_radius=None, windowed=True, edge_val=1, origin=0,
        transform='wcs'):
    """
    Load sources from an image and if a data quality mask is provided, included
    a bitmap of flags in the output catalog. This using SEP to detect
    sources using SExtractor functions (unless an input catalog is provided) 
    and by default calculates the windowed position (see SExtractor or SEP docs
    for more details).
    
    Parameters
    ----------
    img_data: array-like
        Image to use for search
    dqmask_data: array-like, optional
        Data quality mask array. If this is included the output catalog
        will include a ``flags`` column that gives a binary flag for bad
        pixels in the image.
    wtmap: array-like, optional
        Not currently implemented
    exptime: float, optional
        Exposure time. If ``exptime`` is not given, then no magnitudes
        will be calculated
    sex_params: dict, optional
        Dictionary of SExtractor parameters to pass to the
        `~sep.extract` function.
    objects: `~astropy.table.Table`, optional
        If a catalog of sources has already been generated, SExtraction
        will be skipped and the input catalog will be used for aperture
        photometry. The input catalog must contain a list of sources
        either ``ra,dec`` or ``x,y`` as columns.
    subtract_bkg: bool, optional
        Whether or not to subtract the background
    gain: float, optional
        Gain of the detector, used to calculate the magnitude error
    wcs: `~astropy.wcs.WCS`, optional
        World coordinates to calculate RA,DEC from image X,Y. If ``wcs``
        is not given then the output catalog will only contain cartesian
        coordinates for each source.
    aper_radius: int, optional
        Radius of the aperture to use for photometry. If no ``aperture_radius``
        is specified, only the Kron flux will be included in the final
        catalog
    windowed: bool, optional
        Whether or not to use SExtractors window algorithm to calculate a more
        precise position. *Default=True*
    edge_val: integer
        Value to use for pixels outside the edge of the image
    transform: string, optional
        Type of transform to use. Either 'wcs','sip', or 'all'. 
        *Default=wcs*
    """
    import sep
    
    # Estimate the background and subtract it (in place) from the image
    # Note: we might not need to do background subtraction due to the 
    # community pipeline
    bkg = sep.Background(img_data, dqmask_data)
    if subtract_bkg:
        bkg.subfrom(img_data)
        bkg = sep.Background(img_data, dqmask_data)
    
    # Find the objects
    if objects is None:
        if 'extract' not in sex_params:
            sex_params['extract'] = {'thresh': 1.5*bkg.globalrms}
        if 'thresh' not in sex_params['extract']:
            if 'thresh' in sex_params:
                sex_params['extract']['thresh'] = \
                    sex_params['thresh']*bkg.globalrms
            else:
                raise Exception(
                    "You must provide a threshold parameter"
                    " for source extraction")
        sources = sep.extract(img_data, **sex_params['extract'])
        objects = table.Table(sources)
        # Remove sources with a>>b (usually cosmic rays)
        #objects = objects[objects['a']<objects['b']*5]
    
    # Set WCS or X, Y if necessary
    if wcs is not None:
        if transform=='wcs':
            transform_method = wcs.wcs_pix2world
        elif transform=='all':
            transform_method = wcs.all_pix2world
        elif transform=='sip':
            transform_method = wcs.sip_pix2foc
    if 'ra' not in objects.columns.keys() and wcs is not None:
        objects['ra'], objects['dec'] = transform_method(
            objects['x'], objects['y'], 0)
    if 'x' not in objects.columns.keys():
        if wcs is None:
            raise Exception("You must provide a wcs transformation if "
                "specifying ra and dec")
        objects['x'], objects['y'] = wcs.all_world2pix(
            objects['ra'], objects['dec'], 0)
    
    if windowed:
        logger.info("using kron to get windowed positions")
        objects['xwin'], objects['ywin'] = get_winpos(
            img_data, objects['x'], objects['y'], objects['a'])
        if wcs is not None:
            objects['rawin'], objects['decwin'] = transform_method(
                objects['xwin'], objects['ywin'],0)
    
    # Calculate aperture flux
    if aper_radius is not None:
        objects['aper_radius'] = aper_radius
        flux, flux_err, flag = sep.sum_circle(
            img_data, objects['x'], objects['y'], aper_radius, gain=gain)
        objects['aper_flux'] = flux
        objects['aper_flux_err'] = flux_err
        objects['aper_flag'] = flag
        objects['aper_mag'] = -2.5*np.log10(objects['aper_flux']/exptime)
        if gain is not None:
            objects['aper_mag_err'] = 1.0857*np.sqrt(
                2*np.pi*aper_radius**2*bkg.globalrms**2+
                objects['aper_flux']/gain)/objects['aper_flux']
        else:
            objects['aper_mag_err'] = 1.0857*np.sqrt(
                2*np.pi*aper_radius**2*bkg.globalrms**2)/objects['aper_flux']
        # Get the pipeline flags for the image
        if dqmask_data is not None:
            objects['flags'] = get_img_flags(dqmask_data, 
                objects['x'], objects['y'],
                (2*aper_radius+1, 2*aper_radius+1),
                edge_val)
        # Calculate the positional error
        # See SExtractor Documentation for more on
        # ERRX2 and ERRY2
        # Ignore for now since this is very computationally
        # expensive with little to gain
        if False:
            back_data = bkg.back()
            err_x = np.zeros((len(objects,)), dtype=float)
            err_y = np.zeros((len(objects,)), dtype=float)
            err_xy = np.zeros((len(objects,)), dtype=float)
            for n, src in enumerate(objects):
                X = np.linspace(src['x']-aper_radius, src['x']+aper_radius, 
                    2*aper_radius+1)
                Y = np.linspace(src['y']-aper_radius, src['y']+aper_radius, 
                    2*aper_radius+1)
                X,Y = np.meshgrid(X,Y)
                flux = extract_array(img_data, 
                    (2*aper_radius+1, 2*aper_radius+1), (src['y'], src['x']))
                back = extract_array(back_data,
                    (2*aper_radius+1, 2*aper_radius+1), (src['y'], src['x']))
                if gain is not None and gain > 0:
                    sigma2 = back**2 + flux/gain
                else:
                    sigma2 = back**2
                flux2 = np.sum(flux)**2
                err_x[n] = np.sum(sigma2*(X-src['x'])**2)/flux2
                err_y[n] = np.sum(sigma2*(Y-src['y'])**2)/flux2
                err_xy[n] = np.sum(sigma2*(X-src['x'])*(Y-src['y']))/flux2
            objects['ERRX2'] = err_x
            objects['ERRY2'] = err_y
            objects['ERRXY'] = err_xy
        
    # include an index for each source that might be useful later on in
    # post processing
    objects['src_idx'] = [n for n in range(len(objects))]
    
    return objects, bkg
        bkg = sep.Background(data)  #calculate the background

        #Set a detection threshold for stars to be 1.5x RMS of background
        thresh = 1.5 * bkg.globalrms
        #Find all objects that are above threshold in a frame which is the background subtracted data
        objects = sep.extract(data - bkg.back(), thresh)

        #Table with list of object coords and fluxes
        stars = Table([objects['x'], objects['y'], objects['flux']],
                      names=['x', 'y', 'sepflux'])

        #Do the sky subtraction using the average for the frame
        #data_sub = sky subtracted data
        fluxes, fluxerrs, flag = sep.sum_circle((data - bkg),
                                                stars['x'],
                                                stars['y'],
                                                aper,
                                                err=bkg.globalrms,
                                                gain=gain)

        #Do sky subtraction using annuli
        #fluxes, fluxerrs, flag = sep.sum_circle( data, stars['x'], stars['y'], aper, err=bkg.globalrms, gain=gain, bkgann=(ann_in_pix,ann_out_pix) )

        #Add fluxes and uncertainties to table
        stars.add_column(Column(fluxes, name='flux'))
        stars.add_column(Column(fluxerrs, name='flux_err'))

        #Calculate instrumental magnitudes
        expt = float(obj['Exp_time'])
        mags = [
            -2.5 * math.log10(line / expt) if line > 0 else float('nan')
            for line in fluxes
Ejemplo n.º 43
0
def check_photometry(frames, sf_data, seeing_fwhm, step=0,
                     border=300, extinction=0.0,
                     check_photometry_levels=[0.5, 0.8],
                     check_photometry_actions=['warn', 'warn', 'default'],
                     figure=None):
    # Check photometry of few objects
    weigthmap = 'weights4rms.fits'

    wmap = numpy.ones_like(sf_data[0], dtype='bool')

    # Center of the image
    wmap[border:-border, border:-border] = 0
    # fits.writeto(weigthmap, wmap.astype('uintt8'), overwrite=True)

    basename = 'result_i%0d.fits' % (step)

    data_res = fits.getdata(basename)
    data_res = data_res.byteswap().newbyteorder()
    bkg = sep.Background(data_res)
    data_sub = data_res - bkg

    _logger.info('Runing source extraction tor in %s', basename)
    objects = sep.extract(data_sub, 1.5, err=bkg.globalrms, mask=wmap)

    # if seeing_fwhm is not None:
    #    sex.config['SEEING_FWHM'] = seeing_fwhm * sex.config['PIXEL_SCALE']

    # sex.config['PARAMETERS_LIST'].append('CLASS_STAR')

    # sex.config['CATALOG_NAME'] = 'master-catalogue-i%01d.cat' % step

    LIMIT_AREA = 5000
    idx_small = objects['npix'] < LIMIT_AREA
    objects_small = objects[idx_small]
    NKEEP = 15
    idx_flux = objects_small['flux'].argsort()
    objects_nth = objects_small[idx_flux][-NKEEP:]

    # set of indices of the N first objects
    fluxes = []
    errors = []
    times = []
    airmasses = []

    for idx, frame in enumerate(frames):
        imagename = name_skysub_proc(frame.baselabel, step)

        #sex.config['CATALOG_NAME'] = ('catalogue-%s-i%01d.cat' %
        #                              (frame.baselabel, step))

        # Lauch SExtractor on a FITS file
        # om double image mode
        _logger.info('Runing sextractor in %s', imagename)
        with fits.open(imagename) as hdul:
            header = hdul[0].header
            airmasses.append(header['airmass'])
            times.append(header['tstamp'])
            data_i = hdul[0].data
            data_i = data_i.byteswap().newbyteorder()
            bkg_i = sep.Background(data_i)
            data_sub_i = data_i - bkg_i
        # objects_i = sep.extract(data_sub_i, 1.5, err=bkg_i.globalrms, mask=wmap)
        flux_i, fluxerr_i, flag_i = sep.sum_circle(data_sub_i,
                                                   objects_nth['x'], objects_nth['y'],
                                                   3.0, err=bkg_i.globalrms)


        # Extinction correction
        excor = pow(10, -0.4 * frame.airmass * extinction)

        flux_i = excor * flux_i
        fluxerr_i = excor * fluxerr_i
        fluxes.append(flux_i)
        errors.append(fluxerr_i)

    fluxes_a = numpy.array(fluxes)
    errors_a = numpy.array(errors)
    fluxes_n = fluxes_a / fluxes_a[0]
    errors_a = errors_a / fluxes_a[0]  # sigma
    w = 1.0 / (errors_a) ** 2

    # weighted mean of the flux values
    wdata = numpy.average(fluxes_n, axis=1, weights=w)
    wsigma = 1 / numpy.sqrt(w.sum(axis=1))

    levels = check_photometry_levels
    actions = check_photometry_actions

    x = list(six.moves.range(len(frames)))
    vals, (_, sigma) = check_photometry_categorize(
        x, wdata, levels, tags=actions)
    # n sigma level to plt
    nsig = 3

    if True:
        figure = plt.figure()
        ax = figure.add_subplot(111)

        plot_photometry_check(ax, vals, wsigma, check_photometry_levels, nsig * sigma)
        plt.savefig('figure-relative-flux_i%01d.png' % step)

    for x, _, t in vals:
        try:
            action = _dactions[t]
        except KeyError:
            _logger.warning('Action named %s not recognized, ignoring', t)
            action = default_action
        for p in x:
            action(frames[p])
Ejemplo n.º 44
0
def auto_fit(image_data, xpos, ypos):
    """
    Refit algorithm

    :param

    image_data: fits image data 2D array {Numpy 2D array}

    xpos: centered position of the regions on the x axis {integer}

    ypos: centered position of the region on the y axis {integer}

    ##############################################################

    :return: Dictionary of values
    {
    radii [Ap] -- Aperture radius {float}

    an[0] [InAn] -- Inner annulus radius {float}

    an[1] [OutAn] -- Outer annulus radius {float}

    radii_disagree [disagree] -- The difference between the directly returned radius from SEP and the radius from SEP
                                flux sums {float}
    }
    """
    an_width = 18  # defines annulus width | TODO Make this a free parameter in the auto fit function
    temp_image_data = image_data  # creates non mutable version of array internally
    internal_image_data = temp_image_data.byteswap(True).newbyteorder()  # SEP requires that data be byte swaped
    bkg = sep.Background(internal_image_data)
    thresh = 1.5 * bkg.globalback
    objects = sep.extract(internal_image_data, thresh)
    center_x = internal_image_data.shape[0]/2.0
    center_y = internal_image_data.shape[1]/2.0
    center = [center_x, center_y]
    smallest_dFoc = 1000000000  # big distance so it can only go down
    radii = 21
    radii_sep = 21
    sdev = np.std(internal_image_data)

    count = 0

    # Finds radius of center target from the min and max x and y pixel locations of that target returned from SEP
    for i, j in zip(objects['x'], objects['y']):
        pos = [i, j]

        dFoc = math.sqrt(((pos[0]-center[0])**2) + ((pos[1]-center[1])**2))
        if abs(dFoc) < smallest_dFoc:
            smallest_dFoc = dFoc
            minx = objects['xmin'][count]
            miny = objects['ymin'][count]
            maxx = objects['xmax'][count]
            maxy = objects['ymax'][count]
            radii_sep = abs(math.sqrt(((maxx-minx)**2)+((maxy-miny)**2)))
        else:
            pass
        count += 1
    i = 1

    # Finds optimal inner and outer annulus radii based off SEP flux sums
    while i < 90:
        area = (2*np.pi*((i+an_width)**2))-(2*np.pi*(i**2))
        flux, fluxerr, flag = sep.sum_circann(internal_image_data, prev_x,
                                              prev_y, i, i+an_width)
        metric = ((flux/area) - bkg.globalback)
        if i > 1:
            if metric < smallest_metric:
                smallest_metric = metric
                annulus = [i, i+an_width]
        else:
            smallest_metric = metric
            annulus = [i, i+an_width]
        i += 1

    i = 1

    # Finds radius of center target using SEP flux sums
    while i < 90:
        area = 2*np.pi*(i**2)
        flux, fluxerr, flag = sep.sum_circle(internal_image_data, prev_x,
                                             prev_y, i)
        flux = sum(flux)
        metric = flux/area
        if metric > sdev + bkg.globalback:
            radii = i
        i += 1

    # used more pixels
    an = [math.ceil(x) for x in annulus]

    # sanity checks for size
    if radii > an[0]:
        radii = an[0] - 0.5
    if radii > 30:
        radii = 30
    else:
        pass

    if an[0] > an[1]:
        an[0] = an[1] - 0.1 * an[1]
    radii_disagree = abs(radii-radii_sep)
    return {'Ap': radii, 'InAn': an[0], 'OutAn': an[1], 'disagree': radii_disagree}
Ejemplo n.º 45
0
def im_phot(directory,gain,im_file,aperture):
	""" Perform photometry on the image """

	# Read in fits image file and create array with wcs coordinates
	os.chdir(directory)
	hdulist = fits.open(im_file)
	w = WCS(im_file)
	data = hdulist[0].data
	data[np.isnan(data)] = 0
	hdulist.close()

	# Calculate center point of image (RA, Dec) if not input by user
	targetra, targetdec = w.all_pix2world(len(data[:,0])/2,len(data[0,:])/2,0)

	# Use SEP for background subtraction and source detection
	datasw = data.byteswap().newbyteorder().astype('float64')
	bkg = sep.Background(datasw)
	data_bgs = data - bkg
	data_bgs[data_bgs < 0] = 0
	mean = np.mean(data_bgs)
	median = np.median(data_bgs)
	std = bkg.globalrms
	objects = sep.extract(data_bgs,3,err=bkg.globalrms)
	objra, objdec = w.all_pix2world(objects['x'],objects['y'],0)

	# Find dummy magnitudes using aperture photometry and plot images
	fig, ax = plt.subplots()
	image = plt.imshow(data_bgs,cmap='gray',vmin=(mean-3*std),
		vmax=(mean+3*std),origin='lower')
	sepmag = []
	sepmagerr = []
	ra = []
	dec = []
	xpixel = []
	ypixel = []

	for i in range(len(objects)):
				
		# Perform circular aperture photometry
		flux,fluxerr,flag = sep.sum_circle(data_bgs,objects['x'][i],
			objects['y'][i],aperture,err=std,gain=gain)
		mag = -2.5*np.log10(flux)
		maglimit1 = -2.5*np.log10((flux+fluxerr))
		maglimit2 = -2.5*np.log10((flux-fluxerr))
		magerr1 = np.abs(mag-maglimit1)
		magerr2 = np.abs(mag-maglimit2)
		magerr = (magerr1+magerr2)/2
		
		# Save object properties to arrays
		sepmag.append(mag)
		sepmagerr.append(magerr)
		ra.append(objra[i])
		dec.append(objdec[i])
		xpixel.append(objects['x'][i])
		ypixel.append(objects['y'][i])
		
		# Plot the detections on the image
		out = Circle(xy=(objects['x'][i],objects['y'][i]),radius=aperture)
		out.set_facecolor('none')
		out.set_edgecolor('red')
		ax.add_artist(out)

	plt.savefig(directory+'detections.png')	
	return targetra,targetdec,sepmag,sepmagerr,ra,dec,xpixel,ypixel
Ejemplo n.º 46
0
    def _measure(self, img, sources, mask=None):

        logger.info('measuring source parameters')

        # HACK: issues with numerical precision
        # must have pi/2 <= theta <= npi/2
        sources[np.abs(np.abs(sources['theta']) -
                       np.pi / 2) < 1e-6] = np.pi / 2

        for p in ['x', 'y', 'a', 'b', 'theta']:
            sources = sources[~np.isnan(sources[p])]

        # calculate "AUTO" parameters
        kronrad, krflag = sep.kron_radius(img,
                                          sources['x'],
                                          sources['y'],
                                          sources['a'],
                                          sources['b'],
                                          sources['theta'],
                                          6.0,
                                          mask=mask)

        flux, fluxerr, flag = sep.sum_ellipse(img,
                                              sources['x'],
                                              sources['y'],
                                              sources['a'],
                                              sources['b'],
                                              sources['theta'],
                                              2.5 * kronrad,
                                              subpix=5,
                                              mask=mask)
        flag |= krflag  # combine flags into 'flag'

        sources = sources[~np.isnan(flux)]
        flux = flux[~np.isnan(flux)]
        sources = sources[flux > 0]
        flux = flux[flux > 0]

        mag_auto = self.zpt - 2.5 * np.log10(flux)
        r, flag = sep.flux_radius(img,
                                  sources['x'],
                                  sources['y'],
                                  6. * sources['a'],
                                  0.5,
                                  normflux=flux,
                                  subpix=5,
                                  mask=mask)

        sources['mag_auto'] = mag_auto
        sources['flux_auto'] = flux
        sources['flux_radius'] = r * self.pixscale

        # approximate fwhm
        r_squared = sources['a']**2 + sources['b']**2
        sources['fwhm'] = 2 * np.sqrt(np.log(2) * r_squared) * self.pixscale

        q = sources['b'] / sources['a']
        area = np.pi * q * sources['flux_radius']**2
        sources['mu_ave_auto'] = sources['mag_auto'] + 2.5 * np.log10(2 * area)

        area_arcsec = np.pi * (self.psf_fwhm / 2)**2 * self.pixscale**2
        flux, fluxerr, flag = sep.sum_circle(img,
                                             sources['x'],
                                             sources['y'],
                                             self.psf_fwhm / 2,
                                             subpix=5,
                                             mask=mask)
        flux[flux <= 0] = np.nan
        mu_0 = self.zpt - 2.5 * np.log10(flux / area_arcsec)

        sources['mu_0_aper'] = mu_0

        return sources
Ejemplo n.º 47
0
def sourcephot(catalogue,image,segmap,detection,instrument='MUSE',dxp=0.,dyp=0.,
               noise=[False],zpab=False, kn=2.5, circap=1.0):

    """ 

    Get a source catalogue from findsources and a fits image with ZP
    and compute magnitudes in that filter 

    catalogue -> source cat from findsources
    image     -> fits image with ZP in header
    segmap    -> fits of segmentation map 
    detection -> the detection image, used to compute Kron radius 

    instrument -> if not MUSE, map positions from detection to image

    dxp,dyp    -> shifts in pixel of image to register MUSE and image astrometry   
   
    noise      -> if set to a noise model, use equation noise[0]*noise[1]*npix**noise[2]
                  to compute the error

    zpab  -> if ZPAB (zeropoint AB) not stored in header, must be supplied

    kn   -> factor to be used when scaling Kron apertures [sextractor default 2.5]
  
    circap -> radius in arcsec for aperture photmetry to be used when Kron aperture fails 

    """  

    from astropy.io import fits
    import numpy as np
    import sep
    import matplotlib.pyplot as plt
    from astropy.table import Table
    from astropy import wcs 


    #grab root name 
    rname=((image.split('/')[-1]).split('.fits'))[0]
    print ('Working on {}'.format(rname))

    #open the catalogue/fits 
    cat=fits.open(catalogue)
    img=fits.open(image)
    seg=fits.open(segmap)
    det=fits.open(detection)

    #grab reference wcs from detection image 
    wref=wcs.WCS(det[0].header)
    psref=wref.pixel_scale_matrix[1,1]*3600.
    print ('Reference pixel size {}'.format(psref))


    #if not handling MUSE, special cases for format of data
    if('MUSE' not in instrument):
        #handle instrument cases
        if('LRIS' in instrument):
            #data 
            imgdata=img[1].data
            #place holder for varaince as will use noise model below
            vardata=imgdata*0+1
            vardata=vardata.byteswap(True).newbyteorder()
            #grab wcs image
            wimg=wcs.WCS(img[1].header)
            psimg=wimg.pixel_scale_matrix[1,1]*3600.
            #store the ZP 
            if(zpab):
                img[0].header['ZPAB']=zpab
        else:
            print 'Instrument not supported!!'
            exit()
    else:
        #for muse, keep eveything the same
        imgdata=img[0].data
        vardata=img[1].data
        psimg=psref

    #grab flux and var
    dataflx=np.nan_to_num(imgdata.byteswap(True).newbyteorder())
    datavar=np.nan_to_num(vardata.byteswap(True).newbyteorder())
    #grab detection and seg mask 
    detflx=np.nan_to_num(det[0].data.byteswap(True).newbyteorder())
    #go back to 1d
    segmask=(np.nan_to_num(seg[0].data.byteswap(True).newbyteorder()))[0,:,:]

    #if needed, map the segmap to new image with transformation
    if('MUSE' not in instrument):
        #allocate space for transformed segmentation map
        segmasktrans=np.zeros(dataflx.shape)
        print "Remapping segmentation map to new image..."

        #loop over original segmap and map to trasformed one
        #Just use nearest pixel, and keep only 1 when multiple choices 
        for xx in range(segmask.shape[0]):
            for yy in range(segmask.shape[1]):
                #go to world
                radec=wref.wcs_pix2world([[yy,xx]],0)
                #back to new instrument pixel 
                newxy=wimg.wcs_world2pix(radec,0)
                #apply shift to register WCS
                newxy[0][1]=newxy[0][1]+dyp
                newxy[0][0]=newxy[0][0]+dxp
                segmasktrans[newxy[0][1],newxy[0][0]]=segmask[xx,yy]
                
                #grow buffer as needed by individual instruments
                #This accounts for resampling to finer pixel size
                if('LRIS' in instrument):
                    segmasktrans[newxy[0][1]+1,newxy[0][0]+1]=segmask[xx,yy]
                    segmasktrans[newxy[0][1]-1,newxy[0][0]-1]=segmask[xx,yy]
                    segmasktrans[newxy[0][1]+1,newxy[0][0]-1]=segmask[xx,yy]
                    segmasktrans[newxy[0][1]-1,newxy[0][0]+1]=segmask[xx,yy]
                    segmasktrans[newxy[0][1]+1,newxy[0][0]]=segmask[xx,yy]
                    segmasktrans[newxy[0][1]-1,newxy[0][0]]=segmask[xx,yy]
                    segmasktrans[newxy[0][1],newxy[0][0]-1]=segmask[xx,yy]
                    segmasktrans[newxy[0][1],newxy[0][0]+1]=segmask[xx,yy]
                 
        #dump the transformed segmap for checking 
        hdumain  = fits.PrimaryHDU(segmasktrans,header=img[1].header)
        hdulist = fits.HDUList(hdumain)
        hdulist.writeto("{}_segremap.fits".format(rname),clobber=True)
    else:
        #no transformation needed
        segmasktrans=segmask

    #source to extract
    nsrc=len(cat[1].data)
    print('Extract photometry for {} sources'.format(nsrc))
    phot = Table(names=('ID', 'MAGAP', 'MAGAP_ERR','FXAP', 'FXAP_ERR', 
                        'RAD', 'MAGSEG', 'MAGSEG_ERR', 'FXSEG', 'FXSEG_ERR','ZP'), 
                 dtype=('i4','f4','f4','f4','f4','f4','f4','f4','f4','f4','f4'))
    
   
    #create check aperture mask 
    checkaperture=np.zeros(dataflx.shape)
    print('Computing photometry for objects...')

    #loop over each source
    for idobj in range(nsrc):
        
        #########
        #Find positions etc and transform as appropriate
        #########
                
        #extract MUSE source paramaters 
        x= cat[1].data['x'][idobj]
        y= cat[1].data['y'][idobj]
        a= cat[1].data['a'][idobj]
        b= cat[1].data['b'][idobj]
        theta= cat[1].data['theta'][idobj]

        #compute kron radius on MUSE detection image 
        #Kron rad in units of a,b
        tmpdata=np.copy(detflx)
        tmpmask=np.copy(segmask)
        #mask all other sources to avoid overlaps but keep desired one
        pixels=np.where(tmpmask == idobj+1) 
        tmpmask[pixels]=0

        #compute kron radius [pixel of reference image]
        kronrad, flg = sep.kron_radius(tmpdata,x,y,a,b,theta,6.0,mask=tmpmask)

        #plt.imshow(np.log10(tmpdata+1),origin='low')
        #plt.show()
        #exit()

        #now check if size is sensible in units of MUSE data 
        rmin = 2.0  #MUSE pix 
        use_circle = kronrad * np.sqrt(a*b) < rmin
      
        #use circular aperture of 2" in muse pixel unit
        rcircap = circap/psref
        
        #now use info to compute photometry and apply 
        #spatial transformation if needed
        if('MUSE' not in instrument):
            #map centre of aperture - +1 reference
            #go to world
            radec=wref.wcs_pix2world([[x,y]],1)
            #back to new instrument pixel 
            newxy=wimg.wcs_world2pix(radec,1)
            #apply shift to register WCS
            xphot=newxy[0][0]+dxp
            yphot=newxy[0][1]+dyp
                      
            #scale radii to new pixel size 
            rminphot=rcircap*psref/psimg
            aphot=a*psref/psimg
            bphot=b*psref/psimg
            #Kron radius in units of a,b

        else:
            #for muse, transfer to same units
            xphot=x
            yphot=y
            rminphot=rcircap
            aphot=a
            bphot=b     
            
        #####
        #Compute local sky 
        #####
        skyreg=kn*kronrad*np.sqrt(aphot*bphot)+15
        cutskymask=segmasktrans[yphot-skyreg:yphot+skyreg,xphot-skyreg:xphot+skyreg]
        cutskydata=dataflx[yphot-skyreg:yphot+skyreg,xphot-skyreg:xphot+skyreg]
        skymedian=np.nan_to_num(np.median(cutskydata[np.where(cutskymask < 1.0)]))

        #print skymedian    
        #plt.imshow(cutskymask,origin='low')
        #plt.show()
        #if(idobj > 30):
        #    exit()


        #########
        #Now grab the Kron mag computed using detection image
        #########
   
        #mask all other objects to avoid blending   
        tmpdata=np.copy(dataflx)
        #apply local sky subtraction 
        tmpdata=tmpdata-skymedian
        tmpvar=np.copy(datavar)
        tmpmask=np.copy(segmasktrans)
        pixels=np.where(tmpmask == idobj+1) 
        tmpmask[pixels]=0

        #plt.imshow(tmpmask,origin='low')
        #plt.show()
        #exit()

        #circular aperture
        if(use_circle):        
           
            #flux in circular aperture
            flux_kron, err, flg = sep.sum_circle(tmpdata,xphot,yphot,rminphot,mask=tmpmask)
            #propagate variance
            fluxvar, err, flg = sep.sum_circle(tmpvar,xphot,yphot,rminphot,mask=tmpmask)
            #store Rused in arcsec
            rused=rminphot*psimg

            #update check aperture
            tmpcheckaper=np.zeros(dataflx.shape,dtype=bool)
            sep.mask_ellipse(tmpcheckaper,xphot,yphot,1.,1.,0.,r=rminphot)
            checkaperture=checkaperture+tmpcheckaper*(idobj+1)

        #kron apertures 
        else:
            #kron flux 
            flux_kron, err, flg = sep.sum_ellipse(tmpdata,xphot, yphot, aphot, bphot, theta, kn*kronrad,
                                                  mask=tmpmask)            
            #propagate variance 
            fluxvar, err, flg = sep.sum_ellipse(tmpvar,xphot,yphot, aphot, bphot, theta, kn*kronrad,
                                                mask=tmpmask)
            #translate in radius
            rused=kn*kronrad*psimg*np.sqrt(aphot*bphot)

            #update check aperture
            tmpcheckaper=np.zeros(dataflx.shape,dtype=bool)
            sep.mask_ellipse(tmpcheckaper,xphot,yphot,aphot,bphot,theta,r=kn*kronrad)
            checkaperture=checkaperture+tmpcheckaper*(idobj+1)

        #compute error for aperture
        if(noise[0]):
            #use model 
            appix=np.where(tmpcheckaper > 0)
            errflux_kron=noise[0]*noise[1]*len(appix[0])**noise[2]
        else:
            #propagate variance 
            errflux_kron=np.sqrt(fluxvar)

        #go to mag 
        if(flux_kron > 0):
            mag_aper=-2.5*np.log10(flux_kron)+img[0].header['ZPAB']
            errmg_aper=2.5*np.log10(1.+errflux_kron/flux_kron)
        else:
            mag_aper=99.0
            errmg_aper=99.0
        
        #find out if non detections
        if(errflux_kron >= flux_kron):
            errmg_aper=9
            mag_aper=-2.5*np.log10(2.*errflux_kron)+img[0].header['ZPAB']
          
        #######
        #grab the photometry in the segmentation map 
        #####

        #This may not work well for other instruments 
        #if images are not well aligned
        pixels=np.where(segmasktrans == idobj+1) 
        #add flux in pixels
        tmpdata=np.copy(dataflx)
        #apply sky sub
        tmpdata=tmpdata-skymedian
        flux_seg=np.sum(tmpdata[pixels])
        
        #compute noise from model or adding variance 
        if(noise[0]):
            #from model 
            errfx_seg=noise[0]*noise[1]*len(pixels[0])**noise[2]
        else:
            #add variance in pixels to compute error
            errfx_seg=np.sqrt(np.sum(datavar[pixels]))
  
        #go to mag with calibrations 
        if(flux_seg > 0):
            mag_seg=-2.5*np.log10(flux_seg)+img[0].header['ZPAB']
            errmg_seg=2.5*np.log10(1.+errfx_seg/flux_seg)     
        else:
            mag_seg=99.0
            errmg_seg=99.0
      
        #find out if non detections
        if(errfx_seg >= flux_seg):
            errmg_seg=9
            mag_seg=-2.5*np.log10(2.*errfx_seg)+img[0].header['ZPAB']
        
        #stash by id
        phot.add_row((idobj+1,mag_aper,errmg_aper,flux_kron,errflux_kron,rused,mag_seg,errmg_seg,
                      flux_seg,errfx_seg,img[0].header['ZPAB']))

    #dump the aperture check image 
    hdumain  = fits.PrimaryHDU(checkaperture,header=img[1].header)
    hdulist = fits.HDUList(hdumain)
    hdulist.writeto("{}_aper.fits".format(rname),clobber=True)

    #close
    cat.close()
    img.close()
    seg.close()
    det.close()

    return phot
Ejemplo n.º 48
0
def get_spec_with_err(redshift, exp_time, phase = 0, gal_flamb = lambda x:0., pixel_scale = 0.075, slice_in_pixels = 2, show_plots = 0,
                      dark_current = 0.01, offset_i = 0, offset_j = 0,
                      mdl = 'hsiao', PSFs = None, photon_count_rates = None, output_dir = "output", othername = "",
                      IFURfl = "IFU_R_Content.txt", min_wave = 6000., max_wave = 20000.,
                      zodifl = "aldering.txt", effareafl = "IFU_effective_area_160513.txt", thermalfl = None,
                      source_dir = "input/", read_noise = None, read_noise_floor = 4., aper_rad_fn = None, waves = None, fine_waves = None,
                      restframe_bins = [3000., 4000., 5000., 6000., 8000., 10000., 12000.],
                      obsframe_bins = [7000, 8000., 10200, 12850, 16050, 20000.], TTel = 282., IPC = 0.02, nframe = None, use_R07_noise = False):

    if hasattr(effareafl, '__call__'):
        effective_meters2 = effareafl
    else:
        effective_meters2 = interpfile(source_dir + "/" + effareafl, bounds_error = False)

    if hasattr(zodifl, '__call__'):
        zodi_flamb = zodifl
    else:
        zodi_flamb = interpfile(source_dir + "/" + zodifl)
    #galaxy_flamb = interpfile(source_dir + "/" + "NGC_7591_beta_spec.dat", norm = True)

   
    AB_mags = [0., 20., 25.] # AB mags to generate

    
    
    if read_noise == None:
        read_noise = sqrt(read_noise_floor**2 + 
                          3.* 15.**2. / (exp_time/2.6)
                      )

    # Starting model:
    
    waves, dwaves = resolution_to_wavelengths(source_dir, IFURfl, min_wave, max_wave, waves)

    print "waves ", waves.min(), waves.max(), len(waves)
    if show_plots:
        savetxt("output/wavelengths.txt", zip(arange(1, len(waves + 1)), waves), fmt = ["%i", "%f"])
    if fine_waves == None:
        fine_waves = arange(3000., 22001., 10.)

    try:
        mdl_len = len(mdl)
    except:
        mdl_len = 0

        
    if mdl_len == len(waves):
        f_lamb_SN = mdl
        f_lamb_SN_fine = interp1d(waves, mdl, bounds_error = False, fill_value = 0)(fine_waves)
        sntype = "Unknown"
        mdl = "Unknown"
    elif glob.glob(source_dir + "/" + mdl) == []:
        f_lamb_SN, f_lamb_SN_fine, sntype, NA = get_sncosmo(mdl, redshift, waves, fine_waves, phase)

    else:
        # Okay. Reading from file.

        flambfn = interpfile(source_dir + "/" + mdl)
        mu = None
        sntype = "NA"
        
        f_lamb_SN = flambfn(waves)
        f_lamb_SN_fine = flambfn(fine_waves)
        f_lamb_SN_at_max = flambfn(waves)

    if PSFs == None:
        PSFs = initialize_PSFs(scales = [int(round(pixel_scale/0.005))])

    # For reference: waves, dwaves = resolution_to_wavelengths(source_dir, IFURfl, min_wave, max_wave, waves)
    oneD_PSFs, PSFs = get_1D_pixelized_sliced_PSFs(PSFs, scale = int(round(pixel_scale/0.005)), waves = waves, IPC = IPC,
                                                   slice_in_pixels = slice_in_pixels, offset_i = offset_i, offset_j = offset_j)
    
    #print "f_lamb_SN ", f_lamb_SN

    try:
        plt_root = "%s_z=%.2f_exp=%.1f_ph=%.1f_gal=%.1g_PSF=%s_pxsl=%.3f_slicepix=%i_mdl=%s_type=%s_%s_zodi=%s_offi=%ij=%i_RN=%.1f" % (othername, redshift, exp_time, phase, gal_flamb(15000.), PSFs["PSF_source"],
                                                                                                                           pixel_scale, slice_in_pixels, mdl.split("/")[-1].split(".")[0], sntype, IFURfl.split("/")[-1].split(".")[0], zodifl.split("/")[-1].split(".")[0],
                                                                                                                           offset_i, offset_j, read_noise)
    except:
        plt_root = ""

    if show_plots:
        savetxt(output_dir + "/SN_template_z=%.2f_ph=%.1f_mdl=%s_type=%s.txt" % (redshift, 0., mdl.split("/")[-1].split(".")[0], sntype),
                transpose(array(  [fine_waves, f_lamb_SN_fine]   )), fmt = ["%f", "%g"])
    photons_SN_per_sec = flamb_to_photons_per_wave(f_lamb_SN, effective_meters2(waves), waves, dwaves)

    if photon_count_rates != None:
        # This is a dictionary of wavelength range, photon_count_rate
        for waverange in photon_count_rates:
            inds = where((waves >= waverange[0])*(waves < waverange[1]))
            norm_factor = photon_count_rates[waverange]/sum(photons_SN_per_sec[inds])
            print waverange, "norm_factor", norm_factor
            f_lamb_SN[inds] *= norm_factor
            f_lamb_SN_at_max[inds] *= norm_factor
            photons_SN_per_sec[inds] *= norm_factor

        model = None # Prevent the now incorrect model from being used again

    zodi_photons_per_sec_perarcsec2 = flamb_to_photons_per_wave(10.**(zodi_flamb(waves)), effective_meters2(waves), waves, dwaves)
    galaxy_photons_per_sec_perarcsec2 = flamb_to_photons_per_wave(gal_flamb(waves), effective_meters2(waves), waves, dwaves)


    if thermalfl == None:
        thermal_background_per_pix_per_sec = get_thermal_background_per_pix_per_sec(waves, dwaves, pixel_scale, TTel = TTel,
                                                                                    throughput = effective_meters2(waves)/(pi*1.2**2.))
        
        thermal_flamb_arcsec2 = photons_per_wave_to_flamb(get_thermal_background_per_pix_per_sec(waves = waves, dwaves = 1., pixel_scale = 1.,
                                                                                                 TTel = TTel, throughput = effective_meters2(waves)/(pi*1.2**2.)),
                                                          effective_meters2(waves), waves = waves, dwaves = 1.) # For pixel scale 1, get thermal background
    else:
        thermal_flamb_arcsec2 = interpfile(source_dir + "/" + thermalfl)
        thermal_flamb_arcsec2 = 10.**(thermal_flamb_arcsec2(waves))
        thermal_background_per_pix_per_sec = flamb_to_photons_per_wave(thermal_flamb_arcsec2, effective_meters2(waves), waves, dwaves)*pixel_scale**2.


    AB_mag_per_sec = {}
    for AB_mag in AB_mags:
        AB_mag_per_sec[AB_mag] = flamb_to_photons_per_wave(0.10884806248 * 10**(-0.4*AB_mag) /waves**2., effective_meters2(waves), waves, dwaves)


    
    SN_photon_image = transpose(transpose(oneD_PSFs)*photons_SN_per_sec)*exp_time
    zodi_image = transpose(transpose(zeros(oneD_PSFs.shape, dtype=float64)) + zodi_photons_per_sec_perarcsec2*exp_time*pixel_scale**2.)*slice_in_pixels
    gal_image = transpose(transpose(zeros(oneD_PSFs.shape, dtype=float64)) + galaxy_photons_per_sec_perarcsec2*exp_time*pixel_scale**2.)*slice_in_pixels
    thermal_image = transpose(transpose(zeros(oneD_PSFs.shape, dtype=float64)) + thermal_background_per_pix_per_sec*exp_time)*slice_in_pixels
    dark_current_image = zeros(oneD_PSFs.shape, dtype=float64) + dark_current*exp_time
    AB_mag_images = {}
    for AB_mag in AB_mags:
        AB_mag_images[AB_mag] = transpose(transpose(oneD_PSFs)*AB_mag_per_sec[AB_mag])*exp_time

    total_image = SN_photon_image + zodi_image + gal_image + thermal_image + dark_current_image
    #assert all(total_image < 6.e4), "Saturated pixels found!"

    if not use_R07_noise:
        total_noise = sqrt(total_image + read_noise**2.)
    else:
        total_noise = get_R07_noise(electron_count_rate = total_image/exp_time, t_int = exp_time, nframe = nframe)

    sim_noise = random.normal(size = total_noise.shape)*total_noise
    sim_weight = 1./total_noise**2.


    SN_image_with_noise = SN_photon_image + sim_noise

    
    # Make the cubes. Signal cubes should be scaled by 1/slice_in_pixels to preserve flux. Noise cubes should be scaled by 1/sqrt(sice_in_pixels) to preserve noise.
    SN_with_noise_cube = image_to_cube(SN_image_with_noise, slice_in_pixels)/float(slice_in_pixels)
    total_noise_cube = image_to_cube(total_noise, slice_in_pixels)/sqrt(float(slice_in_pixels))
    SN_photon_cube = image_to_cube(SN_photon_image, slice_in_pixels)/float(slice_in_pixels)
    PSF_cube = image_to_cube(oneD_PSFs, slice_in_pixels)/float(slice_in_pixels)
    
    SN_photon_mean2d = mean(SN_photon_cube, axis = 0)

    sn_sep = sep.extract(SN_photon_mean2d, thresh = 0.001)
    SN_aperture_StoN = []
    SN_aperture_signal = []
    aper_rad_by_wave = []
    aper_EE = []

    for i, wave in enumerate(waves):
        PSFsig = PSFs[(int(round(pixel_scale/0.005)), "sigmaFN")](wave)
        if aper_rad_fn == None:
            aper_rad = 2.5*PSFsig/float(pixel_scale/0.005)
        else:
            aper_rad = aper_rad_fn(wave)/float(pixel_scale)
            
        signal, noise, NA = sep.sum_circle(SN_photon_cube[i], x = sn_sep["x"], y = sn_sep["y"], r = aper_rad, err = total_noise_cube[i], subpix = 0)
        apsum, NA, NA = sep.sum_circle(PSF_cube[i], x = sn_sep["x"], y = sn_sep["y"], r = aper_rad, subpix = 0)
        
        try:
            aper_EE.append(apsum[0])
            SN_aperture_StoN.append(signal[0]/noise[0])
            SN_aperture_signal.append(signal[0])
        except:
            aper_EE.append(-1)
            SN_aperture_StoN.append(-1)
            SN_aperture_signal.append(-1)
        aper_rad_by_wave.append(aper_rad)


    if show_plots:
        save_img(oneD_PSFs, output_dir + "/oneD_PSFs_" + plt_root + ".fits")
        save_img(SN_photon_image, output_dir + "/SN_image_" + plt_root + ".fits")
        save_img(zodi_image, output_dir + "/zodi_image_" + plt_root + ".fits")
        save_img(gal_image, output_dir + "/gal_image_" + plt_root + ".fits")
        save_img(thermal_image, output_dir + "/thermal_image_" + plt_root + ".fits")
        save_img(total_image, output_dir + "/total_image_" + plt_root + ".fits")
        save_img(total_noise, output_dir + "/total_noise_" + plt_root + ".fits")
        save_img(total_image + sim_noise, output_dir + "/image_with_noise_" + plt_root + ".fits")
        save_img(SN_with_noise_cube, output_dir + "/SN_with_noise_" + plt_root + "_cube.fits")
        save_img(SN_photon_mean2d, output_dir + "/SN_image_" + plt_root + "_mean2d.fits")

        plt.plot(waves, PSFs[(int(round(pixel_scale/0.005)), "sigmaFN")](waves))
        plt.savefig(output_dir + "/psfsigma_" + plt_root + ".pdf", bbox_inches = 'tight')
        plt.close()
    



    extract_denom = sum(sim_weight*oneD_PSFs*oneD_PSFs, axis = 1)

    extracted_SN = sum(sim_weight*SN_image_with_noise*oneD_PSFs, axis = 1)/extract_denom
    extracted_noise = 1./sqrt(sum(sim_weight*oneD_PSFs*oneD_PSFs, axis = 1))
    extracted_zodinoise = sqrt(sum(sim_weight*zodi_image*oneD_PSFs, axis = 1)/extract_denom)
    extracted_darknoise = sqrt(sum(sim_weight*dark_current_image*oneD_PSFs, axis = 1)/extract_denom)
    extracted_readnoise = sqrt(sum(sim_weight*read_noise**2. * oneD_PSFs, axis = 1)/extract_denom)
    extracted_thermalnoise = sqrt(sum(sim_weight*thermal_image*oneD_PSFs, axis = 1)/extract_denom)
    extracted_galnoise = sqrt(sum(sim_weight*gal_image*oneD_PSFs, axis = 1)/extract_denom)
    extracted_SNnoise = sqrt(sum(sim_weight*SN_photon_image*oneD_PSFs, axis = 1)/extract_denom)

    eff_noise = 1./sqrt(sum(oneD_PSFs*oneD_PSFs, axis = 1))

    yerr_flamb = photons_per_wave_to_flamb(extracted_noise/exp_time, effective_meters2(waves), waves, dwaves)
    yvalswitherr_flamb = photons_per_wave_to_flamb(extracted_SN/exp_time, effective_meters2(waves), waves, dwaves)
    
    
    signal_to_noises = {"obs_frame_band": {}, # band-integrated
                        "obs_frame": {}, # per resolution element
                        "rest_frame_band_S/N": {},
                        "rest_frame_mean_S/N": {},
                        "thermal_flamb_arcsec-2": thermal_flamb_arcsec2,
                        "plt_root": plt_root,
                        "PSFs": PSFs,
                        "PSF_enclosed_flux": sum(oneD_PSFs, axis = 1),
                        "rest_frame_band_mag": {},
                        "photons/s_obs": {}, "dark_photnoise": {}, "n_reselmnts": {}, "thermal_photnoise": {}, "zodi_photnoise": {}, "read_noise": {}, "SN_photnoise": {},
                        "f_lamb_SN": f_lamb_SN, "extracted_SN": extracted_SN,
                        "obs_waves": waves, "obs_dwaves": dwaves,
                        "spec_S/N": f_lamb_SN/yerr_flamb, "spec_aperture_StoN": array(SN_aperture_StoN), "spec_aperture_signal": array(SN_aperture_signal),
                        "aper_rad_by_wave": aper_rad_by_wave, "aperture_EE": aper_EE,
                        "PSF_wghtd_e_SN": sum(oneD_PSFs*SN_photon_image, axis = 1),
                        "PSF_wghtd_e_allbutdark": sum(oneD_PSFs*(SN_photon_image + zodi_image + gal_image + thermal_image), axis = 1),
                        "phot/s_image": (SN_photon_image + zodi_image + gal_image + thermal_image)/exp_time,
                        "noise_sources": {"total": extracted_noise, "zodi": extracted_zodinoise, "thermal": extracted_thermalnoise,
                                          "dark": extracted_darknoise, "read": extracted_readnoise, "SN": extracted_SNnoise, "galaxy": extracted_galnoise}
                        }



    for i in range(len(obsframe_bins) - 1):
        inds = where((waves >= obsframe_bins[i])*(waves < obsframe_bins[i+1]))
        obskey = (obsframe_bins[i], obsframe_bins[i+1])

        signal_to_noises["n_reselmnts"][obskey] = float(len(inds[0]))*0.5
        signal_to_noises["dark_photnoise"][obskey] = sqrt(dot(extracted_darknoise[inds], extracted_darknoise[inds])) # Quadrature sum
        signal_to_noises["read_noise"][obskey] = sqrt(dot(extracted_readnoise[inds], extracted_readnoise[inds])) # Quadrature sum
        signal_to_noises["zodi_photnoise"][obskey] = sqrt(dot(extracted_zodinoise[inds], extracted_zodinoise[inds])) # Quadrature sum
        signal_to_noises["thermal_photnoise"][obskey] = sqrt(dot(extracted_thermalnoise[inds], extracted_thermalnoise[inds])) # Quadrature sum
        signal_to_noises["SN_photnoise"][obskey] = sqrt(dot(extracted_SNnoise[inds], extracted_SNnoise[inds])) # Quadrature sum

        this_errs = sqrt(sum((yerr_flamb[inds]*dwaves[inds]*waves[inds])**2.))
        this_photons = sum(f_lamb_SN[inds]*dwaves[inds]*waves[inds])
        

        #weighted_photons = sum(these_weights*these_photons)/sum(these_weights)
        #weighted_errs = 1./sqrt(sum(these_weights))

        nresl = 0.5*float(len(inds[0]))

        print "MeanS/N", obsframe_bins[i], obsframe_bins[i+1], this_photons/this_errs, this_photons/this_errs/sqrt(nresl)
        signal_to_noises["obs_frame"][obskey] = this_photons/this_errs/sqrt(nresl)
        signal_to_noises["obs_frame_band"][obskey] = this_photons/this_errs
        signal_to_noises["photons/s_obs"][obskey] = sum(photons_SN_per_sec[inds])


    




    s_to_n_tmp = integrate_spec(waves, dwaves, redshift, restframe_bins, f_lamb_SN, yerr_flamb)
    
    for key in s_to_n_tmp:
        signal_to_noises[key] = s_to_n_tmp[key]            


    if show_plots:

        binwaves = arange(min(waves), max(waves), 150.) #clip(exp(arange(log(min(waves)), log(max(waves)), 1./80.)), min(waves), max(waves))
        f_lamb_SN_bin, f_lamb_SN_binerr = bin_vals_fixed_bins(waves, yvalswitherr_flamb, yerr_flamb, binwaves)
        plt.plot(waves, f_lamb_SN, color = 'k', zorder = 1)
        plt.errorbar(binwaves, f_lamb_SN_bin, yerr = f_lamb_SN_binerr, fmt = '.', label = plt_root, capsize = 0,
                     color = 'b'*(1 - dark_background) + dark_background*'w')
        plt.legend(loc = 'best', fontsize = 8)
        plt.ylabel("$f_{\lambda}$")
        plt.xlabel("Observer-Frame Wavelength (Binned)")
        ylim = list(plt.ylim())
        ylim[0] = 0
        plt.ylim(ylim)
        plt.savefig(output_dir + "/spec_binned_" + plt_root + ".pdf", bbox_inches = 'tight')
        plt.close()


        plt.plot(waves, eff_noise)
        plt.savefig(output_dir + "/eff_noise_" + plt_root + ".pdf")
        plt.close()


        plt.errorbar(waves, yvalswitherr_flamb, yerr = yerr_flamb, fmt = '.', label = plt_root, capsize = 0)
        plt.legend(loc = 'best', fontsize = 8)
        plt.ylabel("$f_{\lambda}$")
        plt.xlabel("Observer-Frame Wavelength")
        plt.ylim(ylim)
        plt.savefig(output_dir + "/spec_" + plt_root + ".pdf", bbox_inches = 'tight')
        plt.close()

        plt.plot(waves, f_lamb_SN/yerr_flamb, '.', color = 'k'*(1 - dark_background) + 'w'*dark_background, label = plt_root)
        plt.ylabel("Signal-to-Noise per Wavelength (half resolution element)")
        plt.xlabel("Observer-Frame Wavelength")
        plt.legend(loc = 'best', fontsize = 8)
        plt.savefig(output_dir + "/spec_StoN_" + plt_root + ".pdf", bbox_inches = 'tight')
        plt.close()


        

        plt.plot(waves, signal_to_noises["spec_aperture_StoN"], '.', color = 'k'*(1 - dark_background) + 'w'*dark_background, label = plt_root)
        plt.ylabel("Aperture Signal-to-Noise per Wavelength (half resolution element)")
        plt.xlabel("Observer-Frame Wavelength")
        plt.legend(loc = 'best', fontsize = 8)
        plt.savefig(output_dir + "/spec_aperture_StoN_" + plt_root + ".pdf", bbox_inches = 'tight')
        plt.close()
        

        savetxt(output_dir + "/sim_spectrum_" + plt_root + ".txt", transpose(array([waves, f_lamb_SN, yerr_flamb])), header = "#waves   template   err", fmt = ["%f", "%g", "%g"])
        savetxt(output_dir + "/sim_noise_" + plt_root + ".txt",  transpose(array([waves] + 
                 [photons_per_wave_to_flamb(item/exp_time, effective_meters2(waves), waves, dwaves) for item in [extracted_zodinoise, extracted_darknoise, extracted_readnoise, extracted_SNnoise]]
                                                                             )), header = "#waves   zodi   dark   read   SN", fmt = ["%f"] + ["%g"]*4)

    return signal_to_noises
Ejemplo n.º 49
0
        e = Ellipse(xy=(objects['x'][i], objects['y'][i]),
                    width=6 * objects['a'][i],
                    height=6 * objects['b'][i],
                    angle=objects['theta'][i] * 180. / np.pi)
        e.set_facecolor('none')
        e.set_edgecolor('red')
        ax.add_artist(e)
        #pl.draw()
        #pl.show()

        # available fields
        #print objects.dtype.names

        flux, fluxerr, flag = sep.sum_circle(data_sub,
                                             objects['x'],
                                             objects['y'],
                                             3.0,
                                             gain=1.0)
        xval = objects['x']
        yval = objects['y']

        #print objects['x'], objects['y']
        for j in range(len(objects)):
            print("object {:d}: flux = {:f} {:f}".format(
                j, flux[j], fluxerr[j], xval[j], yval[j]))

#before loop
#f=file.open('fluxout.txt,'w')

#in loop
#outline="%s %s\n"%(var1,var)
Ejemplo n.º 50
0
if CONDENSED:
    r_list = [5.]
    subpix_list = [(5, "subpixel", "subpix=5"), (0, "exact", "exact")]
else:
    r_list = [3., 5., 10., 20.]
    subpix_list = [(1, "center", "subpix=1"), (5, "subpixel", "subpix=5"),
                   (0, "exact", "exact")]

for r in r_list:
    for subpix, method, label in subpix_list:

        line = "| circles  r={0:2d}  {1:8s} |".format(int(r), label)

        t0 = time.time()
        flux, fluxerr, flag = sep.sum_circle(data, x, y, r, subpix=subpix)
        t1 = time.time()
        t_sep = (t1-t0) * 1.e6 / naper / nloop
        line += " {0:7.2f} us/aper |".format(t_sep)

        if HAVE_PHOTUTILS:
            apertures = photutils.CircularAperture((x, y), r)
            t0 = time.time()
            res = photutils.aperture_photometry(
                data, apertures, method=method, subpixels=subpix)
            t1 = time.time()
            t_pu = (t1-t0) * 1.e6 / naper
            line += " {0:7.2f} us/aper | {1:6.2f} |".format(t_pu, t_pu/t_sep)

        print(line)
Ejemplo n.º 51
0
    def asteroids_phot(self, image_path,
                       multi_object=True,
                       target=None,
                       aper_radius=None,
                       plot_aper_test=False,
                       radius=11,
                       exposure=None,
                       sqlite_file=None,
                       table_name="asteroids",
                       gain=0.57,
                       max_mag=20,
                       comp_snr=50):

        """
        Photometry of asteroids.
        @param image_path: Path of FITS file.
        @type image_path: path
        @param multi_object: Apply photometry for other asteroids in the frame?
        @type multi_object: float
        @param target: Target object that photometry applied. If None,
        will be taken form FITS header.
        @type target: float
        @param radius: Aperture radius
        @type radius: float
        @param exposure: Exposure keyword of phot images.
        @type exposure: float
        @param plot_aper_test: Plot aperture test graph
        @type plot_aper_test: bloean
        @param exportdb: Export results SQLite3 database
        @type exportdb: path
        @param db_table: SQLite3 database table
        @type db_table: path
        @param gain: gain value for the image expressed in electrons per adu.
        @type gain: float
        @param max_mag: Faintest object limit.
        @type max_mag: float
        @param comp_snr: Minimum SNR of detected comparison star.
        @type comp_snr: float
        @return: bolean and file
        """
        
        if ".fit" in os.path.basename(image_path):
            fitslist = sorted(glob.glob(image_path))
            if fitslist == 0:
                print('No image FITS found in the {0}'.format(image_path))
                raise SystemExit
        else:
            fitslist = sorted(glob.glob(image_path + '/*.fit?'))
            if fitslist == 0:
                print('No image FITS found in the {0}'.format(image_path))
                raise SystemExit

        # aper_trigger check count
        aper_count = 0
        
        for id, fitsfile in enumerate(fitslist):
            if fitsfile:
                hdu = fits.open(fitsfile)[0]
            else:
                print("FITS image has not been provided by the user!")
                raise SystemExit

            sb = Query()
            ac = AstCalc()
            to = TimeOps()
            fo = FitsOps(fitsfile)
            header = hdu.header
            w = WCS(header)

            naxis1 = fo.get_header('naxis1')
            naxis2 = fo.get_header('naxis2')
            odate = fo.get_header('date-obs')
            t1 = Time("{0}".format(odate),
                      out_subfmt="date")
            dt = TimeDelta(12 * 3600, format='sec')
            onight = t1 - dt
            exptime = fo.get_header('exptime')

            if exptime is not None and exposure is not None:
                if float(exptime) != exposure:
                    continue

            if aper_count == 0:
                aper_trigger = id
                aper_count += 1

            if target is None:
                objct = fo.get_header('object')
            else:
                objct = str(target)
            filter = fo.get_header('filter').replace(" ", "_")
            # t1 = Time(odate.replace('T', ' '))
            # exptime = fo.get_header('exptime')
            # dt = TimeDelta(exptime / 2.0, format='sec')
            # odate_middle = t1 + dt
            # jd = to.date2jd(odate_middle.value)
            jd = to.date2jd(odate)
            ra_dec = ac.center_finder(fitsfile, wcs_ref=True)

            image = f2n.fromfits(fitsfile, verbose=False)
            image.setzscale('auto', 'auto')
            image.makepilimage('log', negative=False)

            request = sb.find_skybot_objects(odate,
                                             ra_dec[0].degree,
                                             ra_dec[1].degree,
                                             radius=radius)

            if request[0]:
                if multi_object:
                    asteroids = Table(np.sort(request[1][::-1],
                                              order=['m_v']))
                else:
                    asteroids = Table(np.sort(request[1],
                                              order=['num']))
                    mask = asteroids['num'] == str(objct).upper()
                    asteroids = asteroids[mask]
            elif request[0] is False:
                print(request[1])
                raise SystemExit

            data = hdu.data.astype(float)

            bkg = sep.Background(data)
            data_sub = data - bkg

            for i in range(len(asteroids)):
                if float(asteroids['m_v'][i]) <= max_mag:
                    c = coordinates.SkyCoord('{0} {1}'.format(
                        asteroids['ra(h)'][i],
                        asteroids['dec(deg)'][i]),
                                             unit=(u.hourangle, u.deg),
                                             frame='icrs')

                    # asteroid's X and Y coor
                    a_x, a_y = w.wcs_world2pix(c.ra.degree, c.dec.degree, 1)

                    if naxis1 < a_x or naxis2 < a_y or a_x < 0 or a_y < 0:
                        continue

                    # phot asteroids
                    flux, fluxerr, flag = sep.sum_circle(
                        data_sub,
                        a_x,
                        a_y,
                        6,
                        err=bkg.globalrms,
                        gain=gain)

                    if flux == 0.0 or fluxerr == 0.0:
                        print("Bad asteroid selected (out of frame!)!")
                        raise SystemExit

                    if id == aper_trigger:
                        snr = []
                        for aper in range(30):
                            # phot asteroids
                            flux_test, fluxerr_test, flag_test = sep.sum_circle(
                                data_sub,
                                a_x,
                                a_y,
                                aper,
                                err=bkg.globalrms,
                                gain=gain)

                            snr.append([aper, (flux_test/fluxerr_test)])

                        npsnr = np.array(snr)
                        maxtab, mintab = peakdet(npsnr[:, 1], 0.1)
                        try:
                            aper_radius = maxtab[:, 0][0]
                            print("Aperture calculated: {0} px".format(
                                aper_radius))
                        except IndexError:
                            continue
                        
                        if plot_aper_test:
                            plt.title(asteroids['num'][i])
                            plt.xlabel('Aperture (px)')
                            plt.ylabel('SNR')
                            
                            plt.scatter(npsnr[:, 0],
                                        npsnr[:, 1])
                            plt.scatter(maxtab[:, 0], maxtab[:, 1],
                                        color='red')
                            plt.scatter(mintab[:, 0], mintab[:, 1],
                                        color='yellow')
                            plt.show()

                    magt_i = ac.flux2mag(flux, float(exptime))
                    magt_i_err = fluxerr / flux * 2.5 / math.log(10)

                    min_mag_ast = float(asteroids['m_v'][i]) - 2

                    label = '{0}'.format(asteroids['num'][i])
                    image.drawcircle(a_x, a_y, r=aper_radius,
                                     colour=(255, 0, 0), label=label)

                    if i == 0 and id == aper_trigger:
                        comptable = sb.query_color(c.ra.degree,
                                                   c.dec.degree,
                                                   5.0 / 60.0,
                                                   min_mag=min_mag_ast,
                                                   max_mag=19.5)

                        s_comptable = sb.sort_stars(comptable, min_mag_ast)

                        if len(s_comptable) == 0:
                            continue

                    phot_res_list = []

                    # phot comp. stars
                    for j in range(len(s_comptable)):
                        # star's X and Y coor
                        s_x, s_y = w.wcs_world2pix(s_comptable['RAJ2000'][j],
                                                   s_comptable['DEJ2000'][j],
                                                   1)

                        if naxis1 < s_x or naxis2 < s_y or s_x < 0 or s_y < 0:
                            continue

                        # print('Circle', s_x, s_y, 10)

                        flux, fluxerr, flag = sep.sum_circle(
                            data_sub,
                            s_x,
                            s_y,
                            aper_radius,
                            err=bkg.globalrms,
                            gain=gain)

                        if flux == 0.0 or fluxerr == 0.0:
                            print("Bad star selected!")
                            raise SystemExit

                        if (flux / fluxerr) <= comp_snr:
                            continue
                    
                        magc_i = ac.flux2mag(flux, float(exptime))
                        magc_i_err = fluxerr / flux * 2.5 / math.log(10)

                        try:
                            magt = (float(magt_i) -
                                    float(magc_i)) + s_comptable['Rmag'][j]
                            magt_err = math.sqrt(
                                math.pow(float(magt_i_err), 2) +
                                math.pow(float(magc_i_err), 2))
                        except:
                            continue

                        label = '{0}'.format(s_comptable['NOMAD1'][j])
                        image.drawcircle(s_x, s_y, r=aper_radius,
                                         colour=(0, 255, 0), label=label)

                        phot_res_list.append([asteroids['num'][i],
                                              jd,
                                              onight.iso,
                                              float(magt_i),
                                              float(magt_i_err),
                                              float(magc_i),
                                              float(magc_i_err),
                                              float(magt),
                                              float(magt_err),
                                              asteroids['m_v'][i],
                                              s_comptable['NOMAD1'][j],
                                              s_comptable['Rmag'][j]])

                    np_phot_res = np.array(phot_res_list)

                    if len(np_phot_res) == 0:
                        continue

                    # magnitude average
                    magt_avr = np.average(np_phot_res[:, 7].astype(float),
                                          weights=np_phot_res[:, 8].astype(
                                               float))

                    # magt_std calc.
                    magt_std = np.std(np_phot_res[:, 7].astype(float))
                    
                    np_magt_avr_std = [[magt_avr,
                                        magt_std,
                                        filter,
                                        exptime] for i in range(
                        len(np_phot_res))]
                    
                    k = np.array(np_magt_avr_std).reshape(
                        len(np_magt_avr_std), 4)

                    # numpy array with magt_avr
                    np_phot_res_avg_std = np.concatenate(
                        (np_phot_res,
                         k),
                        axis=1)

                    phot_res_table = Table(np_phot_res_avg_std,
                                           names=('ast_num',
                                                  'jd',
                                                  'onight',
                                                  'magt_i',
                                                  'magt_i_err',
                                                  'magc_i',
                                                  'magc_i_err',
                                                  'magt',
                                                  'magt_err',
                                                  'ast_mag_cat',
                                                  'nomad1',
                                                  'star_Rmag',
                                                  'magt_avr',
                                                  'magt_std',
                                                  'filter',
                                                  'exposure'),
                                           dtype=('U10',
                                                  'S25',
                                                  'U10',
                                                  'f8',
                                                  'f8',
                                                  'f8',
                                                  'f8',
                                                  'f8',
                                                  'f8',
                                                  'f8',
                                                  'U20',
                                                  'f8',
                                                  'f8',
                                                  'f8',
                                                  'U20',
                                                  'f8'))

                    phot_res_table['magt_i'].format = '.3f'
                    phot_res_table['magt_i_err'].format = '.3f'
                    phot_res_table['magc_i'].format = '.3f'
                    phot_res_table['magc_i_err'].format = '.3f'
                    phot_res_table['magt'].format = '.3f'
                    phot_res_table['magt_err'].format = '.3f'
                    phot_res_table['magt_avr'].format = '.3f'
                    phot_res_table['magt_std'].format = '.3f'

                    with open('{0}/{1}.txt'.format(
                            os.getcwd(),
                            asteroids['num'][i]), 'a') as f_handle:
                        f_handle.seek(0, os.SEEK_END)

                        if not os.path.isfile(str(f_handle)):
                            phot_res_table.write(
                                f_handle,
                                format='ascii.commented_header')
                        else:
                            phot_res_table.write(f_handle,
                                                 format='ascii.no_header')
                        if sqlite_file is not None:
                            self.table_to_database(phot_res_table,
                                                   sqlite_file=sqlite_file,
                                                   table_name=table_name)


            # Test
            time.sleep(0.2)
            self.update_progress(
                "Photometry is done for: {0}".format(fitsfile),
                id / len(fitslist))
            image.writetitle(os.path.basename(fitsfile))

            fitshead, fitsextension = os.path.splitext(fitsfile)
            image.writeinfo([odate], colour=(255, 100, 0))
            image.tonet('{0}.png'.format(fitshead))
        self.update_progress("Photometry done!", 1)
        return(True)