# The standard fare:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline

# Recall our use of this module to work with FITS files in Lab 4:
from astropy.io import fits 

#A dummy image - just a Gaussian PSF with a standard deviation of 5 pixels
import astropy.convolution as conv
gauss = conv.Gaussian2DKernel(stddev=5)

gauss.shape

"""
Explanation: Lab 8 - Image Analysis and Padding
Part 1 - Pyraf Imexam Tutorial
You'll be creating a lot of image files in this lab that you will need to include with your submission. To make your life easy, create a directory and move your Jupyter notebook file into it before beginning. Save all images to this directory, which you will zip before you submit it to Moodle 
Start up pyraf, which should already be installed on your machines, by opening a terminal and typing in the following two commands
source activate iraf27
pyraf  
A pyraf instance will start and you will have a new prompt that looks like this: -->
Now open DS9 normally. 
Back in your pyraf window, type the following two commands.
display dev$pix 1
imexam  
An image of a spiral galaxy (M51?) will appear in DS9 and there will also be a round blinking cursor in the window. If this is the case, great - you can move on to the next step! If this is not the case, please ask Kim or Kate for help. 
Once you have a blinking cursor, with your mouse over the ds9 window type "q" on the keyboard to quit. You will not have your --> prompt back in the Pyraf window. 
Back in your DS9 window, choose your favorite Messier object and pull the DSS image up by clicking Analysis --> Image Servers --> DSS (SAO) and then entering your object. Make sure you pull up an image that has a fair number of stars. Save the image to your lab folder by clicking File --> Save Image --> FITS. Close DS9 and then reopen it and load in the image with File --> Open.  
Once your image is open in DS9, go back to your Pyraf terminal and type imexam again. You should once again have a round blinking cursor. 
Now let's investigate some of imexam's functionality. A basic list of commands are below. For all of them, you should center the blinking cursor on a star in the image before you click the one-letter command (you may wish to zoom and pan around in the image in order to do this effectively). The output of the command will appear in your Pyraf window or in a separate graphical window that will pop up. 
Exercise 1
For each of the commands below, execute it on several different stars in the image until you're absolutely sure that you know what it does. Once you're sure, for each command write:
(a) a description of what it does in your own words (more detailed than the short descriptions in the list below). If the function produces a plot, choose a representative one and take a screenshot with ctrl + shift + 4 and include it with your explanation
Note: The mac screenshot command will create a cursor that you have to drag to capture the part of the screen you want to save. Click in the upper left, hold down the mouse button, and drag to the lower right before releasing. Screenshots get saved by default to your desktop. Rename each one with something descriptive and place it in your lab folder. To include it in the markdown cell together with your explanation use the basic syntax ![caption](filename).
(b) an example of when you think this measurement might be useful   
Basic Imexam commands: 
a Aperture sum, with radius region_size
c Return column plot
e Return a contour plot in a region around the cursor
h Return a histogram in the region around the cursor
j 1D [Gaussian1D default] line fit
k 1D [Gaussian1D default] column fit
l Return line plot
m Square region stats, in [region_size],default is median
r Return the radial profile plot
s Surface plot in the region around the cursor
z prints grid of pixel values
This Markdown cell is for your explanations
Exercise 2
You may have noticed that the parameters for the things like the size of a region over which statistics are computed are set by default, but you can modify them. Generically, the command to do this is :epar + the letter of the command. For example :epar s allows you to modify the parameters of the surface plot function.  Generally this only works for functions that pop up a graphics window with a plot. 
Come up with one example of a (graphical) function above where you might want to modify the default parameters. Run the function with the default parameters on a certain star and then with your modified parameters. Include the otput of each and explain the advantages of modifying the parameters in words.  
 Your answers for exercise 2 go here
Exercise 3
For your purposes later in this class, it is also useful to know how to record the output of imexam as a text file. To do this, first quit imexam by typing q. At your regular Pyraf prompt, type epar imexam. This will open up a little gui with various parameters that you can set, much like when you used epar to modify the parameters for some of the functions within imexam. About a third of the way down, you'll see a prompt that says (logfile). If you enter a filename (e.g. log.txt) here, it will be associated with imexam. Enter log.txt as the logfile and click "Save and Quit" then restart imexam. Note that the output will not always be recorded to the text file by default. Rather, you need to toggle logging on and off with the command "w". 
Toggle the log on, record the "a" output for 20 different stars in your image, then toggle the log off and check the output. Include the log with the files that you hand in for this lab.  
 Your answers for Exercise 3 go here
Part 2 - Padding and Shifting Images
Once you've found the centers of stars in an image, as you did in your homework last week, you need to be able to shift all of the images in your sequence to line up. Ideally, you do this without losing any of the information at the edges of your detector. For example, if I had a 1024x1024 image and I shifted it by -1 pixel in x and -2 pixels in y, I'd be shifting some pixels with real information off of the edge of the array and the rightmost column and the topmost two columns would now be blank. To avoid this loss of information, we typically "pad" images before we shift them to a common orientation. In our case for the Smith telescope, since we don't dither, we don't need to pad our images by very much and can add a small strip around each one. Let's try it.
End of explanation
"""


newarr = np.pad(gauss,5,'constant', constant_values=-0.001)
newarr.shape

plt.imshow(newarr)
plt.colorbar()

"""
Explanation: Numpy has a really handy built-in function for padding images called pad. The required inputs are the array to be padded, the size of the pad region (in each direction), and the nature of the padding (lots of interpolation options are available, but we just need a constant value). The default for a constant value is to propagate the values at the edges outward, but we want in this case to draw a clear distinction between where we have data and where we don't, so we can set the padded region values to some specific constant value. Often astronomers pad arrays with either zeros or NaNs, but NaNs can be problematic when executing the next step (shifting the images) and zero is too close to the actual data values in our sample image below to stand out, so I've chosen an arbitrary value below based solely on its ability to stand out relative to the rest of the colorbar so that I can tell where the padded regions is.
End of explanation
"""


import scipy.ndimage.interpolation as interp

newarr2 = interp.shift(newarr,(2.5,4.5), cval=-0.001)

plt.imshow(newarr2)
plt.colorbar()

"""
Explanation: The next thing that we'd want to do with padded images is to shift the image to some common center so that it can be combined with other images.
End of explanation
"""


newarr2[newarr2 <= -0.0001] = np.nan

plt.imshow(newarr2)
plt.colorbar()

"""
Explanation: One last thing we may wish to do before combining is to replace our arbitrarily set constant pad values with NaNs so that when we combine images, these won't be treated as equal to the real values in the other parts of the array.  This replacement is pretty easy in python using the following handy syntax. Because the shifting of the array is done via interpolation, the padded region values will no longer all be exactly the same. For that reason, you will often need to tweak the value below which you choose to replace pixels with NaNs to coincide with the padded region. To wrap your brain around this a bit, try changing the value after the <= to 0.001 and/or 0.0005 below. Before doing so, you'll need to reexecute the cell above that contains newarr2 = interp.shift(newarr,(2.5,4.5), cval=-0.001) in order to refresh the array with a clean version. 
note that if you want to combine images with nans in numpy you need to use the special functions nanmean, nanmedian, etc. rather than just mean, median, etc.
End of explanation
"""


#your code goes here

"""
Explanation: Exercise 4
Take the image that you used for exercises 1-3 (or another of your choice), read it in, pad it by 25 pixels in each direction with the padded region set to some constant value that stands out relative to the real-valued array, shift it by +10.3 pixels in x and -15.8 pixels in y, replace the padded values with NaNs and display below.
End of explanation
"""


