Index: trunk/psModules/src/objects/models/pmModel_GAUSS.c
===================================================================
--- trunk/psModules/src/objects/models/pmModel_GAUSS.c	(revision 23989)
+++ trunk/psModules/src/objects/models/pmModel_GAUSS.c	(revision 25738)
@@ -19,4 +19,13 @@
  *****************************************************************************/
 
+#include <stdio.h>
+#include <pslib.h>
+
+#include "pmMoments.h"
+#include "pmPeaks.h"
+#include "pmSource.h"
+#include "pmModel.h"
+#include "pmModel_GAUSS.h"
+
 # define PM_MODEL_FUNC            pmModelFunc_GAUSS
 # define PM_MODEL_FLUX            pmModelFlux_GAUSS
@@ -27,4 +36,20 @@
 # define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_GAUSS
 # define PM_MODEL_FIT_STATUS      pmModelFitStatus_GAUSS
+# define PM_MODEL_SET_LIMITS      pmModelSetLimits_GAUSS
+
+// Lax parameter limits
+static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0 };
+static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0 };
+
+// Strict parameter limits
+static float *paramsMinStrict = paramsMinLax;
+static float *paramsMaxStrict = paramsMaxLax;
+
+// Parameter limits to use
+static float *paramsMinUse = paramsMinLax;
+static float *paramsMaxUse = paramsMaxLax;
+static float betaUse[] = { 1000, 3e6, 5, 5, 2.0, 2.0, 0.5 };
+
+static bool limitsApply = true;         // Apply limits?
 
 // the model is a function of the pixel coordinate (pixcoord[0,1] = x,y)
@@ -68,118 +93,66 @@
 bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta)
 {
-    float beta_lim = 0, params_min = 0, params_max = 0;
-    float f1 = 0, f2 = 0, q1 = 0, q2 = 0;
+    if (!limitsApply) {
+        return true;
+    }
+    psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds");
 
     // we need to calculate the limits for SXY specially
+    float q2 = NAN;
     if (nParam == PM_PAR_SXY) {
-        f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
-        q1 = PS_MAX (0.0, q1);
+        float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
+        q1 = (q1 < 0.0) ? 0.0 : q1;
         // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
         // angle and let f2,f1 fight it out
-        q2  = 0.5*sqrt (q1);
+        q2 = 0.5*sqrtf(q1);
     }
 
     switch (mode) {
-    case PS_MINIMIZE_BETA_LIMIT:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            beta_lim = 1000;
-            break;
-        case PM_PAR_I0:
-            beta_lim = 3e6;
-            break;
-        case PM_PAR_XPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_YPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_SXX:
-            beta_lim = 2.0;
-            break;
-        case PM_PAR_SYY:
-            beta_lim = 2.0;
-            break;
-        case PM_PAR_SXY:
-            beta_lim =  0.5*q2;
-            break;
-        default:
-            psAbort("invalid parameter %d for beta test", nParam);
-        }
-        if (fabs(beta[nParam]) > fabs(beta_lim)) {
-            beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim);
-            psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
-                     nParam, beta[nParam], beta_lim);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MIN:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_min = -1000;
-            break;
-        case PM_PAR_I0:
-            params_min =   0.01;
-            break;
-        case PM_PAR_XPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_YPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_SXX:
-            params_min =   0.5;
-            break;
-        case PM_PAR_SYY:
-            params_min =   0.5;
-            break;
-        case PM_PAR_SXY:
-            params_min =   -q2;
-            break;
-        default:
-            psAbort("invalid parameter %d for param min test", nParam);
-        }
-        if (params[nParam] < params_min) {
-            params[nParam] = params_min;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
-                     nParam, params[nParam], params_min);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MAX:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_max =   1e5;
-            break;
-        case PM_PAR_I0:
-            params_max =   1e8;
-            break;
-        case PM_PAR_XPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_YPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_SXX:
-            params_max =   100;
-            break;
-        case PM_PAR_SYY:
-            params_max =   100;
-            break;
-        case PM_PAR_SXY:
-            params_max =   +q2;
-            break;
-        default:
-            psAbort("invalid parameter %d for param max test", nParam);
-        }
-        if (params[nParam] > params_max) {
-            params[nParam] = params_max;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
-                     nParam, params[nParam], params_max);
-            return false;
-        }
-        return true;
+      case PS_MINIMIZE_BETA_LIMIT: {
+          psAssert(beta, "Require beta to limit beta");
+          float limit = betaUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (fabs(beta[nParam]) > fabs(limit)) {
+              beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit);
+              psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
+                      nParam, beta[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MIN: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMinUse, "Require parameter limits to limit parameters");
+          float limit = paramsMinUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] < limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MAX: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMaxUse, "Require parameter limits to limit parameters");
+          float limit = paramsMaxUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] > limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
     default:
         psAbort("invalid choice for limits");
@@ -388,4 +361,33 @@
 }
 
+void PM_MODEL_SET_LIMITS(pmModelLimitsType type)
+{
+    switch (type) {
+      case PM_MODEL_LIMITS_NONE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_IGNORE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = false;
+        break;
+      case PM_MODEL_LIMITS_LAX:
+        paramsMinUse = paramsMinLax;
+        paramsMaxUse = paramsMaxLax;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_STRICT:
+        paramsMinUse = paramsMinStrict;
+        paramsMaxUse = paramsMaxStrict;
+        limitsApply = true;
+        break;
+      default:
+        psAbort("Unrecognised model limits type: %x", type);
+    }
+    return;
+}
+
 # undef PM_MODEL_FUNC
 # undef PM_MODEL_FLUX
@@ -396,2 +398,3 @@
 # undef PM_MODEL_PARAMS_FROM_PSF
 # undef PM_MODEL_FIT_STATUS
+# undef PM_MODEL_SET_LIMITS
Index: trunk/psModules/src/objects/models/pmModel_GAUSS.h
===================================================================
--- trunk/psModules/src/objects/models/pmModel_GAUSS.h	(revision 25738)
+++ trunk/psModules/src/objects/models/pmModel_GAUSS.h	(revision 25738)
@@ -0,0 +1,15 @@
+#ifndef PM_MODEL_GAUSS_H
+
+#include "pmModel.h"
+
+psF32 pmModelFunc_GAUSS(psVector *deriv, const psVector *params, const psVector *pixcoord);
+bool pmModelLimits_GAUSS(psMinConstraintMode mode, int nParam, float *params, float *beta);
+bool pmModelGuess_GAUSS(pmModel *model, pmSource *source);
+psF64 pmModelFlux_GAUSS(const psVector *params);
+psF64 pmModelRadius_GAUSS(const psVector *params, psF64 flux);
+bool pmModelFromPSF_GAUSS(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
+bool  pmModelParamsFromPSF_GAUSS(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
+bool pmModelFitStatus_GAUSS(pmModel *model);
+void pmModelSetLimits_GAUSS(pmModelLimitsType type);
+
+#endif
Index: trunk/psModules/src/objects/models/pmModel_PGAUSS.c
===================================================================
--- trunk/psModules/src/objects/models/pmModel_PGAUSS.c	(revision 23989)
+++ trunk/psModules/src/objects/models/pmModel_PGAUSS.c	(revision 25738)
@@ -19,4 +19,13 @@
  *****************************************************************************/
 
+#include <stdio.h>
+#include <pslib.h>
+
+#include "pmMoments.h"
+#include "pmPeaks.h"
+#include "pmSource.h"
+#include "pmModel.h"
+#include "pmModel_PGAUSS.h"
+
 # define PM_MODEL_FUNC            pmModelFunc_PGAUSS
 # define PM_MODEL_FLUX            pmModelFlux_PGAUSS
@@ -27,4 +36,20 @@
 # define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_PGAUSS
 # define PM_MODEL_FIT_STATUS      pmModelFitStatus_PGAUSS
+# define PM_MODEL_SET_LIMITS      pmModelSetLimits_PGAUSS
+
+// Lax parameter limits
+static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0 };
+static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0 };
+
+// Strict parameter limits
+static float *paramsMinStrict = paramsMinLax;
+static float *paramsMaxStrict = paramsMaxLax;
+
+// Parameter limits to use
+static float *paramsMinUse = paramsMinLax;
+static float *paramsMaxUse = paramsMaxLax;
+static float betaUse[] = { 1000, 3e6, 5, 5, 2.0, 2.0, 0.5 };
+
+static bool limitsApply = true;         // Apply limits?
 
 // the model is a function of the pixel coordinate (pixcoord[0,1] = x,y)
@@ -69,119 +94,67 @@
 bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta)
 {
-    float beta_lim = 0, params_min = 0, params_max = 0;
-    float f1 = 0, f2 = 0, q1 = 0, q2 = 0;
+    if (!limitsApply) {
+        return true;
+    }
+    psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds");
 
     // we need to calculate the limits for SXY specially
+    float q2 = NAN;
     if (nParam == PM_PAR_SXY) {
-        f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
-        q1 = PS_MAX (0.0, q1);
+        float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
+        q1 = (q1 < 0.0) ? 0.0 : q1;
         // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
         // angle and let f2,f1 fight it out
-        q2  = 0.5*sqrt (q1);
+        q2 = 0.5*sqrtf(q1);
     }
 
     switch (mode) {
-    case PS_MINIMIZE_BETA_LIMIT:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            beta_lim = 1000;
-            break;
-        case PM_PAR_I0:
-            beta_lim = 3e6;
-            break;
-        case PM_PAR_XPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_YPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_SXX:
-            beta_lim = 2.0;
-            break;
-        case PM_PAR_SYY:
-            beta_lim = 2.0;
-            break;
-        case PM_PAR_SXY:
-            beta_lim =  0.5*q2;
-            break;
-        default:
-            psAbort("invalid parameter %d for beta test", nParam);
-        }
-        if (fabs(beta[nParam]) > fabs(beta_lim)) {
-            beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim);
-            psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
-                     nParam, beta[nParam], beta_lim);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MIN:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_min = -1000;
-            break;
-        case PM_PAR_I0:
-            params_min =  0.01;
-            break;
-        case PM_PAR_XPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_YPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_SXX:
-            params_min =   0.5;
-            break;
-        case PM_PAR_SYY:
-            params_min =   0.5;
-            break;
-        case PM_PAR_SXY:
-            params_min =   -q2;
-            break;
-        default:
-            psAbort("invalid parameter %d for param min test", nParam);
-        }
-        if (params[nParam] < params_min) {
-            params[nParam] = params_min;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
-                     nParam, params[nParam], params_min);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MAX:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_max =   1e5;
-            break;
-        case PM_PAR_I0:
-            params_max =   1e8;
-            break;
-        case PM_PAR_XPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_YPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_SXX:
-            params_max =   100;
-            break;
-        case PM_PAR_SYY:
-            params_max =   100;
-            break;
-        case PM_PAR_SXY:
-            params_max =   +q2;
-            break;
-        default:
-            psAbort("invalid parameter %d for param max test", nParam);
-        }
-        if (params[nParam] > params_max) {
-            params[nParam] = params_max;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
-                     nParam, params[nParam], params_max);
-            return false;
-        }
-        return true;
-    default:
+      case PS_MINIMIZE_BETA_LIMIT: {
+          psAssert(beta, "Require beta to limit beta");
+          float limit = betaUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (fabs(beta[nParam]) > fabs(limit)) {
+              beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit);
+              psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
+                      nParam, beta[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MIN: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMinUse, "Require parameter limits to limit parameters");
+          float limit = paramsMinUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] < limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MAX: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMaxUse, "Require parameter limits to limit parameters");
+          float limit = paramsMaxUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] > limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      default:
         psAbort("invalid choice for limits");
     }
@@ -189,4 +162,5 @@
     return false;
 }
+
 
 // make an initial guess for parameters
@@ -434,4 +408,34 @@
 }
 
+
+void PM_MODEL_SET_LIMITS(pmModelLimitsType type)
+{
+    switch (type) {
+      case PM_MODEL_LIMITS_NONE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_IGNORE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = false;
+        break;
+      case PM_MODEL_LIMITS_LAX:
+        paramsMinUse = paramsMinLax;
+        paramsMaxUse = paramsMaxLax;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_STRICT:
+        paramsMinUse = paramsMinStrict;
+        paramsMaxUse = paramsMaxStrict;
+        limitsApply = true;
+        break;
+      default:
+        psAbort("Unrecognised model limits type: %x", type);
+    }
+    return;
+}
+
 # undef PM_MODEL_FUNC
 # undef PM_MODEL_FLUX
@@ -442,2 +446,3 @@
 # undef PM_MODEL_PARAMS_FROM_PSF
 # undef PM_MODEL_FIT_STATUS
+# undef PM_MODEL_SET_LIMITS
Index: trunk/psModules/src/objects/models/pmModel_PGAUSS.h
===================================================================
--- trunk/psModules/src/objects/models/pmModel_PGAUSS.h	(revision 25738)
+++ trunk/psModules/src/objects/models/pmModel_PGAUSS.h	(revision 25738)
@@ -0,0 +1,15 @@
+#ifndef PM_MODEL_PGAUSS_H
+
+#include "pmModel.h"
+
+psF32 pmModelFunc_PGAUSS(psVector *deriv, const psVector *params, const psVector *pixcoord);
+bool pmModelLimits_PGAUSS(psMinConstraintMode mode, int nParam, float *params, float *beta);
+bool pmModelGuess_PGAUSS(pmModel *model, pmSource *source);
+psF64 pmModelFlux_PGAUSS(const psVector *params);
+psF64 pmModelRadius_PGAUSS(const psVector *params, psF64 flux);
+bool pmModelFromPSF_PGAUSS(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
+bool  pmModelParamsFromPSF_PGAUSS(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
+bool pmModelFitStatus_PGAUSS(pmModel *model);
+void pmModelSetLimits_PGAUSS(pmModelLimitsType type);
+
+#endif
Index: trunk/psModules/src/objects/models/pmModel_PS1_V1.c
===================================================================
--- trunk/psModules/src/objects/models/pmModel_PS1_V1.c	(revision 23989)
+++ trunk/psModules/src/objects/models/pmModel_PS1_V1.c	(revision 25738)
@@ -20,4 +20,13 @@
    *****************************************************************************/
 
+#include <stdio.h>
+#include <pslib.h>
+
+#include "pmMoments.h"
+#include "pmPeaks.h"
+#include "pmSource.h"
+#include "pmModel.h"
+#include "pmModel_PS1_V1.h"
+
 # define PM_MODEL_FUNC            pmModelFunc_PS1_V1
 # define PM_MODEL_FLUX            pmModelFlux_PS1_V1
@@ -28,7 +37,25 @@
 # define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_PS1_V1
 # define PM_MODEL_FIT_STATUS      pmModelFitStatus_PS1_V1
+# define PM_MODEL_SET_LIMITS      pmModelSetLimits_PS1_V1
 
 # define ALPHA   1.666
 # define ALPHA_M 0.666
+
+// Lax parameter limits
+static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, -1.0 };
+static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 };
+
+// Strict parameter limits
+// k = PAR_7 < 0 is very undesirable (big divot in the middle)
+static float paramsMinStrict[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, 0.0 };
+static float paramsMaxStrict[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 };
+
+// Parameter limits to use
+static float *paramsMinUse = paramsMinLax;
+static float *paramsMaxUse = paramsMaxLax;
+static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5, 2.0 };
+
+static bool limitsApply = true;         // Apply limits?
+
 
 psF32 PM_MODEL_FUNC (psVector *deriv,
@@ -84,128 +111,67 @@
 bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta)
 {
-    float beta_lim = 0, params_min = 0, params_max = 0;
-    float f1 = 0, f2 = 0, q1 = 0, q2 = 0;
+    if (!limitsApply) {
+        return true;
+    }
+    psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds");
 
     // we need to calculate the limits for SXY specially
+    float q2 = NAN;
     if (nParam == PM_PAR_SXY) {
-        f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
+        float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
         q1 = (q1 < 0.0) ? 0.0 : q1;
         // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
         // angle and let f2,f1 fight it out
-        q2  = 0.5*sqrt (q1);
+        q2 = 0.5*sqrtf(q1);
     }
 
     switch (mode) {
-    case PS_MINIMIZE_BETA_LIMIT:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            beta_lim = 1000;
-            break;
-        case PM_PAR_I0:
-            beta_lim = 3e6;
-            break;
-        case PM_PAR_XPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_YPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_SXX:
-            beta_lim = 1.0;
-            break;
-        case PM_PAR_SYY:
-            beta_lim = 1.0;
-            break;
-        case PM_PAR_SXY:
-            beta_lim =  0.5*q2;
-            break;
-        case PM_PAR_7:
-            beta_lim = 2.0;
-            break;
-        default:
-            psAbort("invalid parameter %d for beta test", nParam);
-        }
-        if (fabs(beta[nParam]) > fabs(beta_lim)) {
-            beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim);
-            psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
-                     nParam, beta[nParam], beta_lim);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MIN:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_min = -1000;
-            break;
-        case PM_PAR_I0:
-            params_min =   0.01;
-            break;
-        case PM_PAR_XPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_YPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_SXX:
-            params_min =   0.5;
-            break;
-        case PM_PAR_SYY:
-            params_min =   0.5;
-            break;
-        case PM_PAR_SXY:
-            params_min =  -q2;
-            break;
-        case PM_PAR_7:
-            params_min =  -1.0;
-            break;
-        default:
-            psAbort("invalid parameter %d for param min test", nParam);
-        }
-        if (params[nParam] < params_min) {
-            params[nParam] = params_min;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
-                     nParam, params[nParam], params_min);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MAX:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_max =   1e5;
-            break;
-        case PM_PAR_I0:
-            params_max =   1e8;
-            break;
-        case PM_PAR_XPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_YPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_SXX:
-            params_max =   100;
-            break;
-        case PM_PAR_SYY:
-            params_max =   100;
-            break;
-        case PM_PAR_SXY:
-            params_max =  +q2;
-            break;
-        case PM_PAR_7:
-            params_max =  20.0;
-            break;
-        default:
-            psAbort("invalid parameter %d for param max test", nParam);
-        }
-        if (params[nParam] > params_max) {
-            params[nParam] = params_max;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
-                     nParam, params[nParam], params_max);
-            return false;
-        }
-        return true;
-    default:
+      case PS_MINIMIZE_BETA_LIMIT: {
+          psAssert(beta, "Require beta to limit beta");
+          float limit = betaUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (fabs(beta[nParam]) > fabs(limit)) {
+              beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit);
+              psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
+                      nParam, beta[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MIN: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMinUse, "Require parameter limits to limit parameters");
+          float limit = paramsMinUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] < limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MAX: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMaxUse, "Require parameter limits to limit parameters");
+          float limit = paramsMaxUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] > limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      default:
         psAbort("invalid choice for limits");
     }
@@ -299,10 +265,16 @@
     psF32 *PAR = params->data.F32;
 
-    if (flux <= 0)
-        return (1.0);
-    if (PAR[PM_PAR_I0] <= 0)
-        return (1.0);
-    if (flux >= PAR[PM_PAR_I0])
-        return (1.0);
+    if (flux <= 0) {
+        return 1.0;
+    }
+    if (PAR[PM_PAR_I0] <= 0) {
+        return 1.0;
+    }
+    if (flux >= PAR[PM_PAR_I0]) {
+        return 1.0;
+    }
+    if (PAR[PM_PAR_7] == 0.0) {
+        return powf(PAR[PM_PAR_I0] / flux - 1.0, 1.0 / ALPHA);
+    }
 
     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
@@ -468,4 +440,35 @@
 }
 
+
+void PM_MODEL_SET_LIMITS(pmModelLimitsType type)
+{
+    switch (type) {
+      case PM_MODEL_LIMITS_NONE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_IGNORE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = false;
+        break;
+      case PM_MODEL_LIMITS_LAX:
+        paramsMinUse = paramsMinLax;
+        paramsMaxUse = paramsMaxLax;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_STRICT:
+        paramsMinUse = paramsMinStrict;
+        paramsMaxUse = paramsMaxStrict;
+        limitsApply = true;
+        break;
+      default:
+        psAbort("Unrecognised model limits type: %x", type);
+    }
+    return;
+}
+
+
 # undef PM_MODEL_FUNC
 # undef PM_MODEL_FLUX
@@ -476,4 +479,5 @@
 # undef PM_MODEL_PARAMS_FROM_PSF
 # undef PM_MODEL_FIT_STATUS
+# undef PM_MODEL_SET_LIMITS
 # undef ALPHA
 # undef ALPHA_M
Index: trunk/psModules/src/objects/models/pmModel_PS1_V1.h
===================================================================
--- trunk/psModules/src/objects/models/pmModel_PS1_V1.h	(revision 25738)
+++ trunk/psModules/src/objects/models/pmModel_PS1_V1.h	(revision 25738)
@@ -0,0 +1,15 @@
+#ifndef PM_MODEL_PS1_V1_H
+
+#include "pmModel.h"
+
+psF32 pmModelFunc_PS1_V1(psVector *deriv, const psVector *params, const psVector *pixcoord);
+bool pmModelLimits_PS1_V1(psMinConstraintMode mode, int nParam, float *params, float *beta);
+bool pmModelGuess_PS1_V1(pmModel *model, pmSource *source);
+psF64 pmModelFlux_PS1_V1(const psVector *params);
+psF64 pmModelRadius_PS1_V1(const psVector *params, psF64 flux);
+bool pmModelFromPSF_PS1_V1(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
+bool  pmModelParamsFromPSF_PS1_V1(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
+bool pmModelFitStatus_PS1_V1(pmModel *model);
+void pmModelSetLimits_PS1_V1(pmModelLimitsType type);
+
+#endif
Index: trunk/psModules/src/objects/models/pmModel_QGAUSS.c
===================================================================
--- trunk/psModules/src/objects/models/pmModel_QGAUSS.c	(revision 23989)
+++ trunk/psModules/src/objects/models/pmModel_QGAUSS.c	(revision 25738)
@@ -20,4 +20,13 @@
    *****************************************************************************/
 
+#include <stdio.h>
+#include <pslib.h>
+
+#include "pmMoments.h"
+#include "pmPeaks.h"
+#include "pmSource.h"
+#include "pmModel.h"
+#include "pmModel_QGAUSS.h"
+
 # define PM_MODEL_FUNC            pmModelFunc_QGAUSS
 # define PM_MODEL_FLUX            pmModelFlux_QGAUSS
@@ -28,4 +37,20 @@
 # define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_QGAUSS
 # define PM_MODEL_FIT_STATUS      pmModelFitStatus_QGAUSS
+# define PM_MODEL_SET_LIMITS      pmModelSetLimits_QGAUSS
+
+// Lax parameter limits
+static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, 0.1 };
+static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 };
+
+// Strict parameter limits
+static float *paramsMinStrict = paramsMinLax;
+static float *paramsMaxStrict = paramsMaxLax;
+
+// Parameter limits to use
+static float *paramsMinUse = paramsMinLax;
+static float *paramsMaxUse = paramsMaxLax;
+static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5 };
+
+static bool limitsApply = true;         // Apply limits?
 
 psF32 PM_MODEL_FUNC (psVector *deriv,
@@ -79,129 +104,69 @@
 # define AR_MAX 20.0
 # define AR_RATIO 0.99
+
 bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta)
 {
-    float beta_lim = 0, params_min = 0, params_max = 0;
-    float f1 = 0, f2 = 0, q1 = 0, q2 = 0;
+    if (!limitsApply) {
+        return true;
+    }
+    psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds");
 
     // we need to calculate the limits for SXY specially
+    float q2 = NAN;
     if (nParam == PM_PAR_SXY) {
-        f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
+        float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
         q1 = (q1 < 0.0) ? 0.0 : q1;
         // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
         // angle and let f2,f1 fight it out
-        q2  = 0.5*sqrt (q1);
+        q2 = 0.5*sqrtf(q1);
     }
 
     switch (mode) {
-    case PS_MINIMIZE_BETA_LIMIT:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            beta_lim = 1000;
-            break;
-        case PM_PAR_I0:
-            beta_lim = 3e6;
-            break;
-        case PM_PAR_XPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_YPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_SXX:
-            beta_lim = 1.0;
-            break;
-        case PM_PAR_SYY:
-            beta_lim = 1.0;
-            break;
-        case PM_PAR_SXY:
-            beta_lim =  0.5*q2;
-            break;
-        case PM_PAR_7:
-            beta_lim = 2.0;
-            break;
-        default:
-            psAbort("invalid parameter %d for beta test", nParam);
-        }
-        if (fabs(beta[nParam]) > fabs(beta_lim)) {
-            beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim);
-            psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
-                     nParam, beta[nParam], beta_lim);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MIN:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_min = -1000;
-            break;
-        case PM_PAR_I0:
-            params_min =   0.01;
-            break;
-        case PM_PAR_XPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_YPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_SXX:
-            params_min =   0.5;
-            break;
-        case PM_PAR_SYY:
-            params_min =   0.5;
-            break;
-        case PM_PAR_SXY:
-            params_min =  -q2;
-            break;
-        case PM_PAR_7:
-            params_min =   0.1;
-            break;
-        default:
-            psAbort("invalid parameter %d for param min test", nParam);
-        }
-        if (params[nParam] < params_min) {
-            params[nParam] = params_min;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
-                     nParam, params[nParam], params_min);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MAX:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_max =   1e5;
-            break;
-        case PM_PAR_I0:
-            params_max =   1e8;
-            break;
-        case PM_PAR_XPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_YPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_SXX:
-            params_max =   100;
-            break;
-        case PM_PAR_SYY:
-            params_max =   100;
-            break;
-        case PM_PAR_SXY:
-            params_max =  +q2;
-            break;
-        case PM_PAR_7:
-            params_max =  20.0;
-            break;
-        default:
-            psAbort("invalid parameter %d for param max test", nParam);
-        }
-        if (params[nParam] > params_max) {
-            params[nParam] = params_max;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
-                     nParam, params[nParam], params_max);
-            return false;
-        }
-        return true;
+      case PS_MINIMIZE_BETA_LIMIT: {
+          psAssert(beta, "Require beta to limit beta");
+          float limit = betaUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (fabs(beta[nParam]) > fabs(limit)) {
+              beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit);
+              psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
+                      nParam, beta[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MIN: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMinUse, "Require parameter limits to limit parameters");
+          float limit = paramsMinUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] < limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MAX: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMaxUse, "Require parameter limits to limit parameters");
+          float limit = paramsMaxUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] > limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
     default:
         psAbort("invalid choice for limits");
@@ -464,4 +429,34 @@
 }
 
+
+void PM_MODEL_SET_LIMITS(pmModelLimitsType type)
+{
+    switch (type) {
+      case PM_MODEL_LIMITS_NONE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_IGNORE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = false;
+        break;
+      case PM_MODEL_LIMITS_LAX:
+        paramsMinUse = paramsMinLax;
+        paramsMaxUse = paramsMaxLax;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_STRICT:
+        paramsMinUse = paramsMinStrict;
+        paramsMaxUse = paramsMaxStrict;
+        limitsApply = true;
+        break;
+      default:
+        psAbort("Unrecognised model limits type: %x", type);
+    }
+    return;
+}
+
 # undef PM_MODEL_FUNC
 # undef PM_MODEL_FLUX
@@ -472,2 +467,3 @@
 # undef PM_MODEL_PARAMS_FROM_PSF
 # undef PM_MODEL_FIT_STATUS
+# undef PM_MODEL_SET_LIMITS
Index: trunk/psModules/src/objects/models/pmModel_QGAUSS.h
===================================================================
--- trunk/psModules/src/objects/models/pmModel_QGAUSS.h	(revision 25738)
+++ trunk/psModules/src/objects/models/pmModel_QGAUSS.h	(revision 25738)
@@ -0,0 +1,15 @@
+#ifndef PM_MODEL_QGAUSS_H
+
+#include "pmModel.h"
+
+psF32 pmModelFunc_QGAUSS(psVector *deriv, const psVector *params, const psVector *pixcoord);
+bool pmModelLimits_QGAUSS(psMinConstraintMode mode, int nParam, float *params, float *beta);
+bool pmModelGuess_QGAUSS(pmModel *model, pmSource *source);
+psF64 pmModelFlux_QGAUSS(const psVector *params);
+psF64 pmModelRadius_QGAUSS(const psVector *params, psF64 flux);
+bool pmModelFromPSF_QGAUSS(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
+bool  pmModelParamsFromPSF_QGAUSS(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
+bool pmModelFitStatus_QGAUSS(pmModel *model);
+void pmModelSetLimits_QGAUSS(pmModelLimitsType type);
+
+#endif
Index: trunk/psModules/src/objects/models/pmModel_RGAUSS.c
===================================================================
--- trunk/psModules/src/objects/models/pmModel_RGAUSS.c	(revision 23989)
+++ trunk/psModules/src/objects/models/pmModel_RGAUSS.c	(revision 25738)
@@ -20,4 +20,13 @@
  *****************************************************************************/
 
+#include <stdio.h>
+#include <pslib.h>
+
+#include "pmMoments.h"
+#include "pmPeaks.h"
+#include "pmSource.h"
+#include "pmModel.h"
+#include "pmModel_RGAUSS.h"
+
 # define PM_MODEL_FUNC            pmModelFunc_RGAUSS
 # define PM_MODEL_FLUX            pmModelFlux_RGAUSS
@@ -28,4 +37,20 @@
 # define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_RGAUSS
 # define PM_MODEL_FIT_STATUS      pmModelFitStatus_RGAUSS
+# define PM_MODEL_SET_LIMITS      pmModelSetLimits_RGAUSS
+
+// Lax parameter limits
+static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, 1.25 };
+static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 4.0 };
+
+// Strict parameter limits
+static float *paramsMinStrict = paramsMinLax;
+static float *paramsMaxStrict = paramsMaxLax;
+
+// Parameter limits to use
+static float *paramsMinUse = paramsMinLax;
+static float *paramsMaxUse = paramsMaxLax;
+static float betaUse[] = { 1000, 3e6, 5, 5, 0.5, 0.5, 0.5, 0.5 };
+
+static bool limitsApply = true;         // Apply limits?
 
 psF32 PM_MODEL_FUNC (psVector *deriv,
@@ -73,130 +98,70 @@
 # define AR_MAX 20.0
 # define AR_RATIO 0.99
+
 bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta)
 {
-    float beta_lim = 0, params_min = 0, params_max = 0;
-    float f1 = 0, f2 = 0, q1 = 0, q2 = 0;
+    if (!limitsApply) {
+        return true;
+    }
+    psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds");
 
     // we need to calculate the limits for SXY specially
+    float q2 = NAN;
     if (nParam == PM_PAR_SXY) {
-        f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
+        float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
         q1 = (q1 < 0.0) ? 0.0 : q1;
         // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
         // angle and let f2,f1 fight it out
-        q2  = 0.5*sqrt (q1);
+        q2 = 0.5*sqrtf(q1);
     }
 
     switch (mode) {
-    case PS_MINIMIZE_BETA_LIMIT:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            beta_lim = 1000;
-            break;
-        case PM_PAR_I0:
-            beta_lim = 3e6;
-            break;
-        case PM_PAR_XPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_YPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_SXX:
-            beta_lim = 0.5;
-            break;
-        case PM_PAR_SYY:
-            beta_lim = 0.5;
-            break;
-        case PM_PAR_SXY:
-            beta_lim =  0.5*q2;
-            break;
-        case PM_PAR_7:
-            beta_lim = 0.5;
-            break;
-        default:
-            psAbort("invalid parameter %d for beta test", nParam);
-        }
-        if (fabs(beta[nParam]) > fabs(beta_lim)) {
-            beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim);
-            psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
-                     nParam, beta[nParam], beta_lim);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MIN:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_min = -1000;
-            break;
-        case PM_PAR_I0:
-            params_min =   0.01;
-            break;
-        case PM_PAR_XPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_YPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_SXX:
-            params_min =   0.5;
-            break;
-        case PM_PAR_SYY:
-            params_min =   0.5;
-            break;
-        case PM_PAR_SXY:
-            params_min =  -q2;
-            break;
-        case PM_PAR_7:
-            params_min =   1.25;
-            break;
-        default:
-            psAbort("invalid parameter %d for param min test", nParam);
-        }
-        if (params[nParam] < params_min) {
-            params[nParam] = params_min;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
-                     nParam, params[nParam], params_min);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MAX:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_max =   1e5;
-            break;
-        case PM_PAR_I0:
-            params_max =   1e8;
-            break;
-        case PM_PAR_XPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_YPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_SXX:
-            params_max =   100;
-            break;
-        case PM_PAR_SYY:
-            params_max =   100;
-            break;
-        case PM_PAR_SXY:
-            params_max =  +q2;
-            break;
-        case PM_PAR_7:
-            params_max =  4.0;
-            break;
-        default:
-            psAbort("invalid parameter %d for param max test", nParam);
-        }
-        if (params[nParam] > params_max) {
-            params[nParam] = params_max;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
-                     nParam, params[nParam], params_max);
-            return false;
-        }
-        return true;
-    default:
+      case PS_MINIMIZE_BETA_LIMIT: {
+          psAssert(beta, "Require beta to limit beta");
+          float limit = betaUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (fabs(beta[nParam]) > fabs(limit)) {
+              beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit);
+              psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
+                      nParam, beta[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MIN: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMinUse, "Require parameter limits to limit parameters");
+          float limit = paramsMinUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] < limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MAX: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMaxUse, "Require parameter limits to limit parameters");
+          float limit = paramsMaxUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] > limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      default:
         psAbort("invalid choice for limits");
     }
@@ -204,4 +169,5 @@
     return false;
 }
+
 
 // make an initial guess for parameters
@@ -456,4 +422,34 @@
 }
 
+
+void PM_MODEL_SET_LIMITS(pmModelLimitsType type)
+{
+    switch (type) {
+      case PM_MODEL_LIMITS_NONE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_IGNORE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = false;
+        break;
+      case PM_MODEL_LIMITS_LAX:
+        paramsMinUse = paramsMinLax;
+        paramsMaxUse = paramsMaxLax;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_STRICT:
+        paramsMinUse = paramsMinStrict;
+        paramsMaxUse = paramsMaxStrict;
+        limitsApply = true;
+        break;
+      default:
+        psAbort("Unrecognised model limits type: %x", type);
+    }
+    return;
+}
+
 # undef PM_MODEL_FUNC
 # undef PM_MODEL_FLUX
@@ -464,2 +460,3 @@
 # undef PM_MODEL_PARAMS_FROM_PSF
 # undef PM_MODEL_FIT_STATUS
+# undef PM_MODEL_SET_LIMITS
Index: trunk/psModules/src/objects/models/pmModel_RGAUSS.h
===================================================================
--- trunk/psModules/src/objects/models/pmModel_RGAUSS.h	(revision 25738)
+++ trunk/psModules/src/objects/models/pmModel_RGAUSS.h	(revision 25738)
@@ -0,0 +1,15 @@
+#ifndef PM_MODEL_RGAUSS_H
+
+#include "pmModel.h"
+
+psF32 pmModelFunc_RGAUSS(psVector *deriv, const psVector *params, const psVector *pixcoord);
+bool pmModelLimits_RGAUSS(psMinConstraintMode mode, int nParam, float *params, float *beta);
+bool pmModelGuess_RGAUSS(pmModel *model, pmSource *source);
+psF64 pmModelFlux_RGAUSS(const psVector *params);
+psF64 pmModelRadius_RGAUSS(const psVector *params, psF64 flux);
+bool pmModelFromPSF_RGAUSS(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
+bool  pmModelParamsFromPSF_RGAUSS(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
+bool pmModelFitStatus_RGAUSS(pmModel *model);
+void pmModelSetLimits_RGAUSS(pmModelLimitsType type);
+
+#endif
Index: trunk/psModules/src/objects/models/pmModel_SERSIC.c
===================================================================
--- trunk/psModules/src/objects/models/pmModel_SERSIC.c	(revision 23989)
+++ trunk/psModules/src/objects/models/pmModel_SERSIC.c	(revision 25738)
@@ -23,4 +23,13 @@
    *****************************************************************************/
 
+#include <stdio.h>
+#include <pslib.h>
+
+#include "pmMoments.h"
+#include "pmPeaks.h"
+#include "pmSource.h"
+#include "pmModel.h"
+#include "pmModel_SERSIC.h"
+
 # define PM_MODEL_FUNC            pmModelFunc_SERSIC
 # define PM_MODEL_FLUX            pmModelFlux_SERSIC
@@ -31,4 +40,20 @@
 # define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_SERSIC
 # define PM_MODEL_FIT_STATUS      pmModelFitStatus_SERSIC
+# define PM_MODEL_SET_LIMITS      pmModelSetLimits_SERSIC
+
+// Lax parameter limits
+static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.05, 0.05, -1.0, 0.05 };
+static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 4.0 };
+
+// Strict parameter limits
+static float *paramsMinStrict = paramsMinLax;
+static float *paramsMaxStrict = paramsMaxLax;
+
+// Parameter limits to use
+static float *paramsMinUse = paramsMinLax;
+static float *paramsMaxUse = paramsMaxLax;
+static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5, 2.0 };
+
+static bool limitsApply = true;         // Apply limits?
 
 psF32 PM_MODEL_FUNC (psVector *deriv,
@@ -91,128 +116,67 @@
 bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta)
 {
-    float beta_lim = 0, params_min = 0, params_max = 0;
-    float f1 = 0, f2 = 0, q1 = 0, q2 = 0;
+    if (!limitsApply) {
+        return true;
+    }
+    psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds");
 
     // we need to calculate the limits for SXY specially
+    float q2 = NAN;
     if (nParam == PM_PAR_SXY) {
-        f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
-        q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
+        float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
+        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
         q1 = (q1 < 0.0) ? 0.0 : q1;
         // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
         // angle and let f2,f1 fight it out
-        q2  = 0.5*sqrt (q1);
+        q2 = 0.5*sqrtf(q1);
     }
 
     switch (mode) {
-    case PS_MINIMIZE_BETA_LIMIT:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            beta_lim = 1000;
-            break;
-        case PM_PAR_I0:
-            beta_lim = 3e6;
-            break;
-        case PM_PAR_XPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_YPOS:
-            beta_lim = 5;
-            break;
-        case PM_PAR_SXX:
-            beta_lim = 1.0;
-            break;
-        case PM_PAR_SYY:
-            beta_lim = 1.0;
-            break;
-        case PM_PAR_SXY:
-            beta_lim =  0.5*q2;
-            break;
-        case PM_PAR_7:
-            beta_lim = 2.0;
-            break;
-        default:
-            psAbort("invalid parameter %d for beta test", nParam);
-        }
-        if (fabs(beta[nParam]) > fabs(beta_lim)) {
-            beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim);
-            psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
-                     nParam, beta[nParam], beta_lim);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MIN:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_min = -1000;
-            break;
-        case PM_PAR_I0:
-            params_min =     0.01;
-            break;
-        case PM_PAR_XPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_YPOS:
-            params_min =  -100;
-            break;
-        case PM_PAR_SXX:
-            params_min =   0.05;
-            break;
-        case PM_PAR_SYY:
-            params_min =   0.05;
-            break;
-        case PM_PAR_SXY:
-            params_min =  -q2;
-            break;
-        case PM_PAR_7:
-            params_min =   0.05;
-            break;
-        default:
-            psAbort("invalid parameter %d for param min test", nParam);
-        }
-        if (params[nParam] < params_min) {
-            params[nParam] = params_min;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
-                     nParam, params[nParam], params_min);
-            return false;
-        }
-        return true;
-    case PS_MINIMIZE_PARAM_MAX:
-        switch (nParam) {
-        case PM_PAR_SKY:
-            params_max =   1e5;
-            break;
-        case PM_PAR_I0:
-            params_max =   1e8;
-            break;
-        case PM_PAR_XPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_YPOS:
-            params_max =   1e4;
-            break;
-        case PM_PAR_SXX:
-            params_max =   100;
-            break;
-        case PM_PAR_SYY:
-            params_max =   100;
-            break;
-        case PM_PAR_SXY:
-            params_max =  +q2;
-            break;
-        case PM_PAR_7:
-            params_max =   4.0;
-            break;
-        default:
-            psAbort("invalid parameter %d for param max test", nParam);
-        }
-        if (params[nParam] > params_max) {
-            params[nParam] = params_max;
-            psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
-                     nParam, params[nParam], params_max);
-            return false;
-        }
-        return true;
-    default:
+      case PS_MINIMIZE_BETA_LIMIT: {
+          psAssert(beta, "Require beta to limit beta");
+          float limit = betaUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (fabs(beta[nParam]) > fabs(limit)) {
+              beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit);
+              psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
+                      nParam, beta[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MIN: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMinUse, "Require parameter limits to limit parameters");
+          float limit = paramsMinUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] < limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      case PS_MINIMIZE_PARAM_MAX: {
+          psAssert(params, "Require parameters to limit parameters");
+          psAssert(paramsMaxUse, "Require parameter limits to limit parameters");
+          float limit = paramsMaxUse[nParam];
+          if (nParam == PM_PAR_SXY) {
+              limit *= q2;
+          }
+          if (params[nParam] > limit) {
+              params[nParam] = limit;
+              psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
+                      nParam, params[nParam], limit);
+              return false;
+          }
+          return true;
+      }
+      default:
         psAbort("invalid choice for limits");
     }
@@ -220,5 +184,4 @@
     return false;
 }
-
 
 // make an initial guess for parameters
@@ -447,7 +410,37 @@
 
     fprintf (stderr, "SERSIC status pars: dP: %f, I0: %f, S/N: %f\n",
-	     dP, PAR[PM_PAR_I0], (dPAR[PM_PAR_I0]/PAR[PM_PAR_I0]));
+             dP, PAR[PM_PAR_I0], (dPAR[PM_PAR_I0]/PAR[PM_PAR_I0]));
 
     return status;
+}
+
+
+void PM_MODEL_SET_LIMITS(pmModelLimitsType type)
+{
+    switch (type) {
+      case PM_MODEL_LIMITS_NONE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_IGNORE:
+        paramsMinUse = NULL;
+        paramsMaxUse = NULL;
+        limitsApply = false;
+        break;
+      case PM_MODEL_LIMITS_LAX:
+        paramsMinUse = paramsMinLax;
+        paramsMaxUse = paramsMaxLax;
+        limitsApply = true;
+        break;
+      case PM_MODEL_LIMITS_STRICT:
+        paramsMinUse = paramsMinStrict;
+        paramsMaxUse = paramsMaxStrict;
+        limitsApply = true;
+        break;
+      default:
+        psAbort("Unrecognised model limits type: %x", type);
+    }
+    return;
 }
 
@@ -460,2 +453,3 @@
 # undef PM_MODEL_PARAMS_FROM_PSF
 # undef PM_MODEL_FIT_STATUS
+# undef PM_MODEL_SET_LIMITS
Index: trunk/psModules/src/objects/models/pmModel_SERSIC.h
===================================================================
--- trunk/psModules/src/objects/models/pmModel_SERSIC.h	(revision 25738)
+++ trunk/psModules/src/objects/models/pmModel_SERSIC.h	(revision 25738)
@@ -0,0 +1,15 @@
+#ifndef PM_MODEL_SERSIC_H
+
+#include "pmModel.h"
+
+psF32 pmModelFunc_SERSIC(psVector *deriv, const psVector *params, const psVector *pixcoord);
+bool pmModelLimits_SERSIC(psMinConstraintMode mode, int nParam, float *params, float *beta);
+bool pmModelGuess_SERSIC(pmModel *model, pmSource *source);
+psF64 pmModelFlux_SERSIC(const psVector *params);
+psF64 pmModelRadius_SERSIC(const psVector *params, psF64 flux);
+bool pmModelFromPSF_SERSIC(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
+bool  pmModelParamsFromPSF_SERSIC(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
+bool pmModelFitStatus_SERSIC(pmModel *model);
+void pmModelSetLimits_SERSIC(pmModelLimitsType type);
+
+#endif
