Tom Trebisky's README

These are notes on the MMT wavefront sensor software
worked up by Tom Trebisky in February of 2011

1) Checking out a copy from SVN

I did this onto cholla via:

    svn checkout svn+ssh://mmt/mmt/REPOS/shwfs/trunk shwfs

This was a big mistake, because the real repository for
this software was on hacksaw, so after figuring this out
it was necessary to do the following, then hand merge my
changes:
    svn checkout svn+ssh://hacksaw/mmt/REPOS/shwfs/trunk shwfs

This places the software in /home/tom/shwfs,
after doing this you should do:

    make

This will build the various compiled C components of the wfs
software.  I put together a tiny wrapper script called "wfs"
that I use to start the software for F9 via

    cd /home/tom/shwfs
    ./wfs

I also have a script for testing F5

    cd /home/tom/shwfs
    ./wfs5

It would be nice to touch some file in datadir (either F9 or F5)
so that one script (wfs) could detect which data was being analyzed.

NOTE:  even though the environment variable WFSROOT is defined,
there are places in the software where explicit paths that
include "/mmt/shwfs" are used to run pieces of the software.
This works for me on cholla because I NFS mount /mmt, but
it could certainly lead to confusion if locally built
components in /home/tom/shwfs were expected to be run.
I am working on cleaning this up.

Also, I create the directory "~/shwfs/datadir" and dump the
files I use for testing into that directory,
which seems to work just fine.

Actually what I do is to copy files from /mmt/wfsdat/yyyymmdd
to ~/shwfs/datadir_yyyymmdd and link datadir --> datadir_yyyymmdd
This way I can have a variety of interesting nights to experiment
with and switch between them by changing the link.

----------------------------

My "wfs" script is a tiny wrapper that sets environment variables and then
calls shwfs_unified.tcl.

To run the software do this (ignoring image capture since we are talking
about doing post mortem examination of data sets).

1) select a file in the f9 SHWFS window
2) click the "Centroid Button"

This will display the image in the ds9 window and turn the buttons on the
bottom of the Wavefront Zernikes window green. The display in the "wim"
window is also updates.

In "postmortem" mode, there are 4 GUI windows in use:

A) the ds9 window
B) the main "F9 SHWFS" window
C) the Wavefront Zernikes window
D) the "wim" window

The last 3 windows are all generated by the shwfs_unified script.
The "wim" window is the .wim toplevel
The "wavefront zernikes" window is the .aber toplevel

I introduced an environment variable WFSDEBUG, which I set to "postmortem".
This does a number of minor convenience things in the shwfs_unified.tcl script.
In particular, it suppresses other GUI interfaces which are not needed for
postmortem debugging.  These are:

-- for F5, the "wavedisplay" GUI (written by John Roll)
-- for F5, the "f5wfs_gui"
-- for MMIRS, the "mmirs_gui"
-- for F9, the "f9wfs_gui"
-- for F9 and F5, the "auto_correct_gui"

---------------------------------------------------------

The shwfs_unified GUI has a set of buttons which trigger actions.
It also acts as a MSG server (on port xxxx), which allow other GUI
(typically the auto_correct_gui) to manipulate it and perform WFS
processing remotely.  It can be confusing when looking at the code
if caution is not taken to be sure that a procedure being work on
is the button callback rather than the MSG callback (and vice-versa).
Really a shared common subset of procedures should be shared by both
instead of the current code duplication.  Some changes have been made
to make this so.

The centroid button runs a data reduction sequence, which goes as
follows:

1) A comma separated list of filenames is built from the selection in
    the listbox full of filenames.  Most commonly the selection is just
    one file and this is overkill.

2) A shared procedure "do_centroid" is called with the file list.

3) The python function "daofind.py" is invoked as:
	daofind.py file_list F9 0
	see below for details of what this does.
	(in the common case where a list of files is being
	processed, it generates a new name _ave.fits from the
	name of the LAST file in the list, and processes this file
	which contains averaged values from all the files).
	It produces the file manual_wfs_0000.dao

4) This function returns the name of the output file it generates
	along with the rotator angle as follows:

	manual_wfs_0078.dao -2.05

5) the Tcl procedure "average" is called and passed the dao filename.
	this procedure does much more than the averaging implied.
	In fact, in the usual case where only one file is being
	processed, it does no averaging at all.
	
	- it runs the C program "ihaverage"
	- it calls the Tcl procedure "zernike"
	   this runs the C program "getZernikesAndPhases"

6) A count of linked spots is produced by counting the number
	of lines in the text file datadir/link
	Note that this file is written by getZernikesAndPhases
	via the obscure call:

	    writeMatrix ("link", link, l, 2);

	The routine "associateSpots" in the file
	getZernikesAndPhases.c is the heart of the matter.

7) proc showzerns is called, which reads the .zrn file
	and does "lots of stuff"


----------------------------------------------------------------

daofind.py
	Let's say we are working on manual_wfs_0000.fits
	we invoke:
	    /home/tom/shwfs/daofind.py manual_wfs_0000.fits F9 0
	The processing in this script is as follows:

	0) if a list of files is given, they are averaged
	    using average()
	    (this is the case when we have files named auto_wfs_000*.fits
	     in which case the output of this procedure goes to
	     the file auto_wfs_0002_ave.fits, i.e. a modified filename
	     derived from the last filename in the list).
	1) iraf.imsurfit is fit to the image to obtain "back.fits"
	    this is subtracted from the source image
	    and written back over the original filename.
	2) the image header is read and the rotator angle extracted
	3) the image is displayed via DS9
	4) function daofind() is called
	5) function shcenfind() is called

The function daofind(image) does the following:
	1) the file /mmt/shwfs/F9_reference.center is opened and read
		(used to determine an offset which is never used)
	2) the image is smoothed (low pass filtered)
	3) an iterative threshold algorithm finds the spots
	4) the center of mass of the image is the image center
	5) the file manual_wfs_0000.dao is written
	6) the function returns the center and a spot list
	    (the spot list is never used).

The function shcenfind(fitsfile,"F9",xcen,ycen) does the following:
	1) the file /mmt/shwfs/F9_reference.fwhm is opened and read
		(2 values are read)
	2) the compiled C program "shcenfind" is run as
		shcenfind manual_wfs_0000.dao
		(see details below)
	3) spot centroids are read from xxx.dao
	4) spot centroids are read from /mmt/shwfs/f9newsys.cntr
		169 lines, 168 spots.
	5) a function minimizer (fmin_powell) is used to translate
	    the two spot patterns into best correspondence.
	    the minimizer calculates an offset (actual-ref)
	6) a translated version of the reference pattern is written
	    to "ref.dat" (calculated as ref + offset)
	    (This gets picked up by getZernickesAndPhases much later)

The compiled C code shcenfind is called with a single filename argument.
	It overwrites this file.
	It sorts centroids into rows and columns
	    determines the best X and Y average magnifications
	    it estimates the center of the spot diagram
	    (the mag factors and center go into a header record).
	    the estimated center is used as a starting point for
	    the function minimizer which runs subsequently

----------------------------------------------------------------

getZernickeAndPhases.c is compiled and linked with several "libraries"

	nrutil.c has storage allocators like matrix()
	fileio.c has readMatrix()
	WFSlib.c has associateSpots()
	zernike.c has uZ, duZdx, duZdy, duMCADZdx, duMCADZdy, and upolarZ

getZernickeAndPhases is invoked as:

    /home/tom/shwfs/getZernikesAndPhases ref.dat /u1/tom/shwfs/datadir_20110312/manual_wfs_0000.dao.av 0 -225.0

    the arguments are:
    	ref.dat - the "system file" (reference spots)
	manual_wfs_0000.dao.av (actual spots and header info).
	0 means do NOT solve for phases
	-225.0 (rotator angle)

    The dao.av file looks like:

	# /u1/tom/shwfs/datadir_20110312/manual_wfs_0000.dao
	# X 23.006701 24.031700 274.144714 268.977905
	   218.687     84.241
	   ..... (139 spots, 141 lines in file)

    The first header line gives the name of the dao file (which just has 140 lines)
    The second header line is just copied from the dao file

    The header in the reference file yields:
    	xm1, ym1, xo1, yo1
	sys_mag = (xm1 + ym1) / 2.0

    The header in the stellar file yields:
    	xm2, ym2, xo2, yo2
	stel_mag = (xm2 + ym2) / 2.0

    mag = sys_mag / stel_mag

    This program opens the reference file and the stellar file.
    The reference spots are shifted by (spot - (xo1, yo1))
    The stellar spots are shifted and scaled by (spot-(xo2,yo2)) * mag