- Timestamp:
- May 3, 2010, 8:45:22 AM (16 years ago)
- Location:
- branches/simmosaic_branches
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/simmosaic_branches
- Property svn:mergeinfo changed
-
branches/simmosaic_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/simmosaic_branches/psModules/src/objects/models/pmModel_PS1_V1.c
r23962 r27839 1 1 /****************************************************************************** 2 * this file defines the PS1_V1 source shape model (XXX need a better name!). Note that these3 * model functions are loaded by pmModelGroup.c using 'include', and thus need no 'include'4 * statements of their own. The models use a psVector to represent the set of parameters, with5 * the sequence used to specify the meaning of the parameter. The meaning of the parameters6 * may thus vary depending on the specifics of the model. All models which are used a PSF7 * representations share a fewparameters, for which # define names are listed in pmModel.h:2 * this file defines the PS1_V1 source shape model. Note that these model functions are loaded 3 * by pmModelClass.c using 'include', and thus need no 'include' statements of their own. The 4 * models use a psVector to represent the set of parameters, with the sequence used to specify 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 as a PSF representations share a few 7 * parameters, for which # define names are listed in pmModel.h: 8 8 9 9 power-law with fitted linear term … … 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_PS1_V1.h" 30 22 31 # define PM_MODEL_FUNC pmModelFunc_PS1_V1 23 32 # define PM_MODEL_FLUX pmModelFlux_PS1_V1 … … 28 37 # define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_PS1_V1 29 38 # define PM_MODEL_FIT_STATUS pmModelFitStatus_PS1_V1 39 # define PM_MODEL_SET_LIMITS pmModelSetLimits_PS1_V1 30 40 31 41 # define ALPHA 1.666 32 42 # define ALPHA_M 0.666 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? 33 68 34 69 psF32 PM_MODEL_FUNC (psVector *deriv, … … 84 119 bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta) 85 120 { 86 float beta_lim = 0, params_min = 0, params_max = 0; 87 float f1 = 0, f2 = 0, q1 = 0, q2 = 0; 121 if (!limitsApply) { 122 return true; 123 } 124 psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds"); 88 125 89 126 // we need to calculate the limits for SXY specially 127 float q2 = NAN; 90 128 if (nParam == PM_PAR_SXY) { 91 f 1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);92 f 2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);93 q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);129 float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]); 130 float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]); 131 float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2); 94 132 q1 = (q1 < 0.0) ? 0.0 : q1; 95 133 // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg.. Saturate at that 96 134 // angle and let f2,f1 fight it out 97 q2 = 0.5*sqrt(q1);135 q2 = 0.5*sqrtf(q1); 98 136 } 99 137 100 138 switch (mode) { 101 case PS_MINIMIZE_BETA_LIMIT: 102 switch (nParam) { 103 case PM_PAR_SKY: 104 beta_lim = 1000; 105 break; 106 case PM_PAR_I0: 107 beta_lim = 3e6; 108 break; 109 case PM_PAR_XPOS: 110 beta_lim = 5; 111 break; 112 case PM_PAR_YPOS: 113 beta_lim = 5; 114 break; 115 case PM_PAR_SXX: 116 beta_lim = 1.0; 117 break; 118 case PM_PAR_SYY: 119 beta_lim = 1.0; 120 break; 121 case PM_PAR_SXY: 122 beta_lim = 0.5*q2; 123 break; 124 case PM_PAR_7: 125 beta_lim = 2.0; 126 break; 127 default: 128 psAbort("invalid parameter %d for beta test", nParam); 129 } 130 if (fabs(beta[nParam]) > fabs(beta_lim)) { 131 beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim); 132 psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g", 133 nParam, beta[nParam], beta_lim); 134 return false; 135 } 136 return true; 137 case PS_MINIMIZE_PARAM_MIN: 138 switch (nParam) { 139 case PM_PAR_SKY: 140 params_min = -1000; 141 break; 142 case PM_PAR_I0: 143 params_min = 0.01; 144 break; 145 case PM_PAR_XPOS: 146 params_min = -100; 147 break; 148 case PM_PAR_YPOS: 149 params_min = -100; 150 break; 151 case PM_PAR_SXX: 152 params_min = 0.5; 153 break; 154 case PM_PAR_SYY: 155 params_min = 0.5; 156 break; 157 case PM_PAR_SXY: 158 params_min = -q2; 159 break; 160 case PM_PAR_7: 161 params_min = -1.0; 162 break; 163 default: 164 psAbort("invalid parameter %d for param min test", nParam); 165 } 166 if (params[nParam] < params_min) { 167 params[nParam] = params_min; 168 psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g", 169 nParam, params[nParam], params_min); 170 return false; 171 } 172 return true; 173 case PS_MINIMIZE_PARAM_MAX: 174 switch (nParam) { 175 case PM_PAR_SKY: 176 params_max = 1e5; 177 break; 178 case PM_PAR_I0: 179 params_max = 1e8; 180 break; 181 case PM_PAR_XPOS: 182 params_max = 1e4; 183 break; 184 case PM_PAR_YPOS: 185 params_max = 1e4; 186 break; 187 case PM_PAR_SXX: 188 params_max = 100; 189 break; 190 case PM_PAR_SYY: 191 params_max = 100; 192 break; 193 case PM_PAR_SXY: 194 params_max = +q2; 195 break; 196 case PM_PAR_7: 197 params_max = 20.0; 198 break; 199 default: 200 psAbort("invalid parameter %d for param max test", nParam); 201 } 202 if (params[nParam] > params_max) { 203 params[nParam] = params_max; 204 psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g", 205 nParam, params[nParam], params_max); 206 return false; 207 } 208 return true; 209 default: 139 case PS_MINIMIZE_BETA_LIMIT: { 140 psAssert(beta, "Require beta to limit beta"); 141 float limit = betaUse[nParam]; 142 if (nParam == PM_PAR_SXY) { 143 limit *= q2; 144 } 145 if (fabs(beta[nParam]) > fabs(limit)) { 146 beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit); 147 psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g", 148 nParam, beta[nParam], limit); 149 return false; 150 } 151 return true; 152 } 153 case PS_MINIMIZE_PARAM_MIN: { 154 psAssert(params, "Require parameters to limit parameters"); 155 psAssert(paramsMinUse, "Require parameter limits to limit parameters"); 156 float limit = paramsMinUse[nParam]; 157 if (nParam == PM_PAR_SXY) { 158 limit *= q2; 159 } 160 if (params[nParam] < limit) { 161 params[nParam] = limit; 162 psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g", 163 nParam, params[nParam], limit); 164 return false; 165 } 166 return true; 167 } 168 case PS_MINIMIZE_PARAM_MAX: { 169 psAssert(params, "Require parameters to limit parameters"); 170 psAssert(paramsMaxUse, "Require parameter limits to limit parameters"); 171 float limit = paramsMaxUse[nParam]; 172 if (nParam == PM_PAR_SXY) { 173 limit *= q2; 174 } 175 if (params[nParam] > limit) { 176 params[nParam] = limit; 177 psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g", 178 nParam, params[nParam], limit); 179 return false; 180 } 181 return true; 182 } 183 default: 210 184 psAbort("invalid choice for limits"); 211 185 } … … 216 190 217 191 // make an initial guess for parameters 192 // 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters 218 193 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 219 194 { … … 240 215 if (!isfinite(shape.sxy)) return false; 241 216 242 // XXX turn this off here for now PAR[PM_PAR_SKY] = moments->Sky;243 217 PAR[PM_PAR_SKY] = 0.0; 244 218 PAR[PM_PAR_I0] = peak->flux; … … 293 267 psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux) 294 268 { 295 psF64 z , f;269 psF64 z; 296 270 int Nstep = 0; 297 271 psEllipseShape shape; … … 299 273 psF32 *PAR = params->data.F32; 300 274 301 if (flux <= 0) 302 return (1.0); 303 if (PAR[PM_PAR_I0] <= 0) 304 return (1.0); 305 if (flux >= PAR[PM_PAR_I0]) 306 return (1.0); 275 if (flux <= 0) return 1.0; 276 if (PAR[PM_PAR_I0] <= 0) return 1.0; 277 if (flux >= PAR[PM_PAR_I0]) return 1.0; 278 if (PAR[PM_PAR_7] == 0.0) return powf(PAR[PM_PAR_I0] / flux - 1.0, 1.0 / ALPHA); 307 279 308 280 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2; … … 320 292 321 293 // choose a z value guaranteed to be beyond our limit 322 float z0 = pow((1.0 / limit), (1.0 / ALPHA)); 323 float z1 = (1.0 / limit) / PAR[PM_PAR_7]; 324 z1 = PS_MAX (z0, z1); 325 z0 = 0.0; 326 327 // perform a type of bisection to find the value 328 float f0 = 1.0 / (1 + PAR[PM_PAR_7]*z0 + pow(z0, ALPHA)); 329 float f1 = 1.0 / (1 + PAR[PM_PAR_7]*z1 + pow(z1, ALPHA)); 330 while ((Nstep < 10) && (fabs(z1 - z0) > 0.5)) { 331 z = 0.5*(z0 + z1); 332 f = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 333 if (f > limit) { 334 z0 = z; 335 f0 = f; 336 } else { 337 z1 = z; 338 f1 = f; 339 } 340 Nstep ++; 294 float z0 = 0.0; 295 float z1 = pow((1.0 / limit), (1.0 / ALPHA)); 296 psAssert (isfinite(z1), "fix this code: z1 should not be nan for %f", PAR[PM_PAR_7]); 297 if (PAR[PM_PAR_7] < 0.0) z1 *= 2.0; 298 299 // starting guess: 300 z = 0.5*(z0 + z1); 301 float dz = 1.0; 302 303 // use Newton-Raphson to minimize f(z) - limit = 0 304 for (int i = 0; (i < 10) && (fabs(dz) > 0.0001); i++) { 305 float q = (1.0 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 306 float dqdz = (PAR[PM_PAR_7] + ALPHA*pow(z, ALPHA - 1.0)); 307 308 float f = 1.0 / q; 309 float dfdz = -dqdz * f / q; 310 311 dz = (f - limit) / dfdz; 312 313 // fprintf (stderr, "%f %f %f : %f %f\n", f, z, dz, dfdz, q); 314 z -= dz; 315 z = PS_MAX(z, 0.0); 341 316 } 342 317 psF64 radius = sigma * sqrt (2.0 * z); … … 370 345 // convert to shape terms (SXX,SYY,SXY) 371 346 if (!pmPSF_FitToModel (out, 0.1)) { 372 // psError(PM_ERR_PSF, false, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);373 347 psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]); 374 348 return false; … … 448 422 bool PM_MODEL_FIT_STATUS (pmModel *model) 449 423 { 450 451 psF32 dP;452 424 bool status; 453 425 … … 455 427 psF32 *dPAR = model->dparams->data.F32; 456 428 457 dP = 0;458 dP += PS_SQR(dPAR[PM_PAR_SXX] / PAR[PM_PAR_SXX]);459 dP += PS_SQR(dPAR[PM_PAR_SYY] / PAR[PM_PAR_SYY]);460 dP = sqrt (dP);461 462 429 status = true; 463 // status &= (dP < 0.5);464 430 status &= (PAR[PM_PAR_I0] > 0); 465 431 status &= ((dPAR[PM_PAR_I0]/PAR[PM_PAR_I0]) < 0.5); 466 432 467 433 return status; 434 } 435 436 437 void PM_MODEL_SET_LIMITS(pmModelLimitsType type) 438 { 439 switch (type) { 440 case PM_MODEL_LIMITS_NONE: 441 paramsMinUse = NULL; 442 paramsMaxUse = NULL; 443 limitsApply = true; 444 break; 445 case PM_MODEL_LIMITS_IGNORE: 446 paramsMinUse = NULL; 447 paramsMaxUse = NULL; 448 limitsApply = false; 449 break; 450 case PM_MODEL_LIMITS_LAX: 451 paramsMinUse = paramsMinLax; 452 paramsMaxUse = paramsMaxLax; 453 limitsApply = true; 454 break; 455 case PM_MODEL_LIMITS_MODERATE: 456 paramsMinUse = paramsMinModerate; 457 paramsMaxUse = paramsMaxModerate; 458 limitsApply = true; 459 break; 460 case PM_MODEL_LIMITS_STRICT: 461 paramsMinUse = paramsMinStrict; 462 paramsMaxUse = paramsMaxStrict; 463 limitsApply = true; 464 break; 465 default: 466 psAbort("Unrecognised model limits type: %x", type); 467 } 468 return; 468 469 } 469 470 … … 476 477 # undef PM_MODEL_PARAMS_FROM_PSF 477 478 # undef PM_MODEL_FIT_STATUS 479 # undef PM_MODEL_SET_LIMITS 478 480 # undef ALPHA 479 481 # undef ALPHA_M
Note:
See TracChangeset
for help on using the changeset viewer.
