/* $Id: sinfo_wcal_functions.c,v 1.10 2013-09-17 08:12:53 amodigli Exp $
 *
 * This file is part of the SINFONI 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: amodigli $
 * $Date: 2013-09-17 08:12:53 $
 * $Revision: 1.10 $
 * $Name: not supported by cvs2svn $
 */


#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
/*-----------------------------------------------------------------------------
                                   Includes
 ----------------------------------------------------------------------------*/

#include "sinfo_wcal_functions.h"
#include "sinfo_globals.h"
#include "sinfo_error.h"
#include "sinfo_utils_wrappers.h"

/* struct qc_wcal qc_wcal_par; */
/**@{*/
/**
 * @addtogroup sinfo_rec_wavecal wavecal functions
 *
 * TBD
 */

qc_wcal* sinfo_qc_wcal_new(void)
{  

    qc_wcal * qc;
    qc= cpl_malloc(sizeof(qc_wcal));

    qc->avg_on=0;
    qc->std_on=0;
    qc->avg_of=0;
    qc->std_of=0;
    qc->avg_di=0;
    qc->std_di=0;
    qc->max_on=0;
    qc->max_of=0;
    qc->max_di=0;
    qc->nsat_on=0;
    qc->noise_on=0;
    qc->noise_of=0;
    qc->flux_on=0;
    qc->nsat=0;
    return qc;
}

void sinfo_qc_wcal_delete(qc_wcal** qc)
{
    cpl_free(*qc);
    *qc = NULL;
}

int sinfo_dumpTblToFitParams ( FitParams ** params, char * filename )
{
    cpl_table * fp =NULL;
    char* col=NULL;
    int i =0;
    int j =0;
    int status=0;


    if ( NULL == params )
    {
        sinfo_msg_error ("no fit parameters available!") ;
        return -1;
    }

    if ( NULL == filename )
    {
        sinfo_msg_error ("no filename available!") ;
        return -1;
    }


    fp=cpl_table_load(filename,1,0);
    if(cpl_error_get_code() != CPL_ERROR_NONE) {
        sinfo_msg("cannot load table %s",filename);
        sinfo_msg_error("%s", (char* ) cpl_error_get_message());
        return -1;
    }

    col = (char*) cpl_calloc(MAX_NAME_SIZE,sizeof(char*));
    for ( i = 0 ; i < params[0]->n_params ; i++ )
    {
        params[i]->n_params=cpl_table_get_int(fp,"n_params",i,&status);
        params[i]->column  =cpl_table_get_int(fp,"column",i,&status);
        params[i]->line    =cpl_table_get_int(fp,"line",i,&status);
        for (j=0 ; j < 4; j++) {
            snprintf(col,MAX_NAME_SIZE-1,"%s%d","fpar",j);
            params[i]->fit_par[j]=cpl_table_get_double(fp,col,i,&status);
            snprintf(col,MAX_NAME_SIZE-1,"%s%d","dpar",j);
            params[i]->derv_par[j]=cpl_table_get_double(fp,col,i,&status);
        }
    }
    cpl_free(col);
    cpl_table_delete(fp) ;
    return 0;
}




int sinfo_det_ncounts(cpl_frameset* raw, int thresh_max, qc_wcal* qc)
{
    int i=0;
    int j=0;

    long nraw=0;
    int non=0;
    int noff=0;
    int nsat=0;

    double mean=0;
    double max=0;

    double mjd_on=0;
    double mjd_of=0;
    double mjd_of_frm=0;

    char name[FILE_NAME_SZ];
    char filename[FILE_NAME_SZ];


    cpl_vector* avg_on=NULL;
    cpl_vector* avg_of=NULL;
    cpl_vector* avg_di=NULL;


    cpl_vector* max_on=NULL;
    cpl_vector* max_of=NULL;
    cpl_vector* max_di=NULL;

    cpl_vector* vec_nsat=NULL;

    cpl_frame* frm=NULL;
    cpl_frame* frm_dup=NULL;
    cpl_frame* on_frm=NULL;
    cpl_frame* of_frm=NULL;
    cpl_frame* tmp_of_frm=NULL;

    cpl_image* dif_ima=NULL;
    cpl_image* on_ima=NULL;
    cpl_image* of_ima=NULL;
    cpl_image* tmp_ima=NULL;

    cpl_frameset* on_set=NULL;
    cpl_frameset* of_set=NULL;

    on_set=cpl_frameset_new();
    of_set=cpl_frameset_new();
    nraw = cpl_frameset_get_size(raw);


    for (i=0; i< nraw; i++) {
        check_nomsg(frm = cpl_frameset_get_frame(raw,i));
        check_nomsg(frm_dup = cpl_frame_duplicate(frm));
        if(sinfo_frame_is_on(frm) == 1) {
            cpl_frameset_insert(on_set,frm_dup);
            non++;
        } else {
            cpl_frameset_insert(of_set,frm_dup);
            noff++;
        }
    }


    if (non == noff) {
        sinfo_msg("Monitor counts: case Non==Noff");


        avg_on = cpl_vector_new(non);
        avg_of = cpl_vector_new(non);
        avg_di = cpl_vector_new(non);

        max_on = cpl_vector_new(non);
        max_of = cpl_vector_new(non);
        max_di = cpl_vector_new(non);



        vec_nsat = cpl_vector_new(non);
        for (i=0; i< non; i++) {
            check_nomsg(on_frm = cpl_frameset_get_frame(on_set,i));
            strcpy(name,cpl_frame_get_filename(on_frm));
            check_nomsg(on_ima = cpl_image_load(name,CPL_TYPE_FLOAT,0,0));

            check_nomsg(mean= cpl_image_get_mean(on_ima));
            check_nomsg(cpl_vector_set(avg_on,i,mean));
            check_nomsg(max= cpl_image_get_max(on_ima));
            check_nomsg(cpl_vector_set(max_on,i,max));
            check_nomsg(tmp_ima = cpl_image_duplicate(on_ima));
            check_nomsg(cpl_image_threshold(tmp_ima,thresh_max,thresh_max,0,1));
            check_nomsg(nsat=cpl_image_get_flux(tmp_ima));
            check_nomsg(cpl_vector_set(vec_nsat,i,nsat));


            check_nomsg(of_frm = cpl_frameset_get_frame(of_set,i));
            strcpy(name,cpl_frame_get_filename(of_frm));
            check_nomsg(of_ima = cpl_image_load(name,CPL_TYPE_FLOAT,0,0));
            check_nomsg(mean= cpl_image_get_mean(of_ima));
            check_nomsg(cpl_vector_set(avg_of,i,mean));
            check_nomsg(max= cpl_image_get_max(of_ima));
            check_nomsg(cpl_vector_set(max_of,i,max));

            check_nomsg(dif_ima = cpl_image_subtract_create(on_ima,of_ima));
            check_nomsg(mean= cpl_image_get_mean(dif_ima));
            check_nomsg(cpl_vector_set(avg_di,i,mean));
            check_nomsg(max= cpl_image_get_max(dif_ima));
            check_nomsg(cpl_vector_set(max_di,i,max));

            sinfo_free_image(&on_ima);
            sinfo_free_image(&of_ima);
            sinfo_free_image(&dif_ima);
            sinfo_free_image(&tmp_ima);

        }

        check_nomsg(qc->avg_on=cpl_vector_get_mean(avg_on));
        check_nomsg(qc->avg_of=cpl_vector_get_mean(avg_of));
        check_nomsg(qc->avg_di=cpl_vector_get_mean(avg_di));

        check_nomsg(qc->max_on=cpl_vector_get_max(max_on));
        check_nomsg(qc->max_of=cpl_vector_get_max(max_of));
        check_nomsg(qc->max_di=cpl_vector_get_max(max_di));

        check_nomsg(qc->nsat=cpl_vector_get_mean(vec_nsat));

        if (non > 1) {
            check_nomsg(qc->std_on=cpl_vector_get_stdev(avg_on));
            check_nomsg(qc->std_of=cpl_vector_get_stdev(avg_of));
            check_nomsg(qc->std_di=cpl_vector_get_stdev(avg_di));
        }

        sinfo_free_my_vector(&avg_on);
        sinfo_free_my_vector(&avg_of);
        sinfo_free_my_vector(&avg_di);

        sinfo_free_my_vector(&max_on);
        sinfo_free_my_vector(&max_of);
        sinfo_free_my_vector(&max_di);

        sinfo_free_my_vector(&vec_nsat);


    } else if ( ((non ==0) | (noff == 0)) && (nraw > 0 ) ) {
        sinfo_msg("Monitor counts: case Nraw == 1");
        check_nomsg(avg_di = cpl_vector_new(nraw));
        check_nomsg(max_di = cpl_vector_new(nraw));
        check_nomsg(vec_nsat = cpl_vector_new(nraw));

        for (i=0; i< nraw; i++) {
            check_nomsg(frm = cpl_frameset_get_frame(raw,i));
            strcpy(name,cpl_frame_get_filename(frm));
            check_nomsg(dif_ima = cpl_image_load(name,CPL_TYPE_FLOAT,0,0));

            check_nomsg(mean= cpl_image_get_mean(dif_ima));
            check_nomsg(tmp_ima=cpl_image_duplicate(dif_ima));
            sinfo_clean_nan(&tmp_ima);
            check_nomsg(mean= cpl_image_get_mean(tmp_ima));
            check_nomsg(cpl_vector_set(avg_di,i,mean));
            check_nomsg(max= cpl_image_get_max(tmp_ima));
            check_nomsg(cpl_vector_set(max_di,i,max));
            check_nomsg(cpl_image_threshold(tmp_ima,thresh_max,thresh_max,0,1));
            check_nomsg(nsat=cpl_image_get_flux(tmp_ima));
            check_nomsg(cpl_vector_set(vec_nsat,i,nsat));

            sinfo_free_image(&tmp_ima);
            sinfo_free_image(&dif_ima);

        }

        qc->avg_di=cpl_vector_get_mean(avg_di);
        if (nraw > 1) {
            check_nomsg(qc->std_di=cpl_vector_get_stdev(avg_di));
        }
        check_nomsg(qc->max_di=cpl_vector_get_max(max_di));
        check_nomsg(qc->nsat=cpl_vector_get_mean(vec_nsat));

        sinfo_free_my_vector(&avg_di);
        sinfo_free_my_vector(&max_di);
        sinfo_free_my_vector(&vec_nsat);

    } else {
        sinfo_msg("Monitor counts: else case");

        avg_on = cpl_vector_new(non);
        avg_of = cpl_vector_new(non);
        avg_di = cpl_vector_new(non);

        max_on = cpl_vector_new(non);
        max_of = cpl_vector_new(non);
        max_di = cpl_vector_new(non);

        vec_nsat = cpl_vector_new(non);

        for (i=0;i<non;i++) {
            check_nomsg(on_frm=cpl_frameset_get_frame(on_set,i));
            check_nomsg(mjd_on=sinfo_get_mjd_obs(on_frm));
            check_nomsg(of_frm=cpl_frameset_get_frame(of_set,0));
            check_nomsg(mjd_of=sinfo_get_mjd_obs(of_frm));
            strcpy(filename,cpl_frame_get_filename(of_frm));

            for (j=1;j<noff;j++) {
                check_nomsg(tmp_of_frm = cpl_frameset_get_frame(of_set,j));
                check_nomsg(mjd_of_frm = sinfo_get_mjd_obs(tmp_of_frm));

                if(1000.*(mjd_of_frm-mjd_on)*(mjd_of_frm-mjd_on) <
                                1000.*(mjd_of-    mjd_on)*(mjd_of-    mjd_on) ) {
                    mjd_of=mjd_of_frm;
                    of_frm=tmp_of_frm;
                }
            }

            strcpy(filename,cpl_frame_get_filename(of_frm));
            check_nomsg(of_ima = cpl_image_load(filename,CPL_TYPE_FLOAT,0,0));
            check_nomsg(mean= cpl_image_get_mean(of_ima));
            check_nomsg(cpl_vector_set(avg_of,i,mean));
            check_nomsg(max= cpl_image_get_max(of_ima));
            check_nomsg(cpl_vector_set(max_of,i,max));

            strcpy(filename,cpl_frame_get_filename(on_frm));
            check_nomsg(on_ima = cpl_image_load(filename,CPL_TYPE_FLOAT,0,0));
            check_nomsg(mean= cpl_image_get_mean(on_ima));
            check_nomsg(cpl_vector_set(avg_on,i,mean));
            check_nomsg(max= cpl_image_get_mean(on_ima));
            check_nomsg(cpl_vector_set(max_on,i,max));

            check_nomsg(tmp_ima = cpl_image_duplicate(on_ima));
            check_nomsg(cpl_image_threshold(tmp_ima,thresh_max,thresh_max,0,1));
            check_nomsg(nsat=cpl_image_get_flux(tmp_ima));
            check_nomsg(cpl_vector_set(vec_nsat,i,nsat));

            check_nomsg(dif_ima = cpl_image_subtract_create(on_ima,of_ima));
            check_nomsg(mean= cpl_image_get_mean(dif_ima));
            check_nomsg(cpl_vector_set(avg_di,i,mean));
            check_nomsg(max= cpl_image_get_max(dif_ima));
            check_nomsg(cpl_vector_set(max_di,i,max));

            sinfo_free_image(&on_ima);
            sinfo_free_image(&of_ima);
            sinfo_free_image(&dif_ima);
            sinfo_free_image(&tmp_ima);

        }

        sinfo_free_my_vector(&avg_on);
        sinfo_free_my_vector(&avg_of);
        sinfo_free_my_vector(&avg_di);

        sinfo_free_my_vector(&max_on);
        sinfo_free_my_vector(&max_of);
        sinfo_free_my_vector(&max_di);

        sinfo_free_my_vector(&vec_nsat);

    }

    /*
 sinfo_msg("avg_on=%g std_on=%g ",qc->avg_on,qc_wcal.std_on);
 sinfo_msg("avg_of=%g std_of=%g ",qc->avg_of,qc_wcal.std_of);
 sinfo_msg("avg_di=%g std_di=%g ",qc->avg_di,qc_wcal.std_di);
 sinfo_msg("max_fl=%g nsat_on=%g ",qc->max_di,qc_wcal.nsat);
     */
    cleanup:

    sinfo_free_image(&on_ima);
    sinfo_free_image(&of_ima);
    sinfo_free_image(&dif_ima);
    sinfo_free_image(&tmp_ima);

    sinfo_free_my_vector(&avg_on);
    sinfo_free_my_vector(&avg_of);
    sinfo_free_my_vector(&avg_di);

    sinfo_free_my_vector(&max_on);
    sinfo_free_my_vector(&max_of);
    sinfo_free_my_vector(&max_di);

    sinfo_free_my_vector(&vec_nsat);

    sinfo_free_frameset(&on_set);
    sinfo_free_frameset(&of_set);

    return 0;

}


/**@}*/
