/* $Id: naco_util_spc_argon.c,v 1.6 2011-12-22 11:21:03 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: 2011-12-22 11:21:03 $
 * $Revision: 1.6 $
 * $Name: not supported by cvs2svn $
 */

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

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

#include <string.h>

#include "naco_recipe.h"

#include "naco_spc.h"

/*-----------------------------------------------------------------------------
                            Recipe defines
 -----------------------------------------------------------------------------*/

#define RECIPE_STRING "naco_util_spc_argon"

#ifndef NACO_SPC_ARGON_SIZE
#define NACO_SPC_ARGON_SIZE 80
#endif

/*-----------------------------------------------------------------------------
                            Private Functions prototypes
 -----------------------------------------------------------------------------*/

NACO_RECIPE_DEFINE(naco_util_spc_argon, 0,
                   "Generate FITS table with argon lines",
                   "The input frame(s) must be tagged "
                   NACO_SPC_ARGON_ASCII ".\n"
                   "The file must comprise two columns:"
                   "the 1st with the line wavelength [Angstrom],\n"
                   "the 2nd with the line intensity.\n"
                   "\n"
                   "The default input ASCII-file is in the catalogs/ "
                   "directory of the NACO source-code distribution.");

static IRPLIB_UTIL_SET_ROW(naco_util_spc_argon_set_row);
static IRPLIB_UTIL_CHECK(naco_util_spc_argon_check);

static unsigned nzero = 0; /* Quick hack to count zero-intensity lines */

/*----------------------------------------------------------------------------*/
/**
 * @defgroup naco_util_spc_argon   Generate argon lines FITS table
 */
/*----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------

                                Functions code
 -----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/**
  @brief    Converts an ASCII file with nine columns to a FITS file
  @param    framelist   the frames list
  @return   0 iff everything is ok

 */
/*----------------------------------------------------------------------------*/
static int naco_util_spc_argon(cpl_frameset            * framelist,
                               const cpl_parameterlist * parlist)
{
    irplib_framelist * allframes = NULL;
    irplib_framelist * rawframes = NULL;
    cpl_frameset     * useframes = NULL;
    cpl_table        * self      = NULL;
    

    if (cpl_error_get_code()) return cpl_error_get_code();

    /* Identify the RAW frames in the input frameset */
    skip_if (naco_dfs_set_groups(framelist));

    /* FIXME: Using framelists is the simplest way to extract the relevant
       frames :-( */

    allframes = irplib_framelist_cast(framelist);
    bug_if(allframes == NULL);

    rawframes = irplib_framelist_extract(allframes, NACO_SPC_ARGON_ASCII);
    skip_if (rawframes == NULL);

    irplib_framelist_empty(allframes);

    useframes = irplib_frameset_cast(rawframes);
    bug_if(allframes == NULL);

    /* At least one row per file */
    self = cpl_table_new(irplib_framelist_get_size(rawframes));

    irplib_framelist_empty(rawframes);

    /* Create the table columns - with units */
    bug_if (cpl_table_new_column(self, NACO_SPC_LAB_WAVE,   CPL_TYPE_DOUBLE));
    bug_if (cpl_table_new_column(self, NACO_SPC_LAB_INTENS, CPL_TYPE_DOUBLE));

    bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_WAVE, "micron"));

    skip_if(irplib_dfs_table_convert(self, framelist, useframes, 
                                     NACO_SPC_ARGON_SIZE, '#', NULL,
                                     NACO_SPC_ARGON, parlist, RECIPE_STRING,
                                     NULL, NULL, NULL, "NACO", naco_pipe_id,
                                     naco_util_spc_argon_set_row,
                                     naco_util_spc_argon_check));
    end_skip;

    cpl_table_delete(self);
    cpl_frameset_delete(useframes);
    irplib_framelist_delete(allframes);
    irplib_framelist_delete(rawframes);

    return cpl_error_get_code();
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Convert one ASCII line and insert it into the atble
  @param    self      The table to set
  @param    line      The line to parse
  @param    irow      The row to set (zero for 1st)
  @param    parlist   The recipe parameters
  @return   CPL_TRUE iff the row was modified

  The input catalogs are ASCII files respecting this format:
  
 */
/*----------------------------------------------------------------------------*/
static
cpl_boolean naco_util_spc_argon_set_row(cpl_table * self,
                                        const char * line,
                                        int irow,
                                        const cpl_frame * rawframe,
                                        const cpl_parameterlist * parlist)
{


    /* gcc can only check sscanf()s format when it is a string literal */
#define FORMAT "%lg %lg"

    int nvals;
    double wlen, intens;


    bug_if(0);
    bug_if(self     == NULL);
    bug_if(line     == NULL);
    bug_if(irow   <  0);
    bug_if(rawframe == NULL);
    bug_if(parlist  == NULL);

    nvals = sscanf(line, FORMAT, &wlen, &intens);

    error_if (nvals != 2, CPL_ERROR_BAD_FILE_FORMAT,
              "Line with length=%u has %d not 2 items formatted: %s",
              (unsigned)strlen(line), nvals, FORMAT);

    error_if (wlen <= 0.0, CPL_ERROR_BAD_FILE_FORMAT,
              "Non-positive wavelength %g in line %s", wlen, line);

    error_if (intens < 0.0, CPL_ERROR_BAD_FILE_FORMAT,
              "Negative intensity %g in line %s", intens, line);

    wlen *= 1e-4; /* Convert from Angstrom to Micron */

    bug_if(cpl_table_set_double(self, NACO_SPC_LAB_WAVE,   irow, wlen));
    bug_if(cpl_table_set_double(self, NACO_SPC_LAB_INTENS, irow, intens));

    if (intens <= 0.0) nzero++; /* Don't use == to avoid warning ... */

    end_skip;

    return CPL_TRUE;

}


/*----------------------------------------------------------------------------*/
/**
  @brief    Sort after wavelength, with info on the inserted FITS rows
  @param    self      The table to check
  @param    useframes The frames used to fill the table
  @param    parlist   The recipe parameters
  @return   CPL_ERROR_NONE on success, otherwise the relevant CPL error code
  
 */
/*----------------------------------------------------------------------------*/
static
cpl_error_code naco_util_spc_argon_check(cpl_table * self,
                                         const cpl_frameset * useframes,
                                         const cpl_parameterlist * parlist)
{

    cpl_propertylist * reflist = cpl_propertylist_new();


    bug_if(0);
    bug_if(self     == NULL);
    bug_if(parlist  == NULL);

    /* Sort after wavelength with smallest first */
    bug_if(cpl_propertylist_append_bool(reflist, NACO_SPC_LAB_WAVE, 0));

    bug_if(cpl_table_sort(self, reflist));

    cpl_msg_info(cpl_func, "Created table of %d argon lines (%u with zero "
                 "intensity) from %d file(s)", (int)cpl_table_get_nrow(self),
                 nzero, (int)cpl_frameset_get_size(useframes));

    end_skip;

    cpl_propertylist_delete(reflist);

    return cpl_error_get_code();
}

