- Timestamp:
- Aug 26, 2012, 1:05:27 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20120805/psphot/src/psphotDeblendSatstars.c
r31154 r34360 78 78 psVector *index = psVectorSortIndex (NULL, SN); 79 79 // this results in an index of increasing SN 80 81 psphotVisualPlotRadialProfiles (recipe, sources, PM_SOURCE_MODE_SATSTAR); 80 82 81 83 // examine sources in decreasing SN order … … 219 221 return true; 220 222 } 223 224 bool psphotDeblendSatstarsReadoutOld (pmConfig *config, const pmFPAview *view, const char *filerule, int fileIndex) { 225 226 int N; 227 pmSource *source; 228 bool status; 229 230 psTimerStart ("psphot.deblend.sat"); 231 232 int Nblend = 0; 233 float SAT_MIN_RADIUS = 5.0; 234 235 // find the currently selected readout 236 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, fileIndex); // File of interest 237 psAssert (file, "missing file?"); 238 239 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 240 psAssert (readout, "missing readout?"); 241 242 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 243 psAssert (detections, "missing detections?"); 244 245 psArray *sources = detections->newSources; 246 psAssert (sources, "missing sources?"); 247 248 if (!sources->n) { 249 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping satstar blend"); 250 return true; 251 } 252 253 // select the appropriate recipe information 254 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 255 psAssert (recipe, "missing recipe?"); 256 257 pmCell *cell = readout->parent; 258 259 float SATURATION = NAN; 260 261 // do not completely trust the values in the header... 262 float CELL_SATURATION = psMetadataLookupF32 (&status, cell->concepts, "CELL.SATURATION"); 263 float MIN_SATURATION = psMetadataLookupF32 (&status, recipe, "DEBLEND_MIN_SATURATION"); 264 if (!status || !isfinite(MIN_SATURATION)) { 265 MIN_SATURATION = 40000.0; 266 } 267 if (!isfinite(CELL_SATURATION)) { 268 SATURATION = MIN_SATURATION; 269 } else { 270 SATURATION = PS_MAX(MIN_SATURATION, CELL_SATURATION); 271 } 272 float SAT_TEST_LEVEL = 0.5*SATURATION; 273 274 // we need sources spatially-sorted to find overlaps 275 sources = psArraySort (sources, pmSourceSortByY); 276 277 // source analysis is done in peak order (brightest first) 278 // we use an index for this so the spatial sorting is kept 279 psVector *SN = psVectorAlloc (sources->n, PS_DATA_F32); 280 for (int i = 0; i < SN->n; i++) { 281 source = sources->data[i]; 282 SN->data.F32[i] = source->peak->rawFlux; 283 } 284 psVector *index = psVectorSortIndex (NULL, SN); 285 // this results in an index of increasing SN 286 287 // examine sources in decreasing SN order 288 for (int i = sources->n - 1; i >= 0; i--) { 289 N = index->data.U32[i]; 290 source = sources->data[N]; 291 292 // XXX filter? if (source->mode & PM_SOURCE_MODE_SATSTAR) continue; 293 if (source->mode & PM_SOURCE_MODE_BLEND) continue; 294 if (source->peak->rawFlux < SAT_TEST_LEVEL) continue; 295 296 // save these for reference below 297 int xPeak = source->peak->x; 298 int yPeak = source->peak->y; 299 300 // generate a basic contour (set of x,y coordinates at-or-below flux level) 301 psArray *contour = pmSourceContour (source->pixels, xPeak, yPeak, SAT_TEST_LEVEL); 302 if (contour == NULL) continue; 303 304 // contour consists of a set of X,Y coords giving the boundary 305 psVector *xVec = contour->data[0]; 306 psVector *yVec = contour->data[1]; 307 if (xVec->n < 5) { 308 psFree(contour); 309 continue; 310 } 311 312 // find the center of the contour (let's just use mid[x,y]) 313 int xMin = xVec->data.F32[0]; 314 int xMax = xVec->data.F32[0]; 315 int yMin = yVec->data.F32[0]; 316 int yMax = yVec->data.F32[0]; 317 for (int j = 0; j < xVec->n; j++) { 318 xMin = PS_MIN (xMin, xVec->data.F32[j]); 319 xMax = PS_MAX (xMax, xVec->data.F32[j]); 320 yMin = PS_MIN (yMin, yVec->data.F32[j]); 321 yMax = PS_MAX (yMax, yVec->data.F32[j]); 322 } 323 int xCenter = 0.5*(xMin + xMax); 324 int yCenter = 0.5*(yMin + yMax); 325 psFree (contour); 326 327 psAssert (xCenter >= source->pixels->col0, "invalid shift in object center"); 328 psAssert (xCenter < source->pixels->col0 + source->pixels->numCols, "invalid shift in object center"); 329 psAssert (yCenter >= source->pixels->row0, "invalid shift in object center"); 330 psAssert (yCenter < source->pixels->row0 + source->pixels->numRows, "invalid shift in object center"); 331 332 // reset the peak for this source to the value of the center pixel 333 source->peak->x = xCenter; 334 source->peak->y = yCenter; 335 source->peak->xf = xCenter; 336 source->peak->yf = yCenter; 337 338 // temporary array for overlapping objects we find 339 psArray *overlap = psArrayAllocEmpty (100); 340 341 // search backwards for overlapping sources 342 for (int j = N - 1; j >= 0; j--) { 343 pmSource *testSource = sources->data[j]; 344 if (testSource->peak->x < source->pixels->col0) continue; 345 if (testSource->peak->x >= source->pixels->col0 + source->pixels->numCols) continue; 346 if (testSource->peak->y < source->pixels->row0) break; 347 if (testSource->peak->y >= source->pixels->row0 + source->pixels->numRows) { 348 fprintf (stderr, "warning: invalid condition\n"); 349 continue; 350 } 351 psArrayAdd (overlap, 100, testSource); 352 } 353 354 // search forwards for overlapping sources 355 for (int j = N + 1; j < sources->n; j++) { 356 pmSource *testSource = sources->data[j]; 357 if (testSource->peak->x < source->pixels->col0) continue; 358 if (testSource->peak->x >= source->pixels->col0 + source->pixels->numCols) continue; 359 if (testSource->peak->y < source->pixels->row0) { 360 fprintf (stderr, "warning: invalid condition\n"); 361 continue; 362 } 363 if (testSource->peak->y >= source->pixels->row0 + source->pixels->numRows) break; 364 psArrayAdd (overlap, 100, testSource); 365 } 366 367 if (overlap->n == 0) { 368 psFree (overlap); 369 continue; 370 } 371 372 // now find the contour which is at 0.5*SAT_TEST_LEVEL (xPeak, yPeak is valid high pixel) 373 contour = pmSourceContour (source->pixels, xPeak, yPeak, 0.5*SAT_TEST_LEVEL); 374 if (contour == NULL) { 375 psFree (overlap); 376 continue; 377 } 378 379 // any peaks within this contour should be dropped (mark as blend, drop after loop is done) 380 // also drop any peaks which are too close to this peak 381 psVector *xv = contour->data[0]; 382 psVector *yv = contour->data[1]; 383 for (int k = 0; k < overlap->n; k++) { 384 pmSource *testSource = overlap->data[k]; 385 float radius = hypot((testSource->peak->x - xCenter), (testSource->peak->y - yCenter)); 386 if (radius < SAT_MIN_RADIUS) { 387 testSource->mode |= PM_SOURCE_MODE_BLEND; 388 Nblend ++; 389 continue; 390 } 391 for (int j = 0; j < xv->n; j+=2) { 392 if (fabs(yv->data.F32[j] - testSource->peak->y) > 0.5) continue; 393 if (xv->data.F32[j+0] > testSource->peak->x) break; 394 if (xv->data.F32[j+1] < testSource->peak->x) break; 395 testSource->mode |= PM_SOURCE_MODE_BLEND; 396 Nblend ++; 397 j = xv->n; // skip rest of contour 398 } 399 } 400 psFree (overlap); 401 psFree (contour); 402 } 403 404 // drop the sources marked as BLEND 405 for (int i = 0; i < sources->n;) { 406 pmSource *source = sources->data[i]; 407 408 if (!(source->mode & PM_SOURCE_MODE_BLEND)) { 409 i++; 410 continue; 411 } 412 413 // shuffle the remaining sources forward 414 for (int j = i; j < sources->n - 1; j++) { 415 sources->data[j] = sources->data[j+1]; 416 } 417 psFree (source); 418 sources->n --; 419 } 420 421 psFree (SN); 422 psFree (index); 423 424 psLogMsg ("psphot", PS_LOG_INFO, "found %d satstar blend peaks, leaving %ld sources: %f sec\n", Nblend, sources->n, psTimerMark ("psphot.deblend.sat")); 425 return true; 426 }
Note:
See TracChangeset
for help on using the changeset viewer.
