Index: trunk/psModules/src/objects/pmPSF.c
===================================================================
--- trunk/psModules/src/objects/pmPSF.c	(revision 8815)
+++ trunk/psModules/src/objects/pmPSF.c	(revision 9562)
@@ -6,6 +6,6 @@
  *  @author EAM, IfA
  *
- *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-09-15 09:49:01 $
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-10-14 00:55:43 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -21,4 +21,5 @@
 /*****************************************************************************/
 
+#include <strings.h>  // for strcasecmp
 #include <pslib.h>
 #include "pmHDU.h"
@@ -56,6 +57,4 @@
 /*****************************************************************************/
 
-
-
 /*****************************************************************************
 pmPSFFree(psf): function to free a pmPSF structure
@@ -85,5 +84,5 @@
  Object Normalization
  *****************************************************************************/
-pmPSF *pmPSFAlloc (pmModelType type, bool poissonErrors)
+pmPSF *pmPSFAlloc (pmModelType type, bool poissonErrors, psPolynomial2D *psfTrendMask)
 {
     int Nparams;
@@ -100,6 +99,9 @@
 
     // the ApTrend components are (x, y, r2rflux, flux)
+    // the ApTrend order is defined by the masking
+    // initially we set it to SKYBIAS (no X,Y variation)
+    // this is adjusted in psphotApResid based on the user's choices
     psf->ApTrend = psPolynomial4DAlloc (PS_POLYNOMIAL_ORD, 2, 2, 1, 1);
-    pmPSF_MaskApTrend (psf->ApTrend, PM_PSF_SKYBIAS);
+    pmPSFMaskApTrend (psf->ApTrend, PM_PSF_APTREND_SKYBIAS);
 
     if (psf->poissonErrors) {
@@ -120,7 +122,23 @@
     psf->params = psArrayAlloc(Nparams - 4);
     psf->params->n = psf->params->nalloc;
-    for (int i = 0; i < psf->params->n; i++) {
-        // XXX EAM : make this a user-defined value?
-        psf->params->data[i] = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 1, 1);
+
+    // the order of the PSF parameter (X,Y) fits is determined by the
+    // psfTrendMask polynomial (user-specified as in the recipe). the
+    // masks of psfTrendMask are applied to each parameter.
+    // if psfTrendMask is NULL, these polynomials are not allocated.
+    // in this case, the user must set them by hand (as in pmPSFfromMD)
+    // XXX should we drop the hard-wired '4' above and use NULL to identify
+    // the parameters which are not fitted.  these could be selected by
+    // testing for the value of PM_PAR_XPOS, etc.
+    if (psfTrendMask) {
+        for (int i = 0; i < psf->params->n; i++) {
+            psPolynomial2D *param = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, psfTrendMask->nX, psfTrendMask->nY);
+            for (int nx = 0; nx < param->nX + 1; nx++) {
+                for (int ny = 0; ny < param->nY + 1; ny++) {
+                    param->mask[nx][ny] = psfTrendMask->mask[nx][ny];
+                }
+            }
+            psf->params->data[i] = param;
+        }
     }
 
@@ -223,5 +241,5 @@
 
 // zero and mask out all terms:
-static bool maskAllTerms (psPolynomial4D *trend)
+static bool maskAllApTerms (psPolynomial4D *trend)
 {
 
@@ -243,26 +261,26 @@
  * to enable the specific subset of the coefficients
  **********************************************/
-bool pmPSF_MaskApTrend (psPolynomial4D *trend,
-                        pmPSF_ApTrendOptions option)
+bool pmPSFMaskApTrend (psPolynomial4D *trend,
+                       pmPSFApTrendOptions option)
 {
 
     switch (option) {
-    case PM_PSF_NONE:
-        maskAllTerms (trend);
-        return true;
-
-    case PM_PSF_CONSTANT:
-        maskAllTerms (trend);
-        trend->mask[0][0][0][0] = 0;  // unmask constant
-        return true;
-
-    case PM_PSF_SKYBIAS:
-        maskAllTerms (trend);
-        trend->mask[0][0][0][0] = 0;  // unmask constant
-        trend->mask[0][0][1][0] = 0;  // unmask skybias
-        return true;
-
-    case PM_PSF_SKYSAT:
-        maskAllTerms (trend);
+    case PM_PSF_APTREND_NONE:
+        maskAllApTerms (trend);
+        return true;
+
+    case PM_PSF_APTREND_CONSTANT:
+        maskAllApTerms (trend);
+        trend->mask[0][0][0][0] = 0;  // unmask constant
+        return true;
+
+    case PM_PSF_APTREND_SKYBIAS:
+        maskAllApTerms (trend);
+        trend->mask[0][0][0][0] = 0;  // unmask constant
+        trend->mask[0][0][1][0] = 0;  // unmask skybias
+        return true;
+
+    case PM_PSF_APTREND_SKYSAT:
+        maskAllApTerms (trend);
         trend->mask[0][0][0][0] = 0;  // unmask constant
         trend->mask[0][0][1][0] = 0;  // unmask skybias
@@ -270,13 +288,13 @@
         return true;
 
-    case PM_PSF_XY_LIN:
-        maskAllTerms (trend);
-        trend->mask[0][0][0][0] = 0;  // unmask constant
-        trend->mask[1][0][0][0] = 0;  // unmask x
-        trend->mask[0][1][0][0] = 0;  // unmask y
-        return true;
-
-    case PM_PSF_XY_QUAD:
-        maskAllTerms (trend);
+    case PM_PSF_APTREND_XY_LIN:
+        maskAllApTerms (trend);
+        trend->mask[0][0][0][0] = 0;  // unmask constant
+        trend->mask[1][0][0][0] = 0;  // unmask x
+        trend->mask[0][1][0][0] = 0;  // unmask y
+        return true;
+
+    case PM_PSF_APTREND_XY_QUAD:
+        maskAllApTerms (trend);
         trend->mask[0][0][0][0] = 0;  // unmask constant
         trend->mask[1][0][0][0] = 0;  // unmask x
@@ -287,14 +305,14 @@
         return true;
 
-    case PM_PSF_SKY_XY_LIN:
-        maskAllTerms (trend);
-        trend->mask[0][0][0][0] = 0;  // unmask constant
-        trend->mask[1][0][0][0] = 0;  // unmask x
-        trend->mask[0][1][0][0] = 0;  // unmask y
-        trend->mask[0][0][1][0] = 0;  // unmask skybias
-        return true;
-
-    case PM_PSF_SKYSAT_XY_LIN:
-        maskAllTerms (trend);
+    case PM_PSF_APTREND_SKY_XY_LIN:
+        maskAllApTerms (trend);
+        trend->mask[0][0][0][0] = 0;  // unmask constant
+        trend->mask[1][0][0][0] = 0;  // unmask x
+        trend->mask[0][1][0][0] = 0;  // unmask y
+        trend->mask[0][0][1][0] = 0;  // unmask skybias
+        return true;
+
+    case PM_PSF_APTREND_SKYSAT_XY_LIN:
+        maskAllApTerms (trend);
         trend->mask[0][0][0][0] = 0;  // unmask constant
         trend->mask[1][0][0][0] = 0;  // unmask x
@@ -304,7 +322,7 @@
         return true;
 
-    case PM_PSF_ALL:
+    case PM_PSF_APTREND_ALL:
     default:
-        maskAllTerms (trend);
+        maskAllApTerms (trend);
         trend->mask[0][0][0][0] = 0;  // unmask constant
         trend->mask[0][0][1][0] = 0;  // unmask skybias
@@ -320,2 +338,30 @@
     return false;
 }
+
+pmPSFApTrendOptions pmPSFApTrendOptionFromName (char *name)
+{
+
+    // no correction
+    if (!strcasecmp (name, "NONE"))
+        return PM_PSF_APTREND_NONE;
+    if (!strcasecmp (name, "CONSTANT"))
+        return PM_PSF_APTREND_CONSTANT;
+    if (!strcasecmp (name, "SKYBIAS"))
+        return PM_PSF_APTREND_SKYBIAS;
+    if (!strcasecmp (name, "SKYSAT"))
+        return PM_PSF_APTREND_SKYSAT;
+    if (!strcasecmp (name, "XY_LIN"))
+        return PM_PSF_APTREND_XY_LIN;
+    if (!strcasecmp (name, "XY_QUAD"))
+        return PM_PSF_APTREND_XY_QUAD;
+    if (!strcasecmp (name, "SKY_XY_LIN"))
+        return PM_PSF_APTREND_SKY_XY_LIN;
+    if (!strcasecmp (name, "SKYSAT_XY_LIN"))
+        return PM_PSF_APTREND_SKYSAT_XY_LIN;
+    if (!strcasecmp (name, "ALL"))
+        return PM_PSF_APTREND_ALL;
+
+    psError(PS_ERR_UNKNOWN, true, "Unknown APTREND value: %s", name);
+    return PM_PSF_APTREND_ERROR;
+}
+
