Changeset 36680 for branches/eam_branches/ps2-tc3-20130727/psModules/src/objects/models/pmModel_SERSIC.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_SERSIC.c (modified) (9 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_SERSIC.c
r35768 r36680 20 20 * note that a Sersic model is usually defined in terms of R_e, the half-light radius. This 21 21 construction does not include a factor of 2 in the X^2 term, etc, like for a Gaussian. 22 Conversion from SXX, SYY, SXY to R_major, R_minor, theta can be done by using setting:22 Conversion from SXX, SYY, SXY to R_major, R_minor, theta can be done by using: 23 23 shape.sx = SXX / sqrt(2), shape.sy = SYY / sqrt(2), shape.sxy = SXY, then calling 24 24 psEllipseShapeToAxes, and multiplying the values of axes.major, axes.minor by sqrt(2) … … 50 50 #include "pmSourceDiffStats.h" 51 51 #include "pmSourceSatstar.h" 52 #include "pmSourceLensing.h" 52 53 #include "pmSource.h" 53 54 #include "pmSourceFitModel.h" … … 55 56 #include "pmPSFtry.h" 56 57 #include "pmDetections.h" 58 #include "pmModel_CentralPixel.h" 57 59 58 60 #include "pmModel_SERSIC.h" … … 74 76 75 77 // Lax parameter limits 76 static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.001, 0.001, -1.0, 0.0 5 };77 static float paramsMaxLax[] = { 1.0e5, 1.0e 8, 1.0e4, 1.0e4, 100, 100, 1.0, 4.0 };78 static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.001, 0.001, -1.0, 0.0625 }; 79 static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0, 1.0 }; 78 80 79 81 // Moderate parameter limits … … 88 90 static float *paramsMinUse = paramsMinLax; 89 91 static float *paramsMaxUse = paramsMaxLax; 90 static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5, 2.0};92 static float betaUse[] = { 2, 3e6, 5, 5, 10.0, 10.0, 0.5, 1.0}; 91 93 92 94 static bool limitsApply = true; // Apply limits? 93 95 94 # include "pmModel_SERSIC.CP.h"96 // # include "pmModel_SERSIC.CP.h" 95 97 96 98 psF32 PM_MODEL_FUNC (psVector *deriv, … … 111 113 psAssert (z >= 0, "do not allow negative z values in model"); 112 114 113 float index = 0.5 / PAR[PM_PAR_7];114 float par7 = PAR[PM_PAR_7];115 float bn = 1.9992*index - 0.3271; 116 float Io = exp(bn);117 118 psF32 f2 = bn*pow(z,par7); 119 psF32 f1 = Io*exp(-f2);115 float Sindex = 0.5 / PAR[PM_PAR_7]; 116 float kappa = pmSersicKappa (Sindex); 117 118 float q = kappa*pow(z,PAR[PM_PAR_7]); 119 psF32 f0 = exp(-q); 120 121 assert (isfinite(q)); 120 122 121 123 psF32 radius = hypot(X, Y); 122 if (radius < 1.0) { 123 124 // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center 125 126 // first, use Rmajor and index to find the central pixel flux (fraction of total flux) 127 psEllipseAxes axes; 128 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 129 130 // get the central pixel flux from the lookup table 131 float xPix = (axes.major - centralPixelXo) / centralPixeldX; 132 xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1); 133 float yPix = (index - centralPixelYo) / centralPixeldY; 134 yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1); 135 136 // the integral of a Sersic has an analytical form as follows: 137 float logGamma = lgamma(2.0*index); 138 float bnFactor = pow(bn, 2.0*index); 139 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 140 141 // XXX interpolate to get the value 142 // XXX for the moment, just integerize 143 // XXX I need to multiply by the integrated flux to get the flux in the central pixel 144 float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm; 145 146 float px1 = 1.0 / PAR[PM_PAR_SXX]; 147 float py1 = 1.0 / PAR[PM_PAR_SYY]; 148 float z10 = PS_SQR(px1); 149 float z01 = PS_SQR(py1); 150 151 // which pixels do we need for this interpolation? 152 // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...) 153 if ((X >= 0) && (Y >= 0)) { 154 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 155 float V00 = Vcenter; 156 float V10 = Io*exp(-bn*pow(z10,par7)); 157 float V01 = Io*exp(-bn*pow(z01,par7)); 158 float V11 = Io*exp(-bn*pow(z11,par7)); 159 f1 = interpolatePixels(V00, V10, V01, V11, X, Y); 160 } 161 if ((X < 0) && (Y >= 0)) { 162 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 163 float V00 = Io*exp(-bn*pow(z10,par7)); 164 float V10 = Vcenter; 165 float V01 = Io*exp(-bn*pow(z11,par7)); 166 float V11 = Io*exp(-bn*pow(z01,par7)); 167 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y); 168 } 169 if ((X >= 0) && (Y < 0)) { 170 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 171 float V00 = Io*exp(-bn*pow(z01,par7)); 172 float V10 = Io*exp(-bn*pow(z11,par7)); 173 float V01 = Vcenter; 174 float V11 = Io*exp(-bn*pow(z10,par7)); 175 f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y)); 176 } 177 if ((X < 0) && (Y < 0)) { 178 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 179 float V00 = Io*exp(-bn*pow(z11,par7)); 180 float V10 = Io*exp(-bn*pow(z10,par7)); 181 float V01 = Io*exp(-bn*pow(z01,par7)); 182 float V11 = Vcenter; 183 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y)); 184 } 185 } 186 187 psF32 z0 = PAR[PM_PAR_I0]*f1; 188 psF32 f0 = PAR[PM_PAR_SKY] + z0; 189 190 if (!isfinite(z0)) { 191 fprintf(stderr, "z0 is not finite for %f %f %f %f %f. Parameters: \n", X, Y, radius, z, f1); 124 if (radius <= 1.5) { 125 // Nsub ~ 10*index^2 + 1 126 psEllipseAxes axes = pmPSF_ModelToAxes(PAR, pmModelClassGetType ("PS_MODEL_SERSIC")); 127 int Nsub = 2 * ((int)(6.0*Sindex / axes.minor)) + 1; 128 Nsub = PS_MIN (Nsub, 121); 129 Nsub = PS_MAX (Nsub, 11); 130 f0 = pmModelCP_SersicSubpix (X, Y, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], Sindex, Nsub); 131 } 132 if (!isfinite(f0)) { 133 fprintf(stderr, "f0 is not finite for %f %f %f %f %f. Parameters: \n", X, Y, radius, z, q); 192 134 fprintf(stderr, "%f %f %f %f %f %f %f %f\n", PAR[0], PAR[1], PAR[2], PAR[3], PAR[4], 193 135 PAR[5], PAR[6], PAR[7]); 194 136 } 195 196 assert (isfinite(f2)); 137 assert (isfinite(f0)); 138 139 psF32 f1 = PAR[PM_PAR_I0]*f0; 140 psF32 f = PAR[PM_PAR_SKY] + f1; 141 197 142 assert (isfinite(f1)); 198 assert (isfinite(z0)); 199 assert (isfinite(f0)); 143 assert (isfinite(f)); 200 144 201 145 if (deriv != NULL) { … … 203 147 204 148 dPAR[PM_PAR_SKY] = +1.0; 205 dPAR[PM_PAR_I0] = +f1; 206 207 // gradient is infinite for z = 0; saturate at z = 0.01 208 psF32 z1 = (z < 0.01) ? z0*bn*par7*pow(0.01,par7 - 1.0) : z0*bn*par7*pow(z,par7 - 1.0); 209 210 dPAR[PM_PAR_7] = (z < 0.01) ? -z0*pow(0.01,par7)*log(0.01) : -z0*f2*log(z); 211 dPAR[PM_PAR_7] *= 3.0; 212 213 assert (isfinite(z1)); 149 dPAR[PM_PAR_I0] = +f0; 150 151 if (z > 0.01) { 152 float z1 = f1*kappa*PAR[PM_PAR_7]*pow(z,PAR[PM_PAR_7]-1.0); 153 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px + Y*PAR[PM_PAR_SXY]); 154 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py + X*PAR[PM_PAR_SXY]); 155 dPAR[PM_PAR_SXX] = +2.0*z1*px*px/PAR[PM_PAR_SXX]; 156 dPAR[PM_PAR_SYY] = +2.0*z1*py*py/PAR[PM_PAR_SYY]; 157 dPAR[PM_PAR_SXY] = -1.0*z1*X*Y; 158 dPAR[PM_PAR_7] = -1.0*f1*q*log(z); 159 } else { 160 // gradient -> 0 for z -> 0, but has undef form 161 float z1 = f1*kappa*PAR[PM_PAR_7]*pow(z,PAR[PM_PAR_7]); 162 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SXX] + PAR[PM_PAR_SXY]); 163 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SYY] + PAR[PM_PAR_SXY]); 164 dPAR[PM_PAR_SXX] = +2.0*z1*px/PAR[PM_PAR_SXX]/PAR[PM_PAR_SXX]; 165 dPAR[PM_PAR_SYY] = +2.0*z1*py/PAR[PM_PAR_SYY]/PAR[PM_PAR_SYY]; 166 dPAR[PM_PAR_SXY] = -1.0*z1; 167 // dPAR[PM_PAR_7] = -1.0*f1*q*log(z + 0.0001); 168 dPAR[PM_PAR_7] = -1.0*f1*q*log(z + 0.0001); // factor of 16 to reduce the gain 169 } 214 170 assert (isfinite(dPAR[PM_PAR_7])); 215 216 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px/PAR[PM_PAR_SXX] + Y*PAR[PM_PAR_SXY]); 217 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py/PAR[PM_PAR_SYY] + X*PAR[PM_PAR_SXY]); 218 dPAR[PM_PAR_SXX] = +2.0*z1*px*px/PAR[PM_PAR_SXX]; // XXX : increase drag? 219 dPAR[PM_PAR_SYY] = +2.0*z1*py*py/PAR[PM_PAR_SYY]; 220 dPAR[PM_PAR_SXY] = -1.0*z1*X*Y; 221 } 222 return (f0); 171 } 172 return (f); 223 173 } 224 174 … … 370 320 psEllipseAxes axes; 371 321 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 372 float AspectRatio = axes.minor / axes.major; 373 374 float index = 0.5 / PAR[PM_PAR_7]; 375 float bn = 1.9992*index - 0.3271; 376 377 // the integral of a Sersic has an analytical form as follows: 378 float logGamma = lgamma(2.0*index); 379 float bnFactor = pow(bn, 2.0*index); 380 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 381 382 psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio; 383 384 return(Flux); 322 323 float Sindex = 0.5 / PAR[PM_PAR_7]; 324 float norm = pmSersicNorm (Sindex); 325 326 float flux = PAR[PM_PAR_I0] * 2.0 * M_PI * axes.major * axes.minor * norm; 327 328 return(flux); 385 329 } 386 330 … … 401 345 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 402 346 347 float Sindex = 0.5 / PAR[PM_PAR_7]; 348 float kappa = pmSersicKappa (Sindex); 349 403 350 // f = Io exp(-z^n) -> z^n = ln(Io/f) 404 psF64 zn = log(PAR[PM_PAR_I0] / flux) ;405 psF64 radius = axes.major * sqrt (2.0) * pow(zn, 0.5 / PAR[PM_PAR_7]);351 psF64 zn = log(PAR[PM_PAR_I0] / flux) / kappa; 352 psF64 radius = axes.major * pow(zn, Sindex); 406 353 407 354 psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f), par 7 = %f",
Note:
See TracChangeset
for help on using the changeset viewer.
