Changeset 6556 for branches/rel10_ifa/psModules/src/objects/pmSource.c
- Timestamp:
- Mar 8, 2006, 5:14:23 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/rel10_ifa/psModules/src/objects/pmSource.c
r6537 r6556 1 /** @file pm Objects.c1 /** @file pmSource.c 2 2 * 3 * This file will ...3 * Functions to define and manipulate sources on images 4 4 * 5 5 * @author GLG, MHPCC 6 6 * @author EAM, IfA: significant modifications. 7 7 * 8 * @version $Revision: 1.1.2. 1$ $Name: not supported by cvs2svn $9 * @date $Date: 2006-03-0 7 06:33:35$8 * @version $Revision: 1.1.2.2 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2006-03-09 03:14:23 $ 10 10 * 11 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 17 17 #include <string.h> 18 18 #include "pslib.h" 19 #include "pmObjects.h" 20 #include "pmModelGroup.h" 19 #include "pmHDU.h" 20 #include "pmFPA.h" 21 #include "pmPeaks.h" 22 #include "pmMoments.h" 23 #include "pmModel.h" 24 #include "pmSource.h" 21 25 22 26 static void sourceFree(pmSource *tmp) … … 50 54 tmp->modelPSF = NULL; 51 55 tmp->modelEXT = NULL; 52 tmp->type = PM_SOURCE_ UNKNOWN;53 tmp->mode = PM_SOURCE_ DEFAULT;56 tmp->type = PM_SOURCE_TYPE_UNKNOWN; 57 tmp->mode = PM_SOURCE_MODE_DEFAULT; 54 58 psMemSetDeallocator(tmp, (psFreeFunc) sourceFree); 55 59 … … 219 223 220 224 // XXX EAM : this lets us takes the single highest peak 221 psArraySort (peaks, pm ComparePeakDescend);225 psArraySort (peaks, pmPeaksCompareDescend); 222 226 clump = peaks->data[0]; 223 227 psTrace (".pmObjects.pmSourceRoughClass", 2, "clump is at %d, %d (%f)\n", clump->x, clump->y, clump->counts); … … 331 335 // inner = psRegionForSquare (tmpSrc->peak->x - tmpSrc->mask->col0, tmpSrc->peak->y - tmpSrc->mask->row0, 2); 332 336 inner = psRegionForSquare (tmpSrc->peak->x, tmpSrc->peak->y, 2); 333 int Nsatpix = psImageCountPixelMask (tmpSrc->mask, inner, P SPHOT_MASK_SATURATED);337 int Nsatpix = psImageCountPixelMask (tmpSrc->mask, inner, PM_SOURCE_MASK_SATURATED); 334 338 335 339 // saturated star (size consistent with PSF or larger) … … 338 342 big = true; 339 343 if ((Nsatpix > 1) && big) { 340 tmpSrc->type = PM_SOURCE_ STAR;341 tmpSrc->mode = PM_SOURCE_ SATSTAR;344 tmpSrc->type = PM_SOURCE_TYPE_STAR; 345 tmpSrc->mode = PM_SOURCE_MODE_SATSTAR; 342 346 Nsatstar ++; 343 347 continue; … … 346 350 // saturated object (not a star, eg bleed trails, hot pixels) 347 351 if (Nsatpix > 1) { 348 tmpSrc->type = PM_SOURCE_ SATURATED;349 tmpSrc->mode = PM_SOURCE_ DEFAULT;352 tmpSrc->type = PM_SOURCE_TYPE_SATURATED; 353 tmpSrc->mode = PM_SOURCE_MODE_DEFAULT; 350 354 Nsat ++; 351 355 continue; … … 356 360 // only set candidate defects if 357 361 if ((sigX < 0.05) || (sigY < 0.05)) { 358 tmpSrc->type = PM_SOURCE_ DEFECT;359 tmpSrc->mode = PM_SOURCE_ DEFAULT;362 tmpSrc->type = PM_SOURCE_TYPE_DEFECT; 363 tmpSrc->mode = PM_SOURCE_MODE_DEFAULT; 360 364 Ncr ++; 361 365 continue; … … 364 368 // likely unsaturated extended source (too large to be stellar) 365 369 if ((sigX > (clump.X + 3*clump.dX)) || (sigY > (clump.Y + 3*clump.dY))) { 366 tmpSrc->type = PM_SOURCE_ EXTENDED;367 tmpSrc->mode = PM_SOURCE_ DEFAULT;370 tmpSrc->type = PM_SOURCE_TYPE_EXTENDED; 371 tmpSrc->mode = PM_SOURCE_MODE_DEFAULT; 368 372 Next ++; 369 373 continue; … … 378 382 psF32 radius = hypot ((sigX-clump.X)/clump.dX, (sigY-clump.Y)/clump.dY); 379 383 if ((tmpSrc->moments->SN > PSF_SN_LIM) && (radius < 1.5)) { 380 tmpSrc->type = PM_SOURCE_ STAR;381 tmpSrc->mode = PM_SOURCE_ PSFSTAR;384 tmpSrc->type = PM_SOURCE_TYPE_STAR; 385 tmpSrc->mode = PM_SOURCE_MODE_PSFSTAR; 382 386 Npsf ++; 383 387 continue; … … 385 389 386 390 // random type of star 387 tmpSrc->type = PM_SOURCE_ STAR;388 tmpSrc->mode = PM_SOURCE_ DEFAULT;391 tmpSrc->type = PM_SOURCE_TYPE_STAR; 392 tmpSrc->mode = PM_SOURCE_MODE_DEFAULT; 389 393 } 390 394 … … 409 413 } 410 414 415 /****************************************************************************** 416 pmSourceMoments(source, radius): this function takes a subImage defined in the 417 pmSource data structure, along with the peak location, and determines the 418 various moments associated with that peak. 419 420 Requires the following to have been created: 421 pmSource 422 pmSource->peak 423 pmSource->pixels 424 pmSource->weight 425 pmSource->mask 426 427 XXX: The peak calculations are done in image coords, not subImage coords. 428 429 XXX EAM : this version clips input pixels on S/N 430 XXX EAM : this version returns false for several reasons 431 *****************************************************************************/ 432 # define VALID_RADIUS(X,Y,RAD2) (((RAD2) >= (PS_SQR(X) + PS_SQR(Y))) ? 1 : 0) 433 434 bool pmSourceMoments(pmSource *source, 435 psF32 radius) 436 { 437 psTrace(__func__, 3, "---- %s() begin ----\n", __func__); 438 PS_ASSERT_PTR_NON_NULL(source, false); 439 PS_ASSERT_PTR_NON_NULL(source->peak, false); 440 PS_ASSERT_PTR_NON_NULL(source->pixels, false); 441 PS_ASSERT_PTR_NON_NULL(source->mask, false); 442 PS_ASSERT_FLOAT_LARGER_THAN(radius, 0.0, false); 443 444 // 445 // XXX: Verify the setting for sky if source->moments == NULL. 446 // 447 psF32 sky = 0.0; 448 if (source->moments == NULL) { 449 source->moments = pmMomentsAlloc(); 450 } else { 451 sky = source->moments->Sky; 452 } 453 454 // 455 // Sum = SUM (z - sky) 456 // X1 = SUM (x - xc)*(z - sky) 457 // X2 = SUM (x - xc)^2 * (z - sky) 458 // XY = SUM (x - xc)*(y - yc)*(z - sky) 459 // 460 psF32 peakPixel = -PS_MAX_F32; 461 psS32 numPixels = 0; 462 psF32 Sum = 0.0; 463 psF32 Var = 0.0; 464 psF32 X1 = 0.0; 465 psF32 Y1 = 0.0; 466 psF32 X2 = 0.0; 467 psF32 Y2 = 0.0; 468 psF32 XY = 0.0; 469 psF32 x = 0; 470 psF32 y = 0; 471 psF32 R2 = PS_SQR(radius); 472 473 psF32 xPeak = source->peak->x; 474 psF32 yPeak = source->peak->y; 475 psF32 xOff = source->pixels->col0 - source->peak->x; 476 psF32 yOff = source->pixels->row0 - source->peak->y; 477 478 // XXX why do I get different results for these two methods of finding Sx? 479 // XXX Sx, Sy would be better measured if we clip pixels close to sky 480 // XXX Sx, Sy can still be imaginary, so we probably need to keep Sx^2? 481 // We loop through all pixels in this subimage (source->pixels), and for each 482 // pixel that is not masked, AND within the radius of the peak pixel, we 483 // proceed with the moments calculation. need to do two loops for a 484 // numerically stable result. first loop: get the sums. 485 // XXX EAM : mask == 0 is valid 486 487 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 488 489 psF32 *vPix = source->pixels->data.F32[row]; 490 psF32 *vWgt = source->weight->data.F32[row]; 491 psU8 *vMsk = (source->mask == NULL) ? NULL : source->mask->data.U8[row]; 492 493 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) { 494 if ((vMsk != NULL) && *vMsk) { 495 vMsk++; 496 continue; 497 } 498 499 psF32 xDiff = col + xOff; 500 psF32 yDiff = row + yOff; 501 502 // radius is just a function of (xDiff, yDiff) 503 if (!VALID_RADIUS(xDiff, yDiff, R2)) { 504 if (vMsk != NULL) 505 vMsk++; 506 continue; 507 } 508 509 psF32 pDiff = *vPix - sky; 510 psF32 wDiff = *vWgt; 511 512 // XXX EAM : check for valid S/N in pixel 513 // XXX EAM : should this limit be user-defined? 514 if (PS_SQR(pDiff) < wDiff) { 515 if (vMsk != NULL) 516 vMsk++; 517 continue; 518 } 519 520 Var += wDiff; 521 Sum += pDiff; 522 523 psF32 xWght = xDiff * pDiff; 524 psF32 yWght = yDiff * pDiff; 525 526 X1 += xWght; 527 Y1 += yWght; 528 529 XY += xDiff * yWght; 530 X2 += xDiff * xWght; 531 Y2 += yDiff * yWght; 532 533 peakPixel = PS_MAX (*vPix, peakPixel); 534 numPixels++; 535 if (vMsk != NULL) 536 vMsk++; 537 } 538 } 539 540 // if we have less than (1/4) of the possible pixels, force a retry 541 // XXX EAM - the limit is a bit arbitrary. make it user defined? 542 if ((numPixels < 0.75*R2) || (Sum <= 0)) { 543 psTrace (".psModules.pmSourceMoments", 3, "no valid pixels for source\n"); 544 psTrace(__func__, 3, "---- %s(false) end ----\n", __func__); 545 return (false); 546 } 547 548 psTrace (".psModules.pmSourceMoments", 5, 549 "sky: %f Sum: %f X1: %f Y1: %f X2: %f Y2: %f XY: %f Npix: %d\n", 550 sky, Sum, X1, Y1, X2, Y2, XY, numPixels); 551 552 // 553 // first moment X = X1/Sum + xc 554 // second moment X = sqrt (X2/Sum - (X1/Sum)^2) 555 // Sxy = XY / Sum 556 // 557 x = X1/Sum; 558 y = Y1/Sum; 559 if ((fabs(x) > radius) || (fabs(y) > radius)) { 560 psTrace (".psModules.pmSourceMoments", 3, 561 "large centroid swing; invalid peak %d, %d\n", 562 source->peak->x, source->peak->y); 563 psTrace(__func__, 3, "---- %s(false) end ----\n", __func__); 564 return (false); 565 } 566 567 source->moments->x = x + xPeak; 568 source->moments->y = y + yPeak; 569 570 // XXX EAM : Sxy needs to have x*y subtracted 571 source->moments->Sxy = XY/Sum - x*y; 572 source->moments->Sum = Sum; 573 source->moments->SN = Sum / sqrt(Var); 574 source->moments->Peak = peakPixel; 575 source->moments->nPixels = numPixels; 576 577 // XXX EAM : these values can be negative, so we need to limit the range 578 source->moments->Sx = sqrt(PS_MAX(X2/Sum - PS_SQR(x), 0)); 579 source->moments->Sy = sqrt(PS_MAX(Y2/Sum - PS_SQR(y), 0)); 580 581 psTrace (".psModules.pmSourceMoments", 4, 582 "sky: %f Sum: %f x: %f y: %f Sx: %f Sy: %f Sxy: %f\n", 583 sky, Sum, source->moments->x, source->moments->y, 584 source->moments->Sx, source->moments->Sy, source->moments->Sxy); 585 586 psTrace(__func__, 3, "---- %s(true) end ----\n", __func__); 587 return(true); 588 } 589 590 pmModel *pmSourceSelectModel (pmSource *source) 591 { 592 switch (source->type) { 593 case PM_SOURCE_TYPE_STAR: 594 return source->modelPSF; 595 596 case PM_SOURCE_TYPE_EXTENDED: 597 return source->modelEXT; 598 599 default: 600 return NULL; 601 } 602 return NULL; 603 }
Note:
See TracChangeset
for help on using the changeset viewer.
