IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 42088


Ignore:
Timestamp:
Feb 28, 2022, 2:40:32 PM (4 years ago)
Author:
eugene
Message:

for bright stars in stacks, the peak in the S/N image can have a central divot if the variance of the central pixels is relatively large compared to the ring of pixels further from the center. the detected peaks are then not well centered. this can be avoided if we detect on the signal image itself (after first determining an appropriate flux value for the desired S/N limit); added an option to use the signal image for the first pass peak detetion step

Location:
trunk/psphot
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot

  • trunk/psphot/src/psphot.h

    r41174 r42088  
    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);
  • trunk/psphot/src/psphotFindDetections.c

    r34493 r42088  
    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) {
  • trunk/psphot/src/psphotFindPeaks.c

    r33761 r42088  
    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            psFree (SNvalues);
     44            return NULL;
     45        }
     46        psFree (SNvalues);
     47
     48        if (!isfinite(stats->sampleMedian)) {
     49            // could not determine relationship between SN threshold and image values
     50            // XXX fall-back could be the standard analysis above.
     51            psLogMsg ("psphot", PS_LOG_INFO, "failure to map SN to image values");
     52            psFree (stats);
     53            goto use_significance;
     54        }
     55       
     56        float alt_threshold = stats->sampleMedian;
     57        psFree (stats);
     58
     59        peaks = pmPeaksInImage (significance->image, alt_threshold);
     60        if (peaks == NULL) {
     61            // we only get a NULL peaks array due to a programming or config error.
     62            // this will result in a failure.
     63            psError(PSPHOT_ERR_DATA, false, "no peaks found in this image");
     64            return NULL;
     65        }
    2066    }
     67
     68use_significance:
     69    if (!peaks) {
     70        // peaks is NULL at this point if we did not use signal image (by choice or by failure).
     71        // find the peaks in the smoothed image
     72        // NOTE : significance->variance actually carries the detection S/N image
     73        peaks = pmPeaksInImage (significance->variance, threshold);
     74        if (peaks == NULL) {
     75            // we only get a NULL peaks array due to a programming or config error.
     76            // this will result in a failure.
     77            psError(PSPHOT_ERR_DATA, false, "no peaks found in this image");
     78            return NULL;
     79        }
     80    }
     81
    2182    // return the total number of peaks found before the nMax limit is applied
    2283    if (totalPeaks) {
  • trunk/psphot/src/psphotFitSourcesLinear.c

    r41444 r42088  
    217217    int Nsat = 0;
    218218
     219    // track number kept at several stages of the analysis
     220    int Nstep_0 = 0;
     221    int Nstep_1 = 0;
     222    int Nstep_2 = 0;
     223    int Nstep_3 = 0;
     224    int Nstep_4 = 0;
     225    int Nstep_5 = 0;
     226
    219227    // select the sources which will be used for the fitting analysis
    220228    for (int i = 0; i < sources->n; i++) {
     
    246254        if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue;
    247255
     256        Nstep_0++;
     257
    248258        // XXX count saturated stars
    249259        if (source->mode & PM_SOURCE_MODE_SATSTAR) {
     
    255265            if (!pmSourceCacheModel (source, maskVal)) continue;
    256266        }
     267        Nstep_1++;
    257268
    258269        // save the original coords
     
    265276        if (x > AnalysisRegion.x1) continue;
    266277        if (y > AnalysisRegion.y1) continue;
     278        Nstep_2++;
    267279
    268280        // check the integral of the model : is it large enough?
     
    283295            continue;
    284296        }
     297        Nstep_3++;
     298
    285299        bool isPSF = false;
    286300        pmModel *model = pmSourceGetModel (&isPSF, source);
     
    306320        }
    307321        if (modelSum  < cutModelSum * normFlux) continue;
     322        Nstep_4++;
     323
    308324        if (maskedSum < cutMaskedSum * normFlux) continue;
     325        Nstep_5++;
    309326
    310327        // clear the 'mark' pixels and remask on the fit aperture
     
    322339    }
    323340    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), sources->n);
     341    psLogMsg ("psphot.ensemble", PS_LOG_INFO, "Number of sources kept at each stage: %d %d %d %d %d %d\n", Nstep_0, Nstep_1, Nstep_2, Nstep_3, Nstep_4, Nstep_5);
    324342
    325343    if (fitSources->n == 0) {
  • trunk/psphot/src/psphotSignificanceImage.c

    r35688 r42088  
    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);
  • trunk/psphot/src/psphotSourceFits.c

    r36863 r42088  
    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.