CaliCompari

Compare spectra with reference spectrum.


License
Other
Install
pip install CaliCompari==0.0.3

Documentation

CaliCompari

This repository holds code that allows for relative wavelength calibration comparison between two spectra.

Some helpful links:

Supercalibration Cookbook

This should provide reasonably helpful instructions for how do the solar (either asteroid or solar twin) supercalibration method on UVES exposures. There's a bit at the end which talks of the slight difference between iodine and solar methods (namely you have to point to the correct reference spectrum).

Annoying bit

Getting set up. I do everything in the bash shell, so you might have to make adjustments occasionally if you use something else.

Clone astrotools and add astrotools to PATH:

cd ~/github/
git clone https://github.com/jbwhit/AstroTools.git

# add this to your .bashrc (or equivalent .cshrc)
export PATH=${PATH}:/your-user/path/AstroTools/

Clone supercalibration and add to PYTHONPATH:

cd ~/github/
git clone https://github.com/jbwhit/CaliCompari.git

# add supercal/Python to PYTHONPATH
export PYTHONPATH=${PYTHONPATH}:/your/user/github/CaliCompari/Python

Test that the above commands work by opening a new terminal:

$ supercalibrate

Which should produce the following output and finish without running anything interesting:

test.analysis.p
test.analysis.p test.analysis.header
No header_file found.
cali_500_test.analysis.gz
Not a fits file. test.analysis.p
Consider saving a faster-loading calibration file.

It might fail for several reasons. The first is the python path being incorrect. Another is that several non-standard packages are also required, so try running the following commands. (If you are running OSX 10.9.2 see note below this list):

# try without sudo first, if needed include it; remove brackets
[sudo] pip install -U iminuit
[sudo] pip install -U barak
[sudo] pip install -U pyfits

Note from Julija Bagdonaite if installing iminuit and barak on OSX 10.9.2:

sudo ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future pip install iminuit
sudo ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future pip install barak

Start an instance of python and type:

import calicompari

If it's working it should return you to the python interpreter without an error.

Finally, you need to install UVES_popler with a version that runs with the following options (look for -atmomask):

Mode options:
 -replay     =       0    : Use interactive action replay mode
 -macmap [FILE]           : Read file to map pipeline product path and file names
                             between case-sensitive and case-insensitive operating
                             systems, e.g. Mac and linux.
 -vshift [FILE]           : Read file to apply a velocity shift to each spectrum.
                             File should specify full path name of each file to be
                             shifted, followed by the velocity shift in km/s.
 -atmomask [FILE]         : Read file to mask spectra for atmospheric/telluric
                             features. File should have format: wav. start, wav. end
                             [Ang.], residual intensity, wav. center [Ang.].
                             Wavelengths are in vacuum.
 -distort                 : Apply a random velocity shift, drift and distortion to
                             each echelle order. Use this flag to remove previously
                             applied distortions saved in UPL file.
 -h, -help                : Print this message.

After all of that, you should be ready to start.

Fun bit

I promised a fun bit, but a few more words first. I developed these scripts after working for a long time and running into many problems. A lot of things are dependent on how I set up all kinds files, so if you go changing things please know that stuff might start to break. The good news is that when it breaks, it usually breaks loudly.

The main piece of code you will be using (though initially not directly) is the calicompari python module.

The first thing to keep in mind that there are two main types of supercalibration: Iodine and Solar whose only difference is in which reference spectrum you use (included in the calicompari).

Also, there are two main spectrographs: UVES and HIRES (which matters when preparing the data to be fed to UVES_popler).

An example solar UVES supercal

It should be able to do this in your reduction directory, however, I think the following is an example of the minimum files needed to supercalibrate two exposures.

ls
err_hip102793_sci_564_01_l.fits      fxb_hip102793_sci_564_01_l.fits
err_hip102793_sci_564_01_u.fits      fxb_hip102793_sci_564_01_u.fits
err_hip102793_sci_564_02_l.fits      fxb_hip102793_sci_564_02_l.fits
err_hip102793_sci_564_02_u.fits      fxb_hip102793_sci_564_02_u.fits
errthar_hip102793_sci_564_01_l.fits  hip102793_sci_564_01.fits
errthar_hip102793_sci_564_01_u.fits  hip102793_sci_564_02.fits
errthar_hip102793_sci_564_02_l.fits  thar_wav_564_01_01.fits
errthar_hip102793_sci_564_02_u.fits  thar_wav_564_02_01.fits
errwhip102793_sci_564_01_l.fits      wpol_hip102793_sci_564_01_l.fits
errwhip102793_sci_564_01_u.fits      wpol_hip102793_sci_564_01_u.fits
errwhip102793_sci_564_02_l.fits      wpol_hip102793_sci_564_02_l.fits
errwhip102793_sci_564_02_u.fits      wpol_hip102793_sci_564_02_u.fits

First, get everything into a format that UVES_popler understands.

solar uves script

These lines assume that the folder the reduction is in is named same as science object. If that's not the case, change this part. Also, the grep -v _up_ command makes it clean to re-run.

sciencename=${PWD##*/}
echo $sciencename
ls $PWD/fxb_* | grep -v _up_ > ${sciencename}_red.list

UVES_popler takes a file that is a list absolute paths to the science exposures to be reduced. The atmomask.dat file is included in the AstroTools repository, so link to that file if the next command fails.

popler-uves-iodine ${sciencename}_red.list

popler-uves-iodine is an astrotools script that does the following:

#!/bin/bash
# Takes the inputfiles.list (full paths)
# CPL reduced, iodine exposure

# Checks if telluric lines a system variable.

if [ -z "$POPLER_TELLURIC" ]
then
    echo "Please set up sky lines environment variable."
    echo "POPLER_TELLURIC=\"path_to_telluric.dat\""
    echo "export POPLER_TELLURIC"
    exit
else
    UVES_popler $1 -raw -save 2 -helio -atmomask $POPLER_TELLURIC -disp 1.30
fi

The final command popler's the list of files, and saves in a special format -raw and immediately exists after creating those files -save 2. It is not heliocentric corrected -helio, and an atmospheric mask is given (I've forced mine to be a shell variable, and to throw an error if it isn't set). Finally, there is a -disp 1.30 which should be ignored in principle because the -raw format gives the spectrum pixel-by-pixel without any merging or redispersing. [Michael if any of this is wrong, please let me know].

The new files created are named:

ls fxb_hip102793_sci_564_0*up*
fxb_hip102793_sci_564_01_l_up_001.fits  fxb_hip102793_sci_564_02_l_up_003.fits
fxb_hip102793_sci_564_01_u_up_002.fits  fxb_hip102793_sci_564_02_u_up_004.fits

I often look at a large collection of these files, which makes this naming convention unhelpful overall. So I cp these files to something that tells me extra info that I find useful.

for infile in fxb*up_*fits;
do
    newname=$(echo $(dfits $infile | fitsort -d OBSDATE) | awk '{print substr($2,0,10)"-"$1}')
    cp $infile $newname
done

So they are now named by ISO 8601 date of observation:

2004-03-28-fxb_hip102793_sci_564_01_l_up_001.fits
2004-03-28-fxb_hip102793_sci_564_01_u_up_002.fits
2004-03-28-fxb_hip102793_sci_564_02_l_up_003.fits
2004-03-28-fxb_hip102793_sci_564_02_u_up_004.fits

Now they are named so that I can look at hundreds of these files in a single directory and know at a glance when they were taken. Now, I would like to know exactly which raw science and arc files were used to create this final data product. So, I grab the headers from each of those raw files and put it into a similarly named file with the suffix: .header via the arc-flux-uvesheader script.

for infile in [1,2]*_up_*fits;
do
    arc-flux-uvesheader $infile
done

The arc-flux-uvesheader looks like:

#!/usr/bin/env python
import pyfits as pf
import cPickle as pickle
import gzip
import sys
import re
from glob import glob

# Usage: feed in popler'ed _up_ file (done for MAKEE)
# arc-flux-header 2009-11-03-Flux-199_1-Hiltner600-11-_up_009.fits
# print re.split('_|-', start)

popler_file = sys.argv[1]

globarc = glob("thar_wav*" + "_".join(re.split('_|-', popler_file)[6:8]) + "*.fits")
globflux = glob("*".join(re.split('_|-', popler_file)[4:8]) + "*.fits")

if len(globarc) > 1 or len(globarc) == 0:
    print globarc, "thar_wav*" + "_".join(re.split('_|-', popler_file)[6:8]) + "*.fits"
    raise Exception("Too many (or few) arc files found.")

if len(globflux) > 1 or len(globflux) == 0:
    print globflux, "*".join(re.split('_|-', popler_file)[4:8]) + "*.fits"
    raise Exception("Too many (or few) flux files found.")

arc_file, flux_file = globarc[0], globflux[0]

print "Arc:", arc_file
print "Flux:", flux_file

outfile = '.'.join(popler_file.split('.')[:-1])
outfile = outfile + ".header"
print outfile

arc_hdu = pf.open(arc_file)
arc_header = {}
for key, value in arc_hdu[0].header.iteritems():
    arc_header[key] = value

flux_hdu = pf.open(flux_file)
flux_header = {}
for key, value in flux_hdu[0].header.iteritems():
    flux_header[key] = value

list_of_dictionaries = [arc_header, flux_header]

with gzip.open(outfile, 'wb') as file_handle:
    pickle.dump(list_of_dictionaries, file_handle, pickle.HIGHEST_PROTOCOL)

I make a link to the atmospheric sky line-list [this is so that when I run my script it also mask out sky lines or any other lines if you happen to know a star has a strong feature somewhere].

ln -s /home/jwhitmor/github/CaliCompari/Info/config.wavekill .

Second to last step, because it's solar, I create the run.1.bash script.

for infile in [1,2]*_up_*fits;
do
    echo supercalibrate $infile ~/github/CaliCompari/FTS/KPNO2010.contin.ascii
done > run.1.bash

The only thing left to do here is to run:

bash run.1.bash

Or, if you are sneaky, something like:

cat run.1.bash | parallel -j-8 --nice 15

The final files which are named things like:

cali_500_2004-03-28-fxb_hip102793_sci_564_01_l_up_001.gz
cali_500_2004-03-28-fxb_hip102793_sci_564_01_u_up_002.gz
cali_500_2004-03-28-fxb_hip102793_sci_564_02_l_up_003.gz
cali_500_2004-03-28-fxb_hip102793_sci_564_02_u_up_004.gz
small_cali_500_2004-03-28-fxb_hip102793_sci_564_01_l_up_001.gz
small_cali_500_2004-03-28-fxb_hip102793_sci_564_01_u_up_002.gz
small_cali_500_2004-03-28-fxb_hip102793_sci_564_02_l_up_003.gz
small_cali_500_2004-03-28-fxb_hip102793_sci_564_02_u_up_004.gz

If you have gotten to this point, you've overcome the tricky part, and you've graduated to the slightly tedious step. Good luck.

To recap, if everything works perfectly:

###########################
# UVES SOLAR

sciencename=${PWD##*/}
echo $sciencename
ls $PWD/fxb_* | grep -v _up_ > ${sciencename}_red.list

popler-uves-iodine ${sciencename}_red.list

for infile in fxb*up_*fits;
do
    newname=$(echo $(dfits $infile | fitsort -d OBSDATE) | awk '{print substr($2,0,10)"-"$1}')
    cp $infile $newname
done

for infile in [1,2]*_up_*fits;
do
    arc-flux-uvesheader $infile
done

ln -s /home/jwhitmor/github/CaliCompari/Info/config.wavekill .

for infile in [1,2]*_up_*fits;
do
    echo supercalibrate $infile /home/jwhitmor/github/CaliCompari/FTS/KPNO2010.contin.ascii
done > run.1.bash

bash run.1.bash

And if doing an iodine exposure:

###########################
# UVES Iodine

sciencename=${PWD##*/}
echo $sciencename
ls $PWD/fxb_* | grep -v _up_ > ${sciencename}_red.list

popler-uves-iodine ${sciencename}_red.list

for infile in fxb*up_*fits;
do
    newname=$(echo $(dfits $infile | fitsort -d OBSDATE) | awk '{print substr($2,0,10)"-"$1}')
    cp $infile $newname
done

for infile in [1,2]*_up_*fits;
do
    arc-flux-uvesheader $infile
done

ln -s /home/jwhitmor/github/CaliCompari/Info/config.wavekill .

for infile in [1,2]*_up_*fits;
do
    echo supercalibrate $infile /home/jwhitmor/github/CaliCompari/FTS/vlt.2013-12-07.txt.gz
done > run.1.bash

bash run.1.bash

Part Two

From here on out, I recommend using the ipython notebook. It's a fantastic tool that allows for seamless data plotting and interaction. An example what this looks like is given here.

[sudo] pip install -U ipython

If you don't do use ipython, I have provided an example script in the AstroTools package called: interactive-supercal which takes a file like:

interactive-supercal small_cali_500_2004-03-12-fxb_hip67534_sci_564_01_l_up_001.gz

And allows you to plot the results. Make a copy of this script for each file if you are going to use this script in this way. I strongly suggest using the ipython notebook method.