Changeset 27840 for branches/simtest_nebulous_branches/psModules/src/objects/models/pmModel_RGAUSS.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_RGAUSS.c
r20001 r27840 1 1 /****************************************************************************** 2 2 * this file defines the RGAUSS source shape model (XXX need a better name!). Note that these 3 * model functions are loaded by pmModel Group.c using 'include', and thus need no 'include'3 * model functions are loaded by pmModelClass.c using 'include', and thus need no 'include' 4 4 * statements of their own. The models use a psVector to represent the set of parameters, with 5 5 * the sequence used to specify the meaning of the parameter. The meaning of the parameters 6 * may thus vary depending on the specifics of the model. All models which are used a PSF6 * may thus vary depending on the specifics of the model. All models which are used as a PSF 7 7 * representations share a few parameters, for which # define names are listed in pmModel.h: 8 8 … … 20 20 *****************************************************************************/ 21 21 22 #include <stdio.h> 23 #include <pslib.h> 24 25 #include "pmMoments.h" 26 #include "pmPeaks.h" 27 #include "pmSource.h" 28 #include "pmModel.h" 29 #include "pmModel_RGAUSS.h" 30 22 31 # define PM_MODEL_FUNC pmModelFunc_RGAUSS 23 32 # define PM_MODEL_FLUX pmModelFlux_RGAUSS … … 28 37 # define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_RGAUSS 29 38 # define PM_MODEL_FIT_STATUS pmModelFitStatus_RGAUSS 39 # define PM_MODEL_SET_LIMITS pmModelSetLimits_RGAUSS 40 41 // the model is a function of the pixel coordinate (pixcoord[0,1] = x,y) 42 // 0.5 PIX: the parameters are defined in terms of pixel coords, so the incoming pixcoords 43 // values need to be pixel coords 44 45 // Lax parameter limits 46 static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, 1.25 }; 47 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 4.0 }; 48 49 // Moderate parameter limits 50 static float *paramsMinModerate = paramsMinLax; 51 static float *paramsMaxModerate = paramsMaxLax; 52 53 // Strict parameter limits 54 static float *paramsMinStrict = paramsMinLax; 55 static float *paramsMaxStrict = paramsMaxLax; 56 57 // Parameter limits to use 58 static float *paramsMinUse = paramsMinLax; 59 static float *paramsMaxUse = paramsMaxLax; 60 static float betaUse[] = { 1000, 3e6, 5, 5, 0.5, 0.5, 0.5, 0.5 }; 61 62 static bool limitsApply = true; // Apply limits? 30 63 31 64 psF32 PM_MODEL_FUNC (psVector *deriv, … … 62 95 dPAR[PM_PAR_SXY] = -q*X*Y; 63 96 64 // this model derivative is undefined at z = 0.0, but is actually0.097 // this model derivative is undefined at z = 0.0, but the limit is zero as z -> 0.0 65 98 dPAR[PM_PAR_7] = (z == 0.0) ? 0.0 : -5.0*t*log(z)*p*z; 66 99 } … … 73 106 # define AR_MAX 20.0 74 107 # define AR_RATIO 0.99 108 75 109 bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta) 76 110 { 77 float beta_lim = 0, params_min = 0, params_max = 0; 78 float f1 = 0, f2 = 0, q1 = 0, q2 = 0; 111 if (!limitsApply) { 112 return true; 113 } 114 psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds"); 79 115 80 116 // we need to calculate the limits for SXY specially 117 float q2 = NAN; 81 118 if (nParam == PM_PAR_SXY) { 82 f 1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);83 f 2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);84 q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);119 float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]); 120 float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]); 121 float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2); 85 122 q1 = (q1 < 0.0) ? 0.0 : q1; 86 123 // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg.. Saturate at that 87 124 // angle and let f2,f1 fight it out 88 q2 = 0.5*sqrt(q1);125 q2 = 0.5*sqrtf(q1); 89 126 } 90 127 91 128 switch (mode) { 92 case PS_MINIMIZE_BETA_LIMIT: 93 switch (nParam) { 94 case PM_PAR_SKY: 95 beta_lim = 1000; 96 break; 97 case PM_PAR_I0: 98 beta_lim = 3e6; 99 break; 100 case PM_PAR_XPOS: 101 beta_lim = 5; 102 break; 103 case PM_PAR_YPOS: 104 beta_lim = 5; 105 break; 106 case PM_PAR_SXX: 107 beta_lim = 0.5; 108 break; 109 case PM_PAR_SYY: 110 beta_lim = 0.5; 111 break; 112 case PM_PAR_SXY: 113 beta_lim = 0.5*q2; 114 break; 115 case PM_PAR_7: 116 beta_lim = 0.5; 117 break; 118 default: 119 psAbort("invalid parameter %d for beta test", nParam); 120 } 121 if (fabs(beta[nParam]) > fabs(beta_lim)) { 122 beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim); 123 psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g", 124 nParam, beta[nParam], beta_lim); 125 return false; 126 } 127 return true; 128 case PS_MINIMIZE_PARAM_MIN: 129 switch (nParam) { 130 case PM_PAR_SKY: 131 params_min = -1000; 132 break; 133 case PM_PAR_I0: 134 params_min = 0.01; 135 break; 136 case PM_PAR_XPOS: 137 params_min = -100; 138 break; 139 case PM_PAR_YPOS: 140 params_min = -100; 141 break; 142 case PM_PAR_SXX: 143 params_min = 0.5; 144 break; 145 case PM_PAR_SYY: 146 params_min = 0.5; 147 break; 148 case PM_PAR_SXY: 149 params_min = -q2; 150 break; 151 case PM_PAR_7: 152 params_min = 1.25; 153 break; 154 default: 155 psAbort("invalid parameter %d for param min test", nParam); 156 } 157 if (params[nParam] < params_min) { 158 params[nParam] = params_min; 159 psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g", 160 nParam, params[nParam], params_min); 161 return false; 162 } 163 return true; 164 case PS_MINIMIZE_PARAM_MAX: 165 switch (nParam) { 166 case PM_PAR_SKY: 167 params_max = 1e5; 168 break; 169 case PM_PAR_I0: 170 params_max = 1e8; 171 break; 172 case PM_PAR_XPOS: 173 params_max = 1e4; 174 break; 175 case PM_PAR_YPOS: 176 params_max = 1e4; 177 break; 178 case PM_PAR_SXX: 179 params_max = 100; 180 break; 181 case PM_PAR_SYY: 182 params_max = 100; 183 break; 184 case PM_PAR_SXY: 185 params_max = +q2; 186 break; 187 case PM_PAR_7: 188 params_max = 4.0; 189 break; 190 default: 191 psAbort("invalid parameter %d for param max test", nParam); 192 } 193 if (params[nParam] > params_max) { 194 params[nParam] = params_max; 195 psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g", 196 nParam, params[nParam], params_max); 197 return false; 198 } 199 return true; 200 default: 129 case PS_MINIMIZE_BETA_LIMIT: { 130 psAssert(beta, "Require beta to limit beta"); 131 float limit = betaUse[nParam]; 132 if (nParam == PM_PAR_SXY) { 133 limit *= q2; 134 } 135 if (fabs(beta[nParam]) > fabs(limit)) { 136 beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit); 137 psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g", 138 nParam, beta[nParam], limit); 139 return false; 140 } 141 return true; 142 } 143 case PS_MINIMIZE_PARAM_MIN: { 144 psAssert(params, "Require parameters to limit parameters"); 145 psAssert(paramsMinUse, "Require parameter limits to limit parameters"); 146 float limit = paramsMinUse[nParam]; 147 if (nParam == PM_PAR_SXY) { 148 limit *= q2; 149 } 150 if (params[nParam] < limit) { 151 params[nParam] = limit; 152 psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g", 153 nParam, params[nParam], limit); 154 return false; 155 } 156 return true; 157 } 158 case PS_MINIMIZE_PARAM_MAX: { 159 psAssert(params, "Require parameters to limit parameters"); 160 psAssert(paramsMaxUse, "Require parameter limits to limit parameters"); 161 float limit = paramsMaxUse[nParam]; 162 if (nParam == PM_PAR_SXY) { 163 limit *= q2; 164 } 165 if (params[nParam] > limit) { 166 params[nParam] = limit; 167 psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g", 168 nParam, params[nParam], limit); 169 return false; 170 } 171 return true; 172 } 173 default: 201 174 psAbort("invalid choice for limits"); 202 175 } … … 205 178 } 206 179 180 207 181 // make an initial guess for parameters 182 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters 208 183 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 209 184 { … … 230 205 if (!isfinite(shape.sxy)) return false; 231 206 232 PAR[PM_PAR_SKY] = moments->Sky;207 PAR[PM_PAR_SKY] = 0.0; 233 208 PAR[PM_PAR_I0] = peak->flux; 234 209 PAR[PM_PAR_XPOS] = peak->xf; … … 282 257 psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux) 283 258 { 284 psF64 z , f;259 psF64 z; 285 260 int Nstep = 0; 286 261 psEllipseShape shape; … … 310 285 // choose a z value guaranteed to be beyond our limit 311 286 float z0 = pow((1.0 / limit), (1.0 / PAR[PM_PAR_7])); 287 psAssert (isfinite(z0), "fix this code: z0 should not be nan for %f", PAR[PM_PAR_7]); 312 288 float z1 = (1.0 / limit); 289 psAssert (isfinite(z1), "fix this code: z1 should not be nan for %f", PAR[PM_PAR_7]); 313 290 z1 = PS_MAX (z0, z1); 314 291 z0 = 0.0; 315 292 316 // perform a type of bisection to find the value 317 float f0 = 1.0 / (1 + z0 + pow(z0, PAR[PM_PAR_7])); 318 float f1 = 1.0 / (1 + z1 + pow(z1, PAR[PM_PAR_7])); 319 while ((Nstep < 10) && (fabs(z1 - z0) > 0.5)) { 320 z = 0.5*(z0 + z1); 321 f = 1.0 / (1 + z + pow(z, PAR[PM_PAR_7])); 322 if (f > limit) { 323 z0 = z; 324 f0 = f; 325 } else { 326 z1 = z; 327 f1 = f; 328 } 329 Nstep ++; 330 } 293 // starting guess: 294 z = 0.5*(z0 + z1); 295 float dz = 1.0; 296 297 for (int i = 0; (i < 10) && (fabs(dz) > 0.0001); i++) { 298 // use Newton-Raphson to minimize f(z) - limit = 0 299 float q = (1 + z + pow(z,PAR[PM_PAR_7])); 300 float dqdz = (1.0 + PAR[PM_PAR_7]*pow(z,PAR[PM_PAR_7] - 1.0)); 301 302 float f = 1.0 / q; 303 float dfdz = -dqdz * f / q; 304 305 dz = (f - limit) / dfdz; 306 307 // fprintf (stderr, "%f %f %f : %f %f\n", f, z, dz, dfdz, q); 308 z -= dz; 309 z = PS_MAX(z, 0.0); 310 } 311 331 312 psF64 radius = sigma * sqrt (2.0 * z); 332 313 … … 436 417 bool PM_MODEL_FIT_STATUS (pmModel *model) 437 418 { 438 439 psF32 dP;440 419 bool status; 441 420 … … 443 422 psF32 *dPAR = model->dparams->data.F32; 444 423 445 dP = 0;446 dP += PS_SQR(dPAR[PM_PAR_SXX] / PAR[PM_PAR_SXX]);447 dP += PS_SQR(dPAR[PM_PAR_SYY] / PAR[PM_PAR_SYY]);448 dP = sqrt (dP);449 450 424 status = true; 451 status &= (dP < 0.5);452 425 status &= (PAR[PM_PAR_I0] > 0); 453 426 status &= ((dPAR[PM_PAR_I0]/PAR[PM_PAR_I0]) < 0.5); 454 427 455 428 return status; 429 } 430 431 432 void PM_MODEL_SET_LIMITS(pmModelLimitsType type) 433 { 434 switch (type) { 435 case PM_MODEL_LIMITS_NONE: 436 paramsMinUse = NULL; 437 paramsMaxUse = NULL; 438 limitsApply = true; 439 break; 440 case PM_MODEL_LIMITS_IGNORE: 441 paramsMinUse = NULL; 442 paramsMaxUse = NULL; 443 limitsApply = false; 444 break; 445 case PM_MODEL_LIMITS_LAX: 446 paramsMinUse = paramsMinLax; 447 paramsMaxUse = paramsMaxLax; 448 limitsApply = true; 449 break; 450 case PM_MODEL_LIMITS_MODERATE: 451 paramsMinUse = paramsMinModerate; 452 paramsMaxUse = paramsMaxModerate; 453 limitsApply = true; 454 break; 455 case PM_MODEL_LIMITS_STRICT: 456 paramsMinUse = paramsMinStrict; 457 paramsMaxUse = paramsMaxStrict; 458 limitsApply = true; 459 break; 460 default: 461 psAbort("Unrecognised model limits type: %x", type); 462 } 463 return; 456 464 } 457 465 … … 464 472 # undef PM_MODEL_PARAMS_FROM_PSF 465 473 # undef PM_MODEL_FIT_STATUS 474 # undef PM_MODEL_SET_LIMITS
Note:
See TracChangeset
for help on using the changeset viewer.
