Index: /trunk/Ohana/src/delstar/src/delete_imagename.c
===================================================================
--- /trunk/Ohana/src/delstar/src/delete_imagename.c	(revision 17244)
+++ /trunk/Ohana/src/delstar/src/delete_imagename.c	(revision 17245)
@@ -57,5 +57,5 @@
       find_matches (&catalog, image[j].photcode, start, stop);
 
-      dvo_catalog_save (&catalog, VERBOSE);
+      dvo_catalog_save_complete (&catalog, VERBOSE);
       dvo_catalog_unlock (&catalog);
       dvo_catalog_free (&catalog);
Index: /trunk/Ohana/src/libdvo/include/dvo.h
===================================================================
--- /trunk/Ohana/src/libdvo/include/dvo.h	(revision 17244)
+++ /trunk/Ohana/src/libdvo/include/dvo.h	(revision 17245)
@@ -360,4 +360,5 @@
 int dvo_catalog_open (Catalog *catalog, SkyRegion *region, int VERBOSE, char *iomode);
 int dvo_catalog_save (Catalog *catalog, char VERBOSE);
+int dvo_catalog_save_complete (Catalog *catalog, char VERBOSE);
 int dvo_catalog_update (Catalog *catalog, char VERBOSE);
 int dvo_catalog_catformat (char *catformat);
@@ -373,4 +374,5 @@
 int dvo_catalog_save_split (Catalog *catalog, char VERBOSE);
 int dvo_catalog_update_split (Catalog *catalog, char VERBOSE);
+int dvo_catalog_save_split_complete (Catalog *catalog, char VERBOSE);
 
 int dvo_catalog_load_segment (Catalog *catalog, int VERBOSE, int start, int Nrows);
Index: /trunk/Ohana/src/libdvo/src/dvo_catalog.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 17244)
+++ /trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 17245)
@@ -274,5 +274,5 @@
 
 // write out the data, unlink if empty?  'save' means: write out all data currently in
-// memory.  NOTE: this is currently not always possible: for non-SPLIT moe files, this
+// memory.  NOTE: this is currently not always possible: for non-SPLIT mode files, this
 // operation may require expanding the file size, which does not automatically happen
 int dvo_catalog_save (Catalog *catalog, char VERBOSE) {
@@ -291,4 +291,29 @@
     case DVO_MODE_SPLIT:
       dvo_catalog_save_split (catalog, VERBOSE);
+      break;
+    default:
+      fprintf (stderr, "invalid catalog mode\n");
+      exit (2);
+  }
+  return (TRUE);
+}
+
+// write out the data, assuming the in-memory data represents all data for the table.
+// NOTE: This operation may truncate the file and delete entries.
+int dvo_catalog_save_complete (Catalog *catalog, char VERBOSE) {
+
+  // set the 'sorted' header keyword
+  gfits_modify (&catalog[0].header, "SORTED",  "%t", 1, catalog[0].sorted);
+
+  // XXX handle return status
+  switch (catalog[0].catmode) {
+    case DVO_MODE_RAW:
+      dvo_catalog_save_raw (catalog, VERBOSE);
+      break;
+    case DVO_MODE_MEF:
+      dvo_catalog_save_mef (catalog, VERBOSE);
+      break;
+    case DVO_MODE_SPLIT:
+      dvo_catalog_save_split_complete (catalog, VERBOSE);
       break;
     default:
Index: /trunk/Ohana/src/libdvo/src/dvo_catalog_split.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_catalog_split.c	(revision 17244)
+++ /trunk/Ohana/src/libdvo/src/dvo_catalog_split.c	(revision 17245)
@@ -646,4 +646,204 @@
 }
 
+/* save_catalog_split writes all data currently in memory to disk, truncating if the disk file was larger */
+int dvo_catalog_save_split_complete (Catalog *catalog, char VERBOSE) {
+
+  int Nitems;
+  Header header;
+  FTable ftable;
+  SecFilt *primary, *secfilt;
+  int Nsecfilt;
+  int Naves_disk_new, Nmeas_disk_new, Nmiss_disk_new, Nsecf_disk_new;
+  int first, start, Nrows;
+
+  ftable.header = &header;
+  ftable.buffer = NULL;
+  header.buffer = NULL;
+  primary = NULL;
+  
+  // skip empty catalogs: it is illegal to have Measures without corresponding Averages
+  if (catalog[0].Naves_off > 0) {
+    fprintf (stderr, "ERROR: only partial catalog (Average) was loaded\n");
+    goto failure;
+  }
+  if (catalog[0].Nmeas_off > 0) {
+    fprintf (stderr, "ERROR: only partial catalog (Measure) was loaded\n");
+    goto failure;
+  }
+  if (catalog[0].Nmiss_off > 0) {
+    fprintf (stderr, "ERROR: only partial catalog (Missing) was loaded\n");
+    goto failure;
+  }
+  if (catalog[0].Nsecf_off > 0) {
+    fprintf (stderr, "ERROR: only partial catalog (Secfilt) was loaded\n");
+    goto failure;
+  }
+
+  if ((catalog[0].Naverage > 0) && (Naves_disk_new == 0)) {
+    Naves_disk_new = catalog[0].Naverage;
+    if (VERBOSE) fprintf (stderr, "resulting catalog is empty; delete it\n");
+    // unlink ();
+    return (TRUE);
+  }
+
+  Naves_disk_new = catalog[0].Naverage;
+
+  // for the appropriate types, pull out the first secfilt and pass to AverageToFtable as primary
+  switch (catalog[0].catformat) {
+    case DVO_FORMAT_ELIXIR: // special case for ELIXIR
+    case DVO_FORMAT_LONEOS: // special case for LONEOS
+      dvo_catalog_secfilt_to_primary (catalog, &primary, &secfilt, &Nsecfilt);
+      break;
+    default:
+      primary = NULL;
+      secfilt = catalog[0].secfilt;
+      Nsecfilt = catalog[0].Nsecfilt;
+      break;
+  }
+
+  Nmeas_disk_new = catalog[0].Nmeasure;
+  Nmiss_disk_new = catalog[0].Nmissing;
+  Nsecf_disk_new = catalog[0].Naverage*Nsecfilt;
+
+  /* make sure header is consistent with data */
+  gfits_modify (&catalog[0].header, "NSTARS",   "%d", 1, Naves_disk_new);
+  gfits_modify (&catalog[0].header, "NMEAS",    "%d", 1, Nmeas_disk_new);
+  gfits_modify (&catalog[0].header, "NMISS",    "%d", 1, Nmiss_disk_new);
+  gfits_modify (&catalog[0].header, "NSECFILT", "%d", 1, Nsecfilt);
+  gfits_modify (&catalog[0].header, "EXTEND",   "%t", 1, TRUE);
+
+  /* in split mode, we can save only part of the data */ 
+
+  /*** Average Table ***/
+  if ((catalog[0].catflags & LOAD_AVES) && (catalog[0].average != NULL)) {
+
+    first  = 0;                    // first row in memory to write
+    start  = catalog[0].Naves_off; // first disk row to write
+    Nrows  = catalog[0].Naverage - first;
+
+    assert (Nrows >= 0);
+    assert (first >= 0);
+    assert (first <= catalog[0].Naverage);
+    assert (catalog[0].Naves_disk >= catalog[0].Naves_off);
+
+    /* convert internal to external format */
+    if (!AverageToFtable (&ftable, &catalog[0].average[first], Nrows, catalog[0].catformat, primary)) {
+      fprintf (stderr, "trouble converting format\n");
+      goto failure;
+    }
+
+    if (!dvo_catalog_save_subcat (catalog, &ftable, start, Nrows, catalog[0].Naves_disk, Naves_disk_new)) {
+      fprintf (stderr, "failure writing Average table\n");
+      goto failure;
+    }
+    gfits_free_header (&header);
+    gfits_free_table (&ftable);
+  } else {
+    // even if we do not save the average table, we need to keep the header in sync
+    /* rewind file pointers and truncate (file is still open) */
+    fseek (catalog[0].f, 0, SEEK_SET);
+
+    /* write table PHU header - always write this out */
+    /* XXX EAM : check if disk file size has changed */
+    if (!gfits_fwrite_header  (catalog[0].f, &catalog[0].header)) {
+      fprintf (stderr, "can't write primary header");
+      goto failure;
+    }
+  }
+
+  /*** Measure Table ***/
+  if ((catalog[0].catflags & LOAD_MEAS) && (catalog[0].measure != NULL)) {
+
+    first  = 0;                    // first row in memory to write
+    start  = catalog[0].Nmeas_off; // first disk row to write
+    Nrows  = catalog[0].Nmeasure - first;
+
+    assert (Nrows >= 0);
+    assert (first >= 0);
+    assert (first <= catalog[0].Nmeasure);
+    assert (catalog[0].Nmeas_disk >= catalog[0].Nmeas_off);
+
+    // convert to external table format
+    if (!MeasureToFtable (&ftable, &catalog[0].measure[first], Nrows, catalog[0].catformat)) {
+      fprintf (stderr, "trouble converting format\n");
+      goto failure;
+    }
+
+    // write out Measure table
+    if (!dvo_catalog_save_subcat (catalog[0].measure_catalog, &ftable, start, Nrows, catalog[0].Nmeas_disk, Nmeas_disk_new)) {
+      fprintf (stderr, "trouble writing Measure table\n");
+      goto failure;
+    }
+    gfits_free_header (&header);
+    gfits_free_table (&ftable);
+  }
+
+  /*** Missing Table ***/
+  if ((catalog[0].catflags & LOAD_MISS) && (catalog[0].missing != NULL)) {
+
+    if (catalog[0].Nmiss_off != 0) {
+      fprintf (stderr, "inconsistency: Missing table cannot be written in segments\n");
+      goto failure;
+    }
+
+    // convert to external table format
+    if (!gfits_table_set_Missing (&ftable, catalog[0].missing, catalog[0].Nmissing)) {
+      fprintf (stderr, "trouble converting format\n");
+      goto failure;
+    }
+
+    // write out Missing table (must write out entire table)
+    if (!dvo_catalog_save_subcat (catalog[0].missing_catalog, &ftable, 0, catalog[0].Nmissing, catalog[0].Nmissing, catalog[0].Nmissing)) {
+      fprintf (stderr, "trouble writing Missing Table\n");
+      goto failure;
+    }
+    gfits_free_header (&header);
+    gfits_free_table (&ftable);
+  }
+
+  /*** Secfilt Table ***/
+  if ((catalog[0].catflags & LOAD_SECF) && (catalog[0].secfilt != NULL)) {
+
+    first  = 0;                    // first row in memory to write
+    start  = catalog[0].Nsecf_off; // first disk row to write
+    Nitems = catalog[0].Nsecf_mem;
+    Nrows  = Nitems - first;
+
+    assert (Nrows >= 0);
+    assert (first >= 0);
+    assert (first <= Nitems);
+    assert (catalog[0].Nsecf_disk >= catalog[0].Nsecf_off);
+    // XXX check these for consistency...
+
+    // convert to external table format
+    SecFiltToFtable (&ftable, &secfilt[first], Nrows, catalog[0].catformat);
+
+    // write out SecFilt table
+    if (!dvo_catalog_save_subcat (catalog[0].secfilt_catalog, &ftable, start, Nrows, catalog[0].Nsecf_disk, Nsecf_disk_new)) {
+      fprintf (stderr, "failure writing SecFilt table\n");
+      goto failure;
+    }
+    gfits_free_header (&header);
+    gfits_free_table (&ftable);
+  }
+
+  /* free temp storage */
+  if (primary != NULL) {
+    free (primary);
+    free (secfilt);
+  }
+  return (TRUE);
+
+failure:
+  /* free temp storage */
+  gfits_free_header (&header);
+  gfits_free_table (&ftable);
+  if (primary != NULL) {
+    free (primary);
+    free (secfilt);
+  }
+  return (FALSE);
+}
+
 /* update_catalog_split only writes new lines to file. */
 int dvo_catalog_update_split (Catalog *catalog, char VERBOSE) {
