- Timestamp:
- May 3, 2010, 8:50:52 AM (16 years ago)
- Location:
- branches/simtest_nebulous_branches
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/simtest_nebulous_branches
- Property svn:mergeinfo changed
-
branches/simtest_nebulous_branches/psModules
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk/psModules merged eligible /branches/eam_branches/stackphot.20100406/psModules 27623-27653 /branches/pap_delete/psModules 27530-27595
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/simtest_nebulous_branches/psModules/src/objects/pmSourceMoments.c
r24577 r27840 36 36 #include "pmSource.h" 37 37 38 bool pmSourceMoments_Old(pmSource *source, psF32 radius);39 40 38 /****************************************************************************** 41 39 pmSourceMoments(source, radius): this function takes a subImage defined in the … … 50 48 pmSource->mask (optional) 51 49 52 XXX: The peak calculations are done in image coords, not subImage coords. 53 54 this version clips input pixels on S/N 55 XXX EAM : this version returns false for several reasons 50 The peak calculations are done in image coords, not subImage coords. 51 52 this version optionally clips input pixels on S/N 56 53 *****************************************************************************/ 57 54 # define VALID_RADIUS(X,Y,RAD2) (((RAD2) >= (PS_SQR(X) + PS_SQR(Y))) ? 1 : 0) 58 55 59 bool pmSourceMoments(pmSource *source, psF32 radius, psF32 sigma, psF32 minSN )56 bool pmSourceMoments(pmSource *source, psF32 radius, psF32 sigma, psF32 minSN, psImageMaskType maskVal) 60 57 { 61 58 PS_ASSERT_PTR_NON_NULL(source, false); … … 64 61 PS_ASSERT_FLOAT_LARGER_THAN(radius, 0.0, false); 65 62 66 // XXX supply sky in a different way?63 // use sky from moments if defined, 0.0 otherwise 67 64 psF32 sky = 0.0; 68 65 if (source->moments == NULL) { … … 91 88 // col0,row0: a pixel (x,y) in the primary image has coordinates of (x-col0, y-row0) in 92 89 // this subimage. we subtract off the peak coordinates, adjusted to this subimage, to have 93 // minimal round-off error in the sums 94 95 psF32 xOff = source->peak->x; 96 psF32 yOff = source->peak->y; 97 psF32 xPeak = source->peak->x - source->pixels->col0; // coord of peak in subimage 98 psF32 yPeak = source->peak->y - source->pixels->row0; // coord of peak in subimage 90 // minimal round-off error in the sums. since these values are subtracted just to minimize 91 // the dynamic range and are added back below, the exact value does not matter. these are 92 // (int) so they can be used in the image index below. 93 94 int xOff = source->peak->x; 95 int yOff = source->peak->y; 96 int xPeak = source->peak->x - source->pixels->col0; // coord of peak in subimage 97 int yPeak = source->peak->y - source->pixels->row0; // coord of peak in subimage 98 99 // we are guaranteed to have a valid pixel and variance at this location (right? right?) 100 // psF32 weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]); 101 // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); 102 // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); 103 // psAssert (source->variance->data.F32[yPeak][xPeak] > 0, "peak must be on valid pixel"); 99 104 100 105 for (psS32 row = 0; row < source->pixels->numRows ; row++) { … … 109 114 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) { 110 115 if (vMsk) { 111 if (*vMsk ) {116 if (*vMsk & maskVal) { 112 117 vMsk++; 113 118 continue; … … 126 131 psF32 wDiff = *vWgt; 127 132 128 // skip pixels below specified significance level 133 // skip pixels below specified significance level. this is allowed, but should be 134 // avoided -- the over-weights the wings of bright stars compared to those of faint 135 // stars. 129 136 if (PS_SQR(pDiff) < minSN2*wDiff) continue; 130 if (pDiff < 0) continue; 131 137 // if (pDiff < 0) continue; // XXX : MWV says I should include < 0.0 valued points... 138 139 // Apply a Gaussian window function. Be careful with the window function. S/N 140 // weighting over weights the sky for faint sources 132 141 if (sigma > 0.0) { 133 // apply a pseudo-gaussian weight 134 135 // XXX a lot of extra flops; can we do pre-calculate? 136 psF32 z = (PS_SQR(xDiff) + PS_SQR(yDiff))*rsigma2; 137 assert (z >= 0.0); 138 psF32 t = 1.0 + z*(1.0 + z/2.0*(1.0 + z/3.0)); 139 psF32 weight = 1.0 / t; 140 141 // fprintf (stderr, "%6.1f %6.1f %8.1f %8.1f %5.3f ", xDiff, yDiff, pDiff, wDiff, weight); 142 143 wDiff *= weight; 144 pDiff *= weight; 142 // XXX a lot of extra flops; can we pre-calculate? 143 psF32 z = (PS_SQR(xDiff) + PS_SQR(yDiff))*rsigma2; 144 assert (z >= 0.0); 145 psF32 weight = exp(-z); 146 147 wDiff *= weight; 148 pDiff *= weight; 145 149 } 146 150 … … 154 158 Y1 += yWght; 155 159 156 // fprintf (stderr, " : %6.1f %6.1f %8.1f %8.1f\n", X1, Y1, Sum, Var);157 158 peakPixel = PS_MAX (*vPix, peakPixel); 159 numPixels++;160 } 161 }162 163 // if we have less than (1/2) of the possible pixels, force a retry 160 peakPixel = PS_MAX (*vPix, peakPixel); 161 numPixels++; 162 } 163 } 164 165 // if we have less than (1/4) of the possible pixels (in circle or box), force a retry 166 int minPixels = PS_MIN(0.75*R2, source->pixels->numCols*source->pixels->numRows/4.0); 167 164 168 // XXX EAM - the limit is a bit arbitrary. make it user defined? 165 if ((numPixels < 0.75*R2) || (Sum <= 0)) {166 psTrace ("psModules.objects", 3, "insufficient valid pixels (%d vs %d; %f) for source\n", numPixels, (int)(0.75*R2), Sum);167 return (false);169 if ((numPixels < minPixels) || (Sum <= 0)) { 170 psTrace ("psModules.objects", 3, "insufficient valid pixels (%d vs %d; %f) for source\n", numPixels, minPixels, Sum); 171 return (false); 168 172 } 169 173 … … 172 176 float My = Y1/Sum; 173 177 if ((fabs(Mx) > radius) || (fabs(My) > radius)) { 174 psTrace ("psModules.objects", 3, "large centroid swing; invalid peak %d, %d\n", source->peak->x, source->peak->y);175 return (false);178 psTrace ("psModules.objects", 3, "large centroid swing; invalid peak %d, %d\n", source->peak->x, source->peak->y); 179 return (false); 176 180 } 177 181 … … 179 183 180 184 // add back offset of peak in primary image 181 source->moments->Mx = Mx + xOff; 182 source->moments->My = My + yOff; 185 // also offset from pixel index to pixel coordinate 186 // (the calculation above uses pixel index instead of coordinate) 187 // 0.5 PIX: moments are calculated using the pixel index and converted here to pixel coords 188 source->moments->Mx = Mx + xOff + 0.5; 189 source->moments->My = My + yOff + 0.5; 183 190 184 191 source->moments->Sum = Sum; … … 205 212 Sum = 0.0; // the second pass may include slightly different pixels, re-determine Sum 206 213 207 // center of mass in subimage 214 // center of mass in subimage. Note: the calculation below uses pixel index, so we do not 215 // correct xCM, yCM to pixel coordinate here. 208 216 psF32 xCM = Mx + xPeak; // coord of peak in subimage 209 217 psF32 yCM = My + yPeak; // coord of peak in subimage … … 211 219 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 212 220 213 psF32 yDiff = row - yCM;221 psF32 yDiff = row - yCM; 214 222 if (fabs(yDiff) > radius) continue; 215 223 216 psF32 *vPix = source->pixels->data.F32[row];217 psF32 *vWgt = source->variance->data.F32[row];218 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];219 220 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {221 if (vMsk) {222 if (*vMsk) {223 vMsk++;224 continue;225 }226 vMsk++;227 }228 if (isnan(*vPix)) continue;229 230 psF32 xDiff = col - xCM;224 psF32 *vPix = source->pixels->data.F32[row]; 225 psF32 *vWgt = source->variance->data.F32[row]; 226 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row]; 227 228 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) { 229 if (vMsk) { 230 if (*vMsk & maskVal) { 231 vMsk++; 232 continue; 233 } 234 vMsk++; 235 } 236 if (isnan(*vPix)) continue; 237 238 psF32 xDiff = col - xCM; 231 239 if (fabs(xDiff) > radius) continue; 232 240 233 // radius is just a function of (xDiff, yDiff) 234 psF32 r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 235 psF32 r = sqrt(r2); 236 if (r > radius) continue; 237 238 psF32 pDiff = *vPix - sky; 239 psF32 wDiff = *vWgt; 240 241 // XXX EAM : should this limit be user-defined? 242 243 if (PS_SQR(pDiff) < minSN2*wDiff) continue; 244 if (pDiff < 0) continue; 245 241 // radius is just a function of (xDiff, yDiff) 242 psF32 r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 243 psF32 r = sqrt(r2); 244 if (r > radius) continue; 245 246 psF32 pDiff = *vPix - sky; 247 psF32 wDiff = *vWgt; 248 249 // skip pixels below specified significance level. this is allowed, but should be 250 // avoided -- the over-weights the wings of bright stars compared to those of faint 251 // stars. 252 if (PS_SQR(pDiff) < minSN2*wDiff) continue; 253 // if (pDiff < 0) continue; 254 255 // Apply a Gaussian window function. Be careful with the window function. S/N 256 // weighting over weights the sky for faint sources 246 257 if (sigma > 0.0) { 247 // apply a pseudo-gaussian weight 248 249 // XXX a lot of extra flops; can we do pre-calculate? 250 psF32 z = (PS_SQR(xDiff) + PS_SQR(yDiff))*rsigma2; 251 assert (z >= 0.0); 252 psF32 t = 1.0 + z*(1.0 + z/2.0*(1.0 + z/3.0)); 253 psF32 weight = 1.0 / t; 254 255 // fprintf (stderr, "%6.1f %6.1f %8.1f %8.1f %5.3f ", xDiff, yDiff, pDiff, wDiff, weight); 256 257 wDiff *= weight; 258 pDiff *= weight; 258 // XXX a lot of extra flops; can we do pre-calculate? 259 psF32 z = (PS_SQR(xDiff) + PS_SQR(yDiff))*rsigma2; 260 assert (z >= 0.0); 261 psF32 weight = exp(-z); 262 263 wDiff *= weight; 264 pDiff *= weight; 259 265 } 260 266 261 Sum += pDiff;262 263 psF32 x = xDiff * pDiff;264 psF32 y = yDiff * pDiff;265 266 psF32 xx = xDiff * x;267 psF32 xy = xDiff * y;268 psF32 yy = yDiff * y;269 270 psF32 xxx = xDiff * xx / r;271 psF32 xxy = xDiff * xy / r;272 psF32 xyy = xDiff * yy / r;273 psF32 yyy = yDiff * yy / r;274 275 psF32 xxxx = xDiff * xxx / r2;276 psF32 xxxy = xDiff * xxy / r2;277 psF32 xxyy = xDiff * xyy / r2;278 psF32 xyyy = xDiff * yyy / r2;279 psF32 yyyy = yDiff * yyy / r2;280 281 XX += xx;282 XY += xy;283 YY += yy;284 285 XXX += xxx;286 XXY += xxy;287 XYY += xyy;288 YYY += yyy;289 290 XXXX += xxxx;291 XXXY += xxxy;292 XXYY += xxyy;293 XYYY += xyyy;294 YYYY += yyyy;295 }267 Sum += pDiff; 268 269 psF32 x = xDiff * pDiff; 270 psF32 y = yDiff * pDiff; 271 272 psF32 xx = xDiff * x; 273 psF32 xy = xDiff * y; 274 psF32 yy = yDiff * y; 275 276 psF32 xxx = xDiff * xx / r; 277 psF32 xxy = xDiff * xy / r; 278 psF32 xyy = xDiff * yy / r; 279 psF32 yyy = yDiff * yy / r; 280 281 psF32 xxxx = xDiff * xxx / r2; 282 psF32 xxxy = xDiff * xxy / r2; 283 psF32 xxyy = xDiff * xyy / r2; 284 psF32 xyyy = xDiff * yyy / r2; 285 psF32 yyyy = yDiff * yyy / r2; 286 287 XX += xx; 288 XY += xy; 289 YY += yy; 290 291 XXX += xxx; 292 XXY += xxy; 293 XYY += xyy; 294 YYY += yyy; 295 296 XXXX += xxxx; 297 XXXY += xxxy; 298 XXYY += xxyy; 299 XYYY += xyyy; 300 YYYY += yyyy; 301 } 296 302 } 297 303 … … 311 317 source->moments->Myyyy = YYYY/Sum; 312 318 313 if (source->moments->Mxx < 0) {314 fprintf (stderr, "error: neg second moment??\n");315 }316 if (source->moments->Myy < 0) {317 fprintf (stderr, "error: neg second moment??\n");318 }319 // if (source->moments->Mxx < 0) { 320 // fprintf (stderr, "error: neg second moment??\n"); 321 // } 322 // if (source->moments->Myy < 0) { 323 // fprintf (stderr, "error: neg second moment??\n"); 324 // } 319 325 320 326 psTrace ("psModules.objects", 4, "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", 321 source->moments->Mxx, source->moments->Mxy, source->moments->Myy,322 source->moments->Mxxx, source->moments->Mxxy, source->moments->Mxyy, source->moments->Myyy,323 source->moments->Mxxxx, source->moments->Mxxxy, source->moments->Mxxyy, source->moments->Mxyyy, source->moments->Myyyy);327 source->moments->Mxx, source->moments->Mxy, source->moments->Myy, 328 source->moments->Mxxx, source->moments->Mxxy, source->moments->Mxyy, source->moments->Myyy, 329 source->moments->Mxxxx, source->moments->Mxxxy, source->moments->Mxxyy, source->moments->Mxyyy, source->moments->Myyyy); 324 330 325 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", 326 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, numPixels); 327 328 if (source->moments->Mxx < 0) { 329 fprintf (stderr, "error: neg second moment??\n"); 330 } 331 if (source->moments->Myy < 0) { 332 fprintf (stderr, "error: neg second moment??\n"); 333 } 334 335 // XXX TEST: 336 // pmSourceMoments_Old (source, radius); 332 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, numPixels); 333 337 334 return(true); 338 335 } 339 340 341 bool pmSourceMoments_Old(pmSource *source, psF32 radius)342 {343 PS_ASSERT_PTR_NON_NULL(source, false);344 PS_ASSERT_PTR_NON_NULL(source->peak, false);345 PS_ASSERT_PTR_NON_NULL(source->pixels, false);346 PS_ASSERT_FLOAT_LARGER_THAN(radius, 0.0, false);347 348 psF32 sky = 0.0;349 if (source->moments == NULL) {350 source->moments = pmMomentsAlloc();351 } else {352 sky = source->moments->Sky;353 }354 355 // Sum = SUM (z - sky)356 // X1 = SUM (x - xc)*(z - sky)357 // X2 = SUM (x - xc)^2 * (z - sky)358 // XY = SUM (x - xc)*(y - yc)*(z - sky)359 psF32 peakPixel = -PS_MAX_F32;360 psS32 numPixels = 0;361 psF32 Sum = 0.0;362 psF32 Var = 0.0;363 psF32 X1 = 0.0;364 psF32 Y1 = 0.0;365 psF32 X2 = 0.0;366 psF32 Y2 = 0.0;367 psF32 XY = 0.0;368 psF32 x = 0;369 psF32 y = 0;370 psF32 R2 = PS_SQR(radius);371 372 // a note about coordinates: coordinates of objects throughout psphot refer to the primary373 // image coordinates. the source->pixels image has an offset relative to its parent of374 // col0,row0: a pixel (x,y) in the primary image has coordinates of (x-col0, y-row0) in375 // this subimage. we subtract off the peak coordinates, adjusted to this subimage, to have376 // minimal round-off error in the sums377 378 psF32 xPeak = source->peak->x - source->pixels->col0; // coord of peak in subimage379 psF32 yPeak = source->peak->y - source->pixels->row0; // coord of peak in subimage380 381 for (psS32 row = 0; row < source->pixels->numRows ; row++) {382 383 psF32 *vPix = source->pixels->data.F32[row];384 psF32 *vWgt = source->variance->data.F32[row];385 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];386 387 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {388 if (vMsk) {389 if (*vMsk) {390 vMsk++;391 continue;392 }393 vMsk++;394 }395 if (isnan(*vPix)) continue;396 397 psF32 xDiff = col - xPeak;398 psF32 yDiff = row - yPeak;399 400 // radius is just a function of (xDiff, yDiff)401 if (!VALID_RADIUS(xDiff, yDiff, R2)) continue;402 403 psF32 pDiff = *vPix - sky;404 psF32 wDiff = *vWgt;405 406 // XXX EAM : should this limit be user-defined?407 if (PS_SQR(pDiff) < wDiff) continue;408 409 Var += wDiff;410 Sum += pDiff;411 412 psF32 xWght = xDiff * pDiff;413 psF32 yWght = yDiff * pDiff;414 415 X1 += xWght;416 Y1 += yWght;417 418 X2 += xDiff * xWght;419 XY += xDiff * yWght;420 Y2 += yDiff * yWght;421 422 peakPixel = PS_MAX (*vPix, peakPixel);423 numPixels++;424 }425 }426 427 // if we have less than (1/4) of the possible pixels, force a retry428 // XXX EAM - the limit is a bit arbitrary. make it user defined?429 if ((numPixels < 0.75*R2) || (Sum <= 0)) {430 psTrace ("psModules.objects", 3, "insufficient valid pixels (%d vs %d; %f) for source\n", numPixels, (int)(0.75*R2), Sum);431 return (false);432 }433 434 psTrace ("psModules.objects", 4, "sky: %f Sum: %f X1: %f Y1: %f X2: %f Y2: %f XY: %f Npix: %d\n",435 sky, Sum, X1, Y1, X2, Y2, XY, numPixels);436 437 //438 // first moment X = X1/Sum + xc439 // second moment X = sqrt (X2/Sum - (X1/Sum)^2)440 // Sxy = XY / Sum441 //442 x = X1/Sum;443 y = Y1/Sum;444 if ((fabs(x) > radius) || (fabs(y) > radius)) {445 psTrace ("psModules.objects", 3, "large centroid swing; invalid peak %d, %d\n",446 source->peak->x, source->peak->y);447 return (false);448 }449 450 # if (PS_TRACE_ON)451 float Sxx = PS_MAX(X2/Sum - PS_SQR(x), 0);452 float Sxy = XY / Sum;453 float Syy = PS_MAX(Y2/Sum - PS_SQR(y), 0);454 455 psTrace ("psModules.objects", 3,456 "sky: %f Sum: %f x: %f y: %f Sx: %f Sy: %f Sxy: %f\n",457 sky, Sum, x, y, Sxx, Sxy, Syy);458 # endif459 460 return(true);461 }462
Note:
See TracChangeset
for help on using the changeset viewer.
