def get_gauss_beam(fwhm, pixscale, nfwhm=5.0, oversamp=5): """ Generate Gaussian kernel Parameters ---------- fwhm: float FWHM of the Gaussian beam. pixscale: float Pixel scale, in same units as FWHM. nfwhm: float Number of fwhm (approximately) of each dimension of the output beam. oversamp: int Odd integer giving the oversampling to use when constructing the beam. The beam is generated in pixscale / oversamp size pixels, then rebinned to pixscale. Notes ----- The beam is normalized by having a value of 1 in the center. If oversampling is used, the returned array will be the sum over the neighborhood of this maximum, so will not be one. """ if fwhm <= 0: raise ValueError("Invalid (negative) FWHM") if pixscale <= 0: raise ValueError("Invalid (negative) pixel scale") if nfwhm <= 0.0: raise ValueError("Invalid (non-positive) nfwhm") if fwhm / pixscale < 2.5: raise ValueError("Insufficiently well sampled beam") if oversamp < 1: raise ValueError("Invalid (<1) oversampling") retext = round(fwhm * nfwhm / pixscale) if retext % 2 == 0: retext += 1 bmsigma = fwhm / math.sqrt(8 * math.log(2)) if oversamp == 1: # Easy case beam = make_kernel((retext, retext), bmsigma / pixscale, 'gaussian').astype(np.float32) beam /= beam.max else: genext = retext * oversamp genpixscale = pixscale / oversamp gbeam = make_kernel((genext, genext), bmsigma / genpixscale, 'gaussian').astype(np.float32) gbeam /= gbeam.max() # Normalize -before- rebinning # Rebinning -- tricky stuff! bmview = gbeam.reshape(retext, oversamp, retext, oversamp) beam = bmview.mean(axis=3).mean(axis=1) return beam
def plot_2005ip(): ''' Create a plot of the combined NUV and FUV spectrum of SN 2005ip, label the common SN lines with different colors for different species and save ''' redshift = 0.0072 tbdata = fits.getdata('2005ip_all_x1dsum.fits', 1) sdqflags = fits.getval('2005ip_all_x1dsum.fits', 'sdqflags', 1) good_indx = np.where(tbdata['dq'][0] & sdqflags == 0) fig = pyplot.figure(figsize=[20, 10]) ax = fig.add_subplot(1, 1, 1) deredshift_wl = deredshift_wavelength(tbdata['wavelength'][0][good_indx], redshift) smoothed_signal = convolve.convolve( tbdata['flux'][0][good_indx], make_kernel.make_kernel([15], 15, 'boxcar')) ax.plot(deredshift_wl, smoothed_signal, 'b') ax = label_spectra(ax) ax.set_xlabel('Rest Wavelength ($\AA$)') ax.set_ylabel('Flux (ergs/cm^2/s/$\AA$)') ax.set_title( 'Preliminary HST/STIS Spectrum of SN 2005ip (smoothed by 15 pix)') ax.set_ylim(-0.1E-15, 0.25E-15) add_date_to_plot(ax) pyplot.savefig('2005ip_combined_labeled.pdf')
def plot_2009ip(): ''' Create a plot of the combined NUV and FUV spectrum of SN 2009ip, label the common SN lines with different colors for different species and save ''' redshift = 0.0072 tbdata = fits.getdata('2009ip_all_x1dsum.fits', 1) sdqflags = fits.getval('2009ip_all_x1dsum.fits', 'sdqflags', 1) good_indx = np.where(tbdata['dq'][0]&sdqflags == 0) fig = pyplot.figure(figsize = [20, 10]) ax = fig.add_subplot(1,1,1) deredshift_wl = deredshift_wavelength(tbdata['wavelength'][0][good_indx], redshift) smoothed_signal = convolve.convolve(tbdata['flux'][0][good_indx], make_kernel.make_kernel([15],15,'boxcar')) ax.plot(deredshift_wl, smoothed_signal, 'b') ax = label_spectra(ax) ax.set_xlabel('Rest Wavelength ($\AA$)') ax.set_ylabel('Flux (ergs/cm^2/s/$\AA$)') ax.set_title('Preliminary HST/STIS Spectrum of SN 2009ip (smoothed by 15 pix)') ax.set_ylim(-0.1E-15, 0.25E-15) add_date_to_plot(ax) pyplot.savefig('2009ip_combined_labeled.pdf')
m1 = data[x].mapstruct.map[0] m2 = data[y].mapstruct.map[0] yy1, xx1 = grid1 = np.indices(m1.shape) ratio = m2.shape[0] / float(m1.shape[0]) newm2 = scipy.ndimage.map_coordinates(np.nan_to_num(m2), grid1 * ratio) mask = (m1 == m1) * (newm2 == newm2) * (m1 > 0) * (newm2 > 0) #mask *= (m1>m1[mask].std()) * (newm2>newm2[mask].std()) rr = ((xx1 - m1.shape[1] / 3.)**2 + (yy1 - m1.shape[0] / 3.)**2)**0.5 #mask *= rr < 5 beamsize_delta = (np.abs(data[y].mapstruct['OMEGA_BEAM_AM'] - data[x].mapstruct['OMEGA_BEAM_AM']) / np.pi / 2)**0.5 am_per_pix = data[y].mapstruct['OMEGA_PIX_AM']**0.5 kernelwidth = beamsize_delta / am_per_pix kernel = make_kernel.make_kernel( m1.shape, kernelwidth=kernelwidth) #, normalize_kernel=np.max) newm1 = convolve.convolve_fft(m1, kernel, interpolate_nan=True) newm1 *= data[y].mapstruct['OMEGA_BEAM_AM'] / data[x].mapstruct[ 'OMEGA_BEAM_AM'] plot(newm1[mask], newm2[mask], 'o', alpha=0.5) #kernel = make_kernel.make_kernel(m1.shape, kernelwidth=5) #smm1 = convolve.convolve_fft(newm1,kernel, interpolate_nan=True) #smm2 = convolve.convolve_fft(newm2,kernel, interpolate_nan=True) #plot((newm1-smm1)[mask],(newm2-smm2)[mask],'rs', alpha=0.5) xx = np.linspace(newm1[mask].min(), newm1[mask].max()) plot(xx, xx * (band_waves[x] / band_waves[y])**3.5, 'r--') plot(xx, xx * (band_waves[x] / band_waves[y])**2, 'b:') subplots_adjust(hspace=0.3, wspace=0.3)
def convolve_and_match(data, objectname, clobber=True, writefits=True, unsharpscale=80): """ Convolve all bands to Band 0 resolution and resample all to Band 3 pixelization. The data values are appropriately scaled after smoothing such that they are in units of mJy/beam, where the beam is the Band 0 beam. Sanity checks on this front are warranted. Parameters ---------- data : dict of IDLSAVE structs objectname : str Object name for saving purposes clobber : bool Overwrite FITS files if they exist? writefits : bool Write the fits files to disk? unsharpscale : float Unsharp mask angular scale in arcseconds Returns ------- smoothdict : dict A dictionary of band number : smoothed & resampled map unsharpdict : dict A dictionary of band number : unsharp-masked map """ smoothed = {} unsharped = {} # the band 3 map is used as the reference pixel scale band3 = data[3].mapstruct.map[0] yy1,xx1 = grid1 = np.indices(band3.shape) pixscale = float(data[3].mapstruct['OMEGA_PIX_AM']**0.5 / 60.) pixscale_as = pixscale*3600 if writefits: header = fits.Header() header['CDELT1'] = pixscale header['CDELT2'] = pixscale ffile = fits.PrimaryHDU(data=band3, header=header) for ii in xrange(4): # grab the map from band i m = data[ii].mapstruct.map[0] # ratio of map sizes (assumes they're symmetric, sort of) ratio = m.shape[0]/float(band3.shape[0]) # rescale the band i map to band3 scale newm = scipy.ndimage.map_coordinates(np.nan_to_num(m), grid1*ratio) # flag out the NANs again (we had to make them zeros for the previous step to work) bads = scipy.ndimage.map_coordinates(np.array(m!=m,dtype='float'), grid1*ratio) newm[bads>0.5] = np.nan # Determine the appropriate convolution kernel size # beamsize = np.array([60*(v.mapstruct.omega_beam_am/np.pi/2.)**0.5 * (8*np.log(2))**0.5 for v in data.values()]).ravel() # array([ 45.00000061, 31.00000042, 25.00000034, 23.00000031]) # these check out... beamsize_delta = (np.abs(data[ii].mapstruct['OMEGA_BEAM_AM']-data[0].mapstruct['OMEGA_BEAM_AM'])/np.pi/2)**0.5 # pixel scale in the *output* image am_per_pix = data[3].mapstruct['OMEGA_PIX_AM']**0.5 # kernel width in pixels kernelwidth = beamsize_delta/am_per_pix if kernelwidth > 0: kernel = make_kernel.make_kernel(band3.shape, kernelwidth=kernelwidth) newm = convolve.convolve_fft(newm, kernel, interpolate_nan=True) # rescale the values to be mJy per a much larger beam; the values should therefore be larger newm *= data[0].mapstruct['OMEGA_BEAM_AM']/data[ii].mapstruct['OMEGA_BEAM_AM'] # Now do an unsharp mask with a fairly large kernel to ensure the spatial filters are identical kernel = make_kernel.make_kernel(band3.shape, kernelwidth=unsharpscale/pixscale_as) smm = convolve.convolve_fft(newm,kernel, interpolate_nan=True) smoothed[ii] = newm unsharped[ii] = newm-smm if writefits: ffile.data = newm ffile.writeto("%s_Band%i_smooth.fits" % (objectname,ii), clobber=clobber) ffile.data = newm - smm ffile.writeto("%s_Band%i_smooth_unsharp.fits" % (objectname,ii), clobber=clobber) return smoothed,unsharped
m1 = data[x].mapstruct.map[0] m2 = data[y].mapstruct.map[0] yy1, xx1 = grid1 = np.indices(m1.shape) ratio = m2.shape[0] / float(m1.shape[0]) newm2 = scipy.ndimage.map_coordinates(np.nan_to_num(m2), grid1 * ratio) mask = (m1 == m1) * (newm2 == newm2) * (m1 > 0) * (newm2 > 0) # mask *= (m1>m1[mask].std()) * (newm2>newm2[mask].std()) rr = ((xx1 - m1.shape[1] / 3.0) ** 2 + (yy1 - m1.shape[0] / 3.0) ** 2) ** 0.5 # mask *= rr < 5 beamsize_delta = ( np.abs(data[y].mapstruct["OMEGA_BEAM_AM"] - data[x].mapstruct["OMEGA_BEAM_AM"]) / np.pi / 2 ) ** 0.5 am_per_pix = data[y].mapstruct["OMEGA_PIX_AM"] ** 0.5 kernelwidth = beamsize_delta / am_per_pix kernel = make_kernel.make_kernel(m1.shape, kernelwidth=kernelwidth) # , normalize_kernel=np.max) newm1 = convolve.convolve_fft(m1, kernel, interpolate_nan=True) newm1 *= data[y].mapstruct["OMEGA_BEAM_AM"] / data[x].mapstruct["OMEGA_BEAM_AM"] plot(newm1[mask], newm2[mask], "o", alpha=0.5) # kernel = make_kernel.make_kernel(m1.shape, kernelwidth=5) # smm1 = convolve.convolve_fft(newm1,kernel, interpolate_nan=True) # smm2 = convolve.convolve_fft(newm2,kernel, interpolate_nan=True) # plot((newm1-smm1)[mask],(newm2-smm2)[mask],'rs', alpha=0.5) xx = np.linspace(newm1[mask].min(), newm1[mask].max()) plot(xx, xx * (band_waves[x] / band_waves[y]) ** 3.5, "r--") plot(xx, xx * (band_waves[x] / band_waves[y]) ** 2, "b:") subplots_adjust(hspace=0.3, wspace=0.3) xlabel("Band %i: %0.2f mm" % (x, band_waves[x]))