Index: /trunk/Ohana/src/addstar/include/addstar.h
===================================================================
--- /trunk/Ohana/src/addstar/include/addstar.h	(revision 10888)
+++ /trunk/Ohana/src/addstar/include/addstar.h	(revision 10889)
@@ -8,4 +8,5 @@
 # include <netdb.h>
 # include <arpa/inet.h>
+# include <glob.h>
 
 /* used in find_matches, find_matches_refstars */
Index: /trunk/Ohana/src/addstar/src/LoadStars.c
===================================================================
--- /trunk/Ohana/src/addstar/src/LoadStars.c	(revision 10889)
+++ /trunk/Ohana/src/addstar/src/LoadStars.c	(revision 10889)
@@ -0,0 +1,132 @@
+
+/* read an image header corresponding to a CMF data block */
+Image *ReadImageHeader (Header *header) {
+
+  Image *image;
+
+  ALLOCATE (image, Image, 1);
+
+  /* get astrometry information */
+  if (!GetCoords (&image[0].coords, &header)) {
+    fprintf (stderr, "ERROR: no astrometric solution in header\n");
+    exit (1);
+  }
+  itmp = 0;
+  gfits_scan (&header, "NASTRO",   "%d", 1, &itmp);
+  if ((itmp == 0) && !ACCEPT_ASTROM) {
+    fprintf (stderr, "ERROR: bad astrometric solution in header\n");
+    exit (1);
+  }
+  if (!strcmp (&image[0].coords.ctype[4], "-WRP")) {
+    if (MOSAIC == NULL) {
+      fprintf (stderr, "ERROR: no mosaic for WRP image (use -mosaic)\n");
+      exit (1);
+    }
+    RegisterMosaic (MOSAIC);
+  } else {
+    /* force image to lie in 0-360 range */
+    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 arcsec */
+  if (!gfits_scan (&header, "CERROR",   "%lf", 1, &tmp)) tmp = 1.0;
+  image[0].cerror = tmp * 50.0;
+  gfits_scan (&header, "NAXIS1",   "%hd", 1, &image[0].NX); 
+  gfits_scan (&header, "NAXIS2",   "%hd", 1, &image[0].NY);
+ 
+  /* get photcode from header */
+  if (photcode == 0) {
+    if (!gfits_scan (&header, "PHOTCODE", "%s", 1, photname)) {
+      fprintf (stderr, "ERROR: photcode not supplied in header\n");
+      exit (1);
+    }
+    photcode = GetPhotcodeCodebyName (photname);
+    if (photcode == 0) {
+      fprintf (stderr, "ERROR: photcode %s not found in photcode table\n", photname);
+      exit (1);
+    }
+  }
+  if (photcode == 0) {
+    fprintf (stderr, "ERROR: no valid photcode is supplied\n");
+    exit (1);
+  }
+  image[0].source = photcode;
+
+  image[0].NX -= XOVERSCAN;
+  image[0].NY -= YOVERSCAN;
+  gfits_scan (&header, ExptimeKeyword,  "%lf", 1, &tmp);
+  image[0].exptime = tmp;
+  
+  /*** why are we no longer using APMIFIT?? ***/
+  tmp = 0;
+  /* gfits_scan (&header, "APMIFIT",  "%lf", 1, &tmp); */
+  image[0].apmifit_PS = tmp;
+
+  tmp = 0;
+  /* gfits_scan (&header, "dAPMIFIT", "%lf", 1, &tmp); */
+  image[0].dapmifit_PS = tmp;
+
+  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;
+
+  tmp = 0;
+  gfits_scan (&header, "FWHM_X",   "%lf", 1, &tmp);
+  image[0].fwhm_x = tmp * 25.0 * image[0].coords.cdelt1 * 3600.0;
+
+  tmp = 0;
+  gfits_scan (&header, "FWHM_Y",   "%lf", 1, &tmp);
+  image[0].fwhm_y = tmp * 25.0 * image[0].coords.cdelt1 * 3600.0;
+
+  if (!gfits_scan (&header, "TZERO",   "%d",  1, &image[0].tzero)) {
+    image[0].tzero = parse_time (&header);
+  }
+
+  if (STKeyword[0]) {
+    /* get ST (used for airmass calculation) */
+    gfits_scan (&header, STKeyword, "%s", 1, line);
+    /* remove ':' characters */
+    for (c = strchr (line, ':'); c != (char *) NULL; c = strchr (line, ':')) { *c = ' '; }
+    sscanf (line, "%d %d %lf", &hour, &min, &sec);
+    image[0].sidtime = hour + min/60.0 + sec/3600.0;
+  } else {
+    double jd;
+    jd = sec_to_jd (image[0].tzero);
+    image[0].sidtime  = ohana_lst (jd, Longitude);
+  }
+  image[0].latitude = Latitude;
+
+  tmp = 0;
+  gfits_scan (&header, "TRATE",   "%lf", 1, &tmp);
+  image[0].trate = 10000 * tmp;
+
+  tmp = 0;
+  gfits_scan (&header, AirmassKeyword, "%lf", 1, &tmp);
+  image[0].secz_PS = MIN (NO_MAG, tmp);
+
+  if (!gfits_scan (&header, CCDNumKeyword, "%d", 1, &itmp)) {
+    image[0].ccdnum = 0xff;
+  } else {
+    image[0].ccdnum = itmp;
+  }
+
+  gfits_scan (&header, "ZERO_PT", "%lf", 1, &ZeroPt);
+  SetZeroPoint (ZeroPt);
+
+  /* secz is in units milli-airmass */
+  image[0].Mcal_PS = 0.0;
+  image[0].Xm   = NO_MAG;
+  image[0].code = 0;
+  bzero (image[0].dummy, sizeof(image[0].dummy));
+
+  /* find expected number of stars */
+  if (!gfits_scan (&header, "NSTARS", "%d", 1, &image[0].nstar)) {
+    fprintf (stderr, "ERROR: can't get NSTARS from header\n");
+    exit (1);
+  }
+
Index: /trunk/Ohana/src/addstar/src/addstar.c
===================================================================
--- /trunk/Ohana/src/addstar/src/addstar.c	(revision 10888)
+++ /trunk/Ohana/src/addstar/src/addstar.c	(revision 10889)
@@ -4,8 +4,8 @@
 
   int Nmatch, status;
-  int i, Nstars, Nimage, Noverlap, Nsubset;
+  int i, Nstars, Nimages, Noverlap, Nsubset;
   unsigned long long Naverage, Nmeasure;
   Stars *stars, **subset;
-  Image image, *imageSet, *overlap;
+  Image *images, *overlap;
   Catalog catalog;
   FITS_DB db;
@@ -14,4 +14,5 @@
   SkyTable *sky = NULL;
   SkyList *skylist = NULL;
+  SkyList *newlist = NULL;
 
   double dtime;
@@ -39,8 +40,11 @@
   switch (options.mode) {
     case M_IMAGE:
-      stars = gstars (argv[1], &Nstars, options.photcode, &image);
+      stars = gstars (argv[1], &Nstars, options.photcode, &images, &Nimages);
       if ((DUMP != NULL) && !strcmp (DUMP, "rawstars")) dump_rawstars (stars, Nstars);
       RegisterMosaic (MOSAIC);
-      skylist = SkyListByImage (sky, -1, &image);
+      for (i = 0; i < Nimages; i++) {
+	newlist = SkyListByImage (sky, -1, &image);
+	SkyListMergeLists (&skylist, &newlist);
+      }
       overlap = gimages (&db, &image, MOSAIC, &Noverlap);
       break;
@@ -54,5 +58,5 @@
       break;
     case M_FAKEIMAGE:
-      imageSet = fakeimage (argv[1], &Nimage, options.photcode);
+      images = fakeimage (argv[1], &Nimages, options.photcode);
       RegisterMosaic (MOSAIC);
 
@@ -65,5 +69,5 @@
       }	  
 
-      dvo_image_addrows (&db, imageSet, Nimage);
+      dvo_image_addrows (&db, imageSet, Nimages);
       SetProtect (TRUE);
       dvo_image_update (&db, VERBOSE);
Index: /trunk/Ohana/src/addstar/src/find_matches.c
===================================================================
--- /trunk/Ohana/src/addstar/src/find_matches.c	(revision 10888)
+++ /trunk/Ohana/src/addstar/src/find_matches.c	(revision 10889)
@@ -14,5 +14,19 @@
   Coords tcoords;
 
+  /* changes needed to handle mosaic MEF images:
+     - options should not carry photcode: this is set per star in gstars 
+     - validate that all images have the same equiv code value (same Nsec)
+     - add dt to Stars.d and set in gstars, not here
+     - add airmass to Stars.d and set in gstars, not here
+     - set stars.t in gstars
+     - disallow mosaic and missed?  otherwise, need to loop over all images
+       for each missed source to see if it should have been found
+     - Mcal_PS is supplied by image, but is not correctly set: it is 
+       calculated *after* find_matches in addstar
+  */
+
   /* XXX EAM : options.photcode overridden by image.source.... */
+  /* XXX this function could be modified to handle multiple photcodes as long
+     as they match the same equiv code value, resulting in the same value of Nsec */
   code = GetPhotcodebyCode (image[0].source);
 
Index: /trunk/Ohana/src/addstar/src/gstars.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gstars.c	(revision 10888)
+++ /trunk/Ohana/src/addstar/src/gstars.c	(revision 10889)
@@ -1,8 +1,10 @@
 # include "addstar.h"
 
-Stars *gstars (char *file, int *NSTARS, int photcode, Image *image) {
+/* break into sections, loop over images and load stars one at a time */
+
+Stars *gstars (char *file, int *NSTARS, int photcode, Image **imageList, int Nimages) {
 
   FILE *f;
-  int j, N, Nbytes, naxis;
+  int i, j, N, Nbytes, naxis;
   int itmp, hour, min, simple;
   char *name, *c, photname[64], line[80];
@@ -10,6 +12,33 @@
   Stars *stars, *rdstars;
   Header header;
+  Image *images;
 
   /* XXX which of these values are required, which are just interesting? */
+
+  # if (0)
+  /* file may be a glob, in which case it should represent multiple chip files
+     from a single mosaic image */
+
+  // parse the word as a glob
+  glob_t globList;
+  globList.gl_offs = 0;
+  glob (file, 0, NULL, &globList);
+
+  // if the glob does not match, save the literal word:
+  // otherwise save all glob matches
+  if (globList.gl_pathc == 0) {
+    if (!gfits_read_header (file, &header)) {
+      fprintf (stderr, "ERROR: can't read header for %s\n", file);
+      exit (1);
+    }
+  } else {
+    for (i = 0; i < globList.gl_pathc; i++) {
+      if (!gfits_read_header (globList.gl_pathv[i], &header)) {
+	fprintf (stderr, "ERROR: can't read header for %s\n", globList.gl_pathv[i]);
+	exit (1);
+      }
+    }
+  }
+  # endif
 
   if (!gfits_read_header (file, &header)) {
@@ -19,131 +48,8 @@
 
   /* find image rootname */
+  /* if we are reading a MEF mosaic image, attached [extname] to the name of the image */
   name = filebasename (file);
   strcpy (image[0].name, name);
   free (name);
-
-  /* get astrometry information */
-  if (!GetCoords (&image[0].coords, &header)) {
-    fprintf (stderr, "ERROR: no astrometric solution in header\n");
-    exit (1);
-  }
-  itmp = 0;
-  gfits_scan (&header, "NASTRO",   "%d", 1, &itmp);
-  if ((itmp == 0) && !ACCEPT_ASTROM) {
-    fprintf (stderr, "ERROR: bad astrometric solution in header\n");
-    exit (1);
-  }
-  if (!strcmp (&image[0].coords.ctype[4], "-WRP")) {
-    if (MOSAIC == NULL) {
-      fprintf (stderr, "ERROR: no mosaic for WRP image (use -mosaic)\n");
-      exit (1);
-    }
-    RegisterMosaic (MOSAIC);
-  } else {
-    /* force image to lie in 0-360 range */
-    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 arcsec */
-  if (!gfits_scan (&header, "CERROR",   "%lf", 1, &tmp)) tmp = 1.0;
-  image[0].cerror = tmp * 50.0;
-  gfits_scan (&header, "NAXIS1",   "%hd", 1, &image[0].NX); 
-  gfits_scan (&header, "NAXIS2",   "%hd", 1, &image[0].NY);
- 
-  /* get photcode from header */
-  if (photcode == 0) {
-    if (!gfits_scan (&header, "PHOTCODE", "%s", 1, photname)) {
-      fprintf (stderr, "ERROR: photcode not supplied in header\n");
-      exit (1);
-    }
-    photcode = GetPhotcodeCodebyName (photname);
-    if (photcode == 0) {
-      fprintf (stderr, "ERROR: photcode %s not found in photcode table\n", photname);
-      exit (1);
-    }
-  }
-  if (photcode == 0) {
-    fprintf (stderr, "ERROR: no valid photcode is supplied\n");
-    exit (1);
-  }
-  image[0].source = photcode;
-
-  image[0].NX -= XOVERSCAN;
-  image[0].NY -= YOVERSCAN;
-  gfits_scan (&header, ExptimeKeyword,  "%lf", 1, &tmp);
-  image[0].exptime = tmp;
-  
-  /*** why are we no longer using APMIFIT?? ***/
-  tmp = 0;
-  /* gfits_scan (&header, "APMIFIT",  "%lf", 1, &tmp); */
-  image[0].apmifit_PS = tmp;
-
-  tmp = 0;
-  /* gfits_scan (&header, "dAPMIFIT", "%lf", 1, &tmp); */
-  image[0].dapmifit_PS = tmp;
-
-  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;
-
-  tmp = 0;
-  gfits_scan (&header, "FWHM_X",   "%lf", 1, &tmp);
-  image[0].fwhm_x = tmp * 25.0 * image[0].coords.cdelt1 * 3600.0;
-
-  tmp = 0;
-  gfits_scan (&header, "FWHM_Y",   "%lf", 1, &tmp);
-  image[0].fwhm_y = tmp * 25.0 * image[0].coords.cdelt1 * 3600.0;
-
-  if (!gfits_scan (&header, "TZERO",   "%d",  1, &image[0].tzero)) {
-    image[0].tzero = parse_time (&header);
-  }
-
-  if (STKeyword[0]) {
-    /* get ST (used for airmass calculation) */
-    gfits_scan (&header, STKeyword, "%s", 1, line);
-    /* remove ':' characters */
-    for (c = strchr (line, ':'); c != (char *) NULL; c = strchr (line, ':')) { *c = ' '; }
-    sscanf (line, "%d %d %lf", &hour, &min, &sec);
-    image[0].sidtime = hour + min/60.0 + sec/3600.0;
-  } else {
-    double jd;
-    jd = sec_to_jd (image[0].tzero);
-    image[0].sidtime  = ohana_lst (jd, Longitude);
-  }
-  image[0].latitude = Latitude;
-
-  tmp = 0;
-  gfits_scan (&header, "TRATE",   "%lf", 1, &tmp);
-  image[0].trate = 10000 * tmp;
-
-  tmp = 0;
-  gfits_scan (&header, AirmassKeyword, "%lf", 1, &tmp);
-  image[0].secz_PS = MIN (NO_MAG, tmp);
-
-  if (!gfits_scan (&header, CCDNumKeyword, "%d", 1, &itmp)) {
-    image[0].ccdnum = 0xff;
-  } else {
-    image[0].ccdnum = itmp;
-  }
-
-  gfits_scan (&header, "ZERO_PT", "%lf", 1, &ZeroPt);
-  SetZeroPoint (ZeroPt);
-
-  /* secz is in units milli-airmass */
-  image[0].Mcal_PS = 0.0;
-  image[0].Xm   = NO_MAG;
-  image[0].code = 0;
-  bzero (image[0].dummy, sizeof(image[0].dummy));
-
-  /* find expected number of stars */
-  if (!gfits_scan (&header, "NSTARS", "%d", 1, &image[0].nstar)) {
-    fprintf (stderr, "ERROR: can't get NSTARS from header\n");
-    exit (1);
-  }
 
   /* this is really lame.  get sky background from Flips data */
