Index: trunk/Ohana/src/dvosplit/src/dvosplit.c
===================================================================
--- trunk/Ohana/src/dvosplit/src/dvosplit.c	(revision 15721)
+++ trunk/Ohana/src/dvosplit/src/dvosplit.c	(revision 15721)
@@ -0,0 +1,130 @@
+# include "dvosplit.h"
+# define NROWS 100000 /* ~10MB per row for measures */
+
+int main (int argc, char **argv) {
+
+  // USAGE: dvosplit (outlevel) [-catalog (name)] [-region RA RA DEC DEC]
+
+  // the output catalog needs to inherit the SKY_DEPTH of the input catalog. 
+  // if the CATDIR/SkyTable.fits is not found, assume the HST layout (old default)
+  sky = SkyTableLoadOptimal (CATDIR, NULL, NULL, SKY_DEPTH_HST, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+  skylist = SkyListByPatch (sky, -1, &REGION);
+  
+  for (i = 0; i < skylist[0].Nregions; i++) {
+    fprintf (stderr, "%s\n", skylist[0].regions[i][0].name);
+
+    // if (current level >  out level) skip: cannot currently merge catalogs
+    // if (current level == out level) skip: no action is needed
+
+    // set the parameters which guide catalog open/load/create
+    incatalog.filename = skylist[0].filename[i];
+    incatalog.Nsecfilt = GetPhotcodeNsecfilt ();
+    incatalog.catflags = LOAD_NONE;
+
+    // XXX how do I open and not read the entire catalog?
+
+    // an error exit status here is a significant error
+    if (!dvo_catalog_open (&incatalog, skylist[0].regions[i], VERBOSE, "rp")) {
+      fprintf (stderr, "ERROR: failure to open catalog file %s\n", incatalog.filename);
+      exit (2);
+    }
+
+    // skip empty input catalogs
+    if (!incatalog.Nave_disk) {
+      dvo_catalog_unlock (&incatalog);
+      dvo_catalog_free (&incatalog);
+      continue;
+    }
+
+    outcatalog = SkyTableSubdivide (&incatalog, &Noutcatalog);
+
+    // split out the average entries:
+    incatalog.catflags = LOAD_AVES;
+    Nblocks = incatalog.Nave_disk / NROWS;
+    for (j = 0; j < Nblocks; j++) {
+
+      // read up to NROWS at a time
+      dvo_catalog_load_segment (&incatalog, VERBOSE, j*NROWS, NROWS);
+
+      for (k = 0; k < incatalog.Naverage; k++) {
+	averef = j*NROWS + k;
+	
+	inR  = incatalog.average[k].R;
+	inD = incatalog.average[k].D;
+
+	// which of the outcatalogs contains this coordinate?
+
+	N = -1;
+	for (n = 0; n < Noutcatalog; n++) {
+	  if (inR < outregions[n].Rmin) continue;
+	  if (inR > outregions[n].Rmax) continue;
+	  if (inD < outregions[n].Dmin) continue;
+	  if (inD > outregions[n].Dmax) continue;
+	  Ncat = n;
+	  break;
+	}
+	if (Ncat == -1) continue;
+
+	// XXX this probably needs to be Nave_disk so we can have partial saves
+	Nout = outcatalog[Ncat].Naverage;
+	outref[averef] = Nout;
+	outcat[averef] = Ncat;
+
+	outcatalog[Ncat].average[Nout] = incatalog.average[k];
+	outcatalog[Ncat].Naverage++;
+      }
+
+      for (n = 0; n < Noutcatalog; n++) {
+	dvo_catalog_save_segment (&outcatalog[Ncat], VERBOSE, outcatalog[Ncat].Nave_disk, outcatalog[Ncat].Naverage);
+      }
+    }
+
+    // split out the measure entries:
+    incatalog.catflags = LOAD_MEAS;
+    Nblocks = incatalog.Nmeas_disk / NROWS;
+    for (j = 0; j < Nblocks; j++) {
+
+      // read up to NROWS at a time
+      dvo_catalog_load_segment (&incatalog, VERBOSE, j*NROWS, NROWS);
+
+      for (k = 0; k < incatalog.Nmeasure; k++) {
+
+	averef = incatalog.measure[k].averef;
+	Ncat = outcat[averef];
+
+	Nout = outcatalog[Ncat].Nmeasure;
+	outcatalog[Ncat].measure[Nout] = incatalog.measure[k];
+	outcatalog[Ncat].measure[Nout].averef = outref[averef];
+	outcatalog[Ncat].Nmeasure++;
+      }
+
+      for (n = 0; n < Noutcatalog; n++) {
+	dvo_catalog_save_segment (&outcatalog[N], VERBOSE, outcatalog[N].Nmeas_disk, outcatalog[N].Nmeasure);
+      }
+    }
+
+    // split out the secfilt entries:
+    incatalog.catflags = LOAD_SECF;
+    Nblocks = incatalog.Nsecfilt_disk / NROWS;
+    for (j = 0; j < Nblocks; j++) {
+
+      // read up to NROWS at a time
+      dvo_catalog_load_segment (&incatalog, VERBOSE, j*NROWS, NROWS);
+
+      for (k = 0; k < incatalog.Naverage; k++) {
+
+	averef = j*NROWS + k;
+	Ncat = outcat[averef];
+	Nout = outref[averef] * Nsecfilt;
+
+	for (n = 0; n < Nsecfilt; n++) {
+	  outcatalog[Ncat].secfilt[Nout + n] = incatalog.measure[k*Nsecfilt + n];
+	}
+      }
+
+      for (n = 0; n < Noutcatalog; n++) {
+	dvo_catalog_save_segment (&outcatalog[N], VERBOSE, outcatalog[N].Nmeas_disk, outcatalog[N].Nmeasure);
+      }
+    }
+
