Index: trunk/psModules/src/objects/pmModel.c
===================================================================
--- trunk/psModules/src/objects/pmModel.c	(revision 13898)
+++ trunk/psModules/src/objects/pmModel.c	(revision 14652)
@@ -6,6 +6,6 @@
  *  @author EAM, IfA
  *
- *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-06-20 02:22:26 $
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-08-24 00:11:02 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -21,16 +21,11 @@
 #include <string.h>
 #include <pslib.h>
+#include "pmHDU.h"
+#include "pmFPA.h"
 #include "pmResiduals.h"
+#include "pmGrowthCurve.h"
+#include "pmPSF.h"
 #include "pmModel.h"
-
-/* The following types and functions need to be known by pmModel.c and are defined in
-   pmModelGroup.h.  The use of pmSource and other types in pmModelGroup.h prevent us from
-   directly including it here  ***/
-
-typedef psMinimizeLMChi2Func pmModelFunc;
-typedef bool (*pmModelFitStatusFunc)(pmModel *model);
-pmModelFunc pmModelFunc_GetFunction (pmModelType type);
-pmModelFitStatusFunc pmModelFitStatusFunc_GetFunction (pmModelType type);
-int pmModelParameterCount(pmModelType type);
+#include "pmModelClass.h"
 
 static void modelFree(pmModel *tmp)
@@ -45,5 +40,4 @@
 pmModelAlloc(): Allocate the pmModel structure, along with its parameters,
 and initialize the type member.  Initialize the params to 0.0.
-XXX EAM: simplifying code with pmModelParameterCount
 *****************************************************************************/
 pmModel *pmModelAlloc(pmModelType type)
@@ -53,4 +47,10 @@
     pmModel *tmp = (pmModel *) psAlloc(sizeof(pmModel));
     psMemSetDeallocator(tmp, (psFreeFunc) modelFree);
+
+    pmModelClass *class = pmModelClassSelect (type);
+    if (class == NULL) {
+        psError(PS_ERR_UNKNOWN, true, "Undefined pmModelType");
+        return(NULL);
+    }
 
     tmp->type = type;
@@ -62,12 +62,11 @@
     tmp->residuals = NULL;              // XXX should the model own this memory?
 
-    psS32 Nparams = pmModelParameterCount(type);
-    if (Nparams == 0) {
-        psError(PS_ERR_UNKNOWN, true, "Undefined pmModelType");
-        return(NULL);
-    }
+    psS32 Nparams = pmModelClassParameterCount(type);
+    assert (Nparams);
 
     tmp->params  = psVectorAlloc(Nparams, PS_TYPE_F32);
     tmp->dparams = psVectorAlloc(Nparams, PS_TYPE_F32);
+    assert (tmp->params);
+    assert (tmp->dparams);
 
     for (psS32 i = 0; i < tmp->params->n; i++) {
@@ -75,4 +74,13 @@
         tmp->dparams->data.F32[i] = 0.0;
     }
+
+    tmp->modelFunc   	    = class->modelFunc;
+    tmp->modelFlux   	    = class->modelFlux;
+    tmp->modelRadius 	    = class->modelRadius;
+    tmp->modelLimits 	    = class->modelLimits;
+    tmp->modelGuess         = class->modelGuess;
+    tmp->modelFromPSF       = class->modelFromPSF;
+    tmp->modelParamsFromPSF = class->modelParamsFromPSF;
+    tmp->modelFitStatus     = class->modelFitStatus;
 
     psTrace("psModules.objects", 3, "---- %s() end ----\n", __func__);
@@ -92,11 +100,11 @@
     new->radiusFit = model->radiusFit;
 
-    // XXX note that model->residuals is just a reference
-    new->residuals = model->residuals;
-
     for (int i = 0; i < new->params->n; i++) {
         new->params->data.F32[i]  = model->params->data.F32[i];
         new->dparams->data.F32[i] = model->dparams->data.F32[i];
     }
+
+    // note that model->residuals is just a reference
+    new->residuals = model->residuals;
 
     return (new);
@@ -123,8 +131,26 @@
     x->data.F32[1] = (psF32) (row + image->row0);
     psF32 tmpF;
-    pmModelFunc modelFunc;
-
-    modelFunc = pmModelFunc_GetFunction (model->type);
-    tmpF = modelFunc (NULL, model->params, x);
+
+    tmpF = model->modelFunc (NULL, model->params, x);
+    psFree(x);
+    psTrace("psModules.objects", 3, "---- %s() end ----\n", __func__);
+    return(tmpF);
+}
+
+psF32 pmModelEvalWithOffset(pmModel *model, psImage *image, psS32 col, psS32 row, int dx, int dy)
+{
+    psTrace("psModules.objects", 3, "---- %s() begin ----\n", __func__);
+    PS_ASSERT_PTR_NON_NULL(image, false);
+    PS_ASSERT_PTR_NON_NULL(model, false);
+    PS_ASSERT_PTR_NON_NULL(model->params, false);
+
+    // Allocate the x coordinate structure and convert row/col to image space.
+    //
+    psVector *x = psVectorAlloc(2, PS_TYPE_F32);
+    x->data.F32[0] = (psF32) (col + image->col0 + dx);
+    x->data.F32[1] = (psF32) (row + image->row0 + dy);
+    psF32 tmpF;
+
+    tmpF = model->modelFunc (NULL, model->params, x);
     psFree(x);
     psTrace("psModules.objects", 3, "---- %s() end ----\n", __func__);
@@ -137,5 +163,7 @@
                           pmModelOpMode mode,
                           bool add,
-                          psMaskType maskVal
+                          psMaskType maskVal,
+			  int dx,
+			  int dy
     )
 {
@@ -148,5 +176,5 @@
     psVector *x = psVectorAlloc(2, PS_TYPE_F32);
     psVector *params = model->params;
-    pmModelFunc modelFunc = pmModelFunc_GetFunction (model->type);
+
     psS32 imageCol;
     psS32 imageRow;
@@ -209,6 +237,6 @@
             // Convert i/j to image coord space:
             // XXX should we use using 0.5 pixel offset?
-            imageCol = ix + image->col0;
-            imageRow = iy + image->row0;
+            imageCol = ix + image->col0 + dx;
+            imageRow = iy + image->row0 + dy;
 
             x->data.F32[0] = (float) imageCol;
@@ -219,5 +247,5 @@
             // add in the desired components for this coordinate
             if (mode & PM_MODEL_OP_FUNC) {
-                pixelValue += modelFunc (NULL, params, x);
+                pixelValue += model->modelFunc (NULL, params, x);
             }
 
@@ -280,5 +308,5 @@
 {
     psTrace("psModules.objects", 3, "---- %s() begin ----\n", __func__);
-    psBool rc = AddOrSubModel(image, mask, model, mode, true, maskVal);
+    psBool rc = AddOrSubModel(image, mask, model, mode, true, maskVal, 0.0, 0.0);
     psTrace("psModules.objects", 3, "---- %s(%d) end ----\n", __func__, rc);
     return(rc);
@@ -294,19 +322,38 @@
 {
     psTrace("psModules.objects", 3, "---- %s() begin ----\n", __func__);
-    psBool rc = AddOrSubModel(image, mask, model, mode, false, maskVal);
+    psBool rc = AddOrSubModel(image, mask, model, mode, false, maskVal, 0.0, 0.0);
     psTrace("psModules.objects", 3, "---- %s(%d) end ----\n", __func__, rc);
     return(rc);
 }
 
-// check for success of model fit
-bool pmModelFitStatus (pmModel *model)
-{
-
-    bool status;
-
-    pmModelFitStatusFunc statusFunc = pmModelFitStatusFunc_GetFunction (model->type);
-    status = statusFunc (model);
-
-    return (status);
-}
-
+/******************************************************************************
+ *****************************************************************************/
+bool pmModelAddWithOffset(psImage *image,
+			  psImage *mask,
+			  pmModel *model,
+			  pmModelOpMode mode,
+			  psMaskType maskVal,
+			  int dx,
+			  int dy)
+{
+    psTrace("psModules.objects", 3, "---- %s() begin ----\n", __func__);
+    psBool rc = AddOrSubModel(image, mask, model, mode, true, maskVal, dx, dy);
+    psTrace("psModules.objects", 3, "---- %s(%d) end ----\n", __func__, rc);
+    return(rc);
+}
+
+/******************************************************************************
+ *****************************************************************************/
+bool pmModelSubWithOffset(psImage *image,
+			  psImage *mask,
+			  pmModel *model,
+			  pmModelOpMode mode,
+			  psMaskType maskVal,
+			  int dx,
+			  int dy)
+{
+    psTrace("psModules.objects", 3, "---- %s() begin ----\n", __func__);
+    psBool rc = AddOrSubModel(image, mask, model, mode, false, maskVal, dx, dy);
+    psTrace("psModules.objects", 3, "---- %s(%d) end ----\n", __func__, rc);
+    return(rc);
+}
