Changeset 32347 for trunk/psModules/src/objects/models/pmModel_DEV.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_DEV.c (modified) (7 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_DEV.c
r31451 r32347 89 89 static bool limitsApply = true; // Apply limits? 90 90 91 # include "pmModel_SERSIC.CP.h" 92 91 93 psF32 PM_MODEL_FUNC (psVector *deriv, 92 94 const psVector *params, … … 94 96 { 95 97 psF32 *PAR = params->data.F32; 96 97 float index = 0.5 / ALPHA;98 float bn = 1.9992*index - 0.3271;99 float Io = exp(bn);100 98 101 99 psF32 X = pixcoord->data.F32[0] - PAR[PM_PAR_XPOS]; … … 105 103 psF32 z = (PS_SQR(px) + PS_SQR(py) + PAR[PM_PAR_SXY]*X*Y); 106 104 107 assert (z >= 0); 105 // If the elliptical contour is defined in a valid way, we should never trigger this 106 // assert. Other models (like PGAUSS) don't use fractional powers, and thus do not have 107 // NaN values for negative values of z 108 psAssert (z >= 0, "do not allow negative z values in model"); 109 110 float index = 0.5 / ALPHA; 111 float par7 = ALPHA; 112 float bn = 1.9992*index - 0.3271; 113 float Io = exp(bn); 108 114 109 115 psF32 f2 = bn*pow(z,ALPHA); 110 116 psF32 f1 = Io*exp(-f2); 117 118 psF32 radius = hypot(X, Y); 119 if (radius < 1.0) { 120 121 // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center 122 123 // first, use Rmajor and index to find the central pixel flux (fraction of total flux) 124 psEllipseShape shape; 125 126 shape.sx = PAR[PM_PAR_SXX]; 127 shape.sy = PAR[PM_PAR_SYY]; 128 shape.sxy = PAR[PM_PAR_SXY]; 129 130 // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio 131 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 132 133 // get the central pixel flux from the lookup table 134 float xPix = (axes.major - centralPixelXo) / centralPixeldX; 135 xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1); 136 float yPix = (index - centralPixelYo) / centralPixeldY; 137 yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1); 138 139 // the integral of a Sersic has an analytical form as follows: 140 float logGamma = lgamma(2.0*index); 141 float bnFactor = pow(bn, 2.0*index); 142 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 143 144 // XXX interpolate to get the value 145 // XXX for the moment, just integerize 146 // XXX I need to multiply by the integrated flux to get the flux in the central pixel 147 float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm; 148 149 float px1 = 1.0 / PAR[PM_PAR_SXX]; 150 float py1 = 1.0 / PAR[PM_PAR_SYY]; 151 float z10 = PS_SQR(px1); 152 float z01 = PS_SQR(py1); 153 154 // which pixels do we need for this interpolation? 155 // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...) 156 if ((X >= 0) && (Y >= 0)) { 157 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 158 float V00 = Vcenter; 159 float V10 = Io*exp(-bn*pow(z10,par7)); 160 float V01 = Io*exp(-bn*pow(z01,par7)); 161 float V11 = Io*exp(-bn*pow(z11,par7)); 162 f1 = interpolatePixels(V00, V10, V01, V11, 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(z10,par7)); 167 float V10 = Vcenter; 168 float V01 = Io*exp(-bn*pow(z11,par7)); 169 float V11 = Io*exp(-bn*pow(z01,par7)); 170 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y); 171 } 172 if ((X >= 0) && (Y < 0)) { 173 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 174 float V00 = Io*exp(-bn*pow(z01,par7)); 175 float V10 = Io*exp(-bn*pow(z11,par7)); 176 float V01 = Vcenter; 177 float V11 = Io*exp(-bn*pow(z10,par7)); 178 f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y)); 179 } 180 if ((X < 0) && (Y < 0)) { 181 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 182 float V00 = Io*exp(-bn*pow(z11,par7)); 183 float V10 = Io*exp(-bn*pow(z10,par7)); 184 float V01 = Io*exp(-bn*pow(z01,par7)); 185 float V11 = Vcenter; 186 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y)); 187 } 188 } 189 111 190 psF32 z0 = PAR[PM_PAR_I0]*f1; 112 191 psF32 f0 = PAR[PM_PAR_SKY] + z0; … … 120 199 psF32 *dPAR = deriv->data.F32; 121 200 201 dPAR[PM_PAR_SKY] = +1.0; 202 dPAR[PM_PAR_I0] = +2.0*f1; // XXX extra damping.. 203 122 204 // gradient is infinite for z = 0; saturate at z = 0.01 123 205 psF32 z1 = (z < 0.01) ? z0*bn*ALPHA*pow(0.01,ALPHA - 1.0) : z0*bn*ALPHA*pow(z,ALPHA - 1.0); 124 125 dPAR[PM_PAR_SKY] = +1.0;126 dPAR[PM_PAR_I0] = +2.0*f1;127 206 128 207 assert (isfinite(z1)); … … 223 302 224 303 // set the shape parameters 304 // XXX adjust this? 225 305 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 226 306 return false; … … 246 326 } 247 327 328 // A DeVaucouleur model is equivalent to a Sersic with index = 4.0 248 329 psF64 PM_MODEL_FLUX (const psVector *params) 249 330 { 250 float z, norm;251 331 psEllipseShape shape; 252 332 253 333 psF32 *PAR = params->data.F32; 254 334 255 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;256 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;335 shape.sx = PAR[PM_PAR_SXX]; 336 shape.sy = PAR[PM_PAR_SYY]; 257 337 shape.sxy = PAR[PM_PAR_SXY]; 258 338 259 // Area is equivalent to 2 pi sigma^2339 // for a non-circular DeVaucouleur, the flux of the Rmajor equivalent is scaled by the AspectRatio 260 340 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 261 psF64 Area = 2.0 * M_PI * axes.major * axes.minor; 262 263 // the area needs to be multiplied by the integral of f(z) 264 norm = 0.0; 265 266 # define DZ 0.25 267 268 float f0 = 1.0; 269 float f1, f2; 270 for (z = DZ; z < 150; z += DZ) { 271 f1 = exp(-pow(z,ALPHA)); 272 z += DZ; 273 f2 = exp(-pow(z,ALPHA)); 274 norm += f0 + 4*f1 + f2; 275 f0 = f2; 276 } 277 norm *= DZ / 3.0; 278 279 psF64 Flux = PAR[PM_PAR_I0] * Area * norm; 341 float AspectRatio = axes.minor / axes.major; 342 343 float index = 4.0; 344 float bn = 1.9992*index - 0.3271; 345 346 // the integral of a Sersic has an analytical form as follows: 347 float logGamma = lgamma(2.0*index); 348 float bnFactor = pow(bn, 2.0*index); 349 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 350 351 psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio; 280 352 281 353 return(Flux); … … 297 369 return (1.0); 298 370 299 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;300 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;371 shape.sx = PAR[PM_PAR_SXX]; 372 shape.sy = PAR[PM_PAR_SYY]; 301 373 shape.sxy = PAR[PM_PAR_SXY]; 302 374
Note:
See TracChangeset
for help on using the changeset viewer.
