Welcome to LIFEsim’s documentation!

LIFEsim is the simulator software for the Large Interferometer For Exoplanets (LIFE). It simulates the interferometric measurement of LIFE to demonstrate the capabilities of the observatory. Coupled with on-sky source simulations, LIFEsim will infer the amount and diversity of exoplanets observable with LIFE. Inputting spectral information of exoplanets allows for a description of the spectral measurement potential of LIFE.

For more information, please visit the LIFE Website.

_images/LIFE_visual.jpg

Installation (Linux and Mac OS)

LIFEsim is available for installation from Github. It is compatible with Python 3.8.

Hint

Installation on Mac OS

We recommend the usage of a package manager for mac (e.g. Miniconda). Follow the installation instruction given by the respective package manager, making sure that you use the correct version of python (3.8).

Open a terminal window and activate conda by running

$ conda activate

Virtual Environment

It is highly recommended to install LIFEsim in a virtual environment. This ensures installed packages and changes made do not affect other projects on a system. The package dependencies of LIFEsim are best managed with a package manager like pip.

As a first step, virtualenv is installed with pip

$ pip install virtualenv

Then a virtual environment in the folder new_folder is created in the current directory

$ virtualenv -p python3.8 new_folder

Hint

You might need to deactivate the conda base

$ conda deactivate

To activate and deactivate your new virtual environment use the following statement respectively

$ source path_to_new_folder/new_folder/bin/activate

Check that you are using the correct python version.

$ python --version
Python 3.8.X
$ deactivate

Download from Github

Navigate to the directory in which you desire to place the LIFEsim repository. Then clone the repository from Github by executing

$ git clone https://github.com/fdannert/LIFEsim.git

Hint

If git is not installed on your system run

$ sudo apt install git

The dependencies required by LIFEsim can be installed with

$ pip install -r LIFEsim/requirements.txt

To upgrade already installed dependencies to LIFEsim requirements run

$ pip install --upgrade -r LIFEsim/requirements.txt

Important

LIFEsim need a modified version of the package SpectRes to run. Please install it via the following procedure.

First, make sure that you are in the directory where you want to install SpectRes. Then run

$ git clone https://github.com/fdannert/SpectRes.git

The last step is point the Python install of your virtual environment to LIFEsim and SpectRes. Please do so by running

$ echo "export PYTHONPATH='$PYTHONPATH:/path_to_LIFEsim/LIFEsim/:/path_to_SpectRes/SpectRes/'" >> path_to_new_folder/new_folder/bin/activate

Testing the Installation

To test the installation, open a new console and activate the virtual environment as above. Then open Python and import LIFEsim with

$ python
>>> import lifesim

If the import statement executes, the installation has been successful. As an extra test run

>>> lifesim.util.constants.c
299792000.0

This should return the speed of light in [m s \(^{-1}\) ].

Hint

If the import lifesim command fails, the reason is likely that the the PYTHONPATH is not set correctly. To check for this please run in Python (started with the virtual environment active as above)

>>> import sys
>>> sys.path

If the path to LIFEsim '/path_to_LIFEsim/LIFEsim/' is not returned in the results, please open the file path_to_new_folder/new_folder/bin/activate with a text editor of your choice. Then make sure that the last line of the file reads

  export PYTHONPATH=':/path_to_LIFEsim/LIFEsim/'

The same test can be performed if SpectRes does not import.

Installation (Windows)

Download Conda

Hint

This step can be skipped if a python distribution and package manager is already installed.

First, a python distribution and package manager is required. For windows, we suggest Miniconda, a lightweight variant of the popular Anaconda distribution. To install Miniconda, follow the installation instructions.

Virtual Environment

It is highly recommended to install LIFEsim in a virtual environment. This ensures installed packages and changes made do not affect other projects on a system. The steps of creating a virtual environment with conda are described in the following.

First, open the Conda Prompt, navigate to where you want to create the virtual environment and type

> conda create --name new_folder python=3.8

Note that we specify the required python version in this command. Some conda commands will ask for confirmation, which can be affirmed by typing.

Proceed ([y]/n)?
> y

A virtual environment in the folder new_folder is created in the current directory

Hint

You might need to deactivate the conda base

> conda deactivate

To activate and deactivate your new virtual environment use the following commands respectively

> conda activate new_folder\

Check the python version with the following command

> python --version
> conda deactivate

Download from Github

Navigate to the directory in which you desire to place the LIFEsim repository. Then clone the repository from Github by executing

> git clone https://github.com/fdannert/LIFEsim.git

Hint

If git is not installed on your system run

> conda install git

The dependencies required by LIFEsim can be installed with

> conda install --file requirements.txt

Important

LIFEsim need a modified version of the package SpectRes to run. Please install it via the following procedure.

First, make sure that you are in the directory where you want to install SpectRes. Then run

> git clone https://github.com/fdannert/SpectRes.git

The last step is point the Python install of your virtual environment to LIFEsim and SpectRes. To do so, please navigate to site-packages folder of your virtual environment, most likely located in `` C:Usersuser_nameminiconda3envsnew_folderLibsite-packages``. In this directory, create the file lifesim.pth containing the paths to LIFEsim and SpectRes separated by a new line

C:\path_to_LIFEsim\LIFEsim\
C:\path_to_SpectRes\SpectRes\

Testing the Installation

To test the installation, open a new conda prompt and activate the virtual environment as above. Then open Python and import LIFEsim with

> python
>>> import lifesim

If the import statement executes, the installation has been successful. As an extra test run

>>> lifesim.util.constants.c
299792000.0

This should return the speed of light in [m s \(^{-1}\) ].

Hint

If the import lifesim command fails, the reason is likely that the the PYTHONPATH is not set correctly. To check for this please run in Python (started with the virtual environment active as above)

>>> import sys
>>> sys.path

If the path to LIFEsim 'C:\path_to_LIFEsim\LIFEsim\' is not returned this is likely the source of the issue.

The same test can be performed if SpectRes does not import.

First Examples

The following examples will explore the current two main functionalities of LIFEsim: The simulation of single exoplanets with a given spectrum and the simulation of the LIFE search phase on a catalog of a simulated exoplanets populated.

Using the GUI

The following is a minimal working example of simulating a spectral observation of an exoplanet with the LIFEsim GUI.

As a first step, activate the virtual environment containing the LIFEsim install with

$ source path_to_new_folder/new_folder/bin/activate

Open python

$ python

Then, open the LIFEsim spectrum simulator GUI by running

>>> from lifesim import Gui
>>> Gui()

With executing this command, the following GUI will open

_images/GUI_example.png

Notice the three tabs for setting the instrument options, importing and previewing the spectrum and displaying the results. In the Settings tab, the required parameters for the target star and planet can be set manually. The parameters for the instrument can either be set manually or by pressing on a scenario button on the left side (e.g. Optimistic). This then automatically sets the instruments parameters to correspond with what the LIFE team currently views as an optimistic, baseline or pessimistic scenario.

For importing a spectrum, navigate to the Preview tab.

_images/GUI_example_spectrum.png

Begin by choosing a spectrum to import (in .txt format) by clicking on Browse…. To complete this example, please download this file from the LIFEsim GitHub and open it in the pop-up dialog. Leave the option as absolute to only use the imported spectrum. Setting the option to additive will add the imported spectrum to the planets black body spectrum calculated according to given parameters.

Hint

A pure black body planet can be simulated by choosing the additive option and leaving the file dialog empty.

_images/GUI_example_blackbody.png

To specify the units of the spectrum you are importing, enter them in the fields x-axis units and y-axis units. For this example, please set x-axis units to micron and y-axis units to photon micron-1 s-1 m-2 sr-1.

In the Spectrum Parameter field the parameters used during the creation of the spectrum need to be given. Again, for the example please set Distance to 10pc, Planet Radius to 1 Earth Radius and leave Integration Time at 0.

Pressing Preview Spectrum will now show the spectrum in the units specified by the user. This can be used to check the correct import of the spectrum.

_images/GUI_example_import.png

Changing the drop-down menu to converted units will show the spectrum in the units used in LIFEsim. This completes setting up the simulator for a run.

Change to the Results tab and press Run Simulation on the very left. This will run the simulation and the display the results as shown below.

_images/GUI_example_result.png

Above the Run Simulation button you can change the Integration Time of the simulation and select or deselect the inclusion of specific noise sources in the simulation.

At the bottom of the Results tab you can choose a location to save the results at by clicking on Browse… and then save the results by clicking Save.

Simulating the Search Phase

LIFEsim is capable of taking an artificial exoplanet catalog input from P-Pop, calculate the signal-to-noise ratio for each planet and distribute the observation time available in the search phase to observe and detect an optimal number of exoplanets.

Hint

The following example mirrors the file LIFEsim/lifesim_demo.py.

Set-Up

To run such a simulation, create a new python file. First, LIFEsim needs to imported

3import lifesim

LIFEsim is programmed such that all data and parameters are saved in a single location, which then distributes those to the relevant modules. Create an instance of this so-called bus

8bus = lifesim.Bus()

The bus holds all parameters needed for the simulation (e.g. the collector aperture diameter, the duration of the search phase, etc.). They can all be set at the same time by using scenarios predefined by the LIFE team. These scenarios are the ‘baseline’ case, where the array configuration is as expected, as well as the ‘optimistic’ and ‘pessimistic’ case, where the array is set up in a more or less capable way. Set the parameters to the baseline case by running

11bus.data.options.set_scenario('baseline')

Note, that options can also be set manually. For example, the collector aperture diameter can be manually increased to four meters by

14bus.data.options.set_manual(diameter=4.)

A list of all available options and parameters can be found in the API Documentation for lifesim.util.options.

Downloading the Catalog

A example synthetic planet population based on statistics from the Kepler mission can be downloaded from the P-Pop github page with the following code. Make sure to replace the path with your local project folder.

18data = requests.get('https://raw.githubusercontent.com/kammerje/P-pop/main/TestPlanetPopulation.txt')
19
20with open('path/ppop_catalog.txt', 'wb') as file:
21    file.write(data.content)

Loading the Catalog

Now, the P-Pop catalog can be loaded in. An example catalog can be found in LIFEsim/docs/_static. Run

25bus.data.catalog_from_ppop(input_path='path/ppop_catalog.txt')

Important

The given P-Pop catalog populates known stars in the solar neighborhood of up to 20 pc with artificial planets based on the Kepler statistics. This population is done not only once, but in a Monte Carlo approach 500 different universes are simulated. This needs to be kept in mind when the results are interpreted.

With the catalog loaded into LIFEsim, some selections of stars can be removed. The following will remove all A-type stars and every M-type at a distance larger than 10 pc away from earth.

26bus.data.catalog_remove_distance(stype=0, mode='larger', dist=0.)
27bus.data.catalog_remove_distance(stype=4, mode='larger', dist=10.)

Hint

LIFEsim uses the following numeric integer keys for stellar types:

0 = A, 1 = F, 2 = G, 3 = K, 4 = M.

With this, the setup for the simulation is complete.

Creating the Instrument

Now, an instance of the LIFEsim instrument module needs to be created.

33instrument = lifesim.Instrument(name='inst')

To give any module access to the data and parameters used in a simulation, it needs to be connected to the bus.

34bus.add_module(instrument)

Next, all modules needed for the instrument module to run need to be created. A list of the required modules can be found in the API Documentation of lifesim.instrument.instrument. First, create the module responsible for simulating transmission maps of a four-arm nulling interferometer and add it to the bus.

36transm = lifesim.TransmissionMap(name='transm')
37bus.add_module(transm)

Next, create the modules for the simulation of the astrophysical noise sources and add them to the bus.

39exozodi = lifesim.PhotonNoiseExozodi(name='exo')
40bus.add_module(exozodi)
41localzodi = lifesim.PhotonNoiseLocalzodi(name='local')
42bus.add_module(localzodi)
43star_leak = lifesim.PhotonNoiseStar(name='star')
44bus.add_module(star_leak)

Now, the instrument needs to be told to which modules it should connect to. Do so by running

47bus.connect(('inst', 'transm'))
48bus.connect(('inst', 'exo'))
49bus.connect(('inst', 'local'))
50bus.connect(('inst', 'star'))
51
52bus.connect(('star', 'transm'))

Note, that not all noise sources need to be connected in order for the instrument simulation to run. If required, individual noise sources can be disconnected by running

>>> bus.disconnect(('inst', 'exo'))

Creating the Optimizer

The optimizer is responsible for distributing the available observing time onto the individual stars. Analogously to above, run

59opt = lifesim.Optimizer(name='opt')
60bus.add_module(opt)
61ahgs = lifesim.AhgsModule(name='ahgs')
62bus.add_module(ahgs)
63
64bus.connect(('transm', 'opt'))
65bus.connect(('inst', 'opt'))
66bus.connect(('opt', 'ahgs'))

Running the Simulation

First, the signal-to-noise ratio needs to be calculated for every planet in the catalog. To do so, run

73instrument.get_snr()

This function will assign every planet the SNR after one hour of observation. Since the simulation is entirely contained in the radom noise case, the SNR scales with square-root of the integration time. Therefore, the SNR for any integration time can be calculated by knowing the SNR of a specific integration time.

Note

It is not unusual for instrument.get_snr() to take up to an hour to complete.

Knowing the SNR for each planet, the integration time can be optimally distributed by

75opt.ahgs()

In the baseline case, the observation time is distributed such that the number of planets in the habitable zone around their respective host stars is optimized. The optimization can be changed to respect all planets by setting

>>> bus.data.options.optimization['habitable'] = True

Check the API Documentation for lifesim.util.options to see all parameters used in the optimization process.

Saving the Results

After a simulation run, the results can be saved as a hdf5 file for later analysis by using

79bus.data.export_catalog(output_path='path/filename.hdf5')

Reading the Results

A previously saved simulation can be read into LIFEsim by running

84bus_read = lifesim.Bus()
85bus_read.data.options.set_scenario('baseline')
86bus_read.data.import_catalog(input_path='path/filename.hdf5')

Interpreting Results

All results are saved in the catalog located at bus.data.catalog. This pandas data frame contains rows representing the individual artificial exoplanets. The meaning of most columns can be found in the file LIFEsim/lifesim/core/data.py. The most important columns are listed in the following:

  • 'nuniverse' : The index for the universe the planet is located in. See ‘Important’ box above for further explanation.

  • 'nstar' : The unique index for the star.

  • 'habitable' : Is True if the planet resides in the habitable zone of its host star.

  • 'snr_1h' : The signal-to-noise ration the planet would have after one hour of integration time.

  • 'detected': Is True if the planet is observed long enough to have an SNR larger than bus.data.option.optimization[‘snr_target’]. In this case, the planet is counted towards the planets detected in the search phase.

  • 'int_time': The amount of integration time spend on the system in [s].

Interpretation of this catalog is easily facilitated by the usage of selection masks. For example, the number of detected exoplanets in the habitable zone around M-type stars would be retrieved via

>>> import numpy as np
>>> mask_mtype = bus.data.catalog.stype == 4
>>> mask = np.logical_and.reduce((bus.data.catalog.detected, bus.data.catalog.habitable, mask_mtype))
>>> result_number = mask.sum()/500

Note the division by 500 to factor out the 500 simulated universes.

Architecture

Introduction

This section is meant to function as a starting point for anyone interested in contributing to LIFEsim or understanding the underlying programming ideas behind the package. First, the core of the package is described in some detail. This is then followed up by an example on how to program a new LIFEsim module.

General Structure

Apart from the functional goals, the core of LIFEsim is programmed to achieve two major goals:

  1. LIFEsim must be easy to use for users unfamiliar with programming and for programmers unfamiliar with the code

  2. LIFEsim must be easy to extend.

The implicit aim of goal (1.) is that all members of the LIFE team, largely independent from their background and level of knowledge, should be able to run a LIFEsim simulation. The implicit aim of goal (2.) is that a student can contribute to LIFEsim in the scope of an ETH semester project.

_images/UML_lifesim.png

The diagram above outlines the general core architecture of LIFEsim.

The Bus

The Bus class is the main interface between the user and a LIFEsim simulation. Hence, it is considered to be part of the LIFEsim front-end. All modules taking part in the simulation are aggregated by the Bus. Via the Bus, the user is able to connect modules via their sockets. Furthermore, the Bus holds a single Data class by composition and forwards it to any modules connected to the bus. This makes sure that there are no conflicting instances of the Data class in a single simulation.

Modules

The underlying idea behind the Module class is that every physical, (partially) self-contained model is written into its own Module. This simplifies the program layout and makes it easier to understand on an abstract level. If a new physical model is to be added to LIFEsim, the programmer should create an abstract class inheriting from the Module class. Then, the programmer should identify all functions that the new module should fulfill. These functions are implemented as a stub abstract method, forcing any inheriting modules to implement the respective functionalities. Note here, that on this level the modules should not contain any functional code, but are rather filled with placeholder pass statements.

The Data Class

All data, parameters and options for LIFEsim are contained in the Data and Options classes. Located in the Data class is a catalog containing all target stars and exoplanets and additionally allocated space to save variables needed in the respectively used modules. The catalog can be directly imported from P-Pop.

The Options class saves parameters in dictionaries split after which part of the simulations the parameters concern. The parameters can be set according to existing baseline, optimistic and pessimistic scenarios for a future realization of the LIFE mission. A list of all options and the scenarios can be found in the tables at the bottom of the page. The Options class is connected to the Data class by composition, making sure that only a single instance of options can exist in any given simulation.

Sockets

The method of using sockets is implemented as a tool for interface management between the modules. This allows for independent implementation and re-implementation of modules. The the following is a description of the sockets functionality and how they should be used.

Each Module has an attributed dictionary called sockets. The elements of this dictionary is accessed by a string key, which doubles as the name of the socket. If Module P (see picture below) is to be connected to Module A, the following set-up needs to be done.

_images/socket_structure.png

An entry in the sockets dictionary under a unique socket name s_name is created (e.g. s_name = 'connection_a'). This element contains itself another dictionary specifying

  • the type of module the socket should accept.

  • the number of modules that can be connected to this socket.

  • a (currently empty) list tracking which modules are connected to the socket.

The set-up of the socket is now complete. Connecting the socket is done via the bus as follows

1bus = lifesim.Bus()
2
3mod_p = lifesim.Module_P(name='module_p')
4bus.add_module(mod_p)
5
6mod_a = lifesim.Module_A(name='module_a')
7bus.add_module(mod_a)
8
9bus.connect(('module_p', 'module_a'))

The command in Line 9 searches all sockets of the instance of Module P if they accept connection from an instance of Module A, and connects them if suitable socket is found. The same is done vice-versa, meaning that all Module A sockets are search for connections to Module P.

Now, module_a is connected to the socket connection_a of module_p. It can therefore be accessed in module_p by calling self.sockets['connection_a']['modules'][0].

List of Parameters

_images/parameters_lifesim_1.png _images/parameters_lifesim_2.png _images/parameters_lifesim_3.png

Contributing to LIFEsim

LIFEsim is a community project lead by the LIFE Collaboration. Any contribution to LIFEsim is much encourage and highly appreciated.

We ask that contributions follow the PEP 8 python style guide.

lifesim.core package

Submodules

lifesim.core.core module

lifesim.core.data module

lifesim.core.modules module

lifesim.instrument package

Submodules

lifesim.instrument.instrument module

lifesim.instrument.pn_star module

lifesim.instrument.pn_localzodi module

lifesim.instrument.pn_exozodi module

lifesim.instrument.transmission module

lifesim.util package

Submodules

lifesim.util.options module

lifesim.util.radiation module

lifesim.util.habitable module

lifesim.util.constants module