Changeset 27840 for branches/simtest_nebulous_branches/psModules/src/objects/models/pmModel_PGAUSS.c
- Timestamp:
- May 3, 2010, 8:50:52 AM (16 years ago)
- Location:
- branches/simtest_nebulous_branches
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/simtest_nebulous_branches
- Property svn:mergeinfo changed
-
branches/simtest_nebulous_branches/psModules
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk/psModules merged eligible /branches/eam_branches/stackphot.20100406/psModules 27623-27653 /branches/pap_delete/psModules 27530-27595
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/simtest_nebulous_branches/psModules/src/objects/models/pmModel_PGAUSS.c
r20001 r27840 1 1 /****************************************************************************** 2 2 * this file defines the PGAUSS source shape model. Note that these model functions are loaded 3 * by pmModel Group.c using 'include', and thus need no 'include' statements of their own. The3 * by pmModelClass.c using 'include', and thus need no 'include' statements of their own. The 4 4 * models use a psVector to represent the set of parameters, with the sequence used to specify 5 5 * the meaning of the parameter. The meaning of the parameters may thus vary depending on the 6 * specifics of the model. All models which are used a PSF representations share a few6 * specifics of the model. All models which are used as a PSF representations share a few 7 7 * parameters, for which # define names are listed in pmModel.h: 8 8 … … 19 19 *****************************************************************************/ 20 20 21 #include <stdio.h> 22 #include <pslib.h> 23 24 #include "pmMoments.h" 25 #include "pmPeaks.h" 26 #include "pmSource.h" 27 #include "pmModel.h" 28 #include "pmModel_PGAUSS.h" 29 21 30 # define PM_MODEL_FUNC pmModelFunc_PGAUSS 22 31 # define PM_MODEL_FLUX pmModelFlux_PGAUSS … … 27 36 # define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_PGAUSS 28 37 # define PM_MODEL_FIT_STATUS pmModelFitStatus_PGAUSS 38 # define PM_MODEL_SET_LIMITS pmModelSetLimits_PGAUSS 39 40 // Lax parameter limits 41 static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0 }; 42 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0 }; 43 44 // Moderate parameter limits 45 static float *paramsMinModerate = paramsMinLax; 46 static float *paramsMaxModerate = paramsMaxLax; 47 48 // Strict parameter limits 49 static float *paramsMinStrict = paramsMinLax; 50 static float *paramsMaxStrict = paramsMaxLax; 51 52 // Parameter limits to use 53 static float *paramsMinUse = paramsMinLax; 54 static float *paramsMaxUse = paramsMaxLax; 55 static float betaUse[] = { 1000, 3e6, 5, 5, 2.0, 2.0, 0.5 }; 56 57 static bool limitsApply = true; // Apply limits? 29 58 30 59 // the model is a function of the pixel coordinate (pixcoord[0,1] = x,y) 60 // 0.5 PIX: the parameters are defined in terms of pixel coords, so the incoming pixcoords 61 // values need to be pixel coords 31 62 psF32 PM_MODEL_FUNC(psVector *deriv, 32 63 const psVector *params, … … 69 100 bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta) 70 101 { 71 float beta_lim = 0, params_min = 0, params_max = 0; 72 float f1 = 0, f2 = 0, q1 = 0, q2 = 0; 102 if (!limitsApply) { 103 return true; 104 } 105 psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds"); 73 106 74 107 // we need to calculate the limits for SXY specially 108 float q2 = NAN; 75 109 if (nParam == PM_PAR_SXY) { 76 f 1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);77 f 2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);78 q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);79 q1 = PS_MAX (0.0, q1);110 float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]); 111 float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]); 112 float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2); 113 q1 = (q1 < 0.0) ? 0.0 : q1; 80 114 // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg.. Saturate at that 81 115 // angle and let f2,f1 fight it out 82 q2 = 0.5*sqrt(q1);116 q2 = 0.5*sqrtf(q1); 83 117 } 84 118 85 119 switch (mode) { 86 case PS_MINIMIZE_BETA_LIMIT: 87 switch (nParam) { 88 case PM_PAR_SKY: 89 beta_lim = 1000; 90 break; 91 case PM_PAR_I0: 92 beta_lim = 3e6; 93 break; 94 case PM_PAR_XPOS: 95 beta_lim = 5; 96 break; 97 case PM_PAR_YPOS: 98 beta_lim = 5; 99 break; 100 case PM_PAR_SXX: 101 beta_lim = 2.0; 102 break; 103 case PM_PAR_SYY: 104 beta_lim = 2.0; 105 break; 106 case PM_PAR_SXY: 107 beta_lim = 0.5*q2; 108 break; 109 default: 110 psAbort("invalid parameter %d for beta test", nParam); 111 } 112 if (fabs(beta[nParam]) > fabs(beta_lim)) { 113 beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim); 114 psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g", 115 nParam, beta[nParam], beta_lim); 116 return false; 117 } 118 return true; 119 case PS_MINIMIZE_PARAM_MIN: 120 switch (nParam) { 121 case PM_PAR_SKY: 122 params_min = -1000; 123 break; 124 case PM_PAR_I0: 125 params_min = 0.01; 126 break; 127 case PM_PAR_XPOS: 128 params_min = -100; 129 break; 130 case PM_PAR_YPOS: 131 params_min = -100; 132 break; 133 case PM_PAR_SXX: 134 params_min = 0.5; 135 break; 136 case PM_PAR_SYY: 137 params_min = 0.5; 138 break; 139 case PM_PAR_SXY: 140 params_min = -q2; 141 break; 142 default: 143 psAbort("invalid parameter %d for param min test", nParam); 144 } 145 if (params[nParam] < params_min) { 146 params[nParam] = params_min; 147 psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g", 148 nParam, params[nParam], params_min); 149 return false; 150 } 151 return true; 152 case PS_MINIMIZE_PARAM_MAX: 153 switch (nParam) { 154 case PM_PAR_SKY: 155 params_max = 1e5; 156 break; 157 case PM_PAR_I0: 158 params_max = 1e8; 159 break; 160 case PM_PAR_XPOS: 161 params_max = 1e4; 162 break; 163 case PM_PAR_YPOS: 164 params_max = 1e4; 165 break; 166 case PM_PAR_SXX: 167 params_max = 100; 168 break; 169 case PM_PAR_SYY: 170 params_max = 100; 171 break; 172 case PM_PAR_SXY: 173 params_max = +q2; 174 break; 175 default: 176 psAbort("invalid parameter %d for param max test", nParam); 177 } 178 if (params[nParam] > params_max) { 179 params[nParam] = params_max; 180 psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g", 181 nParam, params[nParam], params_max); 182 return false; 183 } 184 return true; 185 default: 120 case PS_MINIMIZE_BETA_LIMIT: { 121 psAssert(beta, "Require beta to limit beta"); 122 float limit = betaUse[nParam]; 123 if (nParam == PM_PAR_SXY) { 124 limit *= q2; 125 } 126 if (fabs(beta[nParam]) > fabs(limit)) { 127 beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit); 128 psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g", 129 nParam, beta[nParam], limit); 130 return false; 131 } 132 return true; 133 } 134 case PS_MINIMIZE_PARAM_MIN: { 135 psAssert(params, "Require parameters to limit parameters"); 136 psAssert(paramsMinUse, "Require parameter limits to limit parameters"); 137 float limit = paramsMinUse[nParam]; 138 if (nParam == PM_PAR_SXY) { 139 limit *= q2; 140 } 141 if (params[nParam] < limit) { 142 params[nParam] = limit; 143 psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g", 144 nParam, params[nParam], limit); 145 return false; 146 } 147 return true; 148 } 149 case PS_MINIMIZE_PARAM_MAX: { 150 psAssert(params, "Require parameters to limit parameters"); 151 psAssert(paramsMaxUse, "Require parameter limits to limit parameters"); 152 float limit = paramsMaxUse[nParam]; 153 if (nParam == PM_PAR_SXY) { 154 limit *= q2; 155 } 156 if (params[nParam] > limit) { 157 params[nParam] = limit; 158 psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g", 159 nParam, params[nParam], limit); 160 return false; 161 } 162 return true; 163 } 164 default: 186 165 psAbort("invalid choice for limits"); 187 166 } … … 190 169 } 191 170 171 192 172 // make an initial guess for parameters 173 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters 193 174 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 194 175 { … … 205 186 psEllipseShape shape = psEllipseAxesToShape (axes); 206 187 207 PAR[PM_PAR_SKY] = moments->Sky;188 PAR[PM_PAR_SKY] = 0.0; 208 189 PAR[PM_PAR_I0] = peak->flux; 209 190 PAR[PM_PAR_XPOS] = peak->xf; … … 255 236 psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux) 256 237 { 257 psF64 z , f;238 psF64 z; 258 239 int Nstep = 0; 259 240 psEllipseShape shape; … … 284 265 // choose a z value guaranteed to be beyond our limit 285 266 float z0 = pow((1.0 / limit), (1.0 / 3.0)); 267 psAssert (isfinite(z0), "fix this code: z0 should not be nan for %f", PAR[PM_PAR_I0]); 286 268 float z1 = (1.0 / limit); 269 psAssert (isfinite(z1), "fix this code: z1 should not be nan for %f", PAR[PM_PAR_I0]); 287 270 z1 = PS_MAX (z0, z1); 288 271 z0 = 0.0; 289 272 290 // perform a type of bisection to find the value 291 float f0 = 1.0 / (1 + z0 + z0*z0/2.0 + z0*z0*z0/6.0); 292 float f1 = 1.0 / (1 + z1 + z1*z1/2.0 + z1*z1*z1/6.0); 293 while ((Nstep < 10) && (fabs(z1 - z0) > 0.5)) { 294 z = 0.5*(z0 + z1); 295 f = 1.0 / (1 + z + z*z/2.0 + z*z*z/6.0); 296 if (f > limit) { 297 z0 = z; 298 f0 = f; 299 } else { 300 z1 = z; 301 f1 = f; 302 } 303 Nstep ++; 304 } 273 // starting guess: 274 z = 0.5*(z0 + z1); 275 float dz = 1.0; 276 277 for (int i = 0; (i < 10) && (fabs(dz) > 0.0001); i++) { 278 // use Newton-Raphson to minimize f(z) - limit = 0 279 float dqdz = (1.0 + z + z*z/2.0); 280 float q = (dqdz + z*z*z/6.0); 281 282 float f = 1.0 / q; 283 float dfdz = -dqdz * f / q; 284 285 dz = (f - limit) / dfdz; 286 287 // fprintf (stderr, "%f %f %f : %f %f\n", f, z, dz, dfdz, q); 288 z -= dz; 289 z = PS_MAX(z, 0.0); 290 } 291 305 292 psF64 radius = sigma * sqrt (2.0 * z); 306 293 … … 415 402 bool PM_MODEL_FIT_STATUS (pmModel *model) 416 403 { 417 psF32 dP;418 404 bool status; 419 405 … … 421 407 psF32 *dPAR = model->dparams->data.F32; 422 408 423 dP = 0;424 dP += PS_SQR(dPAR[PM_PAR_SXX] / PAR[PM_PAR_SXX]);425 dP += PS_SQR(dPAR[PM_PAR_SYY] / PAR[PM_PAR_SYY]);426 dP = sqrt (dP);427 428 409 status = true; 429 status &= (dP < 0.5);430 410 status &= (PAR[PM_PAR_I0] > 0); 431 411 status &= ((dPAR[PM_PAR_I0]/PAR[PM_PAR_I0]) < 0.5); 432 412 433 413 return status; 414 } 415 416 417 void PM_MODEL_SET_LIMITS(pmModelLimitsType type) 418 { 419 switch (type) { 420 case PM_MODEL_LIMITS_NONE: 421 paramsMinUse = NULL; 422 paramsMaxUse = NULL; 423 limitsApply = true; 424 break; 425 case PM_MODEL_LIMITS_IGNORE: 426 paramsMinUse = NULL; 427 paramsMaxUse = NULL; 428 limitsApply = false; 429 break; 430 case PM_MODEL_LIMITS_LAX: 431 paramsMinUse = paramsMinLax; 432 paramsMaxUse = paramsMaxLax; 433 limitsApply = true; 434 break; 435 case PM_MODEL_LIMITS_MODERATE: 436 paramsMinUse = paramsMinModerate; 437 paramsMaxUse = paramsMaxModerate; 438 limitsApply = true; 439 break; 440 case PM_MODEL_LIMITS_STRICT: 441 paramsMinUse = paramsMinStrict; 442 paramsMaxUse = paramsMaxStrict; 443 limitsApply = true; 444 break; 445 default: 446 psAbort("Unrecognised model limits type: %x", type); 447 } 448 return; 434 449 } 435 450 … … 442 457 # undef PM_MODEL_PARAMS_FROM_PSF 443 458 # undef PM_MODEL_FIT_STATUS 459 # undef PM_MODEL_SET_LIMITS
Note:
See TracChangeset
for help on using the changeset viewer.
