- Timestamp:
- Aug 15, 2013, 5:56:56 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20130711/psModules/src/objects/models/pmModel_DEV.c
r35876 r35961 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, … … 86 85 static float *paramsMinUse = paramsMinLax; 87 86 static float *paramsMaxUse = paramsMaxLax; 88 static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5 };87 static float betaUse[] = { 2, 3e6, 5, 5, 3.0, 3.0, 0.5 }; 89 88 90 89 static bool limitsApply = true; // Apply limits? 91 90 92 # include "pmModel_SERSIC.CP.h"91 // # include "pmModel_SERSIC.CP.h" 93 92 94 93 psF32 PM_MODEL_FUNC (psVector *deriv, … … 109 108 psAssert (z >= 0, "do not allow negative z values in model"); 110 109 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 110 // for DEV, we can hard-wire kappa(4): 111 // float index = 4.0; 112 float kappa = 7.670628; 113 114 // r = sqrt(z) 115 float q = kappa*pow(z,ALPHA); 116 psF32 f0 = exp(-q); 117 118 psF32 f1 = PAR[PM_PAR_I0]*f0; 119 psF32 f = PAR[PM_PAR_SKY] + f1; 120 121 assert (isfinite(q)); 122 assert (isfinite(f0)); 123 assert (isfinite(f1)); 124 assert (isfinite(f)); 125 126 // only worry about the central 4 pixels at most 127 // If I use DELTA = 0.2, I'm way off for the total flux 128 // If I use DELTA = 0.02, I'm totally good (but I am under on the total flux for R = 30 by 0.2 mags -- aperture failure) 129 // For DELTA = 0.02 & Rmin/Rmaj = 0.25, I'm over flux by 0.15 mags (due to the central pixel) 119 130 psF32 radius = hypot(X, Y); 120 131 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); 132 // subdivide the central 2,3,4 pixels by Nx,Ny 133 float Npix = 0.0; 134 float Fpix = 0.0; 135 float Xpix = floor(pixcoord->data.F32[0]) - PAR[PM_PAR_XPOS]; 136 float Ypix = floor(pixcoord->data.F32[1]) - PAR[PM_PAR_YPOS]; 137 # define DELTA 0.02 138 for (float ix = 0.1; ix <= 0.9; ix += DELTA) { 139 for (float iy = 0.1; iy <= 0.9; iy += DELTA) { 140 psF32 X = Xpix + ix; 141 psF32 Y = Ypix + iy; 142 psF32 px = X / PAR[PM_PAR_SXX]; 143 psF32 py = Y / PAR[PM_PAR_SYY]; 144 psF32 z = PS_SQR(px) + PS_SQR(py) + PAR[PM_PAR_SXY]*X*Y; 145 146 // sqrt(z) is r 147 float q = kappa*pow(z,ALPHA); 148 psF32 f0 = exp(-q); 149 150 psF32 f1 = PAR[PM_PAR_I0]*f0; 151 psF32 fx = PAR[PM_PAR_SKY] + f1; 152 Fpix += fx; 153 Npix += 1.0; 158 154 } 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 } 155 } 156 f = Fpix / Npix; 183 157 } 184 185 psF32 z0 = PAR[PM_PAR_I0]*f1;186 psF32 f0 = PAR[PM_PAR_SKY] + z0;187 188 assert (isfinite(f2));189 assert (isfinite(f1));190 assert (isfinite(z0));191 assert (isfinite(f0));192 158 193 159 if (deriv != NULL) { … … 195 161 196 162 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); 163 dPAR[PM_PAR_I0] = +f0; 164 165 if (z > 0.01) { 166 float z1 = f1*kappa*ALPHA*pow(z,ALPHA-1.0); 167 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px + Y*PAR[PM_PAR_SXY]); 168 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py + X*PAR[PM_PAR_SXY]); 169 dPAR[PM_PAR_SXX] = +2.0*z1*px*px/PAR[PM_PAR_SXX]; 170 dPAR[PM_PAR_SYY] = +2.0*z1*py*py/PAR[PM_PAR_SYY]; 171 dPAR[PM_PAR_SXY] = -1.0*z1*X*Y; 172 } else { 173 // gradient -> 0 for z -> 0, but has undef form 174 float z1 = f1*kappa*ALPHA*pow(z,ALPHA); 175 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SXX] + PAR[PM_PAR_SXY]); 176 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SYY] + PAR[PM_PAR_SXY]); 177 dPAR[PM_PAR_SXX] = +2.0*z1*px/PAR[PM_PAR_SXX]/PAR[PM_PAR_SXX]; 178 dPAR[PM_PAR_SYY] = +2.0*z1*py/PAR[PM_PAR_SYY]/PAR[PM_PAR_SYY]; 179 dPAR[PM_PAR_SXY] = -1.0*z1; 180 } 181 } 182 return (f); 211 183 } 212 184 … … 302 274 } 303 275 304 // the normalization is modified by the slope305 float index = 0.5 / ALPHA;306 float bn = 1.9992*index - 0.3271;307 float Io = exp(0.5*bn);308 309 276 // set the model normalization 310 277 if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) { 311 278 return false; 312 279 } 313 PAR[PM_PAR_I0] /= Io;314 280 315 281 // set the model position … … 328 294 psEllipseAxes axes; 329 295 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); 296 297 float norm = 0.00168012; 298 float flux = PAR[PM_PAR_I0] * 2.0 * M_PI * axes.major * axes.minor * norm; 299 300 return(flux); 343 301 } 344 302 … … 359 317 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 360 318 361 // f = Io exp(-z^n) -> z^n = ln(Io/f) 362 psF64 zn = log(PAR[PM_PAR_I0] / flux); 319 // static value for DEV: 320 float kappa = 7.670628; 321 322 // f = Io exp(-kappa*z^n) -> z^n = ln(Io/f) / kappa 323 psF64 zn = log(PAR[PM_PAR_I0] / flux) / kappa; 363 324 psF64 radius = axes.major * sqrt (2.0) * pow(zn, 0.5 / ALPHA); 364 325
Note:
See TracChangeset
for help on using the changeset viewer.
