Changeset 32347 for trunk/psModules/src/objects/models/pmModel_EXP.c
- Timestamp:
- Sep 6, 2011, 1:02:53 PM (15 years ago)
- Location:
- trunk/psModules/src/objects
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
models/pmModel_EXP.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/objects
- Property svn:ignore
-
old new 5 5 *.la 6 6 *.lo 7 pmSourceIO_CMF_PS1_V1.c 8 pmSourceIO_CMF_PS1_V2.c 9 pmSourceIO_CMF_PS1_V3.c
-
- Property svn:ignore
-
trunk/psModules/src/objects/models/pmModel_EXP.c
r31451 r32347 81 81 static bool limitsApply = true; // Apply limits? 82 82 83 # include "pmModel_SERSIC.CP.h" 84 83 85 psF32 PM_MODEL_FUNC (psVector *deriv, 84 86 const psVector *params, … … 93 95 psF32 z = PS_SQR(px) + PS_SQR(py) + PAR[PM_PAR_SXY]*X*Y; 94 96 95 // XXX if the elliptical contour is defined in valid way, this step should not be required. 96 // other models (like PGAUSS) don't use fractional powers, and thus do not have NaN values 97 // for negative values of z 98 // XXX use an assert here to force the elliptical parameters to be correctly determined 99 // if (z < 0) z = 0; 100 assert (z >= 0); 101 102 psF32 f2 = sqrt(z); 103 psF32 f1 = exp(-f2); 97 // If the elliptical contour is defined in a valid way, we should never trigger this 98 // assert. Other models (like PGAUSS) don't use fractional powers, and thus do not have 99 // NaN values for negative values of z 100 psAssert (z >= 0, "do not allow negative z values in model"); 101 102 float index = 1.0; 103 float par7 = 0.5; 104 float bn = 1.9992*index - 0.3271; 105 float Io = exp(bn); 106 107 psF32 f2 = bn*sqrt(z); 108 psF32 f1 = Io*exp(-f2); 109 110 psF32 radius = hypot(X, Y); 111 if (radius < 1.0) { 112 113 // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center 114 115 // first, use Rmajor and index to find the central pixel flux (fraction of total flux) 116 psEllipseShape shape; 117 118 shape.sx = PAR[PM_PAR_SXX]; 119 shape.sy = PAR[PM_PAR_SYY]; 120 shape.sxy = PAR[PM_PAR_SXY]; 121 122 // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio 123 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 124 125 // get the central pixel flux from the lookup table 126 float xPix = (axes.major - centralPixelXo) / centralPixeldX; 127 xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1); 128 float yPix = (index - centralPixelYo) / centralPixeldY; 129 yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1); 130 131 // the integral of a Sersic has an analytical form as follows: 132 float logGamma = lgamma(2.0*index); 133 float bnFactor = pow(bn, 2.0*index); 134 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 135 136 // XXX interpolate to get the value 137 // XXX for the moment, just integerize 138 // XXX I need to multiply by the integrated flux to get the flux in the central pixel 139 float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm; 140 141 float px1 = 1.0 / PAR[PM_PAR_SXX]; 142 float py1 = 1.0 / PAR[PM_PAR_SYY]; 143 float z10 = PS_SQR(px1); 144 float z01 = PS_SQR(py1); 145 146 // which pixels do we need for this interpolation? 147 // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...) 148 if ((X >= 0) && (Y >= 0)) { 149 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 150 float V00 = Vcenter; 151 float V10 = Io*exp(-bn*pow(z10,par7)); 152 float V01 = Io*exp(-bn*pow(z01,par7)); 153 float V11 = Io*exp(-bn*pow(z11,par7)); 154 f1 = interpolatePixels(V00, V10, V01, V11, X, Y); 155 } 156 if ((X < 0) && (Y >= 0)) { 157 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 158 float V00 = Io*exp(-bn*pow(z10,par7)); 159 float V10 = Vcenter; 160 float V01 = Io*exp(-bn*pow(z11,par7)); 161 float V11 = Io*exp(-bn*pow(z01,par7)); 162 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y); 163 } 164 if ((X >= 0) && (Y < 0)) { 165 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 166 float V00 = Io*exp(-bn*pow(z01,par7)); 167 float V10 = Io*exp(-bn*pow(z11,par7)); 168 float V01 = Vcenter; 169 float V11 = Io*exp(-bn*pow(z10,par7)); 170 f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y)); 171 } 172 if ((X < 0) && (Y < 0)) { 173 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 174 float V00 = Io*exp(-bn*pow(z11,par7)); 175 float V10 = Io*exp(-bn*pow(z10,par7)); 176 float V01 = Io*exp(-bn*pow(z01,par7)); 177 float V11 = Vcenter; 178 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y)); 179 } 180 } 181 104 182 psF32 z0 = PAR[PM_PAR_I0]*f1; 105 183 psF32 f0 = PAR[PM_PAR_SKY] + z0; … … 118 196 // gradient is infinite for z = 0; saturate at z = 0.01 119 197 // z1 is -df/dz (the negative sign is canceled by most of dz/dPAR[i] 120 psF32 z1 = (z < 0.01) ? 0.5* z0/sqrt(0.01) : 0.5*z0/sqrt(z);198 psF32 z1 = (z < 0.01) ? 0.5*bn*z0/sqrt(0.01) : 0.5*bn*z0/sqrt(z); 121 199 122 200 // XXX dampen SXX and SYY as in GAUSS? … … 216 294 217 295 // set the shape parameters 296 // XXX adjust this? 218 297 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 219 298 return false; … … 233 312 } 234 313 314 // An exponential model is equivalent to a Sersic with index = 1.0 235 315 psF64 PM_MODEL_FLUX (const psVector *params) 236 316 { 237 float z, norm;238 317 psEllipseShape shape; 239 318 240 319 psF32 *PAR = params->data.F32; 241 320 242 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;243 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;321 shape.sx = PAR[PM_PAR_SXX]; 322 shape.sy = PAR[PM_PAR_SYY]; 244 323 shape.sxy = PAR[PM_PAR_SXY]; 245 324 246 // Area is equivalent to 2 pi sigma^2325 // for a non-circular Exponential, the flux of the Rmajor equivalent is scaled by the AspectRatio 247 326 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 248 psF64 Area = 2.0 * M_PI * axes.major * axes.minor; 249 250 // the area needs to be multiplied by the integral of f(z) = exp(-sqrt(z)) [0 to infinity] 251 norm = 0.0; 252 253 # define DZ 0.25 254 255 float f0 = 1.0; 256 float f1, f2; 257 for (z = DZ; z < 150; z += DZ) { 258 f1 = exp(-sqrt(z)); 259 z += DZ; 260 f2 = exp(-sqrt(z)); 261 norm += f0 + 4*f1 + f2; 262 f0 = f2; 263 } 264 norm *= DZ / 3.0; 265 266 psF64 Flux = PAR[PM_PAR_I0] * Area * norm; 327 float AspectRatio = axes.minor / axes.major; 328 329 float index = 1.0; 330 float bn = 1.9992*index - 0.3271; 331 332 // the integral of a Sersic has an analytical form as follows: 333 float logGamma = lgamma(2.0*index); 334 float bnFactor = pow(bn, 2.0*index); 335 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 336 337 psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio; 267 338 268 339 return(Flux); … … 284 355 return (1.0); 285 356 286 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;287 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;357 shape.sx = PAR[PM_PAR_SXX]; 358 shape.sy = PAR[PM_PAR_SYY]; 288 359 shape.sxy = PAR[PM_PAR_SXY]; 289 360
Note:
See TracChangeset
for help on using the changeset viewer.
