/*********************************************************************
 * E.S.O. - VLT project
 *
 * "@(#) $Id: kmclipm_priv_reconstruct.h,v 1.10 2013-10-08 14:55:01 erw Exp $"
 *
 * Functions that are implemented as recipes. They are also useedd in KMOS
 * data reduction pipeline.
 *
 * who       when        what
 * --------  ----------  ----------------------------------------------
 */

#ifndef KMCLIPM_PRIV_RECONSTRUCT_H
#define KMCLIPM_PRIV_RECONSTRUCT_H

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

#include "kmclipm_functions.h"

/*-----------------------------------------------------------------------------
 *              Types
 *-----------------------------------------------------------------------------*/

/**
    @brief Available error LUT handling methods.

    - LUT_MODE_NONE:   no LUT stored, uses CPU resources (slowest method)
    - LUT_MODE_MEMORY: memory based LUT only, initial LUT is calculated, uses
                       system memory resources
    - LUT_MODE_FILE:   file based LUT only, initial LUT is calculated and stored
                       in file uses file system resources
    - LUT_MODE_BOTH:   memory based LUT, file is used as well: Initial LUT is
                       read from file if available otherwise it is calculated
                       and written to file uses system memory and file system
                       resources

    default: LUT_MODE_FILE
*/
enum nn_lut_mode_type {
    LUT_MODE_NONE,
    LUT_MODE_FILE,
    LUT_MODE_MEMORY,
    LUT_MODE_BOTH};

typedef struct {
  int    no_samples;
  float *value;
  float *noise;
  float *x;
  float *y;
  float *l;
} samples;


typedef struct {
  int   no_neighbors;
  int   *idx;            /* indices into the "samples" array */
  float *distance;       /* distance of the "sample" to the grid point */
  float *x;              /* x-position of neighbor relative to grid point */
  float *y;              /* y-position of neighbor relative to grid point */
  float *l;              /* l-position of neighbor relative to grid point */
} neighbors;

/*-----------------------------------------------------------------------------
 *              Prototypes
 *----------------------------------------------------------------------------*/
cpl_array*      kmclipm_priv_reconstruct_nnlut_get_timestamp(
                        const char *filename,
                        const int ifu,
                        const gridDefinition gd);

neighbors***    kmclipm_priv_reconstruct_nnlut_read(
                        const char *filename,
                        const int ifu,
                        const gridDefinition gd);

void            kmclipm_priv_reconstruct_nnlut_write(
                        const char *filename,
                        const int ifu,
                        const gridDefinition gd,
                        neighbors ***nb,
                        const cpl_array *timestamp,
                        const cpl_vector *calAngles);

int kmclipm_priv_reconstruct_check_lut (const char *filename,
                        const int ifu,
                        const gridDefinition gd,
                        const cpl_array *cal_timestamp,
                        const cpl_vector *calAngles);

cpl_imagelist*  kmclipm_priv_reconstruct_nearestneighbor (
                        int     ifu,
                        int     xSize,
                        int     ySize,
                        const float  *xcal_data,
                        const float  *ycal_data,
                        const float  *lcal_data,
                        const float  *image,
                        const float  *noise_image,
                        const gridDefinition gd,
                        const char *lut_path,
                        int lut_valid,
                        cpl_array *timestamp,
                        const cpl_vector *calAngles,
                        cpl_imagelist **noise_cube_ptr);

cpl_imagelist*  kmclipm_priv_reconstruct_cubicspline (
                        int     ifu,
                        int     xSize,
                        int     ySize,
                        const float  *xcal_data,
                        const float  *ycal_data,
                        const float  *lcal_data,
                        const float  *image,
                        const gridDefinition gd);

cpl_error_code  kmclipm_priv_setup_grid(
                        gridDefinition *gd,
                        const enum reconstructMethod method,
                        double neighborhoodRange,
                        double pixel_scale,
                        double rot_angle);

neighbors***    kmclipm_priv_find_neighbors(
                        const gridDefinition gd,
                        const samples *sampleList);

void            kmclipm_priv_cleanup_neighborlist(
                        neighbors *** nb,
                        gridDefinition gd);

void            kmclipm_priv_reconstruct_nnlut_reset_tables();

cpl_error_code  kmclipm_priv_delete_alien_ifu_cal_data(
                        int ifu,
                        cpl_image* xcal,
                        cpl_image* ycal,
                        cpl_image* lcal);

#endif /* KMCLIPM_PRIV_RECONSTRUCT_H */
