{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook presents a basic description of the simulation procedure with scopesim and tries to give some useful hints how the behaviour of each step can be inspected and controlled. Once scopesim and the necessary instrument packages are installed, a simulation is basically a four-step process using the commands `UserCommands`, `OpticalTrain`, `observe` and `readout`. The cells in this notebook are not executable; the practical application to a variety of different source objects and instrument modes is presented in other notebooks." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Installation and prerequisites\n", "\n", "The easiest way to install Scopesim is to use `pip` from the command line:\n", "```sh\n", "pip install scopesim\n", "```\n", "If you want to upgrade an existing installation, do\n", "```sh\n", "pip install -U scopesim\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In your favourite python environment (e.g. `ipython`, `jupyter notebook` or a script), scopesim is loaded by\n", "```python\n", "import scopesim\n", "```\n", "or\n", "```python\n", "import scopesim as sim\n", "```\n", "Scopesim has a utility function ```sim.bug_report()``` which checks a number of other python packages required by scopesim and reports their version numbers. The output of this command should be included in any bug report or question submitted to the scopesim team." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Instrument packages\n", "Scopesim is a general simulation framework. In order to simulate observations with any particular instrument, you will have to load an instrument package, as well as packages describing the telescope and observatory location (the latter is important for the atmospheric conditions). In the case of METIS, the packages can be downloaded with \n", "```python\n", "sim.download_packages(['instruments/METIS', 'telescopes/ELT', 'locations/Armazones'])\n", "```\n", "By default, scopesim looks for the packages in the subdirectory `inst_pkgs` of the current working directory. The download command will install them there, so there should be no problem. \n", "\n", "It is possible to install the packages elsewhere; if you do that you will have to declare to scopesim where they are. This can be done by setting\n", "```python\n", "sim.rc.__config__[\"!SIM.file.local_packages_path\"] = \"/path/to/inst_pgks\"\n", "```\n", "\n", "If you encounter the error `File cannot be found: default.yaml` when calling `sim.UserCommands` (see below), either call `sim.download_package` from the working directory or set the `local_packages_path` as just explained.\n", "\n", "We suggest following the default scheme, because keeping the instrument packages together with the input and output data of scopesim makes it easier later to reconstruct the conditions under which a simulation was run. \n", "\n", "The command `sim.list_packages()` lists all packages that are available for download, as well as those that are already installed." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Setting up the instrument\n", "The instrument is configured using the `sim.UserCommands()` class. A basic setup for METIS could be\n", "```python\n", "cmd = sim.UserCommands(use_instrument='METIS', set_modes=['img_lm'])\n", "```\n", "This creates a (nested dictionary) containing all parameters that are relevant for the description of the instrument and observational conditions, and the way that the simulation is to be run.\n", "\n", "The modes are predefined in the instrument package (in the file `METIS/default.yaml`). The available modes for METIS are\n", "\n", "- `img_lm` for imaging using the LM imager\n", "- `img_n` for imaging using the N imager\n", "- `lss_l` for long-slit spectroscopy in the L band\n", "- `lss_m` for long-slit spectroscopy in the M band\n", "- `lss_n` for long-slit spectroscopy in the N band\n", "\n", "The LMS modes `lms` and `lms_extended` are not yet functional.\n", "\n", "The `UserCommands` dictionary is structured into a number of sections that can be accessed using a \"bang string\", starting with an exclamation mark. For instance, the list of \"observation\" parameters is obtained with `cmd['!OBS']`. Individual parameters are addressed as `cmd['!OBS.filter_name']` etc. The `!OBS` class contains the parameters that users are most likely to want to change from one simulation to the next. The other sections are more static, and users should only change them with more caution. The following sections are available:\n", "\n", "- `!OBS`: parameters that might be changed from one simulation to the other\n", "- `!SIM`: parameters that set up file paths and simulation parameters for scopesim\n", "- `!ATMO`: parameters that relate to the atmosphere and atmospheric conditions.\n", "- `!TEL`: parameters related to the telescope. Of interest for METIS is the parameter `!TEL.ter_curve`, which defaults to `TER_ELT_6_mirror_field_track.dat` but could be changed to `TER_ELT_6_mirror_pupil_track.dat`. The files differ in that field tracking includes thermal emission from the telescope support spiders, which are assumed to be masked in pupil tracking.\n", "- `!INST`: parameters related to the instrument\n", "- `!DET`: parameters related to the detector\n", "\n", "\n", "The parameters can be changed at this point, for instance to change the pupil transmission (this refers to undersizing of the aperture by inserting a cold stop):\n", "```python\n", "cmd['!OBS.pupil_transmission'] = 0.9\n", "```\n", "\n", "Individual parameters can be set immediately in the `UserCommands` by giving a `properties` dictionary. This gives the compact form\n", "```python\n", "cmd = sim.UserCommands(use_instrument='METIS', set_modes=['lss_m'],\n", " properties={'!OBS.slit': 'D-57_1',\n", " '!OBS.detector_readout_mode': 'slow'})\n", "```\n", "Some parameters can also be set later as will be demonstrated. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Building and modifying the instrument\n", "The combination of atmosphere, telescope and instrument is represented in scopesim as an `OpticalTrain` object, which is instantiated as\n", "```python\n", "metis = sim.OpticalTrain(cmd)\n", "```\n", "The optical train consists of a number of `Effect` objects, which can be listed as\n", "```python\n", "metis.effects\n", "```\n", "The table has four columns of which `name` and `included` are important. An effect is addressed by its name; for example, `metis['detector_linearity']` is the effect that describes the (non-)linearity of the detector. Each effect has a `meta` dictionary that contains parameters used to set it up, as well as meta data from configuration files. To resolve a parameter that contains a bang string, the function `from_currsys` has to be used. For instance, `metis['dark_current']` returns `!DET.dark_current`, which is resolved by\n", "```python\n", "sim.utils.from_currsys(metis['dark_current'])\n", "```\n", "into a number of electrons per second.\n", "\n", "Some parameters support changing parameters, these are notably `filter_wheel` and `slit_wheel`. These have a number of predefined options that can be seen with\n", "```python\n", "metis['filter_wheel'].filters\n", "```\n", "The current setting is found by `metis['filter_wheel'].current_filter` and can be changed by\n", "```python\n", "metis['filter_wheel'].change_filter('PAH_3.3')\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Defining and observing the source\n", "The `observe()` method of an `OpticalTrain` transmits a source object through the atmosphere, telescope and instrument into the detector plane but does not yet include the detector itself (with the exception of the quantum efficiency, which is treated as a transmission effect). The result is an ideal noise-free image in units of electrons per second (electrons because of the inclusion of QE). \n", "\n", "The definition of `Source` objects is described in other notebooks. The observation is done by\n", "```python\n", "src = sim.source.source_templates.star()\n", "metis.observe(src)\n", "```\n", "The same optical train can be used to observe multiple sources in succession. In this case it is advisable (and should never harm) to include the parameter `update=True`:\n", "```python\n", "metis.observe(src, update=True)\n", "```\n", "Sometimes one might have several optical trains to observe the same source, e.g `metis_l` and `metis_n` for observation in the L and M bands, respectively. To switch from one to the other it is necessary to call the method `set_focus()`, as in\n", "```python\n", "metis_l.observe(src)\n", "metis_n.set_focus()\n", "metis_n.observe(src)\n", "```\n", "The noise-free image is an `ImagePlane` object, which can be accessed as\n", "```python\n", "metis.image_planes[0]\n", "```\n", "In general, `image_planes` is a list, although METIS always produces a single `ImagePlane`. An `ImagePlane` is essentially a FITS HDU whose parts are accessed as \n", "```python\n", "metis.image_planes[0].header\n", "metis.image_planes[0].data\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Creating detector images\n", "The `readout()` method applies photon noise and detector noise to the image and creates detector images with a given exposure time. The result of `readout()` is a list of FITS HDULists (essentially FITS \"files\" in memory). For METIS only a single HDULIST is created, so a command like\n", "```python\n", "result = metis.readout()[0]\n", "```\n", "is convenient. The detector image is in the first extension of `result` and one might want to look at\n", "```python\n", "result[0].header\n", "result[1].header\n", "result[1].data\n", "```\n", "\n", "By default, the exposure time is set by the `UserCommands` parameter `!OBS.exptime`. In many cases it is more convenient to set it as a parameter to the `readout()` method:\n", "```python\n", "result = metis.readout(exptime=3600)[0] # exposure time in seconds\n", "```\n", "The exposure time is automatically split into `NDIT` subexposures of length `DIT`, ensuring that the detector is not saturated during a subexposure (a warning is issued if a bright source saturates the detector even in the minimum possible `DIT`).\n", "\n", "The METIS detectors each have two settings (\"fast\" and \"slow\" for the HAWAII detectors, \"high_capacity\" and \"low_capacity\" for the Geosnap). There is a default setting for each instrument mode, but an optimal readout mode can also be automatically determined by\n", "```python\n", "result = metis.readout(detector_readout_mode='auto')\n", "```\n", "The result can be written to disk with\n", "```python\n", "result.writeto(\"simulation_result.fits\", overwrite=True) # careful with overwrite\n", "```\n", "for analysis with external tools." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.4" } }, "nbformat": 4, "nbformat_minor": 4 }