Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/Makefile
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/Makefile	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/Makefile	(revision 21897)
@@ -0,0 +1,76 @@
+default: misc
+help:
+	@echo "make options: misc (default)"
+
+include ../../Configure
+HOME 	=	$(ROOT)/src/misc
+SRC	=	$(HOME)/src
+LIB	= 	$(HOME)/lib
+MAN	=	$(HOME)/doc
+BIN	=	$(HOME)/bin
+INC	=	$(HOME)/include
+
+CFLAGS	=	-I$(INC) -I$(DESTINC) $(INCDIRS) -D$(ARCH)
+LDFLAGS = 	-L$(LIB) -L$(DESTLIB) $(LIBDIRS) $(LIBFLAGS)
+LDFLAGS := 	-ldvo -lFITS -lohana $(LDFLAGS)
+
+# these are all programs which just depend on a single c file: foo : foo.c
+
+PROGRAMS = gconfig mknames fhead ftable fields list_astro glockfile \
+radec mktemp precess csystem fits_insert mkgauss \
+medianfilter mefhead mkfringetable gtfringetable ckfits applyscat fiximg
+
+misc: $(PROGRAMS)
+
+$(PROGRAMS): % : $(BIN)/%.$(ARCH)
+
+fakestars: $(BIN)/fakestars.$(ARCH)
+$(BIN)/fakestars.$(ARCH): $(SRC)/fakestars.$(ARCH).o $(SRC)/random.$(ARCH).o
+
+#### cfhtlog is special (requires additional libs and includes)
+
+$(BIN)/cfhtlog.$(ARCH): $(SRC)/cfhtlog.c
+	$(CC) -I/cfht/include -L/cfht/lib -o $(BIN)/cfhtlog.$(ARCH) $(SRC)/cfhtlog.c -lcfht 
+
+$(DESTBIN)/cfhtlog: $(BIN)/cfhtlog.$(ARCH)
+	@if [ ! -d $(DESTBIN) ]; then mkdir -p $(DESTBIN); fi
+	cp $(SRC)/cfhtlog.$(ARCH) $(DESTBIN)/
+
+cfhtlog:
+	make $(DESTBIN)/cfhtlog
+
+# copied from Makefile.Common : use a single c file: foo : foo.c
+.PRECIOUS: %.$(ARCH).o
+.PRECIOUS: $(BIN)/%.$(ARCH)
+
+%.$(ARCH).o : %.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+$(BIN)/%.$(ARCH) : $(SRC)/%.$(ARCH).o
+	@if [ ! -d $(BIN) ]; then mkdir -p $(BIN); fi
+	$(CC) -o $@ $^ $(LDFLAGS)
+
+$(DESTBIN)/%: $(BIN)/%.$(ARCH) 
+	@if [ ! -d $(DESTBIN) ]; then mkdir -p $(DESTBIN); fi
+	rm -f $(DESTBIN)/$*
+	cp $(BIN)/$*.$(ARCH) $(DESTBIN)/$*
+
+%.install:
+	make $(DESTBIN)/$*
+
+install:
+	for i in $(PROGRAMS); do make $$i.install || exit; done
+
+%.clean:
+	rm -f $(SRC)/$*.$(ARCH).o
+	rm -f $(BIN)/$*.$(ARCH)
+
+clean:
+	rm -f `find . -name "*.o"`
+	rm -f `find . -name "*.o"`
+	rm -f `find . -name "*~"`
+	rm -f `find . -name "#*"`
+
+dist: clean
+	rm -rf $(BIN)
+	rm -rf $(LIB)
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/bin/.cvsignore
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/bin/.cvsignore	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/bin/.cvsignore	(revision 21897)
@@ -0,0 +1,2 @@
+*.linux *.lin64 *.sol *.sun *.sid *.hp *.irix
+*.linrh
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/doc/ChangeLog.txt
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/doc/ChangeLog.txt	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/doc/ChangeLog.txt	(revision 21897)
@@ -0,0 +1,26 @@
+
+- misc-1-3 : 2006.08.23
+  * converted to gfits APIs (forces libfits 1.6)
+
+misc-1-2:
+
+  - minor changes to use new libohana (v1.5) / libfits (v1.4)
+
+2005.10.07
+
+	I was having some memory collision problems, and attempting to
+	use the ohana_allocate functions reminded me that the libFITS
+	functions were not supported under ohana_allocate.  This was
+	unhelpful.  I bit the bullet and split libohana into libohana
+	(base functions only, including ohana_allocate) and libdvo
+	(functions based on the libautocode structures).  Doing this
+	allowed me to make libFITS depend on libohana (including
+	ohana_allocate).  BUT, this forced me to change all LDFLAGS
+	entries in ohana to swap -lohana -lFITS for -lFITS -lohana,
+	and to add include <fitsio.h> in some cases.
+
+misc-1-1:
+  - dropped old, out-of-date programs
+  - minor changes for loneos.h -> dvo.h
+  - cleanup of glockfile things
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/include/cfht/cfht.h
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/include/cfht/cfht.h	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/include/cfht/cfht.h	(revision 21897)
@@ -0,0 +1,793 @@
+/* Copyright (C) 1991-1999  Canada-France-Hawaii Telescope Corp.         */
+/* This program is distributed WITHOUT any warranty, and is under the    */
+/* terms of the GNU General Public License, see the file COPYING         */
+/*****************************************************************************
+ *
+ * file: cfht.h
+ * $Id: cfht.h,v 1.1.1.1 2004-11-24 04:39:33 eugene Exp $
+ * $Locker:  $
+ *
+ * This file is the main include file for the generic library.
+ *
+ *
+ * HISTORY
+ *
+ * who       when          what
+ * -------   -----------   ----------------------------------------------
+ * jab       27 Jan 1988   Original coding
+ * jab        1 Mar 1988   Added config file stuff
+ * jab       12 Mar 1988   Added logging stuff
+ * jk        22 Mar 1988   Added cfht_od()
+ * jk/jab    24 Mar 1988   Added CFHT_TAPE and CFHT_DISPLAY
+ * jab        6 Apr 1988   Added puma link device
+ * jab       29 Apr 1988   Added already included check
+ * sss       08 May 1988   Added CFHT_NPIPE
+ * jk        17 May 1988   Modified tape and display because of collision
+ * jk        06 Oct 1988   added cfht_resetetimer as a define
+ * sss       17 Mar 1989   added cfht_log() support stuffs
+ * sss       11 Apr 1989   added real time defines for detectors,etc.
+ * sss       24 Oct 1989   added CFHT_RELEASE define for .,config access
+ * sss        3 Jan 1990   added CFHT_*SESSIONHOST defines for env. vars
+ * jrw       01 Oct 1990   added stuff for cfht_number
+ * jrw       02 Nov 1990   added CFHT_STR_* defines
+ * jk        27 Feb 1991   cfht_exec unions not used anymore
+ * sss       27 Mar 1991   added cfht_basename()
+ * jrw       09 May 1991   added function definitions (ANSI and crufty flavors)
+ * jk        29 Aug 1991   changed cfht_errno from BOOLEAN to int
+ *
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1.1.1  2001/07/25 02:59:23  eugene
+ * import Ohana
+ *
+ * Revision 1.44  2000/04/10  11:28:40  isani
+ * Added prototype for cfht_log_proxy.
+ * 
+ * Revision 1.43  2000/02/10 13:19:08  isani
+ * Added include of sys/types.h whenever pid_t is needed.
+ *
+ * Revision 1.42  1999/12/02 21:40:30  thomas
+ * Added PFVint
+ *
+ * Revision 1.41  1999/07/25 06:29:57  thomas
+ * Added UTDATE/TIME and PFDATE defs
+ *
+ * Revision 1.40  1999/04/29 17:18:00  thomas
+ * Added @ ( # ) to RCSID string for what(1) to find
+ * Added non-gcc but STDC version of above
+ * Added changes for switch to /cfht
+ *
+ * Revision 1.39  99/02/17  13:55:15  13:55:15  thomas (Jim Thomas)
+ * Added cfht_cfhthome
+ * 
+ * Revision 1.38  98/12/11  18:23:20  18:23:20  thomas (Jim Thomas)
+ * Added CFHT_*OBSERVERPATH
+ * 
+ * Revision 1.37  98/10/22  17:52:44  17:52:44  thomas (Jim Thomas)
+ * Added CFHT_ESESSION
+ * 
+ * Revision 1.36  98/07/16  15:53:32  15:53:32  thomas (Jim Thomas)
+ * Added cfht_system
+ * 
+ * Revision 1.35  98/07/07  12:52:47  12:52:47  thomas (Jim Thomas)
+ * Added CFHTPATH , IOCONFDIR , and CONFDIR definitions
+ * 
+ * Revision 1.34  98/04/09  17:52:20  17:52:20  thomas (Jim Thomas)
+ * Added cfht_argsToString
+ * 
+ * Revision 1.33  98/02/25  16:35:00  16:35:00  thomas (Jim Thomas)
+ * Added prototype for cfht_logpv
+ * 
+ * Revision 1.32  97/12/09  00:11:48  00:11:48  healey (SueAnn Healey)
+ * added CFHT_LIBSSX
+ * 
+ * Revision 1.31  1997/12/01 16:03:29  isani
+ * Moved missing protos to separate file.
+ * Added extern "C" declarations for C++ projects.
+ *
+ * Revision 1.30  1997/09/17 13:48:31  thomas
+ * Added CFHT_EXEC_NOT_EXITED and CFHT_EXEC_FAILED
+ * Documented bogus use of FAIL in exp_controller_t
+ *
+ * Revision 1.29  97/06/29  15:41:07  15:41:07  isani (Sidik Isani)
+ * Had to fiddle with some of the includes to get to compile with GCC
+ *   on the sparc engines.
+ * 
+ * Revision 1.28  97/05/28  02:51:35  isani
+ * added CFHT_SIG_ defines for handler argument of cfht_signal()
+ * 
+ * Revision 1.27  97/04/07  20:10:26  thomas
+ * Added LIBOMS, changed cfht_signal event prototypes
+ * 
+ * Revision 1.26  96/11/22  02:36:44  02:36:44  isani (Sidik Isani)
+ * added macro for TEMP_FAILURE_RETRY, in case anyone wants to use it
+ * changed cfht_delay(n) into a macro that calls cfht_sleep(n,1)
+ * 
+ * Revision 1.25  96/11/19  22:24:19  isani
+ * moved P() and Q() macros closer to top of file
+ * added RCSID() macro
+ * define volatile to nothing on compilers where everything is volatile
+ * define UNUSED for use with gcc, or nothing on compilers that don't care
+ * added a few more missing libcfht prototypes
+ * concentrated most of the old-sun hacks here rather than in each file
+ *   (protos for getenv, putenv, different name for mktime, etc.)
+ * fixed order of arguments in cfht_fromjulian prototype
+ * 
+ * Revision 1.24  96/08/14  13:01:17  13:01:17  thomas (Jim Thomas)
+ * Added TCS_ConsolePrompt error return code
+ * 
+ * Revision 1.23  96/05/20  16:01:16  16:01:16  thomas (Jim Thomas)
+ * Added LIBCX, TCS_CommandFailed,
+ * Fixed F4 cfht_errno definitions
+ * 
+ * Revision 1.22  96/02/21  11:16:07  11:16:07  isani (Sidik Isani)
+ * cfht_errno codes for gecko and f4 server
+ * 
+ * Revision 1.21  1995/07/19 12:48:00  thomas
+ * Added AOB cfht_errno codes
+ *
+ * Revision 1.20  95/06/29  11:38:38  11:38:38  thomas (Jim Thomas)
+ * Added cfht_errno codes for IDS
+ * 
+ * Revision 1.19  95/06/13  12:03:06  12:03:06  thomas (Jim Thomas)
+ * Added environment variables and cfht_log_who entries for CS, DUCK, HELP,
+ * IDS, PIXD, TCS, and UI libraries
+ * 
+ * Revision 1.18  95/06/07  17:22:30  17:22:30  thomas (Jim Thomas)
+ * Added typedef for cfht_errno codes
+ * 
+ * Revision 1.17  94/12/28  17:06:51  17:06:51  thomas (Jim Thomas)
+ * Moved strerror definition for suns here from cfp.h (for cfht_logv)
+ * 
+ * Revision 1.16  94/12/21  10:35:46  10:35:46  john (John Kerr)
+ * add pid_t.
+ * 
+ * Revision 1.15  94/12/15  10:46:42  10:46:42  john (John Kerr)
+ * modified pid in cfht_exec_data to be a pid_t type.
+ * 
+ * Revision 1.14  94/12/14  10:50:01  10:50:01  thomas (Jim Thomas)
+ * Added CFHT_LIBMUSIC, CFHT_VALUE_SIZE, Q macro
+ * Deleted BYTE
+ * 
+ * Revision 1.13  94/09/20  18:40:45  18:40:45  thomas (Jim Thomas)
+ * added CFHT_LOGONLY, CFHT_LIBOCS
+ * reworked symbols related to cfht_log
+ * 
+ * Revision 1.12  94/08/14  10:27:17  10:27:17  jwright (Jim Wright)
+ * add warning log messages and color messages
+ * 
+ * Revision 1.11  94/07/11  15:48:53  15:48:53  veran (Jean-Pierre Veran)
+ * AAdded net logging capabilities
+ * 
+ * Revision 1.10  94/02/02  14:08:00  14:08:00  jwright (Jim Wright)
+ * remove typedef of FILE_ID form cfp.h and put it in cfht.h.  reason is
+ * that cfht_exec() has an argument of type FILE_ID and thus needs to have
+ * this type visible so that it can correctly declare an ANSI prototype.
+ * it is presumed that any file including cfp.h will first have included
+ * cfht.h.
+ * 
+ * Revision 1.9  94/01/20  20:35:13  20:35:13  jwright (Jim Wright)
+ * fix enum
+ * 
+ * Revision 1.8  94/01/20  04:51:31  04:51:31  jwright (Jim Wright)
+ * add enumeration for controller types
+ * 
+ * Revision 1.7  93/11/26  10:14:09  10:14:09  jwright (Jim Wright)
+ * added definitions to retrieve info from net.par
+ * 
+ * Revision 1.6  93/05/19  08:45:49  08:45:49  steve (Steven Smith)
+ * added cfht_logv TIMING define
+ * 
+ * Revision 1.5  93/02/16  16:21:15  16:21:15  john (John Kerr)
+ * added a CFHT_INSTRUMENT_TYPE
+ * 
+ * Revision 1.4  92/12/01  19:21:47  19:21:47  steve (Steven Smith)
+ * added CFHT_ELOGHOST for cfht_log() net based
+ * 
+ * Revision 1.3  92/11/09  13:11:03  13:11:03  john (John Kerr)
+ * added void cfht_goDaemon()
+ * 
+ * Revision 1.2  91/11/15  10:07:52  10:07:52  jwright (Jim Wright)
+ * add macro to handle both ansi and k&r style parameters
+ * in function declarations; convert declarations to use macro
+ * 
+ * Revision 1.1  91/09/24  15:59:31  15:59:31  steve (Steven S Smith)
+ * Initial revision
+ * 
+ ****************************************************************************/
+
+#ifndef CFHTDOTH
+#define CFHTDOTH
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef pid_t
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#endif /* pid_t */
+
+/******************************************************************
+ * macro to declare prototypes for ansi, but still works with k&r *
+ *                                                                *
+ * define prototype like                                          *
+ *        int foo P((int a, char c))                              *
+ *                                                                *
+ * note that the space before the P and the doubled parentheses   *
+ *      are needed                                                *
+ ******************************************************************/
+
+#ifndef P
+#ifdef __STDC__
+#define P(args) args
+#else
+#define P(args) ()
+#endif
+#endif
+
+/********************************************************************
+ * macro to declare routine parameters for ansi that works with k&r *
+ *                                                                  *
+ * define actual routine like                                       *
+ *        int foo Q((int a, char c), (a, c), int a; char c;) {      *
+ *                                                                  *
+ * note that inner parentheses are needed on the ansi parameters    *
+ *                                 needed on the K&R parameters     *
+ *                             and must not be there on the K&R     *
+ *                                          type definition         *
+ *           there must be a space before the Q                     *
+ *           the arguments to Q can be on separate lines like       *
+ *                         int foo Q((int a, char c),               *
+ *                                   (a, c),                        *
+ *                                   int a; char c;)                *
+ *                         {                                        *
+ ********************************************************************/
+
+#ifndef Q
+#ifdef __STDC__
+#define Q(ansi, karparm, kartype) ansi
+#else
+#define Q(ansi, karparm, kartype) karparm kartype
+#endif
+#endif
+
+/*
+ * UNUSED attribute to tell Gnu compiler not to warn
+ * and define volatile to nothing for compilers where everything
+ * is volatile (We hope!)
+ */
+#ifdef __STDC__
+#ifdef __GNUC__
+#define UNUSED __attribute__ ((__unused__))
+#else
+#define UNUSED
+#endif
+#else
+#define UNUSED
+#define volatile
+#endif
+
+/*
+ * Macro to use for inserting rcs id's 
+ */
+
+#ifdef __LINT__
+#define RCSID(string) extern int lint_rcs_id_dummy
+#else
+#if defined(__GNUC__) && defined(__STDC__)
+#define RCSID(string) \
+  static const char rcs_id[] __attribute__ ((__unused__)) = "@(#) " string
+#else
+#if defined(__STDC__)
+#define RCSID(string) static char rcs_id[] = "@(#) " string
+#else
+#define RCSID(string) static char rcs_id[] = string
+#endif
+#endif
+#endif
+
+/*********************
+ * type definitions *
+ ********************/
+
+typedef int BOOLEAN;           /* should only contain TRUE, or FALSE */
+typedef double ANGLE;          /* floating pt. arc seconds */
+typedef double TIME;           /* floating pt. seconds */
+typedef double JDATE;          /* julian day number */
+typedef char *DATE;            /* ascii string date */
+typedef int PASSFAIL;          /* for functions that return PASS, or FAIL */
+typedef void (*PFV) P((void));   /* pointer to function that returns void */
+typedef void (*PFVint) P((int));   /*  ditto, with int parameter */
+typedef void (*PFVui) P((int,int,void*));  /* used for ui callbacks */
+typedef void (*PFVexec) P((pid_t,int));    /* used by cfht_exec() */
+
+enum exp_controller_t {       /* valid detector controller types */
+    FAIL = -1,			  /* NOTE - depends on define below :-( */
+    CONTROLLER_GENIII,
+    CONTROLLER_CC200,
+    CONTROLLER_FTS,
+    CONTROLLER_RETICON
+};
+
+typedef int FILE_ID;              /* used for parse file instance handles */
+
+/*************
+ * constants *
+ *************/
+
+#define PASS  0           /* function returning with no error */
+#define FAIL  -1          /* function returning an error in errno */
+			  /* lots of things depend on FAIL being negative!! */
+
+#define TRUE  1           /* 'C' boolean */
+#define FALSE 0           /* 'C' boolean */
+
+#ifndef NULL              /* make sure it's not already defined */
+#define NULL  0           /* used mostly for null string pointers */
+#endif  /* NULL */
+
+#define CFHTLOCKS  "/tmp/cfhtlocks"
+
+/********************
+ * real time defs   *
+ ********************/
+
+#define CFHT_RT_DETECTOR 65    /* about 1/2 */
+#define CFHT_RT_MOMMA    75    /* not as fast */
+#define CFHT_RT_HANDLER  85    /* slower yet */
+
+/********************
+ * exec definitions *
+ ********************/
+
+#define CFHT_EXEC_NUM    10    /* number of pending deaths allowed */
+#define CFHT_EXEC         1    /* straight exec */
+#define CFHT_EXECFG       2    /* wait and return exit code */
+#define CFHT_EXECBG       3    /* dont wait and dont ever bother me */
+#define CFHT_EXECBGC      4    /* dont wait but deposit exit code when ... */
+#define CFHT_EXECBGH      5    /* dont wait but call handler when ... */
+                               /* (handler is called with pid and exit code */
+#define CFHT_EXEC_NOT_EXITED -1 /* initial value of exit code */
+#define CFHT_EXEC_FAILED -2    /*  exit code if ran but failed to exit */
+/* #define CFHT_EXEC_EXITED (8 bits of system exit code) */ /* normal exit */
+
+#define CFHT_ARGV_NUM   100    /* size of cfht_argv() arg list */
+#define CFHT_ARGS_SIZE 1024    /* size of string to make args out of */
+#define CFHT_VALUE_SIZE 256    /* max length of a value (as in name=value) */
+
+union cfht_exec_addr {
+    volatile int *code;        /* exit code (-1 -> not yet exited) */
+    PFV func;                  /* handler to call */
+};
+
+struct cfht_exec_data {
+    volatile pid_t pid;        /* process id (0 -> unused) */
+    volatile int type;         /* CFHT_EXECBGC, or CFHT_EXECBGH (0 -> ignore) */
+    volatile void *addr;       /* union not used anymore */
+};
+
+extern int cfht_exec_rtprio;
+
+/*
+ * paths and file names
+ * CFHT_E* is the name in the environment, without the E is the actual value
+ * at the moment - so try not to use these (unfortunately that means programs
+ * don't work outside the session, sigh, so they appear in cfp_file.c and
+ * roll.c at least :-(
+ */
+/*
+ * The original path to everything started at /usr/local/cfht .  To get things
+ * out from under /usr/local , we created an automount collection for /cfht .
+ * To make things more consistent with other packages, we changed from
+ * /usr/local/cfht/dev to /cfht/src for the top of the source tree.  While
+ * both paths still exist, handle both possibilities here (and nowhere else in
+ * any c code please :-)
+ */
+#if defined(HPUX10) || defined(Solaris)
+#define CFHT_ECFHTPATH   "cfhtdir"			/* top of our tree */
+#define CFHT_CFHTPATH    "/cfht"			/*   which is */
+#define CFHT_CONFDIR     "src/conf"			/* dir for par files */
+#define CFHT_IOCONFDIR   "conf"				/*   except ioconfig */
+#define CFHT_ECONFPATH   "CFHTCONFPATH"			/* path to par files */
+#define CFHT_CONFPATH    "/cfht/src/conf"		/*   which is */
+#else
+#define CFHT_ECFHTPATH   "cfhtdir"			/* top of our tree */
+#define CFHT_CFHTPATH    "/usr/local/cfht"		/*   which is */
+#define CFHT_CONFDIR     "dev/conf"			/* dir for par files */
+#define CFHT_IOCONFDIR   "conf"				/*   except ioconfig */
+#define CFHT_ECONFPATH   "CFHTCONFPATH"                 /* path to par files */
+#define CFHT_CONFPATH    "/usr/local/cfht/dev/conf"     /*   which is */
+#endif /* HPUX10 or Solaris */
+#define CFHT_ECONFNAME   "CFHTCONFNAME"                 /* name for .,config */
+#define CFHT_CONFNAME    "config"                       /*   which is */
+#define CFHT_ESESSION    "Session"			/* master session name */
+#define CFHT_EOBSERVERPATH "observer"                   /* path to top of homes */
+#define CFHT_OBSERVERPATH "/users/observer"             /*   which is */
+
+/* identifiers within config file */
+#define CFHT_DETECTOR    "detector"                     /* e.g. th1 */
+#define CFHT_RELEASE     "release"                      /* e.g. 901231 */
+#define CFHT_INSTRUMENT  "instrument"                   /* 'who am i' */
+#define CFHT_INSTRUMENT_TYPE  "instrument_type"         /* e.g. FTS */
+#define CFHT_HANDLERS    "handlers"                     /* e.g. tcsh, ccdh */
+#define CFHT_FOCUS       "focus"                        /* e.g. prime */
+#define CFHT_DISPLAY     "display_guy"                  /* display handler */
+#define CFHT_TAPE        "tape_guy"                     /* tape handler */
+#define CFHT_SESSION     "session"                      /* e.g. ccd, focam */
+
+/*****************
+ * net.par stuff *
+ *****************/
+
+#define CFHT_CCDSERVER	"ccdserver"
+#define CFHT_F4SERVER	"f4server"
+#define CFHT_FOCAMSERVER "focamserver"
+#define CFHT_GENSERVER	"genserver"
+#define CFHT_LOGSERVER	"logserver"
+#define CFHT_RFSERVER	"rfserver"
+#define CFHT_TCSSERVER	"tcsserver"
+#define CFHT_TRAFFIC	"traffic"
+
+/**********************
+ * session host stuff *
+ **********************/
+
+#define CFHT_ESESSIONHOST    "SESSIONHOST"    /* used in xstart files */
+#define CFHT_SESSIONHOST     "moe"            /* perhaps hostname()? */
+
+/*****************
+ * logging stuff *
+ *****************/
+
+/* environment variables */
+
+/*
+ * The following are viewed as boolean flags.  For each, the indicated setting
+ * has the described effect (e.g., "setenv CFHTERROR off" will cause error
+ * messages not to appear in the feedback window), and the inverse setting or
+ * no setting has the opposite effect (e.g., otherwise error messages appear
+ * in the feedback window).
+ */
+#define CFHT_EERROR     "CFHTERROR"     /* Off -> no error messages to
+					 * feedback window */
+#define CFHT_EWARN      "CFHTWARN"      /* Off -> no warning messages to
+					 * feedback window */
+#define CFHT_ENODISP    "CFHTNODISP"    /* On -> no START/STATUS/DONE messages
+					 * to feedback window */
+#define CFHT_EDEBUG     "CFHTDEBUG"     /* On -> CFHT_MAIN debug messages to
+					 * log file */
+#define CFHT_ELIB       "CFHTLIB"       /* On -> unknown lib debug messages to
+					 * log file */
+#define CFHT_ELIBCAMAC  "CFHTLIBCAMAC"  /* On -> libcamac debug to log file */
+#define CFHT_ELIBCCD    "CFHTLIBCCD"    /* On -> libccd debug to log file */
+#define CFHT_ELIBCFHT   "CFHTLIBCFHT"   /* On -> libcfht debug to log file */
+#define CFHT_ELIBCFP    "CFHTLIBCFP"    /* On -> libcfp debug to log file */
+#define CFHT_ELIBCS     "CFHTLIBCS"     /* On -> libcs debug to log file */
+#define CFHT_ELIBCX     "CFHTLIBCX"     /* On -> libcx debug to log file */
+#define CFHT_ELIBDUCK   "CFHTLIBDUCK"   /* On -> libduck debug to log file */
+#define CFHT_ELIBFF     "CFHTLIBFF"     /* On -> libff debug to log file */
+#define CFHT_ELIBHELP   "CFHTLIBHELP"   /* On -> libhelp debug to log file */
+#define CFHT_ELIBHH     "CFHTLIBHH"     /* On -> libhh debug to log file */
+#define CFHT_ELIBIDS    "CFHTLIBIDS"    /* On -> libids debug to log file */
+#define CFHT_ELIBMUSIC  "CFHTLIBMUSIC"  /* On -> libmusic debug to log file */
+#define CFHT_ELIBOCS    "CFHTLIBOCS"    /* On -> libocs debug to log file */
+#define CFHT_ELIBOMS    "CFHTLIBOMS"    /* On -> liboms debug to log file */
+#define CFHT_ELIBPIXD   "CFHTLIBPIXD"   /* On -> libpixd debug to log file */
+#define CFHT_ELIBRET    "CFHTLIBRET"    /* On -> libret debug to log file */
+#define CFHT_ELIBRET    "CFHTLIBRET"    /* On -> libret debug to log file */
+#define CFHT_ELIBSSX    "CFHTLIBSSX"    /* On -> libssx debug to log file */
+#define CFHT_ELIBTCS    "CFHTLIBTCS"    /* On -> libtcs debug to log file */
+#define CFHT_ELIBUI     "CFHTLIBUI"     /* On -> libui debug to log file */
+
+#define CFHT_ECOLORLOG	"CFHTCOLORLOG" 	/* Off -> no color on user log */
+
+#define CFHT_LOGU       "CFHTLOGU"      /* user log messages file name */
+#define CFHT_LOGS       "CFHTLOGS"      /* system log messages file name */
+#define CFHT_ELOGHOST	"CFHTLOGHOST" 	/* host for netbased logging */
+
+/* who  (NOTE, should be alphabetized only at release time) */
+typedef enum {
+    CFHT_MAIN = 0,		  /* caller is end user */
+    CFHT_LIB,			  /* caller is undefined library */
+    CFHT_LIBCAMAC,		  /* caller is CAMAC library */
+    CFHT_LIBCCD,		  /* caller is ccd library */
+    CFHT_LIBCFHT,		  /* caller is CFHT library */
+    CFHT_LIBCFP,		  /* caller is CFP library */
+    CFHT_LIBFF,			  /* caller is FITS library */
+    CFHT_LIBHH,			  /* caller is high level HPIB library */
+    CFHT_LIBMUSIC,		  /* caller is music library */
+    CFHT_LIBOCS,		  /* caller is OCS library */
+    CFHT_LIBRET,		  /* caller is reticon library */
+    CFHT_LIBCS,			  /* caller is client/server library */
+    CFHT_LIBDUCK,		  /* caller is DUCK library */
+    CFHT_LIBHELP,		  /* caller is Pegasus help library */
+    CFHT_LIBIDS,		  /* caller is IDS communication library */
+    CFHT_LIBPIXD,		  /* caller is pixel library */
+    CFHT_LIBTCS,		  /* caller is Telescope Control System */
+    CFHT_LIBUI,			  /* caller is user interface library */
+    CFHT_LIBCX,			  /* caller is coordinate transform library */
+    CFHT_LIBOMS,		  /* caller is OMS library */
+    CFHT_LIBSSX			  /* caller is ssx controller library */
+} cfht_log_who;
+
+/* type */
+typedef enum {
+    CFHT_LOG_ID = 0,		  /* client side initialization msg type */
+    CFHT_START,			  /* program is starting */
+    CFHT_STATUS,		  /* something interesting to the user */
+    CFHT_ERROR,			  /* error */
+    CFHT_FATAL = CFHT_ERROR,	  /* obsolete - about to exit due to error */
+    CFHT_ERRNO,			  /* do not use - error with errno message */
+    CFHT_WARN,			  /* warning - something's wrong */
+    CFHT_DONE,			  /* about to exit normally */
+    CFHT_LOGONLY,		  /* operational diagnositc info */
+    CFHT_DEBUG,			  /* program trace info */
+    CFHT_TIMING,		  /* print elapsed + delta times */
+    CFHT_FEEDINIT,		  /* init a feedback type output sink */
+    CFHT_FEEDQUIT,		  /* free up fd's, etc for feedback sinks */
+    CFHT_ROLLINIT,		  /* start up another roll type output sink */
+    CFHT_ROLLQUIT,		  /* shut down roll type output sinks */
+    CFHT_SHOWSINKS,		  /* used by developer to debug...  */
+    CFHT_SERVINIT		  /* re-init da logserver without killing it */
+} cfht_log_type;
+
+#define CFHT_DATE_SIZE 29	  /* size needed for cfht_date result */
+#define CFHT_UTDATE_SIZE 11	  /* size needed for cfht_UTdate result */
+#define CFHT_PFDATE_SIZE 11	  /* size needed for cfht_PFdate result */
+#define CFHT_TIME_SIZE 12	  /* size needed for cfht_time result */
+#define CFHT_UTTIME_SIZE 12	  /* size needed for cfhtUTtime result */
+
+/***********************
+ * parsing definitions *
+ ***********************/
+
+#define CFHT_STR_MATCH     1  /* check if input matches one of set of strings */
+#define CFHT_STR_INCLUDE   2  /* only pass through characters mentioned */
+#define CFHT_STR_EXCLUDE   3  /* only pass through characters not mentioned */
+#define CFHT_STR_NOWHITE   4  /* remove all white space from string */
+#define CFHT_STR_NOTRAIL   5  /* remove all trailing white space */
+#define CFHT_STR_ESCAPE    6  /* convert non-printing chars to escape codes */
+#define CFHT_STR_UNESCAPE  7  /* convert escape codes to chars */
+
+/**************************
+ * cfht_errno definitions *
+ **************************/
+
+typedef enum {
+    /* general error numbers */
+    CHECK_ERRNO = -1,		  /* check unix(tm) errno variable for reason */
+
+    /* unfortunately, some code stuffs errno into cfht_errno (e.g., old libids) */
+    /* so we need to use 0 but skip all low positive values */
+
+    NO_ERROR = 0,		  /* success */
+    NOT_A_TTY = 1000,		  /* historical uses, and general laziness */
+    PARSE_FAILED,		  /* unable to cope with input */
+    TOO_BIG,			  /* input exceeds hardware limit */
+    OUT_OF_RANGE,		  /* input exceeds software restriction */
+    TYPE_ERROR,			  /* incompatible or unexpected type */
+    UNIMPLEMENTED,		  /* feature not yet implemented */
+    BAD_OPTION,			  /* option passed in to routine was invalid */
+    INVALID_RANGE,		  /* range structure malformed or illegal */
+
+    /* OCS error codes */
+
+    OCS_FAILURE = 1100,		  /* internal OCS problem, e.g., buffers*/
+    OCS_NoSuchServer,		  /* requested non-existent server name */
+    OCS_SERVER_BUSY,		  /* couldn't get server's attention */
+    OCS_SERVER_T_REJECTED,	  /* task rejected by the server */
+    OCS_SERVER_T_FAILED,	  /* task didn't complete successfully */
+    OCS_NOTIFYCLOSED,		  /* server quit during transactions */
+    OCS_SERVER_TIMEOUT,		  /* server time-out on request */
+    OCS_ERROR,			  /* catchall */
+
+    /* OCS stuffs music's merrno in, so those should be here too */
+
+    M_NOSTART = 1200,		  /* did not call mstart() */
+    M_BODYTOOBIG,		  /* body overflow */
+    M_WRITERR,			  /* system error during write */
+    M_PARTWRITE,		  /* wrote partial message */
+    M_READERR,			  /* system error during read */
+    M_READCLOSED,		  /* read a closed fd */
+    M_BODYTOOSHORT,		  /* not enough in body for mget() */
+    M_BADMAGIC,			  /* bad magic numbers in header */
+    M_TIMEOUT,			  /* mread_until() timed-out */
+    M_NOQMSG,			  /* nothing to read on msg queue */
+
+    /* ids error codes */
+    IDS_openError = 1300,	  /* problem opening terminal */
+    IDS_termioError,		  /* problem doing termio ioctl */
+    IDS_FlushError,		  /* problem flushing buffer */
+    IDS_writeError,		  /* problem on write */
+    IDS_TimeOut,		  /* no response */
+    IDS_read0Bytes,		  /* read got nothing */
+    IDS_readError,		  /* read failed - not time out */
+
+    /* Client/Server codes */
+    CS_FakeMode = 1400,		  /* server is in fake mode */
+    CS_Disabled,		  /* server is disabled */
+
+    /* TCS error return codes */
+    TCS_InvalidCommand = 1500,	  /* invalid command sent to TCS */
+    TCS_InvalidArgument,	  /* invalid command argument sent to TCS */
+    TCS_NotTracking,		  /* TCS ignored command 'cause it's not on */
+    TCS_CommandFailed,		  /* TCS did command, but it did not work */
+    TCS_ConsolePrompt,		  /* TCS command prompt is probably up */
+    TCS_UnknownStatus,		  /* we don't understand returned code */
+
+    /* AOB error return codes */
+    AOB_UnknownCommand = 1600,	  /* we do not understand the command */
+    AOB_UnlockNotLocked,	  /* unlock when not locked */
+    AOB_NotLockOwner,		  /* unlock attempt by someone else? */
+    AOB_CurrentlyLocked,	  /* OMBA locked by another process */
+    AOB_BadArgValue,		  /* some argument was bad */
+
+    /* Coude f/4 and Gecko server conditions */
+    F4_UnknownCommand = 1700,	  /* empty / badly formed command */
+    F4_UnlockNotLocked,		  /* (NYI) already unlocked */
+    F4_NotLockOwner,		  /* (NYI) not server lock owner */
+    F4_CurrentlyLocked,		  /* (NYI) server locked by another process */
+    F4_BadArgValue,		  /* (NYI) server got bad argument */
+    F4_NotInitialized,		  /* no answer from the instrument hardware */
+    F4_TrafficError,		  /* server had trouble with ocs */
+    F4_DuckCommandError,	  /* problem sending to duck */
+    F4_DuckResponseError,	  /* problem with duck response */
+
+    cfht_errno_codes_filler	  /* ending dummy entry with no comma */
+} cfht_errno_CodesType;
+
+/*************************
+ * structure definitions *
+ *************************/
+
+struct cfht_rng_double {
+    double min;
+    double max;
+    BOOLEAN min_inclusive;
+    BOOLEAN max_inclusive;
+};
+struct cfht_rng_int {
+    int min;
+    int max;
+    BOOLEAN min_inclusive;
+    BOOLEAN max_inclusive;
+};
+struct cfht_rng_string {
+    char **string_array;
+};
+struct cfht_rng_char {
+    char *list_of_chars;
+};
+union cfht_ranges {
+    struct cfht_rng_double cfht_double_range;
+    struct cfht_rng_int cfht_int_range;
+    struct cfht_rng_string cfht_string_range;
+    struct cfht_rng_char cfht_char_range;
+};
+
+typedef union cfht_ranges *cfht_range_t;
+
+/*********************
+ * global references *
+ *********************/
+
+extern BOOLEAN cfht_debug;
+extern BOOLEAN cfht_error;
+extern BOOLEAN cfht_lib;
+extern BOOLEAN cfht_nodisp;
+extern int cfht_errno;
+
+extern union cfht_ranges *CFHT_RNG_RA;
+extern union cfht_ranges *CFHT_RNG_DEC;
+
+#define cfht_resetetimer() cfht_etimer(TRUE)
+#define cfht_delay(millisec) (void)cfht_sleep((millisec),1)
+
+/*
+ * Macro to put around system calls that might be interrupted by a signal.
+ * This is ripped from glibc.  It will keep re-trying systems calls until
+ * at least a partial success, or fatal error is encountered.  Note that
+ * read might still return FEWER BYTES than you told it to read if it is
+ * interrupted!
+ */
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(expression)               \
+({ long int __result;                                \
+     do __result = (long int) (expression);          \
+     while (__result == -1L && errno == EINTR);      \
+     __result; })
+#endif
+
+/*
+ * Special values that can be passed to cfht_signal()'s arg2
+ */
+
+#include <signal.h> /* for SIG_DFL and SIG_IGN */
+
+#define CFHT_SIG_TRAP ((PFV)cfht_signal_handler)
+  /* %%% The protos for CFHT_SIG_DFL et al are defined in terms of
+   *     SIG_DFL et al defined in signal.h, but unfortunately these
+   *     are not properly prototyped either :-(  Overriding them here
+   *     is kind of dangerous, and should be checked carefully.
+   */
+#undef  CFHT_SIG_DFL
+#undef  CFHT_SIG_IGN
+#define CFHT_SIG_DFL ((PFV)(0))
+#define CFHT_SIG_IGN ((PFV)(1))
+/*
+#define CFHT_SIG_DFL  ((PFV)SIG_DFL)
+#define CFHT_SIG_IGN  ((PFV)SIG_IGN)
+*/
+
+/*********************************************
+ * complete (?) list of all cfht_* functions *
+ *********************************************/
+
+char    *cfht_argsToString P((int argc, char *argv[]));
+void	cfht_awake P((double when_from_now, double how_often));
+char	*cfht_basename P((char *dest, char *filename, char *suffix));
+char	*cfht_cfhthome P((void));
+char	*cfht_date P((long *clockp));
+char	*cfht_PFdate P((int  days));
+char	*cfht_UTdate P((long *clockp));
+char	*cfht_UTtime P((long *clockp));
+char	*cfht_doupper P((char *str));
+double	cfht_dtime P((void));
+char	*cfht_fre P((unsigned char *src, unsigned char *dest, int *dsize));
+char	*cfht_toe P((unsigned char *src, unsigned char *dest, int ssize));
+double	cfht_etimer P((BOOLEAN reset));
+void	cfht_signal P((int signo, PFV handler));
+void	cfht_signal_block P((int signo));
+void	cfht_signal_unblock P((int signo));
+void    cfht_signal_handler P((int));
+BOOLEAN	cfht_signal_event P((int signo));
+BOOLEAN	cfht_signal_peek P((int signo));
+int	cfht_exec P((FILE_ID id, char *string, int type, volatile void *addr));
+int	cfht_system P((char *string));
+char	*cfht_frs P((char *dest, double val, int scale, int prec));
+void	cfht_genh P((int argc, char **argv, char **envp));
+void	usage P((char **msg));
+void	getcurdeath P((char *what));
+double	cfht_julian P((int year, int month, int day, int hour, int minute, double sec));
+void    cfht_fromjulian P((double jd, int *year, int *month, int *day, int *hour, int *minute, double *sec));
+char	*cfht_Mjulian P((long *clockp));
+char	*cfht_LocalSidTime P((long *clockp));
+BOOLEAN	cfht_checksem P((int semid));
+int	cfht_initsem P((char *path, char id));
+PASSFAIL cfht_setsem P((int semid));
+PASSFAIL cfht_setsemwait P((int semid, BOOLEAN sigign));
+PASSFAIL cfht_relsem P((int semid));
+PASSFAIL cfht_waitsemrel P((int semid, BOOLEAN sigign));
+PASSFAIL cfht_waitsemset P((int semid, BOOLEAN sigign));
+BOOLEAN cfht_checklock P((int fd));
+int	cfht_initlock P((char *path, char id));
+PASSFAIL cfht_setlock P((int fd));
+PASSFAIL cfht_setlockwait P((int fd, BOOLEAN sigign));
+PASSFAIL cfht_rellock P((int fd));
+PASSFAIL cfht_waitlockrel P((int fd, BOOLEAN sigign));
+PASSFAIL cfht_waitlockset P((int fd, BOOLEAN sigign));
+void	cfht_logv P((int who, int type, char *fmt, ...));
+void	cfht_logpv P((int who, int type, char *fmt, ...));
+void	cfht_log P((int who, int type, char *mess));
+void	cfht_log_proxy P((int who, int type, char *mess, char* id, int pid));
+PASSFAIL cfht_int P((char *in_str, int *out_addr, cfht_range_t rangeinfo));
+PASSFAIL cfht_double P((char *in_str, double *out_addr, cfht_range_t rangeinfo));
+long	cfht_od P((void));
+int	cfht_sleep P((int msec, int igsig));
+char	*cfht_string P((char *in_str, int operation, cfht_range_t rangeinfo));
+char	*cfht_time P((long *clockp));
+BOOLEAN	cfht_tob P((char *string));
+char	*cfht_tok P((char *string, char *sep, char **tail));
+void	cfht_goDaemon P((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * See comments in missing_protos.h
+ */
+#include <missing_protos.h>
+
+#endif /* CFHTDOTH */
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/include/cfht/exits.h
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/include/cfht/exits.h	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/include/cfht/exits.h	(revision 21897)
@@ -0,0 +1,61 @@
+/* Copyright (C) 1991, 94, 96    Canada-France-Hawaii Telescope Corp.    */
+/* This program is distributed WITHOUT any warranty, and is under the    */
+/* terms of the GNU General Public License, see the file COPYING    */
+/*****************************************************************************
+ *
+ * file: exits.h
+ * $Header: /cvsroot/pan-starrs/datasys/IPP/Ohana/src/misc/include/cfht/exits.h,v 1.1.1.1 2004-11-24 04:39:33 eugene Exp $
+ * $Locker:  $
+ *
+ * This file defines the various exit codes for controllers and handlers.
+ *
+ * NOTE: please see ui/listexits.c also when you change this !!!!!!!!!
+ *       The values of these exit codes are available symbolically in
+ *       shell scripts by using ". setexits".
+ *
+ * HISTORY
+ *
+ * who       when           what
+ * ------    -----------    ----------------------------------------------
+ * jk        24 Mar 1988    Original
+ *
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1.1.1  2001/07/25 02:59:24  eugene
+ * import Ohana
+ *
+ * Revision 1.4  96/08/12  15:30:00  15:30:00  thomas (Jim Thomas)
+ * Added AOB exit codes and some comments
+ * 
+ * Revision 1.3  94/12/14  17:27:07  17:27:07  thomas (Jim Thomas)
+ * Added pinger exit codes
+ * 
+ * Revision 1.2  93/06/26  17:59:06  17:59:06  steve (Steven Smith)
+ * added define for environment var to pass exit code of data taking handlers
+ * (ccdh, etc) for passing to all interested -E handlers.
+ * 
+ * Revision 1.1  91/09/24  17:38:54  17:38:54  steve (Steven Smith)
+ * Original checkin
+ * 
+ *****************************************************************************/
+
+#define EXIT_ENV_NAME	"CFHT_EXPOSURE_EXIT"
+#define EXIT_PASS 0		  /* everything is OK */
+#define EXIT_FAIL 1		  /* there was a real problem */
+#define EXIT_EXP_IN_PROGRESS 2	  /* can't do request - exposure already on */
+#define EXIT_EXP_ABORTED 3	  /* exposure trashed by user */
+#define EXIT_EXP_STOPPED 4	  /* exposure stopped by user */
+#define EXIT_CANCEL 5		  /* they hit the cancel button */
+
+/* pinger exit codes */
+#define PNG_EXIT_PASS EXIT_PASS	  /* service is healthy */
+#define PNG_EXIT_BUSY 1		  /* service is busy */
+#define PNG_EXIT_FAKE 2		  /* service is there but in FAKE mode */
+#define PNG_EXIT_NOTTHERE 3	  /* service isn't there at all */
+#define PNG_EXIT_NOTRAFFIC 4	  /* traffic isn't there */
+#define PNG_EXIT_ERROR 5	  /* some program or argument error happened */
+#define PNG_EXIT_HELP 6		  /* typed out the help message */
+
+/* AOB exit codes */
+#define AOB_EXIT_PASS EXIT_PASS	  /* things OK */
+#define AOB_EXIT_FAIL EXIT_FAIL	  /* real problem */
+#define AOB_EXIT_SEPARATION 2	  /* guide and object too far apart */
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/include/missing_protos.h
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/include/missing_protos.h	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/include/missing_protos.h	(revision 21897)
@@ -0,0 +1,303 @@
+/* Copyright (C) 1997-1999  Canada-France-Hawaii Telescope Corp.         */
+/* This program is distributed WITHOUT any warranty, and is under the    */
+/* terms of the GNU General Public License, see the file COPYING         */
+/*****************************************************************************
+ *
+ * missing_protos.h - ANSI prototypes for systems that lack complete ANSI
+ *                    system header files (especially SunOS 4.x).  This file
+ *                    should be included with `#include <missing_protos.h>'
+ *                    from "cfht/cfht.h" so that it does not show up in
+ *                    the dependencies generated by "gcc -MM".  Proper ANSI
+ *                    systems should not need anything from this file anyway,
+ *                    and thus will not be tempted to re-compile everything
+ *                    which depends on this file every time we need to add
+ *                    a new prototype for the SunOS machines.
+ * $Id: missing_protos.h,v 1.1.1.1 2004-11-24 04:39:33 eugene Exp $
+ * $Locker:  $
+ *
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1.1.1  2001/07/25 02:59:23  eugene
+ * import Ohana
+ *
+ * Revision 1.11  2000/02/10 13:52:23  isani
+ * Added a few more prototypes.
+ * Changed to new way of doing SELECT() call.
+ *
+ * Revision 1.10  1999/07/30 22:14:51  thomas
+ * HP added openlog/syslog in 10.X, if it out there
+ *
+ * Revision 1.9  1999/07/13 21:27:28  thomas
+ * Added WCOREDUMP for SunOS
+ *
+ * Revision 1.8  1999/07/13 00:17:24  thomas
+ * Fix 1.7, Sidik's model was not sufficient, plus GNU rcs would not let me
+ * cancel it ???
+ *
+ * Revision 1.7  1999/07/03 04:10:58  thomas
+ * Changed select for 10.20
+ *
+ * Revision 1.6  98/07/10  10:38:35  10:38:35  thomas (Jim Thomas)
+ * Added perror, strerror, memset, drand48 to SunOS prototypes
+ * 
+ * Revision 1.5  97/12/18  21:28:43  21:28:43  thomas (Jim Thomas)
+ * Put floatingpoint.h back in, added strtol, changed __STDC__ to __GNUC__
+ * 
+ * Revision 1.4  97/12/18  02:38:20  02:38:20  isani (Sidik Isani)
+ * Added redefinition of CFHT_SIG_{DFL,IGN} for SunOS
+ * 
+ * Revision 1.3  1997/12/05 20:49:44  thomas
+ * Added definition of const if not ANSI C
+ *
+ * Revision 1.2  97/12/05  20:20:44  20:20:44  jcc (Jean-Charles Cuillandre)
+ * Added include of resource.h
+ * 
+ * Revision 1.1  1997/11/23 11:29:04  isani
+ * Initial revision
+ *
+ ****************************************************************************/
+
+#ifndef _INCLUDED_missing_protos
+#define _INCLUDED_missing_protos 1
+
+/*
+ * Make.Common defines *one* of the following:
+ *             SUNOS, SOLARIS, HPUX, LINUX, VXWORKS, or CYGWIN32
+ * We will use these here, but for projects where Make.Include is used
+ * instead of Make.Common, check for some other predefined symbols like
+ * __sun__ to try to figure out the system type.
+ */
+
+#if defined(SunOS) && !defined(SUNOS)
+#define SUNOS
+#endif
+
+#if (defined(Linux) || defined(linux)) && !defined(LINUX)
+#define LINUX
+#endif
+
+/*
+ * First, make sure SUNOS didn't get defined by accident for a Solaris box.
+ * We use SOLARIS instead, because they are really different OS's.
+ */
+
+#if defined(SUNOS) && defined(__svr4__)
+#undef SUNOS
+#ifndef SOLARIS
+#define SOLARIS
+#endif
+#endif
+
+#if !defined(SUNOS) && !defined(SOLARIS) && !defined(HPUX) && !defined(LINUX) && !defined(CYGWIN32) && !defined(VXWORKS)
+/*
+ * If Make.Common isn't being used ...
+ */
+#if defined(__sun__) || defined(sun)
+#ifndef sun
+#define sun
+#endif
+#ifdef __svr4__
+#define SOLARIS
+#else
+#define SUNOS
+#endif
+#else
+#if defined(__hpux__) || defined(hpux)
+#ifndef hpux
+#define hpux
+#endif
+#define HPUX
+#else
+error: Unknown system type!
+error: This software has not been tested on this platform.
+error: (comment out this block to compile anyway).
+#endif /* __hpux__ */
+#endif /* __sun__ */
+#endif /* !SUNOS && !SOLARIS && !HPUX ... */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* "const" has been added to a bunch of definitions, but that is ANSI :-( */
+#ifndef __STDC__
+#define const
+#endif
+
+/*
+ * Here are the hacks for the old suns, so we don't have to include them
+ * in each source file.  Solaris 2.x does not need any of this stuff...
+ */
+
+#ifdef SUNOS
+#define mktime timelocal
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#ifndef WCOREDUMP
+#define WCOREDUMP(n) 0
+#endif
+#include <malloc.h>
+#include <unistd.h>
+#ifdef __GNUC__
+#include <float.h>             /* for DBL_MIN and DBL_MAX */
+#else
+#include <values.h>
+#ifndef DBL_MIN
+#define DBL_MIN MINDOUBLE
+#define DBL_MAX MAXDOUBLE
+#endif
+#endif /* !__GNUC__ */
+#ifdef __GNUC__
+void    perror(const char *s);
+char	*strerror(int);
+int     ioctl(int, int, ...);
+int     select(int, fd_set*, fd_set*, fd_set*, struct timeval*);
+/* bzero is not ANSI, but the FD_ macros for select need it, so we need a
+ * proto here to prevent warnings.  Use memset() in your own code instead!
+ */
+void    bzero(char*, int);
+void*   memset(void*, int, size_t);
+int     socket(int, int, int);
+int     bind(int,  struct sockaddr*, int);
+int     listen(int, int);
+int     connect(int, struct sockaddr*, int);
+int     accept(int, struct sockaddr*, int*);
+int     shutdown(int, int);
+int     getsockname(int,struct sockaddr*,int*);
+int     getpeername(int,struct sockaddr*,int*);
+int     setsockopt(int,int,int,const void*,int);
+int     socketpair(int,int,int,int [2]);
+int     getrlimit(int,struct rlimit*);
+int     setrlimit(int,const struct rlimit*);
+int     gettimeofday(struct timeval *tp, struct timezone *tzp);
+int     rename(const char*, const char*);
+int     symlink(const char*, const char*);
+int     readlink(const char*, char*, int);
+int     lstat(const char*, struct stat*);
+int     openlog(const char*, int, int);
+int     syslog(int, const char*, ...);
+int     getitimer(int, struct itimerval*);
+int     setitimer(int, const struct itimerval*, struct itimerval*);
+int	fchmod(int, int);
+int	getdtablesize(void);
+int	semop(int, struct sembuf*, unsigned int);
+key_t	ftok(const char *, int);
+int	semget(key_t, int, int);
+int	lockf(int, int, off_t);
+int	ftruncate(int, off_t);
+/* %%% The protos for CFHT_SIG_DFL et al are defined in terms of
+ *     SIG_DFL et al defined in signal.h, but unfortunately these
+ *     are not properly prototyped either :-(  Overriding them here
+ *     is kind of dangerous, and should be checked carefully.
+ */
+#undef  CFHT_SIG_DFL
+#undef  CFHT_SIG_IGN
+#define CFHT_SIG_DFL ((PFV)(0))
+#define CFHT_SIG_IGN ((PFV)(1))
+#else  /* not __GNUC__ */
+#include <floatingpoint.h>
+void perror();
+char *strerror();
+void *memset();
+double drand48();
+long strtol();
+#endif /* __GNUC__ */
+#endif /* SUNOS */
+
+/*
+ * Here are the hacks that are also needed on the newer Solaris 2.x machines.
+ */
+#if defined(SUNOS) || defined(SOLARIS)
+#include <unistd.h>
+#ifdef __STDC__
+int	gethostname(char*, int);
+int     seteuid(uid_t euid);
+int     setegid(gid_t egid);
+int	setreuid(uid_t, uid_t);
+int	setregid(gid_t, gid_t);
+char*   crypt(const char*, const char*);
+#endif
+extern char** environ;
+#endif
+
+/*
+ * HPUX has some quirks too.
+ */
+#ifdef HPUX
+#if defined(OSVersion) && (OSVersion < 10)
+/*
+ * Make.Common defines HACK_SELECT directly and doesn't use this.
+ * See #if/not HACK_SELECT below also.
+ */
+#define HACK_SELECT
+#endif
+
+/* HP 10.20 seems not to define socklen_t */
+
+#define socklen_t int
+
+/* See comments above under SUNOS */
+#undef  CFHT_SIG_DFL
+#undef  CFHT_SIG_IGN
+#define CFHT_SIG_DFL ((PFV)(0))
+#define CFHT_SIG_IGN ((PFV)(1))
+
+#define seteuid(euid) setresuid(-1,(euid),-1)
+#define setegid(egid) setresgid(-1,(egid),-1)
+#ifdef __STDC__
+/* HP-UX 9 needed these.  Shouldn't hurt under 10.20 as long as they match. */
+void openlog(const char *, int, int);
+void syslog(int, const char *, ...);
+#endif
+#else /* not HP */
+#ifdef __STDC__
+/* only HP provides a prealloc function */
+int	prealloc(int fildes, unsigned size);
+#endif
+#endif
+
+/*
+ * CYGWIN32 is still in beta, so probably much of this stuff
+ * will need to be removed once this compiler stabilizes.
+ */
+#ifdef CYGWIN32
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#define seteuid(x) (0)
+#define setegid(x) (0)
+#define setuid(x)  (0)
+#define setgid(x)  (0)
+int readlink(const char*, char*, int);
+int select(int,fd_set*,fd_set*,fd_set*,struct timeval*);
+int lstat(const char*, struct stat*);
+int gettimeofday(struct timeval*, struct timezone*);
+const char* crypt(const char*, const char*);
+#endif
+
+/*
+ * Before version 10, HP defines fd_set, but doesn't use it in the prototype
+ * for select().  Also the count is size_t (which is right, why did ANSI
+ * lose that one?  I guess because C does not really support types :-( ).
+ * So do select() like this to avoid warnings on HP
+ *
+ *   Status = SELECT(n, read, write, error, &timestruct);
+ */
+#ifdef HACK_SELECT
+#define SELECT(n, read, write, error, tp)        \
+        select((size_t) (n), (int *) (read),     \
+               (int *) (write), (int *) (error), \
+	       (tp))
+#else
+/* Let the compiler check against a real prototype. */
+#define SELECT select
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !_INCLUDED_missing_protos */
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/SAOobjects.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/SAOobjects.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/SAOobjects.c	(revision 21897)
@@ -0,0 +1,87 @@
+# include "ohana.h"
+# include "dvo.h"
+
+main (int argc, char **argv) {
+
+  FILE *f;
+  char line[256], name[256];
+  Header header;
+  Coords coords;
+  double R, D, dR, dD;
+  double X, Y, dX, dY;
+  double angle;
+  int Nfield;
+
+  if (argc != 3) {
+    fprintf (stderr, "USAGE: %s (image.fits) (input)\n", argv[0]);
+    exit (1);
+  }
+
+  if (!gfits_read_header (argv[1], &header)) {
+    fprintf (stderr, "can't read header from file %s\n", argv[1]);
+    exit (1);
+  }
+
+  if (!GetCoords (&coords, &header)) {
+    fprintf (stderr, "can't find appropriate astrometry in image header\n");
+    exit (1);
+  }
+
+  /* load in the object description list */
+
+  /* fields for each line should be:
+     name (string)
+     Ra (dec. degrees)
+     Dec (dec. degrees)
+     dRa (arcsec)
+     dDec (arcsec)
+     angle (degrees)
+  */
+
+  if (argv[2][0] == '-') {
+    f = stdin;
+  } else {
+    f = fopen (argv[2], "r");
+    if (f == (FILE *) NULL) {
+      fprintf (stderr, "can't open input data file\n");
+      exit (1);
+    }
+  }
+
+  while (scan_line (f, line) != EOF) {
+    Nfield = sscanf (line, "%s %lf %lf %lf %lf %lf", name, &R, &D, &dR, &dD, &angle);
+    
+    if (Nfield < 4) {
+      fprintf (stderr, "*");
+      continue;
+    }
+    
+    RD_to_XY (&X, &Y, R, D, &coords);
+
+    /* we won't worry about the case of cdelt1 != cdelt2,
+       in which case we don't have to worry about rotation 
+       between RA,DEC and X,Y for the calculation of the
+       slit lenghts.  Note that this assumption does not 
+       cause errors with the varying projected slitlength in
+       RA units, that is taken care of by the projection.
+       But, we are not taking into account a rotated slit */
+
+    dX = dR / 3600.0 / coords.cdelt1;
+    dY = dD / 3600.0 / coords.cdelt2;
+
+    switch (Nfield) {
+    case 4:
+      fprintf (stdout, "%s(%f,%f,%f)\n", name, X, Y, dX);
+      break;
+    case 5:
+      fprintf (stdout, "%s(%f,%f,%f,%f)\n", name, X, Y, dX, dY);
+      break;
+    case 6:
+      fprintf (stdout, "%s(%f,%f,%f,%f,%f)\n", name, X, Y, dX, dY, angle);
+      break;
+    }
+  }
+
+  if (f != stdin) fclose (f);
+
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/addastro.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/addastro.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/addastro.c	(revision 21897)
@@ -0,0 +1,105 @@
+# include <ohana.h>
+# define BLOCK 0x1000
+
+main (int argc, char **argv) {
+
+  /* USAGE: addastro (cmp) (ref) */
+
+  int i, j, nbytes, itmp, oldsize;
+  double tmp;
+  Header header, refhead;
+  FILE *f, *g;
+  char filename[1024];
+  char buffer[0x1000];
+
+  if (argc != 3) {
+    fprintf (stderr, "USAGE: addastro (cmp) (ref)\n");
+    exit (1);
+  }
+
+  if (!gfits_read_header (argv[1], &header)) {
+    fprintf (stderr, "ERROR: can't read header for %s\n", argv[1]);
+    exit (1);
+  }
+  oldsize = header.size;
+
+  if (!gfits_read_header (argv[2], &refhead)) {
+    fprintf (stderr, "ERROR: can't read header for %s\n", argv[2]);
+    exit (1);
+  }
+
+  gfits_scan   (&refhead, "CDELT1",   "%lf", 1, &tmp);
+  gfits_modify (&header,  "CDELT1",   "%le", 1, tmp);
+  gfits_scan   (&refhead, "CDELT2",   "%lf", 1, &tmp);
+  gfits_modify (&header,  "CDELT2",   "%le", 1, tmp);
+  gfits_scan   (&refhead, "CRVAL1",   "%lf", 1, &tmp);
+  gfits_modify (&header,  "CRVAL1",   "%lf", 1, tmp);
+  gfits_scan   (&refhead, "CRVAL2",   "%lf", 1, &tmp);
+  gfits_modify (&header,  "CRVAL2",   "%lf", 1, tmp);
+  gfits_scan   (&refhead, "CRPIX1",   "%lf", 1, &tmp);
+  gfits_modify (&header,  "CRPIX1",   "%lf", 1, tmp);
+  gfits_scan   (&refhead, "CRPIX2",   "%lf", 1, &tmp);
+  gfits_modify (&header,  "CRPIX2",   "%lf", 1, tmp);
+  gfits_scan   (&refhead, "PC001001", "%lf", 1, &tmp);
+  gfits_modify (&header,  "PC001001", "%le", 1, tmp);
+  gfits_scan   (&refhead, "PC001002", "%lf", 1, &tmp);
+  gfits_modify (&header,  "PC001002", "%le", 1, tmp);
+  gfits_scan   (&refhead, "PC002001", "%lf", 1, &tmp);
+  gfits_modify (&header,  "PC002001", "%le", 1, tmp);
+  gfits_scan   (&refhead, "PC002002", "%lf", 1, &tmp);
+  gfits_modify (&header,  "PC002002", "%le", 1, tmp);
+  gfits_scan   (&refhead, "NPLYTERM", "%d",  1, &itmp);
+  gfits_modify (&header,  "NPLYTERM", "%d",  1, itmp);
+  gfits_scan   (&refhead, "NASTRO",   "%d",  1, &itmp);
+  gfits_modify (&header,  "NASTRO",   "%d",  1, itmp);
+  gfits_scan   (&refhead, "CERROR",   "%lf", 1, &tmp);
+  gfits_modify (&header,  "CERROR",   "%lf", 1, tmp);
+  gfits_scan   (&refhead, "CPRECISE", "%lf", 1, &tmp);
+  gfits_modify (&header,  "CPRECISE", "%lf", 1, tmp);
+
+  gfits_modify (&header, "CERROR", "%C", 1, "scatter in astrometry soln (arcsec)");
+  gfits_modify (&header, "CPRECISE", "%C", 1, "precision of astrometry soln (arcsec)");
+
+  /* write to file */
+  sprintf (filename, "%s.tmp", argv[1]);
+  if (!gfits_write_header (filename, &header)) {
+    fprintf (stderr, "ERROR: can't write header for %s\n", filename);
+    exit (1);
+  }
+  g = fopen (filename, "w");
+  if (g == NULL) {
+    fprintf (stderr, "ERROR: can't read write to %s\n", filename);
+    exit (1);
+  }
+  nbytes = fwrite (header.buffer, 1, header.size, g);
+  fseek (g, header.size, SEEK_SET); 
+
+  /* read date from file */
+  f = fopen (argv[1], "r");
+  if (f == NULL) {
+    fprintf (stderr, "ERROR: can't read data from %s\n", argv[1]);
+    exit (1);
+  }
+  fseek (f, oldsize, SEEK_SET); 
+
+  while ((nbytes = fread (buffer, 1, BLOCK, f)) > 0) {
+    if (nbytes != fwrite (buffer, 1, nbytes, g)) {
+      fprintf (stderr, "ERROR: failure writing output data file\n");
+      exit (0);
+    }
+  }
+  
+  fclose (f);
+  fclose (g);
+
+  sprintf (buffer, "mv %s %s~\n", argv[1], argv[1]);
+  system (buffer);
+
+  sprintf (buffer, "mv %s %s\n", filename, argv[1]);
+  system (buffer);
+
+  fprintf (stdout, "SUCCESS\n");
+
+
+}
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/applyscat.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/applyscat.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/applyscat.c	(revision 21897)
@@ -0,0 +1,128 @@
+# include <ohana.h>
+# include <dvo.h>
+# define BYTES_STAR 66
+
+int main (int argc, char **argv) {
+
+  Header header;
+  Matrix matrix;
+  Stars *stars;
+  int Nstar, Nbytes, nbytes;
+  FILE *f;
+  char *buffer, line[10];
+  double dmag, ratio;
+  int i, x, y;
+
+  if (argc != 4) {
+    fprintf (stderr, "USAGE: applyscat (input) (scatter) (output)\n");
+    exit (1);
+  }
+
+  /* read smp header */
+  if (!gfits_read_header (argv[1], &header)) {
+    fprintf (stderr, "ERROR: can't find image file %s\n", argv[1]);
+    exit (1);
+  }
+
+  /* open file for star data */
+  f = fopen (argv[1], "r");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "ERROR: can't read data from %s\n", argv[1]);
+    exit (1);
+  }
+  fseek (f, header.size, SEEK_SET); 
+
+  /* find expected number of stars */
+  gfits_scan (&header, "NSTARS", "%d", 1, &Nstar);
+  if (Nstar == 0) {
+    fprintf (stderr, "ERROR: can't get NSTARS from header\n");
+    exit (1);
+  }
+
+  /* allocate work space */
+  Nbytes = Nstar*BYTES_STAR;
+  ALLOCATE (stars, Stars, Nstar);
+  ALLOCATE (buffer, char, Nbytes + 1);
+
+  /* load in data */
+  nbytes = fread (buffer, 1, Nbytes, f);
+  if (nbytes != Nbytes) {
+    fprintf (stderr, "ERROR: can't load in all stars\n");
+    exit (1);
+  }
+  buffer[Nbytes] = 0;
+  fclose (f);
+  
+  for (i = 0; i < Nstar; i++) {
+    dparse (&stars[i].X,  1, &buffer[i*BYTES_STAR]);
+    dparse (&stars[i].Y,  2, &buffer[i*BYTES_STAR]);
+    dparse (&stars[i].M,  3, &buffer[i*BYTES_STAR]);
+  }
+
+  if (!gfits_read_matrix (argv[2], &matrix)) {
+    fprintf (stderr, "ERROR: can't open scatter image file %s\n", argv[2]);
+    exit (1);
+  }
+  
+  /* flat' = flat*ratio
+     flux' = flux / ratio
+     mag'  = mag - dmag
+     dmag = -2.5*log10(ratio) 
+
+     ie, ratio = 1.1
+     flux' = 0.9*flux (flux' < flux)
+     dmag = -0.103
+     mag' = mag + 0.103 (mag' > mag)
+  */
+
+  for (i = 0; i < Nstar; i++) {
+    x = stars[i].X;
+    y = stars[i].Y;
+    ratio = gfits_get_matrix_value (&matrix, x, y);
+    dmag = -2.5*log10(ratio);
+    dmag = (dmag > +1.0) ? 0.0 : dmag;
+    dmag = (dmag < -1.0) ? 0.0 : dmag;
+    stars[i].M -= dmag;
+  }
+
+  /* full format line: "%6.1f %6.1f %6.3f %03d %2d %3.1f %6.3f %6.3f %6.2f %6.2f %5.1f", X, Y, M, dM, dophot, sky, Mgal, Map, fx, fy, df */
+  for (i = 0; i < Nstar; i++) {
+    sprintf (line, "%6.3f", stars[i].M);
+    memcpy (&buffer[i*BYTES_STAR+14], line, 6);
+  }
+
+  /* write smp header */
+  if (!gfits_write_header (argv[3], &header)) {
+    fprintf (stderr, "ERROR: can't write output file header %s\n", argv[3]);
+    exit (1);
+  }
+
+  /* open file for star data */
+  f = fopen (argv[3], "a");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "ERROR: can't open output file %s\n", argv[3]);
+    exit (1);
+  }
+  fseek (f, header.size, SEEK_SET); 
+
+  /* load in data */
+  nbytes = Fwrite (buffer, 1, Nbytes, f, "char");
+  if (nbytes != Nbytes) {
+    fprintf (stderr, "ERROR: problem writing stars\n");
+    exit (1);
+  }
+  fclose (f);
+
+  exit (0);
+}
+
+
+
+
+/* load in smp header
+   load in smp stars
+   load in scatter frame
+   apply corrections
+   write smp header
+   write smp stars
+*/
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/cfhtlog.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/cfhtlog.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/cfhtlog.c	(revision 21897)
@@ -0,0 +1,405 @@
+/****************************************************************************
+    Copyright (C) 1991, 1995    Canada-France-Hawaii Telescope Corp.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 1, or (at your option)
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    Contact information:
+    CFHT, PO Box 1597, Kamuela, HI 96743, USA
+    daprog@cfht.hawaii.edu
+
+****************************************************************************/
+/*!****************************************************************************
+ * FILE
+ *
+ * $Header: /cvsroot/pan-starrs/datasys/IPP/Ohana/src/misc/src/cfhtlog.c,v 1.1 2003-01-17 18:42:35 eugene Exp $
+ * $Locker:  $
+ *
+ * ROUTINES
+ *
+ *
+ * HISTORY
+ * who          when            what
+ * ---------    ------------    ----------------------------------------------
+ *
+ * $Log: not supported by cvs2svn $
+ * Revision 1.1.1.1  2001/07/25 02:59:22  eugene
+ * import Ohana
+ *
+ * Revision 1.4  2001/01/25 21:21:06  bernt
+ * nothing changed
+ *
+ * Revision 1.3  1999/07/06 14:14:07  bernt
+ * *** empty log message ***
+ *
+ * Revision 1.2  98/06/09  22:50:01  22:50:01  bernt (Bernt Grundseth)
+ * clean some unused vars
+ * 
+ * Revision 1.1  97/11/21  11:28:53  11:28:53  bernt (Bernt Grundseth)
+ * Initial revision
+ * 
+ * Revision 1.5  96/11/17  22:59:00  22:59:00  bernt (Bernt Grundseth)
+ * *** empty log message ***
+ * 
+ * Revision 1.4  96/05/29  15:27:03  15:27:03  bernt (Bernt Grundseth)
+ * removed reading from current.dat file, because the last data file is 
+ * copied to uwila_data every ten minutes instead of the temporary kludge
+ * with the current.dat file.
+ * 
+ * Revision 1.3  96/05/29  07:23:29  07:23:29  bernt (Bernt Grundseth)
+ * *** empty log message ***
+ * 
+ * Revision 1.2  96/02/20  21:58:38  21:58:38  bernt (Bernt Grundseth)
+ * basic operations working still need improvements, range checking
+ * 
+ * Revision 1.1  96/02/19  22:31:43  22:31:43  bernt (Bernt Grundseth)
+ * Initial revision
+ * 
+ * 
+ ***************************************************************************!*/
+
+#include <stdio.h>
+#include <string.h>		  /* for string functions */
+#include <stdlib.h>		  /* for strtoul */
+#ifdef sun
+#define strtoul strtol		  /*   but sun doesn't have one */
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>		  /* for time functions */
+#ifdef sun
+#define mktime timelocal	  /*   but sun has a different name */
+#endif
+#include <errno.h>		  /* for ERANGE */
+
+#include <cfht/cfht.h>		  /* for P macro */
+#include <cfht/exits.h>           /* for standard exit codes */
+
+
+void dp_usage P((char *s));       	  /* usage exit */
+PASSFAIL TimeStringToTime P((char *String, time_t *Time));
+double cfht_julian();
+void cfht_fromjulian();
+double atof();
+
+time_t TimeNow;			  /* current time */
+static char path[] = "/data/logger/";
+#define NUMITEMS 915
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+#ifndef __LINT__
+    static char rcs_id[] =
+      "$Header: /cvsroot/pan-starrs/datasys/IPP/Ohana/src/misc/src/cfhtlog.c,v 1.1 2003-01-17 18:42:35 eugene Exp $";
+#endif
+    /* command line argument values */
+    char *OurName;		  /* name of executing program */
+    char *Input = (char *) NULL;  /* name of [pipe] to read */
+    char *SessionName = (char *) NULL; /* name of session to match */
+    char *FromString = (char *) NULL; /* time to start outputting */
+    char *ToString = (char *) NULL; /* time to stop outputting */
+    char *ProbeString = (char *) NULL; /* probes  */
+    BOOLEAN Verbose = FALSE;	  /* want lots of debug output? */
+    BOOLEAN GoBackwards = TRUE;	  /* want LIFO or FIFO?  TRUE = LIFO */
+    BOOLEAN Dosuid = FALSE;	  /* do suid?  TRUE = yes */
+    unsigned int HoursBack = 0;	  /* start output this far back */
+    time_t FromTime;		  /* from time in internal form */
+    time_t ToTime;		  /* to time in internal form */
+
+    int Probes[100], nprobes;
+    double JDFrom, JDTo;
+    struct tm *tmd;
+
+
+
+    int i;			  /* index into argv */
+    int nlen;			  /* temporary  */
+
+    
+    OurName = cfht_basename((char *) NULL, argv[0], (char *) NULL);
+    if (argc < 2) {
+        dp_usage(argv[0]); /* else error */
+        exit(EXIT_FAIL);
+    }
+
+
+    time(&TimeNow);		  /* get current time */
+    tmd = localtime(&TimeNow);
+    printf("# DATE/TIME now %d %d %d %d %d %d\n",
+		   tmd->tm_year+1900, tmd->tm_mon+1, tmd->tm_mday,
+		   tmd->tm_hour, tmd->tm_min, tmd->tm_sec);
+    
+    for (i = 1 ; i < argc ; i++) {
+	if (argv[i][0] == '-') {
+	    switch (argv[i][1]) {
+
+	      case 'f':
+		FromString = argv[++i]; /* get from time from command line */
+		printf("# from date %s \n",FromString);
+                if (get_JDdate(FromString, &JDFrom)) {
+		    printf("# malformed date: %s \n",FromString);
+                    exit(EXIT_FAIL);
+                }
+		printf("#  julian day = %lf\n", JDFrom);
+		break;
+
+	      case 't':
+		ToString = argv[++i]; /* get to time from command line */
+		printf("# to date %s \n",ToString);
+                if (get_JDdate(ToString, &JDTo)) {
+		    printf("# malformed date: %s \n",ToString);
+                    exit(EXIT_FAIL);
+                }
+		printf("#  julian day = %lf\n", JDTo);
+		break;
+
+	      case 'p':
+		ProbeString = argv[++i]; /* get probes from command line */
+		break;
+
+	      case 'h':
+		/* one hour */
+
+                JDTo = cfht_julian(tmd->tm_year + 1900, tmd->tm_mon + 1,
+		  		  tmd->tm_mday, tmd->tm_hour,
+				  tmd->tm_min, (double)tmd->tm_sec);
+                JDTo = JDTo + 10./24.;
+                JDFrom = JDTo - 1.0/24.0;
+		printf("# INTERVAL: hour\n");
+		break;
+
+	      case 'd':
+		/* one day */
+
+                JDTo = cfht_julian(tmd->tm_year + 1900, tmd->tm_mon + 1,
+		  		  tmd->tm_mday, tmd->tm_hour,
+				  tmd->tm_min, (double)tmd->tm_sec);
+                JDTo = JDTo + 10./24.;
+                JDFrom = JDTo - 1.0;
+		printf("# INTERVAL: day\n");
+		break;
+
+	      case 'w':
+		/* one week */
+
+                JDTo = cfht_julian(tmd->tm_year + 1900, tmd->tm_mon + 1,
+		  		  tmd->tm_mday, tmd->tm_hour,
+				  tmd->tm_min, (double)tmd->tm_sec);
+                JDTo = JDTo + 10./24.;
+                JDFrom = JDTo - 7.0;
+		printf("# INTERVAL: week\n");
+		break;
+
+	      case 'm':
+		/* one month */
+
+                JDTo = cfht_julian(tmd->tm_year + 1900, tmd->tm_mon + 1,
+		  		  tmd->tm_mday, tmd->tm_hour,
+				  tmd->tm_min, (double)tmd->tm_sec);
+                JDTo = JDTo + 10./24.;
+                JDFrom = JDTo - 30.0;
+		printf("# INTERVAL: month\n");
+		break;
+
+	      default:
+		dp_usage(argv[0]); /* else error */
+	    }
+	} 
+
+    }
+
+    /* parse the probes numbers requested, and total # of probes */
+    if (ProbeString == NULL) { printf("# no probes selected\n");
+        exit(EXIT_FAIL);
+	}
+
+    get_tokens(ProbeString, " ,",Probes, &nprobes);
+    printf("# PROBES: %d ", nprobes); 
+    for (i = 0; i < nprobes; i++) {
+	if (Probes[i] < 0 || Probes[i] > 99 ) {
+	    printf("# error probe # out of range\n");
+            exit(EXIT_FAIL);
+        }
+    printf(" %d ", Probes[i]); 
+    }
+    printf("\n"); 
+    get_data(JDFrom, JDTo, Probes, nprobes); 
+
+
+    exit(EXIT_PASS);
+    return(0);			  /* dummy */
+}
+
+PASSFAIL
+get_data(JDstart, JDend, probes, nprobes)
+double JDstart, JDend;
+int probes[], nprobes;
+{
+    FILE *infile;
+    double julind, jd, jd0;
+    int year, month, day, hour, min, dayno;
+    double sec;
+    char fullname[64];
+    char filename[32];
+
+    char string[512];
+    double timestamp;
+    char data[915];
+    char bufstr[12];
+    long line = 0;
+    int nchar,j;
+
+    /* make JDstart to be in the 10 minutes boundary */
+    cfht_fromjulian(JDstart, &year, &month, &day, &hour, &min, &sec);
+    min = min/10*10;
+    sec = 0.;
+    JDstart = cfht_julian(year, month , day, hour, min, sec);
+
+
+    /* At this point it is assumed that the dates are OK.  */
+    /* get get year and day number at start  */
+    for (julind = JDstart -1; julind <= JDend; julind=julind+1.) {
+	jd = julind -10./24.;
+        cfht_fromjulian(jd, &year, &month, &day, &hour, &min, &sec);
+        jd0 = cfht_julian(year, 1 , 1, 0, 0, 0.);
+	dayno = jd -jd0 + 1;
+	strcpy (fullname, path);
+	sprintf(filename, "%d/%d%.3d.dat",year,(year-1900),dayno);
+	strcat (fullname, filename);
+
+	infile = fopen(fullname, "r");
+	if (infile == NULL) {
+	    if ( (int)julind < (int)JDend ) { /* last one ??? */
+	        sprintf (string, "# unable to open input file '%s'", fullname);
+	        perror (string);
+	    }
+
+	} else {
+        /*********************
+         * process each line *
+         *********************/
+            while ((nchar = fread(data, sizeof(char), NUMITEMS, infile)) > 0 ) {
+	        timestamp = atof(data) + 0.00001;
+
+	        if ((timestamp >= JDstart) && (timestamp <= JDend)) {
+                    cfht_fromjulian((timestamp-10./24.), &year, &month, &day,
+				    &hour, &min, &sec);
+		    printf("%lf ", timestamp - JDstart);
+		    printf("%lf ", (timestamp - JDstart)*24.0);
+		    printf("%.2d/%.2d/%.2d %.2d:%.2d ",
+		           year, month,day,hour,min);
+		    for (j = 0; j < nprobes; j++) {
+		        strncpy(bufstr, data + (14 + probes[j]*9), 9);
+		        bufstr[9] =0;
+		        printf("%s ", bufstr);
+		    }
+		    printf("\n");
+                }
+            }
+	    fclose(infile);
+        }
+
+    }
+    return(PASS);
+}
+
+
+PASSFAIL
+get_JDdate(datestring, JD)
+char *datestring;
+double *JD;
+{
+    int vect[10];
+    int n;
+    int year, month, day, hour, min, sec;
+    get_tokens(datestring, " /:", vect, &n);
+    if (n < 3 ) {
+	return(FAIL);
+    }
+/*    year = vect[0] + 1900; */
+    year = vect[0];
+    if (year < 1993 || year > 2010 )
+	return(FAIL);
+    month = vect[1];
+    if (month < 1 || month > 12 )
+	return(FAIL);
+    day = vect[2];
+    if (day < 1 || day > 31 )
+	return(FAIL);
+    hour = 0;
+    min  = 0;
+    sec  = 0;
+    if ( n > 3 ) {
+       hour = vect[3];
+       if (hour < 0 || hour > 23 )
+           return(FAIL);
+    }
+    if ( n > 4 ) {
+       min = vect[4];
+       if (min < 0 || min > 59 )
+           return(FAIL);
+    }
+    if ( n > 5 ) {
+       sec = vect[5];
+       if (sec < 0 || sec > 59 )
+           return(FAIL);
+    }
+    *JD = cfht_julian(year, month, day, hour, min, (double)sec);
+    *JD = *JD + 10.0 / 24.0;
+    return(PASS);
+}
+
+PASSFAIL
+get_tokens(buf, sep, vect, nitems)
+char buf[];
+char *sep;
+int vect[];
+int *nitems;
+{
+    char *cp;
+    int i;
+
+    cp = strtok(buf, sep);
+    vect[0] = atoi(cp);
+
+
+    i = 1;
+    while( 1 ) {
+
+        if( (cp = strtok(0, sep) ) == 0 ) {
+        break;
+        }
+        vect[i] = atoi(cp);
+        i++;
+    }
+    *nitems = i;
+
+    return(PASS);
+}
+
+/* usage: prints default error message and then exits */
+/* s is program name */
+void dp_usage(s)
+    char *s;
+{
+    fprintf(stderr, "Usage: %s\n", s);
+    fprintf(stderr, " [-h ] [-d] [-w] [-m]\n");
+    fprintf(stderr, " 1 hour, 1 day, 1 week, 1 month  \n");
+    fprintf(stderr, " [-f timefrom] [-t timeto] -p probeNumber\n");
+    fprintf(stderr, " Ex. -f \"2000/02/23 10:00:00\" -t \"2000/02/24\" -p 1,2,13,45\n");
+    exit(EXIT_FAIL);
+}
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/ckfits.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/ckfits.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/ckfits.c	(revision 21897)
@@ -0,0 +1,58 @@
+# include <ohana.h>
+# include <gfitsio.h>
+
+int main (int argc, char **argv) {
+
+  int i, Nbytes, nbytes, Ndata, Ntotal, nskip, status;
+  Header header;
+  FILE *f;
+  char *buffer;
+
+  if (argc != 2) {
+    fprintf (stdout, "USAGE: ckfits (filename)\n");
+    exit (2);
+  }
+
+  status = gfits_read_header (argv[1], &header);
+  if (!status) { 
+    fprintf (stdout, "%s: header\n", argv[1]);
+    exit (1);
+  }
+
+  Ntotal = gfits_matrix_size (&header);
+
+  Ndata = abs(header.bitpix / 8);
+  for (i = 0; i < header.Naxes; i++) Ndata *= header.Naxis[i];
+
+  nbytes = Ntotal - Ndata;
+  nskip = Ndata + header.size;
+
+  f = fopen (argv[1], "r");
+  if (f == (FILE *) NULL) {
+    fprintf (stdout, "%s: open\n", argv[1]);
+    exit (1);
+  }
+
+  ALLOCATE (buffer, char, MAX (nbytes, 1));
+  fseek (f, nskip, SEEK_SET);
+  Nbytes = fread (buffer, 1, nbytes, f);
+  fclose (f);
+
+  if (Nbytes != nbytes) {
+    fprintf (stdout, "%s: short\n", argv[1]);
+    exit (1);
+  }
+
+  for (i = 0; i < nbytes; i++) {
+    if (buffer[i]) {
+      fprintf (stdout, "%s: padding\n", argv[1]);
+      exit (1);
+    }
+  }
+
+  fprintf (stdout, "%s: ok\n", argv[1]);
+  exit (0);
+
+}
+
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/csystem.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/csystem.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/csystem.c	(revision 21897)
@@ -0,0 +1,98 @@
+# include <ohana.h>
+
+/* csystem: convert between celestial, galactic, ecliptic, and
+   hoziron systems */
+
+int main (int argc, char **argv) {
+
+  /* USAGE: csystem [C/G/E/H] [C/G/E/H] [epoch] */
+  double x, y, X, Y, Xo, xo, phi, T;
+  double sin_x, sin_y, cos_x, cos_y;
+  
+  if (((argc == 3) && ((argv[1][0] == 'E') || (argv[2][0] == 'E'))) || 
+      ((argc == 4) && ((argv[1][0] != 'E') && (argv[2][0] != 'E'))) ||
+      ((argc != 3) && (argc != 4))) {
+    fprintf (stderr, "USAGE: csystems [C/G/E/H] [C/G/E/H] [epoch]\n");
+    exit (2);
+  }
+
+  switch (argv[1][0]) {
+  case 'C':
+    switch (argv[2][0]) {
+    case 'C': 
+      phi = Xo = xo = 0.0;
+      break;
+    case 'G':
+      phi = -62.6*RAD_DEG;
+      Xo = 282.25;
+      xo = 33;
+      break;
+    case 'E':
+      T = (atof (argv[3]) - 1900) / 100.0;
+      phi = -1*(23.452294 - 0.013013*T - 0.000001639*T*T + 0.000000503*T*T*T);
+      phi *= RAD_DEG;
+      Xo = xo = 0.0;
+      break;
+    }
+    break;
+  case 'E':
+    switch (argv[2][0]) {
+    case 'C': 
+      T = (atof (argv[3]) - 1900) / 100.0;
+      phi = 23.452294 - 0.013013*T - 0.000001639*T*T + 0.000000503*T*T*T;
+      phi *= RAD_DEG;
+      Xo = xo = 0.0;
+      break;
+    case 'G':
+      fprintf (stderr, "error: not working!\n");
+      exit (1);
+      phi = -62.6*RAD_DEG;
+      Xo = 282.25;
+      xo = 33;
+      break;
+    case 'E':
+      phi = Xo = xo = 0.0;
+      break;
+    }
+    break;
+  case 'G':
+    switch (argv[2][0]) {
+    case 'C': 
+      phi = 62.6*RAD_DEG;
+      Xo = 33;
+      xo = 282.25;
+      break;
+    case 'G':
+      phi = Xo = xo = 0.0;
+      break;
+    case 'E':
+      fprintf (stderr, "error: not working!\n");
+      exit (1);
+      phi = -1*(23.452294 - 0.013013*T - 0.000001639*T*T + 0.000000503*T*T*T);
+      Xo = xo = 0.0;
+      break;
+    }
+  }
+ 
+  Xo *= RAD_DEG;
+  for (; fscanf (stdin, "%lf %lf", &X, &Y) == 2;) {
+    
+    X *= RAD_DEG;
+    Y *= RAD_DEG;
+
+    sin_y = cos(Y)*sin(X - Xo)*sin(phi) + sin(Y)*cos(phi);
+    cos_y = sqrt (1 - sin_y*sin_y);
+    sin_x = (cos(Y)*sin(X - Xo)*cos(phi) - sin(Y)*sin(phi)) /  cos_y;
+    cos_x = cos(Y)*cos(X - Xo) / cos_y;
+/*    fprintf (stderr, "%f %f   %f %f   %f %f\n", X, Y, sin_x, cos_x, sin_y, cos_y); */
+    
+    x = (DEG_RAD * atan2 (sin_x, cos_x) + xo + 360);
+    
+    while (x >= 360.0)
+      x -= 360;
+    y = DEG_RAD * atan2 (sin_y, cos_y);
+    
+    fprintf (stdout, "%10.6f %10.6f\n", x, y);
+  }
+  exit (0);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/cubefilter.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/cubefilter.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/cubefilter.c	(revision 21897)
@@ -0,0 +1,146 @@
+# include <ohana.h>
+# define D_NFILES 100
+
+main (int argc, char **argv) {
+
+  int i, j, k, n, Npixels, Npixin, Npixrd, Npixlast, N;
+  int Npass, NFILES, Nfiles;
+
+  char **filename;
+  Header head, *tmphead;
+  Matrix out,  *tmpmatr;
+  float *list, *v, *O;
+  float fmin, fmax, Nval, sum;
+
+  FT_UNSIGN_MODE = FALSE;
+  if (N = get_argument (argc, argv, "-unsign")) {
+    remove_argument (N, &argc, argv);
+    FT_UNSIGN_MODE = TRUE;
+  }
+
+  if (argc != 5) {
+    fprintf (stderr, "USAGE: minmaxfilter infile outfile fmin fmax\n");
+    exit (0);
+  }
+  fmin = atof (argv[2]); 
+  fmax = atof (argv[3]); 
+
+  /* read in the filenames */
+  NFILES = D_NFILES;
+  ALLOCATE (filename, char *, NFILES);
+  ALLOCATE (filename[0], char, 1024);
+  for (i = 0; fscanf (stdin, "%s", filename[i]) != EOF; i++) {
+    if (i == NFILES - 1) {
+      NFILES += D_NFILES;
+      REALLOCATE (filename, char *, NFILES);
+    }
+    ALLOCATE (filename[i+1], char, 1024);
+  }
+  Nfiles = i;
+  REALLOCATE (filename, char *, Nfiles);
+
+  /* load a header, setup output header, matrix */
+  gfits_read_header (filename[0], &head);
+  gfits_create_matrix (&head, &out);
+  gfits_convert_format (&head, &out, -32, 1.0, 0.0, FALSE);
+
+  /* find size of temporary images */
+  Npixels = head.Naxis[0]*head.Naxis[1];
+  Npixin = Npixels / Nfiles;
+  Npixlast = Npixels - Npixin*Nfiles;
+  if (Npixlast == 0) {
+    Npass = Nfiles;
+    Npixlast = Npixin;
+    fprintf (stderr, "operating on %d pixels per pass\n", Npixin);
+  } else {
+    Npass = Nfiles + 1;
+    fprintf (stderr, "operating on %d pixels per pass, %d in last\n", Npixin, Npixlast);
+  }
+  
+  ALLOCATE (tmphead, Header, Nfiles);
+  ALLOCATE (tmpmatr, Matrix, Nfiles);
+  ALLOCATE (list, float, Nfiles);
+  Nval = 0;
+  for (k = fmin*Nfiles; k < fmax*Nfiles; k++) {
+    Nval += 1.0;
+  }
+
+  O = (float *) out.buffer;
+  for (n = 0; n < Npass; n++) {
+    fprintf (stderr, "pass %d\n", n);
+    Npixrd = (n == Npass - 1) ? Npixlast : Npixin;
+    for (i = 0; i < Nfiles; i++) {
+      fprintf (stderr, ".");
+      if (!gfits_read_header  (filename[i], &tmphead[i])) {
+	fprintf (stderr, "trouble reading file %s\n", filename[i]);
+	exit (1);
+      }
+      gfits_read_portion (filename[i], &tmpmatr[i], n*Npixin, Npixrd);
+      tmphead[i].Naxis[0] = 1;
+      tmphead[i].Naxis[1] = Npixrd;
+      gfits_convert_format (&tmphead[i], &tmpmatr[i], -32, 1.0, 0.0, FALSE);
+    }
+    
+    fprintf (stderr, "starting sorts\n");
+    for (j = 0; j < Npixrd; j++, O++) {
+      for (k = 0; k < Nfiles; k++) {
+	v = (float *)tmpmatr[k].buffer;
+	list[k] = v[j];
+      }
+      fsort (list, Nfiles);
+      sum = 0;
+      for (k = fmin*Nfiles; k < fmax*Nfiles; k++) {
+	sum += list[k];
+      }
+      *O = (sum / Nval);
+    }
+
+    for (i = 0; i < Nfiles; i++) {
+      fprintf (stderr, ",");
+      gfits_free_header (&tmphead[i]);
+      gfits_free_matrix (&tmpmatr[i]);
+    }
+    
+  }
+
+  gfits_write_header (argv[1], &head);
+  gfits_write_matrix (argv[1], &out);
+
+  return (0);
+
+}
+
+fsort (value, N) 
+float value[];
+int N;
+{
+  int l,j,ir,i;
+  float temp;
+  
+  l = N >> 1;
+  ir = N - 1;
+  for (;;) {
+    if (l > 0) {
+      temp = value[--l];
+    }
+    else {
+      temp = value[ir];
+      value[ir] = value[0];
+      if (--ir == 0) {
+	value[0] = temp;
+	return;
+      }
+    }
+    i = l;
+    j = (l << 1) + 1;
+    while (j <= ir) {
+      if (j < ir && value[j] < value[j+1]) ++j;
+      if (temp < value[j]) {
+	value[i]=value[j];
+	j += (i=j) + 1;
+      }
+      else j = ir + 1;
+    }
+    value[i] = temp;
+  }
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/dastro.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/dastro.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/dastro.c	(revision 21897)
@@ -0,0 +1,112 @@
+# include <ohana.h>
+
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  
+  int status, REL, N;
+  Header header, refhead;
+  char  filename[1024], reffile[1024], *p;
+  double X_O, X_X, X_Y, Y_O, Y_X, Y_Y;
+  double RA_O, RA_X, RA_Y, DEC_O, DEC_X, DEC_Y;
+  double ra_o, ra_x, ra_y, dec_o, dec_x, dec_y;
+  double dRA, dDEC, dX, dY, dra, ddec;
+  
+  if (N = get_argument (argc, argv, "-rel")) {
+    remove_argument (N, &argc, argv);
+    REL = TRUE;
+  }
+  else {
+    REL = FALSE;
+  }
+  
+  while (fscanf (stdin, "%s", filename) != EOF) {
+    
+    status = gfits_read_header (filename, &header);
+    if (!status) {
+      fprintf (stderr, "error opening file %s\n", filename);
+      continue;
+    }
+    status = gfits_scan (&header, "rREF", "%s", 1, reffile);
+    status &= gfits_scan (&header, "X_O", "%lf", 1, &X_O);
+    status &= gfits_scan (&header, "X_X", "%lf", 1, &X_X);
+    status &= gfits_scan (&header, "X_Y", "%lf", 1, &X_Y);
+    status &= gfits_scan (&header, "Y_O", "%lf", 1, &Y_O);
+    status &= gfits_scan (&header, "Y_X", "%lf", 1, &Y_X);
+    status &= gfits_scan (&header, "Y_Y", "%lf", 1, &Y_Y);
+    status &= gfits_scan (&header, "dX", "%lf", 1, &dX);
+    status &= gfits_scan (&header, "dY", "%lf", 1, &dY);
+    if (!status) {
+      fprintf (stderr, "file missing rastro info: %s\n", filename);
+      gfits_free_header (&header);
+      continue;
+    }
+
+    while ((p = strstr (reffile, "'")) != NULL) {
+      *p = ' ';
+    }
+    stripwhite (reffile);
+    if ((p = strrchr(reffile, '.')) != NULL)
+      strcpy(p, ".head");
+    else 
+      strcat(reffile, ".head");
+
+    if (!strcmp (reffile, filename)) {
+      fprintf (stderr, "%s is %s, not altering\n", reffile, filename);
+      continue;
+    }
+
+    status  = gfits_read_header (reffile, &refhead);
+    if (!status) {
+      fprintf (stderr, "error opening file %s\n", reffile);
+      continue;
+    }
+    status &= gfits_scan (&refhead, "RA_O", "%lf", 1, &RA_O);
+    status &= gfits_scan (&refhead, "RA_X", "%lf", 1, &RA_X);
+    status &= gfits_scan (&refhead, "RA_Y", "%lf", 1, &RA_Y);
+    status &= gfits_scan (&refhead, "DEC_O", "%lf", 1, &DEC_O);
+    status &= gfits_scan (&refhead, "DEC_X", "%lf", 1, &DEC_X);
+    status &= gfits_scan (&refhead, "DEC_Y", "%lf", 1, &DEC_Y);
+    status &= gfits_scan (&refhead, "dRA",   "%lf", 1, &dRA);
+    status &= gfits_scan (&refhead, "dDEC",  "%lf", 1, &dDEC);
+    if (!status) {
+      fprintf (stderr, "file missing rastro info: %s\n", reffile);
+      gfits_free_header (&header);
+      gfits_free_header (&refhead);
+      continue;
+    }
+
+    fprintf (stderr, "%f %f %f\n%f %f %f\n", RA_O, RA_X, RA_Y, DEC_O, DEC_X, DEC_Y);
+    fprintf (stderr, "\n%f %f %f\n%f %f %f\n", X_O, X_X, X_Y, Y_O, Y_X, Y_Y);
+    
+    ra_o = RA_X*X_O + RA_Y*Y_O + RA_O;
+    dec_o = DEC_X*X_O + DEC_Y*Y_O + DEC_O;
+    
+    ra_x = RA_X*X_X + RA_Y*Y_X;
+    ra_y = RA_X*X_Y + RA_Y*Y_Y;
+    dec_x = DEC_X*X_X + DEC_Y*Y_X;
+    dec_y = DEC_X*X_Y + DEC_Y*Y_Y;
+    
+    fprintf (stderr, "%f %f %f\n%f %f %f\n", ra_o, ra_x, ra_y, dec_o, dec_x, dec_y);
+
+    dra = sqrt(dRA*dRA + SQ(3600*dX*RA_X) + SQ(3600*dY*RA_Y));
+    ddec = sqrt(dDEC*dDEC + SQ(3600*dX*DEC_X) + SQ(3600*dY*DEC_Y));
+			   
+    status &= gfits_modify (&header, "RA_O", "%lf", 1, ra_o);
+    status &= gfits_modify (&header, "RA_X", "%le", 1, ra_x);
+    status &= gfits_modify (&header, "RA_Y", "%le", 1, ra_y);
+    status &= gfits_modify (&header, "DEC_O", "%lf", 1, dec_o);
+    status &= gfits_modify (&header, "DEC_X", "%le", 1, dec_x);
+    status &= gfits_modify (&header, "DEC_Y", "%le", 1, dec_y);
+    status &= gfits_modify (&header, "dRA",   "%lf", 1, dra);
+    status &= gfits_modify (&header, "dDEC",  "%lf", 1, ddec);
+    
+    gfits_write_header (filename, &header);
+    gfits_free_header (&header);
+    gfits_free_header (&refhead);
+    
+  }
+
+}
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/dbtest.c.failed
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/dbtest.c.failed	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/dbtest.c.failed	(revision 21897)
@@ -0,0 +1,106 @@
+# include <ohana.h>
+
+static char dbfile[] = "/h/eugene/d4/flattest/test.db";
+
+void main (int argc, char **argv) {
+
+  char buffer[10000];
+  int vbuffer[10000];
+  FILE *f;
+  int i, j, Nrun, status, fd;
+
+  if (argc > 1) {
+    if (!strcmp (argv[1], "-check")) {
+      f = fopen (dbfile, "r");
+      if (f == (FILE *) NULL) {
+	fprintf (stderr, "ERROR: can't open file\n");
+	exit (0);
+      }
+      status = fread (buffer, 1, 5000, f);
+      if (status != 5000) {
+	fprintf (stderr, "ERROR: can't read header\n");
+	exit (0);
+      }
+      sscanf (&buffer[500], "%*s %*s %*s %d", &Nrun);
+      for (j = 0 ; j < Nrun; j++) {
+	status = fread (vbuffer, 4, 1000, f);
+	if (status != 1000) {
+	  fprintf (stderr, "ERROR: can't read data\n");
+	  exit (0);
+	}
+	for (i = 0; i < 1000; i++) {
+	  if (vbuffer[i] != j) {
+	    fprintf (stderr, "ERROR: invalid data %d/%d,  %d - %d\n", j, Nrun, i, vbuffer[i]);
+	    exit (0);
+	  }
+	}
+      }
+      fprintf (stderr, "Data is good\n");
+      exit (0);
+    }
+  }	  
+
+  /* read the header block, change one line, write the header block */
+  /* write a block to EOF */
+
+  /* if lockfile exists, program will complain and quit */
+  if ((fd = setlockfile (dbfile, 60.0)) == -1) {
+    fprintf (stderr, "ERROR: can't set lock on %s\n", dbfile);
+    exit (1);
+  }
+
+  f = fopen (dbfile, "r");
+  if (f == (FILE *) NULL) {
+    /* make a header block */
+    for (i = 0; i < 50; i++) {
+      memset (&buffer[100*i], 65+i, 99);
+      buffer[100*i + 99] = '\n';
+    }
+    sprintf (&buffer[500], "THIS IS TEST    0   \n");
+    Nrun = 0;
+  } else {
+    status = fread (buffer, 1, 5000, f);
+    if (status != 5000) {
+      fprintf (stderr, "ERROR: can't read data\n");
+      exit (0);
+    }
+    
+    sscanf (&buffer[500], "%*s %*s %*s %d", &Nrun);
+    Nrun ++;
+    sprintf (&buffer[500], "THIS IS TEST    %d   \n", Nrun);
+  }
+
+  f = fopen (dbfile, "r+");
+  if (f == NULL) {
+    f = fopen (dbfile, "w");
+    if (f == NULL) {
+      fprintf (stderr, "ERROR: can't create/open file %s\n", dbfile);
+      exit (0);
+    }
+  }
+
+  /* position to begining of file to write header */
+  fseek (f, 0, SEEK_SET);
+  status = fwrite (buffer, 1, 5000, f);
+  if (status != 5000) {
+    fprintf (stderr, "ERROR: failed writing data to header\n");
+    exit (0);
+  }
+
+  for (i = 0; i < 1000; i++) vbuffer[i] = Nrun;
+
+  fseek (f, 0, SEEK_END);
+  status = fwrite (vbuffer, 4, 1000, f);
+  if (status != 1000) {
+    fprintf (stderr, "ERROR: failed writing data to file\n");
+    exit (0);
+  }
+
+  if (!gnfsflush (dbfile)) {
+    fprintf (stderr, "ERROR: failed to flush image catalog\n");
+    exit (0);
+  }
+
+  clearlockfile (dbfile, fd);
+
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/doscript.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/doscript.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/doscript.c	(revision 21897)
@@ -0,0 +1,179 @@
+# include <ohana.h>
+
+void args(), error();
+int COLDSTART, OUTIMAGE;
+double THRESHOLD;
+
+main (argc, argv) 
+     int argc;
+     char **argv;
+{
+  
+  FILE *f, *ft;
+  char name[128], root[128], line[256];
+  double psfx, psfy, sky, tilt;
+
+  args (argc, argv);
+
+  while (fscanf (stdin, "%s", root) != EOF) {
+    if (COLDSTART) {
+      fscanf (stdin, "%lf %lf", &psfx, &sky);
+    }
+    else {
+      fscanf (stdin, "%lf %lf %lf %lf", &psfx, &psfy, &tilt, &sky);
+    }
+
+    /* we demand that the image names have the *.f extension */
+    if (strncmp (&root[strlen(root) - 2], ".f", 2)) {
+      fprintf (stderr, "valid image names are *.f\n");
+      exit (0);
+    }
+
+    ft = fopen (root, "r");
+    if (ft == NULL) {
+      fprintf (stderr, "image %s does not exist\n", root);
+      continue;
+    }
+    fclose(ft);
+
+    /* root contains *.f, remove the .f portion: */
+    root[strlen(root) - 2] = 0;
+
+    strcpy (name, root);
+    strcat (name, ".par_in");
+    f = fopen (name, "w");
+    if (f == (FILE *) NULL) {
+      fprintf (stderr, "couldn't write to parameter file %s\n", name);
+      continue;
+    }
+    fprintf (f, "FWHM = %f\n", psfx);
+    fprintf (f, "SKY = %f\n", sky);
+    if (!COLDSTART) {
+      fprintf (f, "AXIS_RATIO = %f\n", psfy/psfx);
+      fprintf (f, "TILT = %f\n", tilt);
+    }
+    fprintf (f, "=\n");
+    fprintf (f, "PARAMS_DEFAULT = 'dophot.params'\n");
+    fprintf (f, "PARAMS_OUT = '%s.par_out'\n", root);
+    if (THRESHOLD) {
+      fprintf (f, "AUTOTHRESH = 'NO'\n");     
+      fprintf (f, "THRESHMIN = %f\n", THRESHOLD);
+    }
+    else {
+      fprintf (f, "AUTOTHRESH = 'YES'\n");     
+    }
+    fprintf (f, "=\n");
+    fprintf (f, "IMAGE_IN = '%s.f'\n", root);
+    if (OUTIMAGE) 
+      fprintf (f, "IMAGE_OUT = '%s.s'\n", root);
+    else
+      fprintf (f, "IMAGE_OUT = ' '\n");
+    if (!COLDSTART) {
+      strcpy (name, root);
+      strcat (name, ".obj_out");
+      ft = fopen (name, "r");
+      if (ft != (FILE *) NULL) {
+	fclose (ft);
+	sprintf (line, "mv %s.obj_out %s.obj_in\0", root, root);
+	system (line);
+	fprintf (f, "OBJECTS_IN = '%s.obj_in'\n", root);
+      }
+      else {
+	fprintf (f, "OBJECTS_IN = ' '\n");
+      }
+    }
+    else {
+      fprintf (f, "OBJECTS_IN = ' '\n");
+    }
+    fprintf (f, "OBJECTS_OUT = '%s.obj_out'\n", root);
+    fprintf (f, "=\n");
+
+    if (!COLDSTART) {
+      strcpy (name, root);
+      strcat (name, ".shd_out");
+      ft = fopen (name, "r");
+      if (ft != (FILE *) NULL) {
+	fclose (ft);
+	sprintf (line, "mv %s.shd_out %s.shd_in\0", root, root);
+	system (line);
+	fprintf (f, "SHADOWFILE_IN = '%s.shd_in'\n", root);
+      }
+      else {
+	fprintf (f, "SHADOWFILE_IN = ' '\n");
+      }
+    }
+    else {
+      fprintf (f, "SHADOWFILE_IN = ' '\n");
+    }
+    fprintf (f, "SHADOWFILE_OUT = '%s.shd_out'\n", root);
+    
+    fprintf (f, "END\n");
+    fclose (f);
+
+    fprintf (stdout, "dophot << END > %s.dout\n", root);
+    fprintf (stdout, "%s.par_in\n", root);
+    fprintf (stdout, "END\n");
+  }
+}
+
+/* 
+  original image: image
+  flattened im:   image.f
+  star sub image: image.s
+  dp params in:   image.par_in
+  dp params out:  image.par_out
+  dp objects in:  image.obj_in
+  dp objects out: image.obj_out
+  dp shadow in:   image.shd_in
+  dp shadow out:  image.shd_out
+*/
+
+void args (argc, argv)
+     int      argc;
+     char   **argv;
+{
+  
+  int N;
+  
+  if (get_argument (argc, argv, "-h") || get_argument (argc, argv, "-help")) {
+    error ();
+  }
+
+  COLDSTART = TRUE;
+  if (N = get_argument (argc, argv, "-w")) {
+    remove_argument (N, &argc, argv);
+    COLDSTART = FALSE;
+  }
+  if (N = get_argument (argc, argv, "-warm")) {
+    remove_argument (N, &argc, argv);
+    COLDSTART = FALSE;
+  }
+  
+  OUTIMAGE = FALSE;
+  if (N = get_argument (argc, argv, "-sub")) {
+    remove_argument (N, &argc, argv);
+    OUTIMAGE = TRUE;
+  }
+
+  THRESHOLD = 0;
+  if (N = get_argument (argc, argv, "-t")) {
+    remove_argument (N, &argc, argv);
+    if (N < argc) {
+      THRESHOLD = atof (argv[N]);
+    } 
+    else {
+      error ();
+    }   
+  }
+}
+
+void error ()
+{
+  fprintf (stderr, "USAGE:\n");
+  fprintf (stderr, "  doscript [-w/-warm] [-sub] [-t threshold]\n");
+  fprintf (stderr, "    default is coldstart -- takes from stdin: filename FWHM sky\n");
+  fprintf (stderr, "    -w, -warm: warmstart -- takes from stdin: filename FWHMx FWHMy angle sky'\n");
+  fprintf (stderr, "    -t: set minimum threshold, also sets AUTOTHRESH = 'NO'\n");
+  fprintf (stderr, "    -sub: generate star-substracted images\n");
+  exit (0);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/dostat.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/dostat.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/dostat.c	(revision 21897)
@@ -0,0 +1,84 @@
+# include <ohana.h>
+
+main() {
+
+  FILE *f, *fopen();
+  char file[50];
+  int N,n1,n2,n3,n4,n5,n6,n7,n8,nperf,type,status;
+  double Fx,Fy,alpha, FWHMx,FWHMy,angle, ap, F, S, sky;
+  double dtype, A, A2, Ap, Ap2, apmifit, df, S2;
+  char line[512];
+
+  while (fscanf (stdin, "%s", file) != EOF) {
+    f = fopen (file, "r");
+    if (f == NULL) {
+      fprintf (stderr, "file %s not found\n", file);
+      continue;
+    }
+    n1 = n2 = n3 = n4 = n5 = n6 = n7 = n8 = nperf = 0;
+    S2 = S = Fx = Fy = alpha = A = A2 = 0;
+    while (scan_line (f, line) != EOF) {
+      status = TRUE;
+      status &= dparse (&dtype, 2, line);
+      status &= dparse (&df,   6, line);
+      status &= dparse (&sky,   7, line);
+      status &= dparse (&FWHMx, 8, line);
+      status &= dparse (&FWHMy, 9, line);
+      status &= dparse (&angle, 10, line);
+      status &= dparse (&ap,      12, line);
+      status &= dparse (&apmifit, 15, line);
+      if (!status) {
+	fprintf (stderr, "error in file %s, line %d\n", file, n1+n2+n3+n4+n5+n6+n7+n8);
+	continue;
+      }
+      type = dtype;
+      switch (type) {
+      case 1:
+	n1 ++;
+	S += sky;
+	if (ap < 99) {
+	  nperf ++;
+	  A += apmifit/(df*df);
+	  A2 += apmifit*apmifit/(df*df);
+	  S2 += 1.0/(df*df);
+	}
+	Fx = FWHMx;
+	Fy = FWHMy;
+	alpha = angle;
+	break;
+      case 2:
+	n2 ++;
+	break;
+      case 3:
+	n3 ++;
+	break;
+      case 4:
+	n4 ++;
+	break;
+      case 5:
+	n5 ++;
+	break;
+      case 6:
+	n6 ++;
+	break;
+      case 7:
+	n7 ++;
+	break;
+      case 8:
+	n8 ++;
+	break;
+      }
+    }
+    S= S / (1.0*n1);
+    F = nperf / (1.0 * n1);
+    N = n1+n2+n3+n4+n5+n6+n7+n8;
+    Ap = A / S2;
+    Ap2 = sqrt(A2 / (S2) - Ap*Ap);
+    fprintf (stdout, "%s: %5d %5d %5d %5d %5d %5d %5d %5d",
+	     file,n1,n2,n3,n4,n5,n6,n7,n8);
+    fprintf (stdout, "  %5d %5d  %5.3f %7.2f %7.2f %7.1f %7.1f %7.3f %7.3f\n",
+	     N, nperf, F, Fx, Fy, alpha, S, Ap, Ap2);
+    fclose(f);
+  }
+}
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakecmp.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakecmp.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakecmp.c	(revision 21897)
@@ -0,0 +1,137 @@
+# include <ohana.h>
+static char reserved[] = "COMMENT  Reserved space.  This line can be used to add a new FITS card.";
+
+void main (int argc, char **argv) {
+
+  int i, j, N, status;
+  int Nreserved, start_size;
+  char *p, keyword[16], line[256];
+  FILE *f;
+  Header header;
+
+  if (argc != 4) {
+    fprintf (stderr, "USAGE: gfits_insert (input) (template) (output)\n");
+    exit (2);
+  }
+  
+  /*
+    input file consists of: RA DEC MAG dMAG
+    we generate an artificial image with 1 arcsec/pix
+    and the pixel (0,0) at (<RA>,<DEC>)
+    
+    1) find <RA>, <DEC>
+    2) convert X,Y to R,D using <RA>,<DEC> (ra---sin)
+    3) fix template entries: CRVAL1, CRVAL2, NSTARS, (JD)
+    4) write out template
+    5) write out infile in correct format:
+    X     Y      M      dM   T S   Ma     Mb        Fx     Fy  Th
+    237.2 2646.1 16.748 085  1 2.0 17.930 17.768    nan    nan -48.0
+  */
+
+  /* allocate data space */
+  NSTARS = 1000;
+  ALLOCATE (ra, double, NSTARS);
+  ALLOCATE (dec, double, NSTARS);
+  ALLOCATE (mag, double, NSTARS);
+  ALLOCATE (dmag, double, NSTARS);
+
+  /* open data file */
+  f = fopen (argv[1], "r");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "can't open data file %s\n", argv[1]);
+    exit (1);
+  }
+
+  /* load data file into array */
+  for (i = 0;
+       fscanf (f, "%lf %lf %lf %lf", &ra[i], &dec[i], &mag[i], &dmag[i]) != EOF;
+       i++) {
+    
+    if (i == NSTARS - 1) {
+      NSTARS += 1000;
+      REALLOCATE (ra, double, NSTARS);
+      REALLOCATE (dec, double, NSTARS);
+      REALLOCATE (mag, double, NSTARS);
+      REALLOCATE (dmag, double, NSTARS);
+    }
+  }
+  NSTARS = i;
+
+  /* calculate <ra>, <dec> */
+  RA = DEC = 0;
+  for (i = 0; i < NSTARS; i++) {
+    RA += ra[i];
+    
+
+  /* load header from image file */
+  if (!gfits_read_header (argv[1], &header)) {
+    fprintf (stderr, "can't open fits file %s\n", argv[1]);
+    exit (1);
+  }
+  start_size = header.size;
+
+  /* run through the lines in the header data file */
+  while (scan_line (f, line) != EOF) {
+    
+    /* fill in end of line with blanks, force end at 80 */
+    for (N = strlen (line); N < 80; N++) {
+      line[N] = ' ';
+    }
+    line[80] = 0;
+    bzero (keyword, 10);
+    strncpy (keyword, line, 8);
+    
+    /* replace existing keywords, unless this is a COMMENT or HISTORY field */
+    if (strncmp (keyword, "COMMENT ", 8) && strncmp (keyword, "HISTORY ", 8)) {
+      p = gfits_header_field (&header, keyword, 1);
+      if (p != (char *) NULL) {
+	strncpy (p, line, 80);
+	continue;
+      }
+    }
+
+    /* find first line with the reserved line */
+    p = (char *) NULL;
+    Nreserved = strlen (reserved);
+    for (i = 0; (i < header.size) && (p == (char *) NULL) ; i+= FT_LINE_LENGTH) {
+      if (!strncmp (&header.buffer[i], reserved, Nreserved)) {
+	p = &header.buffer[i];
+      }
+    }
+    if (p == (char *) NULL) {
+      fprintf (stderr, "no more reserved spaces!\n");
+      exit (1);
+    }
+
+    /* insert the new line here */
+    strncpy (p, line, 80);
+  }
+
+  fclose (f);
+
+  /* now write the new header on top of the old one. 
+     check first that the header size has not changed.
+  */
+
+  if (header.size != start_size) {
+    fprintf (stderr, "header changed size: should not happen!\n");
+    exit (1);
+  }
+
+  f = fopen (argv[1], "r+");
+  if (f == NULL) {
+    fprintf (stderr, "can't open file for update %s\n", argv[1]);
+    exit (1);
+  }
+
+  fseek (f, 0, SEEK_SET);
+  status = fwrite (header.buffer, 1, header.size, f);
+  if (status != header.size) {
+    fprintf (stderr, "failed to write data to image header\n");
+    exit (1);
+  }
+  fclose (f);
+
+  exit (0);
+}
+    
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakedist.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakedist.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakedist.c	(revision 21897)
@@ -0,0 +1,547 @@
+# include <ohana.h>
+
+# define NGAUSS 2048
+double drand48();
+double gaussint[NGAUSS];
+double gaussian();
+double rnd_gauss();
+
+# define MMIN 1.0
+# define MMAX 120.0
+double rnd_mass();
+double MassTerm;
+
+# define NMASS 87
+# define DMASS 0.05
+# define NPARMAX 30
+int N_Av, N_dist, N_alpha, N_age, NSTARS, NTRY;
+double Av[NPARMAX], dist[NPARMAX], alpha[NPARMAX], age[NPARMAX];
+
+double dVo, dVref, dMo;   /* determine the noise distribution */
+
+double ldA, lAo, ldM, lMo;
+double UV0, V0, DV, DUV;
+Header header, UV_h, V_h, mass_h, age_h;
+Matrix matrix, UV_i, V_i, mass_i, age_i;
+int UV_NX, UV_NY;
+float *UVbuffer, *Vbuffer;
+int MS_NX, MS_NY;
+float *Mbuffer, *Abuffer;
+
+char fakefile[256], magfile[256], colorfile[256], massfile[256], agefile[256];
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+
+  int i, j, m, n, M, A, Nstars;
+  double mag, color, mass, noise, inflation;
+  float *in;
+  char line[1024];
+
+  load_parameters (argc, argv);
+
+  init_outmatrix (); 
+ 
+  gauss_init ();
+
+  read_datafiles ();
+
+  gfits_modify (&header, "SFR", "%s", 1, "Star Formation Rate (Mo / Myr)");
+  for (i = 0; i < N_Av; i++) {
+    for (j = 0; j < N_dist; j++) {
+      for (m = 0; m < N_alpha; m++) {
+	
+	MassTerm = (pow((MMAX/MMIN), -alpha[m]) - 1.0);
+	for (n = 0; n < N_age; n++) {
+	  fprintf (stderr, "age: %d %f -- %f\n", n, age[n], age[n+1]);
+	  
+	  mass = 0;
+	  for (Nstars = 0; Nstars < NSTARS; Nstars++) {
+	    fakestar (Av[i], dist[j], alpha[m], age[n], age[n+1], 
+		      &mag, &color, &mass, &noise);
+	    
+	    magtomass (Av[i], dist[j], mag, color, noise, &M, &A, &inflation);
+
+	    if (inflation > 0.0) add_to_outmatrix (i, j, m, n, A, M, inflation);
+	    
+	  }
+	  /* store the parameters and total mass for this Mass*Age matrix in the (N_age) column */
+	  /* mass is the total mass generated between 1 and 120 Mo for the NSTARS points in this matrix */
+	  sprintf (line, "SFR_%0d\0", n);
+	  gfits_modify (&header, line, "%lf", 1, mass / (age[n+1] - age[n]));
+	  add_to_outmatrix (i, j, m, n, N_age, 0, mass);
+	  add_to_outmatrix (i, j, m, n, N_age, 1, Av[i]);
+	  add_to_outmatrix (i, j, m, n, N_age, 2, dist[j]);
+	  add_to_outmatrix (i, j, m, n, N_age, 3, alpha[m]);
+	  add_to_outmatrix (i, j, m, n, N_age, 4, age[n]);
+	  add_to_outmatrix (i, j, m, n, N_age, 5, age[n+1]);
+	  
+	}
+      }
+    }
+  }
+
+  /* 
+  in = (float *)matrix.buffer;
+  for (i = 0; i < matrix.Naxis[0]; i++) {
+    for (j = 0; j < matrix.Naxis[1]; j++) {
+      mass = in[i + matrix.Naxis[0]*(j + matrix.Naxis[1]*2)];
+      fprintf (stderr, "%f ", mass);
+    }
+    fprintf (stderr, "\n");
+  }
+  */
+
+  gfits_write_header (fakefile, &header);
+  gfits_write_matrix (fakefile, &matrix);
+}
+
+/*****************************************************************************/
+
+load_parameters (argc, argv)
+int argc;
+char **argv;
+{
+
+  int i, stat, test_dVo, test_dVref, test_dMo;
+  int Ffile, Mfile, Cfile, Afile, MSfile;
+  FILE *f;
+  char line[1024];
+  double N_stars, N_try, Ntotal, time;
+
+  if (argc < 2) {
+    fprintf (stderr, "USAGE: %s pfile\n", argv[0]);
+    exit (0);
+  }
+
+  f = fopen (argv[1], "r");
+  if (f == NULL) {
+    fprintf (stderr, "parameter file %s not found\n", argv[1]);
+    exit (0);
+  }
+
+  N_Av = N_dist = N_alpha = N_age = N_stars = N_try = 0.0;
+  test_dVo = test_dVref = test_dMo = FALSE;
+  Ffile = Mfile = Cfile = Afile = MSfile = FALSE;
+  while (scan_line (f, line) != EOF) {
+    if (!stripwhite (line)) continue;
+    if (line[0] == '#') continue;
+    
+    if (!strncmp (line, "Av ", strlen ("Av "))) {
+      for (i = 0; (i < NPARMAX) && (stat = dparse (&Av[i], i+2, line)); i++);
+      if (i == NPARMAX) {
+	fprintf (stderr, "maximum of %d parameter values per parameter\n", NPARMAX);
+	exit (0);
+      }
+      N_Av = i;
+    }
+
+    if (!strncmp (line, "dist ", strlen ("dist "))) {
+      for (i = 0; (i < NPARMAX) && dparse (&dist[i], i+2, line); i++);
+      if (i == NPARMAX) {
+	fprintf (stderr, "maximum of %d parameter values per parameter\n", NPARMAX);
+	exit (0);
+      }
+      N_dist = i;
+    }
+
+    if (!strncmp (line, "alpha ", strlen ("alpha "))) {
+      for (i = 0; (i < NPARMAX) && dparse (&alpha[i], i+2, line); i++);
+      if (i == NPARMAX) {
+	fprintf (stderr, "maximum of %d parameter values per parameter\n", NPARMAX);
+	exit (0);
+      }
+      N_alpha = i;
+    }
+
+    if (!strncmp (line, "age ", strlen ("age "))) {
+      for (i = 0; (i < NPARMAX) && dparse (&age[i], i+2, line); i++);
+      if (i == NPARMAX) {
+	fprintf (stderr, "maximum of %d parameter values per parameter\n", NPARMAX);
+	exit (0);
+      }
+      N_age = MAX (0, i - 1);
+    }
+
+    if (!strncmp (line, "dVo ", strlen ("dVo "))) {
+      dparse (&dVo, 2, line);
+      test_dVo = TRUE;
+    }
+    
+    if (!strncmp (line, "dVref ", strlen ("dVref "))) {
+      dparse (&dVref, 2, line);
+      test_dVref = TRUE;
+    }
+    
+    if (!strncmp (line, "dMo ", strlen ("dMo "))) {
+      dparse (&dMo, 2, line);
+      test_dMo = TRUE;
+    }
+    
+    if (!strncmp (line, "nstars ", strlen ("nstars "))) {
+      dparse (&N_stars, 2, line);
+      NSTARS = N_stars;
+    }
+    
+    if (!strncmp (line, "ntry ", strlen ("ntry "))) {
+      dparse (&N_try, 2, line);
+      NTRY = N_try;
+    }
+    
+    if (!strncmp (line, "magfile ", strlen ("magfile "))) {
+      sscanf (line, "%*s %s", magfile);
+      fprintf (stderr, "magfile: %s\n", magfile);
+      Mfile = TRUE;
+    }
+    
+    if (!strncmp (line, "colorfile ", strlen ("colorfile "))) {
+      sscanf (line, "%*s %s", colorfile);
+      fprintf (stderr, "colorfile: %s\n", colorfile);
+      Cfile = TRUE;
+    }
+    
+    if (!strncmp (line, "agefile ", strlen ("agefile "))) {
+      sscanf (line, "%*s %s", agefile);
+      fprintf (stderr, "agefile: %s\n", agefile);
+      Afile = TRUE;
+    }
+    
+    if (!strncmp (line, "massfile ", strlen ("massfile "))) {
+      sscanf (line, "%*s %s", massfile);
+      fprintf (stderr, "massfile: %s\n", massfile);
+      MSfile = TRUE;
+    }
+    
+    if (!strncmp (line, "fakefile ", strlen ("fakefile "))) {
+      sscanf (line, "%*s %s", fakefile);
+      fprintf (stderr, "fakefile: %s\n", fakefile);
+      Ffile = TRUE;
+    }
+    
+    if (N_Av && N_dist && N_alpha && N_age && N_stars && N_try && 
+	test_dVo && test_dVref && test_dMo &&
+	Ffile && Mfile && Cfile && Afile && MSfile) {
+      Ntotal = N_Av * N_dist * N_alpha * N_age * N_stars * N_try;
+      time = (Ntotal / 1250000.0);
+      fprintf (stderr, "%.0f iterations\n", Ntotal);
+      fprintf (stderr, "process should take about %.1f minutes\n", time);
+      return;
+    }
+  }
+  
+  if (!(N_Av && N_dist && N_alpha && N_age && NSTARS && NTRY && 
+	test_dVo && test_dVref && test_dMo && 
+	Ffile && Mfile && Cfile && Afile && MSfile)) {
+    fprintf (stderr, "failed to get all parameter lines\n");
+    fprintf (stderr, "N_Av: %d\n", N_Av);
+    fprintf (stderr, "N_dist: %d\n", N_dist);
+    fprintf (stderr, "N_alpha: %d\n", N_alpha);
+    fprintf (stderr, "N_age: %d\n", N_age);
+    fprintf (stderr, "N_stars: %d\n", NSTARS);
+    fprintf (stderr, "N_try: %d\n", NTRY);
+    fprintf (stderr, "dVo: %f (%d)\n", dVo, test_dVo);
+    fprintf (stderr, "dVref: %f (%d)\n", dVref, test_dVref);
+    fprintf (stderr, "dMo: %f (%d)\n", dMo, test_dMo);
+    fprintf (stderr, "Ffile: %d\n", Ffile);
+    fprintf (stderr, "Mfile: %d\n", Mfile);
+    fprintf (stderr, "Cfile: %d\n", Cfile);
+    fprintf (stderr, "Afile: %d\n", Afile);
+    fprintf (stderr, "MSfile: %d\n", MSfile);
+    exit (0);
+  }
+  
+}
+
+/*****************************************************************************/
+
+
+init_outmatrix () 
+{
+
+  int i;
+  char line[32];
+  double value;
+
+  header.bitpix = -32;
+  header.Naxes = 7;
+  header.Naxis[0] = NMASS;
+  header.Naxis[1] = N_age + 1;
+  header.Naxis[2] = N_age;
+  header.Naxis[3] = N_alpha;
+  header.Naxis[4] = N_dist;
+  header.Naxis[5] = N_Av;
+  header.Naxis[6] = 2;
+  header.bzero = 0.0;
+  header.bscale = 1.0;
+  header.unsign = FALSE;
+  header.extend = FALSE;
+
+  gfits_create_header (&header);
+  gfits_create_matrix (&header, &matrix);
+
+  gfits_modify (&header, "PAR_1", "%s", 1, "mass (Mo)");
+  for (i = 0; i < NMASS + 1; i++) {
+    sprintf (line, "PAR_1_%0d\0", i);
+    value = 10.0 / SQ(4.5 - DMASS*i);
+    gfits_modify (&header, line, "%lf", 1, value);
+  }
+  
+  gfits_modify (&header, "PAR_2", "%s", 1, "age out (Myr)");
+  for (i = 0; i < N_age + 1; i++) {
+    sprintf (line, "PAR_2_%0d\0", i);
+    gfits_modify (&header, line, "%lf", 1, age[i]);
+  }
+
+  gfits_modify (&header, "PAR_3", "%s", 1, "age in (Myr)");
+  for (i = 0; i < N_age + 1; i++) {
+    sprintf (line, "PAR_3_%0d\0", i);
+    gfits_modify (&header, line, "%lf", 1, age[i]);
+  }
+  
+  gfits_modify (&header, "PAR_4", "%s", 1, "alpha");
+  for (i = 0; i < N_alpha; i++) {
+    sprintf (line, "PAR_4_%0d\0", i);
+    gfits_modify (&header, line, "%lf", 1, alpha[i]);
+  }
+
+  gfits_modify (&header, "PAR_5", "%s", 1, "dist (mag)");
+  for (i = 0; i < N_dist; i++) {
+    sprintf (line, "PAR_5_%0d\0", i);
+    gfits_modify (&header, line, "%lf", 1, dist[i]);
+  }
+
+  gfits_modify (&header, "PAR_6", "%s", 1, "A_V (mag)");
+  for (i = 0; i < N_Av; i++) {
+    sprintf (line, "PAR_6_%0d\0", i);
+    gfits_modify (&header, line, "%lf", 1, Av[i]);
+  }
+
+}
+
+
+/*****************************************************************************/
+
+fakestar (A_V, Dist, Alpha, AgeS, AgeE, mag, color, Mass, Noise)
+double A_V, Dist, Alpha, AgeS, AgeE;
+double *Mass, *mag, *color, *Noise;
+{
+
+  int X, Y, i;
+  double mass, Age, v, uv, noise;
+
+  for (i = 0; i < 500; i++) {
+    mass = rnd_mass (Alpha);
+    Age = (AgeE - AgeS)*drand48() + AgeS;
+    *Mass += mass;
+    
+    /* find star in color, mag images */
+    X = (log10(Age) - lAo) / ldA;
+    Y = (log10(mass) - lMo) / ldM;
+    if ((X >= 0) && (X < UV_NX) && (Y >= 0) && (Y < UV_NY)) {
+      uv = UVbuffer[X + UV_NX*Y];
+      if (uv != 100.0) {
+	uv += 0.7*A_V;   /***** this depends on the extinction law and colors U-V ***/
+	v = Vbuffer[X + UV_NX*Y] + Dist + A_V; 
+	noise = dVo*sqrt(1.0 + pow (10.0, (0.4*(v - dVref)))); 
+	if (noise < dMo) {
+	  *Noise = noise;
+	  *mag = rnd_gauss (v, noise);
+	  *color = rnd_gauss (uv, 1.4*noise);
+	  return;
+	}
+      }
+    }
+  }
+  fprintf (stderr, "problem with generating stars:  none land in safe zone\n");
+  exit (0);
+}
+
+
+
+/* rnd_mass only returns stars with masses in the range MMIN to MMAX */
+double
+rnd_mass (Alpha)
+double Alpha;
+{
+  
+  double dP, x;
+  
+  x = (MMAX + 1);
+  while (x > MMAX) {
+    dP = drand48();
+    x = MMIN * pow ((dP*MassTerm + 1.0), 1.0 / (-Alpha));
+  }
+  return (x);
+
+}
+
+/*****************************************************************************/
+
+read_datafiles ()
+{
+
+  gfits_read_header (colorfile, &UV_h);
+  gfits_read_matrix (colorfile, &UV_i);
+  gfits_read_header (magfile, &V_h);
+  gfits_read_matrix (magfile, &V_i); 
+  UV_NX = UV_h.Naxis[0];
+  UV_NY = UV_h.Naxis[1];
+  UVbuffer = (float *)UV_i.buffer;
+  Vbuffer = (float *)V_i.buffer;
+
+  gfits_scan (&UV_h, "RA_O",  "%lf", 1, &lAo);
+  gfits_scan (&UV_h, "RA_X",  "%lf", 1, &ldA);
+  gfits_scan (&UV_h, "DEC_O", "%lf", 1, &lMo);
+  gfits_scan (&UV_h, "DEC_Y", "%lf", 1, &ldM);
+
+  gfits_read_header (massfile, &mass_h);
+  gfits_read_matrix (massfile, &mass_i);
+  gfits_read_header (agefile, &age_h);
+  gfits_read_matrix (agefile, &age_i); 
+  MS_NX = mass_h.Naxis[0];
+  MS_NY = mass_h.Naxis[1];
+  Mbuffer = (float *)mass_i.buffer;
+  Abuffer = (float *)age_i.buffer;
+
+  gfits_scan (&mass_h, "RA_O",  "%lf", 1, &UV0);
+  gfits_scan (&mass_h, "RA_X",  "%lf", 1, &DUV);
+  gfits_scan (&mass_h, "DEC_O", "%lf", 1, &V0);
+  gfits_scan (&mass_h, "DEC_Y", "%lf", 1, &DV);
+} 
+
+/*****************************************************************************/
+
+double
+rnd_gauss (mean, sigma)
+double mean, sigma; 
+{
+
+  int i;
+  double y;
+
+  y = drand48();
+  i = NGAUSS*y;
+  y = gaussint[i]*sigma + mean;
+
+  return (y);
+
+}
+
+gauss_init ()
+{
+
+  int i;
+  long A, B;
+  double val, x, dx, dx1, dx2, dx3, df;
+  double mean, sigma;
+
+  A = time(NULL);
+  for (B = 0; A == time(NULL); B++);
+  srand48(B);
+
+  val = 0;
+  dx = 0.001;
+  dx1 = dx / 3.0;
+  dx2 = 2.0*dx/3.0;
+  dx3 = dx;
+  mean = 0.0;
+  sigma = 1.0;
+
+  for (i = 0, x = -7.0; (i < NGAUSS) && (x < 7.0); x += dx)  {
+    df = (3.0*gaussian(x    , mean, sigma) + 
+	  9.0*gaussian(x+dx1, mean, sigma) +
+	  9.0*gaussian(x+dx2, mean, sigma) + 
+	  3.0*gaussian(x+dx3, mean, sigma)) * (dx1/8.0);
+    val += df;
+    if (val > (i / (double) NGAUSS)) {
+      gaussint[i] = x + dx / 2.0;
+      i++;
+    }
+  }
+  return (x + dx / 2.0);
+}
+
+double 
+gaussian (x, mean, sigma) 
+double x, mean, sigma; 
+{
+
+  double f, X;
+
+  f = exp (-0.5 * SQ(x - mean) / SQ(sigma)) / sqrt(2 * M_PI * SQ(sigma));
+
+  return (f);
+
+}
+
+/*****************************************************************************/
+
+magtomass (A_V, Dist, mag, color, noise, M, A, inflation)
+double A_V, Dist, mag, color, noise;
+int *M, *A;
+double *inflation;
+{
+
+  int x, y, I, J, i, j, k;
+  double mass, Age, v, uv, Ngood;
+
+  *inflation = 0.0;
+  x = (color - UV0 - 0.7*A_V) / DUV;   /* again, depends on U-V and extinction */
+  y = (mag - Dist - V0 - A_V) / DV;
+  if ((x > 0) && (x < MS_NX) && (y > 0) && (y < MS_NY)) {
+    mass = Mbuffer[x + MS_NX*y];
+    if (mass > 0.0) {
+      Age = Abuffer[x + MS_NX*y];
+      /* age[i]: i = 0,N_age */
+      if ((Age < age[0]) || (Age > age[N_age])) {
+	*inflation = 0.0;
+	return;
+      }
+      for (I = 0; (I < N_age) && (Age > age[I+1]); I++);
+      J = MAX (MIN ((4.5 - sqrt(10.0/mass)) / DMASS, NMASS - 1), 0);
+      Ngood = 1.0;
+      for (k = 0; k < NTRY; k++) {
+	v = rnd_gauss (mag, noise);
+	uv = rnd_gauss (color, 1.4*noise);
+	x = (uv - UV0 - 0.7*A_V) / DUV;
+	y = (v - V0 - Dist - A_V) / DV;
+	if ((x > 0) && (x < MS_NX) && (y > 0) && (y < MS_NY)) {
+	  mass = Mbuffer[x + MS_NX*y];
+	  if (mass > 0.0) {
+	    Age = Abuffer[x + MS_NX*y];
+	    for (i = -1; (i < N_age) && (Age > age[i+1]); i++);
+	    j = MAX (MIN ((4.5 - sqrt(10.0/mass)) / DMASS, NMASS - 1), 0);
+	    if ((i == I) && (j == J)) {
+	      Ngood += 1.0;
+	    }
+	  }
+	}
+      }
+      *inflation = (NTRY / Ngood);
+      *M = J;
+      *A = I;
+    }
+  }
+  if (mass == 0.0) *inflation = 0.0;
+}
+ 
+
+/*****************************************************************************/
+
+add_to_outmatrix (AV, DIST, ALPHA, AGE_IN, AGE_OUT, MASS, value)
+int AV, DIST, ALPHA, AGE_IN, AGE_OUT, MASS;
+double value;
+{
+
+  float *buffer;
+
+  buffer = (float *)matrix.buffer;
+  
+  /* elements in the (N_age) row of each Mass*Age matrix contain special numbers for the matrix */
+  buffer[MASS + NMASS*(AGE_OUT + (N_age + 1)*(AGE_IN + N_age*(ALPHA + N_alpha*(DIST + N_dist*(AV + N_Av*(0))))))] += value;
+  buffer[MASS + NMASS*(AGE_OUT + (N_age + 1)*(AGE_IN + N_age*(ALPHA + N_alpha*(DIST + N_dist*(AV + N_Av*(1))))))] += 1.0;
+
+}
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakedump.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakedump.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakedump.c	(revision 21897)
@@ -0,0 +1,69 @@
+# include <ohana.h>
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+
+  Header in_h, out_h;
+  Matrix in_m, out_m;
+  int i, j;
+  int Nage, Nalpha, Ndist, NAv;
+  float *in, *out;
+
+  if (argc < 7) {
+    fprintf (stderr, "USAGE fakedump infile outfile Nage Nalpha Ndist NAv\n");
+    exit (0);
+  }
+  Nage = atof(argv[3]);
+  Nalpha = atof(argv[4]);
+  Ndist = atof(argv[5]);
+  NAv = atof(argv[6]);
+
+  gfits_read_header (argv[1], &in_h);
+  gfits_read_matrix (argv[1], &in_m);
+
+  if (Nage > in_h.Naxis[2] - 1) {
+    fprintf (stderr, "Nage too big (%d, %d)\n", Nage, in_h.Naxis[2] - 1);
+    exit (0);
+  }
+
+  if (Nalpha > in_h.Naxis[3] - 1) {
+    fprintf (stderr, "Nalpha too big (%d, %d)\n", Nalpha, in_h.Naxis[3] - 1);
+    exit (0);
+  }
+
+  if (Ndist > in_h.Naxis[4] - 1) {
+    fprintf (stderr, "Ndist too big (%d, %d)\n", Ndist, in_h.Naxis[4] - 1);
+    exit (0);
+  }
+
+  if (NAv > in_h.Naxis[5] - 1) {
+    fprintf (stderr, "NAv too big (%d, %d)\n", NAv, in_h.Naxis[5] - 1);
+    exit (0);
+  }
+
+  out_h.bitpix = -32;
+  out_h.Naxes = 2;
+  out_h.Naxis[0] = in_h.Naxis[0];
+  out_h.Naxis[1] = in_h.Naxis[1] - 1;
+  out_h.bzero = 0.0;
+  out_h.bscale = 1.0;
+  out_h.unsign = FALSE;
+  out_h.extend = FALSE;
+  gfits_create_header (&out_h);
+  gfits_create_matrix (&out_h, &out_m);
+  
+  in = (float *)in_m.buffer;
+  out = (float *)out_m.buffer;
+  for (i = 0; i < out_h.Naxis[0]; i++) {
+    for (j = 0; j < out_h.Naxis[1]; j++) {
+      out[i + out_h.Naxis[0]*j] = in[i + in_h.Naxis[0]*(j + in_h.Naxis[1]*(Nage + in_h.Naxis[2]*(Nalpha + in_h.Naxis[3]*(Ndist + in_h.Naxis[4]*(NAv + in_h.Naxis[5] * 0)))))];
+      fprintf (stderr, "%f ", out[i + out_h.Naxis[0]*j]);
+    }
+    fprintf (stderr, "\n");
+  }
+  
+  gfits_write_header (argv[2], &out_h);
+  gfits_write_matrix (argv[2], &out_m);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakepop.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakepop.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakepop.c	(revision 21897)
@@ -0,0 +1,293 @@
+# include <ohana.h>
+# define MMIN 1.0
+# define MMAX 120.0
+extern double drand48();
+extern double rnd_mass();
+double rnd_mass();
+double term;
+extern double rnd_gauss();
+extern double rnd_integrate ();
+extern double gaussian ();
+
+double gaussian();
+double rnd_gauss();
+double rnd_integrate();
+
+# define NGAUSS 2048
+double gaussint[NGAUSS];
+
+double AgeS, AgeE, alpha, d, Av, dMo, dVo, dVref;
+char colorfile[256], magfile[256];
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+
+  Header UV_h, V_h;
+  Matrix UV_i, V_i;
+  double Mtot, M, mass;
+  double age, noise, v, uv, V, UV;
+  double lAo, ldA, lMo, ldM, stage;
+  int X, Y;
+  long A, B;
+  
+  load_parameters (argc, argv);
+  Mtot = atof (argv[2]);
+  term = (pow((MMAX/MMIN), -alpha) - 1.0);
+  
+  gfits_read_header (colorfile, &UV_h);
+  gfits_read_matrix (colorfile, &UV_i);
+  gfits_read_header (magfile, &V_h);
+  gfits_read_matrix (magfile, &V_i); 
+
+  gfits_scan (&UV_h, "RA_O",  "%lf", 1, &lAo);
+  gfits_scan (&UV_h, "RA_X",  "%lf", 1, &ldA);
+  gfits_scan (&UV_h, "DEC_O", "%lf", 1, &lMo);
+  gfits_scan (&UV_h, "DEC_Y", "%lf", 1, &ldM);
+  
+  gauss_init ();
+
+  fprintf (stderr, "beginning main loop\n");
+  
+  stage = 1;
+  for (M = 0; M < Mtot; ) {
+    age = (AgeE - AgeS)*drand48() + AgeS;
+    X = (log10(age) - lAo) / ldA;
+    if (M > stage * Mtot / 10.0) {
+      fprintf (stderr, "M: %f\n", M);
+      stage += 1.0;
+    }
+    mass = rnd_mass (alpha);
+    Y = (log10(mass) - lMo) / ldM;
+    if ((X >= 0) && (X < UV_h.Naxis[0]) &&
+	(Y >= 0) && (Y < UV_h.Naxis[1])) {
+      uv = gfits_get_matrix_value (&UV_i, X, Y); 
+      if (uv != 100.0) {
+	uv += 0.7*Av;
+	v = gfits_get_matrix_value (&V_i, X, Y) + d + Av; 
+	noise = dVo*sqrt(1.0 + pow (10.0, (0.4*(v - dVref)))); 
+	V = rnd_gauss (v, noise);
+	UV = rnd_gauss (uv, 1.4*noise);
+	if (noise < dMo) {
+	  fprintf (stdout, "%f %f   %f %f   %f  %f\n", V, noise, V+UV, noise, mass, age);
+	}
+      }
+    }
+    M += mass;
+  }
+}
+
+/* rnd_mass only returns stars with masses in the range MMIN to MMAX */
+double
+rnd_mass (alpha)
+double alpha;
+{
+  
+  double dP, x;
+  
+  x = (MMAX + 1);
+  while (x > MMAX) {
+    dP = drand48();
+    x = MMIN * pow ((dP*term + 1.0), 1.0 / (-alpha));
+  }
+  return (x);
+
+}
+
+
+double
+rnd_gauss (mean, sigma)
+double mean, sigma; 
+{
+
+  int i;
+  double y;
+
+  y = drand48();
+  i = NGAUSS*y;
+  y = gaussint[i]*sigma + mean;
+
+  return (y);
+
+}
+
+
+gauss_init ()
+{
+
+  int i;
+  long A, B;
+  double val, x, dx, dx1, dx2, dx3, df;
+  double mean, sigma;
+
+  A = time(NULL);
+  for (B = 0; A == time(NULL); B++);
+  srand48(B);
+
+  val = 0;
+  dx = 0.001;
+  dx1 = dx / 3.0;
+  dx2 = 2.0*dx/3.0;
+  dx3 = dx;
+  mean = 0.0;
+  sigma = 1.0;
+
+  for (i = 0, x = -7.0; (i < NGAUSS) && (x < 7.0); x += dx)  {
+    df = (3.0*gaussian(x    , mean, sigma) + 
+	  9.0*gaussian(x+dx1, mean, sigma) +
+	  9.0*gaussian(x+dx2, mean, sigma) + 
+	  3.0*gaussian(x+dx3, mean, sigma)) * (dx1/8.0);
+    val += df;
+    if (val > (i / (double) NGAUSS)) {
+      gaussint[i] = x + dx / 2.0;
+      i++;
+    }
+  }
+  return (x + dx / 2.0);
+}
+
+double 
+rnd_integrate (function, range, mean, sigma) 
+double (*function) ();
+double range, mean, sigma;
+{
+
+  double val, x, dx, dx1, dx2, dx3, df;
+
+  range += 0.0001;
+  val = 0;
+  dx = sigma / 10.0;
+  dx1 = dx / 3.0;
+  dx2 = 2.0*dx/3.0;
+  dx3 = dx;
+
+  for (x = mean - 7*sigma; (val < range) && (x < mean + 7*sigma); x += dx)  {
+    df = (3.0*function(x    , mean, sigma) + 
+	  9.0*function(x+dx1, mean, sigma) +
+	  9.0*function(x+dx2, mean, sigma) + 
+	  3.0*function(x+dx3, mean, sigma)) * (dx1/8.0);
+    val += df;
+  }
+  return (x + dx / 2.0);
+}
+
+double 
+gaussian (x, mean, sigma) 
+double x, mean, sigma; 
+{
+
+  double f, X;
+
+  f = exp (-0.5 * SQ(x - mean) / SQ(sigma)) / sqrt(2 * M_PI * SQ(sigma));
+
+  return (f);
+
+}
+
+
+/*****************************************************************************/
+
+load_parameters (argc, argv)
+int argc;
+char **argv;
+{
+
+  int test_dVo, test_dVref, test_dMo;
+  int test_Age, test_Av, test_alpha, test_d;
+  int Mfile, Cfile;
+  FILE *f;
+  char line[1024];
+
+  if (argc < 3) {
+    fprintf (stderr, "USAGE: %s pfile Mtot\n", argv[0]);
+    exit (0);
+  }
+
+  f = fopen (argv[1], "r");
+  if (f == NULL) {
+    fprintf (stderr, "parameter file %s not found\n", argv[1]);
+    exit (0);
+  }
+
+  test_Age = test_Av = test_alpha = test_d = FALSE;
+  test_dVo = test_dVref = test_dMo = FALSE;
+  Mfile = Cfile = FALSE;
+  while (scan_line (f, line) != EOF) {
+    if (!stripwhite (line)) continue;
+    if (line[0] == '#') continue;
+    
+    fprintf (stderr, "%s\n", line);
+    if (!strncmp (line, "Av ", strlen ("Av "))) {
+      dparse (&Av, 2, line);
+      test_Av = TRUE;
+    }
+
+    if (!strncmp (line, "dist ", strlen ("dist "))) {
+      dparse (&d, 2, line);
+      test_d = TRUE;
+    }
+
+    if (!strncmp (line, "alpha ", strlen ("alpha "))) {
+      dparse (&alpha, 2, line);
+      test_alpha = TRUE;
+    }
+
+    if (!strncmp (line, "age ", strlen ("age "))) {
+      test_Age  = dparse (&AgeS, 2, line);
+      test_Age &= dparse (&AgeE, 3, line);
+    }
+
+    if (!strncmp (line, "dVo ", strlen ("dVo "))) {
+      dparse (&dVo, 2, line);
+      test_dVo = TRUE;
+    }
+    
+    if (!strncmp (line, "dVref ", strlen ("dVref "))) {
+      dparse (&dVref, 2, line);
+      test_dVref = TRUE;
+    }
+    
+    if (!strncmp (line, "dMo ", strlen ("dMo "))) {
+      dparse (&dMo, 2, line);
+      test_dMo = TRUE;
+    }
+    
+    if (!strncmp (line, "magfile ", strlen ("magfile "))) {
+      sscanf (line, "%*s %s", magfile);
+      fprintf (stderr, "magfile: %s\n", magfile);
+      Mfile = TRUE;
+    }
+    
+    if (!strncmp (line, "colorfile ", strlen ("colorfile "))) {
+      sscanf (line, "%*s %s", colorfile);
+      fprintf (stderr, "colorfile: %s\n", colorfile);
+      Cfile = TRUE;
+    }
+    
+    if (test_Age && test_Av && test_d && test_alpha && 
+	test_dVo && test_dVref && test_dMo &&
+	Mfile && Cfile) {
+      return;
+    }
+  }
+  
+  if (!(test_Age && test_Av && test_d && test_alpha && 
+	test_dVo && test_dVref && test_dMo && 
+	Mfile && Cfile)) {
+    fprintf (stderr, "failed to get all parameter lines\n");
+    fprintf (stderr, "test_Av: %d\n", test_Av);
+    fprintf (stderr, "test_d: %d\n", test_d);
+    fprintf (stderr, "test_alpha: %d\n", test_alpha);
+    fprintf (stderr, "test_age: %d\n", test_Age);
+    fprintf (stderr, "dVo: %f (%d)\n", dVo, test_dVo);
+    fprintf (stderr, "dVref: %f (%d)\n", dVref, test_dVref);
+    fprintf (stderr, "dMo: %f (%d)\n", dMo, test_dMo);
+    fprintf (stderr, "Mfile: %d\n", Mfile);
+    fprintf (stderr, "Cfile: %d\n", Cfile);
+    exit (0);
+  }
+  
+}
+
+/*****************************************************************************/
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakestars.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakestars.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fakestars.c	(revision 21897)
@@ -0,0 +1,121 @@
+# include <ohana.h>
+# define NCHAR 66 /* 65 char EXCLUDING return */
+# define D_NSTARS 1000
+# define BYTES_STAR 66
+# define BLOCK 1000
+
+typedef struct {
+  double X;
+  double Y;
+  double R;
+  double D;
+  double M, dM;
+  char   dophot;
+  double sky;
+  double fx, fy, df;
+  double Mgal, Map;
+  int found;
+} Stars;
+
+void   gauss_init ();
+double gaussian (double x, double mean, double sigma);
+double rnd_gauss (double mean, double sigma);
+
+  /* 
+     load in a list of stars in cmp format
+     generate a new list of stars in cmp format
+     new measurements should have the requested noise characteristics */
+
+int main (int argc, char **argv) {
+
+  int Nstar, N, Nbytes, nbytes, i;
+  FILE *f;
+  char *input, *output, *buffer, line[NCHAR];
+  Header header;
+  Stars *stars;
+  double tmp, dMs, dMr, dMo, dM, offset;
+
+  if (argc != 5) {
+    fprintf (stderr, "USAGE: fakestars (input) (output) (syserr) (offset)\n");
+    exit (2);
+  }
+  input  = argv[1];
+  output = argv[2];
+  dMs    = atof (argv[3]);
+  offset = atof (argv[4]);
+
+  gauss_init ();
+
+  /* load header, open file */
+  if (!gfits_read_header (input, &header)) {
+    fprintf (stderr, "ERROR: can't read header for %s\n", input);
+    exit (1);
+  }
+  f = fopen (input, "r");
+  if (f == NULL) {
+    fprintf (stderr, "ERROR: can't read data from %s\n", input);
+    exit (1);
+  }
+  fseek (f, header.size, SEEK_SET); 
+
+  /* find expected number of stars */
+  gfits_scan (&header, "NSTARS", "%d", 1, &Nstar);
+  if (Nstar == 0) {
+    fprintf (stderr, "ERROR: can't get NSTARS from header\n");
+    exit (1);
+  }
+  ALLOCATE (stars, Stars, Nstar);
+
+  /* load in stars */
+  Nbytes = Nstar*BYTES_STAR;
+  ALLOCATE (buffer, char, Nbytes + 1);
+  nbytes = fread (buffer, 1, Nbytes, f);
+  if (nbytes != Nbytes) {
+    fprintf (stderr, "ERROR: failed to read in %d stars\n", Nstar);
+    exit (1);
+  }
+  buffer[Nbytes] = 0;
+
+  for (i = 0; i < Nstar; i++) {
+    Nbytes = i*BYTES_STAR;
+    dparse (&stars[i].X,    1, &buffer[Nbytes]);
+    dparse (&stars[i].Y,    2, &buffer[Nbytes]);
+    dparse (&stars[i].M,    3, &buffer[Nbytes]);
+    dparse (&stars[i].dM,   4, &buffer[Nbytes]);
+    dparse (&stars[i].Mgal, 7, &buffer[Nbytes]);
+    dparse (&stars[i].Map,  8, &buffer[Nbytes]);
+    dparse (&stars[i].fx,   9, &buffer[Nbytes]);
+    dparse (&stars[i].fy,  10, &buffer[Nbytes]);
+    dparse (&stars[i].df,  11, &buffer[Nbytes]);
+    
+    dparse (&tmp,           5, &buffer[Nbytes]);
+    stars[i].dophot = tmp;
+  }
+  fclose (f);
+
+  /* error per star is hypot of systematic & poisson */
+  for (i = 0; i < Nstar; i++) {
+    dMr = 0.001 * stars[i].dM;
+    dMo = hypot (dMs, dMr);
+    dM  = rnd_gauss (0.0, dMo);
+    stars[i].M += dM + offset;
+  }
+
+  gfits_write_header (output, &header);
+  f = fopen (output, "a");
+  if (f == NULL) {
+    fprintf (stderr, "ERROR: can't open file for output: %s\n", output);
+    exit (1);
+  }
+  fseek (f, header.size, SEEK_SET); 
+
+  for (i = 0; i < Nstar; i++) {
+    snprintf (line, NCHAR, "%6.1f %6.1f %6.3f %03d %2d %3.1f %6.3f %6.3f %6.2f %6.2f %5.1f", 
+	      stars[i].X, stars[i].Y, stars[i].M, 
+	      (int)stars[i].dM, stars[i].dophot, stars[i].sky, 
+	      stars[i].Mgal, stars[i].Map, stars[i].fx, stars[i].fy, stars[i].df);
+    fprintf (f, "%s\n", line);
+  }
+  fclose (f);
+}
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fhead.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fhead.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fhead.c	(revision 21897)
@@ -0,0 +1,42 @@
+# include <ohana.h>
+# include <gfitsio.h>
+
+int main (int argc, char **argv) {
+
+  int N, Extend, Nextend, status;
+  int i, j, nbytes;
+  Header head;
+  char *p;
+
+  Extend = FALSE;
+  if ((N = get_argument (argc, argv, "-x"))) {
+    Extend = TRUE;
+    remove_argument (N, &argc, argv);
+    Nextend = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  for (i = 1; i < argc; i++) {
+    if (argc != 2) 
+      fprintf (stdout, "------> %s <------\n", argv[i]);
+    
+    if (Extend) {
+      status = gfits_read_Xheader (argv[i], &head, Nextend);
+    } else {
+      status = gfits_read_header (argv[i], &head);
+    }      
+
+    if (!status) continue;
+
+    for (j = 79; j < head.size; j+= 80) {
+      head.buffer[j] = 10;
+    }
+
+    p = gfits_header_field (&head, "END", 1);
+    nbytes = p - head.buffer;
+    fwrite (head.buffer, nbytes, 1, stdout);
+    gfits_free_header (&head);
+
+  }
+  exit (0);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fields.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fields.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fields.c	(revision 21897)
@@ -0,0 +1,130 @@
+# include <ohana.h>
+# include <gfitsio.h>
+# include <sys/types.h>
+# include <regex.h>
+
+int print_fields (char *filename, char *extname, Header *header, int argc, char **argv);
+
+int usage () {
+
+  fprintf (stderr, "USAGE: fields [options] [KEYWORD] [KEYWORD]...\n");
+  fprintf (stderr, " reads filenames from stdin, writes header values to stdout\n");
+  fprintf (stderr, " options:\n");
+  fprintf (stderr, " -x (extnum)  : PHU is -1, followed by 0,1,2...\n");
+  fprintf (stderr, " -n (extname) : name may include a regex for EXTNAME values\n");
+
+  exit (2);
+}
+
+int main (int argc, char **argv) {
+
+  int i;
+  FILE *f;
+  Header header;
+  char filename[1000], *Extname, extname[80];
+  int N, Nbytes, Extnum, Nextend, status, GotFile, GotField, GotExtension;
+
+  regex_t preg;
+
+  if (get_argument (argc, argv, "-h")) usage();
+  if (get_argument (argc, argv, "--help")) usage();
+
+  Extnum = FALSE;
+  if ((N = get_argument (argc, argv, "-x"))) {
+    Extnum = TRUE;
+    remove_argument (N, &argc, argv);
+    Nextend = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  Extname = NULL;
+  if ((N = get_argument (argc, argv, "-n"))) {
+    remove_argument (N, &argc, argv);
+    Extname = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+    regcomp (&preg, Extname, REG_EXTENDED);
+  }
+
+  GotFile  = TRUE; 
+  GotField = TRUE;
+
+  while (fscanf (stdin, "%s", filename) != EOF) {
+    if (!Extnum && !Extname) {
+      GotFile &= gfits_read_header (filename, &header);
+      GotField &= print_fields (filename, NULL, &header, argc, argv);
+      continue;
+    }
+    if (Extnum) {
+      GotFile  &= gfits_read_Xheader (filename, &header, Nextend);
+      GotField &= print_fields (filename, NULL, &header, argc, argv);
+      continue;
+    } 
+
+    if (Extname) {
+      /* keep reading headers, only parse fields for matching headers */
+      Nextend = 0;
+      GotExtension = FALSE;
+      f = fopen (filename, "r");
+      if (f == NULL) {
+	GotFile = FALSE;
+	continue;
+      }
+      while (gfits_fread_header (f, &header)) {
+	/* extract the EXTNAME for this component (set to PHU for 0th component) */
+	status = gfits_scan (&header, "EXTNAME", "%s", 1, extname);
+	if (!status) {
+	  if (Nextend == 0) {
+	    strcpy (extname, "PHU");
+	  } else {
+	    strcpy (extname, "UNKNOWN");
+	  }
+	}
+	if (!regexec (&preg, extname, 0, NULL, 0)) {
+	  GotField &= print_fields (filename, extname, &header, argc, argv);
+	  GotExtension = TRUE;
+	}   
+    
+	Nbytes = gfits_matrix_size (&header);
+	fseek (f, Nbytes, SEEK_CUR);
+	Nextend ++;
+
+	GotFile = gfits_read_Xheader (filename, &header, Nextend);
+	continue;
+      } 
+      fclose (f);
+      if (Nextend == 0) {
+	GotFile = FALSE;
+      }
+    }
+  }
+
+  if (Extname) regfree (&preg);
+
+  if (!GotFile) exit (1);
+  if (!GotField) exit (2);
+  if (!GotExtension) exit (3);
+  exit (0);
+}
+
+int print_fields (char *filename, char *extname, Header *header, int argc, char **argv) {
+
+  int i, status, GotField;
+  char buffer[1000];
+
+  GotField = TRUE;
+
+  if (extname) {
+    fprintf (stdout, "%s[%s]  ", filename, extname);
+  } else {
+    fprintf (stdout, "%s  ", filename);
+  }
+  for (i = 1; i < argc; i++) {
+    bzero (buffer, 1000);
+    GotField &= gfits_scan (header, argv[i], "%s", 1, buffer);
+    stripwhite (buffer);
+    fprintf (stdout, "%s  ", buffer);
+  }
+  fprintf (stdout, "\n");
+  gfits_free_header (header);
+  return (GotField);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/findexec.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/findexec.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/findexec.c	(revision 21897)
@@ -0,0 +1,121 @@
+# include <stdio.h>
+# include <strings.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <stdlib.h>
+
+# define TRUE 1
+# define FALSE 0
+
+# ifndef ALLOCATE
+# define ALLOCATE(X,T,S)  \
+  X=(T *)malloc((unsigned) ((S)*sizeof(T)));\
+  if(X==NULL) \
+    { \
+      fprintf(stderr,"failed to malloc X\n");\
+        exit(0);\
+    } 
+# define REALLOCATE(X,T,S) \
+  X=(T *)realloc(X,(unsigned) ((S)*sizeof(T))); \
+  if(X==NULL) \
+    { \
+       fprintf(stderr,"failed to realloc X\n"); \
+       exit(0); \
+    }
+# endif /* ALLOCATE */
+
+int _check_permissions (char *filename) {
+  
+  FILE *f;
+  struct stat filestat;
+  uid_t fuid, uid;
+  gid_t fgid, gid;
+  int status;
+
+  uid = getuid();
+  gid = getgid();
+
+  /* check permission to exec file */
+  status = stat (filename, &filestat);
+  if (status == 0) { /* file exists, are permissions OK? */
+    if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR) && (filestat.st_mode & S_IXUSR)) ||
+	((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP) && (filestat.st_mode & S_IXGRP)) || 
+	(                            (filestat.st_mode & S_IROTH) && (filestat.st_mode & S_IXOTH))) {
+      return (TRUE);
+    } else {
+      fprintf (stderr, "can't exec %s\n", filename);
+      return (FALSE);
+    }
+  }
+  fprintf (stderr, "no such file %s\n", filename);
+  return (FALSE);
+}
+
+char *pathname (char *name) {
+ 
+  char *c, *path;
+
+  ALLOCATE (path, char, strlen(name) + 1);
+  strcpy (path, name);
+  c = strrchr (path, '/');
+  if (c == (char *) NULL) {
+    strcpy (path, ".");
+  } else {
+    *c = 0;
+  }
+  
+  return (path);
+  
+}
+
+char *findexec (int argc, char **argv) {
+
+  int i, N, done, status;
+  char *c, *e, *dir, path[1024], name[1024];
+  struct stat state;
+
+  if (argv[0][0] == '/') {
+    status = _check_permissions (argv[0]);
+    if (status) {
+      realpath (argv[0], path);
+      dir = pathname (path);
+      return (dir);
+    }
+  }
+
+  N = 0;
+  for (i = argc+1; argv[i] != (char *) NULL; i++) {
+    if (!strncmp (argv[i], "PATH", 4)) {
+      N = i;
+      break;
+    }
+  }
+
+  if (N) {
+    c = &argv[N][5];
+    e = strchr (c, ':');
+    done = FALSE;
+    i = 0;
+    while (!done && (i < 50)) {
+      if (e == (char *) NULL) {
+	done = TRUE;
+	bzero (path, 256);
+	strncpy (path, c, strlen(c));
+      } else {
+	bzero (path, 256);
+	strncpy (path, c, e-c);
+	c = e+1;
+	e = strchr (c, ':');
+      }
+      sprintf (name, "%s/%s", path, argv[0]);
+      status = _check_permissions (name);
+
+      if (status) {
+	realpath (name, path);
+	dir = pathname (path);
+	return (dir);
+      }
+    }
+    i++;
+  }
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fitdist.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fitdist.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fitdist.c	(revision 21897)
@@ -0,0 +1,627 @@
+# include <ohana.h>
+
+# define NGAUSS 2048
+double drand48();
+double gaussint[NGAUSS];
+double gaussian();
+double rnd_gauss();
+
+# define MMIN 1.0
+# define MMAX 120.0
+double rnd_mass();
+double MassTerm;
+
+# define NPARMAX 30
+int Nmass, N_Av, N_dist, N_alpha, N_age, NTRY;
+double *Mass, Av[NPARMAX], dist[NPARMAX], alpha[NPARMAX], age[NPARMAX];
+
+int COL1, COL2;
+double *mag, *color, *noise;
+double *obsdata;
+
+double UV0, V0, DV, DUV;
+Header fake_h, mass_h, age_h;
+Matrix fake_m, mass_i, age_i;
+int MS_NX, MS_NY;
+float *Mbuffer, *Abuffer;
+
+char datafile[256], fakefile[256], massfile[256], agefile[256];
+
+double get_obs(), get_fake(), get_error(), get_fake_err(), get_chisq();
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+  
+  Header header;
+  Matrix matrix;
+  int i, j, m, n, M, A, Nstars, I, J, k, done, grid, tries;
+  double mass, inflation, sumterm, errterm;
+  double dm, a1, a2, chisq_0, chisq_1, chisq_min, Ndof, *delta;
+  double temp_Factor, *Factor, *dFactor, *SFR, dFactor1, dFactor2;
+
+  load_parameters (argc, argv);
+  fprintf (stderr, "read in parameters\n");
+
+  gauss_init ();
+
+  read_datafiles ();
+  fprintf (stderr, "read in data files (%d x %d)\n", Nmass, N_age);
+
+  Nstars = load_realstars ();
+  fprintf (stderr, "read in %d real stars\n", Nstars);
+
+  ALLOCATE (SFR, double, N_age);
+  ALLOCATE (Factor, double, N_age);
+  ALLOCATE (dFactor, double, N_age);
+  ALLOCATE (delta, double, N_age);
+
+  fprintf (stdout, "# Av   dist   alpha  chisq Ndof");
+  for (n = 0; n < N_age; n++) {
+    fprintf (stdout, " %3.0f My ", age[n]);
+  }
+  fprintf (stdout, "\n");
+
+  for (i = 0; i < N_Av; i++) {
+    for (j = 0; j < N_dist; j++) {
+      
+      /* unique obs. matrix for each Av, dist value only */
+      bzero (obsdata, sizeof(double) * N_age*Nmass*2);
+      for (k = 0; k < Nstars; k++) {
+	magtomass (Av[i], dist[j], mag[k], color[k], noise[k], &M, &A, &inflation);
+	if (inflation > 0.0) add_obs (A, M, inflation);
+      }
+      
+      /* now fit to fake matrices */
+      for (m = 0; m < N_alpha; m++) {
+
+	for (n = 0; n < N_age; n++) {
+	  dm = get_fake (i, j, m, n, N_age, 0);
+	  a1 = get_fake (i, j, m, n, N_age, 4);
+	  a2 = get_fake (i, j, m, n, N_age, 5);
+	  SFR[n] = dm / (a2 - a1);
+	  delta[n] = 0.1;
+	  Factor[n] = 0.0;
+	}	
+	
+	chisq_1 = get_chisq (Factor, i, j, m, &Ndof);
+	chisq_0 = 2*chisq_1;
+	done = FALSE;
+	/* 	while (!done) { */
+	for (tries = 0; ((fabs (chisq_1 - chisq_0) / Ndof > 0.001) && (tries < 100)); tries++) {
+	  chisq_0 = chisq_1;
+	  for (n = 0; n < N_age; n++) {
+	    Factor[n] += delta[n];
+	    chisq_1 = get_chisq (Factor, i, j, m, &Ndof);
+	    dFactor1 = MAX (0.0, MIN (0.5*delta[n], 5.0 * delta[n] * (1.0 - chisq_1/chisq_0)));
+	    Factor[n] -= 2*delta[n];
+	    chisq_1 = get_chisq (Factor, i, j, m, &Ndof);
+	    dFactor2 = MIN (0.0, MAX (-0.5*delta[n], -5.0 * delta[n] * (1.0 - chisq_1/chisq_0)));
+	    if (dFactor1 > fabs(dFactor2)) {
+	      dFactor[n] = dFactor1;
+	    }
+	    else {
+	      dFactor[n] = dFactor2;
+	    }
+	    Factor[n] += delta[n];
+	    if ((delta[n] > 0.001) && (!(tries % 5) || (fabs(dFactor[n]) < 0.01 * delta[n]))) {
+	      /* small grid search */
+	      dFactor1 = temp_Factor = Factor[n];
+	      chisq_min = chisq_0;
+	      for (grid = 0, Factor[n] = MAX (0.0, Factor[n] - 2*delta[n]); grid < 5; grid ++, Factor[n] += delta[n]) {
+		chisq_1 = get_chisq (Factor, i, j, m, &Ndof);
+		if (chisq_1 < chisq_min) {
+		  dFactor1 = Factor[n];
+		  chisq_min = chisq_1;
+		}
+	      }
+	      if (dFactor1 == temp_Factor) {
+		delta[n] = delta[n] / 2.0;
+	      }
+	      Factor[n] = dFactor1;
+	    }
+	  }
+	  done = TRUE; 
+	  for (n = 0; n < N_age; n++) {
+	    Factor[n] += dFactor[n];
+	    Factor[n] = MAX (0.0, Factor[n]);  /* negative star formation is unphysical */
+	    if ((Factor[n] > 0.0) && (fabs(dFactor[n]) == delta[n])) {
+	      delta[n] = MIN (0.1, delta[n] * 1.5);
+	    }
+	  }
+	  chisq_1 = get_chisq (Factor, i, j, m, &Ndof);
+	  /*
+	  fprintf (stderr, "%f %f ", chisq_0, chisq_1);
+	  for (n = 0; n < N_age; n++) {
+	    fprintf (stderr, "%f ", Factor[n]);
+	  }
+	  fprintf (stderr, "\n");
+	  fprintf (stderr, "                       ");
+	  for (n = 0; n < N_age; n++) {
+	    fprintf (stderr, "%f ", delta[n]);
+	  }
+	  fprintf (stderr, "\n");
+	  */
+	}
+
+	chisq_0 = chisq_1;
+	for (n = 0; n < N_age; n++) {
+	  temp_Factor = Factor[n];
+	  for (; chisq_1 < chisq_0 + 1; Factor[n] += 0.1*delta[n])
+	    chisq_1 = get_chisq (Factor, i, j, m, &Ndof);
+	  dFactor[n] = Factor[n] - temp_Factor;
+	  /* fprintf (stderr, "%d %f %f\n", n, Factor[n], dFactor[n]); */
+	  Factor[n] = temp_Factor;
+	  chisq_1 = chisq_0;
+	  for (; chisq_1 < chisq_0 + 1; Factor[n] -= 0.1*delta[n])
+	    chisq_1 = get_chisq (Factor, i, j, m, &Ndof);
+	  dFactor[n] =  0.5 * (dFactor[n] + temp_Factor  - Factor[n]);
+	  Factor[n] = temp_Factor;
+	}
+	if (tries == 100) {
+	  fprintf (stdout, "*** failed to converge *** \n");
+	}
+	fprintf (stdout, "%5.2f %6.2f %4.1f   %6.2f  %.0f ", Av[i], dist[j], alpha[m], chisq_1/Ndof, Ndof);
+	for (n = 0; n < N_age; n++) {
+	  fprintf (stdout, "%7.0f ", SFR[n]*Factor[n]);
+	}
+	fprintf (stdout, "\n");
+	fprintf (stdout, "                               ");
+	for (n = 0; n < N_age; n++) {
+	  fprintf (stdout, "%7.0f ", SFR[n]*dFactor[n]);
+	}
+	fprintf (stdout, "\n");
+      }
+    }
+  }
+}
+
+
+/*****************************************************************************/
+
+double get_chisq (Factor, AV, DIST, ALPHA, Ndof)
+double *Factor;
+int AV, DIST, ALPHA;
+double *Ndof;
+{
+
+  double chisq, sumterm, errterm;
+  int I, J, n;
+
+  *Ndof = chisq = 0.0;
+  for (I = 0; I < Nmass; I++) {
+    for (J = 0; J < N_age; J++) {
+      errterm = get_error (J, I);
+      sumterm = get_obs (J, I);
+      for (n = 0; n < N_age; n++) {
+	sumterm -= Factor[n]*get_fake (AV, DIST, ALPHA, n, J, I);
+	errterm += Factor[n]*get_fake_err (AV, DIST, ALPHA, n, J, I);
+      }
+      if (errterm > 0.0) {
+	chisq += SQ (sumterm) / errterm;
+	*Ndof += 1.0;
+      }
+    }
+  }
+  *Ndof -= N_age + N_Av + N_dist + N_alpha;
+
+  return (chisq);
+}
+
+/*****************************************************************************/
+
+load_parameters (argc, argv)
+int argc;
+char **argv;
+{
+
+  int i;
+  int Dfile, Ffile, Afile, MSfile;
+  FILE *f;
+  char line[1024];
+  double tmp;
+
+  if (argc < 2) {
+    fprintf (stderr, "USAGE: %s pfile\n", argv[0]);
+    exit (0);
+  }
+
+  f = fopen (argv[1], "r");
+  if (f == NULL) {
+    fprintf (stderr, "parameter file %s not found\n", argv[1]);
+    exit (0);
+  }
+
+  COL1 = COL1 = NTRY = 0.0;
+  Dfile = Ffile = Afile = MSfile = FALSE;
+  while (scan_line (f, line) != EOF) {
+    if (!stripwhite (line)) continue;
+    if (line[0] == '#') continue;
+        
+    if (!strncmp (line, "ntry ", strlen ("ntry "))) {
+      dparse (&tmp, 2, line);
+      NTRY = tmp;
+    }
+  
+    if (!strncmp (line, "col1 ", strlen ("col1 "))) {
+      dparse (&tmp, 2, line);
+      COL1 = tmp;
+    }
+  
+    if (!strncmp (line, "col2 ", strlen ("col2 "))) {
+      dparse (&tmp, 2, line);
+      COL2 = tmp;
+    }
+  
+    if (!strncmp (line, "agefile ", strlen ("agefile "))) {
+      sscanf (line, "%*s %s", agefile);
+      fprintf (stderr, "agefile: %s\n", agefile);
+      Afile = TRUE;
+    }
+    
+    if (!strncmp (line, "massfile ", strlen ("massfile "))) {
+      sscanf (line, "%*s %s", massfile);
+      fprintf (stderr, "massfile: %s\n", massfile);
+      MSfile = TRUE;
+    }
+    
+    if (!strncmp (line, "datafile ", strlen ("datafile "))) {
+      sscanf (line, "%*s %s", datafile);
+      fprintf (stderr, "datafile: %s\n", datafile);
+      Dfile = TRUE;
+    }
+    
+    if (!strncmp (line, "fakefile ", strlen ("fakefile "))) {
+      sscanf (line, "%*s %s", fakefile);
+      fprintf (stderr, "fakefile: %s\n", fakefile);
+      Ffile = TRUE;
+    }
+    
+    if (COL1 && COL2 && NTRY && Dfile && Ffile && Afile && MSfile) {
+      return;
+    }
+  }
+  
+  if (!(COL1 && COL2 && NTRY && Dfile && Ffile && Afile && MSfile)) {
+    fprintf (stderr, "failed to get all parameter lines\n");
+    fprintf (stderr, "NTRY: %d\n", NTRY);
+    fprintf (stderr, "COL1: %d\n", COL1);
+    fprintf (stderr, "COL2: %d\n", COL2);
+    fprintf (stderr, "Dfile: %d\n", Dfile);
+    fprintf (stderr, "Ffile: %d\n", Ffile);
+    fprintf (stderr, "Afile: %d\n", Afile);
+    fprintf (stderr, "MSfile: %d\n", MSfile);
+    exit (0);
+  }
+  
+}
+
+/*****************************************************************************/
+
+read_datafiles ()
+{
+
+  int i;
+  char line[1024];
+
+  gfits_read_header (massfile, &mass_h);
+  gfits_read_matrix (massfile, &mass_i);
+  gfits_read_header (agefile, &age_h);
+  gfits_read_matrix (agefile, &age_i); 
+  MS_NX = mass_h.Naxis[0];
+  MS_NY = mass_h.Naxis[1];
+  Mbuffer = (float *)mass_i.buffer;
+  Abuffer = (float *)age_i.buffer;
+
+  gfits_scan (&mass_h, "RA_O",  "%lf", 1, &UV0);
+  gfits_scan (&mass_h, "RA_X",  "%lf", 1, &DUV);
+  gfits_scan (&mass_h, "DEC_O", "%lf", 1, &V0);
+  gfits_scan (&mass_h, "DEC_Y", "%lf", 1, &DV);
+
+  gfits_read_header (fakefile, &fake_h);
+  gfits_read_matrix (fakefile, &fake_m);
+  Nmass = fake_h.Naxis[0];
+  ALLOCATE (Mass, double, Nmass + 1);
+  for (i = 0; i < Nmass + 1; i++) {
+    sprintf (line, "PAR_1_%0d\0", i);
+    gfits_scan (&fake_h, line, "%lf", 1, &Mass[i]);
+  }
+  
+  N_age = fake_h.Naxis[1] - 1;
+  for (i = 0; i < N_age + 1; i++) {
+    sprintf (line, "PAR_2_%0d\0", i);
+    gfits_scan (&fake_h, line, "%lf", 1, &age[i]);
+  }
+
+  N_alpha = fake_h.Naxis[3];
+  for (i = 0; i < N_alpha; i++) {
+    sprintf (line, "PAR_4_%0d\0", i);
+    gfits_scan (&fake_h, line, "%lf", 1, &alpha[i]);
+  }
+
+  N_dist = fake_h.Naxis[4];
+  for (i = 0; i < N_dist; i++) {
+    sprintf (line, "PAR_5_%0d\0", i);
+    gfits_scan (&fake_h, line, "%lf", 1, &dist[i]);
+  }
+
+  N_Av = fake_h.Naxis[5];
+  for (i = 0; i < N_Av; i++) {
+    sprintf (line, "PAR_6_%0d\0", i);
+    gfits_scan (&fake_h, line, "%lf", 1, &Av[i]);
+  }
+
+  ALLOCATE (obsdata, double, Nmass*N_age*2);
+
+}
+ 
+
+/*****************************************************************************/
+
+double
+rnd_gauss (mean, sigma)
+double mean, sigma; 
+{
+
+  int i;
+  double y;
+
+  y = drand48();
+  i = NGAUSS*y;
+  y = gaussint[i]*sigma + mean;
+
+  return (y);
+
+}
+
+gauss_init ()
+{
+
+  int i;
+  long A, B;
+  double val, x, dx, dx1, dx2, dx3, df;
+  double mean, sigma;
+
+  A = time(NULL);
+  for (B = 0; A == time(NULL); B++);
+  srand48(B);
+
+  val = 0;
+  dx = 0.001;
+  dx1 = dx / 3.0;
+  dx2 = 2.0*dx/3.0;
+  dx3 = dx;
+  mean = 0.0;
+  sigma = 1.0;
+
+  for (i = 0, x = -7.0; (i < NGAUSS) && (x < 7.0); x += dx)  {
+    df = (3.0*gaussian(x    , mean, sigma) + 
+	  9.0*gaussian(x+dx1, mean, sigma) +
+	  9.0*gaussian(x+dx2, mean, sigma) + 
+	  3.0*gaussian(x+dx3, mean, sigma)) * (dx1/8.0);
+    val += df;
+    if (val > (i / (double) NGAUSS)) {
+      gaussint[i] = x + dx / 2.0;
+      i++;
+    }
+  }
+  return (x + dx / 2.0);
+}
+
+double 
+gaussian (x, mean, sigma) 
+double x, mean, sigma; 
+{
+
+  double f, X;
+
+  f = exp (-0.5 * SQ(x - mean) / SQ(sigma)) / sqrt(2 * M_PI * SQ(sigma));
+
+  return (f);
+
+}
+
+/*****************************************************************************/
+
+magtomass (A_V, Dist, Mag, Color, Noise, M, A, inflation)
+double A_V, Dist, Mag, Color, Noise;
+int *M, *A;
+double *inflation;
+{
+
+  int x, y, I, J, i, j, k;
+  double mass, Age, v, uv, Ngood;
+
+  *inflation = 0.0;
+  x = (Color - UV0 - 0.7*A_V) / DUV;   /* again, depends on U-V and extinction */
+  y = (Mag - Dist - V0 - A_V) / DV;
+  if ((x > 0) && (x < MS_NX) && (y > 0) && (y < MS_NY)) {
+    mass = Mbuffer[x + MS_NX*y];
+    if (mass > 0.0) {
+      Age = Abuffer[x + MS_NX*y];
+      if ((Age < age[0]) || (Age > age[N_age])) {
+	*inflation = 0.0;
+	return;
+      }
+      for (I = 0; (I < N_age) && (Age > age[I+1]); I++);
+      if ((mass < Mass[0]) || (mass > Mass[Nmass])) {
+	*inflation = 0.0;
+	return;
+      }
+      for (J = 0; (J < Nmass) && (mass > Mass[J+1]); J++);
+      Ngood = 1.0;
+      for (k = 0; k < NTRY; k++) {
+	v = rnd_gauss (Mag, Noise);
+	uv = rnd_gauss (Color, 1.4*Noise);
+	x = (uv - UV0 - 0.7*A_V) / DUV;
+	y = (v - V0 - Dist - A_V) / DV;
+	if ((x > 0) && (x < MS_NX) && (y > 0) && (y < MS_NY)) {
+	  mass = Mbuffer[x + MS_NX*y];
+	  if (mass > 0.0) {
+	    Age = Abuffer[x + MS_NX*y];
+	    for (i = -1; (i < N_age) && (Age > age[i+1]); i++);
+	    for (j = -1; (j < Nmass) && (mass > Mass[j+1]); j++);
+	    if ((i == I) && (j == J)) {
+	      Ngood += 1.0;
+	    }
+	  }
+	}
+      }
+      *inflation = (NTRY / Ngood);
+      *M = J;
+      *A = I;
+    }
+  }
+  if (mass == 0.0) *inflation = 0.0;
+}
+ 
+
+/*****************************************************************************/
+
+add_obs (AGE, MASS, value)
+int AGE, MASS;
+double value;
+{
+
+  if (value == 0.0) {
+    fprintf (stderr, "error: %d %d %f\n", AGE, MASS, value);
+  }
+  else {
+    obsdata[MASS + Nmass*(AGE        )] += value;
+    obsdata[MASS + Nmass*(AGE + N_age)] += 1.0;
+  }
+}
+
+
+/*****************************************************************************/
+
+double get_obs (AGE, MASS)
+int AGE, MASS;
+{
+
+  double value;
+
+  value = obsdata[MASS + Nmass*(AGE)];
+
+  return (value);
+
+}
+
+/*****************************************************************************/
+
+double get_error (AGE, MASS)
+int AGE, MASS;
+{
+
+  double value;
+
+  if (obsdata[MASS + Nmass*(AGE + N_age)] > 5) {
+    value = SQ (obsdata[MASS + Nmass*(AGE)]) / obsdata[MASS + Nmass*(AGE + N_age)];
+    return (value);
+  }
+  if ((obsdata[MASS + Nmass*(AGE + N_age)] < 1) && (obsdata[MASS + Nmass*(AGE)] > 0)) {
+    fprintf (stderr, "error: %d %d %e %e\n", AGE, MASS, 
+	     obsdata[MASS + Nmass*(AGE + 0)], obsdata[MASS + Nmass*(AGE + 1)]);
+  }
+  if (obsdata[MASS + Nmass*(AGE + N_age)] > 0) {
+    value = SQ (3.0 * obsdata[MASS + Nmass*(AGE)] / obsdata[MASS + Nmass*(AGE + N_age)]);
+    return (value);
+  }
+  value = 0.0;
+  return (value);
+
+}
+
+
+/*****************************************************************************/
+
+double get_fake (AV, DIST, ALPHA, AGE_IN, AGE_OUT, MASS)
+int AV, DIST, ALPHA, AGE_IN, AGE_OUT, MASS;
+{
+
+  double value;
+  float *buffer;
+
+  buffer = (float *)fake_m.buffer;
+  
+  /* elements in the (N_age) row of each Mass*Age matrix contain special numbers for the matrix */
+  value = buffer[MASS + Nmass*(AGE_OUT + (N_age + 1)*(AGE_IN + N_age*(ALPHA + N_alpha*(DIST + N_dist*(AV + N_Av*(0))))))];
+  /* buffer[MASS + Nmass*(AGE_OUT + (N_age + 1)*(AGE_IN + N_age*(ALPHA + N_alpha*(DIST + N_dist*(AV + N_Av*(1))))))] += 1.0; */
+
+  return (value);
+
+}
+
+/*****************************************************************************/
+
+double get_fake_err (AV, DIST, ALPHA, AGE_IN, AGE_OUT, MASS)
+int AV, DIST, ALPHA, AGE_IN, AGE_OUT, MASS;
+{
+
+  double value;
+  float *buffer;
+  int pix1, pix2;
+
+  buffer = (float *)fake_m.buffer;
+  
+  /* elements in the (N_age) row of each Mass*Age matrix contain special numbers for the matrix */
+  pix1 = MASS + Nmass*(AGE_OUT + (N_age + 1)*(AGE_IN + N_age*(ALPHA + N_alpha*(DIST + N_dist*(AV + N_Av*(0))))));
+  pix2 = MASS + Nmass*(AGE_OUT + (N_age + 1)*(AGE_IN + N_age*(ALPHA + N_alpha*(DIST + N_dist*(AV + N_Av*(1))))));
+
+  if (buffer[pix2] > 5) {
+    value = SQ (buffer[pix1]) / buffer[pix2];
+    return (value);
+  }
+
+  if (buffer[pix2] > 0) {
+    value = SQ (3.0 * buffer[pix1] / buffer[pix2]);
+    return (value);
+  }
+
+  value = 0.0;
+  return (value);
+
+}
+
+/***************************************************************************/
+
+int load_realstars () 
+
+{
+
+  char line[1024];
+  FILE *f;
+  double U;
+  int i, Nstars;
+
+  f = fopen (datafile, "r");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "couldn't find data file %s\n", datafile);
+    exit (0);
+  }
+  
+  Nstars = 1000;
+  ALLOCATE (mag, double, Nstars);
+  ALLOCATE (color, double, Nstars);
+  ALLOCATE (noise, double, Nstars);
+  
+  /* need to fix allocations */
+  for (i = 0; scan_line (f, line) != EOF; i++) {
+    if (!stripwhite (line)) continue;
+    if (line[0] == '#') continue;
+    dparse (&mag[i], COL1, line);
+    dparse (&noise[i], (COL1+1), line);
+    dparse (&U, COL2, line);
+    color[i] = U - mag[i];
+    if (i == Nstars - 1) {
+      Nstars += 1000;
+      REALLOCATE (mag, double, Nstars);
+      REALLOCATE (color, double, Nstars);
+      REALLOCATE (noise, double, Nstars);
+    }
+  }
+
+  return (i);
+  
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fits_insert.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fits_insert.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fits_insert.c	(revision 21897)
@@ -0,0 +1,160 @@
+# include <ohana.h>
+# include <gfitsio.h>
+
+static char reserved[] =  "COMMENT  Reserved space.  This line can be used to add a new FITS card.         ";
+static char blankline[] = "                                                                                ";
+
+int main (int argc, char **argv) {
+
+  int i, N, status, EXTNUM, Nbytes, skip;
+  int Nreserved, start_size;
+  char *p, keyword[16], line[256];
+  FILE *f;
+  Header header;
+  int COMMENT, Cnumber;
+  char *Cline;
+
+  /* check for command line options */
+  COMMENT = FALSE;
+  if ((N = get_argument (argc, argv, "-comment"))) {
+    COMMENT = TRUE;
+    remove_argument (N, &argc, argv);
+    Cnumber = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    Cline = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  /* check for command line options */
+  EXTNUM = -1; /* -1 is primary header */
+  if ((N = get_argument (argc, argv, "-X"))) {
+    remove_argument (N, &argc, argv);
+    EXTNUM = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 3) {
+    fprintf (stderr, "USAGE: gfits_insert (image.fits) (header.hdx) [-X N] [-comment N line]\n");
+    exit (2);
+  }
+  
+  /* load header from image file */
+  Nbytes = gfits_read_Xheader (argv[1], &header, EXTNUM);
+  if (!Nbytes) {
+    fprintf (stderr, "can't open fits file %s\n", argv[1]);
+    exit (1);
+  }
+  start_size = header.size;
+  skip = Nbytes - header.size;
+
+  /* open header data file */
+  f = fopen (argv[2], "r");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "can't open header data file %s\n", argv[2]);
+    exit (1);
+  }
+
+  /* wipe out COMMENT N and replace with given line */ 
+  if (COMMENT) {
+
+    /* create a pristine FITS line */
+    snprintf (line, 81, "COMMENT  %-71s", Cline);
+
+    p = gfits_header_field (&header, "COMMENT", Cnumber);
+    if (p != (char *) NULL) {
+      strncpy (p, line, 80);
+    }
+  }
+
+  /* run through the lines in the header data file */
+  while (scan_line (f, line) != EOF) {
+    
+    /* fill in end of line with blanks, force end at 80 */
+    for (N = strlen (line); N < 80; N++) {
+      line[N] = ' ';
+    }
+    line[80] = 0;
+    bzero (keyword, 10);
+    strncpy (keyword, line, 8);
+    
+    /* replace existing keywords, unless this is a COMMENT or HISTORY field */
+    if (strncmp (keyword, "COMMENT ", 8) && strncmp (keyword, "HISTORY ", 8)) {
+      p = gfits_header_field (&header, keyword, 1);
+      if (p != (char *) NULL) {
+	strncpy (p, line, 80);
+	continue;
+      }
+    }
+
+    /* check that the line does not already exist */
+    p = (char *) NULL;
+    for (i = 0; (i < header.size) && (p == (char *) NULL) ; i+= FT_LINE_LENGTH) {
+      if (!strncmp (&header.buffer[i], line, 80)) {
+	p = &header.buffer[i];
+      }
+    }
+    if (p != (char *) NULL) continue;
+
+    /* find first line with the reserved line */
+    p = (char *) NULL;
+    Nreserved = strlen (reserved);
+    for (i = 0; (i < header.size) && (p == (char *) NULL) ; i+= FT_LINE_LENGTH) {
+      if (!strncmp (&header.buffer[i], "END     ", 8)) break;
+      if (!strncmp (&header.buffer[i], reserved, Nreserved)) {
+	p = &header.buffer[i];
+      }
+      if (!strncmp (&header.buffer[i], blankline, Nreserved)) {
+	p = &header.buffer[i];
+      }
+    }
+    if (p == (char *) NULL) {
+      fprintf (stdout, "no more reserved spaces, trying for extra space in block\n");
+      p = gfits_header_field (&header, "END", 1);
+      if (p == (char *) NULL) {
+	fprintf (stderr, "header is missing END\n");
+	exit (1);
+      }
+      if (p - header.buffer + 80 == header.size) {
+	fprintf (stderr, "no free space in block, can't insert keyword\n");
+	exit (1);
+      }
+      strncpy (p+80, "END", 3);
+      for (i = 3; i < 80; i++) { p[80+i] = ' '; }
+    }
+    /* insert the new line here */
+    strncpy (p, line, 80);
+  }
+  if (fclose (f)) {
+    fprintf (stderr, "error reading new keywords\n");
+    exit (1);
+  }
+
+  /* now write the new header on top of the old one. 
+     check first that the header size has not changed.
+  */
+
+  if (header.size != start_size) {
+    fprintf (stderr, "header changed size: should not happen!\n");
+    exit (1);
+  }
+
+  f = fopen (argv[1], "r+");
+  if (f == NULL) {
+    fprintf (stderr, "can't open file for update %s\n", argv[1]);
+    exit (1);
+  }
+
+  fseek (f, skip, SEEK_SET);
+  status = fwrite (header.buffer, 1, header.size, f);
+  if (status != header.size) {
+    fprintf (stderr, "failed to write data to image header\n");
+    exit (1);
+  }
+  if (fclose (f)) {
+    fprintf (stderr, "error writing data to disk\n");
+    exit (1);
+  }
+
+  exit (0);
+}
+    
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fiximg.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fiximg.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fiximg.c	(revision 21897)
@@ -0,0 +1,48 @@
+# include <ohana.h>
+# include <gfitsio.h>
+
+int main (int argc, char **argv) {
+
+  char *p;
+  int i, N;
+  Matrix matrix;
+  Header header;
+
+  if (argc != 3) {
+    fprintf (stderr, "USAGE: fiximg (input) (output)\n");
+    exit (1);
+  }
+
+  /* read catalog header */
+  if (!gfits_read_header (argv[1], &header)) {
+    fprintf (stderr, "error loading file %s\n", argv[1]);
+    exit (1);
+  }
+  if (!gfits_read_matrix (argv[1], &matrix)) {
+    fprintf (stderr, "error loading file %s\n", argv[1]);
+    exit (1);
+  }
+
+  N = 0;
+  while (gfits_header_field (&header, "COMMENT", 1) != (char *) NULL) {
+    N++;
+    gfits_delete (&header, "COMMENT", 1);
+  }
+  fprintf (stderr, "deleted %d comments\n", N);
+  p = gfits_header_field (&header, "END", 1);
+  for (i = 3; i < header.size - (int) (p - header.buffer); i++) { 
+    p[i] = ' '; 
+  }
+
+  /* read catalog header */
+  if (!gfits_write_header (argv[2], &header)) {
+    fprintf (stderr, "error writing file %s\n", argv[2]);
+    exit (1);
+  }
+  if (!gfits_write_matrix (argv[2], &matrix)) {
+    fprintf (stderr, "error writing file %s\n", argv[2]);
+    exit (1);
+  }
+  exit (0);
+
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fixsimple.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fixsimple.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/fixsimple.c	(revision 21897)
@@ -0,0 +1,60 @@
+# include <ohana.h>
+
+main (int argc, char **argv) {
+
+  char *p;
+  int i, N;
+  Matrix matrix;
+  Header header;
+
+  if (argc != 3) {
+    fprintf (stderr, "USAGE: fixsimple (input) (output)\n");
+    exit (1);
+  }
+
+  /* read header */
+  if (!gfits_read_header (argv[1], &header)) {
+    fprintf (stderr, "error loading file %s\n", argv[1]);
+    exit (1);
+  }
+
+  N = 0;
+  while (gfits_header_field (&header, "COMMENT", 1) != (char *) NULL) {
+    N++;
+    gfits_delete (&header, "COMMENT", 1);
+  }
+  fprintf (stderr, "deleted %d comments\n", N);
+  p = gfits_header_field (&header, "END", 1);
+  for (i = 3; i < header.size - (int) (p - header.buffer); i++) { 
+    p[i] = ' '; 
+  }
+
+  /* read catalog header */
+  if (!gfits_write_header (argv[2], &header)) {
+    fprintf (stderr, "error writing file %s\n", argv[2]);
+    exit (1);
+  }
+  if (!gfits_write_matrix (argv[2], &matrix)) {
+    fprintf (stderr, "error writing file %s\n", argv[2]);
+    exit (1);
+  }
+  exit (0);
+
+  f = fopen (argv[1], "r+");
+  if (f == NULL) {
+    fprintf (stderr, "can't open file for update %s\n", argv[1]);
+    exit (1);
+  }
+
+  fseek (f, skip, SEEK_SET);
+  status = fwrite (header.buffer, 1, header.size, f);
+  if (status != header.size) {
+    fprintf (stderr, "failed to write data to image header\n");
+    exit (1);
+  }
+  if (fclose (f)) {
+    fprintf (stderr, "error writing data to disk\n");
+    exit (1);
+  }
+
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/ftable.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/ftable.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/ftable.c	(revision 21897)
@@ -0,0 +1,411 @@
+# include <ohana.h>
+# include <gfitsio.h>
+
+char *print_table_row (char *row, Header *header);
+FILE *load_extension (char *file, int Nextend, char *Extname, Header *header);
+void print_column (FTable *table, int Column, char *Colname);
+void usage();
+void list_extnames (char *file);
+void print_layout (Header *header);
+int   ByteSwap (char *ptr, int size, int nitems, char *type);
+int Binary;
+
+int main (int argc, char **argv) {
+
+  int i, N, Nx, Ny, Nbytes, Nread;
+  int Nextend, Column, Row, ListExtname, Layout;
+  char *Extname, *Colname, *line, ttype[80];
+  FTable table;
+  Header header;
+  FILE *f;
+
+  if (get_argument (argc, argv, "-h")) usage ();
+  if (get_argument (argc, argv, "--help")) usage ();
+
+  Nextend = 0;
+  if ((N = get_argument (argc, argv, "-x"))) {
+    remove_argument (N, &argc, argv);
+    Nextend = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  Extname = (char *) NULL;
+  if ((N = get_argument (argc, argv, "-n"))) {
+    if (Nextend) usage ();
+    remove_argument (N, &argc, argv);
+    Extname = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  Row = 0;
+  if ((N = get_argument (argc, argv, "-row"))) {
+    remove_argument (N, &argc, argv);
+    Row = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  Column = 0;
+  if ((N = get_argument (argc, argv, "-ncolumn"))) {
+    remove_argument (N, &argc, argv);
+    Column = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  Colname = 0;
+  if ((N = get_argument (argc, argv, "-column"))) {
+    if (Column) usage ();
+    remove_argument (N, &argc, argv);
+    Colname = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  ListExtname = FALSE;
+  if ((N = get_argument (argc, argv, "-list"))) {
+    remove_argument (N, &argc, argv);
+    ListExtname = TRUE;
+  }
+
+  Layout = FALSE;
+  if ((N = get_argument (argc, argv, "-layout"))) {
+    remove_argument (N, &argc, argv);
+    Layout = TRUE;
+  }
+
+  if (argc != 2) usage ();
+
+  if (ListExtname) list_extnames (argv[1]);
+
+  /* load header */
+  table.header = &header;
+  f = load_extension (argv[1], Nextend, Extname, table.header);
+
+  if (Layout) print_layout (table.header);
+
+  Binary = FALSE;
+  gfits_scan (table.header, "XTENSION", "%s", 1, ttype);
+  if (!strcmp (ttype, "BINTABLE")) Binary = TRUE;
+
+  /* load table data array */
+  Nbytes = gfits_matrix_size (table.header);
+  ALLOCATE (table.buffer, char, Nbytes);
+  Nread = fread (table.buffer, sizeof (char), Nbytes, f);
+  if (Nread != Nbytes) {
+    fprintf (stderr, "failed to read all table data\n");
+    exit (1);
+  }
+  table.size = Nbytes;
+
+  gfits_scan (table.header, "NAXIS1",  "%d", 1, &Nx);
+  gfits_scan (table.header, "NAXIS2",  "%d", 1, &Ny);
+
+  /* print a column */
+  if (Column || (Colname != (char *) NULL)) print_column (&table, Column, Colname);
+
+  /* print a row */
+  if (Row) {
+    line = print_table_row (&table.buffer[Nx*Row], table.header);
+    fprintf (stdout, "%s\n", line);
+    free (line);
+    exit (0);
+  }
+
+  /* print complete table */
+  for (i = 0; i < Ny; i++) {
+    line = print_table_row (&table.buffer[Nx*i], table.header);
+    fprintf (stdout, "%s\n", line);
+    free (line);
+  }    
+  exit (0);
+}
+
+/* print an ASCII table to a row with single spaces separating value */
+char *print_table_row (char *row, Header *header) {
+  
+  int i, j, Nx, Nfields, Nbytes, Nvals, Oout, Oin;
+  char field[16], type[16], format[16], *line;
+
+  gfits_scan (header, "NAXIS1",  "%d", 1, &Nx);
+  gfits_scan (header, "TFIELDS", "%d", 1, &Nfields);
+
+  /* assume we have one space per byte column */
+  ALLOCATE (line, char, 2*Nx + 1);
+
+  Oin = Oout = 0;
+  for (i = 1; i <= Nfields; i++) {
+    sprintf (field, "TFORM%d", i);
+    gfits_scan (header, field, "%s", 1, format); /* get field format */
+    gfits_table_format (format, type, &Nvals, &Nbytes);    /* convert to c-style */
+    memcpy (&line[Oout], &row[Oin], Nvals*Nbytes);
+    for (j = 0; j < Nvals*Nbytes; j++) if (line[Oout+j] == 0) line[Oout+j] = ' ';
+    line[Oout+Nvals*Nbytes] = ' ';
+    Oout += Nvals*Nbytes + 1;
+    Oin += Nvals*Nbytes;
+  }
+
+  return (line);
+}
+
+void usage () {
+    fprintf (stderr, "USAGE: [-h] [-N N] (table.fits)\n");
+    fprintf (stderr, " -x N:       operate on extension N (0 is default)\n");
+    fprintf (stderr, " -n EXTNAME: operate on named extension (incompatible with -x)\n");
+    fprintf (stderr, " -row N:     print row number N\n");
+    fprintf (stderr, " -column n:  print column named n\n");
+    fprintf (stderr, " -ncolumn N: print column number N\n");
+    fprintf (stderr, " -list:      print extension names\n");
+    exit (2);
+}
+
+void list_extnames (char *file) {
+
+  FILE *f;
+  int i, Naxis, Nelem, Ncomp, extend, Nbytes, status;
+  char extname[82], exttype[82], axisname[32];
+  Header header;
+
+  f = fopen (file, "r");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "can't open file %s\n", file);
+    exit (1);
+  }
+
+  /* 
+     if (!gfits_fread_header (f, &header)) {
+     fprintf (stderr, "can't read header from %s\n", file);
+     exit (1);
+     }
+     Nbytes = gfits_matrix_size (&header);
+     fseek (f, Nbytes, SEEK_CUR);
+  */
+
+  fprintf (stdout, "%-30s %-15s NAXIS NAXIS(i)...\n", "extname", "datatype"); 
+
+  Ncomp = 0;
+  while (gfits_fread_header (f, &header)) {
+    /* extract the EXTNAME for this component (set to PHU for 0th component) */
+    status = gfits_scan (&header, "EXTNAME", "%s", 1, extname);
+    if (!status) {
+      if (Ncomp == 0) {
+	strcpy (extname, "PHU");
+      } else {
+	strcpy (extname, "UNKNOWN");
+      }
+    }
+    fprintf (stdout, "%-30s ", extname);
+
+    /* extract the datatype for this component (IMAGE for 0th component) */
+    if (Ncomp == 0) {
+      strcpy (exttype, "IMAGE");
+    } else {
+      status = gfits_scan (&header, "XTENSION", "%s", 1, exttype);
+      if (!status) {
+	strcpy (exttype, "UNKNOWN");
+      }
+    }
+    fprintf (stdout, "%-15s ", exttype);
+
+    /* extract the rank of the component */
+    status = gfits_scan (&header, "NAXIS",  "%d", 1, &Naxis);
+    if (!status) {
+      fprintf (stderr, "component %d is missing Naxis!\n", Ncomp);
+      Ncomp ++;
+      continue;
+    }
+    fprintf (stdout, " %4d", Naxis);
+
+    /* extract the individual axes */
+    for (i = 0; i < Naxis; i++) {
+      sprintf (axisname, "NAXIS%d", i+1);
+      status = gfits_scan (&header, axisname,  "%d", 1, &Nelem);
+      if (!status) {
+	fprintf (stderr, "missing %s\n", axisname);
+      }
+      fprintf (stdout, " %7d", Nelem);
+    }
+    fprintf (stdout, "\n");
+
+    /* are extensions identified? (we will scan for them anyway) */
+    if (Ncomp == 0) {
+      extend = FALSE;
+      gfits_scan (&header, "EXTEND", "%t", 1, &extend);
+      if (!extend) {
+	fprintf (stderr, "no extensions listed in file\n");
+      }
+    }
+
+    Nbytes = gfits_matrix_size (&header);
+    fseek (f, Nbytes, SEEK_CUR);
+
+    Ncomp ++;
+  }
+  fclose (f);
+  exit (0);
+}
+
+FILE *load_extension (char *file, int Nextend, char *Extname, Header *header) {
+
+  int i, extend, Nbytes;
+  char extname[82];
+  FILE *f;
+
+  /* open file */
+  f = fopen (file, "r");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "can't open file %s\n", file);
+    exit (1);
+  }
+
+  /* read PHU */
+  if (!gfits_fread_header (f, header)) {
+    fprintf (stderr, "can't read header from %s\n", file);
+    exit (1);
+  }
+
+  /* check for existence of extensions */
+  extend = FALSE;
+  gfits_scan (header, "EXTEND", "%t", 1, &extend);
+  if (!extend) {
+    fprintf (stderr, "no extensions listed in file\n");
+  }
+
+  /* skip first data array */
+  Nbytes = gfits_matrix_size (header);
+  fseek (f, Nbytes, SEEK_CUR);
+
+  /* search for extension of interest */
+  for (i = 0; gfits_fread_Theader (f, header); i++) {
+    if ((Extname == NULL) && (Nextend == i)) return (f);
+
+    gfits_scan (header, "EXTNAME", "%s", 1, extname);
+    if ((Extname != NULL) && (!strcmp (Extname, extname))) return (f);
+
+    Nbytes = gfits_matrix_size (header);
+    fseek (f, Nbytes, SEEK_CUR);
+    gfits_free_header (header);
+  }
+  fclose (f);
+
+  fprintf (stderr, "failed to load extension of interest\n");
+  exit (1);
+}
+
+void print_column (FTable *table, int Column, char *Colname) {
+  
+  int i, j, Nfields, Nstart, Nv, Nb, Nx, Ny;
+  Header *header;
+  char format[16], field[16], type[16], *line, *data;
+  int *Ti;
+  float *Tf;
+
+  header =  table[0].header;
+  data   =  table[0].buffer;
+
+  gfits_scan (header, "TFIELDS", "%d", 1, &Nfields);
+  gfits_scan (header, "NAXIS1",  "%d", 1, &Nx);
+  gfits_scan (header, "NAXIS2",  "%d", 1, &Ny);
+
+  if (Colname != (char *) NULL) {
+    /* find matching column entry */
+    for (i = 1; i <= Nfields; i++) {
+      sprintf (field, "TTYPE%d", i);
+      gfits_scan (header, field, "%s", 1, type);
+      if (!strcmp (type, Colname)) {
+	Column = i;
+	break;
+      }
+    }
+    if (!Column) {
+      fprintf (stderr, "column %s not found\n", Colname);
+      exit (1);
+    }
+  } else {
+    /* check if Column is in range */
+    if (Column > Nfields) {
+      fprintf (stderr, "-ncolumn %d too large, only %d columns\n", Column, Nfields);
+      exit (1);
+    }
+  }
+
+  /* scan columns to find insert point */
+  Nstart = 0;
+  for (i = 1; i < Column; i++) {
+    sprintf (field, "TFORM%d", i);
+    gfits_scan (header, field, "%s", 1, format);
+    if (Binary) 
+      gfits_table_format (format, type, &Nv, &Nb);
+    else 
+      gfits_bintable_format (format, type, &Nv, &Nb);
+    Nstart += Nv*Nb;
+  }
+
+  sprintf (field, "TFORM%d", Column);
+  gfits_scan (header, field, "%s", 1, format);
+  if (Binary) 
+    gfits_bintable_format (format, type, &Nv, &Nb);    /* convert to c-style */
+  else 
+    gfits_table_format (format, type, &Nv, &Nb);    /* convert to c-style */
+
+  ALLOCATE (line, char, Nv*Nb + 1);
+
+  if (Binary) {
+    if (!gfits_get_bintable_column_type (header, Colname, type, &Nv)) return;
+    if (!strcmp (type, "char")) return;
+    if (!gfits_get_bintable_column (header, table, Colname, (void **)&data)) return;
+
+    for (i = 0; i < Ny; i++) {
+      if (!strcmp (type, "char")) {
+	memcpy (line, &data[i*Nx + Nstart], Nv*Nb);
+	fprintf (stdout, "%s\n", line);
+      } else {
+	for (j = 0; j < Nv; j++) {
+	  if (!strcmp (type, "int")) {
+	    memcpy (line, &data[i*Nx + Nstart + Nb*j], Nb);
+	    ByteSwap (line, Nb, 1, "int");
+	    Ti = (int *)line;
+	    fprintf (stdout, "%d ", Ti[0]);
+	  }
+	  if (!strcmp (type, "float")) {
+	    memcpy (line, &data[i*Nx + Nstart + Nb*j], Nb);
+	    ByteSwap (line, Nb, 1, "float");
+	    Tf = (float *)line;
+	    fprintf (stdout, "%f ", Tf[0]);
+	  }
+	}
+	fprintf (stdout, "\n");
+      }
+    }
+  } else {
+    for (i = 0; i < Ny; i++) {
+      memcpy (line, &data[i*Nx + Nstart], Nv*Nb);
+      sprintf (format, "%%%ds\n", Nv*Nb);
+      fprintf (stdout, format, line);
+    }
+  }
+  exit (0);
+}
+
+void print_layout (Header *header) {
+
+  int i, Nfields;
+  char field[16], type[80], comment[80], format[80], unit[80], null[80], nval[80];
+
+  gfits_scan (header, "TFIELDS", "%d", 1, &Nfields);
+
+  for (i = 1; i <= Nfields; i++) {
+    sprintf (field, "TTYPE%d", i);
+    gfits_scan (header, field, "%s", 1, type);
+    gfits_scan (header, field, "%C", 1, comment);
+    sprintf (field, "TFORM%d", i);
+    gfits_scan (header, field, "%s", 1, format);
+    sprintf (field, "TUNIT%d", i);
+    gfits_scan (header, field, "%s", 1, unit);
+    sprintf (field, "TNULL%d", i);
+    if (!gfits_scan (header, field, "%s", 1, null)) strcpy (null, "none");
+    sprintf (field, "TNVAL%d", i);
+    if (!gfits_scan (header, field, "%s", 1, nval)) strcpy (nval, "none");
+
+    fprintf (stdout, "%-18s %-32s %-18s %-6s %-8s %-8s\n", 
+	  type, comment, unit, format, null, nval); 
+  }
+  exit (0);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/gconfig.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/gconfig.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/gconfig.c	(revision 21897)
@@ -0,0 +1,66 @@
+# include "ohana.h"
+void usage ();
+
+int main (int argc, char **argv) {
+
+  char *config, *file;
+  char word[256];
+  int i, N, VERBOSE, status;
+
+  if ((N = get_argument (argc, argv, "-h"))) { usage (); }
+  if ((N = get_argument (argc, argv, "-help"))) { usage (); }
+
+  /*** load configuration info ***/
+  file = SelectConfigFile (&argc, argv, "ptolemy");
+
+  /* dump raw config file (no interpolation of input files */
+  if ((N = get_argument (argc, argv, "-raw"))) {
+    config = LoadRawConfigFile (file, TRUE);
+    fwrite (config, 1, strlen(config), stdout);
+    exit (0);
+  }
+
+  /* load complete config info from file(s) */
+  config = LoadConfigFile (file);
+  if (config == (char *) NULL) {
+    fprintf (stderr, "ERROR: can't find configuration file %s\n", file);
+    if (file != (char *) NULL) free (file);
+    exit (1);
+  }
+
+  VERBOSE = FALSE;
+  if ((N = get_argument (argc, argv, "-v"))) {
+    remove_argument (N, &argc, argv);
+    VERBOSE = TRUE;
+  }
+  if ((N = get_argument (argc, argv, "-q"))) {
+    remove_argument (N, &argc, argv);
+    VERBOSE = FALSE;
+  }
+
+  /* if no keywords, dump entire config file */
+  if (argc == 1) {
+    fwrite (config, 1, strlen(config), stdout);
+    exit (0);
+  }
+
+  status = 0;
+  for (i = 1; i < argc; i++) {
+    if (ScanConfig (config, argv[i], "%s", 0,  word) == (char *) NULL) {
+      strcpy (word, "not found");
+      status = 1;
+    }
+    if (VERBOSE) {
+      fprintf (stdout, "%s %s\n", argv[i], word);
+    } else {
+      fprintf (stdout, "%s\n", word);
+    }
+  }
+  exit (status);
+}
+
+void usage () {
+  fprintf (stderr, "gconfig: print elixir config information\n");
+  fprintf (stderr, " USAGE: gconfig [keywords...] [-c file] [-C config] [-D keyword value]\n");
+  exit (2);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/get_argument.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/get_argument.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/get_argument.c	(revision 21897)
@@ -0,0 +1,18 @@
+# include <stdio.h>
+
+int
+get_argument (argc, argv, arg)
+int argc;
+char *argv[];
+char arg[];
+{
+
+  int i;
+
+  for (i = 0; i < argc; i++) {
+    if (!strcmp(argv[i], arg))
+      return (i);
+  }
+  
+  return ((int)NULL);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/glockfile.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/glockfile.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/glockfile.c	(revision 21897)
@@ -0,0 +1,41 @@
+# include <ohana.h>
+
+int main (int argc, char **argv) {
+
+  char *filename;
+  double timeout;
+  int holdtime, state, type;
+  FILE *f;
+
+  if (argc != 4) {
+    fprintf (stderr, "USAGE: glock (filename) (type) (holdtime)\n");
+    exit (1);
+  }
+
+  filename = argv[1];
+  timeout = 30.0;
+
+  holdtime = atoi (argv[3]);
+
+  type = 0;
+  if (!strcasecmp (argv[2], "hard")) {
+    type = LCK_HARD;
+  }
+  if (!strcasecmp (argv[2], "soft")) {
+    type = LCK_SOFT;
+  }
+  if (!strcasecmp (argv[2], "xcld")) {
+    type = LCK_XCLD;
+  }
+
+  f = fsetlockfile (filename, timeout, type, &state);
+  if (f == NULL) {
+    fprintf (stderr, "ERROR: can't lock file %s\n", filename);
+    exit (1);
+  }
+
+  fprintf (stderr, "file is locked\n");
+  sleep (holdtime);
+  fclearlockfile (filename, f, type, &state);
+  exit (0);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/gtfringetable.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/gtfringetable.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/gtfringetable.c	(revision 21897)
@@ -0,0 +1,79 @@
+# include <ohana.h>
+# include <gfitsio.h>
+
+static char *version = "gtfringetable $Revision: 1.5 $";
+
+void get_version (int argc, char **argv, char *version);
+
+int main (int argc, char **argv) {
+
+  int i;
+  double binning;
+  float *xmin, *xmax, *ymin, *ymax;
+  FILE *f;
+  FTable table;
+  Header header;
+
+  get_version (argc, argv, version);
+  if (argc != 4) {
+    fprintf (stderr, "USAGE: (table) (ccd) (binning)\n");
+    exit (2);
+  }
+
+  binning = atof (argv[3]);
+
+  /* load data from fringe points file */
+  f = fopen (argv[1], "r");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "error opening fringe file %s\n", argv[1]);
+    exit (1);
+  }
+  table.header = &header;
+  if (!gfits_fread_ftable (f, &table, argv[2])) {
+    fprintf (stderr, "error reading table %s\n", argv[2]);
+    exit (1);
+  }
+  fclose (f);
+
+  gfits_get_table_column (&header, &table, "X_MIN", (void **) &xmin);
+  gfits_get_table_column (&header, &table, "X_MAX", (void **) &xmax);
+  gfits_get_table_column (&header, &table, "Y_MIN", (void **) &ymin);
+  gfits_get_table_column (&header, &table, "Y_MAX", (void **) &ymax);
+
+  for (i = 0; i < header.Naxis[1]; i++) {
+    fprintf (stdout, "%f %f\n", xmin[i] / binning, ymin[i] / binning);
+    fprintf (stdout, "%f %f\n", xmax[i] / binning, ymax[i] / binning);
+  }
+  exit (0);
+}
+
+/**** support functions ******/
+void get_version (int argc, char **argv, char *version) {
+
+  int N;
+  char *p, *q, *line;
+
+  if (get_argument (argc, argv, "-version")) {
+
+    N = strlen (version) + 2;
+    line = (char *) malloc (N);
+    bzero (line, N);
+
+    p = strstr (version, "$Revision: ");
+    if (p != (char *) NULL) 
+      p += strlen ("$Revision: ");
+    else
+      p = version;
+
+    q = strstr (p, "$");
+    if (q != (char *) NULL) 
+      N = q - p; 
+    else
+      N = strlen (p);
+
+    strncpy (line, p, N);
+
+    fprintf (stderr, "%s\n", line);
+    exit (2);
+  }
+}  
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/gunlock.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/gunlock.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/gunlock.c	(revision 21897)
@@ -0,0 +1,18 @@
+# include <stdio.h>
+
+main (int argc, char **argv) {
+
+  if (argc != 2) {
+    fprintf (stderr, "USAGE: gunlock (filename)\n");
+    exit (1);
+  }
+
+  if (!clearlockfile (argv[1], -1, 1)) {
+    fprintf (stdout, "LOCK NOT REMOVED\n");
+    exit (1);
+  }
+  
+  fprintf (stdout, "LOCK REMOVED\n");
+  exit (0);
+
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/list_astro.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/list_astro.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/list_astro.c	(revision 21897)
@@ -0,0 +1,117 @@
+# include <ohana.h>
+
+int main (int argc, char **argv) {
+
+  float *ra1, *ra2, *dec1, *dec2;
+  float x, y, x2, y2, xy, R, D, Rx, Ry, Dx, Dy, N;
+  float x3, x2y, x4, Rx2;
+  float DEC, RA, DX, DY, RX, RY, d2RA, d2DEC, dRA, dDEC;
+  float Sx2, Sy2, Sxy, Srx, Sry, Sdx, Sdy;
+  int i, Npairs, NPAIR;
+
+  NPAIR = 100;
+  ALLOCATE (ra1, float, NPAIR);
+  ALLOCATE (ra2, float, NPAIR);
+  ALLOCATE (dec1, float, NPAIR);
+  ALLOCATE (dec2, float, NPAIR);
+
+/*
+  ALLOCATE (a, double *, 3);
+  ALLOCATE (a[0], double, 3);
+  ALLOCATE (a[1], double, 3);
+  ALLOCATE (a[2], double, 3);
+  ALLOCATE (a[3], double, 4);
+  ALLOCATE (b, double *, 3);
+  ALLOCATE (b[0], double, 1);
+  ALLOCATE (b[1], double, 1);
+  ALLOCATE (b[2], double, 1);
+  ALLOCATE (b[3], double, 1);
+*/
+
+  if (argc > 1) {
+    fprintf (stderr, "USAGE: list_astro x\nTakes list from the stdin in the");
+    fprintf (stderr, " format:\n  X Y RA DEC\nReturns:\n  RA, RX, RY, dRA\n  DEC, DX, DY, dDEC\n");
+    exit(0);
+  }
+    
+  for (i = 0; fscanf (stdin, "%f %f %f %f", &ra1[i], &dec1[i], &ra2[i], &dec2[i]) != EOF; i++) {
+    if (i == NPAIR - 1) {
+      NPAIR += 50;
+      REALLOCATE (ra1, float, NPAIR);
+      REALLOCATE (ra2, float, NPAIR);
+      REALLOCATE (dec1, float, NPAIR);
+      REALLOCATE (dec2, float, NPAIR);
+    }
+  }
+
+  
+  
+  N = x = y = x2 = y2 = xy = R = D = Rx = Ry = Dx = Dy = 0;
+  Npairs = i;
+  for (i = 0; i < Npairs; i++) {
+    x  += ra1[i];
+    y  += dec1[i];
+    x2 += ra1[i]*ra1[i];
+    y2 += dec1[i]*dec1[i];
+    xy += ra1[i]*dec1[i];
+    x3 += ra1[i]*ra1[i]*ra1[i];
+    x2y += ra1[i]*ra1[i]*dec1[i];
+    x4 += ra1[i]*ra1[i]*ra1[i]*ra1[i];
+    R  += ra2[i];
+    D  += dec2[i];
+    Rx += ra2[i]*ra1[i];
+    Ry += ra2[i]*dec1[i];
+    Rx2 += ra2[i]*ra1[i]*ra1[i];
+    Dx += dec2[i]*ra1[i];
+    Dy += dec2[i]*dec1[i];
+    N  += 1.0;
+  }
+
+/*
+  a[0][0] = N;
+  a[0][1] = a[1][0] = x;
+  a[0][2] = a[2][0] = y;
+  a[0][3] = a[3][0] = x2;
+  a[1][1] = x2;
+  a[1][2] = a[2][1] = xy;
+  a[1][3] = a[3][1] = x3;
+  a[2][2] = y2;
+  a[2][3] = a[3][2] = x2y;
+  a[3][3] = x4;
+  b[0][0] = R;
+  b[1][0] = Rx;
+  b[2][0] = Ry;
+  b[1][0] = Rx2;
+*/
+
+  Sx2 = x2 - x*x/N;
+  Sy2 = y2 - y*y/N;
+  Sxy = xy - x*y/N;
+  Srx = Rx - R*x/N;
+  Sry = Ry - R*y/N;
+  Sdx = Dx - D*x/N;
+  Sdy = Dy - D*y/N;
+  
+  RX = (Srx*Sy2 - Sry*Sxy) / (Sx2*Sy2 - Sxy*Sxy);
+  RY = (Sry*Sx2 - Srx*Sxy) / (Sx2*Sy2 - Sxy*Sxy);
+  RA = R/N - RX*x/N - RY*y/N;
+
+  DX  = (Sdx*Sy2 - Sdy*Sxy) / (Sx2*Sy2 - Sxy*Sxy);
+  DY  = (Sdy*Sx2 - Sdx*Sxy) / (Sx2*Sy2 - Sxy*Sxy);
+  DEC = D/N - DX*x/N - DY*y/N;
+
+  d2RA = d2DEC = N = 0;
+  N = x = y = x2 = y2 = xy = R = D = Rx = Ry = Dx = Dy = 0;
+  for (i = 0; i < Npairs; i++) {
+    d2RA += pow((ra2[i] - RA - RX*ra1[i] - RY*dec1[i]), 2.0);
+    d2DEC += pow((dec2[i] - DEC - DX*ra1[i] - DY*dec1[i]), 2.0);
+    N += 1.0;
+  }
+
+  dRA  = 3600.0*sqrt(d2RA / (N - 3.0));
+  dDEC = 3600.0*sqrt(d2DEC / (N - 3.0));
+
+  fprintf (stdout, " %12.9f %12.9e %12.9e %12.9f\n", RA, RX, RY, dRA);
+  fprintf (stdout, " %12.9f %12.9e %12.9e %12.9f\n", DEC, DX, DY, dDEC);
+  exit (0);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/magtoage.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/magtoage.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/magtoage.c	(revision 21897)
@@ -0,0 +1,221 @@
+# include <ohana.h>
+# define MMIN 1.0
+# define MMAX 120.0
+extern double drand48();
+extern double rnd_gauss();
+extern double rnd_integrate ();
+extern double gaussian ();
+
+double gaussian();
+double rnd_gauss();
+double rnd_integrate();
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+
+  Header mass_h, age_h;
+  Matrix mass_i, age_i;
+  double UV0, V0, DV, DUV;
+  double Uo, Vo;
+  double U, V, dUV, dU, dV, mass, age, d, a, da;
+  double M, dM, Ms, M2, m, dm, ldM, lMo, ldA, lAo;
+  double u, v, uv, Av, f, top, bot, alpha;
+  double **Masses, *maxmass, *minmass;
+  double **Ages;
+  int x, y, i, j, Ntry, NAGE, N;
+  char line[1024];
+  long A, B;
+  
+  lAo =   0.0;
+  ldA =   1.0;
+  NAGE =  320;
+  if (N = get_argument (argc, argv, "-age")) {
+    remove_argument (N, &argc, argv);
+    lAo = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    ldA = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    NAGE = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 9) {
+    fprintf (stderr, "USAGE: magtoage massfile agefile d Av Ntry Uo Vo alpha ldM\n");
+    exit (0);
+  }
+  d = atof (argv[3]);
+  Av = atof (argv[4]);
+  Ntry = atof (argv[5]);
+  Uo = atof (argv[6]);
+  Vo = atof (argv[7]);
+  alpha = atof (argv[8]);
+  /*
+  ldM   = atof (argv[9]);
+  lMo = 0.0;
+  */
+  
+  gfits_read_header (argv[1], &mass_h);
+  gfits_read_matrix (argv[1], &mass_i);
+  gfits_read_header (argv[2], &age_h);
+  gfits_read_matrix (argv[2], &age_i); 
+
+  gfits_scan (&mass_h, "RA_O",  "%lf", 1, &UV0);
+  gfits_scan (&mass_h, "RA_X",  "%lf", 1, &DUV);
+  gfits_scan (&mass_h, "DEC_O", "%lf", 1, &V0);
+  gfits_scan (&mass_h, "DEC_Y", "%lf", 1, &DV);
+
+  ALLOCATE (Ages, double *, (Ntry+2));
+  ALLOCATE (maxmass, double, NAGE);
+  ALLOCATE (minmass, double, NAGE);
+  for (i = 0; i < Ntry + 2; i++) {
+    ALLOCATE (Ages[i], double, NAGE);
+    bzero (Ages[i], sizeof(double) * NAGE);
+  }
+
+  A = time(NULL);
+  for (B = 0; A == time(NULL); B++);
+  srand48(B);
+
+  /* find max and min masses for each age bin */
+  for (i = 0; i < NAGE; i++) {
+    maxmass[i] = 0.0;
+    minmass[i] = 1000.0;
+  }
+  for (x = 0; x < age_h.Naxis[0]; x++) {
+    for (y = 0; y < age_h.Naxis[1]; y++) {
+      mass = gfits_get_matrix_value (&mass_i, x, y);
+      if (mass == 0.0) continue;
+      age  = gfits_get_matrix_value (&age_i, x, y);
+      uv = x*DUV + UV0 + 0.7*Av;
+      v  = y*DV + V0 + Av + d;
+      u  = v + uv;
+      if ((u <= Uo) && (v <= Vo)) {
+	i = (age - lAo) / ldA;
+	if ((i > 0) && (i < NAGE)) {
+	  maxmass[i] = MAX(mass, maxmass[i]);
+	  minmass[i] = MIN(mass, minmass[i]);
+	}
+      }
+    }
+  }
+
+  fprintf (stderr, "beginning main loop\n");
+  while (scan_line (stdin, line) != EOF) {
+    if (!stripwhite (line)) continue;
+    if (line[0] == '#') continue;
+    dparse (&V, 8, line);
+    dparse (&dV, 9, line);
+    dparse (&U, 12, line);
+    dparse (&dU, 13, line);
+    dUV = sqrt (dU*dU + dV*dV);
+    for (i = 0; i < Ntry + 1; i++) {
+      if (i == 0) {
+	fprintf (stderr, ".");
+	v = V;
+	uv = U - V;
+      }
+      else {
+	v = rnd_gauss (V, dV);
+	uv = rnd_gauss ((U-V), dUV);
+      }
+      x = (uv - UV0 - 0.7*Av) / DUV;
+      y = (v - d - V0 - Av) / DV;
+      if ((x > 0) && (x < mass_h.Naxis[0]) &&
+	  (y > 0) && (y < mass_h.Naxis[1])) {
+	mass = gfits_get_matrix_value (&mass_i, x, y);
+	if (mass > 0.0) {
+	  age = gfits_get_matrix_value (&age_i, x, y); 
+	  j = (age - lAo) / ldA;
+	  if ((j >= 0) && (j < NAGE))
+	    Ages[i][j] += pow(mass, alpha);
+	}
+      }
+    }
+  }
+
+  top = pow (MMAX, 1.0 - alpha) - pow (MMIN, 1.0 - alpha);
+  fprintf (stderr, "finding scatter per bin\n");
+  for (j = 0; j < NAGE; j++) {
+    Ms = M2 = 0.0;
+    for (i = 1; i < Ntry + 1; i++) {
+      Ms += Ages[i][j];
+      M2 += (Ages[i][j]*Ages[i][j]);
+    }
+    M = dM = 0.0;
+    if (Ms > 0) {
+      M  = Ms / (1.0*Ntry);
+      dM = sqrt (M2 / (1.0*Ntry) - M*M);
+    }
+    Ages[1][j] = M;
+    Ages[2][j] = dM;
+    /*
+    a = pow (10.0, j*ldA + lAo);
+    da = pow (10.0, (j+1)*ldA + lAo) - a;
+    */
+    a = j*ldA + lAo;
+    da = ldA;
+    f = 0.0;
+    if (maxmass[j] > minmass[j]) {
+      bot = pow (maxmass[j], 1.0 - alpha) - pow (minmass[j], 1.0 - alpha);
+      if (bot != 0.0) 
+	f = top * top / ((1.0 - alpha) * bot * 2.30158509);
+    }
+    fprintf (stdout, "%d %f %f %f %f %f %f %f\n", j, a, da, Ages[0][j], Ages[1][j], Ages[2][j], f, Ages[1][j]*f/da);
+  }
+}
+
+double
+rnd_gauss (mean, sigma)
+double mean, sigma; 
+{
+
+  double range, x;
+
+  range = drand48();
+  x = rnd_integrate (*gaussian, range, mean, sigma);
+
+  return (x);
+
+}
+
+
+double 
+rnd_integrate (function, range, mean, sigma) 
+double (*function) ();
+double range, mean, sigma;
+{
+
+  double val, x, dx, dx1, dx2, dx3, df;
+
+  range += 0.0001;
+  val = 0;
+  dx = sigma / 10.0;
+  dx1 = dx / 3.0;
+  dx2 = 2.0*dx/3.0;
+  dx3 = dx;
+
+  for (x = mean - 7*sigma; (val < range) && (x < mean + 7*sigma); x += dx)  {
+    df = (3.0*function(x    , mean, sigma) + 
+	  9.0*function(x+dx1, mean, sigma) +
+	  9.0*function(x+dx2, mean, sigma) + 
+	  3.0*function(x+dx3, mean, sigma)) * (dx1/8.0);
+    val += df;
+  }
+  return (x + dx / 2.0);
+}
+
+double 
+gaussian (x, mean, sigma) 
+double x, mean, sigma; 
+{
+
+  double f, X;
+
+  f = exp (-0.5 * SQ(x - mean) / SQ(sigma)) / sqrt(2 * M_PI * SQ(sigma));
+
+  return (f);
+
+}
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/magtomass.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/magtomass.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/magtomass.c	(revision 21897)
@@ -0,0 +1,292 @@
+# include <ohana.h>
+extern double drand48();
+extern double rnd_gauss();
+extern double rnd_integrate ();
+extern double gaussian ();
+# define NEWWAY 1
+
+double gaussian();
+double rnd_gauss();
+double rnd_integrate();
+
+# define NGAUSS 2048
+double gaussint[NGAUSS];
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+
+  Header mass_h, age_h;
+  Matrix mass_i, age_i;
+  double UV0, V0, DV, DUV, ra, dec;
+  double U, V, dUV, dU, dV, mass, age, d;
+  double M, dM, Ms, M2, m, ldM, lMo, lAo, ldA, dlogM;
+  double v, uv, Av, eta, deta, Ngood;
+  double ***Masses, *maxmass, *minmass;
+  float *Mbuffer, *Abuffer;
+  int x, y, i, j, I, J, Ntry, dump, NMASS, N, NAGE, k, try;
+  int NX, NY;
+  char line[1024];
+  int col1, col2;
+  
+  dump = FALSE;
+  if (N = get_argument (argc, argv, "-dump")) {
+    remove_argument (N, &argc, argv);
+    dump = TRUE;
+  }
+
+  col1 = 8;
+  if (N = get_argument (argc, argv, "-col1")) {
+    remove_argument (N, &argc, argv);
+    col1 = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  col2 = 12;
+  if (N = get_argument (argc, argv, "-col2")) {
+    remove_argument (N, &argc, argv);
+    col2 = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  fprintf (stderr, "using mags in columns %d & %d\n", col1, col2);
+
+  gauss_init ();
+
+  lAo = 0.1;
+  ldA =  0.3;
+  NAGE = 10;
+  lMo = 0.0;
+  ldM =  0.05;
+  if (NEWWAY)
+    NMASS = 87;
+  else 
+    NMASS = 50;
+  if (N = get_argument (argc, argv, "-mass")) {
+    if (dump) {
+      fprintf (stderr, "-mass and -dump incompatible\n");
+      exit (0);
+    }
+    remove_argument (N, &argc, argv);
+    lMo = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    ldM = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    NMASS = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 6) {
+    fprintf (stderr, "USAGE: magtomass massfile agefile d Av Ntry\n");
+    exit (0);
+  }
+  d = atof (argv[3]);
+  Av = atof (argv[4]);
+  Ntry = atof (argv[5]);
+
+  gfits_read_header (argv[1], &mass_h);
+  gfits_read_matrix (argv[1], &mass_i);
+  gfits_read_header (argv[2], &age_h);
+  gfits_read_matrix (argv[2], &age_i); 
+
+  gfits_scan (&mass_h, "RA_O",  "%lf", 1, &UV0);
+  gfits_scan (&mass_h, "RA_X",  "%lf", 1, &DUV);
+  gfits_scan (&mass_h, "DEC_O", "%lf", 1, &V0);
+  gfits_scan (&mass_h, "DEC_Y", "%lf", 1, &DV);
+  Mbuffer = (float *)mass_i.buffer;
+  Abuffer = (float *)age_i.buffer;
+  NX = mass_h.Naxis[0];
+  NY = mass_h.Naxis[1];
+  
+  ALLOCATE (Masses, double **, NAGE);
+  for (i = 0; i < NAGE; i++) {
+    ALLOCATE (Masses[i], double *, NMASS);
+    for (j = 0; j < NMASS; j++) {
+      ALLOCATE (Masses[i][j], double, 3);
+      Masses[i][j][0] = 0.0;
+	Masses[i][j][1] = 0.0;
+    }
+  }
+
+  fprintf (stderr, "beginning main loop\n");
+  while (scan_line (stdin, line) != EOF) {
+    if (!stripwhite (line)) continue;
+    if (line[0] == '#') continue;
+    /* appropriate columns hardwired */
+    dparse (&ra, 1, line);
+    dparse (&dec, 2, line);
+    dparse (&V, col1, line);
+    dparse (&dV, (col1+1), line);
+    dparse (&U, col2, line);
+    dparse (&dU, (col2+1), line);
+    dUV = sqrt (dU*dU + dV*dV);
+    x = (U-V - UV0 - 0.7*Av) / DUV;
+    y = (V - d - V0 - Av) / DV;
+    if ((x > 0) && (x < mass_h.Naxis[0]) && (y > 0) && (y < mass_h.Naxis[1])) {
+      mass = Mbuffer[x + NX*y];
+      /*      mass = gfits_get_matrix_value (&mass_i, x, y); */
+      if (mass > 0.0) {
+	age = Abuffer[x + NX*y];
+	fprintf (stdout, "%f %f %f %f %f %f\n", ra, dec, V, U-V, mass, age);
+      }
+    }
+  }
+}
+
+
+
+/*
+
+	**	age = gfits_get_matrix_value (&age_i, x, y);  **
+	I = MAX (MIN ((log10(age) - lAo) / ldA, NAGE - 1), 0); 
+	if (NEWWAY) {
+	  J = MAX (MIN ((4.5 - sqrt(10.0/mass)) / ldM, NMASS - 1), 0);
+	} else {
+	  J = MAX (MIN ((log10(mass) - lMo) / ldM, NMASS - 1), 0); 
+	}
+	Ngood = 1.0;
+	for (k = 0; k < Ntry; k++) {
+	  v = rnd_gauss (V, dV);
+	  uv = rnd_gauss ((U-V), dUV);
+	  x = (uv - UV0 - 0.7*Av) / DUV;
+	  y = (v - d - V0 - Av) / DV;
+	  if ((x > 0) && (x < mass_h.Naxis[0]) && (y > 0) && (y < mass_h.Naxis[1])) {
+	    mass = Mbuffer[x + NX*y];
+	    **	    mass = gfits_get_matrix_value (&mass_i, x, y); **
+	    if (mass > 0.0) {
+	      age = Abuffer[x + NX*y];
+	      ** age = gfits_get_matrix_value (&age_i, x, y);  **
+	      i = MAX (MIN ((log10(age) - lAo) / ldA, NAGE - 1), 0);
+	      if (NEWWAY) {
+		j = MAX (MIN ((4.5 - sqrt(10.0/mass)) / ldM, NMASS - 1), 0);
+	      } else {
+		j = MAX (MIN ((log10(mass) - lMo) / ldM, NMASS - 1), 0); 
+	      }
+	      if ((i == I) && (j == J)) {
+		Ngood += 1.0;
+	      }
+	    }
+	  }
+	}
+	Masses[I][J][0] += (Ntry / Ngood);
+	Masses[I][J][1] += 1.0;
+      }
+    }
+  }
+
+  fprintf (stderr, "finding scatter per bin\n");
+  fprintf (stdout, "# measured IMF \n");
+  fprintf (stdout, "# distance modulus = %5.2, extinction (A_V) = %5.2f\n", d, Av);
+  fprintf (stdout, "# reference mass and age filess: %s, %s\n", argv[1], argv[2]);
+  fprintf (stdout, "# eta = N(logM, logM+dlogM) / dlogM \\sim ln(10.0) * M dN/dM)\n");
+  fprintf (stdout, "# i  Mass   N(mass)  eta   d_eta\n");
+  for (i = 0; i < NAGE; i++) {
+    for (j = 0; j < NMASS; j++) {
+      if (NEWWAY) {
+	mass = 10.0 / SQ(4.5 - ldM*(j+0.5));
+	dlogM = 2.0 * (log10(4.5 - ldM*j) - log10(4.5 - ldM*(j+1)));
+      } else {
+	mass = pow (10.0, (lMo + ldM*(j+0.5)));
+	dlogM = ldM;
+      }
+      eta  = Masses[i][j][0] / dlogM;
+      deta = (Masses[i][j][1] > 0) ? eta / sqrt(Masses[i][j][1]) : 0.0;
+      age  = pow (10.0, (ldA*i + lAo));
+      M = (Masses[i][j][1] > 0) ? Masses[i][j][0]/Masses[i][j][1] : 0;  ** average correction factor **
+      dM = (Masses[i][j][1] > 0) ? Masses[i][j][0]/sqrt(Masses[i][j][1]) : 0;  ** average correction factor **
+      fprintf (stdout, "%4d %4d %5.1f %5.1f %7.1f %7.1f %6.2f %4.0f\n", i, j, mass, age, eta, deta, M, Masses[i][j][1]);
+    }
+  }
+}
+
+*/
+
+double
+rnd_gauss (mean, sigma)
+double mean, sigma; 
+{
+
+  int i;
+  double y;
+
+  y = drand48();
+  i = NGAUSS*y;
+  y = gaussint[i]*sigma + mean;
+
+  return (y);
+
+}
+
+
+gauss_init ()
+{
+
+  int i;
+  long A, B;
+  double val, x, dx, dx1, dx2, dx3, df;
+  double mean, sigma;
+
+  A = time(NULL);
+  for (B = 0; A == time(NULL); B++);
+  srand48(B);
+
+  val = 0;
+  dx = 0.001;
+  dx1 = dx / 3.0;
+  dx2 = 2.0*dx/3.0;
+  dx3 = dx;
+  mean = 0.0;
+  sigma = 1.0;
+
+  for (i = 0, x = -7.0; (i < NGAUSS) && (x < 7.0); x += dx)  {
+    df = (3.0*gaussian(x    , mean, sigma) + 
+	  9.0*gaussian(x+dx1, mean, sigma) +
+	  9.0*gaussian(x+dx2, mean, sigma) + 
+	  3.0*gaussian(x+dx3, mean, sigma)) * (dx1/8.0);
+    val += df;
+    if (val > (i / (double) NGAUSS)) {
+      gaussint[i] = x + dx / 2.0;
+      i++;
+    }
+  }
+  return (x + dx / 2.0);
+}
+
+double 
+rnd_integrate (function, range, mean, sigma) 
+double (*function) ();
+double range, mean, sigma;
+{
+
+  double val, x, dx, dx1, dx2, dx3, df;
+
+  range += 0.0001;
+  val = 0;
+  dx = sigma / 100.0;
+  dx1 = dx / 3.0;
+  dx2 = 2.0*dx/3.0;
+  dx3 = dx;
+
+  for (x = mean - 7*sigma; (val < range) && (x < mean + 7*sigma); x += dx)  {
+    df = (3.0*function(x    , mean, sigma) + 
+	  9.0*function(x+dx1, mean, sigma) +
+	  9.0*function(x+dx2, mean, sigma) + 
+	  3.0*function(x+dx3, mean, sigma)) * (dx1/8.0);
+    val += df;
+  }
+  return (x + dx / 2.0);
+}
+
+double 
+gaussian (x, mean, sigma) 
+double x, mean, sigma; 
+{
+
+  double f, X;
+
+  f = exp (-0.5 * SQ(x - mean) / SQ(sigma)) / sqrt(2 * M_PI * SQ(sigma));
+
+  return (f);
+
+}
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/medianfilter.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/medianfilter.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/medianfilter.c	(revision 21897)
@@ -0,0 +1,148 @@
+# include <ohana.h>
+# include <gfitsio.h>
+
+# define D_NFILES 100
+
+void fsort (float *value, int N);
+
+int main (int argc, char **argv) {
+
+  int i, j, k, n, Npixels, Npixin, Npixrd, Npixlast, N;
+  int Npass, NFILES, Nfiles;
+
+  char **filename;
+  Header head, *tmphead;
+  Matrix out,  *tmpmatr;
+  float *list, *v, *O;
+  float fmin, fmax, Nval, sum;
+
+  FT_UNSIGN_MODE = FALSE;
+  if ((N = get_argument (argc, argv, "-unsign"))) {
+    remove_argument (N, &argc, argv);
+    FT_UNSIGN_MODE = TRUE;
+  }
+
+  if (argc < 4) {
+    fprintf (stderr, "USAGE: minmaxfilter outfile fmin fmax\n");
+    exit (0);
+  }
+  fmin = atof (argv[2]); 
+  fmax = atof (argv[3]); 
+
+  /* read in the filenames */
+  NFILES = D_NFILES;
+  ALLOCATE (filename, char *, NFILES);
+  ALLOCATE (filename[0], char, 1024);
+  for (i = 0; fscanf (stdin, "%s", filename[i]) != EOF; i++) {
+    if (i == NFILES - 1) {
+      NFILES += D_NFILES;
+      REALLOCATE (filename, char *, NFILES);
+    }
+    ALLOCATE (filename[i+1], char, 1024);
+  }
+  Nfiles = i;
+  REALLOCATE (filename, char *, Nfiles);
+
+  /* load a header, setup output header, matrix */
+  gfits_read_header (filename[0], &head);
+  gfits_create_matrix (&head, &out);
+  gfits_convert_format (&head, &out, -32, 1.0, 0.0, FALSE);
+
+  /* find size of temporary images */
+  Npixels = head.Naxis[0]*head.Naxis[1];
+  Npixin = Npixels / Nfiles;
+  Npixlast = Npixels - Npixin*Nfiles;
+  if (Npixlast == 0) {
+    Npass = Nfiles;
+    Npixlast = Npixin;
+    fprintf (stderr, "operating on %d pixels per pass\n", Npixin);
+  } else {
+    Npass = Nfiles + 1;
+    fprintf (stderr, "operating on %d pixels per pass, %d in last\n", Npixin, Npixlast);
+  }
+  
+  ALLOCATE (tmphead, Header, Nfiles);
+  ALLOCATE (tmpmatr, Matrix, Nfiles);
+  ALLOCATE (list, float, Nfiles);
+  Nval = 0;
+  for (k = fmin*Nfiles; k < fmax*Nfiles; k++) {
+    Nval += 1.0;
+  }
+
+  O = (float *) out.buffer;
+  for (n = 0; n < Npass; n++) {
+    fprintf (stderr, "pass %d\n", n);
+    Npixrd = (n == Npass - 1) ? Npixlast : Npixin;
+    for (i = 0; i < Nfiles; i++) {
+      fprintf (stderr, ".");
+      if (!gfits_read_header  (filename[i], &tmphead[i])) {
+	fprintf (stderr, "trouble reading file %s\n", filename[i]);
+	exit (1);
+      }
+      gfits_read_portion (filename[i], &tmpmatr[i], n*Npixin, Npixrd);
+      tmphead[i].Naxis[0] = 1;
+      tmphead[i].Naxis[1] = Npixrd;
+      gfits_convert_format (&tmphead[i], &tmpmatr[i], -32, 1.0, 0.0, FALSE);
+    }
+    
+    fprintf (stderr, "starting sorts\n");
+    for (j = 0; j < Npixrd; j++, O++) {
+      for (k = 0; k < Nfiles; k++) {
+	v = (float *)tmpmatr[k].buffer;
+	list[k] = v[j];
+      }
+      fsort (list, Nfiles);
+      sum = 0;
+      for (k = fmin*Nfiles; k < fmax*Nfiles; k++) {
+	sum += list[k];
+      }
+      *O = (sum / Nval);
+    }
+
+    for (i = 0; i < Nfiles; i++) {
+      fprintf (stderr, ",");
+      gfits_free_header (&tmphead[i]);
+      gfits_free_matrix (&tmpmatr[i]);
+    }
+    
+  }
+
+  gfits_write_header (argv[1], &head);
+  gfits_write_matrix (argv[1], &out);
+
+  return (0);
+
+}
+
+void fsort (float *value, int N) {
+
+  int l,j,ir,i;
+  float temp;
+  
+  l = N >> 1;
+  ir = N - 1;
+  for (;;) {
+    if (l > 0) {
+      temp = value[--l];
+    }
+    else {
+      temp = value[ir];
+      value[ir] = value[0];
+      if (--ir == 0) {
+	value[0] = temp;
+	return;
+      }
+    }
+    i = l;
+    j = (l << 1) + 1;
+    while (j <= ir) {
+      if (j < ir && value[j] < value[j+1]) ++j;
+      if (temp < value[j]) {
+	value[i]=value[j];
+	j += (i=j) + 1;
+      }
+      else j = ir + 1;
+    }
+    value[i] = temp;
+  }
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mefhead.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mefhead.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mefhead.c	(revision 21897)
@@ -0,0 +1,98 @@
+# include <ohana.h>
+# include <gfitsio.h>
+
+int main (int argc, char **argv) {
+
+  struct stat filestat;
+  int NEXTEND, Nextend, Nmatrix, status;
+  Header header;
+  FILE *f, *g;
+
+  if (argc != 3) {
+    fprintf (stderr, "USAGE: mefhead (input) (output)\n");
+    exit (2);
+  }
+
+  /* exit if file exists */
+  status = stat (argv[2], &filestat);
+  if (status != -1) {
+    fprintf (stderr, "error: output file exists\n");
+    exit (1);
+  } 
+  
+  /* open stream for input */
+  g = fopen (argv[1], "r");
+  if (g == (FILE *) NULL) {
+    fprintf (stderr, "error: can't open input file\n");
+    exit (1);
+  } 
+
+  /* open stream for output */
+  f = fopen (argv[2], "w");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "error: can't create output file\n");
+    exit (1);
+  } 
+
+  /* read PHU */
+  status = gfits_fread_header (g, &header);
+  if (!status) {
+    fprintf (stderr, "error: can't read primary header unit\n");
+    exit (1);
+  }
+  /* skip matrix */
+  Nmatrix = gfits_matrix_size (&header);
+  fseek (g, Nmatrix, SEEK_CUR);
+
+  /* write PHU */
+  gfits_modify (&header, "NAXIS", "%d", 1, 0);
+  status = gfits_fwrite_header (f, &header);
+  if (!status) {
+    fprintf (stderr, "error: can't write primary header unit\n");
+    exit (1);
+  }
+
+  /* check if NEXTEND is accurate */
+  gfits_scan (&header, "NEXTEND", "%d", 1, &NEXTEND);
+
+  Nextend = 0;
+  while (1) {
+    
+    /* read header */
+    status = gfits_fread_header (g, &header);
+    if (!status) break;
+
+    /* skip matrix */
+    Nmatrix = gfits_matrix_size (&header);
+    fseek (g, Nmatrix, SEEK_CUR);
+    
+    /* write header */
+    gfits_modify (&header, "NAXIS", "%d", 1, 0);
+    status = gfits_fwrite_header (f, &header);
+    if (!status) {
+      fprintf (stderr, "error: can't write header unit %d\n", Nextend);
+      exit (1);
+    }
+    Nextend ++;
+    gfits_free_header (&header);
+  }
+
+  if (Nextend != NEXTEND) { 
+    fprintf (stderr, "warning: mismatch in NEXTEND\n");
+  }
+
+  fclose (f);
+  fclose (g);
+  exit (0);
+
+}
+
+
+
+/* mefhead (input) (output) 
+   convert (input) MEF image file to (output) MEF header file:
+   read all headers
+   convert all lines NAXIS=2 to NAXIS=0 
+   write only headers
+
+*/
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/misc.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/misc.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/misc.c	(revision 21897)
@@ -0,0 +1,471 @@
+# include <ohana.h>
+
+static double tz = 0.0;
+void set_timezone (double dt) {
+  tz = dt;
+}
+
+/***** convert [-]00:00:00 to 0.0000 ****/
+int dms_to_ddd (double *Value, char *string) {
+  
+  int valid, neg, status;
+  double tmp, value;
+  char *p1, *p2, *px;
+
+  valid = FALSE; 
+  neg = FALSE;
+  stripwhite (string);
+  p1 = string;
+  px = string + strlen(string);
+
+  if (string[0] == '-') { 
+    valid = TRUE; 
+    neg = TRUE;
+    p1 = &string[1];
+  }
+  if (string[0] == '+') { 
+    valid = TRUE; 
+    neg = FALSE;
+    p1 = &string[1];
+  }
+  if (isdigit(string[0])) { 
+    valid = TRUE;
+    p1 = &string[0];
+  }
+  if (!valid) { return (FALSE); }
+
+  status = 1;
+  tmp = strtod (p1, &p2);
+  if (p2 == p1) return (FALSE); /* entry not a number: +fred */
+  value = tmp;
+  if (p2 == px) goto escape;    /* entry only number: +1.0 */ 
+  p1 = p2 + 1;
+
+  tmp = strtod (p1, &p2);
+  if (p2 == p1) goto escape;    /* entry not a number: +1:fred */
+  status = 2;
+  value += tmp / 60.0;
+  if (p2 == px) goto escape;    /* entry only number: +1:1 */
+  p1 = p2 + 1;
+
+  tmp = strtod (p1, &p2);
+  if (p2 == p1) goto escape;    /* entry not a number: +1:1:fred */
+  value += tmp / 3600.0;
+
+ escape:
+  if (neg) {
+    value *= -1;
+  }
+  *Value = value;
+
+  return (status);
+}
+
+/**********/
+int str_to_radec (double *ra, double *dec, char *str1, char *str2) {
+
+  double Ra, Dec;
+
+  *ra = *dec = 0;
+  switch (dms_to_ddd (&Ra, str1)) {
+  case 0:
+    fprintf (stderr, "syntax error in RA\n");
+    return (FALSE);
+  case 1:
+    break;
+  case 2:
+    Ra = Ra * 15;
+    break;
+  }
+  switch (dms_to_ddd (&Dec, str2)) {
+  case 0:
+    fprintf (stderr, "syntax error in DEC\n");
+    return (FALSE);
+  case 1:
+  case 2:
+    break;
+  }
+  *ra = Ra;
+  *dec = Dec;
+  return (TRUE);
+}
+
+# define FORMAT_DAYS    1
+# define FORMAT_HOURS   2
+# define FORMAT_MINUTES 3
+# define FORMAT_SECONDS 4
+# define FORMAT_JD      5
+# define FORMAT_DATE    6
+
+/**********/
+int chk_time (char *line) {
+
+  char *p1, *p2;
+  double tmp;
+  int mode;
+
+  p1 = line;
+  tmp = strtod (p1, &p2);
+  if (p2 == p1 + strlen (p1) - 1) {
+    if (*p2 == 'd') {
+      mode = FORMAT_DAYS;
+    }
+    if (*p2 == 'h') {
+      mode = FORMAT_HOURS;
+    }
+    if (*p2 == 'm') {
+      mode = FORMAT_MINUTES;
+    }
+    if (*p2 == 's') {
+      mode = FORMAT_SECONDS;
+    }
+    if (*p2 == 'j') {
+      mode = FORMAT_JD;
+    }
+  } else { 
+    mode = FORMAT_DATE;
+  }
+  return (mode);
+}
+
+/**********/
+int str_to_time (char *line, unsigned long *second) {
+  
+  struct timeval now;
+  double jd;
+
+  if (!strcasecmp (line, "NOW")) {
+    gettimeofday (&now, (struct timezone *) NULL);
+    *second = now.tv_sec;
+    return (TRUE);
+  }
+    
+  if (!strcasecmp (line, "TODAY")) {
+    gettimeofday (&now, (struct timezone *) NULL);
+    *second = 86400 * ((int)(now.tv_sec / 86400));
+    return (TRUE);
+  }
+    
+  switch (chk_time (line)) {
+  case 0:
+    return (FALSE);
+  case FORMAT_DAYS:
+    *second = strtod (line, 0) * 86400.0;
+    return (TRUE);
+  case FORMAT_HOURS:
+    *second = strtod (line, 0) * 3600.0;
+    return (TRUE);
+  case FORMAT_MINUTES:
+    *second = strtod (line, 0) * 60.0;
+    return (TRUE);
+  case FORMAT_SECONDS:
+    *second = strtod (line, 0);
+    return (TRUE);
+  case FORMAT_JD:
+    jd = strtod (line, 0);
+    *second = jd_to_sec (jd);
+    return (TRUE);
+  case FORMAT_DATE:
+    *second = date_to_sec (line);
+    return (TRUE);
+  }
+  return (FALSE);
+}
+
+/**********/
+int str_to_dtime (char *line, double *second) {
+  
+  switch (chk_time (line)) {
+  case 0:
+  case FORMAT_JD:
+  case FORMAT_DATE:
+    return (FALSE);
+  case FORMAT_DAYS:
+    *second = strtod (line, 0) * 86400.0;
+    return (TRUE);
+  case FORMAT_HOURS:
+    *second = strtod (line, 0) * 3600.0;
+    return (TRUE);
+  case FORMAT_MINUTES:
+    *second = strtod (line, 0) * 60.0;
+    return (TRUE);
+  case FORMAT_SECONDS:
+    *second = strtod (line, 0);
+    return (TRUE);
+  }
+  return (FALSE);
+}
+
+/**********/
+double sec_to_jd (unsigned long second) {
+
+  double jd;
+  
+  jd = second/86400.0 + 2440587.5;
+  return (jd);
+}
+
+/**********/
+unsigned long int jd_to_sec (double jd) {
+
+  unsigned long int second;
+
+  second = (jd - 2440587.5)*86400;
+  return (second);
+}
+
+/**********/
+char *sec_to_date (unsigned long second) {
+  
+  struct tm *gmt;
+  char *line;
+  
+  ALLOCATE (line, char, 64);
+  second -= 3600*tz;
+  gmt   = gmtime (&second);
+  sprintf (line, "%4d/%02d/%02d,%02d:%02d:%02d", 1900+gmt[0].tm_year, gmt[0].tm_mon+1, gmt[0].tm_mday, gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
+  return (line);
+
+}
+
+/***** date in format yyyy/mm/dd,hh:mm:ss *****/
+unsigned long date_to_sec (char *date) {
+  
+  unsigned long second;
+  double tmp, jd;
+  struct tm now;
+  char *p1, *p2, *px;
+  
+  p1 = date;
+  px = date + strlen(date);
+  bzero (&now, sizeof(now));
+
+  tmp = strtod (p1, &p2);
+  if (p2 == p1) goto escape;
+  now.tm_year = tmp;
+  if (now.tm_year > 1000) now.tm_year -= 1900;
+  if (now.tm_year <   50) now.tm_year += 100;
+  if (p2 == px) goto escape;  
+  p1 = p2 + 1;
+
+  tmp = strtod (p1, &p2);
+  if (p2 == p1) goto escape;
+  now.tm_mon = tmp - 1; /* mon runs from 0 - 11 */
+  if (p2 == px) goto escape;  
+  p1 = p2 + 1;
+
+  tmp = strtod (p1, &p2);
+  if (p2 == p1) goto escape;
+  now.tm_mday = tmp;
+  if (p2 == px) goto escape;  
+  p1 = p2 + 1;
+
+  tmp = strtod (p1, &p2);
+  if (p2 == p1) goto escape;
+  p1 = p2 + 1;
+  now.tm_hour = tmp;
+  if (p2 == px) goto escape;  
+
+  tmp = strtod (p1, &p2);
+  if (p2 == p1) goto escape;
+  now.tm_min = tmp;
+  if (p2 == px) goto escape;  
+  p1 = p2 + 1;
+
+  tmp = strtod (p1, &p2);
+  if (p2 == p1) goto escape;
+  now.tm_sec = tmp;
+  if (p2 == px) goto escape;  
+  p1 = p2 + 1;
+
+ escape:
+  jd = now.tm_mday - 32075 + (int)(1461*(1900 + now.tm_year + 4800 + (int)(((now.tm_mon+1)-14)/12))/4)
+    + (int)(367*((now.tm_mon+1) - 2 - (int)(((now.tm_mon+1) - 14)/12)*12)/12)
+    - (int)(3*(int)((1900 + now.tm_year + 4900 + (int)(((now.tm_mon+1) - 14)/12))/100)/4) - 0.5;
+  
+  second = (jd - 2440587.5)*86400 + 3600.0*now.tm_hour + now.tm_min*60.0 + now.tm_sec;
+
+  second += 3600*tz;
+
+  return (second);
+}
+
+
+/* times may be in forms as:
+   20040200450s (N seconds since 1970.0)
+   2440900.232j (julian date)
+   99/02/23,03:22:18 (date string)
+   (separators may be anything except space, +, -)
+   99:02:15:12:23:30
+   99:02:15:12h23m30s
+   */
+
+
+/* fseek with timeout - 0.5 sec */
+int Fseek (FILE *f, long offset, int whence) {
+
+  int status, k;
+
+  status = fseek (f, offset, whence);
+  if (status == -1) {
+    for (k = 0; (k < 10) && ((status = fseek (f, 0, SEEK_SET)) == -1); k++) usleep (50000);
+    if (status == -1) {
+      return (0);
+    }
+  }
+  return (1);
+}
+
+/* return values:
+   0 - no trange arguments
+   1 - arguments ok
+   2 - arguments bad
+*/
+int get_trange_arguments (int *argc, char **argv, unsigned long **Tstart, unsigned long **Tstop, int *ntimes) {
+
+  int Na, N, Ntimes;
+  double trange;
+  unsigned long tmp, *tstart, *tstop;
+
+  /* allocate space for returned lists */
+  Ntimes = 10;
+  ALLOCATE (tstart, unsigned long, Ntimes);
+  ALLOCATE (tstop,  unsigned long, Ntimes);
+
+  for (N = 0; ; N++) {
+
+    /* find next -trange arg */
+    Na = get_argument (*argc, argv, "-trange");
+    if (Na == 0) {
+      *ntimes = N;
+      *Tstart = tstart;
+      *Tstop  = tstop;
+      return (TRUE);
+    }
+    remove_argument (Na, argc, argv);
+    
+    /* tstart */
+    if (!str_to_time (argv[Na], &tstart[N])) { 
+      return (FALSE);
+    }
+
+    /* interpret second value */
+    remove_argument (Na, argc, argv);
+    if (str_to_dtime (argv[Na], &trange)) { 
+      if (trange < 0) {
+	tstop[N]  = tstart[N];
+	tstart[N] = tstop[N] + trange;
+      } else {
+	tstop[N]  = tstart[N] + trange;
+      }
+      remove_argument (Na, argc, argv);
+      goto goodvalue;
+    }
+    if (str_to_time (argv[Na], &tstop[N])) { 
+      if (tstart[N] > tstop[N]) {
+	tmp     = tstart[N];
+	tstart[N] = tstop[N];
+	tstop[N]  = tmp;
+      }
+      remove_argument (Na, argc, argv);
+      goto goodvalue;
+    }
+    return (FALSE); /* syntax error in 2nd value */
+
+  goodvalue:
+    if (N == Ntimes - 1) {
+      Ntimes += 10;
+      REALLOCATE (tstart, unsigned long, Ntimes);
+      REALLOCATE (tstop,  unsigned long, Ntimes);
+    }
+  }
+}
+  
+void make_backup (char *filename) {
+
+  int status, cmode;
+  struct stat filestat;
+  char line [256];
+
+  status = stat (filename, &filestat);
+  if (status == 0) { /* file exists, make backup copy */
+    sprintf (line, "cp %s %s~", filename, filename);
+    status = system (line);
+    if (status) {
+      fprintf (stderr, "ERROR: unable to create %s~, exiting\n", filename);
+      exit (0);
+    }
+    cmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+    sprintf (line, "%s~", filename);
+    chmod (line, cmode);
+  }
+}
+
+
+int get_filter_arguments (int *argc, char **argv, int **Filt, int *Nfilt) {
+
+  int i, N, Na, NF;
+  int *filt;
+
+  /* allocate space for returned lists */
+  NF = 10;
+  ALLOCATE (filt, int, NF);
+
+  for (N = 0; ; N++) {
+
+    /* find next -trange arg */
+    Na = get_argument (*argc, argv, "-filter");
+    if (Na == 0) {
+      *Nfilt = N;
+      *Filt = filt;
+      return (TRUE);
+    }
+    if (Na > *argc - 2) return (FALSE); /* -filter F */
+    remove_argument (Na, argc, argv);
+    
+    for (i = 0; i < strlen (argv[Na]); i++) { if (isspace (argv[Na][i])) argv[Na][i] = '.'; }
+    for (i = 0; i < NFILTER; i++) {
+      if (!strcasecmp (argv[Na], filtername[i])) {
+	filt[N] = filternum[i];
+      }
+    }
+    if (filt[N] == FILTER_NONE) return (FALSE);
+    remove_argument (Na, argc, argv);
+
+    if (N == NF - 1) {
+      NF += 10;
+      REALLOCATE (filt, int, NF);
+    }
+  }
+}
+  
+   
+int get_version (int argc, char **argv, char *version) {
+
+  int N;
+  char *p, *q, *line;
+
+  if (get_argument (argc, argv, "-version")) {
+
+    N = strlen (version) + 2;
+    line = (char *) malloc (N);
+    bzero (line, N);
+
+    p = strstr (version, "$Revision: ");
+    if (p != (char *) NULL) 
+      p += strlen ("$Revision: ");
+    else
+      p = version;
+
+    q = strstr (p, "$");
+    if (q != (char *) NULL) 
+      N = q - p; 
+    else
+      N = strlen (p);
+
+    strncpy (line, p, N);
+
+    fprintf (stderr, "%s\n", line);
+    exit (2);
+  }
+}  
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mkfringetable.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mkfringetable.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mkfringetable.c	(revision 21897)
@@ -0,0 +1,207 @@
+# include <ohana.h>
+# include <gfitsio.h>
+
+static char *version = "mkfringetable $Revision: 1.8 $";
+
+void get_version (int argc, char **argv, char *version);
+
+int main (int argc, char **argv) {
+
+  int i, j, Npts, NPTS, Nccd, status;
+  char *layout, *config, *file;
+  char filter[64], start[64], stop[64], camera[64], *datestr;
+  char ImagetypeKeyword[64], CCDnumKeyword[64], FilterKeyword[64], CameraKeyword[64];
+  char *row, line[512], field[64], extname[64], filename[512];
+  double x, y, *xmin, *xmax, *ymin, *ymax;
+  FILE *f, *g;
+
+  Header header, theader;
+  Matrix matrix;
+  FTable table;
+
+  get_version (argc, argv, version);
+
+  /*** load ptolemy/elixir configuration info ***/
+  file = SelectConfigFile (&argc, argv, "ptolemy");
+  config = LoadConfigFile (file);
+  if (config == (char *) NULL) {
+    fprintf (stderr, "ERROR: can't find configuration file %s\n", file);
+    if (file != (char *) NULL) free (file);
+    exit (0);
+  }
+  ScanConfig (config, "IMAGETYPE-KEYWORD",           "%s", 0, ImagetypeKeyword);
+  ScanConfig (config, "CCDNUM-KEYWORD",              "%s", 0, CCDnumKeyword);
+  ScanConfig (config, "FILTER-KEYWORD",              "%s", 0, FilterKeyword);
+  ScanConfig (config, "CAMERA-KEYWORD",              "%s", 0, CameraKeyword);
+  free (config);
+  free (file);
+
+  if (argc != 3) {
+    fprintf (stderr, "USAGE: (layout) (output)\n");
+    exit (2);
+  }
+
+  g = fopen (argv[2], "w");
+  if (g == (FILE *) NULL) { 
+    fprintf (stderr, "cannot open %s for output\n", argv[2]);
+    exit (1);
+  }
+
+  /* load info from layout file */
+  layout = LoadConfigFile (argv[1]);
+  if (layout == (char *) NULL) {
+    fprintf (stderr, "cannot open layout file %s\n", argv[1]);
+    exit (1);
+  }
+  status = TRUE;
+  status = status && (NULL == ScanConfig (layout, "NCCD",    "%d", 1, &Nccd));
+  status = status && (NULL == ScanConfig (layout, "FILTER",  "%s", 1, filter));
+  status = status && (NULL == ScanConfig (layout, "CAMERA",  "%s", 1, camera));
+  status = status && (NULL == ScanConfig (layout, "TVSTOP",  "%s", 1, stop));
+  status = status && (NULL == ScanConfig (layout, "TVSTART", "%s", 1, start));
+  if (!status) {
+    fprintf (stderr, "error in layout file\n");
+    fprintf (stderr, "Nccd: %d\n", Nccd);
+    fprintf (stderr, "filter: %s\n", filter);
+    fprintf (stderr, "camera: %s\n", camera);
+    fprintf (stderr, "tvstart: %s\n", start);
+    fprintf (stderr, "tvstop: %s\n", stop);
+    exit (1);
+  }
+
+  { /* save file creation date */ 
+    struct timeval now;
+    gettimeofday (&now, (struct timezone *) NULL);
+    datestr = sec_to_date (now.tv_sec);
+  }
+
+  /* make phu header (no matrix needed) */
+  gfits_init_header (&header);    
+  header.extend = TRUE;
+  gfits_create_header (&header);
+  gfits_create_matrix (&header, &matrix);
+  
+  gfits_modify (&header, "NEXTEND",        "%d", 1, Nccd);
+  gfits_modify (&header, "DATE",           "%s", 1, datestr);
+  gfits_modify (&header, "TVSTART",        "%s", 1, start);
+  gfits_modify (&header, "TVSTOP",         "%s", 1, stop);
+  gfits_modify (&header, "VERSION",        "%s", 1, version);
+  gfits_modify (&header, CameraKeyword,    "%s", 1, camera);
+  gfits_modify (&header, ImagetypeKeyword, "%s", 1, "FRPTS");
+  gfits_modify (&header, FilterKeyword,    "%s", 1, filter);
+    
+  gfits_fwrite_header  (g, &header);
+  gfits_fwrite_matrix  (g, &matrix);
+
+  ALLOCATE (xmin, double, 1);
+  ALLOCATE (xmax, double, 1);
+  ALLOCATE (ymin, double, 1);
+  ALLOCATE (ymax, double, 1);
+
+  for (i = 0; i < Nccd; i++) {
+
+    /* load entry from layout file */
+    sprintf (field, "CCD%02d", i);
+    if (!ScanConfig (layout, field, "%s", 1, line)) {
+      fprintf (stderr, "missing entry for %s\n", field);
+      exit (1);
+    }
+    sscanf (line, "%s %s", extname, filename);
+
+    /* load data from fringe points file */
+    f = fopen (filename, "r");
+    if (f == (FILE *) NULL) {
+      fprintf (stderr, "error opening data file %s\n", filename);
+      exit (1);
+    }
+
+    NPTS = 100;
+    Npts = 0;
+    REALLOCATE (xmin, double, NPTS);
+    REALLOCATE (xmax, double, NPTS);
+    REALLOCATE (ymin, double, NPTS);
+    REALLOCATE (ymax, double, NPTS);
+
+    while (fscanf (f, "%lf %lf", &x, &y) == 2) {
+      xmin[Npts] = x;
+      ymin[Npts] = y;
+      if (fscanf (f, "%lf %lf", &x, &y) != 2) {
+	fprintf (stderr, "Funny line at %d?", Npts);
+	goto done;
+      }
+      xmax[Npts] = x;
+      ymax[Npts] = y;
+      Npts ++;
+      if (Npts == NPTS) {
+	NPTS += 100;
+	REALLOCATE (xmin, double, NPTS);
+	REALLOCATE (xmax, double, NPTS);
+	REALLOCATE (ymin, double, NPTS);
+	REALLOCATE (ymax, double, NPTS);
+      }
+    }
+  done:
+
+    /* create table header */
+    gfits_create_table_header (&theader, "TABLE", extname);
+      
+    /* add current date/time to header */
+    gfits_modify (&theader, "DATE",          "%s", 1, datestr);
+    gfits_modify (&theader, "TVSTART",       "%s", 1, start);
+    gfits_modify (&theader, "TVSTOP",        "%s", 1, stop);
+    gfits_modify (&header, CameraKeyword,    "%s", 1, camera);
+    gfits_modify (&header, ImagetypeKeyword, "%s", 1, "FRPTS");
+    gfits_modify (&header, FilterKeyword,    "%s", 1, filter);
+    gfits_modify (&header, CCDnumKeyword,    "%s", 1, extname);
+    
+    
+    /* define table layout */
+    gfits_define_table_column (&theader, "F6.1", "X_MIN", "min couple x", "pixels"); 
+    gfits_define_table_column (&theader, "F6.1", "Y_MIN", "min couple y", "pixels"); 
+    gfits_define_table_column (&theader, "F6.1", "X_MAX", "max couple x", "pixels"); 
+    gfits_define_table_column (&theader, "F6.1", "Y_MAX", "max couple y", "pixels"); 
+    
+    /* create table, add data values */
+    gfits_create_table (&theader, &table);
+  
+    for (j = 0; j < Npts; j++) {
+      row = gfits_table_print (&table, xmin[j], ymin[j], xmax[j], ymax[j]);
+      gfits_add_rows (&table, row, 1, strlen (row));
+    }
+
+    gfits_fwrite_Theader (g, &theader);
+    gfits_fwrite_table   (g, &table);
+  }
+  exit (0);
+}
+
+/**** support functions ******/
+void get_version (int argc, char **argv, char *version) {
+
+  int N;
+  char *p, *q, *line;
+
+  if (get_argument (argc, argv, "-version")) {
+
+    N = strlen (version) + 2;
+    line = (char *) malloc (N);
+    bzero (line, N);
+
+    p = strstr (version, "$Revision: ");
+    if (p != (char *) NULL) 
+      p += strlen ("$Revision: ");
+    else
+      p = version;
+
+    q = strstr (p, "$");
+    if (q != (char *) NULL) 
+      N = q - p; 
+    else
+      N = strlen (p);
+
+    strncpy (line, p, N);
+
+    fprintf (stderr, "%s\n", line);
+    exit (2);
+  }
+}  
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mkgauss.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mkgauss.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mkgauss.c	(revision 21897)
@@ -0,0 +1,88 @@
+# include <ohana.h>
+
+void   gauss_init ();
+double gaussian (double x, double mean, double sigma);
+double rnd_gauss (double mean, double sigma);
+
+/* NGAUSS defines the resolution of the distribution */
+# define NGAUSS 2048
+static double gaussint[NGAUSS];
+
+int main (int argc, char **argv) {
+
+  int i, Npts;
+  double mean, sigma, f;
+
+  if (argc != 4) {
+    fprintf (stderr, "USAGE: mkgauss (mean) (sigma) (npts)\n");
+    exit (2);
+  }
+
+  mean = atof (argv[1]);
+  sigma = atof (argv[2]);
+  Npts = atoi (argv[3]);
+
+  gauss_init ();
+
+  for (i = 0; i < Npts; i++) {
+    f = rnd_gauss (mean, sigma);
+    fprintf (stdout, "%f\n", f);
+  }
+
+  exit (0);
+}
+
+void gauss_init () {
+
+  int i;
+  long A, B;
+  double val, x, dx, dx1, dx2, dx3, df;
+  double mean, sigma;
+
+  A = time(NULL);
+  for (B = 0; A == time(NULL); B++);
+  srand48(B);
+
+  val = 0;
+  dx = 0.001;
+  dx1 = dx / 3.0;
+  dx2 = 2.0*dx/3.0;
+  dx3 = dx;
+  mean = 0.0;
+  sigma = 1.0;
+
+  for (i = 0, x = -7.0; (i < NGAUSS) && (x < 7.0); x += dx)  {
+    df = (3.0*gaussian(x    , 0.0, 1.0) + 
+	  9.0*gaussian(x+dx1, 0.0, 1.0) +
+	  9.0*gaussian(x+dx2, 0.0, 1.0) + 
+	  3.0*gaussian(x+dx3, 0.0, 1.0)) * (dx1/8.0);
+    val += df;
+    if (val > (i / (double) NGAUSS)) {
+      gaussint[i] = x + dx / 2.0;
+      i++;
+    }
+  }
+  return;
+}
+
+double gaussian (double x, double mean, double sigma) {
+  double f;
+
+  f = exp (-0.5 * SQ(x - mean) / SQ(sigma)) / sqrt(2 * M_PI * SQ(sigma));
+  return (f);
+}
+
+double rnd_gauss (double mean, double sigma) {
+
+  int i;
+  double y;
+
+  i = 0;
+  while ((i == 0) || (i == NGAUSS - 1)) {
+    y = drand48();
+    i = MIN (NGAUSS - 1, MAX (0, NGAUSS*y));
+  }
+  y = gaussint[i]*sigma + mean;
+
+  return (y);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mknames.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mknames.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mknames.c	(revision 21897)
@@ -0,0 +1,66 @@
+# include "ohana.h"
+extern double drand48();
+
+# define NFILTER 5
+static char filtlist[NFILTER][2] = {"B", "V", "R", "I", "Z"};
+
+int main (int argc, char **argv) {
+ 
+  FILE *f;
+  int j, rnd;
+  int ccd, state;
+  char type[64], filter[64], name[64];
+  struct timeval now;
+  struct tm *gmt;
+
+  if (argc != 2) {
+    fprintf (stderr, "USAGE: mknames (fifo)\n");
+    exit (1);
+  }
+
+  /* lock fifo */
+  f = fsetlockfile (argv[1], 60.0, LCK_XCLD, &state);
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "can't open fifo file\n");
+    fclearlockfile (argv[1], f, LCK_XCLD, &state);
+    exit (1);
+  }
+
+  gettimeofday (&now, (void *) NULL);
+  gmt = gmtime (&now.tv_sec);
+  srand48(now.tv_usec);
+  rnd = 1000*drand48();
+  sprintf (name, "%04d.%02d.%02d.%03d", gmt[0].tm_year + 1900, gmt[0].tm_mon + 1, gmt[0].tm_mday, rnd);
+
+  for (ccd = 0; ccd < 12; ccd++) {
+    strcpy (filter, "X");
+    strcpy (type, "bias");
+    fprintf (f, "%02d %s %s %s\n", ccd, type, filter, name);
+    strcpy (type, "dark");
+    fprintf (f, "%02d %s %s %s\n", ccd, type, filter, name);
+    strcpy (type, "flat");
+    for (j = 0; j < NFILTER; j++) {
+      strcpy (filter, filtlist[j]);
+      fprintf (f, "%02d %s %s %s\n", ccd, type, filter, name);
+    }
+  }
+  fclearlockfile (argv[1], f, LCK_XCLD, &state);
+  exit (0);
+}
+
+  /* 
+     
+     we need to generate a list of entries for 'elixir flips'
+     the entries look like:
+
+     (ccd) (type) (filter) (tend) (nameref)
+
+     (ccd)  - ranges from 00 to 11 
+     (type) - values are bias, dark, flat, ?
+     (filter) - for bias & dark = X
+                for flat = B,V,R,I,Z (Hon?, Hoff?)
+     (tend) = 'NOW' (probably don't need to generate this!)
+     (nameref) = SSSSSS (some string, needs to be unique... based on date?)
+
+  */
+		
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mktemp.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mktemp.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mktemp.c	(revision 21897)
@@ -0,0 +1,17 @@
+# include <stdio.h>
+# include <stdlib.h>
+
+int main (int argc, char **argv) {
+
+  if (argc != 2) {
+    fprintf (stderr, "USAGE: %s (template)\n", argv[0]);
+    exit (1);
+  }
+
+  if (mkstemp (argv[1]) == -1) exit (1);
+
+  fprintf (stdout, "%s\n", argv[1]);
+
+  exit (0);
+}
+ 
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mosastro.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mosastro.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/mosastro.c	(revision 21897)
@@ -0,0 +1,504 @@
+# include <ohana.h>
+# include <dvo.h>
+# define NCCD 12
+
+static double **alpha, **talpha;
+static double **beta, **tbeta;
+static double *partry, *dyda;
+static double ochisq, lambda;
+
+double *x, *y, *p, *q;
+double Px, Py, PS;
+int PSfixed;
+
+double chipfunc (int idx, double *P, double *Q, double *par, int Npar);
+double chipfit (int idx, double *par, int Npar, double *dyda);
+double mrqcof (int *index, int Npts, double *par, int Npar, double **ta, double **tb, double (funcs)(int, double *, int, double *));
+double mrqmin (int *index, int Npts, double *par, int Npar,                           double (funcs)(int, double *, int, double *));
+int mrqinit (int *index, int Npts, double *par, int Npar,                             double (funcs)(int, double *, int, double *));
+int mrqfree (int Npar);
+int fit (double *X, double *Y, int N, double *A, double *B);
+
+main (int argc, char **argv) {
+
+  int i, j, n;
+  int Npar, Npts, NPTS, done;
+  int *CCD, *idx;
+  double Ro, Do, chisq, nchisq, gchisq, xf, yf;
+  double Sx, Sy, Lo, Mo, Lp, Mp, dr, DSx, DSy;
+  double *R, *D, *X, *Y, *L, *M, *tmp;
+  double *par;
+  FILE *f;
+  Coords coords;
+  double *Xo, *Yo, *To;
+
+  /* load in RA, DEC, X, Y, CCD vectors */
+  if ((argc != 2) && (argc != 7)) {
+    fprintf (stderr, "USAGE: mosastro (file.mos) [Ro Do ps DSx DSy]\n");
+    exit (2);
+  }
+  PS = DSx = DSy = 0.0;
+  PSfixed = FALSE;
+  if (argc == 7) {
+    PSfixed = TRUE;
+    Ro = atof (argv[2]);
+    Do = atof (argv[3]);
+    PS = atof (argv[4]);
+    DSx = atof (argv[5]) / 1000000.0;
+    DSy = atof (argv[6]) / 1e6;
+  }
+  
+  ALLOCATE (Xo, double, NCCD);
+  ALLOCATE (Yo, double, NCCD);
+  ALLOCATE (To, double, NCCD);
+
+  Npar = 4;
+  if (PSfixed) Npar = 3;
+  ALLOCATE (par, double, Npar);
+
+  NPTS = 100;
+  ALLOCATE (R, double, NPTS);
+  ALLOCATE (D, double, NPTS);
+  ALLOCATE (X, double, NPTS);
+  ALLOCATE (Y, double, NPTS);
+  ALLOCATE (CCD, int, NPTS);
+
+  f = fopen (argv[1], "r");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "can't open file %s\n", argv[1]);
+    exit (1);
+  }
+
+  for (i = 0; fscanf (f, "%lf %lf %lf %lf %d", &R[i], &D[i], &X[i], &Y[i], &CCD[i]) != EOF; i++) {
+    if (i == NPTS - 1) {
+      NPTS += 100;
+      REALLOCATE (R, double, NPTS);
+      REALLOCATE (D, double, NPTS);
+      REALLOCATE (X, double, NPTS);
+      REALLOCATE (Y, double, NPTS);
+      REALLOCATE (CCD, int, NPTS);
+    }
+  }
+  NPTS = i;
+
+  /* find median of RA and DEC for field center */
+  if (!PSfixed) {
+    ALLOCATE (tmp, double, NPTS);
+    memcpy (tmp, R, NPTS*sizeof(double));
+    sort (tmp, NPTS);
+    Ro = tmp[(int)(0.5*NPTS)];
+    memcpy (tmp, D, NPTS*sizeof(double));
+    sort (tmp, NPTS);
+    Do = tmp[(int)(0.5*NPTS)];
+  }
+
+  /* basic coords */
+  strcpy (coords.ctype, "RA---TAN");
+  coords.cdelt1 = coords.cdelt2 = 1.0 / 3600.0;
+  coords.pc1_1  = 1.0;
+  coords.pc2_2  = -1.0;
+  coords.pc1_2  = coords.pc2_1 = 0.0;
+  coords.crval1 = Ro;
+  coords.crval2 = Do;
+  coords.crpix1 = coords.crpix2 = 0;
+  
+  /* RA, DEC -> L, M: */
+  /* only free parameters are Ro, Do */
+  ALLOCATE (L, double, NPTS);
+  ALLOCATE (M, double, NPTS);
+
+  for (i = 0; i < NPTS; i++) {
+    RD_to_XY (&Lp, &Mp, R[i], D[i], &coords);
+    dr = hypot (Lp, Mp);
+    L[i] = Lp * (1 + DSx*dr);
+    M[i] = Mp * (1 + DSy*dr);
+  }
+
+  ALLOCATE (x, double, NPTS);
+  ALLOCATE (y, double, NPTS);
+  ALLOCATE (p, double, NPTS);
+  ALLOCATE (q, double, NPTS);
+  ALLOCATE (idx, int, NPTS);
+
+  gchisq = 0;
+  for (i = 0; i < NCCD; i++) {
+    n = 0;
+    for (j = 0; j < NPTS; j++) {
+      if (CCD[j] == i) {
+	x[n] = X[j];
+	y[n] = Y[j];
+	p[n] = L[j];
+	q[n] = M[j];
+	idx[n] = n;
+	n ++;
+      }
+    }
+    Npts = n;
+
+    /* fit p = ax + b, q = ay + b */
+    fit (x, p, Npts, &Sx, &Lo);
+    fit (y, q, Npts, &Sy, &Mo);
+
+    /* initial guesses for par[0], par[1], par[2], par[3] */
+    par[0] = Lo;
+    par[1] = Mo;
+    par[2] = 0.0;
+    if (!PSfixed) 
+      par[3] = 0.5*fabs (Sx) + 0.5*fabs(Sy);
+
+    Px = SIGN (Sx);
+    Py = SIGN (Sy);
+    /* fprintf (stderr, "%2d: %7.1f  %7.1f  %5.3f  %6.2f\n", i, par[0], par[1], par[2], par[3]); */
+
+    chisq = mrqinit (idx, Npts, par, Npar, chipfit);
+    
+    done = FALSE;
+    for (j = 0; (j < 20) && !done; j++) {
+      nchisq = mrqmin (idx, Npts, par, Npar, chipfit);
+      /* fprintf (stderr, "%7.1f: %7.1f  %7.1f  %5.3f  %6.2f\n", nchisq, par[0], par[1], par[2], par[3]); */
+      /* if (chisq - nchisq < 0.1) done = TRUE; */
+      if (nchisq > 0) chisq = nchisq;
+    }  
+    Xo[i] = par[0];
+    Yo[i] = par[1];
+    To[i] = par[2];
+    gchisq += chisq;
+    if (!PSfixed) PS += par[3];
+
+    /*
+    if (!PSfixed) 
+      fprintf (stderr, "%2d: %7.1f  %7.1f  %6.2f  %7.5f\n", i, par[0], par[1], par[2], par[3]); 
+    else 
+      fprintf (stderr, "%2d: %7.1f  %7.1f  %6.2f  %7.5f\n", i, par[0], par[1], par[2], PS); 
+    */
+
+    for (j = 0; j < Npts; j++) {
+      chipfunc (j, &xf, &yf, par, Npar);
+      n = idx[j];
+      fprintf (stdout, "%f %f  %f %f  %f %f\n", x[n], y[n], p[n], q[n], xf, yf);
+    }
+
+  }
+  if (PSfixed) {
+    fprintf (stderr, "%f   %f  %f  %f  %f %f\n", gchisq, Ro, Do, PS, 1e6*DSx, 1e6*DSy);
+  } else {
+    fprintf (stderr, "%f   %f  %f  %f  %f %f\n", gchisq, Ro, Do, PS / NCCD, 1e6*DSx, 1e6*DSy);
+  }
+  exit (0);
+}
+
+double mrqcof (int *index, int Npts, double *par, int Npar, double **ta, double **tb, 
+	      double (funcs)(int, double *, int, double *)) {
+
+  int k, j, i;
+  double dchi, wt, chisq;
+
+  for (j = 0; j < Npar; j++) {
+    for (k = 0; k <= j; k++) ta[j][k] = 0.0;
+    tb[j][0] = 0.0;
+  }
+
+  chisq = 0.0;
+  for (i = 0; i < Npts; i++) {
+
+    dchi = funcs (index[i], par, Npar, dyda);
+    chisq += dchi;
+
+    for (j = 0; j < Npar; j++) {
+      wt = dyda[j];
+      for (k = 0; k <= j; k++) ta[j][k] += wt * dyda[k];
+      tb[j][0] += wt * dchi;
+    }
+  }
+
+  for (j = 1; j < Npar; j++)
+    for (k = 0; k < j; k++) 
+      ta[k][j] = ta[j][k];
+
+  return (chisq);
+
+}
+
+double mrqmin (int *index, int Npts, 
+	      double *par, int Npar, 
+	      double (funcs)(int, double *, int, double *)) {
+
+  int i, j, k;
+  double chisq;
+
+  /* set up test matrixes for this run */
+  for (j = 0; j < Npar; j++) {
+    for (k = 0; k < Npar; k++) talpha[j][k] = alpha[j][k];
+    talpha[j][j] = alpha[j][j] * (1.0 + lambda);
+    tbeta[j][0] = beta[j][0];
+  }
+
+  gaussj (talpha, Npar, tbeta, 1);
+
+  /* if we keep some fixed, set partry to just them 
+     for (j = 0; j < Npar; j++) partry[j] = par[j]; */
+
+  for (j = 0; j < Npar; j++) partry[j] = par[j] - tbeta[j][0];
+
+  chisq = mrqcof (index, Npts, partry, Npar, talpha, tbeta, funcs);
+
+  /* if good, save temp values */
+  if (chisq < ochisq) {
+    lambda *= 0.1;
+    ochisq = chisq;
+    for (j = 0; j < Npar; j++) {
+      for (k = 0; k < Npar; k++) alpha[j][k] = talpha[j][k];
+      beta[j][0] = tbeta[j][0];
+      par[j] = partry[j];
+    }
+  } else {
+    lambda *= 10.0;
+    chisq = ochisq;
+  }
+
+  return (chisq);
+
+}
+
+int mrqinit (int *index, int Npts, double *par, int Npar, double (funcs)(int, double *, int, double *)) {
+
+  int i;
+
+  ALLOCATE (dyda, double, Npar);
+  ALLOCATE (partry, double, Npar);
+  ALLOCATE (alpha, double *, Npar);
+  ALLOCATE (beta, double *, Npar);
+  ALLOCATE (talpha, double *, Npar);
+  ALLOCATE (tbeta, double *, Npar);
+  for (i = 0; i < Npar; i++) {
+    ALLOCATE (alpha[i], double, Npar);
+    ALLOCATE (beta[i], double, Npar);
+    ALLOCATE (talpha[i], double, Npar);
+    ALLOCATE (tbeta[i], double, Npar);
+  }
+  lambda = 0.1;
+  ochisq = mrqcof (index, Npts, par, Npar, alpha, beta, funcs);
+}
+
+int mrqfree (int Npar) {
+
+  int i;
+
+  for (i = 0; i < Npar; i++) {
+    free (alpha[i]);
+    free (talpha[i]);
+    free (beta[i]);
+    free (tbeta[i]);
+  }
+  free (alpha);
+  free (talpha);
+  free (beta);
+  free (tbeta);
+  free (partry);
+  free (dyda);
+
+}
+
+int gaussj (double **a, int n, double **b, int m) {
+
+  int *indxc,*indxr,*ipiv;
+  int i, icol, irow, j, k, l, ll, status;
+  double big,dum,pivinv;
+  
+  ALLOCATE (indxc, int, n);
+  ALLOCATE (indxr, int, n);
+  ALLOCATE (ipiv, int, n);
+  for (j = 0; j < n; j++) 
+    ipiv[j] = 0;
+
+  for (i = 0; i < n; i++) {
+    big = 0.0;
+    for (j = 0; j < n; j++) {
+      if (ipiv[j] != 1) {
+	for (k = 0; k < n; k++) {
+	  if (ipiv[k] == 0) {
+	    if (fabs (a[j][k]) >= big) {
+	      big  = fabs (a[j][k]);
+	      irow = j;
+	      icol = k;
+	    }
+	  } 
+	  else 
+	    if (ipiv[k] > 1) {
+	      fprintf (stderr, "GAUSSJ: Singular Matrix! (1)\n");
+	      return (0);
+	    }
+	}
+      }
+    }
+    ipiv[icol]++;
+    if (irow != icol) {
+      for (l = 0; l < n; l++) 
+	SWAP (a[irow][l], a[icol][l]);
+      for (l = 0; l < m; l++) 
+	SWAP (b[irow][l], b[icol][l]);
+    }
+    indxr[i] = irow;
+    indxc[i] = icol;
+    if (a[icol][icol] == 0.0) {
+      fprintf (stderr, "GAUSSJ: Singular Matrix! (2)\n");
+      return (0);
+    }
+    pivinv = 1.0 / a[icol][icol];
+    a[icol][icol] = 1.0;
+    for (l = 0; l < n; l++) 
+      a[icol][l] *= pivinv;
+    for (l = 0; l < m; l++) 
+      b[icol][l] *= pivinv;
+    for (ll = 0; ll < n; ll++) {
+      if (ll != icol) {
+	dum = a[ll][icol];
+	a[ll][icol] = 0.0;
+	for (l = 0; l < n; l++) 
+	  a[ll][l] -= a[icol][l]*dum;
+	for (l = 0; l < m; l++) 
+	  b[ll][l] -= b[icol][l]*dum;
+      }
+    }
+  }
+
+  for (l = n - 1; l >= 0; l--) {
+    if (indxr[l] != indxc[l])
+      for (k = 0; k < n; k++)
+	SWAP (a[k][indxr[l]], a[k][indxc[l]]);
+  }
+  free (ipiv);
+  free (indxr);
+  free (indxc);
+  return (1);
+}
+
+  /* par:
+     par[0] = Lo
+     par[1] = Mo
+     par[2] = ps
+     par[3] = theta
+  */
+
+double chipfunc (int idx, double *P, double *Q, double *par, int Npar) {
+  double Lo, Mo, ps, cs, sn;
+  double X, Y;
+
+  Lo = par[0];
+  Mo = par[1];
+  cs = cos (par[2]*RAD_DEG);
+  sn = sin (par[2]*RAD_DEG);
+  if (PSfixed) 
+    ps = PS;
+  else
+    ps = par[3];
+
+  X = x[idx];
+  Y = y[idx];
+
+  *P = Lo + Px * ps * (X*cs + Y*sn);
+  *Q = Mo + Py * ps * (Y*cs - X*sn);
+}
+
+double chipfit (int idx, double *par, int Npar, double *dyda) {
+
+  double Lo, Mo, ps, cs, sn;
+  double X, Y, L, M, P, Q;
+  double chisq, dp, dq;
+
+  Lo = par[0];
+  Mo = par[1];
+  cs = cos (par[2]*RAD_DEG);
+  sn = sin (par[2]*RAD_DEG);
+  if (PSfixed) 
+    ps = PS;
+  else
+    ps = par[3];
+
+  X = x[idx];
+  Y = y[idx];
+  L = p[idx];
+  M = q[idx];
+
+  P = Lo + Px * ps * (X*cs + Y*sn);
+  Q = Mo + Py * ps * (Y*cs - X*sn);
+
+  chisq = SQ(L-P) + SQ(M-Q);
+
+  dp = P - L;
+  dq = Q - M;
+
+  dyda[0] = 2*dp;
+  dyda[1] = 2*dq;
+  
+  dyda[2] =  2*RAD_DEG*ps*(dp*Px*(Y*cs - X*sn) - dq*Py*(X*cs + Y*sn));
+  if (!PSfixed)
+    dyda[3] =  2   *(dp*Px*(X*cs + Y*sn) + dq*Py*(Y*cs - X*sn));
+  
+  return (chisq);
+}
+
+sort (double *value, int N) {
+
+  int l,j,ir,i;
+  double temp;
+  
+  if (N < 2) return;
+  l = N >> 1;
+  ir = N - 1;
+  for (;;) {
+    if (l > 0) {
+      temp = value[--l];
+    }
+    else {
+      temp = value[ir];
+      value[ir] = value[0];
+      if (--ir == 0) {
+	value[0] = temp;
+	return;
+      }
+    }
+    i = l;
+    j = (l << 1) + 1;
+    while (j <= ir) {
+      if (j < ir && value[j] < value[j+1]) ++j;
+      if (temp < value[j]) {
+	value[i]=value[j];
+	j += (i=j) + 1;
+      }
+      else j = ir + 1;
+    }
+    value[i] = temp;
+  }
+}
+
+
+fit (double *X, double *Y, int N, double *A, double *B) {
+
+  int i;
+  double **a, **b;
+
+  ALLOCATE (a, double *, 2);
+  ALLOCATE (b, double *, 2);
+  ALLOCATE (a[0], double, 2);
+  ALLOCATE (a[1], double, 2);
+  ALLOCATE (b[0], double, 1);
+  ALLOCATE (b[1], double, 1);
+  a[0][0] = a[0][1] = a[1][0] = a[1][1] = 0;
+  b[0][0] = b[1][0] = 0;
+
+  for (i = 0; i < N; i++) {
+    a[0][0] += X[i]*X[i];
+    a[0][1] += X[i];
+    a[1][1] += 1;
+    b[0][0] += X[i]*Y[i];
+    b[1][0] += Y[i];
+  }
+
+  a[1][0] = a[0][1];
+  
+  gaussj (a, 2, b, 1);
+
+  *A = b[0][0];
+  *B = b[1][0];
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/posscontour.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/posscontour.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/posscontour.c	(revision 21897)
@@ -0,0 +1,126 @@
+# include <stdio.h>
+# include <gfitsio.h>
+# include <math.h>
+# include <malloc.h>
+# include <string.h>
+# include <sys/time.h>
+# include <stdarg.h>
+# include <stdlib.h>
+
+# define TRUE (1)
+# define FALSE (0)
+# define DEG_RAD (57.29578)
+# define RAD_DEG (0.017453293)
+
+char PLTDECSN[5];
+
+double NX, NY, PLTRAH, PLTRAM, PLTRAS, PLTDECD, PLTDECM, PLTDECS, Do, Ro;
+double CNPIX1, CNPIX2, XPIXELSZ, YPIXELSZ, PPO1, PPO2, PPO3, PPO4, PPO5, PPO6;
+double AMDX1, AMDX2, AMDX3, AMDX4, AMDX5, AMDX6, AMDX7, AMDX8, AMDX9, AMDX10, AMDX11, AMDX12, AMDX13;
+double AMDY1, AMDY2, AMDY3, AMDY4, AMDY5, AMDY6, AMDY7, AMDY8, AMDY9, AMDY10, AMDY11, AMDY12, AMDY13;
+
+convert (ra, dec, X, Y) 
+     double *ra, *dec;
+     double X, Y;
+{
+
+  double x, y, Azeta, Aeta, eta, zeta;
+
+  x = (PPO3 - XPIXELSZ*(X+CNPIX1)) / 1000.0;
+  y = (YPIXELSZ*(Y+CNPIX2) - PPO6) / 1000.0;
+  Azeta = AMDX3 + x*(AMDX1 + x*(AMDX4 + AMDX7 + x*AMDX8)) + y*(AMDX2 + y*(AMDX6 + AMDX7 + y*AMDX11)) + x*y*(AMDX9*x + AMDX10*y + AMDX5) + x*(x*x+y*y)*(AMDX12 + AMDX13*(x*x+y*y));
+  Aeta  = AMDY3 + y*(AMDY1 + y*(AMDY4 + AMDY7 + y*AMDY8)) + x*(AMDY2 + x*(AMDY6 + AMDY7 + x*AMDY11)) + x*y*(AMDY9*y + AMDY10*x + AMDY5) + y*(x*x+y*y)*(AMDY12 + AMDY13*(x*x+y*y));
+  
+  eta = Aeta*RAD_DEG/3600.0;
+  zeta = Azeta*RAD_DEG/3600.0;
+  
+  *ra  = DEG_RAD*atan((zeta/cos(RAD_DEG*Do)) / (1.0 - eta*tan(RAD_DEG*Do))) + Ro;
+  *dec = DEG_RAD*atan(((eta + tan(RAD_DEG*Do)) * (cos (RAD_DEG*(*ra - Ro)))) / (1 - eta * tan(RAD_DEG*Do)));
+  
+}
+
+
+main (int argc, char **argv) 
+{
+
+  int i, status;
+  Header header;
+  double RA, DEC, ra, dec, dRA, dDEC;
+  double X, Y, dX, dY;
+
+  if (argc != 2) {
+    fprintf (stderr, "USAGE: posscontour filename < contour.reg\n");
+    exit (0);
+  }
+
+  status = gfits_read_header (argv[1], &header);
+  if (!status) {
+    fprintf (stderr, "error opening file %s\n", argv[1]);
+    exit (0);
+  }
+
+  gfits_scan (&header, "NAXIS1", "%lf", 1, &NX);
+  gfits_scan (&header, "NAXIS2", "%lf", 1, &NY);
+  gfits_scan (&header, "PLTRAH", "%lf", 1, &PLTRAH);
+  gfits_scan (&header, "PLTRAM", "%lf", 1, &PLTRAM);
+  gfits_scan (&header, "PLTRAS", "%lf", 1, &PLTRAS);
+  gfits_scan (&header, "PLTDECD", "%lf", 1, &PLTDECD);
+  gfits_scan (&header, "PLTDECM", "%lf", 1, &PLTDECM);
+  gfits_scan (&header, "PLTDECS", "%lf", 1, &PLTDECS);
+  gfits_scan (&header, "PLTDECSN", "%s", 1, &PLTDECSN);
+  gfits_scan (&header, "CNPIX1", "%lf", 1, &CNPIX1);
+  gfits_scan (&header, "CNPIX2", "%lf", 1, &CNPIX2);
+  gfits_scan (&header, "XPIXELSZ", "%lf", 1, &XPIXELSZ);
+  gfits_scan (&header, "YPIXELSZ", "%lf", 1, &YPIXELSZ);
+  gfits_scan (&header, "PPO1", "%lf", 1, &PPO1);
+  gfits_scan (&header, "PPO2", "%lf", 1, &PPO2);
+  gfits_scan (&header, "PPO3", "%lf", 1, &PPO3);
+  gfits_scan (&header, "PPO4", "%lf", 1, &PPO4);
+  gfits_scan (&header, "PPO5", "%lf", 1, &PPO5);
+  gfits_scan (&header, "PPO6", "%lf", 1, &PPO6);
+  gfits_scan (&header, "AMDX1", "%lf", 1, &AMDX1);
+  gfits_scan (&header, "AMDX2", "%lf", 1, &AMDX2);
+  gfits_scan (&header, "AMDX3", "%lf", 1, &AMDX3);
+  gfits_scan (&header, "AMDX4", "%lf", 1, &AMDX4);
+  gfits_scan (&header, "AMDX5", "%lf", 1, &AMDX5);
+  gfits_scan (&header, "AMDX6", "%lf", 1, &AMDX6);
+  gfits_scan (&header, "AMDX7", "%lf", 1, &AMDX7);
+  gfits_scan (&header, "AMDX8", "%lf", 1, &AMDX8);
+  gfits_scan (&header, "AMDX9", "%lf", 1, &AMDX9);
+  gfits_scan (&header, "AMDX10", "%lf", 1, &AMDX10);
+  gfits_scan (&header, "AMDX11", "%lf", 1, &AMDX11);
+  gfits_scan (&header, "AMDX12", "%lf", 1, &AMDX12);
+  gfits_scan (&header, "AMDX13", "%lf", 1, &AMDX13);
+  gfits_scan (&header, "AMDY1", "%lf", 1, &AMDY1);
+  gfits_scan (&header, "AMDY2", "%lf", 1, &AMDY2);
+  gfits_scan (&header, "AMDY3", "%lf", 1, &AMDY3);
+  gfits_scan (&header, "AMDY4", "%lf", 1, &AMDY4);
+  gfits_scan (&header, "AMDY5", "%lf", 1, &AMDY5);
+  gfits_scan (&header, "AMDY6", "%lf", 1, &AMDY6);
+  gfits_scan (&header, "AMDY7", "%lf", 1, &AMDY7);
+  gfits_scan (&header, "AMDY8", "%lf", 1, &AMDY8);
+  gfits_scan (&header, "AMDY9", "%lf", 1, &AMDY9);
+  gfits_scan (&header, "AMDY10", "%lf", 1, &AMDY10);
+  gfits_scan (&header, "AMDY11", "%lf", 1, &AMDY11);
+  gfits_scan (&header, "AMDY12", "%lf", 1, &AMDY12);
+  gfits_scan (&header, "AMDY13", "%lf", 1, &AMDY13);
+  Ro = 15.0*(PLTRAH + PLTRAM/60.0 + PLTRAS/3600.0);
+  Do = (PLTDECD + PLTDECM/60.0 + PLTDECS/3600.0);
+  if (PLTDECSN[0] == '-') {
+    Do *= -1;
+  }
+
+  while (fscanf (stdin, "%*s %lf %lf %lf %lf", &X, &Y, &dX, &dY) != EOF) {
+    convert (&RA, &DEC, X, Y);
+    convert (&ra, &dec, (X+dX), (Y+dY));
+    dRA = ra - RA;
+    dDEC = dec - DEC;
+    fprintf (stdout, "LINE %f %f %f %f\n", RA, DEC, dRA, dDEC);
+  }
+  
+  gfits_free_header (&header);
+  
+}
+
+
+/* USAGE: posscontour filename < contour.reg > contour2.reg */
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/precess.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/precess.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/precess.c	(revision 21897)
@@ -0,0 +1,150 @@
+# include <ohana.h>
+
+double BtoJ (double in_epoch);
+double get_epoch (char *in_epoch, char mode);
+
+int main (int argc, char **argv) {
+
+  double T, in_epoch, out_epoch;
+  double A, D, RA, DEC, zeta, z, theta;
+  double SA, CA, SD, CD;
+  int Julian, Besselian;
+
+  Besselian = Julian = 0;
+  Besselian = get_argument (argc, argv, "B");
+  Julian    = get_argument (argc, argv, "J");
+
+  if (argc != 3) {
+    fprintf (stderr, "USAGE:  precess in_epoch out_epoch\n");
+    fprintf (stderr, "   you may use B for B1950.0 or J for J2000.0\n");
+    fprintf (stderr, "   Enter values in degrees\n");
+    exit (2);
+  }
+
+  if (!Julian && !Besselian) { /* assume Julian! */
+    in_epoch  = get_epoch (argv[1], 'J');
+    out_epoch = get_epoch (argv[2], 'J');
+  }
+
+  if ((Julian == 1) && !Besselian) {
+    in_epoch  = 2000.0;
+    out_epoch = get_epoch(argv[2], 'J');
+  }
+
+  if ((Julian == 2) && !Besselian) {
+    in_epoch  = get_epoch(argv[1], 'J');
+    out_epoch = 2000.0;
+  }
+
+  if ((Besselian == 1) && !Julian) {
+    in_epoch  = BtoJ(1950.0); 
+    out_epoch = get_epoch(argv[2], 'B'); 
+  }
+
+  if ((Besselian == 2) && !Julian) {
+    in_epoch  = get_epoch(argv[1], 'B'); 
+    out_epoch = BtoJ(1950.0); 
+  }
+  
+  if (Julian && Besselian) {
+    if (Julian > Besselian) {
+      in_epoch  = BtoJ(1950.0); 
+      out_epoch = 2000.0;
+    }
+    else {
+      in_epoch  = 2000.0;
+      out_epoch = BtoJ(1950.0); 
+    }
+  }
+
+  fprintf (stderr, "converting from J%f to J%f\n", in_epoch, out_epoch);
+
+  T = (out_epoch - in_epoch) / 100.0;
+  
+  zeta  = RAD_DEG*(0.6406161*T + 0.0000839*T*T + 0.0000050*T*T*T);
+  theta = RAD_DEG*(0.5567530*T - 0.0001185*T*T - 0.0000116*T*T*T);
+  z     =          0.6406161*T + 0.0003041*T*T + 0.0000051*T*T*T;
+
+  while (fscanf (stdin, "%lf %lf", &A, &D) != EOF) {
+    SD =  cos(RAD_DEG*A + zeta)*sin(theta)*cos(RAD_DEG*D) + cos(theta)*sin(RAD_DEG*D);
+    CD = sqrt (1 - SD*SD);
+    SA =  sin(RAD_DEG*A + zeta)*cos(RAD_DEG*D)/CD;
+    CA = (cos(RAD_DEG*A + zeta)*cos(theta)*cos(RAD_DEG*D) - sin(theta)*sin(RAD_DEG*D))/CD;
+
+    DEC = DEG_RAD*asin(SD);
+    RA  = DEG_RAD*atan2(SA, CA) + z;
+
+    if (RA < 0)
+      RA += 360;
+    fprintf (stdout, "%f %f\n", RA, DEC);
+  }
+  exit (0);
+}  
+    
+
+double get_epoch (char *in_epoch, char mode) {
+
+  int done;
+  double epoch;
+
+  done = FALSE;
+  if (in_epoch[0] == 'B') {
+    epoch = BtoJ(atof(&in_epoch[1]));
+    done = TRUE;
+  }
+
+  if (in_epoch[0] == 'J') {
+    epoch = atof(&in_epoch[1]);
+    done = TRUE;
+  }
+
+  if (!done && (mode == 'B')) {
+    epoch = BtoJ(atof(in_epoch));
+    done = TRUE;
+  }
+    
+  if (!done && (mode == 'J')) {
+    epoch = atof(in_epoch);
+    done = TRUE;
+  }
+
+  if (!done) {
+    fprintf (stderr, "error finding epoch %s\n", in_epoch);
+    exit (1);
+  }
+  
+  return (epoch);
+}
+
+double BtoJ (double in_epoch) {
+
+  double JD, out_epoch;
+
+  JD = (in_epoch - 1900.0)*365.242198781 + 2415020.31352;
+  out_epoch = 2000.0 + (JD - 2451545.0)/365.25;
+
+  return (out_epoch);
+}
+
+/*
+  time =  (in_epoch - out_epoch) / 100.0;
+
+  fprintf (stderr, "precessing from %f to %f\n", in_epoch, out_epoch);
+  sinE = sin (epsilon*deg_to_rad);
+  cosE = cos (epsilon*deg_to_rad);
+  M = 1.281232*time + 0.0003879*(time*time);
+  N = 0.5567*time - 0.0001185*(time*time);
+
+  while (fscanf (stdin, "%lf %lf", &RA, &Dec) != EOF) {
+    RA = RA - M - N*sin(RA*deg_to_rad)*tan(Dec*deg_to_rad);
+    Dec = Dec - N*cos (RA*deg_to_rad);
+
+    Dec = Dec + time*thetaD*sinE*cos(RA*deg_to_rad);
+    RA = RA + time*thetaD*(cosE + sinE*sin(RA*deg_to_rad)*tan(Dec*deg_to_rad));
+
+    fprintf (stdout, "%f %f\n", RA, Dec);
+  }
+
+*/
+
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/radec.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/radec.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/radec.c	(revision 21897)
@@ -0,0 +1,102 @@
+# include <ohana.h>
+
+int help ();
+int _hms_to_deg (double *h, double *d, char *string, char sep, int Nin);
+
+int main (int argc, char **argv) {
+
+  char line[1000];
+  char sep;
+  double ra, dec;
+  int status, h, m, flag;
+  double s, hh;
+
+  sep = ' ';
+  if (get_argument (argc, argv, "-hms")) {
+    while (scan_line (stdin, line) != EOF) {
+      status = _hms_to_deg (&ra, &dec, line, sep, 3);
+      if (status)
+	fprintf (stdout, "%10.6f %10.6f\n", ra, dec);
+    }
+    exit (0);
+  }
+    
+  if (get_argument (argc, argv, "-hh")) {
+    while (scan_line (stdin, line) != EOF) {
+      dparse (&hh, 1, line);
+      hh /= 15.0;  /* convert from degrees to hours */
+      flag = SIGN(hh);
+      hh *= flag;
+      h = hh;
+      m = 60.000001*(hh - h);
+      s = 3600*(hh - h - m / 60.0);
+      if (flag > 0)
+	fprintf (stdout, " %02d%c%02d%c%06.3f  ", h, sep, m, sep, s);
+      else
+	fprintf (stdout, "-%02d%c%02d%c%06.3f  ", h, sep, m, sep, s);
+      dparse (&hh, 2, line);
+      flag = SIGN(hh);
+      hh *= flag;
+      h = hh;
+      m = 60.000001*(hh - h);
+      s = 3600*(hh - h - m / 60.0);
+      if (flag > 0)
+	fprintf (stdout, " %02d%c%02d%c%06.3f\n", h, sep, m, sep, s);
+      else
+	fprintf (stdout, "-%02d%c%02d%c%06.3f\n", h, sep, m, sep, s);
+    }
+    exit (0);
+  }
+
+  fprintf (stderr, "USAGE: %s [-hh/-hms] \n", argv[0]);
+  fprintf (stderr, "  -hh:  convert from decimal ra,dec to hours, min sec\n");
+  fprintf (stderr, "  -hms: convert from hours, min sec to decimal ra,dec\n");
+  exit (2);
+}
+
+/**********/
+int _hms_to_deg (double *h, double *d, char *string, char sep, int Nin) {
+  
+  char *c;
+  int i, flag_d, flag_h, Nfields;
+  double tmp;
+  
+  *d = *h = 0;
+  stripwhite (string);
+  for (Nfields = 2, i = 0; i < 2*(Nin - 1); i++) {
+    if ((c = strchr (string, sep)) != NULL) {
+      Nfields ++;
+      *c = ' ';
+    }
+  }
+  if (Nfields != 2*Nin) {
+    fprintf (stderr, "warning -- line with too few entries, skipping:  %d != %d\n", Nfields, Nin);
+    return (FALSE);
+  }
+
+  Nfields /= 2;
+
+  flag_h = dparse (h, 1, string);
+  flag_d = dparse (d, Nfields + 1, string);
+  *h *= flag_h;
+  *d *= flag_d;
+
+  if (Nfields > 1) {
+    dparse (&tmp, 2, string);
+    *h += tmp/60.0;
+    dparse (&tmp, Nfields + 2, string);
+    *d += tmp/60.0;
+  }
+
+  if (Nfields > 2) {
+    dparse (&tmp, 3, string);
+    *h += tmp/3600.0;
+    dparse (&tmp, Nfields + 3, string);
+    *d += tmp/3600.0;
+  }
+  
+  *h *= 15*flag_h;
+  *d *= flag_d;
+
+  return (TRUE);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/random.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/random.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/random.c	(revision 21897)
@@ -0,0 +1,64 @@
+# include <ohana.h>
+
+void   gauss_init ();
+double gaussian (double x, double mean, double sigma);
+double rnd_gauss (double mean, double sigma);
+
+/* NGAUSS defines the resolution of the distribution */
+# define NGAUSS 2048
+static double gaussint[NGAUSS];
+
+void gauss_init () {
+
+  int i;
+  long A, B;
+  double val, x, dx, dx1, dx2, dx3, df;
+  double mean, sigma;
+
+  A = time(NULL);
+  for (B = 0; A == time(NULL); B++);
+  srand48(B);
+
+  val = 0;
+  dx = 0.001;
+  dx1 = dx / 3.0;
+  dx2 = 2.0*dx/3.0;
+  dx3 = dx;
+  mean = 0.0;
+  sigma = 1.0;
+
+  for (i = 0, x = -7.0; (i < NGAUSS) && (x < 7.0); x += dx)  {
+    df = (3.0*gaussian(x    , 0.0, 1.0) + 
+	  9.0*gaussian(x+dx1, 0.0, 1.0) +
+	  9.0*gaussian(x+dx2, 0.0, 1.0) + 
+	  3.0*gaussian(x+dx3, 0.0, 1.0)) * (dx1/8.0);
+    val += df;
+    if (val > (i / (double) NGAUSS)) {
+      gaussint[i] = x + dx / 2.0;
+      i++;
+    }
+  }
+  return;
+}
+
+double gaussian (double x, double mean, double sigma) {
+  double f, X;
+
+  f = exp (-0.5 * SQ(x - mean) / SQ(sigma)) / sqrt(2 * M_PI * SQ(sigma));
+  return (f);
+}
+
+double rnd_gauss (double mean, double sigma) {
+
+  int i;
+  double y;
+
+  i = 0;
+  while ((i == 0) || (i == NGAUSS - 1)) {
+    y = drand48();
+    i = MIN (NGAUSS - 1, MAX (0, NGAUSS*y));
+  }
+  y = gaussint[i]*sigma + mean;
+
+  return (y);
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/regions.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/regions.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/regions.c	(revision 21897)
@@ -0,0 +1,135 @@
+# include <ohana.h>
+# define DEBUG 0
+double BigDecBounds[] = {0.0, 7.5, 15.0, 22.5, 30.0, 37.5, 45.0, 
+			   52.5, 60.0, 67.5, 75.0, 82.5, 90.0,
+			   0.0, -7.5, -15.0, -22.5, -30.0, -37.5, -45.0, 
+			   -52.5, -60.0, -67.5, -75.0, -82.5, -90.0};
+char *DecSections[] = {"N0000", "N0730", "N1500", "N2230", "N3000", "N3730", "N4500", 
+			 "N5230", "N6000", "N6730", "N7500", "N8230", "weirdness", 
+			 "S0000", "S0730", "S1500", "S2230", "S3000", "S3730", "S4500", 
+			 "S5230", "S6000", "S6730", "S7500", "S8230", "weirdness"};
+
+char *Dec2Sections[] = {"n0000", "n0730", "n1500", "n2230", "n3000", "n3730", "n4500", 
+			 "n5230", "n6000", "n6730", "n7500", "n8230", "weirdness", 
+			 "s0000", "s0730", "s1500", "s2230", "s3000", "s3730", "s4500", 
+			 "s5230", "s6000", "s6730", "s7500", "s8230", "weirdness"};
+
+char *disk[] = {"disk 1", "disk 1", "disk 1", "disk 1", "disk 1", "disk 1", "disk 1", 
+		  "disk 1", "disk 1", "disk 1", "disk 1", "disk 1", "weirdness", 
+		  "disk 1", "disk 2", "disk 2", "disk 2", "disk 2", "disk 2", "disk 2", 
+		  "disk 2", "disk 2", "disk 2", "disk 2", "disk 2", "weirdness"};
+
+int NBigRASections [] = {48, 47, 45, 43, 40, 36, 32, 28, 21, 15, 9, 3, 3, 48, 47, 45, 43, 40, 36, 32, 28, 21, 15, 9, 3, 3};
+
+int NDecLines[] = {593, 584, 551, 530, 522, 465, 406, 362, 280, 198, 123, 48, 
+                   0, 597, 578, 574, 577, 534, 499, 442, 376, 294, 212, 144, 48};
+
+void  main 
+  (int argc,
+   char **argv) 
+{
+
+  /* USAGE: regions ra dec -- returns filenumber of appropriate GSC region */
+
+  char buffer[2880], temp[50], file[50], line[50];
+  char *p, prefix[1024];
+  FILE *f;
+  double ra, dec, dBigRA, RA, DEC, tmp;
+  double BigRABounds[2], RA0, RA1, DEC0, DEC1;
+  int i, NBigDec, NBigRA, NBig, VMS, N;
+  int NRA, NDEC, NLINES, done, NBLOCKS;
+
+  VMS = FALSE;
+  if (N = get_argument (argc, argv, "-vms")) {
+    remove_argument (N, &argc, argv);
+    VMS = TRUE;
+  }
+
+  strcpy (prefix, "/cdrom/");
+  if (N = get_argument (argc, argv, "-pre")) {
+    remove_argument (N, &argc, argv);
+    strcpy (prefix, argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 2) {
+    fprintf (stderr, "USAGE: %s (regions.tbl) [-pre (prefix)] [-vms]\n", argv[0]);
+    exit (0);
+  }
+
+  while (fscanf (stdin, "%lf %lf", &ra, &dec) != EOF) {
+    f = fopen (argv[1], "r");
+    if (f == NULL) {
+      fprintf (stderr, "could not open GSC regions file %s\n", argv[1]);
+      exit (0);
+    }
+    fread (buffer, 2880, 1, f);
+    fread (buffer, 2880, 1, f);
+    fread (buffer, 2880, 1, f);
+    fread (buffer, 2880, 1, f);
+    fread (buffer, 2880, 1, f);
+    
+    while (ra < 0) { ra += 360.0; }
+    while (ra >= 360.0) { ra -= 360.0; }
+    
+    NBigDec = -1;
+    for (i = 0; i < 12; i++) {
+      (DEBUG) && fprintf (stderr, "%d %f %f %f\n", i, dec, BigDecBounds[i], BigDecBounds[i+1]);
+      if ((dec >= BigDecBounds[i]) && (dec <= BigDecBounds[i+1])) {
+	NBigDec = i;
+	break;
+      }
+    }
+    if (NBigDec < 0) {
+      for (i = 13; i < 24; i++) {
+	(DEBUG) && fprintf (stderr, "%d %f %f %f\n", i, dec, BigDecBounds[i], BigDecBounds[i+1]);
+	if ((dec <= BigDecBounds[i]) && (dec >= BigDecBounds[i+1])) {
+	  NBigDec = i;
+	  break;
+	}
+      }
+    }
+    if (NBigDec < 0) {
+      fprintf (stderr, "dec out of range: %f\n", dec);
+    }
+    
+    NLINES = 0;
+    for (i = 0; i < NBigDec; i++) {
+      NLINES += NDecLines[i];
+    }
+    NBLOCKS = (int) (48*NLINES / 2880);
+    for (i = 0; i < NBLOCKS; i++) {
+      fread (buffer, 2880, 1, f);
+    }
+    
+    done = FALSE;
+    while (!done) {
+      fread (buffer, 2880, 1, f);
+      for (i = 0; !done && (i < 60); i++) {
+	strncpy (temp, &buffer[i*48], 48);
+	temp[49] = 0;
+	hstgsc_hms_to_deg (&RA0, &RA1, &DEC0, &DEC1, &temp[7]);
+	(DEBUG) && fprintf (stderr, "%f %f %f    %f %f %f  %s\n", dec, DEC0, DEC1, ra, RA0, RA1, temp);
+	if ((dec >= 0) && (dec >= DEC0) && (dec < DEC1) && (ra >= RA0) && (ra < RA1)) {
+	  done = TRUE;
+	}
+	if ((dec < 0) && (dec <= DEC0) && (dec > DEC1) && (ra >= RA0) && (ra < RA1)) {
+	  done = TRUE;
+	}
+      }
+    }
+  
+    if (VMS) 
+      sprintf (file, "%s %sGSC/%s/%c%c%c%c.GSC\\;1\0", prefix, disk[NBigDec], DecSections[NBigDec],
+	       temp[1], temp[2], temp[3], temp[4]);
+    else 
+      sprintf (file, "%s %sgsc/%s/%c%c%c%c.gsc\0", disk[NBigDec], prefix, Dec2Sections[NBigDec],
+	       temp[1], temp[2], temp[3], temp[4]);
+
+    fprintf (stdout, "%s\n", file);
+
+    fclose (f);
+    
+  }
+
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/remove_argument.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/remove_argument.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/remove_argument.c	(revision 21897)
@@ -0,0 +1,21 @@
+# include <stdio.h>
+
+int remove_argument (N, argc, argv)
+int N;
+int *argc;
+char *argv[];
+{
+
+  int i;
+
+  if ((N != (int)NULL) && (N != 0)) {
+    (*argc)--;
+    for (i = N; i < *argc; i++) {
+      argv[i] = argv[i+1];
+    }
+  }
+
+  return (N);
+    
+}
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/smaeder.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/smaeder.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/smaeder.c	(revision 21897)
@@ -0,0 +1,512 @@
+# include <ohana.h>
+
+typedef struct {
+  double age;
+  double UV;
+  double V;
+} Model;
+
+typedef struct {
+  double mass;
+  int   Nmodel;
+  Model *model;
+} Track;
+
+int metal;
+double UV0, UV1, dUV;
+double V0, V1, dV;
+int dump, sdump;
+int col1, col2;
+char massfile[1024], agefile[1024];
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+
+  int Ntrack;
+  Track *track, *newtrack;
+
+  args (argc, argv);
+
+  fprintf (stderr, "reading in tracks...\n");
+  readmaeder (argv[1], &track, &Ntrack);
+
+  fprintf (stderr, "smoothing tracks...\n");
+  smoothtracks (&newtrack, track, Ntrack); 
+
+  fprintf (stderr, "interpolating tracks...\n");
+  interpolate_tracks (newtrack, Ntrack);
+
+}
+
+args (argc, argv) 
+int argc;
+char **argv;
+{
+
+  int N;
+
+  metal = 4; /* solar metal */
+  if (N = get_argument (argc, argv, "-metal")) {
+    remove_argument (N, &argc, argv);
+    metal = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  else {
+    fprintf (stderr, "using solar metallicity\n");
+  }
+  
+  dump = -1;
+  if (N = get_argument (argc, argv, "-dump")) {
+    remove_argument (N, &argc, argv);
+    dump = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  
+  sdump = -1;
+  if (N = get_argument (argc, argv, "-sdump")) {
+    remove_argument (N, &argc, argv);
+    sdump = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  
+  col1 = 3;
+  if (N = get_argument (argc, argv, "-col1")) {
+    remove_argument (N, &argc, argv);
+    col1 = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  
+  col2 = 5;
+  if (N = get_argument (argc, argv, "-col2")) {
+    remove_argument (N, &argc, argv);
+    col2 = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  fprintf (stderr, "using mags in columns %d & %d\n", col1, col2);
+  
+  UV0 = -2.0;
+  UV1 =  2.0;
+  dUV =  0.01; 
+  if (N = get_argument (argc, argv, "-color")) {
+    remove_argument (N, &argc, argv);
+    UV0 = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    UV1 = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    dUV = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  V0 =   5.0;
+  V1 = -15.0;
+  dV =  -0.02; 
+  if (N = get_argument (argc, argv, "-mag")) {
+    remove_argument (N, &argc, argv);
+    V0 = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    V1 = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    dV = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  strcpy (massfile, "mass.fits");
+  if (N = get_argument (argc, argv, "-mass")) {
+    remove_argument (N, &argc, argv);
+    strcpy (massfile, argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  strcpy (agefile, "age.fits");
+  if (N = get_argument (argc, argv, "-age")) {
+    remove_argument (N, &argc, argv);
+    strcpy (agefile, argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  
+  if (argc < 2) {
+    fprintf (stderr, "USAGE: smaeder (filename) [options]\n");
+    fprintf (stderr, "  options:\n");
+    fprintf (stderr, "  [-metal N] (N = 0,1,2,3,4)\n");
+    fprintf (stderr, "  [-color min max delta] \n");
+    fprintf (stderr, "  [-mag min max delta] \n");
+    fprintf (stderr, "  [-mass file] \n");
+    fprintf (stderr, "  [-age file]\n");
+    exit (0);
+  }
+}
+
+/* read in the tracks for the requested metalicity */
+/* fairly dependent on the format of the files that Andy produces */
+readmaeder (maederfile, track, Ntrack)
+char  *maederfile;
+Track **track;
+int   *Ntrack;
+{
+
+  int i, j, m;
+  FILE *f;
+  char line[1024];
+  double U, V, ntrack, nmodel;
+
+  f = fopen (maederfile, "r");
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "couldn't find maeder tracks (%s)\n", maederfile);
+    exit (0);
+  }
+
+  for (m = 0; m < 5; m ++) {
+    scan_line (f, line);
+    dparse (&ntrack, 1, line);
+    *Ntrack = ntrack;
+    if (m == metal) {
+      ALLOCATE (track[0], Track, *Ntrack);
+    }
+    for (i = 0; i < ntrack; i++) {
+      scan_line (f, line);
+      dparse (&nmodel, 2, line);
+      if (m == metal) {
+	track[0][i].Nmodel = nmodel;
+	dparse (&track[0][i].mass, 1, line);
+	ALLOCATE (track[0][i].model, Model, track[0][i].Nmodel);
+      }
+      for (j = 0; j < nmodel; j++) {
+	scan_line (f, line);
+	if (m == metal) {
+	  dparse (&track[0][i].model[j].age, 1, line);
+	  track[0][i].model[j].age /= 1000000.0;   /* convert to Myrs */
+	  dparse (&U, col1, line);
+	  dparse (&V, col2, line);
+	  track[0][i].model[j].V = V;
+	  track[0][i].model[j].UV = U-V;
+	}
+      }
+    }
+  }
+  fclose (f);
+
+  if (dump > -1) {
+    if (dump >= *Ntrack) {
+      fprintf (stderr, "track %d not found\n", dump);
+      exit (0);
+    } 
+    for (i = 0; i < track[0][dump].Nmodel; i++) {
+      fprintf (stderr, "%d %d %f %e %f %f\n", 
+	       i, track[0][dump].Nmodel, track[0][dump].mass, track[0][dump].model[i].age,
+	       track[0][dump].model[i].V, track[0][dump].model[i].UV);
+    }
+    exit (0);
+  }
+
+}
+
+
+/* convert the tracks to smooth, monotonically increasing color tracks */
+smoothtracks (newtrack, track, Ntrack)
+Track **newtrack, *track;
+int Ntrack;
+{
+
+  int i, j, J1, J2, npts, done;
+  double minC, maxC, dadc, dmdc, age1, mag1, dcolor;
+  double resolution, c1, c2;
+  
+  fprintf (stderr, "smoothing..\n");
+  resolution = dUV;
+  ALLOCATE (newtrack[0], Track, Ntrack);
+  for (i = 0; i < Ntrack ; i++) {
+    /* find min & max colors */
+    minC = track[i].model[0].UV;
+    maxC = -1000;
+    for (j = 0; j < track[i].Nmodel; j++) {
+      maxC = MAX (track[i].model[j].UV, maxC);
+    }
+    npts = (int) ((maxC - minC) / resolution) + 1;
+    ALLOCATE (newtrack[0][i].model, Model, npts);
+    newtrack[0][i].mass = track[i].mass;
+    newtrack[0][i].Nmodel = npts;
+    for (j = 0; j < npts; j++) {
+      newtrack[0][i].model[j].UV = minC + resolution*j;
+    }
+    if (npts == 1) {
+      newtrack[0][i].model[0].age = track[i].model[0].age;
+      newtrack[0][i].model[0].V = track[i].model[0].V;
+      continue;
+    }
+    J1 = 0;
+    for (J2 = J1+1; (J2 < track[i].Nmodel) 
+	   && (track[i].model[J2].UV < track[i].model[J1].UV); J2++);
+    if (J2 == track[i].Nmodel) {
+      fprintf (stderr, "logical error 1\n");
+      exit (0);
+    }
+    dadc = (track[i].model[J2].age   - track[i].model[J1].age) /
+      (track[i].model[J2].UV - track[i].model[J1].UV);
+    dmdc = (track[i].model[J2].V   - track[i].model[J1].V) /
+      (track[i].model[J2].UV - track[i].model[J1].UV);
+    age1 = track[i].model[J1].age;
+    mag1 = track[i].model[J1].V;
+    for (j = 0; j < npts; j++) {
+      if (track[i].model[J2].UV < newtrack[0][i].model[j].UV) {
+	J1 = J2;
+	for (J2 = J1+1; (J2 < track[i].Nmodel) && ((track[i].model[J2].UV < track[i].model[J1].UV) || (track[i].model[J2].UV < newtrack[0][i].model[j].UV)); J2++) {
+	}
+	if (J2 == track[i].Nmodel) {
+	  fprintf (stderr, "logical error 2\n");
+	  exit (0);
+	}
+	dadc = (track[i].model[J2].age   - track[i].model[J1].age) /
+	       (track[i].model[J2].UV - track[i].model[J1].UV);
+	dmdc = (track[i].model[J2].V   - track[i].model[J1].V) /
+	       (track[i].model[J2].UV - track[i].model[J1].UV);
+	age1 = track[i].model[J1].age;
+	mag1 = track[i].model[J1].V;
+      }	
+      dcolor = newtrack[0][i].model[j].UV - track[i].model[J1].UV;
+      newtrack[0][i].model[j].age = dadc * dcolor + age1; 
+      newtrack[0][i].model[j].V = dmdc * dcolor + mag1; 
+    }
+  }
+  fprintf (stderr, "\n");
+
+  if (sdump > -1) {
+    if (sdump >= Ntrack) {
+      fprintf (stderr, "track %d not found\n", sdump);
+      exit (0);
+    }
+    for (i = 0; i < newtrack[0][sdump].Nmodel; i++) {
+      fprintf (stderr, "%d %f %e %f %f\n", 
+	       i, newtrack[0][sdump].mass, newtrack[0][sdump].model[i].age,
+	       newtrack[0][sdump].model[i].V, newtrack[0][sdump].model[i].UV);
+    }
+    exit (0);
+  }
+  
+}
+
+interpolate_tracks (newtrack, Ntrack)
+Track *newtrack;
+int Ntrack;
+{
+ 
+  Header mass_h, age_h;
+  Matrix mass_i, age_i;
+  double Ms, As, Vs, dM, dA, DV, m, a, a1, a2, m1, m2, v, dummy, tmp;
+  double d, minD, uv;
+  int i, j, k, J1, Sx, Sy, Ey;
+  int ii, I0, I1;
+
+  mass_h.bitpix = -32;
+  mass_h.Naxes = 2;
+  mass_h.Naxis[0] = (UV1 - UV0) / dUV;
+  mass_h.Naxis[1] = fabs((V1 - V0) / dV);
+  mass_h.bzero = 0.0;
+  mass_h.bscale = 1.0;
+  mass_h.unsign = FALSE;
+  mass_h.extend = FALSE;
+
+  age_h.bitpix = -32;
+  age_h.Naxes = 2;
+  age_h.Naxis[0] = (UV1 - UV0) / dUV;
+  age_h.Naxis[1] = fabs((V1 - V0) / dV);
+  age_h.bzero = 0.0;
+  age_h.bscale = 1.0;
+  age_h.unsign = FALSE;
+  age_h.extend = FALSE;
+
+  gfits_create_header (&mass_h);
+  gfits_create_matrix (&mass_h, &mass_i);
+  gfits_create_header (&age_h);
+  gfits_create_matrix (&age_h, &age_i);
+  fprintf (stderr, "created FITS buffers\n");
+
+  for (i = 1; i < Ntrack; i++) {
+    fprintf (stderr, "%d  %d\n", i, newtrack[i].Nmodel);
+    J1 = 0;
+    for (j = 0; j < newtrack[i].Nmodel; j++) {
+      if ((newtrack[i].model[j].V < V0) &&
+	  (newtrack[i].model[j].V > V1) &&
+	  (newtrack[i].model[j].UV > UV0) &&
+	  (newtrack[i].model[j].UV < UV1)) {
+	while ((J1 < newtrack[i-1].Nmodel - 1) && ((int)((newtrack[i].model[j].UV  - UV0) / dUV) > (int)((newtrack[i-1].model[J1].UV  - UV0) / dUV))) {
+	  J1++;
+	}
+	uv = newtrack[i].model[j].UV;
+	Sx = (newtrack[i].model[j].UV  - UV0) / dUV;
+	Sy = (newtrack[i].model[j].V   -  V0) / dV;
+	if (newtrack[i].model[j].UV < newtrack[i-1].model[0].UV) {
+	  tmp = (uv - newtrack[i-1].model[0].UV) / (newtrack[i].model[0].UV -  newtrack[i-1].model[0].UV);
+	  Vs = newtrack[i-1].model[0].V +  tmp * (newtrack[i].model[0].V -  newtrack[i-1].model[0].V);
+	}
+	else {
+	  Vs = newtrack[i-1].model[J1].V;
+	}
+	Ey = (Vs - V0) / dV;
+	if ((j > 20) && (J1 > 20)) {
+	  Vs = newtrack[i-1].model[J1].V;
+	  Ms = newtrack[i-1].mass;
+	  As = newtrack[i-1].model[J1].age;
+	  Ey = (newtrack[i-1].model[J1].V - V0) / dV;
+	  DV = newtrack[i].model[j].V - Vs;
+	  dM = newtrack[i].mass - Ms;
+	  dA = newtrack[i].model[j].age - As;
+	  for (k = Sy; (k >= Ey) && (k >= 0); k--) {
+	    v = k*dV + V0;
+	    m = (v - Vs) * dM / DV + Ms;
+	    a = (v - Vs) * dA / DV + As;
+	    gfits_set_matrix_value (&mass_i, Sx, k, m);
+	    gfits_set_matrix_value (&age_i, Sx, k, a);
+	  }
+	}
+	else {
+	  for (k = Sy; (k >= Ey) && (k >= 0); k--) {
+	    v = k*dV + V0;
+	    minD = 1000;
+	    for (ii = 0; (ii < newtrack[i].Nmodel); ii++) {
+	      I0 = MIN (ii, 20);
+	      tmp = 1.0 / hypot(newtrack[i].model[ii].V - newtrack[i-1].model[I0].V, newtrack[i].model[ii].UV - newtrack[i-1].model[I0].UV);
+	      d = -tmp * ((newtrack[i].model[ii].UV - newtrack[i-1].model[I0].UV)*(v - newtrack[i-1].model[I0].V) - 
+			  (newtrack[i].model[ii].V - newtrack[i-1].model[I0].V)*(uv - newtrack[i-1].model[I0].UV));
+	      if ((d > 0) && (d < minD)) {
+		I1 = ii;
+		minD = d;
+	      }
+	      if (d > minD) {
+		break;
+	      }
+	    }
+	    I0 = MIN (I1, 20);
+	    tmp = ((newtrack[i].model[I1].UV - newtrack[i-1].model[I0].UV)*(uv - newtrack[i-1].model[I0].UV) + 
+		   (newtrack[i].model[I1].V - newtrack[i-1].model[I0].V)*(v - newtrack[i-1].model[I0].V)) / 
+	      hypot(newtrack[i].model[I1].V - newtrack[i-1].model[I0].V, newtrack[i].model[I1].UV - newtrack[i-1].model[I0].UV);
+	    d = tmp / hypot (newtrack[i].model[I1].V - newtrack[i-1].model[I0].V, newtrack[i].model[I1].UV - newtrack[i-1].model[I0].UV);
+	    dM = newtrack[i].mass - newtrack[i-1].mass;
+	    dA = newtrack[i].model[I1].age - newtrack[i-1].model[I0].age;
+	    m1 = d * dM + newtrack[i-1].mass;
+	    a1 = d * dA + newtrack[i-1].model[I0].age;
+	    /*	    fprintf (stderr, "%d  %f  %f  %f  %f  %f\n", I1, minD, d, tmp, dM, m1); */
+	    
+	    tmp = ((newtrack[i].model[I1+1].UV - newtrack[i-1].model[I0+1].UV)*(uv - newtrack[i-1].model[I0+1].UV) + 
+		   (newtrack[i].model[I1+1].V - newtrack[i-1].model[I0+1].V)*(v - newtrack[i-1].model[I0+1].V)) / 
+	      hypot(newtrack[i].model[I1+1].V - newtrack[i-1].model[I0+1].V, newtrack[i].model[I1+1].UV - newtrack[i-1].model[I0+1].UV);
+	    d = tmp / hypot (newtrack[i].model[I1+1].V - newtrack[i-1].model[I0+1].V, newtrack[i].model[I1+1].UV - newtrack[i-1].model[I0+1].UV);
+	    dM = newtrack[i].mass - newtrack[i-1].mass;
+	    dA = newtrack[i].model[I1+1].age - newtrack[i-1].model[I0+1].age;
+	    m2 = d * dM + newtrack[i-1].mass;
+	    a2 = d * dA + newtrack[i-1].model[I0+1].age;
+
+	    d = -((newtrack[i].model[I1].UV - newtrack[i-1].model[I0].UV)*(v - newtrack[i-1].model[I0].V) - 
+		 (newtrack[i].model[I1].V - newtrack[i-1].model[I0].V)*(uv - newtrack[i-1].model[I0].UV))
+	      / hypot(newtrack[i].model[I1].V - newtrack[i-1].model[I0].V, newtrack[i].model[I1].UV - newtrack[i-1].model[I0].UV);
+	    tmp = ((newtrack[i].model[I1+1].UV - newtrack[i-1].model[I0+1].UV)*(v - newtrack[i-1].model[I0+1].V) - 
+		 (newtrack[i].model[I1+1].V - newtrack[i-1].model[I0+1].V)*(uv - newtrack[i-1].model[I0+1].UV))
+	      / hypot(newtrack[i].model[I1+1].V - newtrack[i-1].model[I0+1].V, newtrack[i].model[I1+1].UV - newtrack[i-1].model[I0+1].UV);
+
+	    a = d * (a2 - a1) / (d + tmp) + a1;
+	    m = d * (m2 - m1) / (d + tmp) + m1;
+	    gfits_set_matrix_value (&mass_i, Sx, k, m);
+	    gfits_set_matrix_value (&age_i, Sx, k, a);
+	  }
+	}
+      }
+    }
+  }
+  /*   
+  for (i = 1; i < Ntrack; i++) {
+    fprintf (stderr, "%d  %d\n", i, newtrack[i].Nmodel);
+    for (j = 0; j < newtrack[i].Nmodel; j++) {
+      if ((newtrack[i].model[j].V < V0) &&
+	  (newtrack[i].model[j].V > V1) &&
+	  (newtrack[i].model[j].UV > UV0) &&
+	  (newtrack[i].model[j].UV < UV1)) {
+	Sx = (newtrack[i].model[j].UV  - UV0) / dUV;
+	Sy = (newtrack[i].model[j].V   -  V0) / dV;
+	gfits_set_matrix_value (&age_i, Sx, Sy, 1000.0);
+	gfits_set_matrix_value (&mass_i, Sx, Sy, 1000.0);
+      }
+    }
+  }
+  */
+
+  gfits_modify (&mass_h, "RA_O", "%lf", 1, UV0);
+  gfits_modify (&mass_h, "RA_X", "%lf", 1, dUV);
+  gfits_modify (&mass_h, "RA_Y", "%lf", 1, 0.0);
+  gfits_modify (&mass_h, "DEC_O", "%lf", 1, V0);
+  gfits_modify (&mass_h, "DEC_Y", "%lf", 1, dV);
+  gfits_modify (&mass_h, "DEC_X", "%lf", 1, 0.0);
+
+  gfits_write_header (massfile, &mass_h);
+  gfits_write_matrix (massfile, &mass_i);
+
+  gfits_modify (&age_h, "RA_O",  "%lf", 1, UV0);
+  gfits_modify (&age_h, "RA_X",  "%lf", 1, dUV);
+  gfits_modify (&age_h, "RA_Y",  "%lf", 1, 0.0);
+  gfits_modify (&age_h, "DEC_O", "%lf", 1, V0);
+  gfits_modify (&age_h, "DEC_Y", "%lf", 1, dV);
+  gfits_modify (&age_h, "DEC_X", "%lf", 1, 0.0);
+
+  gfits_write_header (agefile, &age_h);
+  gfits_write_matrix (agefile, &age_i);
+
+}
+
+/*
+ 	  minD = 1000;
+	  for (ii = 0; ii < newtrack[i-1].Nmodel; ii++) {
+	    d = hypot(newtrack[i-1].model[ii].V - v, newtrack[i-1].model[ii].UV - uv);
+	    if (d < minD) {
+	      I0 = ii;
+	      minD = d;
+	    }
+	  }
+	  minD = 1000;
+	  for (ii = 0; ii < newtrack[i].Nmodel; ii++) {
+	    d = hypot(newtrack[i].model[ii].V - v, newtrack[i].model[ii].UV - uv);
+	    if (d < minD) {
+	      I1 = ii;
+	      minD = d;
+	    }
+	  }
+ for (i = 1; i < Ntrack; i++) {
+    fprintf (stderr, "%d  %d\n", i, newtrack[i].Nmodel);
+    J1 = 0;
+    for (j = 0; j < newtrack[i].Nmodel; j++) {
+      if ((newtrack[i].model[j].V < V0) &&
+	  (newtrack[i].model[j].V > V1) &&
+	  (newtrack[i].model[j].UV > UV0) &&
+	  (newtrack[i].model[j].UV < UV1)) {
+	while ((J1 < newtrack[i-1].Nmodel - 1) && ((int)((newtrack[i].model[j].UV  - UV0) / dUV) > (int)((newtrack[i-1].model[J1].UV  - UV0) / dUV))) {
+	  J1++;
+	}
+	Sx = (newtrack[i].model[j].UV  - UV0) / dUV;
+	Sy = (newtrack[i].model[j].V   -  V0) / dV;
+	if (newtrack[i].model[j].UV < newtrack[i-1].model[0].UV) {
+	  tmp = (newtrack[i].model[j].UV - newtrack[i-1].model[0].UV) / (newtrack[i].model[0].UV -  newtrack[i-1].model[0].UV);
+	  Vs = newtrack[i-1].model[0].V +  tmp * (newtrack[i].model[0].V -  newtrack[i-1].model[0].V);
+	  As = newtrack[i-1].model[0].age + tmp * (newtrack[i].model[0].age -  newtrack[i-1].model[0].age);
+	  Ms = newtrack[i-1].mass + tmp * (newtrack[i].mass - newtrack[i-1].mass);
+	  Ey = (Vs  - V0) / dV;
+	}
+	else {
+	  Vs = newtrack[i-1].model[J1].V;
+	  Ms = newtrack[i-1].mass;
+	  As = newtrack[i-1].model[J1].age;
+	  Ey = (newtrack[i-1].model[J1].V - V0) / dV;
+	}
+	DV = newtrack[i].model[j].V - Vs;
+	dM = newtrack[i].mass - Ms;
+	dA = newtrack[i].model[j].age - As;
+	for (k = Sy; (k >= Ey) && (k >= 0); k--) {
+	  v = k*dV + V0;
+	  m = (v - Vs) * dM / DV + Ms;
+	  gfits_set_matrix_value (&mass_i, Sx, k, m);
+	  a = (v - Vs) * dA / DV + As;
+	  gfits_set_matrix_value (&age_i, Sx, k, a);
+	}
+      }
+    }
+  }
+*/
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/string.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/string.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/string.c	(revision 21897)
@@ -0,0 +1,113 @@
+# include <ohana.h>
+
+/* Strip WHITESPACE from the start and end of STRING. */
+int stripwhite (string)
+char *string;
+{
+  int i;
+
+  if (string == (char *) NULL)
+    return (FALSE);
+
+  for (i = 0; OHANA_WHITESPACE (string[i]); i++);
+  if (i) memmove (string, string + i, strlen(string+i)+1);
+  for (i = strlen (string) - 1; (i > 0) && OHANA_WHITESPACE (string[i]); i--);
+  string[++i] = 0;
+  return (i);
+
+}
+
+/* create a new string from this string */
+char *strcreate (string)
+char *string;
+{
+
+  char *line;
+
+  if (string == (char *) NULL) return ((char *) NULL);
+  
+  ALLOCATE (line, char, MAX (1, strlen(string)) + 1);
+  line = strcpy (line, string);
+
+  return (line);
+
+}
+
+/* create a new string of length n from this string */
+char *strncreate (string, n)
+char *string;
+int   n;
+{
+
+  char *line;
+
+  if (string == (char *) NULL) return ((char *) NULL);
+  
+  ALLOCATE (line, char, n + 1);
+  memmove (line, string, n);
+  line[n] = 0;
+  return (line);
+
+}
+
+int scan_line (f, line) 
+FILE *f;
+char line[];
+{
+
+  int i, status;
+  char c;
+  
+  status = EOF + 1;
+  
+  for (i = 0, c = 0; (c != '\n') && (status != EOF); i++) {
+    status = fscanf (f, "%c", &c);
+    line[i] = c;
+  }
+  line[i - 1] = 0;  /* this could make things crash! */
+
+  if (i > 1) {
+    status = EOF + 1;
+  }
+
+  return (status);
+
+}
+
+char *_parse_nextword(string)
+char *string;
+{
+  if (string == (char *) NULL) return ((char *) NULL);
+
+  for (; isspace (*string); string++);
+  for (; (*string != 0) && !isspace (*string); string++);
+  for (; isspace (*string); string++);
+  return (string);
+}
+
+int dparse (X, NX, line)
+double *X;
+int NX;
+char *line;
+{
+
+  int i;
+  char *word;
+  char *ptr;
+
+  word = line;
+  for (i = 0; i < NX - 1; i++)
+    word = _parse_nextword (word);
+
+  *X = strtod (word, &ptr);
+  if (ptr == word)
+    return (FALSE);
+  else {
+    if (word[0] == '-') 
+      return (-1);
+    else
+      return (1);
+  }
+}
+
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/striphead.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/striphead.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/striphead.c	(revision 21897)
@@ -0,0 +1,64 @@
+# include <ohana.h>
+
+main (argc, argv) 
+int argc;
+char *argv[];
+{
+
+  int i, j, status, N, FORCE;
+  char head[1000];
+  Header header;
+  char *p;
+  FILE *f;
+
+  if (get_argument (argc, argv, "-help") || get_argument (argc, argv, "-h")) {
+    fprintf (stderr, "USAGE: %s [-f] (filenames)\n", argv[0]);
+    exit (0);
+  }
+
+  if (N = get_argument (argc, argv, "-f")) {
+    remove_argument (N, &argc, argv);
+    FORCE = TRUE;
+  }
+  else 
+    FORCE = FALSE;
+  
+  if (argc == 1) {
+    fprintf (stderr, "USAGE: %s [-f] (filenames)\n", argv[0]);
+    exit (0);
+  }
+
+  for (i = 1; i < argc; i++) {
+    
+    strcpy (head, argv[i]);
+    if (strrchr(head, '.') !=NULL)
+      strcpy(strrchr(head, '.'), ".head");
+    else 
+      strcat(head, ".head");
+    
+    if (!FORCE) {
+      f = fopen (head, "r");
+      if (f != NULL) {
+	fprintf (stderr, "header file exists for %s, skipping\n", argv[i]);
+	fclose (f);
+	continue;
+      }
+    }
+    
+    if (!gfits_read_header (argv[i], &header)) {
+      fprintf (stderr, "failed to open file %s\n", argv[i]);
+      continue;
+    }
+    
+    for (j = 79; j < header.size; j+= 80) {
+      header.buffer[j] = 10;
+    }
+
+    if (!gfits_write_header (head, &header)) {
+      fprintf (stderr, "failed to write file %s\n", head);
+      continue;
+    }
+    
+    gfits_free_header (&header);
+  }
+}
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/test.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/test.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/test.c	(revision 21897)
@@ -0,0 +1,74 @@
+# include <stdio.h>
+# include <gfitsio.h>
+# include <math.h>
+# include <malloc.h>
+# include <string.h>
+# include <sys/time.h>
+# include <stdarg.h>
+# include <stdlib.h>
+# include <readline/readline.h>
+# include <readline/history.h>
+
+# define TRUE (1)
+# define FALSE (0)
+# define SIGN(X)  (((X) == 0) ? 0 : ((fabs((double)(X))) / (X)))
+# define ROUND(X) ((int) ((X) + 0.5*SIGN(X)))
+# define SQR(X)   (double) (((double)(X))*((double)(X)))
+# define SQ(X)    (double) (((double)(X))*((double)(X)))
+# define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
+# define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
+# define SWAP(X,Y) {double tmp=(X); (X) = (Y); (Y) = tmp;}
+# define ISVAR(a) (isalnum (a) || (a == '.') || (a == '_'))
+# define ISWORD(a,q) ((q) ? (a != '"') : (isalnum(a) || (a == '.') || (a == '_') || (a == '-')))
+# define ISNUM(c) (isdigit(c) || (c == '-') || (c == '.'))
+
+/* Strip WHITESPACE from the start and end of STRING. */
+int stripwhite (string)
+char *string;
+{
+  int i;
+
+  if (string == (char *) NULL)
+    return (0);
+
+  for (i = 0; OHANA_WHITESPACE (string[i]); i++);
+
+  if (i)
+    strcpy (string, string + i);
+
+  i = strlen (string) - 1;
+
+  for (; (i > 0) && OHANA_WHITESPACE (string[i]); i--);
+
+  string[++i] = 0;
+
+  return (i);
+
+}
+
+void main (int argc, char **argv) {
+
+  int i, j, nbytes;
+  Header header;
+  char filename[1000], buffer[1000];
+  char *p;
+
+  /* fprintf (stderr, "starting\n"); */
+  while (fscanf (stdin, "%s", filename) != EOF) {
+    if (!gfits_read_header (filename, &header)) continue;
+    fprintf (stdout, "%s  ", filename);
+    for (i = 1; i < argc; i++) {
+      bzero (buffer, 1000);
+      gfits_scan (&header, argv[i], "%s", 1, buffer);
+      stripwhite (buffer);
+      fprintf (stdout, "%s  ", buffer);
+    }
+    fprintf (stdout, "\n");
+
+    gfits_free_header (&header);
+
+  }
+
+}
+
+
Index: /tags/ohana/misc-1-4-0/Ohana/src/misc/src/usmaeder.c
===================================================================
--- /tags/ohana/misc-1-4-0/Ohana/src/misc/src/usmaeder.c	(revision 21897)
+++ /tags/ohana/misc-1-4-0/Ohana/src/misc/src/usmaeder.c	(revision 21897)
@@ -0,0 +1,191 @@
+# include <ohana.h>
+
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+
+  Header mass_h, age_h, UV_h, V_h;
+  Matrix mass_i, age_i, UV_i, V_i;
+  int x, y, X, Y, X0, X1, Y0, Y1, NAGE, NMASS, N;
+  double ldA, lAo, ldM, lMo, age, mass;
+  double v, uv, UV0, DUV, V0, DV, slope_x, slope_y, tmp;
+  
+  lAo =   0.0;
+  ldA =   0.01;
+  NAGE =  320;
+  if (N = get_argument (argc, argv, "-age")) {
+    remove_argument (N, &argc, argv);
+    lAo = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    ldA = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    NAGE = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  lMo = -0.1;
+  ldM =  0.05;
+  NMASS = 50;
+  if (N = get_argument (argc, argv, "-mass")) {
+    remove_argument (N, &argc, argv);
+    lMo = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    ldM = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    NMASS = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 5) {
+    fprintf (stderr, "USAGE %s massfile agefile colorfile magfile\n", argv[0]);
+    fprintf (stderr, "  options:\n");
+    fprintf (stderr, "  [-mass lMo ldM NMASS]\n");
+    fprintf (stderr, "  [-age  lAo ldA NAGE]\n");
+    exit (0);
+  }
+
+  gfits_read_header (argv[1], &mass_h);
+  gfits_read_matrix (argv[1], &mass_i);
+  gfits_read_header (argv[2], &age_h);
+  gfits_read_matrix (argv[2], &age_i); 
+
+  gfits_scan (&mass_h, "RA_O",  "%lf", 1, &UV0);
+  gfits_scan (&mass_h, "RA_X",  "%lf", 1, &DUV);
+  gfits_scan (&mass_h, "DEC_O", "%lf", 1, &V0);
+  gfits_scan (&mass_h, "DEC_Y", "%lf", 1, &DV);
+
+  V_h.bitpix = -32;
+  V_h.Naxes = 2;
+  V_h.Naxis[0] = NAGE;
+  V_h.Naxis[1] = NMASS;
+  V_h.bzero = 0.0;
+  V_h.bscale = 1.0;
+  V_h.unsign = FALSE;
+  V_h.extend = FALSE;
+
+  UV_h.bitpix = -32;
+  UV_h.Naxes = 2;
+  UV_h.Naxis[0] = NAGE;
+  UV_h.Naxis[1] = NMASS;
+  UV_h.bzero = 0.0;
+  UV_h.bscale = 1.0;
+  UV_h.unsign = FALSE;
+  UV_h.extend = FALSE;
+
+  gfits_create_header (&V_h);
+  gfits_create_matrix (&V_h, &V_i);
+  gfits_create_header (&UV_h);
+  gfits_create_matrix (&UV_h, &UV_i);
+  fprintf (stderr, "created FITS buffers\n");
+
+  gfits_modify (&V_h, "RA_O", "%lf", 1, lAo);
+  gfits_modify (&V_h, "RA_X", "%lf", 1, ldA);
+  gfits_modify (&V_h, "RA_Y", "%lf", 1, 0.0);
+  gfits_modify (&V_h, "DEC_O", "%lf", 1, lMo);
+  gfits_modify (&V_h, "DEC_Y", "%lf", 1, ldM);
+  gfits_modify (&V_h, "DEC_X", "%lf", 1, 0.0);
+
+  gfits_modify (&UV_h, "RA_O",  "%lf", 1, lAo);
+  gfits_modify (&UV_h, "RA_X",  "%lf", 1, ldA);
+  gfits_modify (&UV_h, "RA_Y",  "%lf", 1, 0.0);
+  gfits_modify (&UV_h, "DEC_O", "%lf", 1, lMo);
+  gfits_modify (&UV_h, "DEC_Y", "%lf", 1, ldM);
+  gfits_modify (&UV_h, "DEC_X", "%lf", 1, 0.0);
+
+  /* the value of 100 is hard wired in this and the others as a bad color */
+
+  for (x = 0; x < NAGE; x++) {
+    for (y = 0; y < NMASS; y++) {
+      gfits_set_matrix_value (&UV_i, x, y, 100.0); 
+      gfits_set_matrix_value (&V_i, x, y, 100.0); 
+    }
+  }
+
+  for (x = 0; x < mass_h.Naxis[0]; x++) {
+    fprintf (stderr, ".");
+    for (y = 0; y < mass_h.Naxis[1]; y++) {
+      mass = gfits_get_matrix_value (&mass_i, x, y);
+      age = gfits_get_matrix_value (&age_i, x, y); 
+      if (mass > 0) {
+	X = (log10(age) - lAo) / ldA;
+	Y = (log10(mass) - lMo) / ldM;
+	if ((X >= 0) && (X < NAGE) &&
+	    (Y >= 0) && (Y < NMASS)) {
+	  uv = x*DUV + UV0;
+	  v  = y*DV + V0;
+	  gfits_set_matrix_value (&UV_i, X, Y, uv); 
+	  gfits_set_matrix_value (&V_i, X, Y, v); 
+	}
+      }
+    }
+  }
+  fprintf (stderr, "\n");
+
+  /* fix the holes */
+  for (x = 0; x < NAGE; x++) {
+    for (y = 0; y < NMASS; y++) {
+      uv = gfits_get_matrix_value (&UV_i, x, y);
+      if (uv == 100.0) {
+	/* find neighbors up and down */
+	X1 = NAGE; Y1 = NMASS;
+	X0 = Y0 = -1;
+	for (X = x + 1; X < NAGE; X++) {
+	  if ((gfits_get_matrix_value (&UV_i, X, y)) != 100.0) {
+	    X1 = X;
+	    break;
+	  }
+	}
+	for (X = x - 1; X >= 0; X--) {
+	  if ((gfits_get_matrix_value (&UV_i, X, y)) != 100.0) {
+	    X0 = X;
+	    break;
+	  }
+	}
+	for (Y = y + 1; Y < NMASS; Y++) {
+	  if ((gfits_get_matrix_value (&UV_i, x, Y)) != 100.0) {
+	    Y1 = Y;
+	    break;
+	  }
+	}
+	for (Y = y - 1; Y >= 0; Y--) {
+	  if ((gfits_get_matrix_value (&UV_i, x, Y)) != 100.0) {
+	    Y0 = Y;
+	    break;
+	  }
+	}
+	slope_x = slope_y = 100000.0;
+	if ((X1 < NAGE) && (X0 > -1)) {
+	  slope_x = (gfits_get_matrix_value (&UV_i, X1, y) - gfits_get_matrix_value (&UV_i, X0, y)) / (X1 - X0);
+	}
+	if ((Y1 < NMASS) && (Y0 > -1)) {
+	  slope_y = (gfits_get_matrix_value (&UV_i, x, Y1) - gfits_get_matrix_value (&UV_i, x, Y0)) / (Y1 - Y0);
+	}
+	if ((fabs(slope_x) < fabs(slope_y)) && (slope_x != 100000.0)) {
+	  uv = (x - X0) * slope_x + gfits_get_matrix_value (&UV_i, X0, y);
+	  tmp = (gfits_get_matrix_value (&V_i, X1, y) - gfits_get_matrix_value (&V_i, X0, y)) / (X1 - X0);
+	  v  = (x - X0) * tmp + gfits_get_matrix_value (&V_i, X0, y);
+	  gfits_set_matrix_value (&UV_i, x, y, uv); 
+	  gfits_set_matrix_value (&V_i, x, y, v); 
+	}	  
+	if ((fabs(slope_x) >= fabs(slope_y)) && (slope_y != 100000.0)) {
+	  uv = (y - Y0) * slope_y + gfits_get_matrix_value (&UV_i, x, Y0);
+	  tmp = (gfits_get_matrix_value (&V_i, x, Y1) - gfits_get_matrix_value (&V_i, x, Y0)) / (Y1 - Y0);
+	  v  = (y - Y0) * tmp + gfits_get_matrix_value (&V_i, x, Y0);
+	  gfits_set_matrix_value (&UV_i, x, y, uv); 
+	  gfits_set_matrix_value (&V_i, x, y, v); 
+	}	  
+      }
+    }
+  }
+	
+
+
+  gfits_write_header (argv[3], &V_h);
+  gfits_write_matrix (argv[3], &V_i);
+  gfits_write_header (argv[4], &UV_h);
+  gfits_write_matrix (argv[4], &UV_i);
+
+}
+
