Simple “hello world” example¶
This is a simple “hello world”-style simulation and imaging example
to show basic usage of the main OSKAR Python classes. It can be run
interactively from either an ipython
prompt or a Jupyter notebook,
or as a complete Python script (which is given at the bottom of the page).
Note
This example uses the telescope model from the OSKAR example data, so make sure this is unpacked into the directory from which this script is run.
We require the matplotlib
, numpy
and oskar
Python modules.
The sky model will be created from a numpy array, and we will use
matplotlib to render the output image as a PNG file.
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy
import oskar
First we set up a oskar.SettingsTree
from a Python dictionary.
Note that not all settings are defined at this stage.
As the sky model will be very small for this example, we choose not to
use GPUs here, hence simulator/use_gpus
is set to false
.
params = {
"simulator": {
"use_gpus": False
},
"observation" : {
"num_channels": 3,
"start_frequency_hz": 100e6,
"frequency_inc_hz": 20e6,
"phase_centre_ra_deg": 20,
"phase_centre_dec_deg": -30,
"num_time_steps": 24,
"start_time_utc": "01-01-2000 12:00:00.000",
"length": "12:00:00.000"
},
"telescope": {
"input_directory": "telescope.tm"
},
"interferometer": {
"oskar_vis_filename": "example.vis",
"ms_filename": "",
"channel_bandwidth_hz": 1e6,
"time_average_sec": 10
}
}
settings = oskar.SettingsTree("oskar_sim_interferometer")
settings.from_dict(params)
We choose the numerical precision to use (single
or double
) when
running the simulation, and update one of the settings accordingly.
precision = "single"
if precision == "single":
settings["simulator/double_precision"] = False
The sky model will contain only three sources, which are stored in a
numpy array. The sky model is created with the appropriate precision
using oskar.Sky.from_array()
.
sky_data = numpy.array([
[20.0, -30.0, 1, 0, 0, 0, 100.0e6, -0.7, 0.0, 0, 0, 0],
[20.0, -30.5, 3, 2, 2, 0, 100.0e6, -0.7, 0.0, 600, 50, 45],
[20.5, -30.5, 3, 0, 0, 2, 100.0e6, -0.7, 0.0, 700, 10, -10]])
sky = oskar.Sky.from_array(sky_data, precision) # Pass precision here.
Next, we create the oskar.Interferometer
simulator, set the sky model
and run the simulation to generate visibilities.
Visibility data will be saved to a binary data file named example.vis
.
(To save it in the CASA Measurement Set format, specify a value for
the interferometer/ms_filename
parameter in the settings tree.)
sim = oskar.Interferometer(settings=settings)
sim.set_sky_model(sky)
sim.run()
The simulated visibilities can now be imaged using oskar.Imager
.
This example uses the set()
method to set
multiple properties using the same call. This image will only be 512 pixels
across and will have a field of view of 4 degrees.
A FITS file named example_I.fits
will also be written.
The image is returned to Python and can be accessed from the dictionary
of arrays returned by oskar.Imager.run()
.
imager = oskar.Imager(precision)
imager.set(fov_deg=4, image_size=512)
imager.set(input_file="example.vis", output_root="example")
output = imager.run(return_images=1)
image = output["images"][0]
Finally, the image is plotted using matplotlib and saved as a PNG file
called example.png
, which is included below.
im = plt.imshow(image, cmap="jet")
plt.gca().invert_yaxis()
plt.colorbar(im)
plt.savefig("%s.png" % imager.output_root)
plt.close("all")
For completeness, the whole script is available here
(hello-world.py
):
#!/usr/bin/env python3
"""Script to run a simple test example of an OSKAR simulation."""
import matplotlib
matplotlib.use("Agg")
# pylint: disable=wrong-import-position
import matplotlib.pyplot as plt
import numpy
import oskar
# Basic settings. (Note that the sky model is set up later.)
params = {
"simulator": {
"use_gpus": False
},
"observation" : {
"num_channels": 3,
"start_frequency_hz": 100e6,
"frequency_inc_hz": 20e6,
"phase_centre_ra_deg": 20,
"phase_centre_dec_deg": -30,
"num_time_steps": 24,
"start_time_utc": "01-01-2000 12:00:00.000",
"length": "12:00:00.000"
},
"telescope": {
"input_directory": "telescope.tm"
},
"interferometer": {
"oskar_vis_filename": "example.vis",
"ms_filename": "",
"channel_bandwidth_hz": 1e6,
"time_average_sec": 10
}
}
settings = oskar.SettingsTree("oskar_sim_interferometer")
settings.from_dict(params)
# Set the numerical precision to use.
precision = "single"
if precision == "single":
settings["simulator/double_precision"] = False
# Create a sky model containing three sources from a numpy array.
sky_data = numpy.array([
[20.0, -30.0, 1, 0, 0, 0, 100.0e6, -0.7, 0.0, 0, 0, 0],
[20.0, -30.5, 3, 2, 2, 0, 100.0e6, -0.7, 0.0, 600, 50, 45],
[20.5, -30.5, 3, 0, 0, 2, 100.0e6, -0.7, 0.0, 700, 10, -10]])
sky = oskar.Sky.from_array(sky_data, precision) # Pass precision here.
# Set the sky model and run the simulation.
sim = oskar.Interferometer(settings=settings)
sim.set_sky_model(sky)
sim.run()
# Make an image 4 degrees across and return it to Python.
# (It will also be saved with the filename "example_I.fits".)
imager = oskar.Imager(precision)
imager.set(fov_deg=4, image_size=512)
imager.set(input_file="example.vis", output_root="example")
output = imager.run(return_images=1)
image = output["images"][0]
# Render the image using matplotlib and save it as a PNG file.
im = plt.imshow(image, cmap="jet")
plt.gca().invert_yaxis()
plt.colorbar(im)
plt.savefig("%s.png" % imager.output_root)
plt.close("all")