# include "psphotInternal.h"

// in this psphotReadout-variant, we are only trying to determine the PSF given an existing set
// of input source positions to use as initial PSF stars.
bool psphotReadoutFindPSF(pmConfig *config, const pmFPAview *view) {

    // measure the total elapsed time in psphotReadout.  XXX the current threading plan
    // for psphot envisions threading within psphotReadout, not multiple threads calling
    // the same psphotReadout.  In the current plan, this dtime is the elapsed time used
    // jointly by the multiple threads, not the total time used by all threads.
    psTimerStart ("psphotReadout");

    // select the current recipe
    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
    if (!recipe) {
        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE);
        return false;
    }

    // find the currently selected readout
    pmReadout  *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT");
    PS_ASSERT_PTR_NON_NULL (readout, false);

    // Generate the mask and weight images, including the user-defined analysis region of interest
    psphotSetMaskAndWeight (config, readout, recipe);

    // display the image, weight, mask (ch 1,2,3)
    psphotVisualShowImage (readout);

    // include externally-supplied sources
    // XXX this requires sources to be supplied as PSPHOT.INPUT.CMF
    pmDetections *detections = psphotLoadPSFSources (config, view);
    if (!detections || !detections->peaks) {
        psError(PSPHOT_ERR_ARGUMENTS, true, "Can't find PSF stars");
        return psphotReadoutCleanup(config, readout, recipe, detections, NULL, NULL);
    }

    // construct sources and measure basic stats (moments, local sky)
    psArray *sources = psphotSourceStats(readout, recipe, detections);
    if (!sources) return false;

    // mark all sources as PSFSTAR
    for (int i = 0; i < sources->n; i++) {
      pmSource *source = sources->data[i];
      source->type = PM_SOURCE_TYPE_STAR;
      source->mode |= PM_SOURCE_MODE_PSFSTAR;
    }

    pmPSF *psf = psphotChoosePSF(readout, sources, recipe);
    if (!psf) {
        psError(PSPHOT_ERR_PSF, false, "Failed to construct a psf model");
        psFree(sources);
        return psphotReadoutCleanup(config, readout, recipe, detections, NULL, NULL);
    }
    psphotVisualShowPSFModel(readout, psf);

    // drop the references to the image pixels held by each source
    psphotSourceFreePixels(sources);
    psFree(sources);

    // create the exported-metadata and free local data
    return psphotReadoutCleanup(config, readout, recipe, detections, psf, NULL);
}
