Read an image
Contents
Read an image#
Reminder
Start the exercise with the Python template file in the
src
directory corresponding to the exercise.
Your code must be added to the
main
function.If you write generic functions, put them into libraries to reuse them easily in other applications. Look at Library and Module documentation for more details on Python libraries.
You should carefully follow the division in steps proposed for every exercise and provide specific signatures for each step when this is specified.
Git operations:
Commit very frequently with relevant message. Focus on making clear the reasons why you made the change.
Push once a significant result is obtained.
Code quality:
Check frequently the PyCharm annotations about your code, for example the colored signals in the right vertical gutter.
Execute the
check_commit_status.py
script to check the validation tests.Assess the quality of your code with SonarQube.
Documentation:
Add docstrings (
""" ... """
) at begining of ALL functions & classes.Add one-line comments wherever this is useful to understand your code.
Refer to slides for detailed information on technical topics.
General goal#
This first exercise is about reading an image from a FITS file, with the help of the
the astropy.io.fits
module, and displaying the image with the help of
the pyplot library.
Your data
directory contains those images:
common.fits
: an image common to all students. It is provided to help you to check your developments. For each exercice, you will be given the exact output that your program should produce, when applied tocommon.fits
.
specific.fits
: an image different for each student. For each exercice, you can apply your program to your imagespecific.fits
, and check if it is running fine, but you will not know what is the expected output. Each time you push your code to the reference repository, the continuous integration system will apply your programs to yourspecific.fits
, and the signatures will be compared to the secret exected ones, so to check that your code is doing the right thing. So to see the final diagnostic of the continuous integration, executecheck_commit_status.py
.
global.fits
: the global image of the Bode’s galaxy. It covers a much larger region of the sky than the previous images: in fact,common.fits
and thespecific.fits
of each student pair are a subset of this global image. You can use it as a third image, with different characteristics, to check that your programs are working correctly.
It is very usual, in the astronomical community, to format the file following the FITS
conventions.
A FITS
file contains a sequence of data blocks, and each data block is made of two sections : the
data and the meta-data. Such meta-data contains information about the conditions of the data
acquisition (when, where, sky region, etc…).
Before starting the exercise below, you may want to review Fits slides for more details on FITS format, and the Pyplot slides for information about the construction of a graphic user interface with the PyPlot library.
Application description#
Following the instructions below, you will create a simple application to read
a FITS image file and print some metadata from it.
This must be implemented in a file called ex1_read_image.py
.
Initial application#
As you can see, an initial file ex1_read_image.py
is provided. It is importing
our module npac/args
, whose function get_file_name()
will help you
manage the name of the file to be processed.
This function looks if a file name was provided when the application has been invoked,
on the command line. If there is such an argument, it is expected to be the name
of the file image file to process. If the .fits
extension was not present, it is automatically
added. If no file name is provided on the command line, the function ask one interactively to the user. If the
user types directly return
, the default common.fits
will be used. Also, all those files are searched by
get_file_name()
in the relevant directories, especially your data
subdirectory.
Run this application several times, with or without command-line arguments, with different
files names, with or without the unix path, with or without the .fits
extension : get used
to the way get_file_name()
is working.
Reading the image#
So to extract information from the FITS file, you can rely on the astropy.io.fits
module.
Thus you need to import the module as follows:
from astropy.io import fits
The astropy.io.fits.open()
function allows to open the file. The recommended
and safest way to open a file in Python is to use a with
statement which will take
care of closing the file for you, even if something goes wrong during the operation:
with fits.open(path_to_file) as fits_blocks: block = fits_blocks[0] ...
The dedicated open
function of the astropy.io.fits
module directly returns
a collection of data blocks, which is called fits_blocks
above. Only the first
data block, fits_blocks[0]
, is useful in this course.
Each data block is an object with two members:
header
(the metadata)
data
(the image pixels)
Signature#
This application is expected to print some results on the terminal. This is what we call the exercise signature. For the current exercise, it is made of CRPIX1, CRPIX2 elements from the image header. They represent the coordinate system reference pixel for the image. It is needed to convert any pixel position into a sky coordinate. Each image, representing a different portion of the sky, has a specific reference pixel.
To retrieve those values from the FITS first block header, use the header as if it was a python dictionary,
and retrieve the fields associated with the keys CRPIX1
and CRPIX2
. Then, print them on the terminal,
one line each, using the following format :
signature_fmt_1 = 'RESULT: CRPIX1 = {:.0f}' signature_fmt_2 = 'RESULT: CRPIX2 = {:.0f}'
When running your program with the common image common.fits
, the expected signature is:
RESULT: CRPIX1 = 719 RESULT: CRPIX2 = 755
Handle properly a non existing file#
In Python, errors are often handled using exceptions: this avoid to have a lot
of if
statements in the code to do the error handling, which make the code harder to maintain.
An introduction to exceptions handling is available in the Python Errors Notebook.
An example of exception is FileNotFoundError
which is raised (that means which happens) if you try to open
a non existing file. In the context of our application, this exception will be raised if you mispelled the file name.
You can try to do it and you will see that the program exits in such circumstances.
Try to handle this exception, following the instructions in the exception introduction mentioned above, to either give an explicit message to the user before exiting or, better, to give him a chance to reenter the file name.
To exit the application, use:
exit()
Graphic application#
You are now asked to write a graphic application, within the file display.py
.
Refer to the graphics explanations and to the
Pyplot slides for details on how to use matplotlib.pyplot
.
Reuse previous code#
You must first reuse the code from the previous step, which you will place in a
dedicated module called lib_fits.py
, following the recommended conventions.
We ask you to rewrite both display.py
and ex1_read_image.py
, so that they both
rely on the new shared module lib_fits.py
, this way:
import lib_fits # read_first_image should return 2 values: # - header (metadata of the first block) # - pixels (data of the first block) header, pixels = lib_fits.read_first_image(file_name)
Display the image#
After loading the image, the application display.py
must display it,
with the help of the module matplotlib.pyplot
. You need this kind of import:
import matplotlib.pyplot as plt
The as
keyword creates a short name alias for the module that will be used to refer to its functions,
instead of the full name matplotlib.pyplot
.
Thus, the main actions involved here are:
# Create the graphic context # Returns a reference to the drawing region (fig) and an axes where the image will be drawn fig, axes = plt.subplots() # Send the image into the default display # pixels from FITS file have the appropriate type and can be used directly imgplot = axes.imshow(pixels) # Launch the interactive session (open the window an draw what has been put into the image plt.show()
You should get a window like this one:
Warning
The graphical window with the plot display may be hidden behind the PyCharm window. You can see it using F3 key. You have to move aside the PyCharm window to see your plot and shift it next the PyCharm window!