Changeset 36680 for branches/eam_branches/ps2-tc3-20130727/psModules/src/objects/models/pmModel_DEV.c
- Timestamp:
- Apr 21, 2014, 5:42:34 AM (12 years ago)
- Location:
- branches/eam_branches/ps2-tc3-20130727
- Files:
-
- 4 edited
-
. (modified) (1 prop)
-
psModules (modified) (1 prop)
-
psModules/src/objects (modified) (1 prop)
-
psModules/src/objects/models/pmModel_DEV.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ps2-tc3-20130727
- Property svn:mergeinfo changed
-
branches/eam_branches/ps2-tc3-20130727/psModules
- Property svn:mergeinfo deleted
-
branches/eam_branches/ps2-tc3-20130727/psModules/src/objects
- Property svn:ignore
-
old new 12 12 pmSourceIO_CMF_PS1_V1.v1.c 13 13 pmSourceIO_CMF_PS1_V4.c 14 pmSourceIO_CMF_PS1_V5.c 14 15 pmSourceIO_CMF_PS1_SV1.c 15 16 pmSourceIO_CMF_PS1_SV2.c
-
- Property svn:ignore
-
branches/eam_branches/ps2-tc3-20130727/psModules/src/objects/models/pmModel_DEV.c
r35768 r36680 16 16 * PM_PAR_SYY 5 - Y^2 term of elliptical contour (sqrt(2) / SigmaY) 17 17 * PM_PAR_SXY 6 - X*Y term of elliptical contour 18 * PM_PAR_7 7 - normalized dev parameter19 18 20 19 note that a standard dev model uses exp(-K*(z^(1/2n) - 1). the additional elements (K, … … 44 43 #include "pmSourceDiffStats.h" 45 44 #include "pmSourceSatstar.h" 45 #include "pmSourceLensing.h" 46 46 #include "pmSource.h" 47 47 #include "pmSourceFitModel.h" … … 49 49 #include "pmPSFtry.h" 50 50 #include "pmDetections.h" 51 #include "pmModel_CentralPixel.h" 51 52 52 53 #include "pmModel_DEV.h" … … 63 64 # define PM_MODEL_SET_LIMITS pmModelSetLimits_DEV 64 65 65 // f = exp(-z^0.125) 66 // f = exp(-kappa*r^(1/index)) 67 // f = exp(-kappa*z^(0.5/index)) 68 // index = 4, 0.5/index = 0.125 66 69 # define ALPHA 0.125 67 // # define ALPHA 0.2568 70 69 71 // the model is a function of the pixel coordinate (pixcoord[0,1] = x,y) … … 73 75 // Lax parameter limits 74 76 static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.001, 0.001, -1.0 }; 75 static float paramsMaxLax[] = { 1.0e5, 1.0e 8, 1.0e4, 1.0e4, 100, 100, 1.0 };77 static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0 }; 76 78 77 79 // Moderate parameter limits … … 86 88 static float *paramsMinUse = paramsMinLax; 87 89 static float *paramsMaxUse = paramsMaxLax; 88 static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5 };90 static float betaUse[] = { 2, 3e6, 5, 5, 10.0, 10.0, 0.5 }; 89 91 90 92 static bool limitsApply = true; // Apply limits? 91 92 # include "pmModel_SERSIC.CP.h"93 93 94 94 psF32 PM_MODEL_FUNC (psVector *deriv, … … 109 109 psAssert (z >= 0, "do not allow negative z values in model"); 110 110 111 float index = 0.5 / ALPHA; 112 float par7 = ALPHA; 113 float bn = 1.9992*index - 0.3271; 114 float Io = exp(bn); 115 116 psF32 f2 = bn*pow(z,ALPHA); 117 psF32 f1 = Io*exp(-f2); 118 119 psF32 radius = hypot(X, Y); 120 if (radius < 1.0) { 121 122 // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center 123 124 // first, use Rmajor and index to find the central pixel flux (fraction of total flux) 125 psEllipseAxes axes; 126 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 127 128 // get the central pixel flux from the lookup table 129 float xPix = (axes.major - centralPixelXo) / centralPixeldX; 130 xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1); 131 float yPix = (index - centralPixelYo) / centralPixeldY; 132 yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1); 133 134 // the integral of a Sersic has an analytical form as follows: 135 float logGamma = lgamma(2.0*index); 136 float bnFactor = pow(bn, 2.0*index); 137 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 138 139 // XXX interpolate to get the value 140 // XXX for the moment, just integerize 141 // XXX I need to multiply by the integrated flux to get the flux in the central pixel 142 float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm; 143 144 float px1 = 1.0 / PAR[PM_PAR_SXX]; 145 float py1 = 1.0 / PAR[PM_PAR_SYY]; 146 float z10 = PS_SQR(px1); 147 float z01 = PS_SQR(py1); 148 149 // which pixels do we need for this interpolation? 150 // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...) 151 if ((X >= 0) && (Y >= 0)) { 152 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 153 float V00 = Vcenter; 154 float V10 = Io*exp(-bn*pow(z10,par7)); 155 float V01 = Io*exp(-bn*pow(z01,par7)); 156 float V11 = Io*exp(-bn*pow(z11,par7)); 157 f1 = interpolatePixels(V00, V10, V01, V11, X, Y); 158 } 159 if ((X < 0) && (Y >= 0)) { 160 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 161 float V00 = Io*exp(-bn*pow(z10,par7)); 162 float V10 = Vcenter; 163 float V01 = Io*exp(-bn*pow(z11,par7)); 164 float V11 = Io*exp(-bn*pow(z01,par7)); 165 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y); 166 } 167 if ((X >= 0) && (Y < 0)) { 168 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 169 float V00 = Io*exp(-bn*pow(z01,par7)); 170 float V10 = Io*exp(-bn*pow(z11,par7)); 171 float V01 = Vcenter; 172 float V11 = Io*exp(-bn*pow(z10,par7)); 173 f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y)); 174 } 175 if ((X < 0) && (Y < 0)) { 176 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 177 float V00 = Io*exp(-bn*pow(z11,par7)); 178 float V10 = Io*exp(-bn*pow(z10,par7)); 179 float V01 = Io*exp(-bn*pow(z01,par7)); 180 float V11 = Vcenter; 181 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y)); 182 } 111 // for DEV, we can hard-wire kappa(4): 112 // float index = 4.0; 113 float kappa = 7.670628; 114 115 // r = sqrt(z) 116 float q = kappa*pow(z,ALPHA); 117 float f0 = exp(-q); 118 119 assert (isfinite(q)); 120 121 // only worry about the central pixels at most 122 float radius = hypot(X, Y); 123 if (radius <= 1.5) { 124 // Nsub ~ 10*index^2 + 1 125 psEllipseAxes axes = pmPSF_ModelToAxes(PAR, pmModelClassGetType ("PS_MODEL_DEV")); 126 int Nsub = 2 * ((int)(25 / axes.minor)) + 1; 127 Nsub = PS_MIN (Nsub, 121); 128 Nsub = PS_MAX (Nsub, 11); 129 f0 = pmModelCP_SersicSubpix (X, Y, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], 4.0, Nsub); 183 130 } 184 185 psF32 z0 = PAR[PM_PAR_I0]*f1; 186 psF32 f0 = PAR[PM_PAR_SKY] + z0;187 188 assert (isfinite(f2)); 131 assert (isfinite(f0)); 132 133 float f1 = PAR[PM_PAR_I0]*f0; 134 float f = PAR[PM_PAR_SKY] + f1; 135 189 136 assert (isfinite(f1)); 190 assert (isfinite(z0)); 191 assert (isfinite(f0)); 137 assert (isfinite(f)); 192 138 193 139 if (deriv != NULL) { … … 195 141 196 142 dPAR[PM_PAR_SKY] = +1.0; 197 dPAR[PM_PAR_I0] = +2.0*f1; // XXX extra damping.. 198 199 // gradient is infinite for z = 0; saturate at z = 0.01 200 psF32 z1 = (z < 0.01) ? z0*bn*ALPHA*pow(0.01,ALPHA - 1.0) : z0*bn*ALPHA*pow(z,ALPHA - 1.0); 201 202 assert (isfinite(z1)); 203 204 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px/PAR[PM_PAR_SXX] + Y*PAR[PM_PAR_SXY]); 205 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py/PAR[PM_PAR_SYY] + X*PAR[PM_PAR_SXY]); 206 dPAR[PM_PAR_SXX] = +2.0*z1*px*px/PAR[PM_PAR_SXX]; 207 dPAR[PM_PAR_SYY] = +2.0*z1*py*py/PAR[PM_PAR_SYY]; 208 dPAR[PM_PAR_SXY] = -1.0*z1*X*Y; 209 } 210 return (f0); 143 dPAR[PM_PAR_I0] = +f0; 144 145 if (z > 0.01) { 146 float z1 = f1*kappa*ALPHA*pow(z,ALPHA-1.0); 147 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px + Y*PAR[PM_PAR_SXY]); 148 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py + X*PAR[PM_PAR_SXY]); 149 dPAR[PM_PAR_SXX] = +2.0*z1*px*px/PAR[PM_PAR_SXX]; 150 dPAR[PM_PAR_SYY] = +2.0*z1*py*py/PAR[PM_PAR_SYY]; 151 dPAR[PM_PAR_SXY] = -1.0*z1*X*Y; 152 } else { 153 // gradient -> 0 for z -> 0, but has undef form 154 float z1 = f1*kappa*ALPHA*pow(z,ALPHA); 155 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SXX] + PAR[PM_PAR_SXY]); 156 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SYY] + PAR[PM_PAR_SXY]); 157 dPAR[PM_PAR_SXX] = +2.0*z1*px/PAR[PM_PAR_SXX]/PAR[PM_PAR_SXX]; 158 dPAR[PM_PAR_SYY] = +2.0*z1*py/PAR[PM_PAR_SYY]/PAR[PM_PAR_SYY]; 159 dPAR[PM_PAR_SXY] = -1.0*z1; 160 } 161 } 162 return (f); 211 163 } 212 164 … … 292 244 bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal) 293 245 { 246 // for the moment, we are going to require moments and KronFlux 247 if (!source->moments) return false; 248 pmMoments *moments = source->moments; 249 250 if (!isfinite(moments->KronFlux)) return false; 251 if (!isfinite(moments->Mrf)) return false; 252 if (moments->Mrf < 0.0) return false; 253 294 254 psF32 *PAR = model->params->data.F32; 295 255 … … 297 257 PAR[PM_PAR_SKY] = 0.0; 298 258 299 // set the shape parameters 300 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments, true)) { 301 return false; 302 } 303 304 // the normalization is modified by the slope 305 float index = 0.5 / ALPHA; 306 float bn = 1.9992*index - 0.3271; 307 float Io = exp(0.5*bn); 308 309 // set the model normalization 310 if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) { 311 return false; 312 } 313 PAR[PM_PAR_I0] /= Io; 259 psEllipseMoments emoments; 260 emoments.x2 = moments->Mxx; 261 emoments.xy = moments->Mxy; 262 emoments.y2 = moments->Myy; 263 264 // force the axis ratio to be < 20.0 265 psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0); 266 267 if (!isfinite(axes.major)) return false; 268 if (!isfinite(axes.minor)) return false; 269 if (!isfinite(axes.theta)) return false; 270 271 // Mxx, Mxy, Myy define the elliptical shape, but Mrf defines the width 272 // the factor of 2.3 comes from Table 1 of Graham and Driver (2005) 273 float scale = moments->Mrf / axes.major / 2.3; 274 axes.major *= scale; 275 axes.minor *= scale; 276 277 pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], axes, true); 278 279 // psEllipseAxes axes; 280 // use the code in SetShape here to avoid doing this 2x 281 // pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 282 283 // float norm = pmSersicNorm (4); // hardwire 284 float norm = 0.00168012; 285 float normFlux = 2.0 * M_PI * axes.major * axes.minor * norm; 286 PAR[PM_PAR_I0] = moments->KronFlux / normFlux; 314 287 315 288 // set the model position … … 328 301 psEllipseAxes axes; 329 302 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 330 float AspectRatio = axes.minor / axes.major; 331 332 float index = 4.0; 333 float bn = 1.9992*index - 0.3271; 334 335 // the integral of a Sersic has an analytical form as follows: 336 float logGamma = lgamma(2.0*index); 337 float bnFactor = pow(bn, 2.0*index); 338 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 339 340 psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio; 341 342 return(Flux); 303 304 float norm = 0.00168012; 305 float flux = PAR[PM_PAR_I0] * 2.0 * M_PI * axes.major * axes.minor * norm; 306 307 return(flux); 343 308 } 344 309 … … 359 324 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 360 325 361 // f = Io exp(-z^n) -> z^n = ln(Io/f) 362 psF64 zn = log(PAR[PM_PAR_I0] / flux); 363 psF64 radius = axes.major * sqrt (2.0) * pow(zn, 0.5 / ALPHA); 326 // static value for DEV: 327 float kappa = 7.670628; 328 329 // f = Io exp(-kappa*z^n) -> z^n = ln(Io/f) / kappa 330 psF64 zn = log(PAR[PM_PAR_I0] / flux) / kappa; 331 psF64 radius = axes.major * pow(zn, 0.5 / ALPHA); 364 332 365 333 psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)",
Note:
See TracChangeset
for help on using the changeset viewer.
