Index: /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/Makefile	(revision 34524)
+++ /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/Makefile	(revision 34525)
@@ -114,4 +114,6 @@
 $(SRC)/shift.$(ARCH).o		\
 $(SRC)/sort.$(ARCH).o		\
+$(SRC)/spline.$(ARCH).o		\
+$(SRC)/spline_commands.$(ARCH).o \
 $(SRC)/imspline_apply.$(ARCH).o	\
 $(SRC)/imspline_construct.$(ARCH).o \
Index: /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/init.c	(revision 34524)
+++ /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/init.c	(revision 34525)
@@ -102,4 +102,5 @@
 int shift            PROTO((int, char **));
 int sort_vectors     PROTO((int, char **));
+int spline_command   PROTO((int, char **));
 int imspline_apply   PROTO((int, char **));
 int imspline_construct PROTO((int, char **));
@@ -254,4 +255,5 @@
   {1, "shift",        shift,            "shift data in an image"},
   {1, "sort",         sort_vectors,     "sort list of vectors"},
+  {1, "spline",       spline_command,   "shift data in an image"},
   {1, "imspline.apply", imspline_apply, "apply spline fit to generate an image"},
   {1, "imspline.const", imspline_construct, "create spline 2nd deriv. terms"},
Index: /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/spline.c
===================================================================
--- /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/spline.c	(revision 34525)
+++ /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/spline.c	(revision 34525)
@@ -0,0 +1,60 @@
+# include "data.h"
+
+int spline_list (int argc, char **argv);
+int spline_init (int argc, char **argv);
+int spline_create (int argc, char **argv);
+int spline_delete (int argc, char **argv);
+int spline_getspline (int argc, char **argv);
+int spline_listspline (int argc, char **argv);
+int spline_shuffle (int argc, char **argv);
+int spline_npages (int argc, char **argv);
+int spline_newpage (int argc, char **argv);
+int spline_getpage (int argc, char **argv);
+int spline_delpage (int argc, char **argv);
+int spline_listpage (int argc, char **argv);
+int spline_setword (int argc, char **argv);
+int spline_getword (int argc, char **argv);
+
+static Command spline_commands[] = {
+  {1, "list",       spline_list,       "list splines"},
+  {1, "init",       spline_init,       "initialize a spline"},
+  {1, "create",     spline_create,     "create a spline"},
+  {1, "delete",     spline_delete,     "delete a spline"},
+};
+
+int spline_command (int argc, char **argv) {
+
+  int i, N, status;
+
+  if (argc < 2) {
+    gprint (GP_ERR, "USAGE: spline (command)\n");
+    gprint (GP_ERR, "    spline list                                    : list splines\n");
+    gprint (GP_ERR, "    spline init     (spline)                       : removes all pages from spline\n");
+    gprint (GP_ERR, "    spline create   (spline)                       : create a spline\n");
+    gprint (GP_ERR, "    spline delete   (spline)                       : delete a spline\n");
+    return (FALSE);
+  }
+
+  N = sizeof (spline_commands) / sizeof (Command);
+
+  /* find the spline sub-command which matches */
+  for (i = 0; i < N; i++) {
+    if (!strcmp (spline_commands[i].name, argv[1])) {
+      status = (*spline_commands[i].func) (argc - 1, argv + 1);
+      return (status);
+    }
+  }
+
+  gprint (GP_ERR, "unknown spline command %s\n", argv[1]);
+  return (FALSE);
+}
+
+/* spline is called with the command "spline".  
+   the command line word "spline" is meant to be followed the one of several 
+   possible options:
+   
+   spline create
+   spline delete
+   spline list
+
+*/
Index: /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/spline_commands.c
===================================================================
--- /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/spline_commands.c	(revision 34525)
+++ /branches/eam_branches/ipp-20120905/Ohana/src/opihi/cmd.data/spline_commands.c	(revision 34525)
@@ -0,0 +1,112 @@
+# include "data.h"
+
+int spline_list (int argc, char **argv) {
+  if (argc != 1) {
+    gprint (GP_ERR, "USAGE: spline list\n");
+    return FALSE;
+  }
+
+  ListSplines();
+  return TRUE;
+}
+
+int spline_create (int argc, char **argv) {
+
+  int i;
+  Vector *xvec, *yvec;
+
+  if (argc != 4) {
+    gprint (GP_ERR, "USAGE: spline create (name) (Xknots) (Yknots)\n");
+    return FALSE;
+  }
+
+  if ((xvec = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE);
+  if ((yvec = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE);
+
+  if (xvec->Nelements != yvec->Nelements) {
+    gprint (GP_ERR, "x and y vectors must be the same length\n");
+    return FALSE;
+  }
+
+  Spline *myspline = CreateSpline (argv[1], xvec->Nelements);
+
+  for (i = 0; i < xvec->elements; i++) {
+    myspline->xk[i] = xvec->elements[i];
+    myspline->yk[i] = yvec->elements[i];
+  }    
+
+  spline_construct_dbl (myspline->xk, myspline->yk, myspline->Nknots, myspline->y2);
+  return TRUE;
+}
+
+int spline_apply (int argc, char **argv) {
+
+  int i;
+  Vector *xvec, *yvec;
+
+  if (argc != 4) {
+    gprint (GP_ERR, "USAGE: spline apply (name) (Xpoints) (Ypoints)\n");
+    return FALSE;
+  }
+
+  Spline *myspline = FindSpline (argv[1]);
+  if (!myspline) {
+    gprint (GP_ERR, "spline %s not found\n", argv[1]);
+    return (FALSE);
+  }
+
+  if ((xvec = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE);
+  if ((yvec = SelectVector (argv[3], ANYVECTOR, TRUE)) == NULL) return (FALSE);
+
+  ResetVector (yvec, OPIHI_FLT, xvec->Nelements);
+
+  for (i = 0; i < xvec->elements; i++) {
+    opihi_flt value = spline_apply_dbl (myspline->xk, myspline->yk, myspline->y2, myspline->Nknots, xvec->elements[i]);
+    yvec->elements[i] = value;;
+  }    
+
+  return TRUE;
+}
+
+int spline_delete (int argc, char **argv) {
+
+  int status;
+  Spline *spline;
+
+  if (argc != 2) {
+    gprint (GP_ERR, "USAGE: spline delete (spline)\n");
+    return FALSE;
+  }
+
+  spline = FindSpline (argv[1]);
+  if (spline == NULL) {
+    gprint (GP_ERR, "spline %s not found\n", argv[1]);
+    return FALSE;
+  }
+
+  status = DeleteSpline (spline);
+  if (!status) abort ();
+  return TRUE;
+}
+
+/* 
+int spline_listspline (int argc, char **argv) {
+
+  Spline *spline;
+
+  if (argc != 2) {
+    gprint (GP_ERR, "USAGE: spline listspline (spline)\n");
+    return FALSE;
+  }
+
+  spline = FindSpline (argv[1]);
+  if (spline == NULL) {
+    gprint (GP_ERR, "spline %s not found\n", argv[1]);
+    return FALSE;
+  }
+
+  ListPages (spline);
+  return TRUE;
+}
+*/
+
Index: /branches/eam_branches/ipp-20120905/Ohana/src/opihi/include/data.h
===================================================================
--- /branches/eam_branches/ipp-20120905/Ohana/src/opihi/include/data.h	(revision 34524)
+++ /branches/eam_branches/ipp-20120905/Ohana/src/opihi/include/data.h	(revision 34525)
@@ -84,6 +84,8 @@
 
 /* in spline.c */
-void spline_construct (float *x, float *y, int N, float *y2);
-float spline_apply (float *x, float *y, float *y2, int N, float X);
+void spline_construct_flt (float *x, float *y, int N, float *y2);
+float spline_apply_flt (float *x, float *y, float *y2, int N, float X);
+void spline_construct_dbl (opihi_flt *x, opihi_flt *y, int N, opihi_flt *y2);
+opihi_flt spline_apply_dbl (opihi_flt *x, opihi_flt *y, opihi_flt *y2, int N, opihi_flt X);
 
 /* in svdcmp.c */
@@ -168,4 +170,24 @@
 void FreeQueues (void);
 void FreeBooks (void);
+
+// the interpolating spline has valu
+typedef struct {
+  int Nknots;
+  opihi_flt *xk;
+  opihi_flt *yk;
+  opihi_flt *y2;
+  char *name;
+} Spline;
+
+/* in SplineOps.c */
+void InitSplines ();
+void FreeSplines ();
+void InitSpline (Spline *spline, char *name, int Nknots);
+void FreeSpline (Spline *spline);
+Spline *GetSpline (int where);
+Spline *FindSpline (char *name);
+Spline *CreateSpline (char *name, int Nknots);
+int DeleteSpline (Spline *spline);
+void ListSplines ();
 
 /* hermitian functions */
Index: /branches/eam_branches/ipp-20120905/Ohana/src/opihi/lib.data/SplineOps.c
===================================================================
--- /branches/eam_branches/ipp-20120905/Ohana/src/opihi/lib.data/SplineOps.c	(revision 34525)
+++ /branches/eam_branches/ipp-20120905/Ohana/src/opihi/lib.data/SplineOps.c	(revision 34525)
@@ -0,0 +1,130 @@
+# include "data.h"
+
+/* this file contains functions to manage the collection of Splines.
+   A spline in opihi is a native data structure which defines a 1D spline.  
+ */
+
+Spline **splines;   /* book to store the list of all splines */
+int     Nsplines;   /* number of currently defined splines */
+int     NSPLINES;   /* number of currently allocated splines */
+
+void InitSplines () {
+  Nsplines = 0;
+  NSPLINES = 16;
+  ALLOCATE (splines, Spline *, NSPLINES); 
+}
+
+void FreeSplines () {
+
+  int i;
+
+  for (i = 0; i < Nsplines; i++) {
+    FreeSpline (splines[i]);
+  }
+  free (splines);
+}
+
+void InitSpline (Spline *spline, char *name, int Nknots) {
+
+    spline[0].name = strcreate (name);
+
+    spline[0].Nknots = Nknots;
+    spline[0].NKNOTS = Nknots;
+    ALLOCATE (spline[0].xk, opihi_flt, spline[0].NKNOTS);
+    ALLOCATE (spline[0].yk, opihi_flt, spline[0].NKNOTS);
+    ALLOCATE (spline[0].y2, opihi_flt, spline[0].NKNOTS);
+    memset (spline[0].xk, 0, spline[0].NKNOTS * sizeof(opihi_flt));
+    memset (spline[0].yk, 0, spline[0].NKNOTS * sizeof(opihi_flt));
+    memset (spline[0].y2, 0, spline[0].NKNOTS * sizeof(opihi_flt));
+}
+
+void FreeSpline (Spline *spline) {
+
+    int i;
+
+    free (spline[0].name);
+    free (spline[0].xk);
+    free (spline[0].yk);
+    free (spline[0].y2);
+    free (spline);
+}
+
+/* return the given spline */
+Spline *GetSpline (int where) {
+
+  if (where < 0) where += Nsplines;
+  if (where < 0) return NULL;
+  if (where >= Nsplines) return NULL;
+  return (splines[where]);
+}
+
+/* return the given spline */
+Spline *FindSpline (char *name) {
+
+  int i;
+
+  for (i = 0; i < Nsplines; i++) {
+    if (!strcmp (splines[i][0].name, name)) {
+      return (splines[i]);
+    }
+  }
+  return (NULL);
+}
+
+/* make a new named spline */
+Spline *CreateSpline (char *name, int Nknots) {
+
+  int N;
+  Spline *spline;
+
+  spline = FindSpline (name);
+  if (spline != NULL) return (spline);
+
+  N = Nsplines;
+  Nsplines ++;
+  CHECK_REALLOCATE (splines, Spline *, NSPLINES, Nsplines, 16);
+  ALLOCATE (spline, Spline, 1);
+  InitSpline (spline, name, Nknots);
+  splines[N] = spline;
+  return (spline);
+}
+
+/* delete a spline */
+int DeleteSpline (Spline *spline) {
+
+  int i, N, NSPLINES_2;
+
+  /* find spline in spline list */
+  N = -1;
+  for (i = 0; i < Nsplines; i++) {
+    if (splines[i] == spline) {
+      N = i;
+      break;
+    }
+  }
+  if (N == -1) return (FALSE);
+
+  for (i = N; i < Nsplines - 1; i++) {
+    splines[i] = splines[i + 1];
+  }
+  Nsplines --;
+  NSPLINES_2 = MAX (16, NSPLINES / 2);
+  if (Nsplines < NSPLINES_2) {
+    NSPLINES = NSPLINES_2;
+    REALLOCATE (splines, Spline *, NSPLINES);
+  }
+
+  FreeSpline (spline);
+  return (TRUE);
+}
+
+/* list known books */
+void ListSplines () {
+
+  int i;
+
+  for (i = 0; i < Nsplines; i++) {
+    gprint (GP_ERR, "%-15s %3d\n", splines[i][0].name, splines[i][0].Nknots);
+  }
+  return;
+}
