Index: /branches/delstar-1-7/Ohana/src/delstar/Makefile
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/Makefile	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/Makefile	(revision 10346)
@@ -0,0 +1,42 @@
+default: delstar
+help:
+	@echo "make options: addstar (default)"
+
+include ../../Configure
+HOME 	=	$(ROOT)/src/delstar
+BIN	=	$(HOME)/bin
+LIB	=	$(HOME)/lib
+INC	= 	$(HOME)/include
+SRC	=	$(HOME)/src
+MAN	=	$(HOME)/doc
+include ../../Makefile.Common
+
+CFLAGS	:=	$(CFLAGS) -fPIC
+LDFLAGS := 	-ldvo -lFITS -lohana $(LDFLAGS)
+
+delstar: $(BIN)/delstar.$(ARCH)
+install: $(DESTBIN)/delstar
+
+DELSTAR = \
+$(SRC)/delstar.$(ARCH).o          \
+$(SRC)/SetSignals.$(ARCH).o       \
+$(SRC)/ConfigInit.$(ARCH).o 	  \
+$(SRC)/args.$(ARCH).o	          \
+$(SRC)/delete_imagename.$(ARCH).o \
+$(SRC)/delete_imagefile.$(ARCH).o \
+$(SRC)/delete_times.$(ARCH).o 	  \
+$(SRC)/gimages.$(ARCH).o   	  \
+$(SRC)/find_image_db.$(ARCH).o    \
+$(SRC)/find_matches.$(ARCH).o 	  \
+$(SRC)/parse_time.$(ARCH).o       \
+$(SRC)/sort_lists.$(ARCH).o \
+$(SRC)/check_permissions.$(ARCH).o \
+$(SRC)/Shutdown.$(ARCH).o          
+
+OLD = \
+$(SRC)/gregion_image.$(ARCH).o    \
+$(SRC)/gregion_patch.$(ARCH).o    \
+$(SRC)/RegionOps.$(ARCH).o   	  
+
+$(DELSTAR): $(INC)/delstar.h
+$(BIN)/delstar.$(ARCH) : $(DELSTAR)
Index: /branches/delstar-1-7/Ohana/src/delstar/bin/.cvsignore
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/bin/.cvsignore	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/bin/.cvsignore	(revision 10346)
@@ -0,0 +1,2 @@
+*.linux *.lin64 *.sol *.sun *.sid *.hp *.irix
+*.linrh
Index: /branches/delstar-1-7/Ohana/src/delstar/doc/ChangeLog.txt
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/doc/ChangeLog.txt	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/doc/ChangeLog.txt	(revision 10346)
@@ -0,0 +1,20 @@
+
+- delstar 1.6 : 
+  * converted to gfits APIs (forces libfits 1.6)
+  * converted to new DVO APIs (forces libdvo 1.3)
+  * removed unused code
+
+- delstar 1.5 : 2006.03.26
+  * dropped IMAGE_CATALOG from config
+  * convert to dvo_image_lock,unlock
+
+- delstar 1.4 : 2006.01.06
+  * major work to support SkyRegions
+  * cleaned up signed/unsigned inconsistencies
+
+2005.10.20 : delstar.1-3
+
+    This release keeps delstar in sync with addstar v1.3.  Support is
+    added for the different modes and formats, and for the new
+    internal data types (eg, mags, not millimags).
+
Index: /branches/delstar-1-7/Ohana/src/delstar/include/addstar.h
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/include/addstar.h	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/include/addstar.h	(revision 10346)
@@ -0,0 +1,13 @@
+# include <ohana.h>
+# include <dvo.h>
+
+/* global variables set in parameter file */
+char   ImageCat[256];
+char   ImageTemplate[256];
+char   CatTemplate[256];
+char   GSCFILE[256];
+char   CATDIR[256];
+double NSIGMA;
+double ALPHA;
+int    VERBOSE;
+
Index: /branches/delstar-1-7/Ohana/src/delstar/include/delstar.h
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/include/delstar.h	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/include/delstar.h	(revision 10346)
@@ -0,0 +1,73 @@
+# include <ohana.h>
+# include <dvo.h>
+# include <signal.h>
+
+typedef struct {
+  Coords coords;
+  float *X, *Y;
+  int *N;
+  double RA[2], DEC[2];
+  double Area, density, spacing;
+} CatStats;
+
+/* global variables set in parameter file */
+char   ImageCat[256];
+char   ImageTemplate[256];
+char   CatTemplate[256];
+char   GSCFILE[256];
+char   CATDIR[256];
+char   CATMODE[16];    /* raw, mef, split, mysql */
+char   CATFORMAT[16];  /* internal, elixir, loneos, panstarrs */
+double NSIGMA;
+double ALPHA;
+int    VERBOSE;
+int    ORPHAN;
+int    MISSED;
+char   SKY_TABLE[256];
+int    SKY_DEPTH;  /** XXX EAM : depth of catalog tables, fix usage */
+
+time_t    START;
+time_t    END;
+PhotCode *PHOTCODE;
+
+int    MODE;
+enum {MODE_IMAGENAME, MODE_IMAGEFILE, MODE_TIME, MODE_ORPHAN, MODE_MISSED};
+
+char DateKeyword[64], DateMode[64], UTKeyword[64], MJDKeyword[64], JDKeyword[64];
+
+/*** delstar prototypes ***/
+void       ConfigInit             PROTO((int *argc, char **argv));
+int        FindDecBand            PROTO((double dec, double *DEC0, double *DEC1));
+FILE      *GetDB                  PROTO((int *state));
+Image     *GetImages              PROTO((int *nimage));
+int        SetImages              PROTO((Image *new, int Nnew));
+void       SetProtect             PROTO((int mode));
+int        SetSignals             PROTO(());
+int        Shutdown               PROTO((char *format, ...));
+void       TrapSignal             PROTO((int sig));
+int        args                   PROTO((int *argc, char **argv));
+void       check_permissions      PROTO((char *basefile));
+void       delete_imagefile       PROTO((FITS_DB *db, char *filename));
+void       delete_imagename       PROTO((FITS_DB *db, char *name));
+void       delete_times           PROTO((FITS_DB *db));
+int        edge_check             PROTO((double *x1, double *y1, double *x2, double *y2));
+int       *find_images_data       PROTO((FITS_DB *db, Image *timage, int *nlist));
+int       *find_images_name       PROTO((FITS_DB *db, char *filename, int *nlist));
+int       *find_images_time       PROTO((FITS_DB *db, time_t start, time_t end, PhotCode *code, int *nlist));
+void       find_matches           PROTO((Catalog *catalog, int photcode, int start, int end));
+int        gcatalog               PROTO((Catalog *catalog));
+Image     *gimages                PROTO((char *filename));
+Image     *gtimes                 PROTO((int *NIMAGE));
+void       help                   PROTO(());
+int        load_image_db          PROTO((FITS_DB *db));
+void       lock_image_db          PROTO((FITS_DB *db, char *filename));
+void       match_images           PROTO((Catalog *catalog, Image *image, int Nimage));
+double     opening_angle          PROTO((double x1, double y1, double x2, double y2, double x3, double y3));
+int        parse_time             PROTO((Header *header));
+int        save_image_db          PROTO(());
+void       sort_lists             PROTO((float *X, float *Y, int *S, int N));
+void       unlock_image_db        PROTO((FITS_DB *db));
+void       usage                  PROTO(());
+int        wcatalog               PROTO((Catalog *catalog));
+
+void set_db (FITS_DB *in);
Index: /branches/delstar-1-7/Ohana/src/delstar/src/ConfigInit.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/ConfigInit.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/ConfigInit.c	(revision 10346)
@@ -0,0 +1,51 @@
+# include "delstar.h"
+
+void ConfigInit (int *argc, char **argv) {
+
+  char *config, *file;
+  char PhotCodeFile[256];
+
+  /*** load 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 (1);
+  }
+  if (VERBOSE) fprintf (stderr, "loaded config file: %s\n", file);
+
+  ScanConfig (config, "NSIGMA",                 "%lf", 0, &NSIGMA);
+  ScanConfig (config, "ALPHA",                  "%lf", 0, &ALPHA);
+  ScanConfig (config, "GSCFILE",                "%s", 0, GSCFILE);
+  ScanConfig (config, "CATDIR",                 "%s", 0, CATDIR);
+  ScanConfig (config, "CATMODE",                "%s",  0, CATMODE);
+  ScanConfig (config, "CATFORMAT",              "%s",  0, CATFORMAT);
+  ScanConfig (config, "PHOTCODE_FILE",          "%s", 0, PhotCodeFile);
+
+  sprintf (ImageCat, "%s/Images.dat", CATDIR);
+
+  ScanConfig (config, "DATE-KEYWORD",           "%s", 0, DateKeyword);
+  ScanConfig (config, "DATE-MODE",              "%s", 0, DateMode);
+  ScanConfig (config, "UT-KEYWORD",             "%s", 0, UTKeyword);
+  ScanConfig (config, "MJD-KEYWORD",            "%s", 0, MJDKeyword);
+  ScanConfig (config, "JD-KEYWORD",             "%s", 0, JDKeyword);
+
+  if (!ScanConfig (config, "SKY_DEPTH",         "%d",  0, &SKY_DEPTH)) {
+    SKY_DEPTH = 2;
+  }
+  if (!ScanConfig (config, "SKY_TABLE",         "%s",  0, SKY_TABLE)) {
+    SKY_TABLE[0] = 0;
+  }
+
+  if (*CATMODE == 0) strcpy (CATMODE, "RAW");
+  if (*CATFORMAT == 0) strcpy (CATFORMAT, "ELIXIR");
+
+  if (!LoadPhotcodes (PhotCodeFile)) {
+    fprintf (stderr, "error loading photcodes\n");
+    exit (1);
+  }
+
+  free (config);
+  free (file);
+}
Index: /branches/delstar-1-7/Ohana/src/delstar/src/SetSignals.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/SetSignals.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/SetSignals.c	(revision 10346)
@@ -0,0 +1,118 @@
+# include "delstar.h"
+
+static int Protect = FALSE;
+static int Trapped = FALSE;
+
+void TrapSignal (int sig) {
+    fprintf (stderr, "trapped signal %d\n", sig);
+    if (sig == 11) {
+      fprintf (stderr, "seg fault\n");
+      exit (1);
+    }
+    if (Protect) {
+      Trapped = TRUE;
+      fprintf (stderr, "blocking until protected sections are clear\n");
+      return;
+    }
+    Shutdown ("halted by signal (trapped)");
+}    
+
+void SetProtect (int mode) {
+  Protect = mode;
+  if (Trapped && !Protect) Shutdown ("halted by signal (protect)");
+}
+
+int SetSignals () {
+
+  int i;
+
+  /* disable almost all signal interrupts */
+  for (i = 0; i < 36; i++) {
+    switch (i) {
+      /* can't redirect this signals */
+    case SIGKILL:    /* kill -9: cannot be caught or ignored */
+    case SIGSTOP:    /* SIGSTOP: cannot be caught or ignored */
+      /* ignore these signals */
+    case SIGCHLD:    /* child halted: ignore */
+    case SIGPWR:     /* power failure - why ignore this? */
+    case SIGWINCH:   /* window resized */
+    case SIGCONT:    /* continue - maintain this action */
+    case SIGTSTP:    /* stop signal sent from tty - why ignore? */
+    case SIGURG:     /* socket signal, ignore this */
+      break;
+      
+    default:
+      signal (i, TrapSignal);
+    }
+  }
+  return (TRUE);
+}
+/*
+
+       Signal     Value     Action   Comment
+       -------------------------------------------------------------------------
+       SIGHUP        1        A      Hangup detected on controlling terminal
+                                     or death of controlling process
+       SIGINT        2        A      Interrupt from keyboard
+       SIGQUIT       3        A      Quit from keyboard
+       SIGILL        4        A      Illegal Instruction
+       SIGABRT       6        C      Abort signal from abort(3)
+       SIGFPE        8        C      Floating point exception
+       SIGKILL       9       AEF     Kill signal
+       SIGSEGV      11        C      Invalid memory reference
+       SIGPIPE      13        A      Broken pipe: write to pipe with no readers
+       SIGALRM      14        A      Timer signal from alarm(2)
+       SIGTERM      15        A      Termination signal
+       SIGUSR1   30,10,16     A      User-defined signal 1
+       SIGUSR2   31,12,17     A      User-defined signal 2
+       SIGCHLD   20,17,18     B      Child stopped or terminated
+       SIGCONT   19,18,25            Continue if stopped
+       SIGSTOP   17,19,23    DEF     Stop process
+       SIGTSTP   18,20,24     D      Stop typed at tty
+       SIGTTIN   21,21,26     D      tty input for background process
+       SIGTTOU   22,22,27     D      tty output for background process
+
+       Next various other signals.
+
+       Signal       Value     Action   Comment
+       ---------------------------------------------------------------------
+       SIGTRAP        5         CG     Trace/breakpoint trap
+       SIGIOT         6         CG     IOT trap. A synonym for SIGABRT
+       SIGEMT       7,-,7       G
+       SIGBUS      10,7,10      AG     Bus error
+       SIGSYS      12,-,12      G      Bad argument to routine (SVID)
+       SIGSTKFLT    -,16,-      AG     Stack fault on coprocessor
+       SIGURG      16,23,21     BG     Urgent condition on socket (4.2 BSD)
+       SIGIO       23,29,22     AG     I/O now possible (4.2 BSD)
+       SIGPOLL                  AG     A synonym for SIGIO (System V)
+       SIGCLD       -,-,18      G      A synonym for SIGCHLD
+       SIGXCPU     24,24,30     AG     CPU time limit exceeded (4.2 BSD)
+       SIGXFSZ     25,25,31     AG     File size limit exceeded (4.2 BSD)
+       SIGVTALRM   26,26,28     AG     Virtual alarm clock (4.2 BSD)
+       SIGPROF     27,27,29     AG     Profile alarm clock
+       SIGPWR      29,30,19     AG     Power failure (System V)
+       SIGINFO      29,-,-      G      A synonym for SIGPWR
+       SIGLOST      -,-,-       AG     File lock lost
+       SIGWINCH    28,28,20     BG     Window resize signal (4.3 BSD, Sun)
+       SIGUNUSED    -,31,-      AG     Unused signal
+       (Here - denotes that a signal is absent; there where three values are given, the first one is usually  valid  for  alpha  and
+       sparc,  the  middle  one  for i386 and ppc, the last one for mips. Signal 29 is SIGINFO / SIGPWR on an alpha but SIGLOST on a
+       sparc.)
+
+       The letters in the "Action" column have the following meanings:
+
+       A      Default action is to terminate the process.
+
+       B      Default action is to ignore the signal.
+
+       C      Default action is to dump core.
+
+       D      Default action is to stop the process.
+
+       E      Signal cannot be caught.
+
+       F      Signal cannot be ignored.
+
+       G      Not a POSIX.1 conformant signal.
+
+*/
Index: /branches/delstar-1-7/Ohana/src/delstar/src/Shutdown.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/Shutdown.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/Shutdown.c	(revision 10346)
@@ -0,0 +1,28 @@
+# include "delstar.h"
+
+static FITS_DB *db;
+
+void set_db (FITS_DB *in) {
+  db = in;
+}
+
+/* clean up open / locked ImageCat before shutting down */
+int Shutdown (char *format, ...) {  
+  va_list argp;
+  char *formatplus;
+  
+  ALLOCATE (formatplus, char, strlen(format));
+  strcpy (formatplus, format);
+  strcat (formatplus, "\n");
+
+  va_start (argp, format);
+  vfprintf (stderr, formatplus, argp);
+  free (formatplus);
+  va_end (argp);
+
+  SetProtect (TRUE);
+  gfits_db_close (db);
+  fprintf (stderr, "ERROR: delstar halted\n");
+  exit (1);
+}
+
Index: /branches/delstar-1-7/Ohana/src/delstar/src/args.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/args.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/args.c	(revision 10346)
@@ -0,0 +1,101 @@
+# include "delstar.h"
+
+void help () {
+
+  fprintf (stderr, "USAGE:\n");
+  fprintf (stderr, "  delstar (filename)\n");
+  fprintf (stderr, "  delstar -name (filename)\n");
+  fprintf (stderr, "  delstar -time (start) (stop/range)\n");
+  fprintf (stderr, "  delstar -orphan (region)\n");
+  fprintf (stderr, "  delstar -missed (region)\n\n");
+  fprintf (stderr, "  optional flags:\n");
+  fprintf (stderr, "  -v               : verbose mode\n");
+  fprintf (stderr, "  -photcode (code) : restrict by photcode\n");
+  fprintf (stderr, "\n"); 
+  exit (2);
+
+}
+
+void usage () {
+  fprintf (stderr, "USAGE: delstar (filename) / [optional mode] : -h for help\n");
+  exit (2);
+}
+
+int args (int *argc, char **argv) {
+  
+  int N;
+  double trange;
+  time_t tmp;
+
+  /* check for help request */
+  if (get_argument (*argc, argv, "-help") ||
+      get_argument (*argc, argv, "-h")) {
+    help ();
+  }
+
+  VERBOSE = FALSE;
+  if ((N = get_argument (*argc, argv, "-v"))) {
+    VERBOSE = TRUE;
+    remove_argument (N, argc, argv);
+  }
+
+  MODE = MODE_IMAGEFILE;
+  if ((N = get_argument (*argc, argv, "-name"))) {
+    if (MODE != MODE_IMAGEFILE) usage();
+    MODE = MODE_IMAGENAME;
+    remove_argument (N, argc, argv);
+  }
+  if ((N = get_argument (*argc, argv, "-orphan"))) {
+    if (MODE != MODE_IMAGEFILE) usage();
+    MODE = MODE_ORPHAN;
+    remove_argument (N, argc, argv);
+  }
+  if ((N = get_argument (*argc, argv, "-missed"))) {
+    if (MODE != MODE_IMAGEFILE) usage();
+    MODE = MODE_MISSED;
+    remove_argument (N, argc, argv);
+  }
+  if ((N = get_argument (*argc, argv, "-time"))) {
+    if (MODE != MODE_IMAGEFILE) usage();
+    MODE = MODE_TIME;
+    remove_argument (N, argc, argv);
+
+    if (!str_to_time (argv[N], &START)) usage ();
+    remove_argument (N, argc, argv);
+
+    /* interpret second value */
+    if (str_to_dtime (argv[N], &trange)) { 
+      if (trange < 0) {
+	END = START;
+	START = END + trange;
+      } else {
+	END = START + trange;
+      }
+      remove_argument (N, argc, argv);
+      goto goodtime;
+    }
+    if (str_to_time (argv[N], &END)) { 
+      if (START > END) {
+	tmp   = START;
+	START = END;
+	END   = START;
+      }
+      remove_argument (N, argc, argv);
+      goto goodtime;
+    }
+    usage ();
+  }
+goodtime:
+
+  /* restrict to a single photcode (not compatible with -image) */
+  PHOTCODE = NULL;
+  if ((N = get_argument (*argc, argv, "-photcode"))) {
+    remove_argument (N, argc, argv);
+    PHOTCODE = GetPhotcodebyName (argv[N]);
+    remove_argument (N, argc, argv);
+  }
+
+  if ((MODE == MODE_TIME) && (*argc != 1)) usage ();
+  if ((MODE != MODE_TIME) && (*argc != 2)) usage ();
+  return (TRUE);
+}
Index: /branches/delstar-1-7/Ohana/src/delstar/src/check_permissions.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/check_permissions.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/check_permissions.c	(revision 10346)
@@ -0,0 +1,67 @@
+# include "addstar.h"
+
+void check_permissions (char *basefile) {
+  
+  char *c, dir[256], filename[256];
+  struct stat filestat;
+  uid_t uid;
+  gid_t gid;
+  int status, cmode;
+
+  uid = getuid();
+  gid = getgid();
+
+  /* check permission to write to directory */
+  sprintf (filename, "%s", basefile);
+  c = strrchr (filename, '/');
+  if (c == (char *) NULL) {
+    strcpy (dir, ".");
+  } else {
+    *c = 0;
+    strcpy (dir, filename);
+  }
+  status = stat (dir, &filestat);
+  if (status == -1) {
+    fprintf (stderr, "directory %s does not exist, creating...\n", dir);
+    cmode = S_IRWXU | S_IRWXG | S_IRWXO;
+    status = mkdir (dir, cmode);
+    if (status == -1) {
+      fprintf (stderr, "ERROR: can't create %s\n", dir);
+      exit (1);
+    }
+  } 
+  status = stat (dir, &filestat);
+  if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRWXU)) ||
+      ((gid == filestat.st_gid) && (filestat.st_mode & S_IRWXG)) || 
+      (filestat.st_mode & S_IRWXO)) {
+  } else {
+    fprintf (stderr, "ERROR: can't write to %s\n", dir);
+    exit (1);
+  }
+  
+  /* check permission to write to file */
+  sprintf (filename, "%s", basefile);
+  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_IWUSR)) ||
+	((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP) && (filestat.st_mode & S_IWGRP)) || 
+	((filestat.st_mode & S_IROTH) && (filestat.st_mode & S_IWOTH))) {
+    } else {
+      fprintf (stderr, "ERROR: can't write to %s\n", filename);
+      exit (1);
+    }
+  }
+  
+  /* check permission to write to backup file */
+  sprintf (filename, "%s~", basefile);
+  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_IWUSR)) ||
+	((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP) && (filestat.st_mode & S_IWGRP)) || 
+	((filestat.st_mode & S_IROTH) && (filestat.st_mode & S_IWOTH))) {
+    } else {
+      fprintf (stderr, "ERROR: can't write to %s\n", filename);
+      exit (1);
+    }
+  }
+}
Index: /branches/delstar-1-7/Ohana/src/delstar/src/delete_imagefile.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/delete_imagefile.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/delete_imagefile.c	(revision 10346)
@@ -0,0 +1,65 @@
+# include "delstar.h"
+
+void delete_imagefile (FITS_DB *db, char *filename) {
+
+  int i, Nimlist;
+  int *imlist;
+  double trange;
+  time_t start, stop;
+  Image *image;
+  Catalog catalog;
+  SkyList *skylist;
+  SkyTable *sky;
+
+  /* load sky from correct table */
+  sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+
+  /* load information about file - time/photcode */
+  image = gimages (filename);
+  
+  /* need to define method to get the mosaic (look up from table) */
+  if (VERBOSE) fprintf (stderr, "deleting %s\n", image[0].name);
+
+  for (i = 0; i < skylist[0].Nregions; i++) {
+
+    if (VERBOSE) fprintf (stderr, "deleting from %s\n", skylist[0].filename[i]);
+    catalog.filename = skylist[0].filename[i];  /* don't free region before catalog! */
+    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
+    catalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+
+    // an error exit status here is a significant error
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "a")) {
+      fprintf (stderr, "ERROR: failure to open catalog file %s\n", catalog.filename);
+      exit (2);
+    }
+    if (!catalog.Nave_disk) {
+      dvo_catalog_unlock (&catalog);
+      dvo_catalog_free (&catalog);
+      continue;
+    }
+
+    /* pad exposure time by 1 sec to require a valid time */
+    /* trate is in 0.1 msec / row  - stop is the latest exposure end time */
+    trange = 1e-4*image[0].NY*image[0].trate + image[0].exptime + 1;  
+    start = image[0].tzero;
+    stop  = image[0].tzero + trange;
+    find_matches (&catalog, image[0].source, start, stop);
+
+    dvo_catalog_save (&catalog, VERBOSE);
+    dvo_catalog_unlock (&catalog);
+    dvo_catalog_free (&catalog);
+  }
+
+  /* find and delete matching images */
+  // XXX EAM : load image data above, find mosaic?
+  imlist = find_images_data (db, image, &Nimlist);
+  if (!Nimlist) Shutdown ("image %s not found in db", filename);
+
+  gfits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, imlist, Nimlist);
+  dvo_image_update (db, VERBOSE);
+  dvo_image_unlock (db);
+
+  fprintf (stderr, "SUCCESS\n");
+  exit (0);
+}
Index: /branches/delstar-1-7/Ohana/src/delstar/src/delete_imagename.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/delete_imagename.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/delete_imagename.c	(revision 10346)
@@ -0,0 +1,71 @@
+# include "delstar.h"
+
+void delete_imagename (FITS_DB *db, char *name) {
+
+  int i, j, k;
+  int Nimlist, Nimage;
+  int *imlist;
+  double trange;
+  time_t start, stop;
+  Image *image;
+  Catalog catalog;
+  SkyList *skylist;
+  SkyTable *sky;
+
+  /* load sky from correct table */
+  sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+
+  image = gfits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
+
+  /* find image in db by name */
+  imlist = find_images_name (db, name, &Nimlist);
+  if (!Nimlist) Shutdown ("image %s not found in db", name);
+  
+  for (k = 0; k < Nimlist; k++) {
+
+    j = imlist[k];
+    if (VERBOSE) fprintf (stderr, "deleting %s\n", image[j].name);
+    
+    // XXX EAM : need to handle failure
+    FindMosaicForImage (image, Nimage, j);
+    skylist = SkyListByImage (sky, -1, &image[j]);
+
+    for (i = 0; i < skylist[0].Nregions; i++) {
+      if (VERBOSE) fprintf (stderr, "deleting from %s\n", skylist[0].filename[i]);
+      catalog.filename = skylist[0].filename[i];  /* don't free region before catalog! */
+      catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
+      catalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+
+      // an error exit status here is a significant error
+      if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "a")) {
+	fprintf (stderr, "ERROR: failure to open catalog file %s\n", catalog.filename);
+	exit (2);
+      }
+      if (!catalog.Nave_disk) {
+	dvo_catalog_unlock (&catalog);
+	dvo_catalog_free (&catalog);
+	continue;
+      }
+
+      /* trate is in 0.1 msec / row  - stop is the latest exposure end time */
+      /* pad exposure time by 1 sec to require a valid time */
+      trange = 1e-4*image[j].NY*image[j].trate + image[j].exptime + 1;  
+      start = image[j].tzero;
+      stop  = image[j].tzero + trange;
+      find_matches (&catalog, image[j].source, start, stop);
+
+      dvo_catalog_save (&catalog, VERBOSE);
+      dvo_catalog_unlock (&catalog);
+      dvo_catalog_free (&catalog);
+    }
+  }
+
+  /* delete the identified images */
+  gfits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, imlist, Nimlist);
+  dvo_image_update (db, VERBOSE);
+  dvo_image_unlock (db);
+
+  fprintf (stderr, "SUCCESS\n");
+  exit (0);
+}
Index: /branches/delstar-1-7/Ohana/src/delstar/src/delete_missed.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/delete_missed.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/delete_missed.c	(revision 10346)
@@ -0,0 +1,24 @@
+# include "delstar.h"
+
+/* drop all MISSED values for the given catalog */
+
+delete_missed (Catalog *catalog) {
+
+  int i;
+  int Nave, Nmeas, Nmiss;
+
+  Nave = catalog[0].Naverage;
+  Nmeas = catalog[0].Nmeasure;
+  Nmiss = catalog[0].Nmissing;
+  
+  if (VERBOSE) fprintf (stderr, "starting with Nave, Nmeas, Nmiss: %d %d %d\n", Nave, Nmeas, Nmiss);
+
+  /* set up references for missing to average */
+  for (i = 0; i < Nave; i++) {
+    catalog[0].average[i].Nn = 0;
+  }
+  REALLOCATE (catalog[0].missing, Missing, 1);
+  catalog[0].Nmissing = 0;
+  if (VERBOSE) fprintf (stderr, "  ending with Nave, Nmeas, Nmiss: %d %d %d\n", Nave, Nmeas, Nmiss);
+}
+
Index: /branches/delstar-1-7/Ohana/src/delstar/src/delete_orphans.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/delete_orphans.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/delete_orphans.c	(revision 10346)
@@ -0,0 +1,256 @@
+# include "delstar.h"
+
+delete_orphans (char *name) {
+
+  int i, j, k, n, m, N, M, found;
+  int *N1, *N2,  *next, *next_miss, *ave_miss, last, last_miss;
+  int Nave, NAVE, Nmeas, NMEAS, Nmiss, NMISS, Nmatch;
+  int start, end, Nmeasfound, Nsecfilt;
+  unsigned int flags;
+  Measure *tmpmeasure;
+  Missing *tmpmissing;
+  Coords tcoords;
+  Catalog catalog;
+
+  /* find and load catalog file */
+  catalog.filename = name;
+  dvo_catalog_load (&catalog);
+  gcatstats (&catalog, &catstats);
+
+  /* find images overlapping catalog */
+  image = find_images_region (&catstats, &Nimage);
+  match_images (&catalog, image, Nimage);
+
+  /** allocate local arrays **/
+  Nave = catalog.Naverage;
+
+  Nmeas = catalog.Nmeasure;
+  ALLOCATE (next, int, Nmeas);
+  
+  Nmiss = catalog.Nmissing;
+  ALLOCATE (next_miss, int, Nmiss);
+  ALLOCATE (ave_miss, int, Nmiss);
+  
+  if (VERBOSE) fprintf (stderr, "starting with Nave, Nmeas, Nmiss: %d %d %d\n", Nave, Nmeas, Nmiss);
+
+  /* set up pointers for linked list of measure */
+  for (i = 0; i < Nmeas - 1; i++) {
+    next[i] = i+1;
+  }
+  next[i] = -1;
+  last = i;
+  /* set up pointers for linked list of missing */
+  for (i = 0; i < Nmiss - 1; i++) {
+    next_miss[i] = i+1;
+  }
+  next_miss[i] = -1;
+  last_miss = i;
+  /* set up references for missing to average */
+  for (i = 0; i < Nave; i++) {
+    for (j = 0; j < catalog.average[i].Nn; j++) {
+      ave_miss[catalog.average[i].missing + j] = i;
+    }
+  }
+  Nmeasfound = 0;
+  Nsecfilt = catalog.Nsecfilt;
+
+  /* fprintf (stderr, "fixing the measures...\n"); */
+  for (i = 0; (i < Nmeas); i++) {
+    if ((catalog.measure[i].t != 0) && (catalog.image[i] == -1)) { 
+      /* this star is an orphan */
+      Nmeasfound ++;
+      next[i] = -2; /* we delete this one */
+      /* fix the list links: connect the previous valid link to the next valid link */
+      for (j = i; (j >= 0) && (next[j] == -2); j--); /* find previous entry to fix link */
+      if (j >= 0) { /* if j < 0, there is no previous valid link, ignore this step */
+	if (next[j] != i) {
+	  fprintf (stderr, "error?  this link seems to have been lost\n");
+	  exit (1);
+	}
+	/* find next valid entry to fix link */
+	for (k = i; (k < Nmeas) && (next[k] == -2); k++);
+	if (k < Nmeas)
+	  next[j] = k;
+	else 
+	  next[j] = -1;  /* last link in list gets a -1 */
+      }
+      
+      /*** fix the corresponding average entry ***/
+      n = catalog.measure[i].averef;
+      if (catalog.average[n].Nm == 0) { /* this should never happen */
+	fprintf (stderr, "error? we deleted one too many objects?\n");
+	exit (1);
+      }
+      catalog.average[n].Nm --;
+      /* this was only entry in list: will be deleted below.  meanwhile, delete all missing entries*/
+      if ((catalog.average[n].Nm < 1) && (catalog.average[n].Nn > 0)) { 
+	m = catalog.average[n].missing;
+	for (j = 0; j < catalog.average[n].Nn; j++) {
+	  M = next_miss[m];
+	  next_miss[m] = -2;
+	  m = M;
+	}
+	m = catalog.average[n].missing;
+	/* fix the list links: connect the previous valid link to the next valid link */
+	for (j = m; (j >= 0) && (next_miss[j] == -2); j--); /* find previous entry to fix link */
+	if (j >= 0) { /* if j < 0, there is no previous valid link, ignore this step */
+	  if (next_miss[j] != m) {
+	    fprintf (stderr, "error?  this link seems to have been lost\n");
+	    exit (1);
+	  }
+	  /* find next valid entry to fix link */
+	  for (k = m; (k < Nmiss) && (next_miss[k] == -2); k++);
+	  if (k < Nmiss)
+	    next_miss[j] = k;
+	  else 
+	    next_miss[j] = -1;  /* last link in list gets a -1 */
+	}
+      }
+      /* this was first entry in list */
+      if ((catalog.average[n].offset == i) && (catalog.average[n].Nm > 0)) { 
+	m = catalog.average[n].offset;
+	/* find next valid entry -- notice lack of error checking... */
+	for (j = 0; (j < Nmeas) && (next[m+j] == -2); j++);
+	catalog.average[n].offset = m + j;
+      }
+
+    }
+  }
+  fprintf (stderr, "found %d meas to remove\n", Nmeasfound);
+
+  /* fprintf (stderr, "fixing the missing...\n"); */
+  /** find missing in time range of image **/
+  for (i = 0; (i < Nmiss); i++) {
+    if ((next_miss[i] != -2) && (catalog.missing[i].t >= start) && (catalog.missing[i].t <= end)) { 
+      /* this star is in this image */
+
+      next_miss[i] = -2; /* we delete this one */
+      /* fix the list links: connect the previous valid link to the next valid link */
+      for (j = i; (j >= 0) && (next_miss[j] == -2); j--); /* find previous entry to fix link */
+      if (j >= 0) { /* if j < 0, there is no previous valid link, ignore this step */
+	if (next_miss[j] != i) {
+	  fprintf (stderr, "error?  this link seems to have been lost\n");
+	  exit (1);
+	}
+	/* find next valid entry to fix link */
+	for (k = i; (k < Nmiss) && (next_miss[k] == -2); k++);
+	if (k < Nmiss)
+	  next_miss[j] = k;
+	else 
+	  next_miss[j] = -1;  /* last link in list gets a -1 */
+      }
+      
+      /* find the corresponding avearge entry 
+      found = FALSE;
+      for (n = 0; !found && (n < Nave); n++) {
+	if ((catalog.average[n].missing > 0) && (catalog.average[n].missing <= i) && (catalog.average[n].missing + catalog.average[n].Nn > i)) 
+	  found = TRUE;
+      }
+      n--; */
+      /*** fix the corresponding average entry ***/
+      n = ave_miss[i];
+      if (catalog.average[n].Nn == 0) { /* this should never happen */
+	fprintf (stderr, "error? we deleted one too many missing?\n");
+	exit (1);
+      }
+      catalog.average[n].Nn --;
+      /* this was first entry in list */
+      if ((catalog.average[n].missing == i) && (catalog.average[n].Nn > 0)) { 
+	m = catalog.average[n].missing;
+	for (j = 0; (j < Nmiss) && (next_miss[m+j] == -2); j++);
+	catalog.average[n].missing = m + j;
+      }
+
+    }
+  }
+
+  /* currently not worked out, but we will need to delete the references to blended image and cat stars */
+# if 0
+  /*** handle multiple stars */
+  /* this image star matches more than one catalog star */
+  if (stars[N].found > -1) {
+    catalog.measure[stars[N].found].flags |= BLEND_IMAGE;
+    catalog.measure[Nmeas].flags |= BLEND_IMAGE;
+  } 
+  if (stars[N].found == -2) { /* this image star matches a catalog star on a neighboring catalog */
+    catalog.measure[Nmeas].flags |= BLEND_IMAGE_NEIGHBOR;
+  } 
+  if (stars[N].found == -1) { /* this image star matches only this star */
+    stars[N].found = Nmeas;  /* save first match, in case coincidences are found */
+  }
+  /* this catalog star matches more than one image star */
+  if (catalog.found[n] > -1) {
+    catalog.measure[catalog.found[n]].flags |= BLEND_CATALOG;
+    catalog.measure[Nmeas].flags |= BLEND_CATALOG;
+  } else {
+    catalog.found[n] = Nmeas;
+  }
+# endif  
+
+  /* fprintf (stderr, "fixing the averages...\n"); */
+  /* fix Average list: delete entries with Nm == 0 */
+  for (i = j = 0; (i < Nave) && (j < Nave); i++, j++) {
+    for (; (j < Nave) && (catalog.average[j].Nm == 0); j++);
+    if ((i != j) && (j < Nave)) {
+      catalog.average[i] = catalog.average[j];
+      for (k = 0; k < catalog.Nsecfilt; k++) {
+	catalog.secfilt[i*Nsecfilt + k] = catalog.secfilt[j*Nsecfilt + k];
+      }
+    }
+    if (j == Nave) i--;
+  }
+  Nave = i;
+  REALLOCATE (catalog.average, Average, Nave);
+  REALLOCATE (catalog.secfilt, SecFilt, MAX (1, Nave*Nsecfilt));
+  
+  /* fprintf (stderr, "fixing the measure order...\n"); */
+  /* fix order of Measure (memory intensive, but fast) */
+  N = 0; 
+  ALLOCATE (tmpmeasure, Measure, Nmeas);
+  for (i = 0; i < Nave; i++) {
+    n = catalog.average[i].offset;
+    catalog.average[i].offset = N;
+    for (k = 0; k < catalog.average[i].Nm; k++, N++) {
+      if ((n == -1) || (n == -2)) {
+	fprintf (stderr, "error: linked list is confused\n");
+	exit (1);
+      }
+      tmpmeasure[N] = catalog.measure[n]; 
+      tmpmeasure[N].averef = i;
+      n = next[n];
+    }
+  }
+  Nmeas = N;
+  free (catalog.measure);
+  catalog.measure = tmpmeasure;
+  REALLOCATE (catalog.measure, Measure, Nmeas);
+    
+  /* fprintf (stderr, "fixing the mising order...\n"); */
+  /* fix order of Missing (memory intensive, but fast) */
+  N = 0; 
+  ALLOCATE (tmpmissing, Missing, Nmiss);
+  for (i = 0; i < Nave; i++) {
+    if (catalog.average[i].Nn > 0) {
+      n = catalog.average[i].missing;
+      catalog.average[i].missing = N;
+      for (k = 0; k < catalog.average[i].Nn; k++, N++) {
+	if ((n == -1) || (n == -2)) {
+	  fprintf (stderr, "error: linked list is confused\n");
+	  exit (1);
+	}
+	tmpmissing[N] = catalog.missing[n]; 
+	n = next_miss[n];
+      }
+    }
+  }
+  Nmiss = N;
+  free (catalog.missing);
+  catalog.missing = tmpmissing;
+  REALLOCATE (catalog.missing, Missing, Nmiss);
+
+  catalog.Naverage = Nave;
+  catalog.Nmeasure = Nmeas;
+  catalog.Nmissing = Nmiss;
+  if (VERBOSE) fprintf (stderr, "  ending with Nave, Nmeas, Nmiss: %d %d %d\n", Nave, Nmeas, Nmiss);
+
+}
Index: /branches/delstar-1-7/Ohana/src/delstar/src/delete_times.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/delete_times.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/delete_times.c	(revision 10346)
@@ -0,0 +1,84 @@
+# include "delstar.h"
+
+void delete_times (FITS_DB *db) {
+
+  int i, j, k, n;
+  int Nimage, Nimlist, found, code;
+  int Nregions, NREGIONS;
+  int *imlist;
+  SkyList *skylist, *skyset;
+  SkyTable *sky;
+  Image *image;
+  Catalog catalog;
+
+  code = (PHOTCODE == NULL) ? -1 : PHOTCODE[0].code;
+
+  /* load sky from correct table */
+  sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+
+  Nregions = 0;
+  NREGIONS = 10;
+  ALLOCATE (skylist, SkyList, 1);
+  ALLOCATE (skylist[0].regions, SkyRegion *, NREGIONS);
+
+  image = gfits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
+
+  /* find images for time range, delete each image */ 
+  imlist = find_images_time (db, START, END, PHOTCODE, &Nimlist);
+
+  /* find all overlapping regions */
+  for (n = 0; n < Nimlist; n++) {
+    j = imlist[n];
+    if (VERBOSE) fprintf (stderr, "finding regions for %s\n", image[j].name);
+
+    // XXX EAM : need to handle failure
+    FindMosaicForImage (image, Nimage, j);
+    skyset = SkyListByImage (sky, -1, &image[j]);
+
+    // tregion = gregion_image (&image[j], &Ntregions);
+    for (i = 0; i < skyset[0].Nregions; i++) {
+      found = FALSE;
+      for (k = 0; (k < skylist[0].Nregions) && !found; k++) {
+	found = !strcmp (skylist[0].regions[k][0].name, skyset[0].regions[i][0].name);
+      }
+      if (found) continue;
+      skylist[0].regions[Nregions] = skyset[0].regions[i];
+      Nregions ++;
+      CHECK_REALLOCATE (skylist[0].regions, SkyRegion *, NREGIONS, Nregions, 10);
+    }
+    SkyListFree (skyset, FALSE);
+  }
+
+  /* delete from all identified regions */
+  for (i = 0; i < skylist[0].Nregions; i++) {
+    if (VERBOSE) fprintf (stderr, "deleting from %s\n", skylist[0].filename[i]);
+    catalog.filename = skylist[0].filename[i];  /* don't free region before catalog! */
+    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
+    catalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+
+    // an error exit status here is a significant error
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "a")) {
+      fprintf (stderr, "ERROR: failure to open catalog file %s\n", catalog.filename);
+      exit (2);
+    }
+    if (!catalog.Nave_disk) {
+      dvo_catalog_unlock (&catalog);
+      dvo_catalog_free (&catalog);
+      continue;
+    }
+
+    find_matches (&catalog, code, START, END);
+    dvo_catalog_save (&catalog, VERBOSE);
+    dvo_catalog_unlock (&catalog);
+    dvo_catalog_free (&catalog);
+  }
+
+  /* delete the identified images */
+  gfits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, imlist, Nimlist);
+  dvo_image_update (db, VERBOSE);
+  dvo_image_unlock (db);
+
+  fprintf (stderr, "SUCCESS\n");
+  exit (0);
+}
Index: /branches/delstar-1-7/Ohana/src/delstar/src/delstar.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/delstar.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/delstar.c	(revision 10346)
@@ -0,0 +1,42 @@
+# include "delstar.h"
+
+int main (int argc, char **argv) {
+
+  FITS_DB db;
+
+  int status;
+  SetSignals ();
+  ConfigInit (&argc, argv);
+  args (&argc, argv);
+
+  set_db (&db);
+  status = dvo_image_lock (&db, ImageCat, 60.0, LCK_XCLD); /* XCLD */
+  if (!status) Shutdown ("ERROR: failure to lock image catalog %s", db.filename);
+  if (db.dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db.filename);
+
+  status = dvo_image_load (&db, VERBOSE, FALSE);
+  if (!status) Shutdown ("can't read image catalog %s", db.filename);
+
+  switch (MODE) {
+    case MODE_IMAGEFILE:
+      delete_imagefile (&db, argv[1]);
+      break;
+    case MODE_IMAGENAME:
+      delete_imagename (&db, argv[1]);
+      break;
+    case MODE_TIME:
+      delete_times (&db);
+      break;
+    case MODE_ORPHAN:
+      fprintf (stderr, "delete orphans not available\n");
+      // delete_orphans (argv[1]);
+      break;
+    case MODE_MISSED:
+      fprintf (stderr, "delete missed not available\n");
+      // delete_missed (argv[1]);
+      break;
+    default:
+      usage ();
+  }
+  exit (1);
+}
Index: /branches/delstar-1-7/Ohana/src/delstar/src/find_image_db.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/find_image_db.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/find_image_db.c	(revision 10346)
@@ -0,0 +1,94 @@
+# include "delstar.h"
+
+int *find_images_name (FITS_DB *db, char *filename, int *nlist) {
+
+  int i, Nimage, Nlist, NLIST;
+  int *list;
+  char *p, *name;
+  Image *image;
+
+  /* strip off all but the filename */
+  p = strrchr (filename, '/');
+  if (p == NULL) {
+    name = filename;
+  } else {
+    name = p + 1;
+  }
+
+  image = gfits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
+
+  Nlist = 0;
+  NLIST = 100;
+  ALLOCATE (list, int, NLIST);
+
+  for (i = 0; i < Nimage; i++) {
+    if (strcmp (image[i].name, name)) continue;
+    list[Nlist] = i;
+    Nlist ++;
+    CHECK_REALLOCATE (list, int, NLIST, Nlist, 100);
+  }
+
+  *nlist = Nlist;
+  return (list);
+}
+
+/* find images in db by image data (time/photcode) */
+int *find_images_data (FITS_DB *db, Image *timage, int *nlist) {
+
+  int i, Nimage, Nlist, NLIST; 
+  int *list;
+  Image *image;
+  time_t start, stop;
+  int code;
+
+  image = gfits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
+
+  start = timage[0].tzero - MAX(0.05*timage[0].trate*timage[0].NY, 1);
+  stop  = timage[0].tzero + MAX(1.05*timage[0].trate*timage[0].NY, 1);
+  code  = timage[0].source;
+
+  Nlist = 0;
+  NLIST = 100;
+  ALLOCATE (list, int, NLIST);
+
+  for (i = 0; i < Nimage; i++) {
+    if (image[i].tzero < start) continue;
+    if (image[i].tzero > stop) continue;
+    if (image[i].source != code) continue;
+    list[Nlist] = i;
+    Nlist ++;
+    CHECK_REALLOCATE (list, int, NLIST, Nlist, 100);
+  }
+
+  *nlist = Nlist;
+  return (list);
+}
+
+/* find images in db by image data (time/photcode) */
+int *find_images_time (FITS_DB *db, time_t start, time_t end, PhotCode *code, int *nlist) {
+
+  int i, Nimage, Nlist, NLIST;
+  int *list;
+  Image *image;
+
+  image = gfits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
+
+  Nlist = 0;
+  NLIST = 100;
+  ALLOCATE (list, int, NLIST);
+
+  for (i = 0; i < Nimage; i++) {
+    if (image[i].tzero < START) continue;
+    if (image[i].tzero > END) continue;
+    if (code != NULL) {
+      if (image[i].source != code[0].code) continue;
+    }
+    list[Nlist] = i;
+    Nlist ++;
+    CHECK_REALLOCATE (list, int, NLIST, Nlist, 100);
+  }
+
+  *nlist = Nlist;
+  return (list);
+}
+
Index: /branches/delstar-1-7/Ohana/src/delstar/src/find_matches.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/find_matches.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/find_matches.c	(revision 10346)
@@ -0,0 +1,243 @@
+# include "delstar.h"
+
+void find_matches (Catalog *catalog, int photcode, int start, int end) {
+
+  int i, j, k, n, m, N, M, drop;
+  int *next, *next_miss, *ave_miss, last, last_miss;
+  int Nave, Nmeas, Nmiss;
+  int Nmeasfound, Nsecfilt;
+  int this, prev;
+  Measure *tmpmeasure;
+  Missing *tmpmissing;
+
+  /** allocate local arrays **/
+  Nave = catalog[0].Naverage;
+
+  Nmeas = catalog[0].Nmeasure;
+  ALLOCATE (next, int, MAX(Nmeas,1));
+  
+  Nmiss = catalog[0].Nmissing;
+  ALLOCATE (next_miss, int, MAX(Nmiss,1));
+  ALLOCATE (ave_miss, int, MAX(Nmiss,1));
+  
+  if (VERBOSE) fprintf (stderr, "starting with Nave, Nmeas, Nmiss: %d %d %d\n", Nave, Nmeas, Nmiss);
+
+  /* set up pointers for linked list of measure */
+  for (i = 0; i < Nmeas - 1; i++) {
+    next[i] = i+1;
+  }
+  next[i] = -1;
+  last = i;
+  /* set up pointers for linked list of missing */
+  for (i = 0; i < Nmiss - 1; i++) {
+    next_miss[i] = i+1;
+  }
+  next_miss[i] = -1;
+  last_miss = i;
+  /* set up references for missing to average */
+  for (i = 0; i < Nave; i++) {
+    for (j = 0; j < catalog[0].average[i].Nn; j++) {
+      ave_miss[catalog[0].average[i].missing + j] = i;
+    }
+  }
+
+  if (VERBOSE) fprintf (stderr, "deleting for range %d to %d, photcode %d\n", start, end, photcode);
+  Nmeasfound = 0;
+  Nsecfilt = catalog[0].Nsecfilt;
+
+  if (VERBOSE) fprintf (stderr, "fixing measure...\n"); 
+
+  /** find measure in time range **/
+  this = prev = -1;
+  for (i = 0; (i < Nmeas); i++) {
+    if (VERBOSE && !(i % 10000)) fprintf (stderr, ". ");
+    drop = TRUE;
+    drop &= (catalog[0].measure[i].t >= start);
+    drop &= (catalog[0].measure[i].t <= end);
+    drop &= ((photcode == -1) || (photcode == catalog[0].measure[i].source));
+    if (!drop) {
+      prev = i;
+      continue;
+    }
+    Nmeasfound ++;
+
+    /* this star is in this image */
+    this = next[i];
+    next[i] = -2; /* we delete this one */
+    if (prev != -1) { next[prev] = this; }
+
+# if (0) 
+    /* why is this section disabled? */
+    /* fix the list links: connect the previous valid link to the next valid link */
+    for (j = i; (j >= 0) && (next[j] == -2); j--); /* find previous entry to fix link */
+    if (j >= 0) { /* if j < 0, there is no previous valid link, ignore this step */
+      if (next[j] != i) {
+	fprintf (stderr, "error? (1)  this link seems to have been lost\n");
+	fprintf (stderr, "j: %d, next[j]: %d, i: %d\n", j, next[j], i);
+	exit (1);
+      }
+      /* find next valid entry to fix link */
+      for (k = i; (k < Nmeas) && (next[k] == -2); k++);
+      if (k < Nmeas)
+	next[j] = k;
+      else 
+	next[j] = -1;  /* last link in list gets a -1 */
+    }
+# endif      
+
+    /*** fix the corresponding average entry ***/
+    n = catalog[0].measure[i].averef;
+    if (catalog[0].average[n].Nm == 0) { /* this should never happen */
+      fprintf (stderr, "error? we deleted one too many objects?\n");
+      exit (1);
+    }
+    catalog[0].average[n].Nm --;
+    /* this was only entry in list: will be deleted below.  meanwhile, delete all missing entries*/
+    if ((catalog[0].average[n].Nm < 1) && (catalog[0].average[n].Nn > 0)) { 
+      m = catalog[0].average[n].missing;
+      for (j = 0; j < catalog[0].average[n].Nn; j++) {
+	M = next_miss[m];
+	next_miss[m] = -2;
+	m = M;
+      }
+      m = catalog[0].average[n].missing;
+      /* fix the list links: connect the previous valid link to the next valid link */
+      for (j = m; (j >= 0) && (next_miss[j] == -2); j--); /* find previous entry to fix link */
+      if (j >= 0) { /* if j < 0, there is no previous valid link, ignore this step */
+	if (next_miss[j] != m) {
+	  fprintf (stderr, "error? (2) this link seems to have been lost\n");
+	  fprintf (stderr, "j: %d, next_miss[j]: %d, i: %d\n", j, next_miss[j], i);
+	  exit (1);
+	}
+	/* find next valid entry to fix link */
+	for (k = m; (k < Nmiss) && (next_miss[k] == -2); k++);
+	if (k < Nmiss)
+	  next_miss[j] = k;
+	else 
+	  next_miss[j] = -1;  /* last link in list gets a -1 */
+      }
+    }
+    /* this was first entry in list */
+    if ((catalog[0].average[n].offset == i) && (catalog[0].average[n].Nm > 0)) { 
+      m = catalog[0].average[n].offset;
+      /* find next valid entry -- notice lack of error checking... */
+      for (j = 0; (j < Nmeas) && (next[m+j] == -2); j++);
+      catalog[0].average[n].offset = m + j;
+    }
+  } 
+  fprintf (stderr, "found %d meas to remove\n", Nmeasfound);
+
+  if (VERBOSE) fprintf (stderr, "fixing missing..."); 
+  /** find missing in time range of image **/
+  for (i = 0; (i < Nmiss); i++) {
+    if (next_miss[i] == -2) continue;
+    if (catalog[0].missing[i].t < start) continue;
+    if (catalog[0].missing[i].t > end) continue;
+
+    next_miss[i] = -2; /* we delete this one */
+    /* fix the list links: connect the previous valid link to the next valid link */
+    for (j = i; (j >= 0) && (next_miss[j] == -2); j--); /* find previous entry to fix link */
+    if (j >= 0) { /* if j < 0, there is no previous valid link, ignore this step */
+      if (next_miss[j] != i) {
+	fprintf (stderr, "error? (3) this link seems to have been lost\n");
+	fprintf (stderr, "j: %d, next_miss[j]: %d, i: %d\n", j, next_miss[j], i);
+	exit (1);
+      }
+      /* find next valid entry to fix link */
+      for (k = i; (k < Nmiss) && (next_miss[k] == -2); k++);
+      if (k < Nmiss)
+	next_miss[j] = k;
+      else 
+	next_miss[j] = -1;  /* last link in list gets a -1 */
+    }
+      
+    /*** fix the corresponding average entry ***/
+    n = ave_miss[i];
+    if (catalog[0].average[n].Nn == 0) { /* this should never happen */
+      fprintf (stderr, "error? we deleted one too many missing?\n");
+      exit (1);
+    }
+    catalog[0].average[n].Nn --;
+    /* this was first entry in list */
+    if ((catalog[0].average[n].missing == i) && (catalog[0].average[n].Nn > 0)) { 
+      m = catalog[0].average[n].missing;
+      for (j = 0; (j < Nmiss) && (next_miss[m+j] == -2); j++);
+      catalog[0].average[n].missing = m + j;
+    }
+  }
+
+  /* we should delete the references to blended image and cat stars ?? */
+  /* or drop since we are changing this concept ?? */
+
+  /* fix Average list: delete entries with Nm == 0 */
+  for (i = j = 0; (i < Nave) && (j < Nave); i++, j++) {
+    for (; (j < Nave) && (catalog[0].average[j].Nm == 0); j++);
+    if ((i != j) && (j < Nave)) {
+      catalog[0].average[i] = catalog[0].average[j];
+      for (k = 0; k < catalog[0].Nsecfilt; k++) {
+	catalog[0].secfilt[i*Nsecfilt + k] = catalog[0].secfilt[j*Nsecfilt + k];
+      }
+    }    
+    if (j == Nave) i--;
+  }
+  Nave = i;
+  REALLOCATE (catalog[0].average, Average, Nave);
+  REALLOCATE (catalog[0].secfilt, SecFilt, MAX (1, Nave*Nsecfilt));
+
+  /* fix order of Measure (memory intensive, but fast) */
+  N = 0; 
+  ALLOCATE (tmpmeasure, Measure, Nmeas);
+  for (i = 0; i < Nave; i++) {
+    n = catalog[0].average[i].offset;
+    catalog[0].average[i].offset = N;
+    for (k = 0; k < catalog[0].average[i].Nm; k++, N++) {
+      if ((n == -1) || (n == -2)) {
+	fprintf (stderr, "error: linked list is confused\n");
+	exit (1);
+      }
+      tmpmeasure[N] = catalog[0].measure[n]; 
+      tmpmeasure[N].averef = i;
+      n = next[n];
+    }
+  }
+  Nmeas = N;
+  free (catalog[0].measure);
+  catalog[0].measure = tmpmeasure;
+  REALLOCATE (catalog[0].measure, Measure, Nmeas);
+    
+  /* fprintf (stderr, "fixing the mising order...\n"); */
+  /* fix order of Missing (memory intensive, but fast) */
+  N = 0; 
+  ALLOCATE (tmpmissing, Missing, Nmiss);
+  for (i = 0; i < Nave; i++) {
+    if (catalog[0].average[i].Nn > 0) {
+      n = catalog[0].average[i].missing;
+      catalog[0].average[i].missing = N;
+      for (k = 0; k < catalog[0].average[i].Nn; k++, N++) {
+	if ((n == -1) || (n == -2)) {
+	  fprintf (stderr, "error: linked list is confused\n");
+	  exit (1);
+	}
+	tmpmissing[N] = catalog[0].missing[n]; 
+	n = next_miss[n];
+      }
+    }
+  }
+  Nmiss = N;
+  free (catalog[0].missing);
+  catalog[0].missing = tmpmissing;
+  REALLOCATE (catalog[0].missing, Missing, Nmiss);
+
+  fprintf (stderr, "\n");
+
+  catalog[0].Naverage = Nave;
+  catalog[0].Nmeasure = Nmeas;
+  catalog[0].Nmissing = Nmiss;
+  if (VERBOSE) fprintf (stderr, "  ending with Nave, Nmeas, Nmiss: %d %d %d\n", Nave, Nmeas, Nmiss);
+
+  free (next);
+  free (next_miss);
+  free (ave_miss);
+  return;
+}
+
Index: /branches/delstar-1-7/Ohana/src/delstar/src/gimages.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/gimages.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/gimages.c	(revision 10346)
@@ -0,0 +1,87 @@
+# include "delstar.h"
+
+/* load information about image from image header
+ * this should be the same as addstar/gstars, but it is not...
+ */
+
+Image *gimages (char *filename) {
+ 
+  FILE *f;
+  Header header;
+  char photcode[64], *c;
+  double tmp;
+  Image *image;
+  int Nc;
+
+  ALLOCATE (image, Image, 1);
+  /* load header */
+  if (!gfits_read_header (filename, &header)) {
+    Shutdown ("ERROR: can't find image file %s", filename);
+  }
+
+  /* open file */
+  f = fopen (filename, "r");
+  if (f == NULL) {
+    Shutdown ("ERROR: can't find data file %s", filename);
+  }
+  fseek (f, header.size, SEEK_SET); 
+
+  /* add file name to image structure */
+  c = strrchr (filename, 0x2f);
+  if (c == (char *) NULL) {
+    strcpy (image[0].name, filename);
+  } else { 
+    strcpy (image[0].name, (c+1));
+  }
+
+  /* get astrometry information */
+  if (!GetCoords (&image[0].coords, &header)) {
+    Shutdown ("ERROR: no astrometric solution in header");
+  }
+  while (image[0].coords.crval1 < 0) image[0].coords.crval1 += 360.0;
+  while (image[0].coords.crval1 > 360.0) image[0].coords.crval1 -= 360.0;
+
+  /* CERROR in data file is in pixels, convert to 20*arcsec */
+  image[0].cerror = tmp * 50.0 * image[0].coords.cdelt1 * 3600.0;
+  while (image[0].coords.crval1 < 0) image[0].coords.crval1 += 360.0;
+  while (image[0].coords.crval1 > 360.0) image[0].coords.crval1 -= 360.0;
+ 
+  /* get other header info */
+  gfits_scan (&header, "NAXIS1",   "%hd", 1, &image[0].NX); 
+  gfits_scan (&header, "NAXIS2",   "%hd", 1, &image[0].NY);
+
+  gfits_scan (&header, "PHOTCODE", "%s", 1, photcode);
+  Nc = GetPhotcodeCodebyName (photcode);
+  if (!Nc) {
+    Shutdown ("ERROR: photcode %s not found in photcode table", photcode);
+  }
+  image[0].source = Nc;
+
+  tmp = 0;
+  gfits_scan (&header, "FLIMIT",   "%lf", 1, &tmp);
+  image[0].detection_limit = tmp * 10.0;
+
+  tmp = 0;
+  gfits_scan (&header, "FSATUR",   "%lf", 1, &tmp);
+  image[0].saturation_limit = tmp * 10.0;
+
+  if (!gfits_scan (&header, "TZERO",   "%d",  1, &image[0].tzero)) {
+    image[0].tzero = parse_time (&header);
+  }
+
+  tmp = 0;
+  gfits_scan (&header, "TRATE",   "%lf", 1, &tmp);
+  image[0].trate = 10000 * tmp;
+
+  tmp = 0;
+  gfits_scan (&header, "AIRMASS", "%lf", 1, &tmp);
+  image[0].secz_PS = tmp;
+
+  /* secz is in units milli-airmass */
+  image[0].Mcal_PS =  ALPHA*(image[0].secz_PS - 1.000);
+  image[0].Xm   = NO_MAG;
+
+  free (header.buffer);
+ 
+  return (image);
+}
Index: /branches/delstar-1-7/Ohana/src/delstar/src/match_images.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/match_images.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/match_images.c	(revision 10346)
@@ -0,0 +1,52 @@
+# include "delstar.h"
+
+void match_images (Catalog *catalog, Image *image, int Nimage) {
+  
+  int j, k, found;
+  unsigned int *start, *stop;
+
+  /* this must be allocated so future free will not fail */
+  ALLOCATE (catalog[0].image, int, MAX (catalog[0].Nmeasure, 1));
+  if (catalog[0].Naverage == 0) {
+    if (VERBOSE) fprintf (stderr, "no stars in catalog, skipping\n");
+    return (FALSE);
+  }
+
+  ALLOCATE (start, unsigned int, Nimage);
+  ALLOCATE (stop,  unsigned int, Nimage);
+  for (j = 0; j < Nimage; j++) {
+    start[j] = image[j].tzero - MAX(0.05*image[j].trate*image[j].NY, 1);
+    stop[j]  = image[j].tzero + MAX(1.05*image[j].trate*image[j].NY, 1);
+  }
+
+  for (j = 0; j < catalog[0].Nmeasure; j++) {
+    found = FALSE;
+    if (catalog[0].measure[j].t == 0) {
+      catalog[0].image[j] = -1;
+      found = TRUE;
+    }
+    for (k = 0; (k < Nimage) && !found; k++) {
+      if ((catalog[0].measure[j].t >= start[k]) && 
+	  (catalog[0].measure[j].t <= stop[k])) {
+	catalog[0].image[j] = k;
+	found = TRUE;
+      }
+    }
+    if (!found) {
+      catalog[0].image[j] = -1;
+      /* fprintf (stderr, "missing: %d %d\n", catalog[0].image[j], catalog[0].measure[j].t); */
+    }
+  }
+  free (start);
+  free (stop);
+}
+
+  /* this routine uses the time of each measurement to match the
+measurement with an image.  Since the measurement is only store to 1
+sec accuracy, which corresponds to roughly 30 rows at nominal speed,
+we can't tell exactly which image the star come from.  However, this
+doesn't matter, and in fact this helps a bit: a measurement from the
+top of one image is the same as from the bottom of the next.
+Therefore, we intentionally blur the edges of the images by 5%, which
+will help to tie together neighboring images... */
+
Index: /branches/delstar-1-7/Ohana/src/delstar/src/parse_time.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/parse_time.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/parse_time.c	(revision 10346)
@@ -0,0 +1,112 @@
+# include "delstar.h"
+
+int parse_time (Header *header) {
+
+  double jd;
+  int Ny, Nf, mode;
+  int Nsec, hour, min, sec, year, month, day;
+  char *py, *pm, *pd, *c;
+  char line[256];
+
+  /* we want to find JD or MJD to get Nsec (seconds since 01/01/1970) */
+
+  /* try JD first */
+  if (strcasecmp (JDKeyword, "NONE")) {
+    uppercase (JDKeyword);
+    gfits_scan (header, JDKeyword, "%lf", 1, &jd);
+    Nsec = (jd - 2440587.5)*86400;
+    return (Nsec);
+  }
+
+  /* try MJD next */
+  if (strcasecmp (MJDKeyword, "NONE")) {
+    uppercase (MJDKeyword);
+    gfits_scan (header, MJDKeyword, "%lf", 1, &jd);
+    Nsec = (jd - 40587.0)*86400;
+    return (Nsec);
+  }
+    
+  /* get UT and DATE */
+  uppercase (UTKeyword);
+  gfits_scan (header, UTKeyword, "%s", 1, line);
+  /* remove ':' characters */
+  for (c = strchr (line, 0x3a); c != (char *) NULL; c = strchr (line, 0x3a)) { *c = ' '; }
+  sscanf (line, "%d %d %d", &hour, &min, &sec);
+
+  /* parse mode line */
+  uppercase (DateMode);
+  for (Ny = 0, c = strchr (DateMode, 'Y'); c != (char ) NULL; c = strchr (c + 1, 'Y'), Ny++);
+  if ((Ny != 2) && (Ny != 4)) {
+    Shutdown ("error in DATE-MODE format: %s", DateMode);
+  }
+  py = strchr (DateMode, 'Y');
+  pm = strchr (DateMode, 'M');
+  pd = strchr (DateMode, 'D');
+  if ((py == (char *) NULL) || (pm == (char *) NULL) || (pd == (char *) NULL)) {
+    Shutdown ("error in DATE-MODE format: %s", DateMode);
+  }
+  if ((py > pm) && (py < pd)) {
+    Shutdown ("error in DATE-MODE format: %s", DateMode);
+  }
+  if ((py > pd) && (py < pm)) {
+    Shutdown ("error in DATE-MODE format: %s", DateMode);
+  }
+  mode = 0;
+  if ((py < pm) && (pm < pd)) { mode = 1; }  /* yyyy-mm-dd */
+  if ((py < pm) && (pm > pd)) { mode = 2; }  /* yyyy-dd-mm */
+  if ((py > pm) && (pm < pd)) { mode = 3; }  /* mm-dd-yyyy */
+  if ((py > pm) && (pm > pd)) { mode = 4; }  /* dd-mm-yyyy */
+  if (!mode) {
+    Shutdown ("error in DATE-MODE format: %s", DateMode);
+  }
+
+  /* parse date entry */
+  uppercase (DateKeyword);
+  gfits_scan (header, DateKeyword, "%s",  1, line);
+  /* remove possible separators: ':', '/' '.', '-' */
+  for (c = strchr (line, 0x3a); c != (char *) NULL; c = strchr (line, 0x3a)) { *c = ' '; }
+  for (c = strchr (line, 0x2f); c != (char *) NULL; c = strchr (line, 0x2f)) { *c = ' '; }
+  for (c = strchr (line, 0x2e); c != (char *) NULL; c = strchr (line, 0x2e)) { *c = ' '; }
+  for (c = strchr (line, 0x2d); c != (char *) NULL; c = strchr (line, 0x2d)) { *c = ' '; }
+
+  switch (mode) {
+  case 1:
+    Nf = sscanf (line, "%d %d %d", &year, &month, &day);
+    break;
+  case 2:
+    Nf = sscanf (line, "%d %d %d", &year, &day, &month);
+    break;
+  case 3:
+    Nf = sscanf (line, "%d %d %d", &month, &day, &year);
+    break;
+  case 4:
+    Nf = sscanf (line, "%d %d %d", &day, &month, &year);
+    break;
+  }
+  if (Nf != 3) {
+    Shutdown ("error in date entry (%s) or DATE-MODE format (%s)", line, DateMode);
+  }
+
+  if (year > 1000) {
+    if (Ny == 2) {
+      fprintf (stderr, "warning: mode line claims 2 digit year, but 4 digit year found\n");
+    }
+  } else {
+    if (Ny == 4) {
+      fprintf (stderr, "warning: mode line claims 4 digit year, but 2 digit year found\n");
+    }
+    if (year < 50) year += 100;
+    year += 1900;
+  }    
+
+  /* convert yy.mm.dd hh.mm.ss to Nsec since 1970 (jd = 2440587.5) */
+  /* note that in this section, tm_mon has range 1-12, unlike for gmtime () */
+  jd = day - 32075 + (int)(1461*(year + 4800 + (int)(((month)-14)/12))/4)
+    + (int)(367*((month) - 2 - (int)(((month) - 14)/12)*12)/12)
+    - (int)(3*(int)((year + 4900 + (int)(((month) - 14)/12))/100)/4) - 0.5;
+  /* jd is the julian day of the whole day only not the time */
+  Nsec = (jd - 2440587.5)*86400 + 3600.0*hour + min*60.0 + sec;
+  
+  return (Nsec);
+
+}
Index: /branches/delstar-1-7/Ohana/src/delstar/src/sort_lists.c
===================================================================
--- /branches/delstar-1-7/Ohana/src/delstar/src/sort_lists.c	(revision 10346)
+++ /branches/delstar-1-7/Ohana/src/delstar/src/sort_lists.c	(revision 10346)
@@ -0,0 +1,47 @@
+# include "delstar.h"
+
+void sort_lists (float *X, float *Y, int *S, int N) {
+
+  int l,j,ir,i;
+  double tX, tY, tS;
+  
+  l = N >> 1;
+  ir = N - 1;
+  for (;;) {
+    if (l > 0) {
+      l--;
+      tX = X[l];
+      tY = Y[l];
+      tS = S[l];
+    } else {
+      tX = X[ir];
+      X[ir] = X[0];
+      tY = Y[ir];
+      Y[ir] = Y[0];
+      tS = S[ir];
+      S[ir] = S[0];
+      if (--ir == 0) {
+	X[0] = tX;
+	Y[0] = tY;
+	S[0] = tS;
+	return;
+      }
+    }
+    i = l;
+    j = (l << 1) + 1;
+    while (j <= ir) {
+      if (j < ir && X[j] < X[j+1]) j++;
+      if (tX < X[j]) {
+	X[i] = X[j];
+	Y[i] = Y[j];
+	S[i] = S[j];
+	j += (i=j) + 1;
+      }
+      else j = ir + 1;
+    }
+    X[i] = tX;
+    Y[i] = tY;
+    S[i] = tS;
+  }
+}
+
