simcado.psf module¶
PSFs and PSFCubes¶
Todo
revise this opening text
Description¶
Car Sagan said
- “If you want to bake an apple pie from scratch,
first you must create the universe”
Single PSFs¶
We need to start by generating a single PSF in order to generate a PSFCube. We need to know the spatial characteristics of the PSF: The commonalities of all PSFs are:
pix_width
pix_height
pix_res
type
The types of PSF offered: Moffat, Gaussian2D, Airy, Delta, Line, User For each of the PSF types we need to create a subclass of PSF. Each subclass takes its own list of parameters:
MoffatPSF (alpha, beta)
GaussianPSF (fwhm, eccentricity=0, angle=0)
AiryPSF (first_zero, eccentricity=0, angle=0)
DeltaPSF (x=0, y=0)
LinePSF (x0, x1, y0, y1, angle=0)
UserPSFCube (filename, ext_no=0)
Multiple PSFs in a Cube¶
To generate a PSF cube we need to know the spectral bins and the type of PSF. The bins are defined by a central wavelength, however a cube should also contain the edges of each bin so that transmission and emission can be re-binned properly. - lam_bin_centers - lam_bin_edges - lam_res
A PSF instance will have these additional arguments: - array … a 2D array to hold the PSF image
A psf instance will have these additional arguments: - cube … a (l,x,y) 3D array to hold the PSF cube
As far as input goes, psf should be able to accept a dictionary with the keywords necessary to build the cube.
Notes¶
All wavelength values are given in [um] All pixel dimensions are given in [arcsec] All angles are given in [deg]
Classes¶
PSF(object) psf(object)
Subclasses¶
MoffatPSF(PSF) GaussianPSF(PSF) AiryPSF(PSF) DeltaPSF(PSF) LinePSF(PSF) UserPSFCube(PSF)
Deltapsf(psf) Airypsf(psf) Gaussianpsf(psf) Moffatpsf(psf) CombinedPSFCube(psf) UserPSFCube(psf) ADC_psf(psf)
There are two types of psf object here: - a cube - a single psf image
The cube is essentially a list of psf images, homogenized in size Should we have separate classes for these?
Both PSF and psf can be created from a single model or through convolution of a list of PSF components
-
class
simcado.psf.
PSF
(size, pix_res)[source]¶ Bases:
object
Point spread function (single layer) base class
- Parameters
- sizeint
[pixel] the side length of the array
- pix_resfloat
[arcsec] the pixel scale of the array
-
convolve
(self, kernel)[source]¶ Convolve the PSF with another kernel. The PSF keeps its shape
- Parameters
- kernelnp.array, PSF
Either a numpy.ndarray or a PSF (sub)class
- Returns
- psf_newPSF
-
resample
(self, new_pix_res)[source]¶ Resample the PSF array onto a new grid
Not perfect, but conserves flux
- Parameters
- new_pix_resfloat
[arcsec] the pixel resolution of the returned array
- Returns
- psf_newPSF
Examples
>>> new_PSF = old_PSF.resample(new_pix_res)
-
resize
(self, new_size)[source]¶ Resize the PSF. The target shape is (new_size, new_size).
- Parameters
- new_sizeint
the new square dimensions of the PSF array in pixels
-
set_array
(self, array, threshold=1e-15)[source]¶ Set the spatial flux distribution array for the PSF
Renormalise the array make sure there aren’t any negative values that will screw up the flux
- Parameters
- arraynp.ndarray
the array representing the PSF
- thresholdfloat
by default set to 1E-15. Below this, the array is set to 0
-
class
simcado.psf.
PSFCube
(lam_bin_centers)[source]¶ Bases:
object
Class holding wavelength dependent point spread function.
- Parameters
- lam_bin_centersarray
[um] the centre of each wavelength slice
Notes
len(self) return the number of layers in the psf
self[i] returns the PSF object for layer i. If the __array__ function is called, self[i] will return the array associated with the instance e.g plt.imshow(self[i]) will plot PSF.array from self.psf_slices[i]
Maths operators *,+,- act equally on all PSF.arrays in self.psf_slices
-
convolve
(self, kernel_list)[source]¶ Convolve a list of PSFs with a list of kernels
- Parameters
- kernel_listlist
list of PSF objects of 2D arrays
-
export_to_fits
(self, filename, clobber=True)[source]¶ Export the psf to a FITS file for later use
- Parameters
- filenamestr
-
nearest
(self, lam)[source]¶ Returns the PSF closest to the desired wavelength, lam [um]
- Parameters
- lamfloat
[um] desired wavelength
- Returns
- psf_slicePSF
-
class
simcado.psf.
MoffatPSF
(fwhm, **kwargs)[source]¶ Bases:
simcado.psf.PSF
Generate a PSF for a Moffat function. Alpha is generated from the FWHM and Beta = 4.765 (from Trujillo et al. 2001)
- Parameters
- fwhmfloat
[arcsec] the equivalent FWHM of the Airy disk core.
- sizeint
[pixel] the side length of the array
- pix_resfloat
[arcsec] the pixel scale used in the array, default is 0.004
- modestr
[‘oversample’,’linear_interp’] see Kernel2D (scipy.convolution.core)
-
class
simcado.psf.
MoffatPSFCube
(lam_bin_centers, fwhm=None, **kwargs)[source]¶ Bases:
simcado.psf.PSFCube
Generate a list of MoffatPSFs for wavelengths defined in lam_bin_centers
- Parameters
- lam_bin_centersarray, list
[um] a list with the centres of each wavelength slice
- fwhmarray, list
[arcsec] the equivalent FWHM of the PSF.
- diameterfloat
[m] diamter of primary mirror. Default is 39.3m.
- modestr
[‘oversample’,’linear_interp’] see Kernel2D (scipy.convolution.core)
-
class
simcado.psf.
AiryPSF
(fwhm, obscuration=0.0, size=255, pix_res=0.004, **kwargs)[source]¶ Bases:
simcado.psf.PSF
Generate a PSF for an Airy function with an equivalent FWHM
- Parameters
- fwhmfloat
[arcsec] the equivalent FWHM of the Airy disk core.
- sizeint
[pixel] the side length of the array
- pix_resfloat
[arcsec] the pixel scale used in the array, default is 0.004
- obscurationfloat
[0..1] radius of inner obscuration as fraction of aperture radius
- modestr
[‘oversample’,’linear_interp’] see Kernel2D (scipy.convolution.core)
-
class
simcado.psf.
AiryPSFCube
(lam_bin_centers, fwhm=None, **kwargs)[source]¶ Bases:
simcado.psf.PSFCube
Generate a list of AiryPSFs for wavelengths defined in lam_bin_centers
- Parameters
- lam_bin_centersarray, list
[um] a list with the centres of each wavelength slice
- fwhmarray, list
[arcsec] the equivalent FWHM of the PSF.
- diameterfloat
[m] diamter of primary mirror. Default is 39.3m.
- modestr
[‘oversample’,’linear_interp’] see Kernel2D (scipy.convolution.core)
-
class
simcado.psf.
GaussianPSF
(fwhm, **kwargs)[source]¶ Bases:
simcado.psf.PSF
Generate a PSF for an Gaussian function
- Parameters
- fwhmfloat
[arcsec] the equivalent FWHM of the Airy disk core.
- sizeint
[pixel] the side length of the array
- pix_resfloat
[arcsec] the pixel scale used in the array, default is 0.004
- modestr
[‘oversample’,’linear_interp’] see Kernel2D (scipy.convolution.core)
-
class
simcado.psf.
GaussianPSFCube
(lam_bin_centers, fwhm=None, **kwargs)[source]¶ Bases:
simcado.psf.PSFCube
Generate a list of GaussianPSFs for wavelengths defined in lam_bin_centers
- Parameters
- lam_bin_centersarray, list
[um] a list with the centres of each wavelength slice
- fwhmarray, list
[arcsec] the equivalent FWHM of the PSF.
- diameterfloat
[m] diamter of primary mirror. Default is 39.3m.
- modestr
[‘oversample’,’linear_interp’] see Kernel2D (scipy.convolution.core)
-
class
simcado.psf.
DeltaPSF
(**kwargs)[source]¶ Bases:
simcado.psf.PSF
Generate a PSF with a delta function at position (x,y)
- Parameters
- positiontuple
[pixel] where (x,y) on the array is where the delta function goes default is (x,y) = (0,0) and is the centre of the array
- sizeint
[pixel] the side length of the array
- pix_resfloat
[arcsec] the pixel scale used in the array, default is 0.004
-
class
simcado.psf.
DeltaPSFCube
(lam_bin_centers, positions=(0, 0), **kwargs)[source]¶ Bases:
simcado.psf.PSFCube
Generate a list of DeltaPSFs for wavelengths defined in lam_bin_centers
- Parameters
- lam_bin_centersarray
[um] the centre of each wavelength slice
- positionstuple, list
- (x,y) either a tuple, or a list of tuples denoting the
position of the delta function
- pix_resfloat
[arcsec], pixel scale of the PSF. Default is 0.004 arcsec
- sizeint
[pixel] side length of the PSF array
-
class
simcado.psf.
CombinedPSF
(psf_list, **kwargs)[source]¶ Bases:
simcado.psf.PSF
Generate a PSF from a collection of several PSFs.
- Parameters
- psf_listlist
A list of PSF objects
- sizeint
[pixel] the side length in pixels of the array
-
class
simcado.psf.
CombinedPSFCube
(psf_list, **kwargs)[source]¶ Bases:
simcado.psf.PSFCube
Generate a list of CombinedPSFCubes from the list of psfs in psf_list
- Parameters
- lam_bin_centersarray, list
[um] a list with the centres of each wavelength slice
- fwhmarray, list
[arcsec] the equivalent FWHM of the PSF.
- diameterfloat
[m] diamter of primary mirror. Default is 39.3m.
-
class
simcado.psf.
UserPSF
(filename, **kwargs)[source]¶ Bases:
simcado.psf.PSF
Import a PSF from a FITS file.
- Parameters
- filenamestr
path to the FITS file to be read in
- fits_extint, optional
the FITS extension number (default 0) for the data
- pix_resfloat, optional
[arcsec] the pixel scale used in the array, default is 0.004
-
class
simcado.psf.
UserPSFCube
(filename, lam_bin_centers)[source]¶ Bases:
simcado.psf.PSFCube
Read in a psf previously saved as a FITS file
Keywords needed for a psf to be read in: NSLICES, WAVECENT, NAXIS1, CDELT1, PSF_TYPE, DESCRIPT
- Parameters
- filenamestr
the path to the FITS file holding the cube
See also
Notes
A separate function will exist to convert foreign PSF FITS files into
simcado.psf
readable FITS files
-
simcado.psf.
poppy_eelt_psf
(plan='A', wavelength=2.2, mode='wide', size=1024, segments=None, filename=None, use_pupil_mask=True, **kwargs)[source]¶ Generate a PSF for the E-ELT for plan A or B with POPPY
- Parameters
- planstr, optional
[“A”, “B”], Default = “A” * Plan A is for a fully populated mirror (798 segments) * Plan B has the inner 5 rings missing (588 segments) and a further 5 random segments missing (583 segments)
- wavelengthfloat, list, array, optional
[um] Default = 2.2um. The wavelength(s) for which a PSF should be made
- modestr, optional
[“wide”, “zoom”] Default = “wide”. Sets the pixel size for each of the MICADO imaging modes - {“wide” : 4mas, “zoom” : 1.5mas}
- sizeint, optional
[pixels] Default = 1024
- segmentslist, optional
Default = None. A list of which segments to use for generating the E-ELT mirror. See
get_eelt_segments()
- filenamestr, optional
Default = None. If filename is not None, the resulting FITS object will be saved to disk
- use_pupil_maskstr, optional
Default = True.
- Returns
- ``astropy.HDUList``an astropy FITS object with the PSF in the data
- extensions
- Other Parameters
- Values to pass to the POPPY functions
- flattoflatfloat
[m] Default : 1.256
- gapfloat
[m] Default : 0.004
- secondary_radiusfloat
[m] Default : 5
- n_supportsint
Default : 6
- support_widthfloat
[m] Default : 0.2
- support_angle_offsetfloat
[deg] Default : 0
- n_missingint
Default : None. Number of segments missing
- pupil_inner_radiusfloat
[m] Default : None # Plan A: 5.6m, Plan B: 11.5m
- pupil_outer_radiusfloat
[m] Default : 19
See also
-
simcado.psf.
poppy_ao_psf
(strehl, mode='wide', plan='A', size=1024, filename=None, **kwargs)[source]¶ Create a diffraction limited E-ELT PSF with a Seeing halo
Uses POPPY to create a diffraction limited PSF for the E-ELT for a certain configuration of mirror segments. The diffraction limited core is added to seeing halo, modelled by either a moffat or gassian profile.
- Parameters
- strehlfloat
[0 .. 1] The components are summed and weighted according to the strehl ratio psf = (1-strehl)*seeing_psf + (strehl)*diff_limited_psf
- modestr, optional
[“wide”, “zoom”] Default = “wide”. Sets the pixel size for each of the MICADO imaging modes - {“wide” : 4mas, “zoom” : 1.5mas}
- planstr, optional
[“A”, “B”], Default = “A” * Plan A is for a fully populated mirror (798 segments) * Plan B has the inner 5 rings missing (588 segments) and a further 5 random segments missing (583 segments)
- sizeint, optional
[pixels] Default = 1024
- filenamestr, optional
Default = None. If filename is not None, the resulting FITS object will be saved to disk
- Returns
- hdu_listastropy.HDUList
an astropy FITS object containing the PSFs for the given wavelengths
- Other Parameters
- fwhmfloat
[arcsec] Default : 0.8
- psf_typestr
Default : “moffat”
- wavelengthfloat
[um] Default : 2.2
- segmentslist
Default : None. A list of which hexagonal poppy segments to use See
get_eelt_segments()
- flattoflatfloat
[m] Default : 1.256
- gapfloat
[m] Default : 0.004
- secondary_radiusfloat
[m] Default : 5
- n_supportsint
Default : 6
- support_widthfloat
[m] Default : 0.2
- support_angle_offsetfloat
[deg] Default : 0
- n_missingint
Default : None. Number of segments missing
- pupil_inner_radiusfloat
[m] Default : None # Plan A: 5.6m, Plan B: 11.5m
- pupil_outer_radiusfloat
[m] Default : 19
See also
-
simcado.psf.
seeing_psf
(fwhm=0.8, psf_type='moffat', size=1024, pix_res=0.004, filename=None)[source]¶ Return a seeing limited PSF
- Parameters
- fwhmfloat, optional
[arcsec] Default = 0.8
- psf_typestr, optional
[“moffat, “gaussian”] Default = “moffat”
- sizeint, optional
[pixel] Default = 1024
- pix_resfloat, optional
[arcsec] Default = 0.004
- filenamestr, optional
Default = None. If filename is not None, the resulting FITS object will be saved to disk
- Returns
- seeing_psf2D-array
Notes
# Moffat description # https://www.gnu.org/software/gnuastro/manual/html_node/PSF.html # # Approximate parameters - Bendinelli 1988 # beta = 4.765 - Trujillo et al. 2001
-
simcado.psf.
get_eelt_segments
(plan='A', missing=None, return_missing_segs=False, inner_diam=10.6, outer_diam=39.0)[source]¶ Generate a list of segments for POPPY for the E-ELT
- Parameters
- planstr, optional
[“A”, “B”], Default = “A” * Plan A is for a fully populated mirror (798 segments) * Plan B has the inner 5 rings missing (588 segments) and a further 5 random segments missing (583 segments)
- missingint, list, optional
Default = None. If an integer is passed, this many random segments are removed. If
missing
is a list, entries refer to specific segment IDs- return_missing_segsbool, optional
Defualt is False. Returns the missing segment numbers
- inner_diamfloat, optional
[m] Default = 10.6. Diameter which produces ESO’s mirror configuration
- outer_diamfloat, optional
[m] Default = 39.0. Diameter which produces ESO’s mirror configuration
- Returns
- segslist
A list of segment IDs for the mirror segments.
- missinglist, conditional
Only returned if
return_missing_segs == True
. A list of segment IDS for the segments which are missing.
-
simcado.psf.
make_foreign_PSF_cube
(fnames, out_name=None, window=None, pix_res_orig=None, pix_res_final=None, wavelengths=None)[source]¶ Combine several PSF FITS images into a single PSF FITS file
- Parameters
- fnameslist
List of path names to the FITS files
- out_namestr, optional
If out_name is not
None
, the resulting FITS file is saved under the nameout_name
- windowint, list, tuple, optional
If window is not
None
, a windowed section of the PSFs are extracted window = (left, right, top, bottom) window = square radius
Examples
>>> from glob import glob >>> import simcado as sim >>> fnames = glob("D:\Share_VW\Data_for_SimCADO\PSFs\yann_2016_11_10\*.fits") >>> sim.psf.make_foreign_PSF_cube(fnames, "PSF_SCAO.fits", window=512, pix_res_orig=[0.0028, 0.0037, 0.00492], pix_res_final=[0.004, 0.004, 0.004], wavelengths=[1.25,1.65,2.2])