Index: branches/pap/Ohana/src/addstar/src/find_matches_closest_refstars.c
===================================================================
--- branches/pap/Ohana/src/addstar/src/find_matches_closest_refstars.c	(revision 27708)
+++ branches/pap/Ohana/src/addstar/src/find_matches_closest_refstars.c	(revision 28003)
@@ -159,5 +159,8 @@
     /** in replace mode, search for entry and replace values M, dM, R, D */
     // XXX this fails for unsorted catalogs, right?
-    if (options.replace && replace_match (&catalog[0].average[n], catalog[0].measure, stars[N])) continue;
+    if (options.replace && replace_match (&catalog[0].average[n], catalog[0].measure, stars[N])) {
+	i++;
+	continue;
+    }
 
     /* make sure there is space for next entry */
Index: branches/pap/Ohana/src/dvomerge/src/merge_catalogs_old.c
===================================================================
--- branches/pap/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 27708)
+++ branches/pap/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 28003)
@@ -10,5 +10,5 @@
 int merge_catalogs_old (SkyRegion *region, Catalog *output, Catalog *input, double RADIUS) {
 
-  off_t i, j, n, N, Nin, offset, J, Jmin, status, Nstars;
+  off_t i, j, Nin, offset, J, Jmin, status, Nstars;
   double RADIUS2, Rmin, Rin, Din;
   double *X1, *Y1, *X2, *Y2;
@@ -152,6 +152,6 @@
     /*** a match is found, add to average, measure ***/
     Nmatch ++;
-    n = N2[Jmin];
-    N = N1[i];
+    off_t n = N2[Jmin];
+    off_t N = N1[i];
 
     /* make sure there is space for next Nmeasure entries */
@@ -223,4 +223,6 @@
   /* these new entries are all written out in UPDATE mode */ 
   for (i = 0; i < Nstars; i++) {
+    off_t N = N1[i];
+
     /* make sure there is space for next entry */
     if (Nmeas + input[0].average[N].Nmeasure >= NMEAS) {
@@ -235,5 +237,4 @@
     }
 
-    N = N1[i];
     if (input[0].found[N] >= 0) continue;
     if (!IN_REGION (input[0].average[N].R, input[0].average[N].D)) continue;
Index: branches/pap/Ohana/src/getstar/src/MatchCoords.c
===================================================================
--- branches/pap/Ohana/src/getstar/src/MatchCoords.c	(revision 27708)
+++ branches/pap/Ohana/src/getstar/src/MatchCoords.c	(revision 28003)
@@ -54,5 +54,5 @@
 
 #ifdef notdef
-        printf("%d %8.1f %8.1f %s\n", i, x, y, dbImages[i].name);
+        printf("%ld %8.1f %8.1f %s\n", i, x, y, dbImages[i].name);
 #endif
 
Index: branches/pap/Ohana/src/kapa2/doc/mark.issues.txt
===================================================================
--- branches/pap/Ohana/src/kapa2/doc/mark.issues.txt	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/doc/mark.issues.txt	(revision 28003)
@@ -1,8 +1,13 @@
+
+* option to set window margin
+* option to add section outer box
+* option to set limits based on associated image (and change dynamically...)
+o need consistency of graph defaults : axis, tick, labels should come from kapa
+o clear should erase current plot
+
 -> The "plot" command needs to be fixed so that boundaries of contours do
 not cause it to draw excessive amounts of lines connecting unrelated
 contours. A specific "contour line type" would be useful.
-
--> DVO is not consistently placing the x/y axis labels, especially in
-user-defined sections of the plot window.
+(-pt 100?)
 
 -> DVO does not plot the end-points of histograms properly (e.g., the
@@ -13,3 +18,47 @@
 relay output to the file in the same order. Also, until DVO is closed, the
 output does not appear in the file.
+(fixed both issues)
 
+-> DVO is not consistently placing the x/y axis labels, especially in
+user-defined sections of the plot window. 
+(fixed)
+* box -labelpad -labelpad[x,y] +labelpad[x,y] -
+
+
+---
+
+
+1)You wanted me to remind you to update ~ipp-svn; this was so I could have
+the latest version of DVO on-hand
+
+2)The plotting of axis labels remains inconsistent; depending on section
+dimensions and the presence/absence of tick-marks, labels will change
+their distance from their corresponding axis. This results in labels
+falling off the screen or overlapping with other plot sections
+
+3)Plot section locations in the plot window shift if labels/tick-marks are
+present or absent
+
+4)It would be useful to have an option for the box or section command that
+causes the background to be opaque. This will allow plots to have insets.
+
+5)It would be useful to have a rectangle plotting command in order to
+shade out regions on plots
+
+6)The limits command combined with box will sometimes produce tick-marks
+with only the zero-point labeled, making the axes difficult to interpret
+
+7)Text is printed to a file at different times when using either the echo
+or fprintf commands alongside the output command. Sometimes output is
+printed to the file immediately, while other times it is printed only when
+the file is closed for output.
+
+8)The use of ^C as an interrupt does not always work when a macro is doing
+for loops.
+
+9)It would be useful for DVO to echo which line of a macro contains an
+error, or at which line it was forced to stop. This would help debugging a
+lot.
+
+10)The cgrid could use an option to print RA/DEC tick-mark labels so that
+image plots would be more informative
Index: branches/pap/Ohana/src/kapa2/doc/notes.txt
===================================================================
--- branches/pap/Ohana/src/kapa2/doc/notes.txt	(revision 28003)
+++ branches/pap/Ohana/src/kapa2/doc/notes.txt	(revision 28003)
@@ -0,0 +1,8 @@
+
+2010.04.14
+
+  * one font per frame
+  * user-settable box padding
+  * user-settable label & axis-label padding
+
+  
Index: branches/pap/Ohana/src/kapa2/include/prototypes.h
===================================================================
--- branches/pap/Ohana/src/kapa2/include/prototypes.h	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/include/prototypes.h	(revision 28003)
@@ -26,5 +26,5 @@
 
 /* X drawing utilities */
-void	      DrawFrame		  PROTO((KapaGraphWidget *graph));
+int	      DrawFrame		  PROTO((KapaGraphWidget *graph));
 int           DrawObjects         PROTO((KapaGraphWidget *graph));
 void          DrawLabels          PROTO((KapaGraphWidget *graph));
@@ -39,6 +39,7 @@
 void          DrawXErrors         PROTO((KapaGraphWidget *graph, Gobjects *objects));
 void          DrawYErrors         PROTO((KapaGraphWidget *graph, Gobjects *objects));
-void	      DrawTick		  PROTO((int fx, int fy, int dfx, int dfy, int P, double min, double max, double value, int IsLabel, int IsMajor, int naxis));
+void	      DrawTick		  PROTO((Graphic *graphic, Axis *axis, int P, TickMarkData *tick, int naxis));
 void	      AxisTickScale	  PROTO((Axis *axis, double *major, double *minor));
+TickMarkData *CreateAxisTicks     PROTO((Axis *axis, int *nticks));
 
 /* EventLoop */
@@ -47,4 +48,5 @@
 int           Reconfig            PROTO((XEvent *event));
 void          Refresh             PROTO((void));
+void          DrawSectionBG       PROTO((Graphic *graphic, Section *section));
 
 /* CheckPipe */
@@ -61,4 +63,5 @@
 int           SetSection          PROTO((int sock));
 int           ListSection         PROTO((int sock));
+int           SetSectionBG        PROTO((int sock));
 int           MoveSection         PROTO((int sock));
 int           DefineSection       PROTO((int sock));
@@ -84,5 +87,5 @@
 void          FreeSection	  PROTO((Section *section));
 void          FreeSections	  PROTO((void));
-Section      *AddSection	  PROTO((char *name, float x, float y, float dx, float dy));
+Section      *AddSection	  PROTO((char *name, float x, float y, float dx, float dy, int bg));
 int           DelSection	  PROTO((char *name));
 int           GetSectionByName	  PROTO((char *name));
@@ -112,5 +115,5 @@
 void          PSXErrors           PROTO((KapaGraphWidget *graph, Gobjects *objects, FILE *f));
 void          PSYErrors           PROTO((KapaGraphWidget *graph, Gobjects *objects, FILE *f));
-void	      PSTick		  PROTO((FILE *f, double fx, double fy, double dfx, double dfy, int P, double min, double max, double value, int IsLabel, int IsMajor, int naxis));
+void	      PSTick		  PROTO((Graphic *graphic, Axis *axis, int P, TickMarkData *tick, int naxis, FILE *f));
 void          ClipLinePS          PROTO((double x0, double y0, double x1, double y1, double X0, double Y1, double X1, double Y0, FILE *f));
 int           PSimage    	  PROTO((KapaImageWidget *image, FILE *f));
@@ -131,5 +134,5 @@
 void	      bDrawXErrors	  PROTO((KapaGraphWidget *graph, Gobjects *object));
 void	      bDrawYErrors	  PROTO((KapaGraphWidget *graph, Gobjects *object));
-void	      bDrawTick		  PROTO((double fx, double fy, double dfx, double dfy, int P, double min, double max, double value, int IsLabel, int IsMajor, int naxis));
+void	      bDrawTick		  PROTO((Axis *axis, int P, TickMarkData *tick, int naxis));
 void	      bDrawClipLine	  PROTO((double x0, double y0, double x1, double y1, double X0, double Y1, double X1, double Y0));
 bDrawBuffer  *bDrawIt		  PROTO((void));
Index: branches/pap/Ohana/src/kapa2/include/structures.h
===================================================================
--- branches/pap/Ohana/src/kapa2/include/structures.h	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/include/structures.h	(revision 28003)
@@ -137,8 +137,16 @@
   double min, max;
   char isaxis, areticks, islabel, islog;
+  double pad, labelPad, ticktextPad;
   double fx, dfx, fy, dfy;  /* axis location on graphic */
   double lweight;
   int color;
 } Axis;
+
+// structure to describe the ticks for an axis
+typedef struct {
+  double value;
+  int IsMajor;
+  int IsLabel;
+} TickMarkData;
 
 // a single graph in the display window
@@ -210,4 +218,5 @@
   float  x,  y;
   float dx, dy;
+  int bg;
   char *name;
 } Section;
Index: branches/pap/Ohana/src/kapa2/src/CheckPipe.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/CheckPipe.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/CheckPipe.c	(revision 28003)
@@ -221,4 +221,10 @@
   }
   
+  if (!strcmp (word, "BSEC")) {
+    status = SetSectionBG (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
   if (!strcmp (word, "FONT")) {
     status = SetFont (sock);
Index: branches/pap/Ohana/src/kapa2/src/DefineSection.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/DefineSection.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/DefineSection.c	(revision 28003)
@@ -4,10 +4,10 @@
 int DefineSection (int sock) {
   
-  int N, MoveSection;
+  int N, MoveSection, bg;
   char name[128];
   double x, y, dx, dy;
   Section *section;
 
-  KiiScanMessage (sock, "%s %lf %lf %lf %lf", name, &x, &y, &dx, &dy);
+  KiiScanMessage (sock, "%s %lf %lf %lf %lf %d", name, &x, &y, &dx, &dy, &bg);
 
   MoveSection = FALSE;
@@ -15,5 +15,5 @@
   N = GetSectionByName (name);
   if (N < 0) {
-    section = AddSection (name, x, y, dx, dy);
+    section = AddSection (name, x, y, dx, dy, bg);
     MoveSection = TRUE;
   } else {
@@ -30,4 +30,5 @@
     section[0].dx = dx;
     section[0].dy = dy;
+    section[0].bg = bg;
   }
 
Index: branches/pap/Ohana/src/kapa2/src/DrawFrame.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/DrawFrame.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/DrawFrame.c	(revision 28003)
@@ -1,90 +1,66 @@
 # include "Ximage.h"
-# define MIN_RANGE 1e-10
+
 # define DrawLine(X,Y,DX,DY) (XDrawLine (graphic->display, graphic->window, graphic->gc, (int)(X), (int)(Y), (int)(X+DX), (int)(Y+DY)))
   
-static Graphic *graphic;
-
-void DrawFrame (KapaGraphWidget *graph) {
-  
-  int i, fx, fy, dfx, dfy, P, IsLabel, IsMajor;
-  double range, major, minor, first, next, lweight;
+int DrawFrame (KapaGraphWidget *graph) {
+  
+  int i, j, Nticks, P;
+  double fx, fy, dfx, dfy, lweight;
+  Graphic *graphic;
+  TickMarkData *ticks;
+  int color;
 
   graphic = GetGraphic();
 
-  /* each axis is drawn independently, but ticks and labels are placed according to
-     perpendicular distance. */
+  /* each axis is drawn independently, but ticks and labels are placed according to perpendicular distance. */
   for (i = 0; i < 4; i++) {
-    fx = graph[0].axis[i].fx;
-    fy = graph[0].axis[i].fy;
+    fx  = graph[0].axis[i].fx;
+    fy  = graph[0].axis[i].fy;
     dfx = graph[0].axis[i].dfx;
     dfy = graph[0].axis[i].dfy;
-    P = hypot ((double)graph[0].axis[(i+1)%2].dfx, (double)graph[0].axis[(i+1)%2].dfy);
+    P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
 
     lweight = MAX (0, MIN (10, graph[0].axis[i].lweight));
+    color = MAX (0, MIN (15, graph[0].axis[i].color));
+
     XSetLineAttributes (graphic->display, graphic->gc, lweight, LineSolid, CapNotLast, JoinMiter);
-    
-    graph[0].axis[i].color = MAX (0, MIN (15, graph[0].axis[i].color));
-
-    XSetForeground (graphic->display, graphic->gc, graphic->color[graph[0].axis[i].color]);
-    DrawRotTextInit (graphic->display, graphic->window, graphic->gc, graphic->color[graph[0].axis[i].color], graphic->back);
-
-    // fprintf (stderr, "axis: %d, color: %d, %ld, weight: %f\n", i, graph[0].axis[i].color, graphic->color[graph[0].axis[i].color], lweight);
+    XSetForeground (graphic->display, graphic->gc, graphic->color[color]);
+    DrawRotTextInit (graphic->display, graphic->window, graphic->gc, graphic->color[color], graphic->back);
 
     if (graph[0].axis[i].isaxis) {
       DrawLine (fx, fy, dfx, dfy);
-      // fprintf (stderr, "%d : %d %d - %d %d\n", i, fx, fy, dfx, dfy);
-      // if (i == 0) {
-      // 	int j;
-      // 	for (j = fx; j < fx + dfx; j+= 10) {
-      // 	  DrawLine (j, fy-10, 0, 20);
-      // 	}
-      // }
     }
     
     if (graph[0].axis[i].areticks) {
-      if (isnan(graph[0].axis[i].min) || isinf(graph[0].axis[i].min)) continue;
-      if (isnan(graph[0].axis[i].max) || isinf(graph[0].axis[i].max)) continue;
-
-      range = graph[0].axis[i].max - graph[0].axis[i].min;
-      if (fabs(range) < MIN_RANGE) continue;
-
-      if (fabs(range) < MIN_RANGE) {
-	range = (range < 0) ? -MIN_RANGE : +MIN_RANGE;
+      ticks = CreateAxisTicks (&graph[0].axis[i], &Nticks);
+      for (j = 0; j < Nticks; j++) {
+	DrawTick (graphic, &graph[0].axis[i], P, &ticks[j], i);
       }
-
-      AxisTickScale (&graph[0].axis[i], &major, &minor);
-
-      first = minor*((int)(graph[0].axis[i].min/minor));
-      if ((range > 0) && (first < graph[0].axis[i].min)) {
-	first += minor;
-      }
-      if ((range < 0) && (first > graph[0].axis[i].min)) {
-	first -= minor;
-      }
-      for (next = first; ((range > 0) && (next <= graph[0].axis[i].max)) || ((range < 0) && (next >= graph[0].axis[i].max));) {
-	IsMajor = FALSE;
-	IsMajor |= (fabs((int)(next/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs((int)((next + 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs ((int)((next - 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsLabel = (IsMajor && graph[0].axis[i].islabel);
-	DrawTick (fx, fy, dfx, dfy, P, graph[0].axis[i].min, graph[0].axis[i].max, next, IsLabel, IsMajor, i);
-	if (range > 0) 
-	  next += minor;
-	else 
-	  next -= minor;
-      }
+      FREE (ticks);
     }
   }
-}
-
-void DrawTick (int fx, int fy, int dfx, int dfy, 
-	       int P, double min, double max, 
-	       double value, int IsLabel, int IsMajor, int naxis) {
-  
-  int x, y, dx, dy, pos, dir, fontsize;
-  double size, n;
+  return (TRUE);
+}
+
+void DrawTick (Graphic *graphic, Axis *axis, int P, TickMarkData *tick, int naxis) {
+  
+  double x, y, dx, dy;
+  int pos, dir, fontsize;
+  double size, n, pad;
   char string[64], *fontname;
 
-  if (IsMajor) { 
+  double fx  = axis->fx;
+  double fy  = axis->fy;
+  double dfx = axis->dfx;
+  double dfy = axis->dfy;
+
+  double min = axis->min;
+  double max = axis->max;
+
+  double value = tick->value;
+
+  pos = size = 0;
+
+  if (tick->IsMajor) { 
     size = MAX (0.02, 7.0 / P); 
   } else {
@@ -92,10 +68,15 @@
   }
   
-  n = P / sqrt ((double)(dfx*dfx + dfy*dfy));
+  n = P / hypot(dfx, dfy);
   x = fx + (value-min)*dfx/(max - min);
   y = fy + (value-min)*dfy/(max - min);
 
-  dir = +1;
-  if ((naxis == 0) || (naxis == 1)) dir *= -1;
+  if ((naxis == 0) || (naxis == 2)) {
+    x = MAX(x, fx);
+  }
+  //   y = MAX(y, fy);
+  // }
+
+  dir = ((naxis == 0) || (naxis == 1)) ? -1 : +1;
   dx = dir*size*dfy*n;	
   dy = dir*size*dfx*n;
@@ -103,30 +84,28 @@
   DrawLine (x, y, dx, dy);
 
-# ifdef IN_AND_OUT_TICKS
-# define GAP 0.03
-# else
-# define GAP 0.01
-# endif
-
-  if (IsLabel) {
+  if (tick->IsLabel) {
+    int xt, yt;
+
     fontname = GetRotFont (&fontsize);
-    pos = 0;
+    
+    pad = !isnan(axis->ticktextPad) ? axis->ticktextPad*fontsize : fontsize + 4.0;
+    // pad = !isnan(axis->ticktextPad) ? axis->ticktextPad*fontsize : 0.8*fontsize + 1.0;
     
     /* temporarily assume rectilinear axes */
-    if (naxis == 0) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 1; }
-    if (naxis == 2) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 7; }
-
-    if (naxis == 1) { dy = 0; dx = -(0.8*fontsize + 1); pos = 3; }
-    if (naxis == 3) { dy = 0; dx = +(0.8*fontsize + 1); pos = 5; }
-
-    x = fx + (value-min)*dfx/(max - min) + dx;
-    y = fy + (value-min)*dfy/(max - min) + dy;
+    if (naxis == 0) { dx = 0; dy = +1.0*pad; pos = 7; }
+    if (naxis == 2) { dx = 0; dy = -1.0*pad; pos = 1; }
+
+    if (naxis == 1) { dy = 0; dx = -0.5*pad; pos = 3; }
+    if (naxis == 3) { dy = 0; dx = +0.5*pad; pos = 5; }
+
+    xt = fx + (value-min)*dfx/(max - min) + dx;
+    yt = fy + (value-min)*dfy/(max - min) + dy;
     if (fabs(value/(max-min)) < 0.001) { value = 0.0; }
     sprintf (string, "%4g", value);
-    DrawRotText (x, y, string, pos, 0.0);
-  }
-  
-}
-
+    DrawRotText (xt, yt, string, pos, 0.0);
+  }
+}
+
+# define MIN_RANGE 1e-10
 
 void AxisTickScale (Axis *axis, double *major, double *minor) {
@@ -192,2 +171,69 @@
   }
 }
+
+TickMarkData *CreateAxisTicks (Axis *axis, int *nticks) {
+
+  TickMarkData *ticks;
+  double range, major, minor, first, value, dPixels, overshoot;
+  int i, NTICKS, nPixels, done, ifirst;
+
+  *nticks = 0;
+
+  if (isnan(axis->min) || isinf(axis->min)) return NULL;
+  if (isnan(axis->max) || isinf(axis->max)) return NULL;
+  
+  range = axis->max - axis->min;
+
+  // not sure why I skip out here instead of using the MIN_RANGE value
+  if (fabs(range) < MIN_RANGE) return NULL;
+  
+  if (fabs(range) < MIN_RANGE) {
+    range = (range < 0) ? -MIN_RANGE : +MIN_RANGE;
+  }
+
+  // length of the axis in pixels
+  nPixels = hypot(axis->dfx, axis->dfy);
+  dPixels = nPixels / range; // axis pixel-scale
+
+  AxisTickScale (axis, &major, &minor);
+
+  // be a little generous 
+  NTICKS = (int)(fabs(range / minor)) + 2;
+  ALLOCATE (ticks, TickMarkData, NTICKS);
+
+  // value of the tick mark
+  ifirst = (axis->min < 0.0) ? (axis->min/minor - 0.05) : (axis->min/minor + 0.05);
+  first = minor*ifirst;
+  
+  // allow undershoot by 1 pixel
+  overshoot = (axis->min - first) * dPixels;
+  // if (overshoot > 0.5) {
+  //   if (range > 0) {
+  //     first += minor;
+  //   } else {
+  //     first -= minor;
+  //   }
+  // }
+
+  // loop to find the ticks
+  done = FALSE;
+  value = first; 
+  for (i = 0; !done && (i < NTICKS); i++) {
+    ticks[i].IsMajor = FALSE;
+    ticks[i].IsMajor |= (fabs((int)(value/major) - (value/major)) < 0.5*(minor/major));
+    ticks[i].IsMajor |= (fabs((int)((value + 0.5*minor)/major) - (value/major)) < 0.5*(minor/major));
+    ticks[i].IsMajor |= (fabs((int)((value - 0.5*minor)/major) - (value/major)) < 0.5*(minor/major));
+    ticks[i].IsLabel = (ticks[i].IsMajor && axis->islabel);
+    ticks[i].value = value;
+    if (range > 0) 
+      value += minor;
+    else 
+      value -= minor;
+    
+    done |= (range > 0) && (value > axis->max);
+    done |= (range < 0) && (value < axis->max);
+  }
+
+  *nticks = i;
+  return (ticks);
+}
Index: branches/pap/Ohana/src/kapa2/src/DrawLabels.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/DrawLabels.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/DrawLabels.c	(revision 28003)
@@ -34,6 +34,6 @@
       switch (i) {
       case 0: pos = 7; break;
+      case 2: pos = 1; break;
       case 1: pos = 1; angle = -90; break;
-      case 2: pos = 1; break;
       case 3: pos = 1; angle =  90; break;
       case 4: pos = 2; break;
Index: branches/pap/Ohana/src/kapa2/src/EraseSections.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/EraseSections.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/EraseSections.c	(revision 28003)
@@ -8,5 +8,5 @@
   
   FreeSections ();
-  AddSection ("default", 0.0, 0.0, 1.0, 1.0);
+  AddSection ("default", 0.0, 0.0, 1.0, 1.0, -1);
 
   if (USE_XWINDOW) XClearWindow (graphic->display, graphic->window);
Index: branches/pap/Ohana/src/kapa2/src/Graphs.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/Graphs.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/Graphs.c	(revision 28003)
@@ -18,5 +18,20 @@
     graph[0].axis[i].lweight = 0.0;
     graph[0].axis[i].color = 0;
+    graph[0].axis[i].ticktextPad = NAN;
+    graph[0].axis[i].labelPad = NAN;
+    graph[0].axis[i].pad = NAN;
   }    
+  graph[0].data.ticktextPad = NAN;
+
+  graph[0].data.labelPadXm = NAN;
+  graph[0].data.labelPadXp = NAN;
+  graph[0].data.labelPadYm = NAN;
+  graph[0].data.labelPadYp = NAN;
+
+  graph[0].data.padXm = NAN;
+  graph[0].data.padXp = NAN;
+  graph[0].data.padYm = NAN;
+  graph[0].data.padYp = NAN;
+
   for (i = 0; i < 8; i++) {
     strcpy (graph[0].label[i].text, "");
@@ -37,6 +52,18 @@
   graph[0].data.size    = 1.0;		// point size of 1.0
 
-  graph[0].data.flipeast  = 1;		// +East  = -X by default
-  graph[0].data.flipnorth = 0;		// +North = +Y by default
+  graph[0].data.flipeast = TRUE;	// +East  = -X by default
+  graph[0].data.flipnorth = FALSE;	// +North = +Y by default
+
+  graph[0].data.coords.pc1_1 = graph[0].data.coords.pc2_2 = 1.0;
+  graph[0].data.coords.pc1_2 = graph[0].data.coords.pc2_1 = 0.0;
+  graph[0].data.coords.crval1 = 0.0;
+  graph[0].data.coords.crval2 = 0.0;
+  graph[0].data.coords.crpix1 = 0.0;
+  graph[0].data.coords.crpix2 = 0.0;
+  graph[0].data.coords.cdelt1 = graph[0].data.coords.cdelt2 = 1.0;
+  strcpy (graph[0].data.coords.ctype, "RA---LIN");
+  strcpy (graph[0].data.axis, "2222");
+  strcpy (graph[0].data.ticks, "2222");
+  strcpy (graph[0].data.labels, "2222");
 
   graph[0].Nobjects = 0;
Index: branches/pap/Ohana/src/kapa2/src/Layout.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/Layout.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/Layout.c	(revision 28003)
@@ -43,4 +43,4 @@
 
   /* create basic section, empty of image or graph */
-  section = AddSection ("default", 0.0, 0.0, 1.0, 1.0);
+  section = AddSection ("default", 0.0, 0.0, 1.0, 1.0, -1);
 }
Index: branches/pap/Ohana/src/kapa2/src/LoadFrame.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/LoadFrame.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/LoadFrame.c	(revision 28003)
@@ -3,7 +3,5 @@
 int LoadFrame (int sock) {
   
-  int i, color;
-  char Axis[16], Labels[16], Ticks[16];
-  double lweight;
+  int i;
   Section *section;
   KapaGraphWidget *graph;
@@ -16,7 +14,5 @@
   graph = section->graph;
 
-  KiiScanMessage (sock, "%lf %lf %lf %lf", 
-		  &graph[0].axis[0].min, &graph[0].axis[0].max, 
-		  &graph[0].axis[1].min, &graph[0].axis[1].max);
+  KapaScanGraphData (sock, &graph[0].data);
 
   graph[0].axis[3].min = graph[0].axis[1].min;
@@ -25,14 +21,24 @@
   graph[0].axis[2].max = graph[0].axis[0].max;
   
-  KiiScanMessage (sock, "%lf %d", &lweight, &color);
-  color = MAX (0, MIN (15, color));
+  // XXX this is fragile
+  graph[0].data.color = MAX (0, MIN (15, graph[0].data.color));
 
-  KiiScanMessage (sock, "%s %s %s", Axis, Labels, Ticks);
+  graph[0].axis[0].pad = graph[0].data.padXm;
+  graph[0].axis[1].pad = graph[0].data.padYm;
+  graph[0].axis[2].pad = graph[0].data.padXp;
+  graph[0].axis[3].pad = graph[0].data.padYp;
+
+  graph[0].axis[0].labelPad = graph[0].data.labelPadXm;
+  graph[0].axis[1].labelPad = graph[0].data.labelPadYm;
+  graph[0].axis[2].labelPad = graph[0].data.labelPadXp;
+  graph[0].axis[3].labelPad = graph[0].data.labelPadYp;
 
   for (i = 0; i < 4; i++) {
-    graph[0].axis[i].lweight = lweight;
-    graph[0].axis[i].color = color;
+    graph[0].axis[i].lweight = graph[0].data.lweight;
+    graph[0].axis[i].color = graph[0].data.color;
 
-    switch (Axis[i]) {
+    graph[0].axis[i].ticktextPad = graph[0].data.ticktextPad;
+
+    switch (graph[0].data.axis[i]) {
     case '0':
       graph[0].axis[i].isaxis = FALSE;
@@ -45,5 +51,5 @@
       break;
     }
-    switch (Ticks[i]) {
+    switch (graph[0].data.ticks[i]) {
     case '0':
       graph[0].axis[i].areticks = FALSE;
@@ -56,5 +62,5 @@
       break;
     }
-    switch (Labels[i]) {
+    switch (graph[0].data.labels[i]) {
     case '0':
       graph[0].axis[i].islabel = FALSE;
@@ -70,6 +76,7 @@
 
   SetSectionSizes (section);
-  if (USE_XWINDOW) DrawFrame (graph);
-  FlushDisplay ();
+  Refresh();
+  // if (USE_XWINDOW) DrawFrame (graph);
+  // FlushDisplay ();
 
   /* XXX why did I do this??? */
Index: branches/pap/Ohana/src/kapa2/src/PSFrame.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/PSFrame.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/PSFrame.c	(revision 28003)
@@ -4,9 +4,8 @@
 int PSFrame (KapaGraphWidget *graph, FILE *f) {
   
-  int i, P, IsLabel, IsMajor, fontsize;
-  double fx, fy, dfx, dfy, range, major, minor, first, next;
-  char *fontname;
+  int i, Nticks, P;
+  double fx, fy, dfx, dfy, lweight;
   Graphic *graphic;
-  float weight;
+  TickMarkData *ticks;
   bDrawColor color;
 
@@ -14,60 +13,54 @@
 
   /* each axis is drawn independently */
-  fontname = GetRotFont (&fontsize);
   fprintf (f, "1 setlinewidth\n");
   for (i = 0; i < 4; i++) {
-    fx = graph[0].axis[i].fx;
-    fy = graphic->dy - graph[0].axis[i].fy;
+    fx  = graph[0].axis[i].fx;
+    fy  = graphic->dy - graph[0].axis[i].fy;
     dfx = graph[0].axis[i].dfx;
     dfy = -graph[0].axis[i].dfy;
-    P = hypot ((double)graph[0].axis[(i+1)%2].dfx, (double)graph[0].axis[(i+1)%2].dfy);
+    P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
 
-    weight = MAX (0, MIN (10, graph[0].axis[i].lweight));
+    lweight = MAX (0, MIN (10, graph[0].axis[i].lweight));
     color = MAX (0, MIN (15, graph[0].axis[i].color));
-    fprintf (f, "%.1f setlinewidth\n", weight);
+
+    fprintf (f, "%.1f setlinewidth\n", lweight);
     fprintf (f, "%s setrgbcolor\n", KapaColorRGBString(color));
+    // no need to init rot font
 
-    if (graph[0].axis[i].isaxis) { DrawLine (fx, fy, dfx, dfy); }
+    if (graph[0].axis[i].isaxis) { 
+      DrawLine (fx, fy, dfx, dfy); 
+    }
     
     if (graph[0].axis[i].areticks) {
-      if (isnan(graph[0].axis[i].min) || isinf(graph[0].axis[i].min)) continue;
-      if (isnan(graph[0].axis[i].max) || isinf(graph[0].axis[i].max)) continue;
-
-      range = graph[0].axis[i].max - graph[0].axis[i].min;
-      AxisTickScale (&graph[0].axis[i], &major, &minor);
-
-      first = minor*((int)(graph[0].axis[i].min/minor));
-      if ((range > 0) && (first < graph[0].axis[i].min)) {
-	first += minor;
+      ticks = CreateAxisTicks (&graph[0].axis[i], &Nticks);
+      for (i = 0; i < Nticks; i++) {
+	PSTick (graphic, &graph[0].axis[i], P, &ticks[i], i, f);
       }
-      if ((range < 0) && (first > graph[0].axis[i].min)) {
-	first -= minor;
-      }
-      for (next = first; ((range > 0) && (next <= graph[0].axis[i].max)) || ((range < 0) && (next >= graph[0].axis[i].max));) {
-	IsMajor = FALSE;
-	IsMajor |= (fabs((int)(next/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs ((int)((next + 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs ((int)((next - 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsLabel = (IsMajor && graph[0].axis[i].islabel);
-	PSTick (f, fx, fy, dfx, dfy, P, graph[0].axis[i].min, graph[0].axis[i].max, next, IsLabel, IsMajor, i);
-	if (range > 0) 
-	  next += minor;
-	else 
-	  next -= minor;
-      }
-    }
+      FREE (ticks);
+    }      
   }
   return (TRUE);
 }
 
-void PSTick (FILE *f, double fx, double fy, double dfx, double dfy, int P, double min, double max, double value, int IsLabel, int IsMajor, int naxis) {
+void PSTick (Graphic *graphic, Axis *axis, int P, TickMarkData *tick, int naxis, FILE *f) {
   
+  double x, y, dx, dy;
   int pos, dir, fontsize;
-  double size, n, x, y, dx, dy;
+  double size, n, pad;
   char string[64], *fontname;
+
+  double fx  = axis->fx;
+  double fy  = graphic->dy - axis->fy;
+  double dfx = axis->dfx;
+  double dfy = -axis->dfy;
+
+  double min = axis->min;
+  double max = axis->max;
+
+  double value = tick->value;
 
   pos = size = 0;
 
-  if (IsMajor) { 
+  if (tick->IsMajor) { 
     size = MAX (0.02, 7.0 / P); 
   } else {
@@ -75,10 +68,9 @@
   }
   
-  n = P / sqrt ((double)(dfx*dfx + dfy*dfy));
+  n = P / hypot(dfx, dfy);
   x = fx + (value-min)*dfx/(max - min);
   y = fy + (value-min)*dfy/(max - min);
 
-  dir = -1;
-  if ((naxis == 0) || (naxis == 1)) dir *= -1;
+  dir = ((naxis == 0) || (naxis == 1)) ? -1 : +1;
   dx = dir*size*dfy*n;	
   dy = dir*size*dfx*n;
@@ -86,19 +78,23 @@
   DrawLine (x, y, dx, dy);
 
-  if (IsLabel) {
+  if (tick->IsLabel) {
+    int xt, yt;
+
     fontname = GetRotFont (&fontsize);
 
+    pad = !isnan(axis->ticktextPad) ? axis->ticktextPad*fontsize : 0.8*fontsize + 1.0;
+    
     /* temporarily assume rectilinear axes */
-    if (naxis == 0) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 1; }
-    if (naxis == 2) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 7; }
+    if (naxis == 0) { dx = 0; dy = +pad; pos = 1; }
+    if (naxis == 2) { dx = 0; dy = -pad; pos = 7; }
 
-    if (naxis == 1) { dy = 0; dx = -(0.8*fontsize + 1); pos = 3; }
-    if (naxis == 3) { dy = 0; dx = +(0.8*fontsize + 1); pos = 5; }
+    if (naxis == 1) { dy = 0; dx = -pad; pos = 3; }
+    if (naxis == 3) { dy = 0; dx = +pad; pos = 5; }
 
-    x = fx + (value-min)*dfx/(max - min) + dx;
-    y = fy + (value-min)*dfy/(max - min) + dy;
-    if (fabs(value) < 1e-14) { value = 0.0; }
-    sprintf (string, "%g", value);
-    PSRotText (f, (int)x, (int)y, string, pos, 0.0);
+    xt = fx + (value-min)*dfx/(max - min) + dx;
+    yt = fy + (value-min)*dfy/(max - min) + dy;
+    if (fabs(value) < 0.001) { value = 0.0; }
+    sprintf (string, "%4g", value);
+    PSRotText (f, xt, yt, string, pos, 0.0);
   }
 }
Index: branches/pap/Ohana/src/kapa2/src/Refresh.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/Refresh.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/Refresh.c	(revision 28003)
@@ -21,4 +21,5 @@
   for (i = 0; i < Nsection; i++) {
       section = GetSectionByNumber (i);
+      DrawSectionBG (graphic, section);
       DrawImage (section->image);
       DrawGraph (section->graph);
@@ -28,2 +29,25 @@
 }
 
+void DrawSectionBG (Graphic *graphic, Section *section) {
+
+  int Ncolors;
+  int X0, Y0, dX, dY;
+
+  if (section->bg == -1) return;
+
+  Ncolors = KapaColormapSize();
+
+  if (section->bg < 0) return;
+  if (section->bg >= Ncolors) return;
+
+  XSetForeground (graphic->display, graphic->gc, graphic->color[section->bg]);
+
+  dY = graphic[0].dy * section[0].dy;
+  dX = graphic[0].dx * section[0].dx;
+  Y0 = graphic[0].dy - graphic[0].dy * section[0].y - dY;
+  X0 = graphic[0].dx * section[0].x;
+  // fprintf (stderr, "section: (%s) %d %d - %d %d\n", section[0].name, X0, Y0, dX, dY);
+
+  XFillRectangle (graphic[0].display,  graphic[0].window, graphic[0].gc, X0, Y0, dX, dY);
+  return;
+}
Index: branches/pap/Ohana/src/kapa2/src/Sections.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/Sections.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/Sections.c	(revision 28003)
@@ -16,4 +16,5 @@
   section[0].dx = 0;
   section[0].dy = 0;
+  section[0].bg = -1;
 
   section[0].name = NULL;
@@ -42,5 +43,5 @@
 }
 
-Section *AddSection (char *name, float x, float y, float dx, float dy) {
+Section *AddSection (char *name, float x, float y, float dx, float dy, int bg) {
 
   int N;
@@ -61,4 +62,5 @@
   sections[N][0].dx = dx;
   sections[N][0].dy = dy;
+  sections[N][0].bg = bg;
   ActiveSection = N;
   return (sections[N]);
@@ -155,4 +157,22 @@
 }
 
+int SetSectionBG (int sock) {
+
+  int N, background;
+  char name[128];
+
+  KiiScanMessage (sock, "%s %d", name, &background);
+  
+  N = GetSectionByName (name);
+  if (N < 0) {
+    fprintf (stderr, "section %s not found\n", name);
+    return (TRUE);
+  }
+
+  sections[N][0].bg = background;
+
+  return (TRUE);
+}
+
 // return TRUE even for nonsense cases to avoid quitting kapa
 int MoveSection (int sock) {
Index: branches/pap/Ohana/src/kapa2/src/SetGraphData.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/SetGraphData.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/SetGraphData.c	(revision 28003)
@@ -18,38 +18,18 @@
   graph = section->graph;
   
-  // get graph data from client 
-  KiiScanMessage (sock, "%d %d %d %d %d %d %lf %lf", 
-		  &graph[0].data.style, 
-		  &graph[0].data.ptype, 
-		  &graph[0].data.ltype, 
-		  &graph[0].data.etype, 
-		  &graph[0].data.ebar, 
-		  &graph[0].data.color, 
-		  &graph[0].data.lweight, 
-		  &graph[0].data.size);
+  KapaScanGraphData (sock, &graph[0].data);
 
-  KiiScanMessage (sock, "%lf %lf %lf %lf", 
-		  &graph[0].data.xmin, 
-		  &graph[0].data.xmax, 
-		  &graph[0].data.ymin, 
-		  &graph[0].data.ymax);
+  for (i = 0; i < 4; i++) {
+    graph[0].axis[i].ticktextPad = graph[0].data.ticktextPad;
+  }    
+  graph[0].axis[0].labelPad = graph[0].data.labelPadXm;
+  graph[0].axis[1].labelPad = graph[0].data.labelPadYm;
+  graph[0].axis[2].labelPad = graph[0].data.labelPadXp;
+  graph[0].axis[3].labelPad = graph[0].data.labelPadYp;
 
-  KiiScanMessage (sock, "%f %f %f %f", 
-		  &graph[0].data.coords.pc1_1, &graph[0].data.coords.pc2_2,
-		  &graph[0].data.coords.pc1_2, &graph[0].data.coords.pc2_1);
-
-  KiiScanMessage (sock, "%d %d %s", 
-		  &graph[0].data.flipeast, &graph[0].data.flipnorth,
-		  graph[0].data.coords.ctype);
-
-  KiiScanMessage (sock, "%lf %lf %f %f %f %f", 
-		  &graph[0].data.coords.crval1,
-		  &graph[0].data.coords.crval2,
-		  &graph[0].data.coords.crpix1,
-		  &graph[0].data.coords.crpix2,
-		  &graph[0].data.coords.cdelt1,
-		  &graph[0].data.coords.cdelt2);
-
-
+  graph[0].axis[0].pad = graph[0].data.padXm;
+  graph[0].axis[1].pad = graph[0].data.padYm;
+  graph[0].axis[2].pad = graph[0].data.padXp;
+  graph[0].axis[3].pad = graph[0].data.padYp;
 
   xmin = graph[0].data.xmin;
@@ -90,29 +70,5 @@
   graph = section->graph;
 
-  KiiSendMessage (sock, "%8d %d %d %d %d %d %f %f", 
-		  graph[0].data.style, 
-		  graph[0].data.ptype, graph[0].data.ltype, 
-		  graph[0].data.etype, graph[0].data.ebar, graph[0].data.color, 
-		  graph[0].data.lweight, graph[0].data.size);
-
-  KiiSendMessage (sock, "%g %g %g %g", 
-		  graph[0].data.xmin, graph[0].data.xmax, 
-		  graph[0].data.ymin, graph[0].data.ymax);
-
-  KiiSendMessage (sock, "%g %g %g %g", 
-		  graph[0].data.coords.pc1_1, graph[0].data.coords.pc2_2,
-		  graph[0].data.coords.pc1_2, graph[0].data.coords.pc2_1);
-
-  KiiSendMessage (sock, "%d %d %s", 
-		  graph[0].data.flipeast, graph[0].data.flipnorth,
-		  graph[0].data.coords.ctype);
-
-  KiiSendMessage (sock, "%g %g %g %g %g %g", 
-		  graph[0].data.coords.crval1,
-		  graph[0].data.coords.crval2,
-		  graph[0].data.coords.crpix1,
-		  graph[0].data.coords.crpix2,
-		  graph[0].data.coords.cdelt1,
-		  graph[0].data.coords.cdelt2);
+  KapaSendGraphData (sock, &graph[0].data);
 
   return (TRUE);
Index: branches/pap/Ohana/src/kapa2/src/SetGraphSize.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/SetGraphSize.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/SetGraphSize.c	(revision 28003)
@@ -6,12 +6,16 @@
 void SetGraphSize (Section *section) {
 
-  int fontsize, bump, Nc;
-  int textpad, textdY, WdY; 
-  double PADx, PADy, Dx, Dy;
-  double PXm, PXp, PYm, PYp;
+  int i, Nticks;
+  int fontsize, Nc = 0;
+  int textpad, textdY, WdY;
+  int dXm, dXp, dYm, dYp;
+  double padXm, padXp, padYm, padYp;
+  double minPADx, maxPADx, minPADy;
+  double minPAD, maxPAD;
   double X0, Y0, dX, dY;
   char string[64], *fontname;
   KapaGraphWidget *graph;
   Graphic *graphic;
+  TickMarkData *ticks;
 
   if (section == NULL) return;
@@ -22,20 +26,95 @@
   fontname = GetRotFont (&fontsize);
 
-  PADx = MAX (graphic->dx / 20.0, fontsize);
-  PADy = MAX (graphic->dy / 20.0, fontsize);
-  Dx = graphic->dx - 2*PADx;
-  Dy = graphic->dy - 2*PADy;
+  minPAD = 1.0*fontsize + 0;
+  maxPAD = 2.0*fontsize + 4;
 
-  /* each graph has a padding PXm, PXp, PYm, PYp */
-  PXm = (graph[0].axis[1].islabel) ? 4*fontsize : 0;
-  PXp = (graph[0].axis[3].islabel) ? 4*fontsize : 0;
-  PYm = (graph[0].axis[0].islabel) ? 4*fontsize : 0;
-  PYp = (graph[0].axis[2].islabel) ? 4*fontsize : 0;
- 
+  minPADx = 1.5*fontsize;
+  maxPADx = 2.5*fontsize + 4.0;
+
+  minPADy = 1.5*fontsize;
+
+  // dXm : offset to label from lower x-axis, dYp : offset to label from right y-axis, etc
+  // padXm : padding below x-axis, padYp : padding to right of y-axis, etc
+
+  // offset from lower x-axis to labels and tick values
+  // these depend on (a) existence of tick labels and (b) auto-offset or not
+  if (isnan(graph[0].axis[0].labelPad)) {
+    dXm = (graph[0].axis[0].islabel) ? maxPAD  : minPAD;
+  } else {
+    dXm = graph[0].axis[0].labelPad * fontsize;
+  }
+  if (isnan(graph[0].axis[0].pad)) {
+    padXm = graph[0].axis[0].islabel ? maxPADx : minPADx;
+  } else {
+    padXm = graph[0].axis[0].pad * fontsize;
+  }
+
+  // offset from upper x-axis to labels and tick values
+  // these depend on (a) existence of tick labels and (b) auto-offset or not
+  if (isnan(graph[0].axis[2].labelPad)) {
+    dXp = (graph[0].axis[2].islabel) ? maxPAD : minPAD;
+  } else {
+    dXp = graph[0].axis[2].labelPad * fontsize;
+  }
+  if (isnan(graph[0].axis[2].pad)) {
+    padXp = graph[0].axis[2].islabel ? maxPADx : minPADx;
+  } else {
+    padXp = graph[0].axis[2].pad * fontsize;
+  }
+
+  // offset from left y-axis to labels and tick values
+  // these depend on (a) existence of tick labels and (b) auto-offset or not.
+  // in the auto-offset case, offset depends on the width of the tick label strings
+  if (graph[0].axis[1].islabel && (isnan(graph[0].axis[1].labelPad) || isnan(graph[0].axis[1].pad))) {
+    /* check for the max size of the axis label */
+    Nc = 0;
+    ticks = CreateAxisTicks (&graph[0].axis[1], &Nticks);
+    for (i = 0; i < Nticks; i++) {
+      if (!ticks[i].IsMajor) continue;
+      sprintf (string, "%g", ticks[i].value);
+      Nc = MAX (Nc, strlen (string));
+    }
+    FREE(ticks);
+  }
+  if (isnan(graph[0].axis[1].labelPad)) {
+    dYm = (graph[0].axis[1].islabel) ? (0.7*(Nc + 1.5)*fontsize) : minPAD;
+  } else {
+    dYm = graph[0].axis[1].labelPad * fontsize;
+  }
+  if (isnan(graph[0].axis[1].pad)) {
+    padYm = graph[0].axis[1].islabel ? (0.7*(Nc + 2.5)*fontsize) : minPADy;
+  } else {
+    padYm = graph[0].axis[1].pad * fontsize;
+  }
+
+  // offset from right y-axis to labels and tick values
+  // these depend on (a) existence of tick labels and (b) auto-offset or not.
+  // in the auto-offset case, offset depends on the width of the tick label strings
+  if (graph[0].axis[3].islabel && (isnan(graph[0].axis[3].labelPad) || isnan(graph[0].axis[3].pad))) {
+    Nc = 0;
+    ticks = CreateAxisTicks (&graph[0].axis[3], &Nticks);
+    for (i = 0; i < Nticks; i++) {
+      if (!ticks[i].IsMajor) continue;
+      sprintf (string, "%g", ticks[i].value);
+      Nc = MAX (Nc, strlen (string));
+    }
+    FREE(ticks);
+  }
+  if (isnan(graph[0].axis[3].labelPad)) {
+    dYp = (graph[0].axis[3].islabel) ? (0.7*(Nc + 1.5)*fontsize) : minPAD;
+  } else {
+    dYp = graph[0].axis[3].labelPad * fontsize;
+  }
+  if (isnan(graph[0].axis[3].pad)) {
+    padYp = graph[0].axis[3].islabel ? (0.7*(Nc + 2.5)*fontsize) : minPADy;
+  } else {
+    padYp = graph[0].axis[3].pad * fontsize;
+  }
+
   /* basic size of the graph in Xwindow coordinates */
-  X0 = PADx + PXm + (Dx * section[0].x);
-  Y0 = PADy + PYm + (Dy * section[0].y);
-  dX = (Dx * section[0].dx) - PXp - PXm;
-  dY = (Dy * section[0].dy) - PYp - PYm;
+  X0 = graphic[0].dx * section[0].x + padYm;
+  Y0 = graphic[0].dy * section[0].y + padXm;
+  dX = graphic[0].dx * section[0].dx - padYm - padYp;
+  dY = graphic[0].dy * section[0].dy - padXm - padXp;
 
   // if we are tied to an image, make mods as needed
@@ -47,17 +126,17 @@
     switch (section->image->location) {
       case 1:
-	Y0 = graphic[0].dy * section[0].y + 2*PAD1 + WdY + 2; // tied to image in Y
-	dY = graphic[0].dy * section[0].dy - 5*PAD1 - WdY - COLORPAD + 1;
-	break;
+        Y0 = graphic[0].dy * section[0].y  + 2*PAD1 + WdY + 2; // tied to image in Y
+        dY = graphic[0].dy * section[0].dy - 5*PAD1 - WdY - COLORPAD + 1;
+        break;
       case 3:
-	dY = graphic[0].dy * section[0].dy - 5*PAD1 - WdY - COLORPAD - PADy - PYm;
-	break;
+        dY = graphic[0].dy * section[0].dy - 5*PAD1 - WdY - COLORPAD - padYm - padYp;
+        break;
       case 2:
-	X0 = graphic[0].dx * section[0].x  + 2*PAD1 + ZOOM_X;
-	dX = graphic[0].dx * section[0].dx - 3*PAD1 - ZOOM_X;
-	break;
+        X0 = graphic[0].dx * section[0].x  + 2*PAD1 + ZOOM_X;
+        dX = graphic[0].dx * section[0].dx - 3*PAD1 - ZOOM_X;
+        break;
       case 4:
-	dX = graphic[0].dx * section[0].dx - 3*PAD1 - ZOOM_X - PADx - PXm;
-	break;
+        dX = graphic[0].dx * section[0].dx - 3*PAD1 - ZOOM_X - padXm - padXp;
+        break;
     }
   }
@@ -68,5 +147,5 @@
   graph[0].axis[0].dfx = dX;
   graph[0].axis[0].dfy = 0;
-  
+
   graph[0].axis[1].fx  = X0;
   graph[0].axis[1].fy  = graphic->dy - Y0;
@@ -84,45 +163,28 @@
   graph[0].axis[3].dfy = -dY;
 
-  PADx = 0.8*fontsize + 2;
-  PADy = 3.0*fontsize + 4;
+  /* define locations of axis labels */
+  graph[0].label[LABELLL].x = graph[0].axis[0].fx;
+  graph[0].label[LABELLL].y = graph[0].axis[0].fy + dXm;
+  graph[0].label[LABELX0].x = graph[0].axis[0].fx + 0.5*graph[0].axis[0].dfx;
+  graph[0].label[LABELX0].y = graph[0].axis[0].fy + dXm;
+  graph[0].label[LABELLR].x = graph[0].axis[0].fx + graph[0].axis[0].dfx;
+  graph[0].label[LABELLR].y = graph[0].axis[0].fy + dXm;
 
-  /* define locations of axis labels */
-  graph[0].label[LABELX0].x = graph[0].axis[0].fx + 0.5*graph[0].axis[0].dfx;
-  bump = (graph[0].axis[0].islabel) ? PADy : PADx;
-  graph[0].label[LABELX0].y = graph[0].axis[0].fy + bump;
-
+  graph[0].label[LABELUL].x = graph[0].axis[2].fx;
+  graph[0].label[LABELUL].y = graph[0].axis[2].fy - dXp;
   graph[0].label[LABELX1].x = graph[0].axis[2].fx + 0.5*graph[0].axis[2].dfx;
-  bump = (graph[0].axis[2].islabel) ? PADy : PADx;
-  graph[0].label[LABELX1].y = graph[0].axis[2].fy - bump;
-
-  /* check for the max size of the axis label */
-  sprintf (string, "%4g", graph[0].axis[1].min);
-  Nc = strlen (string);
-  sprintf (string, "%4g", graph[0].axis[1].max);
-  Nc = MAX (Nc, strlen (string));
+  graph[0].label[LABELX1].y = graph[0].axis[2].fy - dXp;
+  graph[0].label[LABELUR].x = graph[0].axis[2].fx + graph[0].axis[2].dfx;
+  graph[0].label[LABELUR].y = graph[0].axis[2].fy - dXp;
 
   graph[0].label[LABELY0].y = graph[0].axis[1].fy + 0.5*graph[0].axis[1].dfy;
-  bump = (graph[0].axis[1].islabel) ? (0.8*Nc*fontsize + 1) : PADx;
-  graph[0].label[LABELY0].x = graph[0].axis[1].fx - bump;
-
-  sprintf (string, "%4g", graph[0].axis[3].min);
-  Nc = strlen (string);
-  sprintf (string, "%4g", graph[0].axis[3].max);
-  Nc = MAX (Nc, strlen (string));
+  graph[0].label[LABELY0].x = graph[0].axis[1].fx - dYm;
 
   graph[0].label[LABELY1].y = graph[0].axis[3].fy + 0.5*graph[0].axis[3].dfy;
-  bump = (graph[0].axis[3].islabel) ? (0.8*Nc*fontsize + 1) : PADx;
-  graph[0].label[LABELY1].x = graph[0].axis[3].fx + bump;
-  
+  graph[0].label[LABELY1].x = graph[0].axis[3].fx + dYp;
+
+  // fprintf (stderr, "section %s, %f,%f : %f,%f\n", section->name, X0, Y0, dX, dY);
+
   /* these are wrong and have to be adjusted to sit in the corners */
 
-  graph[0].label[LABELUL].x = graph[0].axis[2].fx - PADx;
-  graph[0].label[LABELUL].y = graph[0].axis[2].fy - PADx;
-  graph[0].label[LABELUR].x = graph[0].axis[2].fx + graph[0].axis[2].dfx + PADx;
-  graph[0].label[LABELUR].y = graph[0].axis[2].fy - PADx;
-  graph[0].label[LABELLL].x = graph[0].axis[0].fx - PADx;
-  graph[0].label[LABELLL].y = graph[0].axis[0].fy + PADx;
-  graph[0].label[LABELLR].x = graph[0].axis[0].fx + graph[0].axis[0].dfx + PADx;
-  graph[0].label[LABELLR].y = graph[0].axis[0].fy + PADx;
-
 }
Index: branches/pap/Ohana/src/kapa2/src/bDrawFrame.c
===================================================================
--- branches/pap/Ohana/src/kapa2/src/bDrawFrame.c	(revision 27708)
+++ branches/pap/Ohana/src/kapa2/src/bDrawFrame.c	(revision 28003)
@@ -1,14 +1,16 @@
 # include "Ximage.h"
+// bDrawLine is a function, not a macro like DrawLine
 
 int bDrawFrame (KapaGraphWidget *graph) {
   
-  int i, P, IsLabel, IsMajor, fontsize;
-  double fx, fy, dfx, dfy, range, major, minor, first, next;
-  char *fontname;
-  int weight;
+  int i, Nticks, P;
+  double fx, fy, dfx, dfy, lweight;
+  // Graphic graphic; is not needed
+  TickMarkData *ticks;
   bDrawColor color;
 
+  // don't need graphic, unlink DrawFrame
+
   /* each axis is drawn independently */
-  fontname = GetRotFont (&fontsize);
   for (i = 0; i < 4; i++) {
     fx  = graph[0].axis[i].fx;
@@ -16,9 +18,12 @@
     dfx = graph[0].axis[i].dfx;
     dfy = graph[0].axis[i].dfy;
-    P = hypot ((double)graph[0].axis[(i+1)%2].dfx, (double)graph[0].axis[(i+1)%2].dfy);
+    P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
 
-    weight = MAX (0, MIN (10, graph[0].axis[i].lweight));
+    lweight = MAX (0, MIN (10, graph[0].axis[i].lweight));
     color = MAX (0, MIN (15, graph[0].axis[i].color));
-    bDrawSetStyle (color, weight, 0);
+
+    bDrawSetStyle (color, lweight, 0);
+    // function about sets solor and weight
+    // bDrawRotTextInit does not exist
 
     if (graph[0].axis[i].isaxis) { 
@@ -27,30 +32,9 @@
     
     if (graph[0].axis[i].areticks) {
-      if (isnan(graph[0].axis[i].min) || isinf(graph[0].axis[i].min)) continue;
-      if (isnan(graph[0].axis[i].max) || isinf(graph[0].axis[i].max)) continue;
-
-      range = graph[0].axis[i].max - graph[0].axis[i].min;
-
-      AxisTickScale (&graph[0].axis[i], &major, &minor);
-
-      first = minor*((int)(graph[0].axis[i].min/minor));
-      if ((range > 0) && (first < graph[0].axis[i].min)) {
-	first += minor;
+      ticks = CreateAxisTicks (&graph[0].axis[i], &Nticks);
+      for (i = 0; i < Nticks; i++) {
+	bDrawTick (&graph[0].axis[i], P, &ticks[i], i);
       }
-      if ((range < 0) && (first > graph[0].axis[i].min)) {
-	first -= minor;
-      }
-      for (next = first; ((range > 0) && (next <= graph[0].axis[i].max)) || ((range < 0) && (next >= graph[0].axis[i].max));) {
-	IsMajor = FALSE;
-	IsMajor |= (fabs((int)(next/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs ((int)((next + 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs ((int)((next - 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsLabel = (IsMajor && graph[0].axis[i].islabel);
-	bDrawTick (fx, fy, dfx, dfy, P, graph[0].axis[i].min, graph[0].axis[i].max, next, IsLabel, IsMajor, i);
-	if (range > 0) 
-	  next += minor;
-	else 
-	  next -= minor;
-      }
+      FREE (ticks);
     }
   }
@@ -58,13 +42,24 @@
 }
 
-void bDrawTick (double fx, double fy, double dfx, double dfy, int P, double min, double max, double value, int IsLabel, int IsMajor, int naxis) {
+void bDrawTick (Axis *axis, int P, TickMarkData *tick, int naxis) {
   
+  double x, y, dx, dy;
   int pos, dir, fontsize;
-  double size, n, x, y, dx, dy;
+  double size, n, pad;
   char string[64], *fontname;
+
+  double fx  = axis->fx;
+  double fy  = axis->fy;
+  double dfx = axis->dfx;
+  double dfy = axis->dfy;
+
+  double min = axis->min;
+  double max = axis->max;
+
+  double value = tick->value;
 
   pos = size = 0;
 
-  if (IsMajor) { 
+  if (tick->IsMajor) { 
     size = MAX (0.02, 7.0 / P); 
   } else {
@@ -72,10 +67,9 @@
   }
   
-  n = P / sqrt ((double)(dfx*dfx + dfy*dfy));
+  n = P / hypot(dfx, dfy);
   x = fx + (value-min)*dfx/(max - min);
   y = fy + (value-min)*dfy/(max - min);
 
-  dir = +1;
-  if ((naxis == 0) || (naxis == 1)) dir *= -1;
+  dir = ((naxis == 0) || (naxis == 1)) ? -1 : +1;
   dx = dir*size*dfy*n;	
   dy = dir*size*dfx*n;
@@ -83,19 +77,23 @@
   bDrawLine (x, y, x+dx, y+dy);
 
-  if (IsLabel) {
+  if (tick->IsLabel) {
+    int xt, yt;
+
     fontname = GetRotFont (&fontsize);
 
+    pad = !isnan(axis->ticktextPad) ? axis->ticktextPad*fontsize : 0.8*fontsize + 1.0;
+    
     /* temporarily assume rectilinear axes */
-    if (naxis == 0) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 1; }
-    if (naxis == 2) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 7; }
+    if (naxis == 0) { dx = 0; dy = +pad; pos = 1; }
+    if (naxis == 2) { dx = 0; dy = -pad; pos = 7; }
 
-    if (naxis == 1) { dy = 0; dx = -(0.8*fontsize + 1); pos = 3; }
-    if (naxis == 3) { dy = 0; dx = +(0.8*fontsize + 1); pos = 5; }
+    if (naxis == 1) { dy = 0; dx = -pad; pos = 3; }
+    if (naxis == 3) { dy = 0; dx = +pad; pos = 5; }
 
-    x = fx + (value-min)*dfx/(max - min) + dx;
-    y = fy + (value-min)*dfy/(max - min) + dy;
-    if (fabs(value) < 1e-14) { value = 0.0; }
-    sprintf (string, "%g", value);
-    bDrawRotText ((int)x, (int)y, string, pos, 0.0);
+    xt = fx + (value-min)*dfx/(max - min) + dx;
+    yt = fy + (value-min)*dfy/(max - min) + dy;
+    if (fabs(value) < 0.001) { value = 0.0; }
+    sprintf (string, "%4g", value);
+    bDrawRotText (xt, yt, string, pos, 0.0);
   }
 }
Index: branches/pap/Ohana/src/libdvo/include/dvo.h
===================================================================
--- branches/pap/Ohana/src/libdvo/include/dvo.h	(revision 27708)
+++ branches/pap/Ohana/src/libdvo/include/dvo.h	(revision 28003)
@@ -443,4 +443,5 @@
 void sort_image_subset (Image *image, off_t *subset, off_t N);
 void sort_coords_index (double *X, double *Y, off_t *S, off_t N);
+void sort_coords_indexonly (double *X, double *Y, off_t *S, off_t N);
 void sort_regions (SkyRegion *region, off_t N);
 
Index: branches/pap/Ohana/src/libdvo/src/coordops.c
===================================================================
--- branches/pap/Ohana/src/libdvo/src/coordops.c	(revision 27708)
+++ branches/pap/Ohana/src/libdvo/src/coordops.c	(revision 28003)
@@ -353,5 +353,5 @@
       dY = (dM*dLdX - dL*dMdX) * Do;
 
-      // fprintf (stderr, "X,Y + dX,dY : %f, %f : %f, %f\n", X, Y, dX, dY);
+      // fprintf (stderr, "Xo,Yo + dX,dY : %f, %f : %f, %f\n", Xo, Yo, dX, dY);
 
       Xo += dX;
Index: branches/pap/Ohana/src/libdvo/src/dvosorts.c
===================================================================
--- branches/pap/Ohana/src/libdvo/src/dvosorts.c	(revision 27708)
+++ branches/pap/Ohana/src/libdvo/src/dvosorts.c	(revision 28003)
@@ -46,4 +46,19 @@
 }
 
+/* sort a coordinate pair (X,Y) and the associated index (S) */
+void sort_coords_indexonly (double *X, double *Y, off_t *S, off_t N) {
+  
+# define SWAPFUNC(A,B){ off_t itmp; \
+  itmp = S[A]; S[A] = S[B]; S[B] = itmp; \
+}
+# define COMPARE(A,B)(X[S[A]] < X[S[B]])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+
 void sort_regions (SkyRegion *region, off_t N) {
 
Index: branches/pap/Ohana/src/libkapa/include/kapa.h
===================================================================
--- branches/pap/Ohana/src/libkapa/include/kapa.h	(revision 27708)
+++ branches/pap/Ohana/src/libkapa/include/kapa.h	(revision 28003)
@@ -72,4 +72,5 @@
   float dx;
   float dy;
+  int bg;
 } KapaSection;
 
@@ -78,4 +79,7 @@
   int style, ptype, ltype, etype, ebar, color;
   double lweight, size;
+  double ticktextPad;
+  double labelPadXm, labelPadYm, labelPadXp, labelPadYp;
+  double padXm, padXp, padYm, padYp;
   Coords coords;
   int flipeast, flipnorth;
@@ -173,7 +177,10 @@
 int KapaSelectSection (int fd, char *name);
 int KapaGetSection (int fd, char *name);
+int KapaSectionBG (int fd, char *name, int bg);
 int KapaMoveSection (int fd, char *name, char *direction);
 int KapaSetGraphData (int fd, Graphdata *graphmode);
 int KapaGetGraphData (int fd, Graphdata *graphmode);
+int KapaScanGraphData (int fd, Graphdata *graphmode);
+int KapaSendGraphData (int fd, Graphdata *graphmode);
 int KapaSetImageData (int fd, KapaImageData *graphmode);
 int KapaGetImageData (int fd, KapaImageData *graphmode);
Index: branches/pap/Ohana/src/libkapa/src/KapaColors.c
===================================================================
--- branches/pap/Ohana/src/libkapa/src/KapaColors.c	(revision 27708)
+++ branches/pap/Ohana/src/libkapa/src/KapaColors.c	(revision 28003)
@@ -37,4 +37,6 @@
     }	
   }
+  if (!strcasecmp (name, "none")) return (-1);
+
   fprintf (stderr, "color may be one of:\n");
   for (i = 0; i < N_KAPA_COLORS; i++) {
Index: branches/pap/Ohana/src/libkapa/src/KapaOpen.c
===================================================================
--- branches/pap/Ohana/src/libkapa/src/KapaOpen.c	(revision 27708)
+++ branches/pap/Ohana/src/libkapa/src/KapaOpen.c	(revision 28003)
@@ -31,8 +31,8 @@
   if (status == -1) {
     if (errno == EADDRINUSE) {
-	close (InitSocket);
-	Address[0].sin_port ++;
-	if (Address[0].sin_port > MY_PORT_MAX) exit (2);
-	goto retry_server;
+        close (InitSocket);
+        Address[0].sin_port ++;
+        if (Address[0].sin_port > MY_PORT_MAX) exit (2);
+        goto retry_server;
     }
     perror ("bind: ");
@@ -69,4 +69,5 @@
 
   /* do I need to clear rfds on each pass? */
+  FD_ZERO(&rfds);
   FD_SET (InitSocket, &rfds);
   status = select (InitSocket + 1, &rfds, NULL, NULL, &wait);
@@ -98,7 +99,7 @@
 
   for (i = 0; i < Nvalid; i++) {
-    /* valid IP addresses may be machines (120.90.121.142) or 
+    /* valid IP addresses may be machines (120.90.121.142) or
        class C networks (120.90.121.0) */
-       
+
     /* for machine, address must match */
     if ((0xff & (VALID[i] >> 24)) != 0) {
@@ -138,8 +139,8 @@
   test = TRUE;
   test &= (status == 4);
-  test &= ((ip1 > 0) && (ip1 < 256)); 
-  test &= ((ip2 > 0) && (ip2 < 256)); 
-  test &= ((ip3 > 0) && (ip3 < 256)); 
-  test &= ((ip4 >=0) && (ip4 < 256)); 
+  test &= ((ip1 > 0) && (ip1 < 256));
+  test &= ((ip2 > 0) && (ip2 < 256));
+  test &= ((ip3 > 0) && (ip3 < 256));
+  test &= ((ip4 >=0) && (ip4 < 256));
   if (!test) {
     fprintf (stderr, "invalid IP address %s\n", string);
@@ -205,5 +206,5 @@
 
   // the client uses a BLOCKing socket by default
-  fcntl (InitSocket, F_SETFL, !O_NONBLOCK); 
+  fcntl (InitSocket, F_SETFL, !O_NONBLOCK);
   return (InitSocket);
 }
@@ -211,5 +212,5 @@
 int KapaOpen (char *kapa_exec, char *kapa_name) {
 
-  // kapa_exec may be kapa://host, in which case we attempt to connect to an 
+  // kapa_exec may be kapa://host, in which case we attempt to connect to an
   // already running kapa, or the program path, in which case we are supposed
   // to launch it locally, then connect to it.
@@ -265,10 +266,10 @@
   unlink (socket_name);
 
-  strcpy (Address.sun_path, socket_name); 
-  Address.sun_family = AF_UNIX; 
-  InitSocket = socket (AF_UNIX, SOCK_STREAM, 0); 
+  strcpy (Address.sun_path, socket_name);
+  Address.sun_family = AF_UNIX;
+  InitSocket = socket (AF_UNIX, SOCK_STREAM, 0);
   status = bind (InitSocket, (struct sockaddr *) &Address, sizeof (Address));
   status = listen (InitSocket, 1);
-  
+
   if (name == NULL) {
     sprintf (temp, "%s -socket %s &", kapa_exec, socket_name);
@@ -282,5 +283,5 @@
 
   AddressLength =  sizeof (Address);
-  fcntl (InitSocket, F_SETFL, O_NONBLOCK); 
+  fcntl (InitSocket, F_SETFL, O_NONBLOCK);
 
 # define NTRY 500
@@ -297,5 +298,5 @@
 
   // the client uses a BLOCKing socket by default
-  fcntl (fd, F_SETFL, !O_NONBLOCK); 
+  fcntl (fd, F_SETFL, !O_NONBLOCK);
   return (fd);
 }
@@ -317,5 +318,5 @@
 
   // the server uses an unblocked socket
-  fcntl (sock, F_SETFL, O_NONBLOCK);  
+  fcntl (sock, F_SETFL, O_NONBLOCK);
   unlink (sockpath);
   return (sock);
Index: branches/pap/Ohana/src/libkapa/src/KapaWindow.c
===================================================================
--- branches/pap/Ohana/src/libkapa/src/KapaWindow.c	(revision 27708)
+++ branches/pap/Ohana/src/libkapa/src/KapaWindow.c	(revision 28003)
@@ -38,10 +38,7 @@
 
   KiiSendCommand (fd, 4, "DBOX");
-  KiiSendMessage (fd, "%12.6g %12.6g %12.6g %12.6g", 
-		    graphdata[0].xmin, graphdata[0].xmax, graphdata[0].ymin, graphdata[0].ymax);
-
-  KiiSendMessage (fd, "%lf %d", graphdata[0].lweight, graphdata[0].color);
-
-  KiiSendMessage (fd, "%s %s %s", graphdata[0].axis, graphdata[0].labels, graphdata[0].ticks);
+
+  KapaSendGraphData (fd, graphdata);
+
   KiiWaitAnswer (fd, "DONE");
   return (TRUE);
@@ -84,4 +81,5 @@
 }
 
+// XXX drop this function? : kapa is responsible for the graph initialization
 int KapaInitGraph (Graphdata *graphdata) {
 
@@ -103,7 +101,20 @@
   graphdata[0].flipeast = TRUE;
   graphdata[0].flipnorth = FALSE;
+
   strcpy (graphdata[0].axis, "2222");
   strcpy (graphdata[0].ticks, "2222");
   strcpy (graphdata[0].labels, "2222");
+
+  graphdata[0].ticktextPad = NAN;
+
+  graphdata[0].labelPadXm = NAN;
+  graphdata[0].labelPadXp = NAN;
+  graphdata[0].labelPadYm = NAN;
+  graphdata[0].labelPadYp = NAN;
+
+  graphdata[0].padXm = NAN;
+  graphdata[0].padXp = NAN;
+  graphdata[0].padYm = NAN;
+  graphdata[0].padYp = NAN;
 
   return (TRUE);
@@ -128,10 +139,11 @@
 }
 
-int KapaSetGraphData (int fd, Graphdata *data) {
-
-  /* tell kapa to look for the incoming image */
-  KiiSendCommand (fd, 4, "SSTY"); 
-  
+int KapaSendGraphData (int fd, Graphdata *data) {
+
   /* send kapa the plot details */
+  KiiSendMessage (fd, "%g %g %g %g", 
+		  data[0].xmin, data[0].xmax, 
+		  data[0].ymin, data[0].ymax);
+
   KiiSendMessage (fd, "%8d %d %d %d %d %d %f %f", 
 		  data[0].style, 
@@ -140,7 +152,12 @@
 		  data[0].lweight, data[0].size);
 
+  KiiSendMessage (fd, "%g %g %g %g %g", 
+		  data[0].ticktextPad,
+		  data[0].padXm, data[0].padXp, 
+		  data[0].padYm, data[0].padYp);
+
   KiiSendMessage (fd, "%g %g %g %g", 
-		  data[0].xmin, data[0].xmax, 
-		  data[0].ymin, data[0].ymax);
+		  data[0].labelPadXm, data[0].labelPadXp, 
+		  data[0].labelPadYm, data[0].labelPadYp);
 
   KiiSendMessage (fd, "%g %g %g %g", 
@@ -160,14 +177,16 @@
 		  data[0].coords.cdelt2);
 
-  KiiWaitAnswer (fd, "DONE");
-  return (TRUE);
-}
-
-int KapaGetGraphData (int fd, Graphdata *data) {
-
-  /* tell kapa to look for the incoming image */
-  KiiSendCommand (fd, 4, "GSTY"); 
-  
+  KiiSendMessage (fd, "%s %s %s", data[0].axis, data[0].ticks, data[0].labels);
+
+  return (TRUE);
+}
+
+int KapaScanGraphData (int fd, Graphdata *data) {
+
   /* send kapa the plot details */
+  KiiScanMessage (fd, "%lf %lf %lf %lf", 
+		  &data[0].xmin, &data[0].xmax, 
+		  &data[0].ymin, &data[0].ymax);
+
   KiiScanMessage (fd, "%d %d %d %d %d %d %lf %lf", 
 		  &data[0].style, 
@@ -176,7 +195,12 @@
 		  &data[0].lweight, &data[0].size);
 
+  KiiScanMessage (fd, "%lf %lf %lf %lf %lf", 
+		  &data[0].ticktextPad, 
+		  &data[0].padXm, &data[0].padXp, 
+		  &data[0].padYm, &data[0].padYp);
+
   KiiScanMessage (fd, "%lf %lf %lf %lf", 
-		  &data[0].xmin, &data[0].xmax, 
-		  &data[0].ymin, &data[0].ymax);
+		  &data[0].labelPadXm, &data[0].labelPadXp, 
+		  &data[0].labelPadYm, &data[0].labelPadYp);
 
   KiiScanMessage (fd, "%f %f %f %f", 
@@ -196,8 +220,31 @@
 		  &data[0].coords.cdelt2);
 
+  KiiScanMessage (fd, "%s %s %s", data[0].axis, data[0].ticks, data[0].labels);
+
   // XXX at some point, we need to add polynomials and 2-level mosaic
   // astrometry here.
 
   data[0].coords.Npolyterms = 0;
+
+  return (TRUE);
+}
+
+int KapaSetGraphData (int fd, Graphdata *data) {
+
+  /* tell kapa to look for the incoming image */
+  KiiSendCommand (fd, 4, "SSTY"); 
+  
+  KapaSendGraphData (fd, data);
+
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaGetGraphData (int fd, Graphdata *data) {
+
+  /* tell kapa to look for the incoming image */
+  KiiSendCommand (fd, 4, "GSTY"); 
+  
+  KapaScanGraphData (fd, data);
 
   KiiWaitAnswer (fd, "DONE");
@@ -312,10 +359,19 @@
 
   KiiSendCommand (fd, 4, "DSEC");
-  KiiSendMessage (fd, "%s %6.3f %6.3f %6.3f %6.3f", 
+  KiiSendMessage (fd, "%s %6.3f %6.3f %6.3f %6.3f %3d", 
 		  section[0].name, 
 		  section[0].x,
 		  section[0].y,
 		  section[0].dx,
-		  section[0].dy);
+		  section[0].dy,
+		  section[0].bg);
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaSectionBG (int fd, char *name, int bg) {
+
+  KiiSendCommand (fd, 4, "BSEC");
+  KiiSendMessage (fd, "%s %3d", name, bg);
   KiiWaitAnswer (fd, "DONE");
   return (TRUE);
Index: branches/pap/Ohana/src/libkapa/src/KiiPicture.c
===================================================================
--- branches/pap/Ohana/src/libkapa/src/KiiPicture.c	(revision 27708)
+++ branches/pap/Ohana/src/libkapa/src/KiiPicture.c	(revision 28003)
@@ -46,5 +46,5 @@
   Nwrite = write (fd, image[0].data1d, size);
   if (Nwrite != size) {
-    fprintf (stderr, "error reading picture\n");
+    fprintf (stderr, "error sending picture to kapa\n");
     return (FALSE);
   }
@@ -105,5 +105,5 @@
   Nwrite = write (fd, outbuffer, size);
   if (Nwrite != size) {
-    fprintf (stderr, "error reading picture\n");
+    fprintf (stderr, "error sending picture to kapa\n");
     return (FALSE);
   }
@@ -142,6 +142,6 @@
     Nbytes = image[0].Nx*sizeof(float);
     Nwrite = write (fd, image[0].data2d[j], Nbytes);
-    if (Nwrite != size) {
-      fprintf (stderr, "error reading picture\n");
+    if (Nwrite != Nbytes) {
+      fprintf (stderr, "error sending picture to kapa\n");
       return (FALSE);
     }
Index: branches/pap/Ohana/src/opihi/cmd.basic/break.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.basic/break.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.basic/break.c	(revision 28003)
@@ -1,15 +1,16 @@
 # include "basic.h"
 
+// auto_break is currently a global
 int exec_break (int argc, char **argv) {
 
   int N, value;
 
+  if ((N = get_argument (argc, argv, "-h"))) goto usage;
+  if ((N = get_argument (argc, argv, "-help"))) goto usage;
+  if ((N = get_argument (argc, argv, "--help"))) goto usage;
+
   if ((N = get_argument (argc, argv, "-auto"))) {
     remove_argument (N, &argc, argv);
-    value = -1;
-    if (!strcasecmp (argv[N], "on")) value = 1;
-    if (!strcasecmp (argv[N], "off")) value = 0;
-    if (value == -1) {
-      gprint (GP_ERR, "USAGE: break -auto [on / off]\n");
+    if (N == argc) {
       if (auto_break) 
 	gprint (GP_ERR, "auto break on\n");
@@ -18,10 +19,17 @@
       return (FALSE);
     }
+    value = -1;
+    if (!strcasecmp (argv[N], "on")) value = 1;
+    if (!strcasecmp (argv[N], "off")) value = 0;
+    if (value == -1) goto usage;
     auto_break = value;
     return (TRUE);
   }
-
+  
   loop_break = TRUE;
   return (FALSE);
-
+  
+usage:
+  gprint (GP_ERR, "USAGE: break -auto [on / off]\n");
+  return (FALSE);
 }
Index: branches/pap/Ohana/src/opihi/cmd.basic/opihi.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.basic/opihi.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.basic/opihi.c	(revision 28003)
@@ -3,8 +3,8 @@
 int opihi_setmode (int argc, char **argv) {
 
-  int value;
+  OpihiVerboseMode value;
 
   if (argc < 2) {
-    gprint (GP_ERR, "USAGE: opihi (verbose) [on/off]\n");
+    gprint (GP_ERR, "USAGE: opihi (verbose) [on/off/error]\n");
     return (FALSE);
   }
@@ -13,17 +13,30 @@
       if (argc == 2) {
 	  value = get_verbose_shell();
-	  if (value) {
-	    gprint (GP_ERR, "opihi verbose mode: on\n");
-	  } else {
-	    gprint (GP_ERR, "opihi verbose mode: off\n");
-	  }
+	  switch (value) {
+	    case OPIHI_VERBOSE_OFF:
+	      gprint (GP_ERR, "opihi verbose mode: off\n");
+	      break;
+	    case OPIHI_VERBOSE_ON:
+	      gprint (GP_ERR, "opihi verbose mode: on\n");
+	      break;
+	    case OPIHI_VERBOSE_ERROR:
+	      gprint (GP_ERR, "opihi verbose mode: error\n");
+	      break;
+	    default:
+	      fprintf (stderr, "impossible condition\n");
+	      abort();
+	  } 
 	  return (TRUE);
       }
       if (!strcasecmp(argv[2], "on")) {
-	set_verbose_shell (TRUE);
+	set_verbose_shell (OPIHI_VERBOSE_ON);
 	return (TRUE);
       }
       if (!strcasecmp(argv[2], "off")) {
-	set_verbose_shell (FALSE);
+	set_verbose_shell (OPIHI_VERBOSE_OFF);
+	return (TRUE);
+      }
+      if (!strcasecmp(argv[2], "error")) {
+	set_verbose_shell (OPIHI_VERBOSE_ERROR);
 	return (TRUE);
       }
Index: branches/pap/Ohana/src/opihi/cmd.basic/run_for.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.basic/run_for.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.basic/run_for.c	(revision 28003)
@@ -7,5 +7,5 @@
   int ThisList, depth, i, done, status, found, NLINES, j;
   double start, end, delta;
-  char *input;
+  char *input, *endptr;
   double value, sign;
   Macro loop;
@@ -16,8 +16,24 @@
   }
 
-  start = atof (argv[2]);
-  end   = atof (argv[3]);
+  start = strtod (argv[2], &endptr);
+  if (*endptr) {
+    gprint (GP_ERR, "for loop starting value must be numerical (%s)\n", argv[2]);
+    return (FALSE);
+  }
+
+  end = strtod (argv[3], &endptr);
+  if (*endptr) {
+    gprint (GP_ERR, "for loop ending value must be numerical (%s)\n", argv[3]);
+    return (FALSE);
+  }
+
   delta = 1.0;
-  if (argc == 5) delta = atof (argv[4]);
+  if (argc == 5) { 
+    delta = strtod (argv[4], &endptr);
+    if (*endptr) {
+      gprint (GP_ERR, "for loop delta value must be numerical (%s)\n", argv[4]);
+      return (FALSE);
+    }
+  }
   sign = SIGN(delta);
 
Index: branches/pap/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.data/Makefile	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.data/Makefile	(revision 28003)
@@ -72,4 +72,5 @@
 $(SRC)/lookup.$(ARCH).o	\
 $(SRC)/matrix.$(ARCH).o	\
+$(SRC)/match2d.$(ARCH).o	\
 $(SRC)/mkrgb.$(ARCH).o	\
 $(SRC)/mcreate.$(ARCH).o	\
Index: branches/pap/Ohana/src/opihi/cmd.data/box.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.data/box.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.data/box.c	(revision 28003)
@@ -25,5 +25,5 @@
   } 
 
-  graphmode.lweight = 1;
+  // graphmode.lweight = 1;
   if ((N = get_argument (argc, argv, "-lw"))) {
     remove_argument (N, &argc, argv);
@@ -32,5 +32,5 @@
   }
 
-  graphmode.color = KapaColorByName ("black");
+  // graphmode.color = KapaColorByName ("black");
   if ((N = get_argument (argc, argv, "-c"))) {
     remove_argument (N, &argc, argv);
@@ -40,5 +40,6 @@
   }
 
-  strcpy (graphmode.ticks, "2222");
+  // XXX need to get the current values from kapa
+  // strcpy (graphmode.ticks, "2222");
   if ((N = get_argument (argc, argv, "-ticks"))) {
     remove_argument (N, &argc, argv);
@@ -51,5 +52,5 @@
   }
   
-  strcpy (graphmode.labels, "2222");
+  // strcpy (graphmode.labels, "2222");
   if ((N = get_argument (argc, argv, "-labels"))) {
     remove_argument (N, &argc, argv);
@@ -62,5 +63,5 @@
   }
 
-  strcpy (graphmode.axis, "2222");
+  // strcpy (graphmode.axis, "2222");
   if ((N = get_argument (argc, argv, "-axis"))) {
     remove_argument (N, &argc, argv);
@@ -71,4 +72,72 @@
       if ((graphmode.axis[i] != '0') && (graphmode.axis[i] != '1') && (graphmode.axis[i] != '2')) { goto usage; }
     }
+  }
+
+  if ((N = get_argument (argc, argv, "-tickpad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.ticktextPad = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "-labelpadx"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.labelPadXm = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "-labelpady"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.labelPadYm = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "+labelpadx"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.labelPadXp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "+labelpady"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.labelPadYp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "-labelpad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.labelPadXm = atof(argv[N]);
+    graphmode.labelPadXp = atof(argv[N]);
+    graphmode.labelPadYm = atof(argv[N]);
+    graphmode.labelPadYp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "-pad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.padXm = atof(argv[N]);
+    graphmode.padXp = atof(argv[N]);
+    graphmode.padYm = atof(argv[N]);
+    graphmode.padYp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-xpad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.padXm = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "+xpad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.padXp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-ypad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.padYm = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "+ypad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.padYp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
   }
 
Index: branches/pap/Ohana/src/opihi/cmd.data/create.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.data/create.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.data/create.c	(revision 28003)
@@ -14,5 +14,6 @@
 
   if ((argc != 5) && (argc != 4)) {
-    gprint (GP_ERR, "USAGE: create vector start end [delta]\n");
+    gprint (GP_ERR, "USAGE: create vector start end [delta] [-int]\n");
+    gprint (GP_ERR, " -int : resulting vector is integer type (delta must be integer)\n");
     return (FALSE);
   }
@@ -20,8 +21,9 @@
   if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
+  delta = 1;
   start = atof (argv[2]);
   end   = atof (argv[3]);
-  delta = 1;
   if (argc == 5) delta = atof (argv[4]);
+
   if ((start == end) || (delta == 0)) {
     gprint (GP_ERR, "error in value: %f to %f, %f\n", start, end, delta);
Index: branches/pap/Ohana/src/opihi/cmd.data/fit1d.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.data/fit1d.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.data/fit1d.c	(revision 28003)
@@ -53,9 +53,9 @@
     return (FALSE);
   }
-  REQUIRE_VECTOR_FLT (xvec, FALSE); 
-  REQUIRE_VECTOR_FLT (yvec, FALSE); 
+  CastVector (xvec, OPIHI_FLT);
+  CastVector (yvec, OPIHI_FLT);
 
   if (Weight) {
-    REQUIRE_VECTOR_FLT (dyvec, FALSE); 
+    CastVector (dyvec, OPIHI_FLT);
     if (xvec[0].Nelements != dyvec[0].Nelements) {
       gprint (GP_ERR, "vectors must have same length\n");
Index: branches/pap/Ohana/src/opihi/cmd.data/fit2d.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.data/fit2d.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.data/fit2d.c	(revision 28003)
@@ -64,10 +64,10 @@
     return (FALSE);
   }
-  REQUIRE_VECTOR_FLT (xvec, FALSE); 
-  REQUIRE_VECTOR_FLT (yvec, FALSE); 
-  REQUIRE_VECTOR_FLT (zvec, FALSE); 
+  CastVector (xvec, OPIHI_FLT);
+  CastVector (yvec, OPIHI_FLT);
+  CastVector (zvec, OPIHI_FLT);
 
   if (Weight) {
-    REQUIRE_VECTOR_FLT (dzvec, FALSE); 
+    CastVector (dzvec, OPIHI_FLT);
     if (xvec[0].Nelements != dzvec[0].Nelements) {
       gprint (GP_ERR, "vectors must have same length\n");
Index: branches/pap/Ohana/src/opihi/cmd.data/histogram.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.data/histogram.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.data/histogram.c	(revision 28003)
@@ -3,11 +3,18 @@
 int histogram (int argc, char **argv) {
   
-  int i, bin, Nbins;
+  int i, N, bin, Nbins;
   opihi_int *OUT;
   opihi_flt start, end, delta;
-  Vector *xvec, *yvec;
+  Vector *xvec, *yvec, *range;
+
+  range = NULL;
+  if ((N = get_argument (argc, argv, "-range"))) {
+    remove_argument (N, &argc, argv);
+    if ((range = SelectVector (argv[N], ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+    remove_argument (N, &argc, argv);
+  }
 
   if ((argc != 6) && (argc != 5)) {
-    gprint (GP_ERR, "USAGE: hist invec outvec start end [delta]\n");
+    gprint (GP_ERR, "USAGE: hist invec outvec start end [delta] [-range range]\n");
     return (FALSE);
   }
@@ -31,4 +38,11 @@
   if ((xvec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
   if ((yvec = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);
+
+  if (range) {
+    ResetVector (range, OPIHI_FLT, Nbins);
+    for (i = 0; i < range[0].Nelements; i++) {
+      range[0].elements.Flt[i] = start + i*delta;
+    }
+  }
 
   ResetVector (yvec, OPIHI_INT, Nbins);
Index: branches/pap/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.data/init.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.data/init.c	(revision 28003)
@@ -61,4 +61,5 @@
 int lookup           PROTO((int, char **));
 int matrix           PROTO((int, char **));
+int match2d          PROTO((int, char **));
 int mkrgb            PROTO((int, char **));
 int mcreate          PROTO((int, char **));
@@ -201,4 +202,5 @@
   {1, "iminterp",     minterp,          "interpolate image pixels"},
   {1, "matrix",       matrix,           "matrix math operations"},
+  {1, "match2d",      match2d,          "match 2 pairs of X,Y vectors and return matched indexes"},
   {1, "mkrgb",        mkrgb,            "convert 3 images to rgb jpeg (use Kapa for better control)"},
   {1, "mset",         mset,             "insert a vector in an image"},
Index: branches/pap/Ohana/src/opihi/cmd.data/match2d.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.data/match2d.c	(revision 28003)
+++ branches/pap/Ohana/src/opihi/cmd.data/match2d.c	(revision 28003)
@@ -0,0 +1,133 @@
+# include "data.h"
+int find_matches2d (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index1, Vector *index2);
+
+// match2d (X1) (Y1) (X2) (Y2) (Radius) [-index1 (index1)] [-index2 (index2)] [-nomatch1 nomatch1] [-nomatch2 nomatch2]
+// X1[Index1] <=> X2[Index2] (etc)
+int match2d (int argc, char **argv) {
+  
+  int N;
+  double Radius;
+  char *endptr;
+  Vector *X1vec, *Y1vec, *X2vec, *Y2vec;
+  Vector *index1, *index2;
+
+  if ((N = get_argument (argc, argv, "-index1"))) {
+    remove_argument (N, &argc, argv);
+    if ((index1 = SelectVector (argv[N], ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+    remove_argument (N, &argc, argv);
+  } else {
+    if ((index1 = SelectVector ("index1", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+  }
+
+  if ((N = get_argument (argc, argv, "-index2"))) {
+    remove_argument (N, &argc, argv);
+    if ((index2 = SelectVector (argv[N], ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+    remove_argument (N, &argc, argv);
+  } else {
+    if ((index2 = SelectVector ("index2", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+  }
+
+  if (argc != 6) {
+    gprint (GP_ERR, "USAGE: match2d X1 Y1 X2 Y2 Radius [-index1 (index1)] [-index2 (index2)] [-closest]\n");
+    // gprint (GP_ERR, "USAGE: match2d X1 Y1 X2 Y2 Radius [-index1 (index1)] [-index2 (index2)] [-closest]\n");
+    // gprint (GP_ERR, "  if -closest is provided, index1 & index2 will have the same length as X1 and X2 (respectively)\n");
+    // gprint (GP_ERR, "    with either the index of the match or a value of -1 for non-matches\n");
+    return (FALSE);
+  }
+
+  if ((X1vec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+  if ((Y1vec = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+  if ((X2vec = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+  if ((Y2vec = SelectVector (argv[4], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+
+  if (X1vec[0].Nelements != Y1vec[0].Nelements) {
+    gprint (GP_ERR, "X1 & Y1 vectors must have same length\n");
+    return (FALSE);
+  }
+  if (X2vec[0].Nelements != Y2vec[0].Nelements) {
+    gprint (GP_ERR, "X2 & Y2 vectors must have same length\n");
+    return (FALSE);
+  }
+
+  REQUIRE_VECTOR_FLT (X1vec, FALSE); 
+  REQUIRE_VECTOR_FLT (Y1vec, FALSE); 
+  REQUIRE_VECTOR_FLT (X2vec, FALSE); 
+  REQUIRE_VECTOR_FLT (Y2vec, FALSE); 
+
+  Radius = strtod (argv[5], &endptr);
+  if (*endptr) {
+    gprint (GP_ERR, "Radius must be numerical (%s)\n", argv[5]);
+    return (FALSE);
+  }
+
+  find_matches2d (X1vec, Y1vec, X2vec, Y2vec, Radius, index1, index2);
+
+  return (TRUE);
+}
+
+// we are not defining a relative offset DX,DY for now
+int find_matches2d (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index1, Vector *index2) {
+  
+  off_t i, j, first_j, I, J, *N1, *N2, Nmatch, NMATCH, DMATCH;
+  double dX, dY, dR, Radius2;
+
+  NMATCH = MAX(MAX(0.01*X1->Nelements, 0.01*X2->Nelements), 100);
+  DMATCH = NMATCH;
+
+  ResetVector (index1, OPIHI_INT, NMATCH);
+  ResetVector (index2, OPIHI_INT, NMATCH);
+
+  ALLOCATE (N1, off_t, X1->Nelements);
+  ALLOCATE (N2, off_t, X2->Nelements);
+
+  for (i = 0; i < X1->Nelements; i++) { N1[i] = i; }
+  for (i = 0; i < X2->Nelements; i++) { N2[i] = i; }
+
+  sort_coords_indexonly (X1->elements.Flt, Y1->elements.Flt, N1, X1->Nelements);
+  sort_coords_indexonly (X2->elements.Flt, Y2->elements.Flt, N2, X2->Nelements);
+
+  Radius2 = Radius*Radius;
+
+  Nmatch = 0;
+  for (i = j = 0; (i < X1->Nelements) && (j < X2->Nelements);) {
+    I = N1[i];
+    J = N2[j];
+
+    dX = X1->elements.Flt[I] - X2->elements.Flt[J];
+
+    if (dX <= -1.02*Radius) { i++; continue; }
+    if (dX >= +1.02*Radius) { j++; continue; }
+
+    // look for all matches of list2() to list1(i)
+    first_j = j;
+    for (j = first_j; (dX > -1.02*Radius) && (j < X2->Nelements); j++) {
+      J = N2[j];
+      dX = X1->elements.Flt[I] - X2->elements.Flt[J];
+      dY = Y1->elements.Flt[I] - Y2->elements.Flt[J];
+      dR = dX*dX + dY*dY;
+      if (dR < Radius2) {
+	index1->elements.Int[Nmatch] = I;
+	index2->elements.Int[Nmatch] = J;
+
+	// XXX track matches 1 and 2 with internal vector, save new nomatch index vectors
+	// after this loop
+
+	Nmatch ++;
+	if (Nmatch >= NMATCH) {
+	  NMATCH += DMATCH;
+	  REALLOCATE (index1->elements.Int, opihi_int, NMATCH);
+	  REALLOCATE (index2->elements.Int, opihi_int, NMATCH);
+	}
+      }
+    }
+    j = first_j;
+    i++;
+  }
+  index1->Nelements = Nmatch;
+  index2->Nelements = Nmatch;
+
+  free (N1);
+  free (N2);
+
+  return (TRUE);
+}
Index: branches/pap/Ohana/src/opihi/cmd.data/section.c
===================================================================
--- branches/pap/Ohana/src/opihi/cmd.data/section.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/cmd.data/section.c	(revision 28003)
@@ -1,9 +1,9 @@
 # include "data.h"
 
-enum {NONE, LIST, UP, DOWN, TOP, BOTTOM, TOOL};
+enum {NONE, LIST, UP, DOWN, TOP, BOTTOM, TOOL, BG};
 
 int section (int argc, char **argv) {
   
-  int N, action, kapa;
+  int N, action, kapa, background;
   Graphdata graphmode;
   KapaSection section;
@@ -37,4 +37,16 @@
     location = argv[N];
     remove_argument (N, &argc, argv);
+  }
+
+  background = -1; // invisible
+  if ((N = get_argument (argc, argv, "-bg"))) {
+    remove_argument (N, &argc, argv);
+    if (!strcasecmp (argv[N], "NONE")) {
+      background = -1;
+    } else {
+      background = KapaColorByName(argv[N]);
+    }
+    remove_argument (N, &argc, argv);
+    action = BG;
   }
 
@@ -82,4 +94,8 @@
 	break;
 
+      case BG:
+	KapaSectionBG (kapa, argv[1], background);
+	break;
+
       case TOOL:
 	if (!strcmp(location, "-x")) {
@@ -121,4 +137,5 @@
     section.dx = atof (argv[4]);
     section.dy = atof (argv[5]);
+    section.bg = background;
     KapaSetSection (kapa, &section);
     return (TRUE);
Index: branches/pap/Ohana/src/opihi/include/shell.h
===================================================================
--- branches/pap/Ohana/src/opihi/include/shell.h	(revision 27708)
+++ branches/pap/Ohana/src/opihi/include/shell.h	(revision 28003)
@@ -15,4 +15,5 @@
 typedef enum {GP_FILE, GP_BUFF} gpMode;
 typedef enum {GP_LOG, GP_ERR} gpDest;
+typedef enum {OPIHI_VERBOSE_OFF, OPIHI_VERBOSE_ON, OPIHI_VERBOSE_ERROR} OpihiVerboseMode;
 
 typedef int CommandF (int argc, char **argv);
Index: branches/pap/Ohana/src/opihi/lib.data/open_graph.c
===================================================================
--- branches/pap/Ohana/src/opihi/lib.data/open_graph.c	(revision 27708)
+++ 	(revision )
@@ -1,176 +1,0 @@
-# include "display.h"
-# include "shell.h"
-# define DEBUG 0
-
-/* we have space for several kapa windows */
-# define NXGRAPH 5
-
-static int       Active;
-static int       Xgraph[NXGRAPH];  
-static Graphdata graphdata[NXGRAPH];
-
-void QuitGraph () {
-
-  int i;
-  
-  for (i = 0; i < NXGRAPH; i++) {
-    KiiClose (Xgraph[i]);
-  }
-}
-
-void InitGraph () {
-
-  int i;
-
-  Active = 0;
-  for (i = 0; i < NXGRAPH; i++) {
-    Xgraph[i] = -1;
-
-    graphdata[i].xmin = graphdata[i].ymin = 0.0;
-    graphdata[i].xmax = graphdata[i].ymax = 1.0;
-    graphdata[i].style = graphdata[i].ptype = 0;
-    graphdata[i].ltype = graphdata[i].color = 0;
-    graphdata[i].etype = graphdata[i].ebar = 0;
-    graphdata[i].lweight = graphdata[i].size = 1.0;
-    
-    graphdata[i].coords.pc1_1 = graphdata[i].coords.pc2_2 = 1.0;
-    graphdata[i].coords.pc1_2 = graphdata[i].coords.pc2_1 = 0.0;
-    strcpy (graphdata[i].coords.ctype, "RA---LIN");
-    graphdata[i].coords.crval1 = 0.0;
-    graphdata[i].coords.crval2 = 0.0;
-    graphdata[i].coords.crpix1 = 0.0;
-    graphdata[i].coords.crpix2 = 0.0;
-    graphdata[i].coords.cdelt1 = graphdata[i].coords.cdelt2 = 1.0;
-    graphdata[i].flipeast = TRUE;
-    graphdata[i].flipnorth = FALSE;
-    strcpy (graphdata[i].axis, "2222");
-    strcpy (graphdata[i].ticks, "2222");
-    strcpy (graphdata[i].labels, "2222");
-  }
-}
-
-/* set SIGPIPE to this function to close cleanly */ 
-void XGraphDead (int input) {
-  signal (SIGPIPE, XGraphDead);
-  gprint (GP_ERR, "kapa is dead, must restart\n");
-  Xgraph[Active] = -1;
-}
-
-/** start socketed connection */
-int open_graph (int N) {
-
-  int fd;
-  char *kapa_exec, name[16];
-  
-  kapa_exec = get_variable ("KAPA");
-  if (kapa_exec == (char *) NULL) {
-    gprint (GP_ERR, "variable KAPA not found\n");
-    return (FALSE);
-  }
-
-  snprintf (name, 16, "[%d]", N);
-  fd = KiiOpen (kapa_exec, name);
-  free (kapa_exec);
-
-  if (fd < 0) {
-    gprint (GP_ERR, "error starting kapa\n");
-    return (FALSE);
-  } 
-
-  Xgraph[N] = fd;
-  return (TRUE);
-}
-
-int close_graph (int N) {
-
-  if (N <  0) return (FALSE);
-  if (N >= NXGRAPH) return (FALSE);
-
-  KiiClose (Xgraph[N]); 
-  Xgraph[N] = -1;
-  return (TRUE);
-}
-
-/* return pointers for current Xgraph, set if desired, test, open if needed */
-int GetGraph (Graphdata *data, int *socket, int *N) {
-
-  int i, n;
-  char buffer[70];
-
-  SetImageDevice (FALSE);
-  if (N == (int *) NULL) {
-    n = Active;
-  } else {
-    if (*N >= NXGRAPH) {
-      gprint (GP_ERR, "invalid Xgraph window %d\n", *N); 
-      return (FALSE);
-    }
-    if (*N < 0) {
-      *N = n = Active;
-    } else {
-      Active = n = *N;
-    }
-  }
-  
-  /* test Xgraph[0], flush junk from pipe */
-  signal (SIGPIPE, XGraphDead);
-  fcntl (Xgraph[n], F_SETFL,  O_NONBLOCK); 
-  for (i = 0; (read (Xgraph[n], buffer, 64) > 0) && (i < 20); i++);
-  fcntl (Xgraph[n], F_SETFL, !O_NONBLOCK); 
-  
-  if (Xgraph[n] < 1) {
-    if (!open_graph(n)) {
-      return (FALSE);
-    }
-  }
-
-  if (data != (Graphdata *) NULL) *data  = graphdata[n];
-  if (socket != (int *) NULL) *socket = Xgraph[n];
-
-  return (TRUE);
-
-}
-
-/* return pointers for given Xgraph, don't set or open */
-int GetGraphData (Graphdata *data, int *sock, int *N) {
-
-  int n;
-
-  if (N == (int *) NULL) {
-    n = Active;
-  } else {
-    if (*N >= NXGRAPH) {
-      gprint (GP_ERR, "invalid Xgraph window %d\n", *N); 
-      return (FALSE);
-    }
-    if (*N < 0) {
-      n = Active;
-    } else {
-      n = *N;
-    }
-  }
-  
-  if (data != (Graphdata *) NULL) *data  = graphdata[n];
-  if (sock != (int *) NULL) *sock = Xgraph[n];
-
-  return (TRUE);
-
-}
-
-/* assign given values to current Xgraph */
-void SetGraph (Graphdata data) {
-  graphdata[Active] = data;
-}
-
-/** internal tracking of current active device type **/
-
-static int       IsImage = FALSE;
-
-int GetCurrentDevice () {
-  return (IsImage);
-}
-
-void SetImageDevice (int state) {
-  IsImage = state;
-}
-
Index: branches/pap/Ohana/src/opihi/lib.data/open_image.c
===================================================================
--- branches/pap/Ohana/src/opihi/lib.data/open_image.c	(revision 27708)
+++ 	(revision )
@@ -1,133 +1,0 @@
-# include "display.h"
-# include "shell.h"
-# define DEBUG 0
-
-/* we have space for several kii windows */
-# define NXIMAGE 5
-
-static int       Active;
-static int       Ximage[NXIMAGE];  
-static char      Ximbuffer[NXIMAGE][512];
-static double    Xzero[NXIMAGE];
-static double    Xrange[NXIMAGE];
-
-void QuitImage () {
-
-  int i;
-  
-  for (i = 0; i < NXIMAGE; i++) {
-    KiiClose (Ximage[i]);
-  }
-}
-
-void InitImage () {
-
-  int i;
-
-  Active = 0;
-  for (i = 0; i < NXIMAGE; i++) {
-    Ximage[i] = -1;
-    Xzero[i] = 0;
-    Xrange[i] = 1024;
-    strcpy (Ximbuffer[i], "none");
-  }
-}
-
-/* set SIGPIPE to this function to close cleanly */ 
-void XImageDead (int input) {
-  signal (SIGPIPE, XImageDead);
-  gprint (GP_ERR, "kii is dead, must restart\n");
-  Ximage[Active] = -1;
-}
-
-/** start socketed connection */
-int open_image (int N) {
-
-  int fd;
-  char *kii_exec, name[16];
-
-  kii_exec = get_variable ("KII");
-  if (kii_exec == (char *) NULL) {
-    gprint (GP_ERR, "variable KII not found\n");
-    return (FALSE);
-  }
-
-  snprintf (name, 16, "[%d]", N);
-  fd = KiiOpen (kii_exec, name);
-  free (kii_exec);
-
-  if (fd < 0) {
-    gprint (GP_ERR, "error starting kii\n");
-    return (FALSE);
-  } 
-
-  Ximage[N] = fd;
-  return (TRUE);
-}
-
-int close_image (int N) {
-
-  if (N <  0) return (FALSE);
-  if (N >= NXIMAGE) return (FALSE);
-
-  KiiClose (Ximage[N]); 
-  Ximage[N] = -1;
-  return (TRUE);
-}
-
-/* return pointers for current Ximage, set if desired, test, open if needed */
-int GetImage (int *socket, int *N) {
-
-  int i, n;
-  char buffer[70];
-
-  SetImageDevice (TRUE);
-  if (N == (int *) NULL) {
-    n = Active;
-  } else {
-    if (*N >= NXIMAGE) {
-      gprint (GP_ERR, "invalid Ximage window %d\n", *N); 
-      return (FALSE);
-    }
-    if (*N < 0) {
-      *N = n = Active;
-    } else {
-      Active = n = *N;
-    }
-  }
-  
-  /* test Ximage[0], flush junk from pipe */
-  signal (SIGPIPE, XImageDead);
-  fcntl (Ximage[n], F_SETFL,  O_NONBLOCK); 
-  for (i = 0; (read (Ximage[n], buffer, 64) > 0) && (i < 20); i++);
-  fcntl (Ximage[n], F_SETFL, !O_NONBLOCK); 
-  
-  if (Ximage[n] < 1) {
-    if (!open_image(n)) {
-      return (FALSE);
-    }
-  }
-
-  if (socket != (int *) NULL) *socket = Ximage[n];
-
-  return (TRUE);
-
-}
-
-void SetImageName (char *name) {
-  strcpy (Ximbuffer[Active], name);
-}
-
-char *GetImageName () {
-  return (Ximbuffer[Active]);
-}
- 
-// leave this information on kapa, request when needed? 
-void SetImageScale (double zero, double range) {
-  Xzero[Active] = zero;
-  Xrange[Active] = range;
-}
-void GetImageScale (double *zero, double *range) {
-  *zero = Xzero[Active];
-  *range = Xrange[Active];
-}
Index: branches/pap/Ohana/src/opihi/lib.shell/command.c
===================================================================
--- branches/pap/Ohana/src/opihi/lib.shell/command.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/lib.shell/command.c	(revision 28003)
@@ -2,5 +2,5 @@
 # define DEBUG 0
 
-static int VERBOSE_SHELL = FALSE;
+static int VERBOSE_SHELL = OPIHI_VERBOSE_OFF;
 
 int command (char *line, char **outline, int VERBOSE) {
@@ -10,6 +10,6 @@
   Command *cmd;
 
-  rawline = NULL;
-  // rawline = strcreate (line);
+  // rawline = NULL;
+  rawline = strcreate (line);
 
   /* force a space between ! and first word: !ls becomes ! ls */
@@ -24,4 +24,9 @@
   /* expand anything of the form fred[N] */ 
   line = expand_vectors (line);  /* line is freed here, new one allocated */
+
+  // print the line with the variables and vectors expanded, but before evaluating 
+  // any in-line math expression
+  if (VERBOSE_SHELL == OPIHI_VERBOSE_ON) gprint (GP_ERR, "opihi: %s\n", line);
+
   /* solve math expresions, assign variable, if needed */
   line = parse (line);        /* line is freed here, new one allocated */
@@ -31,6 +36,4 @@
   *outline = line;
   
-  if (VERBOSE_SHELL) gprint (GP_ERR, "opihi: %s\n", line);
-
   argv = parse_commands (line, &argc);
   if (argc == 0) {
@@ -60,5 +63,5 @@
     msg = get_variable_ptr ("ERRORMSG");
     if (msg != (char *) NULL) gprint (GP_ERR, "%s\n", msg);
-    if (VERBOSE_SHELL) gprint (GP_ERR, "error on line: %s\n", rawline);
+    if (VERBOSE_SHELL != OPIHI_VERBOSE_OFF) gprint (GP_ERR, "error on line: %s\n", rawline);
   }
 
Index: branches/pap/Ohana/src/opihi/lib.shell/startup.c
===================================================================
--- branches/pap/Ohana/src/opihi/lib.shell/startup.c	(revision 27708)
+++ branches/pap/Ohana/src/opihi/lib.shell/startup.c	(revision 28003)
@@ -124,7 +124,12 @@
     if (LOAD_RC && !is_script) {
       rcfile = get_variable ("RCFILE");
-      sprintf (line, "input %s/%s", home, rcfile);
-      status = command (line, &outline, TRUE);
-      if (outline != (char *) NULL) free (outline);
+      if (rcfile && check_file_access (rcfile, FALSE, FALSE, FALSE)) {
+	sprintf (line, "input %s/%s", home, rcfile);
+	status = command (line, &outline, TRUE);
+	if (outline != (char *) NULL) free (outline);
+	if (status) {
+	  gprint (GP_LOG, "loaded file %s\n", rcfile); 
+	}	  
+      }
       if (rcfile) free (rcfile);
     }
Index: branches/pap/Ohana/src/opihi/pantasks/Makefile
===================================================================
--- branches/pap/Ohana/src/opihi/pantasks/Makefile	(revision 27708)
+++ branches/pap/Ohana/src/opihi/pantasks/Makefile	(revision 28003)
@@ -125,2 +125,6 @@
 
 .PHONY: pantasks pantasks_client pantasks_server
+
+.PRECIOUS: $(SRC)/pantasks.c
+.PRECIOUS: $(SRC)/pantasks_client.c 
+.PRECIOUS: $(SRC)/pantasks_server.c
Index: branches/pap/Ohana/src/opihi/pantasks/pantasks.c.in
===================================================================
--- branches/pap/Ohana/src/opihi/pantasks/pantasks.c.in	(revision 27708)
+++ branches/pap/Ohana/src/opihi/pantasks/pantasks.c.in	(revision 28003)
@@ -18,4 +18,5 @@
   InitBasic ();
   InitData ();
+  InitAstro ();
   InitPantasks ();
 
Index: branches/pap/Ohana/src/opihi/pantasks/pantasks_server.c.in
===================================================================
--- branches/pap/Ohana/src/opihi/pantasks/pantasks_server.c.in	(revision 27708)
+++ branches/pap/Ohana/src/opihi/pantasks/pantasks_server.c.in	(revision 28003)
@@ -13,8 +13,10 @@
 */
 
+void special_init (int *argc, char **argv);
+
 /* program-dependent initialization */
 int main (int argc, char **argv) {
   
-  char log_stdout[128], log_stderr[128];
+  char log_stdout[1024], log_stderr[1024];
   pthread_t JobsAndTasksThread;
   pthread_t clientsThread;
@@ -23,11 +25,40 @@
   SockAddress Address;
 
-  general_init (&argc, argv);
+  strcpy (log_stdout, "stdout");
+  strcpy (log_stderr, "stderr");
 
-  // define server output log files
+  special_init (&argc, argv);
+
+  // 
+  stdin = freopen ("/dev/zero", "r", stdin);
+
+  // this block redirects the actual stderr, stdout steams to the output files
   if (VarConfig ("PANTASKS_SERVER_STDOUT", "%s", log_stdout) != NULL) {
+    if (strcmp (log_stdout, "stdout")) {
+      stdout = freopen (log_stdout, "a", stdout);
+      if (!stdout) {
+	fprintf (stderr, "failed to open %s for output\n", log_stdout);
+	exit (1);
+      }
+    }
+  }
+  if (VarConfig ("PANTASKS_SERVER_STDERR", "%s", log_stderr) != NULL) {
+    if (strcmp (log_stderr, "stderr")) {
+      stderr = freopen (log_stderr, "a", stderr);
+      if (!stderr) {
+	fprintf (stdout, "failed to open %s for error output\n", log_stderr);
+	exit (1);
+      }
+    }
+  }
+
+  /* init for main (or only) thread */
+  gprintInit ();
+
+  // this block changes the target of the gprint output streams
+  if (strcmp (log_stdout, "stdout")) {
       gprintSetFileThisThread (GP_LOG, log_stdout);
   }
-  if (VarConfig ("PANTASKS_SERVER_STDERR", "%s", log_stderr) != NULL) {
+  if (strcmp (log_stderr, "stderr")) {
       gprintSetFileThisThread (GP_ERR, log_stderr);
   }
@@ -41,4 +72,5 @@
   InitBasic ();
   InitData ();
+  InitAstro ();
   InitPantasksServer ();
 
@@ -105,2 +137,24 @@
 void welcome () { }
 void program_init (int *argc, char **argv) {}
+
+// I need to do things in a different order here to have config / freopen / gprint sequenced correctly
+void special_init (int *argc, char **argv) {
+
+  /* init srand for rnd numbers elsewhere */
+  long A, B;
+  A = time(NULL);
+  for (B = 0; A == time(NULL); B++);
+  srand48(B);
+ 
+  /* set signals */
+  signal (SIGINT, SIG_IGN);
+
+  init_error ();
+
+  /* load config data (.ptolemyrc) */
+  if (!ConfigInit (argc, argv)) {
+    fprintf (stderr, "can't find (.ptolemyrc,ptolemy.rc) config file. some functions will be unavailable\n");
+  }
+
+  return;
+}
Index: branches/pap/Ohana/src/relphot/src/StarOps.c
===================================================================
--- branches/pap/Ohana/src/relphot/src/StarOps.c	(revision 27708)
+++ branches/pap/Ohana/src/relphot/src/StarOps.c	(revision 28003)
@@ -225,4 +225,5 @@
 	  }
 
+	  // XXX make it optional to apply Mcal (do I need an extra field for advisory Mcal?)
 	  list[N] = Msys - catalog[i].measure[m].Mcal;
 	  dlist[N] = MAX (catalog[i].measure[m].dM, MIN_ERROR);
Index: branches/pap/Ohana/src/uniphot/Makefile
===================================================================
--- branches/pap/Ohana/src/uniphot/Makefile	(revision 27708)
+++ branches/pap/Ohana/src/uniphot/Makefile	(revision 28003)
@@ -1,5 +1,5 @@
-default: uniphot
+default: uniphot setphot
 help:
-	@echo "make options: uniphot (default)"
+@echo "make options: uniphot setphot default help install default (uniphot setphot)"
 
 include ../../Makefile.System
@@ -18,5 +18,6 @@
 
 uniphot: $(BIN)/uniphot.$(ARCH)
-install: $(DESTBIN)/uniphot
+setphot: $(BIN)/setphot.$(ARCH)
+install: $(DESTBIN)/uniphot $(DESTBIN)/setphot 
 
 UNIPHOT = \
@@ -24,5 +25,5 @@
 $(SRC)/initialize.$(ARCH).o	    \
 $(SRC)/ConfigInit.$(ARCH).o	    \
-$(SRC)/args.$(ARCH).o		    \
+$(SRC)/args.$(ARCH).o               \
 $(SRC)/liststats.$(ARCH).o	    \
 $(SRC)/load_images.$(ARCH).o	    \
@@ -39,2 +40,18 @@
 $(UNIPHOT): $(INC)/uniphot.h
 $(BIN)/uniphot.$(ARCH): $(UNIPHOT)
+
+SETPHOT = \
+$(SRC)/setphot.$(ARCH).o	    \
+$(SRC)/initialize.$(ARCH).o	    \
+$(SRC)/ConfigInit.$(ARCH).o	    \
+$(SRC)/args.$(ARCH).o               \
+$(SRC)/liststats.$(ARCH).o	    \
+$(SRC)/load_zpt_table.$(ARCH).o	    \
+$(SRC)/load_images.$(ARCH).o	    \
+$(SRC)/match_zpts_to_images.$(ARCH).o	    \
+$(SRC)/update_catalog_setphot.$(ARCH).o \
+$(SRC)/SetSignals.$(ARCH).o	    \
+$(SRC)/Shutdown.$(ARCH).o	    
+
+$(SETPHOT): $(INC)/uniphot.h
+$(BIN)/setphot.$(ARCH): $(SETPHOT)
Index: branches/pap/Ohana/src/uniphot/include/uniphot.h
===================================================================
--- branches/pap/Ohana/src/uniphot/include/uniphot.h	(revision 27708)
+++ branches/pap/Ohana/src/uniphot/include/uniphot.h	(revision 28003)
@@ -39,4 +39,10 @@
 } Group;
 
+typedef struct {
+    float zpt;
+    e_time time;
+    int found;
+} ZptTable;
+
 /* global variables set in parameter file */
 char         ImageCat[256];
@@ -44,4 +50,7 @@
 char         CATMODE[16];    /* raw, mef, split, mysql */
 char         CATFORMAT[16];  /* internal, elixir, loneos, panstarrs */
+char         SKY_TABLE[256];
+int          SKY_DEPTH;  /** XXX EAM : depth of catalog tables, fix usage */
+char         GSCFILE[256];
 char         STATMODE[64];
 int          VERBOSE;
@@ -66,41 +75,50 @@
 
 /***** prototypes ****/
-void          ConfigInit         PROTO((int *argc, char **argv));
-void          DonePlotting       PROTO((Graphdata *graphmode, int N));
-void          JpegPlot           PROTO((Graphdata *graphmode, int N, char *filename));
-void          PSPlot             PROTO((Graphdata *graphmode, int N, char *filename));
-void          PlotLabel          PROTO((char *string, int N));
-void          PlotVector         PROTO((int Npts, double *vect, int mode, int N));
-void          PrepPlotting       PROTO((int Npts, Graphdata *graphmode, int N));
-void          XDead              PROTO((void));
-int           args               PROTO((int argc, char **argv));
-void          dumpresult         PROTO((void));
-Group        *find_image_sgroups PROTO((FITS_DB *db, ImageLink **imlink, int *Nsgroup));
-Group        *find_image_tgroups PROTO((FITS_DB *db, ImageLink **imlink, int *Ntgroup));
-void          fit_sgroup         PROTO((Group *sgroup, int Nsgroup));
-void          fit_tgroup         PROTO((Group *tgroup, int Ntgroup));
-int           gcatalog           PROTO((Catalog *catalog));
-void          initialize         PROTO((int argc, char **argv));
-void          initstats          PROTO((char *mode));
-int           liststats          PROTO((double *value, double *dvalue, int N, StatType *stats));
-int           load_images        PROTO((FITS_DB *db));
-int           main               PROTO((int argc, char **argv));
-int           open_graph         PROTO((int N));
-void          sort               PROTO((unsigned int *X, int N));
-void          sortB              PROTO((double *X, double *Y, int N));
-void          sortD              PROTO((double *X, double *Y, double *Z, int N));
-void          update_dvo_catalog PROTO((Catalog *catalog, Group *sgroup, int warn));
-void          wcatalog           PROTO((Catalog *catalog));
-void          wimages            PROTO((Image *image, int Nimage));
-void 	      check_permissions  PROTO((char *basefile));
-void 	      lock_image_db 	 PROTO((FITS_DB *db, char *filename));
-void	      unlock_image_db 	 PROTO((FITS_DB *db));
-void	      create_image_db 	 PROTO((FITS_DB *db));
-void	      set_db 		 PROTO((FITS_DB *in));
-int 	      Shutdown 		 PROTO((char *format, ...) OHANA_FORMAT(printf, 1, 2) );
-void 	      TrapSignal 	 PROTO((int sig));
-void 	      SetProtect 	 PROTO((int mode));
-int 	      SetSignals 	 PROTO((void));
-int 	      subset_images 	 PROTO((FITS_DB *db));
-void 	      update 		 PROTO((FITS_DB *db, Group *sgroup, int Nsgroup));
-void 	      sort_time 	 PROTO((unsigned int *value, int N));
+void          ConfigInit          PROTO((int *argc, char **argv));
+void          DonePlotting        PROTO((Graphdata *graphmode, int N));
+void          JpegPlot            PROTO((Graphdata *graphmode, int N, char *filename));
+void          PSPlot              PROTO((Graphdata *graphmode, int N, char *filename));
+void          PlotLabel           PROTO((char *string, int N));
+void          PlotVector          PROTO((int Npts, double *vect, int mode, int N));
+void          PrepPlotting        PROTO((int Npts, Graphdata *graphmode, int N));
+void          XDead               PROTO((void));
+int           args_uniphot        PROTO((int argc, char **argv));
+int           args_setphot        PROTO((int argc, char **argv));
+void          dumpresult          PROTO((void));
+Group        *find_image_sgroups  PROTO((FITS_DB *db, ImageLink **imlink, int *Nsgroup));
+Group        *find_image_tgroups  PROTO((FITS_DB *db, ImageLink **imlink, int *Ntgroup));
+void          fit_sgroup          PROTO((Group *sgroup, int Nsgroup));
+void          fit_tgroup          PROTO((Group *tgroup, int Ntgroup));
+int           gcatalog            PROTO((Catalog *catalog));
+void          initialize_uniphot  PROTO((int argc, char **argv));
+void          initialize_setphot  PROTO((int argc, char **argv));
+void          initstats           PROTO((char *mode));
+int           liststats           PROTO((double *value, double *dvalue, int N, StatType *stats));
+int           load_images_uniphot PROTO((FITS_DB *db));
+int           main                PROTO((int argc, char **argv));
+int           open_graph          PROTO((int N));
+void          sort                PROTO((unsigned int *X, int N));
+void          sortB               PROTO((double *X, double *Y, int N));
+void          sortD               PROTO((double *X, double *Y, double *Z, int N));
+void          update_dvo_catalog  PROTO((Catalog *catalog, Group *sgroup, int warn));
+void          wcatalog            PROTO((Catalog *catalog));
+void          wimages             PROTO((Image *image, int Nimage));
+void 	      check_permissions   PROTO((char *basefile));
+void 	      lock_image_db 	  PROTO((FITS_DB *db, char *filename));
+void	      unlock_image_db 	  PROTO((FITS_DB *db));
+void	      create_image_db 	  PROTO((FITS_DB *db));
+void	      set_db 		  PROTO((FITS_DB *in));
+int 	      Shutdown 		  PROTO((char *format, ...) OHANA_FORMAT(printf, 1, 2) );
+void 	      TrapSignal 	  PROTO((int sig));
+void 	      SetProtect 	  PROTO((int mode));
+int 	      SetSignals 	  PROTO((void));
+int 	      subset_images 	  PROTO((FITS_DB *db));
+void 	      update 		  PROTO((FITS_DB *db, Group *sgroup, int Nsgroup));
+void 	      sort_time 	  PROTO((unsigned int *value, int N));
+
+// setphot-specific prototypes
+ZptTable     *load_zpt_table         PROTO((char *filename, int *nzpts));
+Image        *load_images_setphot    PROTO((FITS_DB *db, off_t *Nimage));
+int           match_zpts_to_images   PROTO((Image *image, off_t Nimage, ZptTable *zpts, int Nzpts));
+int           update_setphot         PROTO((Image *image, off_t Nimage));
+void          update_catalog_setphot PROTO((Catalog *catalog, Image *image, off_t *index, off_t Nimage));
Index: branches/pap/Ohana/src/uniphot/src/ConfigInit.c
===================================================================
--- branches/pap/Ohana/src/uniphot/src/ConfigInit.c	(revision 27708)
+++ branches/pap/Ohana/src/uniphot/src/ConfigInit.c	(revision 28003)
@@ -1,3 +1,5 @@
 # include "uniphot.h"
+
+void GetConfig (char *config, char *field, char *format, int N, void *ptr);
 
 void ConfigInit (int *argc, char **argv) {
@@ -18,5 +20,5 @@
   if (VERBOSE) fprintf (stderr, "loaded config file: %s\n", file);
 
-  ScanConfig (config, "CATDIR",                 "%s",  0, CATDIR);
+  GetConfig (config, "CATDIR",                 "%s",  0, CATDIR);
   ScanConfig (config, "CATMODE",                "%s",  0, CATMODE);
   ScanConfig (config, "CATFORMAT",              "%s",  0, CATFORMAT);
@@ -24,4 +26,12 @@
 
   sprintf (ImageCat, "%s/Images.dat", CATDIR);
+
+  GetConfig (config, "GSCFILE",                 "%s",  0, GSCFILE);
+  if (!ScanConfig (config, "SKY_DEPTH",         "%d",  0, &SKY_DEPTH)) {
+    SKY_DEPTH = 2;
+  }
+  if (!ScanConfig (config, "SKY_TABLE",         "%s",  0, SKY_TABLE)) {
+    SKY_TABLE[0] = 0;
+  }
 
   ScanConfig (config, "ZERO_PT",                "%lf", 0, &ZERO_POINT);
@@ -42,2 +52,14 @@
 
 }
+
+void GetConfig (char *config, char *field, char *format, int N, void *ptr) {
+
+  char *status;
+
+  status = ScanConfig (config, field, format, N, ptr);
+  if (status == NULL) {
+    fprintf (stderr, "error in config, cannot find %s\n", field);
+    exit (1);
+  }
+  return;
+}
Index: branches/pap/Ohana/src/uniphot/src/Shutdown.c
===================================================================
--- branches/pap/Ohana/src/uniphot/src/Shutdown.c	(revision 27708)
+++ branches/pap/Ohana/src/uniphot/src/Shutdown.c	(revision 28003)
@@ -23,5 +23,5 @@
   SetProtect (TRUE);
   gfits_db_close (db);
-  fprintf (stderr, "ERROR: addstar halted\n");
+  fprintf (stderr, "ERROR: halted\n");
   exit (1);
 }
Index: branches/pap/Ohana/src/uniphot/src/args.c
===================================================================
--- branches/pap/Ohana/src/uniphot/src/args.c	(revision 27708)
+++ branches/pap/Ohana/src/uniphot/src/args.c	(revision 28003)
@@ -1,5 +1,5 @@
 # include "uniphot.h"
 
-int args (int argc, char **argv) {
+int args_uniphot (int argc, char **argv) {
 
   int N;
@@ -72,2 +72,26 @@
 }
 
+int args_setphot (int argc, char **argv) {
+
+  int N;
+
+  VERBOSE = FALSE;
+  if ((N = get_argument (argc, argv, "-v"))) {
+    VERBOSE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  UPDATE = FALSE;
+  if ((N = get_argument (argc, argv, "-update"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE = TRUE;
+  }
+
+  if (argc != 2) {
+    fprintf (stderr, "ERROR: USAGE: setphot (zptfile) [options]\n");
+    exit (2);
+  } 
+
+  return (TRUE);
+}
+
Index: branches/pap/Ohana/src/uniphot/src/initialize.c
===================================================================
--- branches/pap/Ohana/src/uniphot/src/initialize.c	(revision 27708)
+++ branches/pap/Ohana/src/uniphot/src/initialize.c	(revision 28003)
@@ -1,9 +1,9 @@
 # include "uniphot.h"
 
-void initialize (int argc, char **argv) {
+void initialize_uniphot (int argc, char **argv) {
 
   /* are these set correctly? */
   ConfigInit (&argc, argv);
-  args (argc, argv);
+  args_uniphot (argc, argv);
 
   if ((photcode = GetPhotcodebyName (argv[1])) == NULL) {
@@ -21,2 +21,9 @@
 }
 
+void initialize_setphot (int argc, char **argv) {
+
+  /* are these set correctly? */
+  ConfigInit (&argc, argv);
+  args_setphot (argc, argv);
+}
+
Index: branches/pap/Ohana/src/uniphot/src/load_images.c
===================================================================
--- branches/pap/Ohana/src/uniphot/src/load_images.c	(revision 27708)
+++ branches/pap/Ohana/src/uniphot/src/load_images.c	(revision 28003)
@@ -1,5 +1,5 @@
 # include "uniphot.h"
 
-int load_images (FITS_DB *db) {
+int load_images_uniphot (FITS_DB *db) {
 
   if (VERBOSE) fprintf (stderr, "finding images\n");
@@ -10,2 +10,19 @@
   return (TRUE);
 }
+
+Image *load_images_setphot (FITS_DB *db, off_t *Nimage) {
+
+  Image *image;
+
+  if (VERBOSE) fprintf (stderr, "finding images\n");
+
+  /* read entire db table */
+  if (!dvo_image_load (db, VERBOSE, FALSE)) Shutdown ("can't read image catalog %s", db[0].filename);
+
+  /* use a vtable to keep the images to be calibrated */
+  image = gfits_table_get_Image (&db[0].ftable, Nimage, &db[0].swapped);
+
+  fprintf (stderr, "loaded %lld images\n", (long long) *Nimage);
+
+  return (image);
+}
Index: branches/pap/Ohana/src/uniphot/src/load_zpt_table.c
===================================================================
--- branches/pap/Ohana/src/uniphot/src/load_zpt_table.c	(revision 28003)
+++ branches/pap/Ohana/src/uniphot/src/load_zpt_table.c	(revision 28003)
@@ -0,0 +1,41 @@
+# include "uniphot.h"
+
+ZptTable *load_zpt_table (char *filename, int *nzpts) {
+
+  int Nzpts, NZPTS;
+  ZptTable *zpts;
+  double zpt, mjd;
+
+  FILE *f;
+
+  f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open zpt table file %s\n", filename);
+    exit (1);
+  }
+
+  Nzpts = 0;
+  NZPTS = 100;
+  ALLOCATE (zpts, ZptTable, NZPTS);
+
+  // format is fixed: (time) (zpt)
+  int status;
+  while ((status = fscanf (f, "%lf %lf", &mjd, &zpt)) == 2) {
+    zpts[Nzpts].zpt = zpt;
+    zpts[Nzpts].time = ohana_mjd_to_sec (mjd);
+    zpts[Nzpts].found = FALSE;
+
+    Nzpts ++;
+    CHECK_REALLOCATE (zpts, ZptTable, NZPTS, Nzpts, 100);
+  }
+
+  if (status != EOF) {
+    fprintf (stderr, "unexpected formatting on line %d\n", Nzpts);
+    exit (2);
+  }
+
+  fprintf (stderr, "loaded %d zero points\n", Nzpts);
+
+  *nzpts = Nzpts;
+  return zpts;
+}
Index: branches/pap/Ohana/src/uniphot/src/match_zpts_to_images.c
===================================================================
--- branches/pap/Ohana/src/uniphot/src/match_zpts_to_images.c	(revision 28003)
+++ branches/pap/Ohana/src/uniphot/src/match_zpts_to_images.c	(revision 28003)
@@ -0,0 +1,90 @@
+# include "uniphot.h"
+
+/* sort a coordinate pair (X,Y) and the associated index (S) */
+static void sort_zpts_by_time (ZptTable *zpts, int Nzpts) {
+  
+# define SWAPFUNC(A,B){ ZptTable tmp;		\
+    tmp = zpts[A]; zpts[A] = zpts[B]; zpts[B] = tmp;	\
+  }
+# define COMPARE(A,B)(zpts[A].time < zpts[B].time)
+
+  OHANA_SORT (Nzpts, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+}
+
+# define SCALE 0.001
+
+int match_zpts_to_images (Image *image, off_t Nimage, ZptTable *zpts, int Nzpts) {
+
+  // I have two lists.  I need to match images->tzero to zpts->time.  multiple images may match a single zpt
+  
+  // sort both lists by time (or at least get sorted indices)
+  // sweep through both lists, advancing the one that is lagging
+  // apply the matches
+
+  int dT, NImatch, Nmatch;
+  off_t i, Ni, Nz, *index;
+  PhotCode *code;
+
+  // create index and sort
+  ALLOCATE (index, off_t, Nimage);
+  for (i = 0; i < Nimage; i++) {
+    index[i] = i;
+  }
+  sort_image_subset(image, index, Nimage);  // slightly misnamed sort function from libdvo
+
+  // sort the zpts
+  sort_zpts_by_time (zpts, Nzpts);
+
+  NImatch = 0; // matched images
+  for (i = Nz = 0; (i < Nimage) && (Nz < Nzpts); ) {
+
+    if (i % 1000 == 0) fprintf (stderr, ".");
+    if (Nz % 100 == 0) fprintf (stderr, "!");
+
+    Ni = index[i];
+    dT = image[Ni].tzero - zpts[Nz].time;
+
+    // negative dT, i is too small (allow a 1sec overlap window)
+    if (dT < -1) {
+      i++;
+      continue;
+    }
+
+    // XXX careful about definition of image->tzero and zpt->time
+    // negative dT, i is too small (allow a 1sec overlap window)
+    if (dT > +1) {
+      Nz++;
+      continue;
+    }
+
+    // check that we have a valid photcode (skip mosaic images)
+    code = GetPhotcodebyCode(image[Ni].photcode);
+    if (!code) { 
+      i++;
+      continue;
+    }
+
+    // we have a match: set zpt and record the match
+    image[Ni].Mcal = SCALE*code[0].C - zpts[Nz].zpt;
+    image[Ni].flags &= ~ID_IMAGE_NOCAL; // clear the NOCAL flag
+    zpts[Nz].found = TRUE;
+    NImatch ++;
+
+    // advance the image counter only -- a single zpt may match more than one image
+    i++;
+  }
+
+  // how many zpts have we matched?
+  Nmatch = 0;
+  for (Nz = 0; Nz < Nzpts; Nz++) {
+    if (zpts[Nz].found) Nmatch ++;
+  }
+
+  fprintf (stderr, "found %d zpt matches, %d image matches\n", Nmatch, NImatch);
+
+  return (TRUE);
+}
+
Index: branches/pap/Ohana/src/uniphot/src/setphot.c
===================================================================
--- branches/pap/Ohana/src/uniphot/src/setphot.c	(revision 28003)
+++ branches/pap/Ohana/src/uniphot/src/setphot.c	(revision 28003)
@@ -0,0 +1,49 @@
+# include "uniphot.h"
+
+int main (int argc, char **argv) {
+
+  off_t Nimage;
+  int status, Nzpts;
+  FITS_DB db;
+  ZptTable *zpts;
+  Image *image;
+
+  /* get configuration info, args, lockfile */
+  initialize_setphot (argc, argv);
+
+  set_db (&db);
+  status = dvo_image_lock (&db, ImageCat, 60.0, (UPDATE ? LCK_XCLD : LCK_SOFT));
+  if (!status) Shutdown ("ERROR: failure to lock image catalog %s", db.filename);
+  if (db.dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db.filename);
+
+  zpts = load_zpt_table (argv[1], &Nzpts);
+
+  // load images 
+  image  = load_images_setphot (&db, &Nimage);
+  if (!UPDATE) dvo_image_unlock (&db); 
+  
+  match_zpts_to_images (image, Nimage, zpts, Nzpts);
+
+  update_setphot(image, Nimage);
+
+  // write image table
+  if (UPDATE) {
+    dvo_image_save (&db, VERBOSE);
+  }
+
+  exit (0);
+}
+  
+
+/* setphot : set the zero points for images in the db (perhaps based on external information)
+   setphot (zpt_table)
+
+ * load text table of zpts, time (photcode?)
+ * load images
+ * match images to zpts
+ * set zpts
+ * load catalogs
+ * update detection (& averages?)
+
+ */
+
Index: branches/pap/Ohana/src/uniphot/src/uniphot.c
===================================================================
--- branches/pap/Ohana/src/uniphot/src/uniphot.c	(revision 27708)
+++ branches/pap/Ohana/src/uniphot/src/uniphot.c	(revision 28003)
@@ -9,5 +9,5 @@
 
   /* get configuration info, args, lockfile */
-  initialize (argc, argv);
+  initialize_uniphot (argc, argv);
 
   set_db (&db);
@@ -18,5 +18,5 @@
 
   /* load images */
-  load_images (&db);
+  load_images_uniphot (&db);
   
   /* filter image list by selection */
Index: branches/pap/Ohana/src/uniphot/src/update_catalog_setphot.c
===================================================================
--- branches/pap/Ohana/src/uniphot/src/update_catalog_setphot.c	(revision 28003)
+++ branches/pap/Ohana/src/uniphot/src/update_catalog_setphot.c	(revision 28003)
@@ -0,0 +1,97 @@
+# include "uniphot.h"
+# include <glob.h>
+
+int update_setphot (Image *image, off_t Nimage) {
+
+  SkyRegion UserPatch;
+  SkyTable *sky = NULL;
+  SkyList *skylist = NULL;
+  Catalog catalog;
+  off_t i, maxID, *index;
+
+  // create an index for the image IDs
+  maxID = 0;
+  for (i = 0; i < Nimage; i++) {
+    maxID = MAX(maxID, image[i].imageID);
+  }
+  ALLOCATE (index, off_t, maxID + 1);
+  for (i = 0; i < Nimage; i++) {
+    if (!image[i].imageID) continue; // images with ID == 0 are virtual
+    index[image[i].imageID] = i;
+  }
+  
+
+  // load the current sky table (layout of all SkyRegions) 
+  sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+  
+  // determine the populated SkyRegions overlapping the requested area (default depth)
+  UserPatch.Rmin = 0;
+  UserPatch.Rmax = 360;
+  UserPatch.Dmin = -90;
+  UserPatch.Dmax = +90;
+  skylist = SkyListByPatch (sky, -1, &UserPatch);
+
+  // update measurements for each populated catalog
+  for (i = 0; i < skylist[0].Nregions; i++) {
+
+    // set up the basic catalog info
+    catalog.filename  = skylist[0].filename[i];
+    catalog.catformat = dvo_catalog_catformat (CATFORMAT);    // set the default catformat from config data
+    catalog.catmode   = dvo_catalog_catmode (CATMODE);        // set the default catmode from config data
+    catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
+
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "w")) {
+      fprintf (stderr, "ERROR: failure reading catalog %s\n", catalog.filename);
+      exit (1);
+    }
+    if (!catalog.Naves_disk) {
+      if (VERBOSE) fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
+      dvo_catalog_unlock (&catalog);
+      dvo_catalog_free (&catalog);
+      continue;
+    }
+
+    update_catalog_setphot (&catalog, image, index, Nimage);
+
+    if (!UPDATE) {
+      dvo_catalog_unlock (&catalog);
+      dvo_catalog_free (&catalog);
+      continue;
+    }
+    
+    if (VERBOSE) fprintf (stderr, "saving catalog %s\n", catalog.filename);
+    
+    dvo_catalog_save (&catalog, VERBOSE); 
+    dvo_catalog_unlock (&catalog);
+    dvo_catalog_free (&catalog);
+  }
+  return (TRUE);
+}      
+
+void update_catalog_setphot (Catalog *catalog, Image *image, off_t *index, off_t Nimage) {
+
+  off_t i, j, m, id, idx, found;
+  float Mcal;
+
+  found = 0;    
+  for (i = 0; i < catalog[0].Naverage; i++) {
+
+    m = catalog[0].average[i].measureOffset;
+    for (j = 0; j < catalog[0].average[i].Nmeasure; j++, m++) {
+      idx = catalog[0].measure[m].imageID;
+      if (idx <= 0) continue; // detections with imageID == 0 do not have a valid image (eg, ref photcode)
+
+      id = index[idx];
+      Mcal = image[id].Mcal;
+
+      catalog[0].measure[m].Mcal = image[id].Mcal;
+      found ++;
+    }
+  }
+
+  if (found) {
+    fprintf (stderr, "found %lld matches\n", (long long) found);
+  }
+}
