/* $Id: naco_strehl.c,v 1.22 2008-04-18 00:25:30 llundin Exp $
 *
 * This file is part of the NACO Pipeline
 * Copyright (C) 2002,2003 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., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
 */

/*
 * $Author: llundin $
 * $Date: 2008-04-18 00:25:30 $
 * $Revision: 1.22 $
 * $Name: not supported by cvs2svn $
 */

#define HDRL_USE_EXPERIMENTAL

/*-----------------------------------------------------------------------------
                                   Includes
 -----------------------------------------------------------------------------*/

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

#include "naco_strehl.h"
#include "naco_parameter.h"

#include "irplib_strehl.h"

#ifdef HDRL_USE_EXPERIMENTAL
#include "hdrl.h"
#endif

/*----------------------------------------------------------------------------*/
/**
 * @defgroup naco_strehl  STREHL related functions
 *
 * TBD
 */
/*----------------------------------------------------------------------------*/

/**@{*/

/*----------------------------------------------------------------------------*/
/**
  @brief    Compute the strehl ratio in an image
  @param    self           Image with pixel-type float
  @param    parlist        The recipe parameter list
  @param    recipename     The recipe name
  @param    lam            Central wavelength [micron]
  @param    dlam           Filter bandwidth [micron]
  @param    pos_x          Object X-position [pixel]
  @param    pos_y          Object Y-position [pixel]
  @param    pixscale       The pixel scale (from the header)
  @param    pstrehl        Pointer to the Strehl Error (positive on success)
  @param    pstrehl_err    Pointer to the Strehl Error (non-negative on success)
  @param    pstar_bg       Pointer to the Star Background
  @param    pstar_peak     Pointer to the Star Peak (positive on success)
  @param    pstar_flux     Pointer to the Star Flux (positive on success)
  @param    ppsf_peak      Pointer to the PSF Peak (positive on success)
  @param    ppsf_flux      Pointer to the PSF Flux (1 on success)
  @param    pbg_noise      Pointer to the Background Noise
  @return   CPL_ERROR_NONE or the relevant CPL error code on error

 */
/*----------------------------------------------------------------------------*/
cpl_error_code naco_strehl_compute(const cpl_image         * self,
                                   const cpl_parameterlist * parlist,
                                   const char *              recipename,
                                   double                    lam,
                                   double                    dlam,
                                   double   pos_x,
                                   double   pos_y,
                                   double   pixscale,
                                   double * pstrehl,
                                   double * pstrehl_err,
                                   double * pstar_bg,
                                   double * pstar_peak,
                                   double * pstar_flux,
                                   double * ppsf_peak,
                                   double * ppsf_flux,
                                   double * pbg_noise)
{

    cpl_errorstate cleanstate = cpl_errorstate_get();
    const double r1 = naco_parameterlist_get_double(parlist, recipename,
                                                    NACO_PARAM_STAR_R);
    const double r2 = naco_parameterlist_get_double(parlist, recipename,
                                                    NACO_PARAM_BG_RINT);
    const double r3 = naco_parameterlist_get_double(parlist, recipename,
                                                    NACO_PARAM_BG_REXT);

#ifdef HDRL_USE_EXPERIMENTAL
    hdrl_parameter   * hdrl_param = NULL;
    hdrl_strehl_result hdrl_strehl;
    hdrl_image       * hdrl_self = NULL;

#endif

    skip_if(irplib_strehl_compute(self,
                                  IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
                                  lam, dlam,
                                  pixscale,
                                  IRPLIB_STREHL_BOX_SIZE, 
                                  pos_x, 
                                  pos_y, 
                                  r1, r2, r3,                          
                                  -1, -1,
                                  pstrehl,
                                  pstrehl_err,
                                  pstar_bg,
                                  pstar_peak,
                                  pstar_flux,
                                  ppsf_peak,
                                  ppsf_flux,
                                  pbg_noise));

#ifdef HDRL_USE_EXPERIMENTAL

    hdrl_self = hdrl_image_create(self, NULL);

    skip_if (hdrl_self == NULL);

    /* HDRL uses SI (m) and the mirror dimensions are given as radii */
    hdrl_param = hdrl_strehl_parameter_create(lam * 1e-6,
                                              IRPLIB_STREHL_M1 * 0.5,
                                              IRPLIB_STREHL_M2 * 0.5,
                                              pixscale, pixscale,
                                              r1, r2, r3);
    if (hdrl_param != NULL)
        hdrl_strehl = hdrl_strehl_compute(hdrl_self, hdrl_param);

    if (!cpl_errorstate_is_equal(cleanstate)) {
        irplib_error_recover(cleanstate, "HDRL Strehl computation failed "
                             "(keeping %g)", *pstrehl);
    } else if (0.0 < *pstrehl && *pstrehl < 1.0 &&
               (hdrl_strehl.strehl_value.data <= 0.0 ||
                hdrl_strehl.strehl_value.data >= 1.0)) {
        cpl_msg_warning(cpl_func, "Ignoring suspicious HDRL Strehl: %g "
                        "(keeping %g)", hdrl_strehl.strehl_value.data,
                        *pstrehl);
    } else {
        cpl_msg_info(cpl_func, "Changing Strehl: %g -> %g",
                     *pstrehl, hdrl_strehl.strehl_value.data);
        *pstrehl     = hdrl_strehl.strehl_value.data;
    }

#endif

    end_skip;

#ifdef HDRL_USE_EXPERIMENTAL
    hdrl_parameter_delete(hdrl_param);
    hdrl_image_delete(hdrl_self);
#endif

    return cpl_error_get_code();
}

/**@}*/
