Index: branches/tap_branches/psastro/src/psastroRemoveClumps.c
===================================================================
--- branches/tap_branches/psastro/src/psastroRemoveClumps.c	(revision 25900)
+++ branches/tap_branches/psastro/src/psastroRemoveClumps.c	(revision 27838)
@@ -13,8 +13,81 @@
 # include "psastroInternal.h"
 
+bool psastroRemoveClumpsRawstars (pmConfig *config) {
+
+    bool status;
+
+    pmChip *chip = NULL;
+    pmCell *cell = NULL;
+    pmReadout *readout = NULL;
+
+    // select the current recipe
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSASTRO_RECIPE);
+    if (!recipe) {
+        psError(PSASTRO_ERR_CONFIG, true, "Can't find PSASTRO recipe");
+        return false;
+    }
+
+    // select the input data sources
+    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PSASTRO.INPUT");
+    if (!input) {
+        psError(PSASTRO_ERR_CONFIG, true, "Can't find input data");
+        return false;
+    }
+
+    pmFPAview *view = pmFPAviewAlloc (0);
+    pmFPA *fpa = input->fpa;
+
+    while ((chip = pmFPAviewNextChip (view, fpa, 1)) != NULL) {
+        psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+        if (!chip->process || !chip->file_exists) { continue; }
+
+        while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {
+            psTrace ("psastro", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+            if (!cell->process || !cell->file_exists) { continue; }
+            if (!chip->fromFPA) { continue; }
+
+            // process each of the readouts
+            while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) {
+                if (! readout->data_exists) { continue; }
+
+                // select the raw objects for this readout
+                psArray *rawstars = psMetadataLookupPtr (&status, readout->analysis, "PSASTRO.RAWSTARS");
+                if (rawstars == NULL) { continue; }
+
+		// generate a reduced subset excluding the clumps
+		// XXX do we need both RAWSTARS and SUBSET? 
+		// XXX put these parameters in the recipe, please
+		psArray *subset = psastroRemoveClumpsIterate(rawstars, 150, 3);
+		psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSASTRO.RAWSTARS.SUBSET", PS_DATA_ARRAY, "astrometry objects", subset);
+		psFree (subset);
+	    }
+	}
+    }
+    psFree (view);
+    return true;
+}
+
+psArray *psastroRemoveClumpsIterate (psArray *input, int scale, int nIter) {
+
+    psArray *newset = psMemIncrRefCounter (input);
+    for (int i = 0; i < nIter; i++) {
+	psArray *subset = psastroRemoveClumps (newset, 150);
+	psFree (newset);
+	newset = subset;
+    }
+    return newset;
+}    
+
 /**
  * look for and exclude objects in clumps in the input list
  */
 psArray *psastroRemoveClumps (psArray *input, int scale) {
+
+    if (!input) return NULL;
+
+    if (!input->n) {
+	psArray *output = psArrayAllocEmpty (16);
+	return output;
+    }
 
     // determine data range
