Index: /branches/eam_branches/ipp-20150419/Ohana/src/addstar/Makefile
===================================================================
--- /branches/eam_branches/ipp-20150419/Ohana/src/addstar/Makefile	(revision 38183)
+++ /branches/eam_branches/ipp-20150419/Ohana/src/addstar/Makefile	(revision 38184)
@@ -76,4 +76,5 @@
 $(SRC)/LoadData.$(ARCH).o \
 $(SRC)/LoadDataSDSS.$(ARCH).o \
+$(SRC)/LoadDataUKIRT.$(ARCH).o \
 $(SRC)/LoadDataPMM.$(ARCH).o \
 $(SRC)/in_image.$(ARCH).o \
@@ -90,4 +91,5 @@
 $(SRC)/ReadStarsTEXT.$(ARCH).o \
 $(SRC)/ReadStarsSDSS.$(ARCH).o \
+$(SRC)/ReadStarsUKIRT.$(ARCH).o \
 $(SRC)/ReadXradFITS.$(ARCH).o \
 $(SRC)/FilterStars.$(ARCH).o \
@@ -204,4 +206,5 @@
 $(SRC)/LoadData.$(ARCH).o \
 $(SRC)/LoadDataSDSS.$(ARCH).o \
+$(SRC)/LoadDataUKIRT.$(ARCH).o \
 $(SRC)/LoadDataPMM.$(ARCH).o \
 $(SRC)/grefstars.$(ARCH).o \
@@ -213,4 +216,5 @@
 $(SRC)/ReadStarsTEXT.$(ARCH).o \
 $(SRC)/ReadStarsSDSS.$(ARCH).o \
+$(SRC)/ReadStarsUKIRT.$(ARCH).o \
 $(SRC)/ImageIndex.$(ARCH).o \
 $(SRC)/UpdateImageIDs.$(ARCH).o \
Index: /branches/eam_branches/ipp-20150419/Ohana/src/addstar/include/addstar.h
===================================================================
--- /branches/eam_branches/ipp-20150419/Ohana/src/addstar/include/addstar.h	(revision 38183)
+++ /branches/eam_branches/ipp-20150419/Ohana/src/addstar/include/addstar.h	(revision 38184)
@@ -332,4 +332,7 @@
 
 
+Stars *ReadStarsUKIRT (FILE *f, char *name, Header *header, Image *images, off_t *nimages, unsigned int *nstars);
+int LoadDataUKIRT (FILE *f, char *file, Image **images, off_t *nimages, Stars **stars, unsigned int *Nstars, Header **headers, off_t *extsize, HeaderSet *headerSets, off_t NheaderSets);
+
 /** 
     there is an inconsistency to be resolved: fixed structures (like Image)
Index: /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/GetFileMode.c
===================================================================
--- /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/GetFileMode.c	(revision 38183)
+++ /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/GetFileMode.c	(revision 38184)
@@ -31,5 +31,5 @@
   int have_TELESCOPE  = gfits_scan (header, "TELESCOP", "%s", 1, telescope);
   int have_INSTRUMENT = gfits_scan (header, "INSTRUME", "%s", 1, instrument);
-  if (haveTELESCOPE && have_INSTRUMENT && !strcmp(telescope, "UKIRT"), && !strcmp(instrument, "WFCAM")) {
+  if (have_TELESCOPE && have_INSTRUMENT && !strcmp(telescope, "UKIRT") && !strcmp(instrument, "WFCAM")) {
     if (VERBOSE) fprintf (stderr, "found UKIRT data\n");
     return UKIRT_OBJ;
Index: /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/LoadDataUKIRT.c
===================================================================
--- /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/LoadDataUKIRT.c	(revision 38183)
+++ /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/LoadDataUKIRT.c	(revision 38184)
@@ -2,9 +2,10 @@
 
 // examine the header sets and set the Image entries for the the valid images
+// UKIRT data has the WCS/image metadata header intermixed with the bintable header
 int LoadDataUKIRT (FILE *f, char *file, Image **images, off_t *nimages, Stars **stars, unsigned int *Nstars, Header **headers, off_t *extsize, HeaderSet *headerSets, off_t NheaderSets) {
 
   off_t Nskip, Nvalid, NVALID;
   char *name;
-  int j, Nhead, Ndata;
+  int i, j, Nhead, Ndata;
   unsigned int Ninstars;
   Stars *inStars;
@@ -29,5 +30,5 @@
 
     // advance the pointer to the start of the corresponding table block
-    Nhead = headerSets[0].extnum_head;
+    Nhead = headerSets[i].extnum_head;
     Ndata = headerSets[i].extnum_data;
     Nskip = 0;
@@ -37,8 +38,7 @@
     fseeko (f, Nskip, SEEK_SET); 
 
-    inStars = ReadStarsUKIRT (f, name, headers[Nhead], headers[Ndata], images[0], &Nvalid, &Ninstars);
+    inStars = ReadStarsUKIRT (f, name, headers[Nhead], images[0], &Nvalid, &Ninstars);
     *stars = MergeStars (*stars, Nstars, inStars, Ninstars);
 
-    free (name);
     *nimages = Nvalid;
   }    
Index: /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/MatchHeaders.c
===================================================================
--- /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/MatchHeaders.c	(revision 38183)
+++ /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/MatchHeaders.c	(revision 38184)
@@ -53,4 +53,7 @@
       }
     }
+
+    // the 0th entry is an empty PHU
+    extsize[0][0] = headers[0][0].datasize + gfits_data_size (headers[0]);
 
     for (i = 1; i < Nheaders; i++) {
Index: /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/ReadStarsUKIRT.c
===================================================================
--- /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/ReadStarsUKIRT.c	(revision 38183)
+++ /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/ReadStarsUKIRT.c	(revision 38184)
@@ -6,52 +6,43 @@
   assert (NAME); assert (!strcmp (type, #TYPE)); assert (Nrow == Nstars); assert (Ncol == 1);
 
-/* grab named photcode */
-# define NAMED_PHOTCODE_AND_ZP(CODE,ZP,NAME) { \
-  PhotCode *code; \
-  code = GetPhotcodebyName (NAME); \
-  if (code == NULL) { \
-    fprintf (stderr, "ERROR:  photcode %s not found in photcode table\n", NAME); \
-    exit (0); } \
-  CODE = code[0].code; \
-  ZP = 0.001*code[0].C; }
-
 // given a file with the pointer at the start of the table block and the 
 // corresponding image header, load the stars from the table
-Stars *ReadStarsSDSS (FILE *f, char *name, Header *header, Header *in_theader, Image *images, off_t *nimages, unsigned int *nstars) {
-
-  off_t Nskip, Nrow;
-  int i, j, N, Nstars, camcol;
+Stars *ReadStarsUKIRT (FILE *f, char *name, Header *header, Image *images, off_t *nimages, unsigned int *nstars) {
+
+  off_t Nrow;
+  int Ncol;
   char type[80];
-  Header theader;
   FTable table;
   Stars *stars;
-  double clockRate, mjd[5], jd, sidtime, alt, az;
-  float seeing[5], photErr[5], zeropt[5], ZeroPt;
-  time_t tzero[5];
-  char filtname[16][5];
-  int photcode[5];
-  int Ncol; // used in the GET_COLUMN_1,5 macros above
-  
-  // XXX ??? what is this for?
-  if (in_theader == NULL) {
-    table.header = &theader;
-    if (!gfits_fread_header (f, table.header)) Shutdown ("ERROR: can't read table header");
-  } else {
-    table.header = in_theader;
-    Nskip = in_theader[0].datasize;
-    fseeko (f, Nskip, SEEK_CUR); 
-  }
+  
+  // ohana_memcheck_func (TRUE);
+
+  // the FITS binary table header is the same as the image header
+  table.header = header;
+
+  // put the file pointer at the start of the fits table data
+  off_t Nskip = header[0].datasize;
+  fseeko (f, Nskip, SEEK_CUR); 
 
   /* load the table data */
   if (!gfits_fread_ftable_data (f, &table, FALSE)) {
-    fprintf (stderr, "ERROR: can't read table header\n");
+    fprintf (stderr, "ERROR: can't read table data\n");
     exit (1);
   }
 
+  // ohana_memcheck_func (TRUE);
+
   Coords coords;
-  if (!GetCoords (&coords, &table.header)) {
+  if (!GetCoords (&coords, header)) {
     fprintf (stderr, "unable to read header WCS info\n");
     exit (3);
   }
+
+  // longitude and latitude for UKIRT:
+  // Latitude = 19.822433, Longitude = -155.470289 W (from google maps)
+  // longitude = 155.470289 deg = 10.3646859333 h
+
+  double Longitude = 10.3646859333;	// hours (+ = W)
+  double Latitude  = 19.822433;	// degrees
 
   // DETECTID tells us which chip supplied the data
@@ -79,4 +70,5 @@
 
   int knownFilter = FALSE;
+  if (!strcmp (filter, "Z")) { knownFilter = TRUE; }
   if (!strcmp (filter, "Y")) { knownFilter = TRUE; }
   if (!strcmp (filter, "J")) { knownFilter = TRUE; }
@@ -88,5 +80,6 @@
   }
   
-  sprintf (photcodeName, "UKIRT.%s.%d", filter, detID);
+  char photcodeName[64];
+  snprintf (photcodeName, 64, "UKIRT.%s.%02d", filter, detID);
   PhotCode *code = GetPhotcodebyName (photcodeName);
   if (code == NULL) {
@@ -96,17 +89,37 @@
   int photcode = code[0].code;
 
+  float zeropt;
   if (!gfits_scan (header, "MAGZPT", "%f", 1, &zeropt)) {
     fprintf (stderr, "ERROR:  missing MAGZPT\n");
     exit (3); 
   }
-
-  gfits_scan (header, "MJD_OBS", "%lf", 1, &mjd);
-  tzero = ohana_mjd_to_sec (mjd);
+  // Mrel = Minst + K*(airmass - 1.0) + zp_nom - Mcal
+  // Mrel = Minst + K*(airmass - 1.0) + zp
+  // zp = zp_nom - Mcal
+  // Mcal = zp_nom - zp
+  float Mcal = code[0].C*0.001 - zeropt;
+
+  float ApCor4, ApCor7;
+  if (!gfits_scan (header, "APCOR4", "%f", 1, &ApCor4)) {
+    fprintf (stderr, "ERROR:  missing APCOR4\n");
+    exit (3); 
+  }
+  if (!gfits_scan (header, "APCOR7", "%f", 1, &ApCor7)) {
+    fprintf (stderr, "ERROR:  missing APCOR7\n");
+    exit (3); 
+  }
+
+  // ohana_memcheck_func (TRUE);
+
+  double mjd;
+  gfits_scan (header, "MJD-OBS", "%lf", 1, &mjd);
+  time_t tzero = ohana_mjd_to_sec (mjd);
   double jd = ohana_sec_to_jd (tzero);
-  double sidtime  = 15.0*ohana_lst (jd, Longitude); // sidtime in degrees
+
+  double sidtime  = ohana_lst (jd, Longitude); // sidtime in hours
+  double sidtime_deg = 15.0*sidtime; // sidtime in degrees
 
   float seeing;
   gfits_scan (header, "SEEING", "%f", 1, &seeing);
-  
 
   float exptime;
@@ -114,9 +127,11 @@
   float magtime = 2.5*log10(exptime);
 
-  ZeroPt = GetZeroPoint();
+  float ZeroPt = GetZeroPoint();
+
+  // ohana_memcheck_func (TRUE);
 
   // create a Star entry for each filter and detection
-  Nstars = table.header[0].Naxis[1];
-  ALLOCATE (stars, Stars, NFILTER*Nstars);
+  int Nstars = table.header[0].Naxis[1];
+  ALLOCATE (stars, Stars, Nstars);
 
   GET_COLUMN (X_coordinate, float);
@@ -126,9 +141,9 @@
   GET_COLUMN (Y_coordinate_err, float);
 
-  GET_COLUMN (Aper_flux_8, float);
-  GET_COLUMN (Aper_flux_8_err, float);
-
-  GET_COLUMN (Aper_flux_5, float);
-  GET_COLUMN (Aper_flux_5_err, float);
+  GET_COLUMN (Aper_flux_4, float); // 1 arcsec aperture
+  GET_COLUMN (Aper_flux_4_err, float);
+
+  GET_COLUMN (Aper_flux_7, float); // 4 arcsec aperture
+  GET_COLUMN (Aper_flux_7_err, float);
 
   GET_COLUMN (Kron_flux, float);
@@ -138,79 +153,72 @@
   GET_COLUMN (Sky_rms, float);
 
-  // the value of stars[].M is supposed to be the instrumental magnitude offset by the
-  // default zero point 25.0 (-2.5*log_10(counts/sec) + ZeroPt).  The magnitude reported
-  // by SDSS is the calibrated mag: -2.5*log_10(counts/sec) + C_0.  Adjust magnitudes to
-  // compensate for the difference.
-
+  double R, D, alt, az;
+
+  // ohana_memcheck_func (TRUE);
+
+  int i;
   for (i = 0; i < Nstars; i++) {
-      InitStar (&stars[i]);
+    InitStar (&stars[i]);
       
-      // any values not explicitly set are left at 0.0
-      XY_to_RD (&R, &D, X_coordinate[i], Y_coordinate[i], &coords);
-
-      stars[i].average.R         = R;
-      stars[i].average.D         = D;
-      stars[i].average.dR        = NAN;
-      stars[i].average.dD        = NAN;
-
-      stars[i].measure.Xccd      = X_coordinate[i];
-      stars[i].measure.Yccd      = Y_coordinate[i];
-      stars[i].measure.dXccd     = ToShortPixels(X_coordinate_err[i]);
-      stars[i].measure.dYccd     = ToShortPixels(Y_coordinate_err[i]);
-      stars[i].measure.M         = -2.5*log10(Aper_flux_8[i]) + ZeroPt - zeropt;
-      stars[i].measure.dM        = Aper_flux_8_err[i] / Aper_flux_8[i];
-      stars[i].measure.Map       = -2.5*log10(Aper_flux_8[i]) + ZeroPt - zeropt;
-      stars[i].measure.dMap      = Aper_flux_5_err[i] / Aper_flux_5[i];
-      stars[i].measure.Mkron     = -2.5*log10(Aper_flux_8[i]) + ZeroPt - zeropt;
-      stars[i].measure.dMkron    = Aper_flux_5_err[i] / Aper_flux_5[i];
-      stars[i].measure.Sky       = Sky_level[i]; // adjust this to counts?
-      stars[i].measure.dSky      = Sky_rms[i];
-      stars[i].measure.FWx       = ToShortPixels(seeing); // reported in arcsec?
-      stars[i].measure.FWy       = ToShortPixels(seeing);
-
-      stars[i].measure.detID     = i;
-      stars[i].measure.t         = tzero; // time since row 0
-      stars[i].measure.dt        = magtime; // 2.5 * log(exptime) 
-
-      // longitude and latitude for UKIRT:
-      // Latitude , Longitude ???
-      // longitude = 105.820419312 deg = 7.05469417 h
-      // latitude = 32.7803611755 deg
-
-      double Longitude = 7.05469417 * foo;   // hours (+ = W)
-      double Latitude = 32.7803611755 * fooo; // degrees
-
-      altaz (&alt, &az, sidtime - stars[i].average.R, stars[i].average.D, Latitude);
-
-      stars[i].measure.airmass   = 1.0 / dCOS(90.0 - alt);
-      stars[i].measure.az        = az;
-      stars[i].measure.photcode  = photcode;
-      stars[i].measure.imageID   = *nimages; // set imageID to entry for this filter
-    }
-  }    
-
-  for (i = 0; i < NFILTER; i++) {
-
-    N = i + *nimages;
+    // any values not explicitly set are left at 0.0
+    XY_to_RD (&R, &D, X_coordinate[i], Y_coordinate[i], &coords);
+
+    stars[i].average.R         = R;
+    stars[i].average.D         = D;
+    stars[i].average.dR        = NAN;
+    stars[i].average.dD        = NAN;
+
+    stars[i].measure.Xccd      = X_coordinate[i];
+    stars[i].measure.Yccd      = Y_coordinate[i];
+    stars[i].measure.dXccd     = ToShortPixels(X_coordinate_err[i]);
+    stars[i].measure.dYccd     = ToShortPixels(Y_coordinate_err[i]);
+
+    stars[i].measure.M         = -2.5*log10(Aper_flux_4[i]) + ZeroPt + magtime + ApCor4;
+    stars[i].measure.dM        = Aper_flux_4_err[i] / Aper_flux_4[i];
+    stars[i].measure.Map       = -2.5*log10(Aper_flux_7[i]) + ZeroPt + magtime + ApCor7;
+    stars[i].measure.dMap      = Aper_flux_7_err[i] / Aper_flux_7[i];
+    stars[i].measure.Mkron     = -2.5*log10(Kron_flux[i]) + ZeroPt + magtime;
+    stars[i].measure.dMkron    = Kron_flux_err[i] / Kron_flux[i];
+    stars[i].measure.Sky       = Sky_level[i]; // adjust this to counts?
+    stars[i].measure.dSky      = Sky_rms[i];
+    stars[i].measure.FWx       = ToShortPixels(seeing); // reported in arcsec?
+    stars[i].measure.FWy       = ToShortPixels(seeing);
+
+    stars[i].measure.Mcal      = Mcal;
+
+    stars[i].measure.detID     = i;
+    stars[i].measure.t         = tzero; // time since row 0
+    stars[i].measure.dt        = magtime; // 2.5 * log(exptime) 
+
+    altaz (&alt, &az, sidtime_deg - stars[i].average.R, stars[i].average.D, Latitude);
+
+    stars[i].measure.airmass   = 1.0 / dCOS(90.0 - alt);
+    stars[i].measure.az        = az;
+    stars[i].measure.photcode  = photcode;
+    stars[i].measure.imageID   = *nimages; // set imageID to entry for this filter
+  }
+
+  if (1) {
+    int N = *nimages;
     
-    // XXX for now, we define a totally fake coordinate system centered on the first listed star
-    InitCoords (&images[N].coords, "DEC--TAN");
-    images[N].coords.crval1 = stars[0].average.R;
-    images[N].coords.crval2 = stars[0].average.D;
-    images[N].coords.crpix1 = stars[0].measure.Xccd;
-    images[N].coords.crpix2 = stars[0].measure.Yccd;
-    images[N].coords.cdelt1 = images[N].coords.cdelt2 = 0.4 / 3600.0;
-
-    images[N].NX = 2048;
-    images[N].NY = 1490;
-
-    images[N].tzero = tzero[i];
+    // ohana_memcheck_func (TRUE);
+
+    images[N].coords = coords;
+
+    int Nx, Ny;
+    gfits_scan (header, "NXOUT", "%d", 1, &Nx);
+    gfits_scan (header, "NYOUT", "%d", 1, &Ny);
+
+    images[N].NX = Nx;
+    images[N].NY = Ny;
+  
+    images[N].tzero = tzero;
     images[N].cerror = 0.0;
  
     // set photcodes for the 5 images (SDSS_U,G,R,I,Z)
-    images[N].photcode = photcode[i];
+    images[N].photcode = photcode;
 
     // calculate this from : C_OBS, TRACKING, and NY
-    images[N].exptime = 2048*clockRate;
+    images[N].exptime = exptime;
   
     images[N].apmifit = 0.0;
@@ -218,27 +226,19 @@
     images[N].detection_limit = 0.0; 
     images[N].saturation_limit = 0.0;
-    images[N].fwhm_x = seeing[i];
-    images[N].fwhm_y = seeing[i];
-
-    // XXX longitude and latitude are known for SDSS
-    // SDSS is at : Latitude 32° 46' 49.30" N, Longitude 105° 49' 13.50" W
-    // longitude = 105.820419312 deg = 7.05469417
-    // latitude = 32.7803611755 deg
-
-    double Longitude = 7.05469417;   // hours (+ = W)
-    double Latitude = 32.7803611755; // degrees
-
-    jd = ohana_sec_to_jd (images[N].tzero);
-    images[N].sidtime  = ohana_lst (jd, Longitude);
+    images[N].fwhm_x = seeing * 25.0 * images[N].coords.cdelt1 * 3600.0;
+    images[N].fwhm_y = seeing * 25.0 * images[N].coords.cdelt1 * 3600.0;
+
+    images[N].sidtime  = sidtime;
     images[N].latitude = Latitude;
 
-    altaz (&alt, &az, 15.0*images[N].sidtime - images[N].coords.crval1, images[N].coords.crval2, Latitude);
-
-    images[N].trate = clockRate * 1e-4;
-    images[N].secz = stars[0].measure.airmass;
-    images[N].ccdnum = camcol;
+    XY_to_RD (&R, &D, 0.5*images[N].NX, 0.5*images[N].NY, &coords);
+    altaz (&alt, &az, sidtime_deg - R, D, Latitude);
+
+    images[N].trate = 0.0;
+    images[N].secz = 1.0 / sin (RAD_DEG * alt);
+    images[N].ccdnum = detID;
 
     // secz is in units milli-airmass
-    images[N].Mcal = 0.0;
+    images[N].Mcal = Mcal;
     images[N].Xm   = NAN_S_SHORT;
     images[N].flags = 0;
@@ -252,10 +252,11 @@
 
     // save the filename
-    snprintf (images[N].name, DVO_IMAGE_NAME_LEN, "%s[%s]", name, filtname[i]);
-  }
-
-  NSTAR_GROUP = NFILTER;
-  *nimages += NFILTER;
-  *nstars = Nstars*NFILTER;
+    snprintf (images[N].name, DVO_IMAGE_NAME_LEN, "%s[%02d]", name, detID);
+    *nimages = N + 1;
+  }
+  
+  // ohana_memcheck_func (TRUE);
+
+  *nstars = Nstars;
   return (stars);
 }
Index: /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/UpdateImageIDs.c
===================================================================
--- /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/UpdateImageIDs.c	(revision 38183)
+++ /branches/eam_branches/ipp-20150419/Ohana/src/addstar/src/UpdateImageIDs.c	(revision 38184)
@@ -19,5 +19,5 @@
     dvo_image_create (&db, GetZeroPoint());
     ImageIndexFileInit ();
-  isEmpty = TRUE;
+    isEmpty = TRUE;
   } else {
     /* position to start of file */
