Index: /branches/eam_branches/ipp-20110710/psphot/src/psphot.h
===================================================================
--- /branches/eam_branches/ipp-20110710/psphot/src/psphot.h	(revision 32298)
+++ /branches/eam_branches/ipp-20110710/psphot/src/psphot.h	(revision 32299)
@@ -487,4 +487,5 @@
 bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule);
 bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf);
+bool psphotKronIterate_Threaded (psThreadJob *job);
 
 #endif
Index: /branches/eam_branches/ipp-20110710/psphot/src/psphotKronIterate.c
===================================================================
--- /branches/eam_branches/ipp-20110710/psphot/src/psphotKronIterate.c	(revision 32298)
+++ /branches/eam_branches/ipp-20110710/psphot/src/psphotKronIterate.c	(revision 32299)
@@ -94,9 +94,4 @@
     // maskVal is used to test for rejected pixels, and must include markVal
     maskVal |= markVal;
-
-    // psphotSaveImage (NULL, readout->mask, "kron.unmasked.fits");
-
-    // XXX tmp visualization
-    // int kapa = psphotKapaChannel (1);
 
     // source analysis is done in S/N order (brightest first)
@@ -123,7 +118,78 @@
 	psphotKronWindowSetSource (source, kronWindow, false, true);
     }
-    // psphotVisualRangeImage (kapa, kronWindow, "kronwin", 0, 0.0, 1.0);
-
-    // psphotSaveImage (NULL, kronWindow, "kron.window.v0.fits");
+
+    // threaded measurement of the source magnitudes
+    // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts)
+    int Cx = 1, Cy = 1;
+    psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);
+
+    psArray *cellGroups = psphotAssignSources (Cx, Cy, sources);
+
+    for (int i = 0; i < cellGroups->n; i++) {
+
+        psArray *cells = cellGroups->data[i];
+
+        for (int j = 0; j < cells->n; j++) {
+
+            // allocate a job -- if threads are not defined, this just runs the job
+            psThreadJob *job = psThreadJobAlloc ("PSPHOT_KRON_ITERATE");
+
+            psArrayAdd(job->args, 1, readout);
+            psArrayAdd(job->args, 1, kronWindow);
+            psArrayAdd(job->args, 1, cells->data[j]); // sources
+            PS_ARRAY_ADD_SCALAR(job->args, markVal,            PS_TYPE_IMAGE_MASK);
+            PS_ARRAY_ADD_SCALAR(job->args, maskVal,            PS_TYPE_IMAGE_MASK);
+            PS_ARRAY_ADD_SCALAR(job->args, RADIUS,             PS_TYPE_F32);
+            PS_ARRAY_ADD_SCALAR(job->args, MIN_KRON_RADIUS,    PS_TYPE_F32);
+            PS_ARRAY_ADD_SCALAR(job->args, EXT_FIT_MAX_RADIUS, PS_TYPE_F32);
+
+// set this to 0 to run without threading
+# if (1)
+            if (!psThreadJobAddPending(job)) {
+                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+                return false;
+            }
+# else
+	    if (!psphotExtendedSourceFits_Threaded(job)) {
+		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+		psFree(AnalysisRegion);
+		return false;
+	    }
+	    psFree(job);
+# endif
+        }
+
+        // wait for the threads to finish and manage results
+        if (!psThreadPoolWait (false)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+            return false;
+        }
+
+        // we have only supplied one type of job, so we can assume the types here
+        psThreadJob *job = NULL;
+        while ((job = psThreadJobGetDone()) != NULL) {
+            if (job->args->n < 1) {
+                fprintf (stderr, "error with job\n");
+            }
+            psFree(job);
+        }
+    }
+    psFree (cellGroups);
+    psFree (kronWindow);
+
+    psLogMsg ("psphot.kron", PS_LOG_WARN, "measure masked kron magnitudes : %f sec for %ld objects\n", psTimerMark ("psphot.kron"), sources->n);
+    return true;
+}
+
+bool psphotKronIterate_Threaded (psThreadJob *job) {
+
+    pmReadout *readout              = job->args->data[0];
+    psImage *kronWindow             = job->args->data[1];
+    psArray *sources                = job->args->data[2];
+    psImageMaskType markVal         = PS_SCALAR_VALUE(job->args->data[3],PS_TYPE_IMAGE_MASK_DATA);
+    psImageMaskType maskVal         = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA);
+    float RADIUS                    = PS_SCALAR_VALUE(job->args->data[5],F32);
+    float MIN_KRON_RADIUS           = PS_SCALAR_VALUE(job->args->data[6],F32);
+    float EXT_FIT_MAX_RADIUS        = PS_SCALAR_VALUE(job->args->data[7],F32);
 
     for (int j = 0; j < 5; j++) {
@@ -151,5 +217,4 @@
 	    // clear the window function for this source based on the moments
 	    psphotKronWindowSetSource (source, kronWindow, (j > 0), false);
-	    // psphotVisualRangeImage (kapa, kronWindow, "kronwin", 1, 0.0, 1.0);
 
 	    // this function populates moments->Mrf,KronFlux,KronFluxErr
@@ -165,12 +230,5 @@
 	    }
 	}
-	// char name[64];
-	// sprintf (name, "kron.window.v%d.fits", j+1);
-	// psphotSaveImage (NULL, kronWindow, name);
-    }
-    psFree (kronWindow);
-
-    psLogMsg ("psphot.kron", PS_LOG_WARN, "measure masked kron magnitudes : %f sec for %ld objects\n", psTimerMark ("psphot.kron"), sources->n);
-
+    }
     return true;
 }
Index: /branches/eam_branches/ipp-20110710/psphot/src/psphotSetThreads.c
===================================================================
--- /branches/eam_branches/ipp-20110710/psphot/src/psphotSetThreads.c	(revision 32298)
+++ /branches/eam_branches/ipp-20110710/psphot/src/psphotSetThreads.c	(revision 32299)
@@ -30,4 +30,9 @@
     psFree(task);
 
+    task = psThreadTaskAlloc("PSPHOT_KRON_ITERATE", 8);
+    task->function = &psphotKronIterate_Threaded;
+    psThreadTaskAdd(task);
+    psFree(task);
+
     task = psThreadTaskAlloc("PSPHOT_BLEND_FIT", 10);
     task->function = &psphotBlendFit_Threaded;
