Index: /branches/elixir/Ohana/src/delstar/Makefile
===================================================================
--- /branches/elixir/Ohana/src/delstar/Makefile	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/Makefile	(revision 2462)
@@ -0,0 +1,63 @@
+include ../../Configure
+CC      =       gcc -g  # override this for now for minimal test
+HOME 	=	$(ROOT)/src/delstar
+CONFIG  =	$(ROOT)/config
+PROGRAM =       delstar
+
+BIN	=	$(HOME)/bin
+INC	= 	$(HOME)/include
+SRC	=	$(HOME)/src
+MAN	=	$(HOME)/doc
+DESTBIN	=	$(LBIN)
+DESTLIB	=	$(LLIB)
+DESTINC	=	$(LINC)
+DESTMAN	=	$(LMAN)
+
+#  
+INCS	= 	-I$(INC) -I$(LINC) -I$(XINC) -I$(LINC)/$(ARCH)
+LIBS	= 	-L$(LLIB) -lFITS -lohana -lm 
+CFLAGS	=	-o $*.$(ARCH).o $(INCS)
+CCFLAGS	=	$(INCS) $(LIBS) 
+
+DELSTAR = \
+$(SRC)/delstar.$(ARCH).o 	$(SRC)/gcatalog.$(ARCH).o   	\
+$(SRC)/gregions.$(ARCH).o 	$(SRC)/gimages.$(ARCH).o    	\
+$(SRC)/dimages.$(ARCH).o        $(SRC)/gtimes.$(ARCH).o     	\
+$(SRC)/find_matches.$(ARCH).o 	$(SRC)/wcatalog.$(ARCH).o   	\
+$(SRC)/ConfigInit.$(ARCH).o 	$(SRC)/args.$(ARCH).o	        \
+$(SRC)/aregion.$(ARCH).o	$(SRC)/delete_missed.$(ARCH).o  \
+$(SRC)/sort_lists.$(ARCH).o	$(SRC)/parse_time.$(ARCH).o     \
+$(SRC)/gcatstats.$(ARCH).o	$(SRC)/find_images.$(ARCH).o	\
+$(SRC)/match_images.$(ARCH).o	$(SRC)/delete_orphans.$(ARCH).o
+
+OBJ = $(DELSTAR)
+
+default: $(PROGRAM)
+
+$(DELSTAR): $(INC)/delstar.h
+
+# dependancy rules for binary code ##########################
+$(PROGRAM): $(BIN)/$(PROGRAM).$(ARCH)
+
+$(BIN)/$(PROGRAM).$(ARCH): $(OBJ)
+	$(CC) $(OBJ) -o $(BIN)/$(PROGRAM).$(ARCH) $(CCFLAGS)
+
+install: $(DESTBIN)/$(PROGRAM)
+
+$(DESTBIN)/$(PROGRAM): $(BIN)/$(PROGRAM).$(ARCH)
+	rm -f $(DESTBIN)/$(PROGRAM)
+	cp $(BIN)/$(PROGRAM).$(ARCH) $(DESTBIN)/$(PROGRAM)
+
+# utilities #################################################
+clean:	
+	rm -f $(BIN)/*.$(ARCH)
+	rm -f `find . -name "*.o"`
+	rm -f `find . -name "*~"`
+	rm -f `find . -name "#*"`
+
+.SUFFIXES: .$(ARCH).o
+
+.c.$(ARCH).o:
+	$(CC) $(CFLAGS) -c $<
+
+
Index: /branches/elixir/Ohana/src/delstar/include/addstar.h
===================================================================
--- /branches/elixir/Ohana/src/delstar/include/addstar.h	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/include/addstar.h	(revision 2462)
@@ -0,0 +1,13 @@
+# include <ohana.h>
+# include <loneos.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/elixir/Ohana/src/delstar/include/delstar.h
===================================================================
--- /branches/elixir/Ohana/src/delstar/include/delstar.h	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/include/delstar.h	(revision 2462)
@@ -0,0 +1,25 @@
+# include <ohana.h>
+# include <loneos.h>
+# include <signal.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;
+int    ORPHAN;
+int    MISSED;
+
+typedef struct {
+  Coords coords;
+  float *X, *Y;
+  int *N;
+  double RA[2], DEC[2];
+  double Area, density, spacing;
+} CatStats;
+
+char DateKeyword[64], DateMode[64], UTKeyword[64], MJDKeyword[64], JDKeyword[64];
Index: /branches/elixir/Ohana/src/delstar/src/ConfigInit.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/ConfigInit.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/ConfigInit.c	(revision 2462)
@@ -0,0 +1,40 @@
+# include "delstar.h"
+
+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, "IMAGE_CATALOG",          "%s", 0, ImageCat);
+  ScanConfig (config, "IMAGE_CATALOG_TEMPLATE", "%s", 0, ImageTemplate);
+  ScanConfig (config, "CATALOG_TEMPLATE",       "%s", 0, CatTemplate);
+  ScanConfig (config, "GSCFILE",                "%s", 0, GSCFILE);
+  ScanConfig (config, "CATDIR",                 "%s", 0, CATDIR);
+  ScanConfig (config, "PHOTCODE_FILE",          "%s", 0, PhotCodeFile);
+
+  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 (!LoadPhotcodes (PhotCodeFile)) {
+    fprintf (stderr, "error loading photcodes\n");
+    exit (1);
+  }
+
+  free (config);
+  free (file);
+}
Index: /branches/elixir/Ohana/src/delstar/src/aregion.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/aregion.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/aregion.c	(revision 2462)
@@ -0,0 +1,186 @@
+# include "delstar.h"
+
+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, 24, 
+                   0, 597, 578, 574, 577, 534, 499, 442, 376, 294, 212, 144, 48};
+
+/* find region file which contains ra, dec */
+aregion (region, f, ra, dec) 
+GSCRegion region[];
+FILE *f;
+double ra, dec;
+{
+  
+  
+  char buffer[28800], temp[50], file[50];
+  double dr, dd;
+  double RA0, RA1, DEC0, DEC1;
+  int i, NBigDec, NLINES, done, nregion;
+  
+  while (ra < 0) { ra += 360.0; }
+  while (ra >= 360.0) { ra -= 360.0; }
+    
+  if (dec >= 86.25) {
+    sprintf (file, "%s/n8230/pole.cpt\0", CATDIR);
+    region[0].DEC[0] = 86.25;
+    region[0].DEC[1] = 93.75;
+    region[0].RA[0] = -180.0;
+    region[0].RA[1] =  540.0;
+    strcpy (region[0].filename, file);
+    return;
+  }
+    
+  NBigDec = -1;
+  for (i = 0; i < 12; i++) {
+# ifdef DEBUG
+    fprintf (stderr, "%d %f %f %f\n", i, dec, BigDecBounds[i], BigDecBounds[i+1]);
+# endif
+    if ((dec >= BigDecBounds[i]) && (dec < BigDecBounds[i+1])) {
+      NBigDec = i;
+      break;
+    }
+  }
+  if (NBigDec < 0) {
+    for (i = 13; i < 24; i++) {
+# ifdef DEBUG
+      fprintf (stderr, "%d %f %f %f\n", i, dec, BigDecBounds[i], BigDecBounds[i+1]);
+# endif
+      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];
+  }
+  fseek (f, 5*2880 + 48*NLINES, SEEK_SET);
+      
+  done = FALSE;
+  Fread (buffer, 1, 48*NDecLines[NBigDec], f, "char");
+  for (i = 0; !done && (i < NDecLines[NBigDec]); i++) {
+    strncpy (temp, &buffer[i*48], 48);
+    temp[49] = 0;
+    hms_to_deg (&RA0, &RA1, &DEC0, &DEC1, &temp[7]);
+    if (RA1 < RA0) RA1 += 360.0;
+# ifdef DEBUG
+    fprintf (stderr, "%f %f %f  %f %f %f  %s\n", DEC0, dec, DEC1, RA0, ra, RA1, temp);
+# endif
+    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 (!done) {
+    fprintf (stderr, "error in search: %f %f\n", ra, dec);
+    exit (1);
+  }
+  temp[5] = 0;
+  sprintf (file, "%s/%s/%s.cpt\0", CATDIR, Dec2Sections[NBigDec],&temp[1]);
+  if (DEC0 < DEC1) {
+    region[0].DEC[0] = DEC0;
+    region[0].DEC[1] = DEC1;
+  } else {
+    region[0].DEC[0] = DEC1;
+    region[0].DEC[1] = DEC0;
+  }     
+  region[0].RA[0] = RA0;
+  region[0].RA[1] = RA1;
+  strcpy (region[0].filename, file);
+  return;
+}
+
+
+/**********/
+int hms_to_deg (h0, h1, d0, d1, string) 
+     char *string;
+     double *h0, *h1, *d0, *d1;
+{
+  
+  int flag_d0, flag_d1, flag_h0, flag_h1;
+  double tmp;
+  
+  *d0 = *h0 = *d1 = *h1 = 0;
+
+  flag_h0 = dparse (h0, 1, string);
+  flag_h1 = dparse (h1, 4, string);
+  flag_d0 = dparse (d0, 7, string);
+  flag_d1 = dparse (d1, 9, string);
+  *h0 *= flag_h0;
+  *h1 *= flag_h1;
+  *d0 *= flag_d0;
+  *d1 *= flag_d1;
+
+  dparse (&tmp, 2, string);
+  *h0 += tmp/60.0;
+  dparse (&tmp, 3, string);
+  *h0 += tmp/3600.0;
+  
+  dparse (&tmp, 5, string);
+  *h1 += tmp/60.0;
+  dparse (&tmp, 6, string);
+  *h1 += tmp/3600.0;
+  
+  dparse (&tmp, 8, string);
+  *d0 += tmp/60.0;
+
+  dparse (&tmp, 10, string);
+  *d1 += tmp/60.0;
+
+  *h0 *= 15*flag_h0;
+  *h1 *= 15*flag_h1;
+  *d0 *= flag_d0;
+  *d1 *= flag_d1;
+
+  return (TRUE);
+}
+
+
+/*
+      if (buffer[i*48 + 19] == ' ') continue;
+      strncpy (temp, &buffer[i*48 + 19], 20);       temp[20] = 0;
+      hms_to_deg (&RA,  &DEC, temp, ' ', 3);
+
+
+  dBigRA = 360.0 / (int)(0.5 + 48*cos(3.1415927*0.5*(BigDecBounds[NBigDec] + BigDecBounds[NBigDec + 1])/180.0));
+
+  NBigRA = ra / dBigRA;
+
+  NBig = NBigRA;
+  for (i = 0; (i < 12) && (i < NBigDec); i++) {
+    NBig += NBigRASections[i];
+  }
+  for (i = 13; (i < 24) && (i < NBigDec); i++) {
+    NBig += NBigRASections[i];
+  }
+
+
+  fprintf (stderr, "%d %d %d %d %f %f -> %f %f %f\n", NBigDec, NBigRA, NBigRASections[NBigDec], NBig, ra, dec, BigDecBounds[NBigDec], BigDecBounds[NBigDec + 1], dBigRA);
+*/
Index: /branches/elixir/Ohana/src/delstar/src/args.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/args.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/args.c	(revision 2462)
@@ -0,0 +1,49 @@
+# include "delstar.h"
+
+void help () {
+
+  fprintf (stderr, "USAGE: delstar (filename) or (start range) or -orphan (region)\n");
+  fprintf (stderr, "  optional flags:\n");
+  fprintf (stderr, "  -v (verbose mode)\n");
+  fprintf (stderr, "\n"); 
+  exit (2);
+
+}
+
+int args (int *argc, char **argv) {
+  
+
+  int N;
+
+  ConfigInit (argc, argv);
+
+  /* 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);
+  }
+
+  ORPHAN = FALSE;
+  if ((N = get_argument (*argc, argv, "-orphan"))) {
+    ORPHAN = TRUE;
+    remove_argument (N, argc, argv);
+  }
+
+  MISSED = FALSE;
+  if ((N = get_argument (*argc, argv, "-missed"))) {
+    MISSED = TRUE;
+    remove_argument (N, argc, argv);
+  }
+
+  if ((*argc != 2) && (*argc != 3)) {
+    fprintf (stderr, "ERROR: Usage: delstar (filename) or (start range) or -orphan (region)\n");
+    exit (2);
+  }
+
+}
Index: /branches/elixir/Ohana/src/delstar/src/delete_missed.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/delete_missed.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/delete_missed.c	(revision 2462)
@@ -0,0 +1,22 @@
+# include "delstar.h"
+
+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/elixir/Ohana/src/delstar/src/delete_orphans.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/delete_orphans.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/delete_orphans.c	(revision 2462)
@@ -0,0 +1,248 @@
+# include "delstar.h"
+
+delete_orphans (Catalog *catalog) {
+
+  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;
+
+
+  /** allocate local arrays **/
+  Nave = catalog[0].Naverage;
+
+  Nmeas = catalog[0].Nmeasure;
+  ALLOCATE (next, int, Nmeas);
+  
+  Nmiss = catalog[0].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[0].average[i].Nn; j++) {
+      ave_miss[catalog[0].average[i].missing + j] = i;
+    }
+  }
+  Nmeasfound = 0;
+  Nsecfilt = catalog[0].Nsecfilt;
+
+  /* fprintf (stderr, "fixing the measures...\n"); */
+  for (i = 0; (i < Nmeas); i++) {
+    if ((catalog[0].measure[i].t != 0) && (catalog[0].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[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?  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[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);
+
+  /* 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[0].missing[i].t >= start) && (catalog[0].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[0].average[n].missing > 0) && (catalog[0].average[n].missing <= i) && (catalog[0].average[n].missing + catalog[0].average[n].Nn > i)) 
+	  found = TRUE;
+      }
+      n--; */
+      /*** 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;
+      }
+
+    }
+  }
+
+  /* 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[0].measure[stars[N].found].flags |= BLEND_IMAGE;
+    catalog[0].measure[Nmeas].flags |= BLEND_IMAGE;
+  } 
+  if (stars[N].found == -2) { /* this image star matches a catalog star on a neighboring catalog */
+    catalog[0].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[0].found[n] > -1) {
+    catalog[0].measure[catalog[0].found[n]].flags |= BLEND_CATALOG;
+    catalog[0].measure[Nmeas].flags |= BLEND_CATALOG;
+  } else {
+    catalog[0].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[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));
+  
+  /* 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[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);
+
+  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);
+
+}
+
Index: /branches/elixir/Ohana/src/delstar/src/delstar.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/delstar.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/delstar.c	(revision 2462)
@@ -0,0 +1,212 @@
+# include "delstar.h"
+
+/* these variables are needed by Shutdown */
+static FILE *f = (FILE *) NULL;
+static int Protect = FALSE;
+static int Trapped = FALSE;
+
+/* clean up open / locked ImageCat before shutting down */
+int Shutdown () {  
+  int dbstate;
+
+  Protect = TRUE;
+  fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
+  fprintf (stderr, "ERROR: delstar halted\n");
+  exit (1);
+}
+
+void TrapSignal (int sig) {
+    fprintf (stderr, "trapped signal %d, exiting gracefully\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 ();
+}    
+
+main (int argc, char **argv) {
+
+  int i, j, k, found, Nimage, Nregions, Ntregions, NREGIONS;
+  int start, end, dbstate;
+  Image *image, *gimages(), *gtimes(), *find_images();
+  Catalog catalog;
+  CatStats catstats;
+  GSCRegion *region, *tregion, *gregions();
+  
+  SetSignals ();
+  args (&argc, argv);
+
+  /* lock the image catalog */
+  f = fsetlockfile (ImageCat, 3600.0, LCK_HARD, &dbstate);
+  if (f == (FILE *) NULL) {
+    fprintf (stderr, "ERROR: can't lock image catalog\n");
+    exit (1);
+  }
+  fseek (f, 0, SEEK_SET);
+
+  /* delete orphaned measurements (no image) from catalog */ 
+  if (ORPHAN) {
+    ALLOCATE (region, GSCRegion, 1);
+    catalog.filename = argv[1];
+    gcatalog (&catalog);
+    gcatstats (&catalog, &catstats);
+    image = find_images (f, &catstats, &Nimage);
+    match_images (&catalog, image, Nimage);
+    delete_orphans (&catalog);
+    wcatalog (&catalog);
+    fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
+    fprintf (stderr, "SUCCESS\n");
+    exit (0);
+  } 
+
+  /* delete missed measurements from catalog */ 
+  if (MISSED) {
+    catalog.filename = argv[1];
+    switch (lock_catalog (&catalog, LCK_XCLD)) {
+    case 0:
+      fprintf (stderr, "ERROR: can't lock file\n");
+      exit (1);
+    case 1:
+      gcatalog (&catalog);
+      break;
+    case 2:
+      fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
+      catalog.Naverage = 0;
+      catalog.Nmeasure = 0;
+      break;
+    default:
+      fprintf (stderr, "weird lock_catalog exit state\n");
+      exit (1);
+    }
+    delete_missed (&catalog);
+    wcatalog (&catalog);
+    fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
+    fprintf (stderr, "SUCCESS\n");
+    exit (0);
+  } 
+
+  /* delete given image from catalogs */
+  if (argc == 2) {
+    image = gimages (argv[1]);
+  
+    fprintf (stderr, "deleting %s\n", image[0].name);
+    region = gregions (&image[0], &Nregions);
+
+    for (i = 0; i < Nregions; i++) {
+      fprintf (stderr, "deleting from %s\n", region[i].filename);
+      catalog.filename = region[i].filename;  /* don't free region before catalog! */
+      switch (lock_catalog (&catalog, LCK_SOFT)) {
+      case 0:
+	fprintf (stderr, "ERROR: can't lock file\n");
+	exit (1);
+      case 1:
+	gcatalog (&catalog);
+	break;
+      case 2:
+	fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
+	catalog.Naverage = 0;
+	catalog.Nmeasure = 0;
+	break;
+      default:
+	fprintf (stderr, "weird lock_catalog exit state\n");
+	exit (1);
+      }
+      find_matches (&catalog, &image[0], 0, 0);
+      wcatalog (&catalog);
+    }
+
+    dimages (f, image, 1); 
+    fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
+    fprintf (stderr, "SUCCESS\n");
+    exit (0);
+  }
+
+  /* delete measurements in time range */
+  if (argc == 3) {
+    Nregions = 0;
+    NREGIONS = 10;
+    ALLOCATE (region, GSCRegion, NREGIONS);
+
+    /* find image for time range, delete each image */ 
+    image = gtimes (f, argv, &Nimage, &start, &end);
+    for (j = 0; j < Nimage; j++) {
+      fprintf (stderr, "finding regions for %s\n", image[j].name);
+      tregion = gregions (&image[j], &Ntregions);
+      for (i = 0; i < Ntregions; i++) {
+	found = FALSE;
+	for (k = 0; (k < Nregions) && !found; k++) {
+	  found = !strcmp (region[k].filename, tregion[i].filename);
+	}
+	if (!found) {
+	  strcpy (region[Nregions].filename, tregion[i].filename);
+	  region[Nregions].RA[0] = tregion[i].RA[0];
+	  region[Nregions].RA[1] = tregion[i].RA[1];
+	  region[Nregions].DEC[0] = tregion[i].DEC[0];
+	  region[Nregions].DEC[1] = tregion[i].DEC[1];
+	  Nregions ++;
+	  if (Nregions >= NREGIONS) {
+	    NREGIONS += 10;
+	    REALLOCATE (region, GSCRegion, NREGIONS);
+	  }
+	}
+      }
+    }
+    for (i = 0; i < Nregions; i++) {
+      fprintf (stderr, "deleting from %s\n", region[i].filename);
+      catalog.filename = region[i].filename;  /* don't free region before catalog! */
+      switch (lock_catalog (&catalog, LCK_SOFT)) {
+      case 0:
+	fprintf (stderr, "ERROR: can't lock file\n");
+	exit (1);
+      case 1:
+	gcatalog (&catalog);
+	break;
+      case 2:
+	fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
+	catalog.Naverage = 0;
+	catalog.Nmeasure = 0;
+	break;
+      default:
+	fprintf (stderr, "weird lock_catalog exit state\n");
+	exit (1);
+      }
+      find_matches (&catalog, &image[0], start, end);
+      wcatalog (&catalog);
+    }
+    dimages (f, image, Nimage);
+    fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
+    fprintf (stderr, "SUCCESS\n");
+    exit (0);
+  }
+}
+
+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);
+    }
+  }
+
+}
Index: /branches/elixir/Ohana/src/delstar/src/dimages.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/dimages.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/dimages.c	(revision 2462)
@@ -0,0 +1,72 @@
+# include "addstar.h"
+
+dimages (FILE *f, Image *image, int Nimages) {
+  
+  int i, j, Ntimage, ntimage, mode;
+  int start, end, tstart, tend, status;
+  char line[256];
+  struct stat filestat;
+  Image *timage;
+  Header header;
+
+  /* use cp to make backup copy */
+  sprintf (line, "cp %s %s~\0", ImageCat, ImageCat);
+  status = system (line);
+  if (status) {
+    fprintf (stderr, "ERROR: unable to create %s~, exiting\n", ImageCat);
+    Shutdown ();
+  }
+  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+  sprintf (line, "%s~\0", ImageCat);
+  chmod (line, mode);
+
+  /* check if image datafile exists, get header */
+  fseek (f, 0, SEEK_SET); 
+  if (!fits_fread_header (f, &header)) {
+    fprintf (stderr, "Can't find image catalog\n");
+    exit (1);
+  }
+  fseek (f, header.size, SEEK_SET); 
+
+  fits_scan (&header, "NIMAGES", "%d", 1, &Ntimage);
+  ALLOCATE (timage, Image, Ntimage);
+  ntimage = Fread (timage, sizeof(Image), Ntimage, f, "image");
+  if (Ntimage != ntimage) {
+    fprintf (stderr, "failed to read in entire image file %s\n", ImageCat);
+    exit (1);
+  }
+
+  /* need to delete on basis of both image time & photcode */
+  /* first, mark the deleted images with a flag (NX = 0) */
+  for (i = 0; i < Ntimage; i++) {
+    for (j = 0; j < Nimages; j++) {
+      tstart = timage[i].tzero;
+      tend = timage[i].tzero + timage[i].trate * timage[i].NY;
+      start = image[j].tzero;
+      end = image[j].tzero + image[j].trate * image[j].NY;
+      if ((tstart <= end) && (tend >= start) && (timage[i].source == image[j].source)) {
+	fprintf (stderr, "deleting %s\n", timage[i].name);
+	timage[i].NX = 0;
+      }
+    }
+  }
+
+  /* delete the marked images */
+  for (i = 0, j = 0; j < Ntimage; j++) {
+    if (timage[j].NX) {
+      if (i != j) {
+	timage[i] = timage[j];
+      }
+      i++;
+    }
+  }
+  Ntimage = i;
+  REALLOCATE (timage, Image, Ntimage);
+  fits_modify (&header, "NIMAGES", "%d", 1, Ntimage);
+
+  /* should make a backup copy of the ImageCat file */
+  fseek (f, 0, SEEK_SET);
+  Fwrite (header.buffer, 1, header.size, f, "char");
+  Fwrite (timage, sizeof(Image), Ntimage, f, "image");
+
+}
Index: /branches/elixir/Ohana/src/delstar/src/find_images.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/find_images.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/find_images.c	(revision 2462)
@@ -0,0 +1,190 @@
+# include "delstar.h"
+double opening_angle ();
+
+Image *find_images (FILE *f, CatStats *catstats, int *Nimages) {
+  
+  Header header;
+  Image *timage, *image;
+  int i, j, k, found, nimage, Nimage, NIMAGE, NTIMAGE, Nloop, Nlast;
+  int n, Nim, status;
+  double Xc[6], Yc[6], Xi[6], Yi[6], r, d, x, y, dx, dy;
+  Coords *tcoords;
+
+  /* we make positional comparisons in the projection of catalog */
+  tcoords = &catstats[0].coords;
+  /* define catalog corners */
+  Xc[0] = catstats[0].RA[0]; Yc[0] = catstats[0].DEC[0];
+  Xc[1] = catstats[0].RA[1]; Yc[1] = catstats[0].DEC[0];
+  Xc[2] = catstats[0].RA[1]; Yc[2] = catstats[0].DEC[1];
+  Xc[3] = catstats[0].RA[0]; Yc[3] = catstats[0].DEC[1];
+  Xc[4] = catstats[0].RA[0]; Yc[4] = catstats[0].DEC[0];
+  Xc[5] = catstats[0].RA[1]; Yc[5] = catstats[0].DEC[1];
+  for (j = 0; j < 6; j++) {
+    r = Xc[j]; d = Yc[j];
+    RD_to_XY (&Xc[j], &Yc[j], r, d, tcoords);
+  }
+  /* find Y positions of RA center */
+  r = 0.5*(catstats[0].RA[0] + catstats[0].RA[1]);
+  d = catstats[0].DEC[0];
+  RD_to_XY (&x, &y, r, d, tcoords);
+  Yc[0] = MIN (y, Yc[0]);
+  Yc[1] = MIN (y, Yc[1]);
+  Yc[4] = MIN (y, Yc[4]);
+  /* find Y positions of RA center */
+  r = 0.5*(catstats[0].RA[0] + catstats[0].RA[1]);
+  d = catstats[0].DEC[1];
+  RD_to_XY (&x, &y, r, d, tcoords);
+  Yc[2] = MAX (y, Yc[2]);
+  Yc[3] = MAX (y, Yc[3]);
+  Yc[5] = MAX (y, Yc[5]);
+
+  dx = 0.02*(Xc[2] - Xc[0]);
+  dy = 0.02*(Yc[2] - Yc[0]);
+  Xc[0] -= dx; Yc[0] -= dy;
+  Xc[1] += dx; Yc[1] -= dy;
+  Xc[2] += dx; Yc[2] += dy;
+  Xc[3] -= dx; Yc[3] += dy;
+  Xc[4] -= dx; Yc[4] -= dy;
+  Xc[5] -= dx; Yc[5] -= dy;
+
+  /* check if image datafile exists, get header, number of images */
+  if (!fits_fread_header (f, &header)) {
+    fprintf (stderr, "ERROR: error reading image catalog header\n");
+    exit (1);
+  }
+  Nimage = 0;
+  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
+  if (Nimage == 0) {
+    fprintf (stderr, "ERROR: No images in catalog %s (1)\n", ImageCat);
+    Shutdown ();
+  }
+  fseek (f, header.size, SEEK_SET); 
+
+  /* set up buffers for images, temporary storage */
+  NTIMAGE = 100;
+  ALLOCATE (timage, Image, NTIMAGE);
+  NIMAGE = 100;
+  ALLOCATE (image, Image, NIMAGE);
+  nimage = 0;
+  Nloop = Nimage / NTIMAGE + 1;
+  Nlast = Nimage % NTIMAGE;
+  
+  /* read in images in groups of NTIMAGE (100) */
+  for (n = 0; n < Nloop; n++) {
+    Nim = (n == Nloop - 1) ? Nlast : NTIMAGE;
+    status = Fread (timage, sizeof(Image), Nim, f, "image");
+    if (status != Nim) {
+      fprintf (stderr, "ERROR: couldn't read images from image catalog: %s\n", ImageCat);
+      exit (1);
+    }
+    /* test each image in block */
+    for (i = 0; i < Nim; i++) {
+      /* define image corners */
+      Xi[0] = 0;            Yi[0] = 0;
+      Xi[1] = timage[i].NX; Yi[1] = 0;
+      Xi[2] = timage[i].NX; Yi[2] = timage[i].NY;
+      Xi[3] = 0;            Yi[3] = timage[i].NY;
+      Xi[4] = 0;            Yi[4] = 0;
+      Xi[5] = timage[i].NX; Yi[5] = timage[i].NY;
+      found = FALSE;
+      /* transform to tcoords */
+      if (catstats[0].DEC[1] > 86.25) { /* pole */
+	for (j = 0; j < 6; j++) {
+	  XY_to_RD (&r, &d, Xi[j], Yi[j], &timage[i].coords);
+	  if (d > catstats[0].DEC[0] - 0.5) found = TRUE;
+	}
+      } else {
+	for (j = 0; j < 6; j++) {
+	  XY_to_RD (&r, &d, Xi[j], Yi[j], &timage[i].coords);
+	  RD_to_XY (&Xi[j], &Yi[j], r, d, tcoords);
+	}
+	/* check if edges cross */
+	for (j = 0; (j < 5) && !found; j++) {
+	  for (k = 0; (k < 5) && !found; k++) {
+	    found |= edge_check (&Xi[j], &Yi[j], &Xc[k], &Yc[k]);
+	  }
+	}
+      }
+      if (found) {
+	image[nimage] = timage[i]; 
+	image[nimage].code = 0;
+	nimage ++;
+	if (nimage == NIMAGE) {
+	  NIMAGE += 100;
+	  REALLOCATE (image, Image, NIMAGE);
+	}
+      }
+    }
+  }
+      
+  if (VERBOSE) { 
+    for (i = 0; i < nimage; i++) {
+      XY_to_RD (&r, &d, 0.5*image[i].NX, 0.5*image[i].NY, &image[i].coords);
+      fprintf (stderr, "associated images: %d %8.4f %8.4f %10d %6d  %5.3f %6.3f %6.3f\n", 
+	       i, r, d, image[i].tzero, image[i].nstar, 0.001*image[i].secz, 
+	       0.001*image[i].Mcal, 0.001*image[i].dMcal);
+    }
+  }
+
+  REALLOCATE (image, Image, MAX (nimage, 1));
+  free (timage);
+  *Nimages = nimage;
+  return (image);
+}
+
+int edge_check (x1, y1, x2, y2)
+double *x1, *y1, *x2, *y2;
+{
+
+  double theta1, theta2;
+  double Theta1, Theta2;
+
+  theta1 = opening_angle (x1[0], y1[0], x2[0], y2[0], x1[1], y1[1]); 
+  theta2 = opening_angle (x1[0], y1[0], x2[0], y2[0], x2[1], y2[1]); 
+
+  if (theta1*theta2 < 0.0) {
+    return (FALSE);
+  }
+
+  if (fabs(theta1) < fabs(theta2)) {
+    return (FALSE);
+  }
+
+  Theta1 = theta1;
+  Theta2 = theta2;
+  theta1 = opening_angle (x2[0], y2[0], x1[1], y1[1], x2[1], y2[1]); 
+  theta2 = opening_angle (x2[0], y2[0], x1[1], y1[1], x1[0], y1[0]); 
+  
+ 
+  if (theta1*theta2 < 0.0) {
+    return (FALSE);
+  }
+
+  if (fabs(theta1) < fabs(theta2)) {
+    return (FALSE);
+  }
+
+  return (TRUE);
+
+}
+
+double opening_angle (x1, y1, x2, y2, x3, y3)
+double x1, y1, x2, y2, x3, y3;
+{
+
+  double dx1, dy1, dx2, dy2, ct, st, theta;
+
+  dx1 = x1 - x2;
+  dy1 = y1 - y2;
+  
+  dx2 = x3 - x2;
+  dy2 = y3 - y2;
+  
+  ct = (dx1*dx2 + dy1*dy2);
+  st = (dx1*dy2 - dx2*dy1);
+
+  theta = atan2 (st, ct);
+
+  return (theta);
+
+}
Index: /branches/elixir/Ohana/src/delstar/src/find_matches.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/find_matches.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/find_matches.c	(revision 2462)
@@ -0,0 +1,270 @@
+# include "delstar.h"
+
+find_matches (Catalog *catalog, Image *image, int start, int end) {
+
+  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, photcode;
+  int Nmeasfound, Nsecfilt;
+  int this, prev;
+  unsigned int flags;
+  Measure *tmpmeasure;
+  Missing *tmpmissing;
+  Coords tcoords;
+
+  /** 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;
+    }
+  }
+  photcode = -1;
+  if ((start == 0) && (end == 0)) {
+    start = image[0].tzero;
+    end   = image[0].tzero + 1e-4*image[0].NY*image[0].trate;  /* trate is in 0.1 msec / row */
+    photcode = image[0].source;
+  }
+  if (VERBOSE) fprintf (stderr, "deleting for range %d to %d (photcode %d)\n", start, end, photcode);
+  Nmeasfound = 0;
+  Nsecfilt = catalog[0].Nsecfilt;
+
+  /* fprintf (stderr, "fixing the measures...\n"); */
+  /** find measure in time range of image **/
+  this = prev = -1;
+  for (i = 0; (i < Nmeas); i++) {
+    if ((i % 10000) == 0) fprintf (stderr, ". ");
+    if ((catalog[0].measure[i].t >= start) && (catalog[0].measure[i].t <= end) && (photcode == catalog[0].measure[i].source)) { 
+      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;
+      }
+    } else {
+      prev = i;
+    }
+  }
+  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[0].missing[i].t >= start) && (catalog[0].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? (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 */
+      }
+      
+      /* find the corresponding avearge entry 
+      found = FALSE;
+      for (n = 0; !found && (n < Nave); n++) {
+	if ((catalog[0].average[n].missing > 0) && (catalog[0].average[n].missing <= i) && (catalog[0].average[n].missing + catalog[0].average[n].Nn > i)) 
+	  found = TRUE;
+      }
+      n--; */
+      /*** 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;
+      }
+
+    }
+  }
+
+  /* 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[0].measure[stars[N].found].flags |= BLEND_IMAGE;
+    catalog[0].measure[Nmeas].flags |= BLEND_IMAGE;
+  } 
+  if (stars[N].found == -2) { /* this image star matches a catalog star on a neighboring catalog */
+    catalog[0].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[0].found[n] > -1) {
+    catalog[0].measure[catalog[0].found[n]].flags |= BLEND_CATALOG;
+    catalog[0].measure[Nmeas].flags |= BLEND_CATALOG;
+  } else {
+    catalog[0].found[n] = Nmeas;
+  }
+# endif  
+
+  /* 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);
+
+}
+
Index: /branches/elixir/Ohana/src/delstar/src/gcatalog.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/gcatalog.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/gcatalog.c	(revision 2462)
@@ -0,0 +1,45 @@
+# include "delstar.h"
+
+int gcatalog (Catalog *catalog) {
+  
+  int Nsecfilt;
+  char mode;
+
+  /* read catalog header */
+  mode = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+  if (!load_catalog (catalog, mode, VERBOSE)) {
+    fprintf (stderr, "ERROR: failure loading catalog\n");
+    exit (1);
+  }
+
+  /* check Nsecfile value, update if needed */
+  Nsecfilt = GetPhotcodeNsecfilt ();
+  if (catalog[0].Nsecfilt < Nsecfilt) {
+
+    int i, j, Nextra, in, out;
+    SecFilt *insec, *outsec;
+
+    Nextra = Nsecfilt - catalog[0].Nsecfilt;
+    insec = catalog[0].secfilt;
+    ALLOCATE (outsec, SecFilt, catalog[0].Naverage * Nsecfilt);
+    for (in = out = i = 0; i < catalog[0].Naverage; i++) {
+      for (j = 0; j < catalog[0].Nsecfilt; j++, in++, out++) {
+	outsec[out].M = insec[in].M;
+	outsec[out].Xm = insec[in].Xm;
+      }
+      for (j = 0; j < Nextra; j++, out++) {
+	outsec[out].M = NO_MAG;
+	outsec[out].Xm = NO_MAG;
+      }
+    }
+    free (catalog[0].secfilt);
+    catalog[0].secfilt = outsec;
+    catalog[0].Nsecfilt = Nsecfilt;
+  }
+
+  if (catalog[0].Nsecfilt > Nsecfilt) {
+    fprintf (stderr, "ERROR: can't reduce number of secondary filters\n");
+    exit (1);
+  }
+  return (TRUE);
+}
Index: /branches/elixir/Ohana/src/delstar/src/gcatstats.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/gcatstats.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/gcatstats.c	(revision 2462)
@@ -0,0 +1,57 @@
+# include "delstar.h"
+
+gcatstats (catalog, catstats)
+Catalog catalog[];
+CatStats catstats[];
+{
+
+  int i;
+  double RaCenter, DecCenter;
+  double MinRA, MaxRA, MinDEC, MaxDEC;
+  float *X1, *Y1;
+  int *N1;
+  Coords tcoords;
+  
+  fits_scan (&catalog[0].header, "RA0", "%lf", 1, &MinRA);
+  fits_scan (&catalog[0].header, "RA1", "%lf", 1, &MaxRA);
+  fits_scan (&catalog[0].header, "DEC0", "%lf", 1, &MinDEC);
+  fits_scan (&catalog[0].header, "DEC1", "%lf", 1, &MaxDEC);
+
+  /* double check on region RA and DEC ranges */
+  DecCenter = 0.5*(MinDEC + MaxDEC);
+  RaCenter = 0.5*(MinRA + MaxRA);
+  if (MaxDEC > 86.25) {  /* we are on the pole */
+    DecCenter = 90.0;
+    RaCenter = 0.0;
+  }
+
+  catstats[0].RA[0] = MinRA;
+  catstats[0].RA[1] = MaxRA;
+  catstats[0].DEC[0] = MinDEC;
+  catstats[0].DEC[1] = MaxDEC;
+
+  /** allocate local arrays **/
+  ALLOCATE (catstats[0].X, float, catalog[0].Naverage);
+  ALLOCATE (catstats[0].Y, float, catalog[0].Naverage);
+  ALLOCATE (catstats[0].N, int,   catalog[0].Naverage);
+
+  /* project onto rectilinear grid with 1 arcsec pixels, sort by X */
+  /* reference for coords is center of field  */
+  catstats[0].coords.crval1 = RaCenter;
+  catstats[0].coords.crval2 = DecCenter;
+  catstats[0].coords.crpix1 = catstats[0].coords.crpix2 = 0.0;
+  catstats[0].coords.cdelt1 = catstats[0].coords.cdelt2 = 1.0 / 3600.0;
+  catstats[0].coords.pc1_1 = catstats[0].coords.pc2_2 = 1.0;
+  catstats[0].coords.pc1_2 = catstats[0].coords.pc2_1 = 0.0;
+  strcpy (catstats[0].coords.ctype, "RA---TAN");
+
+  X1 = catstats[0].X;
+  Y1 = catstats[0].Y;
+  for (i = 0; i < catalog[0].Naverage; i++, X1++, Y1++) {
+    fRD_to_XY (X1, Y1, catalog[0].average[i].R, catalog[0].average[i].D, &catstats[0].coords);
+    catstats[0].N[i] = i;
+  }
+  if (catalog[0].Naverage > 1) sort_lists (catstats[0].X, catstats[0].Y, catstats[0].N, catalog[0].Naverage);
+  
+}
+
Index: /branches/elixir/Ohana/src/delstar/src/gimages.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/gimages.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/gimages.c	(revision 2462)
@@ -0,0 +1,88 @@
+# include "delstar.h"
+
+Image *gimages (char *filename) {
+ 
+  FILE *f;
+  Header header;
+  char line[64], photcode[64], *c;
+  struct tm timeptr;
+  double tmp, jd;
+  Image *image;
+  int Nsec, Nc;
+
+  ALLOCATE (image, Image, 1);
+  /* load header */
+  if (!fits_read_header (filename, &header)) {
+    fprintf (stderr, "ERROR: can't find image file %s\n", filename);
+    Shutdown ();
+  }
+
+  /* open file */
+  f = fopen (filename, "r");
+  if (f == NULL) {
+    fprintf (stderr, "ERROR: can't find data file %s\n", filename);
+    Shutdown ();
+  }
+  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)) {
+    fprintf (stderr, "ERROR: no astrometric solution in header\n");
+    Shutdown ();
+  }
+  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 */
+  fits_scan (&header, "NAXIS1",   "%hd", 1, &image[0].NX); 
+  fits_scan (&header, "NAXIS2",   "%hd", 1, &image[0].NY);
+
+  fits_scan (&header, "PHOTCODE", "%s", 1, photcode);
+  Nc = GetPhotcodeCodebyName (photcode);
+  if (!Nc) {
+    fprintf (stderr, "ERROR: photcode %s not found in photcode table\n", photcode);
+    Shutdown ();
+  }
+  image[0].source = Nc;
+
+  tmp = 0;
+  fits_scan (&header, "FLIMIT",   "%lf", 1, &tmp);
+  image[0].detection_limit = tmp * 10.0;
+
+  tmp = 0;
+  fits_scan (&header, "FSATUR",   "%lf", 1, &tmp);
+  image[0].saturation_limit = tmp * 10.0;
+
+  if (!fits_scan (&header, "TZERO",   "%d",  1, &image[0].tzero)) {
+    image[0].tzero = parse_time (&header);
+  }
+
+  tmp = 0;
+  fits_scan (&header, "TRATE",   "%lf", 1, &tmp);
+  image[0].trate = 10000 * tmp;
+
+  tmp = 0;
+  fits_scan (&header, "AIRMASS", "%lf", 1, &tmp);
+  image[0].secz = 1000*tmp;
+
+  /* secz is in units milli-airmass */
+  image[0].Mcal =  ALPHA*(image[0].secz - 1000);
+  image[0].Xm   = NO_MAG;
+
+  free (header.buffer);
+ 
+  return (image);
+}
Index: /branches/elixir/Ohana/src/delstar/src/gregions.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/gregions.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/gregions.c	(revision 2462)
@@ -0,0 +1,53 @@
+# include "delstar.h"
+
+GSCRegion *gregions (Image *image, int *Nregions) {
+  
+  GSCRegion *region;
+  FILE *f;
+  double x, y;
+  double dr, dd, dec, ra;
+  int i, j, done, nregion, NREGION;
+  
+  f = fopen (GSCFILE, "r");
+  if (f == NULL) {
+    fprintf (stderr, "ERROR: can't find GSC region file %s\n", GSCFILE);
+    exit (1);
+  }
+  
+  /* find regions at image corners */
+  NREGION = 10;
+  ALLOCATE (region, GSCRegion, NREGION);
+  nregion = 0;
+
+  /* look for new regions on grid across image */ 
+  for (x = 0; x <= 1; x+=0.25) {
+    for (y = 0; y <= 1; y+=0.25) {
+      XY_to_RD (&ra, &dec, image[0].NX*(1.1*x - 0.05), image[0].NY*(1.1*y - 0.05), &image[0].coords);
+      aregion (&region[nregion], f, ra, dec);
+      done = FALSE;
+      for (j = 0; (j < nregion) && !done; j++) {
+	if (!strcmp (region[nregion].filename, region[j].filename)) {
+	  nregion --;
+	  done = TRUE;
+	}
+      }
+      nregion ++;
+      if (nregion == NREGION) {
+	NREGION += 10;
+	REALLOCATE (region, GSCRegion, NREGION);
+      }
+    }
+  }
+
+  if (VERBOSE) {
+    fprintf (stderr, "found %d region files:\n", nregion);
+    for (i = 0; i < nregion; i++) {
+      fprintf (stderr, "  %d %s\n", i, region[i].filename);
+    }
+  }
+  *Nregions = nregion;
+  
+  fclose (f);
+  return (region);
+  
+}
Index: /branches/elixir/Ohana/src/delstar/src/gtimes.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/gtimes.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/gtimes.c	(revision 2462)
@@ -0,0 +1,66 @@
+# include "delstar.h"
+
+Image *gtimes (FILE *f, char **argv, int *NIMAGE, int *START, int *END) {
+ 
+  int i, npimage, NPIMAGE, ntimage, Ntimage, NTIMAGE, Nimage;
+  int start, end, range, tstart, tend;
+  double Ra, Dec;
+  Image *pimage, *timage;
+  Header header;
+
+  start = atof(argv[1]);
+  range = atof(argv[2]);
+  if (range < 2) {
+    start = start - 1;
+    range = 2;
+  }
+  end = start + range;
+  *START = start;
+  *END = end;
+
+  /* get image header */
+  fseek (f, 0, SEEK_SET); 
+  if (!fits_fread_header (f, &header)) {
+    fprintf (stderr, "Can't find image catalog: %s\n", ImageCat);
+    exit (1);
+  }
+  fseek (f, header.size, SEEK_SET); 
+
+  Nimage = 0;
+  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
+
+  NTIMAGE = 100;
+  ALLOCATE (timage, Image, NTIMAGE);
+
+  npimage = 0;
+  NPIMAGE = 20;
+  ALLOCATE (pimage, Image, NPIMAGE);
+
+  for (Ntimage = 0; Ntimage < Nimage; Ntimage += ntimage) {
+    ntimage = Fread (timage, sizeof(Image), NTIMAGE, f, "image");
+    for (i = 0; i < ntimage; i++) {
+      tstart = timage[i].tzero;
+      tend = timage[i].tzero + 1e-4*timage[i].trate*timage[i].NY;
+      if ((tstart <= end) && (tend >= start)) {
+	pimage[npimage] = timage[i];
+	npimage ++;
+	if (npimage == NPIMAGE) {
+	  NPIMAGE += 20;
+	  REALLOCATE (pimage, Image, NPIMAGE);
+	}
+      }
+    }
+  }
+  free (timage);
+
+  fprintf (stderr, "found the following images:\n");
+  for (i = 0; i < npimage; i++) {
+    XY_to_RD (&Ra, &Dec, 0.5*pimage[i].NX, 0.5*pimage[i].NY, &pimage[i].coords);
+    fprintf (stderr, "%3d %s %8.4f %8.4f %d %d\n", i, pimage[i].name, Ra, Dec,
+	     pimage[i].tzero, pimage[i].nstar);
+  }
+
+  *NIMAGE = npimage;
+  return (pimage);
+
+}
Index: /branches/elixir/Ohana/src/delstar/src/match_images.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/match_images.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/match_images.c	(revision 2462)
@@ -0,0 +1,56 @@
+# include "delstar.h"
+
+match_images (catalog, image, Nimage)
+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/elixir/Ohana/src/delstar/src/parse_time.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/parse_time.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/parse_time.c	(revision 2462)
@@ -0,0 +1,126 @@
+# include "delstar.h"
+
+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);
+    fits_scan (header, JDKeyword, "%lf", 1, &jd);
+    Nsec = (jd - 2440587.5)*86400;
+    return (Nsec);
+  }
+
+  /* try MJD next */
+  if (strcasecmp (MJDKeyword, "NONE")) {
+    uppercase (MJDKeyword);
+    fits_scan (header, MJDKeyword, "%lf", 1, &jd);
+    Nsec = (jd - 40587.0)*86400;
+    return (Nsec);
+  }
+    
+  /* get UT and DATE */
+  uppercase (UTKeyword);
+  fits_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)) {
+    fprintf (stderr, "error in DATE-MODE format: %s\n", DateMode);
+    Shutdown ();
+  }
+  py = strchr (DateMode, 'Y');
+  pm = strchr (DateMode, 'M');
+  pd = strchr (DateMode, 'D');
+  if ((py == (char *) NULL) || (pm == (char *) NULL) || (pd == (char *) NULL)) {
+    fprintf (stderr, "error in DATE-MODE format: %s\n", DateMode);
+    Shutdown ();
+  }
+  if ((py > pm) && (py < pd)) {
+    fprintf (stderr, "error in DATE-MODE format: %s\n", DateMode);
+    Shutdown ();
+  }
+  if ((py > pd) && (py < pm)) {
+    fprintf (stderr, "error in DATE-MODE format: %s\n", DateMode);
+    Shutdown ();
+  }
+  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) {
+    fprintf (stderr, "error in DATE-MODE format: %s\n", DateMode);
+    Shutdown ();
+  }
+
+  /* parse date entry */
+  uppercase (DateKeyword);
+  fits_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) {
+    fprintf (stderr, "error in date entry (%s) or DATE-MODE format (%s)\n", line, DateMode);
+    Shutdown ();
+  }
+
+  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);
+
+}
+
+uppercase (char *string) {
+
+  int i;
+    
+  for (i = 0; i < strlen (string); i++) string[i] = toupper (string[i]);
+
+}
Index: /branches/elixir/Ohana/src/delstar/src/sort_lists.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/sort_lists.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/sort_lists.c	(revision 2462)
@@ -0,0 +1,48 @@
+
+sort_lists (X, Y, S, N) 
+float *X, *Y;
+int *S, 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;
+  }
+}
Index: /branches/elixir/Ohana/src/delstar/src/wcatalog.c
===================================================================
--- /branches/elixir/Ohana/src/delstar/src/wcatalog.c	(revision 2462)
+++ /branches/elixir/Ohana/src/delstar/src/wcatalog.c	(revision 2462)
@@ -0,0 +1,37 @@
+# include "delstar.h"
+
+wcatalog (Catalog *catalog) {
+  
+  int status;
+
+  /* we'll leave these for now, but they are LONEOS specific */
+  fits_modify (&catalog[0].header, "MARKSTAR", "%t", 1, FALSE);
+  fits_modify (&catalog[0].header, "ADDUSNO", "%t", 1, FALSE);
+  fits_modify (&catalog[0].header, "MARKROCK", "%t", 1, FALSE);
+
+  if (!save_catalog (catalog, VERBOSE)) {
+    fprintf (stderr, "ERROR: failure saving catalog\n");
+    exit (1);
+  }
+
+  /* free, initialize data structures */
+
+  if (catalog[0].Naverage) {
+    free (catalog[0].average); 
+    catalog[0].Naverage = 0;
+  }
+  if (catalog[0].Nmeasure) {
+    free (catalog[0].measure); 
+    catalog[0].Nmeasure = 0;
+  }
+  if (catalog[0].Nmissing) {
+    free (catalog[0].missing); 
+    catalog[0].Nmissing = 0;
+  }
+  if (catalog[0].Nsecfilt) {
+    free (catalog[0].secfilt); 
+    catalog[0].Nsecfilt = 0;
+  }
+  fits_free_header (&catalog[0].header);
+}
+
