Changeset 27840 for branches/simtest_nebulous_branches/psModules/src/objects/models/pmModel_QGAUSS.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_QGAUSS.c
r20001 r27840 1 1 /****************************************************************************** 2 2 * this file defines the QGAUSS 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 … … 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_QGAUSS.h" 30 22 31 # define PM_MODEL_FUNC pmModelFunc_QGAUSS 23 32 # define PM_MODEL_FLUX pmModelFlux_QGAUSS … … 28 37 # define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_QGAUSS 29 38 # define PM_MODEL_FIT_STATUS pmModelFitStatus_QGAUSS 39 # define PM_MODEL_SET_LIMITS pmModelSetLimits_QGAUSS 40 41 # define ALPHA 2.250 42 # define ALPHA_M 1.250 43 44 // the model is a function of the pixel coordinate (pixcoord[0,1] = x,y) 45 // 0.5 PIX: the parameters are defined in terms of pixel coords, so the incoming pixcoords 46 // values need to be pixel coords 47 48 // Lax parameter limits 49 static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, -1.0 }; 50 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 }; 51 52 // Moderate parameter limits 53 // Tolerate a small divot (k < 0) 54 static float paramsMinModerate[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, -0.05 }; 55 static float paramsMaxModerate[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 }; 56 57 // Strict parameter limits 58 // k = PAR_7 < 0 is very undesirable (big divot in the middle) 59 static float paramsMinStrict[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, 0.0 }; 60 static float paramsMaxStrict[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 }; 61 62 // Parameter limits to use 63 static float *paramsMinUse = paramsMinLax; 64 static float *paramsMaxUse = paramsMaxLax; 65 static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5, 2.0 }; 66 67 static bool limitsApply = true; // Apply limits? 30 68 31 69 psF32 PM_MODEL_FUNC (psVector *deriv, … … 48 86 assert (z >= 0); 49 87 50 psF32 zp = pow(z, 1.25);88 psF32 zp = pow(z,ALPHA_M); 51 89 psF32 r = 1.0 / (1 + PAR[PM_PAR_7]*z + z*zp); 52 90 … … 59 97 // note difference from a pure gaussian: q = params->data.F32[PM_PAR_I0]*r 60 98 psF32 t = r1*r; 61 psF32 q = t*(PAR[PM_PAR_7] + 2.25*zp);99 psF32 q = t*(PAR[PM_PAR_7] + ALPHA*zp); 62 100 63 101 dPAR[PM_PAR_SKY] = +1.0; … … 79 117 # define AR_MAX 20.0 80 118 # define AR_RATIO 0.99 119 81 120 bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta) 82 121 { 83 float beta_lim = 0, params_min = 0, params_max = 0; 84 float f1 = 0, f2 = 0, q1 = 0, q2 = 0; 122 if (!limitsApply) { 123 return true; 124 } 125 psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds"); 85 126 86 127 // we need to calculate the limits for SXY specially 128 float q2 = NAN; 87 129 if (nParam == PM_PAR_SXY) { 88 f 1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);89 f 2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);90 q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);130 float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]); 131 float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]); 132 float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2); 91 133 q1 = (q1 < 0.0) ? 0.0 : q1; 92 134 // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg.. Saturate at that 93 135 // angle and let f2,f1 fight it out 94 q2 = 0.5*sqrt(q1);136 q2 = 0.5*sqrtf(q1); 95 137 } 96 138 97 139 switch (mode) { 98 case PS_MINIMIZE_BETA_LIMIT: 99 switch (nParam) { 100 case PM_PAR_SKY: 101 beta_lim = 1000; 102 break; 103 case PM_PAR_I0: 104 beta_lim = 3e6; 105 break; 106 case PM_PAR_XPOS: 107 beta_lim = 5; 108 break; 109 case PM_PAR_YPOS: 110 beta_lim = 5; 111 break; 112 case PM_PAR_SXX: 113 beta_lim = 1.0; 114 break; 115 case PM_PAR_SYY: 116 beta_lim = 1.0; 117 break; 118 case PM_PAR_SXY: 119 beta_lim = 0.5*q2; 120 break; 121 case PM_PAR_7: 122 beta_lim = 2.0; 123 break; 124 default: 125 psAbort("invalid parameter %d for beta test", nParam); 126 } 127 if (fabs(beta[nParam]) > fabs(beta_lim)) { 128 beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim); 129 psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g", 130 nParam, beta[nParam], beta_lim); 131 return false; 132 } 133 return true; 134 case PS_MINIMIZE_PARAM_MIN: 135 switch (nParam) { 136 case PM_PAR_SKY: 137 params_min = -1000; 138 break; 139 case PM_PAR_I0: 140 params_min = 0.01; 141 break; 142 case PM_PAR_XPOS: 143 params_min = -100; 144 break; 145 case PM_PAR_YPOS: 146 params_min = -100; 147 break; 148 case PM_PAR_SXX: 149 params_min = 0.5; 150 break; 151 case PM_PAR_SYY: 152 params_min = 0.5; 153 break; 154 case PM_PAR_SXY: 155 params_min = -q2; 156 break; 157 case PM_PAR_7: 158 params_min = 0.1; 159 break; 160 default: 161 psAbort("invalid parameter %d for param min test", nParam); 162 } 163 if (params[nParam] < params_min) { 164 params[nParam] = params_min; 165 psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g", 166 nParam, params[nParam], params_min); 167 return false; 168 } 169 return true; 170 case PS_MINIMIZE_PARAM_MAX: 171 switch (nParam) { 172 case PM_PAR_SKY: 173 params_max = 1e5; 174 break; 175 case PM_PAR_I0: 176 params_max = 1e8; 177 break; 178 case PM_PAR_XPOS: 179 params_max = 1e4; 180 break; 181 case PM_PAR_YPOS: 182 params_max = 1e4; 183 break; 184 case PM_PAR_SXX: 185 params_max = 100; 186 break; 187 case PM_PAR_SYY: 188 params_max = 100; 189 break; 190 case PM_PAR_SXY: 191 params_max = +q2; 192 break; 193 case PM_PAR_7: 194 params_max = 20.0; 195 break; 196 default: 197 psAbort("invalid parameter %d for param max test", nParam); 198 } 199 if (params[nParam] > params_max) { 200 params[nParam] = params_max; 201 psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g", 202 nParam, params[nParam], params_max); 203 return false; 204 } 205 return true; 140 case PS_MINIMIZE_BETA_LIMIT: { 141 psAssert(beta, "Require beta to limit beta"); 142 float limit = betaUse[nParam]; 143 if (nParam == PM_PAR_SXY) { 144 limit *= q2; 145 } 146 if (fabs(beta[nParam]) > fabs(limit)) { 147 beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit); 148 psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g", 149 nParam, beta[nParam], limit); 150 return false; 151 } 152 return true; 153 } 154 case PS_MINIMIZE_PARAM_MIN: { 155 psAssert(params, "Require parameters to limit parameters"); 156 psAssert(paramsMinUse, "Require parameter limits to limit parameters"); 157 float limit = paramsMinUse[nParam]; 158 if (nParam == PM_PAR_SXY) { 159 limit *= q2; 160 } 161 if (params[nParam] < limit) { 162 params[nParam] = limit; 163 psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g", 164 nParam, params[nParam], limit); 165 return false; 166 } 167 return true; 168 } 169 case PS_MINIMIZE_PARAM_MAX: { 170 psAssert(params, "Require parameters to limit parameters"); 171 psAssert(paramsMaxUse, "Require parameter limits to limit parameters"); 172 float limit = paramsMaxUse[nParam]; 173 if (nParam == PM_PAR_SXY) { 174 limit *= q2; 175 } 176 if (params[nParam] > limit) { 177 params[nParam] = limit; 178 psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g", 179 nParam, params[nParam], limit); 180 return false; 181 } 182 return true; 183 } 206 184 default: 207 185 psAbort("invalid choice for limits"); … … 213 191 214 192 // make an initial guess for parameters 193 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters 215 194 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 216 195 { … … 237 216 if (!isfinite(shape.sxy)) return false; 238 217 239 // XXX turn this off here for now PAR[PM_PAR_SKY] = moments->Sky;240 218 PAR[PM_PAR_SKY] = 0.0; 241 219 PAR[PM_PAR_I0] = peak->flux; … … 273 251 float f1, f2; 274 252 for (z = DZ; z < 50; z += DZ) { 275 f1 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, 2.25));253 f1 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 276 254 z += DZ; 277 f2 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, 2.25));255 f2 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 278 256 norm += f0 + 4*f1 + f2; 279 257 f0 = f2; … … 290 268 psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux) 291 269 { 292 psF64 z , f;270 psF64 z; 293 271 int Nstep = 0; 294 272 psEllipseShape shape; … … 296 274 psF32 *PAR = params->data.F32; 297 275 298 if (flux <= 0) 299 return (1.0); 300 if (PAR[PM_PAR_I0] <= 0) 301 return (1.0); 302 if (flux >= PAR[PM_PAR_I0]) 303 return (1.0); 276 if (flux <= 0) return 1.0; 277 if (PAR[PM_PAR_I0] <= 0) return 1.0; 278 if (flux >= PAR[PM_PAR_I0]) return 1.0; 279 if (PAR[PM_PAR_7] == 0.0) return powf(PAR[PM_PAR_I0] / flux - 1.0, 1.0 / ALPHA); 304 280 305 281 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2; … … 317 293 318 294 // choose a z value guaranteed to be beyond our limit 319 float z0 = pow((1.0 / limit), (1.0 / 2.25)); 320 float z1 = (1.0 / limit) / PAR[PM_PAR_7]; 321 z1 = PS_MAX (z0, z1); 322 z0 = 0.0; 323 324 // perform a type of bisection to find the value 325 float f0 = 1.0 / (1 + PAR[PM_PAR_7]*z0 + pow(z0, 2.25)); 326 float f1 = 1.0 / (1 + PAR[PM_PAR_7]*z1 + pow(z1, 2.25)); 327 while ((Nstep < 10) && (fabs(z1 - z0) > 0.5)) { 328 z = 0.5*(z0 + z1); 329 f = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, 2.25)); 330 if (f > limit) { 331 z0 = z; 332 f0 = f; 333 } else { 334 z1 = z; 335 f1 = f; 336 } 337 Nstep ++; 295 float z0 = 0.0; 296 float z1 = pow((1.0 / limit), (1.0 / ALPHA)); 297 psAssert (isfinite(z1), "fix this code: z1 should not be nan for %f", PAR[PM_PAR_7]); 298 if (PAR[PM_PAR_7] < 0.0) z1 *= 2.0; 299 300 // starting guess: 301 z = 0.5*(z0 + z1); 302 float dz = 1.0; 303 304 // use Newton-Raphson to minimize f(z) - limit = 0 305 for (int i = 0; (i < 10) && (fabs(dz) > 0.0001); i++) { 306 float q = (1.0 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 307 float dqdz = (PAR[PM_PAR_7] + ALPHA*pow(z, ALPHA - 1.0)); 308 309 float f = 1.0 / q; 310 float dfdz = -dqdz * f / q; 311 312 dz = (f - limit) / dfdz; 313 314 // fprintf (stderr, "%f %f %f : %f %f\n", f, z, dz, dfdz, q); 315 z -= dz; 316 z = PS_MAX(z, 0.0); 338 317 } 339 318 psF64 radius = sigma * sqrt (2.0 * z); … … 444 423 bool PM_MODEL_FIT_STATUS (pmModel *model) 445 424 { 446 447 psF32 dP;448 425 bool status; 449 426 … … 451 428 psF32 *dPAR = model->dparams->data.F32; 452 429 453 dP = 0;454 dP += PS_SQR(dPAR[PM_PAR_SXX] / PAR[PM_PAR_SXX]);455 dP += PS_SQR(dPAR[PM_PAR_SYY] / PAR[PM_PAR_SYY]);456 dP = sqrt (dP);457 458 430 status = true; 459 // status &= (dP < 0.5);460 431 status &= (PAR[PM_PAR_I0] > 0); 461 432 status &= ((dPAR[PM_PAR_I0]/PAR[PM_PAR_I0]) < 0.5); 462 433 463 434 return status; 435 } 436 437 438 void PM_MODEL_SET_LIMITS(pmModelLimitsType type) 439 { 440 switch (type) { 441 case PM_MODEL_LIMITS_NONE: 442 paramsMinUse = NULL; 443 paramsMaxUse = NULL; 444 limitsApply = true; 445 break; 446 case PM_MODEL_LIMITS_IGNORE: 447 paramsMinUse = NULL; 448 paramsMaxUse = NULL; 449 limitsApply = false; 450 break; 451 case PM_MODEL_LIMITS_LAX: 452 paramsMinUse = paramsMinLax; 453 paramsMaxUse = paramsMaxLax; 454 limitsApply = true; 455 break; 456 case PM_MODEL_LIMITS_MODERATE: 457 paramsMinUse = paramsMinModerate; 458 paramsMaxUse = paramsMaxModerate; 459 limitsApply = true; 460 break; 461 case PM_MODEL_LIMITS_STRICT: 462 paramsMinUse = paramsMinStrict; 463 paramsMaxUse = paramsMaxStrict; 464 limitsApply = true; 465 break; 466 default: 467 psAbort("Unrecognised model limits type: %x", type); 468 } 469 return; 464 470 } 465 471 … … 472 478 # undef PM_MODEL_PARAMS_FROM_PSF 473 479 # undef PM_MODEL_FIT_STATUS 480 # undef PM_MODEL_SET_LIMITS 481 # undef ALPHA 482 # undef ALPHA_M
Note:
See TracChangeset
for help on using the changeset viewer.
