Introduction to Astropy

Marco Fumana @ INAF-IASF Milano

Astropy

The astropy package contains key functionality and common tools needed by astronomers who work with Python. It is the core of the Astropy Project, which aims to enable the community to develop a robust ecosystem of Affiliated Packages covering a broad range of needs for astronomical research, data processing, and data analysis.

In this course we will provide an introduction to Astropy and its main packages:

  • NumPy Base N-dimensional array package
  • scipy Fundamental library for scientific computing
  • matplotlib Comprehensive 2D Plotting library

reproject package out the Astropy core project for images resampling

Warnings

  • We will not have a detailed explanation of astropy and all its packages (not enough time)
  • My idea is just to touch on a few topics here and there. I would like to show you the existence of tools/libraries that might be useful for you.

  • I don't want to convince you that Python is the best choice to explore data interactively. But for sure, Python is one of the simplest and most intuitive languages to automate repetitive operations, and create smart programs useful for your science

Disclaimers

  • The course is based on examples. I have done my best to create real astronomical examples, but simplifications and approximations in the examples are necessary, given the purpose of this course.

  • I'm not an astronomer, please focus on example methodologies and ignore possible errors with regard to Astronomy.

Overview

  • Part 1

    • Introduction
    • Handle multi extension FITS files
    • (Header manipulation)
  • Part 2 Astropy by examples

    • Images and Numpy
    • Catalogs
    • $\gamma$ ray spectrum visualization and fitting
    • Images manipulation
    • Wavelength calibration and fitting
  • Part 3 (bonus?)

    • Debug and code reusing

Introduction

First of all, we will see:

  • Python3 basic concepts
  • The IPython shell
  • Project Jupyter and JupyterLab

Keys: Python, IPython, object oriented, jupyter lab

Python3

  • Python is an interpreted language)

    • gcc -o prova prova.c

    • python prova.py

  • The interpreter is available for many OS

  • interactive shell

$ python3
In [ ]:
 

IPython3

  • IPython is a powerful interactive shell
  • Tab completition
  • history
  • magic commands: % prefix (e.g. %matplotlib qt, ...)
  • shell commands: ! prefix
  • ...
$ ipython3
In [ ]:
 

Jupyter lab

JupyterLab is the next-generation web-based user interface for Project Jupyter

$ jupyter lab

...back to the language

Python is dynamically typed

/* C syntax: a is declared and then assigned */
int a=7;
In [55]:
a=7
type(a)
Out[55]:
int
In [ ]:
 

One can assigne to a variable a value of one type and then later re-assigne a value of a different type

In [56]:
#Type is defined by the value assigned
a=7*2.7
type(a)
Out[56]:
float
In [ ]:
 

automatic memory management

Python is garbage-collected) (no malloc/alloc required)

In [57]:
#Create a list without defining the size
a=[1,2,3]
type(a)
Out[57]:
list
In [ ]:
 
In [58]:
# Increase the size of the object
a+=[4,5]
a
Out[58]:
[1, 2, 3, 4, 5]
In [ ]:
 

Code blocks

Python uses whitespace indentation, rather than curly brackets or keywords, to delimit blocks.

Spaces are the preferred indentation method (see PEP8). Python 3 disallows mixing the use of tabs and spaces for indentation.

int k=0;
while (k<10){
    k+=1;
    printf("%d ", k);
    if (k>3){
        break;
    }
}
In [59]:
k = 0
while k<10:
    k+=1
    print(k, end=" ")
    if k>3:
        break
1 2 3 4 

Defining functions

The def keyword is used to define functions. White spaces are used to define function blocks, exactly like other blocks.

In [60]:
def sgn(x):
    if x > 0.0:
        return 1.0
    elif x < 0.0:
        return -1.0
    else:
        raise Exception("No sign defined")
In [ ]:
 

Objects - Classes - Instances

We can see an object like a data structure with properties (attributes) and functions which operate on it (methods).

This isn't a definition of what object in Computer Science is, but in my opinion this is a good starting point.

A class is a blueprint or template to build a specific type of object. Every object is built from a class Class provides initial values for state (member variables or attributes) and implementations of behavior (member functions or methods)

An instance is a specific object built from a specific class

In [61]:
#Instance of complex number
c=7.0+3j
type(c)
Out[61]:
complex
In [62]:
#Another instance of complex number
d=2.0-1j
type(d)
Out[62]:
complex
In [ ]:
 

Attributes and methods

attribute of d (a property of...)

In [63]:
d.real, d.imag
Out[63]:
(2.0, -1.0)
In [ ]:
 

method of d

In [64]:
d.conjugate()
Out[64]:
(2+1j)
In [ ]:
 

The dir function

dir() is a builtin function, which returns list of the attributes and methods of any object

In [65]:
%pprint
dir(c)
Pretty printing has been turned OFF
Out[65]:
['__abs__', '__add__', '__bool__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__int__', '__le__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__pos__', '__pow__', '__radd__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmod__', '__rmul__', '__rpow__', '__rsub__', '__rtruediv__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', 'conjugate', 'imag', 'real']
In [ ]:
 
In [66]:
dir()
Out[66]:
['In', 'Out', '_', '_1', '_10', '_11', '_12', '_13', '_16', '_17', '_18', '_2', '_21', '_22', '_23', '_24', '_27', '_28', '_29', '_3', '_30', '_31', '_32', '_33', '_36', '_37', '_38', '_4', '_41', '_42', '_43', '_44', '_45', '_46', '_49', '_50', '_51', '_52', '_53', '_54', '_55', '_56', '_57', '_58', '_61', '_62', '_63', '_64', '_65', '_7', '_8', '_9', '__', '___', '__builtin__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '_dh', '_i', '_i1', '_i10', '_i11', '_i12', '_i13', '_i14', '_i15', '_i16', '_i17', '_i18', '_i19', '_i2', '_i20', '_i21', '_i22', '_i23', '_i24', '_i25', '_i26', '_i27', '_i28', '_i29', '_i3', '_i30', '_i31', '_i32', '_i33', '_i34', '_i35', '_i36', '_i37', '_i38', '_i39', '_i4', '_i40', '_i41', '_i42', '_i43', '_i44', '_i45', '_i46', '_i47', '_i48', '_i49', '_i5', '_i50', '_i51', '_i52', '_i53', '_i54', '_i55', '_i56', '_i57', '_i58', '_i59', '_i6', '_i60', '_i61', '_i62', '_i63', '_i64', '_i65', '_i66', '_i7', '_i8', '_i9', '_ih', '_ii', '_iii', '_oh', 'a', 'b', 'c', 'd', 'decrease_first', 'exit', 'get_ipython', 'k', 'quit', 'sgn']
In [ ]:
 

Every item in a Python program is an object

Every item in a Python program is an object of a specific class

In [67]:
a=7
a.bit_length()
Out[67]:
3
In [ ]:
 

Variables

A variable is symbolic name that is a reference or a pointer to an object

In [68]:
a = [1,2,3,4]

I'm creating the list object [1,2,3,4] in memory and a is pointing to this object somewhere in memory

The b object is pointing to the same object

In [69]:
b = a

b is a reference to a. NOT a copy.

If b changes... a changes!

In [70]:
b[1]=0.0
b
Out[70]:
[1, 0.0, 3, 4]
In [ ]:
 

Basically, a and b are the same object

In [71]:
a is b
Out[71]:
True
In [ ]:
 

They have the same ID

In [72]:
id(a), id(b)
Out[72]:
(139767957787400, 139767957787400)
In [ ]:
 

Still references

Objects to functions are passed by reference as well

In [73]:
def decrease_first(l):
    l[0]-=10
    print("Value of l (inside function)", l)
In [74]:
a=[1,2,3]
decrease_first(a)
print("Value of a", a)
Value of l (inside function) [-9, 2, 3]
Value of a [-9, 2, 3]
In [ ]:
 

Variable names

Python has a set of built in functions and types. To avoid name conflics do not use built-in functions, or types as variable names

int is a built in function

In [ ]:
int(3.7)

a variable named int

In [ ]:
int=4

the int function is no more available

In [ ]:
int(3.7) # Raise an error!
In [ ]:
del int # restore the proper behavior