/* $Id: casu_imcore.c,v 1.5 2015/11/05 12:00:35 jim Exp $
 *
 * This file is part of the CASU Pipeline utilities
 * Copyright (C) 2015 European Southern Observatory
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * $Author: jim $
 * $Date: 2015/11/05 12:00:35 $
 * $Revision: 1.5 $
 * $Name:  $
 */

/* Includes */

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

#include <math.h>

#include "casu_mods.h"
#include "casu_utils.h"
#include "casu_wcsutils.h"
#include "casu_fits.h"
#include "catalogue/imcore.h"

/**@{*/

/*---------------------------------------------------------------------------*/
/**
    \ingroup casu_modules
    \brief Generate object catalogues from input images

    \par Name:
        casu_imcore
    \par Purpose:
        Generate object catalogues from input images
    \par Description:
        A frame and its confidence map are given. Detection thresholds and
        various other parameters are also given. Output is a table with all
        the extracted objects with object classifications included.
    \par Language:
        C
    \param infile
        The input frame with the image to be analysed
    \param conf
        The input frame with the confidence map
    \param ipix
        The minimum allowable size of an object
    \param threshold
        The detection threshold in sigma above sky
    \param icrowd
        If set then the deblending software will be used
    \param rcore
        The core radius in pixels
    \param nbsize
        The smoothing box size for background map estimation
    \param cattype
        The type of catalogue to be produced
    \param filtfwhm
        The FWHM of the smoothing kernel in the detection algorithm
    \param outtab
        The output table of object
    \param gainloc
        The detector gain in e-/ADU
    \param status
        The input/output status that has the same return value a below
    \retval CASU_OK 
        if everything is ok
    \retval CASU_WARN,CASU_FATAL
        errors in the called routines
    \par QC headers:
        The following values will go into the extension propertylist
        - \b SATURATION
            Saturation level in ADU
        - \b MEAN_SKY
            Mean sky brightness in ADU
        - \b SKY_NOISE
            Pixel noise at sky level in ADU
        - \b IMAGE_SIZE
            The average FWHM of stellar objects in arcsec
        - \b ELLIPTICITY
            The average stellar ellipticity (1 - b/a)
        - \b POSANG
             The average position angle in degrees from North towards East.
             NB: this value only makes sense if the ellipticity is significant
        - \b APERTURE_CORR
            The stellar aperture correction for 1x core flux
        - \b NOISE_OBJ
            The number of noise objects
    \par DRS headers:
        The following values will go into the extension propertylist
        - \b THRESHOL
            The detection threshold in ADU
        - \b MINPIX 
            The minimum number of pixels per image
        - \b CROWDED
            Flag for crowded field analysis
        - \b RCORE
            The core radius for default profile fit in pixels
        - \b FILTFWHM
            The FWHM of the smoothing kernel in the detection algorithm
        - \b SEEING
            The average FWHM of stellar objects in pixels
        - \b XCOL
            The column containing the X position
        - \b YCOL
            The column containing the Y position
        - \b NXOUT
            The X dimension of the original image array
        - \b NYOUT
            The Y dimension of the original image array
        - \b CLASSIFD
            A flag to say that the catalgoue has been classified
        - \b SKYLEVEL
            Mean sky brightness in ADU
        - \b SKYNOISE
            Pixel noise at sky level in ADU
        - \b IMAGE_SIZE
            The average FWHM of stellar objects in arcsec
    \par Other headers:
        The following values will go into the extension propertylist
        - \b APCORxx
            A series of aperture correction values for each of the core
            radius apertures.
        - \b SYMBOLx
            A series of keywords to be used by GAIA for plotting ellipses
    \author
        Jim Lewis, CASU

 */
/*---------------------------------------------------------------------------*/

extern int casu_imcore(casu_fits *infile, casu_fits *conf, int ipix,
                       float threshold, int icrowd, float rcore, int nbsize,
                       int cattype, float filtfwhm, casu_tfits **outtab, 
                       float gainloc, int *status) {
    int retval;
    const char *fctid = "casu_imcore";
    cpl_propertylist *plist,*elist;
    casu_fits *in,*c;
    double theta_east,*cd,theta_north,theta_north_2,pixarcsec;
    float fwhm,fitpa,ell;
    cpl_wcs *wcs;

    /* Inherited status */

    *outtab = NULL;
    if (*status != CASU_OK)
        return(*status);

    /* Copy the input */

    in = casu_fits_duplicate(infile);
    c = casu_fits_duplicate(conf);

    /* Call the main processing routine and get the catalogue */


    retval = imcore_conf(in,c,ipix,threshold,icrowd,rcore,nbsize,cattype,
                         filtfwhm,gainloc,outtab);
    casu_fits_delete(in);
    casu_fits_delete(c);
    if (retval != CASU_OK)
        FATAL_ERROR;
    if ((int)cpl_table_get_nrow(casu_tfits_get_table(*outtab)) == 0) {
        cpl_msg_warning(fctid,"No objects found in %s",
                        casu_fits_get_fullname(infile));
        freetfits(*outtab);
        WARN_RETURN
    }

    /* Get the property list from the input frame */

    plist = casu_fits_get_phu(infile);
    if (plist == NULL) {
        cpl_msg_error(fctid,"Unable to open propertylist %s",
                      casu_fits_get_filename(infile));
        FATAL_ERROR
    }

    /* Do the classification */

    if (cattype != 3) {
        retval = imcore_classify(*outtab,16.0,cattype);
        if (retval != CASU_OK) 
            WARN_RETURN

        /* Convert the QC FWHM value to arcsec */

        elist = casu_fits_get_ehu(infile);
        wcs = cpl_wcs_new_from_propertylist(elist);
        cd = cpl_matrix_get_data((cpl_matrix *)cpl_wcs_get_cd(wcs));
        pixarcsec = 3600.0*sqrt(fabs(cd[0]*cd[3] - cd[1]*cd[2]));
        cpl_wcs_delete((cpl_wcs *)wcs); 
        fwhm = cpl_propertylist_get_float(casu_tfits_get_ehu(*outtab),
                                             "ESO QC IMAGE_SIZE");
        if (fwhm != -1.0) 
            fwhm *= pixarcsec;
        casu_propertylist_update_float(casu_tfits_get_ehu(*outtab),
                                       "ESO QC IMAGE_SIZE",fwhm);
        cpl_propertylist_set_comment(casu_tfits_get_ehu(*outtab),
                                     "ESO QC IMAGE_SIZE",
                                     "[arcsec] Average FWHM of stellar objects");
        casu_propertylist_update_float(elist,"ESO DRS IMAGE_SIZE",fwhm);
        cpl_propertylist_set_comment(elist,"ESO DRS IMAGE_SIZE",
                                     "[arcsec] Average FWHM of stellar objects");

        /* Now convert the median position angle estimate to degrees from 
           North in an Easterly direction...*/

        fitpa = cpl_propertylist_get_float(casu_tfits_get_ehu(*outtab),
                                           "ESO QC POSANG");
        if (fitpa != 0.0) {
            wcs = cpl_wcs_new_from_propertylist(elist);
            cd = cpl_matrix_get_data((cpl_matrix *)cpl_wcs_get_cd(wcs));
            theta_east = DEGRAD*atan2(cd[1],cd[0]);
            theta_north = DEGRAD*atan2(cd[3],cd[2]);
            theta_north_2 = (theta_north < 0.0 ? theta_north + 360.0 : theta_north);
            if (fabs(theta_north-theta_east-90.0) < 5.0 ||
                fabs(theta_north-theta_east+270.0) < 5.0) {
                fitpa = theta_north_2 - fitpa;
            } else {
                fitpa = 360.0 - theta_north_2 + fitpa;
            }
            if (fitpa < 0.0)
                fitpa += 360.0;
            if (fitpa > 180.0)
                fitpa -= 180.0;
            cpl_wcs_delete((cpl_wcs *)wcs);
            cpl_propertylist_update_float(casu_tfits_get_ehu(*outtab),
                                          "ESO QC POSANG",fitpa);
            cpl_propertylist_set_comment(casu_tfits_get_ehu(*outtab),
                                         "ESO QC POSANG",
                                         "[degrees] Median position angle (from North)");
        }

        /* Add a few things to help with PhaseIII deliverables */

        casu_propertylist_update_float(casu_tfits_get_ehu(*outtab),"PSF_FWHM",
                                       fwhm);
        cpl_propertylist_set_comment(casu_tfits_get_ehu(*outtab),"PSF_FWHM",
                                     "[arcsec] spatial resolution");
        casu_propertylist_update_float(casu_fits_get_ehu(infile),"PSF_FWHM",
                                       fwhm);
        cpl_propertylist_set_comment(casu_fits_get_ehu(infile),"PSF_FWHM",
                                     "[arcsec] spatial resolution");
        ell = cpl_propertylist_get_float(casu_tfits_get_ehu(*outtab),
                                         "ESO QC ELLIPTICITY");
        casu_propertylist_update_float(casu_fits_get_ehu(infile),"ELLIPTIC",
                                       ell);
        cpl_propertylist_set_comment(casu_fits_get_ehu(infile),"ELLIPTIC",
                                     "average ellipticity of point sources");
        casu_propertylist_update_float(casu_tfits_get_ehu(*outtab),"ELLIPTIC",
                                       ell);
        cpl_propertylist_set_comment(casu_tfits_get_ehu(*outtab),"ELLIPTIC",
                                     "average ellipticity of point sources");
    }
    GOOD_STATUS
}

/**@}*/

/*

$Log: casu_imcore.c,v $
Revision 1.5  2015/11/05 12:00:35  jim
*** empty log message ***

Revision 1.4  2015/09/30 08:33:06  jim
superficial changes

Revision 1.3  2015/08/12 11:20:23  jim
changed call to imcore procedure names where necessary

Revision 1.2  2015/08/07 13:06:54  jim
Fixed copyright to ESO

Revision 1.1.1.1  2015/06/12 10:44:32  jim
Initial import

Revision 1.6  2015/02/14 12:31:45  jim
Modified the way some stuff is written to headers

Revision 1.5  2015/01/29 11:51:56  jim
modified comments

Revision 1.4  2015/01/09 12:13:15  jim
*** empty log message ***

Revision 1.3  2014/12/11 12:23:33  jim
new version

Revision 1.2  2013/11/21 09:38:14  jim
detabbed

Revision 1.1.1.1  2013-08-27 12:07:48  jim
Imported


*/
