IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 41968


Ignore:
Timestamp:
Dec 25, 2021, 2:22:11 PM (5 years ago)
Author:
eugene
Message:

allow option to use signal image on first pass for detections

Location:
branches/eam_branches/ipp-20211108/psphot/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20211108/psphot/src/psphot.h

    r41174 r41968  
    216216// used by psphotFindDetections
    217217pmReadout      *psphotSignificanceImage (pmReadout *readout, psMetadata *recipe, psImageMaskType maskVal);
    218 psArray        *psphotFindPeaks (pmReadout *significance, pmReadout *readout, psMetadata *recipe, const float threshold, const int nMax, int *totalPeaks);
     218psArray        *psphotFindPeaks (pmReadout *significance, pmReadout *readout, psMetadata *recipe, const float threshold, const int nMax, int *totalPeaks, bool firstPass);
    219219bool            psphotFindFootprints (pmDetections *detections, pmReadout *significance, pmReadout *readout, psMetadata *recipe, const float threshold, const int pass, psImageMaskType maskVal);
    220220psErrorCode     psphotCullPeaks(const pmReadout *readout, const pmReadout *signifRO, const psMetadata *recipe, psArray *footprints);
  • branches/eam_branches/ipp-20211108/psphot/src/psphotFindDetections.c

    r34493 r41968  
    112112    // detect the peaks in the significance image
    113113    int totalPeaks = 0;
    114     detections->peaks = psphotFindPeaks (significance, readout, recipe, threshold, NMAX, &totalPeaks);
     114    detections->peaks = psphotFindPeaks (significance, readout, recipe, threshold, NMAX, &totalPeaks, firstPass);
    115115    psMetadataAddF32  (readout->analysis, PS_LIST_TAIL, "PEAK_THRESHOLD", PS_META_REPLACE, "Peak Detection Threshold", threshold);
    116116    if (!detections->peaks) {
  • branches/eam_branches/ipp-20211108/psphot/src/psphotFindPeaks.c

    r33761 r41968  
    44// image must be constructed to represent (S/N)^2.  If nMax is non-zero, only return a maximum
    55// of nMax peaks
    6 psArray *psphotFindPeaks (pmReadout *significance, pmReadout *readout, psMetadata *recipe, const float threshold, const int nMax, int *totalPeaks) {
     6psArray *psphotFindPeaks (pmReadout *significance, pmReadout *readout, psMetadata *recipe, const float threshold, const int nMax, int *totalPeaks, bool firstPass) {
    77
    88    bool status = false;
     
    1010    psTimerStart ("psphot.peaks");
    1111
    12     // find the peaks in the smoothed image
    13     // NOTE : significance->variance actually carries the detection S/N image
    14     psArray *peaks = pmPeaksInImage (significance->variance, threshold);
    15     if (peaks == NULL) {
    16         // we only get a NULL peaks array due to a programming or config error.
    17         // this will result in a failure.
    18         psError(PSPHOT_ERR_DATA, false, "no peaks found in this image");
    19         return NULL;
     12    psArray *peaks = NULL;
     13
     14    bool useSignalImage = psMetadataLookupF32 (&status, recipe, "PEAKS_USE_SIGNAL_IMAGE"); PS_ASSERT (status, NULL);
     15
     16    if (firstPass && useSignalImage) {
     17        // find the approximate smoothed signal image that corresponds to the desired threshold
     18
     19        // find all pixels within 25% of the threshold:
     20        float minThresh = threshold * 0.80;
     21        float maxThresh = threshold * 1.25;
     22
     23        psImage *smooth_sn = significance->variance;
     24        psImage *smooth_im = significance->image;
     25
     26        psVector *SNvalues = psVectorAllocEmpty (1000, PS_TYPE_F32);
     27        for (int iy = 0; iy < smooth_im->numRows; iy++) {
     28            for (int ix = 0; ix < smooth_im->numCols; ix++) {
     29                // select all valid pixels within the S/N range
     30                if (!isfinite(smooth_sn->data.F32[iy][ix])) continue;
     31                if (!isfinite(smooth_im->data.F32[iy][ix])) continue;
     32                if (smooth_sn->data.F32[iy][ix] < minThresh) continue;
     33                if (smooth_sn->data.F32[iy][ix] > maxThresh) continue;
     34                psVectorAppend (SNvalues, smooth_im->data.F32[iy][ix]);
     35            }
     36        }
     37
     38        // what is the median of the selected values?
     39        psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     40        if (!psVectorStats(stats, SNvalues, NULL, NULL, 0)) {
     41            // psVectorStats will only fail due to a programming error (e.g., invalid vector type)
     42            psError(PSPHOT_ERR_UNKNOWN, false, "Unable to perform statistics to measure image quality");
     43            return NULL;
     44        }
     45        if (!isfinite(stats->sampleMedian)) {
     46            // could not determine relationship between SN threshold and image values
     47            // XXX fall-back could be the standard analysis above.
     48            psLogMsg ("psphot", PS_LOG_INFO, "failure to map SN to image values");
     49            goto use_significance;
     50        }
     51       
     52        float alt_threshold = stats->sampleMedian;
     53        peaks = pmPeaksInImage (significance->image, alt_threshold);
     54        if (peaks == NULL) {
     55            // we only get a NULL peaks array due to a programming or config error.
     56            // this will result in a failure.
     57            psError(PSPHOT_ERR_DATA, false, "no peaks found in this image");
     58            return NULL;
     59        }
    2060    }
     61
     62use_significance:
     63    if (!peaks) {
     64        // peaks is NULL at this point if we did not use signal image (by choice or by failure).
     65        // find the peaks in the smoothed image
     66        // NOTE : significance->variance actually carries the detection S/N image
     67        peaks = pmPeaksInImage (significance->variance, threshold);
     68        if (peaks == NULL) {
     69            // we only get a NULL peaks array due to a programming or config error.
     70            // this will result in a failure.
     71            psError(PSPHOT_ERR_DATA, false, "no peaks found in this image");
     72            return NULL;
     73        }
     74    }
     75
    2176    // return the total number of peaks found before the nMax limit is applied
    2277    if (totalPeaks) {
  • branches/eam_branches/ipp-20211108/psphot/src/psphotSignificanceImage.c

    r35688 r41968  
    105105              //              float v2 = value + PS_SQR(value/100.0);
    106106              // CZW 2013-06-20: I don't think this hack was helping.
     107              // EAM 2021-12-21: see note below about divots in the significance image
    107108              float v2 = value;
    108109              smooth_wt->data.F32[j][i] = factor * PS_SQR(v2) / smooth_wt->data.F32[j][i];
     
    122123    }
    123124    psImageConvolveSetThreads(oldThreads);
     125
     126    // We now have the significance image and the signal image.  In some cases (e.g.,
     127    // stacks), the variance on pixels in the cores of stars is elevated compared to pure
     128    // poisson statistics.  In this case, especially at high signal levels, the ratio of
     129    // signal / noise in the core of the star can be lower than the surrounding ring of
     130    // pixels.  This results in a divot in the center of the star in the significance
     131    // image.  the apparent peak of the significance is then not centered on the star and
     132    // chaos ensues.  A possible fix is to use the signal image for signficance for
     133    // the high S/N detection pass.
    124134
    125135    pmReadout *significanceRO = pmReadoutAlloc(NULL);
  • branches/eam_branches/ipp-20211108/psphot/src/psphotSourceFits.c

    r36863 r41968  
    499499
    500500# if (PS_TRACE_ON)
    501     if (psTraceGetLevel ("psphot") >= 6) {
     501    if ( (source->peak->xf > 5500) &&
     502         (source->peak->yf < 500) &&
     503         psTraceGetLevel ("psphot") >= 6) {
    502504
    503505      // Moments-based shapes parameters
     
    546548
    547549# if (PS_TRACE_ON)
    548     if (psTraceGetLevel ("psphot") >= 5) {
    549       if (psTraceGetLevel ("psphot") >= 6) {
    550         fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
    551       }
     550    if ((source->peak->xf > 5500) &&
     551        (source->peak->yf < 500) &&
     552        psTraceGetLevel ("psphot") >= 6) {
     553      fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);
    552554      fprintf (stderr, "--- fitted values ---\n");
    553555      for (int i = 0; i < model->params->n; i++) {
    554556        fprintf (stderr, "par %d: %f\n", i, model->params->data.F32[i]);
    555557      }
    556       psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
    557     }
     558    }
     559    psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0);
    558560# endif
    559561
Note: See TracChangeset for help on using the changeset viewer.