Changeset 36085 for trunk/psModules/src/objects/models/pmModel_EXP.c
- Timestamp:
- Aug 31, 2013, 5:55:16 AM (13 years ago)
- Location:
- trunk/psModules
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
src/objects/models/pmModel_EXP.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules
- Property svn:mergeinfo changed
/branches/eam_branches/ipp-20130711/psModules (added) merged: 35843,35876,35947-35948,35961-35963,35966-35967,36021,36024,36027,36066-36069,36075
- Property svn:mergeinfo changed
-
trunk/psModules/src/objects/models/pmModel_EXP.c
r35768 r36085 45 45 #include "pmPSFtry.h" 46 46 #include "pmDetections.h" 47 #include "pmModel_CentralPixel.h" 47 48 48 49 #include "pmModel_EXP.h" … … 65 66 // Lax parameter limits 66 67 static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.05, 0.05, -1.0 }; 67 static float paramsMaxLax[] = { 1.0e5, 1.0e 8, 1.0e4, 1.0e4, 100, 100, 1.0 };68 static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0 }; 68 69 69 70 // Moderate parameter limits … … 78 79 static float *paramsMinUse = paramsMinLax; 79 80 static float *paramsMaxUse = paramsMaxLax; 80 static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5};81 static float betaUse[] = { 2, 3e6, 5, 5, 10.0, 10.0, 0.5}; 81 82 82 83 static bool limitsApply = true; // Apply limits? 83 84 84 # include "pmModel_SERSIC.CP.h" 85 // # include "pmModel_SERSIC.CP.h" 86 87 // the problems I'm having with the SERSIC-like functions are: 88 // 1) making sure I have the right functional form so that PAR[SXX,etc] represent R_eff (half-light radius) 89 // 2) getting the central pixel right 90 // 3) getting the derivaties right. 85 91 86 92 psF32 PM_MODEL_FUNC (psVector *deriv, … … 101 107 psAssert (z >= 0, "do not allow negative z values in model"); 102 108 103 float index = 1.0; 104 float par7 = 0.5; 105 float bn = 1.9992*index - 0.3271; 106 float Io = exp(bn); 107 108 psF32 f2 = bn*sqrt(z); 109 psF32 f1 = Io*exp(-f2); 110 109 // for EXP, we can hard-wire kappa(1): 110 // float index = 1.0; 111 float kappa = 1.70056; 112 113 // sqrt(z) is r 114 float q = kappa*sqrt(z); 115 psF32 f0 = exp(-q); 116 117 assert (isfinite(q)); 118 119 // only worry about the central 4 pixels at most 111 120 psF32 radius = hypot(X, Y); 112 if (radius < 1.0) { 113 114 // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center 115 116 // first, use Rmajor and index to find the central pixel flux (fraction of total flux) 117 psEllipseAxes axes; 118 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 119 120 // get the central pixel flux from the lookup table 121 float xPix = (axes.major - centralPixelXo) / centralPixeldX; 122 xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1); 123 float yPix = (index - centralPixelYo) / centralPixeldY; 124 yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1); 125 126 // the integral of a Sersic has an analytical form as follows: 127 float logGamma = lgamma(2.0*index); 128 float bnFactor = pow(bn, 2.0*index); 129 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 130 131 // XXX interpolate to get the value 132 // XXX for the moment, just integerize 133 // XXX I need to multiply by the integrated flux to get the flux in the central pixel 134 float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm; 135 136 float px1 = 1.0 / PAR[PM_PAR_SXX]; 137 float py1 = 1.0 / PAR[PM_PAR_SYY]; 138 float z10 = PS_SQR(px1); 139 float z01 = PS_SQR(py1); 140 141 // which pixels do we need for this interpolation? 142 // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...) 143 if ((X >= 0) && (Y >= 0)) { 144 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 145 float V00 = Vcenter; 146 float V10 = Io*exp(-bn*pow(z10,par7)); 147 float V01 = Io*exp(-bn*pow(z01,par7)); 148 float V11 = Io*exp(-bn*pow(z11,par7)); 149 f1 = interpolatePixels(V00, V10, V01, V11, X, Y); 150 } 151 if ((X < 0) && (Y >= 0)) { 152 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 153 float V00 = Io*exp(-bn*pow(z10,par7)); 154 float V10 = Vcenter; 155 float V01 = Io*exp(-bn*pow(z11,par7)); 156 float V11 = Io*exp(-bn*pow(z01,par7)); 157 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + 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(z01,par7)); 162 float V10 = Io*exp(-bn*pow(z11,par7)); 163 float V01 = Vcenter; 164 float V11 = Io*exp(-bn*pow(z10,par7)); 165 f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y)); 166 } 167 if ((X < 0) && (Y < 0)) { 168 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 169 float V00 = Io*exp(-bn*pow(z11,par7)); 170 float V10 = Io*exp(-bn*pow(z10,par7)); 171 float V01 = Io*exp(-bn*pow(z01,par7)); 172 float V11 = Vcenter; 173 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y)); 174 } 175 } 176 177 psF32 z0 = PAR[PM_PAR_I0]*f1; 178 psF32 f0 = PAR[PM_PAR_SKY] + z0; 179 180 assert (isfinite(f2)); 121 if (radius <= 1.5) { 122 f0 = pmModelCP_SersicSubpix (X, Y, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], 1.0, 51); 123 } 124 assert (isfinite(f0)); 125 126 psF32 f1 = PAR[PM_PAR_I0]*f0; 127 psF32 f = PAR[PM_PAR_SKY] + f1; 128 181 129 assert (isfinite(f1)); 182 assert (isfinite(z0)); 183 assert (isfinite(f0)); 130 assert (isfinite(f)); 184 131 185 132 if (deriv != NULL) { … … 187 134 188 135 dPAR[PM_PAR_SKY] = +1.0; 189 dPAR[PM_PAR_I0] = +f1; 190 191 // gradient is infinite for z = 0; saturate at z = 0.01 192 // z1 is -df/dz (the negative sign is canceled by most of dz/dPAR[i] 193 psF32 z1 = (z < 0.01) ? 0.5*bn*z0/sqrt(0.01) : 0.5*bn*z0/sqrt(z); 194 195 // XXX dampen SXX and SYY as in GAUSS? 196 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px/PAR[PM_PAR_SXX] + Y*PAR[PM_PAR_SXY]); 197 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py/PAR[PM_PAR_SYY] + X*PAR[PM_PAR_SXY]); 198 dPAR[PM_PAR_SXX] = +2.0*z1*px*px/PAR[PM_PAR_SXX]; 199 dPAR[PM_PAR_SYY] = +2.0*z1*py*py/PAR[PM_PAR_SYY]; 200 dPAR[PM_PAR_SXY] = -1.0*z1*X*Y; 201 } 202 return (f0); 136 dPAR[PM_PAR_I0] = +f0; 137 138 if (z > 0.01) { 139 float z1 = 0.5*f1*kappa/sqrt(z); 140 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px + Y*PAR[PM_PAR_SXY]); 141 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py + X*PAR[PM_PAR_SXY]); 142 dPAR[PM_PAR_SXX] = +2.0*z1*px*px/PAR[PM_PAR_SXX]; 143 dPAR[PM_PAR_SYY] = +2.0*z1*py*py/PAR[PM_PAR_SYY]; 144 dPAR[PM_PAR_SXY] = -1.0*z1*X*Y; 145 } else { 146 // gradient -> 0 for z -> 0, but has undef form 147 float z1 = 0.5*f1*kappa; 148 dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SXX] + PAR[PM_PAR_SXY]); 149 dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SYY] + PAR[PM_PAR_SXY]); 150 dPAR[PM_PAR_SXX] = +2.0*z1*px/PAR[PM_PAR_SXX]/PAR[PM_PAR_SXX]; 151 dPAR[PM_PAR_SYY] = +2.0*z1*py/PAR[PM_PAR_SYY]/PAR[PM_PAR_SYY]; 152 dPAR[PM_PAR_SXY] = -1.0*z1; 153 } 154 } 155 return (f); 203 156 } 204 157 … … 314 267 psEllipseAxes axes; 315 268 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 316 float AspectRatio = axes.minor / axes.major; 317 318 float index = 1.0; 319 float bn = 1.9992*index - 0.3271; 320 321 // the integral of a Sersic has an analytical form as follows: 322 float logGamma = lgamma(2.0*index); 323 float bnFactor = pow(bn, 2.0*index); 324 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 325 326 psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio; 327 328 return(Flux); 269 270 // static value for EXP: 271 float norm = 0.34578; // \int exp(-kappa*sqrt(z)) r dr 272 273 float flux = PAR[PM_PAR_I0] * 2.0 * M_PI * axes.major * axes.minor * norm; 274 275 return(flux); 329 276 } 330 277 … … 345 292 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 346 293 347 // f = Io exp(-sqrt(z)) -> sqrt(z) = ln(Io/f) 348 psF64 zn = log(PAR[PM_PAR_I0] / flux); 349 psF64 radius = axes.major * sqrt (2.0) * zn; 294 // static value for EXP: 295 float kappa = 1.70056; 296 297 // f = Io exp(-kappa*sqrt(z)) -> sqrt(z) = ln(Io/f) / kappa 298 psF64 zn = log(PAR[PM_PAR_I0] / flux) / kappa; 299 psF64 radius = axes.major * zn; 350 300 351 301 psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)", … … 501 451 return; 502 452 } 453 454 # if (0) 455 void bilin_inter_function () { 456 // first, use Rmajor and index to find the central pixel flux (fraction of total flux) 457 psEllipseAxes axes; 458 pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 459 460 // get the central pixel flux from the lookup table 461 float xPix = (axes.major - centralPixelXo) / centralPixeldX; 462 xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1); 463 float yPix = (index - centralPixelYo) / centralPixeldY; 464 yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1); 465 466 // the integral of a Sersic has an analytical form as follows: 467 float logGamma = lgamma(2.0*index); 468 float bnFactor = pow(bn, 2.0*index); 469 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 470 471 // XXX interpolate to get the value 472 // XXX for the moment, just integerize 473 // XXX I need to multiply by the integrated flux to get the flux in the central pixel 474 float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm; 475 476 float px1 = 1.0 / PAR[PM_PAR_SXX]; 477 float py1 = 1.0 / PAR[PM_PAR_SYY]; 478 float z10 = PS_SQR(px1); 479 float z01 = PS_SQR(py1); 480 481 // which pixels do we need for this interpolation? 482 // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...) 483 if ((X >= 0) && (Y >= 0)) { 484 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 485 float V00 = Vcenter; 486 float V10 = Io*exp(-bn*pow(z10,par7)); 487 float V01 = Io*exp(-bn*pow(z01,par7)); 488 float V11 = Io*exp(-bn*pow(z11,par7)); 489 f1 = interpolatePixels(V00, V10, V01, V11, X, Y); 490 } 491 if ((X < 0) && (Y >= 0)) { 492 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 493 float V00 = Io*exp(-bn*pow(z10,par7)); 494 float V10 = Vcenter; 495 float V01 = Io*exp(-bn*pow(z11,par7)); 496 float V11 = Io*exp(-bn*pow(z01,par7)); 497 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y); 498 } 499 if ((X >= 0) && (Y < 0)) { 500 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 501 float V00 = Io*exp(-bn*pow(z01,par7)); 502 float V10 = Io*exp(-bn*pow(z11,par7)); 503 float V01 = Vcenter; 504 float V11 = Io*exp(-bn*pow(z10,par7)); 505 f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y)); 506 } 507 if ((X < 0) && (Y < 0)) { 508 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 509 float V00 = Io*exp(-bn*pow(z11,par7)); 510 float V10 = Io*exp(-bn*pow(z10,par7)); 511 float V01 = Io*exp(-bn*pow(z01,par7)); 512 float V11 = Vcenter; 513 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y)); 514 } 515 } 516 # endif
Note:
See TracChangeset
for help on using the changeset viewer.
