Changeset 31153 for trunk/psModules/src/objects
- Timestamp:
- Apr 4, 2011, 1:04:41 PM (15 years ago)
- Location:
- trunk/psModules
- Files:
-
- 54 edited
- 2 copied
-
. (modified) (1 prop)
-
src/objects/Makefile.am (modified) (2 diffs)
-
src/objects/models/pmModel_DEV.c (modified) (2 diffs)
-
src/objects/models/pmModel_EXP.c (modified) (2 diffs)
-
src/objects/models/pmModel_GAUSS.c (modified) (2 diffs)
-
src/objects/models/pmModel_PGAUSS.c (modified) (2 diffs)
-
src/objects/models/pmModel_PS1_V1.c (modified) (2 diffs)
-
src/objects/models/pmModel_QGAUSS.c (modified) (2 diffs)
-
src/objects/models/pmModel_RGAUSS.c (modified) (2 diffs)
-
src/objects/models/pmModel_SERSIC.c (modified) (4 diffs)
-
src/objects/pmFootprint.c (modified) (1 diff)
-
src/objects/pmFootprint.h (modified) (2 diffs)
-
src/objects/pmFootprintAssignPeaks.c (modified) (3 diffs)
-
src/objects/pmFootprintCullPeaks.c (modified) (6 diffs)
-
src/objects/pmFootprintFindAtPoint.c (modified) (6 diffs)
-
src/objects/pmFootprintIDs.c (modified) (1 diff)
-
src/objects/pmModel.c (modified) (3 diffs)
-
src/objects/pmModel.h (modified) (2 diffs)
-
src/objects/pmModelUtils.c (modified) (1 diff)
-
src/objects/pmModelUtils.h (modified) (1 diff)
-
src/objects/pmMoments.h (modified) (1 diff)
-
src/objects/pmPCMdata.c (modified) (2 diffs)
-
src/objects/pmPCMdata.h (modified) (1 diff)
-
src/objects/pmPSF.c (modified) (2 diffs)
-
src/objects/pmPSFtryFitPSF.c (modified) (1 diff)
-
src/objects/pmPeaks.c (modified) (7 diffs)
-
src/objects/pmPeaks.h (modified) (4 diffs)
-
src/objects/pmPhotObj.c (modified) (3 diffs)
-
src/objects/pmPhotObj.h (modified) (2 diffs)
-
src/objects/pmSource.c (modified) (9 diffs)
-
src/objects/pmSource.h (modified) (2 diffs)
-
src/objects/pmSourceExtendedPars.c (modified) (2 diffs)
-
src/objects/pmSourceExtendedPars.h (modified) (2 diffs)
-
src/objects/pmSourceFitModel.c (modified) (3 diffs)
-
src/objects/pmSourceFitModel.h (modified) (1 diff)
-
src/objects/pmSourceFitPCM.c (modified) (3 diffs)
-
src/objects/pmSourceFitSet.c (modified) (11 diffs)
-
src/objects/pmSourceFitSet.h (modified) (2 diffs)
-
src/objects/pmSourceIO_CMF_PS1_DV1.c (modified) (10 diffs)
-
src/objects/pmSourceIO_CMF_PS1_DV2.c (modified) (11 diffs)
-
src/objects/pmSourceIO_CMF_PS1_SV1.c (modified) (20 diffs)
-
src/objects/pmSourceIO_CMF_PS1_V1.c (modified) (9 diffs)
-
src/objects/pmSourceIO_CMF_PS1_V2.c (modified) (9 diffs)
-
src/objects/pmSourceIO_CMF_PS1_V3.c (modified) (10 diffs)
-
src/objects/pmSourceIO_PS1_CAL_0.c (modified) (5 diffs)
-
src/objects/pmSourceIO_PS1_DEV_0.c (modified) (2 diffs)
-
src/objects/pmSourceIO_PS1_DEV_1.c (modified) (5 diffs)
-
src/objects/pmSourceIO_RAW.c (modified) (5 diffs)
-
src/objects/pmSourceIO_SMPDATA.c (modified) (1 diff)
-
src/objects/pmSourceMasks.h (modified) (1 diff)
-
src/objects/pmSourceMoments.c (modified) (6 diffs)
-
src/objects/pmSourceOutputs.c (copied) (copied from branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourceOutputs.c )
-
src/objects/pmSourceOutputs.h (copied) (copied from branches/eam_branches/ipp-20110213/psModules/src/objects/pmSourceOutputs.h )
-
src/objects/pmSourcePhotometry.c (modified) (11 diffs)
-
src/objects/pmSourcePhotometry.h (modified) (1 diff)
-
src/objects/pmSourceVisual.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules
- Property svn:ignore
-
old new 28 28 ChangeLog 29 29 psmodules-*.tar.* 30 a.out.dSYM
-
- Property svn:ignore
-
trunk/psModules/src/objects/Makefile.am
r29004 r31153 32 32 pmSourceFitSet.c \ 33 33 pmSourcePhotometry.c \ 34 pmSourceOutputs.c \ 34 35 pmSourceIO.c \ 35 36 pmSourceIO_RAW.c \ … … 102 103 pmSourceFitSet.h \ 103 104 pmSourcePhotometry.h \ 105 pmSourceOutputs.h \ 104 106 pmSourceIO.h \ 105 107 pmSourcePlots.h \ -
trunk/psModules/src/objects/models/pmModel_DEV.c
r29004 r31153 217 217 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 218 218 { 219 pmMoments *moments = source->moments; 220 pmPeak *peak = source->peak; 221 psF32 *PAR = model->params->data.F32; 222 223 psEllipseMoments emoments; 224 emoments.x2 = moments->Mxx; 225 emoments.xy = moments->Mxy; 226 emoments.y2 = moments->Myy; 227 228 // force the axis ratio to be < 20.0 229 psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0); 230 231 if (!isfinite(axes.major)) return false; 232 if (!isfinite(axes.minor)) return false; 233 if (!isfinite(axes.theta)) return false; 234 235 psEllipseShape shape = psEllipseAxesToShape (axes); 236 237 if (!isfinite(shape.sx)) return false; 238 if (!isfinite(shape.sy)) return false; 239 if (!isfinite(shape.sxy)) return false; 240 241 // the other parameters depend on the guess for PAR_7 219 psF32 *PAR = model->params->data.F32; 220 221 // sky is set to 0.0 222 PAR[PM_PAR_SKY] = 0.0; 223 224 // set the shape parameters 225 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 226 return false; 227 } 228 229 // the normalization is modified by the slope 242 230 float index = 0.5 / ALPHA; 243 231 float bn = 1.9992*index - 0.3271; 244 // float fR = 1.0 / (sqrt(2.0) * pow (bn, index));245 232 float Io = exp(0.5*bn); 246 233 247 float Sxx = PS_MAX(0.5, shape.sx); 248 float Syy = PS_MAX(0.5, shape.sy); 249 250 PAR[PM_PAR_SKY] = 0.0; 251 PAR[PM_PAR_I0] = peak->flux / Io; 252 PAR[PM_PAR_XPOS] = peak->xf; 253 PAR[PM_PAR_YPOS] = peak->yf; 254 // PAR[PM_PAR_SXX] = Sxx * fR; 255 // PAR[PM_PAR_SYY] = Syy * fR; 256 PAR[PM_PAR_SXX] = Sxx; 257 PAR[PM_PAR_SYY] = Syy; 258 PAR[PM_PAR_SXY] = shape.sxy; 234 // set the model normalization 235 if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) { 236 return false; 237 } 238 PAR[PM_PAR_I0] /= Io; 239 240 // set the model position 241 if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) { 242 return false; 243 } 259 244 260 245 return(true); … … 322 307 psF64 radius = axes.major * sqrt (2.0) * pow(zn, 0.5 / ALPHA); 323 308 324 psAssert (isfinite(radius), "fix this code: z should not be nan"); 309 psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)", 310 PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY]); 311 325 312 return (radius); 326 313 } -
trunk/psModules/src/objects/models/pmModel_EXP.c
r29004 r31153 210 210 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 211 211 { 212 pmMoments *moments = source->moments; 213 pmPeak *peak = source->peak; 214 psF32 *PAR = model->params->data.F32; 215 216 psEllipseMoments emoments; 217 emoments.x2 = moments->Mxx; 218 emoments.xy = moments->Mxy; 219 emoments.y2 = moments->Myy; 220 221 // force the axis ratio to be < 20.0 222 psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0); 223 224 if (!isfinite(axes.major)) return false; 225 if (!isfinite(axes.minor)) return false; 226 if (!isfinite(axes.theta)) return false; 227 228 psEllipseShape shape = psEllipseAxesToShape (axes); 229 230 if (!isfinite(shape.sx)) return false; 231 if (!isfinite(shape.sy)) return false; 232 if (!isfinite(shape.sxy)) return false; 233 212 psF32 *PAR = model->params->data.F32; 213 214 // sky is set to 0.0 234 215 PAR[PM_PAR_SKY] = 0.0; 235 PAR[PM_PAR_I0] = peak->flux; 236 PAR[PM_PAR_XPOS] = peak->xf; 237 PAR[PM_PAR_YPOS] = peak->yf; 238 PAR[PM_PAR_SXX] = PS_MAX(0.5, M_SQRT2*shape.sx); 239 PAR[PM_PAR_SYY] = PS_MAX(0.5, M_SQRT2*shape.sy); 240 PAR[PM_PAR_SXY] = shape.sxy; 216 217 // set the shape parameters 218 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 219 return false; 220 } 221 222 // set the model normalization 223 if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) { 224 return false; 225 } 226 227 // set the model position 228 if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) { 229 return false; 230 } 231 241 232 return(true); 242 233 } … … 303 294 psF64 radius = axes.major * sqrt (2.0) * zn; 304 295 305 psAssert (isfinite(radius), "fix this code: z should not be nan for %f", PAR[PM_PAR_7]); 296 psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)", 297 PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY]); 306 298 return (radius); 307 299 } -
trunk/psModules/src/objects/models/pmModel_GAUSS.c
r29004 r31153 193 193 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 194 194 { 195 pmMoments *moments = source->moments; 196 pmPeak *peak = source->peak; 197 psF32 *PAR = model->params->data.F32; 198 199 psEllipseMoments emoments; 200 emoments.x2 = moments->Mxx; 201 emoments.y2 = moments->Myy; 202 emoments.xy = moments->Mxy; 203 204 // force the axis ratio to be < 20.0 205 psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0); 206 psEllipseShape shape = psEllipseAxesToShape (axes); 207 195 psF32 *PAR = model->params->data.F32; 196 197 // sky is set to 0.0 208 198 PAR[PM_PAR_SKY] = 0.0; 209 PAR[PM_PAR_I0] = peak->flux; 210 PAR[PM_PAR_XPOS] = peak->xf; 211 PAR[PM_PAR_YPOS] = peak->yf; 212 PAR[PM_PAR_SXX] = PS_MAX(0.5, M_SQRT2*shape.sx); 213 PAR[PM_PAR_SYY] = PS_MAX(0.5, M_SQRT2*shape.sy); 214 PAR[PM_PAR_SXY] = shape.sxy; 199 200 // set the shape parameters 201 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 202 return false; 203 } 204 205 // set the model normalization 206 if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) { 207 return false; 208 } 209 210 // set the model position 211 if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) { 212 return false; 213 } 214 215 215 return(true); 216 216 } … … 258 258 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 259 259 psF64 radius = axes.major * sqrt (2.0 * log(PAR[PM_PAR_I0] / flux)); 260 psAssert (isfinite(radius), "fix this code: radius should not be nan for %f", PAR[PM_PAR_I0]); 260 psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)", 261 PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY]); 261 262 262 263 return (radius); -
trunk/psModules/src/objects/models/pmModel_PGAUSS.c
r29004 r31153 194 194 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 195 195 { 196 pmMoments *moments = source->moments; 197 pmPeak *peak = source->peak; 198 psF32 *PAR = model->params->data.F32; 199 200 psEllipseMoments emoments; 201 emoments.x2 = moments->Mxx; 202 emoments.xy = moments->Mxy; 203 emoments.y2 = moments->Myy; 204 205 psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0); 206 psEllipseShape shape = psEllipseAxesToShape (axes); 207 196 psF32 *PAR = model->params->data.F32; 197 198 // sky is set to 0.0 208 199 PAR[PM_PAR_SKY] = 0.0; 209 PAR[PM_PAR_I0] = peak->flux; 210 PAR[PM_PAR_XPOS] = peak->xf; 211 PAR[PM_PAR_YPOS] = peak->yf; 212 PAR[PM_PAR_SXX] = PS_MAX(0.5, M_SQRT2*shape.sx); 213 PAR[PM_PAR_SYY] = PS_MAX(0.5, M_SQRT2*shape.sy); 214 PAR[PM_PAR_SXY] = shape.sxy; 200 201 // set the shape parameters 202 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 203 return false; 204 } 205 206 // set the model normalization 207 if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) { 208 return false; 209 } 210 211 // set the model position 212 if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) { 213 return false; 214 } 215 215 216 return(true); 216 217 } … … 285 286 // choose a z value guaranteed to be beyond our limit 286 287 float z0 = pow((1.0 / limit), (1.0 / 3.0)); 287 psAssert (isfinite(z0), "fix this code: z0 should not be nan for %f", PAR[PM_PAR_I0]); 288 psAssert (isfinite(z0), "fix this code: z0 should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)", 289 PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY]); 290 288 291 float z1 = (1.0 / limit); 289 psAssert (isfinite(z1), "fix this code: z1 should not be nan for %f", PAR[PM_PAR_I0]); 292 psAssert (isfinite(z1), "fix this code: z1 should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)", 293 PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY]); 294 290 295 z1 = PS_MAX (z0, z1); 291 296 z0 = 0.0; -
trunk/psModules/src/objects/models/pmModel_PS1_V1.c
r29004 r31153 213 213 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 214 214 { 215 pmMoments *moments = source->moments; 216 pmPeak *peak = source->peak; 217 psF32 *PAR = model->params->data.F32; 218 219 psEllipseMoments emoments; 220 emoments.x2 = moments->Mxx; 221 emoments.xy = moments->Mxy; 222 emoments.y2 = moments->Myy; 223 224 // force the axis ratio to be < 20.0 225 psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0); 226 227 if (!isfinite(axes.major)) return false; 228 if (!isfinite(axes.minor)) return false; 229 if (!isfinite(axes.theta)) return false; 230 231 psEllipseShape shape = psEllipseAxesToShape (axes); 232 233 if (!isfinite(shape.sx)) return false; 234 if (!isfinite(shape.sy)) return false; 235 if (!isfinite(shape.sxy)) return false; 236 215 psF32 *PAR = model->params->data.F32; 216 217 // sky is set to 0.0 237 218 PAR[PM_PAR_SKY] = 0.0; 238 PAR[PM_PAR_I0] = peak->flux; 239 PAR[PM_PAR_XPOS] = peak->xf; 240 PAR[PM_PAR_YPOS] = peak->yf; 241 PAR[PM_PAR_SXX] = PS_MAX(0.5, M_SQRT2*shape.sx); 242 PAR[PM_PAR_SYY] = PS_MAX(0.5, M_SQRT2*shape.sy); 243 PAR[PM_PAR_SXY] = shape.sxy; 219 220 // set the shape parameters 221 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 222 return false; 223 } 224 225 // set the model normalization 226 if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) { 227 return false; 228 } 229 230 // set the model position 231 if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) { 232 return false; 233 } 234 235 // extra parameter 244 236 PAR[PM_PAR_7] = 0.5; 245 237 … … 314 306 float z0 = 0.0; 315 307 float z1 = pow((1.0 / limit), (1.0 / ALPHA)); 316 psAssert (isfinite(z1), "fix this code: z1 should not be nan for %f", PAR[PM_PAR_7]); 308 psAssert (isfinite(z1), "fix this code: z1 should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)", 309 PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY]); 317 310 if (PAR[PM_PAR_7] < 0.0) z1 *= 2.0; 318 311 -
trunk/psModules/src/objects/models/pmModel_QGAUSS.c
r29004 r31153 214 214 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 215 215 { 216 pmMoments *moments = source->moments; 217 pmPeak *peak = source->peak; 218 psF32 *PAR = model->params->data.F32; 219 220 psEllipseMoments emoments; 221 emoments.x2 = moments->Mxx; 222 emoments.xy = moments->Mxy; 223 emoments.y2 = moments->Myy; 224 225 // force the axis ratio to be < 20.0 226 psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0); 227 228 if (!isfinite(axes.major)) return false; 229 if (!isfinite(axes.minor)) return false; 230 if (!isfinite(axes.theta)) return false; 231 232 psEllipseShape shape = psEllipseAxesToShape (axes); 233 234 if (!isfinite(shape.sx)) return false; 235 if (!isfinite(shape.sy)) return false; 236 if (!isfinite(shape.sxy)) return false; 237 216 psF32 *PAR = model->params->data.F32; 217 218 // sky is set to 0.0 238 219 PAR[PM_PAR_SKY] = 0.0; 239 PAR[PM_PAR_I0] = peak->flux; 240 PAR[PM_PAR_XPOS] = peak->xf; 241 PAR[PM_PAR_YPOS] = peak->yf; 242 PAR[PM_PAR_SXX] = PS_MAX(0.5, M_SQRT2*shape.sx); 243 PAR[PM_PAR_SYY] = PS_MAX(0.5, M_SQRT2*shape.sy); 244 PAR[PM_PAR_SXY] = shape.sxy; 220 221 // set the shape parameters 222 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 223 return false; 224 } 225 226 // set the model normalization 227 if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) { 228 return false; 229 } 230 231 // set the model position 232 if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) { 233 return false; 234 } 235 236 // extra parameter 245 237 PAR[PM_PAR_7] = 1.0; 246 238 … … 315 307 float z0 = 0.0; 316 308 float z1 = pow((1.0 / limit), (1.0 / ALPHA)); 317 psAssert (isfinite(z1), "fix this code: z1 should not be nan for %f", PAR[PM_PAR_7]); 309 psAssert (isfinite(z1), "fix this code: z1 should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)", 310 PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY]); 318 311 if (PAR[PM_PAR_7] < 0.0) z1 *= 2.0; 319 312 -
trunk/psModules/src/objects/models/pmModel_RGAUSS.c
r29004 r31153 203 203 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 204 204 { 205 pmMoments *moments = source->moments; 206 pmPeak *peak = source->peak; 207 psF32 *PAR = model->params->data.F32; 208 209 psEllipseMoments emoments; 210 emoments.x2 = moments->Mxx; 211 emoments.xy = moments->Mxy; 212 emoments.y2 = moments->Myy; 213 214 // force the axis ratio to be < 20.0 215 psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0); 216 217 if (!isfinite(axes.major)) return false; 218 if (!isfinite(axes.minor)) return false; 219 if (!isfinite(axes.theta)) return false; 220 221 psEllipseShape shape = psEllipseAxesToShape (axes); 222 223 if (!isfinite(shape.sx)) return false; 224 if (!isfinite(shape.sy)) return false; 225 if (!isfinite(shape.sxy)) return false; 226 205 psF32 *PAR = model->params->data.F32; 206 207 // sky is set to 0.0 227 208 PAR[PM_PAR_SKY] = 0.0; 228 PAR[PM_PAR_I0] = peak->flux; 229 PAR[PM_PAR_XPOS] = peak->xf; 230 PAR[PM_PAR_YPOS] = peak->yf; 231 PAR[PM_PAR_SXX] = PS_MAX(0.5, shape.sx); 232 PAR[PM_PAR_SYY] = PS_MAX(0.5, shape.sy); 233 PAR[PM_PAR_SXY] = shape.sxy; 209 210 // set the shape parameters 211 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 212 return false; 213 } 214 215 // set the model normalization 216 if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) { 217 return false; 218 } 219 220 // set the model position 221 if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) { 222 return false; 223 } 224 225 // extra parameter 234 226 PAR[PM_PAR_7] = 1.5; 235 227 … … 305 297 // choose a z value guaranteed to be beyond our limit 306 298 float z0 = pow((1.0 / limit), (1.0 / PAR[PM_PAR_7])); 307 psAssert (isfinite(z0), "fix this code: z0 should not be nan for %f", PAR[PM_PAR_7]); 299 psAssert (isfinite(z0), "fix this code: z0 should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f), par 7 = %f", 300 PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], PAR[PM_PAR_7]); 301 308 302 float z1 = (1.0 / limit); 309 psAssert (isfinite(z1), "fix this code: z1 should not be nan for %f", PAR[PM_PAR_7]); 303 psAssert (isfinite(z1), "fix this code: z1 should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f), par 7 = %f", 304 PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], PAR[PM_PAR_7]); 305 310 306 z1 = PS_MAX (z0, z1); 311 307 z0 = 0.0; -
trunk/psModules/src/objects/models/pmModel_SERSIC.c
r29028 r31153 222 222 { 223 223 pmMoments *moments = source->moments; 224 pmPeak *peak = source->peak;225 224 psF32 *PAR = model->params->data.F32; 225 226 // sky is set to 0.0 227 PAR[PM_PAR_SKY] = 0.0; 226 228 227 229 // the other parameters depend on the guess for PAR_7 … … 236 238 float Zero = 1.16 - 0.615 * PAR[PM_PAR_7]; 237 239 240 // Sersic shape is a bit special 238 241 psEllipseMoments emoments; 239 242 emoments.x2 = moments->Mxx; … … 273 276 float Syy = PS_MAX(0.5, shape.sy); 274 277 275 PAR[PM_PAR_SKY] = 0.0;276 PAR[PM_PAR_I0] = peak->flux / Io;277 PAR[PM_PAR_XPOS] = peak->xf;278 PAR[PM_PAR_YPOS] = peak->yf;279 278 PAR[PM_PAR_SXX] = Sxx; 280 279 PAR[PM_PAR_SYY] = Syy; 281 280 PAR[PM_PAR_SXY] = shape.sxy; 281 282 // set the model normalization (adjust for Sersic best guess) 283 if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) { 284 return false; 285 } 286 PAR[PM_PAR_I0] /= Io; 287 288 // set the model position 289 if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) { 290 return false; 291 } 282 292 283 293 return(true); … … 346 356 psF64 radius = axes.major * sqrt (2.0) * pow(zn, 0.5 / PAR[PM_PAR_7]); 347 357 348 // fprintf (stderr, "sersic model %f %f, n %f, radius: %f, zn: %f, f/Io: %f, major: %f\n", PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], PAR[PM_PAR_7], radius, zn, flux/PAR[PM_PAR_I0], axes.major); 349 350 psAssert (isfinite(radius), "fix this code: z should not be nan for %f", PAR[PM_PAR_7]); 358 psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f), par 7 = %f", 359 PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], PAR[PM_PAR_7]); 351 360 return (radius); 352 361 } -
trunk/psModules/src/objects/pmFootprint.c
r30621 r31153 98 98 } 99 99 100 // XXX not actually used anywhere 100 101 pmFootprint *pmFootprintNormalize(pmFootprint *fp) { 101 102 if (fp != NULL && !fp->normalized) { 102 fp->peaks = psArraySort(fp->peaks, pmPeakSortBySN); 103 if (PM_PEAKS_CULL_WITH_SMOOTHED_IMAGE) { 104 fp->peaks = psArraySort(fp->peaks, pmPeaksSortBySmoothFluxDescend); 105 } else { 106 fp->peaks = psArraySort(fp->peaks, pmPeaksSortByRawFluxDescend); 107 } 103 108 fp->normalized = true; 104 109 } -
trunk/psModules/src/objects/pmFootprint.h
r30621 r31153 10 10 #ifndef PM_FOOTPRINT_H 11 11 #define PM_FOOTPRINT_H 12 13 // We need to choose up front if the culling algorithm uses the raw or smoothed image. 14 // depending on which we choose, we should produce sorted peaks based on peak->rawFlux or 15 // peak->smoothFlux 16 17 # define PM_PEAKS_CULL_WITH_SMOOTHED_IMAGE 1 12 18 13 19 typedef struct { … … 84 90 const float nsigma_delta, // how many sigma above local background a peak needs to be to survive 85 91 const float fPadding, // fractional padding added to stdev since bright peaks have unreasonably high significance 86 const float min_threshold // minimum permitted coll height 92 const float min_threshold, // minimum permitted coll height 93 const float max_threshold,// maximum permitted coll height 94 const bool isWeightVar // the input weight may be variance (sigma^2) or S/N (1/sigma) 87 95 ); 88 96 -
trunk/psModules/src/objects/pmFootprintAssignPeaks.c
r30621 r31153 46 46 */ 47 47 psImage *ids = pmSetFootprintArrayIDs(footprints, true); 48 assert (ids != NULL);49 assert (ids->type.type == PS_TYPE_S32);50 const int row0 = ids ->row0;51 const int col0 = ids ->col0;52 const int numRows = ids ->numRows;53 const int numCols = ids ->numCols;48 if (ids) { assert (ids->type.type == PS_TYPE_S32); } 49 50 const int row0 = ids ? ids->row0 : 0; 51 const int col0 = ids ? ids->col0 : 0; 52 const int numRows = ids ? ids->numRows : -1; 53 const int numCols = ids ? ids->numCols : -1; 54 54 55 55 for (int i = 0; i < peaks->n; i++) { … … 58 58 const int y = peak->y - row0; 59 59 60 assert (x >= 0 && x < numCols && y >= 0 && y < numRows); 61 int id = ids->data.S32[y][x - col0]; 60 if (ids) { assert (x >= 0 && x < numCols && y >= 0 && y < numRows);} 61 int id = ids ? ids->data.S32[y][x - col0] : 0; 62 // XXX I think the '[x - col0]' above is just wrong (should be [x], but never gets triggerd. 62 63 63 64 if (id == 0) { // peak isn't in a footprint, so make one for it … … 86 87 if (fp->peaks->n == 1) continue; 87 88 88 fp->peaks = psArraySort(fp->peaks, pmPeakSortBySN); 89 // make sure the peaks are sorted in a way consistent with our cull process 90 if (PM_PEAKS_CULL_WITH_SMOOTHED_IMAGE) { 91 fp->peaks = psArraySort(fp->peaks, pmPeaksSortBySmoothFluxDescend); 92 } else { 93 fp->peaks = psArraySort(fp->peaks, pmPeaksSortByRawFluxDescend); 94 } 89 95 90 96 // XXX check for an assert on duplicates (I don't think they can happen, but -
trunk/psModules/src/objects/pmFootprintCullPeaks.c
r30621 r31153 38 38 const float nsigma_delta, // how many sigma above local background a peak needs to be to survive 39 39 const float fPadding, // fractional padding added to stdev since bright peaks have unreasonably high significance 40 const float min_threshold) { // minimum permitted coll height 40 const float min_threshold, // minimum permitted coll height 41 const float max_threshold, 42 const bool useSmoothedImage 43 ) { // maximum permitted coll height 41 44 assert (img != NULL); assert (img->type.type == PS_TYPE_F32); 42 45 assert (weight != NULL); assert (weight->type.type == PS_TYPE_F32); … … 44 47 assert (fp != NULL); 45 48 46 if (fp->peaks == NULL || fp->peaks->n == 0) { // nothing to do49 if (fp->peaks == NULL || fp->peaks->n < 2) { // nothing to do 47 50 return PS_ERR_NONE; 48 51 } … … 53 56 54 57 psImage *subImg = psImageSubset((psImage *)img, subRegion); 55 psImage *subWt = psImageSubset((psImage *)weight, subRegion); 56 assert (subImg != NULL && subWt != NULL); 58 psAssert (subImg, "trouble making local subimage"); 57 59 58 60 psImage *idImg = psImageAlloc(subImg->numCols, subImg->numRows, PS_TYPE_S32); … … 68 70 psArrayAdd (brightPeaks, 128, fp->peaks->data[0]); 69 71 72 // XXX test point 73 // pmPeak *myPeak = fp->peaks->data[0]; 74 // if ((fabs(myPeak->x - 205) < 100) && (fabs(myPeak->y - 806) < 100)) { 75 // fprintf (stderr, "test peak\n"); 76 // } 77 70 78 // allocate the peakFootprint and peakFPSpans containers -- these are re-used by pmFootprintsFindAtPoint to minimize allocs in this function 71 79 pmFootprint *peakFootprint = pmFootprintAlloc(fp->nspans, subImg); … … 77 85 psImage *subMask = psImageCopy(NULL, subImg, PS_TYPE_IMAGE_MASK); 78 86 79 // The brightest peak is always safe; go through other peaks trying to cull them 80 for (int i = 1; i < fp->peaks->n; i++) { // n.b. fp->peaks->n can change within the loop 81 const pmPeak *peak = fp->peaks->data[i]; 82 int x = peak->x - subImg->col0; 83 int y = peak->y - subImg->row0; 84 // 85 // Find the level nsigma below the peak that must separate the peak 86 // from any of its friends 87 // 88 assert (x >= 0 && x < subImg->numCols && y >= 0 && y < subImg->numRows); 89 90 // const float stdev = sqrt(subWt->data.F32[y][x]); 91 // float threshold = subImg->data.F32[y][x] - nsigma_delta*stdev; 92 93 const float stdev = sqrt(subWt->data.F32[y][x]); 94 const float flux = subImg->data.F32[y][x]; 95 const float fStdev = fabs(stdev/flux); 96 const float stdev_pad = fabs(flux * hypot(fStdev, fPadding)); 97 // if flux is negative, careful with fStdev 98 99 float threshold = flux - nsigma_delta*stdev_pad; 100 101 if (isnan(threshold)) { 102 // min_threshold is assumed to be below the detection threshold, 103 // so all the peaks are pmFootprint, and this isn't the brightest 104 continue; 105 } 106 107 // XXX EAM : if stdev >= 0, i'm not sure how this can ever be true? 108 if (threshold > subImg->data.F32[y][x]) { 109 threshold = subImg->data.F32[y][x] - 10*FLT_EPSILON; 110 } 111 112 if (threshold < min_threshold) { 113 threshold = min_threshold; 114 } 115 116 // init peakFootprint here? 117 pmFootprintsFindAtPoint(peakFootprint, peakFPSpans, subImg, subMask, threshold, brightPeaks, peak->y, peak->x); 118 if (peakFPSpans->nStartSpans > 2000) { 119 // dumpfootprints(peakFootprint, peakFPSpans); 120 // fprintf (stderr, "big footprint %d : %d\n", peakFootprint->nspans, peakFPSpans->nStartSpans); 121 fprintf (stderr, "big test footprint: %f %f to %f %f (%d pix)\n", peakFootprint->bbox.x0, peakFootprint->bbox.y0, peakFootprint->bbox.x1, peakFootprint->bbox.y1, peakFootprint->npix); 122 } 123 124 // at this point brightPeaks only has the peaks brighter than the current 125 126 // we set the IDs to either 1 (in peak) or 0 (not in peak) 127 pmSetFootprintID (idImg, peakFootprint, IN_PEAK); 128 129 // If this peak has not already been assigned to a source, then we can look for any 130 // brighter peaks within its footprint. Check if any of the previous (brighter) peaks 131 // are within the footprint of this peak If so, the current peak is bogus; drop it. 132 bool keep = true; 133 for (int j = 0; keep && !peak->assigned && (j < brightPeaks->n); j++) { 134 const pmPeak *peak2 = fp->peaks->data[j]; 135 int x2 = peak2->x - subImg->col0; 136 int y2 = peak2->y - subImg->row0; 137 if (idImg->data.S32[y2][x2] == IN_PEAK) { 138 // There's a brighter peak within the footprint above threshold; so cull our initial peak 139 keep = false; 140 } 141 } 142 if (!keep) { 143 psAssert (!peak->assigned, "logic error: trying to drop a previously-assigned peak"); // we should not drop any already assigned peaks. 144 continue; 145 } 146 147 psArrayAdd (brightPeaks, 128, fp->peaks->data[i]); 87 // if we have many peaks in a large footprint, we waste a lot of time generating nearly identical footprints 88 // here we attempt to cull peaks drawing a single footprint for all peaks in some threshold range 89 // fprintf (stderr, "footprint: %d x %d : %d pix, %d peaks\n", subImg->numCols, subImg->numRows, fp->npix, (int) fp->peaks->n); 90 if ((fp->npix > 30000) && (fp->peaks->n > 10)) { 91 92 // max flux is above threshold for brightest peak 93 pmPeak *maxPeak = fp->peaks->data[0]; 94 float maxFlux = useSmoothedImage ? maxPeak->smoothFlux : maxPeak->rawFlux; 95 96 // we have a relationship between the bin and the threshold of: 97 // threshold = 0.25 beta^2 bin^2 + minThreshold 98 // thus, the max bin is: sqrt(4.0*(maxThreshold - minThreshold)/ALPHA^2) 99 100 # define ALPHA 0.1 101 102 float beta = nsigma_delta * ALPHA; 103 float beta2 = PS_SQR(beta); 104 int nBins = sqrt(4.0*(maxFlux - min_threshold)/beta2) + 10; // let's be extra generous 105 106 // create a vector to store the threshold bins used for each peak 107 psVector *threshbins = psVectorAlloc(fp->peaks->n, PS_TYPE_S32); 108 threshbins->data.S32[0] = -1; // we skip the first peak 109 110 /// create a vector to track if a peak has been tried or not: 111 psVector *peaktried = psVectorAlloc(fp->peaks->n, PS_TYPE_U8); 112 psVectorInit(peaktried, 0); 113 peaktried->data.U8[0] = true; // we skip the first peak 114 115 psVector *threshbounds = psVectorAlloc(nBins, PS_TYPE_F32); 116 for (int i = 0; i < nBins; i++) { 117 threshbounds->data.F32[i] = 0.25*beta2*PS_SQR(i) + min_threshold; 118 } 119 psAssert(threshbounds->data.F32[threshbounds->n-1] > maxFlux, "upper limit does not include max flux"); 120 121 psHistogram *threshist = psHistogramAllocGeneric(threshbounds); 122 123 // assign the peaks to the histogram bins based on their nominal thresholsd 124 for (int i = 1; i < fp->peaks->n; i++) { 125 const pmPeak *peak = fp->peaks->data[i]; 126 float flux = useSmoothedImage ? peak->smoothFlux : peak->rawFlux; 127 float stdev = useSmoothedImage ? peak->smoothFluxStdev : peak->rawFluxStdev; 128 129 // if flux is negative, careful with fStdev 130 const float fStdev = fabs(stdev/flux); 131 const float stdev_pad = fabs(flux * hypot(fStdev, fPadding)); 132 133 float threshold = flux - nsigma_delta*stdev_pad; 134 psAssert(!isnan(threshold), "impossible"); 135 136 if (threshold <= min_threshold) { 137 threshist->nums->data.F32[0] += 1.0; 138 threshbins->data.S32[i] = 0; 139 continue; 140 } 141 int bin = sqrt(4.0*(threshold - min_threshold)/beta2); 142 psAssert(bin >= 0, "impossible bin"); 143 144 bin = PS_MIN(bin, threshist->nums->n - 1); 145 threshist->nums->data.F32[bin] += 1.0; 146 147 // record the bin selected for this peak 148 threshbins->data.S32[i] = bin; 149 } 150 151 // XXX TEST: did we assign correctly 152 # if (0) 153 int nPeaks = 1; // we don't put the brightest in the histogram 154 for (int i = 0; i < threshist->nums->n; i++) { 155 if (threshist->nums->data.F32[i] > 0) { 156 fprintf (stderr, "%f : %f : %d\n", threshist->bounds->data.F32[i], threshist->bounds->data.F32[i+1], (int)threshist->nums->data.F32[i]); 157 nPeaks += threshist->nums->data.F32[i]; 158 } 159 } 160 fprintf (stderr, "%d peaks vs %d in histogram\n", (int) fp->peaks->n, nPeaks); 161 # endif 162 163 // XXX for the moment, we will use the alternate cull for all peaks -- it might be 164 // faster to use the standard process for the peaks for which the threshold bin 165 // contains < N sources (N ~ 5-10?) 166 167 // loop over the threshold bins from brightest to faintest 168 for (int i = threshist->nums->n - 1; i >= 0; i--) { 169 if (threshist->nums->data.F32[i] == 0) continue; 170 171 // we are going to examine the footprints at this threshold 172 float threshold = 0.5*(threshist->bounds->data.F32[i] + threshist->bounds->data.F32[i+1]); 173 174 // generate all footprints corresponding to this threshold 175 psArray *myFP = pmFootprintsFind(subImg, threshold, 5); 176 if (!myFP) { 177 psWarning ("missing footprint?"); 178 continue; 179 } 180 if (!myFP->n) { 181 psWarning ("empty footprint?"); 182 continue; 183 } 184 185 // an array to track if the footprint has a brighter peak or not 186 psVector *found = psVectorAlloc(myFP->n + 1, PS_TYPE_U8); 187 psVectorInit(found, 0); 188 int nFound = 0; 189 190 // set IDs to distinguish the footprints 191 psImageInit(idImg, 0); 192 pmSetFootprintArrayIDsForImage(idImg, myFP, true); 193 194 // check which footprints contain already-accepted (brighter) peaks 195 // (we can give up if/when we found a peak for all footprints) 196 for (int j = 0; (j < brightPeaks->n) && (nFound < found->n); j++) { 197 const pmPeak *peak = brightPeaks->data[j]; 198 int x = peak->x - subImg->col0; 199 int y = peak->y - subImg->row0; 200 int myID = idImg->data.S32[y][x]; 201 psAssert(myID >= 0, "impossible"); 202 psAssert(myID < found->n, "impossible"); 203 204 if (myID == 0) continue; // bright peak is not in a footprint 205 if (found->data.U8[myID]) continue; // we already know this footprint contains a peak 206 found->data.U8[myID] = true; 207 nFound ++; 208 } 209 210 // check the peaks from this threshold bin: if they land in a footprint which has 211 // been found, we should drop that peak. otherwise, keep it 212 for (int j = 0; j < fp->peaks->n; j++) { 213 pmPeak *peak = fp->peaks->data[j]; 214 if (peak->assigned) continue; // peak is already claimed by a source -- don't cull 215 216 // skip peaks if we've already tried them 217 if (peaktried->data.U8[j]) continue; 218 219 // is this peak in the threshold bin of interest? 220 if (threshbins->data.S32[j] != i) continue; 221 222 // do not try this peak again 223 peaktried->data.U8[j] = true; 224 225 int x = peak->x - subImg->col0; 226 int y = peak->y - subImg->row0; 227 int myID = idImg->data.S32[y][x]; 228 psAssert(myID < found->n, "impossible"); 229 230 // a peak in this threshold bin without a valid footprint comes from a region 231 // with only a handful of pixels (1 or more from the peak itself). It probably 232 // cannot be joined to a neighbor 233 if (myID == 0) { 234 psArrayAdd (brightPeaks, 128, peak); 235 continue; 236 } 237 238 // keep this peak if found->data.U8[myID] == false (no brighter peak in the footprint) 239 if (!found->data.U8[myID]) { 240 // fprintf (stderr, "keeping %d: %d,%d\n", j, peak->x, peak->y); 241 psArrayAdd (brightPeaks, 128, peak); 242 continue; 243 } 244 // fprintf (stderr, "skipping %d: %d,%d\n", j, peak->x, peak->y); 245 } 246 psFree (myFP); 247 psFree (found); 248 } 249 psFree (threshist); 250 psFree (threshbounds); 251 psFree (threshbins); 252 psFree (peaktried); 253 254 } else { 255 256 // The brightest peak is always safe; go through other peaks trying to cull them 257 for (int i = 1; i < fp->peaks->n; i++) { // n.b. fp->peaks->n can change within the loop 258 const pmPeak *peak = fp->peaks->data[i]; 259 260 float flux = useSmoothedImage ? peak->smoothFlux : peak->rawFlux; 261 float stdev = useSmoothedImage ? peak->smoothFluxStdev : peak->rawFluxStdev; 262 263 // if flux is negative, careful with fStdev 264 const float fStdev = fabs(stdev/flux); 265 const float stdev_pad = fabs(flux * hypot(fStdev, fPadding)); 266 267 float threshold = flux - nsigma_delta*stdev_pad; 268 269 if (isnan(threshold)) { 270 // min_threshold is assumed to be below the detection threshold, 271 // so all the peaks are pmFootprint, and this isn't the brightest 272 continue; 273 } 274 275 // just in case, force the threshold below the peak source flux 276 if (threshold > flux) { 277 threshold = flux - 10*FLT_EPSILON; 278 } 279 280 if (threshold < min_threshold) { 281 threshold = min_threshold; 282 } 283 if (threshold > max_threshold) { 284 threshold = max_threshold; 285 } 286 287 pmFootprintsFindAtPoint(peakFootprint, peakFPSpans, subImg, subMask, threshold, brightPeaks, peak->y, peak->x); 288 // if (peakFPSpans->nStartSpans > 2000) { 289 // // dumpfootprints(peakFootprint, peakFPSpans); 290 // // fprintf (stderr, "big footprint %d : %d\n", peakFootprint->nspans, peakFPSpans->nStartSpans); 291 // // fprintf (stderr, "big test footprint: %f %f to %f %f (%d pix)\n", peakFootprint->bbox.x0, peakFootprint->bbox.y0, peakFootprint->bbox.x1, peakFootprint->bbox.y1, peakFootprint->npix); 292 // } 293 294 // at this point brightPeaks only has the peaks brighter than the current 295 296 // we set the IDs to either 1 (in peak) or 0 (not in peak) 297 pmSetFootprintID (idImg, peakFootprint, IN_PEAK); 298 299 // If this peak has not already been assigned to a source, then we can look for any 300 // brighter peaks within its footprint. Check if any of the previous (brighter) peaks 301 // are within the footprint of this peak If so, the current peak is bogus; drop it. 302 bool keep = true; 303 for (int j = 0; keep && !peak->assigned && (j < brightPeaks->n); j++) { 304 // const pmPeak *peak2 = fp->peaks->data[j]; XXX isn't this an error? we only care about the kept brighter peak, right? 305 const pmPeak *peak2 = brightPeaks->data[j]; 306 int x2 = peak2->x - subImg->col0; 307 int y2 = peak2->y - subImg->row0; 308 if (idImg->data.S32[y2][x2] == IN_PEAK) { 309 // There's a brighter peak within the footprint above threshold; so cull our initial peak 310 keep = false; 311 } 312 } 313 if (!keep) { 314 psAssert (!peak->assigned, "logic error: trying to drop a previously-assigned peak"); // we should not drop any already assigned peaks. 315 continue; 316 } 317 psArrayAdd (brightPeaks, 128, fp->peaks->data[i]); 318 } 148 319 } 149 320 … … 153 324 psFree(idImg); 154 325 psFree(subImg); 155 psFree(subWt);156 326 psFree(subMask); 157 327 psFree(peakFootprint); -
trunk/psModules/src/objects/pmFootprintFindAtPoint.c
r29004 r31153 31 31 * 32 32 * This is the guts of pmFootprintsFindAtPoint 33 * 34 * This function is/was ill-defined if pixel values are NAN. we should either treat NAN as > 35 * threshold or < threshold, but the current (r29004) code is ambiguous. 36 * EAM : change code so NAN is always > threshold 33 37 */ 34 38 bool pmFootprintSpansBuild(pmFootprint *fp, // the footprint that we're building … … 103 107 for (int j = x0 - 1; j >= -1; j--) { 104 108 double pixVal = (j < 0) ? threshold - 100 : (F32 ? imgRowF32[j] : imgRowS32[j]); 105 if ((maskRow[j] & PM_STARTSPAN_DETECTED) || pixVal < threshold) { 109 bool belowThreshold = (pixVal < threshold) && isfinite(pixVal); 110 if ((maskRow[j] & PM_STARTSPAN_DETECTED) || belowThreshold) { 106 111 if (j < x0 - 1) { // we found some pixels above threshold 107 112 nx0 = j + 1; … … 119 124 for (int j = nx0 + 1; j <= numCols; j++) { 120 125 double pixVal = (j >= numCols) ? threshold - 100 : (F32 ? imgRowF32[j] : imgRowS32[j]); 121 if ((maskRow[j] & PM_STARTSPAN_DETECTED) || pixVal < threshold) { 126 bool belowThreshold = (pixVal < threshold) && isfinite(pixVal); 127 if ((maskRow[j] & PM_STARTSPAN_DETECTED) || belowThreshold) { 122 128 nx1 = j - 1; 123 129 break; … … 146 152 for (int j = nx1 + 1; j <= x1 + 1; j++) { 147 153 double pixVal = (j >= numCols) ? threshold - 100 : (F32 ? imgRowF32[j] : imgRowS32[j]); 148 if (!(maskRow[j] & PM_STARTSPAN_DETECTED) && pixVal >= threshold) { 154 bool aboveThreshold = (pixVal >= threshold) || !isfinite(pixVal); 155 if (!(maskRow[j] & PM_STARTSPAN_DETECTED) && aboveThreshold) { 149 156 int sx0 = j++; // span that we're working on is sx0:sx1 150 157 int sx1 = -1; // We know that if we got here, we'll also set sx1 151 158 for (; j <= numCols; j++) { 152 159 double pixVal = (j >= numCols) ? threshold - 100 : (F32 ? imgRowF32[j] : imgRowS32[j]); 153 if ((maskRow[j] & PM_STARTSPAN_DETECTED) || pixVal < threshold) { // end of span 160 bool belowThreshold = (pixVal < threshold) && isfinite(pixVal); 161 if ((maskRow[j] & PM_STARTSPAN_DETECTED) || belowThreshold) { // end of span 154 162 sx1 = j; 155 163 break; … … 306 314 for (i = col; i >= 0; i--) { 307 315 pixVal = F32 ? imgRowF32[i] : imgRowS32[i]; 308 if ((maskRow[i] & PM_STARTSPAN_DETECTED) || pixVal < threshold) { 316 bool belowThreshold = (pixVal < threshold) && isfinite(pixVal); 317 if ((maskRow[i] & PM_STARTSPAN_DETECTED) || belowThreshold) { 309 318 break; 310 319 } … … 313 322 for (i = col; i < numCols; i++) { 314 323 pixVal = F32 ? imgRowF32[i] : imgRowS32[i]; 315 if ((maskRow[i] & PM_STARTSPAN_DETECTED) || pixVal < threshold) { 324 bool belowThreshold = (pixVal < threshold) && isfinite(pixVal); 325 if ((maskRow[i] & PM_STARTSPAN_DETECTED) || belowThreshold) { 316 326 break; 317 327 } -
trunk/psModules/src/objects/pmFootprintIDs.c
r29004 r31153 66 66 67 67 if (footprints->n == 0) { 68 psError(PS_ERR_BAD_PARAMETER_SIZE, true, "You didn't provide any footprints"); 68 // XXX this was an error, but is an allowed condition -- NULL returned image means no footprints for any peaks 69 // psError(PS_ERR_BAD_PARAMETER_SIZE, true, "You didn't provide any footprints"); 69 70 return NULL; 70 71 } -
trunk/psModules/src/objects/pmModel.c
r30621 r31153 41 41 psFree(tmp->params); 42 42 psFree(tmp->dparams); 43 psFree(tmp->covar); 43 44 psTrace("psModules.objects", 10, "---- %s() end ----\n", __func__); 44 45 } … … 66 67 tmp->chisqNorm = NAN; 67 68 tmp->nDOF = 0; 69 tmp->nPar = 0; 68 70 tmp->nPix = 0; 69 71 tmp->nIter = 0; … … 71 73 tmp->flags = PM_MODEL_STATUS_NONE; 72 74 tmp->residuals = NULL; // do not free: the model does not own this memory 75 tmp->covar = NULL; 73 76 tmp->isPCM = false; 74 77 -
trunk/psModules/src/objects/pmModel.h
r30621 r31153 33 33 psVector *params; ///< Paramater values. 34 34 psVector *dparams; ///< Parameter errors. 35 psImage *covar; ///< Optional covariance matrix 35 36 float chisq; ///< Fit chi-squared. 36 37 float chisqNorm; ///< re-normalized fit chi-squared. … … 38 39 float magErr; ///< integrated model magnitude error 39 40 int nPix; ///< number of pixels used for fit 40 int nDOF; ///< number of degrees of freedom 41 int nPar; ///< number of parameters in fit 42 int nDOF; ///< number of degrees of freedom (nDOF = nPix - nPar) 41 43 int nIter; ///< number of iterations to reach min 42 44 pmModelStatus flags; ///< model status flags -
trunk/psModules/src/objects/pmModelUtils.c
r29004 r31153 107 107 return true; 108 108 } 109 110 bool pmModelSetShape (float *Sxx, float *Sxy, float *Syy, pmMoments *moments) { 111 112 psEllipseMoments emoments; 113 emoments.x2 = moments->Mxx; 114 emoments.xy = moments->Mxy; 115 emoments.y2 = moments->Myy; 116 117 // force the axis ratio to be < 20.0 118 psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0); 119 120 if (!isfinite(axes.major)) return false; 121 if (!isfinite(axes.minor)) return false; 122 if (!isfinite(axes.theta)) return false; 123 124 psEllipseShape shape = psEllipseAxesToShape (axes); 125 126 if (!isfinite(shape.sx)) return false; 127 if (!isfinite(shape.sy)) return false; 128 if (!isfinite(shape.sxy)) return false; 129 130 // set the shape parameters 131 *Sxx = PS_MAX(0.5, M_SQRT2*shape.sx); 132 *Syy = PS_MAX(0.5, M_SQRT2*shape.sy); 133 *Sxy = shape.sxy; 134 135 return true; 136 } 137 138 bool pmModelSetNorm (float *Io, pmSource *source) { 139 140 *Io = source->peak->rawFlux; 141 if (!isfinite(*Io) && !source->moments) return false; 142 143 *Io = source->moments->Peak; 144 if (!isfinite(*Io)) return false; 145 146 return true; 147 } 148 149 bool pmModelSetPosition (float *Xo, float *Yo, pmSource *source) { 150 151 bool useMoments = pmSourcePositionUseMoments(source); 152 153 if (useMoments) { 154 *Xo = source->moments->Mx; 155 *Yo = source->moments->My; 156 } else { 157 *Xo = source->peak->xf; 158 *Yo = source->peak->yf; 159 } 160 161 return true; 162 } -
trunk/psModules/src/objects/pmModelUtils.h
r15843 r31153 42 42 ); 43 43 44 44 bool pmModelSetPosition (float *Xo, float *Yo, pmSource *source); 45 bool pmModelSetNorm (float *Io, pmSource *source); 46 bool pmModelSetShape (float *Sxx, float *Sxy, float *Syy, pmMoments *moments); 45 47 46 48 /// @} -
trunk/psModules/src/objects/pmMoments.h
r29004 r31153 51 51 int nPixels; ///< Number of pixels used. 52 52 53 float KronFlux; ///< Kron flux (flux in 2.5*Mrf) 53 float KronCore; ///< flux in r < 1.0*Mrf 54 float KronCoreErr; ///< error on flux in r < 1.0*Mrf 55 56 float KronFlux; ///< Kron flux (flux in r < 2.5*Mrf) 54 57 float KronFluxErr; ///< Kron flux error 55 58 56 float KronFinner; ///< Kron flux (flux in 2.5*Mrf) 57 float KronFouter; ///< Kron flux (flux in 2.5*Mrf) 58 59 float KronFinner; ///< Kron flux (flux in 1.0*Mrf < r < 2.5*Mrf) 60 float KronFouter; ///< Kron flux (flux in 2.5*Mrf < r < 4.0*Mrf) 59 61 } 60 62 pmMoments; -
trunk/psModules/src/objects/pmPCMdata.c
r29546 r31153 254 254 255 255 pcm->nPix = nPix; 256 pcm->nDOF = nPix - nParams - 1; 256 pcm->nPar = nParams; 257 pcm->nDOF = nPix - nParams; 257 258 258 259 return pcm; … … 341 342 return false; 342 343 } 343 pcm->nDOF = pcm->nPix - nParams - 1; 344 pcm->nPar = nParams; 345 pcm->nDOF = pcm->nPix - nParams; 344 346 345 347 // has the source pixel window changed? -
trunk/psModules/src/objects/pmPCMdata.h
r30621 r31153 33 33 psMinConstraint *constraint; 34 34 int nPix; 35 int nPar; 35 36 int nDOF; 36 37 } pmPCMdata; -
trunk/psModules/src/objects/pmPSF.c
r29004 r31153 430 430 return NAN; 431 431 } 432 433 // get the model full-width at half-max 434 float fwhmMajor = 2*model->modelRadius (model->params, 0.5); 435 436 # if (0) 432 437 psF32 *params = model->params->data.F32; // Model parameters 433 438 psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO); // Ellipse axes … … 439 444 440 445 return fwhm; 441 } 446 # else 447 448 psFree(model); 449 450 return fwhmMajor; 451 # endif 452 } -
trunk/psModules/src/objects/pmPSFtryFitPSF.c
r30621 r31153 109 109 110 110 // This function calculates the psf and aperture magnitudes 111 status = pmSourceMagnitudes (source, psfTry->psf, PM_SOURCE_PHOT_INTERP, maskVal, markVal ); // raw PSF mag, AP mag111 status = pmSourceMagnitudes (source, psfTry->psf, PM_SOURCE_PHOT_INTERP, maskVal, markVal, options->apRadius); // raw PSF mag, AP mag 112 112 if (!status || isnan(source->apMag)) { 113 113 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask -
trunk/psModules/src/objects/pmPeaks.c
r29004 r31153 115 115 XXX: Macro this. 116 116 *****************************************************************************/ 117 # if (0) 117 118 static bool isItInThisRegion(const psRegion valid, 118 119 psS32 x, … … 130 131 return(false); 131 132 } 133 # endif 132 134 133 135 /****************************************************************************** … … 148 150 tmp->x = x; 149 151 tmp->y = y; 150 tmp->value = value; 151 tmp->flux = value; 152 tmp->SN = 0; 152 tmp->detValue = value; 153 tmp->rawFlux = value; // set this by default: it is up to the user to supply a better value 154 tmp->rawFluxStdev = NAN; 155 tmp->smoothFlux = value; // set this by default: it is up to the user to supply a better value 156 tmp->smoothFluxStdev = NAN; 157 // tmp->SN = 0; 153 158 tmp->xf = x; 154 159 tmp->yf = y; … … 170 175 171 176 172 // psSort comparison function for peaks177 // psSort comparison functions for peaks 173 178 // XXX: Add error-checking for NULL args 174 int pmPeaksCompareAscend (const void **a, const void **b) 175 { 176 psTrace("psModules.objects", 10, "---- %s() begin ----\n", __func__); 179 int pmPeaksSortByDetValueAscend (const void **a, const void **b) 180 { 177 181 pmPeak *A = *(pmPeak **)a; 178 182 pmPeak *B = *(pmPeak **)b; … … 180 184 psF32 diff; 181 185 182 diff = A-> value - B->value;186 diff = A->detValue - B->detValue; 183 187 if (diff < FLT_EPSILON) { 184 psTrace("psModules.objects", 10, "---- %s(-1) end ----\n", __func__);185 188 return (-1); 186 189 } else if (diff > FLT_EPSILON) { 187 psTrace("psModules.objects", 10, "---- %s(+1) end ----\n", __func__);188 190 return (+1); 189 191 } 190 psTrace("psModules.objects", 10, "---- %s(0) end ----\n", __func__);191 192 return (0); 192 193 } 193 194 // psSort comparison function for peaks 195 // XXX: Add error-checking for NULL args 196 int pmPeaksCompareDescend (const void **a, const void **b) 197 { 198 psTrace("psModules.objects", 10, "---- %s() begin ----\n", __func__); 194 int pmPeaksSortByDetValueDescend (const void **a, const void **b) 195 { 199 196 pmPeak *A = *(pmPeak **)a; 200 197 pmPeak *B = *(pmPeak **)b; … … 202 199 psF32 diff; 203 200 204 diff = A-> value - B->value;201 diff = A->detValue - B->detValue; 205 202 if (diff < FLT_EPSILON) { 206 psTrace("psModules.objects", 10, "---- %s(+1) end ----\n", __func__);207 203 return (+1); 208 204 } else if (diff > FLT_EPSILON) { 209 psTrace("psModules.objects", 10, "---- %s(-1) end ----\n", __func__);210 205 return (-1); 211 206 } 212 psTrace("psModules.objects", 10, "---- %s(0) end ----\n", __func__);213 207 return (0); 214 208 } 215 216 // sort by SN (descending) 217 int pmPeakSortBySN (const void **a, const void **b) 209 int pmPeaksSortByRawFluxAscend (const void **a, const void **b) 218 210 { 219 211 pmPeak *A = *(pmPeak **)a; 220 212 pmPeak *B = *(pmPeak **)b; 221 213 222 psF32 fA = A->SN;223 psF32 fB = B->SN; 224 if (isnan (fA)) fA = 0;225 if ( isnan (fB)) fB = 0;226 227 psF32 diff = fA - fB;228 if (diff > FLT_EPSILON) return (-1);229 if (diff < FLT_EPSILON) return (+1);214 psF32 diff; 215 216 diff = A->rawFlux - B->rawFlux; 217 if (diff < FLT_EPSILON) { 218 return (-1); 219 } else if (diff > FLT_EPSILON) { 220 return (+1); 221 } 230 222 return (0); 231 223 } 232 233 // sort by Y (ascending) 234 int pmPeakSortByY (const void **a, const void **b) 224 int pmPeaksSortByRawFluxDescend (const void **a, const void **b) 235 225 { 236 226 pmPeak *A = *(pmPeak **)a; 237 227 pmPeak *B = *(pmPeak **)b; 238 228 239 psF32 fA = A->y; 240 psF32 fB = B->y; 241 242 psF32 diff = fA - fB; 243 if (diff > FLT_EPSILON) return (+1); 244 if (diff < FLT_EPSILON) return (-1); 229 psF32 diff; 230 231 diff = A->rawFlux - B->rawFlux; 232 if (diff < FLT_EPSILON) { 233 return (+1); 234 } else if (diff > FLT_EPSILON) { 235 return (-1); 236 } 245 237 return (0); 246 238 } 239 int pmPeaksSortBySmoothFluxAscend (const void **a, const void **b) 240 { 241 pmPeak *A = *(pmPeak **)a; 242 pmPeak *B = *(pmPeak **)b; 243 244 psF32 diff; 245 246 diff = A->smoothFlux - B->smoothFlux; 247 if (diff < FLT_EPSILON) { 248 return (-1); 249 } else if (diff > FLT_EPSILON) { 250 return (+1); 251 } 252 return (0); 253 } 254 int pmPeaksSortBySmoothFluxDescend (const void **a, const void **b) 255 { 256 pmPeak *A = *(pmPeak **)a; 257 pmPeak *B = *(pmPeak **)b; 258 259 psF32 diff; 260 261 diff = A->smoothFlux - B->smoothFlux; 262 if (diff < FLT_EPSILON) { 263 return (+1); 264 } else if (diff > FLT_EPSILON) { 265 return (-1); 266 } 267 return (0); 268 } 269 270 // // sort by SN (descending) 271 // int pmPeakSortBySN (const void **a, const void **b) 272 // { 273 // pmPeak *A = *(pmPeak **)a; 274 // pmPeak *B = *(pmPeak **)b; 275 // 276 // psF32 fA = A->flux; 277 // psF32 fB = B->flux; 278 // if (isnan (fA)) fA = 0; 279 // if (isnan (fB)) fB = 0; 280 // 281 // psF32 diff = fA - fB; 282 // if (diff > FLT_EPSILON) return (-1); 283 // if (diff < FLT_EPSILON) return (+1); 284 // return (0); 285 // } 286 // 287 // // sort by Y (ascending) 288 // int pmPeakSortByY (const void **a, const void **b) 289 // { 290 // pmPeak *A = *(pmPeak **)a; 291 // pmPeak *B = *(pmPeak **)b; 292 // 293 // psF32 fA = A->y; 294 // psF32 fB = B->y; 295 // 296 // psF32 diff = fA - fB; 297 // if (diff > FLT_EPSILON) return (+1); 298 // if (diff < FLT_EPSILON) return (-1); 299 // return (0); 300 // } 247 301 248 302 /****************************************************************************** … … 554 608 return(list); 555 609 } 556 557 // return a new array of peaks which are in the valid region and below threshold558 // XXX this function is unused and probably could be dropped559 psArray *pmPeaksSubset(560 psArray *peaks,561 psF32 maxValue,562 const psRegion valid)563 {564 psTrace("psModules.objects", 10, "---- %s() begin ----\n", __func__);565 PS_ASSERT_PTR_NON_NULL(peaks, NULL);566 567 psArray *output = psArrayAllocEmpty (200);568 569 psTrace ("psModules.objects", 3, "list size is %ld\n", peaks->n);570 571 for (int i = 0; i < peaks->n; i++) {572 pmPeak *tmpPeak = (pmPeak *) peaks->data[i];573 if (tmpPeak->value > maxValue)574 continue;575 if (isItInThisRegion(valid, tmpPeak->x, tmpPeak->y))576 continue;577 psArrayAdd (output, 200, tmpPeak);578 }579 psTrace("psModules.objects", 10, "---- %s() end ----\n", __func__);580 return(output);581 } -
trunk/psModules/src/objects/pmPeaks.h
r29004 r31153 35 35 PM_PEAK_EDGE, ///< Peak on edge. 36 36 PM_PEAK_FLAT, ///< Peak has equal-value neighbors. 37 PM_PEAK_SUSPECT_SATURATION, ///< Peak is probably saturated 37 38 PM_PEAK_UNDEF ///< Undefined. 38 39 } pmPeakType; … … 45 46 * associated with the source: 46 47 * 48 * There are 3 values which define the amplitude of the peak and which may be used to sort the 49 * peaks: 50 * * detValue - the peak in the detection image (nominally, the S/N) 51 * * rawFlux - the peak in the unsmoothed image 52 * * smoothFlux - the peak in the smoothed image 53 * 54 * For a given image, peaks do necesarily not have the same sequence for these three values. 55 * Depending on the analysis, it may make sense to sort by one or the other of these values 47 56 */ 48 57 typedef struct … … 55 64 float dx; ///< bicube fit error on peak coord (x) 56 65 float dy; ///< bicube fit error on peak coord (y) 57 float value; ///< level in detection image 58 float flux; ///< level in unsmoothed sci image 59 float SN; ///< S/N implied by detection level 66 float detValue; ///< peak flux in detection image (= S/N) 67 float rawFlux; ///< peak flux in unsmoothed signal image 68 float rawFluxStdev; ///< peak stdev in unsmoothed signal image 69 float smoothFlux; ///< peak flux in smoothed signal image 70 float smoothFluxStdev; ///< peak stdev in smoothed signal image 71 // float SNestimated; ///< S/N estimated from the detection image 60 72 bool assigned; ///< is peak assigned to a source? 61 73 pmPeakType type; ///< Description of peak. … … 136 148 ); 137 149 138 int pmPeaksCompareAscend (const void **a, const void **b); 139 int pmPeaksCompareDescend (const void **a, const void **b); 140 141 int pmPeakSortBySN (const void **a, const void **b); 142 int pmPeakSortByY (const void **a, const void **b); 150 int pmPeaksSortByDetValueAscend (const void **a, const void **b); 151 int pmPeaksSortByDetValueDescend (const void **a, const void **b); 152 int pmPeaksSortByRawFluxAscend (const void **a, const void **b); 153 int pmPeaksSortByRawFluxDescend (const void **a, const void **b); 154 int pmPeaksSortBySmoothFluxAscend (const void **a, const void **b); 155 int pmPeaksSortBySmoothFluxDescend (const void **a, const void **b); 143 156 144 157 /// @} -
trunk/psModules/src/objects/pmPhotObj.c
r29004 r31153 67 67 return false; 68 68 } 69 if (! finite(source->peak->xf)) {69 if (!isfinite(source->peak->xf)) { 70 70 psError(PS_ERR_UNKNOWN, true, "NAN peak coordinate"); 71 71 return false; 72 72 } 73 if (! finite(source->peak->yf)) {73 if (!isfinite(source->peak->yf)) { 74 74 psError(PS_ERR_UNKNOWN, true, "NAN peak coordinate"); 75 75 return false; … … 81 81 object->x = source->peak->xf; 82 82 object->y = source->peak->yf; 83 object-> SN = source->peak->SN;83 object->flux = source->peak->rawFlux; 84 84 } else { 85 object-> SN = PS_MAX(object->SN, source->peak->SN);85 object->flux = PS_MAX(object->flux, source->peak->rawFlux); 86 86 } 87 87 psArrayAdd (object->sources, 1, source); … … 89 89 } 90 90 91 // sort by SN(descending)92 int pmPhotObjSortBy SN(const void **a, const void **b)91 // sort by flux (descending) 92 int pmPhotObjSortByFlux (const void **a, const void **b) 93 93 { 94 94 pmPhotObj *objA = *(pmPhotObj **)a; 95 95 pmPhotObj *objB = *(pmPhotObj **)b; 96 96 97 psF32 fA = objA-> SN;98 psF32 fB = objB-> SN;97 psF32 fA = objA->flux; 98 psF32 fB = objB->flux; 99 99 100 100 psF32 diff = fA - fB; -
trunk/psModules/src/objects/pmPhotObj.h
r29004 r31153 34 34 float x; 35 35 float y; 36 float SN; // max of peak->SNfor all matched sources36 float flux; // max of peak->rawFlux for all matched sources 37 37 } pmPhotObj; 38 38 … … 41 41 bool pmPhotObjAddSource(pmPhotObj *object, pmSource *source); 42 42 43 int pmPhotObjSortBy SN(const void **a, const void **b);43 int pmPhotObjSortByFlux (const void **a, const void **b); 44 44 int pmPhotObjSortByX (const void **a, const void **b); 45 45 -
trunk/psModules/src/objects/pmSource.c
r30621 r31153 171 171 // peak has the same values as the original 172 172 if (in->peak != NULL) { 173 source->peak = pmPeakAlloc (in->peak->x, in->peak->y, in->peak-> value, in->peak->type);173 source->peak = pmPeakAlloc (in->peak->x, in->peak->y, in->peak->detValue, in->peak->type); 174 174 source->peak->xf = in->peak->xf; 175 175 source->peak->yf = in->peak->yf; 176 source->peak->flux = in->peak->flux; 177 source->peak->SN = in->peak->SN; 176 source->peak->rawFlux = in->peak->rawFlux; 177 source->peak->rawFluxStdev = in->peak->rawFluxStdev; 178 source->peak->smoothFlux = in->peak->smoothFlux; 179 source->peak->smoothFluxStdev = in->peak->smoothFluxStdev; 180 // source->peak->SN = in->peak->SN; 178 181 } 179 182 … … 328 331 *****************************************************************************/ 329 332 330 // XXX EAM include a S/N cutoff in selecting the sources?331 // XXX this function should probably accept the values, not a recipe. wrap with a332 // psphot-specific function which applies the recipe values333 // only apply selection to sources within specified region334 333 pmPSFClump pmSourcePSFClump(psImage **savedImage, psRegion *region, psArray *sources, float PSF_SN_LIM, float PSF_CLUMP_GRID_SCALE, psF32 SX_MAX, psF32 SY_MAX, psF32 AR_MAX) 335 334 { … … 429 428 430 429 psfClump.nSigma = stats->sampleStdev; 430 psfClump.nTotal = nValid; 431 431 432 432 if (savedImage) { … … 465 465 psStats *stats = NULL; 466 466 467 // select the single highest peak 468 psArraySort (peaks, pmPeaks CompareDescend);467 // select the single highest peak (note that we only have detValue, not rawFlux, etc 468 psArraySort (peaks, pmPeaksSortByDetValueDescend); 469 469 clump = peaks->data[0]; 470 psTrace ("psModules.objects", 2, "clump is at %d, %d (%f)\n", clump->x, clump->y, clump-> value);470 psTrace ("psModules.objects", 2, "clump is at %d, %d (%f)\n", clump->x, clump->y, clump->detValue); 471 471 472 472 // XXX store the mean sigma? 473 473 float meanSigma = psfClump.nSigma; 474 psfClump.nStars = clump-> value;475 psfClump.nSigma = clump-> value / meanSigma;474 psfClump.nStars = clump->detValue; 475 psfClump.nSigma = clump->detValue / meanSigma; 476 476 477 477 // define section window for clump … … 643 643 } 644 644 645 // check for insignificant sources or excessively low-surface brightness 646 float coreSN = source->moments->KronCore / source->moments->KronCoreErr; 647 float coreKR = source->moments->KronCore / source->moments->KronFlux; 648 649 // XXX these values need to be in the recipe... 650 if (false && isfinite(coreSN) && (coreSN < 5.0)) { 651 source->type = PM_SOURCE_TYPE_DEFECT; 652 source->mode |= PM_SOURCE_MODE_DEFECT; 653 Ncr ++; 654 continue; 655 } 656 if (false && isfinite(coreKR) && (coreKR < 0.1)) { 657 source->type = PM_SOURCE_TYPE_DEFECT; 658 source->mode |= PM_SOURCE_MODE_DEFECT; 659 Ncr ++; 660 continue; 661 } 662 645 663 // likely unsaturated extended source (too large to be stellar) 646 664 if (sigX > clump.X + 3*clump.dX || sigY > clump.Y + 3*clump.dY) { … … 651 669 652 670 // the rest are probable stellar objects 671 // the vectors below are accumulated to give user feedback on the S/N ranges 653 672 starsn_moments->data.F32[starsn_moments->n] = source->moments->SN; 654 673 starsn_moments->n ++; 655 starsn_peaks->data.F32[starsn_peaks->n] = s ource->peak->SN;674 starsn_peaks->data.F32[starsn_peaks->n] = sqrt(source->peak->detValue); 656 675 starsn_peaks->n ++; 657 676 Nstar ++; … … 1149 1168 } 1150 1169 1170 // this function decides if the source position should be based on the peak or the moments. 1171 // this is only used if we know we should not use a model fit position (eg, no model, or no 1172 // model yet) 1173 bool pmSourcePositionUseMoments(pmSource *source) { 1174 1175 if (!source->moments) return false; // can't if there are no moments 1176 if (!source->moments->nPixels) return false; // can't if the moments were not measured 1177 if (source->mode && PM_SOURCE_MODE_MOMENTS_FAILURE) return false; // can't if the moments failed... 1178 1179 if (source->mode & PM_SOURCE_MODE_SATSTAR) return true; // moments are best for SATSTARs 1180 1181 float dX = source->moments->Mx - source->peak->xf; 1182 float dY = source->moments->My - source->peak->yf; 1183 float dR = hypot(dX, dY); 1184 1185 // only use the moments position if the moment-peak offset is small or the star is saturated 1186 if (dR > 1.5) return false; 1187 1188 return true; 1189 } 1190 1151 1191 // sort by SN (descending) 1152 int pmSourceSortBy SN(const void **a, const void **b)1192 int pmSourceSortByFlux (const void **a, const void **b) 1153 1193 { 1154 1194 pmSource *A = *(pmSource **)a; 1155 1195 pmSource *B = *(pmSource **)b; 1156 1196 1157 psF32 fA = (A->peak == NULL) ? 0 : A->peak-> SN;1158 psF32 fB = (B->peak == NULL) ? 0 : B->peak-> SN;1197 psF32 fA = (A->peak == NULL) ? 0 : A->peak->rawFlux; 1198 psF32 fB = (B->peak == NULL) ? 0 : B->peak->rawFlux; 1159 1199 if (isnan (fA)) fA = 0; 1160 1200 if (isnan (fB)) fB = 0; … … 1166 1206 } 1167 1207 1208 // sort by SN (descending) 1209 int pmSourceSortByParentFlux (const void **a, const void **b) 1210 { 1211 pmSource *Ao = *(pmSource **)a; 1212 pmSource *Bo = *(pmSource **)b; 1213 pmSource *A = Ao->parent; 1214 pmSource *B = Bo->parent; 1215 1216 psF32 fA = (A->peak == NULL) ? 0 : A->peak->rawFlux; 1217 psF32 fB = (B->peak == NULL) ? 0 : B->peak->rawFlux; 1218 if (isnan (fA)) fA = 0; 1219 if (isnan (fB)) fB = 0; 1220 1221 psF32 diff = fA - fB; 1222 if (diff > FLT_EPSILON) return (-1); 1223 if (diff < FLT_EPSILON) return (+1); 1224 return (0); 1225 } 1226 1168 1227 // sort by Y (ascending) 1169 1228 int pmSourceSortByY (const void **a, const void **b) … … 1201 1260 pmSource *A = *(pmSource **)a; 1202 1261 pmSource *B = *(pmSource **)b; 1262 1263 int iA = A->seq; 1264 int iB = B->seq; 1265 1266 int diff = iA - iB; 1267 if (diff > 0) return (+1); 1268 if (diff < 0) return (-1); 1269 return (0); 1270 } 1271 1272 // sort by Seq (ascending) 1273 int pmSourceSortByParentSeq (const void **a, const void **b) 1274 { 1275 pmSource *Ao = *(pmSource **)a; 1276 pmSource *Bo = *(pmSource **)b; 1277 pmSource *A = Ao->parent; 1278 pmSource *B = Bo->parent; 1203 1279 1204 1280 int iA = A->seq; -
trunk/psModules/src/objects/pmSource.h
r30621 r31153 121 121 float dY; 122 122 int nStars; 123 int nTotal; 123 124 float nSigma; 124 125 } … … 286 287 bool pmSourceCachePSF (pmSource *source, psImageMaskType maskVal); 287 288 288 int pmSourceSortBySN (const void **a, const void **b); 289 bool pmSourcePositionUseMoments(pmSource *source); 290 289 291 int pmSourceSortByY (const void **a, const void **b); 290 292 int pmSourceSortByX (const void **a, const void **b); 291 293 int pmSourceSortBySeq (const void **a, const void **b); 294 int pmSourceSortByParentSeq (const void **a, const void **b); 295 int pmSourceSortByFlux (const void **a, const void **b); 296 int pmSourceSortByParentFlux (const void **a, const void **b); 292 297 293 298 pmSourceMode pmSourceModeFromString (const char *name); -
trunk/psModules/src/objects/pmSourceExtendedPars.c
r30621 r31153 55 55 psFree(radial->flux); 56 56 psFree(radial->fluxErr); 57 psFree(radial->fluxStdev); 57 58 psFree(radial->fill); 58 59 } … … 65 66 radial->flux = NULL; 66 67 radial->fluxErr = NULL; 68 radial->fluxStdev = NULL; 67 69 radial->fill = NULL; 68 70 return radial; -
trunk/psModules/src/objects/pmSourceExtendedPars.h
r28013 r31153 23 23 typedef struct { 24 24 psVector *flux; // fluxes measured at above radii 25 psVector *fluxStdev; // scatter (standard deviation) of flux 25 26 psVector *fluxErr; // formal error on the fluxes (sqrt\sum(variance)) 26 27 psVector *fill; // angles corresponding to above radial profiles … … 63 64 float petrosianR50; 64 65 float petrosianR50Err; 66 float petrosianFill; 65 67 } pmSourceExtendedPars; 66 68 -
trunk/psModules/src/objects/pmSourceFitModel.c
r29004 r31153 40 40 #include "pmSourceDiffStats.h" 41 41 #include "pmSource.h" 42 #include "pmSourcePhotometry.h" 42 43 #include "pmSourceFitModel.h" 43 44 … … 59 60 opt->maxChisqDOF = NAN; 60 61 opt->poissonErrors = true; 62 opt->saveCovariance = false; 61 63 62 64 return opt; … … 231 233 psTrace ("psModules.objects", 4, "%f +/- %f", params->data.F32[i], dparams->data.F32[i]); 232 234 } 235 if (options->saveCovariance) { 236 model->covar = psMemIncrRefCounter(covar); 237 } 238 model->nIter = myMin->iter; 239 model->nPar = nParams; 240 233 241 psTrace ("psModules.objects", 4, "niter: %d, chisq: %f", myMin->iter, myMin->value); 234 242 235 243 // save the resulting chisq, nDOF, nIter 236 model->chisq = myMin->value; 237 model->nIter = myMin->iter; 238 model->nPix = y->n; 239 model->nDOF = y->n - nParams; 240 model->chisqNorm = model->chisq / model->nDOF; 244 // NOTE: if (!options->poissonErrors) chisq will be wrong : recalculate 245 if (options->poissonErrors) { 246 model->chisq = myMin->value; 247 model->nPix = y->n; 248 model->nDOF = y->n - model->nPar; 249 model->chisqNorm = model->chisq / model->nDOF; 250 } else { 251 pmSourceChisqUnsubtracted (source, model, maskVal); 252 } 253 254 // set the model success or failure status 241 255 model->flags |= PM_MODEL_STATUS_FITTED; 242 256 if (!fitStatus) model->flags |= PM_MODEL_STATUS_NONCONVERGE; -
trunk/psModules/src/objects/pmSourceFitModel.h
r29004 r31153 31 31 float maxChisqDOF; ///< convergence criterion 32 32 float weight; ///< use this weight for constant-weight fits 33 float covarFactor; ///< covariance factor for calculating the chisq 33 34 bool poissonErrors; ///< use poisson errors for fits? 35 bool saveCovariance; 34 36 } pmSourceFitOptions; 35 37 -
trunk/psModules/src/objects/pmSourceFitPCM.c
r30621 r31153 38 38 #include "pmSourceDiffStats.h" 39 39 #include "pmSource.h" 40 #include "pmSourcePhotometry.h" 40 41 #include "pmSourceFitModel.h" 41 42 #include "pmPCMdata.h" … … 70 71 psTrace ("psModules.objects", 4, "%f +/- %f", params->data.F32[i], dparams->data.F32[i]); 71 72 } 73 if (fitOptions->saveCovariance) { 74 psFree(pcm->modelConv->covar); 75 pcm->modelConv->covar = psMemIncrRefCounter(covar); 76 } 72 77 psTrace ("psphot", 4, "niter: %d, chisq: %f", myMin->iter, myMin->value); 73 78 … … 79 84 } 80 85 } 86 pcm->modelConv->nIter = myMin->iter; 87 pcm->modelConv->nPar = pcm->nPar; 81 88 82 89 // save the resulting chisq, nDOF, nIter 83 pcm->modelConv->chisq = myMin->value; 84 pcm->modelConv->nIter = myMin->iter; 85 pcm->modelConv->nPix = pcm->nPix; 86 pcm->modelConv->nDOF = pcm->nDOF; 87 pcm->modelConv->chisqNorm = pcm->modelConv->chisq / pcm->modelConv->nDOF; 90 if (fitOptions->poissonErrors) { 91 pcm->modelConv->chisq = myMin->value; 92 pcm->modelConv->nPix = pcm->nPix; 93 pcm->modelConv->nDOF = pcm->nDOF; 94 pcm->modelConv->chisqNorm = pcm->modelConv->chisq / pcm->modelConv->nDOF; 95 } else { 96 // xxx this is wrong because it does not convolve with the psf 97 pmSourceChisqUnsubtracted (source, pcm->modelConv, maskVal); 98 } 99 100 // set the model success or failure status 88 101 pcm->modelConv->flags |= PM_MODEL_STATUS_FITTED; 89 102 if (!fitStatus) pcm->modelConv->flags |= PM_MODEL_STATUS_NONCONVERGE; -
trunk/psModules/src/objects/pmSourceFitSet.c
r29004 r31153 39 39 #include "pmSourceDiffStats.h" 40 40 #include "pmSource.h" 41 #include "pmSourcePhotometry.h" 41 42 42 43 #include "pmSourceFitModel.h" … … 296 297 297 298 // set the model parameters for this fit set 298 bool pmSourceFitSetValues (pmSourceFitSetData *set, const psVector *dparam, 299 const psVector *param, pmSource *source, 300 psMinimization *myMin, int nPix, bool fitStatus) 299 bool pmSourceFitSetValues (pmSourceFitSetData *set, 300 const psVector *dparam, const psVector *param, const psImage *covar, 301 pmSource *source, psMinimization *myMin, int nPix, 302 bool fitStatus, pmSourceFitOptions *options, psImageMaskType maskVal) 301 303 { 302 304 PS_ASSERT_PTR_NON_NULL(set, false); … … 311 313 312 314 int n = 0; 315 int nStart = 0; 313 316 for (int i = 0; i < set->paramSet->n; i++) { 314 317 … … 320 323 psTrace ("psModules.objects", 4, "%f +/- %f", param->data.F32[n], dparam->data.F32[n]); 321 324 } 325 if (options->saveCovariance) { 326 // we only save the covar matrix for this object with itself (ignore cross terms between objects) 327 model->covar = psImageAlloc(model->params->n, model->params->n, PS_TYPE_F32); 328 for (int ix = 0; ix < model->params->n; ix++) { 329 for (int iy = 0; iy < model->params->n; iy++) { 330 model->covar->data.F32[iy][ix] = covar->data.F32[nStart+iy][nStart+ix]; 331 } 332 } 333 } 334 nStart += model->params->n; 322 335 psTrace ("psModules.objects", 4, " src %d", i); 336 337 model->nIter = myMin->iter; 338 // model->nPar is set by pmSourceFitSetMasks 323 339 324 340 // save the resulting chisq, nDOF, nIter 325 341 // these are not unique for any one source 326 model->chisq = myMin->value; 327 model->nIter = myMin->iter; 328 model->nDOF = nPix - model->params->n; 342 if (options->poissonErrors) { 343 model->chisq = myMin->value; 344 model->nPix = nPix; 345 model->nDOF = nPix - model->nPar; 346 model->chisqNorm = model->chisq / model->nDOF; 347 } else { 348 pmSourceChisqUnsubtracted (source, model, maskVal); 349 } 329 350 330 351 // set the model success or failure status … … 380 401 for (int i = 0; i < set->paramSet->n; i++) { 381 402 psVector *paramOne = set->paramSet->data[i]; 403 pmModel *modelOne = set->modelSet->data[i]; 382 404 383 405 switch (mode) { … … 387 409 if (j == PM_PAR_I0) continue; 388 410 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[n + j] = 1; 411 modelOne->nPar = 1; 389 412 } 390 413 break; … … 396 419 if (j == PM_PAR_I0) continue; 397 420 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[n + j] = 1; 421 modelOne->nPar = 3; 398 422 } 399 423 break; … … 401 425 // EXT model fits all params (except sky) 402 426 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[n + PM_PAR_SKY] = 1; 427 modelOne->nPar = paramOne->n - 1; 403 428 break; 404 429 default: … … 550 575 } 551 576 552 // parameter errors from the covariance matrix577 // parameter errors from the covariance matrix 553 578 psVector *dparams = psVectorAlloc (thisSet->nParamSet, PS_TYPE_F32); 554 579 for (int i = 0; i < dparams->n; i++) { … … 558 583 } 559 584 560 // get the Gauss-Newton distance for fixed model parameters585 // get the Gauss-Newton distance for fixed model parameters 561 586 if (constraint->paramMask != NULL) { 562 587 psVector *delta = psVectorAlloc (params->n, PS_TYPE_F32); … … 580 605 } 581 606 582 pmSourceFitSetValues (thisSet, dparams, params, source, myMin, y->n, fitStatus);607 pmSourceFitSetValues (thisSet, dparams, params, covar, source, myMin, y->n, fitStatus, options, maskVal); 583 608 psTrace ("psModules.objects", 5, "onPic: %d, fitStatus: %d, nIter: %d, chisq: %f, nPix: %ld\n", onPic, fitStatus, myMin->iter, myMin->value, y->n); 584 609 -
trunk/psModules/src/objects/pmSourceFitSet.h
r29004 r31153 40 40 bool pmSourceFitSetJoin (psVector *deriv, psVector *param, pmSourceFitSetData *set); 41 41 bool pmSourceFitSetSplit (pmSourceFitSetData *set, const psVector *deriv, const psVector *param); 42 bool pmSourceFitSetValues (pmSourceFitSetData *set, const psVector *dparam, const psVector *param, pmSource *source, psMinimization *myMin, int nPix, bool fitStatus); 42 43 bool pmSourceFitSetValues (pmSourceFitSetData *set, 44 const psVector *dparam, const psVector *param, const psImage *covar, 45 pmSource *source, psMinimization *myMin, int nPix, 46 bool fitStatus, pmSourceFitOptions *options, psImageMaskType maskVal); 43 47 44 48 psF32 pmSourceFitSetFunction(psVector *deriv, const psVector *param, const psVector *x); … … 57 61 psArray *modelSet, ///< model to be fitted 58 62 pmSourceFitOptions *options, ///< define options for fitting process 59 psImageMaskType maskVal ///< Val e to mask63 psImageMaskType maskVal ///< Value to mask 60 64 61 65 ); -
trunk/psModules/src/objects/pmSourceIO_CMF_PS1_DV1.c
r30621 r31153 49 49 50 50 #include "pmSourceIO.h" 51 #include "pmSourceOutputs.h" 51 52 52 53 // panstarrs-style FITS table output (header + table in 1st extension) … … 62 63 PS_ASSERT_PTR_NON_NULL(extname, false); 63 64 64 int i;65 65 psArray *table; 66 66 psMetadata *row; 67 psF32 *PAR, *dPAR;68 psEllipseAxes axes;69 psF32 xPos, yPos;70 psF32 xErr, yErr;71 psF32 errMag, chisq, apRadius;72 psS32 nPix, nDOF;73 67 74 68 pmChip *chip = readout->parent->parent; 75 pmFPA *fpa = chip->parent; 76 77 bool status1 = false; 78 bool status2 = false; 79 float magOffset = NAN; 80 float exptime = psMetadataLookupF32 (&status1, fpa->concepts, "FPA.EXPOSURE"); 81 float zeropt = psMetadataLookupF32(&status2, fpa->concepts, "FPA.ZP"); 82 if (!isfinite(zeropt)) { 83 zeropt = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS"); 84 } 85 if (status1 && status2 && (exptime > 0.0)) { 86 magOffset = zeropt + 2.5*log10(exptime); 87 } 88 float zeroptErr = psMetadataLookupF32 (&status2, imageHeader, "ZPT_ERR"); 69 89 70 90 71 // if the sequence is defined, write these in seq order; otherwise … … 94 75 if (source->seq == -1) { 95 76 // let's write these out in S/N order 96 sources = psArraySort (sources, pmSourceSortBy SN);77 sources = psArraySort (sources, pmSourceSortByFlux); 97 78 } else { 98 79 sources = psArraySort (sources, pmSourceSortBySeq); … … 100 81 } 101 82 83 short nImageOverlap; 84 float magOffset; 85 float zeroptErr; 86 float fwhmMajor; 87 float fwhmMinor; 88 pmSourceOutputsCommonValues (&nImageOverlap, &magOffset, &zeroptErr, &fwhmMajor, &fwhmMinor, readout, imageHeader); 89 102 90 table = psArrayAllocEmpty (sources->n); 103 91 104 92 // we write out PSF-fits for all sources, regardless of quality. the source flags tell us the state 105 93 // by the time we call this function, all values should be assigned. let's use asserts to be sure in some cases. 106 for (i = 0; i < sources->n; i++) {94 for (int i = 0; i < sources->n; i++) { 107 95 pmSource *source = (pmSource *) sources->data[i]; 108 96 … … 115 103 } 116 104 117 // no difference between PSF and non-PSF model 118 pmModel *model = source->modelPSF; 119 120 if (model != NULL) { 121 PAR = model->params->data.F32; 122 dPAR = model->dparams->data.F32; 123 xPos = PAR[PM_PAR_XPOS]; 124 yPos = PAR[PM_PAR_YPOS]; 125 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) { 126 xErr = dPAR[PM_PAR_XPOS]; 127 yErr = dPAR[PM_PAR_YPOS]; 128 } else { 129 // in linear-fit mode, there is no error on the centroid 130 xErr = source->peak->dx; 131 yErr = source->peak->dy; 132 } 133 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 134 axes = pmPSF_ModelToAxes (PAR, 20.0); 135 } else { 136 axes.major = NAN; 137 axes.minor = NAN; 138 axes.theta = NAN; 139 } 140 chisq = model->chisq; 141 nDOF = model->nDOF; 142 nPix = model->nPix; 143 apRadius = source->apRadius; 144 errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0]; 145 } else { 146 xPos = source->peak->xf; 147 yPos = source->peak->yf; 148 xErr = source->peak->dx; 149 yErr = source->peak->dy; 150 axes.major = NAN; 151 axes.minor = NAN; 152 axes.theta = NAN; 153 chisq = NAN; 154 nDOF = 0; 155 nPix = 0; 156 apRadius = NAN; 157 errMag = NAN; 158 } 159 160 float calMag = isfinite(magOffset) ? source->psfMag + magOffset : NAN; 161 float peakMag = (source->peak->flux > 0) ? -2.5*log10(source->peak->flux) : NAN; 162 psS16 nImageOverlap = 1; 163 164 psSphere ptSky = {0.0, 0.0, 0.0, 0.0}; 165 float posAngle = 0.0; 166 float pltScale = 0.0; 167 pmSourceLocalAstrometry (&ptSky, &posAngle, &pltScale, chip, xPos, yPos); 105 // set the 'best' values for various output fields: 106 pmSourceOutputs outputs; 107 pmSourceOutputsSetValues (&outputs, source, chip, fwhmMajor, fwhmMinor, magOffset); 108 109 pmSourceOutputsMoments moments; 110 pmSourceOutputsSetMoments (&moments, source); 168 111 169 112 pmSourceDiffStats diffStats; … … 175 118 row = psMetadataAlloc (); 176 119 psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET", PS_DATA_U32, "IPP detection identifier index", source->seq); 177 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", xPos);178 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", yPos);179 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", xErr); // XXX this is only measured for non-linear fits180 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", yErr); // XXX this is only measured for non-linear fits181 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", posAngle*PS_DEG_RAD);182 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", pltScale*PS_DEG_RAD*3600.0);120 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", outputs.xPos); 121 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", outputs.yPos); 122 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", outputs.xErr); // XXX this is only measured for non-linear fits 123 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", outputs.yErr); // XXX this is only measured for non-linear fits 124 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", outputs.posAngle); 125 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", outputs.pltScale); 183 126 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG", PS_DATA_F32, "PSF fit instrumental magnitude", source->psfMag); 184 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", errMag);127 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", source->errMag); 185 128 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX", PS_DATA_F32, "PSF fit instrumental magnitude", source->psfFlux); 186 129 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX_SIG",PS_DATA_F32, "Sigma of PSF instrumental magnitude", source->psfFluxErr); 187 130 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG", PS_DATA_F32, "magnitude in standard aperture", source->apMag); 188 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", apRadius);189 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", peakMag);190 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", calMag);131 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", outputs.apRadius); 132 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", outputs.peakMag); 133 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", outputs.calMag); 191 134 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG_SIG", PS_DATA_F32, "measured scatter of zero point calibration", zeroptErr); 192 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", ptSky.r*PS_DEG_RAD);193 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", ptSky.d*PS_DEG_RAD);135 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", outputs.ra); 136 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", outputs.dec); 194 137 psMetadataAdd (row, PS_LIST_TAIL, "SKY", PS_DATA_F32, "Sky level", source->sky); 195 138 psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA", PS_DATA_F32, "Sigma of sky level", source->skyErr); 196 139 197 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", chisq);140 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", outputs.chisq); 198 141 psMetadataAdd (row, PS_LIST_TAIL, "CR_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to CF", source->crNsigma); 199 142 psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to EXT", source->extNsigma); 200 143 201 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", axes.major);202 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", axes.minor);203 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", axes.theta);144 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", outputs.psfMajor); 145 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", outputs.psfMinor); 146 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", outputs.psfTheta); 204 147 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF", PS_DATA_F32, "PSF coverage/quality factor", source->pixWeightNotBad); 205 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", nDOF); 206 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", nPix); 207 208 // distinguish moments measure from window vs S/N > XX ?? 209 float mxx = source->moments ? source->moments->Mxx : NAN; 210 float mxy = source->moments ? source->moments->Mxy : NAN; 211 float myy = source->moments ? source->moments->Myy : NAN; 212 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", mxx); 213 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", mxy); 214 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", myy); 215 216 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NPOS", PS_DATA_S32, "nPos (n pix > 3 sigma)", diffStats.nGood); 217 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_FRATIO", PS_DATA_F32, "fPos / (fPos + fNeg)", diffStats.fRatio); 218 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_BAD", PS_DATA_F32, "nPos / (nPos + nNeg)", diffStats.nRatioBad); 219 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_MASK", PS_DATA_F32, "nPos / (nPos + nMask)", diffStats.nRatioMask); 220 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_ALL", PS_DATA_F32, "nPos / (nGood + nMask + nBad)", diffStats.nRatioAll); 148 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", outputs.nDOF); 149 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", outputs.nPix); 150 151 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", moments.Mxx); 152 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", moments.Mxy); 153 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", moments.Myy); 154 155 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NPOS", PS_DATA_S32, "nPos (n pix > 3 sigma)", diffStats.nGood); 156 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_FRATIO", PS_DATA_F32, "fPos / (fPos + fNeg)", diffStats.fRatio); 157 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_BAD", PS_DATA_F32, "nPos / (nPos + nNeg)", diffStats.nRatioBad); 158 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_MASK", PS_DATA_F32, "nPos / (nPos + nMask)", diffStats.nRatioMask); 159 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_ALL", PS_DATA_F32, "nPos / (nGood + nMask + nBad)", diffStats.nRatioAll); 221 160 222 161 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS", PS_DATA_U32, "psphot analysis flags", source->mode); … … 331 270 // recreate the peak to match (xPos, yPos) +/- (xErr, yErr) 332 271 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 333 source->peak->flux = peakFlux; 272 source->peak->rawFlux = peakFlux; 273 source->peak->smoothFlux = peakFlux; 334 274 source->peak->xf = PAR[PM_PAR_XPOS]; // more accurate position 335 275 source->peak->yf = PAR[PM_PAR_YPOS]; // more accurate position 336 276 source->peak->dx = dPAR[PM_PAR_XPOS]; 337 277 source->peak->dy = dPAR[PM_PAR_YPOS]; 338 if (isfinite (source->errMag) && (source->errMag > 0.0)) {339 source->peak->SN = 1.0 / source->errMag;340 } else {341 source->peak->SN = sqrt(source->peak->flux); // an alternate proxy: various functions sort by peak S/N342 }343 278 344 279 source->pixWeightNotBad = psMetadataLookupF32 (&status, row, "PSF_QF"); … … 353 288 354 289 source->moments = pmMomentsAlloc (); 290 source->moments->Mx = source->peak->xf; // we don't have both Mx,My and xf,yf in the cmf 291 source->moments->My = source->peak->yf; // we don't have both Mx,My and xf,yf in the cmf 292 355 293 source->moments->Mxx = psMetadataLookupF32 (&status, row, "MOMENTS_XX"); 356 294 source->moments->Mxy = psMetadataLookupF32 (&status, row, "MOMENTS_XY"); … … 395 333 396 334 // let's write these out in S/N order 397 sources = psArraySort (sources, pmSourceSortBy SN);335 sources = psArraySort (sources, pmSourceSortByFlux); 398 336 399 337 table = psArrayAllocEmpty (sources->n); … … 568 506 569 507 // let's write these out in S/N order 570 sources = psArraySort (sources, pmSourceSortBy SN);508 sources = psArraySort (sources, pmSourceSortByFlux); 571 509 572 510 // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams -
trunk/psModules/src/objects/pmSourceIO_CMF_PS1_DV2.c
r30621 r31153 49 49 50 50 #include "pmSourceIO.h" 51 #include "pmSourceOutputs.h" 51 52 52 53 // panstarrs-style FITS table output (header + table in 1st extension) … … 62 63 PS_ASSERT_PTR_NON_NULL(extname, false); 63 64 64 int i;65 65 psArray *table; 66 66 psMetadata *row; 67 psF32 *PAR, *dPAR;68 psEllipseAxes axes;69 psF32 xPos, yPos;70 psF32 xErr, yErr;71 psF32 chisq, apRadius;72 psS32 nPix, nDOF;73 67 74 68 pmChip *chip = readout->parent->parent; 75 pmFPA *fpa = chip->parent;76 77 bool status1 = false;78 bool status2 = false;79 float magOffset = NAN;80 float exptime = psMetadataLookupF32 (&status1, fpa->concepts, "FPA.EXPOSURE");81 float zeropt = psMetadataLookupF32(&status2, fpa->concepts, "FPA.ZP");82 if (!isfinite(zeropt)) {83 zeropt = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");84 }85 if (status1 && status2 && (exptime > 0.0)) {86 magOffset = zeropt + 2.5*log10(exptime);87 }88 float zeroptErr = psMetadataLookupF32 (&status2, imageHeader, "ZPT_ERR");89 90 // we need a measure of the image quality (FWHM) for this image, in order to get the positional errors91 float fwhmMajor = psMetadataLookupF32(&status1, readout->analysis, "FWHM_MAJ");92 if (!status1) {93 fwhmMajor = psMetadataLookupF32(&status1, readout->analysis, "IQ_FW1");94 if (!status1) {95 fwhmMajor = 5.0; // XXX just a guess!96 }97 }98 float fwhmMinor = psMetadataLookupF32(&status1, readout->analysis, "FWHM_MIN");99 if (!status1) {100 fwhmMinor = psMetadataLookupF32(&status1, readout->analysis, "IQ_FW2");101 if (!status1) {102 fwhmMinor = 5.0; // XXX just a guess!103 }104 }105 69 106 70 // if the sequence is defined, write these in seq order; otherwise … … 110 74 if (source->seq == -1) { 111 75 // let's write these out in S/N order 112 sources = psArraySort (sources, pmSourceSortBy SN);76 sources = psArraySort (sources, pmSourceSortByFlux); 113 77 } else { 114 78 sources = psArraySort (sources, pmSourceSortBySeq); … … 118 82 table = psArrayAllocEmpty (sources->n); 119 83 84 short nImageOverlap; 85 float magOffset; 86 float zeroptErr; 87 float fwhmMajor; 88 float fwhmMinor; 89 pmSourceOutputsCommonValues (&nImageOverlap, &magOffset, &zeroptErr, &fwhmMajor, &fwhmMinor, readout, imageHeader); 90 120 91 // we write out PSF-fits for all sources, regardless of quality. the source flags tell us the state 121 92 // by the time we call this function, all values should be assigned. let's use asserts to be sure in some cases. 122 for (i = 0; i < sources->n; i++) {93 for (int i = 0; i < sources->n; i++) { 123 94 pmSource *source = (pmSource *) sources->data[i]; 124 95 … … 131 102 } 132 103 133 // no difference between PSF and non-PSF model 134 pmModel *model = source->modelPSF; 135 136 if (model != NULL) { 137 PAR = model->params->data.F32; 138 dPAR = model->dparams->data.F32; 139 xPos = PAR[PM_PAR_XPOS]; 140 yPos = PAR[PM_PAR_YPOS]; 141 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) { 142 xErr = dPAR[PM_PAR_XPOS]; 143 yErr = dPAR[PM_PAR_YPOS]; 144 } else { 145 // in linear-fit mode, there is no error on the centroid 146 xErr = fwhmMajor * source->errMag / 2.35; 147 yErr = fwhmMinor * source->errMag / 2.35; 148 } 149 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 150 axes = pmPSF_ModelToAxes (PAR, 20.0); 151 } else { 152 axes.major = NAN; 153 axes.minor = NAN; 154 axes.theta = NAN; 155 } 156 chisq = model->chisq; 157 nDOF = model->nDOF; 158 nPix = model->nPix; 159 apRadius = source->apRadius; 160 } else { 161 bool useMoments = true; 162 useMoments = (useMoments && source->moments); // can't if there are no moments 163 useMoments = (useMoments && source->moments->nPixels); // can't if the moments were not measured 164 useMoments = (useMoments && !(source->mode && PM_SOURCE_MODE_MOMENTS_FAILURE)); // can't if the moments failed... 165 166 if (useMoments) { 167 xPos = source->moments->Mx; 168 yPos = source->moments->My; 169 xErr = fwhmMajor * source->errMag / 2.35; 170 yErr = fwhmMinor * source->errMag / 2.35; 171 } else { 172 xPos = source->peak->xf; 173 yPos = source->peak->yf; 174 xErr = source->peak->dx; 175 yErr = source->peak->dy; 176 } 177 axes.major = NAN; 178 axes.minor = NAN; 179 axes.theta = NAN; 180 chisq = NAN; 181 nDOF = 0; 182 nPix = 0; 183 apRadius = NAN; 184 } 185 186 float calMag = isfinite(magOffset) ? source->psfMag + magOffset : NAN; 187 float peakMag = (source->peak->flux > 0) ? -2.5*log10(source->peak->flux) : NAN; 188 psS16 nImageOverlap = 1; 189 190 psSphere ptSky = {0.0, 0.0, 0.0, 0.0}; 191 float posAngle = 0.0; 192 float pltScale = 0.0; 193 pmSourceLocalAstrometry (&ptSky, &posAngle, &pltScale, chip, xPos, yPos); 104 // set the 'best' values for various output fields: 105 pmSourceOutputs outputs; 106 pmSourceOutputsSetValues (&outputs, source, chip, fwhmMajor, fwhmMinor, magOffset); 107 108 pmSourceOutputsMoments moments; 109 pmSourceOutputsSetMoments (&moments, source); 194 110 195 111 pmSourceDiffStats diffStats; … … 201 117 row = psMetadataAlloc (); 202 118 psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET", PS_DATA_U32, "IPP detection identifier index", source->seq); 203 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", xPos);204 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", yPos);205 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", xErr); // XXX this is only measured for non-linear fits206 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", yErr); // XXX this is only measured for non-linear fits207 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", posAngle*PS_DEG_RAD);208 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", pltScale*PS_DEG_RAD*3600.0);119 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", outputs.xPos); 120 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", outputs.yPos); 121 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", outputs.xErr); // XXX this is only measured for non-linear fits 122 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", outputs.yErr); // XXX this is only measured for non-linear fits 123 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", outputs.posAngle); 124 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", outputs.pltScale); 209 125 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG", PS_DATA_F32, "PSF fit instrumental magnitude", source->psfMag); 210 126 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", source->errMag); … … 214 130 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG", PS_DATA_F32, "magnitude in standard aperture", source->apMag); 215 131 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RAW", PS_DATA_F32, "magnitude in real aperture", source->apMagRaw); 216 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", apRadius);132 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", outputs.apRadius); 217 133 psMetadataAdd (row, PS_LIST_TAIL, "AP_FLUX", PS_DATA_F32, "instrumental flux in standard aperture", source->apFlux); 218 134 psMetadataAdd (row, PS_LIST_TAIL, "AP_FLUX_SIG", PS_DATA_F32, "aperture flux error", source->apFluxErr); 219 135 220 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", peakMag);221 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", calMag);136 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", outputs.peakMag); 137 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", outputs.calMag); 222 138 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG_SIG", PS_DATA_F32, "measured scatter of zero point calibration", zeroptErr); 223 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", ptSky.r*PS_DEG_RAD);224 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", ptSky.d*PS_DEG_RAD);139 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", outputs.ra); 140 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", outputs.dec); 225 141 psMetadataAdd (row, PS_LIST_TAIL, "SKY", PS_DATA_F32, "Sky level", source->sky); 226 142 psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA", PS_DATA_F32, "Sigma of sky level", source->skyErr); 227 143 228 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", chisq);144 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", outputs.chisq); 229 145 psMetadataAdd (row, PS_LIST_TAIL, "CR_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to CF", source->crNsigma); 230 146 psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to EXT", source->extNsigma); 231 147 232 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", axes.major);233 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", axes.minor);234 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", axes.theta);148 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", outputs.psfMajor); 149 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", outputs.psfMinor); 150 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", outputs.psfTheta); 235 151 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF", PS_DATA_F32, "PSF coverage/quality factor (bad)", source->pixWeightNotBad); 236 152 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF_PERFECT", PS_DATA_F32, "PSF coverage/quality factor (poor)", source->pixWeightNotPoor); 237 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", nDOF); 238 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", nPix); 239 240 // distinguish moments measure from window vs S/N > XX ?? 241 float mxx = source->moments ? source->moments->Mxx : NAN; 242 float mxy = source->moments ? source->moments->Mxy : NAN; 243 float myy = source->moments ? source->moments->Myy : NAN; 244 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", mxx); 245 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", mxy); 246 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", myy); 247 248 float Mrf = source->moments ? source->moments->Mrf : NAN; 249 float Mrh = source->moments ? source->moments->Mrh : NAN; 250 float Krf = source->moments ? source->moments->KronFlux : NAN; 251 float dKrf = source->moments ? source->moments->KronFluxErr : NAN; 252 253 float Kinner = source->moments ? source->moments->KronFinner : NAN; 254 float Kouter = source->moments ? source->moments->KronFouter : NAN; 255 256 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", Mrf); 257 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", Mrh); 258 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", Krf); 259 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", dKrf); 260 261 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 1.0 R1)", Kinner); 262 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 4.0 R1)", Kouter); 263 264 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NPOS", PS_DATA_S32, "nPos (n pix > 3 sigma)", diffStats.nGood); 265 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_FRATIO", PS_DATA_F32, "fPos / (fPos + fNeg)", diffStats.fRatio); 266 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_BAD", PS_DATA_F32, "nPos / (nPos + nNeg)", diffStats.nRatioBad); 267 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_MASK", PS_DATA_F32, "nPos / (nPos + nMask)", diffStats.nRatioMask); 268 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_ALL", PS_DATA_F32, "nPos / (nGood + nMask + nBad)", diffStats.nRatioAll); 153 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", outputs.nDOF); 154 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", outputs.nPix); 155 156 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", moments.Mxx); 157 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", moments.Mxy); 158 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", moments.Myy); 159 160 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", moments.Mrf); 161 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", moments.Mrh); 162 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Krf); 163 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", moments.dKrf); 164 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 1.0 R1)", moments.Kinner); 165 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 4.0 R1)", moments.Kouter); 166 167 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NPOS", PS_DATA_S32, "nPos (n pix > 3 sigma)", diffStats.nGood); 168 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_FRATIO", PS_DATA_F32, "fPos / (fPos + fNeg)", diffStats.fRatio); 169 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_BAD", PS_DATA_F32, "nPos / (nPos + nNeg)", diffStats.nRatioBad); 170 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_MASK", PS_DATA_F32, "nPos / (nPos + nMask)", diffStats.nRatioMask); 171 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_NRATIO_ALL", PS_DATA_F32, "nPos / (nGood + nMask + nBad)", diffStats.nRatioAll); 269 172 270 173 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_R_P", PS_DATA_F32, "distance to positive match source", diffStats.Rp); … … 385 288 // recreate the peak to match (xPos, yPos) +/- (xErr, yErr) 386 289 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 387 source->peak->flux = peakFlux; 290 source->peak->rawFlux = peakFlux; 291 source->peak->smoothFlux = peakFlux; 388 292 source->peak->xf = PAR[PM_PAR_XPOS]; // more accurate position 389 293 source->peak->yf = PAR[PM_PAR_YPOS]; // more accurate position 390 294 source->peak->dx = dPAR[PM_PAR_XPOS]; 391 295 source->peak->dy = dPAR[PM_PAR_YPOS]; 392 if (isfinite (source->errMag) && (source->errMag > 0.0)) {393 source->peak->SN = 1.0 / source->errMag;394 } else {395 source->peak->SN = sqrt(source->peak->flux); // an alternate proxy: various functions sort by peak S/N396 }397 296 398 297 source->pixWeightNotBad = psMetadataLookupF32 (&status, row, "PSF_QF"); … … 408 307 409 308 source->moments = pmMomentsAlloc (); 309 source->moments->Mx = source->peak->xf; // we don't have both Mx,My and xf,yf in the cmf 310 source->moments->My = source->peak->yf; // we don't have both Mx,My and xf,yf in the cmf 311 410 312 source->moments->Mxx = psMetadataLookupF32 (&status, row, "MOMENTS_XX"); 411 313 source->moments->Mxy = psMetadataLookupF32 (&status, row, "MOMENTS_XY"); … … 456 358 457 359 // let's write these out in S/N order 458 sources = psArraySort (sources, pmSourceSortBy SN);360 sources = psArraySort (sources, pmSourceSortByFlux); 459 361 460 362 table = psArrayAllocEmpty (sources->n); … … 629 531 630 532 // let's write these out in S/N order 631 sources = psArraySort (sources, pmSourceSortBy SN);533 sources = psArraySort (sources, pmSourceSortByFlux); 632 534 633 535 // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams -
trunk/psModules/src/objects/pmSourceIO_CMF_PS1_SV1.c
r30621 r31153 50 50 51 51 #include "pmSourceIO.h" 52 #include "pmSourceOutputs.h" 52 53 53 54 // panstarrs-style FITS table output (header + table in 1st extension) … … 66 67 psArray *table; 67 68 psMetadata *row; 68 psF32 *PAR, *dPAR;69 psEllipseAxes axes;70 psF32 xPos, yPos;71 psF32 xErr, yErr;72 psF32 errMag, chisq, apRadius;73 psS32 nPix, nDOF;74 69 75 70 pmChip *chip = readout->parent->parent; 76 pmFPA *fpa = chip->parent; 77 78 bool status1 = false; 79 bool status2 = false; 80 float magOffset = NAN; 81 float exptime = psMetadataLookupF32 (&status1, fpa->concepts, "FPA.EXPOSURE"); 82 float zeropt = psMetadataLookupF32(&status2, fpa->concepts, "FPA.ZP"); 83 if (!isfinite(zeropt)) { 84 zeropt = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS"); 85 } 86 if (status1 && status2 && (exptime > 0.0)) { 87 magOffset = zeropt + 2.5*log10(exptime); 88 } 89 float zeroptErr = psMetadataLookupF32 (&status2, imageHeader, "ZPT_ERR"); 90 91 // if the sequence is defined, write these in seq order; otherwise 92 // write them in S/N order: 71 72 // if the sequence is defined, write these in seq order; otherwise write them in S/N order. 73 // Careful: if we are working with child sources, then we need to sort by the parent info, 74 // not our info 93 75 if (sources->n > 0) { 94 pmSource *source = (pmSource *)sources->data[0];76 pmSource *source = sources->data[0]; 95 77 if (source->seq == -1) { 96 // let's write these out in S/N order 97 sources = psArraySort (sources, pmSourceSortBySN); 78 sources = psArraySort (sources, pmSourceSortByFlux); 98 79 } else { 99 80 sources = psArraySort (sources, pmSourceSortBySeq); … … 103 84 table = psArrayAllocEmpty (sources->n); 104 85 105 # if (0) 106 // we use this just to define the output vectors (which must be present for all objects) 107 bool status = false; 108 psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER"); 109 psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER"); 110 psAssert (radMax, "this must have been defined and tested earlier!"); 111 psAssert (radMax->n, "this must have been defined and tested earlier!"); 112 psAssert (radMin->n == radMax->n, "inconsistent annular bins"); 113 114 // write the radial profile apertures to header 115 for (int i = 0; i < radMax->n; i++) { 116 sprintf (keyword1, "RMIN_%02d", i); 117 sprintf (keyword2, "RMAX_%02d", i); 118 psMetadataAddF32 (imageHeader, PS_LIST_TAIL, keyword1, PS_META_REPLACE, "min radius for SB profile", radMin->data.F32[i]); 119 psMetadataAddF32 (imageHeader, PS_LIST_TAIL, keyword2, PS_META_REPLACE, "min radius for SB profile", radMax->data.F32[i]); 120 } 121 # endif 86 short nImageOverlap; 87 float magOffset; 88 float zeroptErr; 89 float fwhmMajor; 90 float fwhmMinor; 91 pmSourceOutputsCommonValues (&nImageOverlap, &magOffset, &zeroptErr, &fwhmMajor, &fwhmMinor, readout, imageHeader); 122 92 123 93 // we write out PSF-fits for all sources, regardless of quality. the source flags tell us the state 124 94 // by the time we call this function, all values should be assigned. let's use asserts to be sure in some cases. 125 95 for (int i = 0; i < sources->n; i++) { 126 pmSource *source = (pmSource *) sources->data[i]; 127 128 // If source->seq is -1, source was generated in this analysis. If source->seq is 129 // not -1, source was read from elsewhere: in the latter case, preserve the source 130 // ID. source.seq is used instead of source.id since the latter is a const 131 // generated on Alloc, and would thus be wrong for read in sources. 96 // this is the source associated with this image 97 pmSource *thisSource = sources->data[i]; 98 99 // this is the "real" version of this source 100 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 101 102 // If source->seq is -1, source is unique and generated in this analysis. If 103 // source->seq is not -1, source was read from elsewhere or tied to other source (eg 104 // from another image): in the latter case, preserve the source ID. source.seq is used 105 // instead of source.id since the latter is a const generated on Alloc, and would thus 106 // be wrong for read in sources. 132 107 if (source->seq == -1) { 133 108 source->seq = i; 134 109 } 135 110 136 // no difference between PSF and non-PSF model 137 pmModel *model = source->modelPSF; 138 139 if (model != NULL) { 140 PAR = model->params->data.F32; 141 dPAR = model->dparams->data.F32; 142 xPos = PAR[PM_PAR_XPOS]; 143 yPos = PAR[PM_PAR_YPOS]; 144 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) { 145 xErr = dPAR[PM_PAR_XPOS]; 146 yErr = dPAR[PM_PAR_YPOS]; 147 } else { 148 // in linear-fit mode, there is no error on the centroid 149 xErr = source->peak->dx; 150 yErr = source->peak->dy; 151 } 152 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 153 axes = pmPSF_ModelToAxes (PAR, 20.0); 154 } else { 155 axes.major = NAN; 156 axes.minor = NAN; 157 axes.theta = NAN; 158 } 159 chisq = model->chisq; 160 nDOF = model->nDOF; 161 nPix = model->nPix; 162 apRadius = source->apRadius; 163 errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0]; 164 } else { 165 xPos = source->peak->xf; 166 yPos = source->peak->yf; 167 xErr = source->peak->dx; 168 yErr = source->peak->dy; 169 axes.major = NAN; 170 axes.minor = NAN; 171 axes.theta = NAN; 172 chisq = NAN; 173 nDOF = 0; 174 nPix = 0; 175 apRadius = NAN; 176 errMag = NAN; 177 } 178 179 float calMag = isfinite(magOffset) ? source->psfMag + magOffset : NAN; 180 float peakMag = (source->peak->flux > 0) ? -2.5*log10(source->peak->flux) : NAN; 181 psS16 nImageOverlap = 1; 182 183 psSphere ptSky = {0.0, 0.0, 0.0, 0.0}; 184 float posAngle = 0.0; 185 float pltScale = 0.0; 186 pmSourceLocalAstrometry (&ptSky, &posAngle, &pltScale, chip, xPos, yPos); 111 // set the 'best' values for various output fields: 112 pmSourceOutputs outputs; 113 pmSourceOutputsSetValues (&outputs, source, chip, fwhmMajor, fwhmMinor, magOffset); 114 115 pmSourceOutputsMoments moments; 116 pmSourceOutputsSetMoments (&moments, source); 187 117 188 118 row = psMetadataAlloc (); 189 119 psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET", PS_DATA_U32, "IPP detection identifier index", source->seq); 190 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", xPos);191 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", yPos);192 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", xErr); // XXX this is only measured for non-linear fits193 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", yErr); // XXX this is only measured for non-linear fits194 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", posAngle*PS_DEG_RAD);195 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", pltScale*PS_DEG_RAD*3600.0);120 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", outputs.xPos); 121 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", outputs.yPos); 122 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", outputs.xErr); 123 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", outputs.yErr); 124 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", outputs.posAngle); 125 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", outputs.pltScale); 196 126 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG", PS_DATA_F32, "PSF fit instrumental magnitude", source->psfMag); 197 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", errMag);127 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", source->errMag); 198 128 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX", PS_DATA_F32, "PSF fit instrumental flux (counts)", source->psfFlux); 199 129 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX_SIG",PS_DATA_F32, "Sigma of PSF instrumental flux", source->psfFluxErr); 200 130 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG", PS_DATA_F32, "magnitude in standard aperture", source->apMag); 201 131 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RAW", PS_DATA_F32, "magnitude in reported aperture", source->apMagRaw); 202 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", apRadius);203 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", peakMag);204 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", calMag);132 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", outputs.apRadius); 133 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", outputs.peakMag); 134 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", outputs.calMag); 205 135 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG_SIG", PS_DATA_F32, "measured scatter of zero point calibration", zeroptErr); 206 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", ptSky.r*PS_DEG_RAD);207 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", ptSky.d*PS_DEG_RAD);136 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", outputs.ra); 137 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", outputs.dec); 208 138 psMetadataAdd (row, PS_LIST_TAIL, "SKY", PS_DATA_F32, "Sky level", source->sky); 209 139 psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA", PS_DATA_F32, "Sigma of sky level", source->skyErr); 210 140 211 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", chisq);141 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", outputs.chisq); 212 142 psMetadataAdd (row, PS_LIST_TAIL, "CR_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to CF", source->crNsigma); 213 143 psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to EXT", source->extNsigma); 214 144 215 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", axes.major);216 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", axes.minor);217 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", axes.theta);145 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", outputs.psfMajor); 146 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", outputs.psfMinor); 147 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", outputs.psfTheta); 218 148 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF", PS_DATA_F32, "PSF coverage/quality factor (bad)", source->pixWeightNotBad); 219 149 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF_PERFECT", PS_DATA_F32, "PSF coverage/quality factor (poor)", source->pixWeightNotPoor); 220 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", nDOF); 221 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", nPix); 222 223 // distinguish moments measure from window vs S/N > XX ?? 224 float Mxx = source->moments ? source->moments->Mxx : NAN; 225 float Mxy = source->moments ? source->moments->Mxy : NAN; 226 float Myy = source->moments ? source->moments->Myy : NAN; 227 228 float Mrf = source->moments ? source->moments->Mrf : NAN; 229 float Mrh = source->moments ? source->moments->Mrh : NAN; 230 float Krf = source->moments ? source->moments->KronFlux : NAN; 231 float dKrf = source->moments ? source->moments->KronFluxErr : NAN; 232 233 float Kinner = source->moments ? source->moments->KronFinner : NAN; 234 float Kouter = source->moments ? source->moments->KronFouter : NAN; 235 236 float M_c3 = source->moments ? 1.0*source->moments->Mxxx - 3.0*source->moments->Mxyy : NAN; 237 float M_s3 = source->moments ? 3.0*source->moments->Mxxy - 1.0*source->moments->Myyy : NAN; 238 float M_c4 = source->moments ? 1.0*source->moments->Mxxxx - 6.0*source->moments->Mxxyy + 1.0*source->moments->Myyyy : NAN; 239 float M_s4 = source->moments ? 4.0*source->moments->Mxxxy - 4.0*source->moments->Mxyyy : NAN; 240 241 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", Mxx); 242 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", Mxy); 243 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", Myy); 244 245 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3C", PS_DATA_F32, "third momemt cos theta", M_c3); 246 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3S", PS_DATA_F32, "third momemt sin theta", M_s3); 247 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4C", PS_DATA_F32, "fourth momemt cos theta", M_c4); 248 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4S", PS_DATA_F32, "fourth momemt sin theta", M_s4); 249 250 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", Mrf); 251 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", Mrh); 252 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", Krf); 253 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", dKrf); 254 255 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", Kinner); 256 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", Kouter); 150 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", outputs.nDOF); 151 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", outputs.nPix); 152 153 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", moments.Mxx); 154 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", moments.Mxy); 155 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", moments.Myy); 156 157 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3C", PS_DATA_F32, "third momemt cos theta", moments.M_c3); 158 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3S", PS_DATA_F32, "third momemt sin theta", moments.M_s3); 159 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4C", PS_DATA_F32, "fourth momemt cos theta", moments.M_c4); 160 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4S", PS_DATA_F32, "fourth momemt sin theta", moments.M_s4); 161 162 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", moments.Mrf); 163 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", moments.Mrh); 164 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Krf); 165 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", moments.dKrf); 166 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kinner); 167 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kouter); 257 168 258 169 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS", PS_DATA_U32, "psphot analysis flags", source->mode); 259 170 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS2", PS_DATA_U32, "psphot analysis flags", source->mode2); 260 261 # if (0)262 // XXX if we have raw radial apertures, write them out here263 psVector *radFlux = psVectorAlloc(radMax->n, PS_TYPE_F32);264 psVector *radFluxErr = psVectorAlloc(radMax->n, PS_TYPE_F32);265 psVector *radFill = psVectorAlloc(radMax->n, PS_TYPE_F32);266 psVectorInit (radFlux, NAN);267 psVectorInit (radFluxErr, NAN);268 psVectorInit (radFill, NAN);269 if (!source->radial) goto empty_annuli;270 if (!source->radial->flux) goto empty_annuli;271 if (!source->radial->fill) goto empty_annuli;272 psAssert (source->radial->flux->n <= radFlux->n, "inconsistent vector lengths");273 psAssert (source->radial->fill->n <= radFlux->n, "inconsistent vector lengths");274 275 // copy the data from fluxVal (which is not guaranteed to be the full length) to radFlux276 for (int j = 0; j < source->radial->flux->n; j++) {277 radFlux->data.F32[j] = source->radial->flux->data.F32[j];278 radFluxErr->data.F32[j] = source->radial->fluxErr->data.F32[j];279 radFill->data.F32[j] = source->radial->fill->data.F32[j];280 }281 282 empty_annuli:283 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX", PS_DATA_VECTOR, "flux within annuli", radFlux);284 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX_ERR", PS_DATA_VECTOR, "flux error in annuli", radFluxErr);285 psMetadataAdd (row, PS_LIST_TAIL, "APER_FILL", PS_DATA_VECTOR, "fill factor of annuli", radFill);286 psFree (radFlux);287 psFree (radFluxErr);288 psFree (radFill);289 # endif290 171 291 172 // XXX not sure how to get this : need to load Nimages with weight? … … 406 287 // recreate the peak to match (xPos, yPos) +/- (xErr, yErr) 407 288 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 408 source->peak->flux = peakFlux; 289 source->peak->rawFlux = peakFlux; 290 source->peak->smoothFlux = peakFlux; 409 291 source->peak->xf = PAR[PM_PAR_XPOS]; // more accurate position 410 292 source->peak->yf = PAR[PM_PAR_YPOS]; // more accurate position 411 293 source->peak->dx = dPAR[PM_PAR_XPOS]; 412 294 source->peak->dy = dPAR[PM_PAR_YPOS]; 413 if (isfinite (source->errMag) && (source->errMag > 0.0)) {414 source->peak->SN = 1.0 / source->errMag;415 } else {416 source->peak->SN = sqrt(source->peak->flux); // an alternate proxy: various functions sort by peak S/N417 }418 295 419 296 source->pixWeightNotBad = psMetadataLookupF32 (&status, row, "PSF_QF"); … … 429 306 430 307 source->moments = pmMomentsAlloc (); 308 source->moments->Mx = source->peak->xf; // we don't have both Mx,My and xf,yf in the cmf 309 source->moments->My = source->peak->yf; // we don't have both Mx,My and xf,yf in the cmf 310 431 311 source->moments->Mxx = psMetadataLookupF32 (&status, row, "MOMENTS_XX"); 432 312 source->moments->Mxy = psMetadataLookupF32 (&status, row, "MOMENTS_XY"); … … 500 380 501 381 // let's write these out in S/N order 502 sources = psArraySort (sources, pmSourceSortBy SN);382 sources = psArraySort (sources, pmSourceSortByFlux); 503 383 504 384 table = psArrayAllocEmpty (sources->n); … … 522 402 // we write out all sources, regardless of quality. the source flags tell us the state 523 403 for (int i = 0; i < sources->n; i++) { 524 pmSource *source = sources->data[i]; 404 // this is the source associated with this image 405 pmSource *thisSource = sources->data[i]; 406 407 // this is the "real" version of this source 408 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 525 409 526 410 // skip sources without measurements … … 556 440 } 557 441 psMetadataAdd (row, PS_LIST_TAIL, "F25_ARATIO", PS_DATA_F32, "Axial Ratio of radial profile", AxialRatio); 558 psMetadataAdd (row, PS_LIST_TAIL, "F25_THETA", PS_DATA_F32, "Angle of radial profile ellipse", AxialTheta);442 psMetadataAdd (row, PS_LIST_TAIL, "F25_THETA", PS_DATA_F32, "Angle of radial profile ellipse", AxialTheta); 559 443 560 444 // Petrosian measurements … … 567 451 float mag = (extpars->petrosianFlux > 0.0) ? -2.5*log10(extpars->petrosianFlux) + magOffset : NAN; // XXX zero point 568 452 float magErr = (extpars->petrosianFlux > 0.0) ? extpars->petrosianFlux / extpars->petrosianFluxErr : NAN; // XXX zero point 569 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG", PS_DATA_F32, "Petrosian Magnitude", mag);570 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR", PS_DATA_F32, "Petrosian Magnitude Error", magErr);571 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS", PS_DATA_F32, "Petrosian Radius (pix)", extpars->petrosianRadius);572 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error (pix)", extpars->petrosianRadiusErr);453 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG", PS_DATA_F32, "Petrosian Magnitude", mag); 454 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR", PS_DATA_F32, "Petrosian Magnitude Error", magErr); 455 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS", PS_DATA_F32, "Petrosian Radius (pix)", extpars->petrosianRadius); 456 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error (pix)", extpars->petrosianRadiusErr); 573 457 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50", PS_DATA_F32, "Petrosian R50 (pix)", extpars->petrosianR50); 574 458 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50_ERR", PS_DATA_F32, "Petrosian R50 Error (pix)", extpars->petrosianR50Err); 575 459 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90", PS_DATA_F32, "Petrosian R90 (pix)", extpars->petrosianR90); 576 460 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90_ERR", PS_DATA_F32, "Petrosian R90 Error (pix)", extpars->petrosianR90Err); 461 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_FILL", PS_DATA_F32, "Petrosian Fill Factor", extpars->petrosianFill); 577 462 } else { 578 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG", PS_DATA_F32, "Petrosian Magnitude", NAN);579 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR", PS_DATA_F32, "Petrosian Magnitude Error", NAN);580 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS", PS_DATA_F32, "Petrosian Radius", NAN);581 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error", NAN);463 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG", PS_DATA_F32, "Petrosian Magnitude", NAN); 464 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR", PS_DATA_F32, "Petrosian Magnitude Error", NAN); 465 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS", PS_DATA_F32, "Petrosian Radius", NAN); 466 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error", NAN); 582 467 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50", PS_DATA_F32, "Petrosian R50 (pix)", NAN); 583 468 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50_ERR", PS_DATA_F32, "Petrosian R50 Error (pix)",NAN); 584 469 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90", PS_DATA_F32, "Petrosian R90 (pix)", NAN); 585 470 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90_ERR", PS_DATA_F32, "Petrosian R90 Error (pix)",NAN); 471 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_FILL", PS_DATA_F32, "Petrosian Fill Factor", NAN); 586 472 } 587 473 } … … 672 558 673 559 // let's write these out in S/N order 674 sources = psArraySort (sources, pmSourceSortBy SN);560 sources = psArraySort (sources, pmSourceSortByFlux); 675 561 676 562 // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams 677 563 int nParamMax = 0; 678 564 for (int i = 0; i < sources->n; i++) { 679 pmSource *source = sources->data[i]; 565 // this is the source associated with this image 566 pmSource *thisSource = sources->data[i]; 567 568 // this is the "real" version of this source 569 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 570 680 571 if (source->modelFits == NULL) continue; 681 572 for (int j = 0; j < source->modelFits->n; j++) { … … 691 582 for (int i = 0; i < sources->n; i++) { 692 583 693 pmSource *source = sources->data[i]; 584 pmSource *thisSource = sources->data[i]; 585 586 // this is the "real" version of this source 587 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 694 588 695 589 // XXX if no model fits are saved, write out modelEXT? … … 747 641 748 642 if (k < model->params->n) { 749 psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "", model->params->data.F32[k]);643 psMetadataAddF32 (row, PS_LIST_TAIL, name, 0, "", model->params->data.F32[k]); 750 644 } else { 751 psMetadataAddF32 (row, PS_LIST_TAIL, name, PS_DATA_F32, "", NAN);645 psMetadataAddF32 (row, PS_LIST_TAIL, name, 0, "", NAN); 752 646 } 753 647 } 754 648 755 // XXX other parameters which may be set. 756 // XXX flag / value to define the model 757 // XXX write out the model type, fit status flags 758 649 // optionally, write out the covariance matrix values 650 // XXX do I need to pad this to match the biggest covar matrix? 651 if (model->covar) { 652 for (int iy = 0; iy < model->covar->numCols; iy++) { 653 for (int ix = iy; ix < model->covar->numCols; ix++) { 654 snprintf (name, 64, "EXT_COVAR_%02d_%02d", iy, ix); 655 psMetadataAddF32 (row, PS_LIST_TAIL, name, 0, "", model->covar->data.F32[iy][ix]); 656 657 } 658 } 659 } 759 660 psArrayAdd (table, 100, row); 760 661 psFree (row); … … 790 691 bool pmSourcesWrite_CMF_PS1_SV1_XRAD(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe) 791 692 { 792 693 bool status = false; 793 694 psArray *table; 794 695 psMetadata *row; … … 796 697 char keyword1[80], keyword2[80]; 797 698 699 // perform full non-linear fits / extended source analysis? 700 if (!psMetadataLookupBool (&status, recipe, "RADIAL_APERTURES")) { 701 psLogMsg ("psphot", PS_LOG_INFO, "radial apertures were not measured, skipping\n"); 702 return true; 703 } 704 798 705 // create a header to hold the output data 799 706 psMetadata *outhead = psMetadataAlloc (); … … 803 710 804 711 // we use this just to define the output vectors (which must be present for all objects) 805 bool status = false;806 712 psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER"); 807 713 psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER"); … … 818 724 } 819 725 726 // the FWHM values are available if we measured a psf-matched convolved set 820 727 psVector *fwhmValues = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES"); 821 if (!fwhmValues) {822 psError (PM_ERR_CONFIG, true, "convolved or measured FWHM is not defined for this readout");823 return false;824 }825 728 826 729 // let's write these out in S/N order 827 sources = psArraySort (sources, pmSourceSortBy SN);730 sources = psArraySort (sources, pmSourceSortByFlux); 828 731 829 732 table = psArrayAllocEmpty (sources->n); … … 832 735 for (int i = 0; i < sources->n; i++) { 833 736 834 pmSource *source = sources->data[i]; 737 // this is the source associated with this image 738 pmSource *thisSource = sources->data[i]; 739 740 // this is the "real" version of this source 741 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 835 742 836 743 // skip sources without radial aper measurements (or insufficient) 837 if (source->radialAper == NULL) continue; 838 psAssert (source->radialAper->n == fwhmValues->n, "inconsistent radial aperture set"); 839 840 for (int entry = 0; entry < fwhmValues->n; entry++) { 744 if (source->radialAper == NULL) continue; 745 746 // psAssert (source->radialAper->n == fwhmValues->n, "inconsistent radial aperture set"); 747 748 for (int entry = 0; entry < source->radialAper->n; entry++) { 841 749 842 750 // choose the convolved EXT model, if available, otherwise the simple one … … 844 752 assert (radialAper); 845 753 846 bool useMoments = true; 847 useMoments = (useMoments && source->moments); // can't if there are no moments 848 useMoments = (useMoments && source->moments->nPixels); // can't if the moments were not measured 849 useMoments = (useMoments && !(source->mode && PM_SOURCE_MODE_MOMENTS_FAILURE)); // can't if the moments failed... 850 851 if (useMoments) { 754 if (pmSourcePositionUseMoments(source)) { 852 755 xPos = source->moments->Mx; 853 756 yPos = source->moments->My; … … 863 766 psMetadataAddF32 (row, PS_LIST_TAIL, "X_APER", 0, "Center of aperture measurements", xPos); 864 767 psMetadataAddF32 (row, PS_LIST_TAIL, "Y_APER", 0, "Center of aperture measurements", yPos); 865 psMetadataAddF32 (row, PS_LIST_TAIL, "PSF_FWHM", 0, "FWHM of matched PSF", fwhmValues->data.F32[entry]); 768 if (fwhmValues) { 769 psMetadataAddF32 (row, PS_LIST_TAIL, "PSF_FWHM", 0, "FWHM of matched PSF", fwhmValues->data.F32[entry]); 770 } else { 771 psMetadataAddF32 (row, PS_LIST_TAIL, "PSF_FWHM", 0, "image is not FWHM-matched", NAN); 772 } 866 773 867 774 // XXX if we have raw radial apertures, write them out here 868 psVector *radFlux = psVectorAlloc(radMax->n, PS_TYPE_F32); 869 psVector *radFluxErr = psVectorAlloc(radMax->n, PS_TYPE_F32); 870 psVector *radFill = psVectorAlloc(radMax->n, PS_TYPE_F32); 775 psVector *radFlux = psVectorAlloc(radMax->n, PS_TYPE_F32); 776 psVector *radFluxErr = psVectorAlloc(radMax->n, PS_TYPE_F32); 777 psVector *radFill = psVectorAlloc(radMax->n, PS_TYPE_F32); 778 psVector *radFluxStdev = psVectorAlloc(radMax->n, PS_TYPE_F32); 871 779 psVectorInit (radFlux, NAN); 872 780 psVectorInit (radFluxErr, NAN); … … 879 787 // copy the data from fluxVal (which is not guaranteed to be the full length) to radFlux 880 788 for (int j = 0; j < radialAper->flux->n; j++) { 881 radFlux->data.F32[j] = radialAper->flux->data.F32[j]; 882 radFluxErr->data.F32[j] = radialAper->fluxErr->data.F32[j]; 883 radFill->data.F32[j] = radialAper->fill->data.F32[j]; 789 radFlux->data.F32[j] = radialAper->flux->data.F32[j]; 790 radFluxErr->data.F32[j] = radialAper->fluxErr->data.F32[j]; 791 radFluxStdev->data.F32[j] = radialAper->fluxStdev->data.F32[j]; 792 radFill->data.F32[j] = radialAper->fill->data.F32[j]; 884 793 } 885 794 886 795 write_annuli: 887 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX", PS_DATA_VECTOR, "flux within annuli", radFlux); 888 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX_ERR", PS_DATA_VECTOR, "flux error in annuli", radFluxErr); 889 psMetadataAdd (row, PS_LIST_TAIL, "APER_FILL", PS_DATA_VECTOR, "fill factor of annuli", radFill); 796 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX", PS_DATA_VECTOR, "flux within annuli", radFlux); 797 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX_ERR", PS_DATA_VECTOR, "flux error in annuli", radFluxErr); 798 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX_STDEV", PS_DATA_VECTOR, "flux standard deviation", radFluxStdev); 799 psMetadataAdd (row, PS_LIST_TAIL, "APER_FILL", PS_DATA_VECTOR, "fill factor of annuli", radFill); 890 800 psFree (radFlux); 891 801 psFree (radFluxErr); 802 psFree (radFluxStdev); 892 803 psFree (radFill); 893 804 -
trunk/psModules/src/objects/pmSourceIO_CMF_PS1_V1.c
r30621 r31153 49 49 50 50 #include "pmSourceIO.h" 51 #include "pmSourceOutputs.h" 51 52 52 53 // panstarrs-style FITS table output (header + table in 1st extension) … … 62 63 psArray *table; 63 64 psMetadata *row; 64 int i;65 psF32 *PAR, *dPAR;66 psEllipseAxes axes;67 psF32 xPos, yPos;68 psF32 xErr, yErr;69 psF32 errMag, chisq, apRadius;70 psS32 nPix, nDOF;71 65 72 66 pmChip *chip = readout->parent->parent; 73 pmFPA *fpa = chip->parent;74 75 bool status1 = false;76 bool status2 = false;77 float magOffset = NAN;78 float exptime = psMetadataLookupF32 (&status1, fpa->concepts, "FPA.EXPOSURE");79 float zeropt = psMetadataLookupF32(&status2, fpa->concepts, "FPA.ZP");80 if (!isfinite(zeropt)) {81 zeropt = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");82 }83 if (status1 && status2 && (exptime > 0.0)) {84 magOffset = zeropt + 2.5*log10(exptime);85 }86 float zeroptErr = psMetadataLookupF32 (&status2, imageHeader, "ZPT_ERR");87 67 88 68 // if the sequence is defined, write these in seq order; otherwise … … 92 72 if (source->seq == -1) { 93 73 // let's write these out in S/N order 94 sources = psArraySort (sources, pmSourceSortBy SN);74 sources = psArraySort (sources, pmSourceSortByFlux); 95 75 } else { 96 76 sources = psArraySort (sources, pmSourceSortBySeq); … … 100 80 table = psArrayAllocEmpty (sources->n); 101 81 82 short nImageOverlap; 83 float magOffset; 84 float zeroptErr; 85 float fwhmMajor; 86 float fwhmMinor; 87 pmSourceOutputsCommonValues (&nImageOverlap, &magOffset, &zeroptErr, &fwhmMajor, &fwhmMinor, readout, imageHeader); 88 102 89 // we write out PSF-fits for all sources, regardless of quality. the source flags tell us the state 103 90 // by the time we call this function, all values should be assigned. let's use asserts to be sure in some cases. 104 for (i = 0; i < sources->n; i++) {91 for (int i = 0; i < sources->n; i++) { 105 92 pmSource *source = (pmSource *) sources->data[i]; 106 93 … … 113 100 } 114 101 115 // no difference between PSF and non-PSF model 116 pmModel *model = source->modelPSF; 117 118 if (model != NULL) { 119 PAR = model->params->data.F32; 120 dPAR = model->dparams->data.F32; 121 xPos = PAR[PM_PAR_XPOS]; 122 yPos = PAR[PM_PAR_YPOS]; 123 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) { 124 xErr = dPAR[PM_PAR_XPOS]; 125 yErr = dPAR[PM_PAR_YPOS]; 126 } else { 127 // in linear-fit mode, there is no error on the centroid 128 xErr = source->peak->dx; 129 yErr = source->peak->dy; 130 } 131 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 132 axes = pmPSF_ModelToAxes (PAR, 20.0); 133 } else { 134 axes.major = NAN; 135 axes.minor = NAN; 136 axes.theta = NAN; 137 } 138 chisq = model->chisq; 139 nDOF = model->nDOF; 140 nPix = model->nPix; 141 apRadius = source->apRadius; 142 errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0]; 143 } else { 144 xPos = source->peak->xf; 145 yPos = source->peak->yf; 146 xErr = source->peak->dx; 147 yErr = source->peak->dy; 148 axes.major = NAN; 149 axes.minor = NAN; 150 axes.theta = NAN; 151 chisq = NAN; 152 nDOF = 0; 153 nPix = 0; 154 apRadius = NAN; 155 errMag = NAN; 156 } 157 158 float calMag = isfinite(magOffset) ? source->psfMag + magOffset : NAN; 159 float peakMag = (source->peak->flux > 0) ? -2.5*log10(source->peak->flux) : NAN; 160 psS16 nImageOverlap = 1; 161 162 psSphere ptSky = {0.0, 0.0, 0.0, 0.0}; 163 float posAngle = 0.0; 164 float pltScale = 0.0; 165 pmSourceLocalAstrometry (&ptSky, &posAngle, &pltScale, chip, xPos, yPos); 102 // set the 'best' values for various output fields: 103 pmSourceOutputs outputs; 104 pmSourceOutputsSetValues (&outputs, source, chip, fwhmMajor, fwhmMinor, magOffset); 105 106 pmSourceOutputsMoments moments; 107 pmSourceOutputsSetMoments (&moments, source); 166 108 167 109 row = psMetadataAlloc (); 168 110 psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET", PS_DATA_U32, "IPP detection identifier index", source->seq); 169 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", xPos);170 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", yPos);171 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", xErr); // XXX this is only measured for non-linear fits172 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", yErr); // XXX this is only measured for non-linear fits173 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F32, "PSF RA coordinate (degrees)", ptSky.r*PS_DEG_RAD);174 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F32, "PSF DEC coordinate (degrees)", ptSky.d*PS_DEG_RAD);175 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", posAngle*PS_DEG_RAD);176 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", pltScale*PS_DEG_RAD*3600.0);111 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", outputs.xPos); 112 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", outputs.yPos); 113 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", outputs.xErr); // XXX this is only measured for non-linear fits 114 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", outputs.yErr); // XXX this is only measured for non-linear fits 115 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F32, "PSF RA coordinate (degrees)", outputs.ra); 116 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F32, "PSF DEC coordinate (degrees)", outputs.dec); 117 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", outputs.posAngle); 118 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", outputs.pltScale); 177 119 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG", PS_DATA_F32, "PSF fit instrumental magnitude", source->psfMag); 178 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", errMag);120 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", source->errMag); 179 121 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG", PS_DATA_F32, "magnitude in standard aperture", source->apMag); 180 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", apRadius);181 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", peakMag);182 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", calMag);122 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", outputs.apRadius); 123 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", outputs.peakMag); 124 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", outputs.calMag); 183 125 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG_SIG", PS_DATA_F32, "measured scatter of zero point calibration", zeroptErr); 184 126 psMetadataAdd (row, PS_LIST_TAIL, "SKY", PS_DATA_F32, "Sky level", source->sky); 185 127 psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA", PS_DATA_F32, "Sigma of sky level", source->skyErr); 186 128 187 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", chisq);129 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", outputs.chisq); 188 130 psMetadataAdd (row, PS_LIST_TAIL, "CR_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to CF", source->crNsigma); 189 131 psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to EXT", source->extNsigma); 190 132 191 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", axes.major);192 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", axes.minor);193 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", axes.theta);133 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", outputs.psfMajor); 134 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", outputs.psfMinor); 135 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", outputs.psfTheta); 194 136 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF", PS_DATA_F32, "PSF coverage/quality factor", source->pixWeightNotBad); 195 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", nDOF); 196 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", nPix); 197 198 // distinguish moments measure from window vs S/N > XX ?? 199 float mxx = source->moments ? source->moments->Mxx : NAN; 200 float mxy = source->moments ? source->moments->Mxy : NAN; 201 float myy = source->moments ? source->moments->Myy : NAN; 202 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", mxx); 203 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", mxy); 204 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", myy); 137 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", outputs.nDOF); 138 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", outputs.nPix); 139 140 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", moments.Mxx); 141 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", moments.Mxy); 142 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", moments.Myy); 205 143 206 144 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS", PS_DATA_U32, "psphot analysis flags", source->mode); … … 317 255 // recreate the peak to match (xPos, yPos) +/- (xErr, yErr) 318 256 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 319 source->peak->flux = peakFlux; 257 source->peak->rawFlux = peakFlux; 258 source->peak->smoothFlux = peakFlux; 320 259 source->peak->xf = PAR[PM_PAR_XPOS]; // more accurate position 321 260 source->peak->yf = PAR[PM_PAR_YPOS]; // more accurate position 322 261 source->peak->dx = dPAR[PM_PAR_XPOS]; 323 262 source->peak->dy = dPAR[PM_PAR_YPOS]; 324 if (isfinite (source->errMag) && (source->errMag > 0.0)) {325 source->peak->SN = 1.0 / source->errMag;326 } else {327 source->peak->SN = sqrt(source->peak->flux); // an alternate proxy: various functions sort by peak S/N328 }329 263 330 264 source->pixWeightNotBad = psMetadataLookupF32 (&status, row, "PSF_QF"); … … 339 273 340 274 source->moments = pmMomentsAlloc (); 275 source->moments->Mx = source->peak->xf; // we don't have both Mx,My and xf,yf in the cmf 276 source->moments->My = source->peak->yf; // we don't have both Mx,My and xf,yf in the cmf 277 341 278 source->moments->Mxx = psMetadataLookupF32 (&status, row, "MOMENTS_XX"); 342 279 source->moments->Mxy = psMetadataLookupF32 (&status, row, "MOMENTS_XY"); … … 371 308 372 309 // let's write these out in S/N order 373 sources = psArraySort (sources, pmSourceSortBy SN);310 sources = psArraySort (sources, pmSourceSortByFlux); 374 311 375 312 table = psArrayAllocEmpty (sources->n); … … 549 486 550 487 // let's write these out in S/N order 551 sources = psArraySort (sources, pmSourceSortBy SN);488 sources = psArraySort (sources, pmSourceSortByFlux); 552 489 553 490 // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams -
trunk/psModules/src/objects/pmSourceIO_CMF_PS1_V2.c
r30621 r31153 49 49 50 50 #include "pmSourceIO.h" 51 #include "pmSourceOutputs.h" 51 52 52 53 // panstarrs-style FITS table output (header + table in 1st extension) … … 62 63 psArray *table; 63 64 psMetadata *row; 64 psF32 *PAR, *dPAR;65 psEllipseAxes axes;66 psF32 xPos, yPos;67 psF32 xErr, yErr;68 psF32 errMag, chisq, apRadius;69 psS32 nPix, nDOF;70 65 71 66 pmChip *chip = readout->parent->parent; 72 pmFPA *fpa = chip->parent;73 74 bool status1 = false;75 bool status2 = false;76 float magOffset = NAN;77 float exptime = psMetadataLookupF32 (&status1, fpa->concepts, "FPA.EXPOSURE");78 float zeropt = psMetadataLookupF32(&status2, fpa->concepts, "FPA.ZP");79 if (!isfinite(zeropt)) {80 zeropt = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");81 }82 if (status1 && status2 && (exptime > 0.0)) {83 magOffset = zeropt + 2.5*log10(exptime);84 }85 float zeroptErr = psMetadataLookupF32 (&status2, imageHeader, "ZPT_ERR");86 67 87 68 // if the sequence is defined, write these in seq order; otherwise … … 91 72 if (source->seq == -1) { 92 73 // let's write these out in S/N order 93 sources = psArraySort (sources, pmSourceSortBy SN);74 sources = psArraySort (sources, pmSourceSortByFlux); 94 75 } else { 95 76 sources = psArraySort (sources, pmSourceSortBySeq); … … 98 79 99 80 table = psArrayAllocEmpty (sources->n); 81 82 short nImageOverlap; 83 float magOffset; 84 float zeroptErr; 85 float fwhmMajor; 86 float fwhmMinor; 87 pmSourceOutputsCommonValues (&nImageOverlap, &magOffset, &zeroptErr, &fwhmMajor, &fwhmMinor, readout, imageHeader); 100 88 101 89 // we write out PSF-fits for all sources, regardless of quality. the source flags tell us the state … … 112 100 } 113 101 114 // no difference between PSF and non-PSF model 115 pmModel *model = source->modelPSF; 116 117 if (model != NULL) { 118 PAR = model->params->data.F32; 119 dPAR = model->dparams->data.F32; 120 xPos = PAR[PM_PAR_XPOS]; 121 yPos = PAR[PM_PAR_YPOS]; 122 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) { 123 xErr = dPAR[PM_PAR_XPOS]; 124 yErr = dPAR[PM_PAR_YPOS]; 125 } else { 126 // in linear-fit mode, there is no error on the centroid 127 xErr = source->peak->dx; 128 yErr = source->peak->dy; 129 } 130 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 131 axes = pmPSF_ModelToAxes (PAR, 20.0); 132 } else { 133 axes.major = NAN; 134 axes.minor = NAN; 135 axes.theta = NAN; 136 } 137 chisq = model->chisq; 138 nDOF = model->nDOF; 139 nPix = model->nPix; 140 apRadius = source->apRadius; 141 errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0]; 142 } else { 143 xPos = source->peak->xf; 144 yPos = source->peak->yf; 145 xErr = source->peak->dx; 146 yErr = source->peak->dy; 147 axes.major = NAN; 148 axes.minor = NAN; 149 axes.theta = NAN; 150 chisq = NAN; 151 nDOF = 0; 152 nPix = 0; 153 apRadius = NAN; 154 errMag = NAN; 155 } 156 157 float calMag = isfinite(magOffset) ? source->psfMag + magOffset : NAN; 158 float peakMag = (source->peak->flux > 0) ? -2.5*log10(source->peak->flux) : NAN; 159 psS16 nImageOverlap = 1; 160 161 psSphere ptSky = {0.0, 0.0, 0.0, 0.0}; 162 float posAngle = 0.0; 163 float pltScale = 0.0; 164 pmSourceLocalAstrometry (&ptSky, &posAngle, &pltScale, chip, xPos, yPos); 102 // set the 'best' values for various output fields: 103 pmSourceOutputs outputs; 104 pmSourceOutputsSetValues (&outputs, source, chip, fwhmMajor, fwhmMinor, magOffset); 105 106 pmSourceOutputsMoments moments; 107 pmSourceOutputsSetMoments (&moments, source); 165 108 166 109 row = psMetadataAlloc (); 167 110 psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET", PS_DATA_U32, "IPP detection identifier index", source->seq); 168 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", xPos);169 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", yPos);170 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", xErr); // XXX this is only measured for non-linear fits171 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", yErr); // XXX this is only measured for non-linear fits172 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", posAngle*PS_DEG_RAD);173 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", pltScale*PS_DEG_RAD*3600.0);111 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", outputs.xPos); 112 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", outputs.yPos); 113 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", outputs.xErr); // XXX this is only measured for non-linear fits 114 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", outputs.yErr); // XXX this is only measured for non-linear fits 115 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", outputs.posAngle); 116 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", outputs.pltScale); 174 117 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG", PS_DATA_F32, "PSF fit instrumental magnitude", source->psfMag); 175 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", errMag);118 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", source->errMag); 176 119 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG", PS_DATA_F32, "magnitude in standard aperture", source->apMag); 177 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", apRadius);178 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", peakMag);179 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", calMag);120 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", outputs.apRadius); 121 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", outputs.peakMag); 122 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", outputs.calMag); 180 123 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG_SIG", PS_DATA_F32, "measured scatter of zero point calibration", zeroptErr); 181 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", ptSky.r*PS_DEG_RAD);182 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", ptSky.d*PS_DEG_RAD);124 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", outputs.ra); 125 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", outputs.dec); 183 126 psMetadataAdd (row, PS_LIST_TAIL, "SKY", PS_DATA_F32, "Sky level", source->sky); 184 127 psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA", PS_DATA_F32, "Sigma of sky level", source->skyErr); 185 128 186 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", chisq);129 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", outputs.chisq); 187 130 psMetadataAdd (row, PS_LIST_TAIL, "CR_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to CF", source->crNsigma); 188 131 psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to EXT", source->extNsigma); 189 132 190 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", axes.major);191 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", axes.minor);192 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", axes.theta);133 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", outputs.psfMajor); 134 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", outputs.psfMinor); 135 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", outputs.psfTheta); 193 136 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF", PS_DATA_F32, "PSF coverage/quality factor", source->pixWeightNotBad); 194 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", nDOF); 195 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", nPix); 196 197 // distinguish moments measure from window vs S/N > XX ?? 198 float mxx = source->moments ? source->moments->Mxx : NAN; 199 float mxy = source->moments ? source->moments->Mxy : NAN; 200 float myy = source->moments ? source->moments->Myy : NAN; 201 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", mxx); 202 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", mxy); 203 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", myy); 137 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", outputs.nDOF); 138 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", outputs.nPix); 139 140 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", moments.Mxx); 141 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", moments.Mxy); 142 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", moments.Myy); 204 143 205 144 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS", PS_DATA_U32, "psphot analysis flags", source->mode); … … 322 261 // recreate the peak to match (xPos, yPos) +/- (xErr, yErr) 323 262 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 324 source->peak->flux = peakFlux; 263 source->peak->rawFlux = peakFlux; 264 source->peak->smoothFlux = peakFlux; 325 265 source->peak->xf = PAR[PM_PAR_XPOS]; // more accurate position 326 266 source->peak->yf = PAR[PM_PAR_YPOS]; // more accurate position 327 267 source->peak->dx = dPAR[PM_PAR_XPOS]; 328 268 source->peak->dy = dPAR[PM_PAR_YPOS]; 329 if (isfinite (source->errMag) && (source->errMag > 0.0)) {330 source->peak->SN = 1.0 / source->errMag;331 } else {332 source->peak->SN = sqrt(source->peak->flux); // an alternate proxy: various functions sort by peak S/N333 }334 269 335 270 source->pixWeightNotBad = psMetadataLookupF32 (&status, row, "PSF_QF"); … … 344 279 345 280 source->moments = pmMomentsAlloc (); 281 source->moments->Mx = source->peak->xf; // we don't have both Mx,My and xf,yf in the cmf 282 source->moments->My = source->peak->yf; // we don't have both Mx,My and xf,yf in the cmf 283 346 284 source->moments->Mxx = psMetadataLookupF32 (&status, row, "MOMENTS_XX"); 347 285 source->moments->Mxy = psMetadataLookupF32 (&status, row, "MOMENTS_XY"); … … 392 330 393 331 // let's write these out in S/N order 394 sources = psArraySort (sources, pmSourceSortBy SN);332 sources = psArraySort (sources, pmSourceSortByFlux); 395 333 396 334 table = psArrayAllocEmpty (sources->n); … … 611 549 612 550 // let's write these out in S/N order 613 sources = psArraySort (sources, pmSourceSortBy SN);551 sources = psArraySort (sources, pmSourceSortByFlux); 614 552 615 553 // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams -
trunk/psModules/src/objects/pmSourceIO_CMF_PS1_V3.c
r30621 r31153 49 49 50 50 #include "pmSourceIO.h" 51 #include "pmSourceOutputs.h" 51 52 52 53 // panstarrs-style FITS table output (header + table in 1st extension) … … 62 63 psArray *table; 63 64 psMetadata *row; 64 psF32 *PAR, *dPAR;65 psEllipseAxes axes;66 psF32 xPos, yPos;67 psF32 xErr, yErr;68 psF32 chisq, apRadius;69 psS32 nPix, nDOF;70 65 71 66 pmChip *chip = readout->parent->parent; 72 pmFPA *fpa = chip->parent;73 74 bool status1 = false;75 bool status2 = false;76 float magOffset = NAN;77 float exptime = psMetadataLookupF32 (&status1, fpa->concepts, "FPA.EXPOSURE");78 float zeropt = psMetadataLookupF32(&status2, fpa->concepts, "FPA.ZP");79 if (!isfinite(zeropt)) {80 zeropt = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");81 }82 if (status1 && status2 && (exptime > 0.0)) {83 magOffset = zeropt + 2.5*log10(exptime);84 }85 float zeroptErr = psMetadataLookupF32 (&status2, imageHeader, "ZPT_ERR");86 87 // we need a measure of the image quality (FWHM) for this image, in order to get the positional errors88 float fwhmMajor = psMetadataLookupF32(&status1, readout->analysis, "FWHM_MAJ");89 if (!status1) {90 fwhmMajor = psMetadataLookupF32(&status1, readout->analysis, "IQ_FW1");91 if (!status1) {92 fwhmMajor = 5.0; // XXX just a guess!93 }94 }95 float fwhmMinor = psMetadataLookupF32(&status1, readout->analysis, "FWHM_MIN");96 if (!status1) {97 fwhmMinor = psMetadataLookupF32(&status1, readout->analysis, "IQ_FW2");98 if (!status1) {99 fwhmMinor = 5.0; // XXX just a guess!100 }101 }102 67 103 68 // if the sequence is defined, write these in seq order; otherwise … … 107 72 if (source->seq == -1) { 108 73 // let's write these out in S/N order 109 sources = psArraySort (sources, pmSourceSortBy SN);74 sources = psArraySort (sources, pmSourceSortByFlux); 110 75 } else { 111 76 sources = psArraySort (sources, pmSourceSortBySeq); … … 114 79 115 80 table = psArrayAllocEmpty (sources->n); 81 82 short nImageOverlap; 83 float magOffset; 84 float zeroptErr; 85 float fwhmMajor; 86 float fwhmMinor; 87 pmSourceOutputsCommonValues (&nImageOverlap, &magOffset, &zeroptErr, &fwhmMajor, &fwhmMinor, readout, imageHeader); 116 88 117 89 // we write out PSF-fits for all sources, regardless of quality. the source flags tell us the state … … 128 100 } 129 101 130 // no difference between PSF and non-PSF model 131 pmModel *model = source->modelPSF; 132 133 if (model != NULL) { 134 PAR = model->params->data.F32; 135 dPAR = model->dparams->data.F32; 136 xPos = PAR[PM_PAR_XPOS]; 137 yPos = PAR[PM_PAR_YPOS]; 138 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) { 139 xErr = dPAR[PM_PAR_XPOS]; 140 yErr = dPAR[PM_PAR_YPOS]; 141 } else { 142 xErr = fwhmMajor * source->errMag / 2.35; 143 yErr = fwhmMinor * source->errMag / 2.35; 144 } 145 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 146 axes = pmPSF_ModelToAxes (PAR, 20.0); 147 } else { 148 axes.major = NAN; 149 axes.minor = NAN; 150 axes.theta = NAN; 151 } 152 chisq = model->chisq; 153 nDOF = model->nDOF; 154 nPix = model->nPix; 155 apRadius = source->apRadius; 156 } else { 157 bool useMoments = true; 158 useMoments = (useMoments && source->moments); // can't if there are no moments 159 useMoments = (useMoments && source->moments->nPixels); // can't if the moments were not measured 160 useMoments = (useMoments && !(source->mode && PM_SOURCE_MODE_MOMENTS_FAILURE)); // can't if the moments failed... 161 162 if (useMoments) { 163 xPos = source->moments->Mx; 164 yPos = source->moments->My; 165 xErr = fwhmMajor * source->errMag / 2.35; 166 yErr = fwhmMinor * source->errMag / 2.35; 167 } else { 168 xPos = source->peak->xf; 169 yPos = source->peak->yf; 170 xErr = source->peak->dx; 171 yErr = source->peak->dy; 172 } 173 axes.major = NAN; 174 axes.minor = NAN; 175 axes.theta = NAN; 176 chisq = NAN; 177 nDOF = 0; 178 nPix = 0; 179 apRadius = NAN; 180 } 181 182 float calMag = isfinite(magOffset) ? source->psfMag + magOffset : NAN; 183 float peakMag = (source->peak->flux > 0) ? -2.5*log10(source->peak->flux) : NAN; 184 psS16 nImageOverlap = 1; 185 186 psSphere ptSky = {0.0, 0.0, 0.0, 0.0}; 187 float posAngle = 0.0; 188 float pltScale = 0.0; 189 pmSourceLocalAstrometry (&ptSky, &posAngle, &pltScale, chip, xPos, yPos); 102 // set the 'best' values for various output fields: 103 pmSourceOutputs outputs; 104 pmSourceOutputsSetValues (&outputs, source, chip, fwhmMajor, fwhmMinor, magOffset); 105 106 pmSourceOutputsMoments moments; 107 pmSourceOutputsSetMoments (&moments, source); 190 108 191 109 row = psMetadataAlloc (); 192 110 psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET", PS_DATA_U32, "IPP detection identifier index", source->seq); 193 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", xPos);194 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", yPos);195 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", xErr);196 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", yErr);197 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", posAngle*PS_DEG_RAD);198 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", pltScale*PS_DEG_RAD*3600.0);111 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", outputs.xPos); 112 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", outputs.yPos); 113 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", outputs.xErr); 114 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", outputs.yErr); 115 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", outputs.posAngle); 116 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", outputs.pltScale); 199 117 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG", PS_DATA_F32, "PSF fit instrumental magnitude", source->psfMag); 200 118 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", source->errMag); … … 203 121 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG", PS_DATA_F32, "magnitude in standard aperture", source->apMag); 204 122 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RAW", PS_DATA_F32, "magnitude in reported aperture", source->apMagRaw); 205 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", apRadius);206 207 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", calMag);123 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", outputs.apRadius); 124 125 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", outputs.calMag); 208 126 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG_SIG", PS_DATA_F32, "measured scatter of zero point calibration", zeroptErr); 209 127 210 128 // NOTE: RA & DEC (both double) need to be on an 8-byte boundary... 211 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", ptSky.r*PS_DEG_RAD);212 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", ptSky.d*PS_DEG_RAD);213 214 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", peakMag);129 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", outputs.ra); 130 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", outputs.dec); 131 132 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", outputs.peakMag); 215 133 psMetadataAdd (row, PS_LIST_TAIL, "SKY", PS_DATA_F32, "Sky level", source->sky); 216 134 psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA", PS_DATA_F32, "Sigma of sky level", source->skyErr); 217 135 218 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", chisq);136 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", outputs.chisq); 219 137 psMetadataAdd (row, PS_LIST_TAIL, "CR_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to CF", source->crNsigma); 220 138 psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to EXT", source->extNsigma); 221 139 222 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", axes.major);223 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", axes.minor);224 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", axes.theta);140 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", outputs.psfMajor); 141 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", outputs.psfMinor); 142 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", outputs.psfTheta); 225 143 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF", PS_DATA_F32, "PSF coverage/quality factor (bad)", source->pixWeightNotBad); 226 144 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF_PERFECT", PS_DATA_F32, "PSF coverage/quality factor (poor)", source->pixWeightNotPoor); 227 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", nDOF); 228 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", nPix); 229 230 // distinguish moments measure from window vs S/N > XX ?? 231 float Mxx = source->moments ? source->moments->Mxx : NAN; 232 float Mxy = source->moments ? source->moments->Mxy : NAN; 233 float Myy = source->moments ? source->moments->Myy : NAN; 234 235 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", Mxx); 236 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", Mxy); 237 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", Myy); 238 239 float M_c3 = source->moments ? 1.0*source->moments->Mxxx - 3.0*source->moments->Mxyy : NAN; 240 float M_s3 = source->moments ? 3.0*source->moments->Mxxy - 1.0*source->moments->Myyy : NAN; 241 float M_c4 = source->moments ? 1.0*source->moments->Mxxxx - 6.0*source->moments->Mxxyy + 1.0*source->moments->Myyyy : NAN; 242 float M_s4 = source->moments ? 4.0*source->moments->Mxxxy - 4.0*source->moments->Mxyyy : NAN; 243 244 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3C", PS_DATA_F32, "third momemt cos theta", M_c3); 245 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3S", PS_DATA_F32, "third momemt sin theta", M_s3); 246 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4C", PS_DATA_F32, "fourth momemt cos theta", M_c4); 247 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4S", PS_DATA_F32, "fourth momemt sin theta", M_s4); 248 249 float Mrf = source->moments ? source->moments->Mrf : NAN; 250 float Mrh = source->moments ? source->moments->Mrh : NAN; 251 float Krf = source->moments ? source->moments->KronFlux : NAN; 252 float dKrf = source->moments ? source->moments->KronFluxErr : NAN; 253 254 float Kinner = source->moments ? source->moments->KronFinner : NAN; 255 float Kouter = source->moments ? source->moments->KronFouter : NAN; 256 257 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", Mrf); 258 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", Mrh); 259 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", Krf); 260 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", dKrf); 261 262 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", Kinner); 263 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", Kouter); 264 265 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS", PS_DATA_U32, "psphot analysis flags", source->mode); 266 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS2", PS_DATA_U32, "psphot analysis flags", source->mode2); 145 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", outputs.nDOF); 146 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", outputs.nPix); 147 148 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", moments.Mxx); 149 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", moments.Mxy); 150 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", moments.Myy); 151 152 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3C", PS_DATA_F32, "third momemt cos theta", moments.M_c3); 153 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3S", PS_DATA_F32, "third momemt sin theta", moments.M_s3); 154 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4C", PS_DATA_F32, "fourth momemt cos theta", moments.M_c4); 155 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4S", PS_DATA_F32, "fourth momemt sin theta", moments.M_s4); 156 157 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", moments.Mrf); 158 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", moments.Mrh); 159 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Krf); 160 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", moments.dKrf); 161 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kinner); 162 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kouter); 163 // psMetadataAdd (row, PS_LIST_TAIL, "KRON_CORE_FLUX", PS_DATA_F32, "Kron Flux (in 1.0 R1)", moments.KronCore); 164 // psMetadataAdd (row, PS_LIST_TAIL, "KRON_CORE_ERROR", PS_DATA_F32, "Kron Error (in 1.0 R1)", moments.KronCoreErr); 165 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS", PS_DATA_U32, "psphot analysis flags", source->mode); 166 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS2", PS_DATA_U32, "psphot analysis flags", source->mode2); 267 167 psMetadataAdd (row, PS_LIST_TAIL, "PADDING2", PS_DATA_S32, "more padding", 0); 268 168 … … 384 284 // recreate the peak to match (xPos, yPos) +/- (xErr, yErr) 385 285 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 386 source->peak->flux = peakFlux; 286 source->peak->rawFlux = peakFlux; 287 source->peak->smoothFlux = peakFlux; 387 288 source->peak->xf = PAR[PM_PAR_XPOS]; // more accurate position 388 289 source->peak->yf = PAR[PM_PAR_YPOS]; // more accurate position 389 290 source->peak->dx = dPAR[PM_PAR_XPOS]; 390 291 source->peak->dy = dPAR[PM_PAR_YPOS]; 391 if (isfinite (source->errMag) && (source->errMag > 0.0)) { 392 source->peak->SN = 1.0 / source->errMag; 393 } else { 394 source->peak->SN = sqrt(source->peak->flux); // an alternate proxy: various functions sort by peak S/N 395 } 292 293 // we no longer sort by S/N, only flux 294 // if (isfinite (source->errMag) && (source->errMag > 0.0)) { 295 // source->peak->SN = 1.0 / source->errMag; 296 // } else { 297 // source->peak->SN = sqrt(source->peak->flux); // an alternate proxy: various functions sort by peak S/N 298 // } 396 299 397 300 source->pixWeightNotBad = psMetadataLookupF32 (&status, row, "PSF_QF"); … … 407 310 408 311 source->moments = pmMomentsAlloc (); 312 source->moments->Mx = source->peak->xf; // we don't have both Mx,My and xf,yf in the cmf 313 source->moments->My = source->peak->yf; // we don't have both Mx,My and xf,yf in the cmf 314 409 315 source->moments->Mxx = psMetadataLookupF32 (&status, row, "MOMENTS_XX"); 410 316 source->moments->Mxy = psMetadataLookupF32 (&status, row, "MOMENTS_XY"); … … 477 383 478 384 // let's write these out in S/N order 479 sources = psArraySort (sources, pmSourceSortBy SN);385 sources = psArraySort (sources, pmSourceSortByFlux); 480 386 481 387 table = psArrayAllocEmpty (sources->n); … … 649 555 650 556 // let's write these out in S/N order 651 sources = psArraySort (sources, pmSourceSortBy SN);557 sources = psArraySort (sources, pmSourceSortByFlux); 652 558 653 559 // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams -
trunk/psModules/src/objects/pmSourceIO_PS1_CAL_0.c
r30621 r31153 91 91 92 92 // let's write these out in S/N order 93 sources = psArraySort (sources, pmSourceSortBy SN);93 sources = psArraySort (sources, pmSourceSortByFlux); 94 94 95 95 table = psArrayAllocEmpty (sources->n); … … 136 136 137 137 float calMag = source->psfMag + magOffset; 138 float peakMag = (source->peak-> flux > 0) ? -2.5*log10(source->peak->flux) : NAN;138 float peakMag = (source->peak->rawFlux > 0) ? -2.5*log10(source->peak->rawFlux) : NAN; 139 139 psS16 nImageOverlap = 1; 140 140 … … 294 294 295 295 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 296 source->peak->flux = peakFlux; 296 source->peak->rawFlux = peakFlux; 297 source->peak->smoothFlux = peakFlux; 297 298 source->peak->dx = dPAR[PM_PAR_XPOS]; 298 299 source->peak->dy = dPAR[PM_PAR_YPOS]; … … 357 358 358 359 // let's write these out in S/N order 359 sources = psArraySort (sources, pmSourceSortBy SN);360 sources = psArraySort (sources, pmSourceSortByFlux); 360 361 361 362 table = psArrayAllocEmpty (sources->n); … … 576 577 577 578 // let's write these out in S/N order 578 sources = psArraySort (sources, pmSourceSortBy SN);579 sources = psArraySort (sources, pmSourceSortByFlux); 579 580 580 581 // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams -
trunk/psModules/src/objects/pmSourceIO_PS1_DEV_0.c
r30621 r31153 101 101 } 102 102 103 float peakMag = (source->peak-> flux > 0) ? -2.5*log10(source->peak->flux) : NAN;103 float peakMag = (source->peak->rawFlux > 0) ? -2.5*log10(source->peak->rawFlux) : NAN; 104 104 psS16 nImageOverlap = 1; 105 105 psS32 ID = 0; // XXX need to figure out how to generate this … … 220 220 221 221 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 222 source->peak->flux = peakFlux; 222 source->peak->rawFlux = peakFlux; 223 source->peak->smoothFlux = peakFlux; 223 224 source->peak->dx = dPAR[PM_PAR_XPOS]; 224 225 source->peak->dy = dPAR[PM_PAR_YPOS]; -
trunk/psModules/src/objects/pmSourceIO_PS1_DEV_1.c
r30621 r31153 73 73 74 74 // let's write these out in S/N order 75 sources = psArraySort (sources, pmSourceSortBy SN);75 sources = psArraySort (sources, pmSourceSortByFlux); 76 76 77 77 table = psArrayAllocEmpty (sources->n); … … 117 117 } 118 118 119 float peakMag = (source->peak-> flux > 0) ? -2.5*log10(source->peak->flux) : NAN;119 float peakMag = (source->peak->rawFlux > 0) ? -2.5*log10(source->peak->rawFlux) : NAN; 120 120 psS16 nImageOverlap = 1; 121 121 … … 263 263 264 264 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 265 source->peak->flux = peakFlux; 265 source->peak->rawFlux = peakFlux; 266 source->peak->smoothFlux = peakFlux; 266 267 source->peak->dx = dPAR[PM_PAR_XPOS]; 267 268 source->peak->dy = dPAR[PM_PAR_YPOS]; … … 307 308 308 309 // let's write these out in S/N order 309 sources = psArraySort (sources, pmSourceSortBy SN);310 sources = psArraySort (sources, pmSourceSortByFlux); 310 311 311 312 table = psArrayAllocEmpty (sources->n); … … 480 481 481 482 // let's write these out in S/N order 482 sources = psArraySort (sources, pmSourceSortBy SN);483 sources = psArraySort (sources, pmSourceSortByFlux); 483 484 484 485 // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams -
trunk/psModules/src/objects/pmSourceIO_RAW.c
r29004 r31153 126 126 source[0].apMag, source[0].type, source[0].mode, 127 127 logChi, logChiNorm, 128 source[0].peak-> SN,128 source[0].peak->rawFlux, 129 129 source[0].apRadius, 130 130 source[0].pixWeightNotBad, … … 188 188 log10(model[0].chisq/model[0].nDOF), 189 189 log10(model[0].chisqNorm/model[0].nDOF), 190 source[0].peak-> SN,190 source[0].peak->rawFlux, 191 191 source[0].apRadius, 192 192 source[0].pixWeightNotBad, … … 234 234 235 235 fprintf (f, "%5d %5d %7.1f %7.1f %7.1f %6.3f %6.3f %8.1f %7.1f %7.1f %7.1f %4d %2d\n", 236 source->peak->x, source->peak->y, source->peak-> value,236 source->peak->x, source->peak->y, source->peak->detValue, 237 237 moment->Mx, moment->My, 238 238 moment->Mxx, moment->Myy, … … 270 270 continue; 271 271 fprintf (f, "%5d %5d %8.1f %7.1f %7.1f %6.3f %6.3f %10.1f %7.1f %7.1f %7.1f %4d %2d %#5x\n", 272 source->peak->x, source->peak->y, source->peak-> value,272 source->peak->x, source->peak->y, source->peak->detValue, 273 273 source->moments->Mx, source->moments->My, 274 274 source->moments->Mxx, source->moments->Myy, … … 299 299 continue; 300 300 fprintf (f, "%5d %5d %7.1f %7.2f %7.2f %7.2f\n", 301 peak->x, peak->y, peak-> value, peak->SN, peak->xf, peak->yf);302 } 303 fclose (f); 304 return true; 305 } 306 301 peak->x, peak->y, peak->detValue, peak->rawFlux, peak->xf, peak->yf); 302 } 303 fclose (f); 304 return true; 305 } 306 -
trunk/psModules/src/objects/pmSourceIO_SMPDATA.c
r30621 r31153 205 205 206 206 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 207 source->peak->flux = peakFlux;208 207 209 208 sources->data[i] = source; -
trunk/psModules/src/objects/pmSourceMasks.h
r29546 r31153 46 46 PM_SOURCE_MODE2_DIFF_WITH_DOUBLE = 0x00000002, ///< diff source matched to positive detections in both images 47 47 PM_SOURCE_MODE2_MATCHED = 0x00000004, ///< diff source matched to positive detections in both images 48 49 PM_SOURCE_MODE2_ON_SPIKE = 0x00000008, ///< > 25% of (PSF-weighted) pixels land on diffraction spike 50 PM_SOURCE_MODE2_ON_STARCORE = 0x00000010, ///< > 25% of (PSF-weighted) pixels land on starcore 51 PM_SOURCE_MODE2_ON_BURNTOOL = 0x00000020, ///< > 25% of (PSF-weighted) pixels land on burntool 52 PM_SOURCE_MODE2_ON_CONVPOOR = 0x00000040, ///< > 25% of (PSF-weighted) pixels land on convpoor 48 53 } pmSourceMode2; 49 54 -
trunk/psModules/src/objects/pmSourceMoments.c
r29602 r31153 82 82 psF32 Sum = 0.0; 83 83 psF32 Var = 0.0; 84 psF32 SumCore = 0.0; 85 psF32 VarCore = 0.0; 84 86 psF32 R2 = PS_SQR(radius); 85 87 psF32 minSN2 = PS_SQR(minSN); … … 248 250 249 251 int nKronPix = 0; 252 int nCorePix = 0; 253 int nInner = 0; 254 int nOuter = 0; 250 255 Sum = Var = 0.0; 251 256 float SumInner = 0.0; … … 255 260 256 261 psF32 yDiff = row - yCM; 257 if (fabs(yDiff) > radK ron) continue;262 if (fabs(yDiff) > radKouter) continue; 258 263 259 264 psF32 *vPix = source->pixels->data.F32[row]; … … 272 277 273 278 psF32 xDiff = col - xCM; 274 if (fabs(xDiff) > radK ron) continue;279 if (fabs(xDiff) > radKouter) continue; 275 280 276 281 // radKron is just a function of (xDiff, yDiff) … … 293 298 } 294 299 300 // use sigma (fixed by psf) not a radKron based value 301 if (r < sigma) { 302 SumCore += pDiff; 303 VarCore += wDiff; 304 nCorePix ++; 305 } 306 295 307 if ((r > radKinner) && (r < radKron)) { 296 308 SumInner += pDiff; 309 nInner ++; 297 310 } 298 311 if ((r > radKron) && (r < radKouter)) { 299 312 SumOuter += pDiff; 313 nOuter ++; 300 314 } 301 315 } 302 316 } 303 source->moments->KronFlux = Sum; 304 source->moments->KronFinner = SumInner; 305 source->moments->KronFouter = SumOuter; 306 source->moments->KronFluxErr = sqrt(Var); 317 // *** should I rescale these fluxes by pi R^2 / nNpix? 318 source->moments->KronCore = SumCore * M_PI * PS_SQR(sigma) / nCorePix; 319 source->moments->KronCoreErr = sqrt(VarCore) * M_PI * PS_SQR(sigma) / nCorePix; 320 source->moments->KronFlux = Sum * M_PI * PS_SQR(radKron) / nKronPix; 321 source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix; 322 source->moments->KronFinner = SumInner * M_PI * (PS_SQR(radKron) - PS_SQR(radKinner)) / nInner; 323 source->moments->KronFouter = SumOuter * M_PI * (PS_SQR(radKouter) - PS_SQR(radKron)) / nOuter; 307 324 308 325 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", … … 313 330 314 331 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", 315 source->peak->xf, source->peak->yf, source->peak-> flux, source->peak->SN, source->moments->Mx, source->moments->My, Sum, source->moments->Mxx, source->moments->Mxy, source->moments->Myy, sky, source->moments->nPixels);332 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); 316 333 317 334 return(true); -
trunk/psModules/src/objects/pmSourcePhotometry.c
r29935 r31153 23 23 #include "pmFPAMaskWeight.h" 24 24 25 #include "pmConfigMask.h" 25 26 #include "pmTrend2D.h" 26 27 #include "pmResiduals.h" … … 49 50 static float AP_MIN_SN = 0.0; 50 51 51 bool pmSourceMagnitudesInit (psMetadata *config) 52 { 53 PS_ASSERT_PTR_NON_NULL(config, false); 52 // make this a bit more clever and dynamic 53 static psImageMaskType maskSuspect = 0; 54 static psImageMaskType maskSpike = 0; 55 static psImageMaskType maskStarCore = 0; 56 static psImageMaskType maskBurntool = 0; 57 static psImageMaskType maskConvPoor = 0; 58 59 bool pmSourceMagnitudesInit (pmConfig *config, psMetadata *recipe) 60 { 61 PS_ASSERT_PTR_NON_NULL(recipe, false); 54 62 bool status; 55 63 56 float limit = psMetadataLookupF32 (&status, config, "AP_MIN_SN"); 64 // we are going to test specially against these poor values 65 if (config) { 66 maskSpike = pmConfigMaskGet("SPIKE", config); 67 maskStarCore = pmConfigMaskGet("STARCORE", config); 68 maskBurntool = pmConfigMaskGet("BURNTOOL", config); 69 maskConvPoor = pmConfigMaskGet("CONV.POOR", config); 70 maskSuspect = maskSpike | maskStarCore | maskBurntool | maskConvPoor; 71 } 72 73 float limit = psMetadataLookupF32 (&status, recipe, "AP_MIN_SN"); 57 74 if (status) { 58 75 AP_MIN_SN = limit; … … 77 94 // XXX masked region should be (optionally) elliptical 78 95 // if mode is PM_SOURCE_PHOT_PSFONLY, we skip all other magnitudes 79 bool pmSourceMagnitudes (pmSource *source, pmPSF *psf, pmSourcePhotometryMode mode, psImageMaskType maskVal, psImageMaskType markVal )96 bool pmSourceMagnitudes (pmSource *source, pmPSF *psf, pmSourcePhotometryMode mode, psImageMaskType maskVal, psImageMaskType markVal, float radius) 80 97 { 81 98 PS_ASSERT_PTR_NON_NULL(source, false); … … 166 183 // measure the contribution of included pixels 167 184 if (mode & PM_SOURCE_PHOT_WEIGHT) { 168 pmSourcePixelWeight ( &source->pixWeightNotBad, &source->pixWeightNotPoor, model, source->maskObj, maskVal, markVal);185 pmSourcePixelWeight (source, model, source->maskObj, maskVal, radius); 169 186 } 170 187 … … 342 359 343 360 // return source aperture magnitude 344 bool pmSourcePixelWeight (float *pixWeightNotBad, float *pixWeightNotPoor, pmModel *model, psImage *mask, psImageMaskType maskVal, psImageMaskType markVal) 345 { 346 PS_ASSERT_PTR_NON_NULL(pixWeightNotBad, false); 347 PS_ASSERT_PTR_NON_NULL(pixWeightNotPoor, false); 361 bool pmSourcePixelWeight (pmSource *source, pmModel *model, psImage *mask, psImageMaskType maskVal, float radius) 362 { 363 PS_ASSERT_PTR_NON_NULL(source, false); 364 source->pixWeightNotBad = NAN; 365 source->pixWeightNotPoor = NAN; 366 348 367 PS_ASSERT_PTR_NON_NULL(mask, false); 349 368 PS_ASSERT_PTR_NON_NULL(model, false); … … 355 374 float value; 356 375 376 float spikeSum = 0; 377 float starcoreSum = 0; 378 float burntoolSum = 0; 379 float convpoorSum = 0; 380 357 381 int Xo, Yo, dP; 358 382 int dX, DX, NX; 359 383 int dY, DY, NY; 360 384 361 *pixWeightNotBad = 0.0; 362 *pixWeightNotPoor = 0.0; 385 float radius2 = PS_SQR(radius); 363 386 364 387 // we only care about the value of the object model, not the local sky … … 387 410 NY = mask->numRows; 388 411 412 psImageMaskType maskBad = maskVal; 413 maskBad &= ~maskSuspect; 414 389 415 // measure modelSum and validSum. this function is applied to a sources' subimage. the 390 416 // value of DX is chosen (see above) to cover the full possible size of the subimage if it 391 417 // were not by an edge; ie, if the source is cut in half by an image edge, we correctly 392 418 // count the virtual pixels off the edge in normalizing the value of the pixWeight 419 420 // we skip any pixels [real or virtual] outside of the specified radius (nominally the aperture radius) 393 421 for (int ix = -DX; ix < DX + 1; ix++) { 422 if (ix > radius) continue; 394 423 int mx = ix + dX; 395 424 for (int iy = -DY; iy < DY + 1; iy++) { 425 if (iy > radius) continue; 426 if (ix*ix + iy*iy > radius2) continue; 396 427 int my = iy + dY; 397 428 … … 409 440 if (my >= NY) continue; 410 441 411 if (!(mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskVal)) { 442 // count pixels which are masked only with bad pixels 443 if (!(mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskBad)) { 412 444 notBadSum += value; 413 445 } 414 if (!(mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & ~markVal)) { 446 447 // count pixels which are masked with an mask bit (bad or poor) 448 if (!(mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskVal)) { 415 449 notPoorSum += value; 416 450 } 451 452 // count pixels which are masked with an mask bit (bad or poor) 453 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskSpike) { 454 spikeSum += value; 455 } 456 // count pixels which are masked with an mask bit (bad or poor) 457 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskStarCore) { 458 starcoreSum += value; 459 } 460 // count pixels which are masked with an mask bit (bad or poor) 461 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskBurntool) { 462 burntoolSum += value; 463 } 464 // count pixels which are masked with an mask bit (bad or poor) 465 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[my][mx] & maskConvPoor) { 466 convpoorSum += value; 467 } 417 468 } 418 469 } 419 470 psFree (coord); 420 471 421 *pixWeightNotBad = notBadSum / modelSum; 422 *pixWeightNotPoor = notPoorSum / modelSum; 472 source->pixWeightNotBad = notBadSum / modelSum; 473 source->pixWeightNotPoor = notPoorSum / modelSum; 474 475 if ((spikeSum/modelSum) > 0.25) { 476 source->mode2 |= PM_SOURCE_MODE2_ON_SPIKE; 477 } 478 if ((starcoreSum/modelSum) > 0.25) { 479 source->mode2 |= PM_SOURCE_MODE2_ON_STARCORE; 480 } 481 if ((burntoolSum/modelSum) > 0.25) { 482 source->mode2 |= PM_SOURCE_MODE2_ON_BURNTOOL; 483 } 484 if ((convpoorSum/modelSum) > 0.25) { 485 source->mode2 |= PM_SOURCE_MODE2_ON_CONVPOOR; 486 } 487 488 if (isfinite(source->pixWeightNotBad) && isfinite(source->pixWeightNotPoor)) { 489 psAssert (source->pixWeightNotBad <= source->pixWeightNotPoor, "error: all bad pixels should also be poor"); 490 } 423 491 424 492 return (true); … … 427 495 # define FLUX_LIMIT 3.0 428 496 429 // measure stats that may be us ingin difference images for distinguishing real sources from bad residuals497 // measure stats that may be used in difference images for distinguishing real sources from bad residuals 430 498 bool pmSourceMeasureDiffStats (pmSource *source, psImageMaskType maskVal, psImageMaskType markVal) 431 499 { … … 673 741 # endif 674 742 675 // determine chisq, etc for linear normalization-only fit676 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *variance, psImageMaskType maskVal , const float covarFactor)743 // determine chisq, nPix, nDOF, chisqNorm : model->nPar must be set 744 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *variance, psImageMaskType maskVal) 677 745 { 678 746 PS_ASSERT_PTR_NON_NULL(model, false); … … 689 757 if (variance->data.F32[j][i] <= 0) 690 758 continue; 691 dC += PS_SQR (image->data.F32[j][i]) / (covarFactor * variance->data.F32[j][i]);759 dC += PS_SQR (image->data.F32[j][i]) / variance->data.F32[j][i]; 692 760 Npix ++; 693 761 } 694 762 } 695 763 model->nPix = Npix; 696 model->nDOF = Npix - 1;764 model->nDOF = Npix - model->nPar; 697 765 model->chisq = dC; 766 model->chisqNorm = dC / model->nDOF; 698 767 699 768 return (true); 700 769 } 701 770 771 772 // return source aperture magnitude 773 bool pmSourceChisqUnsubtracted (pmSource *source, pmModel *model, psImageMaskType maskVal) 774 { 775 PS_ASSERT_PTR_NON_NULL(source, false); 776 PS_ASSERT_PTR_NON_NULL(model, false); 777 778 float dC = 0.0; 779 int Npix = 0; 780 781 // the model function returns the source flux at a position 782 psVector *coord = psVectorAlloc(2, PS_TYPE_F32); 783 784 psVector *params = model->params; 785 psImage *image = source->pixels; 786 psImage *mask = source->maskObj; 787 psImage *variance = source->variance; 788 789 int dX = image->col0; 790 int dY = image->row0; 791 792 for (int iy = 0; iy < image->numRows; iy++) { 793 for (int ix = 0; ix < image->numCols; ix++) { 794 795 // skip pixels which are masked 796 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & maskVal) continue; 797 798 if (variance->data.F32[iy][ix] <= 0) continue; 799 800 coord->data.F32[0] = (psF32) ix + dX + 0.5; 801 coord->data.F32[1] = (psF32) iy + dY + 0.5; 802 803 // for the full model, add all points 804 float value = model->modelFunc (NULL, params, coord); 805 806 // fprintf (stderr, "%d, %d : %f, %f : %f - %f : %f\n", 807 // ix, iy, coord->data.F32[0], coord->data.F32[1], image->data.F32[iy][ix], value, dC); 808 809 dC += PS_SQR (image->data.F32[iy][ix] - value) / variance->data.F32[iy][ix]; 810 Npix ++; 811 } 812 } 813 model->nPix = Npix; 814 model->nDOF = Npix - model->nPar; 815 model->chisq = dC; 816 model->chisqNorm = dC / model->nDOF; 817 818 psFree (coord); 819 return (true); 820 } 702 821 703 822 double pmSourceModelWeight(const pmSource *Mi, int term, const bool unweighted_sum, const float covarFactor, psImageMaskType maskVal) -
trunk/psModules/src/objects/pmSourcePhotometry.h
r29546 r31153 64 64 ); 65 65 66 bool pmSourceMagnitudesInit (p sMetadata *config);67 bool pmSourceMagnitudes (pmSource *source, pmPSF *psf, pmSourcePhotometryMode mode, psImageMaskType maskVal, psImageMaskType markVal );66 bool pmSourceMagnitudesInit (pmConfig *config, psMetadata *recipe); 67 bool pmSourceMagnitudes (pmSource *source, pmPSF *psf, pmSourcePhotometryMode mode, psImageMaskType maskVal, psImageMaskType markVal, float radius); 68 68 69 bool pmSourcePixelWeight ( float *pixWeightNotBad, float *pixWeightNotPoor, pmModel *model, psImage *mask, psImageMaskType maskVal, psImageMaskType markVal);69 bool pmSourcePixelWeight (pmSource *source, pmModel *model, psImage *mask, psImageMaskType maskVal, float radius); 70 70 71 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight, psImageMaskType maskVal, const float covarFactor); 71 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight, psImageMaskType maskVal); 72 bool pmSourceChisqUnsubtracted (pmSource *source, pmModel *model, psImageMaskType maskVal); 72 73 73 74 bool pmSourceMeasureDiffStats (pmSource *source, psImageMaskType maskVal, psImageMaskType markVal); -
trunk/psModules/src/objects/pmSourceVisual.c
r29004 r31153 56 56 57 57 if (!pmVisualTestLevel("psphot.psf.metric", 2)) return true; 58 59 if (kapa1 == -1) { 60 kapa1 = KapaOpenNamedSocket ("kapa", "pmSource:plots"); 61 if (kapa1 == -1) { 62 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 63 pmVisualSetVisual(false); 64 return false; 65 } 66 } 58 if (!pmVisualInitWindow (&kapa1, "pmSource:plots")) return false; 67 59 68 60 KapaClearSections (kapa1); … … 140 132 141 133 if (!pmVisualTestLevel("psphot.psf.subpix", 3)) return true; 142 143 if (kapa1 == -1) { 144 kapa1 = KapaOpenNamedSocket ("kapa", "pmSource:plots"); 145 if (kapa1 == -1) { 146 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 147 pmVisualSetVisual(false); 148 return false; 149 } 150 } 134 if (!pmVisualInitWindow (&kapa1, "pmSource:plots")) return false; 151 135 152 136 KapaClearSections (kapa1); 153 137 KapaInitGraph (&graphdata); 138 section.bg = KapaColorByName ("none"); // XXX probably should be 'none' 154 139 155 140 int n; … … 302 287 303 288 if (!pmVisualTestLevel("psphot.psf.fits", 2)) return true; 304 305 if (kapa2 == -1) { 306 kapa2 = KapaOpenNamedSocket ("kapa", "pmSource:images"); 307 if (kapa2 == -1) { 308 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 309 pmVisualSetVisual(false); 310 return false; 311 } 312 } 289 if (!pmVisualInitWindow (&kapa2, "pmSource:images")) return false; 313 290 314 291 // create images 1/10 scale: … … 385 362 if (!source->pixels) return false; 386 363 if (!source->modelFlux) return false; 387 388 if (kapa2 == -1) { 389 kapa2 = KapaOpenNamedSocket ("kapa", "pmSource:images"); 390 if (kapa2 == -1) { 391 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 392 pmVisualSetVisual(false); 393 return false; 394 } 395 } 364 if (!pmVisualInitWindow (&kapa2, "pmSource:images")) return false; 396 365 397 366 // KapaClearSections (kapa2); … … 428 397 if (!plotPSF) return true; 429 398 if (!pmVisualTestLevel("psphot.psf.resid", 2)) return true; 430 431 if (kapa1 == -1) { 432 kapa1 = KapaOpenNamedSocket ("kapa", "pmSource:plots"); 433 if (kapa1 == -1) { 434 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 435 pmVisualSetVisual(false); 436 return false; 437 } 438 } 399 if (!pmVisualInitWindow (&kapa1, "pmSource:plots")) return false; 439 400 440 401 KapaClearPlots (kapa1); 441 402 KapaInitGraph (&graphdata); 403 section.bg = KapaColorByName ("none"); // XXX probably should be 'none' 442 404 443 405 float Xmin = +1e32;
Note:
See TracChangeset
for help on using the changeset viewer.
