/** @file ppSubMakePSF.c
 *
 *  @brief
 *
 *  @ingroup ppSub
 *
 *  @author IfA
 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
 *  @date $Date: 2009-02-18 00:31:20 $
 *  Copyright 2009 Institute for Astronomy, University of Hawaii
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <pslib.h>
#include <psmodules.h>
#include <psphot.h>

#include "ppSub.h"

bool ppSubMakePSF(pmConfig *config, const pmFPAview *view)
{
    psAssert(config, "Require configuration");
    psAssert(view, "Require view");

    psTimerStart("PPSUB_PHOT");

    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSub
    psAssert(recipe, "We checked this earlier, so it should be here.");

    if (!psMetadataLookupBool(NULL, recipe, "PHOTOMETRY")) {
        return true;
    }

    psMetadata *psphotRecipe = psMetadataLookupMetadata(NULL, config->recipes, PSPHOT_RECIPE);// psphot recipe
    psAssert(recipe, "We checked this earlier, so it should be here.");

    bool reverse = psMetadataLookupBool(NULL, config->arguments, "REVERSE"); // Reverse sense of subtraction?

    bool mdok = false;                  // Status of MD lookup
    pmReadout *minuend = NULL;          // Image that will be positive following subtraction
    pmFPAfile *minuendFile = NULL;      // File for minuend image
    if (reverse) {
        minuend = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.CONV");
        minuendFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.REF.CONV");
    } else {
        minuend = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT.CONV");
        minuendFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.INPUT.CONV");
    }

#if 1
    pmReadout *template = minuend;
    pmFPAfile *photFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.INPUT"); // Photometry file
    pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout to photometer
    if (!photRO) {
        pmCell *cell = pmFPAviewThisCell(view, photFile->fpa); // Cell to photometer
        photRO = pmReadoutAlloc(cell); // Output readout: subtraction
    }
    photRO->image = psImageCopy(photRO->image, template->image, PS_TYPE_F32);
    if (template->variance) {
        photRO->variance = psImageCopy(photRO->variance, template->variance, PS_TYPE_F32);
    } else {
        psFree(photRO->variance);
        photRO->variance = NULL;
    }
    if (template->mask) {
        photRO->mask = psImageCopy(photRO->mask, template->mask, PS_TYPE_IMAGE_MASK);
    } else {
        psFree(photRO->mask);
        photRO->mask = NULL;
    }
#else
    // Supply the minuend pmFPAfile to psphot as PSPHOT.INPUT:
    psMetadataAddPtr(config->files, PS_LIST_TAIL, "PSPHOT.INPUT", PS_DATA_UNKNOWN | PS_META_REPLACE,
                     "psphot input: view on another pmFPAfile", minuendFile);
#endif

    // Extract the loaded sources from the associated readout, and generate PSF
    // Here, we assume the image is background-subtracted
    pmReadout *sourcesRO = pmFPAfileThisReadout(config->files, view, "PPSUB.SOURCES");
    psArray *sources = psMetadataLookupPtr(&mdok, sourcesRO->analysis, "PSPHOT.SOURCES");
    if (!psphotReadoutFindPSF(config, view, sources)) {
        psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry on subtracted image.");
        return false;
    }

    // Record the FWHM in the output header
    pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT"); // Output readout
    pmHDU *hdu = pmHDUFromCell(outRO->parent); // HDU with header
    psMetadataItemSupplement(hdu->header, psphotRecipe, "FWHM_MAJ");
    psMetadataItemSupplement(hdu->header, psphotRecipe, "FWHM_MIN");

    // Get rid of the generated header; it will be regenerated by the real photometry run
    psMetadataRemoveKey(photRO->analysis, "PSPHOT.HEADER");

    return true;
}

// XXX we used to need this, is it still needed?

// pmCell *photCell = pmFPAfileThisCell(config->files, view, "PSPHOT.INPUT");
// pmCellFreeReadouts(photCell);

// if (!pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL") ||
//     !pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV") ||
//     !pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND")) {
//     psError(PS_ERR_UNKNOWN, false, "Unable to drop PSPHOT internal files.");
//     return false;
// }

// Blow away the sources psphot found --- they're irrelevant for the subtraction
// XXX is this still needed?  These are now probably not being set
// pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout with sources
// psMetadataRemoveKey(photRO->analysis, "PSPHOT.SOURCES");
// psMetadataRemoveKey(photRO->analysis, "PSPHOT.HEADER");

