# include "psphotInternal.h"

// Find peaks in the significance image above a threshold significance level.  The significance
// image must be constructed to represent (S/N)^2.  If nMax is non-zero, only return a maximum
// of nMax peaks
psArray *psphotFindPeaks (psImage *significance, pmReadout *readout, psMetadata *recipe, const float threshold, const int nMax) {

    bool status = false;

    psTimerStart ("peaks");

    // find the peaks in the smoothed image
    psArray *peaks = pmPeaksInImage (significance, threshold);
    if (peaks == NULL) {
	// XXX should we be sending back an empty array instead of NULL?
        // XXX this may also be due to a programming or config error
        // XXX do we need to set something in the readout->analysis to indicate that
        // we tried and failed to find peaks (something in the header data)
        psError(PSPHOT_ERR_DATA, false, "no peaks found in this image");
        return false;
    }

    // correct the peak values to S/N = sqrt(significance)
    // get the peak flux from the unsmoothed image
    // the peak pixel coords are guaranteed to be on the image
    int row0 = readout->image->row0;
    int col0 = readout->image->col0;
    for (int i = 0; i < peaks->n; i++) {
        pmPeak *peak = peaks->data[i];
        peak->SN = sqrt(peak->value);
        peak->flux = readout->image->data.F32[peak->y-row0][peak->x-col0];
    }

    // limit the total number of returned peaks as specified
    psArraySort (peaks, pmPeakSortBySN);
    if (nMax && (peaks->n > nMax)) {
	psArray *tmpPeaks = psArrayAllocEmpty (nMax);
	for (int i = 0; i < nMax; i++) {
	    psArrayAdd (tmpPeaks, 100, peaks->data[i]);
	}
	psFree (peaks);
	peaks = tmpPeaks;
    }

    // optional dump of all peak data 
    char *output = psMetadataLookupStr (&status, recipe, "PEAKS_OUTPUT_FILE");
    if (output && strcasecmp (output, "NONE")) {
        pmPeaksWriteText (peaks, output);
    }
    psLogMsg ("psphot", PS_LOG_INFO, "%ld peaks: %f sec\n", peaks->n, psTimerMark ("peaks"));

    return peaks;

}
