Wide-field observations of PSF variations with SCAO¶
In this example we will show the effect of the off-axis AO correction on the shape of the PSF when observing with the SCAO mode. To make a semi-realistic observation, we will observe an open cluster created by the ScopeSim_Templates package. This cluster extends over the full MICADO field of view. As such it should show the full extend of the expected PSF variations over the field.
It should be noted that adding PSF field variations is a computationally expensive process. ScopeSim does it’s best to reduce the level of complexity by discretising the PSF variation into different zones over the field of view. Occasionally the borders between these zones is visible
[ ]:
import numpy as np
import matplotlib.pyplot as plt
from astropy import units as u
import scopesim as sim
import scopesim_templates as sim_tp
The PSF field-variation is complex and computationally expensive. Hence this functionality is not inluded in the MICADO package. For use cases requireing field variations we must use the pipeline-oriented MICADO package. As we will be using the SCAO mode, we can ignore the MORFEO module.
sim.download_packages(["Armazones", "ELT", "MORFEO", "MICADO"])
Note
In ScopeSim v0.5 both download_packages (new format) and download_package (old format) exist.
If we would like to keep the instrument packages in a separate directory, we can set the following config value:
sim.rc.__config__["!SIM.file.local_packages_path"] = "path/to/packages"
Set up an open cluster Source object¶
The first step is to create a Source object. Here we take advantage of the cluster function from the ScopeSim_Templates.stellar.clusters submodule. The cluster function draws masses from an standard Kroupa IMF until the mass limit has been reached. It then generates randomly draw positions from a 2D gaussian distribution with a HWHM equal to the given core_radius in parsec. The distance parameter sets the distance in parsec to the centre of the cluster. This allows
the final on-sky star positions in units of arcsec from the centre of the cluster to be calculated. Spectra for all the stars are taken from the Pickles (1998) catalogue and are imported from the Pyckles python packages.
Here we choose a cluster with a mass of 10000 solar masses (~250000 stars) with a core radius of 0.5 parsec, located at a distance of 8 kpc from the Earth. This essentially gives us a cluster that covers the whole MICADO filed of view in wide-field mode (4mas / pixel).
[ ]:
cluster = sim_tp.cluster(mass=10000, core_radius=0.5, distance=8000)
[ ]:
cluster.plot();
Set up the MICADO optical system for SCAO and include a field-varying PSF¶
The next step is the standard proceedure - set the instrument to MICADO and the modes to SCAO and IMG_4mas, then create an Simulation object.
[ ]:
micado = sim.Simulation("MICADO", ["SCAO", "IMG_4mas"])
By default the PSF model in the pipeline-oriented MICADO package is set to use a field-constant PSF cube. We need to change this to use a Field-Varying PSF model.
Note: to view all the optical effects contained within the optical model, use the .effects attribute in the OpticalTrain class.
Here we see the PSF model in the 4th last line:
[ ]:
micado.optical_train
We can access the PSF model using the standard python dictionary notion using the name of the element. In this case it is called relay_psf as this refers to the internal MICADO relay optics which are connected to the SCAO system.
We do not want to use the default relay_psf object, so we need to tell ScopeSim not to include it
[ ]:
micado.optical_train["relay_psf"].include = False
Next we want to add a FieldVaryingPSF object from the ScopeSim library of optical effect. Before we initialise the object though, we will need the correct PSF cube.
A small library of precomputed PSFs can be found on the ScopeSim server: https://scopesim.univie.ac.at/InstPkgSvr/psfs/
Once we have downloaded the PSF cube of our choice (in this case the cube corresponding to ESO median atmospheric conditions) we can pass the file path to the FieldVaryingPSF object.
For the purpose of testing this notebook, we’re using a much smaller test PSF file. If you’d like to see the real deal, simply uncomment the one below and comment out the test file instead.
[ ]:
from pooch import retrieve
# fname = retrieve(
# "https://scopesim.univie.ac.at/InstPkgSvr/psfs/AnisoCADO_SCAO_FVPSF_4mas_EsoMedian_20190328.fits",
# known_hash="a9bd309e5ac025f2aa5f8ded85323465578906e47025ce86501985c9b258474c",
# fname="AnisoCADO_SCAO_FVPSF_4mas_EsoMedian_20190328.fits",
# progressbar=True,
# )
fname = retrieve(
"https://scopesim.univie.ac.at/InstPkgSvr/psfs/test_fvpsf.fits",
known_hash="c13aba82e4faf42568b5996f3d32135ddb69b537a832c753da189b698a7ad48c",
fname="test_fvpsf.fits",
progressbar=True,
)
[ ]:
fv_psf = sim.effects.psfs.FieldVaryingPSF(filename=fname, name="SCAO_FV_PSF")
We now need to add the new PSF to the MICADO relay optics element inside the MICADO optical train.
[ ]:
micado.optical_train.optics_manager["default_ro"].add_effect(fv_psf)
Viewing an on-axis PSF is boring. Therefore we will move the 1024x1024 detector window off centre 10 arcseconds in both x and y directions. We will also increase the exposure time to 60 seconds.
Now we are ready to observe and readout the MICADO detector window
[ ]:
micado.settings["!OBS.dit"] = 600 # [s]
micado.settings["!DET.x"] = 10 # [arcsec]
micado.settings["!DET.y"] = 10
hdus = micado(cluster)
The elongation of the PSF along the radial axis is quite visible.
First look at limited FOV¶
[ ]:
_, ax = plt.subplots(figsize=(12, 12))
img = hdus[1].data
ax.imshow(img, origin="lower", norm="log", vmin=0.9*np.median(img), vmax=1.1*np.median(img));
Larger view¶
Alternatively we could re-centre the detector window, but expand the window size to 4096x4096 pixels (16x16 arcsecond) which is the equivalent of the central MICADO detector.
[ ]:
micado.settings["!DET.x"] = 0
micado.settings["!DET.y"] = 0
micado.settings["!DET.width"] = 4096
micado.settings["!DET.height"] = 4096
hdus = micado(cluster)
It should be noted, the larger the detector size, the longer the simulation takes to run. Hence the option to simply shift the detector centre while keeping the detector size small.
This option does however let us see the change in orientation of the PSF elongation around the on-axis position
[ ]:
_, ax = plt.subplots(figsize=(12, 12))
img = hdus[1].data
ax.imshow(img, origin="lower", norm="log", vmin=0.9*np.median(img), vmax=3*np.median(img));
Full detector array¶
It is ONLY recommended to run the full MICADO detector configuration is you have >8 GB of RAM
While the MICADO package only has a customisable detector window for simulated observations, the MICADO package contains a full description of the 9 detectors in the MICADO detector array.
This requires simulating a ~13000x13000 pixel field, which understandable takes a lot of computer resources and takes on the order of 10 minutes to run.
Ideally the user would write a script using the commands in this notebook and run that script in the background.
That said, swapping to the full detector array is a simple matter of setting the .include parameter to True and False for the two Detector options provided in the MICADO package (see micado.effects table above).
[ ]:
# micado.optical_train["full_detector_array"].include = True
# micado.optical_train["detector_window"].include = False
In this case, it is worth saving the final HDUList to disk as a multi-extension FITS file so the data are safe in case something happens to the Python session
[ ]:
# micado(cluster, filename="micado_full_detector.fits")