Adjusting the wavelength calibration of spectra using night-sky lines

In some observing runs the arc-line calibrations are not reliable enough for precise radial-velocity work. This can happen when insufficient arc lamp spectra are taken during the night and the spectrograph has a significant amount of flexure. In particular, the WHT/ISIS spectrograph is quite wobbly but arc lamp exposures take a long time to obtain, so there are often a shortage of them.

When there are too few arc lamp spectra, it is quite straightforward to adjust the wavelength calibration according to the positions of night sky emission lines, which are very stable but also very variable in strength. In the case discussed here, a full wavelength calibration has been obtained from arc line spectra and applied to the science and sky spectra. The procedure is then to obtain a pixel shift from one specific emission line in each sky spectrum and apply it to the relevant science spectrum.

It is possible to rely totally on the sky spectrum for wavelength calibration (assuming there are sufficient sky lines). This procedure is discussed here.

Useful emission lines

Investigations of the night sky spectrum have been published by Osterbrock et al (1992, 1996, 1997, 2000; see bibliography below). You should refer to these papers for most details, but here is a list of emission lines which I have found useful:

4358.34     Hg I      weak - probably useless for exposure times below 15 minutes
5577.338    O I       strong emission line - can be relied upon
6300.304    O I       strong emission line - can be relied upon
7913.708    O I       reasonably strong and reliable
8344.602    O I       reasonably strong and reliable
8827.096    O I       reasonably strong

It is always a good idea to check your results using several lines if possible, as this will turn up any mistakes, problems with lines (whose strength can vary a lot due to the conditions), or difficulties with the spectrograph.

Calculating the pixel shifts

Getting radial velocity shifts: start molly and read in the sky spectra:

load  skyo.mol  1  1000  1

Firstly, the Vearth header item may still be in the molly sky spectra files. If it is, you must remove it because which is automatically applied to radial velocity results calculated by molly. Whilst this is important for the science spectra, which are of objects outside the Solar System, it is totally incorrect to apply it to flux coming from the Earth's atmosphere. To remove it you use the edit command to delete the double-precision Vearth header item:

edit  [first slot]  [last slot]

Now, for each sky spectrum, measure the position of the sky line using the command rvel. Print out the results to a file, give the rest wavelength of your sky line of interest (Ångstroms) and choose Core for your method. A search box of 200 km/s should be plenty, unless your spectrograph is extremely floppy. The Gaussian FWHM should be a bit larger than the width of the sky line (in km/s) - if the width is too low then you will get nasty pixellation effects. The command looks like this:

rvel  [first slot]  [last slot]  [filename]  [wavelength]  C  100.0  [Gaussian FWHM]

rvel will find the position of the sky line centre (by cross-correlating against a Gaussian function) in pixels. It then converts this to km/s (using the reciprocal dispersion - km/s per pixel - of the spectrum at the wavelength of the spectral line) and writes it to the file you specified.

Getting conversion between radial velocity and pixel shift: We expect the flexure in the spectrograph to be constant over the spectrum (assuming the pixels of the CCD are all of the same size) so we want the position of the sky line in pixels, not the km/s outputted by molly. To convert back to pixels, we need the reciprocal dispersion of the spectrum - km/s per pixel - around the spectral line.

In molly, print out the wavelengths of a group (e.g. ten) of pixels around the sky line using the type command. Work out the wavelength difference between the first and last of your group and divide it by the number of pixels in the group. This gives the wavelength interval of one pixel. Divide by the wavelength and multiply by the speed of light (300,000 km/s) to find the reciprocal dispersion (km/s per pixel). Using the average reciprocal dispersion of the whole spectrum (which molly prints out whenever you vbin a spectrum) is probably accurate enough in most cases, but it is better to be exact.

WARNING: sometimes the dispersion of the spectrum is negative (wavelengths decrease to higher pixel values). In this case your km/s per pixel value must also be negative, because if it is not the wavelength scale will be adjusted in the wrong direction. You can use the molly command flis to check this for a specific spectrum.

Converting radial velocity to pixel shift: the velocities outputted by molly need to be converted to pixel shifts using the reciprocal dispersion you have just calculated. This FORTRAN 77 code does so using the output file from molly:

      implicit none
      real*8 CRAP1(1000),CRAP2(1000),RV(1000),RVERR(1000),DISP
      integer i,ERROR,NRV
      character*40 INFILE,OUTFILE

      print*, "Enter the name of the file to read: "
      read*, INFILE
      open (20,FILE=INFILE,iostat=ERROR)
      if ( ERROR /= 0 ) print*,"Error opening file ",INFILE
      if ( ERROR /= 0 ) STOP
      close (21)

      do i = 1,1000
        read (20,*,iostat=ERROR) CRAP1(i),CRAP2(i),RV(i),RVERR(i)
        if ( ERROR /= 0 ) exit
      end do
      NRV = i - 1

      print*, "Read ",NRV," lines from file ",INFILE
      print*, "Enter dispersion (km/s per pixel):"
      read*, DISP

      print*, "Enter the name of the file to write: "
      read*, OUTFILE
      open (21,FILE=OUTFILE,iostat=ERROR)
      if ( ERROR /= 0 ) print*,"Error opening file ",OUTFILE
      if ( ERROR /= 0 ) STOP

      do i=1,NRV
        write (21,'(F10.6,2X,F8.6)') RV(i)/DISP,RVERR(i)/DISP
      end do

      close (21)


Save this code as rv2pix.f, then compile it using the Gnu g77 compiler and run it:

g77 -o rv2pix rv2pix.f

Give the input filename, the reciprocal dispersion (km/s per pixel), and the output filename as prompted. The output file contains the radial velocities measured by rvel converted to pixel shifts.

Applying the pixel shifts

In molly, read in the science spectra:

load  opt.mol  1  1000  1 

and move the wavelength scales by the numbers of pixels given in the output file from rv2pix:

move  1  1000  [pixel shift file]  p  s  

and save the result to a new file:

write opt-fix.mol  1  1000  N 

You now have science spectra which have been wavelength-calibrated using arc lamp spectra and then shifted slightly so the line centres of the sky line are all at the same wavelength.


1992PASP..104...76O   Osterbrock & Martel
Sky spectra at a light-polluted site and the use of atomic and OH sky emission lines for wavelength calibration

1996PASP..108..277O   Osterbrock, Fulbright, Martel, Keane, Trager & Basri
Night-Sky High-Resolution Spectral Atlas of OH and O2 Emission Lines for Echelle Spectrograph Wavelength Calibration

1997PASP..109..614O   Osterbrock, Fulbright & Bida
Night-Sky High-Resolution Spectral Atlas of OH Emission Lines for Echelle Spectrograph Wavelength Calibration. II.

2000PASP..112..733O   Osterbrock, Waters, Barlow, Slanger & Cosby
Faint Emission Lines in the Blue and Red Spectral Regions of the Night Airglow