/* $Id: fors_stack-test.c,v 1.10 2013-09-11 10:04:50 cgarcia Exp $
 *
 * This file is part of the FORS Library
 * Copyright (C) 2002-2006 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  02110-1301 USA
 */

/*
 * $Author: cgarcia $
 * $Date: 2013-09-11 10:04:50 $
 * $Revision: 1.10 $
 * $Name: not supported by cvs2svn $
 */

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

#include <fors_image.h>
#include <fors_stack.h>
#include <fors_dfs.h>
#include <fors_utils.h>

#include <test_simulate.h>
#include <test.h>

/**
 * @defgroup fors_stack_test  Test image stacking
 */

/**@{*/

#undef cleanup
#define cleanup \
do { \
    cpl_frameset_delete(raw); \
    fors_stack_method_delete(&sm); \
    fors_setting_delete(&setting); \
    cpl_parameterlist_delete(parameters); \
    fors_image_list_delete_const(&ilist, fors_image_delete); \
} while(0)

/**
 * @brief   Test image i/o + stacking
 */
static void
test_stack(void)
{
    const unsigned N = 3;
    const fors_image_list *ilist = NULL;
    cpl_frameset *raw = cpl_frameset_new();
    fors_setting *setting = NULL;
    stack_method *sm = NULL;
    fors_image *master = NULL;
    const char *master_filename = NULL;
    cpl_parameterlist *parameters = NULL;
    const char *filename[] = {"stack_bias_1.fits",
                              "stack_bias_2.fits",
                              "stack_bias_3.fits"};

    const char *method[] = {"average",
                            "median",
                            "minmax",
                            "ksigma"};
    unsigned i;

    /* Simulate raw bias */
    for (i = 0; i < N; i++) {
        cpl_frame *bias;

        bias = create_bias(filename[i], BIAS, CPL_FRAME_GROUP_RAW);

        assure( !cpl_error_get_code(), return, 
                "Create bias %s failed", filename[i] );
    
        cpl_frameset_insert(raw, bias);
    }

    setting = fors_setting_new(cpl_frameset_get_position(raw, 0));

    ilist = fors_image_load_list(raw);
    assure( ilist != NULL, return, "Loading list failed" );
    
    test_eq( fors_image_list_size(ilist), 3 );
    
    /* For each stack method */
    for (i = 0; i < 2; i++) {
//fixme: enable these tests    for (i = 0; i < sizeof(method)/sizeof(char *); i++) {
        const char *const context = "test";
        
        parameters = cpl_parameterlist_new();
        
        fors_stack_define_parameters(parameters, context, "median");
        assure( !cpl_error_get_code(), return, 
                "Define parameters" );
        
        cpl_parameter_set_string(cpl_parameterlist_find(
                                     parameters, "test.stack_method"),
                                 method[i]);
        

        sm = fors_stack_method_new(parameters, context);
        
        /* Call function */
        master = fors_stack_const(ilist, sm);
        assure( !cpl_error_get_code(), return, 
                "Could not stack images using method %s", method[i]);

        /* Compare results */
        
        /* Same level */
        test_abs( fors_image_get_mean(master, NULL), 
                  fors_image_get_mean(fors_image_list_first_const(ilist), NULL), 1.0);

        /* Test that avg(sigma_i) is consistent with empirical stdev */
        test_rel( fors_image_get_stdev(master, NULL), 
                  fors_image_get_error_mean(master, NULL), 
                  i == 0 ? 0.01 :
                  i == 1 ? 0.1 : 0.01);


        /* Save */
        master_filename = cpl_sprintf("stack_master_bias_%s.fits", method[i]);
        
        fors_image_save(master, NULL, NULL, master_filename);
        assure( !cpl_error_get_code(), return, 
                "Error saving stacked image to %s", master_filename);


        fors_stack_method_delete(&sm);
        cpl_parameterlist_delete(parameters); parameters = NULL;        
        fors_image_delete(&master);                        
        cpl_free((void *)master_filename); master_filename = NULL;
    }

    cleanup;
    return;
}

/**
 * @brief   Test of image stacking module
 */
int main(void)
{
    TEST_INIT;

    /* cpl_msg_set_level(CPL_MSG_DEBUG); */
    test_stack();

    TEST_END;
}

/**@}*/
