Welcome to SimCADocs!¶
The (slowly expanding) documentation base for SimCADO, the instrument data simulation package for MICADO at the ELT.
Important
SimCADO is currently under active development. The current version of SimCADO (dubbed v0.7) is however capable to answer many questions about the future performance of MICADO imaging mode and your favorite science case. For the spectroscopic mode, please consult SpecCADO.
In this latest version SimCADO is able to correctly simulate DIT and NDITs. Accordingly, the
keyword OBS_EXPTIME
has been replaced by OBS_DIT
, with total observing time given by
OBS_DIT*OBS_NDIT
.
Please update your scripts and configuration files after downloading the latest version.
SimCADO in a nutshell¶
SimCADO is a python package designed to simulate the effects of the Atmosphere, E-ELT, and MICADO instrument on incoming light. The current version (v0.7) can simulate the MICADO imaging mode (4mas and 1.5mas per pixel in the wavelength range 0.7µm to 2.5µm).

A simple simulation in 30 seconds with SimCADO.¶
Reference Material¶
The inner workings of SimCADO are described in detail in Leschinski et al. (2016)
The current status of MICADO is described in Davies et al. (2018)
Downloading and Installing¶
For more information, see the Download section
SimCADO has only been tested in Python 3.x.
It is hightly recommended to use Python 3, however the basics of generating images will still work in Python 2.7. We cannot guarantee this though.
The quick way:
$ pip install SimCADO
We also recomend to install SimCADO in an anaconda/miniconda/etc python distributions as it is much easier to keep control over your python environment.
The first time in python you should update the SimCADO data directory with
get_extras()
:
>>> import simcado
>>> simcado.get_extras()
>>>
>>> # !! Only works in Python 3 - See Downloads section
>>> simcado.install_noise_cube()
If you running Python 3, it would be helpful to expand the internal detector
noise cube with install_noise_cube()
.
Keeping SimCADO updated¶
As MICADO developes, the data files that SimCADO uses will also be
updated. Therefore before you do any major work with SimCADO we HIGHLY
recommend calling get_extras()
:
>>> simcado.get_extras()
iPython/Jupyter notebooks¶
A (continualy expanding) series of iPython Notebooks detailing how to use SimCADO are available here in the Notebooks section.
Hint
Don’t feel like sifting through documentation? Common commands and examples are on the SimCADO cheat-sheet:
Running a simulation in 3 lines¶
The easiest way to run a simulation is to create, or load, a Source
object and then call the run()
command. If you specify a filename,
the resulting image will be output to a FITS file under that name. If
you do not specify a filename, the output will be returned to the
console/notebook as an HDUList
object.
To begin, we will import the simcado module (assuming it is already installed).:
>>> import simcado
At the very least, we need to create a Source
object which contains
both spatial and spectral information on our object of interest. Here we
use the built-in command simcado.source.cluster()
to create a
Source
object for a 10000-Msun stellar cluster. (Creating
Sources for more information).:
>>> src = simcado.source.cluster()
We now pass the Source
object through SimCADO. This is as easy as
calling run()
. If we specify a filename
, SimCADO will write the
output to disk in the form of a FITS file. If no filename
is given, then
SimCADO returns an astropy fits
object to the console or
notebook.:
>>> simcado.run(src, filename="my_first_sim.fits")
Changing simulation parameters¶
The run()
also takes any configuration keywords as
parameters for running the simulation. For example, the default exposure time
for the simulation is 60 seconds, however this can be increased of decreased by
using the keyword OBS_EXPTIME (and/or combining it with OBS_NDIT). A stacked
6x 10 minute observation sequence would look like:
>>> simcado.run(src, filename="my_first_sim.fits", OBS_DIT=600, OBS_NDIT=6)
That’s it. Of course SimCADO can also go in the other direction, providing many more levels of complexity, but for that the reader is directed to the examples pages and/or the API documentation.
SimCADO building blocks¶
For a brief explanation of how SimCADO works and which classes are relevant, please see either the GettingStarted or SimCADO in depth section.
Using SimCADO¶
Getting Started with SimCADO¶
SimCADO can be super easy to use, or super complicated. The level of
complexity is completely up to the user. A basic simulation involves
only 1 thing: a Source
object to describe the observable object.
Once the user has created this object, the function
simcado.simulation.run()
is all that needs to be called. Controlling
the parameters of the simulation can be done either by passing keyword-value
pairs, or my using a UserCommands
dictionary.
Contents
-
-
Loading a pre-existing
Source
object
-
The
UserCommands
object
-
Note
Even though this documentation is not yet complete (it is a very big job),
lots more information is included in the docstrings of every SimCADO
function and class. These can be easily viewed in the interactive python
interface (iPython, or Jupyter Notebook) with either the question mark
operator or by using SHIFT+TAB
with the cursor over the function name.
Doing this in iPython will call up the docstring:
>>> simcado.Source?
Source¶
For full details, please see the API and examples of Source Objects
The Source
class is probably the most important class for testing
science cases. Therefore spending time on creating accurate Source
representations of the object of interest is key to getting good results
with SimCADO. Source
objects can be created from scratch, with
functions provided by SimCADO, or by loading in a pre-existing
Source
-FITS file.
Note
SimCADO is CaSe SensITIVe! SimCADO has the class simcado.Source()
and the module simcado.source
. These should not be confused.
simcado.source
is the module which contains the class Source
and all the helper functions for creating various types of Source
objects. The source code for the class Source
is actually in
simcado.source.Source
, however to make things easy, Source
is available directly as simcado.Source()
. Be careful and remember
simcado.Source != simcado.source
.
For a description of the Source
object, and the source
module,
see How SimCADO works.
Loading a pre-existing Source
object¶
To load in a pre-existing Source
(i.e. one that you saved earlier),
specify the keyword filename=
when initialising the Source
object.:
>>> import simcado as sim
>>> my_src = sim.Source(filename="star_grid.fits")
Source
-FITS files have a very specific file format, so it’s best to
only import files that were generated directly from other Source
objects. It’s a chicken/egg scenario, which is why the next section
deals with creating Source
objects in memory. For a description of
the file format for saved Source
objects, see “File Format of saved
Source objects”.
Making a Source
with SimCADO’s in-built functions¶
The simcado.source
module provides an ever-increasing series of
functions to create Source
objects in memory. These include, (from
simcado.source
)
Two useful functions here are stars()
and source_from_image()
stars()
takes a list of magnitudes (and optionally spectral types) and positions for a common broad-band filter (default is “K”) and generates aSource
object with those stars in the field.>>> x, y = [-2.5, 0.7, 16.3], [3.3, -0.2, 25.1] >>> mags, spec_types = [25,21,28], ["K0V", "A0III", "G2V"] >>> filt = "H" >>> >>> my_src = sim.source.stars(mags=mags, x=x, y=y, filter_name=filt, spec_types=spec_types)
source_from_image()
creates aSource
based on a 2D numpy array provided by the user. The 2D array can come from anywhere, e.g. the data from a FITS image, a BITMAP image, from memory, etc. Alongside the image, the user must provide a spectrum (plus a vector with the bin centres) and the pixel field of view (e.g. 0.004 arcsec for MICADO). SimCADO then extracts all pixels from the image which have values aboveflux_threshold
(defualt is 0) and saves these pixel coordinates. The spectrum provided is then connected to these pixel, and scaled by the pixel value.>>> # ... Create an image - a circle with a radius of 20 pixels on a >>> # ... grid 200 pixel wide >>> XX = np.array([np.arange(-100,101)]*201) >>> im = np.sqrt(XX**2 + XX.transpose()**2) >>> im[im>20] = 0; im[im>0] = 1 >>> >>> # ... Pull in the spectrum for a G2V star with K=20 >>> lam, spec = simcado.source.SED("G2V", filter_name="K", magnitude=20) >>> >>> # ... Make the source object >>> my_src = sim.source.source_from_image(images=im, lam=lam, spectra=spec, plate_scale=0.004)
SimCADO also provides a series of spectra for stars and galaxies, however these are meant as a guide to those who are just starting out. For serious work, the user is encouraged to provide their own spectra. More information on the in-built spectra can be found in the Source Objects example section.
Simulating with SimCADO¶
The quick, the dirty and the ugly¶
As seen on the index page, a simulation can be run using 3 lines of code:
>>> import simcado
>>> src = simcado.Source(filename="my_source.fits")
>>> simcado.run(src, filename="my_image.fits")
The run()
function is quite powerful. Many users may find that they
don’t need anything else to run the simulations they need. The full
function call looks like this:
simcado.run(src, filename=None,
mode="wide", detector_layout="small",
cmds=None, opt_train=None, fpa=None,
return_internals=False,
**kwargs)
Lets pull this function call apart in order of importance to the simulation:
src
: Obviously the more important aspect is theSource
object. Without aSource
these is nothing to observefilename
: Where to save the output FITS file. IfNone
is provided (or the parameter is ignored), the output is returned to the user. This comes in handy if you are working in a Jupyter Notebook and wand to play with the output data immediately. Or if you are scripting with SimCADO and don’t want to be slowed down by writing all images to diskTwo important parameters here are
mode
anddetector_layout
: These two define the MICADO observing modes.
Currently mode
can be either "wide"
(4mas/pixel) or "zoom"
(1.5mas/pixel).
The detector_layout
can also be changed to speed up simulations of
single objects. For example if the galaxy you’re interested in is at
z=5, you don’t need to read out all 9 MICADO chips for each observation.
In fact, a 1024x1024 window at the centre of the middle chip will
probably be enough. Therefore SimCADO offers the following “layouts” for
the detector - “small”, “wide”, “full”. The default is “small”.
small
- 1x 1k-detector centred in the FoVcentre
- 1x 4k-detector centred in the FoVfull
- 9x 4k-detector as described by the keywordFPA_CHIP_LAYOUT
cmds, opt_train, fpa
are all parameters that allow you to provide custom built parts of the machinary. Say you have a set of commands saved from a previous simulation run which differ from the default values, then you can use these by passing aUserCommands
object via thecmd
parameter. The same goes for passing an customOpticalTrain
object toopt_train
and a customDetector
object tofpa
. For more information see the relevant examples sections -UserCommands
examples,OpticalTrain
examples,Detector
examples.return_internals
allows you to do the opposite of the previous three parameters. If you would like to save theUserCommands
,Detector
and/orOpticalTrain
from your simulation run, the by settingreturn_internals=True
, SimCADO will return these along with the simulated imagery. Note that this only works iffilename=None
.**kwargs
: Althoughkwargs
is the last parameter, it actually allows you to control every aspect of the simulation.kwargs
takes any keyword-value pair that exist in the SimCADO configuration file, and so you can control single aspects of the simulation by passing these keyword-value pairs torun()
. For example, you can increase the exposure time of the image by passingsimcado.run(src, … , OBS_DIT=600, INST_FILTER_TC=“J”, …)
A list of all the available keyword-value pairs can be found in the Keywords section .
Alternatively you can dump a copy of the default parameters by calling
simcado.commands.dump_defaults()
.
Changing Filters¶
The keyword INST_FILTER_TC
allows you to supply either the name of a
filter (i.e. “Ks”, “PaBeta”) or a path to an ASCII file containing a
filter curve. INST_FILTER_TC
can be passed to run()
just like
any other SimCADO configuration keyword:
>>> simcado.run(src, INST_FILTER_TC="J")
>>> simcado.run(src, INST_FILTER_TC="path/to/my_filter_curve.txt")
SimCADO has some generic filters built in. These include all the regular NIR broadband filters (I, z, Y, J, H, K, Ks). There are also some narrow band filter. As the MICADO filter set is expected to change, we will not list the SimCADO filter set here. Instead the user can find out which filters are available by calling the function (as of Nov 2016):
>>> print(sim.optics.get_filter_set())
['B', 'BrGamma', 'CH4_169', 'CH4_227', 'FeII_166', 'H', 'H2O_204', 'H2_212',
'Hcont_158', 'I', 'J', 'K', 'Ks', 'NH3_153', 'PaBeta', 'R', 'U', 'V', 'Y',
'z']
If you’d like to use your own filter curve, note that the ASCII file should contain two columns - the first holds the wavelength values and the second hold the transmission values between 0 and 1.
Setting the observation sequence¶
The important keywords here are: OBS_DIT
, OBS_NDIT
OBS_DIT
[in seconds] sets the length of a single exposure. The default setting is for a 60s exposureOBS_NDIT
sets how many exposures are taken. The default is 1.
Depending on what your intended use for SimCADO is, the keyword
OBS_SAVE_ALL_FRAMES=["no", "yes"]
could also be useful. The default
is to not save all the individual exposures, but stack them and
return a single HDU object (or save to a single FITS file). If
OBS_SAVE_ALL_FRAMES="yes"
, then a filename
must also be given so
that each and every DIT can be saved to disk.
Reading out the detector¶
Warning: running a full simulation could take ~10 minutes, depending on how much RAM you have available:
>>> simcado.run(detector_layout="small"")
The detector_layout
keyword is key:
detector_layout : str, optional
["small", "centre", "full"] Default is "small".
Where each of the strings means:
"small"
- 1x 1k-detector centred in the FoV"centre"
- 1x 4k-detector centred in the FoV"full"
- 9x 4k-detector as per MICADO imaging mode (either 4mas or 1.5mas)"default"
- depends on “mode” keyword. Full MICADO 9 chip detector array for either 4mas or 1.5mas modes
PSF utilities in SimCADO¶
In SimCADO we have pre-packaged some simulated PSFs which match the expectations of the different AO modes of MICADO. As new simulations of the AO capabilities become available we will include these new PSFs in SimCADO. The available PSFs are
PSF_SCAO.fits
PSF_MCAO.fits
which are the AO modes available. Additionally we provide a LTAO PSF (PSF_LTAO.fits) and a EELT diffraction limited PSF (PSF_POPPY.fits) calculated with poppy
For the moment, the PSF is assumed constant accross the field. The new (refractored) version will be capable to deal with field varying PSFs in a realistic manner.
SimCADO also provides utility functions that are able to produce analytic PSFs to be used in the simulation in adition to the pre-calculated PSFs. Please check the simcado.psf
module. The
most important functions are the following:
simcado.psf.poppy_eelt_psf()
creates a diffraction limited PSF based with mirror segments provided bysimcado.psf.get_eelt_segments()
simcado.psf.seeing_psf()
creates a seeing limited PSF with an user provided FWHM. Moffat and Gaussian profiles are availablesimcado.psf.poppy_ao_psf()
creates an analytical AO PSF with a user provided Strehl ratio
All these functions can save the computed PSFs in fits format by specifying a filename. That file can be later used in the simulations as a parameter in simcado.simulation.run()
using the SCOPE_PSF_FILE=filename
keyword.
In the notebook section you can find a few detailed examples how to create and work with these PSFs.
Saving and reusing commands¶
The UserCommands
object¶
Passing more than a few keyword-value pairs to the simcado.run()
becomes tedious. SimCADO therefore provides a dictionary of commands so
that you can keep track of everthing that is happening in a simulation.
>>> my_cmds = simcado.UserCommands()
>>> simcado.run(my_src, cmds=my_cmds)
When initialised the UserCommands
object contains all the default
values for MICADO, as given in Keywords. The
UserCommands
object is used just like a normal python dictionary:
>>> my_cmds["OBS_DIT"] = 180
>>> my_cmds["OBS_DIT"]
180.0
It can be saved to disk and re-read later on:
>>> my_cmds.writeto("path/to/new_cmds.txt")
>>> new_cmds = simcado.UserCommands("path/to/new_cmds.txt")
>>> new_cmds["OBS_DIT"]
180.0
If you prefer not to use interactive python and just want to dump a commands file to edit in your favourite text editor:
>>> simcado.commands.dump_defaults("path/to/cmds_file.txt")
More information on the UserCommands
object is given in the
Examples Section
Behind the scenes of SimCADO¶
SimCADO uses 4 main classes during a simulation:
Source
holds spatial and spectral information about the astronomical source of photons, e.g. galaxy, star cluster, etc.OpticalTrain
contains information on the various elements along the optical path, e.g. mirrors reflectivity curves, PSFs, instrumental distortion, etc.Detector
represents the focal plane detector array and contains information on the electronic characteristics of the detector chips and their physical positions.UserCommands
is a dictionary of all the important keywords needed by SimCADO to run the simultationm, e.g.OBS_DIT
(exposure time) orINST_FILTER_TC
(filter curve)
For more information on how SimCADO works please see the SimCADO in Depth section.
Things to watch out for¶
This space. It will soon expand!
Installation¶
The latest stable version of SimCADO can be installed from PyPI with
pip install simcado
If you have SimCADO already installed and you want to install the latest version, please type
pip install --upgrade simcado
Please do not forget to obtain the latest data file package as explained in the section below
The latest development version of SimCADO can be found on GitHub:
https://github.com/astronomyk/SimCADO
Python 3 vs Python 2¶
Note
SimCADO has been programmed in Python 3.
While most of the basic functionality for SimCADO will work with Python
2.7, we haven’t tested it properly. For example, the function
simcado.install_noise_cube()
only works in Python 3. This isn’t
critical - it just means that if you want to have read noise variations
in your images, you need to use Python 3. However it won’t crash SimCADO
for single images.
Note
A side note: Astropy will stop supporting Python 2.7 in 2019 and the official End-of-Life for Python 2.7 is 2020, i.e. no more maintainance. We are running under the assumption that SimCADO will (hopefully) still be around after 2020, hence why we have concentrated our efforts on developing in Python 3.
Note
SimCADO will need to download several hundreds of MBs of instrument data into the install directory. Hence why we use the –user flag when installing via pip. If you want to keep SimCADO in your normal packages directory, then you will need to give python root access while updating SimCADO’s data files.
Dependencies¶
Required
Package |
Version |
---|---|
numpy |
>1.10.4 |
scipy |
>0.17 |
astropy |
>1.1.2 |
wget |
>3.0 |
requests |
>2.0 |
synphot |
>0.1 |
pyyaml |
Optional
Package |
Version |
---|---|
matplotlib |
>1.5.0 |
poppy |
>0.4 |
All dependencies should be automatically installed when typing the pip command above. In case of any error message you can try to install them manually:
$ pip install numpy scipy astropy wget matplotlib poppy pyyaml synphot requests
We really recomend to install SimCADO in a python distribution like anaconda or miniconda as they allow to have full control over your python environment without interfering with your system instalation.
Getting up-to-date data for SimCADO¶
SimCADO is being developed along side MICADO. To keep the files that SimCADO uses as fresh as possible, you should run the following command, at the very least the first time you start SimCADO:
>>> import simcado
>>> simcado.get_extras()
This downloads the latest versions of all the files SimCADO uses behind the scenes, e.g. PSF files, transmission curves etc. If you haven’t used SimCADO for several months, chances are there are new data available. It is therefore advantageous to run this command periodically.
Adding variation to the Detector noise¶
Note
Currently only available for Python 3.
By default SimCADO only supplies a single H4RG noise frame. Hence if you plan on generating a series of images, all images will have the same detector noise pattern. Don’t worry, photon shot noise is still completely random, however if you stack 1000s of simulated images with the same detector noise frame, this pattern will show through. This problem can be avoided by running the following function the first time you run simcado:
We recommend running this command in a separate Python session as it can take up to 10 minutes depending on your computer.:
>>> simcado.install_noise_cube(n=25)
SimCADO contains the code to generate unique detector noise images
(Rauscher 2015),
however creating a 4k detector noise frame takes about 20 seconds. In
order to avoid wasting time by generating noise for each frame every
time SimCADO is run, .install_noise_cube(n)
generates n
noise
frames and saves them in the SimCADO data directory. In future
simulation one of these detector noise frames are picked at random
whenever a <Detector>.read_out()
is called.
Obviously a trade-off has to be made when running
.install_noise_cube(n)
. The more noise frames available, the less
systematic noise is visible in the read noise of stacked images.
However, the more frames are generated, the longer it takes. A good
solution is to open a separate window and have SimCADO generate frames
in the background.
SimCADO FAQs¶
Here are some answers to known issues with SimCADO.
Work around for failing install_noise_cube()
with Python 2.7¶
The problem lies with Python 2.7. The noise cube code is 3rd party code that only works on Python 3 and I haven’t had a chance to dig into that code yet to find the problem
Generate a noise cube in Python 3. First install python3:
$ pip install simcado
$ python3
Then create the noise cube:
>>> import simcado
>>> sim.detector.make_noise_cube(num_layers=25, filename='FPA_noise.fits', multicore=True)
Note
Your simcado/data folder can be found by printing the __pkg_dir__
variable:
>>> simcado.utils.__pkg_dir__
Copy the new noise cube into the Python 2.7 simcado/data folder.¶
By default SimCADO looks for the noise cube in its data directory -
<Your Python 2.7 Directory>/lib/python/site-packages/simcado/data/
:
$ cp ./FPA_noise.fits <Your Python 2.7 Directory>/lib/python/site-packages/simcado/data/FPA_noise.fits
No access to the simcado/data
folder?¶
If you can’t save files into the simcado/data directory (or you can’t be bothered finding it), you can use the FPA_NOISE_PATH keyword when running a simulation to point simcado to the new noise cube file:
>>> simcado.run(my_source, ..... , FPA_NOISE_PATH="<path/to/new>/FPA_noise.fits")
or if you’re using a UserCommands object to control the simulation:
>>> cmds = simcado.UserCommands()
>>> cmds["FPA_NOISE_PATH"] = "<path/to/new>/FPA_noise.fits"
Surface brightness scaling in SimCADO¶
Question
Is it true that if the array that I pass to simcado has a value of 1,
then simcado will simulate exactly a SB = m
mag/sq.arcsec pixel?
What happens if the passed numpy array has a different pixel size. Are
the counts in each pixel then scaled according to their different
surface area?
To answer the question on scaling we need look at the docstring for
source_from_image
:
source_from_image(images, lam, spectra, plate_scale, oversample=1,
units="ph/s/m2", flux_threshold=0,
center_pixel_offset=(0, 0),
conserve_flux=True)
The 3 parameters of interest here are plate_scale
, oversample
and conserve_flux
.
plate_scale
is the plate scale of the image. So if we take a HAWK-I image, we have a plate_scale of 0.106 arcsec. SimCADO needs this so that it can work out how many photons are coming in per pixel in the image you provide.oversample
. If oversample stays at 1 (default), then SimCADO will generate a “point source” for each pixel - i.e. every 0.106 arcsec there will be one source emitting with the intensity of that pixel. This is sub-optimal if we want to use an extended object, as SimCADO will turn the image into a grid of point sources with a spacing equal toplate_scale
. Therefore we need to over sample the image so that SimCADO makes at least 1 light source per pixel. Hence to get down to 4mas for the SimCADO wide field mode, we would need to oversample the HAWK-I image by a factor of 0.106/0.004 = 26.5. I.e.oversample=26.5
.conserve_flux
. If this isTrue
(default), then when SimCADO oversamples the image, it multiplies the new image by a scaling factor= sum(orig_image) / sum(new_image). Thus a pixel with the value 1 in the original image will now have a value
=(1 / 26.5)^2. If
conserve_flux=False`, this scaling factor is not applied. Note: The scaling doesn’t affect the spectrum associated with the image at all.
Sub-pixel accuracy with SimCADO¶
There are two ways to go about getting SimCADO to simulate at the sub-pixel level (Nov 2016, only one is working so far):
Turn on SimCADO’s oversample mode with the keyword SIM_OVERSAMPLING:
simcado.run(my\_src, ... , SIM\_OVERSAMPLING=4)
If SimCADO is using the 0.004 arcsec mode, then it will calculate everything based on a 0.001 arcsec grid. It resamples back up to 0.004 when passing the image to the detector module. Depending on the level of accuracy you need (and the computer power you have available), you can oversample as much as you’d like. Be careful with this - it uses lots of RAM.
SimCADO also has a sub-pixel mode built into the method
<Source>.apply_optical_train(... ,sub_pixel=False)
, - (very slow if there are >100 stars, it doesn’t use FFTs) - however I’ve only done a quick tests to make sure the code works. I can’t guarantee it’s accurate though. I’ll put that on my list of things to do this week (22 Nov 2016)
I have many PSFs in a FITS Cube. How do I use just one layer¶
To extract a slice from the cube, we use astropy. Here i
is the layer we
want to extract:
from astropy.io import fits
f = fits.open("path/to/my/psf_cube.fits")
i = 24 # which ever layer from the cube that you want
psf = f[0].data[i, :,:]
hdr = f[0].header
hdu = fits.PrimaryHDU(data=psf, header=hdr)
hdu.header["CDELT1"] = 0.002 # whatever the plate scale of the PSF file is in arcsec
hdu.header["WAVELENG"] = 2.16 # whatever the wavelength of that layer is in micron
hdu.writeto("my_psf_layer.fits")
To use this PSF with SimCADO, we use the keyword SCOPE_PSF_FILE
and pass the
filename of the saved PSF slice:
simcado.run( ... , SCOPE_PSF_FILE="my_psf_layer.fits", ...)
Which filters are included in my version of SimCADO?¶
SimCADO provides a function to list all the filter curves contained in the simcado/data install directory:
>>> simcado.optics.get_filter_set()
The files containing the spectral response of the curves are located in the simcado/data install directory, which can be found by calling:
>>> simcado.__data_dir__
These files following the naming convention: TC_filter_<name>.dat. They contain two columns Wavelength [um] and Transmission [0..1]
Plotting Filter Transmission curves¶
To access a transmission curve, use the get_filter_curve() function:
>>> T_curve = simcado.optics.get_filter_curve(<FilterName>)
The returned TransmissionCurve
object contains two arrays:
.lam (wavelength) and .val (transmission). To access the numpy arrays:
>>> wavelength = Tcurve.lam
>>> transmission = Tcurve.val
Each TransmissionCurve
object can be plotted by calling the internal
method .plot(). The method uses matplotlib``s current axis (``plt.gca()
),
so if you are not using an iPython
notebook, you will still need to call the
plt.show()
function afterwards. E.g.:
>>> import matplotlib.pyplot as plt
>>> T_curve.plot()
>>> plt.show()
SimCADO also has a somewhat inflexible function to plot all filter transmission
curves which are in the simcado/data
directory. Basically it loops over all
names returned by get_filter_set()
and plots them. It
also applies a nice colour scheme.
>>> plot_filter_set()
I can also accept a custom list of filter names, if you don’t want to plot absolutely everything in the `simcado/data`directory (fyi, in early versions of simcado this includes many useless files - sorry)
>>> plot_filter_set(filters=("J","PaBeta","Ks"),savefig="filters.png")
What SimCADO can do?¶
Many things. Chances are it can do what you’d like, however you may need some patience, and or help from the held desk - see the contact section for who to contact if you have any questions.
What SimCADO can’t yet do?¶
Coronography, Spectroscopy
For the current version of the MICADO spectroscopy simulator see SpecCADO
https://github.com/oczoske/SpecCADO/
We are still working on incorporating SpecCADO into SimCADO, however as the SimCADO <=0.5 was primarily focused on imaging, we need to refactor the core code somewhat in order to achieve this.
Updates to SimCADO¶
Data updates¶
The data files used by SimCADO are continually being updated to reflect the newest information coming from the MICADO work packages.
To update your version of SimCADO, use the simcado.get_extras()
command.
2019-09-18¶
SimCADO can now correctly perform DITs and NDITS
Accordingly, OBS_EXPTIME keyword in now OBS_DIT
Documents updated
2019-07-30¶
Several examples added to the notebooks
Bug fixes to source.elliptical
2019-03-26¶
SimCADO can now simulate a field varying PSF. See updated docs
2019-03-14¶
pip friendly setup.py
2019-02-19¶
Documentation Updated
Reference spectrum now based on synphot
2018-11-23¶
Moved the documentation to ReadTheDocs (finally)
Added filter plotting functionality
2017-01-31¶
New stable version available: SimCADO 0.4
2017-01-18¶
Added E-ELT mirror transmission curve TC_mirror_EELT.dat
2017-01-05¶
VLT mirror coating TC_aluminium.dat
HAWK-I filter curves: TC_filter_J.dat TC_filter_H.dat TC_filter_Ks.dat TC_filter_Y.dat
Updated detector layout FPA_chip_layout.dat
2016-11-12¶
TC_surface.dat
Updated with more optimistic Strehl values for JHK central wavelengthsTC_mirror_gold.dat
Added a reflectivity curve for an unprotected gold coatingdefault.config
ChangedINST_MIRROR_TC
to referenceTC_mirror_gold.dat
Source Code updates¶
The current stable version is SimCADO v0.4. The current development version is SimCADO v0.5dev
Development version¶
2017-01-05 * SimCADO now preloads the transmission curves. Generating an OpticalTrain now only takes ~2 seconds (compared to 20 previously)
2016-12-06 * Added functionality to generate “ideal” AO PSFs using POPPY for the diffraction limited core and added a Seeing halo
2016-11-12 * Bug fix in simcado.psf - psf.lam_bin_centers was taking opt_train.lam_bin_centers instead of using the “WAVE0” keywords in the FITS header * Bug fix in source.psf - apply_optical_train() was asking for PSFs outisde of the opt.train.psf range. related to the point above
SimCADO Gallery¶
Images from recent simulations with SimCADO

This is the lightcurve that follows the shape of the Crab Pulsar, but scaled so that each pulse is easily visible in a 5ms windowed H-band exposure with MICADO. The star is H=15mag. The light curve has been extracted from the intermediate non-destructive reads from an up-the-ramp simulated exposure.¶

Omega Cen as imaged with HST/WFC3, HST/SimCADO and MICADO/SimCADO by Maximilian Fabricius (MPE). The synthetic images of the same region of Omega Cen are based on the HST catalog by Anderson & van der Marel 2010 and augmented by all the faint stars that did not end up in the HST catalogue.¶

A galaxy field based on B, R and Halpha images of the Antennae galaxy generated with SimCADO as a proof of concept. The image includes all ways of generating input for SimCADO: importing intensity maps from real (HST) images, generating galaxies based on a sersic profile in memory, and basic stars as point sources with spectra from the Pickles (1998) catalogue. The code to generate this image can be found in the Notebooks section.¶
Examples and Tutorials¶
Here are a list of scripts andnotebooks detailing how to use SimCADO. If you would like to add a notebook to this collection, please email it to Kieran Leschinski.
Cheat Sheet¶
Hint
If you don’t like sifting through documentation, try looking through the cheat sheet at some common commands and examples. If you find what you need, then you’ll know exactly what to look for in the simcado package
Tutorials¶
-
An introductory notebook to SimCADO. Topics include: first steps with SimCADO, creating
Source
objects and customising simulations.
-
A example of how stars looks like with a field changing PSF as expected in the SCAO mode. Here, a bunch of stars are observed at 0, 7, 14 and 21 arcsec off-axis. Also available as a stand-alone script (stars_anisocado.py)
-
This example simulates a star cluster filling the whole MICADO array with a MAORY-like PSF in the J-band. For that a new J-band PSF was generated with a Strehl of 7%. This PSF can be downloaded from the data directory (as well as others in H and Ks). Also available as stand-alone script (star_cluster_fullarray.py)
-
We put here a local galaxy and see how it would look like with MICADO at z=2. We use a SCAO PSF. Stand-alone script: extended_source.py
-
We simulate here a disk galaxy surrounded by (proto-) globular clusters and using a number of observing possibilites with SimCADO. Stand-alone script: galaxy_globclusters.py
Science Cases¶
-
Examples for how to use
limiting_mags()
from the sub-modulesimcado.simulation
.
-
A quick look at whether it would be possible to observe Betelgeuse (J = -3 mag) with SimCADO without destroying the detectors. Short answer: yes.
-
If General Tarkin were to attack Earth and has hidding in orbit around the moon in his spaceship, could the E-ELT see it, and would we we know what it was?
-
A quick look to some of the cababilities of SimCADO to work with extended sources
PSF experiments¶
-
A notebook showing the different PSFs available in SimCADO and doing a bit of analysis of their characteristics.
-
As the primary mirror of the E-ELT was innitially thought to be built in 2 phases, this notebook uses SimCADO to have a look at what that means for the resulting E-ELT PSF.
Note
the PSFs generated here are only approximations based on a diffraction limited core combined with a Seeing Halo. These are meant only as a guide.
Workshop notebooks¶
-
Some basics about running SimCADO
-
The basics for making and combining point source objects
Notes on simulation with sub-pixel resolution
A couple of examples on how to get SimCADO to do sub-pixel scale simulations
-
Creating a galaxy field with a large galaxy (the Antennae) and adding a series of background galaxies Here are the FITS file used in the simulation
Using PSFs with SimCADO¶
Point spread function (PSF) kernels are used by SimCADO to mimic the spread in the beam due to the specific optical configuration of the ELT+MAORY+MICADO optical system.
A PSF kernel is in essence a two dimensional array which describes how the light from a point source is spread out over the detector plane. While SimCADO can accept 2D numpy arrays as input directly from the user, more often than not the user will probably want to use a set of pre-calculated PSFs.
Default PSFs for MICADO¶
Warning
The default PSFs are approaching their expiry date
The PSF files described below are useful for quick simulations which don’t require a super accurate PSF. Furthermore they were generated in 2015 (MCAO, NOVA), and 2016 (SCAO, LESIA), and only cover a single set of atmospheric parameters.
For newer PSFs, see the section on SCAO PSFs (from AnisoCADO) or contact the SimCADO team about MCAO PSFs (from MAROY)
By default the MICADO instrument package includes PSF kernels (arrays) in FITS
format for the MCAO and SCAO observing modes. These default kernel FITS files
are found in the MICADO data folder under the names: PSF_MCAO.fits
,
PSF_SCAO.fits
.
SimCADO can be told to use either one of these PSFs by passing the
SCOPE_PSF_FILE
keyword to either the simcado.run
function, or to a
UserCommands
dictionary:
hdu = simcado.run(... , SCOPE_PSF_FILE="PSF_MCAO.fits")
or:
cmds = simcado.UserCommands()
cmds["SCOPE_PSF_FILE"] = "PSF_MCAO.fits"
Note
The default PSFs are field-constant.
This means that they do not vary over the field of view. For the MCAO option this is the optimal case - a constant AO correction everywhere in the field - however for the SCAO case, this is only valid for the central ~2x2 arcsec.
If we are interested in simulating the full MICADO field of view, it
will be unrealistic to use the PSF_SCAO.fits
file. More on this below.
Both the MCAO and SCAO files were generated for reasonably good conditions and should be understood as offering an optimistic view of how MICADO will perform.
Field varying SCAO PSF¶
As stated above the default PSFs contained in the MICADO package are for the case where the PSF doesn’t vary over the field. For the SCAO observation modes this is an unrealistic assumption unless one is only interested in the central ~2x2 arcsec or so. SimCADO (v0.6 and above) accepts a so-called FV-PSF file (field-varying PSF file) in order to simulate the degredation of the PSF over the field of view.
FV-PSF files are quite large (several 100 MB to GB) as they contain PSF kernels for many different positions over the field (and generally for several different wavelengths).
We have generated SCAO FV-PSF files for three observing conditions which roughly correspond to “good”, “median”, and “bad” atmospheric conditions.
Warning
These files are ~1 GB in size.
Profile |
Seeing |
Zenith Distance |
Wind Speed |
Turbulence Profile |
File Link |
---|---|---|---|---|---|
Good |
0.4 |
0 |
8.8 |
ESO Quartile 1 |
|
Median |
0.67 |
30 |
10 |
ESO Median |
|
Bad |
1.0 |
60 |
13 |
ESO Quartile 4 |
This FV-PSFs were generated by AnisoCADO. AnisoCADO is python package derived from Eric Gendron’s code for generating SCAO PSFs for the ELT+MICADO for any wavelength and off-axis guide star position. To generate custom FV-PSF kernels, see AnisoCADO’s documentation for how to make SimCADO-readable FV-PSF FITS files.
Images and profiles of the central PSF from each of these files can be found here:
To use these PSF files we simply pass the filename to SimCADO (as with the other PSF), and SimCADO (! >=v0.6) does the rest:
fvpsf_path = "path/to/AnisoCADO_SCAO_FVPSF_4mas_EsoQ1_20190328.fits"
simcado.run(... , SCOPE_PSF_FILE=fvpsf_path)
Warning
SimCADO will (probably) run slower when using a FV-PSF file.
This is because SimCADO convolves the FOV of each detector with each PSF kernel that is present inside the borders of that FOV. This means, e.g., if there are 9 different PSFs to be used in the region covered by the central detector chip, then this region will be convolved 9 times with different PSFs (and masked accordingly 9 times). Hence simulating the central chip will take 9 times as long as when using a field-constant PSF.
Custom instrument packages for SimCADO¶
Warning
This format will only work with SimCADO v0.4 and later versions
This way of specifying files and parameters has been depreciated for newer versions of SimCADO. A new API description will be available by June 2019.
SimCADO is a (reasonably) flexible framework for simulating telescope and instrument optical trains. It was primarily developed for use with the ELT telescope and the MICADO / MAORY instrument, however many other instruments can be simulated with SimCADO if the proper configuration files are provided.
This page aims to give a short overview of which files SimCADO needs in order to simulate a custom optical train.
Note
We’re happy to help implement other instruments with SimCADO
If you would like to use SimCADO to model another telescope / instrument system, and would like some help with how to do this, please contact the SimCADO team. We’re more that happy to help out.
Config Files¶
The default SimCADO configuration file can be found in the data folder of the
installation directory: simcado/data/default.config
. This folder can be
found by calling:
import simcado
simcado.__data_dir__
To create a custom instrument package, we will need to create our own
.config
file. We can dump the default file by calling:
simcado.commands.dump_defaults("my_new_instrument.config", selection="all")
Next we will need to alter the values to fit our instrument. For some keywords we will need to provide file paths to a (correctly formatted) file describing the given effect. The most important files are described below.
File paths¶
Note
Use simcado.__search_path__
to store files in multiple places
SimCADO contains a function (find_file
) which looks for file names in
the directories contained in the list simcado.__search_path__
.
By default this list contains the working directory, and the two main
folders in the installation directory:
>>> simcado.__search_path__
['./', '<pkg_dir>/simcado', '<pkg_dir>/simcado/data']
By adding directory names to the __search_path__
list at the beginning
of a python script/session, we can tell SimCADO to look in other directories
for the relevant files.
Required Files¶
PSF files¶
Keywords : SCOPE_PSF_FILE
This file should contain a (series of) PSF kernel(s) as FITS image extensions.
Each extension must contain the keyword WAVE0
which tells SimCADO the
wavelength for which the PSF kernel is relevant (in m
or in um
).
For MICADO, the default PSF FITS file contains extensions for each of the major broadband filters: I [0.87um], z [1.05um], J [1.25um], H [1.65um], Ks [2.15um]. For filters with central wavelengths which fall between these PSF kernels, SimCADO takes the extension with the closest wavelength.
In case we need to include field-variations in the PSF cube, the new PSF format is also accepted by SimCADO. It’s description can be found here :
Mirror transmission curves¶
Keywords : SCOPE_M1_TC, INST_MIRROR_AO_TC, INST_MIRROR_TC, INST_FILTER_TC
TC (transmission curve) files are ASCII table files with two columns. The transmission profile can be as simple or as detailed as we want. Here is an example of a very simple filter transmission file:
# TC_filter_Ks.dat
Wavelength Transmission
0.1 0
1.89 0
1.9 1
2.4 1
2.41 0
3.0 0
SimCADO uses astropy.table
to read the file, so if astropy
can read it,
SimCADO can too.
Mirror lists¶
Keywords : SCOPE_MIRROR_LIST, INST_MIRROR_AO_LIST
These list files contain information on the geometry of the mirrors included in either the telescope section, or AO section of the optical system. Below we have the first 3 lines of the ELT’s mirror list file:
# EC_mirrors_scope.tbl
Mirror Outer Inner Angle Temp Coating
M1 37.3 11.1 0. 0. TC_mirror_mgf2agal.dat
where Outer, Inner [m] refer to the diameter of the mirror, Angle [deg] is the angle at which the plane of the mirror differs from that of the light beam, Temp [deg C] is the mirror temperature for determining the thermal background, and Coating is the filename of the Transmission Curve (TC) file describing the spectral response of the mirror coating material (see above: Mirror transmission curves).
The internal mirror configuration of the actual instrument is a special case. It is assumed that the cryostat temperature is sufficiently low that the blackbody emission from the internal mirrors is negligible. Hence only the mirror transmission is important and can therefore be described with the following two parameters:
INST_NUM_MIRRORS
INST_MIRROR_TC
For instruments without AO module, we can force SimCADO to ignore the AO components by setting the following keyword:
INST_USE_AO_MIRROR_BG = False
Wavefront errors¶
Keywords : INST_WFE
The current version of SimCADO (v0.6) includes only the reduction in strehl ratio induced by wave front error. It does this by calculating the peak of a normalised 2D Gaussian kernel (i.e. between 1 and 0) for each wavelength in the final system transmission curve, and applying an effective transmission loss based on the Gaussian peak value. This is very much a ‘first order approximation’ to including wavefront errors in the optical train. It should be noted that this has been improved upon in SimCADO v1.0.
The file passed to FPA_QE
should follow this table format (taken from the
MICADO+ELT INST_wfe.tbl
file):
# wfe_rms no_surfaces material optics
# [nm] [#] [str] [str]
20 11 gold mirror
10 4 glass entrance_window
10 2 glass filter
10 8 glass ADC
Optional files¶
Atmospheric spectra¶
Keywords : ATMO_TC, ATMO_EC
By default SimCADO uses precalculated output from the ESO skycalc tool for the
atmospheric emission and transmission curves. The default tables
(EC_sky_25.tbl
and TC_sky_25.tbl
) are for PWV = 2.5mm and include
columns for various airmasses over a wavelength range or [0.3, 3.0]um.
Additional transmission curves¶
Keywords : INST_DICHROIC_TC, INST_ENTR_WINDOW_TC, INST_PUPIL_TC
In case the transmission properties of any dichroics, entrance windows or pupil optics need to be included. The file format is the same as above for Mirror transmission curves
Detector noise images¶
Keywords : FPA_NOISE_PATH
By default SimCADO uses a FITS file containing an image of the detector noise
pattern for the HAWAII-4RG detectors. We can include pre-calculated noise maps
by passing a FITS file to FPA_NOISE_PATH
. No special header keywords are
needed.
Detector linearity curve¶
Keywords : FPA_LINEARITY_CURVE
Detector linearity can be included by passing an ASCII table with two columns which relate the real incoming flux to the measured photon flux as measured by the read-out electronics. The table should look like this:
# real_flux measured_flux
0 0
1 1
1000 998
3500 3200
... ...
200000 180000
1000000 180000
Note
Linearity is applied to any imaging observation, regardless of length
Yes, this shouldn’t be, but we haven’t got around to fixing that yet. Hence
to model long exposure observations (i.e. >1 min), it’s best just to set
FPA_LINEARITY_CURVE = False
Simulation Building Blocks¶
SimCADO objects¶
Source¶
The Source
class is probably the most important class for testing
science cases. Therefore spending time on creating accurate Source
representations of the object of interest is key to getting good results
with SimCADO.
Basically a Source
object represents photon sources using lists of
positions (.x, .y
), a list of unique spectra (.spectra
) and a
list of references which match each photon source to a spectrum in the
list of spectra (.ref
). All sources (extended and point source) can
be decomposed into these lists. The advantage of using this approach is
that objects with highly similar spectra can both reference the same
position in .spectra
, thereby reducing the number of spectra that
need to be manipulated during a simulation.
File Format of saved Source
objects¶
Source
objects are stored as FITS files with 2 extensions. The first
(ext=0) contains an image with dimensions (n, 4) where n is the number
of positions for which there exists a spectrum - i.e. non-empty space.
The 4 rows of the image correspond to the .x, .y, .ref, .weight
arrays. The second extension (ext=1) contains another image with
dimensions (m+1, len(lam)), where m is the number of unique spectra and
len(lam) is the length of the .lam
array containing the centres of
all wavelength bins. The first row in the second extension is the
.lam
array.
Todo
describe how Source
is linked to OpticalTrain
, Detector
and
UserCommands
OpticalTrain¶
Todo
describe how OpticalTrain
is linked to Source
, Detector
and
UserCommands
Detector¶
Todo
describe how Detector
is linked to Source
, OpticalTrain
and
UserCommands
UserCommands¶
Todo
descript how UserCommands
is linked to Source
, OpticalTrain
and
Detector
SimCADO methods¶
Method behind applying an OpticalTrain
to a Source
object¶
(Taken from Leschinski et al. 2016)
In an ideal world, SimCADO would apply all spectral and spatial changes
at the resolution of the input data. However, the memory requirements to
do this are well outside the limits of a personal computer. The solution
to this problem is to split the effects based on dimensionality. For
certain elements in the optical train, the spectral and spatial effects
can be decoupled (e.g. purely transmissive elements like the filters
versus purely spatial effects like telescope vibration). For other
elements, most notably the PSF and ADC, all three dimensions must be
considered simultaneously. When applying an OpticalTrain
, SimCADO
follows the procedure described graphically in Figure 1. The example
used in Figure 1 is for a simplified stellar cluster with only two
different stellar types - A0V and K5V type stars.

Figure 1 - The steps involved in applying an OpticalTrain
object to
a Source
object. The example used here is for a simplified stellar
cluster with only two different stellar types - A0V and K5V type stars.¶
A. The original
Source
object includes an array of spectra for each unique photon source (in the case of Figure 1, there are only two unique spectra) and four vectors:x
,y
,ref
,weight
.x
andy
hold the spatial information for each photon source,ref
connects each source to a spectrum in the array of spectra andweight
allows the spectrum to be scaled.Spectral-effects. The first step in
apply_optical_train()
is to combine all optical elements which only act in the wavelength domain (e.g. filters, mirrors, etc.) into a single effect, then apply that effect to the array of spectra in theSource
object.B. The spectra in the
Source
object are now representative of the photo-electron count at the detector, assuming a perfect optical train and at the internal spatial resolution of the simulation, i.e. not at the pixel scale of the detector. The position vectors are converted into a two-dimensional “image” of theSource
.Spectrospatial-effects. The second step includes creating “slices” through the data. The spectra are binned according to several criteria (ADC shift, PSF FWHM difference, etc) with a spectral resolution anywhere from R=1 to R>100, and the number of photons per source in each wavelength bin is calculated. The sources in each “slice” are scaled according to the number of photons in each bin. The relevant spatial effects (atmospheric dispersion, convolution with PSF kernel, etc.) are then applied to each slice in turn.
C. At this stage, the
Source
object contains many spectral slices. Each is essentially the equivalent of a (very) narrow-band filter image.D. All spectral effects have been taken into account, and so the binning in the spectral domain is no longer needed. The third step in
apply_optical_train()
is to add all the slices together to create a single monochrome image.Spatial-effects. Fourth in the series of operations is to apply the purely spatial effects (e.g. telescope jitter, field rotation, etc) to the monochrome image.
E. The resulting image represents how the incoming photons from the source would be distributed on the focal plane after travelling through the entire optical train. At this point the background photons are also added to the image. Because SimCADO doesn’t take into account the changing sky background, the sky emission is approximated as a constant background photon count determined from an atmospheric emission curve (either provided by the user or generated by
SkyCalc
[Noll et al. 2012, Jones et al. 2013]). The mirror blackbody emission is also approximated as spatially constant. For all filters, with the exception of K, the amount of additional photons due to the mirror is close to negligible.Detector-effects. The image is resampled down from the internally oversampled grid down to the pixel scale of the detector chips - in the case of MICADO either 4 mas or 1.5 mas, depending on mode. The final step is to add noise in all its forms to the image. Various aspects of the detector noise (correlated and uncorrelated white and pink noise read-out (see Rauscher 2015), dead pixels, etc.), as well as photon shot noise for both the atmospheric and object photons are taken into account. Further effects (e.g. detector persistence, cross-talk, etc) are also added to the image at this point.
F. The final image represents the spatial distribution of all photo-electrons (from the source object + atmosphere + primary mirror) plus the electronic noise generated by reading out the detector chips. The images from all the chips considered in a simulation are packed into a FITS extension and the FITS file is either written out to disk, or returned to the user if generated during an interactive Python session.
Method behind reading out a Detector
object¶
Todo
add in a description of how Detectoctor.read_out()
works
Controlling simulations¶
This page describes two ways of simulating: the quick and the repeatable. More about how SimCADO deals with commands can be found in the section on the UserCommands object.
Simulating the quick way¶
The function run()
runs a simulation with all the default
parameters. That said, SimCADO has a safety switch to stop you wasting
10 minutes on a Source
that will be invisible, or so bright that it
saturates the detector completely.
To get the full detector array, we set detector_array="full"
:
>>> im = sim.run(src, detector_array="full")
Note
Note, by patient! Simulating 9x 4k detectors is heavy lifting. Remember to use the internals if you don’t plan on changing the optical train.
Notes on simcado.run()¶
There are two parameters still to be covered in detail. Please see the
documention (or read the docstring by using sim.run?
). They are:
filename=
: instead of returning the FITS object to the console, save it to disk under this namemode=
: default is “wide” for 4mas imaging. Also accepts “zoom” for 1.5mas imaging mode.
Viewing a full detector read out¶
Each chip read-out is stored in a FITS extension. There are 3 options to view the images:
Save the FITS object to disk and use DS9, etc:
>>> im.writeto("full_detector.fits")
Use the
filename=
insimcado.run()
to save directly to disk, and bypass the console. This is useful for scripting with SimCADO.>>> simcado.run(src, filename="full_detector.fits")
Use the SimCADO function
.plot_detector()
from the.detector
module:>>> im, (cmd, opt, fpa) = simcado.run(src, filename="full_detector.fits", return_internals=True) >>> simcado.detector.plot_detector(fpa)
The 3rd option is probably the least favourable as there are no options available, but it allows you to see what the readout will look like in a mosaic mode.
Using KEYWORD=VALUE pairs from the configuration file¶
SimCADO is controlled with a series of keyword-value pairs contained in a configuration file. The defaults are the best approximation to MICADO so changing them is not recommended if you want to simulate MICADO images. There are however some which are useful to play around with.
Note
SimCADO is CAsE sEnsiTIve**. All KEYWORDS are writen with capital letters.
Similar to SExtractor, SimCADO provides a way to dump both commonly used
and less-common keywords to a file with command
sim.commands.dump_defaults()
:
>>> sim.commands.dump_defaults()
#########################################################
## FREQUENTLY USED KEYWORDS ##
#########################################################
#-------------------------------------------------------#
# To dump a file with all keywords, use: #
# >>> sim.commands.dump_defaults(filename, type="all") #
#-------------------------------------------------------#
OBS_DIT 60 # [sec] simulated exposure time
OBS_NDIT 1 # [#] number of exposures taken
INST_FILTER_TC Ks # [<filename>, string(filter name)] List acceptable filters with >>> simcado.optics.get_filter_set()
ATMO_USE_ATMO_BG yes # [yes/no]
SCOPE_USE_MIRROR_BG yes # [yes/no]
INST_USE_AO_MIRROR_BG yes # [yes/no]
FPA_USE_NOISE yes # [yes/no]
FPA_CHIP_LAYOUT small # [small/centre/full] description of the chip layout on the detector array.
SCOPE_PSF_FILE scao # ["scao" (default), <filename>, "ltao", "mcao", "poppy"] import a PSF from a file. Default is <pkg_dir>/data/PSF_SCAO.fits
SIM_DETECTOR_PIX_SCALE 0.004 # [arcsec] plate scale of the detector
SIM_VERBOSE yes # [yes/no] print information on the simulation run
OBS_ZENITH_DIST 60 # [deg] from zenith
INST_ADC_PERFORMANCE 100 # [%] how well the ADC does its job
To list all keyword-value pairs, use:
>>> sim.commands.dump_defaults(filename, type="all")
Any of the KEYWORD=VALUE pairs can be passed as extras to :func:.run`. For example if we wanted to observe in J-band for 60 minutes, we would pass:
src = sim.source.source_1E4_Msun_cluster()
im = sim.run(src, OBS_EXPTIME=3600, INST_FILTER_TC="J")
The jupyter notebook my_first_sim.ipynb has more exmples of this.
The UserCommands object¶
Behind the scenes of the simcado.run()
command, three objects are
created:
a
UserCommands
object - for holding all the information on how a simulation should be runan
OpticalTrain
object - which contains the models to describe each effect that needs to be simulateda
Detector
object - commonly referred to as anfpa
or Focal Plane Array. It describes the layout of the detectros and holds the observed images.
The UserCommands
object is arguably the most important of these
three, because the other two need the keyword-value pairs contained
within the UserCommands
object to correctly describe the optical
train and detector for the simulation.
A UserCommands
object is created by reading in the defaults conifg
file (defaults.config
) and then updating any of the keywords that
the user (or function) provides. For example, we can see all the default
keyword-value pairs by calling:
>>> cmd = sim.UserCommands()
The UserCommands
object contains 7 ordered dictionaries, one for
each topic and one general dictionary. Each can be referenced
individually, however all are updated when a value changes.
cmd.cmds - contains all keyword-value pairs
cmd.atmo - keyword-value pairs for the atmosphere
cmd.scope - keyword-value pairs for the telescope
cmd.inst - keyword-value pairs for the instrument (plus AO system)
cmd.fpa - keyword-value pairs for the dector array
cmd.obs - keyword-value pairs for the observation
cmd.sim - keyword-value pairs for the simulation
A UserCommands
object can be used as a dictionary itself, although
technically all that happens is that it references the general
dictionary cmd.cmds
. For example
>>> cmd["OBS_DIT"] = 60
is exactly the same as either of the following two expressions
>>> cmd.cmds["OBS_DIT"] = 60
>>> cmd.obs["OBS_DIT"] = 60
Therefore for the sake of ease, we recommoned treating the UserCommands
object as a dictionary and just using the default syntax: cmd["..."] = xxx
Saving and loading a UserCommands
object¶
Saving¶
In case you have made changes to the values in a UserCommands
object
that you would like to keep for next time, a UserCommands
object can
be saved to disk with the following command:
>>> cmd = sim.UserCommands()
>>> cmd.writeto(filename="my_cmds.txt")
SimCADO writes out the dictionary in ASCII format.
Loading¶
Creating a UserCommands
object based on a text file is as simple as
passing the file path:
>>> cmd = sim.UserCommands("my_cmds.txt")
Special attributes¶
A UserCommands
object not only contains a dictionary of
keyword-value pairs, but also a select number of parameters pertaining
to the optical train for quick access. These include values for:
the exposure time for simulations:
cmd.exptime
the primary mirror:
cmd.area
,cmd.diameter
the wavelength vector for purely spectral data (i.e. transmission curves):
cmd.lam
the wavelength centres and edges for each spectral bin:
cmd.lam_bin_centres
,cmd.lam_bin_edges
the mirror configuration:
cmd.mirrors_telescope
,cmd.mirrors_ao
the detector plate scale and internal sampling resolutions:
cmd.fpa_res
,cmd.pix_res
Mirror and Detector configuration files¶
A quick note on the other files that SimCADO uses when creating an optical train and the appropriate keywords
The detector array¶
The detector array is described by a text file containing information on the plate scale and the positions of the detector chips:
>>> sim.commands.dump_chip_layout(path=None)
# id x_cen y_cen x_len y_len
# arcsec arcsec pixel pixel
4 0 0 4096 4096
0 -17.084 -17.084 4096 4096
1 0 -17.084 4096 4096
2 17.084 -17.084 4096 4096
3 -21.484 0 4096 4096
5 17.084 0 4096 4096
6 -17.084 17.084 4096 4096
7 0 17.084 4096 4096
8 17.084 17.084 4096 4096
This small file can be saved to disk by passing a filename to the
path=
parameters
>>> sim.commands.dump_chip_layout(path="my_fpa.txt")
Any detector array can be provided to SimCADO, as long as the text file follows this format. For example the HAWK-I detector array (4x HAWAII-2RG) would look like this:
# id x_cen y_cen x_len y_len
# arcsec arcsec pixel pixel
0 -116 -116 2048 2048
1 116 -116 2048 2048
2 -116 116 2048 2048
3 116 116 2048 2048
To pass a detector array description to SimCADO, use the
FPA_CHIP_LAYOUT
keyword:
>>> cmd = sim.UserCommands()
>>> cmd["FPA_CHIP_LAYOUT"] = "hawki_chip_layout.txt"
or pass is directly to the :func:.run` command:
>>> sim.run(... , FPA_CHIP_LAYOUT="hawki_chip_layout.txt", ...)
The mirror configurations¶
The mirror configuration can be dumped either to the screen or to disk by using:
>>> dump_mirror_config(path=None, what="scope")
#Mirror Outer Inner Temp
M1 37.3 11.1 0.
M2 4.2 0.545 0.
M3 3.8 0.14 0.
M4 2.4 0. 0.
M5 2.4 0. 0.
If path=None
the contents of the default file are printed to the
screen. The parameter what
is for the section of the optical train
that should be shown - either scope
for the telescope, or ao
of
the AO system. For most existing telescope, this parameter is
irrelevant. For the MICADO/MAORY setup however another six optical
surfaces are introduced into the system.
It is possible to specifiy different mirror configurations using a text file with the same format as above. For example the VLT unit telescope mirror config files would look like this:
#Mirror Outer Inner Temp
M1 8.2 1.0 0.
M2 1.116 0.05 0.
M3 1.0 0. 0.
To use this mirro config file in SimCADO use the keywords
SCOPE_MIRROR_LIST
and INST_MIRROR_AO_LIST
>>> cmd = sim.UserCommands()
>>> cmd["SCOPE_MIRROR_LIST"] = "vlt_mirrors.txt"
>>> cmd["INST_MIRROR_AO_LIST"] = "none"
Examples with the Source object¶
The Source
class is probably the most important class for testing
science cases. Therefore spending time on creating accurate Source
representations of the object of interest is key to getting good results
with SimCADO.
Basically a Source
object represents photon sources using lists of
positions (.x, .y
), a list of unique spectra (.spectra
) and a
list of references which match each photon source to a spectrum in the
list of spectra (.ref
). All sources (extended and point source) can
be decomposed into these lists. The advantage of using this approach is
that objects with highly similar spectra can both reference the same
position in .spectra
, thereby reducing the number of spectra that
need to be manipulated during a simulation.
Contents
Examples with the Source object
-
Creating a
Source
object from scratchCombining two (or more)
Source
objects
-
My first Source object¶
To begin with it is probably easiest to let SimCADO generate a
Source
object. The convenience function simcado.source.star()
will generate a Source
object containing a single star. In this
case, we’ll choose an G2V star with a K-band magnitude of 20, placed 5
arcsec above the centre of the focal plane:
>>> star_1 = simcado.source.star(mag=20, filter_name="K", spec_type="G2V", x=5, y=0))
star_1
the coordinates of the star are held in the arrays .x
and
.y
, and the G2V spectrum in `.spectra´:
>>> star_1.x[0], star_1.y[0]
(5, 0)
The spectrum for star_1
is held in .spectra
and the central
wavelength of each of the spectral bins is in .lam
.
>>> star_1.lam, star_1.spectra[0]
<insert output here>
Note
.lam is a (1,n) array where as .spectra is a (m,n) array where n is the number of bins in the spectra and m is the number of unique spectra in the Source object. If the Source only contains a single unique spectrum, then .spectra will be a (1,n) array too.
Combining Source
objects¶
Because a Source
object is just a collection of arrays, it is easy
to add many together with the +
operator:
>>> star_2 = simcado.source.star(mag=22, filter_name="K", spec_type="A0V", x=2, y=-2)
>>> two_stars = star_1 + star_2
>>> two_stars.x, two_stars.y
((5, 2), (0, -2))
Note
this is a very trivial example (for which SimCADO has a more elegant function: simcado.source.stars()), but it serves to illustrate the main idea. The overloaded + operator is very useful for combining objects, e.g. forground stars and background galaxies, in order to get a better representation of the sky.
Note
if you are planning on creating sources for large numbers of stars (e.g. >>10 stars), using the plural function stars()
will save you a lot of time.
Point sources¶
For generating a field of stars, SimCADO offers a series of convenience functions. Please see the docstring or API documentation for more information on how best to use them.
simcado.source.star()
simcado.source.stars()
simcado.source.star_grid()
simcado.source.cluster()
SimCADO’s in-built example spectra¶
Add a section on this
Stellar templates from Pickles (1998)
simcado.source.SED()
simcado.source.empty_sky()
Galaxy templates from STSCI
Each of these functions returns two arrays: lam
and spec
Using an image as a template for a Source
object¶
If we have an extended source that we wish to simulate, e.g. a galaxy, a
nebula, etc. we can use the function
simcado.source.source_from_image()
. The image must be a 2D
numpy.ndarray
, but it can come from anywhere, e.g. a FITS file,
generated my another function, or even a MS Paint bitmap image.
>>> image_1 = astropy.io.fits.getdata("orion.fits")
>>> image_1
array([[0.0, ... 0.0],
... ,
[0.0, ... 0.0]])
Here SimCADO takes a the pixel coordinates of the image and converts them to positions on the focal plane.
Note
the user must specify a plate-scale in arcseconds (pix_res=) for the image. Each pixel with a value above a certain threshold (default flux_threshold=0) will be used in the Source object. The coordinates of these pixels are added to the arrays .x and .y.
We also need to provide a spectrum for the image. This spectrum is assumed to be the only spectrum for each pixel in the image. The pixel values are then the intensity assigned to that spectrum at that pixel position.
SimCADO provides the pickles library for stellar spectra. Unfortunately there aren’t any built-in galactic spectra yet - for this the user will need to provide their own spectrum.
>>> lam, spec_1 = simcado.source.SED("G2V", "K", magnitude=20)
>>> lam, spec_1
(array([0.7 ... 2.5]), array([0.0 ... 0.0]))
With image_1
, lam
and spec_1
we can now build a Source
object for an orion-like nebula that has the spectrum of a sun-like
star.
>>> simcado.source.source_from_image(image_1, lam, spec_1, pix_res=0.004, flux_threshold=0)
While this example is physically unrealistic, it serves the purpose of
showing how to build a Source
object from an image. The user is
Images with multipe spectra¶
In reality assigning a single spectrum to an extended object is of
limited use. For a Source
to be realistic is should contain multiple
spectra for objects in different locations. The best way to simulate
this with SimCADO is to create a Source
object for each unique group
of objects (e.g. old stellar population, star forming regions, AGN, etc)
and then combine them into a single Source
object with the +
operator.
As a worked example, lets create a “first-order” approximation to a star forming galaxy. The two major components of this source are 1. the aged stellar population and, 2. the star forming regions.
In our (very) crude model the aged stellar population can be approximated by an ellipse with Gaussian light distribution. As M stars make up the majority of this population, we can assign a M0V spectrum to this population.
>>> from astropy.convolution import Gaussian2DKernel
>>> from simcado.source import SED
>>>
>>> old_pop = Gaussian2DKernel(128).array[::3,:]
>>> m0v_spec = SED()
To illustrate (very crudely) the star forming regions we can create a
random distribution of elliptical Gaussians using the astropy
function Gasussian2DKernel
:
Creating a Source
object from scratch¶
To create a Source
object from scratch, we initialise the object by
passing 5 (or 6) arrays. All the parameter names must be specified.
sim.Source(lam=, spectra=, x=, y=, ref=, [weight=])
where: + x, y
- [each a numpy.ndarray
]. Coordinates for each
point source in the image in units of [arcsec] from the focal plane
centre
lam
- [numpy.ndarray
]. An array with the centre of the wavelength bins in [um] for each unique spectrumspectra
- [numpy.ndarray
]. An (n, m) array holding n spectra, each with m values. Default units are [ph/s] Note -lam
andspectra
should use a constant bin width. Variable bin widths leads to unpredictable results.ref
- [numpy.ndarray
]. An array to connect the point source atx[i]
,y[i]
to a unique spectrum atspectra[j]
, i.e.ref[i] = j
Optional keywords can be specified:
weight
- [numpy.ndarray
], optional. If two sources share the same spectrum, but are at different distances or have different luminosities a scaling factor can be specified to the spectrum when applied to each specific point source.units
[default"ph/s"
] is the units for the spectra, i.e. n phontons per second per spectral bin. The size of the spectral bins is resolution of the.lam
array.
Combining two (or more) Source
objects¶
Source
objects can be created in different ways, but the underlying
table-structure is the same. Therefore adding Source
objects
together means simply combining tables. The mathematical operator +
can be used to do this:
>>> # ... create a A0V star at (0,0) and a G2V star at (5,-5)
>>> star_A0V = sim.source.star(20, spec_type="A0V", x=0, y=0)
>>> star_G2V = sim.source.star(20, spec_type="G2V", x=5, y=-5)
>>>
>>> src_combi = star_A0V + star_G2V
>>>
>>> print(src_combi.x, src_combi.y)
[0 5] [ 0 -5]
By adding different Source
objects together, it is possible to build
up complex objects that will be representative of the observed sky,
e.g. old + new galaxy stellar population + gas emission + foreground
stars
See examples for how to use the *
and -
operators with a Source
object
Saving a Source
object to disk¶
The Source
object is saved as a FITS file with two extensions. See
How SimCADO works for more on the file structure.
>>> src_combi.write("my_src.fits")
The file can be read in at a later time by specifying filename=
when
initialising a Source
object - as stated above
>>> my_src = sim.Source(filename="my_src.fits")
In-built Source
object for a star cluster¶
As a test object, SimCADO provides the function, with all distances in parsecs
sim.source.cluster(mass=1E4, distance=50000, half_light_radius=1)
SimCADO convenience functions¶
Keywords for Controlling SimCADO¶
Observation Parameters¶
Keyword Default [units] Explanation
-----------------------------------------------------------------------------------------------
OBS_DATE 0 # [dd/mm/yyyy] Date of the observation [not yet implemented]
OBS_TIME 0 # [hh:mm:ss] Time of the observation [not yet implemented]
OBS_RA 90. # [deg] RA of the object
OBS_DEC -30. # [deg] Dec of the object
OBS_ALT 0 # [deg] Altitude of the object [not yet implemented]
OBS_AZ 0 # [deg] Azimuth of the object [not yet implemented]
OBS_ZENITH_DIST 0 # [deg] from zenith
OBS_PARALLACTIC_ANGLE 0 # [deg] rotation of the source relative to the zenith
OBS_SEEING 0.6 # [arcsec]
OBS_FIELD_ROTATION 0 # [deg] field rotation with respect to the detector array
OBS_DIT 60 # [sec] simulated exposure time
OBS_NDIT 1 # [#] number of exposures taken
OBS_NONDESTRUCT_TRO 2.6 # [sec] time between non-destructive readouts in the detector
OBS_REMOVE_CONST_BG no # remove the median background value
OBS_READ_MODE single # [single, fowler, ramp] Only single is implemented at the moment
OBS_SAVE_ALL_FRAMES no # yes/no to saving all DITs in an NDIT sequence
OBS_INPUT_SOURCE_PATH none # Path to input Source FITS file
OBS_FITS_EXT 0 # the extension number where the useful data cube is
OBS_OUTPUT_DIR "./output.fits" # [filename] Path to save output in.
Simulation Parameters¶
Keyword Default [units] Explanation
-----------------------------------------------------------------------------------------------
SIM_DETECTOR_PIX_SCALE 0.004 # [arcsec] plate scale of the detector
SIM_OVERSAMPLING 1 # The factor of oversampling inside the simulation
SIM_PIXEL_THRESHOLD 1 # photons per pixel summed over the wavelength range. Values less than this are assumed to be zero
SIM_LAM_TC_BIN_WIDTH 0.001 # [um] wavelength resolution of spectral curves
SIM_SPEC_MIN_STEP 1E-4 # [um] minimum step size where resampling spectral curves
SIM_FILTER_THRESHOLD 1E-9 # transmission below this threshold is assumed to be 0
SIM_USE_FILTER_LAM yes # [yes/no] to basing the wavelength range off the filter non-zero range - if no, specify LAM_MIN, LAM_MAX
# if "no"
SIM_LAM_MIN 1.9 # [um] lower wavelength range of observation
SIM_LAM_MAX 2.41 # [um] upper wavelength range of observation
SIM_LAM_PSF_BIN_WIDTH 0.1 # [um] wavelength resolution of the PSF layers
SIM_ADC_SHIFT_THRESHOLD 1 # [pixel] the spatial shift before a new spectral layer is added (i.e. how often the spectral domain is sampled for an under-performing ADC)
SIM_PSF_SIZE 1024 # size of PSF
SIM_PSF_OVERSAMPLE no # use astropy's inbuilt oversampling technique when generating the PSFs. Kills memory for PSFs over 511 x 511
SIM_VERBOSE no # [yes/no] print information on the simulation run
SIM_SIM_MESSAGE_LEVEL 3 # the amount of information printed [5-everything, 0-nothing]
SIM_OPT_TRAIN_IN_PATH none # Options for saving and reusing optical trains. If "none": "./"
SIM_OPT_TRAIN_OUT_PATH none # Options for saving and reusing optical trains. If "none": "./"
SIM_DETECTOR_IN_PATH none # Options for saving and reusing detector objects. If "none": "./"
SIM_DETECTOR_OUT_PATH none # Options for saving and reusing detector objects. If "none": "./"
Atmospheric Parameters¶
Keyword Default [units] Explanation
-----------------------------------------------------------------------------------------------
ATMO_USE_ATMO_BG yes # [yes/no]
ATMO_TC TC_sky_25.tbl # [filename] for atmospheric transmission curve. Default: <pkg_dir>/data/TC_sky_25.tbl
ATMO_EC EC_sky_25.tbl # [filename, "none"] for atmospheric emission curve. Default: <pkg_dir>/data/EC_sky_25.tbl
# If ATMO_EC is "none": set ATMO_BG_MAGNITUDE for the simulation filter.
ATMO_BG_MAGNITUDE 13.6 # [ph/s] background photons for the bandpass. If set to None, the ATMO_EC spectrum is assumed to return the needed number of photons
ATMO_TEMPERATURE 0 # deg Celcius
ATMO_PRESSURE 750 # millibar
ATMO_REL_HUMIDITY 60 # %
ATMO_PWV 2.5 # [mm] Paranal standard value
Telescope Parameters¶
Keyword Default [units] Explanation
-----------------------------------------------------------------------------------------------
SCOPE_ALTITUDE 3060 # meters above sea level
SCOPE_LATITUDE -24.589167 # decimal degrees
SCOPE_LONGITUDE -70.192222 # decimal degrees
SCOPE_PSF_FILE scao # [scao (default), <filename>, ltao, mcao, poppy] import a PSF from a file.
SCOPE_STREHL_RATIO 1 # [0..1] defines the strength of the seeing halo if SCOPE_PSF_FILE is "default"
SCOPE_AO_EFFECTIVENESS 100 # [%] percentage of seeing PSF corrected by AO - 100% = diff limited, 0% = 0.8" seeing
SCOPE_JITTER_FWHM 0.001 # [arcsec] gaussian telescope jitter (wind, tracking)
SCOPE_DRIFT_DISTANCE 0 # [arcsec/sec] the drift in tracking by the telescope
SCOPE_DRIFT_PROFILE linear # [linear, gaussian] the drift profile. If linear, simulates when tracking is off. If gaussian, simulates rms distance of tracking errors
SCOPE_USE_MIRROR_BG yes # [yes/no]
SCOPE_NUM_MIRRORS 5 # number of reflecting surfaces
SCOPE_TEMP 0 # deg Celsius - temperature of mirror
SCOPE_M1_TC TC_mirror_EELT.dat # [filename] Mirror reflectance curve. Default: <pkg_dir>/data/TC_mirror_EELT.dat
SCOPE_MIRROR_LIST EC_mirrors_EELT_SCAO.tbl # [filename] List of mirror sizes. Default: <pkg_dir>/data/EC_mirrors_EELT_SCAO.tbl
Instrument Parameters¶
Keyword Default [units] Explanation
-----------------------------------------------------------------------------------------------
INST_TEMPERATURE -190 # deg Celsius - inside temp of instrument
INST_ENTR_NUM_SURFACES 4 # number of surfaces on the entrance window
INST_ENTR_WINDOW_TC TC_window.dat # [filename] Default: <pkg_dir>/data/TC_window.dat --> transmission = 0.98 per surface
INST_DICHROIC_NUM_SURFACES 2 # number of surfaces on the entrance window
INST_DICHROIC_TC TC_dichroic.dat # [filename] Default: <pkg_dir>/data/TC_dichroic.dat --> transmission = 1 per surface
INST_FILTER_TC Ks # [filename, string(filter name)] List acceptable filters with >>> simcado.optics.get_filter_set()
INST_PUPIL_NUM_SURFACES 2 # number of surfaces on the pupil window
INST_PUPIL_TC TC_pupil.dat # [filename] Default: <pkg_dir>/data/TC_pupil.dat --> transmission = 1 per surface
# MICADO, collimator 5x, wide-field 2x (zoom 4x), camera 4x
INST_NUM_MIRRORS 11 # number of reflecting surfaces in MICADO
INST_MIRROR_TC TC_mirror_gold.dat # [filename, "default"] If "default": INST_MIRROR_TC = SCOPE_M1_TC
INST_USE_AO_MIRROR_BG yes # [yes/no]
INST_AO_TEMPERATURE 0 # deg Celsius - inside temp of AO module
INST_NUM_AO_MIRRORS 7 # number of reflecting surfaces between telescope and instrument (i.e. MAORY)
INST_MIRROR_AO_TC TC_mirror_gold.dat # [filename, "default"] If "default": INST_MIRROR_AO_TC = INST_MIRROR_TC
INST_MIRROR_AO_LIST EC_mirrors_ao.tbl # List of mirrors in the AO. Default: <pkg_dir>/data/EC_mirrors_ao.tbl
INST_ADC_PERFORMANCE 100 # [%] how well the ADC does its job
INST_ADC_NUM_SURFACES 8 # number of surfaces in the ADC
INST_ADC_TC TC_ADC.dat # [filename] Default: <pkg_dir>/data/TC_ADC.dat --> transmission = 0.98 per surface
INST_DEROT_PERFORMANCE 100 # [%] how well the derotator derotates
INST_DEROT_PROFILE linear # [linear, gaussian] the profile with which it does it's job
INST_DISTORTION_MAP none # path to distortion map
INST_WFE data/INST_wfe.tbl # [nm] (float or filename) A single number for the total WFE of a table of wavefront errors for each surface in the instrument
INST_FLAT_FIELD none # path to a FITS file containing a flat field (median = 1) for each chip.
Spectroscopy parameters¶
Keyword Default [units] Explanation
-----------------------------------------------------------------------------------------------
SPEC_ORDER_SORT HK # Order-sorting filter: "HK" or "IJ"
SPEC_SLIT_WIDTH narrow # Slit width: "narrow" or "wide"
Detector parameters¶
Keyword Default [units] Explanation
-----------------------------------------------------------------------------------------------
FPA_USE_NOISE yes # [yes/no]
FPA_READOUT_MEDIAN 4 # e-/px
FPA_READOUT_STDEV 1 # e-/px
FPA_DARK_MEDIAN 0.01 # e-/s/px
FPA_DARK_STDEV 0.01 # e-/s/px
FPA_QE TC_detector_H2RG.dat # [filename] Quantum efficiency of detector.
FPA_NOISE_PATH FPA_noise.fits # [filename, "generate"] if "generate": use NGHxRG to create a noise frame.
FPA_GAIN 1 # e- to ADU conversion
FPA_LINEARITY_CURVE FPA_linearity.dat # [filename, "none"]
FPA_FULL_WELL_DEPTH 1E5 # [e-] The level where saturation occurs
FPA_PIXEL_MAP none # path to a FITS file with the pixel sensitivity map
# if FPA_PIXEL_MAP == none
FPA_DEAD_PIXELS 1 # [%] if FPA_PIXEL_MAP=none, a percentage of detector pixel which are dead
FPA_DEAD_LINES 1 # [%] if FPA_PIXEL_MAP=none, a percentage of detector lines which are dead
FPA_CHIP_LAYOUT centre # ["tiny", "small", "centre", "full", <filename>] description of the chip layout on the detector array.
FPA_PIXEL_READ_TIME 1E-5 # [s] read time for y pixel - typically ~10 us
FPA_READ_OUT_SCHEME double_corr # "double_corr", "up-the-ramp", "fowler"
NXRG Noise Generator package parameters¶
Keyword Default [units] Explanation
-----------------------------------------------------------------------------------------------
# See Rauscher (2015) for details
# http://arxiv.org/pdf/1509.06264.pdf
HXRG_NUM_OUTPUTS 64 # Number of
HXRG_NUM_ROW_OH 8 # Number of row overheads
HXRG_PCA0_FILENAME FPA_nirspec_pca0.fits # if "default": <pkg_dir>/data/
HXRG_OUTPUT_PATH none # Path to save the detector noise
HXRG_PEDESTAL 4 # Pedestal noise
HXRG_CORR_PINK 3 # Correlated Pink noise
HXRG_UNCORR_PINK 1 # Uncorrelated Pink noise
HXRG_ALT_COL_NOISE 0.5 # Alternating Column noise
HXRG_NAXIS1 4096 # Size of the HAWAII 4RG detectors
HXRG_NAXIS2 4096
HXRG_NUM_NDRO 1 # Number of non-destructive readouts to add to a noise cube
SimCADO Package¶
simcado.commands module
¶
simcado.commands Module¶
Functions¶
|
Dump the frequent.config file to a path specified by the user |
|
Dump the FPA_chip_layout.dat file to a path specified by the user |
|
Dump the EC_mirrors_scope.tbl or the EC_mirrors_ao.tbl to disk |
|
Read in a SimCADO configuration file |
|
Update a SimCADO configuration dictionary |
Classes¶
|
An extended dictionary with the parameters needed for running a simulation |
simcado.detector module
¶
simcado.detector Module¶
A description of the Chip noise properties and their positions on the Detector
Module Summary¶
This module holds three classes: Detector
, Chip
and HXRGNoise
.
Chip
Everything to do with photons and electrons happens in the Chip
class. Each
Chip
is initialised with a position relative to the centre of the detector
array, a size [in pixels] and a resolution [in arcsec]. Photons fall onto the
Chip
s and are read out together with the read noise characteristics of the
Chip
.
Detector
The Detector
holds the information on where the Chip
s are placed on the
focal plane. Focal plane coordinates are in [arcsec]. These coordinates are
either read in from a default file or determined by the user. The Detector
object is an intermediary - it only passes information on the photons to the
Chip
s. It is mainly a convenience class so that the user can read out all
Chip
s at the same time.
Classes¶
- Detector
builds an array of
Chip
objects based on aUserCommands
object- Chip
converts incoming photons into ADUs and adds in read-out noise
See Also¶
Notes¶
References¶
[1] Bernhard Rauscher’s HxRG Noise Generator script
Examples¶
The Detector
can be used in stand-alone mode. In this case it outputs
only the noise that a sealed-off detector would generate:
>>> import simcado
>>> fpa = simcado.Detector(simcado.UserCommands())
>>> fpa.read_out(output=True, chips=[0])
The Detector
is more useful if we combine it with a Source
object and an OpticalTrain
. Here we create a Source
object
for an open cluster in the LMC and pass the photons arriving from it through the
E-ELT and MICADO. The photons are then cast onto the detector array. Each
Chip
converts the photons to ADUs and adds the resulting image to an
Astropy HDUList
. The HDUList
is then written to disk.
>>> # Create a set of commands, optical train and detector
>>>
>>> import simcado
>>> cmds = simcado.UserCommands()
>>> opt_train = simcado.OpticalTrain(cmds)
>>> fpa = simcado.Detector(cmds)
>>>
>>> # Pass photons from a 10^4 Msun open cluster in the LMC through to the detector
>>>
>>> src = sim.source.source_1E4_Msun_cluster()
>>> src.apply_optical_train(opt_train, fpa)
>>>
>>># Read out the detector array to a FITS file
>>>
>>> fpa.read_out(filename="my_raw_image.fits")
Functions¶
|
Opens a saved |
|
Plot the contents of a detector array |
|
Plot the detector layout |
|
Create a large noise cube with many separate readout frames. |
|
Install a noise cube in the package directory |
Classes¶
|
Generate a series of |
|
Holds the “image” as seen by a single chip in the focal plane |
simcado.nghxrg module
¶
simcado.nghxrg Module¶
NGHXRG by Bernard Rauscher see the paper: http://arxiv.org/abs/1509.06264 downloaded from: http://jwst.nasa.gov/publications.html
Classes¶
|
A class to generate HxRG noise frames |
simcado.optics module
¶
simcado.optics Module¶
optics.py
Functions¶
|
Return a Vis/NIR broadband filter TransmissionCurve object |
|
Return a list of the filters installed in the package directory |
Classes¶
|
The OpticalTrain object reads in or generates the information necessary to model the optical path for all (3) sources of photons: the astronomical source, the atmosphere and the primary mirror. |
simcado.psf module
¶
simcado.psf Module¶
PSFs and PSFCubes¶
Todo
revise this opening text
Car Sagan said
- “If you want to bake an apple pie from scratch,
first you must create the universe”
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)
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.
All wavelength values are given in [um] All pixel dimensions are given in [arcsec] All angles are given in [deg]
PSF(object) psf(object)
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
Functions¶
|
Generate a PSF for the E-ELT for plan A or B with POPPY |
|
Create a diffraction limited E-ELT PSF with a Seeing halo |
|
Return a seeing limited PSF |
|
Generate a list of segments for POPPY for the E-ELT |
|
Combine several PSF FITS images into a single PSF FITS file |
Classes¶
|
Point spread function (single layer) base class |
|
Class holding wavelength dependent point spread function. |
|
Generate a PSF for a Moffat function. |
|
Generate a list of MoffatPSFs for wavelengths defined in lam_bin_centers |
|
Generate a PSF for an Airy function with an equivalent FWHM |
|
Generate a list of AiryPSFs for wavelengths defined in lam_bin_centers |
|
Generate a PSF for an Gaussian function |
|
Generate a list of GaussianPSFs for wavelengths defined in lam_bin_centers |
|
Generate a PSF with a delta function at position (x,y) |
|
Generate a list of DeltaPSFs for wavelengths defined in lam_bin_centers |
|
Generate a PSF from a collection of several PSFs. |
|
Generate a list of CombinedPSFCubes from the list of psfs in psf_list |
|
Import a PSF from a FITS file. |
|
Read in a psf previously saved as a FITS file |
|
simcado.simulation module
¶
simcado.simulation Module¶
simulation.py
Functions¶
|
Run a MICADO simulation with default parameters |
|
Returns the signal-to-noise ratio(s) for given exposure times and magnitudes |
|
Creates a series of grids of stars and generates the output images |
|
Return or plot a graph of the limiting magnitudes for MICADO |
|
Returns the zero point magnitude for a SimCADO filter |
simcado.source module
¶
simcado.source Module¶
The module that contains the functionality to create Source objects
Module Summary¶
The Source is essentially a list of spectra and a list of positions. The list of positions contains a reference to the relevant spectra. The advantage here is that if there are repeated spectra in a data cube, we can reduce the amount of calculations needed. Furthermore, if the input is originally a list of stars, etc., where the position of a star is not always an integer multiple of the plate scale, we can keep the information until the PSFs are needed.
Classes¶
Source
Functions¶
Functions to create Source
objects
empty_sky()
star(mag, filter_name="Ks", spec_type="A0V", x=0, y=0)
stars(mags, filter_name="Ks", spec_types=["A0V"], x=[0], y=[0])
star_grid(n, mag_min, mag_max, filter_name="Ks", separation=1, area=1,
spec_type="A0V")
source_from_image(images, lam, spectra, pix_res, oversample=1,
units="ph/s/m2", flux_threshold=0,
center_pixel_offset=(0, 0))
source_1E4_Msun_cluster(distance=50000, half_light_radius=1)
Functions for manipulating spectra for a Source
object
scale_spectrum(lam, spec, mag, filter_name="Ks", return_ec=False)
scale_spectrum_sb(lam, spec, mag_per_arcsec, pix_res=0.004,
filter_name="Ks", return_ec=False)
flat_spectrum(mag, filter_name="Ks", return_ec=False)
flat_spectrum_sb(mag_per_arcsec, filter_name="Ks", pix_res=0.004,
return_ec=False)
Functions regarding photon flux and magnitudes
zero_magnitude_photon_flux(filter_name)
_get_stellar_properties(spec_type, cat=None, verbose=False)
_get_stellar_mass(spec_type)
_get_stellar_Mv(spec_type)
_get_pickles_curve(spec_type, cat=None, verbose=False)
Helper functions
value_at_lambda(lam_i, lam, val, return_index=False)
SED(spec_type, filter_name="V", magnitude=0.)
Functions¶
|
Creates a simcado.Source object for a star with a given magnitude |
|
Creates a simcado.Source object for a bunch of stars. |
|
Generate a source object for a cluster |
|
Creates a simcado.Source object for a point source with a given magnitude |
|
Create a extended |
|
Creates a spiral profile with arbitary parameters |
|
Create a extended |
|
Returns a 2D array with a normalised Sersic profile |
|
Create a Source object from an image or a list of images. |
|
Creates a square grid of A0V stars at equal magnitude intervals |
Returns an empty source so that instrumental fluxes can be simulated |
|
|
Return a scaled SED for a star or type of galaxy |
|
Redshift a SimCADO SED and scale it to a magnitude in a user specified filter |
|
Compute the deflection of an SIE (singular isothermal ellipsoid) potential |
|
Apply a singular isothermal ellipsoid (SIE) gravitational lens to an image |
|
Return a list of the SEDs installed in the package directory |
|
Scale a spectrum to be a certain magnitude |
|
Scale a spectrum to be a certain magnitude per arcsec2 |
|
Return a flat spectrum scaled to a certain magnitude |
|
Return a flat spectrum for a certain magnitude per arcsec |
|
Return the value at a certain wavelength - i.e. |
|
Returns the latest main sequence spectral type(s) for (a) B-V colour |
|
Return the number of photons for a m=0 star for a filter with synphot |
|
Return the number of photons for a certain filter and magnitude |
|
Return the number of photons for a certain filter and magnitude |
|
Returns the emission curve for a single or list of |
|
Returns an |
|
Returns a single (or list of) float(s) with the V-band absolute magnitude(s) |
|
Returns a single (or list of) float(s) with the stellar mass(es) |
Classes¶
|
Create a source object from a file or from arrays |
simcado.spatial module
¶
simcado.spatial Module¶
TODO: Insert docstring
Functions¶
|
A method to simulate tracking errors ===== Currently a place holder with minimum functionality ========= !! TODO, work out the shift during the DIT for the object RA, DEC etc !! |
|
A method to simulate field rotation in case the derotator is <100% effective ===== Currently a place holder with minimum functionality ========= !! TODO, work out the rotation during the DIT for the object RA, DEC etc !! |
|
A method to simulate wind jitter ===== Currently a place holder with minimum functionality ========= !! TODO, get the read spectrum for wind jitter !! !! Add in an angle parameter for the ellipse !! |
|
Generates a list of x and y shifts from a commands object |
|
Generate distortion maps based on star positions. |
|
Returns the distortion offsets for position relative to the FoV centre |
simcado.spectral module
¶
simcado.spectral Module¶
Classes for spectral curves
Functions¶
|
Return a spectral curve for the sky for a certain airmass |
Classes¶
|
Very basic class to either read in a text file for a transmission curve or take two vectors to make a transmission curve |
|
Class for emission curves |
|
Blackbody emission curve |
|
Constant transmission curve |
simcado.utils module
¶
simcado.utils Module¶
Helper functions for SimCADO
Functions¶
|
Adds the SED given in |
|
Add a keyword, value pair to an extension header in a FITS file |
|
Returns a combined magnitude for a group of objects with |
|
Convert airmass to zenith distance |
|
returns zenith distance in degrees |
|
Returns the angular distance of an object in arcseconds. |
|
Compute atmospheric refraction |
Get versions of dependencies for inclusion in bug report |
|
|
Derivatives (gradient) of a Polynomial2D model |
mu = 5 * np.log10(d) - 5 |
|
d = 10**(1 + mu / 5) |
|
|
Download the extra data that aren’t in the SimCADO package |
|
Find a file in search path |
Downloads large files that SimCADO needs to simulate MICADO |
|
|
Checks if file is a FITS file based on extension |
|
!!Unfinished!! Return a Moffat function |
|
Prints a message based on the level of verbosity given in cmds |
|
Return the index of the value from ‘arr’ which is closest to ‘val’ |
|
Compute the parallactic angle |
|
Add a realisation of the poisson process to the array ‘arr’. |
|
Ensure an item is a Quantity |
|
Replacement for numpy.arange modelled after R’s seq function |
|
Returns the diffraction limit of a telescope |
|
Turn an angular distance into a proper transverse distance |
|
Convert all types of input to an astropy array/unit pair |
|
Convert zenith distance to airmass |
|
|
Bugs and Issues¶
We freely admit that there may still be several bugs that we have not found. If you come across an buggy part of SimCADO, please please tell us. We can’t make SimCADO better if we don’t know about things.
The preferable option is to open an issue on our Github page: astronomyk/SimCADO/issues, or you can contact one of us directly.
Contact¶
For questions and complaints alike, please contact the authors:
Developers (Vienna): Kieran Leschinski, Oliver Czoske, Miguel Verdugo
Data Flow Team Leader (Gronigen): Gijs Verdoes Kleijn
MICADO home office (MPE): http://www.mpe.mpg.de/ir/micado