Пример #1
1
def do_phot(image,position,radius = 5, r_in=15., r_out=20.):
    
    aperture = CircularAperture(position,r=radius)

    bkg_aperture = CircularAnnulus(position,r_in=r_in,r_out=r_out)

    # perform the photometry; the default method is 'exact'
    phot = aperture_photometry(image, aperture)
    bkg = aperture_photometry(image, bkg_aperture)

    # calculate the mean background level (per pixel) in the annuli
    bkg_mean = bkg['aperture_sum'] / bkg_aperture.area()
    bkg_sum = bkg_mean * aperture.area()
   
    #look at ipython notebook; his may need editing; 'phot' in second line below may need brackets with 'flux_sum' inside
    #phot['bkg_sum'] = bkg_sum
    #phot['flux_sum'] = phot['flux'] - bkg_sum
    
    #these two lines from ipython notebook
    flux_bkgsub = phot['aperture_sum'] - bkg_sum
    phot['aperture_sum_bkgsub'] = flux_bkgsub
    
    return phot
Пример #2
0
def plot_light_curves(diff_cube, unique_extracted_objects):
    
    frame_data = [i for i in range(len(diff_cube))]
    colors = [(random.uniform(0.5, 1),random.uniform(0.5, 1),random.uniform(0.5,1)) for i in range(len(unique_extracted_objects))]


    plt.figure(figsize=(20,10))


    for i, extracted_obj in enumerate(unique_extracted_objects):
        ap_data=[]
        plt.figure(i, figsize=(10, 12))
        for frame in diff_cube:
            diff_cube_test = frame.copy()
            flux, fluxerr, flag = sep.sum_ellipse(diff_cube_test, x=extracted_obj[0], y=extracted_obj[1], a=extracted_obj[2], b=extracted_obj[3], theta=extracted_obj[4])
            #flux /= diff_cube_test.sum()
            ap_data.append(flux)

  
        plt.ylim((0,800))
        plt.plot(frame_data, ap_data, '-o', color=colors[i],linewidth=5.0, )

    plt.show()

    plt.figure(2, figsize=(10, 12))

    plt.imshow(diff_cube[1], cmap='gray', vmin=1, vmax=12)
    plt.colorbar()

    for i, extracted_obj in enumerate(unique_extracted_objects):
        positions = (extracted_obj[0], extracted_obj[1])
        apertures = CircularAperture(positions, r=5.)
        apertures.plot(color=colors[i], linewidth=10.0, lw=2.5, alpha=0.5)
Пример #3
0
    def autocorr(self, ell_mask_scale=2, aperture_radius=5, annulus_width=4):
        # Compute 2D autocorrelation function

        try:
            masked_image = self.masked_image.copy() 
            if ell_mask_scale > 0:
                masked_image.mask |=  ~self.elliptical_mask(ell_mask_scale)
            masked_image = masked_image.filled(0.0)

            fft_imgae = np.fft.fft2(masked_image)
            acorr_image = np.fft.ifft2(fft_imgae * np.conjugate(fft_imgae)).real
            acorr_image = np.fft.ifftshift(acorr_image)

            ny, nx = masked_image.shape
            yy, xx = np.mgrid[:ny, :nx]

            circ = CircularAperture([nx // 2, ny // 2], r=aperture_radius)
            ann = CircularAnnulus([nx // 2, ny // 2],
                                  r_in=aperture_radius,
                                  r_out=aperture_radius + annulus_width)

            ann_mean = aperture_photometry(
                acorr_image, ann)['aperture_sum'][0] / ann.area()
            circ_mean = aperture_photometry(
                acorr_image, circ)['aperture_sum'][0] / circ.area()
        except:
            acorr_image = np.nan
            circ_mean = np.nan
            ann_mean = np.nan

        return acorr_image, circ_mean, ann_mean
Пример #4
0
def measure_one_annular_bg(image, center, innerRad, outerRad, metric, apMethod='exact'):
    """Class methods are similar to regular functions.

    Note:
        Do not include the `self` parameter in the ``Args`` section.

    Args:
        param1: The first parameter.
        param2: The second parameter.

    Returns:
        True if successful, False otherwise.

    """
    
    innerAperture   = CircularAperture(center, innerRad)
    outerAperture   = CircularAperture(center, outerRad)
    
    inner_aper_mask = innerAperture.to_mask(method=apMethod)[0]
    inner_aper_mask = inner_aper_mask.to_image(image.shape).astype(bool)
    
    outer_aper_mask = outerAperture.to_mask(method=apMethod)[0]
    outer_aper_mask = outer_aper_mask.to_image(image.shape).astype(bool)
    
    backgroundMask = (~inner_aper_mask)*outer_aper_mask
    
    return metric(image[backgroundMask])
Пример #5
0
def measure_one_median_bg(image, center, aperRad, metric, nSig, apMethod='exact'):
    """Class methods are similar to regular functions.

    Note:
        Do not include the `self` parameter in the ``Args`` section.

    Args:
        param1: The first parameter.
        param2: The second parameter.

    Returns:
        True if successful, False otherwise.

    """
    
    aperture       = CircularAperture(center, aperRad)
    aperture       = aperture.to_mask(method=apMethod)[0]
    aperture       = aperture.to_image(image.shape).astype(bool)
    backgroundMask = ~aperture
    
    medFrame  = median(image[backgroundMask])
    madFrame  = std(image[backgroundMask])
    
    medianMask= abs(image - medFrame) < nSig*madFrame
    
    maskComb  = medianMask*backgroundMask
    
    return median(image[maskComb])
Пример #6
0
def plot_peaks(box, x_peaks, y_peaks, radius=None, title=None, vmin=None, vmax=None):

    """
    This function plots the data with peaks marked ...
    :param box:
    :param x_peaks:
    :param y_peaks:
    :return:
    """

    # Determine the maximum value in the box and the minium value for plotting
    if vmin is None: vmin = max(np.nanmin(box), 0.)
    if vmax is None: vmax = 0.5 * (np.nanmax(box) + vmin)

    # Set the normalization
    norm = ImageNormalize(stretch=SqrtStretch())

    # Make the plot
    plt.figure(figsize=(8,2.5))
    plt.imshow(box, origin='lower', norm=norm, interpolation='nearest', vmin=vmin, vmax=vmax, cmap="viridis")

    if radius is None: plt.plot(x_peaks, y_peaks, ls='none', color='white', marker='+', ms=40, lw=10, mew=4)
    else:

        positions = (x_peaks, y_peaks)
        apertures = CircularAperture(positions, r=radius)
        apertures.plot(color='green', lw=1.5, alpha=0.5)

    plt.xlim(0, box.shape[1]-1)
    plt.ylim(0, box.shape[0]-1)

    if title is not None: plt.title(title)

    plt.show()
Пример #7
0
def plot(sources, data, path):
    positions = (sources['xcentroid'], sources['ycentroid'])
    apertures = CircularAperture(positions, r=4.)
    norm = ImageNormalize(stretch=SqrtStretch())
    plt.imshow(data, cmap='Greys', origin='lower', norm=norm)
    apertures.plot(color='blue', lw=1.5, alpha=0.5)

    plt.savefig(path)
Пример #8
0
def plot_light_curves(diff_cube, unique_extracted_objects):
    # The diff_cube has to be byte swapped BEFORE being sent as parameter (diff_cube.byteswap(True).newbyteorder()), otherwise the method is not goint to work. Unique_extracted_objects only work for elliptic-shapped apertures

    # We get the number of frames from the cube
    frame_data = [i for i in range(len(diff_cube))]
    # Random colours array
    colours = [
        (random.uniform(0.5, 1), random.uniform(0.5, 1), random.uniform(0.5, 1))
        for i in range(len(unique_extracted_objects))
    ]

    maxVal = 0
    minVal = float("inf")

    plt.figure(2, figsize=(10, 12))

    # Bonus: Show the image with the sources on the same colour than the plots.
    if len(diff_cube) == 1:
        plt.imshow(diff_cube[0], cmap="gray", vmin=1, vmax=12)
    else:
        plt.imshow(diff_cube[1], cmap="gray", vmin=1, vmax=12)
    plt.colorbar()
    for i, extracted_obj in enumerate(unique_extracted_objects):
        positions = (extracted_obj[0], extracted_obj[1])
        apertures = CircularAperture(positions, r=5.0)
        apertures.plot(color=colours[i], linewidth=10.0, lw=2.5, alpha=0.5)
    # For every object we are going to calculate the aperture
    plt.figure(1, figsize=(20, 12))
    for i, extracted_obj in enumerate(unique_extracted_objects):
        ap_data = []
        # The standard size of each independent figure
        # plt.figure(i, figsize=(10, 12))
        # For every frame...
        for frame in diff_cube:
            diff_cube_test = frame.copy()
            # The parameters passed in order are x, y, a, b and theta
            flux, fluxerr, flag = sep.sum_ellipse(
                diff_cube_test,
                x=extracted_obj[0],
                y=extracted_obj[1],
                a=extracted_obj[2],
                b=extracted_obj[3],
                theta=extracted_obj[4],
            )

            ap_data.append(flux)
        maxVal = np.maximum(maxVal, np.max(ap_data))
        minVal = np.minimum(minVal, np.min(ap_data))
        # Hard-coded value!!! ALERT!!!

        # Plot every curve as a dotted line with the points visible
        plt.plot(frame_data, ap_data, "-o", color=colours[i], linewidth=5.0)
    plt.ylim((minVal * 1.1, maxVal * 0.9))
    # Voila
    plt.show()
Пример #9
0
    def show_image(self,sourceRA,sourceDEC,refRA=None,refDEC=None, ref2RA=None, ref2DEC=None):
        print('RED circle is the cepheid. WHITE circle is the reference object(s).')
        print('Add more reference stars by defining ref1aper = blahblahbelow, and ref1aper.plot(etc...)')
        #aper_annulus = CircularAnnulus((sourceRA, sourceDEC), r_in=6., r_out = 8.)

        apertures = CircularAperture((self.worldcoord.wcs_world2pix(sourceRA,sourceDEC,0)), r=10)
       
        #ref2aper  = CircularAperture((worldcoord.wcs_world2pix(ref2RA,ref2DEC,0)),     r=7)
        #ref3aper  = CircularAperture((worldcoord.wcs_world2pix(ref3RA,ref3DEC,0)),     r=3.5)
        #darkaper  = CircularAperture((worldcoord.wcs_world2pix(darkRA,darkDEC,0)),     r=3.5)
        
        
        fig = plt.figure()
        fig.add_subplot(111, projection = self.worldcoord)
        plt.imshow(self.stardata,origin='lower', cmap='jet')
        apertures.plot(color='red',lw=5, alpha=1)
        
        if refRA != None:
           ref1aper  = CircularAperture((self.worldcoord.wcs_world2pix(refRA,refDEC,0)),     r=10)
           ref1aper.plot(color='red', lw=5, alpha=1)
        #apertures2.plot(color='white',lw=2.0,alpha=0.5)
        #largeaperture.plot(color='red',  lw=1.5, alpha=0.5)
        if ref2RA != None:
           ref2aper  = CircularAperture((self.worldcoord.wcs_world2pix(ref2RA,ref2DEC,0)),     r=10)
           ref2aper.plot(color='red', lw=5, alpha=1)
Пример #10
0
def starbright(fnstar,fnflat,istar,axs,fg):
    #%% load data
    data = meanstack(fnstar,100)[0]
    #%% flat field
    flatnorm = readflat(fnflat,fnstar)
    data = (data/flatnorm).round().astype(data.dtype)
    #%% background
    mean, median, std = sigma_clipped_stats(data, sigma=3.0)

    rfact=data.shape[0]//40
    cfact=data.shape[1]//40
    bg = Background(data,(rfact,cfact),interp_order=1, sigclip_sigma=3)
# http://docs.astropy.org/en/stable/units/#module-astropy.units
    #dataphot = (data - bg.background)*u.ph/(1e-4*u.m**2 * u.s * u.sr)
 #   data = (data-0.97*data.min()/bg.background.min()*bg.background) * u.ph/(u.cm**2 * u.s * u.sr)
    data = data* u.ph/(u.cm**2 * u.s * u.sr)
    #%% source extraction
    sources = daofind(data, fwhm=3.0, threshold=5*std)
    #%% star identification and quantification
    XY = column_stack((sources['xcentroid'], sources['ycentroid']))
    apertures = CircularAperture(XY, r=4.)
    norm = ImageNormalize(stretch=SqrtStretch())

    flux = apertures.do_photometry(data,effective_gain=camgain)[0]
#%% plots
    fg.suptitle('{}'.format(fnflat.parent),fontsize='x-large')

    hi = axs[-3].imshow(flatnorm,interpolation='none',origin='lower')
    fg.colorbar(hi,ax=axs[-3])
    axs[-3].set_title('flatfield {}'.format(fnflat.name))

    hi = axs[-2].imshow(bg.background,interpolation='none',origin='lower')
    fg.colorbar(hi,ax=axs[-2])
    axs[-2].set_title('background {}'.format(fnstar.name))

    hi = axs[-1].imshow(data.value,
                    cmap='Greys', origin='lower', norm=norm,interpolation='none')
    fg.colorbar(hi,ax=axs[-1])
    for i,xy in enumerate(XY):
        axs[-1].text(xy[0],xy[1], str(i),ha='center',va='center',fontsize=16,color='w')
    apertures.plot(ax=axs[-1], color='blue', lw=1.5, alpha=0.5)
    axs[-1].set_title('star {}'.format(fnstar.name))

    return flux[istar]
Пример #11
0
 def phot(self, image, objpos, aper):
     """
     Aperture photometry using Astropy's photutils.
     
     Parameters
     ----------
     image : numpy array
         2D image array
         
     objpos : list of tuple
         Object poistions as list of tuples
         
     aper : float
         Aperture radius in pixels
      
     Returns 
     -------
     phot_table : astropy table
          Output table with stellar photometry   
     """
     try:
         from astropy.table import hstack
         from photutils import aperture_photometry, CircularAnnulus, CircularAperture
     except ImportError:
         pass
 
     apertures = CircularAperture(objpos, r = aper) 
     annulus_apertures = CircularAnnulus(objpos, r_in = self.inner_radius, r_out = self.outer_radius)
     
     rawflux_table = aperture_photometry(image, apertures = apertures, method = self.method)
     bkgflux_table = aperture_photometry(image, apertures = annulus_apertures, method = self.method)
     phot_table = hstack([rawflux_table, bkgflux_table], table_names = ["raw", "bkg"])
     
     bkg = phot_table["aperture_sum_bkg"] / annulus_apertures.area()
     phot_table["msky"] = bkg
     phot_table["area"] = apertures.area()
     phot_table["nsky"] = annulus_apertures.area()
             
     bkg_sum = bkg * apertures.area()
     final_sum = phot_table["aperture_sum_raw"] - bkg_sum
     phot_table["flux"] = final_sum
     
     return phot_table
Пример #12
0
def process_file(inpath, file_name, t_constant, sigma, fwhm, r, kernel_size, outpath, plot):
    print "Processing " + file_name
    hdulist = fits.open(inpath + file_name)
    image = hdulist[0].data

    if isinstance(sigma, list):
        threshold = calc_sigma(image, sigma[0], sigma[1]) * t_constant
    else:
        threshold = t_constant*sigma

    median_out = signal.medfilt(image,kernel_size)
    median_sub = np.subtract(image,median_out)
    sources = daofind(median_sub, threshold, fwhm)

    sources_2 = np.array(sources["id", "xcentroid", "ycentroid", "sharpness", "roundness1", "roundness2", "npix", "sky", "peak", "flux", "mag"])
    print_line= (file_name+","+str(sources_2))
    base_name = os.path.splitext(file_name)[0]
    file = open(outpath + base_name + ".out", "a")
    file.write(print_line)
    file.close()

    positions = (sources['xcentroid'], sources['ycentroid'])
#    print positions
    apertures = CircularAperture(positions, r)
    phot_table = aperture_photometry(median_sub, apertures)
    phot_table_2 = np.array(phot_table["aperture_sum", "xcenter", "ycenter"])
    print_line= (","+str(phot_table_2)+"\n")
    file = open(outpath + base_name + ".out", "a")
    file.write(print_line)
    file.write("\n")
    file.close()

    hdulist[0].data = median_sub
    file = open(outpath + base_name + ".fits", "w")
    hdulist.writeto(file)
    file.close()

    if plot:
        median_sub[median_sub<=0]=0.0001
        plt.imshow(median_sub, cmap='gray', origin='lower')
        apertures.plot(color='blue', lw=1.5, alpha=0.5)
        plt.show()
Пример #13
0
def find_stars(image, plot = False, fwhm = 20.0, threshold=3.):

    from astropy.stats import sigma_clipped_stats
    mean, median, std = sigma_clipped_stats(image, sigma=3.0)
    from photutils import daofind
    sources = daofind(image - median, fwhm=fwhm, threshold=threshold*std)
    
   # stars already found accurately, vet_sources will be implemented when working properly
   # vet_sources(10.0,10.0)
        
    if plot == True:
       # from astropy.visualization import SqrtStretch
       # from astropy.visualization.mpl_normalize import ImageNormalize
        positions = (sources['xcentroid'], sources['ycentroid'])
        apertures = CircularAperture(positions, r=4.)
        #norm = ImageNormalize(stretch=SqrtStretch())
        #plt.imshow(image, cmap='Greys', origin='lower', norm=norm)
        qi.display_image(image)
        apertures.plot(color='blue', lw=1.5, alpha=0.5)
        
    return sources
Пример #14
0
def calc_bkg_rms(ap, image, src_ap_area, rpsrc, mask=None, min_ap=6):

    if isinstance(ap, CircularAnnulus):
        aback = bback =  ap.r_in + rpsrc
        ap_theta = 0
    elif isinstance(ap, EllipticalAnnulus):
        aback = ap.a_in + rpsrc
        bback = ap.b_in + rpsrc
        ap_theta = ap.theta
    
    ecirc = ellip_circumference(aback, bback)
    diam = 2*rpsrc
    
    # Estimate the number of background apertures that can fit around the source
    # aperture.
    naps = np.int(np.round(ecirc/diam))
    
    # Use a minimum of 6 apertures
    naps = np.max([naps, min_ap])
    #naps = 6
    
    theta_back = np.linspace(0, 2*np.pi, naps, endpoint=False)
    
    # Get the x, y positions of the background apertures
    x, y = ellip_point(ap.positions[0], aback, bback, ap_theta, theta_back)

    # Create the background apertures and calculate flux within each
    bkg_aps = CircularAperture(np.vstack([x,y]).T, rpsrc)
    flux_bkg = aperture_photometry(image, bkg_aps, mask=mask)
    flux_bkg = flux_bkg['aperture_sum']
    flux_bkg_adj = flux_bkg/bkg_aps.area() * src_ap_area
 	
	# Use sigma-clipping to determine the RMS of the background
	# Scale to the area of the source aperture
    me, md, sd = sigma_clipped_stats(flux_bkg_adj, sigma=3)


    bkg_rms = sd
    
    return bkg_rms, bkg_aps
Пример #15
0
    def plot(self,scale='log'):
        apertures = CircularAperture([self.locx,self.locy], r=self.r)

        z = self.copy()
        z -= np.nanmedian(z)
        if scale=='log':
            z = np.log10(self)
            z = ma.masked_invalid(z)
            z.mask = z.mask | (z < 0)
            z.fill_value = 0
            z = z.filled()

        imshow2(z)

        if self.pixels is not None:
            for i,pos in enumerate(self.pixels):
                r,c = pos
                plt.text(c,r,i,va='center',ha='center',color='Orange')

        apertures.plot(color='Lime',lw=1.5,alpha=0.5)
        plt.xlabel('Column (pixels)')
        plt.ylabel('Row (pixels)')
Пример #16
0
def measure_one_circle_bg(image, center, aperRad, metric, apMethod='exact'):
    """Class methods are similar to regular functions.

    Note:
        Do not include the `self` parameter in the ``Args`` section.

    Args:
        param1: The first parameter.
        param2: The second parameter.

    Returns:
        True if successful, False otherwise.

    """
    
    aperture  = CircularAperture(center, aperRad)
    aper_mask = aperture.to_mask(method=apMethod)[0]    # list of ApertureMask objects (one for each position)
    
    # backgroundMask = abs(aperture.get_fractions(np.ones(self.imageCube[0].shape))-1)
    backgroundMask = aper_mask.to_image(image.shape).astype(bool)
    backgroundMask = ~backgroundMask#[backgroundMask == 0] = False
    
    return metric(image[backgroundMask])
Пример #17
0
def measure_one_KDE_bg(image, center, aperRad, metric, apMethod='exact'):
    """Class methods are similar to regular functions.

    Note:
        Do not include the `self` parameter in the ``Args`` section.

    Args:
        param1: The first parameter.
        param2: The second parameter.

    Returns:
        True if successful, False otherwise.

    """
    
    aperture       = CircularAperture(center, aperRad)
    aperture       = aperture.to_mask(method=apMethod)[0]
    aperture       = aperture.to_image(image.shape).astype(bool)
    backgroundMask = ~aperture
    
    kdeFrame = kde.KDEUnivariate(image[backgroundMask])
    kdeFrame.fit()
    
    return kdeFrame.support[kdeFrame.density.argmax()]
Пример #18
0
def try_dao(fitsfile, outfile='out.png'):
   
    hdulist = fits.open(fitsfile)
    hdu = hdulist[0]

    if len(hdu.data.shape) == 3:
        data = hdu.data[0]
    else:
        data = hdu.data

    mean, median, std = sigma_clipped_stats(data[800:900, 800:900], sigma=3.0, iters=5)
    print(mean, median, std)

    #data = hdu.data
    sources = daofind(data - median, fwhm=3.0, threshold=5.*std)
    print 'Found %i sources' % len(sources)

    positions = (sources['xcentroid'], sources['ycentroid'])
    apertures = CircularAperture(positions, r=4.)
    norm = ImageNormalize(stretch=SqrtStretch(), vmin=2000, vmax=3000)
    plt.imshow(data, cmap='Greys', origin='lower', norm=norm)
    plt.title('%i Sources from a single all-sky frame' % len(sources))
    apertures.plot(color='blue', lw=1.5, alpha=0.5)
    plt.savefig(filename=outfile)
Пример #19
0
def measure_one_background(image, center, aperRad, metric, apMethod='exact', bgMethod='circle'):
    """Class methods are similar to regular functions.

    Note:
        Do not include the `self` parameter in the ``Args`` section.

    Args:
        param1: The first parameter.
        param2: The second parameter.

    Returns:
        True if successful, False otherwise.

    """
    
    if np.ndim(aperRad) == 0:
        aperture  = CircularAperture(center, aperRad)
        aperture  = aperture.to_mask(method=apMethod)[0]    # list of ApertureMask objects (one for each position)
        aperture  = ~aperture.to_image(image).astype(bool) # inverse to keep 'outside' aperture
    else:
        innerRad, outerRad = aperRad
        
        innerAperture   = CircularAperture(center, innerRad)
        outerAperture   = CircularAperture(center, outerRad)
        
        inner_aper_mask = innerAperture.to_mask(method=method)[0]
        inner_aper_mask = inner_aper_mask.to_image(image.shape).astype(bool)
    
        outer_aper_mask = outerAperture.to_mask(method=method)[0]
        outer_aper_mask = outer_aper_mask.to_image(image.shape).astype(bool)     
        
        aperture        = (~inner_aper_mask)*outer_aper_mask
    
    if bgMethod == 'median':
        medFrame  = median(image[aperture])
        madFrame  = scale.mad(image[aperture])
        
        medianMask= abs(image - medFrame) < nSig*madFrame
        
        aperture  = medianMask*aperture
    
    if bgMethod == 'kde':
        kdeFrame = kde.KDEUnivariate(image[aperture].ravel())
        kdeFrame.fit()
        
        return kdeFrame.support[kdeFrame.density.argmax()]
    
    return metric(image[aperture])
Пример #20
0
def extraction(aornum, chnum, plnm, plnm2, radii, var_rad, var_add, basepath, fromx, to):

    for aor in aornum:
        aor=str(aor)
        paths = glob.glob(basepath+'r'+aor+ '/ch*')
        fpathout=basepath+aor[-8:]
        directory = os.path.dirname(fpathout)
        if not os.path.exists(directory):
            os.makedirs(directory)

        fpath=basepath+'r' + aor + '/ch' + str(chnum) + '/bcd/' #path to fits files

        filenames=glob.glob(fpath + '*bcd.fits')
        filenames.sort()
        nframes=len(filenames)
        print ('Analyzing over ' + str(nframes) + ' frames.')
     
        hold_pos=np.zeros(shape=(nframes*64, 2))
        hold_posg=np.zeros(shape=(nframes*64, 2))
        hold_pos_diff = hold_pos - hold_posg
        central_pix=np.zeros(shape=(5,5, nframes*64))
        lightcurve=np.zeros(shape=(nframes*64, len(radii)+len(var_rad)+len(var_add)))
        lightcurveg=np.zeros(shape=(nframes*64, len(radii)+len(var_rad)+len(var_add)))
        time=np.zeros(nframes*64)
        beta_np=np.zeros(nframes*64)

        for i in range(0,nframes):
            if i % 10==0: 
                os.system('clear')
                print(aor, i,' of ',str(nframes))

            hdulist = fits.open(filenames[i])
            channel=str(hdulist[0].header['CHNLNUM'])
            
            cube=hdulist[0].data
            exptime=hdulist[0].header['EXPTIME']
            framtime=hdulist[0].header['FRAMTIME']
            mmbjd=hdulist[0].header['BMJD_OBS']
            for j in range(0,64):    
                scidata=cube[j,:,:]
                bkgd= backgr(scidata)
                data=scidata-bkgd  
                data=ma.masked_invalid(data)
                
                bnp1=np.sum(data)**2
                bnp2=np.sum(np.multiply(data,data))
                bnp=bnp1/bnp2
        
                xc,yc, xcg, ycg=centroid(data) #use both centroiding
                position=[xc,yc]
                positiong = [xcg, ycg]
                beta_np[64*i+j]=bnp
                hold_pos[64*i+j, :]=position  
                hold_posg[64*i+j, :]=positiong
                hold_pos_diff[64*i+j,:] = hold_pos[64*i+j, :] - hold_posg[64*i+j, :]
                vrad1=var_rad*np.sqrt(bnp)
                vrad2=var_add+np.sqrt(bnp)
                vrad=np.concatenate((vrad1, vrad2))
                all_rad=np.concatenate((radii, vrad))
                apertures = [CircularAperture(position, r=r) if r > 0 else CircularAperture(position, r=2.0) for r in all_rad]
                aperturesg = [CircularAperture(positiong, r=r) if r > 0 else CircularAperture(positiong, r=2.0) for r in all_rad]

                phot_table = aperture_photometry(scidata, apertures)
                phot_tableg = aperture_photometry(scidata, aperturesg)

                for q in range (0,len(all_rad)):
                    if q ==0: 
                        phot=np.zeros(len(all_rad))
                        photg=np.zeros(len(all_rad))
                    phot[q]=phot_table.columns[q+3]
                    photg[q] = phot_tableg.columns[q+3]  
                time[64*i+j]=mmbjd+framtime*j/86400.0
                lightcurve[64*i+j, :]=phot
                lightcurveg[64*i+j,:]=photg
                central_pix[:,:,64*i+j]=data[13:18, 13:18]
            hdulist.close()
        orbparams=get_orb_pars(plnm2, basepath)

        #pmap=pmap_corr(hold_pos, channel) - if using pmap

        np.savez(fpathout+'extraction',  ch=channel, time=time, lc=lightcurve, lcg=lightcurveg, cp=central_pix,  op=orbparams, 
            exptime=exptime, framtime=framtime, beta_np=beta_np, hold_pos=hold_pos, hold_posg=hold_posg, 
            hold_pos_diff = hold_pos_diff, all_rad=all_rad, pos=position, posg=positiong)
        t=time
        npix=beta_np

        plt.figure()
        plt.subplot(311)
        plt.title(plnm+' Ch: '+str(chnum)+'\n'+aor)
        plt.scatter(t, hold_pos[:,0], s=1)
        plt.ylim(14.5, 15.5)
        plt.ylabel('X position')
        plt.xticks([])
        plt.subplot(312)
        plt.scatter(t, hold_pos[:,1], s=1)
        plt.ylim(14.5, 15.5)
        plt.ylabel('Y position')
        plt.xticks([])
        plt.subplot(313)
        plt.scatter(t, np.sqrt(npix), s=1)
        plt.ylim(2, 3)
        plt.ylabel('Sqrt Noise Pixel')
        plt.xlabel('Time')
        plt.savefig(fpathout+'xyb_plot')

        plt.figure()
        plt.subplot(311)
        plt.title(plnm+' Ch: '+str(chnum)+'\n'+aor)
        plt.scatter(t, hold_posg[:,0], s=1)
        plt.ylim(14.5, 15.5)
        plt.ylabel('X position - Gaussian')
        plt.xticks([])
        plt.subplot(312)
        plt.scatter(t, hold_posg[:,1], s=1)
        plt.ylim(14.5, 15.5)
        plt.ylabel('Y position - Gaussian')
        plt.xticks([])
        plt.subplot(313)
        plt.scatter(t, np.sqrt(npix), s=1)
        plt.ylim(2, 3)
        plt.ylabel('Sqrt Noise Pixel')
        plt.xlabel('Time')
        plt.savefig(fpathout+'xyb_plot_gaussian')

        #send_mail('xyb_plot.png', fpathout, aor, fromx, to)
    return None
Пример #21
0
num_comp = len(df) - 1
coord_targetx = df['XCoord'][0]
coord_targety = df['YCoord'][0]
positions = [(coord_targetx, coord_targety)]
comp_mag = []
for i in range(num_comp):
    maggy = df['Mag'][i + 1]
    xcoord = df['XCoord'][i + 1]
    ycoord = df['YCoord'][i + 1]
    coords = (xcoord, ycoord)
    positions.append(coords)
    comp_mag.append(maggy)
ap = eval(input("Enter the aperature size: "))
# Create the aperature
aperture = CircularAperture(positions, r=ap)
# Run the aperature photometry for each file
if oneorno != 'Yes':
    for i in range(len(filelist)):
        image = filelist[i]
        image = str(image)
        im = fits.getdata(image)
        phot_table = aperture_photometry(im, aperture)
        # Save the pixel values from the table
        flux = []
        target_flux = phot_table[0][3]
        for i in range(num_comp):
            ff = phot_table[i + 1][3]
            flux.append(ff)
        phot_table = str(phot_table)
        # Create a file to save
Пример #22
0
def tso_aperture_photometry(datamodel, xcenter, ycenter, radius, radius_inner,
                            radius_outer):
    """
    Create a photometric catalog for NIRCam TSO imaging observations.

    Parameters
    ----------
    datamodel : `CubeModel`
        The input `CubeModel` of a NIRCam TSO imaging observation.

    xcenter, ycenter : float
        The ``x`` and ``y`` center of the aperture.

    radius : float
        The radius (in pixels) of the circular aperture.

    radius_inner, radius_outer : float
        The inner and outer radii (in pixels) of the circular-annulus
        aperture, used for local background estimation.

    Returns
    -------
    catalog : `~astropy.table.QTable`
        An astropy QTable (Quantity Table) containing the source
        photometry.
    """

    if not isinstance(datamodel, CubeModel):
        raise ValueError('The input data model must be a CubeModel.')

    aper1 = CircularAperture((xcenter, ycenter), r=radius)
    aper2 = CircularAnnulus((xcenter, ycenter), r_in=radius_inner,
                            r_out=radius_outer)

    nimg = datamodel.data.shape[0]
    aperture_sum = []
    aperture_sum_err = []
    annulus_sum = []
    annulus_sum_err = []

    for i in np.arange(nimg):
        tbl1 = aperture_photometry(datamodel.data[i, :, :], aper1,
                                   error=datamodel.err[i, :, :])
        tbl2 = aperture_photometry(datamodel.data[i, :, :], aper2,
                                   error=datamodel.err[i, :, :])

        aperture_sum.append(tbl1['aperture_sum'][0])
        aperture_sum_err.append(tbl1['aperture_sum_err'][0])
        annulus_sum.append(tbl2['aperture_sum'][0])
        annulus_sum_err.append(tbl2['aperture_sum_err'][0])

    # convert array of Quantities to Quantity arrays
    aperture_sum = u.Quantity(aperture_sum)
    aperture_sum_err = u.Quantity(aperture_sum_err)
    annulus_sum = u.Quantity(annulus_sum)
    annulus_sum_err = u.Quantity(annulus_sum_err)

    # construct metadata for output table
    meta = OrderedDict()
    meta['instrument'] = datamodel.meta.instrument.name
    meta['detector'] = datamodel.meta.instrument.detector
    meta['channel'] = datamodel.meta.instrument.channel
    meta['subarray'] = datamodel.meta.subarray.name
    meta['filter'] = datamodel.meta.instrument.filter
    meta['pupil'] = datamodel.meta.instrument.pupil

    meta['target_name'] = datamodel.meta.target.catalog_name
    meta['xcenter'] = xcenter
    meta['ycenter'] = ycenter
    ra_icrs, dec_icrs = datamodel.meta.wcs(xcenter, ycenter)
    meta['ra_icrs'] = ra_icrs
    meta['dec_icrs'] = dec_icrs

    info = ('Photometry measured in a circular aperture of r={0} pixels. '
            'Background calculated as the mean in a circular annulus with '
            'r_inner={1} pixels and r_outer={2} pixels.'
            .format(radius, radius_inner, radius_outer))
    meta['apertures'] = info

    tbl = QTable(meta=meta)

    dt = (datamodel.meta.exposure.group_time *
          (datamodel.meta.exposure.ngroups + 1))
    dt_arr = (np.arange(1, 1 + datamodel.meta.exposure.nints) *
              dt - (dt / 2.))
    int_dt = TimeDelta(dt_arr, format='sec')
    int_times = (Time(datamodel.meta.exposure.start_time, format='mjd') +
                 int_dt)
    tbl['MJD'] = int_times.mjd

    tbl['aperture_sum'] = aperture_sum
    tbl['aperture_sum_err'] = aperture_sum_err
    tbl['annulus_sum'] = annulus_sum
    tbl['annulus_sum_err'] = annulus_sum_err

    annulus_mean = annulus_sum / aper2.area()
    annulus_mean_err = annulus_sum_err / aper2.area()
    tbl['annulus_mean'] = annulus_mean
    tbl['annulus_mean_err'] = annulus_mean_err

    aperture_bkg = annulus_mean * aper1.area()
    aperture_bkg_err = annulus_mean_err * aper1.area()
    tbl['aperture_bkg'] = aperture_bkg
    tbl['aperture_bkg_err'] = aperture_bkg_err

    net_aperture_sum = aperture_sum - aperture_bkg
    net_aperture_sum_err = np.sqrt(aperture_sum_err ** 2 +
                                   aperture_bkg_err ** 2)
    tbl['net_aperture_sum'] = net_aperture_sum
    tbl['net_aperture_sum_err'] = net_aperture_sum_err

    return tbl
Пример #23
0
for i in np.arange(np.size(lamda)):  
    ra = 46.852292
    dec = 58.514656
    data, hdr = fits.getdata(name[i]+'.fits', 0, header = True)
    if i in (0,1,2,4):
        delt = abs(hdr['PXSCAL1'])/3600. 
    else:
        delt = abs(hdr['CDELT1'])
    r_pix = aper/delt/3600.
    w = wcs.WCS(hdr)
    if lamda[i]>=70.:
        coordiante = SkyCoord(ra*u.deg, dec*u.deg, frame='fk5')
        ra = coordiante.galactic.l.degree
        dec = coordiante.galactic.b.degree
    phot_center = w.wcs_world2pix(ra, dec, 1)
    aperture = CircularAperture(phot_center, r=r_pix)
    phot = aperture_photometry(data, aperture)

    # bg as median in an annulus
    grid = annulus_index.go([data.shape[1],data.shape[0]],phot_center,r_pix*2,r_pix)
    bgdata = np.ndarray(shape=data.shape)
    bgdata[:,:] = np.median(data[grid])   
    bgphot = aperture_photometry(bgdata, aperture) 
    if i in (3,5,6,7):
        flux = phot['aperture_sum'].data[0]
        bg = bgphot['aperture_sum'].data[0]
    else:
        flux = phot['aperture_sum'].data[0]*delt**2*304.61741978670857
        bg = bgphot['aperture_sum'].data[0]*delt**2*304.61741978670857
    
    print flux
Пример #24
0
    def do_detection(self):
        """Flag outlier pixels in DQ of input images."""
        self.build_suffix(**self.outlierpars)
        self._convert_inputs()

        pars = self.outlierpars
        save_intermediate_results = pars['save_intermediate_results']

        # Start by performing initial TSO Photometry on stack of DataModels
        # TODO:  need information about the actual source position in
        # TSO imaging mode (for all subarrays).
        # Meanwhile, this is a placeholder representing the geometric
        # center of the image.
        nints, ny, nx = self.inputs.data.shape
        xcenter = (ny - 1) / 2.
        ycenter = (ny - 1) / 2.

        # all radii are in pixel units
        if self.inputs.meta.instrument.pupil == 'WLP8':
            radius = 50
            radius_inner = 60
            radius_outer = 70
        else:
            radius = 3
            radius_inner = 4
            radius_outer = 5

        apertures = CircularAperture((xcenter, ycenter), r=radius)
        aperture_mask = apertures.to_mask(method='center')[0]
        # This mask has 1 for mask region, 0 for outside of mask
        median_mask = aperture_mask.to_image((ny, nx))
        inv_median_mask = np.abs(median_mask - 1)
        # Perform photometry
        catalog = tso_aperture_photometry(self.inputs, xcenter, ycenter,
                                          radius, radius_inner,
                                          radius_outer)

        # Extract net photometry for the source
        # This will be the value used for scaling the median image within
        # the aperture region
        phot_values = catalog['net_aperture_sum']

        # Convert CubeModel into ModelContainer of 2-D DataModels
        for image in self.input_models:
            image.wht = resample_utils.build_driz_weight(
                image,
                weight_type='exptime',
                good_bits=pars['good_bits']
            )

        # Initialize intermediate products used in the outlier detection
        input_shape = self.input_models[0].data.shape
        median_model = datamodels.ImageModel(init=input_shape)
        median_model.meta = deepcopy(self.input_models[0].meta)
        base_filename = self.inputs.meta.filename
        median_model.meta.filename = self.make_output_path(
            basepath=base_filename, suffix='median'
        )

        # Perform median combination on set of drizzled mosaics
        median_model.data = self.create_median(self.input_models)
        aper2 = CircularAnnulus((xcenter, ycenter), r_in=radius_inner,
                                r_out=radius_outer)

        tbl1 = aperture_photometry(median_model.data, apertures,
                                   error=median_model.data * 0.0 + 1.0)
        tbl2 = aperture_photometry(median_model.data, aper2,
                                   error=median_model.data * 0.0 + 1.0)

        aperture_sum = u.Quantity(tbl1['aperture_sum'][0])
        annulus_sum = u.Quantity(tbl2['aperture_sum'][0])
        annulus_mean = annulus_sum / aper2.area()
        aperture_bkg = annulus_mean * apertures.area()
        median_phot_value = aperture_sum - aperture_bkg

        if save_intermediate_results:
            log.info("Writing out MEDIAN image to: {}".format(
                     median_model.meta.filename))
            median_model.save(median_model.meta.filename)

        # Scale the median image by the initial photometry (only in aperture)
        # to create equivalent of 'blot' images
        # Area outside of aperture in median will remain unchanged
        blot_models = datamodels.ModelContainer()
        for i in range(nints):
            scale_factor = float(phot_values[i] / median_phot_value)
            scaled_image = datamodels.ImageModel(init=median_model.data.shape)
            scaled_image.meta = deepcopy(median_model.meta)
            scaled_data = (median_model.data * (scale_factor * median_mask) + (
                           median_model.data * inv_median_mask))
            scaled_image.data = scaled_data
            blot_models.append(scaled_image)

        if save_intermediate_results:
            log.info("Writing out Scaled Median images...")

            def make_output_path(ignored, idx=None):
                output_path = self.make_output_path(
                    basepath=base_filename, suffix='blot', idx=idx,
                    component_format='_{asn_id}_{idx}'
                )
                return output_path

            blot_models.save(make_output_path)

        # Perform outlier detection using statistical comparisons between
        # each original input image and its blotted version of the median image
        self.detect_outliers(blot_models)

        # clean-up (just to be explicit about being finished
        # with these results)
        del median_model, blot_models
Пример #25
0
 def circular_mask(self, radius=4):
     circ =  CircularAperture(self.centroid, radius)
     circ_mask = circ.to_mask()[0].to_image(self.image.shape).astype(bool)
     return circ_mask
Пример #26
0
def radial_profile(data, x, y, step_size, fwhm, rad):
    '''

    Function used to create a plot of the radial profile of a source at the coordinates (``x``, ``y``).
    Performs aperture photometry on concentric circles of radii ``step_size``.
    This function does not show the plot but does everything up to that point.

    :param data: CCDData
        Data of the image.

    :param x: float
        Pixel coordinate.

    :param y: float
        Pixel coordinate.

    :param step_size: float
        Radial size of each ring (concentric circles). Anything less than ``0.7`` is too pixelated and does not
        represent the data accurately

    :param fwhm: float
        FWHM of the image.

    :param rad: float
        Radius to extent to (actually is ``rad`` * ``fwhm``).

    :return: nothing
        Makes the plot but does not return anything.
    '''

    radii = np.arange(step_size, rad * fwhm, step_size)  # Radii of apertures
    x_data = np.arange(
        0, rad * fwhm,
        step_size)  # Steps (starting at zero, to 2.5 * fwhm, by step_size)
    apers_area = [np.pi * (step_size**2)]  # Circle area = pi*(r**2)
    for r in radii:
        apers_area.append(np.pi *
                          ((r + step_size)**2 -
                           r**2))  # Annulus area = pi*(r_out**2 - r_in**2)
    apertures = [CircularAperture(
        (x, y), r=step_size)]  # For circle aperture around center
    for r in radii:
        apertures.append(CircularAnnulus(
            (x, y), r_in=r, r_out=r + step_size))  # Annuli apertures
    rad_prof_large = aperture_photometry(
        data, apertures)  # Radial profile photometry of new fake source
    sums = [
        rad_prof_large[0][k] / apers_area[k - 3]
        for k in range(3, len(rad_prof_large[0]))
    ]  # For radial profile
    w_fit = x_data
    f_fit = sums
    g, _ = curve_fit(fix_x0, w_fit, f_fit)
    plt.figure(1)
    # plt.plot(x_data, sums, 'o-', alpha=0.5, lw=2, markersize=4)
    plt.plot(x_data, sums, 'o-', alpha=0.5, lw=2,
             markersize=4)  # Plot the radial profiles
    plt.plot(x_data, fix_x0(x_data, *g), '^-', alpha=0.5, lw=2, markersize=4)
    plt.title("Radial profile of target")
    plt.xlabel("Radial distance from centroid of source (pixels)")
    plt.ylabel("Count (adu per second per pixel)")
Пример #27
0
def photom(ima, pos, radius, r_in=None, r_out=None, method='median'):
    '''
    Aperture photometry in an aperture located at pixel coordinates 
    pos = ( (x0, y0), (x1, y1), ... ) with a radius=radius.
    When r_in and r_out are given, background is estimated in CircularAnnulus and subtracted.
    
    method refers to how the background is estimated within the circlar annulus.
    Can be 'median' or 'mean' or 'mode'

    '''
    
    ima_local = np.ma.asanyarray(ima.copy())
    ima_local.fill_value = np.nan
    mask_ = ima_local.mask
    ima_  = ima_local.filled()
    
    ### Do photometry - identical for each method
    apertures = CircularAperture(pos, r = radius)
    ap        = aperture_photometry(ima_, apertures, 
                                    mask=mask_, method='exact')
    # Aperture photometry on mask to estimate # of masked pixels in aperture
    apm       = aperture_photometry(mask_.astype(int), apertures,
                                    method='exact')
    ap.add_columns( [apertures.area()-apm['aperture_sum'], apm['aperture_sum']],
                   names=['aperture_area', 'aperture_badpix'])
    ap.add_column(ap['aperture_sum'], index=3, name='Flux')

    if ( r_in == None or r_out == None or not method in ('mean', 'median', 'mode') ): 
      # Quit here if background correction is not requested
      return ap

    annulus_apertures = CircularAnnulus(pos, r_in=r_in, r_out=r_out)
    annulus_masks = annulus_apertures.to_mask(method='center')
    bg_values = []
    for annulus_mask in annulus_masks:
      bg_ima = annulus_mask.cutout(ima_)
      bg_mask = annulus_mask.cutout(mask_.astype(np.int))
      bg_ima = np.ma.array(bg_ima, mask= bg_mask.astype(np.bool) | ~annulus_mask.data.astype(np.bool))
      
      if method == 'mean': bg_val = bg_ima.mean()
      elif method == 'median': bg_val = np.ma.median(bg_ima)
      elif method == 'mode': 
        kernel = gaussian_kde(bg_ima.data[~bg_ima.mask], bw_method='silverman')
        mode = bg_ima.mean()
        std  = bg_ima.std()
        
        mode = minimize_scalar(lambda x: -kernel(x), bounds=(mode-3*std, mode+3*std),
                               method='bounded')
        bg_val=mode.x[0]
        
        if False:
          median = np.ma.median(bg_ima)
          h, b = np.histogram(bg_ima.data[~bg_ima.mask], bins=15, normed=True)
          bc = 0.5*(b[1:]+ b[:-1])
          plt.figure(33); plt.clf(); plt.ioff()
          fig, (ax0,ax1) = plt.subplots(ncols=2, nrows=1, num=33)
          ax0.plot(bc, h, 'x')
          x = np.linspace(bc.min(), bc.max(), 100)
          ax0.plot(x, kernel(x))
          ax0.vlines(mode.x, ax0.get_ylim()[0], ax0.get_ylim()[1])
          ax0.vlines(median, ax0.get_ylim()[0], ax0.get_ylim()[1])
          ax1.imshow(bg_ima)
          plt.show()
        
        
      bg_values.append(bg_val)
    ap.add_column(Column(data=bg_values, name = 'background'))  
    ap['Flux'] = ap['Flux'] - ap['aperture_area']*ap['background']
    return ap, bg_ima
Пример #28
0
for image_name in files:
	image = fits.getdata(star+"/"+image_name, ext=0)
	data = image[x_1:x_2, y_1:y_2]
	image_head = fits.getheader(star+"/"+image_name, ext=0)
	tbl = find_peaks(data, 300, box_size=50)
	pe = np.array(tbl['peak_value'])
	pe_x = np.array(tbl['x_peak'])
	pe_y = np.array(tbl['y_peak'])
	peaks = np.array((pe_x, pe_y, pe)).T
	peaks = peaks.tolist()
	peaks = sorted(peaks, key=lambda t: t[2], reverse=True)
	positions = ([peaks[0][0], peaks[0][1]], [peaks[ref][0], peaks[ref][1]])
	"""
	x, y = centroid_1dg(image[x_1:x_2, y_1:y_2])
	#fits.writeto(image_name, image[x_1:x_2, y_1:y_2], overwrite=True)"""
	apertures = CircularAperture(positions, r=r)
	annulus = CircularAnnulus(positions, r_in=12., r_out= 15.)
	apers = [apertures, annulus]
	phot_table = aperture_photometry(data, apers, error=np.sqrt(abs(data)))
	bkg_mean = phot_table['aperture_sum_1']/annulus.area()
	bkg_mean_err = 1/annulus.area() * phot_table['aperture_sum_err_1']
	flux = phot_table['aperture_sum_0'] - bkg_mean * apertures.area()
	flux_err = np.sqrt((phot_table['aperture_sum_err_0'])**2 + (apertures.area()*bkg_mean_err)**2)
	#number_of_counts = np.array(phot_table['aperture_sum']) # The number of counts of the star and the reference star in an cicular area around the star
	#ratio_noc = number_of_counts[0]/number_of_counts[1]
	ratio_flux = flux[0]/flux[1]
	ratio_flux_err = np.sqrt((flux_err[0]/flux[1])**2 + (flux[0]*flux_err[1]/flux[1]**2)**2)
	magnitude = -2.5*np.log10(ratio_flux) + mag_ref # Calculate the apparent magnitude
	magnitude_err = 2.5/(np.log(10)*ratio_flux) * ratio_flux_err
	date = image_head['Date-OBS']
	time = datetime(int(date[:4]), int(date[5:7]), int(date[8:10]), int(date[11:13]), int(date[14:16]), int(date[17:19]), int(float(date[19:22])*10**6))
Пример #29
0
def find_target_phot(stack,
                     fil,
                     fwhm,
                     zp,
                     zp_err,
                     pixscale,
                     show_phot=False,
                     log=None,
                     log2=None,
                     ra=None,
                     dec=None,
                     x=None,
                     y=None):
    '''

    Function to perform photometry on a target at a specific RA and Dec. Usually used after `find_zero_point`
    (this finds the ``zp``, ``zp_err``, and ``fwhm``).
    During this process, the user has the options to change the target's location and radii used in
    aperture photometry (if ``show_plots`` is ``True``, user can see cutouts of target and its radial profile).
    Attempts to find the magnitude of the target using aperture photometry.


    If magnitude cannot be found at a 3 sigma confidence interval, limiting magnitude is found at the same position.
    Limiting magnitude is found by adding fake sources of increasing magnitude at the target's position until it is
    more than 3 sigma above the background.

    :param stack: str
        Name of the stack to use (include path to the stack).

    :param fil: str
        Name of the filter of the stack.

    :param fwhm: float
        FWHM of image.

    :param zp: float
        Zero point of image in AB mag.

    :param zp_err: float
        Error on the zero point of image.

    :param show_phot: boolean, optional
        Option to see the cutout of the source with apertures along with its radial profile.
        Default is ``False``.

    :param log: log, optional
        In-depth log.
        If no log is inputted, information is printed out instead of being written to ``log``.
        Default is ``None``.

    :param log2: log, optional
        Overview log.
        If no log is inputted, information is printed out instead of being written to ``log2``.
        Default is ``None``.

    :param ra: float, optional
        RA coordinate of target.
        Default is ``None``.

    :param dec: float, optional
        Dec coordinate of target.
        Default is ``None``.

    :param x: float, optional
        X pixel coordinate (not RA).
        Default is ``None``.

    :param y: float, optional
        Y pixel coordiante (not Dec).
        Default is ``None``.

    Returns
    -------

    :return: float, float
        Three options:
            * Returns the magnitude of the target (in AB) and its error.
            * Returns tne limiting magnitude at the target's location (in AB) and its error.
            * Returns ``None``, ``None`` if a fake source of amplitude 5 (adu / sec / pixel) is not three
                sigma above the background.

    '''

    with fits.open(stack) as hdr:
        header, data = hdr[0].header, hdr[0].data
        w = wcs.WCS(header)  # Parse the WCS keywords in the primary HDU

    if ra is not None:
        coords = np.array(
            [[ra, dec]],
            np.float)  # Array of coordinates: [[RA, Dec]] in [deg, deg]
        pixel_coords = w.wcs_world2pix(
            coords, 1)[0]  # Find the pixel coordinates in the image
        x = pixel_coords[0]
        y = pixel_coords[1]
    elif x is not None:
        x -= 1
        y -= 1
        coords = np.array(
            [[x, y]],
            np.float)  # Array of coordinates: [[RA, Dec]] in [deg, deg]
        pixel_coords = w.wcs_pix2world(
            coords, 1)[0]  # Find the pixel coordinates in the image
        ra = pixel_coords[0]
        dec = pixel_coords[1]
    else:
        print("No coordinates inputted")

    d_x_y = 125  # Pixels above and below the target when showing image...125 corresponds to a 50" x 50" cutout
    if log is not None:
        log.info("Pixel coordinates: (%.3f, %.3f)" % (x, y))
    else:
        print("Pixel coordinates: (%.3f, %.3f)" % (x, y))
    if input('Would you like to choose the cutout size? Default is 50"x50". '
             ) == "yes":
        try:
            d_x_y = int(input("Choose the radius, in arcsec: ")) * 2.5
        except TypeError:
            pass

    sigma_clip = SigmaClip(
        sigma=3)  # This section is to find the error on the background
    bkg_estimator = MedianBackground()
    bkg = Background2D(data, (120, 120),
                       filter_size=(3, 3),
                       sigma_clip=sigma_clip,
                       bkg_estimator=bkg_estimator)
    error = calc_total_error(data, bkg.background_rms,
                             1)  # Used later as well for limiting magnitude

    if log is not None:
        log.info("You will now get to pick the position you would like. "
                 "Decide what pixel coordinates you would like to use")
        log.info(
            "Blue circle in image is the distance the radial profile extends to"
        )
    else:
        print("You will now get to pick the position you would like. "
              "Decide what pixel coordinates you would like to use")
        print(
            "Blue circle in image is the distance the radial profile extends to"
        )
    correct_position = "no"
    while correct_position == "no":
        if show_phot:
            radial_profile(data, x, y, 0.2, fwhm, rad=6)  # Radial profile
            plt.axvline(6 * fwhm)

            print(
                "Double click to set the new center. Do nothing if you are ok with current coordinates."
            )
            fig = plt.figure(2)
            new_coords = []
            fig.canvas.mpl_connect(
                'button_press_event',
                lambda event: onclick(event, new_coords=new_coords))
            ap_in = CircularAperture((x, y),
                                     1)  # Aperture to perform photometry
            ap_out = CircularAperture(
                (x, y), 6 * fwhm)  # Aperture to perform photometry
            ap_in.plot(color='r',
                       lw=1)  # Plot of target with apertures and annulus
            ap_out.plot(color='b', lw=2)
            norm = simple_norm(data, 'sqrt', percent=99)
            plt.imshow(data, norm=norm)
            plt.xlim(int(x) - d_x_y, int(x) + d_x_y)
            plt.ylim(int(y) - d_x_y, int(y) + d_x_y)
            plt.colorbar()
            plt.show()

            if len(new_coords) != 0:
                x, y = new_coords[len(new_coords) -
                                  2], new_coords[len(new_coords) - 1]
                real_coords = w.wcs_pix2world(
                    np.array([[x, y]], np.float),
                    1)[0]  # Find the pixel coords in the image
                ra, dec = real_coords[0], real_coords[1]

                radial_profile(data, x, y, 0.2, fwhm, rad=6)  # Radial profile
                plt.axvline(6 * fwhm)

                print("Showing new position.")
                fig = plt.figure(2)
                ap_in = CircularAperture((x, y),
                                         1)  # Aperture to perform photometry
                ap_out = CircularAperture(
                    (x, y), 6 * fwhm)  # Aperture to perform photometry
                ap_in.plot(color='r',
                           lw=1)  # Plot of target with apertures and annulus
                ap_out.plot(color='b', lw=2)
                norm = simple_norm(data, 'sqrt', percent=99)
                plt.imshow(data, norm=norm)
                plt.xlim(int(x) - d_x_y, int(x) + d_x_y)
                plt.ylim(int(y) - d_x_y, int(y) + d_x_y)
                plt.colorbar()
                plt.show()

        if input("Would you like to use a centroid? Type 'yes' or 'no': "
                 ) == "yes":
            d_x_y = 50
            d = data[int(y) - d_x_y:int(y) + d_x_y,
                     int(x) - d_x_y:int(x) +
                     d_x_y]  # Cutout of source; upside down from normal
            x_mesh, y_mesh = np.meshgrid(
                np.linspace(0,
                            np.shape(d)[1] - 1,
                            np.shape(d)[1]),
                np.linspace(0,
                            np.shape(d)[0] - 1,
                            np.shape(d)[0]))
            popt, pcov = curve_fit(twoD_Gaussian, (x_mesh, y_mesh),
                                   d.ravel(),
                                   p0=(np.max(d), 50, 50, fwhm / 2.35482,
                                       fwhm / 2.35482, 0, 0))
            x += popt[1] - d_x_y
            y += popt[2] - d_x_y
            if log:
                log.info('Centroid calculated position: (%.3f, %.3f)' % (x, y))
            else:
                print('Centroid calculated position: (%.3f, %.3f)' % (x, y))

            real_coords = w.wcs_pix2world(
                np.array([[x, y]],
                         np.float), 1)[0]  # Find the pixel coords in the image
            ra, dec = real_coords[0], real_coords[1]

            radial_profile(data, x, y, 0.2, fwhm, rad=6)  # Radial profile
            plt.axvline(6 * fwhm)

            print("Showing centroid position.")
            fig = plt.figure(2)
            ap_in = CircularAperture((x, y),
                                     1)  # Aperture to perform photometry
            ap_out = CircularAperture(
                (x, y), 6 * fwhm)  # Aperture to perform photometry
            ap_in.plot(color='r',
                       lw=1)  # Plot of target with apertures and annulus
            ap_out.plot(color='b', lw=2)
            norm = simple_norm(data, 'sqrt', percent=99)
            plt.imshow(data, norm=norm)
            plt.xlim(int(x) - d_x_y, int(x) + d_x_y)
            plt.ylim(int(y) - d_x_y, int(y) + d_x_y)
            plt.colorbar()
            plt.show()

        if input("Are you ok with this position? Type 'yes' or 'no': "
                 ) != "yes":
            pass
        else:
            correct_position = "yes"
            if log is not None:
                log.info(
                    "Coordinates chosen: (%.3f, %.3f) at RA = %.5f and Dec = %.5f"
                    % (x, y, ra, dec))
            else:
                print(
                    "Coordinates chosen: (%.3f, %.3f) at RA = %.5f and Dec = %.5f"
                    % (x, y, ra, dec))
            if log2 is not None:
                log2.info(
                    "Final coordinates: (%.3f, %.3f) at RA = %.5f and Dec = %.5f"
                    % (x, y, ra, dec))

    print(
        "You will now get to choose the radii for the circular aperture and the r_in and r_out of the annulus"
    )
    correct_radii = "no"
    while correct_radii == "no":
        if log is not None:
            log.info(
                "Automatic radii picked by comparing to FWHM of field: rad = %.3f, r_in = %.3f, r_out = %.3f"
                % (2.5 * fwhm, 2.5 * fwhm, 4.5 * fwhm))
        else:
            print(
                "Automatic radii picked by comparing to FWHM of field: rad = %.3f, r_in = %.3f, r_out = %.3f"
                % (2.5 * fwhm, 2.5 * fwhm, 4.5 * fwhm))
        if input("Would you like to use these radii? Type 'yes or 'no': "
                 ) == "yes":
            rad, r_in, r_out = 2.5 * fwhm, 2.5 * fwhm, 4.5 * fwhm
        else:
            if log:
                log.info("FWHM = %.3f pixels" % fwhm)
            rad = float(
                input("Pick a radius (in pixels) for the circular aperture: "))
            r_in = float(
                input(
                    "Pick an inner radius (in pixels) for the background annulus: "
                ))
            r_out = float(
                input(
                    "Pick an outer radius (in pixels) for the background annulus: "
                ))
            if r_in >= r_out:
                r_out = r_in + 1
                if log is not None:
                    log.info(
                        "You selected an invalid r_out value. Automatically set to %s"
                        % r_out)
                else:
                    print(
                        "You selected an invalid r_out value. Automatically set to %s"
                        % r_out)

        aperture = CircularAperture((x, y),
                                    rad)  # Aperture to perform photometry
        annulus_aperture = CircularAnnulus((x, y), r_in=r_in,
                                           r_out=r_out)  # Annulus of target
        annulus_mask = annulus_aperture.to_mask(
            method='center')  # Create masks to highlight pixels in annuli

        annulus_data = annulus_mask.multiply(data)
        annulus_data_1d = annulus_data[annulus_mask.data > 0]
        _, median_sigclip, stddev = sigma_clipped_stats(annulus_data_1d)

        phot_table = aperture_photometry(
            data, aperture, error=error)  # Photometry, error accounted for
        bkg_aper = median_sigclip * aperture.area

        if show_phot:
            # Radial profile out to 6 * fwhm (large just to be safe)
            radial_profile(data, x, y, 0.2, fwhm, rad=6)
            plt.axvline(rad, c='r')
            plt.axvline(r_in)
            plt.axvline(r_out)
            plt.figure(2)
            aperture.plot(color='white',
                          lw=2)  # Plot of target with apertures and annulus
            annulus_aperture.plot(color='b', lw=2)
            norm = simple_norm(data, 'sqrt', percent=99)
            plt.imshow(data, norm=norm)
            plt.xlim(int(x) - d_x_y, int(x) + d_x_y)
            plt.ylim(int(y) - d_x_y, int(y) + d_x_y)
            plt.colorbar()
            plt.show()

        correct_radii = input(
            "Are you ok with the previously selected radii? Type 'yes' or 'no': "
        )
    if log is not None:
        log.info("Radii chosen in pixels: %.3f, %.3f, %.3f" %
                 (rad, r_in, r_out))
    else:
        print("Radii chosen in pixels: %.3f, %.3f, %.3f" % (rad, r_in, r_out))
    if log2 is not None:
        log2.info("Final radii: %.3f, %.3f, %.3f" % (rad, r_in, r_out))

    three_sigma = 3  # Change according to what sigma you'd like to use
    if (phot_table['aperture_sum']) - bkg_aper > 0:
        mag = -2.5 * np.log10(
            (phot_table['aperture_sum']) - bkg_aper)  # Instrumental magnitude
        mag_err = 2.5 / np.log(10.) * (phot_table['aperture_sum_err']) / (
            phot_table['aperture_sum'])
        mag += zp  # Apparent magnitude (Vega)
        mag_err = np.sqrt(mag_err**2 + zp_err**2)
        if log is not None:
            log.info("Magnitude of target = %.3f +/- %.3f AB mag" %
                     (mag, mag_err))  # Final mag
        if log2 is not None:
            log2.info("Magnitude of target = %.3f +/- %.3f AB mag" %
                      (mag, mag_err))  # Final mag
        else:
            print("Magnitude of target = %.3f +/- %.3f AB mag" %
                  (mag, mag_err))  # Final magnitude

        if np.abs(mag_err
                  ) < 1 / three_sigma:  # Good! No limiting magnitude needed
            return float(mag), float(mag_err)
        if log is not None:
            log.info("Target was not %s sigma above the background." %
                     three_sigma)
        else:
            print("Target was not %s sigma above the background." %
                  three_sigma)
        if log2 is not None:
            log2.info("Target not found")

    else:
        if log is not None:
            log.info(
                "Target's aperture sum was less than background aperture sum. Target was not found"
            )
        else:
            print(
                "Target's aperture sum was less than background aperture sum. Target was not found"
            )
        if log2 is not None:
            log2.info("Target not found")

    # Finding the limiting magnitude in the area 30" around where the target is supposed to be located
    if log is not None:
        log.info("Now finding the limiting magnitude to %s sigma." %
                 three_sigma)
    else:
        print("Now finding the limiting magnitude to %s sigma." % three_sigma)
    d_x_y = int(np.round(30 / pixscale, -1) / 2)
    d = data[int(y) - d_x_y:int(y) + d_x_y,
             int(x) - d_x_y:int(x) +
             d_x_y]  # Cutout of source; upside down from normal
    d_error = error[int(y) - d_x_y:int(y) + d_x_y,
                    int(x) - d_x_y:int(x) + d_x_y]
    x_mesh, y_mesh = np.meshgrid(
        np.linspace(0,
                    np.shape(d)[1] - 1,
                    np.shape(d)[1]),
        np.linspace(0,
                    np.shape(d)[0] - 1,
                    np.shape(d)[0]))

    source_mask = make_source_mask(d, nsigma=3, npixels=5)
    ind = np.ma.nonzero(~source_mask)
    inds = [(x, y) for x, y in zip(ind[0], ind[1]) if x > 2 * fwhm and y > 2 *
            fwhm and x < 2 * d_x_y - 2 * fwhm and y < 2 * d_x_y - 2 * fwhm]
    mag_list = []
    mag_err_list = []
    for i in range(50):
        xy_fake = random.choice(inds)
        gauss_data = twoD_Gaussian(
            (x_mesh, y_mesh), 3 * error[xy_fake[1], xy_fake[0]], xy_fake[0],
            xy_fake[1], fwhm / 2.35482, fwhm / 2.35482, 0, 0)
        d += gauss_data.reshape(np.shape(d))
        aperture = CircularAperture((xy_fake[0], xy_fake[1]), 2.5 * fwhm)
        annulus_aperture = CircularAnnulus((xy_fake[0], xy_fake[1]),
                                           r_in=2.5 * fwhm,
                                           r_out=3.5 * fwhm)
        annulus_mask = annulus_aperture.to_mask(method='center')
        annulus_data = annulus_mask.multiply(d)
        annulus_data_1d = annulus_data[annulus_mask.data > 0]
        _, median_sigclip, stddev = sigma_clipped_stats(annulus_data_1d)
        phot_table = aperture_photometry(d, aperture, error=d_error)
        bkg_aper = median_sigclip * aperture.area
        if (phot_table['aperture_sum']) - bkg_aper > 0:
            mag = -2.5 * np.log10((phot_table['aperture_sum']) - bkg_aper)
            mag_err = 2.5 / np.log(10.) * (phot_table['aperture_sum_err']) / (
                phot_table['aperture_sum'])
            mag_list.append(mag[0])
            mag_err_list.append(mag_err[0])
        d -= gauss_data.reshape(np.shape(d))
    mag_list = [
        mi for i, mi in enumerate(mag_list)
        if mag_err_list[i] > 0.2 and mag_err_list[i] < 0.5
    ]
    mag_err_list = [
        mi for i, mi in enumerate(mag_err_list)
        if mag_err_list[i] > 0.2 and mag_err_list[i] < 0.5
    ]
    mag_list = [x for _, x in sorted(zip(mag_err_list, mag_list))]
    mag_err_list = sorted(mag_err_list)
    limit3 = np.interp(0.333, mag_err_list, mag_list) + zp
    if log is not None:
        log.info("Limiting magnitude = %.3f +/- %.3f AB mag" % (limit3, 0.333))
    else:
        print("Limiting magnitude = %.3f +/- %.3f AB mag" % (limit3, 0.333))
    return float(limit3), float(0.333)
Пример #30
0
def STAR_FLUX(coord_table, OBJ, f, numb=[1, 2, 3], rad_aperture=10, standart=False,\
                main_obj=False, apert=False, PSF=False, PLOT_data=False, flux_10_m=None, err_flux_10_m=None):
    file = f'./data/2020-08-19/{OBJ}/{OBJ}-1MHz-76mcs-PreampX4-000' + '{}' + f'{f}.fit'
    file_0 = file.format(numb[0])
    hdu_0 = fits.open(file_0)
    data, head = hdu_0[0].data.astype(np.float32), hdu_0[0].header
    for i in numb[1:]:
        data += fits.open(file.format(i))[0].data.astype(np.float32)
    data = data / (3 * head['EXPTIME'])
    int_max = 0.9 * 2**16 / (head['EXPTIME'])
    data_clear, backgr_mean = bkg(data, SNR=5, box_size=30, filter_size=10)

    good_coord = (coord_table['X']>=0)&(coord_table['X']<len(data))&\
        (coord_table['Y']>=0)&(coord_table['Y']<len(data))
    for i, j, good, num in zip(coord_table['X'], coord_table['Y'], good_coord,
                               range(len(coord_table))):
        if not good:
            continue
        cutout = Cutout2D(data, (i, j),
                          (2 * rad_aperture + 1, 2 * rad_aperture + 1)).data
        # print(i, j)
        # plt.imshow(cutout)
        if np.max(cutout) > int_max:
            good_coord[num] = False
        if np.mean(np.sort(np.ravel(cutout))
                   [-2:]) < np.median(cutout) + 3 * np.std(cutout):
            good_coord[num] = False
        # plt.colorbar()
        # plt.show()
        # plt.close()

    if "good_star" not in coord_table.columns:
        coord_table.add_column(Column([True] * len(coord_table)),
                               name="good_star")
        coord_table['good_star'] = good_coord
    coord_table['good_star'] = coord_table['good_star'] * good_coord

    if apert:
        FLUX = apert_photometry(data_clear,
                                coord_table,
                                rad_aperture=rad_aperture)
    if PSF:
        FLUX = PSF_photometry(data, coord_table, sigma_psf=rad_aperture)

    if PLOT_data:
        plt.figure(figsize=(13, 13))
        plt.imshow(data, norm=LogNorm(), cmap='gray')
        apertures = CircularAperture(np.transpose((coord_table['X'], coord_table['Y'])),\
                                        r=rad_aperture)
        apertures.plot(color='blue', lw=1., alpha=0.5)
        plt.colorbar()
        plt.show()

    if standart:
        filtr = [(coord_table[f] != -100) & (coord_table['good_star'])]
        col_name = f"FLUX_{f}"
        coord_table.add_column(Column([np.nan] * len(coord_table)),
                               name=col_name)
        coord_table[col_name][filtr] = FLUX[filtr]
        coord_table.add_column(Column([np.nan] * len(coord_table)),
                               name=f'10m_FLUX_{f}')
        coord_table[f'10m_FLUX_{f}'][
            filtr] = coord_table[col_name][filtr] * 10**(
                (coord_table[f][filtr] - 10) / 2.5)

    if main_obj:
        col_name = f"FLUX_{f}"
        filtr = [coord_table['good_star']]
        coord_table.add_column(Column([np.nan] * len(coord_table)),
                               name=col_name)
        coord_table.add_column(Column([np.nan] * len(coord_table)),
                               name=f'MAG_{f}')
        coord_table.add_column(Column([np.nan] * len(coord_table)),
                               name=f'E_MAG_{f}')
        coord_table[col_name][filtr] = FLUX
        coord_table[f'MAG_{f}'][filtr] = 10 - 2.5 * np.log10(
            coord_table[col_name][filtr] / flux_10_m[f])
        coord_table[f'E_MAG_{f}'][filtr] = -2.5 * np.log10(
            1 - err_flux_10_m[f] / flux_10_m[f])
    return coord_table
Пример #31
0
 DAOfound = DAOfind(img)
 
 if len(DAOfound)==0 :
     print ('No star was founded using DAOStarFinder\n'*3)
 else : 
     # Use the object "found" for aperture photometry:
     print (len(DAOfound), 'stars were founded')
     #print('DAOfound \n', DAOfound)
     DAOfound.pprint(max_width=1800)
     # save XY coordinates:
     DAOfound.write(f_name[:-4]+'_DAOStarFinder.csv', overwrite=True, format='ascii.fast_csv')
     DAOcoord = (DAOfound['xcentroid'], DAOfound['ycentroid']) 
     DAOannul = CircAn(positions=DAOcoord, r_in=4*FWHM, r_out=6*FWHM)
     
     # Save apertures as circular, 4 pixel radius, at each (X, Y)
     DAOapert = CircAp(DAOcoord, r=4.)  
     #print('DAOapert\n ', DAOapert)
     
     DAOimgXY = np.array(DAOcoord)
     #print('DAOimgXY \n', DAOimgXY)
     
     plt.figure(figsize=(16,12))
     ax = plt.gca()
     im = plt.imshow(img, vmax=0.35, origin='lower')
     DAOannul.plot(color='red', lw=2., alpha=0.7)
     divider = make_axes_locatable(ax)
     cax = divider.append_axes("right", size="3%", pad=0.05)
     plt.colorbar(im, cax=cax)
     plt.savefig(f_name[:-4]+'_Annulus.png', overwrite=True)
     plt.show()
 
    for i in range(0, len(collection)):

        # read in the images
        file = glob.glob(dir + 'J0905_final_' + collection[i] + '*sci.fits')
        hdu = fits.open(file[0])
        data[i], header[i] = hdu[0].data, hdu[0].header
        fnu[i] = header[i]['PHOTFNU']
        exp[i] = header[i]['EXPTIME']

        #define positions for photometry
        positions = [(xcen, ycen)]

        #do photometry on images
        #convert to proper units
        for j in range(0, len(radii)):
            aperture = CircularAperture(positions, radii[j])
            phot_table = aperture_photometry(data[i], aperture)
            flux[i, j] = phot_table['aperture_sum'][0] * (fnu[i] / exp[i])
            if j == 0:
                subflux[i, j] = flux[i, j]
            else:
                subflux[i, j] = flux[i, j] - flux[i, j - 1]

    #calculating galaxy-wide

    #set up two-dimensional arrays for the a and b coefficients based on the luminosity and color
    #this will be in the same format ish as the table in Josh's blue notebook
    Ba = [-1.019, -1.113, -1.026, -.990, -1.110, -.994, -.888]
    Bb = [1.937, 2.065, 1.954, 1.883, 2.018, 1.804, 1.758]
    B_coeff = [Ba, Bb]
    Va = [-.759, -.853, -.766, -.730, -.850, -.734, -.628]
Пример #33
0
def symmetric_circular_aperture_photom(scidata, starts, inverted, jpeg='', plot=False, sat_adu = 16383):
    '''
    Method to use for june2017 firmware
    TODO unfinished, still very experimental
    '''
    logger = logging.getLogger()
    
    positions, radii, thetas = aperture_centers(starts)
        
    #===Asymmetric has error map and a co-ord shift for R & B bands(halving)===#
    #error_map = get_error_map(scidata)

    # get median pixel value inside the fireball bounding box
    median_bckgnd = np.median(get_bounding_box(scidata, starts))
    #logger.debug(median_bckgnd)


    if plot:
        plt.close()
        fig = plt.gcf()
        ax = fig.gca()
        plt.imshow(jpeg, cmap=plt.cm.gray)

    #=======In asymmetric, exp_time = nan and aperture_saturated = False=======#

    starts['aperture_sum'] = np.nan
    starts['bckgng_sub_measurements'] = np.nan
    starts['SNR'] = np.nan
    starts['signal'] = np.nan
    starts['exp_time'] = 0.01
    starts['aperture_sum_err'] = np.nan
    starts['aperture_sum_err_plus'] = np.nan
    starts['aperture_sum_err_minus'] = np.nan
    starts['aperture_saturated'] = np.nan

    #===============In asymmetric, shutter open time is calced=================#
    for el, pos, radius, theta in zip(starts, positions, radii, thetas):
        
        zero_order_light = scidata[int(pos[1])][int(pos[0])]
        if zero_order_light >= sat_adu:
            el['aperture_saturated'] = True
        else:
            el['aperture_saturated'] = False
        
        #============Below and above commentout swap for asymmetric============#
        
        #zero_order_saturation_level = float(zero_order_light)/sat_adu
        #=============Switched to RectangularAperture in asymmetric============#
        aperture = CircularAperture(pos, radius*2)
        
        #===In asymmetric, saturation levels assessed here, and mask applied===#
        # do photometry
        aperture_result = aperture_photometry(scidata, aperture)
        
        ## get saturated pixels once photutils 0.4 is available TODO FIXME
        
        el['aperture_sum'] = aperture_result['aperture_sum'].data
        #el['aperture_sum_err'] = aperture_result['aperture_sum_err'].data TODO FIXME
        
        # calculating SNR and error, should bckgng by bckgnd?
        el['bckgng_sub_measurements'] = el['aperture_sum'] -  aperture.area()*median_bckgnd
        el['SNR'] = el['bckgng_sub_measurements'] / np.sqrt(el['bckgng_sub_measurements'] + aperture.area()*median_bckgnd)
        el['aperture_sum_err_plus'] = 1/el['SNR']
        el['aperture_sum_err_minus'] = 1/el['SNR']
        if plot:
            aperture.plot(color='white')

    # plotting something, find out what??
    
    if plot:
        #min_x, min_y, max_x, max_y = get_bounds([p['x_image'] for p in points], pos2)
        margin = 100
        ax.set_xlim([np.min(starts['x_image'])-margin, np.max(starts['x_image'])+margin])
        ax.set_ylim([np.min(starts['y_image'])-margin, np.max(starts['y_image'])+margin])
        
        # saving figure to file
        full_path = starts.meta['self_file_name']
        dirname = os.path.dirname(full_path)
        basename = os.path.basename(full_path).split('.')[0]
        fname = os.path.join(dirname, basename + "_aperture_photometry.jpg")
        #plt.show()
        plt.savefig(fname, dpi=150)

    return starts
Пример #34
0
    setup_config()
    config = load_config()

data_path = path.join(here, 'data', 'instrument')
cache_path = config['DEFAULT']['data_cache_path']
# Photometric aperture contamation calculation from PSF for make_xml_files
pfile = path.join(cache_path, 'Contamination_33arcsec_aperture.p')
psf_path = path.join(data_path, config['psf_file']['psf_file'])
if not path.isfile(pfile) or (path.getmtime(pfile) < path.getmtime(psf_path)):
    radius = 33  # Aperture radius in pixels
    psf_x0 = config['psf_file']['x0']
    psf_y0 = config['psf_file']['y0']
    with open(psf_path) as fp:
        data = [[float(digit) for digit in line.split()] for line in fp]
    position0 = [psf_x0, psf_y0]
    aperture0 = CircularAperture(position0, r=radius)
    photTable0 = aperture_photometry(data, aperture0)
    target_flux = photTable0['aperture_sum'][0]
    rad = np.linspace(0.0, 125, 25, endpoint=True)
    contam = np.zeros_like(rad)
    contam[0] = 1.0
    for i, r in enumerate(rad[1:]):
        nthe = max(4, int(round(r / 5)))
        the = np.linspace(0, 2 * np.pi, nthe)
        pos = np.array((100 + np.array(r * np.cos(the)),
                        100 + np.array(r * np.sin(the)))).T
        apertures = CircularAperture(pos, r=radius)
        photTable = aperture_photometry(data, apertures)
        contam[i + 1] = max(photTable['aperture_sum']) / target_flux
    contam = np.array(contam)  # convert to numpy array else sphinx complains
    I = interp1d(rad, contam, fill_value=min(contam), bounds_error=False)
Пример #35
0
def extract_ifu(input_model, source_type, extract_params):
    """This function does the extraction.

    Parameters
    ----------
    input_model : IFUCubeModel
        The input model.

    source_type : string
        "point" or "extended"

    extract_params : dict
        The extraction parameters for aperture photometry.

    Returns
    -------
    ra, dec : float
        ra and dec are the right ascension and declination respectively
        at the nominal center of the image.

    wavelength : ndarray, 1-D
        The wavelength in micrometers at each pixel.

    net : ndarray, 1-D
        The count rate (counts / s) minus the background at each pixel.

    background : ndarray, 1-D
        The background count rate that was subtracted from the total
        source count rate to get `net`.

    dq : ndarray, 1-D, int32
        The data quality array.
    """

    data = input_model.data
    shape = data.shape
    if len(shape) != 3:
        log.error("Expected a 3-D IFU cube; dimension is %d.", len(shape))
        raise RuntimeError("The IFU cube should be 3-D.")

    # We need to allocate net, background, and dq arrays no matter what.
    net = np.zeros(shape[0], dtype=np.float64)
    background = np.zeros(shape[0], dtype=np.float64)

    dq = np.zeros(shape[0], dtype=np.int32)

    x_center = extract_params['x_center']
    y_center = extract_params['y_center']
    if x_center is None:
        x_center = float(shape[2]) / 2.
    else:
        x_center = float(x_center)
    if y_center is None:
        y_center = float(shape[1]) / 2.
    else:
        y_center = float(y_center)

    method = extract_params['method']
    # subpixels is only needed if method = 'subpixel'.
    subpixels = extract_params['subpixels']

    subtract_background = extract_params['subtract_background']
    smaller_axis = float(min(shape[1], shape[2]))       # for defaults
    if source_type == 'point':
        radius = extract_params['radius']
        if radius is None:
            radius = smaller_axis / 4.
        if subtract_background:
            inner_bkg = extract_params['inner_bkg']
            if inner_bkg is None:
                inner_bkg = radius
            outer_bkg = extract_params['outer_bkg']
            if outer_bkg is None:
                outer_bkg = min(inner_bkg * math.sqrt(2.),
                                smaller_axis / 2. - 1.)
            if inner_bkg <= 0. or outer_bkg <= 0. or inner_bkg >= outer_bkg:
                log.debug("Turning background subtraction off, due to "
                          "the values of inner_bkg and outer_bkg.")
                subtract_background = False
        width = None
        height = None
        theta = None
    else:
        width = extract_params['width']
        if width is None:
            width = smaller_axis / 2.
        height = extract_params['height']
        if height is None:
            height = smaller_axis / 2.
        theta = extract_params['theta'] * math.pi / 180.
        radius = None
        subtract_background = False
        inner_bkg = None
        outer_bkg = None

    log.debug("IFU 1-D extraction parameters:")
    log.debug("  x_center = %s", str(x_center))
    log.debug("  y_center = %s", str(y_center))
    if source_type == 'point':
        log.debug("  radius = %s", str(radius))
        log.debug("  subtract_background = %s", str(subtract_background))
        log.debug("  inner_bkg = %s", str(inner_bkg))
        log.debug("  outer_bkg = %s", str(outer_bkg))
        log.debug("  method = %s", method)
        if method == "subpixel":
            log.debug("  subpixels = %s", str(subpixels))
    else:
        log.debug("  width = %s", str(width))
        log.debug("  height = %s", str(height))
        log.debug("  theta = %s degrees", str(extract_params['theta']))
        log.debug("  subtract_background = %s", str(subtract_background))
        log.debug("  method = %s", method)
        if method == "subpixel":
            log.debug("  subpixels = %s", str(subpixels))

    # Check for out of bounds.
    # The problem with having the background aperture extend beyond the
    # image is that the normalization would not account for the resulting
    # decrease in the area of the annulus, so the background subtraction
    # would be systematically low.
    outside = False
    f_nx = float(shape[2])
    f_ny = float(shape[1])
    if x_center < 0. or x_center >= f_nx - 1. or \
       y_center < 0. or y_center >= f_ny - 1.:
        outside = True
        log.error("Target location is outside the image.")
    if subtract_background and \
       (x_center - outer_bkg < -0.5 or x_center + outer_bkg > f_nx - 0.5 or
        y_center - outer_bkg < -0.5 or y_center + outer_bkg > f_ny - 0.5):
            outside = True
            log.error("Background region extends outside the image.")

    if outside:
        (ra, dec) = (0., 0.)
        wavelength = np.zeros(shape[0], dtype=np.float64)
        dq[:] = dqflags.pixel['DO_NOT_USE']
        return (ra, dec, wavelength, net, background, dq)       # all bad

    if hasattr(input_model.meta, 'wcs'):
        wcs = input_model.meta.wcs
    else:
        log.warning("WCS function not found in input.")
        wcs = None

    if wcs is not None:
        x_array = np.empty(shape[0], dtype=np.float64)
        x_array.fill(float(shape[2]) / 2.)
        y_array = np.empty(shape[0], dtype=np.float64)
        y_array.fill(float(shape[1]) / 2.)
        z_array = np.arange(shape[0], dtype=np.float64) # for wavelengths
        ra, dec, wavelength = wcs(x_array, y_array, z_array)
        nelem = len(wavelength)
        ra = ra[nelem // 2]
        dec = dec[nelem // 2]
    else:
        (ra, dec) = (0., 0.)
        wavelength = np.arange(1, shape[0] + 1, dtype=np.float64)

    position = (x_center, y_center)
    if source_type == 'point':
        aperture = CircularAperture(position, r=radius)
        if subtract_background:
            annulus = CircularAnnulus(position,
                                      r_in=inner_bkg, r_out=outer_bkg)
            normalization = aperture.area() / annulus.area()
    else:
        aperture = RectangularAperture(position, width, height, theta)
        # No background is computed for an extended source.

    for k in range(shape[0]):
        phot_table = aperture_photometry(data[k, :, :], aperture,
                                         method=method, subpixels=subpixels)
        net[k] = float(phot_table['aperture_sum'][0])
        if subtract_background:
            bkg_table = aperture_photometry(data[k, :, :], annulus,
                                            method=method, subpixels=subpixels)
            background[k] = float(bkg_table['aperture_sum'][0])
            net[k] = net[k] - background[k] * normalization

    # Check for NaNs in the wavelength array, flag them in the dq array,
    # and truncate the arrays if NaNs are found at endpoints (unless the
    # entire array is NaN).
    nan_mask = np.isnan(wavelength)
    n_nan = nan_mask.sum(dtype=np.intp)
    if n_nan > 0:
        log.warning("%d NaNs in wavelength array.", n_nan)
        dq[nan_mask] = np.bitwise_or(dq[nan_mask], dqflags.pixel['DO_NOT_USE'])
        not_nan = np.logical_not(nan_mask)
        flag = np.where(not_nan)
        if len(flag[0]) > 0:
            n_trimmed = flag[0][0] + nelem - (flag[0][-1] + 1)
            if n_trimmed > 0:
                log.info("Output arrays have been trimmed by %d elements",
                         n_trimmed)
                slc = slice(flag[0][0], flag[0][-1] + 1)
                wavelength = wavelength[slc]
                net = net[slc]
                background = background[slc]
                dq = dq[slc]
        else:
            dq |= dqflags.pixel['DO_NOT_USE']

    return (ra, dec, wavelength, net, background, dq)
Пример #36
0
def init_centroids(first_image_path,
                   master_flat,
                   master_dark,
                   target_centroid,
                   max_number_stars=10,
                   min_flux=0.2,
                   plots=False):

    first_image = (fits.getdata(first_image_path) - master_dark) / master_flat

    # Clean cosmic rays
    mask, first_image = detect_cosmics(first_image)

    tophat_kernel = Tophat2DKernel(23)
    convolution = convolve_fft(first_image,
                               tophat_kernel,
                               fftn=fft2,
                               ifftn=ifft2)

    convolution -= np.median(convolution)

    from astropy.stats import mad_std
    mad = mad_std(convolution)

    convolution[convolution < -5 * mad] = 0.0

    from skimage.filters import threshold_otsu, threshold_yen
    from skimage.measure import label, regionprops

    thresh = threshold_yen(convolution) / 3.0

    masked = np.ones_like(convolution)
    masked[convolution <= thresh] = 0

    label_image = label(masked)

    # plt.figure()
    # plt.imshow(label_image, origin='lower', cmap=plt.cm.viridis)
    # plt.show()

    regions = regionprops(label_image, convolution)
    centroids = [region.weighted_centroid for region in regions]
    intensities = [region.mean_intensity for region in regions]

    centroids = np.array(centroids)[np.argsort(intensities)[::-1]]

    #positions = np.vstack([sources['xcentroid'], sources['ycentroid']])
    # positions = np.array(centroids).T

    positions = np.vstack([[y for x, y in centroids],
                           [x for x, y in centroids]])

    if plots:
        apertures = CircularAperture(positions, r=12.)
        apertures.plot(color='r', lw=2, alpha=1)
        plt.imshow(first_image,
                   vmin=np.percentile(first_image, 0.01),
                   vmax=np.percentile(first_image, 99.9),
                   cmap=plt.cm.viridis,
                   origin='lower')
        plt.show()
    return positions
Пример #37
0
    #    r_inner_as=r_inner*u.arcsec
    #    r_outer_as=r_outer*u.arcsec
    #    print(r_inner_as,r_outer_as)

    #   sys.exit(0)

    #    time.sleep(1)
    #    print(WCS.world_axis_physical_types)
    #    aperture_pix=aperture.to_pixel(wcs)
    #    print(aperture_pix)
    #    positions_pix=aperture_pix.positions
    #    r_pix=aperture_pix.r
    #    print('r_pix =',r_pix)
    positions_pix = (ra_pix, dec_pix)
    positions_pix = np.transpose(positions_pix)
    aperture_pix = CircularAperture(positions_pix, r_circle)

    mask_circle = aperture_pix.to_mask(method='center')
    mask_data = mask_circle[0].multiply(imdata)

    #    phot_table = aperture_photometry(imdata, aperture,wcs=wcs)
    phot_table = aperture_photometry(imdata, aperture_pix)
    #    print(phot_table)
    #    print(phot_table.colnames)
    #   print(phot_table['sky_center'])
    #    print(phot_table['xcenter'])
    #    print(phot_table['ycenter'])
    aper_sum = phot_table['aperture_sum']
    phot_table[
        'aperture_sum'].info.format = '%.8g'  # for consistent table output
    phot_table['xcenter'].info.format = '%.8g'  # for consistent table output
Пример #38
0
def draw_mask_map(image,
                  seg_map,
                  mask_deep,
                  stars,
                  r_core=None,
                  r_out=None,
                  vmin=None,
                  vmax=None,
                  pad=0,
                  save=False,
                  save_dir='./'):
    """ Visualize mask map """

    from matplotlib import patches

    mu = np.nanmedian(image)
    std = mad_std(image)

    if vmin is None:
        vmin = mu - std
    if vmax is None:
        vmax = mu + 10 * std

    fig, (ax1, ax2, ax3) = plt.subplots(ncols=3,
                                        nrows=1,
                                        figsize=(20, 6),
                                        dpi=100)

    im1 = ax1.imshow(image, cmap='gray', norm=LogNorm(), vmin=vmin, vmax=1e4)
    ax1.set_title("Image")

    n_label = seg_map.max()
    ax2.imshow(seg_map, vmin=1, vmax=n_label - 2, cmap=make_rand_cmap(n_label))
    ax2.set_title("Deep Mask")

    image2 = image.copy()
    image2[mask_deep] = 0
    im3 = ax3.imshow(image2, norm=LogNorm(), vmin=vmin, vmax=vmax)
    ax3.set_title("Sky")
    colorbar(im3, pad=0.1, size="2%")

    if r_core is not None:
        if np.ndim(r_core) == 0:
            r_core = [r_core, r_core]

        star_pos_A = stars.star_pos_verybright + pad
        star_pos_B = stars.star_pos_medbright + pad

        aper = CircularAperture(star_pos_A, r=r_core[0])
        aper.plot(color='lime', lw=2, label="", alpha=0.9, axes=ax3)

        aper = CircularAperture(star_pos_B, r=r_core[1])
        aper.plot(color='c', lw=2, label="", alpha=0.7, axes=ax3)

        if r_out is not None:
            aper = CircularAperture(star_pos_A, r=r_out[0])
            aper.plot(color='lime', lw=1.5, label="", alpha=0.9, axes=ax3)
            aper = CircularAperture(star_pos_B, r=r_out[1])
            aper.plot(color='c', lw=1.5, label="", alpha=0.7, axes=ax3)

    patch_Xsize = image.shape[1] - pad * 2
    patch_Ysize = image.shape[0] - pad * 2
    rec = patches.Rectangle((pad, pad),
                            patch_Xsize,
                            patch_Ysize,
                            facecolor='none',
                            edgecolor='w',
                            linewidth=2,
                            linestyle='--',
                            alpha=0.8)
    ax3.add_patch(rec)

    plt.tight_layout()

    if save:
        plt.savefig(os.path.join(save_dir, "Mask_dual.png"), dpi=100)
        plt.show()
        plt.close()
    else:
        plt.show()
    file = glob.glob(dir + 'final_F8*sci.fits')
    hdu = fits.open(file[0])
    data814, header814 = hdu[0].data, hdu[0].header

    # read in the F160W image
    file = glob.glob(dir + 'final_F1*sci.fits')
    hdu = fits.open(file[0])
    data160, header160 = hdu[0].data, hdu[0].header

    # define positions for photometry
    positions = [(xcen, ycen)]

    # do photometry on F475W image
    flux475 = [0.]
    for radius in radii:
        aperture = CircularAperture(positions, radius)
        phot_table = aperture_photometry(data475, aperture)
        flux475.append(phot_table['aperture_sum'][0])

    # do photometry on F814W image
    flux814 = [0.]
    for radius in radii:
        aperture = CircularAperture(positions, radius)
        phot_table = aperture_photometry(data814, aperture)
        flux814.append(phot_table['aperture_sum'][0])

    # do photometry on F160W image
    flux160 = [0.]
    for radius in radii:
        aperture = CircularAperture(positions, radius)
        phot_table = aperture_photometry(data160, aperture)
Пример #40
0
hdulist = fits.open(inpath+file_name)
image = hdulist[0].data
#image = image.astype(float) - np.median(image)
from photutils import daofind
from astropy.stats import mad_std
bkg_sigma = mad_std(image)
sources = daofind(image, fwhm, threshold*bkg_sigma)
#print_line= (file_name+","+str(sources_2)+"\n")
sources_2 = np.array(sources["id", "xcentroid", "ycentroid", "sharpness", "roundness1", "roundness2", "npix", "sky", "peak", "flux", "mag"])
print_line= (file_name+","+str(sources_2))
file= open(outpath, "a")
file.write(print_line)
file.close()

from photutils import aperture_photometry, CircularAperture
positions = (sources['xcentroid'], sources['ycentroid'])
apertures = CircularAperture(positions, r)
phot_table = aperture_photometry(image, apertures)
phot_table_2 = np.array(phot_table["aperture_sum", "xcenter", "ycenter"])
print_line= (","+str(phot_table_2)+"\n")
file= open(outpath, "a")
file.write(print_line)
file.close()

import matplotlib.pylab as plt
im2 = image
im2[im2<=0]=0.0001
plt.imshow(im2, cmap='gray', origin='lower')
apertures.plot(color='blue', lw=1.5, alpha=0.5)
plt.show()
Пример #41
0
groups = daogroup(intab, crit_separation=2.0*sigma_psf*gaussian_sigma_to_fwhm)

plt.subplot(1, 2, 1)
plt.imshow(image, origin='lower', interpolation='nearest')
plt.title('Simulated data')
plt.xlabel('x-position (pixel units)')
plt.ylabel('y-position (pixel units)')

plt.subplot(1, 2, 2)
for i in range(len(groups)):
    for j in range(len(groups[i]['id'])):
        # show ids
        # plt.text(groups[i]['x_0'][j], groups[i]['y_0'][j],
        #          str(groups[i]['id'][j]))
        aperture = CircularAperture((groups[i]['x_0'][j],
                                     groups[i]['y_0'][j]),
                                     r=sigma_psf*gaussian_sigma_to_fwhm)
        aperture.plot(lw=1.5, alpha=0.5)
tab, residual_image = nstar(image-bkg, groups, (5,5),
                            fitting.LevMarLSQFitter(),
                            IntegratedGaussianPRF, sigma=2.0)
tab.sort('id')
tab.write('starlist_estimated.html')

plt.imshow(residual_image, origin='lower', interpolation='nearest')
plt.title('Residual')
plt.xlabel('x-position (pixel units)')
plt.ylabel('y-position (pixel units)')
plt.show()
Пример #42
0
def init_centroids(first_image_path,
                   master_flat,
                   master_dark,
                   target_centroid,
                   max_number_stars=10,
                   min_flux=0.2,
                   plots=False):

    first_image = (fits.getdata(first_image_path) - master_dark) / master_flat

    kernel = Gaussian2DKernel(5, 5)
    convolution = convolve_fft(first_image, kernel, fftn=fft2, ifftn=ifft2)

    convolution -= np.median(convolution)

    mad = mad_std(convolution)

    convolution[convolution < -5 * mad] = 0.0

    from skimage.filters import threshold_otsu, threshold_yen
    from skimage.measure import label, regionprops

    thresh = threshold_yen(convolution) / 4
    # thresh = threshold_otsu(image=convolution) # Use 10 for 20171104, 15 for all other nights

    masked = np.ones_like(convolution)
    masked[convolution <= thresh] = 0

    label_image = label(masked)

    plt.figure()
    plt.imshow(label_image, origin='lower', cmap=plt.cm.viridis)
    plt.show()

    regions = regionprops(label_image, convolution)

    # reject regions near to edge of detector
    buffer_pixels = 5
    regions = [
        region for region in regions
        if ((region.weighted_centroid[0] > buffer_pixels and region.
             weighted_centroid[0] < label_image.shape[0] - buffer_pixels) and (
                 region.weighted_centroid[1] > buffer_pixels and region.
                 weighted_centroid[1] < label_image.shape[1] - buffer_pixels))
    ]

    # TYC 3561-1538-1 is a delta Scuti variable. Remove it:
    # variable_star = [1790.1645248,  1153.91737674]
    # tol = 100
    # regions = [region for region in regions
    #            if ((region.weighted_centroid[0] > variable_star[0] + tol) or
    #               (region.weighted_centroid[0] < variable_star[0] - tol)) and
    #               ((region.weighted_centroid[1] > variable_star[1] + tol) or
    #               (region.weighted_centroid[1] < variable_star[1] - tol))]

    centroids = np.array([region.weighted_centroid for region in regions])
    intensities = np.array([region.mean_intensity for region in regions])

    sort_order = np.argsort(intensities)[::-1]
    centroids = np.array(centroids)[sort_order]
    intensities = intensities[sort_order]

    positions = np.vstack([[y for x, y in centroids],
                           [x for x, y in centroids]])

    flux_threshold = intensities > min_flux * intensities[0]
    positions = positions[:, flux_threshold]

    if plots:
        apertures = CircularAperture(positions, r=12.)
        apertures.plot(color='r', lw=2, alpha=1)
        plt.imshow(first_image,
                   vmin=np.percentile(first_image, 0.01),
                   vmax=np.percentile(first_image, 99.9),
                   cmap=plt.cm.viridis,
                   origin='lower')
        plt.show()
    return positions
def init_centroids(first_image_path, master_flat, master_dark, target_centroid,
                   max_number_stars=10, min_flux=0.2, plots=False):

    first_image = np.median([(fits.getdata(path) - master_dark)/master_flat
                             for path in first_image_path], axis=0)

    tophat_kernel = Tophat2DKernel(5)
    convolution = convolve_fft(first_image, tophat_kernel, fftn=fft2, ifftn=ifft2)

    convolution -= np.median(convolution)

    mad = mad_std(convolution)

    convolution[convolution < -5*mad] = 0.0

    from skimage.filters import threshold_yen
    from skimage.measure import label, regionprops

    thresh = threshold_yen(convolution)/4 # Use /4 for planet c, /2 for planet b
    #thresh = threshold_otsu(convolution)/15

    masked = np.ones_like(convolution)
    masked[convolution <= thresh] = 0

    label_image = label(masked)

    plt.figure()
    plt.imshow(label_image, origin='lower', cmap=plt.cm.viridis)
    plt.show()

    # regions = regionprops(label_image, convolution)
    regions = regionprops(label_image, first_image)

    # reject regions near to edge of detector
    buffer_pixels = 50
    regions = [region for region in regions
               if ((region.weighted_centroid[0] > buffer_pixels and
                   region.weighted_centroid[0] < label_image.shape[0] - buffer_pixels)
               and (region.weighted_centroid[1] > buffer_pixels and
                    region.weighted_centroid[1] < label_image.shape[1] - buffer_pixels))]

    #centroids = [region.weighted_centroid for region in regions]
    #intensities = [region.mean_intensity for region in regions]

    target_intensity = regions[0].mean_intensity
    target_diameter = regions[0].equivalent_diameter
    #  and region.equivalent_diameter > 0.8 * target_diameter
    centroids = [region.weighted_centroid for region in regions
                 if min_flux * target_intensity < region.mean_intensity]
    # intensities = [region.mean_intensity for region in regions
    #                if min_flux * target_intensity < region.mean_intensity]
#    centroids = np.array(centroids)[np.argsort(intensities)[::-1]]

    distances = [np.sqrt((target_centroid[0] - d[0])**2 +
                         (target_centroid[1] - d[1])**2) for d in centroids]

    centroids = np.array(centroids)[np.argsort(distances)]

    positions = np.vstack([[y for x, y in centroids], [x for x, y in centroids]])

    if plots:
        apertures = CircularAperture(positions, r=12.)
        apertures.plot(color='r', lw=2, alpha=1)
        plt.imshow(first_image, vmin=np.percentile(first_image, 0.01),
                   vmax=np.percentile(first_image, 99.9), cmap=plt.cm.viridis,
                   origin='lower')
        plt.scatter(positions[0, 0], positions[1, 0], s=150, marker='x')

        plt.show()
    return positions
def test_mrs_spec3():
    """ 
	Test the extract1d step when reducing MRS data in spec3
	"""

    import tkinter as tk  #  TKinter imported for a dialog box for choosing the file
    from tkinter import filedialog  # TKinter also seems to be needed for matplotlib plots

    root = tk.Tk()
    root.withdraw()
    #read in cube from cube_build step that immediately precedes extract_1d step in Level 3
    cubefile = "/Users/sargent/mirisim/20180813_123620_mirisim/det_images/nod4point_ch1-short_s3d.fits"
    with fits.open(cubefile) as hduin:  # open the cube file
        firstpart = cubefile[
            0:len(cubefile) -
            5]  #a string with the part of the file path except the .fits extension
        tempfilepath = firstpart + '_temp.fits'  # file name for temporary file
        fake_data = hduin['SCI'].data  # read in cube
        print(fake_data.shape)
        fake_data[0:, 0:, 0:] = 0.0  # zero out all the pixels in the cube
        fake_data[
            0:, 10,
            10] = 100.0  # add in a fake point source continuum in the zeroed-out cube
        fake_data[0:, 10, 9] = 50.0  # same
        fake_data[0:, 9, 10] = 50.0  # same
        fake_data[0:, 11, 10] = 50.0  # same
        fake_data[0:, 10, 11] = 50.0  # same

        fake_data[
            399, 10,
            10] = 150.0  # add in fake point source emission line in zeroed-out cube
        fake_data[399, 10, 9] = 75.0  # same
        fake_data[399, 9, 10] = 75.0  # same
        fake_data[399, 11, 10] = 75.0  # same
        fake_data[399, 10, 11] = 75.0  # same

        fake_data[400, 10, 10] = 200.0  # same
        fake_data[400, 10, 9] = 100.0  # same
        fake_data[400, 9, 10] = 100.0  # same
        fake_data[400, 11, 10] = 100.0  # same
        fake_data[400, 10, 11] = 100.0  # same

        fake_data[401, 10, 10] = 150.0  # same
        fake_data[401, 10, 9] = 75.0  # same
        fake_data[401, 9, 10] = 75.0  # same
        fake_data[401, 11, 10] = 75.0  # same
        fake_data[401, 10, 11] = 75.0  # same
        hduin.writeto(
            tempfilepath,
            overwrite=True)  # save the file with the fake signal in the cube

    apphotflux = np.zeros(fake_data.shape[0])
    for j in range(
            fake_data.shape[0]
    ):  # go through each slice of zeroed-out cube with fake signal
        position = [(10, 10)]
        aperture = CircularAperture(
            position,
            r=3.)  # perform aperture photometry on slice on fake signal
        phot_table = aperture_photometry(fake_data[j, :, :], aperture)
        apphotflux[j] = phot_table['aperture_sum']

    import matplotlib.pyplot as plt  # this is needed to make plots

    #run the extract1d step
    result = Extract1dStep.call(
        tempfilepath,
        config_file=
        "/Users/sargent/func/inst/nirspec/pipelinetesting/maria/configs72/extract_1d_mrs3.cfg"
    )
    # perform extract_1d step on cube with fake signal
    outextractfile = '/Users/sargent/mirisim/20180813_123620_mirisim/det_images/extract1dmrs3out.fits'
    result.save(outextractfile)  # save the result of the extract1d step
    with fits.open(outextractfile) as hdubackin:
        wl1d = hdubackin['EXTRACT1D'].data[
            'wavelength']  # read spectrum from extract1d step
        fl1d = hdubackin['EXTRACT1D'].data['flux']
        er1d = hdubackin['EXTRACT1D'].data['error']
        plt.plot(wl1d, fl1d, '.', color='r',
                 markersize=4)  # plot spectrum from extract1d step
        plt.plot(wl1d, apphotflux, '.', color='b',
                 markersize=1)  #overplot spectrum extracted
        plt.xlabel('wavelength (microns)'
                   )  # by doing aperture photometry on cube slices
        plt.ylabel('flux (Jy)')
        plt.title('Spectrum from Extract1d')
        plt.show()  # show the spectrum

    relerror = (
        fl1d - apphotflux) / apphotflux  # compute relative difference spectrum
    maxrelerr = max(
        relerror)  # compute the maximum of the relative difference spectrum
    print("Maximum Relative Error for MRS Slit Level 3")
    print(maxrelerr)
    plt.plot(wl1d, relerror, '-',
             color='r')  # plot the relative difference spectrum
    plt.xlabel('wavelength (microns)')
    plt.ylabel('relative error (fraction)')
    plt.title('Relative Error for MRS Slit Level 3')
    plt.show()
Пример #45
0
def photom_av(ima, pos, radius, r_in=False, r_out=False, mode='median'):
    '''
    Aperture photometry in an aperture located at pixel coordinates 
    pos = ( (x0, y0), (x1, y1), ... ) with a radius=radius.
    When r_in and r_out are given, background is estimated in CircularAnnulus and subtracted.
    
    mode refers to how the background is estimated within the circlar annulus.
    Can be 'median' or 'mean'
    
    Photometry is calculating by median averaging the pixels within the aperture and 
    multiplying by the number of pixels in the aperture (including fractions of pixels).

    '''
    # Setting up the mask 
    if hasattr(ima, 'mask'):
      if ima.mask.size == 1:
	mask = np.zeros(ima.shape, dtype=np.bool) | ima.mask
      else:
        mask = ima.mask.copy()
    else:
        mask = np.zeros(ima.shape, dtype=np.bool)
        
        
    ### Performing the actual photometry - identical for each method
    # Median averaging of flux in aperture
    # Setting up the aperture 
    apertures = CircularAperture(pos, r = radius) 
    ap_mask = apertures.to_mask(method='center')
    # Setting up arrays to store data
    nflx = len(ap_mask)
    flx = np.zeros(nflx, dtype=np.float)
    flux_max = np.zeros(nflx, dtype=np.float)
    flux_min = np.zeros(nflx, dtype=np.float)
    # Median averaging of flux
    for i, am in enumerate(ap_mask):
      fluxmask = ~mask & am.to_image(shape=mask.shape).astype(np.bool)
      flx[i] = np.median(ima[fluxmask])
      flux_max[i] = np.max(ima[fluxmask])
      flux_min[i] = np.min(ima[fluxmask])
      
      
      
      
    # Aperture photometry on mask to see how many masked pixels are in the 
    # aperture
    apm       = aperture_photometry(mask.astype(int), apertures)
    # Number of unmasked pixels in aperture
    ap_area   = Column(name = 'area_aper',
		       data=apertures.area() - apm['aperture_sum'].data)
    
    # Flux in aperture using median av flux and fractional no. pixels in aperture
    flux_init = flx*ap_area
    

    ### Two different modes for analysing the background
    if ( r_in and r_out and mode in ('mean', 'median') ):
      
      ### This stuff is the same regardless of method
      # Setting up the annulus
      anulus_apertures = CircularAnnulus(pos, r_in=r_in, r_out=r_out)
      # Performing annulus photometry on the mask
      bkgm = aperture_photometry(mask.astype(int), anulus_apertures)
      # Number of masked pixels in bkg
      mbkg_area = Column(name = 'bpix_bkg',
			 data=bkgm['aperture_sum'])  
      # Number of non-masked pixels in aperture and bkg        
      bkg_area  = Column(name = 'area_bkg',
			 data=anulus_apertures.area() - bkgm['aperture_sum'])
      
      
      ### This stuff is specific to the mean
      if mode == 'mean':
	# Perform the annulus photometry on the image
	bkg  = aperture_photometry(ima, anulus_apertures, mask=mask)
        # Average bkg where this divides by only number of NONMASKED pixels
        # as the aperture photometry ignores the masked pixels
        bkga = Column(name='background',
		      data=bkg['aperture_sum']/bkg_area)
        # Bkg subtracted flux
        flux = flux_init - bkga*ap_area
        # Adding that data
        ap.add_column(bkga)
        
        
      elif mode == 'median':
	# Number of pixels in the annulus, a different method
	aperture_mask = anulus_apertures.to_mask(method='center')
	nbkg = len(aperture_mask)
	
	# Background mask
	bkgm = np.zeros(nbkg, dtype=np.float)
	
	# Median averaging
	for i, am in enumerate(aperture_mask):
	  bmask = ~mask & am.to_image(shape=mask.shape).astype(np.bool)
	  bkgm[i] = np.median(ima[bmask])
		
	flux = flux_init - bkgm*ap_area
	bkgm = Column(name = 'background', data = bkgm)

        
    return flux, apm, flx, ap_area, flux_max, flux_min #flux, no.masked pixels in ap, median av flux
Пример #46
0
def draw_comparison_2D(data,
                       mask,
                       image_fit,
                       image_stars,
                       bkg_image,
                       noise_image=0,
                       r_core=None,
                       vmin=None,
                       vmax=None,
                       Gain=None,
                       cmap='gnuplot2',
                       norm=AsinhNorm(0.05),
                       manual_locations=None,
                       save=False,
                       save_dir=".",
                       suffix=""):
    """ Compare data and fit in 2D """

    mask_fit = getattr(mask, 'mask_comb', mask.mask_deep)

    std = np.std(image_fit[~mask_fit])
    if vmin is None:
        vmin = np.mean(bkg_image) - std
    if vmax is None:
        vmax = vmin + min([10 * std, 100])

    norm2 = deepcopy(norm)

    fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(2,
                                                           3,
                                                           figsize=(19, 11))

    im = ax1.imshow(data, vmin=vmin, vmax=vmax, norm=norm, cmap=cmap)
    ax1.set_title("Data [I$_0$]", fontsize=15)
    colorbar(im)

    im = ax2.imshow(image_fit + noise_image,
                    vmin=vmin,
                    vmax=vmax,
                    norm=norm,
                    cmap=cmap)
    ax2.set_title("Fit [I$_f$] + noise", fontsize=15)
    colorbar(im)

    im = ax3.imshow(image_stars,
                    vmin=0,
                    vmax=vmax - vmin,
                    norm=norm2,
                    cmap=cmap)
    contour = ax3.contour(image_stars,
                          levels=[0, 1, 2, 5, 10, 25],
                          norm=norm2,
                          colors='w',
                          alpha=0.7)
    ax3.clabel(contour,
               fmt='%1g',
               inline=1,
               fontsize=12,
               manual=manual_locations)
    ax3.set_title("Bright Stars [I$_{f,B}$]", fontsize=15)
    colorbar(im)

    if Gain is None:
        frac_diff = (image_fit - data) / data
        im = ax4.imshow(frac_diff, vmin=-0.1, vmax=0.1, cmap="bwr")
        ax4.set_title("Frac. Diff. [(I$_f$ - I$_0$)/I$_0$]", fontsize=15)
        colorbar(im)
    else:
        uncertainty = np.sqrt(
            np.std(noise_image)**2 + (image_fit - bkg_image) / Gain)
        chi = (image_fit - data) / uncertainty
        # chi[mask_fit] = 0
        im = ax4.imshow(chi, vmin=-5, vmax=5, cmap="coolwarm")
        ax4.set_title("$\chi$ [(I$_f$ - I$_0$)/$\sigma$]", fontsize=15)
        colorbar(im)

    residual = (data - image_stars)
    im = ax5.imshow(residual, vmin=vmin, vmax=vmax, norm=norm, cmap=cmap)
    ax5.set_title("Bright Subtracted [I$_0$ - I$_{f,B}$]", fontsize=15)
    colorbar(im)

    residual[mask_fit] = 0
    im = ax6.imshow(residual, vmin=vmin, vmax=vmax, norm=norm, cmap=cmap)
    ax6.set_title("Bright Subtracted (masked)", fontsize=15)
    colorbar(im)

    if r_core is not None:
        if np.ndim(r_core) == 0:
            r_core = [r_core, r_core]
        aper1 = CircularAperture(mask.stars.star_pos_verybright, r=r_core[0])
        aper1.plot(color='lime', lw=2, alpha=0.95, axes=ax6)
        aper2 = CircularAperture(mask.stars.star_pos_medbright, r=r_core[1])
        aper2.plot(color='skyblue', lw=2, label="", alpha=0.85, axes=ax6)

    plt.tight_layout()
    if save:
        plt.savefig(os.path.join(save_dir,
                                 "Comparison_fit_data2D%s.png" % suffix),
                    dpi=100)
        plt.show()
        plt.close()
    else:
        plt.show()
Пример #47
0
def runPhotUtils(targname, filt, jdanUse=None, saveDir='./'):

    if filt == 'F606W':
        # EEband = 0.839  # 4 pixel
        EEband = 0.795
        ZPT = 26.667
        fils = '_f606w/'

    elif filt == 'F814W':
        # EEband = 0.830  # 4 pixels
        EEband = 0.77
        ZPT = 26.779
        fils = '_f814w/'

    for ff in range(len(jdanUse)):
        image = targname + fils + '/crClean/' + jdanUse[ff] + '_WJ2.fits'

        hdu = fits.open(image)
        sci = hdu[0].data
        hdr = hdu[0].header
        hdu.close()

        outname = saveDir + jdanUse[ff] + '_' + filt + 'photU.dat'

        # print(type(saveDir))
        # print(type(jdanUse[ff]))
        # print(type(filt))
        data = sci.copy()

        mean, median, std = sigma_clipped_stats(data, sigma=3.0, maxiters=10)

        daofind = DAOStarFinder(fwhm=2.5, threshold=5. * std)
        sources = daofind(data - median)

        loc = np.array([sources['xcentroid'], sources['ycentroid']])
        positions = np.transpose(loc)

        apertures_r3 = CircularAperture(positions, r=3.)
        rawflux_r3 = aperture_photometry(data, apertures_r3)

        annulus_apertures = CircularAnnulus(positions, r_in=9., r_out=12.)

        annulus_masks = annulus_apertures.to_mask(method='center')

        bkg_median = []
        for mask in annulus_masks:

            annulus_data = mask.multiply(data)
            annulus_data_1d = annulus_data[mask.data > 0]
            _, median_sigclip, _ = sigma_clipped_stats(annulus_data_1d)
            bkg_median.append(median_sigclip)

        bkg_median = np.array(bkg_median)

        rawflux_r3['annulus_median'] = bkg_median
        rawflux_r3['aper_bkg'] = bkg_median * apertures_r3.area

        rawflux_r3['final_phot'] = rawflux_r3['aperture_sum'] \
            - rawflux_r3['aper_bkg']

        mask_negative = (rawflux_r3['final_phot'] > 0)
        rawflux_pos_r3 = rawflux_r3[mask_negative]

        final_phot = -2.5 * np.log10(rawflux_pos_r3['final_phot'] / EEband) \
            + 2.5 * np.log10(hdr['exptime']) + ZPT

        rawflux_pos_r3['magr'] = final_phot

        rawflux_pos_r3['id'] = np.arange(0, len(rawflux_pos_r3), 1)

        s0 = ' '
        header = s0.join(rawflux_pos_r3.dtype.names)

        outname = saveDir + jdanUse[ff] + '_' + filt + 'photU.dat'

        np.savetxt(outname, rawflux_pos_r3, header=header)

    return None
Пример #48
0
def tso_aperture_photometry(datamodel, xcenter, ycenter, radius, radius_inner,
                            radius_outer):
    """
    Create a photometric catalog for NIRCam TSO imaging observations.

    Parameters
    ----------
    datamodel : `CubeModel`
        The input `CubeModel` of a NIRCam TSO imaging observation.

    xcenter, ycenter : float
        The ``x`` and ``y`` center of the aperture.

    radius : float
        The radius (in pixels) of the circular aperture.

    radius_inner, radius_outer : float
        The inner and outer radii (in pixels) of the circular-annulus
        aperture, used for local background estimation.

    Returns
    -------
    catalog : `~astropy.table.QTable`
        An astropy QTable (Quantity Table) containing the source
        photometry.
    """

    if not isinstance(datamodel, CubeModel):
        raise ValueError('The input data model must be a CubeModel.')

    # For the SUB64P subarray with the WLP8 pupil, the circular aperture
    # extends beyond the image and the circular annulus does not have any
    # overlap with the image.  In that case, we simply sum all values
    # in the array and skip the background subtraction.
    sub64p_wlp8 = False
    if (datamodel.meta.instrument.pupil == 'WLP8' and
            datamodel.meta.subarray.name == 'SUB64P'):
        sub64p_wlp8 = True

    if not sub64p_wlp8:
        phot_aper = CircularAperture((xcenter, ycenter), r=radius)
        bkg_aper = CircularAnnulus((xcenter, ycenter), r_in=radius_inner,
                                   r_out=radius_outer)

    aperture_sum = []
    aperture_sum_err = []
    annulus_sum = []
    annulus_sum_err = []

    nimg = datamodel.data.shape[0]

    if sub64p_wlp8:
        info = ('Photometry measured as the sum of all values in the '
               'subarray.  No background subtraction was performed.')

        for i in np.arange(nimg):
            aperture_sum.append(np.sum(datamodel.data[i, :, :]))
            aperture_sum_err.append(
                np.sqrt(np.sum(datamodel.err[i, :, :]**2)))
    else:
        info = ('Photometry measured in a circular aperture of r={0} '
                'pixels.  Background calculated as the mean in a '
                'circular annulus with r_inner={1} pixels and '
                'r_outer={2} pixels.'.format(radius, radius_inner,
                                                radius_outer))
        for i in np.arange(nimg):
            aper_sum, aper_sum_err = phot_aper.do_photometry(
                datamodel.data[i, :, :], error=datamodel.err[i, :, :])
            ann_sum, ann_sum_err = bkg_aper.do_photometry(
                datamodel.data[i, :, :], error=datamodel.err[i, :, :])

            aperture_sum.append(aper_sum[0])
            aperture_sum_err.append(aper_sum_err[0])
            annulus_sum.append(ann_sum[0])
            annulus_sum_err.append(ann_sum_err[0])

    aperture_sum = np.array(aperture_sum)
    aperture_sum_err = np.array(aperture_sum_err)
    annulus_sum = np.array(annulus_sum)
    annulus_sum_err = np.array(annulus_sum_err)

    # construct metadata for output table
    meta = OrderedDict()
    meta['instrument'] = datamodel.meta.instrument.name
    meta['detector'] = datamodel.meta.instrument.detector
    meta['channel'] = datamodel.meta.instrument.channel
    meta['subarray'] = datamodel.meta.subarray.name
    meta['filter'] = datamodel.meta.instrument.filter
    meta['pupil'] = datamodel.meta.instrument.pupil
    meta['target_name'] = datamodel.meta.target.catalog_name
    meta['xcenter'] = xcenter
    meta['ycenter'] = ycenter
    ra_icrs, dec_icrs = datamodel.meta.wcs(xcenter, ycenter)
    meta['ra_icrs'] = ra_icrs
    meta['dec_icrs'] = dec_icrs
    meta['apertures'] = info

    # initialize the output table
    tbl = QTable(meta=meta)

    if hasattr(datamodel, 'int_times') and datamodel.int_times is not None:
        nrows = len(datamodel.int_times)
    else:
        nrows = 0
    if nrows == 0:
        log.warning("There is no INT_TIMES table in the input file.")

    if nrows > 0:
        shape = datamodel.data.shape
        if len(shape) == 2:
            num_integ = 1
        else:                                   # len(shape) == 3
            num_integ = shape[0]
        int_start = datamodel.meta.exposure.integration_start
        if int_start is None:
            int_start = 1
            log.warning("INTSTART not found; assuming a value of %d",
                        int_start)

        # Columns of integration numbers & times of integration from the
        # INT_TIMES table.
        int_num = datamodel.int_times['integration_number']
        mid_utc = datamodel.int_times['int_mid_MJD_UTC']
        offset = int_start - int_num[0]                 # both are one-indexed
        if offset < 0:
            log.warning("Range of integration numbers in science data extends "
                        "outside the range in INT_TIMES table.")
            log.warning("Can't use INT_TIMES table.")
            del int_num, mid_utc
            nrows = 0                   # flag as bad
        else:
            log.debug("Times are from the INT_TIMES table.")
            time_arr = mid_utc[offset: offset + num_integ]
            int_times = Time(time_arr, format='mjd', scale='utc')
    else:
        log.debug("Times were computed from EXPSTART and TGROUP.")

        dt = (datamodel.meta.exposure.group_time *
              (datamodel.meta.exposure.ngroups + 1))
        dt_arr = (np.arange(1, 1 + datamodel.meta.exposure.nints) *
                  dt - (dt / 2.))
        int_dt = TimeDelta(dt_arr, format='sec')
        int_times = (Time(datamodel.meta.exposure.start_time, format='mjd') +
                     int_dt)

    tbl['MJD'] = int_times.mjd

    tbl['aperture_sum'] = aperture_sum
    tbl['aperture_sum_err'] = aperture_sum_err

    if not sub64p_wlp8:
        tbl['annulus_sum'] = annulus_sum
        tbl['annulus_sum_err'] = annulus_sum_err

        annulus_mean = annulus_sum / bkg_aper.area()
        annulus_mean_err = annulus_sum_err / bkg_aper.area()
        tbl['annulus_mean'] = annulus_mean
        tbl['annulus_mean_err'] = annulus_mean_err

        aperture_bkg = annulus_mean * phot_aper.area()
        aperture_bkg_err = annulus_mean_err * phot_aper.area()
        tbl['aperture_bkg'] = aperture_bkg
        tbl['aperture_bkg_err'] = aperture_bkg_err

        net_aperture_sum = aperture_sum - aperture_bkg
        net_aperture_sum_err = np.sqrt(aperture_sum_err ** 2 +
                                       aperture_bkg_err ** 2)
        tbl['net_aperture_sum'] = net_aperture_sum
        tbl['net_aperture_sum_err'] = net_aperture_sum_err
    else:
        colnames = ['annulus_sum', 'annulus_sum_err', 'annulus_mean',
                    'annulus_mean_err', 'aperture_bkg', 'aperture_bkg_err']
        for col in colnames:
            tbl[col] = np.full(nimg, np.nan)

        tbl['net_aperture_sum'] = aperture_sum
        tbl['net_aperture_sum_err'] = aperture_sum_err

    return tbl
Пример #49
0
        kern = np.ones((growarray,growarray))
        pommap2040=ndimage.convolve(pommap2040, kern, mode='constant', cval=0.0)
        pommap2040[np.where(pommap2040>1.0)]=1.0

        #Merge the GR150C and GR150R images and shift if necessary when placing within the full detector
        if k==0:
            pommap[4+yoff:2044+yoff,4+xoff:2044+xoff]=pommap2040
            pomintens[4:2044,4:2044]=grismminusmeasuredata[k]*pommap[4:2044,4:2044]
        else:
            pommap[4+yoff:2044+yoff,4+xoff:2044+xoff]=np.maximum(pommap[4+yoff:2044+yoff,4+xoff:2044+xoff],pommap2040)        
            pomintens[4:2044,4:2044]=np.maximum(pomintens[4:2044,4:2044],(grismminusmeasuredata[k]*pommap[4:2044,4:2044]))

    #Set constant high value in central regions of coronagraphic spots as too noisy to measure in flats 
    #Iterate over the four spots
    for k in range(4):
        coroaperture = CircularAperture(corocen[k,:], r=corodarkradius[k])
        coro_obj_mask = coroaperture.to_mask(method='center')
        coro_obj_mask_corr=2.0*coro_obj_mask.data
        pomintens[corocenfloor[k,1]-corodarkradius[k]:corocenfloor[k,1]+corodarkradius[k]+1,corocenfloor[k,0]-corodarkradius[k]:corocenfloor[k,0]+corodarkradius[k]+1]+=coro_obj_mask_corr

    #Replace pixels with intensity>0.98 to 1.00 as even though centres of spots in CV3 had values of a few percent this was probably scattered
    w=np.where(pomintens>0.98)
    pomintens[w]=1.00

    #Interpolate across bad pixels if at least 3 out of 4 corner neighbours are in POM mask
    pomintensfixbadpix=deepcopy(pomintens)
    for j in range(numbadpix):
        y=donotuseindices[0][j]
        x=donotuseindices[1][j]
        #Do not include reference pixels
        if y>3 and y<2044 and x>3 and x<2044:
Пример #50
0
def circle(pos, r):
    return CircularAperture(pos, r)
Пример #51
0
objects = sep.extract(
    A_rN_img,
    thresh=2.5,
    clean=True,
    mask=elip_mask_gal + star_mask,
    deblend_nthresh=8,
    minarea=5,
    deblend_cont=0.0005,
)
peak_filter = np.where(objects["peak"] < 30)

x_sep = objects["x"][peak_filter]
y_sep = objects["y"][peak_filter]

positions = [(x, y) for x, y in zip(x_sep, y_sep)]
apertures = CircularAperture(positions, r=4)
plt.figure(figsize=(16, 16))
plt.imshow(A_rN_img, origin="lower", cmap="CMRmap", vmin=1, vmax=8.)
apertures.plot(color="green")

# Add on the eliptical and star masks
ax = plt.gca()
elip_gal = Ellipse((xe, ye),
                   width,
                   length,
                   angle=alpha * (180 / np.pi),
                   fill=False,
                   color="white")
ax.add_artist(elip_gal)
for star in galaxy_info["star_mask"]:
    ax.add_artist(
Пример #52
0
def limiting_magnitude_prob(syntax, image, model=None, r_table=None):
    '''
    syntax - dict
        dDtionary of input paramters
    image - np.array
        Image of region of interest with target in center of image
    model - function
        - psf function from autophot
    '''
    try:

        from photutils import CircularAperture
        import matplotlib.pyplot as plt
        import numpy as np
        import matplotlib.gridspec as gridspec
        import random
        from scipy.optimize import curve_fit
        import warnings
        from photutils.datasets import make_noise_image
        # from autophot.packages.functions import mag
        from photutils import DAOStarFinder
        from astropy.stats import sigma_clipped_stats
        # from matplotlib.ticker import MultipleLocator
        from mpl_toolkits.axes_grid1 import make_axes_locatable
        from autophot.packages.rm_bkg import rm_bkg

        from astropy.visualization import ZScaleInterval

        import logging

        logger = logging.getLogger(__name__)

        limiting_mag_figure = plt.figure(figsize=set_size(240, aspect=1.5))

        gs = gridspec.GridSpec(2, 2, hspace=0.5, wspace=0.2)
        ax0 = limiting_mag_figure.add_subplot(gs[:, :-1])

        ax1 = limiting_mag_figure.add_subplot(gs[-1, -1])
        ax2 = limiting_mag_figure.add_subplot(gs[:-1, -1])

        # level for detection - Rule of thumb ~ 5 is a good detection level
        level = syntax['lim_SNR']

        logger.info('Limiting threshold: %d sigma' % level)

        image_no_surface, surface = rm_bkg(image, syntax, image.shape[0] / 2,
                                           image.shape[0] / 2)

        # =============================================================================
        # find and mask sources in close up
        # =============================================================================

        image_mean, image_median, image_std = sigma_clipped_stats(
            image,
            sigma=syntax['source_sigma_close_up'],
            maxiters=syntax['iters'])

        daofind = DAOStarFinder(fwhm=syntax['fwhm'],
                                threshold=syntax['bkg_level'] * image_std)

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            # ignore no sources warning
            sources = daofind(image - image_median)

        if sources != None:
            positions = list(
                zip(np.array(sources['xcentroid']),
                    np.array(sources['ycentroid'])))

            positions.append((image.shape[0] / 2, image.shape[1] / 2))

        else:
            positions = [(image.shape[0] / 2, image.shape[1] / 2)]

        # "size" of source
        source_size = syntax['image_radius']

        pixel_number = int(np.ceil(np.pi * source_size**2))

        # Mask out target region
        mask_ap = CircularAperture(positions, r=source_size)

        mask = mask_ap.to_mask(method='center')

        mask_sumed = [i.to_image(image.shape) for i in mask]

        if len(mask_sumed) != 1:
            mask_sumed = sum(mask_sumed)
        else:
            mask_sumed = mask_sumed[0]

        mask_sumed[mask_sumed > 0] = 1

        logging.info('Number of pixels in star: %d' % pixel_number)

        # Mask out center region
        mask_image = (image_no_surface) * (1 - mask_sumed)

        vmin, vmax = (ZScaleInterval(nsamples=1500)).get_limits(mask_image)

        excluded_points = mask_image == 0
        exclud_x = excluded_points[0]
        exclud_y = excluded_points[1]

        exclud_zip = list(zip(exclud_x, exclud_y))

        included_points = np.where(mask_image != 0)

        includ_x = list(included_points[0])
        includ_y = list(included_points[1])

        includ_zip = list(zip(includ_x, includ_y))

        # ax2.scatter(exclud_y,exclud_x,color ='black',marker = 'X',alpha = 0.5  ,label = 'excluded_pixels',zorder = 1)
        ax2.scatter(includ_y,
                    includ_x,
                    color='red',
                    marker='x',
                    alpha=0.5,
                    label='included_pixels',
                    zorder=2)

        number_of_points = 300

        fake_points = {}

        if len(includ_zip) < pixel_number:
            includ_zip = includ_zip + exclud_zip

        for i in range(number_of_points):
            fake_points[i] = []
            # count = 0
            random_pixels = random.sample(includ_zip, pixel_number)
            xp_ran = [i[0] for i in random_pixels]
            yp_ran = [i[1] for i in random_pixels]

            fake_points[i].append([xp_ran, yp_ran])

        fake_sum = {}
        for i in range(number_of_points):

            fake_sum[i] = []

            for j in fake_points[i]:

                for k in range(len(j[0])):

                    fake_sum[i].append(image_no_surface[j[0][k]][j[1][k]])

        fake_mags = {}

        for f in fake_sum.keys():

            fake_mags[f] = np.sum(fake_sum[f])

# =============================================================================
#     Histogram
# =============================================================================

        hist, bins = np.histogram(list(fake_mags.values()),
                                  bins=len(list(fake_mags.values())),
                                  density=True)

        center = (bins[:-1] + bins[1:]) / 2

        sigma_guess = np.nanstd(list(fake_mags.values()))
        mean_guess = np.nanmean(list(fake_mags.values()))
        A_guess = np.nanmax(hist)

        def gauss(x, a, x0, sigma):
            return a * np.exp(-(x - x0)**2 / (2 * sigma**2))

        popt, pcov = curve_fit(gauss,
                               center,
                               hist,
                               p0=[A_guess, mean_guess, sigma_guess],
                               absolute_sigma=True)

        mean = popt[1]
        std = abs(popt[2])

        logging.info('Mean: %s - std: %s' % (round(mean, 3), round(std, 3)))

        if syntax['probable_detection_limit']:

            beta = float(syntax['probable_detection_limit_beta'])

            def detection_probability(n, sigma, beta):
                from scipy.special import erfinv
                '''

                Probabilistic upper limit computation base on:
                http://web.ipac.caltech.edu/staff/fmasci/home/mystats/UpperLimits_FM2011.pdf

                Assuming Gassauin nose distribution

                n: commonly used threshold value integer above some background level

                sigma: sigma value from noise distribution found from local area around source

                beta: Detection probability


                '''
                flux_upper_limit = (n +
                                    np.sqrt(2) * erfinv(2 * beta - 1)) * sigma

                return flux_upper_limit

            logging.info("Using Probable detection limit [b' = %d%% ]" %
                         (100 * beta))

            f_ul = mean + detection_probability(level, std, beta)

            logging.info("Flux Upper limit: %.3f" % f_ul)

        else:
            f_ul = abs(mean + level * std)
            logging.info('Detection at %s std: %.3f' % (level, f_ul))

        # =============================================================================
        # Plot histogram of background values
        # =============================================================================

        line_kwargs = dict(alpha=0.5, color='black', ls='--')

        # the histogram of the data
        n, bins, patches = ax0.hist(list(fake_mags.values()),
                                    density=True,
                                    bins=30,
                                    facecolor='blue',
                                    alpha=1,
                                    label='Pseudo-Flux\nDistribution')

        ax0.axvline(mean, **line_kwargs)
        ax0.axvline(mean + 1 * std, **line_kwargs)
        ax0.text(mean + 1 * std,
                 np.max(n),
                 r'$1\sigma$',
                 rotation=-90,
                 va='top')
        ax0.axvline(mean + 2 * std, **line_kwargs)
        ax0.text(mean + 2 * std,
                 np.max(n),
                 r'$2\sigma$',
                 rotation=-90,
                 va='top')

        if syntax['probable_detection_limit']:

            ax0.axvline(f_ul, **line_kwargs)
            ax0.text(f_ul,
                     np.max(n),
                     r"$\beta'$ = %d%%" % (100 * beta),
                     rotation=-90,
                     va='top')

        else:
            ax0.axvline(f_ul, **line_kwargs)
            ax0.text(mean + level * std,
                     np.max(n),
                     r'$' + str(level) + r'\sigma$',
                     rotation=-90,
                     va='top')

        x_fit = np.linspace(ax0.get_xlim()[0], ax0.get_xlim()[1], 250)

        ax0.plot(x_fit, gauss(x_fit, *popt), label='Gaussian Fit', color='red')

        ax0.ticklabel_format(axis='y', style='sci', scilimits=(-2, 0))
        ax0.yaxis.major.formatter._useMathText = True

        ax0.set_xlabel('Pseudo-Flux')
        ax0.set_ylabel('Normalised Probability')

        im2 = ax2.imshow(image - surface,
                         origin='lower',
                         aspect='auto',
                         interpolation='nearest')
        divider = make_axes_locatable(ax2)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = limiting_mag_figure.colorbar(im2, cax=cax)
        cb.ax.set_ylabel('Counts', rotation=270, labelpad=10)

        cb.formatter.set_powerlimits((0, 0))
        cb.ax.yaxis.set_offset_position('left')
        cb.update_ticks()

        ax2.set_title('Image - Surface')

        # =============================================================================
        # Convert counts to magnitudes
        # =============================================================================

        flux = f_ul / syntax['exp_time']

        mag_level = -2.5 * np.log10(flux)

        # =============================================================================
        # We now have an upper and lower estimate of the the limiting magnitude
        # =============================================================================
        '''
        Visual display of limiting case

        if PSF model is available use that

        else

        use a gaussian profile with the same number of counts
        '''
        fake_sources = np.zeros(image.shape)

        try:

            if syntax['c_counts']:
                pass

            model_label = 'PSF'

            def mag2image(m):
                '''
                Convert magnitude to height of PSF
                '''
                Amplitude = (syntax['exp_time'] /
                             (syntax['c_counts'] + syntax['r_counts'])) * (
                                 10**(m / -2.5))

                return Amplitude

            # PSF model that matches close-up shape around target
            def input_model(x, y, flux):
                return model(x, y, 0, flux, r_table, pad_shape=image.shape)

        except:
            '''
            if PSF model isn't available - use Gaussian instead

            '''
            logging.info('PSF model not available - Using Gaussian')
            model_label = 'Gaussian'

            sigma = syntax['fwhm'] / 2 * np.sqrt(2 * np.log(2))

            def mag2image(m):
                '''
                Convert magnitude to height of Gaussian
                '''

                #  Volumne/counts under 2d gaussian for a magnitude m
                volume = (10**(m / -2.5)) * syntax['exp_time']

                # https://en.wikipedia.org/wiki/Gaussian_function
                Amplitude = volume / (2 * np.pi * sigma**2)

                return Amplitude

            #  Set up grid

            def input_model(x, y, A):

                x = np.arange(0, image.shape[0])
                xx, yy = np.meshgrid(x, x)

                from autophot.packages.functions import gauss_2d, moffat_2d

                if syntax['use_moffat']:
                    model = moffat_2d(
                        (xx, yy), x, y, 0, A,
                        syntax['image_params']).reshape(image.shape)

                else:
                    model = gauss_2d(
                        (xx, yy), x, y, 0, A,
                        syntax['image_params']).reshape(image.shape)

                return model

        # =============================================================================
        #  What magnitude do you want this target to be?
        # =============================================================================

        mag2image = mag2image

        inject_source_mag = mag2image(mag_level)

        # =============================================================================
        # Random well-spaced points to plot
        # =============================================================================

        random_sources = sample_with_minimum_distance(
            n=[int(syntax['fwhm']),
               int(image.shape[0] - syntax['fwhm'])],
            k=syntax['inject_sources_random_number'],
            d=int(syntax['fwhm'] / 2))
        import math

        def PointsInCircum(r, n=100):
            return [(math.cos(2 * math.pi / n * x) * r + image.shape[1] / 2,
                     math.sin(2 * math.pi / n * x) * r + image.shape[0] / 2)
                    for x in range(0, n)]

        random_sources = PointsInCircum(2 * syntax['fwhm'], n=3)
        x = [abs(i[0]) for i in random_sources]
        y = [abs(i[1]) for i in random_sources]

        print(x)
        print(y)

        # =============================================================================
        # Inject sources
        # =============================================================================

        try:
            if syntax['inject_source_random']:

                for i in range(0, len(x)):

                    fake_source_i = input_model(x[i], y[i], inject_source_mag)

                    if syntax['inject_source_add_noise']:

                        nan_idx = np.isnan(fake_source_i)
                        fake_source_i[nan_idx] = 0
                        fake_source_i[fake_source_i < 0] = 0

                        fake_source_i = make_noise_image(
                            fake_source_i.shape,
                            distribution='poisson',
                            mean=fake_source_i,
                            random_state=np.random.randint(0, 1e3))
                        # fake_source_i[nan_idx] = np.nan1

                    fake_sources += fake_source_i
                    ax1.scatter(x[i],
                                y[i],
                                marker='o',
                                s=150,
                                facecolors='none',
                                edgecolors='r',
                                alpha=0.5)
                    ax1.annotate(str(i), (x[i], -.5 + y[i]),
                                 color='r',
                                 alpha=0.5,
                                 ha='center')

            if syntax['inject_source_on_target']:

                fake_source_on_target = input_model(image.shape[1] / 2,
                                                    image.shape[0] / 2,
                                                    inject_source_mag)

                if syntax['inject_source_add_noise']:
                    nan_idx = np.isnan(fake_source_on_target)
                    fake_source_on_target[nan_idx] = 1e-6
                    fake_source_on_target[fake_source_on_target < 0] = 0

                    fake_source_on_target = make_noise_image(
                        fake_source_on_target.shape,
                        distribution='poisson',
                        mean=fake_source_on_target,
                        random_state=np.random.randint(0, 1e3))

                fake_sources += fake_source_on_target

                ax1.scatter(image.shape[1] / 2,
                            image.shape[0] / 2,
                            marker='o',
                            s=150,
                            facecolors='none',
                            edgecolors='black',
                            alpha=0.5)
                ax1.annotate('On\nTarget',
                             (image.shape[1] / 2, -1 + image.shape[0] / 2),
                             color='black',
                             alpha=0.5,
                             ha='center')

            im1 = ax1.imshow(
                image - surface + fake_sources,
                # vmin = vmin,
                # vmax = vmax,
                aspect='auto',
                # norm = norm,
                origin='lower',
                interpolation='nearest')
            ax1.set_title(' Fake [%s] Sources ' % model_label)

        except Exception as e:
            logging.exception(e)
            im1 = ax1.imshow(
                image - surface,
                origin='lower',
                aspect='auto',
            )
            ax1.set_title('[ERROR] Fake Sources [%s]' % model_label)

        # plt.colorbar(im1,ax=ax1)
        divider = make_axes_locatable(ax1)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        cb = limiting_mag_figure.colorbar(im1, cax=cax)
        cb.ax.set_ylabel('Counts', rotation=270, labelpad=10)
        # cb = fig.colorbar(im)
        cb.formatter.set_powerlimits((0, 0))
        cb.ax.yaxis.set_offset_position('left')
        cb.update_ticks()

        ax0.legend(loc='lower center',
                   bbox_to_anchor=(0.5, 1.02),
                   ncol=2,
                   frameon=False)

        limiting_mag_figure.savefig(
            syntax['write_dir'] + 'limiting_mag_porb.pdf',
            # box_extra_artists=([l]),
            bbox_inches='tight',
            format='pdf')
        plt.close('all')

    # master try/except
    except Exception as e:
        print('limit issue')
        logging.exception(e)

    syntax['maglim_mean'] = mean
    syntax['maglim_std'] = std

    return mag_level, syntax
Пример #53
0
 data = fits.getdata(cubename, ext=1)
 t = Table.read(cubename)
 t['FILTER'].tolist()
 idx = t['FILTER'].tolist().index('R')
 rband = data[idx, :, :]
 #Creating Aperture Objects
 positions = np.array([0.5 * rband.shape[0], 0.5 * rband.shape[1]])
 radii = np.linspace(1, rband.shape[0] / 2., 30)
 # apertures = [CircularAperture(positions, r=r) for r in radii]
 apertures = []
 plt.subplot(1, 2, 1)
 vmin = np.percentile(rband, 10)
 vmax = np.percentile(rband, 95)
 plt.imshow(rband, vmin=vmin, vmax=vmax)
 for r in radii:
     aperture = CircularAperture(positions, r=r)
     apertures.append(aperture)
     aperture.plot(color='r', lw=1)
 plt.subplot(1, 2, 2)
 # Colocar código para máscara aqui
 ###
 ###
 mask = np.zeros_like(rband)
 # Performing Aperture Photometry
 phot_table = aperture_photometry(rband, apertures, mask=mask)
 # Lendo os valores da table
 phot = [float(phot_table["aperture_sum_{}".format(i)]) for i in range(30)]
 table = Table([radii, phot], names=["r", "photsum"])
 table.write("photometry_R.fits", overwrite=True)
 plt.plot(radii, phot, "o")
 plt.savefig('CUBE_FOTOMETRIA_R.png')
#plt.subplot(4,4,13)
plt.subplot(427)
plt.imshow(np.log(stamp11))
vari_funcs.no_ticks()
plt.title('11B')
#plt.subplot(4,4,15)
plt.subplot(428)
plt.imshow(np.log(stamp12))
vari_funcs.no_ticks()
plt.title('12B')
plt.savefig(str(obnum) + 'PSFs.png')

### Run aperture phot to see if flux curve is the same ###
centre = [29, 29]
pixelr = (1.5 / 3600) / const
aperture = CircularAperture(centre, pixelr)
aper05 = aperture_photometry(stamp05, aperture)
aper06 = aperture_photometry(stamp06, aperture)
aper07 = aperture_photometry(stamp07, aperture)
aper08 = aperture_photometry(stamp08, aperture)
aper09 = aperture_photometry(stamp09, aperture)
aper10 = aperture_photometry(stamp10, aperture)
aper11 = aperture_photometry(stamp11, aperture)
aper12 = aperture_photometry(stamp12, aperture)
aperflux = np.array([
    aper05['aperture_sum'][0], aper06['aperture_sum'][0],
    aper07['aperture_sum'][0], aper08['aperture_sum'][0],
    aper09['aperture_sum'][0], aper10['aperture_sum'][0],
    aper11['aperture_sum'][0], aper12['aperture_sum'][0]
])
plt.figure(1)
    for xStar, yStar in zip(xStars, yStars):
        lf, rt = xStar - 10, xStar + 10
        bt, tp = yStar - 10, yStar + 10
        patch = stokesI.arr[lf:rt, bt:tp]
        saturatedStars.append(np.sum(np.logical_or(patch > 9e3, patch < -100)) > 1)
    
    # Check for stars near the edge of the image
    ny, nx    = stokesI.arr.shape
    edgeStars = np.logical_or(
                np.logical_or(xStars < 40, xStars > (nx - 40)),
                np.logical_or(yStars < 40, yStars > (ny - 40)))
    
    # Now let's do aperture photometry on the remaining sources in the image
    # 1. Setup the apertures
    sourcePos = [xStars, yStars]
    apertures = CircularAperture(sourcePos, r = 6.0)
    annulus_apertures = CircularAnnulus(sourcePos, r_in=12., r_out=14.)
    # 2. Perform the basic photometry
    rawflux_table = aperture_photometry(stokesI.arr, apertures)
    bkgflux_table = aperture_photometry(stokesI.arr, annulus_apertures)
    phot_table = hstack([rawflux_table, bkgflux_table], table_names=['raw', 'bkg'])
    
    # 3. Compute background contribution and subtract from raw photometry
    bkg_mean = phot_table['aperture_sum_bkg'] / annulus_apertures.area()
    bkg_sum = bkg_mean * apertures.area()
    final_sum = phot_table['aperture_sum_raw'] - bkg_sum
    phot_table['residual_aperture_sum'] = final_sum

    # Compute the signal-to-noise ratio and find the stars with SNR < 3.0
    SNR          = final_sum/bkg_sum
    bkgDominated = SNR < 1.0
Пример #56
0
def photometry_on_directory(directory_with_images, object_of_interest,
                            star_locs, aperture_rad,
                            inner_annulus, outer_annulus,
                            max_adu, star_ids,
                            gain, read_noise, dark_current):
    """
    Perform aperture photometry on a directory of images.

    Parameters
    ----------

    directory_with_images : str
        Folder containing the images on which to do photometry. Photometry
        will only be done on images that contain the ``object_of_interest``.

    object_of_interest : str
        Name of the object of interest. The only files on which photometry
        will be done are those whose header contains the keyword ``OBJECT``
        whose value is ``object_of_interest``.

    star_locs : tuple of numpy array
        The first entry in the tuple should be the right ascension of the
        sources, in degrees. The second should be the declination of
        the sources, in degrees.

    aperture_rad : int
        Radius of the aperture to use when performing photometry.

    inner_annulus : int
        Inner radius of annulus to use in for performing local sky
        subtraction.

    outer_annulus : int
        Outer radius of annulus to use in for performing local sky
        subtraction.

    max_adu : int
        Maximum allowed pixel value before a source is considered
        saturated.

    star_ids : array-like
        Unique identifier for each source in ``star_locs``.

    gain : float
        Gain, in electrons/ADU, of the camera that took the image. The gain
        is used in calculating the instrumental magnitude.

    read_noise : float
        Read noise of the camera in electrons. Used in the CCD equation
        to calculate error.

    dark_current : float
        Dark current, in electron/sec. Used in the CCD equation
        to calculate error.
    """
    ifc = ImageFileCollection(directory_with_images)
    phots = []
    missing_stars = []
    for a_ccd, fname in ifc.ccds(object=object_of_interest, return_fname=True):
        print('on image ', fname)
        try:
            # Convert RA/Dec to pixel coordinates for this image
            pix_coords = a_ccd.wcs.all_world2pix(star_locs[0], star_locs[1], 0)
        except AttributeError:
            print('    ....SKIPPING THIS IMAGE, NO WCS')
            continue

        xs, ys = pix_coords

        # Remove anything that is too close to the edges/out of frame
        padding = 3 * aperture_rad
        out_of_bounds = ((xs < padding) | (xs > (a_ccd.shape[1] - padding)) |
                         (ys < padding) | (ys > (a_ccd.shape[0] - padding)))
        in_bounds = ~out_of_bounds

        # Find centroids of each region around star that is in_bounds
        xs_in = xs[in_bounds]
        ys_in = ys[in_bounds]
        print('    ...finding centroids')
        try:
            xcen, ycen = centroid_sources(a_ccd.data, xs_in, ys_in,
                                          box_size=2 * aperture_rad + 1)
        except NoOverlapError:
            print('    ....SKIPPING THIS IMAGE, CENTROID FAILED')
            continue

        # Calculate offset between centroid in this image and the positions
        # based on input RA/Dec. Later we will set the magnitude of those with
        # large differences to an invalid value (maybe).
        center_diff = np.sqrt((xs_in - xcen)**2 + (ys_in - ycen)**2)

        # Set up apertures and annuli based on the centroids in this image.
        aps = CircularAperture((xcen, ycen), r=aperture_rad)
        anuls = CircularAnnulus((xcen, ycen), inner_annulus, outer_annulus)

        # Set any clearly bad values to NaN
        a_ccd.data[a_ccd.data > max_adu] = np.nan
        print('    ...doing photometry')
        # Do the photometry...
        pho = aperture_photometry(a_ccd.data, (aps, anuls),
                                  mask=a_ccd.mask, method='center')

        # We may have some stars we did not do photometry for because
        # those stars were out of bounds.
        # Add the ones we missed to the list of missing
        missed = star_ids[out_of_bounds]
        missing_stars.append(missed)

        # Add all the extra goodies to the table
        print('    ...adding extra columns')
        add_to_photometry_table(pho, a_ccd, anuls, aps,
                                fname=fname, star_ids=star_ids[in_bounds],
                                gain=1.47)
        # And add the final table to the list of tables
        phots.append(pho)

    # ### Combine all of the individual photometry tables into one

    all_phot = vstack(phots)

    # ### Eliminate any stars that are missing from one or more images
    #
    # This makes life a little easier later...

    uniques = set()
    for miss in missing_stars:
        uniques.update(set(miss))

    actually_bad = sorted([u for u in uniques if u in all_phot['star_id']])
    len(uniques), len(actually_bad)

    all_phot.add_index('star_id')
    if actually_bad:
        bad_rows = all_phot.loc_indices[actually_bad]
        try:
            bad_rows = list(bad_rows)
        except TypeError:
            bad_rows = [bad_rows]
        all_phot.remove_indices('star_id')
        all_phot.remove_rows(sorted(bad_rows))

    all_phot.remove_indices('star_id')

    snr = (gain * all_phot['aperture_net_flux'] /
           np.sqrt(gain * all_phot['aperture_net_flux'].value +
                   all_phot['aperture_area'] *
                   (1 + all_phot['aperture_area'] / all_phot['annulus_area']) *
                   (gain * all_phot['sky_per_pix_avg'].value +
                    gain * dark_current * all_phot['exposure'].value +
                    read_noise**2
                   )
                  ))

    all_phot['mag_error'] = 1.085736205 / snr

    return all_phot
Пример #57
0
Файл: ifu.py Проект: mcara/jwst
def extract_ifu(input_model, source_type, extract_params):
    """This function does the extraction.

    Parameters
    ----------
    input_model : IFUCubeModel
        The input model.

    source_type : string
        "point" or "extended"

    extract_params : dict
        The extraction parameters for aperture photometry.

    Returns
    -------
    ra, dec : float
        ra and dec are the right ascension and declination respectively
        at the nominal center of the image.

    wavelength : ndarray, 1-D
        The wavelength in micrometers at each pixel.

    net : ndarray, 1-D
        The count rate (or flux) minus the background at each pixel.

    background : ndarray, 1-D
        The background count rate that was subtracted from the total
        source count rate to get `net`.

    npixels : ndarray, 1-D, float64
        For each slice, this is the number of pixels that were added
        together to get `net`.

    dq : ndarray, 1-D, uint32
        The data quality array.
    """

    data = input_model.data
    shape = data.shape
    if len(shape) != 3:
        log.error("Expected a 3-D IFU cube; dimension is %d.", len(shape))
        raise RuntimeError("The IFU cube should be 3-D.")

    # We need to allocate net, background, npixels, and dq arrays
    # no matter what.  We may need to divide by npixels, so the default
    # is 1 rather than 0.
    net = np.zeros(shape[0], dtype=np.float64)
    background = np.zeros(shape[0], dtype=np.float64)
    npixels = np.ones(shape[0], dtype=np.float64)

    dq = np.zeros(shape[0], dtype=np.uint32)

    x_center = extract_params['x_center']
    y_center = extract_params['y_center']
    if x_center is None:
        x_center = float(shape[2]) / 2.
    else:
        x_center = float(x_center)
    if y_center is None:
        y_center = float(shape[1]) / 2.
    else:
        y_center = float(y_center)

    method = extract_params['method']
    # subpixels is only needed if method = 'subpixel'.
    subpixels = extract_params['subpixels']

    subtract_background = extract_params['subtract_background']
    smaller_axis = float(min(shape[1], shape[2]))       # for defaults
    radius = None
    inner_bkg = None
    outer_bkg = None

    if source_type == 'point':
        radius = extract_params['radius']
        if radius is None:
            radius = smaller_axis / 4.
        if subtract_background:
            inner_bkg = extract_params['inner_bkg']
            if inner_bkg is None:
                inner_bkg = radius
            outer_bkg = extract_params['outer_bkg']
            if outer_bkg is None:
                outer_bkg = min(inner_bkg * math.sqrt(2.),
                                smaller_axis / 2. - 1.)
            if inner_bkg <= 0. or outer_bkg <= 0. or inner_bkg >= outer_bkg:
                log.debug("Turning background subtraction off, due to "
                          "the values of inner_bkg and outer_bkg.")
                subtract_background = False
        width = None
        height = None
        theta = None
    else:
        width = extract_params['width']
        if width is None:
            width = smaller_axis / 2.
        height = extract_params['height']
        if height is None:
            height = smaller_axis / 2.
        theta = extract_params['theta'] * math.pi / 180.
        subtract_background = False

    log.debug("IFU 1-D extraction parameters:")
    log.debug("  x_center = %s", str(x_center))
    log.debug("  y_center = %s", str(y_center))
    if source_type == 'point':
        log.debug("  radius = %s", str(radius))
        log.debug("  subtract_background = %s", str(subtract_background))
        log.debug("  inner_bkg = %s", str(inner_bkg))
        log.debug("  outer_bkg = %s", str(outer_bkg))
        log.debug("  method = %s", method)
        if method == "subpixel":
            log.debug("  subpixels = %s", str(subpixels))
    else:
        log.debug("  width = %s", str(width))
        log.debug("  height = %s", str(height))
        log.debug("  theta = %s degrees", str(extract_params['theta']))
        log.debug("  subtract_background = %s", str(subtract_background))
        log.debug("  method = %s", method)
        if method == "subpixel":
            log.debug("  subpixels = %s", str(subpixels))

    # Check for out of bounds.
    # The problem with having the background aperture extend beyond the
    # image is that the normalization would not account for the resulting
    # decrease in the area of the annulus, so the background subtraction
    # would be systematically low.
    outside = False
    f_nx = float(shape[2])
    f_ny = float(shape[1])
    if x_center < 0. or x_center >= f_nx - 1. or \
       y_center < 0. or y_center >= f_ny - 1.:
        outside = True
        log.error("Target location is outside the image.")
    if subtract_background and \
       (x_center - outer_bkg < -0.5 or x_center + outer_bkg > f_nx - 0.5 or
        y_center - outer_bkg < -0.5 or y_center + outer_bkg > f_ny - 0.5):
            outside = True
            log.error("Background region extends outside the image.")

    if outside:
        (ra, dec) = (0., 0.)
        wavelength = np.zeros(shape[0], dtype=np.float64)
        dq[:] = dqflags.pixel['DO_NOT_USE']
        return (ra, dec, wavelength, net, background, npixels, dq)  # all bad

    x0 = float(shape[2]) / 2.
    y0 = float(shape[1]) / 2.
    (ra, dec, wavelength) = get_coordinates(input_model, x0, y0)

    position = (x_center, y_center)
    if source_type == 'point':
        aperture = CircularAperture(position, r=radius)
        if subtract_background:
            annulus = CircularAnnulus(position,
                                      r_in=inner_bkg, r_out=outer_bkg)
            normalization = aperture.area() / annulus.area()
    else:
        aperture = RectangularAperture(position, width, height, theta)
        # No background is computed for an extended source.

    npixels[:] = aperture.area()
    for k in range(shape[0]):
        phot_table = aperture_photometry(data[k, :, :], aperture,
                                         method=method, subpixels=subpixels)
        net[k] = float(phot_table['aperture_sum'][0])
        if subtract_background:
            bkg_table = aperture_photometry(data[k, :, :], annulus,
                                            method=method, subpixels=subpixels)
            background[k] = float(bkg_table['aperture_sum'][0])
            net[k] = net[k] - background[k] * normalization

    # Check for NaNs in the wavelength array, flag them in the dq array,
    # and truncate the arrays if NaNs are found at endpoints (unless the
    # entire array is NaN).
    (wavelength, net, background, npixels, dq) = \
                nans_in_wavelength(wavelength, net, background, npixels, dq)

    return (ra, dec, wavelength, net, background, npixels, dq)
Пример #58
0
def photutils_stellar_photometry(ccd_image, sources,
                                 aperture_radius, inner_annulus,
                                 outer_annulus, gain=1.0, N_R=0, N_dark_pp=0,
                                 reject_background_outliers=True):
    """
    Perform aperture photometry on an image, with a few options for estimating
    the local background from an annulus around the aperture.

    Parameters
    ----------
    ccd_image : `~ccdproc.CCDData`
        Image on which to perform aperture photometry.

    sources : `~astropy.table.Table`
        Table of extracted sources. Assumed to be the output of
        `~photutils.daofind()` source extraction function.

    aperture_radius : float
        Radius of aperture(s) in pixels.

    inner_annulus : float
        Inner radius of the annulus in pixels.

    outer_annulus : float
        Outer radius of the annulus in pixels.

    gain : float
        Gain of the CCD. In units of electrons per DN.

    N_R : float
        Read noise of the CCD in electrons per pixel.

    N_dark_pp : float
        Number of dark counts per pixel.

    reject_background_outliers : bool, optional
        If ``True``, sigma clip the pixels in the annulus to reject outlying
        pixels (e.g. like stars in the annulus)

    Returns
    -------
    phot_table : `~astropy.table.Table`
        Astropy table with columns for flux, x/y coordinates of center,
        RA/dec coordinates of center, sky background per pixel,
        net flux, aperture and annulus radii used, and flux error.
    """

    # check that the outer radius is greater or equal the inner radius
    # for annulus
    if inner_annulus >= outer_annulus:
        raise ValueError("outer_annulus must be greater than inner_annulus")

    # check that the annulus inner radius is greater or equal
    # the aperture radius
    if aperture_radius >= inner_annulus:
        raise ValueError("inner_radius must be greater than aperture_radius")

    # Extract x,y coordinates from sources table, construct aperture and
    # annulus objects from coordinates, and perform aperture photometry
    coords = (sources['xcentroid'], sources['ycentroid'])
    apertures = CircularAperture(coords, aperture_radius)
    annulus = CircularAnnulus(coords, inner_annulus, outer_annulus)
    phot_table = aperture_photometry(ccd_image, apertures)
    phot_table_1 = aperture_photometry(ccd_image, annulus)

    # Obtain the local background/pixel and net flux between the aperture and
    # annulus objects
    n_pix_ap = apertures.area
    n_pix_ann = annulus.area

    if reject_background_outliers:
        annulus_masks = annulus.to_mask()
        bkgd_pp = []
        for mask in annulus_masks:
            annulus_data = mask.cutout(ccd_image)
            bool_mask = mask.data < 1
            # Only include whole pixels in the estimate of the background
            bkgd, _, _ = sigma_clipped_stats(annulus_data * mask,
                                             mask=bool_mask)
            bkgd_pp.append(bkgd)
        bkgd_pp = np.array(bkgd_pp)
    else:
        bkgd_pp = phot_table_1['aperture_sum'] / n_pix_ann

    net_flux = phot_table['aperture_sum'] - (n_pix_ap * bkgd_pp)
    phot_table['background_per_pixel'] = bkgd_pp
    phot_table['net_flux'] = net_flux

    # Return a columns with the aperture radius and
    # the inner/outer annulus radii
    phot_table['aperture_radius'] = \
        np.ones(len(phot_table['aperture_sum'])) * aperture_radius
    phot_table['inner_radius'] = \
        np.ones(len(phot_table['aperture_sum'])) * inner_annulus
    phot_table['outer_radius'] = \
        np.ones(len(phot_table['aperture_sum'])) * outer_annulus

    # Obtain RA/Dec coordinates and add them to table
    try:
        ra, dec = convert_pixel_wcs(ccd_image, coords[0], coords[1], 1)
        phot_table['RA_center'] = ra
        phot_table['Dec_center'] = dec
    except AttributeError:
        pass

    # Obtain flux error and add column to return table
    noise = np.sqrt(gain * net_flux + n_pix_ap * (1 + (n_pix_ap / n_pix_ann)) *
                    (gain * (bkgd_pp + N_dark_pp) + (N_R**2)))
    phot_table['aperture_sum_err'] = noise

    return phot_table
Пример #59
0
def draw_mask_map_strip(image,
                        seg_comb,
                        mask_comb,
                        stars,
                        ma_example=None,
                        r_core=None,
                        vmin=None,
                        vmax=None,
                        pad=0,
                        save=False,
                        save_dir='./'):
    """ Visualize mask map w/ strips """

    from matplotlib import patches

    star_pos_A = stars.star_pos_verybright + pad
    star_pos_B = stars.star_pos_medbright + pad

    mu = np.nanmedian(image)
    std = mad_std(image)
    if vmin is None:
        vmin = mu - std
    if vmax is None:
        vmax = mu + 10 * std

    fig, (ax1, ax2, ax3) = plt.subplots(ncols=3,
                                        nrows=1,
                                        figsize=(20, 6),
                                        dpi=100)

    if ma_example is not None:
        mask_strip, mask_cross = ma_example
        mask_strip[mask_cross.astype(bool)] = 0.5
        ax1.plot(star_pos_A[0][0], star_pos_A[0][1], "r*", ms=18)
    else:
        mask_strip = np.zeros_like(image)
    ax1.imshow(mask_strip, cmap="gray_r")
    ax1.set_title("Strip/Cross")

    n_label = seg_comb.max()
    ax2.imshow(seg_comb,
               vmin=1,
               vmax=n_label - 3,
               cmap=make_rand_cmap(n_label))
    ax2.plot(star_pos_A[:, 0], star_pos_A[:, 1], "r*", ms=18)
    ax2.set_title("Mask Comb.")

    image3 = image.copy()
    image3[mask_comb] = 0
    im3 = ax3.imshow(image3, norm=LogNorm(), vmin=vmin, vmax=vmax)
    ax3.plot(star_pos_A[:, 0], star_pos_A[:, 1], "r*", ms=18)
    ax3.set_title("Sky")
    colorbar(im3, pad=0.1, size="2%")

    if r_core is not None:
        if np.ndim(r_core) == 0:
            r_core = [r_core, r_core]

        aper = CircularAperture(star_pos_A, r=r_core[0])
        aper.plot(color='lime', lw=2, label="", alpha=0.9, axes=ax3)

        aper = CircularAperture(star_pos_B, r=r_core[1])
        aper.plot(color='c', lw=2, label="", alpha=0.7, axes=ax3)

    patch_Xsize = image.shape[1] - pad * 2
    patch_Ysize = image.shape[0] - pad * 2

    rec = patches.Rectangle((pad, pad),
                            patch_Xsize,
                            patch_Ysize,
                            facecolor='none',
                            edgecolor='w',
                            linewidth=2,
                            linestyle='--',
                            alpha=0.8)
    ax3.add_patch(rec)

    plt.tight_layout()
    if save:
        plt.savefig(os.path.join(save_dir, "Mask_strip.png"), dpi=100)
        plt.show()
        plt.close()
    else:
        plt.show()
Пример #60
0

mosaic_area = fits.getdata(dir + '/Mosaic_B/mosaic_area.fits')
#mosaic area plot:
plt.figure(1) 
plt.imshow(mosaic_area, origin='lower')
plt.xlabel('Pixels', fontsize=15)
plt.ylabel('Pixels', fontsize=15)

mosaic_area_cropped = mosaic_area[400:1490, 380:1610]
raw_cropped = 

sourcesB = daofind(nosky_crop, fwhm=5.0, threshold=1.5*bkg_sigma)


#background subtraction:
#phot_table = aperture_photometry(data - bkg, apertures)
data = 
apertures = CircularAperture(positions, r=3)
annulus_apertures = CircularAnnulus(positions, r_in=6, r_out=8)
rawflux_table = aperture_photometry(data, apertures)
bkgflux_table = aperture_photometry(data, annulus_apertures)
phot_table = hstack([rawflux_table, bkgflux_table], table_names=['raw', 'bkg'])

aperture_area = np.pi*3**2
annulus_area = np.pi*(8**2-6**2)
final_sum = (phot_table['aperture_sum_raw']-phot_table['aperture_sum_bkg'] * aperture_area/annulus_area)
phot_table = ['residual_aperture_sum']