/* $Id: kmo_functions.h,v 1.18 2013-10-09 12:16:10 aagudo Exp $
 *
 * This file is part of the KMOS 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * $Author: aagudo $
 * $Date: 2013-10-09 12:16:10 $
 * $Revision: 1.18 $
 * $Name: not supported by cvs2svn $
 */

#ifndef KMOS_FUNCTIONS_H
#define KMOS_FUNCTIONS_H

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

#include <cpl.h>

#include "kmclipm_functions.h"
#include "kmclipm_constants.h"

#define NO_CORRESPONDING_SKYFRAME ((cpl_frame* ) -1)

typedef struct {
    cpl_frame *objFrame;                // pointer to frame containing objects
    cpl_frame *skyFrames[KMOS_NR_IFUS]; // array of pointers to according sky frames
    int       skyIfus[KMOS_NR_IFUS];    // array of integers to according IFUs in sky frames
} objSkyTable;

typedef struct {                        // just for connecting frame filenames to entries in objSkyStruct
    const char        *filename;
    int               index;
} objSkyIndexStruct;

typedef struct {
    int               size;             // number of frames with objects in it
    objSkyTable       *table;           // array of objSkyTables                             size: size
    int               sizeIndexStruct;
    objSkyIndexStruct *indexStruct;     //                                                   size: sizeIndexStruct
} objSkyStruct;

typedef struct {
    int          size;                  // number of frames with objects in it (same as objSkyStruct->size)
    int          nrNames;               // number of object names
    objSkyStruct *obj_sky_struct;       // pointer to structure with obj/sky-associations,   size: [1]
    char         **names;               // array of object names                             size: [nrNames]
    int          *namesCnt;             // array with number of object name occurences       size: [nrNames]
    int          *telluricCnt;          // array with number of telluric occurences          size: [nrNames]
    int          *sameTelluric;         // array with boolean if same telluric for all IFUs  size: [nrNames]
    int          *name_ids;             // array with IDs of object names                    size: [size*KMOS_NR_IFUS]
                                        // 0: no object available, 1: 1st object ID etc.
} armNameStruct;


/*------------------------------------------------------------------------------
 *                        Prototypes
 *----------------------------------------------------------------------------*/

extern int      print_warning_once;

void            kmo_print_objSkyStruct(const objSkyStruct *obj_sky_struct);

cpl_error_code  kmo_save_objSkyStruct(const objSkyStruct *obj_sky_struct);

objSkyStruct*   kmo_read_objSkyStruct(
                                    const char *filename,
                                    cpl_frameset *frameset,
                                    const char *frameType);

objSkyStruct*   kmo_create_objSkyStruct(
                                    cpl_frameset *frameset,
                                    const char *frameType,
                                    int acceptAllSky);

objSkyIndexStruct*   kmo_create_objSkyIndexStruct(
                                    cpl_frameset *frameset,
                                    objSkyStruct *obj_sky_struct);

void            kmo_collapse_objSkyStruct(
                                    objSkyStruct* obj_sky_struct,
                                    int ifu_nr,
                                    cpl_frame** obj_frame,
                                    cpl_frame** sky_frame);

void            kmo_delete_objSkyStruct(
                                    objSkyStruct *obj_sky_struct);

void            kmo_print_armNameStruct(
                                    cpl_frameset *frameset,
                                    armNameStruct *arm_name_struct);

armNameStruct*  kmo_create_armNameStruct(cpl_frameset *frameset,
                                    const char *frameType,
                                    const cpl_vector *ifus,
                                    const char *name,
                                    cpl_array **unused_ifus,
                                    const int *bounds,
                                    const char *mapping_mode,
                                    int acceptAllSky);

armNameStruct*  kmo_create_armNameStruct2(
                                    objSkyStruct *obj_sky_struct,
                                    cpl_frameset *frameset,
                                    const char *frameType,
                                    const cpl_vector *ifus,
                                    const char *name,
                                    cpl_array **unused_ifus,
                                    const int *bounds,
                                    const char *mapping_mode,
                                    int acceptAllSky);

cpl_error_code  kmo_priv_create_armNameStruct(
                                    armNameStruct *arm_name_struct,
                                    cpl_frameset *frameset,
                                    const char *frameType,
                                    const cpl_vector *ifus,
                                    const char *name,
                                    cpl_array **unused_ifus,
                                    const int *bounds,
                                    const char *mapping_mode,
                                    int acceptAllSky);

void            kmo_delete_armNameStruct(
                                    armNameStruct *arm_name_struct);


cpl_array*      kmo_get_timestamps(
                                cpl_frame* xcalFrame,
                                cpl_frame* ycalFrame,
                                cpl_frame* lcalFrame);

cpl_error_code  kmo_reconstruct_sci_image(
                                int             ifu_nr,
                                int             lowBound,
                                int             highBound,
                                cpl_image       *objectDataDetImage,
                                cpl_image       *objectNoiseDetImage,
                                cpl_image       *skyDataDetImage,
                                cpl_image       *skyNoiseDetImage,
                                cpl_image       *flatfieldDataDetImage,
                                cpl_image       *flatfieldNoiseDetImage,
                                cpl_image       *xcalDetImage,
                                cpl_image       *ycalDetImage,
                                cpl_image       *lcalDetImage,
                                const gridDefinition *gd,
                                cpl_array       *calTimestamp,
                                cpl_vector      *calAngles,
                                const char      *lutFilename,
                                cpl_imagelist   **dataCube,
                                cpl_imagelist   **noiseCube,
                                int             flux,
                                int             background,
                                double          *ret_flux_in,
                                double          *ret_flux_out,
                                double          *ret_background);

cpl_error_code  kmo_reconstruct_sci(
                                int            ifu_nr,
                                int            lowBound,
                                int            highBound,
                                cpl_frame      *objectFrame,
                                const char     *obj_tag,
                                cpl_frame      *skyFrame,
                                const char     *sky_tag,
                                cpl_frame      *flatFrame,
                                cpl_frame      *xcalFrame,
                                cpl_frame      *ycalFrame,
                                cpl_frame      *lcalFrame,
                                cpl_polynomial *lcorrection,
                                double         *velocity_correction,
                                const gridDefinition *gd,
                                cpl_imagelist  **dataCubePtr,
                                cpl_imagelist  **noiseCubePtr,
                                int            flux,
                                int            background,
                                int            xcal_interpolation,
                                int            oscan_corr);

cpl_image *kmo_calc_mode_for_flux_image(
                                const cpl_image *data,
                                const cpl_image *xcal,
                                int ifu_nr,
                                double *noise);

cpl_error_code  kmo_calc_mode_for_flux_cube(
                                const cpl_imagelist *data,
                                double *mode,
                                double *noise);

cpl_error_code kmo_rotate_x_y_cal (
                                const float rot_ang,
                                const int ifu_nr,
//                                const gridDefinition *gd,
                                cpl_image *xcal,
                                cpl_image *ycal,
                                cpl_image *lcal);

int kmo_tweak_find_ifu(cpl_frameset *frameset, int ifu_nr) ;

#endif
