Index: trunk/psphot/src/psModulesUtils.c
===================================================================
--- trunk/psphot/src/psModulesUtils.c	(revision 4954)
+++ trunk/psphot/src/psModulesUtils.c	(revision 4977)
@@ -1,3 +1,50 @@
-# include "psphot.h"
+# include "psModulesUtils.h"
+
+// extract config informatin from config data or from image header, if specified
+psF32 pmConfigLookupF32 (bool *status, psMetadata *config, psMetadata *header, char *name) {
+
+    char *source;
+    char *keyword;
+    psF32 value;
+    psMetadataItem *item;
+
+    // look for the entry in the config collection
+    item = psMetadataLookup (config, name);
+    if (item == NULL) {
+	psLogMsg ("pmConfigLookupF32", 2, "no key %s in config data, trying as header keyword", name);
+	value = psMetadataLookupF32 (status, header, name);
+	if (*status == false) {
+	    psAbort ("pmConfigLookupF32", "no key %s in header", name);
+	}
+	*status = true;
+	return (value);
+    }	
+
+    // I'm either expecting a string, with the name "HD:keyword"...
+    if (item->type == PS_META_STR) {
+	source = item->data.V;
+	if (!strncasecmp (source, "HD:", 3)) {
+	    keyword = &source[3]; 
+	    value = psMetadataLookupF32 (status, header, keyword);
+	    if (*status == false) {
+		psAbort ("pmConfigLookupF32", "no key %s in config", name);
+	    }
+	    *status = true;
+	    // psFree (item);
+	    return (value);
+	}	
+    }
+
+    //  ... or a value (F32?)
+    if (item->type == PS_META_F32) {
+	value = item->data.F32;
+	// psFree (item);
+	return (value);
+    }
+
+    *status = false;
+    psError(PS_ERR_UNKNOWN, true, "invalid item");
+    return (0);
+}
 
 // XXX EAM : these are my alternate implementations of psModule functions
@@ -321,2 +368,26 @@
     return (status);
 }
+
+bool pmSourcePhotometry (float *fitMag, float *obsMag, pmModel *model, psImage *image, psImage *mask) {
+
+    float obsSum = 0;
+    float fitSum = 0;
+    float sky = model->params->data.F32[0];
+
+    pmModelFlux modelFluxFunc = pmModelFlux_GetFunction (model->type);
+    fitSum = modelFluxFunc (model->params);
+
+    for (int ix = 0; ix < image->numCols; ix++) {
+	for (int iy = 0; iy < image->numRows; iy++) {
+	    if (mask->data.U8[iy][ix]) continue;
+	    obsSum += image->data.F32[iy][ix] - sky;
+	}
+    }
+    if (obsSum <= 0) return false;
+    if (fitSum <= 0) return false;
+
+    *fitMag = -2.5*log10(fitSum);
+    *obsMag = -2.5*log10(obsSum);
+    return (true);
+} 
+
