Index: trunk/psphot/src/psphotApResid.c
===================================================================
--- trunk/psphot/src/psphotApResid.c	(revision 9734)
+++ trunk/psphot/src/psphotApResid.c	(revision 9771)
@@ -1,3 +1,5 @@
 # include "psphot.h"
+// XXXX this code fails if there are too few sources to measure the aperture residual
+// the larger problem is that the rules for accepting more polynomial terms are weak.
 
 static pmPSFApTrendOptions DEFAULT_OPTION = PM_PSF_APTREND_SKYBIAS;
@@ -12,4 +14,10 @@
     pmModel *model;
     pmSource *source;
+
+    PS_ASSERT_PTR_NON_NULL(psf, false);
+    PS_ASSERT_PTR_NON_NULL(psf->ApTrend, false);
+    PS_ASSERT_PTR_NON_NULL(readout, false);
+    PS_ASSERT_PTR_NON_NULL(sources, false);
+    PS_ASSERT_PTR_NON_NULL(recipe, false);
 
     psTimerStart ("psphot");
@@ -115,170 +123,151 @@
         break;
       case PM_PSF_APTREND_CONSTANT:
-        stats->clipIter = 2;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
-        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
-            return false;
-        }
-        // apply the fit
-        stats->clipIter = 3;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "Fitting aperture correction");
-            return false;
-        }
-        break;
+	stats->clipIter = 2;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
+	if (!psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
+	    return false;
+	}
+	// apply the fit
+	stats->clipIter = 3;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "Fitting aperture correction");
+	    return false;
+	}
+	break;
       case PM_PSF_APTREND_SKYBIAS:
-        // first clip out objects which are too far from the median
-        stats->clipIter = 2;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
-        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
-            return false;
-        }
-        // apply the fit
-        stats->clipIter = 3;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYBIAS);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting sky bias");
-            return false;
-        }
-        break;
+	// first clip out objects which are too far from the median 
+	stats->clipIter = 2;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
+	if (!psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
+	    return false;
+	}
+	// apply the fit
+	stats->clipIter = 3;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYBIAS);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting sky bias");
+	    return false;
+	}
+	break;
       case PM_PSF_APTREND_SKYSAT:
-        // first clip out objects which are too far from the median
-        stats->clipIter = 2;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
-        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
-            return false;
-        }
-        // apply the fit
-        stats->clipIter = 2;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYBIAS);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting sky bias");
-            return false;
-        }
-        // apply the fit
-        stats->clipIter = 3;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYSAT);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting skysat");
-            return false;
-        }
-        break;
+	// first clip out objects which are too far from the median 
+	stats->clipIter = 2;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
+	if (!psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
+	    return false;
+	}
+	// apply the fit
+	stats->clipIter = 2;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYBIAS);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting sky bias");
+	    return false;
+	}
+	// apply the fit
+	stats->clipIter = 3;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYSAT);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting skysat");
+	    return false;
+	}
+	break;
       case PM_PSF_APTREND_XY_LIN:
-        // first clip out objects which are too far from the median
-        stats->clipIter = 2;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
-        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
-            return false;
-        }
-        // apply the fit
-        stats->clipIter = 3;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_XY_LIN);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "fitting, XY_LIN");
-            return false;
-        }
-        break;
+	// first clip out objects which are too far from the median 
+	stats->clipIter = 2;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
+	if (!psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
+	    return false;
+	}
+	// apply the fit
+	stats->clipIter = 3;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_XY_LIN);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "fitting, XY_LIN");
+	    return false;
+	}
+	break;
       case PM_PSF_APTREND_XY_QUAD:
-        // first clip out objects which are too far from the median
-        stats->clipIter = 2;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
-        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
-            return false;
-        }
-        // apply the fit
-        stats->clipIter = 3;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_XY_QUAD);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "Fitting XY_QUAD");
-            return false;
-        }
-        break;
+	// first clip out objects which are too far from the median 
+	stats->clipIter = 2;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
+	if (!psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
+	    return false;
+	}
+	// apply the fit
+	stats->clipIter = 3;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_XY_QUAD);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "Fitting XY_QUAD");
+	    return false;
+	}
+	break;
       case PM_PSF_APTREND_SKY_XY_LIN:
-        // first clip out objects which are too far from the median
-        stats->clipIter = 2;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
-        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
-            return false;
-        }
-        // apply the fit
-        stats->clipIter = 3;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKY_XY_LIN);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "Fitting sky xy_lin");
-            return false;
-        }
-        break;
+	// first clip out objects which are too far from the median 
+	stats->clipIter = 2;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
+	if (!psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
+	    return false;
+	}
+	// apply the fit
+	stats->clipIter = 3;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKY_XY_LIN);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "Fitting sky xy_lin");
+	    return false;
+	}
+	break;
       case PM_PSF_APTREND_SKYSAT_XY_LIN:
-        // first clip out objects which are too far from the median
-        stats->clipIter = 2;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
-        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
-            return false;
-        }
-        // apply the fit
-        stats->clipIter = 3;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYBIAS);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting sky bias");
-            return false;
-        }
-        // apply the fit
-        stats->clipIter = 3;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYSAT_XY_LIN);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "Fitting skyset xy_lin");
-            return false;
-        }
-        break;
+	// first clip out objects which are too far from the median 
+	stats->clipIter = 2;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
+	if (!psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting nothing");
+	    return false;
+	}
+	// apply the fit
+	stats->clipIter = 3;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYBIAS);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "clipping, fitting sky bias");
+	    return false;
+	}
+	// apply the fit
+	stats->clipIter = 3;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYSAT_XY_LIN);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "Fitting skyset xy_lin");
+	    return false;
+	}
+	break;
       case PM_PSF_APTREND_ALL:
-        // first clip out objects which are too far from the median
-        stats->clipIter = 2;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
-        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "Failed to measure apTrend");
-            return false;
-        }
-        // fit just SkyBias and clip out objects which are too far from the median
-        stats->clipIter = 2;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYBIAS);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "fitting skyBias");
-            return false;
-        }
-        // finally, fit x, y, SkyBias and clip out objects which are too far from the median
-        stats->clipIter = 3;
-        pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_ALL);
-        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
-        if (psf->ApTrend == NULL) {
-            psError(PSPHOT_ERR_PHOTOM, false, "fitting all");
-            return false;
-        }
-        break;
+	// first clip out objects which are too far from the median 
+	stats->clipIter = 2;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_CONSTANT);
+	if (!psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "Failed to measure apTrend");
+	    return false;
+	}
+	// fit just SkyBias and clip out objects which are too far from the median 
+	stats->clipIter = 2;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYBIAS);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "fitting skyBias");
+	    return false;
+	}
+	// finally, fit x, y, SkyBias and clip out objects which are too far from the median 
+	stats->clipIter = 3;
+	pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_ALL);
+	if (!psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux)) {
+	    psError(PSPHOT_ERR_PHOTOM, false, "fitting all");
+	    return false;
+	}
+	break;
       default:
         psError(PSPHOT_ERR_PHOTOM, true, "Unknown APTREND value: %s", optionName);
