Index: trunk/psphot/src/Makefile.am
===================================================================
--- trunk/psphot/src/Makefile.am	(revision 20070)
+++ trunk/psphot/src/Makefile.am	(revision 20079)
@@ -43,4 +43,5 @@
 	psphotReplaceUnfit.c	       \
 	psphotApResid.c		       \
+	psphotMakeGrowthCurve.c	       \
 	psphotMagnitudes.c	       \
 	psphotSkyReplace.c	       \
Index: trunk/psphot/src/psphotMakeGrowthCurve.c
===================================================================
--- trunk/psphot/src/psphotMakeGrowthCurve.c	(revision 20079)
+++ trunk/psphot/src/psphotMakeGrowthCurve.c	(revision 20079)
@@ -0,0 +1,35 @@
+# include "psphotInternal.h"
+
+bool psphotMakeGrowthCurve (pmReadout *readout, psMetadata *recipe, pmPSF *psf) {
+
+    bool status;
+
+    // set limits on the aperture magnitudes
+    pmSourceMagnitudesInit (recipe);
+
+    // bit-masks to test for good/bad pixels
+    psMaskType maskVal = psMetadataLookupU8(&status, recipe, "MASK.PSPHOT");
+    assert (maskVal);
+
+    // bit-mask to mark pixels not used in analysis
+    psMaskType markVal = psMetadataLookupU8(&status, recipe, "MARK.PSPHOT");
+    assert (markVal);
+
+    // maskVal is used to test for rejected pixels, and must include markVal
+    maskVal |= markVal;
+
+    // measure the aperture loss as a function of radius for PSF
+    bool IGNORE_GROWTH = psMetadataLookupBool (&status, recipe, "IGNORE_GROWTH");
+    float REF_RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_REF_RADIUS");
+    float PSF_FIT_PAD   = psMetadataLookupF32 (&status, recipe, "PSF_FIT_PADDING");
+
+    psf->growth = pmGrowthCurveAlloc (PSF_FIT_PAD, 100.0, REF_RADIUS);
+
+    if (!pmGrowthCurveGenerate (readout, psf, IGNORE_GROWTH, maskVal, markVal)) {
+        psError(PSPHOT_ERR_APERTURE, false, "Fitting aperture corrections");
+        psFree(psf->growth); psf->growth = NULL;
+        return false;
+    }
+
+    return true;
+}
