Index: /trunk/psphot/src/basic_classes.c
===================================================================
--- /trunk/psphot/src/basic_classes.c	(revision 4398)
+++ /trunk/psphot/src/basic_classes.c	(revision 4398)
@@ -0,0 +1,11 @@
+# include "psphot.h"
+
+bool basic_classes (psArray *sources, psMetadata *config) {
+
+    // group into STAR, COSMIC, GALAXY, SATURATED
+    psfClump = pmSourcePSFClump (sources, config);
+    pmSourceRoughClass (sources, config, psfClump);
+
+    // make this optional
+    // DumpMoments (sources, "moments.dat");
+}
Index: /trunk/psphot/src/choose_psf_model.c
===================================================================
--- /trunk/psphot/src/choose_psf_model.c	(revision 4397)
+++ /trunk/psphot/src/choose_psf_model.c	(revision 4398)
@@ -7,5 +7,5 @@
     bool        status;
     char       *modelName;
-    char        key[64];
+    char        key[64], filename[64];
     pmPSF_Test *test  = NULL;
     psArray    *stars = NULL;
@@ -35,24 +35,6 @@
 	tests->data[i] = pmPSF_TestModel (stars, modelName, RADIUS);
 
-	// dump psf test data to file:
-	{
-	  sprintf (key, "metric.%d.dat", i);
-	  FILE *f = fopen (key, "w");
-	  test = tests->data[i];
-
-
-	  for (int j = 0; j < test->sources->n; j++) {
-	    psSource *source = test->sources->data[j];
-	    psModel  *model  = test->modelPSF->data[j];	    
-	    float sky = 0;
-
-	    if (model != NULL) sky = model->params->data.F32[0];
-
-	    fprintf (f, "%3d %6.1f %6.1f  %7.4f %7.4f  %8.4f\n", 
-		     j, source->moments->x, source->moments->y,
-		     test->metric->data.F64[j], test->fitMag->data.F64[j], sky);
-	  }
-	  fclose (f);
-	}
+	sprintf (filename, "metric.%d.dat", i);
+	DumpPSFTestData (tests->data[i], filename);
     }
 
Index: /trunk/psphot/src/output.c
===================================================================
--- /trunk/psphot/src/output.c	(revision 4398)
+++ /trunk/psphot/src/output.c	(revision 4398)
@@ -0,0 +1,159 @@
+# include "psphot.h"
+
+// output functions
+// we have several fixed modes (sx, obj, cmp)
+
+// we require a fixed number of chars already allocated
+init_line (char *line, int *Nline) {
+  *Nline = 0;
+}
+
+add_to_line (char *line, int *Nline, char *format, ...) {
+
+    va_list ap;
+
+    va_start (ap, format);
+    Nchar = vsprintf (&line[*Nline], format, ap);
+    *Nline += Nchar;
+}
+
+// dophot-style output list with fixed line width
+bool WriteSourcesOBJ (psArray *sources, char *filename) {
+
+# define NCHAR 104
+
+    char line[NCHAR];
+
+    FILE *f = fopen (filename, "w");
+    if (f == NULL) {
+	psLogMsg ("WriteSourceOBJ", 3, "can't open output file for output %s\n", filename);
+	return false;
+    }
+
+    // write sources with models first 
+    for (i = 0; i < sources->n; i++) {
+	psSource *source = (psSource *) sources->data[i];
+	model = (psModel  *) source->modelPSF;
+	if (model == NULL) continue;
+	params = model->params;
+	dparams = model->dparams;
+
+	pmSourcePhotometry (&fitMag, &apMag, model, source->pixels, source->mask);
+	dmag = dparams[0].data.F32[1] / params[0].data.F32[1];
+
+	type = GetDophotType (source);
+	init_line (line, &Nline);
+	add_to_line (line, &Nline, "%3d", type);
+	add_to_line (line, &Nline, "%8.2f", params[0].data.F32[2]);
+	add_to_line (line, &Nline, "%8.2f", params[0].data.F32[3]);
+	add_to_line (line, &Nline, "%8.3f", fitMag);
+	add_to_line (line, &Nline, "%6.3f", dmag);
+	add_to_line (line, &Nline, "%9.2f", params[0].data.F32[0]);
+	add_to_line (line, &Nline, "%9.3f", params[0].data.F32[4]);
+	add_to_line (line, &Nline, "%9.3f", params[0].data.F32[5]);
+	add_to_line (line, &Nline, "%7.2f", params[0].data.F32[6]);
+	add_to_line (line, &Nline, "%8.3f", 32.0);
+	add_to_line (line, &Nline, "%8.3f", apMag);
+	add_to_line (line, &Nline, "%8.2f", apMag - fitMag);
+    }
+    fclose (f);
+    return true;
+
+}
+
+// elixir/sextractor-style output list with fixed line width
+bool WriteSourcesSX (psArray *sources, char *filename) {
+
+# define NCHAR 104
+
+    char line[NCHAR];
+
+    FILE *f = fopen (filename, "w");
+    if (f == NULL) {
+	psLogMsg ("WriteSourceOBJ", 3, "can't open output file for output %s\n", filename);
+	return false;
+    }
+
+    // write sources with models first 
+    for (i = 0; i < sources->n; i++) {
+	psSource *source = (psSource *) sources->data[i];
+	model = (psModel  *) source->modelPSF;
+	if (model == NULL) continue;
+	params = model->params;
+	dparams = model->dparams;
+
+	pmSourcePhotometry (&fitMag, &apMag, model, source->pixels, source->mask);
+	dmag = dparams[0].data.F32[1] / params[0].data.F32[1];
+
+	// XXX EAM : fix this to match sextractor output
+	type = GetDophotType (source);
+	init_line (line, &Nline);
+	add_to_line (line, &Nline, "%3d", type);
+	add_to_line (line, &Nline, "%8.2f", params[0].data.F32[2]);
+	add_to_line (line, &Nline, "%8.2f", params[0].data.F32[3]);
+	add_to_line (line, &Nline, "%8.3f", fitMag);
+	add_to_line (line, &Nline, "%6.3f", dmag);
+	add_to_line (line, &Nline, "%9.2f", params[0].data.F32[0]);
+	add_to_line (line, &Nline, "%9.3f", params[0].data.F32[4]);
+	add_to_line (line, &Nline, "%9.3f", params[0].data.F32[5]);
+	add_to_line (line, &Nline, "%7.2f", params[0].data.F32[6]);
+	add_to_line (line, &Nline, "%8.3f", 32.0);
+	add_to_line (line, &Nline, "%8.3f", apMag);
+	add_to_line (line, &Nline, "%8.2f", apMag - fitMag);
+    }
+    fclose (f);
+    return true;
+
+}
+
+// elixir-style pseudo FITS table (header + ascii list)
+bool WriteSourcesCMP (psMetadata *header, psArray *sources, char *filename) {
+
+
+# define NCHAR 104
+
+    char line[NCHAR];
+
+    FILE *f = fopen (filename, "w");
+    if (f == NULL) {
+	psLogMsg ("WriteSourceOBJ", 3, "can't open output file for output %s\n", filename);
+	return false;
+    }
+
+    // write header to file
+
+    // write sources with models first 
+    for (i = 0; i < sources->n; i++) {
+	psSource *source = (psSource *) sources->data[i];
+	model = (psModel  *) source->modelPSF;
+	if (model == NULL) continue;
+	params = model->params;
+	dparams = model->dparams;
+
+	pmSourcePhotometry (&fitMag, &apMag, model, source->pixels, source->mask);
+	dmag = dparams[0].data.F32[1] / params[0].data.F32[1];
+
+	// XXX EAM : fix this to match sextractor output
+	type = GetDophotType (source);
+	init_line (line, &Nline);
+	add_to_line (line, &Nline, "%3d", type);
+	add_to_line (line, &Nline, "%8.2f", params[0].data.F32[2]);
+	add_to_line (line, &Nline, "%8.2f", params[0].data.F32[3]);
+	add_to_line (line, &Nline, "%8.3f", fitMag);
+	add_to_line (line, &Nline, "%6.3f", dmag);
+	add_to_line (line, &Nline, "%9.2f", params[0].data.F32[0]);
+	add_to_line (line, &Nline, "%9.3f", params[0].data.F32[4]);
+	add_to_line (line, &Nline, "%9.3f", params[0].data.F32[5]);
+	add_to_line (line, &Nline, "%7.2f", params[0].data.F32[6]);
+	add_to_line (line, &Nline, "%8.3f", 32.0);
+	add_to_line (line, &Nline, "%8.3f", apMag);
+	add_to_line (line, &Nline, "%8.2f", apMag - fitMag);
+    }
+    fclose (f);
+    return true;
+}
+
+// elixir-style FITS table output (header + table in 1st extension)
+bool WriteSourcesCMF (psArray *sources, char *filename) {
+    // ???
+}
Index: /trunk/psphot/src/psphot-utils.c
===================================================================
--- /trunk/psphot/src/psphot-utils.c	(revision 4397)
+++ /trunk/psphot/src/psphot-utils.c	(revision 4398)
@@ -52,4 +52,24 @@
     fclose (f);
     return true;
+}
+
+bool DumpPSFTestData (pmPSF_Test *test, char *filename) 
+{
+
+  FILE *f = fopen (key, "w");
+
+  for (int j = 0; j < test->sources->n; j++) {
+
+    psSource *source = test->sources->data[j];
+    psModel  *model  = test->modelPSF->data[j];	    
+
+    float sky = 0;
+    if (model != NULL) sky = model->params->data.F32[0];
+
+    fprintf (f, "%3d %6.1f %6.1f  %7.4f %7.4f  %8.4f\n", 
+	     j, source->moments->x, source->moments->y,
+	     test->metric->data.F64[j], test->fitMag->data.F64[j], sky);
+  }
+  fclose (f);
 }
 
Index: /trunk/psphot/src/psphot.c
===================================================================
--- /trunk/psphot/src/psphot.c	(revision 4397)
+++ /trunk/psphot/src/psphot.c	(revision 4398)
@@ -24,4 +24,6 @@
     // construct sources and measure basic stats
     sources = source_moments (imdata, config, peaks);
+
+    basic_classes (sources, config);
 
     // source analysis is done in S/N order (brightest first)
Index: /trunk/psphot/src/source_moments.c
===================================================================
--- /trunk/psphot/src/source_moments.c	(revision 4397)
+++ /trunk/psphot/src/source_moments.c	(revision 4398)
@@ -35,11 +35,4 @@
     }
 
-    // group into STAR, COSMIC, GALAXY, SATURATED
-    psfClump = pmSourcePSFClump (sources, config);
-    pmSourceRoughClass (sources, config, psfClump);
-
-    // make this optional
-    // DumpMoments (sources, "moments.dat");
-
     psLogMsg ("psphot", 3, "moments: %f sec\n", psTimerMark ("psphot"));
     psLogMsg ("psphot", 3, "%d sources\n", sources->n);
