def create_example_frame(self, plot=True, figsize=(13, 13)): fits_files = list(self.datadir.glob('MCT*fits')) assert len(fits_files) > 0, 'No example frame fits-files found.' f = fits_files[0] f1 = pf.open(f) f2 = pf.open(f.with_suffix('.wcs')) h1 = f1[0].header.copy() h1.append(('COMMENT', '*********************')) h1.append(('COMMENT', ' WCS ')) h1.append(('COMMENT', '*********************')) h1.extend(f2[0].header, unique=True, bottom=True) f1[0].header = h1 filter = h1['filter'] f1.writeto(self._dres.joinpath( f'{self.ticname}_20{self.date}_MuSCAT2_{filter}_frame.fits'), overwrite=True) if plot: wcs = WCS(f1[0].header) data = f1[0].data.astype('d') norm = simple_norm(data, stretch='log') fig = figure(figsize=figsize, constrained_layout=True) ax = fig.add_subplot(111, projection=wcs) ax.imshow(data, origin='image', norm=norm, cmap=cm.gray_r) apts = SkyCircularAperture( self.phs[0].centroids_sky, float(self.phs[0]._flux.aperture[self.lpf.aid]) * u.pixel) apts.to_pixel(wcs).plot(color='w')
def measure_aper_flux(hdu, aper): # create mask (set True for where you want to mask) im_mask = im == 0 # define circular aperture and annulus aperture for background subtraction aper = SkyCircularAperture(coords, r=radius) aper_annulus = SkyCircularAnnulus(coords, annulus[0], annulus[1]) mask = aper_annulus.to_pixel(w).to_mask(method="center").data annulus_data = aper_annulus.to_pixel(w).to_mask( method="center").multiply(im) annulus_data_1d = annulus_data[mask > 0] annulus_mask = aper_annulus.to_pixel(w).to_mask( method="center").multiply(im_mask) annulus_mask_1d = annulus_mask[mask > 0] # determine fractional fiber coverage apcor_im = aper.to_pixel(w).to_mask( method="center").multiply(im_mask) / aper.to_pixel(w).to_mask( method="center").multiply(np.ones_like(im)) apcor = np.sum(apcor_im == 0) / np.sum(np.isfinite(apcor_im)) # get median and standard deviation in background mean_sigclip, median_sigclip, stddev_sigclip = sigma_clipped_stats( annulus_data_1d, mask=annulus_mask_1d) bkg_median = median_sigclip * aper.to_pixel(w).area * apcor bkg_stddev = stddev_sigclip * aper.to_pixel(w).area * apcor phottable = aperture_photometry( hdu[0].data, [aper, aper_annulus], error=hdu[1].data, mask=im_mask, wcs=wcs.WCS(hdu[0].header), ) if np.abs(bkg_median) > 2 * bkg_stddev: flux = (phottable["aperture_sum_0"][0] - bkg_median) * u.Unit("10^-17 erg cm-2 s-1") else: flux = (phottable["aperture_sum_0"][0]) * u.Unit("10^-17 erg cm-2 s-1") flux_err = phottable["aperture_sum_err_0"][0] * u.Unit( "10^-17 erg cm-2 s-1") if plot: plt.subplot(111, projection=w) plt.imshow(im, vmin=0 * stddev_sigclip, vmax=3 * stddev_sigclip) aper.to_pixel(w).plot(color="white") # for SkyCircularAperture aper_annulus.to_pixel(w).plot(color="red", linestyle="dashed") plt.xlabel("RA") plt.ylabel("Dec") plt.colorbar() if plottitle is not None: plt.title(plottitle) return flux, flux_err, bkg_stddev * u.Unit("10^-17 erg cm-2 s-1"), apcor
def get_image_datatab(ra, dec, width): fitsurl = geturl(ra, dec, size=int(width * 240), filters="i", format="fits") fh = fits.open(fitsurl[0]) fhead = fh[0].header wcs = WCS(fhead) fim = fh[0].data # replace NaN values with zero for display fim[numpy.isnan(fim)] = 0.0 # set contrast to something reasonable transform = AsinhStretch() + PercentileInterval(90) bfim = transform(fim) #query PS1 catalog datatab = panstarrs_query_pos(ra, dec, width) #query the table with positions and aperture pre-defined positions = SkyCoord(ra=datatab['raMean'], dec=datatab['decMean'], unit='deg') aper = SkyCircularAperture(positions, 0.5 * u.arcsec) pix_aperture = aper.to_pixel(wcs) #plot fig = plt.figure() fig.add_subplot(111, projection=wcs) #norm = ImageNormalize(stretch=SqrtStretch()) plt.imshow(bfim, cmap='Greys', origin='lower') pix_aperture.plot(color='blue', lw=0.5, alpha=0.5) plt.xlabel('RA') plt.ylabel('Dec') image = plt.savefig('test_run.jpg', dpi=1000) fits.writeto('test_run.fits', fim, fhead, overwrite=True) ascii.write(datatab, 'test_run.csv', format='csv', fast_writer=False) return datatab
def ap_phot(inp_img, rad_ap, rad_sky_i, rad_sky_o, show_plot=True): # Define Aperture Pars =========== ap = SkyCircularAperture(inp_img['coords_sky'], r=rad_ap) # Roughly WISE4 PSF sky = SkyCircularAnnulus(inp_img['coords_sky'], r_in=rad_sky_i, r_out=rad_sky_o) ap_px = ap.to_pixel(wcs=inp_img['wcs']) sky_px = sky.to_pixel(wcs=inp_img['wcs']) # Perform Photometry ============= phot_dat = aperture_photometry(inp_img['data'], ap, wcs=inp_img['wcs']) phot_sky = aperture_photometry(inp_img['data'], sky, wcs=inp_img['wcs']) bkg_mean = phot_sky['aperture_sum'] / sky_px.area() phot_dat['Phot'] = phot_dat['aperture_sum'] - (bkg_mean * ap_px.area()) # Compute S/N ==================== sky_stats = sample_comp.get_photmask_stats(sky_px, inp_img=inp_img['data']) ap__stats = sample_comp.get_photmask_stats(ap_px, inp_img=inp_img['data']) phot_dat['SN'] = (ap__stats['max'] - sky_stats['mean']) / sky_stats['std'] for col in ['aperture_sum', 'Phot', 'SN']: phot_dat[col].format = '10.2f' if show_plot: fig = plt.figure(figsize=[7, 7]) ax = plt.subplot(111) img = ax.imshow(inp_img['data'], origin='lower', cmap='viridis') ap_px.plot() sky_px.plot(color='red') plt.show() return { 'phot_tab': phot_dat, 'phot_ap_px': ap_px, 'phot_sky_px': sky_px }
def extractSpectra(fitsfile, pos, radius, axes=[0, 1, 2], smth=False, freqsmth=0, verbose=False, restfreq=115.27120, z=0.01): apertures = SkyCircularAperture(pos, r=radius * aunits.arcsec) w = WCS(fitsfile).celestial pix_aperture = apertures.to_pixel(w) header = f.open(fitsfile)[0].header cube = np.squeeze(f.open(fitsfile)[0].data).transpose(axes) df, dx, dy = np.shape(cube) if dx != dy: print('warning : image is not square, may need a transpose') mask = pix_aperture.to_mask()[0] image = mask.to_image(shape=((dx, dy))).astype('bool') freqs = np.linspace(header['CRVAL4'], header['CRVAL4'] + header['CDELT4'] * header['NAXIS4'], header['NAXIS4']) vels = Freq2Vel(x0=freqs / 1e9, z=z, restfreq=restfreq) if smth: cube = ndimage.gaussian_filter(cube, sigma=[freqsmth, 0, 0], mode='reflect')[::freqsmth, :, :] freqs = freqs[::freqsmth] vels = vels[::freqsmth] spec = np.mean(cube[:, image], axis=(1)) if verbose: print('assuming NAXIS 4 is the frequency one') return vels, freqs, spec
fitsimage = ratioDir + 'NGC5258_12CO10_combine_contsub_uvrange_smooth_masked_pbcor_mom0.fits' wcs = fits_import(fitsimage)[0] data10_masked = fits_import(fitsimage)[1] # import the channel used map. # fitsimage='NGC5258_12CO10_combine_uvrange_smooth_regrid21_nchan.fits' # chans=fits_import(fitsimage)[1] chans = 50 chans_10 = chans # define the aperture position = SkyCoord(dec=0.8309 * u.degree, ra=204.9906 * u.degree, frame='icrs') center_sky = SkyCircularAperture(position, r=3 * u.arcsec) center_pix = center_sky.to_pixel(wcs=wcs) apertures['center'] = center_pix ring_sky = SkyCircularAnnulus(position, r_in=3 * u.arcsec, r_out=7 * u.arcsec) ring_pix = ring_sky.to_pixel(wcs=wcs) apertures['ring'] = ring_pix position = SkyCoord(dec=0.8340 * u.degree, ra=204.9935 * u.degree, frame='icrs') northarm_sky = SkyEllipticalAperture(position, a=13 * u.arcsec, b=4 * u.arcsec, theta=185 * u.degree) northarm_pix = northarm_sky.to_pixel(wcs=wcs) apertures['northarm'] = northarm_pix
def calc_radial_profile(fitsfile, center, rstart, rend, rstep, verbose=False, detmaskfile=None, plot=True): """ Utility function to calculate the radial profile from an image `fitsfile` at a `center` """ # if (not os.path.isfile(fitsfile)): print(f"ERROR. FITS file {fitsfile} not found. Cannot continue.") return None # qhdu = fits.open(fitsfile) wcs = WCS(qhdu[0].header) # # if detmaskfile is provided then will use it for detector mask # doMask = False if (detmaskfile != None): if (not os.path.isfile(detmaskfile)): print(f"Warning. Detector mask file {detmaskfile} not found. Will not use detector mask!") doMask = False else: det = fits.open(detmaskfile) detmask = det['MASK'] # need the WCS wcs_det = WCS(detmask.header) doMask = True # if (not isinstance(center, SkyCoord)): print(f"ERROR: the input radial profile centre is not SkyCoord object. Cannot continue.") return None # j = 0 rx = rstart counts = [] counts_err = [] rmid = [] # emtpy = False while rx < rend: r0 = rstart + rstep * j rx = rstart + rstep * (j + 1) # the mid point, can be better the mid area point rmid.append((r0.value + rx.value) / 2.0) if (j == 0): xap = SkyCircularAperture(center, rx) photo = aperture_photometry(qhdu[0].data, xap, wcs=wcs) if (doMask): masked = aperture_photometry(detmask.data, xap, wcs=wcs_det) else: xap = SkyCircularAnnulus(center, r0, rx) photo = aperture_photometry(qhdu[0].data, xap, wcs=wcs) if (doMask): masked = aperture_photometry(detmask.data, xap, wcs=wcs_det) # ap_area = xap.to_pixel(wcs).area good_area = ap_area if (doMask): good_area = masked['aperture_sum'][0] # compare the two annuli areas: with and without bad pixels if (verbose): print( f"Annulus: {r0:.2f},{rx:.2f},geometric area: {ap_area:.1f} pixels,non-masked area {good_area:.1f} pixels, ratio: {ap_area / good_area:.2f}") # taking into account the masked pixels if (good_area == 0.0): counts.append(float('nan')) counts_err.append(float('nan')) else: counts.append(photo['aperture_sum'][0] / good_area) counts_err.append(np.sqrt(photo['aperture_sum'][0]) / good_area) j += 1 # # convert the results in numpy arrays # rmid = np.array(rmid) counts = np.array(counts) counts_err = np.array(counts_err) # # convert per pixel to per arcsec^2 pix_area = utils.proj_plane_pixel_area(wcs) * 3600.0 * 3600.0 # in arcsec^2 counts = counts / pix_area counts_err = counts_err / pix_area # if (plot): fig, ax = plt.subplots(figsize=(10, 8)) ax.errorbar(rmid, counts, xerr=rstep.value / 2.0, yerr=counts_err) ax.set_xscale('linear') ax.set_yscale('log') ax.set_xlabel('Radial distance (arcsec)') ax.set_ylabel(r'Counts/arcsec$^2$') ax.grid() ax.set_title(f"Radial profile"); qhdu.close() if (doMask): det.close() return rmid, counts, counts_err
beamarea = 6 * u.arcsec * 6 * u.arcsec * 1.1331 # flux measured from original image flux_33GHz = 6.8e-4 error = 1.4e-5 flux_unpb = 6.4e-4 # compare to the smoothed image filename = imageDir + 'NGC5257_33GHz_pbcor_smooth_6arcsec.fits' wcs_33GHz = fits_import(filename)[0] data_33GHz = fits_import(filename)[1] ra = -2.7057736283005824 dec = 0.014605178692092591 position = SkyCoord(dec=dec * u.rad, ra=ra * u.rad, frame='icrs') south_sky = SkyCircularAperture(positions=position, r=3 * ratio * u.arcsec) south_pix = south_sky.to_pixel(wcs_33GHz) flux = aperture_photometry(data_33GHz, apertures=south_pix)['aperture_sum'][0] flux = float(flux / (beamarea / pixsize)) freq = 33 SFR_33GHz = sfr_radio(flux_33GHz, freq, d) error = np.full(np.shape(data_33GHz), rms_33) flux_error = aperture_photometry( data_33GHz, apertures=south_pix, error=error)['aperture_sum_err'][0] / (np.sqrt(1.1331 * 6 * 6 / 0.12**2)) # error=np.sqrt(np.ma.count(arm_masked)/(1.1331*6*6/0.12**2))*rms_33 df['region']['33GHz'] = 'south' df['flux']['33GHz'] = flux_33GHz df['SFR']['33GHz'] = SFR_33GHz
size = u.Quantity((54, 42), u.arcsec) cont_wcs_cut = cut_2d(cont, center, size, cont_wcs)[0] cont_cut = cut_2d(cont, center, size, cont_wcs)[1] # spitzer 3.6um image. fitsimage = imageDir + 'spitzer_regrid_36um.fits' ir_wcs = fits_import(fitsimage)[0] ir = fits_import(fitsimage)[1] ### south continuum source ra = 15 * (13 * u.degree + 39 * u.arcmin + 52.939 * u.arcsec) dec = 50 * u.arcmin + 12.473 * u.arcsec position = SkyCoord(ra=ra, dec=dec, frame='icrs') south_sky = SkyCircularAperture(positions=position, r=1.1 * u.arcsec) south_pix = south_sky.to_pixel(wcs) south_pix_cut = south_sky.to_pixel(wcs_cut) highchan = np.shape(data)[0] - 1 lowchan = 0 south_masked = Regmask3d(data, south_pix, lowchan, highchan) south_mask = np.isnan(south_masked) south = Imcube.with_mask(south_mask) spectrum = south.mean(axis=(1, 2)) # spectrum.quicklook() specarray = spectrum.hdu.data velocity = np.linspace(-300, 390, 70) vel_mean = np.nansum(specarray * velocity) / np.nansum(specarray)
# aperture=SkyCircularAperture(position, r=4. * u.arcsec) # print(r_circle_as) # r_inner=fwhm[i]*8 # r_outer=fwhm[i]*10 # r_inner=20. # r_outer=25. # 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) r_pix = aperture_pix.r print('r_pix =', r_pix) # 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 aper_annu = SkyCircularAnnulus(positions, r_inner_as, r_outer_as)
def PDF(cutout): """ Create a pdf file with the plot of your objects in different filters Parameters ---------- cutout: list array of images N filt x N sources """ # create the pdf pdfOut = PdfPages(dirpath + 'stampPDF.pdf') # it's a sum to derive the good number of stamp p = 0 # Placement of the Id sizeId = cutout[0][0].shape # while p < np.size(cutout[0]) - 1: print(p) if np.size(cutout[0]) - p > 10: fig, axs = plt.subplots(10, len(cutout), figsize=(8.3, 11.7)) else: fig, axs = plt.subplots(np.size(cutout[0]) - p, len(cutout), figsize=(8.3, 11.7)) # Loop over the 10 sources to be include in one PDF page for k in range(10): # id of object axs[k, 0].text(-sizeId[0], sizeId[0] / 2, tbl['id'][p]) # Loop over the filters for j in range(len(cutout)): # Display the image mappa = axs[k, j].imshow(cutout[j][p].data, cmap='afmhot', origin='lower', interpolation='nearest') axs[k, j].set_title(filters[j], fontsize=5, pad=2.5) axs[k, j].get_xaxis().set_visible(False) axs[k, j].get_yaxis().set_visible(False) # Plot circular aperture at the coordinate of your object apertures = SkyCircularAperture(tbl['skycoord'][p], r=1.5 * u.arcsec) aperturesPix = apertures.to_pixel(cutout[j][p].wcs) aperturesPix.plot(color='cyan', ax=axs[k, j], lw=1, alpha=0.5) # DS9 zscale zrange = zscale.zscale(cutout[j][p].data) mappa.set_clim(zrange) # it's a sum to derive the good number of stamp if p < np.size(cutout[0]) - 1: p = p + 1 else: break # save the page plt.savefig(pdfOut, format='pdf') pdfOut.close() return
def app_phot(self, imagefile, ras, decs, fwhm, plot=False, save=False): ''' Computes the aperture photometry on the image, for the coordinates given. Parameters ---------- imagefile : str The name of the fits file with the image. ras : array Array of floats with the RA positions for which aperture photometry is needed. decs : array Array of floats with the DEC positions for which aperture photometry is needed. fwhm : float Average FWHM of the field used to compute the aperture. plot : boolean Shall the apertures be plotted in the plot directory? save : boolean Save the aperture measurement to a file. Returns ------- phot : QTable A table of the photometry with the following columns: 'id': The source ID. 'xcenter', 'ycenter': The x and y pixel coordinates of the input aperture center(s). 'celestial_center': 'aperture_sum': The sum of the values within the aperture. 'aperture_sum_err': The corresponding uncertainty in the 'aperture_sum' values. Returned only if the input error is not None. ''' data = fits.open(imagefile)[self.ext].data filt = fitsutils.get_par(imagefile, 'FILTER', self.ext) mjd = Time(fitsutils.get_par(imagefile, "DATE-OBS", ext=self.ext)).mjd zp = fitsutils.get_par(imagefile, 'ZP', self.ext) color = fitsutils.get_par(imagefile, 'COLOR', self.ext) kcoef = fitsutils.get_par(imagefile, 'KCOEF', self.ext) zperr = fitsutils.get_par(imagefile, 'ZPERR', self.ext) if zp is None: zp = 0 if zperr is None: zperr = 0 wcs = astropy.wcs.WCS(fits.open(imagefile)[self.ext].header) positions = SkyCoord(ras*u.deg, decs*u.deg, frame='icrs') # Set aperture radius to three times the fwhm radius aperture_rad = np.median(fwhm)*2* u.arcsec aperture = SkyCircularAperture(positions, r=aperture_rad) annulus_apertures = SkyCircularAnnulus(positions, r_in=aperture_rad*2, r_out=aperture_rad*4) #Convert to pixels pix_aperture = aperture.to_pixel(wcs) pix_annulus = annulus_apertures.to_pixel(wcs) pix_annulus_masks = pix_annulus.to_mask(method='center') #Plot apertures from astropy.visualization import simple_norm try: if np.ndim(ras) == 0: c = wcs.wcs_world2pix(np.array([[ras, decs]]), 0) else: c = wcs.wcs_world2pix(np.array([ras, decs]).T, 0) except ValueError: self.logger.error('The vectors of RAs, DECs could not be converted into pixels using the WCS!') self.logger.error(str(np.array([ras, decs]).T)) if plot: x = c[:,0] y = c[:,1] plt.figure(figsize=(10,10)) norm = simple_norm(data, 'sqrt', percent=99) plt.imshow(data, norm=norm) pix_aperture.plot(color='white', lw=2) pix_annulus.plot(color='red', lw=2) plt.xlim(x[0]-200, x[0]+200) plt.ylim(y[0]-200, y[0]+200) plt.title('Apertures for filter %s'%filt) plt.savefig(os.path.join(self._plotpath, "apertures_cutout_%s.png"%os.path.basename(imagefile))) plt.clf() #Divide each pixel in 5 subpixels to make apertures apers = [pix_aperture, pix_annulus] phot_table = aperture_photometry(data, apers, method='subpixel', subpixels=5) for col in phot_table.colnames: phot_table[col].info.format = '%.8g' # for consistent table output bkg_median = [] std_counts = [] for mask in pix_annulus_masks: annulus_data = mask.multiply(data) annulus_data_1d = annulus_data[mask.data > 0] _, median_sigclip, stdv_clip = sigma_clipped_stats(annulus_data_1d) bkg_median.append(median_sigclip) std_counts.append(stdv_clip) bkg_median = np.array(bkg_median) std_counts = np.array(std_counts) phot = aperture_photometry(data, pix_aperture) phot['annulus_median'] = bkg_median phot['annulus_std'] = std_counts phot['aper_bkg'] = bkg_median * pix_aperture.area() phot['aper_sum_bkgsub'] = phot['aperture_sum'] - phot['aper_bkg'] # Flux = Gain * Counts / Exptime. exptime = fitsutils.get_par(imagefile, 'EXPTIME', self.ext) gain = fitsutils.get_par(imagefile, self.gain_keyword, self.ext) flux = gain * phot['aper_sum_bkgsub'] / exptime inst_mag = -2.5*np.log10(flux) phot['flux'] = flux phot['inst_mag'] = inst_mag #Noise is the poisson noise of the source plus the background noise for the extracted area err = np.sqrt (flux + pix_aperture.area() * std_counts**2) #Transform pixels to magnitudes flux2 = gain * (phot['aper_sum_bkgsub']+err) / exptime inst_mag2 = -2.5*np.log10(flux2) errmag = np.abs(inst_mag2 - inst_mag) phot['err_counts'] = err phot['err_mag'] = errmag for col in phot.colnames: phot[col].info.format = '%.8g' # for consistent table output if save: appfile = os.path.join(self._photpath, fitsutils.get_par(imagefile, "OBJECT", self.ext)+".app.phot.txt") self.logger.info('Creating aperture photometry out file as %s'%appfile) #Save the photometry into a file if (not os.path.isfile(appfile)): with open(appfile, 'w') as f: f.write("mjd filter instr_mag zp zperr color kcoef mag magerr\n") with open(appfile, 'a') as f: self.logger.info('Adding aperture photometry to file %s'%appfile) f.write("%.3f %s %.4f %.4f %.4f %s %.4f %.4f %.4f\n"%(mjd, filt, phot['inst_mag'].data[0], \ zp, zperr, color, kcoef, phot['inst_mag'].data[0]+ zp, phot['err_mag'].data[0])) return phot
SFR_cut_wcs, SFR_cut=cut_2d(SFR, position, size, wcs) SFR_cutbin=reproj_binning(SFR_cut, SFR_cut_wcs, bin_number)[1] # ax=plt.subplot(projection=Qtot_cut_wcs) ax=plt.subplot('111', projection=Qtotbin_wcs) ax.tick_params(direction='in') ax.text(9, 31, galaxy+' Q$_{tot}$', fontsize=17) # ax.set_xticks([]) # ax.set_yticks([]) im=ax.imshow(Qtot_cutbin,origin='lower', vmax=3.0, norm=colors.PowerNorm(gamma=0.5)) # rings[11].plot() # rings[13].plot() plt.xlabel('J2000 Right Ascension') plt.ylabel('J2000 Declination') cbar=plt.colorbar(im) cbar.set_label('$Q_{tot}$',fontsize=24) cbar.ax.tick_params(labelsize=20) ax.contour(SFR_cutbin,levels=levels,colors=['red']) plt.savefig(picDir+galaxy_label+'_Toomre_map.png') ############################################################ # check fig=plt.figure() circle=SkyCircularAperture(positions=position, r=3*u.arcsec) circle_pix=circle.to_pixel(Qtot_cut_wcs) plt.imshow(Qtot_cut, origin='lower') circle_pix.plot()
############################################################ # main program Dir='/1/home/heh15/workingspace/Arp240/NGC5258/12CO10/' imageDir=Dir+'casa5.4/' regionDir=Dir+'region/' fitsimage=imageDir+'NGC5258_12CO10_combine_contsub_pbcor_mom0.fits' wcs=fits_import(fitsimage)[0] data_masked=fits_import(fitsimage)[1] data=data_masked.data # regionfile=regionDir+'southarm.reg' # southarm=read_ds9(regionfile)[0] r=0.5/0.485*u.arcsec southarm=SkyCircularAperture(positions=position,r=r) southarm_pix=southarm.to_pixel(wcs) southarm_masked=Apmask_convert(southarm_pix,data) intensity_southarm=np.ma.mean(southarm_masked)*incl regionfile=regionDir+'whole.reg' whole_pix=read_ds9(regionfile)[0] # whole_pix=whole.to_pixel(wcs) fig=plt.figure() ax=plt.subplot('111',projection=wcs) plt.imshow(data,origin='lower') southarm_pix.plot() def Apmask_convert(aperture,data_cut): apmask=aperture.to_mask()
def plot_image(self, data, wcs, coords=None): """ convience function to plot data on a wcs projection Input: data - the data array wcs - the WCS object coords - the coordinates of the object for plotting (1x2 array, optional) """ # set up the plot fig, axs = plt.subplots(1, 1, figsize=(8, 8), subplot_kw={'projection': wcs}) # set up limits of the colour scale for plotting vmin = 5e-2 # plot axs.imshow(data, cmap='jet', interpolation='nearest', origin='lower', norm=LogNorm(vmin=vmin)) #axs.scatter(coords[0], coords[1], transform=axs.get_transform('fk5'), s=20000, lw=2, # edgecolor='white', facecolor='none') # define the apertures to plot (these are the same as in other functions) # SNR position = SkyCoord(self.ra_deg * u.degree, self.dec_deg * u.degree, frame='icrs') snr_aperture = SkyCircularAperture(position, r=self.radius * u.arcsec) snr_pix_aperture = snr_aperture.to_pixel(wcs) snr_pix_aperture.plot(color='white', lw=3, alpha=1.0) # BKG x = Angle(self.radius, u.arcsec) y = 2.25 * x.degree z = y * 2.5 t1_pos = SkyCoord((self.ra_deg + z) * u.degree, (self.dec_deg) * u.degree, frame='icrs') t2_pos = SkyCoord((self.ra_deg - z) * u.degree, (self.dec_deg) * u.degree, frame='icrs') t3_pos = SkyCoord((self.ra_deg) * u.degree, (self.dec_deg + y) * u.degree, frame='icrs') t4_pos = SkyCoord((self.ra_deg) * u.degree, (self.dec_deg - y) * u.degree, frame='icrs') ap1 = SkyCircularAperture(t1_pos, r=self.radius * u.arcsec) ap1_pix = ap1.to_pixel(wcs) ap1_pix.plot(color='white', lw=4, ls='--', alpha=1.0) ap2 = SkyCircularAperture(t2_pos, r=self.radius * u.arcsec) ap2_pix = ap2.to_pixel(wcs) ap2_pix.plot(color='white', lw=4, ls='--', alpha=1.0) ap3 = SkyCircularAperture(t3_pos, r=self.radius * u.arcsec) ap3_pix = ap3.to_pixel(wcs) ap3_pix.plot(color='white', lw=4, ls='--', alpha=1.0) ap4 = SkyCircularAperture(t4_pos, r=self.radius * u.arcsec) ap4_pix = ap4.to_pixel(wcs) ap4_pix.plot(color='white', lw=4, ls='--', alpha=1.0) # MIRI Imager FOVs x = Angle(self.radius, u.arcsec) y = x.degree z = y * 2.5 t1_pos = SkyCoord((self.ra_deg + z) * u.degree, (self.dec_deg) * u.degree, frame='icrs') t2_pos = SkyCoord((self.ra_deg - z) * u.degree, (self.dec_deg) * u.degree, frame='icrs') t3_pos = SkyCoord((self.ra_deg) * u.degree, (self.dec_deg + y) * u.degree, frame='icrs') t4_pos = SkyCoord((self.ra_deg) * u.degree, (self.dec_deg - y) * u.degree, frame='icrs') ap1 = SkyRectangularAperture(t1_pos, 74 * u.arcsec, 113 * u.arcsec, 90 * u.degree) ap1_pix = ap1.to_pixel(wcs) ap1_pix.plot(color='white', lw=5, ls=':', alpha=1.0) ap2 = SkyRectangularAperture(t2_pos, 74 * u.arcsec, 113 * u.arcsec, 90 * u.degree) ap2_pix = ap2.to_pixel(wcs) ap2_pix.plot(color='white', lw=5, ls=':', alpha=1.0) ap3 = SkyRectangularAperture(t3_pos, 74 * u.arcsec, 113 * u.arcsec, 0 * u.degree) ap3_pix = ap3.to_pixel(wcs) ap3_pix.plot(color='white', lw=5, ls=':', alpha=1.0) ap4 = SkyRectangularAperture(t4_pos, 74 * u.arcsec, 113 * u.arcsec, 0 * u.degree) ap4_pix = ap4.to_pixel(wcs) ap4_pix.plot(color='white', lw=5, ls=':', alpha=1.0) axs.set_facecolor('black') axs.coords.grid(True, color='white', ls='dotted') axs.coords[0].set_axislabel('Right Ascension (J2000)') axs.coords[1].set_axislabel('Declination (J2000)') # display the plot plt.tight_layout() # save as a pdf plot_name = os.path.join( str(self.name), str(self.name) + '_' + str(self.wavelength) + '.pdf') try: os.remove(plot_name) except: pass fig.savefig(plot_name, dpi=200)
def sb_at_frb(host, cut_dat: np.ndarray, cut_err: np.ndarray, wcs: WCS, fwhm=3., physical=False, min_uncert=2): """ Measure the surface brightness at an FRB location in a host galaxy Args: host (Host object): host galaxy object from frb repo cut_dat (np.ndarray): data (data from astorpy 2D Cutout object) cut_err (np.ndarray): inverse variance of data (from astropy 2D Cutout object) wcs (WCS): WCS for the cutout fwhm (float, optional): FWHM of the PSF of the image in either pixels or kpc. Defaults to 3 [pix]. physical (bool, optional): If True, FWHM is in kpc. Defaults to False. min_uncert (int, optional): Minimum localization unceratainty for the FRB, in pixels. Defaults to 2. Returns: tuple: sb_average, sb_average_err [counts/sqarcsec] """ # Generate the x,y grid of coordiantes x = np.arange(np.shape(cut_dat)[0]) y = np.arange(np.shape(cut_dat)[1]) xx, yy = np.meshgrid(x, y) coords = wcs_utils.pixel_to_skycoord(xx, yy, wcs) xfrb, yfrb = wcs_utils.skycoord_to_pixel(host.frb.coord, wcs) plate_scale = coords[0, 0].separation(coords[0, 1]).to('arcsec').value # Calculate total a, b uncertainty (FRB frame) uncerta, uncertb = host.calc_tot_uncert() # Put in pixel space uncerta /= plate_scale uncertb /= plate_scale # Set a minimum threshold uncerta = max(uncerta, min_uncert) uncertb = max(uncertb, min_uncert) # check if in ellipse -- pixel space! theta = host.frb.eellipse['theta'] in_ellipse = ( (xx - xfrb.item()) * np.cos(theta) + (yy - yfrb.item()) * np.sin(theta))**2 / (uncerta**2) + ( (xx - xfrb.item()) * np.sin(theta) - (yy - yfrb.item()) * np.cos(theta))**2 / (uncertb**2) <= 1 idx = np.where(in_ellipse) xval = xx[idx] yval = yy[idx] # x, y gal on the tilted grid (same for frb coords) xp = yval * np.cos(theta) - xval * np.sin(theta) yp = xval * np.cos(theta) + yval * np.sin(theta) xpfrb = yfrb.item() * np.cos(theta) - xfrb.item() * np.sin(theta) ypfrb = xfrb.item() * np.cos(theta) + yfrb.item() * np.sin(theta) # convert fwhm from pixels to arcsec or kpc to arcsec if physical: fwhm_as = fwhm * units.kpc * defs.frb_cosmo.arcsec_per_kpc_proper( host.z) else: fwhm_as = fwhm * plate_scale * units.arcsec # Aperture photometry at every pixel in the ellipse photom = [] photom_var = [] for i in np.arange(np.shape(idx)[1]): aper = SkyCircularAperture(coords[idx[0][i], idx[1][i]], fwhm_as) apermap = aper.to_pixel(wcs) # aperture photometry for psf-size within the galaxy photo_frb = aperture_photometry(cut_dat, apermap) photo_err = aperture_photometry(1 / cut_err, apermap) photom.append(photo_frb['aperture_sum'][0]) photom_var.append(photo_err['aperture_sum'][0]) # ff prob distribution p_ff = np.exp(-(xp - xpfrb)**2 / (2 * uncerta**2)) * np.exp(-(yp - ypfrb)**2 / (2 * uncertb**2)) f_weight = (photom / (np.pi * fwhm_as.value**2)) * p_ff # weighted photometry fvar_weight = (photom_var / (np.pi * fwhm_as.value**2)) * p_ff # weighted sigma weight_avg = np.sum(f_weight) / np.sum(p_ff) # per unit area (arcsec^2) # Errors weight_var_avg = np.sum(fvar_weight) / np.sum(p_ff) weight_err_avg = np.sqrt(weight_var_avg) return weight_avg, weight_err_avg
from regions import read_ds9 fitsimage = imageDir + 'mass_map.fits' hdr = fits.open(fitsimage)[0].header wcs = fits_import(fitsimage)[0] mass = fits_import(fitsimage)[1] # file=regionDir+'stellar_total.reg' # whole_star=read_ds9(file)[0] # wholestar_pix=whole_star.to_pixel(wcs) # whole_masked=Apmask_convert(wholestar_pix, mass) # SM=np.ma.sum(whole_masked)*(480*0.3)**2 radius = 17.53 # SDSS petrosian radius for NGC 5257 in arcsec. center = position aperture_whole = SkyCircularAperture(center, radius * u.arcsec) aperture_whole_pix = aperture_whole.to_pixel(wcs=wcs) aperture_whole_masked = Apmask_convert(aperture_whole_pix, mass) SM = np.ma.sum(aperture_whole_masked) * (480 * 0.3)**2 fig = plt.figure() plt.imshow(mass, origin='lower') aperture_whole_pix.plot(color='red') #### check total stellar mass flux_36 = 19448.31 * 1e6 / (4.25e10) * 0.3**2 flux_45 = 13959 * 1e6 / (4.25e10) * 0.3**2 Mstar_total = mass_calc(flux_36, flux_45)
def show_cutout_with_slit(hdr, data=None, slit_ra=None, slit_dec=None, slit_shape='rectangular', slit_width=0.2, slit_length=3.3, slit_angle=90, slit_radius=0.2, slit_rout=0.5, cmap='Greys_r', plotname='', **kwargs): """Show a cutout image with the slit(s) superimposed. Parameters ---------- hdr : dict Cutout image header. data : ndarray or `None`, optional Cutout image data. If not given, data is not shown. slit_ra, slit_dec : float or array or `None`, optional Slit RA and DEC in degrees. Default is to use object position from image header. If an array is given, each pair of RA and DEC becomes a slit. slit_shape : {'annulus', 'circular', 'rectangular'}, optional Shape of the slit (circular or rectangular). Default is rectangular. slit_width, slit_length : float, optional Rectangular slit width and length in arcseconds. Defaults are some fudge values. slit_angle : float, optional Rectangular slit angle in degrees for the display. Default is vertical. slit_radius : float, optional Radius of a circular or annulus slit in arcseconds. For annulus, this is the inner radius. Default is some fudge value. slit_rout : float, optional Outer radius of an annulus slit in arcseconds. Default is some fudge value. cmap : str or obj, optional Matplotlib color map for image display. Default is grayscale. plotname : str, optional Filename to save plot as. If not given, it is not saved. kwargs : dict, optional Keyword argument(s) for the aperture overlay. If ``ax`` is given, it will also be used for image display. See Also -------- make_cutouts """ # Optional dependencies... import matplotlib.pyplot as plt from photutils import (SkyCircularAnnulus, SkyCircularAperture, SkyRectangularAperture) if slit_ra is None: slit_ra = hdr['OBJ_RA'] if slit_dec is None: slit_dec = hdr['OBJ_DEC'] position = SkyCoord(slit_ra, slit_dec, unit='deg') if slit_shape == 'circular': slit_radius = u.Quantity(slit_radius, u.arcsec) aper = SkyCircularAperture(position, slit_radius) elif slit_shape == 'annulus': slit_rin = u.Quantity(slit_radius, u.arcsec) slit_rout = u.Quantity(slit_rout, u.arcsec) aper = SkyCircularAnnulus(position, slit_rin, slit_rout) else: # rectangular slit_width = u.Quantity(slit_width, u.arcsec) slit_length = u.Quantity(slit_length, u.arcsec) slit_angle = u.Quantity(slit_angle, u.degree) aper = SkyRectangularAperture(position, slit_width, slit_length, theta=slit_angle) wcs = WCS(hdr) aper_pix = aper.to_pixel(wcs) ax = kwargs.get('ax', plt) if data is not None: ax.imshow(data, cmap=cmap, origin='lower') aper_pix.plot(**kwargs) if plotname: ax.savefig(plotname)
def extract_photometry(ccddata, catalog, catalog_coords, target, image_path=None, aperture_radius=2. * u.arcsec, bg_radius_in=None, bg_radius_out=None): apertures = SkyCircularAperture(catalog_coords, aperture_radius) if bg_radius_in is not None and bg_radius_out is not None: apertures = [ apertures, SkyCircularAnnulus(catalog_coords, bg_radius_in, bg_radius_out) ] photometry = aperture_photometry(ccddata, apertures) target_row = photometry[target][0] if target_row['xcenter'].value < 0. or target_row['xcenter'].value > ccddata.shape[1] or \ target_row['ycenter'].value < 0. or target_row['ycenter'].value > ccddata.shape[0]: logging.error( 'target not contained in the image (or coordinate solution is bad)' ) return if 'aperture_sum_1' in photometry.colnames: flux = photometry['aperture_sum_0'] - photometry['aperture_sum_1'] dflux = (photometry['aperture_sum_err_0']**2. + photometry['aperture_sum_err_1']**2.)**0.5 else: flux = photometry['aperture_sum'] dflux = photometry['aperture_sum_err'] photometry['aperture_mag'] = u.Magnitude(flux / ccddata.meta['exptime']) photometry['aperture_mag_err'] = 2.5 / np.log(10.) * dflux / flux photometry = hstack([catalog, photometry]) photometry['zeropoint'] = photometry['catalog_mag'] - photometry[ 'aperture_mag'].value zeropoints = photometry['zeropoint'][~target].filled(np.nan) zp = np.nanmedian(zeropoints) zperr = mad_std( zeropoints, ignore_nan=True) / np.isfinite(zeropoints).sum()**0.5 # std error target_row = photometry[target][0] mag = target_row['aperture_mag'].value + zp dmag = (target_row['aperture_mag_err'].value**2. + zperr**2.)**0.5 with open(lc_file, 'a') as f: f.write( f'{ccddata.meta["MJD-OBS"]:11.5f} {mag:6.3f} {dmag:5.3f} {zp:6.3f} {zperr:5.3f} {ccddata.meta["FILTER"]:>6s} ' f'{ccddata.meta["TELESCOP"]:>16s} {ccddata.meta["filename"]:>22s}\n' ) if image_path is not None: ax = plt.axes() mark = ',' if np.isfinite( photometry['aperture_mag']).sum() > 1000 else '.' ax.plot(photometry['aperture_mag'], photometry['catalog_mag'], ls='none', marker=mark, zorder=1, label='calibration stars') ax.plot(mag - zp, mag, ls='none', marker='*', zorder=3, label='target') yfit = np.array([21., 13.]) xfit = yfit - zp ax.plot(xfit, yfit, label=f'$Z = {zp:.2f}$ mag', zorder=2) ax.set_xlabel('Instrumental Magnitude') ax.set_ylabel('AB Magnitude') ax.legend() plt.savefig(image_path, overwrite=True) plt.savefig('latest_cal.pdf', overwrite=True) plt.close() plt.figure(figsize=(6., 6.)) imshow_norm(ccddata.data, interval=ZScaleInterval()) plt.axis('off') plt.axis('tight') plt.tight_layout(pad=0.) if isinstance(apertures, list): for aperture in apertures: aperture.to_pixel(ccddata.wcs).plot(color='r', lw=1) else: apertures.to_pixel(ccddata.wcs).plot(color='r', lw=1) image_filename = ccddata.meta['filename'].replace('.fz', '').replace( '.fits', '.png') plt.savefig(os.path.join(image_dir, image_filename), overwrite=True) plt.savefig('latest_image.png', overwrite=True) plt.close()
def show_cutout_with_slit(hdr, data=None, slit_ra=None, slit_dec=None, slit_shape='rectangular', slit_width=0.2, slit_length=3.3, slit_angle=90, slit_radius=0.2, slit_rout=0.5, cmap='Greys_r', plotname='', **kwargs): """Show a cutout image with the slit(s) superimposed. Parameters ---------- hdr : dict Cutout image header. data : ndarray or `None`, optional Cutout image data. If not given, data is not shown. slit_ra, slit_dec : float or array or `None`, optional Slit RA and DEC in degrees. Default is to use object position from image header. If an array is given, each pair of RA and DEC becomes a slit. slit_shape : {'annulus', 'circular', 'rectangular'}, optional Shape of the slit (circular or rectangular). Default is rectangular. slit_width, slit_length : float, optional Rectangular slit width and length in arcseconds. Defaults are some fudge values. slit_angle : float, optional Rectangular slit angle in degrees for the display. Default is vertical. slit_radius : float, optional Radius of a circular or annulus slit in arcseconds. For annulus, this is the inner radius. Default is some fudge value. slit_rout : float, optional Outer radius of an annulus slit in arcseconds. Default is some fudge value. cmap : str or obj, optional Matplotlib color map for image display. Default is grayscale. plotname : str, optional Filename to save plot as. If not given, it is not saved. kwargs : dict, optional Keyword argument(s) for the aperture overlay. If ``ax`` is given, it will also be used for image display. See Also -------- make_cutouts """ # Optional dependencies... import matplotlib.pyplot as plt from photutils import (SkyCircularAnnulus, SkyCircularAperture, SkyRectangularAperture) from scipy.ndimage.interpolation import rotate if slit_ra is None: slit_ra = hdr['OBJ_RA'] if slit_dec is None: slit_dec = hdr['OBJ_DEC'] position = SkyCoord(slit_ra, slit_dec, unit='deg') if slit_shape == 'circular': slit_radius = u.Quantity(slit_radius, u.arcsec) aper = SkyCircularAperture(position, slit_radius) elif slit_shape == 'annulus': slit_rin = u.Quantity(slit_radius, u.arcsec) slit_rout = u.Quantity(slit_rout, u.arcsec) aper = SkyCircularAnnulus(position, slit_rin, slit_rout) else: # rectangular slit_width = u.Quantity(slit_width, u.arcsec) slit_length = u.Quantity(slit_length, u.arcsec) theta = u.Quantity(90, u.degree) aper = SkyRectangularAperture(position, slit_width, slit_length, theta=theta) # Rotate data and keep slit upright if data is not None: data = rotate(data, slit_angle - theta.value, reshape=False) wcs = WCS(hdr) aper_pix = aper.to_pixel(wcs) ax = kwargs.get('ax', plt) if data is not None: ax.imshow(data, cmap=cmap, origin='lower') aper_pix.plot(**kwargs) if plotname: ax.savefig(plotname)
# wcs=fits_import(fitsimage)[0] # data=fits_import(fitsimage)[1] # flux measured from original image via casa. flux_33GHz = 2.16e-3 error = 1.1e-5 / 3.4e-4 * flux_33GHz # compare to the smoothed image filename = imageDir + 'NGC5258_33GHz_pbcor_smooth.fits' wcs_33GHz = fits_import(filename)[0] data_33GHz = fits_import(filename)[1] ra = (13 * u.degree + 39 * u.arcmin + 57.14 * u.arcsec) * 15 dec = 49 * u.arcmin + 44.309 * u.arcsec position = SkyCoord(dec=dec, ra=ra, frame='icrs') southarm_sky = SkyCircularAperture(positions=position, r=3 * ratio * u.arcsec) southarm_pix = southarm_sky.to_pixel(wcs_33GHz) flux = aperture_photometry(data_33GHz, apertures=southarm_pix)['aperture_sum'][0] flux = float(flux / (beamarea / pixsize)) freq = 33 SFR_33GHz = sfr_radio(flux_33GHz, freq, d) df['region']['33GHz'] = 'south' df['flux']['33GHz'] = flux_33GHz df['SFR']['33GHz'] = SFR_33GHz df['uncertainty']['33GHz'] = error / flux_33GHz * SFR_33GHz fig = plt.figure() plt.imshow(data_33GHz, origin='lower') southarm_pix.plot(color='red')
def plot_image(self, data, wcs, coords=None): """ convience function to plot data on a wcs projection Input: data - the data array wcs - the WCS object coords - the coordinates of the object for plotting (1x2 array, optional) """ # set up the plot fig, axs = plt.subplots(1, 1, figsize=(8, 8), subplot_kw={'projection': wcs}) # set up limits of the colour scale for plotting vmin = 1e-1 vmax = np.max(data) * 0.9 # plot axs.imshow(data, cmap='magma', interpolation='nearest', origin='lower', norm=LogNorm(vmin=vmin, vmax=vmax)) #axs.scatter(coords[0], coords[1], transform=axs.get_transform('fk5'), s=20000, lw=2, # edgecolor='white', facecolor='none') # define the apertures to plot (these are the same as in other functions) # SNR position = SkyCoord(self.ra_deg * u.degree, self.dec_deg * u.degree, frame='icrs') snr_aperture = SkyCircularAperture(position, r=self.radius * u.arcsec) snr_pix_aperture = snr_aperture.to_pixel(wcs) snr_pix_aperture.plot(color='white', lw=5, alpha=1.0) # BKG r = self.radius * u.arcsec r_in = r + (40. * u.arcsec) r_out = r + (100. * u.arcsec) bkg_ap = SkyCircularAnnulus(position, r_in=r_in, r_out=r_out) bkg_ap_pix = bkg_ap.to_pixel(wcs) bkg_ap_pix.plot(color='red', lw=3, ls='--', alpha=0.9) # MIRI Imager r = self.radius * u.arcsec r_in = r - (37. * u.arcsec) r_out = r + (37. * u.arcsec) arc_ap = SkyCircularAnnulus(position, r_in=r_in, r_out=r_out) arc_ap_pix = arc_ap.to_pixel(wcs) arc_ap_pix.plot(color='cyan', lw=3, ls=':', alpha=0.9) axs.set_facecolor('black') axs.coords.grid(True, color='white', ls='dotted') axs.coords[0].set_axislabel('Right Ascension (J2000)') axs.coords[1].set_axislabel('Declination (J2000)') # indicative MIRI FOV x = Angle(self.radius, u.arcsec) y = x.degree t3_pos = SkyCoord((self.ra_deg) * u.degree, (self.dec_deg + y) * u.degree, frame='icrs') ap3 = SkyRectangularAperture(t3_pos, 74 * u.arcsec, 113 * u.arcsec, 0 * u.degree) ap3_pix = ap3.to_pixel(wcs) ap3_pix.plot(color='yellow', lw=3, ls='-', alpha=0.9) axs.set_facecolor('black') axs.coords.grid(True, color='white', ls='dotted') axs.coords[0].set_axislabel('Right Ascension (J2000)') axs.coords[1].set_axislabel('Declination (J2000)') # display the plot plt.tight_layout() # save as a pdf plot_name = os.path.join( str(self.name), str(self.name) + '_' + str(self.wavelength) + '.pdf') try: os.remove(plot_name) except: pass fig.savefig(plot_name, dpi=200)