# Python Boot Camp¶

Lecturer: Leo Singer
Jupyter Notebook Author: Leo Singer & Cameron Hummels

This is a Jupyter notebook lesson taken from the GROWTH Winter School 2018. For other lessons and their accompanying lectures, please see: http://growth.caltech.edu/growth-astro-school-2018-resources.html

## Objective¶

Introduce the user to basic usage of Python. Includes some basic analysis of photometric data using astropy.

## Key steps¶

• Variable manipulation
• Lists, arrays, floats, ints, sets, dictionaries
• Conditionals, loops
• Error handling
• Intro to numpy
• Intro to astropy

## Required dependencies¶

See GROWTH school webpage for detailed instructions on how to install these modules and packages. Nominally, you should be able to install the python modules with pip install <module>. The external astromatic packages are easiest installed using package managers (e.g., rpm, apt-get).

• python 3
• astropy
• numpy
• matplotlib

None

## I. Introduction¶

This workshop is about doing astronomical data analysis with the Python programming language. No previous experience with Python is necessary!

Python is a powerful tool, but it comes into its own as a numerical and data analysis environment with the following packages, which you will definitely want to have:

• Matplotlib: plotting interactive or publication-quality figures
• Numpy: vectorized arithmetic and linear algebra
• Scipy: curated collection of algorithms for root finding, interpolation, integration, signal processing, statistics, linear algebra, and much more
• Jupyter Notebook (formerly IPython Notebook): the Mathematica-like interface that you are using now, and last but not least
• Astropy: a community library for astronomy.

We'll cover the basics of Python itself and then dive in to some applications to explore each of these packages.

NOTE: The purest way of interacting with Python is via its command line interpreter, which looks like this:

A relatively new but very powerful way of using Python is through the Jupyter Notebook interface, which like Mathematica allows you to intermingle computer code with generated plots. You're using one now.

In [1]:
from matplotlib import pyplot as plt
import numpy as np
%matplotlib inline

x = np.linspace(0, 2 * np.pi)
plt.plot(x, np.sin(x))
plt.xlabel('ppm caffeine in bloodstream')
plt.ylabel('cheeriness')

Out[1]:
Text(0,0.5,'cheeriness')

and tables...

In [2]:
import astropy.table
tbl = astropy.table.Table()
name='integers'))
name='their squares'))
tbl

Out[2]:
Table length=5
integerstheir squares
int64int64
00
11
24
39
416

and even notes and typeset mathematics...

And God said:

$$\nabla \cdot \mathbf{D} = \rho$$$$\nabla \cdot \mathbf{B} = 0$$$$\nabla \times \mathbf{E} = -\frac{\partial\mathbf{B}}{\partial t}$$$$\nabla \times \mathbf{H} = J + \frac{\partial\mathbf{D}}{\partial t}$$

and there was light.

This is all very useful for doing interactive data analysis, so we will use the IPython Notebook interface for this tutorial. WARNING: I'm spoiling you rotten by doing this.

## II. How to get Python/Matplotlib/Numpy/Scipy/Astropy (if necessary)¶

Python and all of the packages that we discuss in this tutorial are open source software, so there multiple options for installing them. But if you followed the instructions on the GROWTH website for downloading/installing these modules, you have already installed these dependencies. Skip to the next step.

### For Linux/UNIX users¶

If you have one of the common Linux/UNIX distros (for example, Ubuntu, Debian, or Fedora), then you probably already have Python and you can get Matplotlib and friends from your package manager.

For example, on Debian or Ubuntu, use:

### For Windows users¶

Windows does not come with Python, but popular and free builds of Python for Windows include Anaconda and Canopy. Another alternative for Windows is to set up a virtual machine with VirtualBox and then install a Linux distribution on that.

## III. Python basics¶

### The print() function and string literals¶

If this is your first time looking at Python code, the first thing that you might notice is that it is very easy to understand. For example, to print something to the screen, it's just:

In [3]:
print('Hello world!')

Hello world!


This is a Python statement, consisting of the built-in command print and a string surrounded by single quotes. Double quotes are fine inside a string:

In [4]:
print('She said, "Hello, world!"')

She said, "Hello, world!"


But if you want single quotes inside your string, you had better delimit it with double quotes:

In [5]:
print("She said, 'Hello, world!'")

She said, 'Hello, world!'


If you need both single quotes and double quotes, you can use backslashes to escape characters.

In [6]:
print('She said, "O brave new world, that has such people in\'t!"')

She said, "O brave new world, that has such people in't!"


If you need a string that contains newlines, use triple quotes (''') or triple double quotes ("""):

In [7]:
print("""MIRANDA
O, wonder!
How many goodly creatures are there here!
How beauteous mankind is! O brave new world
That has such people in't!""")

MIRANDA
O, wonder!
How many goodly creatures are there here!
How beauteous mankind is! O brave new world
That has such people in't!


Let's say that you need to print a few different things on the same line. Just separate them with commas, as in:

In [8]:
person = 'Miranda'
print("'Tis new to", person)

'Tis new to Miranda


Oops. I'm getting ahead of myselfâ€”you've now seen your first variable assignment in Python. Strings can be concatened by adding them:

In [9]:
'abc' + 'def'

Out[9]:
'abcdef'

Or repeated by multiplying them:

In [10]:
'abcdef' * 2

Out[10]:
'abcdefabcdef'

### Numeric and boolean literals¶

Python's numeric types include integers and both real and complex floating point numbers:

In [11]:
a = 30 # an integer
b = 0xDEADBEEF # an integer in hexadecimal
c = 3.14159 # a floating point number
d = 5.1e10 # scientific notation
e = 2.5 + 5.3j # a complex number
hungry = True # boolean literal
need_coffee = False # another boolean literal


By the way, all of the text on a given line after the trailing hash sign (#) is a comment, ignored by Python.

The arithmetic operators in Python are similar to C, C++, Java, and so on. There is addition (and subtraction):

In [12]:
a + c

Out[12]:
33.14159

Multiplication:

In [13]:
a * e

Out[13]:
(75+159j)

Division:

In [14]:
a / c

Out[14]:
9.549304651466295

Important note: unlike C, C++, Java, etc., division of integers gives you floats:

In [15]:
7 / 3

Out[15]:
2.3333333333333335

If you want integer division, then use the double-slash // operator:

In [16]:
a = 7
b = 3
7 // 3

Out[16]:
2

The % sign is the remainder operator:

In [17]:
32 % 26

Out[17]:
6

Exponentiation is accomplished with the ** operator:

In [18]:
print(5 ** 3, 9**-0.5)

125 0.3333333333333333


### Tuples¶

A tuple is a sequence of values. It's just about the handiest thing since integers. A tuple is immutable: once you have created it, you cannot add items to it, remove items from it, or change items. Tuples are very handy for storing short sequences of related values or returning multiple values from a function. This is what tuples look like:

In [19]:
some_tuple = ('a', 'b', 'c')
another_tuple = ('caffeine', 6.674e-11, 3.14, 2.718)
nested_tuple = (5, 4, 3, 2, ('a', 'b'), 'c')


Once you have made a tuple, you might want to retrieve a value from it. You index a tuple with square brackets, starting from zero:

In [20]:
some_tuple[0]

Out[20]:
'a'
In [21]:
some_tuple[1]

Out[21]:
'b'

You can access whole ranges of values using slice notation:

In [22]:
nested_tuple[1:4]

Out[22]:
(4, 3, 2)

Or, to count backward from the end of the tuple, use a negative index:

In [23]:
another_tuple[-1]

Out[23]:
2.718
In [24]:
another_tuple[-2]

Out[24]:
3.14

Strings can be treated just like tuples of individual charaters:

In [25]:
person = 'Miranda'
print(person[3:6])

and


### Lists¶

What if you want a container like a tuple but to which you can add or remove items or alter existing items? That's a list. The syntax is almost the same, except that you create a list using square brackets [] instead of round ones ():

In [26]:
your_list = ['foo', 'bar', 'bat', 'baz']
my_list = ['xyzzy', 1, 3, 5, 7]


But you can change elements:

In [27]:
my_list[1] = 2
print(my_list)

['xyzzy', 2, 3, 5, 7]


Or append elements to an existing list:

In [28]:
my_list.append(11)
print(my_list)

['xyzzy', 2, 3, 5, 7, 11]


Or delete elements:

In [29]:
del my_list[0]
print(my_list)

[2, 3, 5, 7, 11]


### Sets¶

Sometimes you need a collection of items where order doesn't necessarily matter, but each item is guaranteed to be unique. That's a set, created just like a list or tuple but with curly braces {}:

In [30]:
a = {5, 6, 'foo', 7, 7, 8}
print(a)

{'foo', 5, 6, 7, 8}


You can add items to a set:

In [31]:
a.add(3)
print(a)

{3, 'foo', 5, 6, 7, 8}


Or take them away:

In [32]:
a.remove(3)
print(a)

{'foo', 5, 6, 7, 8}


You also have set-theoretic intersections with the & operator:

In [33]:
{1, 2, 3, 4, 5, 6} & {3, 4}

Out[33]:
{3, 4}

And union with the | operator:

In [34]:
{1, 2, 3, 4, 5, 6} | {6, 7}

Out[34]:
{1, 2, 3, 4, 5, 6, 7}

And set difference with the - operator:

In [35]:
{1, 2, 3, 4, 5, 6} - {3, 4}

Out[35]:
{1, 2, 5, 6}

### Dictionaries¶

Sometimes, you want a collection that is like a list, but whose indices are strings or other Python values. That's a dictionary. Dictionaries are handy for any type of database-like operation, or for storing mappings from one set of values to another. You create a dictionary by enclosing a list of key-value pairs in curly braces:

In [36]:
my_grb = {'name': 'GRB 130702A', 'redshift': 0.145, 'ra': (14, 29, 14.78), 'dec': (15, 46, 26.4)}
my_grb

Out[36]:
{'name': 'GRB 130702A',
'redshift': 0.145,
'ra': (14, 29, 14.78),
'dec': (15, 46, 26.4)}

You can index items in dictionaries with square braces [], similar to tuples or lists:

In [37]:
my_grb['dec']

Out[37]:
(15, 46, 26.4)

or add items to them:

In [38]:
my_grb['url'] = 'http://gcn.gsfc.nasa.gov/other/130702A.gcn3'
my_grb

Out[38]:
{'name': 'GRB 130702A',
'redshift': 0.145,
'ra': (14, 29, 14.78),
'dec': (15, 46, 26.4),
'url': 'http://gcn.gsfc.nasa.gov/other/130702A.gcn3'}

or delete items from them:

In [39]:
del my_grb['url']
my_grb

Out[39]:
{'name': 'GRB 130702A',
'redshift': 0.145,
'ra': (14, 29, 14.78),
'dec': (15, 46, 26.4)}

Dictionary keys can be any immutable kind of Python object: tuples, strings, integers, and floats are all fine. Values in a dictionary can be any Python value at all, including lists or other dictionaries:

In [40]:
{
'foods': ['chicken', 'veggie burger', 'banana'],
'cheeses': {'muenster', 'gouda', 'camembert', 'mozarella'},
(5.5, 2): 42,
'plugh': 'bat'
}

Out[40]:
{'foods': ['chicken', 'veggie burger', 'banana'],
'cheeses': {'camembert', 'gouda', 'mozarella', 'muenster'},
(5.5, 2): 42,
'plugh': 'bat'}

### The None object¶

Sometimes you need to represent the absence of a value, for instance, if you have a gap in a dataset. You might be tempted to use some special value like -1 or 99 for this purpose, but don't! Use the built-in object None.

In [41]:
a = None


### Conditionals¶

In Python, control flow statements such as conditionals and loops have blocks indicated with indentation. Any number of spaces or tabs is fine, as long as you are consistent within a block. Common choices include four spaces, two spaces, or a tab.

You can use the if...elif...else statement to have different bits of code run depending on the truth or falsehood of boolean expressions. For example:

In [42]:
a = 5

if a < 3:
print("i'm in the 'if' block")
messsage = 'a is less than 3'
elif a == 3:
print("i'm in the 'elif' block")
messsage = 'a is 3'
else:
print("i'm in the 'else' block")
message = 'a is greater than 3'

print(message)

i'm in the 'else' block
a is greater than 3


You can chain together inequalities just like in mathematical notation:

In [43]:
if 0 < a <= 5:
print('a is greater than 0 but less than or equal to 5')

a is greater than 0 but less than or equal to 5


You can also combine comparison operators with the boolean and, or, and not operators:

In [44]:
if a < 6 or a > 8:
print('yahoo!')

yahoo!

In [45]:
if a < 6 and a % 2 == 1:
print('a is an odd number less than 6!')

a is an odd number less than 6!

In [46]:
if not a == 5: # same as a != 5
print('a is not 5')


The comparison operator is tests whether two Python values are not only equal, but represent the same object. Since there is only one None object, the is operator is particularly useful for detecting None.

In [47]:
food = None

if food is None:
print('No, thanks')
else:
print('Here is your', food)

No, thanks


Likewise, there is an is not operator:

In [48]:
if food is not None:
print('Yum!')


The in and not in operators are handy for testing for membership in a string, set, or dictionary:

In [49]:
if 3 in {1, 2, 3, 4, 5}:
print('indeed it is')

indeed it is

In [50]:
if 'i' not in 'team':
print('there is no "i" in "team"')

there is no "i" in "team"


When referring to a dictionary, the in operator tests if the item is among the keys of the dictionary.

In [51]:
d = {'foo': 3, 'bar': 5, 'bat': 9}
if 'foo' in d:
print('the key "foo" is in the dictionary')

the key "foo" is in the dictionary


### The for and while loops¶

In Python, there are just two types of loops: for and while. for loops are useful for repeating a set of statements for each item in a collection (tuple, set, list, dictionary, or string). while loops are not as common, but can be used to repeat a set of statements until a boolean expression becomes false.

In [52]:
for i in [0, 1, 2, 3]:
print(i**2)

0
1
4
9


The built-in function range, which returns a list of numbers, is often handy here:

In [53]:
for i in range(4):
print(i**2)

0
1
4
9


Or you can have the range start from a nonzero value:

In [54]:
for i in range(-2, 4):
print(i**2)

4
1
0
1
4
9


You can iterate over the keys and values in a dictionary with .items():

In [55]:
for key, val in d.items():
print(key, '...', val**3)

foo ... 27
bar ... 125
bat ... 729


The syntax of the while loop is similar to the if statement:

In [56]:
a = 1
while a < 5:
a = a * 2
print(a)

2
4
8


### List comprehensions¶

Sometimes you need a loop to create one list from another. List comprehensions make this very terse. For example, the following for loop:

In [57]:
a = []
for i in range(5):
a.append(i * 10)


is equivalent to this list comprehension:

In [58]:
a = [i * 10 for i in range(5)]


You can even incorporate conditionals into a list comprehension. The following:

In [59]:
a = []
for i in range(5):
if i % 2 == 0:
# i is even
a.append(i * 10)


can be written as:

In [60]:
a = [i * 10 for i in range(5) if i % 2 == 0]


### Conditional expressions¶

Conditional expressions are a closely related shorthand. The following:

In [61]:
if 6/2 == 3:
a = 'foo'
else:
a = 'bar'


is equivalent to:

In [62]:
a = 'foo' if 6/2 == 3 else 'bar'


### Functions¶

Functions are created with the def statement. A function may either have or not have a return statement to send back a return value.

In [63]:
def square(n):
return n * n

a = square(3)
print(a)

9


If you want to return multiple values from a function, return a tuple. Parentheses around the tuple are optional.

In [64]:
def powers(n):
return n**2, n**3

print(powers(3))

(9, 27)


If a function returns multiple values, you can automatically unpack them into multiple variables:

In [65]:
square, cube = powers(3)
print(square)

9


If you pass a mutable value such as a list to a function, then the function may modify that value. For example, you might implement the Fibonacci sequence like this:

In [66]:
def fibonacci(seed, n):
while len(seed) < n:
seed.append(seed[-1] + seed[-2])
# Note: no return statement

seed = [1, 1]
fibonacci(seed, 10)
print(seed)

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]


You can also give a function's arguments default values, such as:

In [67]:
def fibonacci(seed, n=6):
while len(seed) < n:
seed.append(seed[-1] + seed[-2])
# Note: no return statement

seed = [1, 1]
fibonacci(seed)
print(seed)

[1, 1, 2, 3, 5, 8]


If a function has a large number of arguments, it may be easier to read if you pass the arguments by keyword, as in:

In [68]:
seq = [1, 1]
fibonacci(seed=seq, n=4)


## IV. The Python standard library¶

Python comes with an extensive standard library consisting of individual modules that you can opt to use with the import statement. For example:

In [69]:
import math
math.sqrt(3)

Out[69]:
1.7320508075688772
In [70]:
from math import pi
pi

Out[70]:
3.141592653589793

Some particularly useful parts of the Python standard library are:

### Error handling¶

It can be important for your code to be able to handle error conditions. For example, let's say that you are implementing a sinc function:

In [71]:
def sinc(x):
return math.sin(x) / x

print(sinc(0))

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-71-e7a6fa28a489> in <module>
2     return math.sin(x) / x
3
----> 4 print(sinc(0))

<ipython-input-71-e7a6fa28a489> in sinc(x)
1 def sinc(x):
----> 2     return math.sin(x) / x
3
4 print(sinc(0))

ZeroDivisionError: float division by zero

Oops! We know that by definition $\mathrm{sinc}(0) = 1$ , so we should catch this error:

In [72]:
def sinc(x):
try:
result = math.sin(x) / x
except ZeroDivisionError:
result = 1
return result

print(sinc(0))

1


### Reading and writing files¶

The built-in open function opens a file and returns a file object that you can use to read or write data. Here's an example of writing data to a file:

In [73]:
myfile = open('myfile.txt', 'w') # open file for writing
myfile.write("red 1\n")
myfile.write("green 2\n")
myfile.write("blue 3\n")
myfile.close()


And here is reading it:

In [74]:
d = {} # create empty dictionary

for line in open('myfile.txt', 'r'): # open file for reading
color, num = line.split() # break apart line by whitespace
num = int(num) # convert num to integer
d[color] = num

print(d)

{'red': 1, 'green': 2, 'blue': 3}


## V. Numpy & Matplotlib¶

Numpy provides array operations and linear algebra to Python. A Numpy array is a bit like a Python list, but supports elementwise arithmetic. For example:

In [75]:
import numpy as np

x = np.asarray([1, 2, 3, 4, 5])
y = 2 * x
print(y)

[ 2  4  6  8 10]


Numpy arrays may have any number of dimensions:

In [76]:
x = np.asarray([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
x

Out[76]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [77]:
y = np.asarray([[9, 8, 7], [6, 5, 4], [3, 2, 1]])
y

Out[77]:
array([[9, 8, 7],
[6, 5, 4],
[3, 2, 1]])

An array has a certain number of dimensions denoted .ndim:

In [78]:
x.ndim

Out[78]:
2

and the dimensions' individual lengths are given by .shape:

In [79]:
x.shape

Out[79]:
(3, 3)

and the total number of elements by .size:

In [80]:
x.size

Out[80]:
9

By default, multiplication is elementwise:

In [81]:
x * y

Out[81]:
array([[ 9, 16, 21],
[24, 25, 24],
[21, 16,  9]])

To perform matrix multiplication, either convert arrays to np.matrix or use np.dot:

In [82]:
np.asmatrix(x) * np.asmatrix(y)

Out[82]:
matrix([[ 30,  24,  18],
[ 84,  69,  54],
[138, 114,  90]])
In [83]:
np.dot(x, y)

Out[83]:
array([[ 30,  24,  18],
[ 84,  69,  54],
[138, 114,  90]])

You can also perform comparison operations on arrays...

In [84]:
x > 5

Out[84]:
array([[False, False, False],
[False, False,  True],
[ True,  True,  True]])

Although a boolean array doesn't directly make sense in an if statement:

In [85]:
if x > 5:
print('oops')

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-85-5a5904c20c71> in <module>
----> 1 if x > 5:
2     print('oops')

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
In [86]:
if np.any(x > 5):
print('at least some elements are greater than 5')

at least some elements are greater than 5


You can use conditional expressions like indices:

In [87]:
x[x > 5] = 5
x

Out[87]:
array([[1, 2, 3],
[4, 5, 5],
[5, 5, 5]])

Or manipulate individual rows:

In [88]:
x[1, :] = -1
x

Out[88]:
array([[ 1,  2,  3],
[-1, -1, -1],
[ 5,  5,  5]])

Or individual columns:

In [89]:
x[:, 1] += 100
x

Out[89]:
array([[  1, 102,   3],
[ -1,  99,  -1],
[  5, 105,   5]])

Other useful features include various random number generators:

In [90]:
from matplotlib import pyplot as plt
%matplotlib inline

# Plot histogram of 10k normal random variates
plt.hist(np.random.randn(10000))

Out[90]:
(array([3.000e+00, 4.700e+01, 3.210e+02, 1.117e+03, 2.430e+03, 3.047e+03,
2.007e+03, 8.400e+02, 1.670e+02, 2.100e+01]),
array([-4.17837775, -3.39916472, -2.61995168, -1.84073865, -1.06152561,
-0.28231258,  0.49690045,  1.27611349,  2.05532652,  2.83453956,
3.61375259]),
<a list of 10 Patch objects>)
In [91]:
np.random.uniform(low=0, high=2*np.pi)

Out[91]:
4.859973657700913

You've already seen a few examples of Matplotlib. If you have used MATLAB, then Matplotlib code may look familiar.

In [92]:
x = np.linspace(-10, 10)
y = 1 / (1 + np.exp(x))
plt.plot(x, y)
plt.annotate(
'foo bar', (x[20], y[20]), (50, 5),
textcoords='offset points',
arrowprops={'arrowstyle': '->'})
plt.grid()


## VI. Astropy¶

Astropy is a core Python package for astronomy. It is formed from the merger of a number of other Python astronomy packages, but also contains a lot of original code. Core features include:

• astropy.constants, astropy.units: Physical constants, units, and unit conversion
• astropy.time: Manipulation of dates and times
• astropy.coordinates: Representation of and conversion between astronomical coordinate systems
• astropy.table: Tables and gridded data
• astropy.io.fits: Manipulating FITS files
• astropy.io.ascii: Manipulating ASCII tables of many different formats
• astropy.io.votable: Virtual Observatory tables
• astropy.wcs: World Coordinate System transformations
• astropy.cosmology: Cosmological calculations
• astropy.stats: Astrostatistics
• astropy.modeling: multi-D model fitting Swiss army knife

The Astropy project also has sevearl "affiliated packages" that have similar design but are maintained separately, including:

Let's experiment by opening up a P48 image. We'll need several modules from the Astropy package for this exercise.

In [93]:
import astropy.coordinates
import astropy.units as u
import astropy.io.fits
import astropy.stats
import astropy.table
import astropy.wcs
import astropy.cosmology
import scipy.optimize
import scipy.odr


I've downloaded a P48 image and put it in the data/ directory.

In [94]:
fits = astropy.io.fits.open('data/PTF_201307021787_i_p_scie_t041723_u016616794_f02_p003486_c11.fits')
fits

Out[94]:
[<astropy.io.fits.hdu.image.PrimaryHDU object at 0x7f8dfa037ba8>]

Let's grab the first (and only) HDU of this FITS file:

In [95]:
hdu = fits[0]


Then let's take a look at the contents of the header:

In [96]:
hdu.header

Out[96]:
SIMPLE  =                    T / Fits standard
BITPIX  =                  -32 / FOUR-BYTE SINGLE PRECISION FLOATING POINT
NAXIS   =                    2 / STANDARD FITS FORMAT
NAXIS1  =                 2048 / STANDARD FITS FORMAT
NAXIS2  =                 4096 / STANDARD FITS FORMAT
ORIGIN  = 'Palomar Transient Factory' / Origin of these image data
CREATOR = 'Infrared Processing and Analysis Center' / Creator of this FITS file
TELESCOP= 'P48     '           / Name of telescope
INSTRUME= 'PTF/MOSAIC'         / Instrument name
OBSERVER= 'KulkarniPTF'        / Observer name and project
CCDID   = '11      '           / CCD number (0..11)
DATE-OBS= '2013-07-02T04:17:23.555' / UTC shutter time YYYY-MM-DDTHH:MM:SS.SSS
DATE    = '2013-07-01T21:35:19' / File creation date (YYYY-MM-DDThh:mm:ss UT)
REFERENC= 'http://www.astro.caltech.edu/ptf' / URL of PTF website

/ PROPOSAL INFORMATION

PTFPRPI = 'Kulkarni'           / PTF Project PI
PTFPID  = '30011   '           / Project type: 00000-49999
OBJECT  = 'PTF_survey'         / Fields object
PTFFIELD= '3486    '           / PTF unique field ID
PTFFLAG = '1       '           / 1 = PTF; 0 = non-PTF category

/ TIME AND EXPOSURE INFORMATION

FILTER  = 'R       '           / Filter name
FILTERID= '2       '           / Filter ID
FILTERSL= '1       '           / Filter changer slot position
EXPTIME =                  60. / [s] Requested exposure time
AEXPTIME=                  60. / actual exposure time (sec)
UTC-OBS = '2013-07-02T04:17:23.555' / UTC time shutter open YYYY-MM-DDTHH:MM:SS.
OBSJD   =        2456475.67874 / [day] Julian day corresponds to UTC-OBS
OBSMJD  =          56475.17874 / MJD corresponds to UTC-OBS (day)
OBSLST  = '15:11:26.46'        / Mean LST corresponds to UTC-OBS 'HH:MM:SS.S'
HOURANG = '0:48:14.61'         / Mean HA (sHH:MM:SS.S) based on LMST at UTC-OBS
HJD     =        2456475.68019 / [day] Heliocentric Julian Day
OBSTYPE = 'object  '           / Image type (dark,science,bias,focus)
IMGTYP  = 'object  '           / Image type (dark,science,bias,focus)

/ MOON AND SUN

MOONRA  =             30.98457 / [deg] Moon J2000.0 R.A.
MOONDEC =            12.984756 / [deg] Moon J2000.0 Dec.
MOONILLF=            -0.306369 / [frac] Moon illuminated fraction
MOONPHAS=             247.2158 / [deg] Moon phase angle
MOONESB =                  -0. / Moon excess in sky brightness V-band
MOONALT =            -40.94289 / [deg] Moon altitude
SUNAZ   =             310.3019 / [deg] Sun azimuth
SUNALT  =            -14.00398 / [deg] Sun altitude

/ PHOTOMETRY

BUNIT   = 'DN      '           / Data number (analog-to-digital units or ADU)
PHTCALEX=                    1 / Was phot.-cal. module executed?
PHTCALFL=                    1 / Flag for image is photometric (0=N, 1=Y)
PCALRMSE=             0.215766 / RMSE from (zeropoint, extinction) data fit
IMAGEZPT=             23.72382 / Image magnitude zeropoint
COLORTRM=            -0.012228 / Image color term (g-r)
ZPTSIGMA=             1.886777 / Robust dispersion of SEx-SDSS magnitudes
IZPORIG = 'SDSS    '           / Photometric-calibration origin
ZPRULE  = 'DIRECT  '           / Photometric-calibration method
MAGZPT  =             23.77773 / Magnitude zeropoint at airmass=1
EXTINCT =            -0.195707 / Extinction
APSFILT = 'r       '           / SDSS filter used in abs phot cal
APSCOL  = 'r-i     '           / SDSS color used in abs phot cal
APRMS   =           0.05618604 / RMS in mag of final abs phot cal
APBSRMS =            0.0344094 / RMS in mag of final abs phot cal for bright sta
APNSTDI1=               177080 / Number of standard stars in first iteration
APNSTDIF=               160107 / Number of standard stars in final iteration
APCHI2  =      771280.24477198 / Chi2 of final abs phot cal
APDOF   =              160096. / Dof of chi2 of final abs phot cal
APMEDJD =     2456475.80246722 / Median JD used in abs phot cal
APPN01  = 'ZeroPoint'          / Name of parameter abs phot cal 01
APPAR01 =          23.68493517 / Value of parameter abs phot cal 01
APPARE01=            0.0026937 / Error of parameter abs phot cal 01
APPN02  = 'ColorTerm'          / Name of parameter abs phot cal 02
APPAR02 =          -0.03174945 / Value of parameter abs phot cal 02
APPARE02=           0.00383537 / Error of parameter abs phot cal 02
APPN03  = 'AirMassTerm'        / Name of parameter abs phot cal 03
APPAR03 =          -0.28459543 / Value of parameter abs phot cal 03
APPARE03=           0.00226667 / Error of parameter abs phot cal 03
APPN04  = 'AirMassColorTerm'   / Name of parameter abs phot cal 04
APPAR04 =           0.24261075 / Value of parameter abs phot cal 04
APPARE04=           0.00313212 / Error of parameter abs phot cal 04
APPN05  = 'TimeTerm'           / Name of parameter abs phot cal 05
APPAR05 =           0.19911481 / Value of parameter abs phot cal 05
APPARE05=           0.00219937 / Error of parameter abs phot cal 05
APPN06  = 'Time2Term'          / Name of parameter abs phot cal 06
APPAR06 =           1.65698453 / Value of parameter abs phot cal 06
APPARE06=           0.02684713 / Error of parameter abs phot cal 06
APPN07  = 'XTerm   '           / Name of parameter abs phot cal 07
APPAR07 =           0.02703671 / Value of parameter abs phot cal 07
APPARE07=           0.00053429 / Error of parameter abs phot cal 07
APPN08  = 'YTerm   '           / Name of parameter abs phot cal 08
APPAR08 =          -0.01528394 / Value of parameter abs phot cal 08
APPARE08=           0.00131972 / Error of parameter abs phot cal 08
APPN09  = 'Y2Term  '           / Name of parameter abs phot cal 09
APPAR09 =           0.00938432 / Value of parameter abs phot cal 09
APPARE09=           0.00208283 / Error of parameter abs phot cal 09
APPN10  = 'Y3Term  '           / Name of parameter abs phot cal 10
APPAR10 =           0.03443254 / Value of parameter abs phot cal 10
APPARE10=           0.00825142 / Error of parameter abs phot cal 10
APPN11  = 'XYTerm  '           / Name of parameter abs phot cal 11
APPAR11 =           0.01025838 / Value of parameter abs phot cal 11
APPARE11=           0.00188474 / Error of parameter abs phot cal 11

/ ASTROMETRY

WCSAXES =                    2 / Number of axes in world coordinate system
CRVAL1  =     217.309490953823 / [deg] RA of reference point
CRVAL2  =     16.6581466832508 / [deg] DEC of reference point
CRPIX1  =             1497.193 / [pix] Image reference point
CRPIX2  =             609.3031 / [pix] Image reference point
CTYPE1  = 'RA---TAN-SIP'       / TAN (gnomic) projection + SIP distortions
CTYPE2  = 'DEC--TAN-SIP'       / TAN (gnomic) projection + SIP distortions
CUNIT1  = 'deg     '           / Image axis-1 celestial-coordinate units
CUNIT2  = 'deg     '           / Image axis-2 celestial-coordinate units
CRTYPE1 = 'deg     '           / Data units of CRVAL1
CRTYPE2 = 'deg     '           / Data units of CRVAL2
CD1_1   = 0.000280377484830748 / Transformation matrix
CD1_2   = -1.71606271442079E-06
CD2_1   = -1.61073877029747E-06
CD2_2   = -0.000280943199913645
OBJRA   = '14:22:34.454'       / Requested field J2000.0 Ra.
OBJDEC  = '+16:52:30.00'       / Requested field J2000.0 Dec.
OBJRAD  =            215.64356 / [deg] Requested field RA (J2000.0)
OBJDECD =               16.875 / [deg] Requested field Dec (J2000.0)
PIXSCALE=                 1.01 / [arcsec/pix] Pixel scale
EQUINOX =                2000. / [yr] Equatorial coordinates definition
LONPOLE =                 180.
LATPOLE =                   0.

/ IMAGE QUALITY

SEEING  =                 1.71 / [pix] Seeing FWHM
PEAKDIST=    0.389898704794061 / [pix] Mean dist brightest pixel-centroid pixel
ELLIP   =                0.107 / Mean image ellipticity A/B
ELLIPPA =               -35.01 / [deg] Mean image ellipticity PA
FBIAS   =             689.3355 / [DN] Floating bias of the image
SATURVAL=               53000. / [DN] Saturation value of the CCD array
FWHMSEX =                 1.85 / [arcsec] SExtractor SEEING estimate
MDSKYMAG=             20.39761 / [mag/s-arcsec^2] Median sky obsolete
MSMAPCZP=             20.05711 / [mag/s-arcsec^2] Median sky abs. phot. cal.
LIMITMAG=             21.74218 / [mag/s-arcsec^2] Limiting magnitude obsolete
LMGAPCZP=             21.40168 / [mag/s-arcsec^2] Limiting mag. abs. phot. cal.
MEDFWHM =             2.608781 / [arcsecond] Median FWHM
MEDELONG=             1.168383 / [dimensionless] Median elongation
STDELONG=            0.6377625 / [dimensionless] Std. dev. of elongation
MEDTHETA=            -7.846824 / [deg] Atan(median sin(theta)/median cos(theta))
STDTHETA=              64.7667 / [deg] Atan(stddev sin(theta)/stddev cos(theta))
MEDDLMAG=             30.16257 / [mag/s-arcsec^2] Median (MU_MAX-MAG_AUTO)
STDDLMAG=             1.823812 / [mag/s-arcsec^2] Stddev of (MU_MAX-MAG_AUTO)

/ OBSERVATORY AND TCS

OCS_TIME= '2013-07-02T04:17:23.461' / UTC Date for OCS calc time-dep params
OPERMODE= 'OCS     '           / Mode of operation: OCS | Manual | N/A
SOFTVER = '1.1.1.1 '           / Softwere version (TCS.Camera.OCS.Sched)
OCS_VER = '1       '           / OCS software version and date
TCS_VER = '1       '           / TCS software version and date
SCH_VER = '1       '           / OCS-Scheduler software version and date
MAT_VER = '7.7.0.471'          / Matlab version
HDR_VER = '1       '           / Header version
TRIGGER = 'N/A     '           / trigger ID for TOO, e.g. VOEVENT-Nr
TCSMODE = 'Star    '           / TCS fundamental mode
TCSSMODE= 'Active  '           / TCS fundamental submode
TCSFMODE= 'Pos     '           / TCS focus mode
TCSFSMOD= 'On-Target'          / TCS focus submode
TCSDMODE= 'Stop    '           / TCS dome mode
TCSDSMOD= 'N/A     '           / TCS dome submode
TCSWMODE= 'Slave   '           / TCS windscreen mode
TCSWSMOD= 'N/A     '           / TCS windscreen submode
OBSLAT  =              33.3574 / [deg] Telescope geodetic latitude in WGS84
OBSLON  =            -116.8599 / [deg] Telescope geodetic longitude in WGS84
OBSALT  =               1703.2 / [m] Telescope geodetic altitude in WGS84
DEFOCUS =                   0. / [mm] Focus position - nominal focus
FOCUSPOS=               1.3785 / [mm] Exposures focusPos
DOMESTAT= 'open    '           / Dome status at begining of exposure
TRACKRA =                 10.6 / [arcsec/hr] Track speed RA rel to sidereal
TRACKDEC=                  1.3 / [arcsec/hr] Track speed Dec rel to sidereal
AZIMUTH =             216.6835 / [deg] Telescope Azimuth
ALTITUDE=             70.18806 / [deg] Telescope altitude
AIRMASS =             1.062788 / Telescope airmass
TELRA   =             215.7994 / [deg] Telescope ap equinox of date RA
TELDEC  =              16.8139 / [deg] Telescope ap equinox of date Dec
TELHA   =              12.0595 / [deg] Telescope ap equinox of date HA
DOMEAZ  =             215.3933 / [deg] Dome azimuth
WINDSCAL=              10.1089 / [deg] Wind screen altitude
WINDDIR =                  1.6 / [deg] Azimuth of wind direction
WINDSPED=               9.1656 / Wind speed (km/hour)
OUTTEMP =             23.33333 / [C] Outside temperature
OUTRELHU=                0.409 / [frac] Outside relative humidity
OUTDEWPT=             9.277778 / [C] Outside dew point

/ INSTRUMENT TELEMETRY

PANID   = '_p48s   '           / PAN identification
DHSID   = '_p48s   '           / DHS identification
CCDSEC  = '[1:2048,1:4096]'    / CCD section
CCDSIZE = '[1:2048,1:4096]'    / CCD size
DATASEC = '[1:2048,1:4096]'    / Data section
DETSEC  = '[1:2048,1:4096]'    / Detector section
ROISEC  = '[1:2048,1:4096]'    / ROI section
FPA     = 'P48MOSAIC'          / Focal plan array
CCDNAME = 'W7C1    '           / Detector mfg serial number
CHECKSUM= '        '           / Image header unit checksum
DATASUM = '        '           / Image data unit checksum
DHEINF  = 'SDSU, Gen-III'      / Controller info
DHEFIRM = '/usr/src/dsp/20090618/tim_m.lod' / DSP software
CAM_VER = '20090615.1.3.100000' / Camera server date.rev.cfitsio
LV_VER  = '8.5     '           / LabVIEW software version
PCI_VER = '2.0c    '           / Astropci software version
DETID   = 'PTF/MOSAIC'         / Detector ID
AUTHOR  = 'PTF/OCS/TCS/Camera' / Source for header information
DATAMIN =                   0. / Minimum value for array
ROISTATE= 'ROI     '           / ROI State (FULL | ROI)
LEDBLUE = 'OFF     '           / 470nm LED state (ON | OFF)
LEDRED  = 'OFF     '           / 660nm LED state (ON | OFF)
LEDNIR  = 'OFF     '           / 880nm LED state (ON | OFF)
CCD9TEMP=              175.002 / [K] 0x0 servo temp sensor on CCD09
HSTEMP  =               150.25 / [K] 0x1 heat spreader temp
DHE0TEMP=              303.015 / [K] 0x2 detector head electronics temp, master
DHE1TEMP=              304.935 / [K] 0x3 detector head electronics temp, slave
DEWWTEMP=              292.787 / [K] 0x4 dewar wall temp
HEADTEMP=              141.038 / [K] 0x5 cryo cooler cold head temp
CCD5TEMP=              175.312 / [K] 0x6 temp sensor on CCD05
CCD11TEM=              176.263 / [K] 0x7 temp sensor on CCD11
CCD0TEMP=              169.376 / [K] 0x8 temp sensor on CCD00
RSTEMP  =              241.756 / [K] 0x9 temp sensor on radiation shield
DEWPRESS=                  2.3 / [milli-torr] Dewar pressure
DETHEAT =                 28.5 / [%] Detector focal plane heater power
NAMPSXY = '6 2     '           / Number of amplifiers in x y
CCDSUM  = '1 1     '           / [pix] Binning in x and y
MODELFOC= 'N/A     '           / MODELFOC
EXPCKSUM= '4VHn7S9l4SEl4S9l'   / Primary header unit checksum
EXPDTSUM= '         0'         / Primary data unit checksum
GAIN    =                  1.5 / [e-/D.N.] Gain of detector.
READNOI =                  5.2 / [e-] Read noise of detector.
DARKCUR =                  0.1 / [e-/s] Dark current of detector

/ SCAMP DISTORTION KEYWORDS

RADECSYS= 'ICRS    '           / Astrometric system
PV1_0   =                   0. / Projection distortion parameter
PV1_1   =                   1. / Projection distortion parameter
PV1_2   =                   0. / Projection distortion parameter
PV1_4   = -0.00173789497161513 / Projection distortion parameter
PV1_5   = 6.00083003595371E-05 / Projection distortion parameter
PV1_6   = -0.00054585707358405 / Projection distortion parameter
PV1_7   = -0.00133490210858131 / Projection distortion parameter
PV1_8   = 0.000173741003278833 / Projection distortion parameter
PV1_9   = -0.000547160675264968 / Projection distortion parameter
PV1_10  = 0.000251433351740168 / Projection distortion parameter
PV1_12  = -0.00328774077188989 / Projection distortion parameter
PV1_13  = -0.000280710215945655 / Projection distortion parameter
PV1_14  = 0.000714951620183291 / Projection distortion parameter
PV1_15  = -0.000275634808657675 / Projection distortion parameter
PV1_16  = 0.000192684172156633 / Projection distortion parameter
PV2_0   =                   0. / Projection distortion parameter
PV2_1   =                   1. / Projection distortion parameter
PV2_2   =                   0. / Projection distortion parameter
PV2_4   =  0.00025061777603867 / Projection distortion parameter
PV2_5   = -0.00125376481783182 / Projection distortion parameter
PV2_6   = -0.000118547045320473 / Projection distortion parameter
PV2_7   = -0.000709046387896288 / Projection distortion parameter
PV2_8   = 0.000780095509401425 / Projection distortion parameter
PV2_9   = -0.000924905030225836 / Projection distortion parameter
PV2_10  = -0.000525520061118934 / Projection distortion parameter
PV2_12  = -0.000283472622900895 / Projection distortion parameter
PV2_13  = 0.000738353372557653 / Projection distortion parameter
PV2_14  = 0.000164958172111789 / Projection distortion parameter
PV2_15  = -0.00144743155797026 / Projection distortion parameter
PV2_16  = -0.000422174086212961 / Projection distortion parameter
FGROUPNO=                    1 / SCAMP field group label
ASTIRMS1=                   0. / Astrom. dispersion RMS (intern., high S/N)
ASTIRMS2=                   0. / Astrom. dispersion RMS (intern., high S/N)
ASTRRMS1=          2.60633E-05 / Astrom. dispersion RMS (ref., high S/N)
ASTRRMS2=         2.679676E-05 / Astrom. dispersion RMS (ref., high S/N)
ASTINST =                    1 / SCAMP astrometric instrument label
FLXSCALE=                   0. / SCAMP relative flux scale
MAGZEROP=                   0. / SCAMP zero-point
PHOTIRMS=                   0. / mag dispersion RMS (internal, high S/N)
RA_RMS  =            0.4284936 / [arcsec] RMS of SCAMP fit from 2MASS matching
DEC_RMS =            0.3289862 / [arcsec] RMS of SCAMP fit from 2MASS matching
ASTROMN =                 1003 / Number of stars in SCAMP astrometric solution
SCAMPPTH= '/ptf/pos/archive/fallbackcal/scamp/11/' / SCAMP catalog path
SCAMPFIL= 'PTF_201102044118_c_e_sdss_t095258_u003860515_f01_p003486_c11.fits'

/ SIP DISTORTION KEYWORDS

A_ORDER =                    4 / Distortion order for A
A_0_2   = -1.53991686981733E-07 / Projection distortion parameter
A_0_3   = -1.9961153583439E-11 / Projection distortion parameter
A_0_4   = 4.28220501859733E-15 / Projection distortion parameter
A_1_1   = -1.48140435828959E-08 / Projection distortion parameter
A_1_2   = -4.37451084272745E-11 / Projection distortion parameter
A_1_3   = 6.11763923987906E-15 / Projection distortion parameter
A_2_0   = -4.87160559968282E-07 / Projection distortion parameter
A_2_1   = -1.27084757090404E-11 / Projection distortion parameter
A_2_2   = 1.57779409644097E-14 / Projection distortion parameter
A_3_0   = -1.04765134994984E-10 / Projection distortion parameter
A_3_1   = 7.95789862286398E-15 / Projection distortion parameter
A_4_0   = -7.23704568938464E-14 / Projection distortion parameter
A_DMAX  =     2.44291521352919 / Projection distortion parameter
B_ORDER =                    4 / Distortion order for B
B_0_2   = -6.7373693835656E-08 / Projection distortion parameter
B_0_3   = -5.54765729401967E-11 / Projection distortion parameter
B_0_4   = 6.16120047283346E-15 / Projection distortion parameter
B_1_1   = -3.5264356557202E-07 / Projection distortion parameter
B_1_2   = -6.12610617364653E-11 / Projection distortion parameter
B_1_3   = 1.64880764414739E-14 / Projection distortion parameter
B_2_0   = 3.39463080480267E-08 / Projection distortion parameter
B_2_1   = -7.40973776817625E-11 / Projection distortion parameter
B_2_2   = -2.8629870353495E-15 / Projection distortion parameter
B_3_0   = 4.14105136847929E-11 / Projection distortion parameter
B_3_1   = -3.22124747225646E-14 / Projection distortion parameter
B_4_0   = 9.51825972208521E-15 / Projection distortion parameter
B_DMAX  =     2.95057287643024 / Projection distortion parameter
AP_ORDER=                    4 / Distortion order for AP
AP_0_1  = 2.05105623663409E-08 / Projection distortion parameter
AP_0_2  = 1.54047990787523E-07 / Projection distortion parameter
AP_0_3  = 1.99841723199859E-11 / Projection distortion parameter
AP_0_4  = -4.27260819246964E-15 / Projection distortion parameter
AP_1_0  = -7.88989114580002E-08 / Projection distortion parameter
AP_1_1  = 1.49024754213322E-08 / Projection distortion parameter
AP_1_2  = 4.39773302986539E-11 / Projection distortion parameter
AP_1_3  = -6.1078457561122E-15 / Projection distortion parameter
AP_2_0  = 4.87351326761802E-07 / Projection distortion parameter
AP_2_1  = 1.27034030399091E-11 / Projection distortion parameter
AP_2_2  = -1.56781266527055E-14 / Projection distortion parameter
AP_3_0  = 1.05609755183277E-10 / Projection distortion parameter
AP_3_1  = -7.88269146660008E-15 / Projection distortion parameter
AP_4_0  =  7.2479268759029E-14 / Projection distortion parameter
BP_ORDER=                    4 / Distortion order for BP
BP_0_1  = -3.61828763934933E-08 / Projection distortion parameter
BP_0_2  = 6.74317721340757E-08 / Projection distortion parameter
BP_0_3  = 5.55651238033361E-11 / Projection distortion parameter
BP_0_4  = -6.14956183405539E-15 / Projection distortion parameter
BP_1_0  = -5.01841161647254E-08 / Projection distortion parameter
BP_1_1  = 3.52809293826258E-07 / Projection distortion parameter
BP_1_2  = 6.13665672637537E-11 / Projection distortion parameter
BP_1_3  = -1.64300062518365E-14 / Projection distortion parameter
BP_2_0  = -3.4054112344702E-08 / Projection distortion parameter
BP_2_1  = 7.45298070253847E-11 / Projection distortion parameter
BP_2_2  = 2.92717865788252E-15 / Projection distortion parameter
BP_3_0  = -4.14183265768535E-11 / Projection distortion parameter
BP_3_1  = 3.23323470749901E-14 / Projection distortion parameter
BP_4_0  = -9.48831790286268E-15 / Projection distortion parameter

/ DATA FLOW

ORIGNAME= '/data/PTF_default_56753.fits' / Filename as written by the camera
FILENAME= 'PTF201307021787_2_o_56753.fits' / Filename of delivered camera image
PROCORIG= 'IPAC-PTF pipelines' / Processing origin
PROCDATE= 'Wed Jul  3 19:07:12 2013' / Processing date/time (Pacific time)
PTFVERSN=                   5. / Version of PTFSCIENCEPIPELINE program
SFLATPTH= '/ptf/pos/sbx2/2013/07/02/f2/c11/cal/p4/cId98684/' / Pathname of super
SFLATFIL= 'PTF_201307020000_i_s_flat_t120000_u000098684_f02_p000000_c11.fits'
SBIASPTH= '/ptf/pos/sbx2/2013/07/02/f2/c11/cal/p1/cId98678/' / Pathname of super
SBIASFIL= 'PTF_201307020000_i_s_bias_t120000_u000098678_f00_p000000_c11.fits'
DBNID   =                 1550 / Database night ID
DBEXPID =               342625 / Database exposure ID
DBRID   =              5743856 / Database raw-image ID
DBPID   =             16616794 / Database processed-image ID
DBFID   =                    2 / Database filter ID
DBPIID  =                    1 / Database P.I. ID
DBPRID  =                   17 / Database project ID
DBFIELD =               342625 / Database field ID
DBSVID  =                   51 / Database software-version ID
DBCVID  =                   57 / Database config-data-file ID
INFOBITS=                    0 / Database infobits (2^2 and 2^3 excluded)       

Now let's plot the image data. But let's use sigma-clipping to pick a nice scale for the image.

In [97]:
mean, median, std = astropy.stats.sigma_clipped_stats(hdu.data)

In [98]:
plt.figure(figsize=(20, 10))
plt.imshow(hdu.data, vmin=mean-std, vmax=mean+3*std, cmap='binary')
plt.xlabel('pixel $x$')
plt.ylabel('pixel $y$')

Out[98]:
Text(0,0.5,'pixel $y$')

I happen to know that there is something interesting to look at near $\mathrm{RA, Dec}=14^\mathrm{h}29^{m}14.781^{s}, +15^\circ46^\prime26.385^{\prime\prime}$. Let's open the catalog file from IPAC and find this object.

In [99]:
catalog_filename = 'data/PTF_201307021787_c_p_scie_t041723_u016616794_f02_p003486_c11.ctlg.gz'
catalog_table

Out[99]:
Table length=3677
pixpixdegdegpixpixdegdegpix2pix2pix2degdegmagmagmagmagmagmagmagmagmagmagmagmagmag / arcsec2mag / arcsec2ctctdegdegdegdeg2deg2pix2pix2pix2pix2pix2pix2pix2pix2pixctctctctctctctctpixpixpix2pix2pix2degpixpixdegpix2pix2pix2pixdegdegdegpixpixpixpixdegdegdegdegdegpix2pix2pix2pixpixctct
int32int16float64float64float64float64int32int32float32float64float64float64float64float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float64float32float32float32float32float32int32int32int32int32int32int32int32int32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float64float64float64float32float32float32float32float64float64float64float32int32int32float32float32float32float32float32float32float32float32float32float32float32float32float64float64float64float32float32float32float32float32
1282043.074214.0942.1746988032e+021.6768041142e+01204321287.416.76821105.6769986187e+001.6965502946e+016.5196985681e-020.0011570050.0006676022-17.51350.0003-17.49880.0003-17.51440.0003-13.2036 .. -16.49100.0033 .. 0.0005-17.51180.0003-17.49880.0003-4.0448-11.92321316.30538.65126217.469992389.70.064.5588.099405e-058.729097e-05102971746530423720317816729.242.505.280.7199893542799.24399893542799.2431.012528e+072911.335191172.9 .. 3948118584.841 .. 1915.6552042.695214.7015.2066121064e+001.0815026130e+02-5.6963231037e-02-90.00.00110.000989.97.4104895621e-071.1675932674e-061.9696284927e-083.719 .. 22.7139629473.03627e-072.410763e-07-87.810.4000.00342.2820.00100.0029212419.450149e-070.00063931652.804898e-0789.71.0020437010e-061.1318135079e-055.4623076615e-084.1192.3831.010962e+072991.67127.846247
2465.380121.9192.1689073057e+021.6797018546e+0166122-89.016.79701911.3250237361e+002.1440943129e+00-9.7237642208e-030.00041154210.0003232088-15.55040.0008-15.51370.0007-15.55260.0008-13.1979 .. -15.51720.0034 .. 0.0007-15.53960.0007-15.51370.0007-3.9759-11.92041302.12842.14668216.8907428-89.30.921.3742.684059e-053.164199e-0534823413586564232252.172.503.960.9916050651061.00716050651061.00716601241192.634190185.4 .. 1610221589.9341 .. 1068.22965.338121.9222.8985469346e+005.4736777658e+00-2.9297647083e-02-89.30.00090.000889.16.1528742993e-077.8340161585e-07-2.8935308061e-091.477 .. 4.4772583012.487633e-072.202488e-0788.82.3400.00281.7020.00210.00065755827.742271e-070.00047802775.778505e-0789.74.2348475924e-067.5889872594e-061.8240460563e-081.4641.15116438421118.45927.824438
30983.16638.5582.1715994445e+021.6819311393e+019833955.316.81929261.1139941515e+001.1306721510e+004.0566587761e-020.00030289370.0002918463-11.03970.0146-10.97700.0141-11.12720.0167-9.3016 .. -10.90050.0196 .. 0.0132-11.33120.0257-10.97700.0141-4.0448-8.21821296.62341.99482217.159906950.8-37.721.1798.894391e-061.054733e-051138349292014742.742.707.260.0324591.92319.063624591.92319.063626055.44349.90355255.96 .. 22919.0495.0915 .. 278.9724983.29438.4914.4003347820e+005.3312111907e+006.4142420463e-0163.00.00980.0097-52.39.5226090170e-059.5668119409e-055.8885196793e-071.121 .. 5.7742922.752732e-062.732792e-06-62.02.3790.04902.0180.03930.00066800261.376218e-050.00056648131.10276e-0564.01.7084132417e-032.2366507334e-033.3831831693e-041.0791.04034078.66806.372427.827711
424347.43511.8802.1697360841e+021.6827481128e+013471216.616.82762401.0355505696e+019.4271396643e+006.2975688637e-010.00091723580.0008479064-12.45400.0077-12.41150.0076-12.53340.0085-8.9267 .. -11.57080.0262 .. 0.0079-12.47400.0142-12.41150.0076-4.0448-7.85151296.03938.57433216.973596026.8-62.701.2503.667952e-053.959184e-05466397296189124692278.312.505.940.0292170.45644.940292170.45644.940295853.72682.35173721.011 .. 42494.7489.64857 .. 309.8721347.47912.3882.5359695764e+012.0887850756e+014.5488104494e+0031.90.01760.0174-27.33.0953533623e-043.0234345647e-042.3611621748e-063.193 .. 11.88024534.944153e-064.880243e-06-18.15.3100.05074.2490.03960.0014909451.425063e-050.001193481.112322e-0533.02.2771986388e-031.8666918714e-034.5979305959e-043.2673.01897637.421273.24227.829847
501419.64416.5432.1728782282e+021.6824814907e+0114201752.916.82480904.4178439291e-014.3311540951e-017.1139474826e-030.00018731060.0001839508-13.30290.0024-13.25590.0022-13.30750.0025-12.3278 .. -13.29720.0040 .. 0.0023-13.29950.0024-13.25590.0022-4.0448-11.21561298.33342.10085217.287823629.3-57.811.0116.926605e-067.792431e-068867463223151141.982.503.960.98200614.2397.3951200614.2397.3951209490.2465.555485333.2 .. 208391.3312.4908 .. 447.75141419.64216.5221.7794715373e+001.7409274455e+00-1.8805991238e-03-2.80.00140.0014-32.21.8508188539e-061.8686180321e-063.1349550057e-080.764 .. 3.0822873.862136e-073.79287e-07-56.21.3340.00451.3190.00450.00037405431.255708e-060.00037069391.250092e-0649.41.9914545968e-051.9937354494e-057.4353676281e-080.6680.655208834.9453.907727.834558
60514.56410.7062.1702260024e+021.6827724383e+0151411-62.416.82774985.9142447503e-016.5556088470e-01-1.0051526135e-010.00023985090.0002020227-7.29300.1261-7.66310.1285-7.75330.1569-6.4307 .. -7.91120.1572 .. 0.1874-7.65280.1402-7.66310.1285-4.0448-5.55311294.7442.08438217.0225999-53.836.081.4336.296913e-078.658256e-07866653222.933.233.500.571162.136137.53691162.136137.5369826.418795.98862373.4989 .. 1460.42154.04912 .. 251.9493514.56510.7967.9410111742e-017.4420238692e-01-2.6412677874e-01-42.30.08330.082853.96.8785857821e-036.9232021883e-03-3.1993471041e-050.880 .. 2.906272.340519e-052.325019e-0566.91.0170.14980.7100.09970.0002855934.205139e-050.00019934892.79971e-05-41.11.7033715173e-021.5332180723e-02-6.1888949186e-030.8540.7201151.076148.574127.824036
716681.2126.8262.1707146999e+021.6828635858e+0168176.916.82862564.4507014800e-014.3518368289e-013.2035187791e-030.00018740130.0001851478-11.22040.0085-11.18530.0075-11.23800.0089-10.2205 .. -11.22990.0119 .. 0.0101-11.23530.0110-11.18530.0075-4.0448-9.37731297.52942.13911217.071457716.5-71.571.0273.069745e-063.778148e-0639312418139631.882.504.620.9829792.91206.591829792.91206.591830771.28241.591112251.4 .. 31041.84134.256 .. 288.1205681.2546.7891.5324851307e+001.4617770069e+00-1.9257480957e-02-14.30.00410.0040-18.41.6616793079e-051.6305715315e-053.8301279627e-080.695 .. 2.9582451.143899e-061.134507e-06-8.11.2400.01431.2070.01340.00034792224.016769e-060.00033913543.754562e-06-15.32.0308719233e-041.8039068319e-04-6.7193523572e-060.6680.65931196.84314.96327.82548
8171702.2023.9952.1737056495e+021.6827823624e+0117024-88.316.82785563.9485783164e-015.0578787752e-01-1.8279240727e-020.00020038510.0001754766-7.46130.1046-7.48520.1071-7.74600.1312-6.6235 .. -7.86580.1366 .. 0.1884-8.09940.1722-7.74600.1312-4.0448-5.65561296.54642.34091217.3706056-80.99.301.2057.084028e-077.871142e-07987444412.312.507.260.021254.308151.5553986.457297.26327964.976992.93609446.0672 .. 1400.67756.11121 .. 243.02241702.0644.1105.4506024457e-017.8801548301e-01-1.7972054473e-02-85.80.06110.060880.73.7027137114e-033.7375703017e-03-1.0604899876e-060.689 .. 1.909281.717515e-051.705734e-0588.60.8880.11280.7370.08930.00024960913.168354e-050.00020668522.503702e-05-89.07.9794737455e-031.2717063303e-02-8.6559355843e-050.7130.6261736.771275.43127.84032
9161462.9554.0412.1730049055e+021.6828159935e+0114634-7.016.82825044.3208523858e-013.0241714646e-01-5.3747741519e-020.00018838990.0001494983-6.29740.2121-6.29740.2121-6.90740.2528-5.8143 .. -3.96900.2687 .. 6.8096-4.68702.9836-6.29740.2121-4.0448-4.98181298.29942.09095217.3005322-19.870.281.6883.148457e-073.935571e-07444332113.372.507.260.19330.337564.52986330.337564.52986330.337564.52986211.7029 .. 38.6908352.38777 .. 242.60621462.8154.3645.1806758222e-012.3159829416e-01-1.0915492893e-01-18.70.10280.101919.71.0560099709e-021.0381090241e-02-2.2266092367e-050.610 .. 1.299002.881802e-052.862082e-058.80.7450.20150.4410.11660.00020881595.649244e-050.00012412153.281079e-05-18.53.7883472443e-021.6338130602e-02-8.1444611907e-030.6720.53274.95251205.921427.834024
....................................................................................................................................................................................................................................................................................
36680633.1493001.5702.1705290781e+021.5987372267e+01633300288.015.98738333.1695085312e-013.1255683988e-011.4692101828e-020.00016095680.0001538191-6.44160.1860-6.44500.2178-6.89660.2317-5.9800 .. -6.94400.2301 .. 0.4540-6.99820.2588-6.44500.2178-4.0524-5.09981314.17942.02858217.052900940.7-48.821.6143.935571e-073.935571e-07543332212.352.725.280.52378.456575.90158378.456575.90158377.254364.59866246.6039 .. 599.249852.23959 .. 250.5046633.1733001.6094.9827473314e-012.3816529236e-01-9.9857172373e-02-18.80.10090.0940-41.28.8338777886e-031.0188009690e-024.8218427149e-050.590 .. 1.351002.833521e-052.636368e-05-89.00.7300.19580.4520.11330.00020467435.491983e-050.00012687453.180012e-05-18.43.5768722370e-021.5379015370e-02-7.6515311048e-030.5740.548629.93150.108527.823418
366901349.1982992.6682.1726180192e+021.5989050378e+011349299330.215.98904524.9992717193e-014.5168815976e-011.2350089568e-020.00019873970.0001880702-9.02940.0381-9.02400.0390-9.12520.0438-8.0382 .. -9.08870.0447 .. 0.0651-9.07470.0656-9.02400.0390-4.0516-7.10571311.01142.62583217.261789213.6-76.851.1301.495517e-061.731651e-061916141176322.192.504.620.434069.963146.12934069.963146.12934090.453143.33821641.714 .. 4320.16367.5742 .. 258.88811349.2422992.6491.2627686357e+001.0631121646e+001.0036056951e-0122.60.02030.0202-13.14.1143877142e-044.1013433214e-041.1465648627e-060.759 .. 2.6652205.687514e-065.682804e-06-28.61.1420.05291.0110.04380.00032006761.481833e-050.00028376981.229285e-0525.42.6345776193e-032.0781525143e-033.4015252068e-040.7090.6704264.755257.68127.827106
36700480.2573026.5872.1700821869e+021.5980538406e+014803027-59.215.98051495.7886289965e-016.1019401366e-011.6653773775e-020.00022041080.0002122875-8.63070.0540-8.62120.0556-8.81170.0659-7.4545 .. -8.75050.0691 .. 0.0869-8.74530.1027-8.62120.0556-4.0517-6.38751315.90741.89695217.008246266.6-21.921.1751.416806e-061.810363e-061818121087442.522.505.280.202808.468143.67862808.468143.67862833.177140.9358958.993 .. 3163.67761.0404 .. 253.008480.1623026.5041.1833870985e+001.3657640267e+001.8268373761e-0158.30.03330.0332-68.11.1049152686e-031.1082441067e-03-3.0670787409e-060.843 .. 2.8652159.358972e-069.312046e-0657.31.2160.08111.0350.06490.00034102022.274565e-050.00029061061.821759e-0560.34.7891089193e-035.9949305356e-031.0218168574e-030.7860.7563148.517297.79927.822645
36710438.9923038.1342.1699621435e+021.5977296508e+01439303825.715.97731367.7328533035e-017.8177881138e-01-7.5047803371e-030.00024906440.0002458616-9.08590.0409-9.14740.0432-9.22660.0488-7.7208 .. -9.21700.0579 .. 0.0570-9.35460.0749-9.14740.0432-4.0339-6.80081317.02141.98452216.9961863-59.831.241.0252.20392e-062.361342e-062821171298412.742.695.940.024559.762181.21954559.762181.21954308.801162.44831225.493 .. 4862.0165.30345 .. 255.2488439.0893038.1951.5606822514e+001.6401189355e+00-3.6946528436e-03-87.30.02830.028258.87.9751264753e-047.9493136342e-041.6213178333e-060.945 .. 3.4592247.923373e-067.914764e-06-7.21.2810.06221.2490.05950.00035957681.744968e-050.00035044171.66874e-0577.73.5496666568e-033.8518509101e-036.9061212639e-050.8870.8775518.571380.483227.822363
367201200.9232973.8692.1721859432e+021.5994474845e+0112012974-63.215.99450884.6180383224e-015.2668444271e-01-1.0539288851e-010.00021836730.0001735725-6.72420.1707-6.72420.1707-7.26930.2079-5.8372 .. -6.95280.2663 .. 0.4545-7.07980.2780-6.72420.1707-4.0463-4.86701312.25542.37002217.2185822-53.636.561.6775.509799e-075.509799e-07766643324.052.505.280.00489.399476.93464489.399476.93464489.399476.93464216.2127 .. 604.098453.01835 .. 252.79751200.9652973.9905.2971578939e-015.3752872920e-01-2.5352386331e-01-45.40.11100.110153.41.2166436645e-021.2286774291e-02-8.1456611196e-050.684 .. 1.641003.118279e-053.085466e-0562.10.8870.19900.5290.11520.00024910665.587126e-050.00014823643.227017e-05-45.02.6453803700e-022.6419403872e-02-1.3164182300e-020.7780.620679.0667173.811827.827667
367301900.7142959.8482.1742267631e+021.5997509267e+011901296014.815.99749854.5932568139e-013.8612735148e-017.2142228876e-020.00019877120.0001641378-6.73990.1625-6.86680.1560-7.15260.2036-6.0360 .. -6.72820.2293 .. 0.5789-6.64870.5401-6.86680.1560-4.0414-5.06271311.32743.96854217.422654231.6-58.191.3314.722685e-074.722685e-07666652223.232.506.600.03558.088780.1562558.088780.1562496.534574.28085259.6469 .. 491.227954.82244 .. 261.86921900.7902959.8094.3497144686e-014.2454665016e-011.1960471761e-0143.80.09840.0974-31.89.6633230034e-039.5040439447e-034.5268400738e-050.690 .. 1.647002.754936e-052.735004e-05-9.90.7410.15940.5570.11760.00020763164.464085e-050.00015634813.302552e-0544.81.9652602964e-021.9579179721e-025.7833329226e-030.7100.585456.535227.047127.843845
36740871.1562991.5052.1712236874e+021.5989970172e+01871299285.115.98995014.9720379341e-014.8758384034e-012.1765163686e-030.00019778640.0001959698-12.29290.0045-12.25270.0039-12.30240.0046-11.2074 .. -12.29170.0071 .. 0.0045-12.29470.0046-12.25270.0039-4.0436-10.20121313.71342.29378217.122358812.2-81.751.0124.958819e-065.982068e-06635037291914842.002.503.960.9879630.47286.212379630.47286.212382632.88340.419730407.3 .. 82544.04197.4957 .. 343.8496871.1902991.4331.8141462940e+001.7979999553e+00-1.9700869937e-02-33.90.00240.0024-8.25.5529471103e-065.7751211695e-061.9021598322e-080.778 .. 3.2502636.745829e-076.60849e-07-88.21.3520.00841.3360.00820.0003795592.351123e-060.00037455682.304393e-06-52.06.8537264998e-056.9134038145e-05-1.2020153741e-060.7050.69882773.5353.251627.826073
367531023.8663017.4372.1716687006e+021.5982508284e+0110243017-55.315.98249477.2083494020e-017.9105130729e-01-5.0721378004e-020.00025397090.0002334704-8.76540.0509-8.77220.0532-8.94700.0620-7.4321 .. -9.02740.0707 .. 0.0676-9.15390.0871-8.94700.0620-4.0783-6.30531311.42142.02868217.1668593-62.327.961.2361.731651e-062.046497e-062219161297533.732.565.940.013791.384216.58863227.564157.9613207.528150.2645939.3902 .. 4082.89961.14021 .. 254.33191023.9033017.3891.2382394949e+001.8311604932e+00-1.2183333173e-01-78.80.03600.035862.01.2849502077e-031.2896658597e-03-6.2798325948e-060.930 .. 3.0332221.010307e-051.002847e-0556.01.3620.08141.1020.06420.00038248962.284805e-050.00030878871.798708e-05-84.84.1383206015e-036.6020195367e-03-2.2747061376e-040.9040.8334587.294367.740627.82908
367601179.1593018.9572.1721207826e+021.5981892510e+011180301975.915.98188119.9507435525e-011.2667342814e+001.6175461849e-010.00032479730.0002692479-7.38590.1214-7.88000.1386-7.85150.1509-5.8273 .. -8.07590.2768 .. 0.1618-8.23150.1788-7.88000.1386-4.0774-5.24121310.86342.25343217.212149865.0-24.441.5887.084028e-079.44537e-07777664435.323.566.600.041419.085181.06341419.085181.0634900.2398100.6331214.2556 .. 1699.71454.61708 .. 253.28221178.9133018.9178.0612094546e-011.3013292107e+003.8236517990e-0161.50.12150.1210-65.61.4656128957e-021.4764826594e-022.9161487289e-051.274 .. 4.035263.410456e-053.394318e-0589.41.2290.18660.7730.11180.00034434845.229758e-050.00021736633.141866e-0561.21.7673829008e-022.9631894207e-029.4240517764e-031.1590.9591961.532322.996427.8279
367701662.3273030.1112.1735296976e+021.5978082454e+011662303060.115.97811985.3105649862e-015.8383334448e-01-1.5526484766e-020.00021531520.0002033029-7.52250.1086-7.75320.1275-7.89010.1367-6.6035 .. -7.93570.1379 .. 0.1860-7.93540.2174-7.75320.1275-4.0387-5.88461310.83142.66018217.3530129-74.816.201.1947.871142e-079.44537e-071087522112.563.226.600.541262.682148.2071262.682148.2071020.894102.1292437.9241 .. 1493.69255.60824 .. 255.82421662.1803030.2457.5889562155e-018.6272534715e-01-1.3242078747e-01-55.70.07460.074473.85.5481008954e-035.5591019851e-039.4166956312e-060.766 .. 3.179282.092381e-052.087486e-0582.40.9760.12720.8180.10220.00027415463.57211e-050.00022893632.861356e-05-54.81.2348910210e-021.4276510853e-02-2.7003988950e-030.7670.7261493.354298.898627.834106

Now, let's create a coordinates object to represent the target that we are searching for:

In [100]:
target_coord = astropy.coordinates.SkyCoord(
'14h29m14.781s +15d46m26.385s')
target_coord

Out[100]:
<SkyCoord (ICRS): (ra, dec) in deg
(217.3115875, 15.77399583)>

Now, let's match this position against the source catalog:

In [101]:
# Coordinates of objects in catalog
catalog_coords = astropy.coordinates.SkyCoord(
ra=catalog_table['ALPHAWIN_J2000'],
dec=catalog_table['DELTAWIN_J2000'])

# Do source matching
index, separation, distance = target_coord.match_to_catalog_sky(catalog_coords)
index, separation

Out[101]:
(array(3259), <Angle [4.20500043e-06] deg>)

Here is the closest-matching row:

In [102]:
index = np.asscalar(index)
matching_row = catalog_table[index]

In [103]:
plt.figure(figsize=(10, 10))
plt.imshow(hdu.data, vmin=mean-std, vmax=mean+3*std, cmap='binary', interpolation='nearest')
plt.xlim(matching_row['XWIN_IMAGE'] - 64, matching_row['XWIN_IMAGE'] + 64)
plt.ylim(matching_row['YWIN_IMAGE'] - 64, matching_row['YWIN_IMAGE'] + 64)

# I happen to know that these images are upside down; use APLPy or the like to
# automatically orient North upward
plt.gca().invert_yaxis()

plt.xlabel('pixel $x$')
plt.ylabel('pixel $y$')

Out[103]:
Text(0,0.5,'pixel $y$')

Let's calibrate the Sextractor photometry. We'll query the PTF photometric calibrator catalog at IRSA using Astroquery...

In [104]:
from astroquery.irsa import Irsa

calib_table = Irsa.query_region(
target_coord,
catalog='ptfphotcalcat',
calib_table

Out[104]:
degdegmagmagmagmagarcsecdeg
float64float64objectobjectobjectobjectfloat64float64float64float64float64float64float64objectobjectobjectfloat64float64object
217.31115.77214h29m14.59s15d46m19.51s950.0218.0510.0320.0220.042-0.930.11634861117.428213201.9365920
217.29815.76014h29m11.60s15d45m35.21s950.0215.7420.0110.0160.006-0.0080.109348611168.740981221.8722191
217.32615.78914h29m18.12s15d47m19.13s950.0215.2090.0070.0070.007-0.0030.059348611171.44111542.430062
217.29115.77014h29m09.80s15d46m13.63s950.0217.9420.0230.0350.01-0.3990.077348611172.972506259.9220783
217.31615.75314h29m15.86s15d45m09.99s950.0216.1880.010.0060.0150.0380.085348611177.979509168.4844824
217.29415.78814h29m10.52s15d47m18.12s950.0218.1020.0440.050.038-1.1590.09348611180.340374310.0763745
217.34215.78114h29m22.06s15d46m52.22s950.0218.7220.0310.0240.039-0.0290.1073486111108.25466776.1956356
217.29915.80214h29m11.65s15d48m07.24s950.0216.7280.0160.0010.0320.010.0943486111110.518047335.8446417
217.28015.76914h29m07.21s15d46m06.83s850.0218.5810.0280.0130.0430.0180.0893486111111.05929259.8552918
217.27915.75514h29m07.01s15d45m18.12s950.0218.20.0230.0060.04-0.3570.0823486111131.381738238.6893579
217.29315.80714h29m10.39s15d48m24.89s950.0214.5980.0080.0030.013-0.0430.0933486111134.386258331.84919510
217.27115.76814h29m04.98s15d46m03.62s950.0217.7620.0290.0230.036-0.5530.0933486111143.252977260.856711
217.34415.74914h29m22.58s15d44m57.72s950.0218.2720.030.0260.033-0.6320.1033486111143.308281128.2257912
217.26815.76814h29m04.35s15d46m05.74s950.0218.2980.0270.0390.015-0.2710.1023486111152.001619262.19258613
217.27915.74614h29m06.85s15d44m45.74s950.0217.7510.0210.0270.0150.050.0873486111152.512542228.70215814
217.27515.74514h29m05.90s15d44m42.06s950.0218.210.0270.0250.030.0630.1283486111165.322266230.87034415
217.29615.73014h29m11.02s15d43m47.69s950.0215.4870.0110.0030.0180.0010.13486111167.738282198.89024316
217.34915.80714h29m23.79s15d48m23.43s950.0217.520.0190.0190.0190.0040.083486111174.98033548.02110317
217.32315.82614h29m17.40s15d49m34.13s840.0218.7590.0370.0180.056-0.0460.0923486111191.51262411.4007918

Let's look at where these are in relation to are target. We'll need to convert the RA, Dec in the table to pixel coordinates. That's where the World Coordinate System (WCS) transformation comes in.

In [105]:
wcs = astropy.wcs.WCS(hdu.header)

WARNING: FITSFixedWarning: RADECSYS= 'ICRS ' / Astrometric system
the RADECSYS keyword is deprecated, use RADESYSa. [astropy.wcs.wcs]
WARNING: FITSFixedWarning: Removed redundant SCAMP distortion parameters because SIP parameters are also present [astropy.wcs.wcs]

In [106]:
plt.figure(figsize=(10, 10))
ax = plt.axes(projection=wcs)
ax.imshow(hdu.data, vmin=mean-std, vmax=mean+3*std, cmap='binary')
ax.set_xlim(matching_row['XWIN_IMAGE'] - 256, matching_row['XWIN_IMAGE'] + 256)
ax.set_ylim(matching_row['YWIN_IMAGE'] - 256, matching_row['YWIN_IMAGE'] + 256)

# Note: last argument is 'origin': FITS standard uses 1-based Fortran-like
# indexing, but Python uses 0-based C-like indexing. In this case, we are
# aligning these locations to a Python array, so we want 0-based indexing.

x, y = wcs.all_world2pix(calib_table['ra'], calib_table['dec'], 0)
ax.scatter(x, y, facecolor='none', edgecolor='red')

# I happen to know that these images are upside down; use APLPy or the like to
# automatically orient North upward
ax.invert_yaxis()

ax.set_xlabel('pixel $x$')
ax.set_ylabel('pixel $y$')