Changeset 32347
- Timestamp:
- Sep 6, 2011, 1:02:53 PM (15 years ago)
- Location:
- trunk/psModules/src
- Files:
-
- 3 deleted
- 44 edited
- 1 copied
-
camera/pmReadoutFake.c (modified) (2 diffs)
-
objects (modified) (1 prop)
-
objects/Makefile.am (modified) (1 diff)
-
objects/mksource.pl (modified) (2 diffs)
-
objects/models/pmModel_DEV.c (modified) (7 diffs)
-
objects/models/pmModel_EXP.c (modified) (6 diffs)
-
objects/models/pmModel_PGAUSS.c (modified) (2 diffs)
-
objects/models/pmModel_PS1_V1.c (modified) (3 diffs)
-
objects/models/pmModel_QGAUSS.c (modified) (2 diffs)
-
objects/models/pmModel_RGAUSS.c (modified) (2 diffs)
-
objects/models/pmModel_SERSIC.CP.h (copied) (copied from branches/eam_branches/ipp-20110710/psModules/src/objects/models/pmModel_SERSIC.CP.h )
-
objects/models/pmModel_SERSIC.c (modified) (7 diffs)
-
objects/pmFootprintCullPeaks.c (modified) (1 diff)
-
objects/pmModelUtils.c (modified) (1 diff)
-
objects/pmMoments.c (modified) (2 diffs)
-
objects/pmMoments.h (modified) (1 diff)
-
objects/pmPCM_MinimizeChisq.c (modified) (6 diffs)
-
objects/pmPCMdata.c (modified) (4 diffs)
-
objects/pmPCMdata.h (modified) (2 diffs)
-
objects/pmPSF.c (modified) (7 diffs)
-
objects/pmPSF.h (modified) (1 diff)
-
objects/pmPeaks.c (modified) (2 diffs)
-
objects/pmPeaks.h (modified) (1 diff)
-
objects/pmSource.c (modified) (3 diffs)
-
objects/pmSource.h (modified) (2 diffs)
-
objects/pmSourceExtendedPars.c (modified) (1 diff)
-
objects/pmSourceExtendedPars.h (modified) (2 diffs)
-
objects/pmSourceFitModel.c (modified) (2 diffs)
-
objects/pmSourceFitPCM.c (modified) (6 diffs)
-
objects/pmSourceIO_CMF.c.in (modified) (11 diffs)
-
objects/pmSourceIO_CMF_PS1_DV1.c (modified) (2 diffs)
-
objects/pmSourceIO_CMF_PS1_DV2.c (modified) (2 diffs)
-
objects/pmSourceIO_CMF_PS1_SV1.c (modified) (2 diffs)
-
objects/pmSourceIO_CMF_PS1_V1.c (deleted)
-
objects/pmSourceIO_CMF_PS1_V2.c (deleted)
-
objects/pmSourceIO_CMF_PS1_V3.c (deleted)
-
objects/pmSourceIO_CMP.c (modified) (2 diffs)
-
objects/pmSourceIO_OBJ.c (modified) (1 diff)
-
objects/pmSourceIO_PS1_CAL_0.c (modified) (3 diffs)
-
objects/pmSourceIO_PS1_DEV_0.c (modified) (2 diffs)
-
objects/pmSourceIO_PS1_DEV_1.c (modified) (3 diffs)
-
objects/pmSourceIO_SMPDATA.c (modified) (2 diffs)
-
objects/pmSourceIO_SX.c (modified) (1 diff)
-
objects/pmSourceMoments.c (modified) (10 diffs)
-
objects/pmSourceOutputs.c (modified) (2 diffs)
-
objects/pmSourceOutputs.h (modified) (1 diff)
-
objects/pmSourcePhotometry.c (modified) (1 diff)
-
objects/pmSourcePlotPSFModel.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/camera/pmReadoutFake.c
r29004 r32347 51 51 52 52 psF32 *params = model->params->data.F32; // Model parameters 53 psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO ); // Ellipse axes53 psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO, model->type); // Ellipse axes 54 54 // Curiously, the minor axis can be larger than the major axis, so need to check. 55 55 if (axes.major >= axes.minor) { … … 58 58 axes.major = axes.minor; 59 59 } 60 return pmPSF_AxesToModel(params, axes );60 return pmPSF_AxesToModel(params, axes, model->type); 61 61 } 62 62 -
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/Makefile.am
r31670 r32347 130 130 131 131 # pmSourceID_CMF_* functions use a common framework 132 BUILT_SOURCES = pmSourceIO_CMF_PS1_V1. v1.c pmSourceIO_CMF_PS1_V2.v1.c pmSourceIO_CMF_PS1_V3.v1.c132 BUILT_SOURCES = pmSourceIO_CMF_PS1_V1.c pmSourceIO_CMF_PS1_V2.c pmSourceIO_CMF_PS1_V3.c 133 133 134 pmSourceIO_CMF_PS1_V1. v1.c : pmSourceIO_CMF.c.in mksource.pl135 mksource.pl pmSourceIO_CMF.c.in PS1_V1 pmSourceIO_CMF_PS1_V1. v1.c134 pmSourceIO_CMF_PS1_V1.c : pmSourceIO_CMF.c.in mksource.pl 135 mksource.pl pmSourceIO_CMF.c.in PS1_V1 pmSourceIO_CMF_PS1_V1.c 136 136 137 pmSourceIO_CMF_PS1_V2. v1.c : pmSourceIO_CMF.c.in mksource.pl138 mksource.pl pmSourceIO_CMF.c.in PS1_V2 pmSourceIO_CMF_PS1_V2. v1.c137 pmSourceIO_CMF_PS1_V2.c : pmSourceIO_CMF.c.in mksource.pl 138 mksource.pl pmSourceIO_CMF.c.in PS1_V2 pmSourceIO_CMF_PS1_V2.c 139 139 140 pmSourceIO_CMF_PS1_V3. v1.c : pmSourceIO_CMF.c.in mksource.pl141 mksource.pl pmSourceIO_CMF.c.in PS1_V 2 pmSourceIO_CMF_PS1_V3.v1.c140 pmSourceIO_CMF_PS1_V3.c : pmSourceIO_CMF.c.in mksource.pl 141 mksource.pl pmSourceIO_CMF.c.in PS1_V3 pmSourceIO_CMF_PS1_V3.c 142 142 143 143 # EXTRA_DIST = pmErrorCodes.h.in pmErrorCodes.dat pmErrorCodes.c.in -
trunk/psModules/src/objects/mksource.pl
r31670 r32347 14 14 15 15 # see if we can add in PS1_DV* and PS1_SV* as well... 16 @cmfmodes = ("PS1_V1", 1,16 %cmfmodes = ("PS1_V1", 1, 17 17 "PS1_V2", 2, 18 18 "PS1_V3", 3); 19 20 print "1: $cmfmodes{1}\n"; 21 print "PS1_V1: $cmfmodes{'PS1_V1'}\n"; 19 22 20 23 open (FILE, "$template") || die "failed to open template $template\n"; … … 50 53 51 54 if ($gtMode) { 55 # print "gtMode : $line\n"; 52 56 $thisLevel = $cmfmodes{$gtMode}; 53 57 $myLevel = $cmfmodes{$cmfmode}; 54 if ($thisLevel <= $myLevel) { next; } 55 $line =~ s|\@<\S*\@\s*||; 58 print "gtMode : $gtMode vs $cmfmode, $thisLevel, $myLevel\n"; 59 if ($myLevel <= $thisLevel) { next; } 60 $line =~ s|\@>\S*\@\s*||; 56 61 } 57 62 58 63 if ($ltMode) { 64 # print "ltMode : $line\n"; 59 65 $thisLevel = $cmfmodes{$ltMode}; 60 66 $myLevel = $cmfmodes{$cmfmode}; 61 if ($thisLevel >= $myLevel) { next; } 62 $line =~ s|\@>\S*\@\s*||; 67 print "ltMode : $ltMode vs $cmfmode, $thisLevel, $myLevel\n"; 68 if ($myLevel >= $thisLevel) { next; } 69 $line =~ s|\@<\S*\@\s*||; 63 70 } 64 71 -
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 -
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 -
trunk/psModules/src/objects/models/pmModel_PGAUSS.c
r31451 r32347 217 217 } 218 218 219 psF64 PM_MODEL_FLUX(const psVector *params) 220 { 221 float norm, z; 219 // integrate the model to get the full flux 220 psF64 PM_MODEL_FLUX (const psVector *params) 221 { 222 float z, norm; 222 223 psEllipseShape shape; 223 224 … … 228 229 shape.sxy = PAR[PM_PAR_SXY]; 229 230 230 // Area is equivalent to 2 pi sigma^2231 231 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 232 psF64 Area = 2.0 * M_PI * axes.major * axes.minor;233 234 // the area needs to be multiplied by the integral of f(z)232 float AspectRatio = axes.minor / axes.major; 233 234 // flux = 2 \pi \int f(r) r dr 235 235 norm = 0.0; 236 236 237 # define DZ 0.25 238 239 float f0 = 1.0; 237 # define DR 0.25 238 239 // f = f(r) * r 240 float f0 = 0.0; 240 241 float f1, f2; 241 for (z = DZ; z < 150; z += DZ) { 242 f1 = 1.0 / (1 + z + z*z/2.0 + z*z*z/6.0); 243 z += DZ; 244 f2 = 1.0 / (1 + z + z*z/2.0 + z*z*z/6.0); 242 for (float r = DR; r < 150; r += DR) { 243 z = 0.5 * PS_SQR(r / axes.major); 244 f1 = r / (1 + z + z*z/2.0 + z*z*z/6.0); 245 r += DR; 246 z = 0.5 * PS_SQR(r / axes.major); 247 f2 = r / (1 + z + z*z/2.0 + z*z*z/6.0); 245 248 norm += f0 + 4*f1 + f2; 246 249 f0 = f2; 247 250 } 248 norm *= D Z/ 3.0;249 250 psF64 Flux = PAR[PM_PAR_I0] * Area * norm;251 norm *= DR / 3.0; 252 253 psF64 Flux = PAR[PM_PAR_I0] * norm * 2.0 * M_PI * AspectRatio; 251 254 252 255 return(Flux); -
trunk/psModules/src/objects/models/pmModel_PS1_V1.c
r31670 r32347 14 14 * PM_PAR_XPOS 2 - X center of object 15 15 * PM_PAR_YPOS 3 - Y center of object 16 * PM_PAR_SXX 4 - X^2 term of elliptical contour ( sqrt(2) / SigmaX)17 * PM_PAR_SYY 5 - Y^2 term of elliptical contour ( sqrt(2) / SigmaY)16 * PM_PAR_SXX 4 - X^2 term of elliptical contour (SigmaX / sqrt(2)) 17 * PM_PAR_SYY 5 - Y^2 term of elliptical contour (SigmaY / sqrt(2)) 18 18 * PM_PAR_SXY 6 - X*Y term of elliptical contour 19 19 * PM_PAR_7 7 - amplitude of the linear component (k) … … 239 239 } 240 240 241 // integrate the model to get the full flux 241 242 psF64 PM_MODEL_FLUX (const psVector *params) 242 243 { … … 250 251 shape.sxy = PAR[PM_PAR_SXY]; 251 252 252 // Area is equivalent to 2 pi sigma^2253 253 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 254 psF64 Area = 2.0 * M_PI * axes.major * axes.minor;255 256 // the area needs to be multiplied by the integral of f(z)254 float AspectRatio = axes.minor / axes.major; 255 256 // flux = 2 \pi \int f(r) r dr 257 257 norm = 0.0; 258 258 259 # define DZ 0.25 260 261 float f0 = 1.0; 259 # define DR 0.25 260 261 // f = f(r) * r 262 float f0 = 0.0; 262 263 float f1, f2; 263 for (z = DZ; z < 150; z += DZ) { 264 f1 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 265 z += DZ; 266 f2 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 264 for (float r = DR; r < 150; r += DR) { 265 z = 0.5 * PS_SQR(r / axes.major); 266 f1 = r / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 267 r += DR; 268 z = 0.5 * PS_SQR(r / axes.major); 269 f2 = r / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 267 270 norm += f0 + 4*f1 + f2; 268 271 f0 = f2; 269 272 } 270 norm *= D Z/ 3.0;271 272 psF64 Flux = PAR[PM_PAR_I0] * Area * norm;273 norm *= DR / 3.0; 274 275 psF64 Flux = PAR[PM_PAR_I0] * norm * 2.0 * M_PI * AspectRatio; 273 276 274 277 return(Flux); -
trunk/psModules/src/objects/models/pmModel_QGAUSS.c
r31670 r32347 240 240 } 241 241 242 // integrate the model to get the full flux 242 243 psF64 PM_MODEL_FLUX (const psVector *params) 243 244 { … … 251 252 shape.sxy = PAR[PM_PAR_SXY]; 252 253 253 // Area is equivalent to 2 pi sigma^2254 254 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 255 psF64 Area = 2.0 * M_PI * axes.major * axes.minor;256 257 // the area needs to be multiplied by the integral of f(z)255 float AspectRatio = axes.minor / axes.major; 256 257 // flux = 2 \pi \int f(r) r dr 258 258 norm = 0.0; 259 259 260 # define DZ 0.25 261 262 float f0 = 1.0; 260 # define DR 0.25 261 262 // f = f(r) * r 263 float f0 = 0.0; 263 264 float f1, f2; 264 for (z = DZ; z < 150; z += DZ) { 265 f1 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 266 z += DZ; 267 f2 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 265 for (float r = DR; r < 150; r += DR) { 266 z = 0.5 * PS_SQR(r / axes.major); 267 f1 = r / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 268 r += DR; 269 z = 0.5 * PS_SQR(r / axes.major); 270 f2 = r / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 268 271 norm += f0 + 4*f1 + f2; 269 272 f0 = f2; 270 273 } 271 norm *= D Z/ 3.0;272 273 psF64 Flux = PAR[PM_PAR_I0] * Area * norm;274 norm *= DR / 3.0; 275 276 psF64 Flux = PAR[PM_PAR_I0] * norm * 2.0 * M_PI * AspectRatio; 274 277 275 278 return(Flux); -
trunk/psModules/src/objects/models/pmModel_RGAUSS.c
r31451 r32347 229 229 } 230 230 231 // integrate the model to get the full flux 231 232 psF64 PM_MODEL_FLUX (const psVector *params) 232 233 { 233 float norm, z;234 float z, norm; 234 235 psEllipseShape shape; 235 236 … … 240 241 shape.sxy = PAR[PM_PAR_SXY]; 241 242 242 // Area is equivalent to 2 pi sigma^2243 243 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 244 psF64 Area = 2.0 * M_PI * axes.major * axes.minor;245 246 // the area needs to be multiplied by the integral of f(z)244 float AspectRatio = axes.minor / axes.major; 245 246 // flux = 2 \pi \int f(r) r dr 247 247 norm = 0.0; 248 248 249 # define DZ 0.25 250 251 float f0 = 1.0; 249 # define DR 0.25 250 251 // f = f(r) * r 252 float f0 = 0.0; 252 253 float f1, f2; 253 for (z = DZ; z < 150; z += DZ) { 254 f1 = 1.0 / (1 + z + pow(z, PAR[PM_PAR_7])); 255 z += DZ; 256 f2 = 1.0 / (1 + z + pow(z, PAR[PM_PAR_7])); 254 for (float r = DR; r < 150; r += DR) { 255 z = 0.5 * PS_SQR(r / axes.major); 256 f1 = r / (1 + z + pow(z, PAR[PM_PAR_7])); 257 r += DR; 258 z = 0.5 * PS_SQR(r / axes.major); 259 f2 = r / (1 + z + pow(z, PAR[PM_PAR_7])); 257 260 norm += f0 + 4*f1 + f2; 258 261 f0 = f2; 259 262 } 260 norm *= D Z/ 3.0;261 262 psF64 Flux = PAR[PM_PAR_I0] * Area * norm;263 norm *= DR / 3.0; 264 265 psF64 Flux = PAR[PM_PAR_I0] * norm * 2.0 * M_PI * AspectRatio; 263 266 264 267 return(Flux); -
trunk/psModules/src/objects/models/pmModel_SERSIC.c
r31451 r32347 13 13 * PM_PAR_XPOS 2 - X center of object 14 14 * PM_PAR_YPOS 3 - Y center of object 15 * PM_PAR_SXX 4 - X^2 term of elliptical contour ( sqrt(2) / SigmaX)16 * PM_PAR_SYY 5 - Y^2 term of elliptical contour ( sqrt(2) / SigmaY)15 * PM_PAR_SXX 4 - X^2 term of elliptical contour (SigmaX / sqrt(2)) 16 * PM_PAR_SYY 5 - Y^2 term of elliptical contour (SigmaY / sqrt(2)) 17 17 * PM_PAR_SXY 6 - X*Y term of elliptical contour 18 18 * PM_PAR_7 7 - normalized sersic parameter 19 20 * note that a Sersic model is usually defined in terms of R_e, the half-light radius. This 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: 23 shape.sx = SXX / sqrt(2), shape.sy = SYY / sqrt(2), shape.sxy = SXY, then calling 24 psEllipseShapeToAxes, and multiplying the values of axes.major, axes.minor by sqrt(2) 19 25 20 26 note that a standard sersic model uses exp(-K*(z^(1/2n) - 1). the additional elements (K, … … 85 91 static bool limitsApply = true; // Apply limits? 86 92 93 # include "pmModel_SERSIC.CP.h" 94 87 95 psF32 PM_MODEL_FUNC (psVector *deriv, 88 96 const psVector *params, … … 97 105 psF32 z = PS_SQR(px) + PS_SQR(py) + PAR[PM_PAR_SXY]*X*Y; 98 106 99 // XXX if the elliptical contour is defined in valid way, this step should not be required. 100 // other models (like PGAUSS) don't use fractional powers, and thus do not have NaN values 101 // for negative values of z 102 // XXX use an assert here to force the elliptical parameters to be correctly determined 103 // if (z < 0) z = 0; 104 assert (z >= 0); 107 // If the elliptical contour is defined in a valid way, we should never trigger this 108 // assert. Other models (like PGAUSS) don't use fractional powers, and thus do not have 109 // NaN values for negative values of z 110 psAssert (z >= 0, "do not allow negative z values in model"); 105 111 106 112 float index = 0.5 / PAR[PM_PAR_7]; 113 float par7 = PAR[PM_PAR_7]; 107 114 float bn = 1.9992*index - 0.3271; 108 115 float Io = exp(bn); 109 116 110 psF32 f2 = bn*pow(z, PAR[PM_PAR_7]);117 psF32 f2 = bn*pow(z,par7); 111 118 psF32 f1 = Io*exp(-f2); 119 120 psF32 radius = hypot(X, Y); 121 if (radius < 1.0) { 122 123 // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center 124 125 // first, use Rmajor and index to find the central pixel flux (fraction of total flux) 126 psEllipseShape shape; 127 128 shape.sx = PAR[PM_PAR_SXX]; 129 shape.sy = PAR[PM_PAR_SYY]; 130 shape.sxy = PAR[PM_PAR_SXY]; 131 132 // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio 133 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 134 135 // get the central pixel flux from the lookup table 136 float xPix = (axes.major - centralPixelXo) / centralPixeldX; 137 xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1); 138 float yPix = (index - centralPixelYo) / centralPixeldY; 139 yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1); 140 141 // the integral of a Sersic has an analytical form as follows: 142 float logGamma = lgamma(2.0*index); 143 float bnFactor = pow(bn, 2.0*index); 144 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 145 146 // XXX interpolate to get the value 147 // XXX for the moment, just integerize 148 // XXX I need to multiply by the integrated flux to get the flux in the central pixel 149 float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm; 150 151 float px1 = 1.0 / PAR[PM_PAR_SXX]; 152 float py1 = 1.0 / PAR[PM_PAR_SYY]; 153 float z10 = PS_SQR(px1); 154 float z01 = PS_SQR(py1); 155 156 // which pixels do we need for this interpolation? 157 // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...) 158 if ((X >= 0) && (Y >= 0)) { 159 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 160 float V00 = Vcenter; 161 float V10 = Io*exp(-bn*pow(z10,par7)); 162 float V01 = Io*exp(-bn*pow(z01,par7)); 163 float V11 = Io*exp(-bn*pow(z11,par7)); 164 f1 = interpolatePixels(V00, V10, V01, V11, X, Y); 165 } 166 if ((X < 0) && (Y >= 0)) { 167 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 168 float V00 = Io*exp(-bn*pow(z10,par7)); 169 float V10 = Vcenter; 170 float V01 = Io*exp(-bn*pow(z11,par7)); 171 float V11 = Io*exp(-bn*pow(z01,par7)); 172 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y); 173 } 174 if ((X >= 0) && (Y < 0)) { 175 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 176 float V00 = Io*exp(-bn*pow(z01,par7)); 177 float V10 = Io*exp(-bn*pow(z11,par7)); 178 float V01 = Vcenter; 179 float V11 = Io*exp(-bn*pow(z10,par7)); 180 f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y)); 181 } 182 if ((X < 0) && (Y < 0)) { 183 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 184 float V00 = Io*exp(-bn*pow(z11,par7)); 185 float V10 = Io*exp(-bn*pow(z10,par7)); 186 float V01 = Io*exp(-bn*pow(z01,par7)); 187 float V11 = Vcenter; 188 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y)); 189 } 190 } 191 112 192 psF32 z0 = PAR[PM_PAR_I0]*f1; 113 193 psF32 f0 = PAR[PM_PAR_SKY] + z0; … … 121 201 psF32 *dPAR = deriv->data.F32; 122 202 123 // gradient is infinite for z = 0; saturate at z = 0.01124 psF32 z1 = (z < 0.01) ? z0*bn*PAR[PM_PAR_7]*pow(0.01,PAR[PM_PAR_7] - 1.0) : z0*bn*PAR[PM_PAR_7]*pow(z,PAR[PM_PAR_7] - 1.0);125 126 203 dPAR[PM_PAR_SKY] = +1.0; 127 204 dPAR[PM_PAR_I0] = +f1; 128 dPAR[PM_PAR_7] = (z < 0.01) ? -z0*pow(0.01,PAR[PM_PAR_7])*log(0.01) : -z0*f2*log(z); 205 206 // gradient is infinite for z = 0; saturate at z = 0.01 207 psF32 z1 = (z < 0.01) ? z0*bn*par7*pow(0.01,par7 - 1.0) : z0*bn*par7*pow(z,par7 - 1.0); 208 209 dPAR[PM_PAR_7] = (z < 0.01) ? -z0*pow(0.01,par7)*log(0.01) : -z0*f2*log(z); 129 210 dPAR[PM_PAR_7] *= 3.0; 130 211 … … 269 350 float Io = exp(0.5*bn); 270 351 271 // XXX do we need this factor of sqrt(2)?272 // float Sxx = PS_MAX(0.5, M_SQRT2*shape.sx);273 // float Syy = PS_MAX(0.5, M_SQRT2*shape.sy);274 275 352 float Sxx = PS_MAX(0.5, shape.sx); 276 353 float Syy = PS_MAX(0.5, shape.sy); … … 294 371 } 295 372 373 // A sersic model has an integral flux which can be analytically represented 296 374 psF64 PM_MODEL_FLUX (const psVector *params) 297 375 { 298 float z, norm;299 376 psEllipseShape shape; 300 377 301 378 psF32 *PAR = params->data.F32; 302 379 303 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;304 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;380 shape.sx = PAR[PM_PAR_SXX]; 381 shape.sy = PAR[PM_PAR_SYY]; 305 382 shape.sxy = PAR[PM_PAR_SXY]; 306 383 307 // Area is equivalent to 2 pi sigma^2384 // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio 308 385 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 309 psF64 Area = 2.0 * M_PI * axes.major * axes.minor; 310 311 // the area needs to be multiplied by the integral of f(z) 312 norm = 0.0; 313 314 # define DZ 0.25 315 316 float f0 = 1.0; 317 float f1, f2; 318 for (z = DZ; z < 150; z += DZ) { 319 // f1 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, 2.25)); 320 f1 = exp(-pow(z,PAR[PM_PAR_7])); 321 z += DZ; 322 f2 = exp(-pow(z,PAR[PM_PAR_7])); 323 norm += f0 + 4*f1 + f2; 324 f0 = f2; 325 } 326 norm *= DZ / 3.0; 327 328 psF64 Flux = PAR[PM_PAR_I0] * Area * norm; 386 float AspectRatio = axes.minor / axes.major; 387 388 float index = 0.5 / PAR[PM_PAR_7]; 389 float bn = 1.9992*index - 0.3271; 390 391 // the integral of a Sersic has an analytical form as follows: 392 float logGamma = lgamma(2.0*index); 393 float bnFactor = pow(bn, 2.0*index); 394 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 395 396 psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio; 329 397 330 398 return(Flux); … … 346 414 return (1.0); 347 415 348 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;349 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;416 shape.sx = PAR[PM_PAR_SXX]; 417 shape.sy = PAR[PM_PAR_SYY]; 350 418 shape.sxy = PAR[PM_PAR_SXY]; 351 419 -
trunk/psModules/src/objects/pmFootprintCullPeaks.c
r31263 r32347 181 181 if (!myFP->n) { 182 182 psWarning ("empty footprint?"); 183 psFree (myFP); 183 184 continue; 184 185 } -
trunk/psModules/src/objects/pmModelUtils.c
r31153 r32347 122 122 if (!isfinite(axes.theta)) return false; 123 123 124 // Mxx, Mxy, Myy define the elliptical shape, but Mrf defines the width 125 float scale = (isfinite(moments->Mrf) && (moments->Mrf > 0.0)) ? moments->Mrf / axes.major : 1.0; 126 axes.major *= scale; 127 axes.minor *= scale; 128 124 129 psEllipseShape shape = psEllipseAxesToShape (axes); 125 130 -
trunk/psModules/src/objects/pmMoments.c
r29004 r32347 32 32 tmp->Mrf = 0.0; 33 33 tmp->Mrh = 0.0; 34 35 tmp->KronCore = 0.0; 36 tmp->KronCoreErr = 0.0; 37 34 38 tmp->KronFlux = 0.0; 35 39 tmp->KronFluxErr = 0.0; … … 37 41 tmp->KronFinner = 0.0; 38 42 tmp->KronFouter = 0.0; 43 44 tmp->KronFluxPSF = 0.0; 45 tmp->KronFluxPSFErr = 0.0; 46 tmp->KronRadiusPSF = 0.0; 39 47 40 48 tmp->Mx = 0.0; -
trunk/psModules/src/objects/pmMoments.h
r31153 r32347 51 51 int nPixels; ///< Number of pixels used. 52 52 53 float KronFluxPSF; ///< Kron Flux using PSF-optimized window 54 float KronFluxPSFErr; ///< Kron Flux Error using PSF-optimized window 55 float KronRadiusPSF; ///< Kron Radius using PSF-optimized window (Flux in 2.5 Radius) 56 53 57 float KronCore; ///< flux in r < 1.0*Mrf 54 58 float KronCoreErr; ///< error on flux in r < 1.0*Mrf -
trunk/psModules/src/objects/pmPCM_MinimizeChisq.c
r29012 r32347 45 45 # define USE_FFT 1 46 46 # define PRE_CONVOLVE 1 47 # define TESTCOPY 0 47 48 48 49 bool pmPCM_MinimizeChisq ( … … 93 94 psFree (pcm->psfFFT); 94 95 } 95 pcm->psfFFT = psImageConvolveKernelInit(pcm->modelFlux, pcm->psf); 96 # if (!TESTCOPY) 97 if (!pcm->use1Dgauss) { 98 pcm->psfFFT = psImageConvolveKernelInit(pcm->modelFlux, pcm->psf); 99 } 100 # endif 96 101 # endif 97 102 … … 285 290 286 291 // Convert i/j to image space: 287 coord->data.F32[0] = (psF32) (j + source->pixels->col0);288 coord->data.F32[1] = (psF32) (i + source->pixels->row0);292 coord->data.F32[0] = (psF32) (j + 0.5 + source->pixels->col0); 293 coord->data.F32[1] = (psF32) (i + 0.5 + source->pixels->row0); 289 294 290 295 pcm->modelFlux->data.F32[i][j] = pcm->modelConv->modelFunc (deriv, params, coord); … … 309 314 # if (PRE_CONVOLVE) 310 315 // convolve model image and derivative images with pre-convolved kernel 311 psImageConvolveKernel (pcm->modelConvFlux, pcm->modelFlux, NULL, 0, pcm->psfFFT); 316 317 // XXX for a test, just copy, rather than convolve 318 # if (TESTCOPY) 319 psImageCopy (pcm->modelConvFlux, pcm->modelFlux, pcm->modelFlux->type.type); 320 # else 321 if (pcm->use1Dgauss) { 322 // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread): 323 // * the model flux is not masked 324 // * threading takes place above this level 325 pcm->modelConvFlux = psImageCopy (pcm->modelConvFlux, pcm->modelFlux, pcm->modelFlux->type.type); 326 psImageSmooth (pcm->modelConvFlux, pcm->sigma, pcm->nsigma); 327 } else { 328 psImageConvolveKernel (pcm->modelConvFlux, pcm->modelFlux, NULL, 0, pcm->psfFFT); 329 } 330 # endif 331 312 332 for (int n = 0; n < pcm->dmodelsFlux->n; n++) { 313 333 if (pcm->dmodelsFlux->data[n] == NULL) continue; … … 315 335 psImage *dmodel = pcm->dmodelsFlux->data[n]; 316 336 psImage *dmodelConv = pcm->dmodelsConvFlux->data[n]; 317 psImageConvolveKernel (dmodelConv, dmodel, NULL, 0, pcm->psfFFT); 337 # if (TESTCOPY) 338 psImageCopy (dmodelConv, dmodel, dmodel->type.type); 339 # else 340 if (pcm->use1Dgauss) { 341 // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread): 342 // * the model flux is not masked 343 // * threading takes place above this level 344 dmodelConv = psImageCopy (dmodelConv, dmodel, dmodel->type.type); 345 psImageSmooth (dmodelConv, pcm->sigma, pcm->nsigma); 346 } else { 347 psImageConvolveKernel (dmodelConv, dmodel, NULL, 0, pcm->psfFFT); 348 } 349 # endif 318 350 } 319 351 # else … … 325 357 psImage *dmodel = pcm->dmodelsFlux->data[n]; 326 358 psImage *dmodelConv = pcm->dmodelsConvFlux->data[n]; 327 psImageConvolveFFT (dmodelConv, dmodel, NULL, 0, pcm->psf); 359 360 if (pcm->use1Dgauss) { 361 // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread): 362 // * the model flux is not masked 363 // * threading takes place above this level 364 dmodelConv = psImageCopy (dmodelConv, dmodel, dmodel->type.type); 365 psImageSmooth (dmodelConv, pcm->sigma, pcm->nsigma); 366 } else { 367 psImageConvolveFFT (dmodelConv, dmodel, NULL, 0, pcm->psf); 368 } 328 369 } 329 370 # endif // PRE-CONVOLVE -
trunk/psModules/src/objects/pmPCMdata.c
r31451 r32347 41 41 #include "pmPCMdata.h" 42 42 43 # define USE_DELTA_PSF 0 44 # define USE_1D_GAUSS 1 45 43 46 static void pmPCMdataFree (pmPCMdata *pcm) { 44 47 … … 88 91 pcm->constraint = NULL; 89 92 pcm->nDOF = 0; 93 94 // full convolution with the PSF is expensive. if we have to save time, we can do a 1D 95 // convolution with a Gaussian approximation to the kernel 96 pcm->use1Dgauss = false; 97 pcm->nsigma = 3.0; 98 pcm->sigma = 1.0; // this should be set to something sensible when the psf is known 90 99 91 100 return pcm; … … 257 266 pcm->nDOF = nPix - nParams; 258 267 268 # if (USE_1D_GAUSS) 269 pmModel *modelPSF = source->modelPSF; 270 psAssert (modelPSF, "psf model must be defined"); 271 272 psEllipseShape shape; 273 psEllipseAxes axes; 274 275 shape.sx = modelPSF->params->data.F32[PM_PAR_SXX]; 276 shape.sy = modelPSF->params->data.F32[PM_PAR_SYY]; 277 shape.sxy = modelPSF->params->data.F32[PM_PAR_SXY]; 278 axes = psEllipseShapeToAxes (shape, 20.0); 279 280 float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*modelPSF->params->data.F32[PM_PAR_I0]); 281 float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major); 282 283 pcm->use1Dgauss = true; 284 pcm->sigma = 0.5 * (FWHM_MAJOR + FWHM_MINOR) / 2.35; 285 pcm->nsigma = 2.0; 286 # endif 287 259 288 return pcm; 260 289 } … … 368 397 return true; 369 398 } 399 400 // construct a realization of the source model 401 bool pmPCMCacheModel (pmSource *source, psImageMaskType maskVal, int psfSize) { 402 403 PS_ASSERT_PTR_NON_NULL(source, false); 404 405 // select appropriate model 406 pmModel *model = pmSourceGetModel (NULL, source); 407 if (model == NULL) return false; // model must be defined 408 409 // if we already have a cached image, re-use that memory 410 source->modelFlux = psImageCopy (source->modelFlux, source->pixels, PS_TYPE_F32); 411 psImageInit (source->modelFlux, 0.0); 412 413 // modelFlux always has unity normalization (I0 = 1.0) 414 pmModelAdd (source->modelFlux, source->maskObj, model, PM_MODEL_OP_FULL | PM_MODEL_OP_NORM, maskVal); 415 416 // convolve the model image with the PSF 417 if (USE_1D_GAUSS) { 418 // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread): 419 // * the model flux is not masked 420 // * threading takes place above this level 421 422 // define the Gauss parameters from the psf 423 pmModel *modelPSF = source->modelPSF; 424 psAssert (modelPSF, "psf model must be defined"); 425 426 psEllipseShape shape; 427 psEllipseAxes axes; 428 429 shape.sx = modelPSF->params->data.F32[PM_PAR_SXX]; 430 shape.sy = modelPSF->params->data.F32[PM_PAR_SYY]; 431 shape.sxy = modelPSF->params->data.F32[PM_PAR_SXY]; 432 axes = psEllipseShapeToAxes (shape, 20.0); 433 434 float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*modelPSF->params->data.F32[PM_PAR_I0]); 435 float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major); 436 437 float sigma = 0.5 * (FWHM_MAJOR + FWHM_MINOR) / 2.35; 438 float nsigma = 2.0; 439 440 psImageSmooth (source->modelFlux, sigma, nsigma); 441 } else { 442 // make sure we save a cached copy of the psf flux 443 pmSourceCachePSF (source, maskVal); 444 445 // convert the cached cached psf model for this source to a psKernel 446 psKernel *psf = pmPCMkernelFromPSF (source, psfSize); 447 if (!psf) { 448 // NOTE: this only happens if the source is too close to an edge 449 model->flags |= PM_MODEL_STATUS_BADARGS; 450 return NULL; 451 } 452 453 // XXX not sure if I can place the output on top of the input 454 psImageConvolveFFT (source->modelFlux, source->modelFlux, NULL, 0, psf); 455 } 456 return true; 457 } 458 -
trunk/psModules/src/objects/pmPCMdata.h
r31153 r32347 35 35 int nPar; 36 36 int nDOF; 37 38 bool use1Dgauss; 39 float sigma; 40 float nsigma; 37 41 } pmPCMdata; 38 42 … … 90 94 bool pmSourceFitPCM (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 91 95 96 bool pmPCMCacheModel (pmSource *source, psImageMaskType maskVal, int psfSize); 92 97 93 98 /// @} -
trunk/psModules/src/objects/pmPSF.c
r31451 r32347 281 281 // convert the parameters used in the fitted source model 282 282 // to the parameters used in the 2D PSF model 283 // XXX this function may be invalid for SERSIC, DEV, EXP models (SQRT2 not used?) 283 284 bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis) 284 285 { … … 307 308 // convert the PSF parameters used in the 2D PSF model fit into the 308 309 // parameters used in the source model 310 // XXX this function may be invalid for SERSIC, DEV, EXP models (SQRT2 not used?) 309 311 psEllipsePol pmPSF_ModelToFit (psF32 *modelPar) 310 312 { … … 329 331 // convert the parameters used in the fitted source model to the psEllipseAxes representation 330 332 // (major,minor,theta) 331 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR )333 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR, pmModelType type) 332 334 { 333 335 psEllipseShape shape; … … 336 338 axes.minor = NAN; 337 339 axes.theta = NAN; 338 // XXX: must assert non-NULL input parameter340 // XXX: must assert non-NULL input parameter 339 341 PS_ASSERT_PTR_NON_NULL(modelPar, axes); 340 342 341 shape.sx = modelPar[PM_PAR_SXX] / M_SQRT2; 342 shape.sy = modelPar[PM_PAR_SYY] / M_SQRT2; 343 shape.sxy = modelPar[PM_PAR_SXY]; 343 bool useReff = true; 344 useReff |= (type == pmModelClassGetType ("PS_MODEL_SERSIC")); 345 useReff |= (type == pmModelClassGetType ("PS_MODEL_DEV")); 346 useReff |= (type == pmModelClassGetType ("PS_MODEL_EXP")); 347 348 if (useReff) { 349 shape.sx = modelPar[PM_PAR_SXX]; 350 shape.sy = modelPar[PM_PAR_SYY]; 351 shape.sxy = modelPar[PM_PAR_SXY]; 352 } else { 353 shape.sx = modelPar[PM_PAR_SXX] / M_SQRT2; 354 shape.sy = modelPar[PM_PAR_SYY] / M_SQRT2; 355 shape.sxy = modelPar[PM_PAR_SXY]; 356 } 344 357 345 358 if ((shape.sx == 0) || (shape.sy == 0)) { … … 357 370 // convert the psEllipseAxes representation (major,minor,theta) to the parameters used in the 358 371 // fitted source model 359 bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes )372 bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes, pmModelType type) 360 373 { 361 374 PS_ASSERT_PTR_NON_NULL(modelPar, false); … … 370 383 psEllipseShape shape = psEllipseAxesToShape (axes); 371 384 372 modelPar[PM_PAR_SXX] = shape.sx * M_SQRT2; 373 modelPar[PM_PAR_SYY] = shape.sy * M_SQRT2; 374 modelPar[PM_PAR_SXY] = shape.sxy; 375 385 bool useReff = true; 386 useReff |= pmModelClassGetType ("PS_MODEL_SERSIC"); 387 useReff |= pmModelClassGetType ("PS_MODEL_DEV"); 388 useReff |= pmModelClassGetType ("PS_MODEL_EXP"); 389 390 if (useReff) { 391 modelPar[PM_PAR_SXX] = shape.sx; 392 modelPar[PM_PAR_SYY] = shape.sy; 393 modelPar[PM_PAR_SXY] = shape.sxy; 394 } else { 395 modelPar[PM_PAR_SXX] = shape.sx * M_SQRT2; 396 modelPar[PM_PAR_SYY] = shape.sy * M_SQRT2; 397 modelPar[PM_PAR_SXY] = shape.sxy; 398 } 376 399 return true; 377 400 } … … 438 461 # if (0) 439 462 psF32 *params = model->params->data.F32; // Model parameters 440 psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO ); // Ellipse axes463 psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO, model->type); // Ellipse axes 441 464 442 465 // Curiously, the minor axis can be larger than the major axis, so need to check. -
trunk/psModules/src/objects/pmPSF.h
r31451 r32347 106 106 pmPSF *pmPSFBuildSimple (char *typeName, float sxx, float syy, float sxy, ...); 107 107 108 bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes );108 bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes, pmModelType type); 109 109 bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis); 110 110 111 111 psEllipsePol pmPSF_ModelToFit (psF32 *modelPar); 112 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR );112 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR, pmModelType type); 113 113 114 114 /// Calculate FWHM value from a PSF -
trunk/psModules/src/objects/pmPeaks.c
r31451 r32347 137 137 *****************************************************************************/ 138 138 static void peakFree(pmPeak *tmp) 139 {} // 139 { 140 if (!tmp) return; 141 psFree (tmp->saddlePoints); 142 return; 143 } 140 144 141 145 pmPeak *pmPeakAlloc(psS32 x, … … 162 166 tmp->type = type; 163 167 tmp->footprint = NULL; 168 tmp->saddlePoints = NULL; 164 169 165 170 psMemSetDeallocator(tmp, (psFreeFunc) peakFree); -
trunk/psModules/src/objects/pmPeaks.h
r31451 r32347 72 72 pmPeakType type; ///< Description of peak. 73 73 pmFootprint *footprint; ///< reference to containing footprint 74 psArray *saddlePoints; ///< set of saddle points between this peak and near neighbors 74 75 } 75 76 pmPeak; -
trunk/psModules/src/objects/pmSource.c
r31670 r32347 58 58 psFree(tmp->modelEXT); 59 59 psFree(tmp->modelFits); 60 psFree(tmp->extFitPars); 60 61 psFree(tmp->extpars); 61 62 psFree(tmp->moments); … … 119 120 source->modelEXT = NULL; 120 121 source->modelFits = NULL; 122 source->extFitPars = NULL; 121 123 source->type = PM_SOURCE_TYPE_UNKNOWN; 122 124 source->mode = PM_SOURCE_MODE_DEFAULT; … … 196 198 // NOTE : because of the const id element, we cannot just assign *source = *in 197 199 200 source->imageID = in->imageID; 198 201 source->type = in->type; 199 202 source->mode = in->mode; -
trunk/psModules/src/objects/pmSource.h
r31670 r32347 36 36 PM_SOURCE_TMPF_MOMENTS_MEASURED = 0x0010, 37 37 PM_SOURCE_TMPF_CANDIDATE_PSFSTAR = 0x0020, 38 PM_SOURCE_TMPF_STACK_KEEP = 0x0040, 39 PM_SOURCE_TMPF_STACK_SKIP = 0x0080, 38 40 } pmSourceTmpF; 39 41 … … 76 78 pmModel *modelEXT; ///< EXT Model fit used for subtraction (parameters and type) 77 79 psArray *modelFits; ///< collection of extended source models (best == modelEXT) 80 psArray *extFitPars; ///< extra extended fit parameters 78 81 pmSourceType type; ///< Best identification of object. 79 82 pmSourceMode mode; ///< analysis flags set for object. -
trunk/psModules/src/objects/pmSourceExtendedPars.c
r31153 r32347 258 258 return ( psMemGetDeallocator(ptr) == (psFreeFunc) pmSourceExtendedFluxFree); 259 259 } 260 261 // *** pmSourceExtFitPars describes extra metadata related to an extended fit 262 static void pmSourceExtFitParsFree (pmSourceExtFitPars *pars) { 263 return; 264 } 265 266 pmSourceExtFitPars *pmSourceExtFitParsAlloc (void) { 267 268 pmSourceExtFitPars *pars = (pmSourceExtFitPars *) psAlloc(sizeof(pmSourceExtFitPars)); 269 psMemSetDeallocator(pars, (psFreeFunc) pmSourceExtFitParsFree); 270 271 pars->Mxx = NAN; 272 pars->Mxy = NAN; 273 pars->Myy = NAN; 274 275 pars->Mrf = NAN; 276 pars->Mrh = NAN; 277 278 pars->apMag = NAN; 279 pars->krMag = NAN; 280 pars->psfMag = NAN; 281 pars->peakMag = NAN; 282 283 return pars; 284 } -
trunk/psModules/src/objects/pmSourceExtendedPars.h
r31153 r32347 67 67 } pmSourceExtendedPars; 68 68 69 // additional measurements related to the model fits 70 typedef struct { 71 float Mxx; 72 float Mxy; 73 float Myy; 74 75 float Mrf; 76 float Mrh; 77 78 float apMag; 79 float krMag; 80 float psfMag; 81 float peakMag; 82 } pmSourceExtFitPars; 83 69 84 pmSourceRadialFlux *pmSourceRadialFluxAlloc(); 70 85 bool psMemCheckSourceRadialFlux(psPtr ptr); … … 92 107 bool pmSourceRadialProfileSortPair(psVector *index, psVector *extra); 93 108 94 109 pmSourceExtFitPars *pmSourceExtFitParsAlloc (void); 95 110 96 111 /// @} -
trunk/psModules/src/objects/pmSourceFitModel.c
r31153 r32347 176 176 break; 177 177 case PM_SOURCE_FIT_EXT: 178 // EXT model fits all params (exceptsky)179 nParams = params->n - 1;178 // EXT model fits all shape params and Io (not Xo, Yo, sky) 179 nParams = params->n - 3; 180 180 psVectorInit (constraint->paramMask, 0); 181 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 1; 182 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 1; 181 183 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1; 182 184 break; … … 193 195 break; 194 196 case PM_SOURCE_FIT_NO_INDEX: 195 // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params197 // PSF model only fits Io, Sxx, Sxy, Syy 196 198 psVectorInit (constraint->paramMask, 0); 199 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 1; 200 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 1; 197 201 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1; 198 202 if (params->n == 7) { 199 nParams = params->n - 1;203 nParams = params->n - 3; 200 204 } else { 201 nParams = params->n - 2;205 nParams = params->n - 4; 202 206 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 1; 203 207 } -
trunk/psModules/src/objects/pmSourceFitPCM.c
r31153 r32347 48 48 // convolved model image. 49 49 50 # define TIMING 0 51 50 52 bool pmSourceFitPCM (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 51 53 54 if (TIMING) { psTimerStart ("pmSourceFitPCM"); } 55 52 56 psVector *params = pcm->modelConv->params; 53 57 psVector *dparams = pcm->modelConv->dparams; … … 64 68 psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F32); 65 69 70 float t1, t2, t3, t4, t5; 71 if (TIMING) { t1 = psTimerMark ("pmSourceFitPCM"); } 72 66 73 bool fitStatus = pmPCM_MinimizeChisq (myMin, covar, params, source, pcm); 74 if (TIMING) { t2 = psTimerMark ("pmSourceFitPCM"); } 75 67 76 for (int i = 0; i < dparams->n; i++) { 68 77 if ((pcm->constraint->paramMask != NULL) && pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) … … 76 85 } 77 86 psTrace ("psphot", 4, "niter: %d, chisq: %f", myMin->iter, myMin->value); 87 if (TIMING) { t3 = psTimerMark ("pmSourceFitPCM"); } 78 88 79 89 // renormalize output model image (generated by fitting process) … … 97 107 pmSourceChisqUnsubtracted (source, pcm->modelConv, maskVal); 98 108 } 109 if (TIMING) { t4 = psTimerMark ("pmSourceFitPCM"); } 99 110 100 111 // set the model success or failure status … … 114 125 115 126 source->mode |= PM_SOURCE_MODE_FITTED; // XXX is this needed? 127 if (TIMING) { t5 = psTimerMark ("pmSourceFitPCM"); } 128 129 if (TIMING) { 130 fprintf (stderr, "nIter: %2d, npix: %5d, t1: %6.4f, t2: %6.4f, t3: %6.4f, t4: %6.4f, t5: %6.4f\n", myMin->iter, pcm->nPix, t1, t2, t3, t4, t5); 131 } 116 132 117 133 psFree(myMin); … … 121 137 } 122 138 139 // XXX deprecate this function or merge with the empirical model 123 140 bool pmSourceModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal) { 124 141 -
trunk/psModules/src/objects/pmSourceIO_CMF.c.in
r31670 r32347 55 55 // followed by a zero-size matrix, followed by the table data 56 56 57 // # define MODE @CMFMODE@58 57 bool pmSourcesWrite_CMF_@CMFMODE@ (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname, psMetadata *recipe) 59 58 { … … 171 170 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kouter); 172 171 172 // XXX do not keep this long term, just a TEST: 173 // @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_PSF", PS_DATA_F32, "Kron Flux", moments.KronPSF); 174 // @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_PSF_SIG",PS_DATA_F32, "Kron Flux", moments.KronPSFErr); 173 175 // Do NOT write these : not consistent with the definition of PS1_V3 in Ohana/src/libautocode/dev/cmf-ps1-v3.d 174 176 // psMetadataAdd (row, PS_LIST_TAIL, "KRON_CORE_FLUX", PS_DATA_F32, "Kron Flux (in 1.0 R1)", moments.KronCore); 175 177 // psMetadataAdd (row, PS_LIST_TAIL, "KRON_CORE_ERROR", PS_DATA_F32, "Kron Error (in 1.0 R1)", moments.KronCoreErr); 178 176 179 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "FLAGS", PS_DATA_U32, "psphot analysis flags", source->mode); 177 180 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "FLAGS2", PS_DATA_U32, "psphot analysis flags", source->mode2); … … 222 225 223 226 // read in a readout from the fits file 224 psArray *pmSourcesRead_CMF_ PS1_V3(psFits *fits, psMetadata *header)227 psArray *pmSourcesRead_CMF_@CMFMODE@ (psFits *fits, psMetadata *header) 225 228 { 226 229 PS_ASSERT_PTR_NON_NULL(fits, false); … … 281 284 // XXX use these to determine PAR[PM_PAR_I0]? 282 285 @ALL@ source->psfMag = psMetadataLookupF32 (&status, row, "PSF_INST_MAG"); 283 @ALL@ source->psfMagErr = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG");286 @ALL@ source->psfMagErr = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG"); 284 287 @ALL@ source->apMag = psMetadataLookupF32 (&status, row, "AP_MAG"); 288 @=PS1_V3@ source->apMagRaw = psMetadataLookupF32 (&status, row, "AP_MAG_RAW"); 289 290 // XXX use these to determine PAR[PM_PAR_I0] if they exist? 291 @=PS1_V3@ source->psfFlux = psMetadataLookupF32 (&status, row, "PSF_INST_FLUX"); 292 @=PS1_V3@ source->psfFluxErr= psMetadataLookupF32 (&status, row, "PSF_INST_FLUX_SIG"); 285 293 286 294 // XXX this scaling is incorrect: does not include the 2 \pi AREA factor … … 288 296 @ALL@ dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 289 297 290 pmPSF_AxesToModel (PAR, axes );298 pmPSF_AxesToModel (PAR, axes, modelType); 291 299 292 300 @ALL@ float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 353 361 } 354 362 355 bool pmSourcesWrite_CMF_ PS1_V3_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe)363 bool pmSourcesWrite_CMF_@CMFMODE@_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe) 356 364 { 357 365 bool status; … … 541 549 542 550 // XXX this layout is still the same as PS1_DEV_1 543 bool pmSourcesWrite_CMF_ PS1_V3_XFIT (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname)551 bool pmSourcesWrite_CMF_@CMFMODE@_XFIT (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname) 544 552 { 545 553 … … 590 598 assert (model); 591 599 600 // pmSourceExtFitPars *extPars = source->extFitPars->data[j]; 601 // assert (extPars); 602 592 603 // skip models which were not actually fitted 593 604 if (model->flags & PM_MODEL_STATUS_BADARGS) continue; … … 600 611 yErr = dPAR[PM_PAR_YPOS]; 601 612 602 axes = pmPSF_ModelToAxes (PAR, 20.0); 613 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 614 615 float kronFlux = source->moments ? source->moments->KronFlux : NAN; 616 float kronMag = isfinite(kronFlux) ? -2.5*log10(kronFlux) : NAN; 603 617 604 618 row = psMetadataAlloc (); … … 612 626 psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG", 0, "EXT fit instrumental magnitude", model->mag); 613 627 psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG_SIG", 0, "Sigma of PSF instrumental magnitude", model->magErr); 628 629 // psMetadataAddF32 (row, PS_LIST_TAIL, "MOMENTS_XX", 0, "second moment in x", extPars->Mxx); 630 // psMetadataAddF32 (row, PS_LIST_TAIL, "MOMENTS_XY", 0, "second moment in x,y", extPars->Mxy); 631 // psMetadataAddF32 (row, PS_LIST_TAIL, "MOMENTS_YY", 0, "second moment in y", extPars->Myy); 632 // psMetadataAddF32 (row, PS_LIST_TAIL, "MOMENTS_R1", 0, "first radial moment", extPars->Mrf); 633 // psMetadataAddF32 (row, PS_LIST_TAIL, "MOMENTS_RH", 0, "half radial moment", extPars->Mrh); 634 635 psMetadataAddF32 (row, PS_LIST_TAIL, "PSF_INST_MAG", 0, "PSF fit instrumental magnitude", source->psfMag); 636 psMetadataAddF32 (row, PS_LIST_TAIL, "AP_MAG", 0, "PSF-sized aperture magnitude", source->apMag); 637 psMetadataAddF32 (row, PS_LIST_TAIL, "KRON_MAG", 0, "Kron Mag", kronMag); 614 638 615 639 psMetadataAddF32 (row, PS_LIST_TAIL, "NPARAMS", 0, "number of model parameters", model->params->n); … … 673 697 } 674 698 675 bool pmSourcesWrite_CMF_ PS1_V3_XRAD(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe)699 bool pmSourcesWrite_CMF_@CMFMODE@_XRAD(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe) 676 700 { 677 701 return true; -
trunk/psModules/src/objects/pmSourceIO_CMF_PS1_DV1.c
r31451 r32347 263 263 dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 264 264 265 pmPSF_AxesToModel (PAR, axes );265 pmPSF_AxesToModel (PAR, axes, modelType); 266 266 267 267 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 547 547 yErr = dPAR[PM_PAR_YPOS]; 548 548 549 axes = pmPSF_ModelToAxes (PAR, 20.0 );549 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 550 550 551 551 row = psMetadataAlloc (); -
trunk/psModules/src/objects/pmSourceIO_CMF_PS1_DV2.c
r31451 r32347 281 281 dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 282 282 283 pmPSF_AxesToModel (PAR, axes );283 pmPSF_AxesToModel (PAR, axes, modelType); 284 284 285 285 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 572 572 yErr = dPAR[PM_PAR_YPOS]; 573 573 574 axes = pmPSF_ModelToAxes (PAR, 20.0 );574 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 575 575 576 576 row = psMetadataAlloc (); -
trunk/psModules/src/objects/pmSourceIO_CMF_PS1_SV1.c
r31451 r32347 280 280 dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 281 281 282 pmPSF_AxesToModel (PAR, axes );282 pmPSF_AxesToModel (PAR, axes, modelType); 283 283 284 284 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 607 607 yErr = dPAR[PM_PAR_YPOS]; 608 608 609 axes = pmPSF_ModelToAxes (PAR, 20.0 );609 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 610 610 611 611 row = psMetadataAlloc (); -
trunk/psModules/src/objects/pmSourceIO_CMP.c
r31451 r32347 135 135 lsky = (source->sky < 1.0) ? 0.0 : log10(source->sky); 136 136 137 axes = pmPSF_ModelToAxes (PAR, 20.0 );137 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 138 138 139 139 float psfMagErr = isfinite(source->psfMagErr) ? source->psfMagErr : 999; … … 293 293 goto skip_source; 294 294 295 pmPSF_AxesToModel (PAR, axes );295 pmPSF_AxesToModel (PAR, axes, modelType); 296 296 297 297 psArrayAdd (sources, 100, source); -
trunk/psModules/src/objects/pmSourceIO_OBJ.c
r29004 r32347 91 91 } 92 92 93 axes = pmPSF_ModelToAxes (PAR, 20.0 );93 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 94 94 95 95 psLineInit (line); -
trunk/psModules/src/objects/pmSourceIO_PS1_CAL_0.c
r31451 r32347 113 113 yErr = dPAR[PM_PAR_YPOS]; 114 114 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 115 axes = pmPSF_ModelToAxes (PAR, 20.0 );115 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 116 116 } else { 117 117 axes.major = NAN; … … 288 288 dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 289 289 290 pmPSF_AxesToModel (PAR, axes );290 pmPSF_AxesToModel (PAR, axes, modelType); 291 291 292 292 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 618 618 yErr = dPAR[PM_PAR_YPOS]; 619 619 620 axes = pmPSF_ModelToAxes (PAR, 20.0 );620 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 621 621 622 622 // generate RA,DEC -
trunk/psModules/src/objects/pmSourceIO_PS1_DEV_0.c
r31451 r32347 89 89 yErr = dPAR[PM_PAR_YPOS]; 90 90 91 axes = pmPSF_ModelToAxes (PAR, 20.0 );91 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 92 92 } else { 93 93 // XXX: This code seg faults if source->peak is NULL. … … 214 214 source->psfMagErr = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG"); 215 215 216 pmPSF_AxesToModel (PAR, axes );216 pmPSF_AxesToModel (PAR, axes, modelType); 217 217 218 218 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); -
trunk/psModules/src/objects/pmSourceIO_PS1_DEV_1.c
r31451 r32347 95 95 yErr = dPAR[PM_PAR_YPOS]; 96 96 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 97 axes = pmPSF_ModelToAxes (PAR, 20.0 );97 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 98 98 } else { 99 99 axes.major = NAN; … … 257 257 dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 258 258 259 pmPSF_AxesToModel (PAR, axes );259 pmPSF_AxesToModel (PAR, axes, modelType); 260 260 261 261 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 522 522 yErr = dPAR[PM_PAR_YPOS]; 523 523 524 axes = pmPSF_ModelToAxes (PAR, 20.0 );524 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 525 525 526 526 row = psMetadataAlloc (); -
trunk/psModules/src/objects/pmSourceIO_SMPDATA.c
r31451 r32347 92 92 lsky = (source->sky < 1.0) ? 0.0 : log10(source->sky); 93 93 94 axes = pmPSF_ModelToAxes (PAR, 20.0 );94 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 95 95 96 96 } else { … … 190 190 axes.theta = psMetadataLookupF32 (&status, row, "THETA"); 191 191 192 pmPSF_AxesToModel (PAR, axes );192 pmPSF_AxesToModel (PAR, axes, modelType); 193 193 194 194 source->psfMag = psMetadataLookupF32 (&status, row, "MAG_RAW") - ZERO_POINT; -
trunk/psModules/src/objects/pmSourceIO_SX.c
r31451 r32347 81 81 // pmSourceSextractType (source, &type, &flags); 82 82 83 axes = pmPSF_ModelToAxes (PAR, 20.0 );83 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 84 84 85 85 psLineInit (line); -
trunk/psModules/src/objects/pmSourceMoments.c
r31670 r32347 96 96 // (int) so they can be used in the image index below. 97 97 98 // do 2 passes : the first pass should use a somewhat smaller radius and no sigma window to 99 // get an unbiased (but probably noisy) centroid 100 if (!pmSourceMomentsGetCentroid (source, 0.75*radius, 0.0, minSN, maskVal, source->peak->xf, source->peak->yf)) { 101 return false; 102 } 103 // second pass applies the Gaussian window and uses the centroid from the first pass 104 if (!pmSourceMomentsGetCentroid (source, radius, sigma, minSN, maskVal, source->moments->Mx, source->moments->My)) { 98 // XXX // do 2 passes : the first pass should use a somewhat smaller radius and no sigma window to 99 // XXX // get an unbiased (but probably noisy) centroid 100 // XXX if (!pmSourceMomentsGetCentroid (source, 0.75*radius, 0.0, minSN, maskVal, source->peak->xf, source->peak->yf)) { 101 // XXX return false; 102 // XXX } 103 // XXX // second pass applies the Gaussian window and uses the centroid from the first pass 104 // XXX if (!pmSourceMomentsGetCentroid (source, radius, sigma, minSN, maskVal, source->moments->Mx, source->moments->My)) { 105 // XXX return false; 106 // XXX } 107 108 // If we use a large radius for the centroid, it will be biased by any neighbors. The flux 109 // of any object drops pretty quickly outside 1-2 sigmas. (The exception is bright 110 // saturated stars, for which we need to use a very large radius here) 111 if (!pmSourceMomentsGetCentroid (source, 1.5*sigma, 0.0, minSN, maskVal, source->peak->xf, source->peak->yf)) { 105 112 return false; 106 113 } … … 108 115 // Now calculate higher-order moments, using the above-calculated first moments to adjust coordinates 109 116 // Xn = SUM (x - xc)^n * (z - sky) 110 111 float RFW = 0.0;112 float RHW = 0.0;113 114 float RF = 0.0;115 float RH = 0.0;116 float RS = 0.0;117 117 float XX = 0.0; 118 118 float XY = 0.0; … … 143 143 float yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage 144 144 145 // calculate the higher-order moments using Xo,Yo 145 146 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 146 147 … … 194 195 Sum += pDiff; 195 196 196 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?)197 197 float r = sqrt(r2); 198 float rf = r * fDiff;199 float rh = sqrt(r) * fDiff;200 float rs = fDiff;201 202 float rfw = r * pDiff;203 float rhw = sqrt(r) * pDiff;204 198 205 199 float x = xDiff * pDiff; … … 221 215 float yyyy = yDiff * yyy / r2; 222 216 223 RF += rf;224 RH += rh;225 RS += rs;226 227 RFW += rfw;228 RHW += rhw;229 230 217 XX += xx; 231 218 XY += xy; … … 242 229 XYYY += xyyy; 243 230 YYYY += yyyy; 231 232 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?) 233 // XXX float r = sqrt(r2); 234 // XXX float rf = r * fDiff; 235 // XXX float rh = sqrt(r) * fDiff; 236 // XXX float rs = fDiff; 237 // XXX 238 // XXX float rfw = r * pDiff; 239 // XXX float rhw = sqrt(r) * pDiff; 240 // XXX 241 // XXX RF += rf; 242 // XXX RH += rh; 243 // XXX RS += rs; 244 // XXX 245 // XXX RFW += rfw; 246 // XXX RHW += rhw; 244 247 } 245 248 } 246 247 source->moments->Mrf = RF/RS;248 source->moments->Mrh = RH/RS;249 250 249 source->moments->Mxx = XX/Sum; 251 250 source->moments->Mxy = XY/Sum; … … 262 261 source->moments->Mxyyy = XYYY/Sum; 263 262 source->moments->Myyyy = YYYY/Sum; 263 264 // *** now calculate the 1st radial moment (for kron flux) -- symmetrical averaging 265 266 float **vPix = source->pixels->data.F32; 267 float **vWgt = source->variance->data.F32; 268 psImageMaskType **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA; 269 270 float RF = 0.0; 271 float RH = 0.0; 272 float RS = 0.0; 273 274 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 275 276 float yDiff = row - yCM; 277 if (fabs(yDiff) > radius) continue; 278 279 // coordinate of mirror pixel 280 int yFlip = yCM - yDiff; 281 if (yFlip < 0) continue; 282 if (yFlip >= source->pixels->numRows) continue; 283 284 for (psS32 col = 0; col < source->pixels->numCols ; col++) { 285 // check mask and value for this pixel 286 if (vMsk && (vMsk[row][col] & maskVal)) continue; 287 if (isnan(vPix[row][col])) continue; 288 289 float xDiff = col - xCM; 290 if (fabs(xDiff) > radius) continue; 291 292 // coordinate of mirror pixel 293 int xFlip = xCM - xDiff; 294 if (xFlip < 0) continue; 295 if (xFlip >= source->pixels->numCols) continue; 296 297 // check mask and value for mirror pixel 298 if (vMsk && (vMsk[yFlip][xFlip] & maskVal)) continue; 299 if (isnan(vPix[yFlip][xFlip])) continue; 300 301 // radius is just a function of (xDiff, yDiff) 302 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 303 if (r2 > R2) continue; 304 305 float fDiff1 = vPix[row][col] - sky; 306 float fDiff2 = vPix[yFlip][xFlip] - sky; 307 float pDiff = (fDiff1 > 0.0) ? sqrt(fabs(fDiff1*fDiff2)) : -sqrt(fabs(fDiff1*fDiff2)); 308 309 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?) 310 float r = sqrt(r2); 311 float rf = r * pDiff; 312 float rh = sqrt(r) * pDiff; 313 float rs = 0.5 * (fDiff1 + fDiff2); 314 315 RF += rf; 316 RH += rh; 317 RS += rs; 318 } 319 } 320 321 source->moments->Mrf = RF/RS; 322 source->moments->Mrh = RH/RS; 264 323 265 324 // if Mrf (first radial moment) is very small, we are getting into low-significance … … 270 329 kronRefRadius = MIN(radius, kronRefRadius); 271 330 } 331 332 // *** now calculate the kron flux values using the 1st radial moment 272 333 273 334 float radKinner = 1.0*kronRefRadius; … … 283 344 float SumOuter = 0.0; 284 345 346 // calculate the Kron flux, and related fluxes (NO symmetrical averaging) 285 347 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 286 348 287 349 float yDiff = row - yCM; 288 350 if (fabs(yDiff) > radKouter) continue; 351 352 for (psS32 col = 0; col < source->pixels->numCols ; col++) { 353 // check mask and value for this pixel 354 if (vMsk && (vMsk[row][col] & maskVal)) continue; 355 if (isnan(vPix[row][col])) continue; 356 357 float xDiff = col - xCM; 358 if (fabs(xDiff) > radKouter) continue; 359 360 // radKron is just a function of (xDiff, yDiff) 361 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 362 363 float fDiff1 = vPix[row][col] - sky; 364 float pDiff = fDiff1; 365 float wDiff = vWgt[row][col]; 366 367 // skip pixels below specified significance level. this is allowed, but should be 368 // avoided -- the over-weights the wings of bright stars compared to those of faint 369 // stars. 370 if (PS_SQR(pDiff) < minSN2*wDiff) continue; 371 372 float r = sqrt(r2); 373 if (r < radKron) { 374 Sum += pDiff; 375 Var += wDiff; 376 nKronPix ++; 377 // if (beVerbose) fprintf (stderr, "mome: %d %d %f %f %f\n", col, row, sky, *vPix, Sum); 378 } 379 380 // use sigma (fixed by psf) not a radKron based value 381 if (r < sigma) { 382 SumCore += pDiff; 383 VarCore += wDiff; 384 nCorePix ++; 385 } 386 387 if ((r > radKinner) && (r < radKron)) { 388 SumInner += pDiff; 389 nInner ++; 390 } 391 if ((r > radKron) && (r < radKouter)) { 392 SumOuter += pDiff; 393 nOuter ++; 394 } 395 } 396 } 397 // *** should I rescale these fluxes by pi R^2 / nNpix? 398 // XXX source->moments->KronCore = SumCore * M_PI * PS_SQR(sigma) / nCorePix; 399 // XXX source->moments->KronCoreErr = sqrt(VarCore) * M_PI * PS_SQR(sigma) / nCorePix; 400 // XXX source->moments->KronFlux = Sum * M_PI * PS_SQR(radKron) / nKronPix; 401 // XXX source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix; 402 // XXX source->moments->KronFinner = SumInner * M_PI * (PS_SQR(radKron) - PS_SQR(radKinner)) / nInner; 403 // XXX source->moments->KronFouter = SumOuter * M_PI * (PS_SQR(radKouter) - PS_SQR(radKron)) / nOuter; 404 405 source->moments->KronCore = SumCore; 406 source->moments->KronCoreErr = sqrt(VarCore); 407 source->moments->KronFlux = Sum; 408 source->moments->KronFluxErr = sqrt(Var); 409 source->moments->KronFinner = SumInner; 410 source->moments->KronFouter = SumOuter; 411 412 // XXX not sure I should save this here... 413 source->moments->KronFluxPSF = source->moments->KronFlux; 414 source->moments->KronFluxPSFErr = source->moments->KronFluxErr; 415 source->moments->KronRadiusPSF = source->moments->Mrf; 416 417 psTrace ("psModules.objects", 4, "Mrf: %f KronFlux: %f Mxx: %f Mxy: %f Myy: %f Mxxx: %f Mxxy: %f Mxyy: %f Myyy: %f Mxxxx: %f Mxxxy: %f Mxxyy: %f Mxyyy: %f Mxyyy: %f\n", 418 source->moments->Mrf, source->moments->KronFlux, 419 source->moments->Mxx, source->moments->Mxy, source->moments->Myy, 420 source->moments->Mxxx, source->moments->Mxxy, source->moments->Mxyy, source->moments->Myyy, 421 source->moments->Mxxxx, source->moments->Mxxxy, source->moments->Mxxyy, source->moments->Mxyyy, source->moments->Myyyy); 422 423 psTrace ("psModules.objects", 3, "peak %f %f (%f = %f) Mx: %f My: %f Sum: %f Mxx: %f Mxy: %f Myy: %f sky: %f Npix: %d\n", 424 source->peak->xf, source->peak->yf, source->peak->rawFlux, sqrt(source->peak->detValue), source->moments->Mx, source->moments->My, Sum, source->moments->Mxx, source->moments->Mxy, source->moments->Myy, sky, source->moments->nPixels); 425 426 return(true); 427 } 428 429 bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) { 430 431 // First Pass: calculate the first moments (these are subtracted from the coordinates below) 432 // Sum = SUM (z - sky) 433 // X1 = SUM (x - xc)*(z - sky) 434 // .. etc 435 436 float sky = 0.0; 437 438 float peakPixel = -PS_MAX_F32; 439 psS32 numPixels = 0; 440 float Sum = 0.0; 441 float Var = 0.0; 442 float X1 = 0.0; 443 float Y1 = 0.0; 444 float R2 = PS_SQR(radius); 445 float minSN2 = PS_SQR(minSN); 446 float rsigma2 = 0.5 / PS_SQR(sigma); 447 448 float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage 449 float yPeak = yGuess - source->pixels->row0; // coord of peak in subimage 450 451 // we are guaranteed to have a valid pixel and variance at this location (right? right?) 452 // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]); 453 // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); 454 // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); 455 // psAssert (source->variance->data.F32[yPeak][xPeak] > 0, "peak must be on valid pixel"); 456 457 // the moments [Sum(x*f) / Sum(f)] are calculated in pixel index values, and should 458 // not depend on the fractional pixel location of the source. However, the aperture 459 // (radius) and the Gaussian window (sigma) depend subtly on the fractional pixel 460 // position of the expected centroid 461 462 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 463 464 float yDiff = row + 0.5 - yPeak; 465 if (fabs(yDiff) > radius) continue; 289 466 290 467 float *vPix = source->pixels->data.F32[row]; 291 468 float *vWgt = source->variance->data.F32[row]; 292 469 293 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];294 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];470 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row]; 471 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row]; 295 472 296 473 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) { … … 304 481 if (isnan(*vPix)) continue; 305 482 306 float xDiff = col - xCM;307 if (fabs(xDiff) > radKouter) continue;308 309 // radKron is just a function of (xDiff, yDiff)310 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff);311 312 float pDiff = *vPix - sky;313 float wDiff = *vWgt;314 315 // skip pixels below specified significance level. this is allowed, but should be316 // avoided -- the over-weights the wings of bright stars compared to those of faint317 // stars.318 if (PS_SQR(pDiff) < minSN2*wDiff) continue;319 320 float r = sqrt(r2);321 if (r < radKron) {322 Sum += pDiff;323 Var += wDiff;324 nKronPix ++;325 // if (beVerbose) fprintf (stderr, "mome: %d %d %f %f %f\n", col, row, sky, *vPix, Sum);326 }327 328 // use sigma (fixed by psf) not a radKron based value329 if (r < sigma) {330 SumCore += pDiff;331 VarCore += wDiff;332 nCorePix ++;333 }334 335 if ((r > radKinner) && (r < radKron)) {336 SumInner += pDiff;337 nInner ++;338 }339 if ((r > radKron) && (r < radKouter)) {340 SumOuter += pDiff;341 nOuter ++;342 }343 }344 }345 // *** should I rescale these fluxes by pi R^2 / nNpix?346 source->moments->KronCore = SumCore * M_PI * PS_SQR(sigma) / nCorePix;347 source->moments->KronCoreErr = sqrt(VarCore) * M_PI * PS_SQR(sigma) / nCorePix;348 source->moments->KronFlux = Sum * M_PI * PS_SQR(radKron) / nKronPix;349 source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix;350 source->moments->KronFinner = SumInner * M_PI * (PS_SQR(radKron) - PS_SQR(radKinner)) / nInner;351 source->moments->KronFouter = SumOuter * M_PI * (PS_SQR(radKouter) - PS_SQR(radKron)) / nOuter;352 353 psTrace ("psModules.objects", 4, "Mrf: %f KronFlux: %f Mxx: %f Mxy: %f Myy: %f Mxxx: %f Mxxy: %f Mxyy: %f Myyy: %f Mxxxx: %f Mxxxy: %f Mxxyy: %f Mxyyy: %f Mxyyy: %f\n",354 source->moments->Mrf, source->moments->KronFlux,355 source->moments->Mxx, source->moments->Mxy, source->moments->Myy,356 source->moments->Mxxx, source->moments->Mxxy, source->moments->Mxyy, source->moments->Myyy,357 source->moments->Mxxxx, source->moments->Mxxxy, source->moments->Mxxyy, source->moments->Mxyyy, source->moments->Myyyy);358 359 psTrace ("psModules.objects", 3, "peak %f %f (%f = %f) Mx: %f My: %f Sum: %f Mxx: %f Mxy: %f Myy: %f sky: %f Npix: %d\n",360 source->peak->xf, source->peak->yf, source->peak->rawFlux, sqrt(source->peak->detValue), source->moments->Mx, source->moments->My, Sum, source->moments->Mxx, source->moments->Mxy, source->moments->Myy, sky, source->moments->nPixels);361 362 return(true);363 }364 365 bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) {366 367 // First Pass: calculate the first moments (these are subtracted from the coordinates below)368 // Sum = SUM (z - sky)369 // X1 = SUM (x - xc)*(z - sky)370 // .. etc371 372 float sky = 0.0;373 374 float peakPixel = -PS_MAX_F32;375 psS32 numPixels = 0;376 float Sum = 0.0;377 float Var = 0.0;378 float X1 = 0.0;379 float Y1 = 0.0;380 float R2 = PS_SQR(radius);381 float minSN2 = PS_SQR(minSN);382 float rsigma2 = 0.5 / PS_SQR(sigma);383 384 float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage385 float yPeak = yGuess - source->pixels->row0; // coord of peak in subimage386 387 // we are guaranteed to have a valid pixel and variance at this location (right? right?)388 // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]);389 // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel");390 // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel");391 // psAssert (source->variance->data.F32[yPeak][xPeak] > 0, "peak must be on valid pixel");392 393 // the moments [Sum(x*f) / Sum(f)] are calculated in pixel index values, and should394 // not depend on the fractional pixel location of the source. However, the aperture395 // (radius) and the Gaussian window (sigma) depend subtly on the fractional pixel396 // position of the expected centroid397 398 for (psS32 row = 0; row < source->pixels->numRows ; row++) {399 400 float yDiff = row + 0.5 - yPeak;401 if (fabs(yDiff) > radius) continue;402 403 float *vPix = source->pixels->data.F32[row];404 float *vWgt = source->variance->data.F32[row];405 406 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];407 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];408 409 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {410 if (vMsk) {411 if (*vMsk & maskVal) {412 vMsk++;413 continue;414 }415 vMsk++;416 }417 if (isnan(*vPix)) continue;418 419 483 float xDiff = col + 0.5 - xPeak; 420 484 if (fabs(xDiff) > radius) continue; -
trunk/psModules/src/objects/pmSourceOutputs.c
r31451 r32347 107 107 } 108 108 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXY]) && isfinite(PAR[PM_PAR_SYY])) { 109 axes = pmPSF_ModelToAxes (PAR, 20.0 );109 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 110 110 outputs->psfMajor = axes.major; 111 111 outputs->psfMinor = axes.minor; … … 178 178 moments->KronCore = source->moments ? source->moments->KronCore : NAN; 179 179 moments->KronCoreErr = source->moments ? source->moments->KronCoreErr : NAN; 180 181 return true; 182 } 180 moments->KronPSF = source->moments ? source->moments->KronFluxPSF : NAN; 181 moments->KronPSFErr = source->moments ? source->moments->KronFluxPSFErr : NAN; 182 183 return true; 184 } 185 186 bool pmSourceLocalAstrometry (psSphere *ptSky, float *posAngle, float *pltScale, pmChip *chip, float xPos, float yPos) { 187 188 pmFPA *fpa = chip->parent; 189 190 if (!chip->toFPA) goto escape; 191 if (!fpa->toTPA) goto escape; 192 if (!fpa->toSky) goto escape; 193 194 // generate RA,DEC 195 psPlane ptCH, ptFP, ptTP_o, ptTP_x, ptTP_y; 196 197 // calculate the astrometry for the coordinate of interest 198 ptCH.x = xPos; 199 ptCH.y = yPos; 200 psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH); 201 psPlaneTransformApply (&ptTP_o, fpa->toTPA, &ptFP); 202 psDeproject (ptSky, &ptTP_o, fpa->toSky); 203 204 // calculate the astrometry for the coordinate + 1pix in X 205 ptCH.x = xPos + 1.0; 206 ptCH.y = yPos; 207 psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH); 208 psPlaneTransformApply (&ptTP_x, fpa->toTPA, &ptFP); 209 210 // calculate the astrometry for the coordinate + 1pix in Y 211 ptCH.x = xPos; 212 ptCH.y = yPos + 1.0; 213 psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH); 214 psPlaneTransformApply (&ptTP_y, fpa->toTPA, &ptFP); 215 216 // the resulting Tangent Plane coordinates are in TP pixels; convert to local Tangent Plane 217 // degrees 218 219 float dTPx_dCHx = fpa->toSky->Xs * (ptTP_x.x - ptTP_o.x); 220 float dTPy_dCHx = fpa->toSky->Ys * (ptTP_x.y - ptTP_o.y); 221 222 float dTPx_dCHy = fpa->toSky->Xs * (ptTP_y.x - ptTP_o.x); 223 float dTPy_dCHy = fpa->toSky->Ys * (ptTP_y.y - ptTP_o.y); 224 225 float pltScale_x = hypot(dTPx_dCHx, dTPy_dCHx); 226 float pltScale_y = hypot(dTPx_dCHy, dTPy_dCHy); 227 *pltScale = 0.5*(pltScale_x + pltScale_y); 228 229 float posAngle_x = atan2 (+dTPy_dCHx, +dTPx_dCHx); 230 float posAngle_y = atan2 (-dTPy_dCHy, +dTPx_dCHy); 231 *posAngle = 0.5*(posAngle_x + posAngle_y); 232 233 return true; 234 235 escape: 236 // no astrometry calibration, give up 237 ptSky->r = NAN; 238 ptSky->d = NAN; 239 *posAngle = NAN; 240 *pltScale = NAN; 241 242 return false; 243 } 244 -
trunk/psModules/src/objects/pmSourceOutputs.h
r31153 r32347 52 52 float KronCore; 53 53 float KronCoreErr; 54 float KronPSF; 55 float KronPSFErr; 54 56 } pmSourceOutputsMoments; 55 57 -
trunk/psModules/src/objects/pmSourcePhotometry.c
r31670 r32347 94 94 { 95 95 PS_ASSERT_PTR_NON_NULL(source, false); 96 PS_ASSERT_PTR_NON_NULL(psf, false);96 // PS_ASSERT_PTR_NON_NULL(psf, false); 97 97 98 98 int status = false; -
trunk/psModules/src/objects/pmSourcePlotPSFModel.c
r29004 r32347 145 145 // force the axis ratio to be < 20.0 146 146 psEllipseAxes axes_mnt = psEllipseMomentsToAxes (moments, 20.0); 147 psEllipseAxes axes_psf = pmPSF_ModelToAxes (PAR, 20.0 );147 psEllipseAxes axes_psf = pmPSF_ModelToAxes (PAR, 20.0, model->type); 148 148 149 149 // moments major axis
Note:
See TracChangeset
for help on using the changeset viewer.
