In this loop, we look for strings of CRpixels on the same row and adjoining columns; each of these becomes a Span with a unique ID.
321 {
322 typedef typename MaskedImageT::Image ImageT;
323 typedef typename ImageT::Pixel ImagePixel;
324 typedef typename MaskedImageT::Mask::Pixel MaskPixel;
325
326
327 double const minSigma = ps.getAsDouble("minSigma");
328 double const minDn = ps.getAsDouble("min_DN");
329 double const cond3Fac = ps.getAsDouble("cond3_fac");
330 double const cond3Fac2 = ps.getAsDouble("cond3_fac2");
331 int const niteration = ps.getAsInt("niteration");
332
333 int const nCrPixelMax = ps.getAsInt("nCrPixelMax");
334
335
336
337
338
340 if (!kernel) {
341 throw LSST_EXCEPT(pexExcept::NotFoundError,
"Psf is unable to return a kernel");
342 }
345 kernel->computeImage(psfImage, true);
346
347 int const xc = kernel->getCtr().getX();
348 int const yc = kernel->getCtr().getY();
349
350 double const I0 = psfImage(xc, yc);
351 double const thresH =
352 cond3Fac2 * (0.5 * (psfImage(xc - 1, yc) + psfImage(xc + 1, yc))) / I0;
353 double const thresV = cond3Fac2 * (0.5 * (psfImage(xc, yc - 1) + psfImage(xc, yc + 1))) / I0;
354 double const thresD = cond3Fac2 *
355 (0.25 * (psfImage(xc - 1, yc - 1) + psfImage(xc + 1, yc + 1) +
356 psfImage(xc - 1, yc + 1) + psfImage(xc + 1, yc - 1))) /
357 I0;
358
359
360
361 MaskPixel const badBit = mimage.getMask()->getPlaneBitMask("BAD");
362 MaskPixel const crBit = mimage.getMask()->getPlaneBitMask("CR");
363 MaskPixel const interpBit = mimage.getMask()->getPlaneBitMask("INTRP");
364 MaskPixel const saturBit = mimage.getMask()->getPlaneBitMask("SAT");
365 MaskPixel const nodataBit = mimage.getMask()->getPlaneBitMask("NO_DATA");
366
367 MaskPixel const badMask = (badBit | interpBit | saturBit | nodataBit);
368
369
370
371 int const ncol = mimage.getWidth();
372 int const nrow = mimage.getHeight();
373
377
378 for (int j = 1; j < nrow - 1; ++j) {
379 typename MaskedImageT::xy_locator loc = mimage.xy_at(1, j);
380
381 for (int i = 1; i < ncol - 1; ++i, ++loc.x()) {
382 ImagePixel corr = 0;
383 if (!is_cr_pixel<MaskedImageT>(&corr, loc, minSigma, thresH, thresV, thresD, bkgd, cond3Fac)) {
384 continue;
385 }
386
387
388
389 if (loc.mask() & badMask) {
390 continue;
391 }
392 if ((loc.mask(-1, 1) | loc.mask(0, 1) | loc.mask(1, 1) | loc.mask(-1, 0) | loc.mask(1, 0) |
393 loc.mask(-1, -1) | loc.mask(0, -1) | loc.mask(1, -1)) &
394 interpBit) {
395 continue;
396 }
397
398
399
400
401
402
403 crpixels.
push_back(CRPixel<ImagePixel>(i + mimage.getX0(), j + mimage.getY0(), loc.image()));
404 loc.image() = corr;
405
406 if (
static_cast<int>(crpixels.
size()) > nCrPixelMax) {
407 reinstateCrPixels(mimage.getImage().get(), crpixels);
408
410 (boost::format(
"Too many CR pixels (max %d)") % nCrPixelMax).
str());
411 }
412 }
413 }
414
415
416
417
418 std::vector<int> aliases;
420
421 std::vector<afw::detection::IdSpan::Ptr> spans;
423
425
430
431 int ncr = 0;
432 if (!crpixels.
empty()) {
433 int id;
434 int x0 = -1, x1 = -1,
y = -1;
435
436
437 CRPixel<ImagePixel> dummy(0, -1, 0, -1);
439
440
441 for (crpixel_iter crp = crpixels.
begin(); crp < crpixels.
end() - 1; ++crp) {
442
443
444
445 if (crp->id < 0) {
446 crp->id = ++ncr;
449 x0 = x1 = crp->col;
450
451 }
452 id = crp->id;
453
454
455
456 if (crp[1].row == crp[0].row && crp[1].col == crp[0].col + 1) {
457
458 crp[1].id = id;
459 ++x1;
460 } else {
461 assert(y >= 0 && x0 >= 0 && x1 >= 0);
463
464 }
465 }
466 }
467
468
469
470 if (crpixels.
size() > 0) {
471 for (crpixel_iter cp = crpixels.
begin(); cp != crpixels.
end() - 1; cp++) {
472 assert(cp->id >= 0);
473 assert(cp->col >= 0);
474 assert(cp->row >= 0);
475 }
476
477 assert(crpixels[crpixels.
size() - 1].id == -1);
478 assert(crpixels[crpixels.
size() - 1].col == 0);
479 assert(crpixels[crpixels.
size() - 1].row == -1);
480 }
481
482 for (std::vector<afw::detection::IdSpan::Ptr>::iterator sp = spans.
begin(), end = spans.
end(); sp != end;
483 sp++) {
484 assert((*sp)->id >= 0);
485 assert((*sp)->y >= 0);
486 assert((*sp)->x0 >= 0);
487 assert((*sp)->x1 >= (*sp)->x0);
488 for (std::vector<afw::detection::IdSpan::Ptr>::iterator sp2 = sp + 1; sp2 !=
end; sp2++) {
489 assert((*sp2)->y >= (*sp)->y);
490 if ((*sp2)->y == (*sp)->y) {
491 assert((*sp2)->x0 > (*sp)->x1);
492 }
493 }
494 }
495
496
497
498
499 for (std::vector<afw::detection::IdSpan::Ptr>::iterator sp = spans.
begin(), end = spans.
end(); sp != end;
500 ++sp) {
501 int const y = (*sp)->y;
502 int const x0 = (*sp)->x0;
503 int const x1 = (*sp)->x1;
504
505
506 for (std::vector<afw::detection::IdSpan::Ptr>::iterator sp2 = sp + 1; sp2 !=
end; ++sp2) {
507 if ((*sp2)->y == y) {
508
509
510 continue;
511 } else if ((*sp2)->y != (y + 1)) {
512
513 break;
514 } else if ((*sp2)->x0 > (x1 + 1)) {
515
516 break;
517 } else if ((*sp2)->x1 >= (x0 - 1)) {
518
521 aliases[r1] = r2;
522 }
523 }
524 }
525
526
527
528
529 for (
unsigned int i = 0; i != spans.
size(); ++i) {
531 }
532
533
534
535
536 if (spans.
size() > 0) {
538 }
539
540
541
542
543 std::vector<std::shared_ptr<afw::detection::Footprint>> CRs;
544
545 if (spans.
size() > 0) {
546 int id = spans[0]->id;
547 unsigned int i0 = 0;
548 for (
unsigned int i = i0; i <= spans.
size(); ++i) {
549 if (i == spans.
size() || spans[i]->id !=
id) {
550 std::shared_ptr<afw::detection::Footprint> cr(new afw::detection::Footprint());
551
552 std::vector<afw::geom::Span> spanList;
554 for (; i0 < i; ++i0) {
555 spanList.
push_back(afw::geom::Span(spans[i0]->y, spans[i0]->x0, spans[i0]->x1));
556 }
559 }
560
561 if (i < spans.
size()) {
562 id = spans[i]->id;
563 }
564 }
565 }
566
567 reinstateCrPixels(mimage.getImage().get(), crpixels);
568
569
570
571 CountsInCR<typename ImageT::Pixel> CountDN(bkgd);
572 for (std::vector<std::shared_ptr<afw::detection::Footprint>>::iterator cr = CRs.
begin(), end = CRs.
end();
573 cr != end; ++cr) {
574
575 (*cr)->getSpans()->applyFunctor(CountDN, *mimage.getImage());
576
577 LOGL_DEBUG(
"TRACE4.lsst.algorithms.CR",
"CR at (%d, %d) has %g DN", (*cr)->getBBox().getMinX(),
578 (*cr)->getBBox().getMinY(), CountDN.getCounts());
579 if (CountDN.getCounts() < minDn) {
580 LOGL_DEBUG(
"TRACE5.lsst.algorithms.CR",
"Erasing CR");
581
583 --cr;
585 }
586 CountDN.reset();
587 }
589
590
591
592 bool const debias_values = true;
593 bool grow = false;
594 LOGL_DEBUG(
"TRACE2.lsst.algorithms.CR",
"Removing initial list of CRs");
595 removeCR(mimage, CRs, bkgd, crBit, saturBit, badMask, debias_values, grow);
596#if 0
597 (void)setMaskFromFootprintList(mimage.getMask().get(), CRs,
598 mimage.getMask()->getPlaneBitMask("DETECTED"));
599#endif
600
601
602
603
604
605
606
607 bool too_many_crs = false;
608 int nextra = 0;
609 for (int i = 0; i != niteration && !too_many_crs; ++i) {
610 LOGL_DEBUG(
"TRACE1.lsst.algorithms.CR",
"Starting iteration %d", i);
611 for (std::vector<std::shared_ptr<afw::detection::Footprint>>::iterator fiter = CRs.
begin();
612 fiter != CRs.
end(); fiter++) {
613 std::shared_ptr<afw::detection::Footprint> cr = *fiter;
614
615
616
617 {
618
619
620
621
623 int const npix = (om) ? om->getArea() : 0;
624
625 if (
static_cast<std::size_t>(npix) == cr->getArea()) {
626 continue;
627 }
628 }
629
630
631
632 afw::detection::Footprint extra;
633 for (auto siter = cr->getSpans()->begin(); siter != cr->getSpans()->end(); siter++) {
634 auto const span = siter;
635
636
637
638
639
640
641
642 int const y = span->getY() - mimage.getY0();
643 if (y < 2 || y >= nrow - 2) {
644 continue;
645 }
646 int x0 = span->getX0() - mimage.getX0();
647 int x1 = span->getX1() - mimage.getX0();
648 x0 = (x0 < 2) ? 2 : (x0 > ncol - 3) ? ncol - 3 : x0;
649 x1 = (x1 < 2) ? 2 : (x1 > ncol - 3) ? ncol - 3 : x1;
650
651 checkSpanForCRs(&extra, crpixels, y - 1, x0, x1, mimage, minSigma / 2, thresH, thresV, thresD,
652 bkgd, 0, keep);
653 checkSpanForCRs(&extra, crpixels, y, x0, x1, mimage, minSigma / 2, thresH, thresV, thresD,
654 bkgd, 0, keep);
655 checkSpanForCRs(&extra, crpixels, y + 1, x0, x1, mimage, minSigma / 2, thresH, thresV, thresD,
656 bkgd, 0, keep);
657 }
658
659 if (extra.getSpans()->size() > 0) {
660 if (nextra +
static_cast<int>(crpixels.
size()) > nCrPixelMax) {
661 too_many_crs = true;
662 break;
663 }
664
665 nextra += extra.getArea();
666
667 std::vector<afw::geom::Span> tmpSpanList(cr->getSpans()->begin(), cr->getSpans()->end());
668 for (auto const &spn : (*extra.getSpans())) {
669 tmpSpanList.push_back(spn);
670 }
672 }
673 }
674
675 if (nextra == 0) {
676 break;
677 }
678 }
679
680
681
682 if (!too_many_crs) {
683 for (auto const &foot : CRs) {
684 foot->getSpans()->setMask(*mimage.getMask().get(), crBit);
685 }
686 }
687
688
689
690
691
692
693
694 if (keep || too_many_crs) {
695 if (crpixels.
size() > 0) {
696 int const imageX0 = mimage.getX0();
697 int const imageY0 = mimage.getY0();
698
700
701 crpixel_riter rend = crpixels.
rend();
702 for (crpixel_riter crp = crpixels.
rbegin(); crp != rend; ++crp) {
703 if (crp->row == -1)
704
705 continue;
706 mimage.at(crp->col - imageX0, crp->row - imageY0).image() = crp->val;
707 }
708 }
709 } else {
710 if (true || nextra > 0) {
711 grow = true;
712 LOGL_DEBUG(
"TRACE2.lsst.algorithms.CR",
"Removing final list of CRs, grow = %d", grow);
713 removeCR(mimage, CRs, bkgd, crBit, saturBit, badMask, debias_values, grow);
714 }
715
716
717
718 for (auto const &foot : CRs) {
719 foot->getSpans()->setMask(*mimage.getMask().get(),
static_cast<MaskPixel>(crBit | interpBit));
720 }
721 }
722
723 if (too_many_crs) {
725 (boost::format(
"Too many CR pixels (max %d)") % nCrPixelMax).
str());
726 }
727
728 return CRs;
729}
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
std::shared_ptr< IdSpan > Ptr
image::Image< Pixel > Image
Image type returned by computeImage.
int resolve_alias(const std::vector< int > &aliases, int id)
Follow a chain of aliases, returning the final resolved value.
decltype(sizeof(void *)) size_t