Index: trunk/psModules/src/objects/pmSourcePhotometry.c
===================================================================
--- trunk/psModules/src/objects/pmSourcePhotometry.c	(revision 10031)
+++ trunk/psModules/src/objects/pmSourcePhotometry.c	(revision 10050)
@@ -3,6 +3,6 @@
  *  @author EAM, IfA; GLG, MHPCC
  *
- *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-11-17 02:39:34 $
+ *  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-11-17 23:02:18 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -76,24 +76,8 @@
     source->apMag  = NAN;
 
-    // XXX these tests prevent aperture photometry without valid model.  is
-    // this reasonable?  probably not...
-    switch (source->type) {
-    case PM_SOURCE_TYPE_STAR:
-        model = source->modelPSF;
-        if (model == NULL)
-            return false;
-        isPSF = true;
-        break;
-
-    case PM_SOURCE_TYPE_EXTENDED:
-        model = source->modelEXT;
-        if (model == NULL)
-            return false;
-        isPSF = false;
-        break;
-
-    default:
-        return false;
-    }
+    // we must have a valid model
+    model = pmSourceGetModel (&isPSF, source);
+    if (model == NULL)
+        return false;
 
     if (model->dparams->data.F32[PM_PAR_I0] > 0) {
@@ -278,10 +262,13 @@
     }
 
+    psF32 **imData = image->data.F32;
+    psU8 **mkData = mask->data.U8;
+
     // measure apMag
     for (int ix = 0; ix < image->numCols; ix++) {
         for (int iy = 0; iy < image->numRows; iy++) {
-            if (mask->data.U8[iy][ix])
-                continue;
-            apSum += image->data.F32[iy][ix] - sky;
+            if (mkData[iy][ix])
+                continue;
+            apSum += imData[iy][ix] - sky;
         }
     }
@@ -487,4 +474,53 @@
 }
 
+double pmSourceWeight(const pmSource *Mi,
+                      int term,
+                      const bool unweighted_sum) // should the cross product be weighted?
+{
+
+    int xi, yi;
+    double flux, wt, factor;
+
+    const psImage *Pi = Mi->pixels;
+    const psImage *Wi = Mi->weight;
+    const psImage *Ti = Mi->mask;
+
+    // note that this is addressing the same image pixels,
+    // though only if both are source not model images
+    flux = 0;
+    for (yi = 0; yi < Pi->numRows; yi++) {
+        for (xi = 0; xi < Pi->numCols; xi++) {
+            if (Ti->data.U8[yi][xi])
+                continue;
+            if (!unweighted_sum) {
+                wt = Wi->data.F32[yi][xi];
+                if (wt == 0)
+                    continue;
+            }
+
+            switch (term) {
+            case 0:
+                factor = 1;
+                break;
+            case 1:
+                factor = xi + Pi->col0;
+                break;
+            case 2:
+                factor = yi + Pi->row0;
+                break;
+            default:
+                psAbort ("models/objects", "invalid term for pmSourceWeight");
+            }
+
+            if (unweighted_sum) {
+                flux += (factor * Pi->data.F32[yi][xi]);
+            } else {
+                flux += (factor * Pi->data.F32[yi][xi]) / wt;
+            }
+        }
+    }
+    return flux;
+}
+
 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight)
 {
@@ -507,2 +543,44 @@
     return (true);
 }
+
+// given a source, which model is currently appropriate?
+// choose PSF or EXT based on source->type, but fall back on PSF
+// if the EXT model is NULL
+pmModel *pmSourceGetModel (bool *isPSF, const pmSource *source)
+{
+
+    pmModel *model;
+
+    switch (source->type) {
+    case PM_SOURCE_TYPE_STAR:
+        model = source->modelPSF;
+        if (model == NULL)
+            return NULL;
+        if (isPSF)
+            *isPSF = true;
+        return model;
+
+    case PM_SOURCE_TYPE_EXTENDED:
+        model = source->modelEXT;
+        if (isPSF)
+            *isPSF = false;
+        if (model == NULL) {
+            model = source->modelPSF;
+            if (isPSF)
+                *isPSF = true;
+        }
+        if (model == NULL) {
+            if (isPSF)
+                *isPSF = FALSE;
+            return NULL;
+        }
+        return (model);
+        break;
+
+    default:
+        if (isPSF)
+            *isPSF = false;
+        return NULL;
+    }
+    return NULL;
+}
