def residual_jitter(array, array_spax, res_jitt): '''Function that takes wavelength channel array and convolves with Gaussian of FWHM given by res_jitt. Inputs: array: 2D array corresponding to wavelength channel array_spax: Spatial scale of array [mas/pix] res_jitt: Residual jitter sigma in units of [mas] FWHM = 2.*n.sqrt(2.*n.log(2.))*sigma Outputs: jitt_array: New array of jittered PSF. ''' #If res_jitt == 0, ignore function and return array. if res_jitt == 0.: return array else: fwhm_jitt = 2. * n.sqrt(2. * n.log(2.)) * res_jitt pix_fwhm = abs(fwhm_jitt) / (array_spax) g_array = Gauss2D(array.shape[0], pix_fwhm) #Convolve using FFTs conv_array = n.fft.ifft2(n.fft.fft2(array) * n.fft.fft2(g_array)) jitt_array = n.fft.fftshift(conv_array.real) return jitt_array
def create_instpsf(array_dim, psfspax, output_spax, psfoutspax): '''Function that creates an instrument PSF array given the parameter values and sampling scale. Inputs: array_dim: Size of PSF array psfspax: PSF sampling scale [mas/spaxel] output_spax: Output sampling scale tuple (x, y) [mas/spaxel] psfoutspax: PSF convolution sampling scale to match datacube: tuple (x, y) [mas/spaxel] Outputs: instpsf = 2D PSF array ''' #FWHM of Instrument PSF depending on output spaxel scale #Factors taken into account: #design image quality, manufacturing and assembly tolerances, vibration, flexure, diff refraction, #Also interpolating the data back onto a regular grid. #The interpolation adds another contribution of 0.8-1.8 PIXEL FWHM. #So a reasonable assumption: 1.1 pix FWHM. #FWHMs given in mas according to output spaxel scale instpsf_data = { (30., 60.): 65., (20., 20.): 34., (10., 10.): 17., (4., 4.): 6. } #print 'SPAX = ', output_spax try: FWHM = instpsf_data[output_spax] #print 'FWHM = ', FWHM instpsf = Gauss2D(array_dim, FWHM / float(psfspax)) except: #print 'Non-HARMONI spaxel scale - no instrument PSF' instpsf = n.zeros([array_dim, array_dim], dtype=float) instpsf[array_dim / 2, array_dim / 2] = 1.0 #total field of view in mas x_field = array_dim * psfspax y_field = array_dim * psfspax x_newsize = x_field / float(psfoutspax[0]) y_newsize = y_field / float(psfoutspax[1]) instpsf = frebin(instpsf, (x_newsize, y_newsize), total=True) return instpsf
def create_Gausspsf_channel(wave, seeing, aperture, res_jitter, array_dim, Nyquist, psfspax, output_spax): '''Function that creates a 2D spatial Gaussian PSF. The FWHM of the Gaussian is depends on wavelength in the following way: FWHM(radians) = 0.98 Lambda/r_0 r_0 = A Lambda^(6/5.) FWHM(arcsec) = (0.98/A)/Lambda^(1/5.) Inputs: wave: wavelength [microns] seeing: FWHM value of the seeing at 500nm (V-band) in arcseconds. aperture: List containing [diameter of telescope, obscuration ratio]. Diameter only used when Nyquist=True. array_dim: Spatial size of PSF arrays. Nyquist: Boolean - True returns Nyquist sampling for each wavelength channel. - False uses value of spaxel. psfspax: Initial spatial sampling value [mas]. output_spax: Output spatial sampling [mas]. Output: psf: PSF array for given wavelength. ''' ## lam = 500.E-9 ## #Compute r_0 from given seeing value ## r_0 = 0.98*lam/float(seeing/206265.) ## ## #Use r_0 to find A ## A = r_0/lam**(6/5.) ## ## #Use A to find constant for FWHM propto Lambda**(-1/5) equation ## B = 0.98*206265./A r0 = 0.976 * 500.E-9 / float(seeing) * (180. / n.pi * 3600.) * (wave / 0.5)**1.2 #in m fwhm = seeing * (wave / 0.5)**(-0.2) * n.sqrt( 1. + (1. / (1. + 300. * aperture[0] / 23.) - 1) * 2.183 * (r0 / 23.)**(0.356)) #in arcsec if Nyquist: #fwhm = B/float((wave*(1.E-6))**(1/5.)) #in arcsec diff = wave * (1.E-6) / (2. * float(aperture[0])) diff *= 206265 #in arcsec/spaxel channel = Gauss2D(array_dim, fwhm / diff) #Apply residual jitter psf = residual_jitter(channel, diff, res_jitter) elif not Nyquist: spax = psfspax / 1000. #in arcsec/spaxel #fwhm = B/float((wave*(1.E-6))**(1/5.)) #in arcsec channel = Gauss2D(array_dim, fwhm / spax) #Apply residual jitter psf = residual_jitter(channel, spax, res_jitter) #Normalise PSF psf /= psf.sum() #Frebin PSF up to same sampling as datacube channels #total field of view in mas x_field = array_dim * psfspax y_field = array_dim * psfspax x_newsize = x_field / float(output_spax[0]) y_newsize = y_field / float(output_spax[1]) psf = frebin(psf, (x_newsize, y_newsize), total=True) return psf