
/*********************************************************************
 * E.S.O. - VLT project
 *
 * "@(#) $Id: kmclipm_vector.h,v 1.3 2013-05-17 15:53:08 aagudo Exp $"
 *
 * Functions that are implemented as recipes. They are also useedd in KMOS
 * data reduction pipeline.
 *
 * who       when        what
 * --------  ----------  ----------------------------------------------
 * agudo     2008-06-12  created
 */

#ifndef KMCLIPM_VECTOR_H
#define KMCLIPM_VECTOR_H

/**
    @defgroup kmclipm_vector Wrapper to cpl_vector

    kmclipm_vector provides the functionality of rejected values like cpl_image does.
    It is a struct containing to vectors. The data vector can contain any value.
    If there are any infinite values in the data, these values will be masked
    already in kmclipm_vector_create() and kmclipm_vector_create2()

    The mask vector can just contain the values 0 and 1.
    (this is asserted in kmclipm_new() and kmclipm_create() and
    kmclipm_create2()))

    @par Synopsis:
    @code
      #include <kmclipm_vector.h>
    @endcode

    @{
 */

/*------------------------------------------------------------------------------
 *              Includes
 *----------------------------------------------------------------------------*/
#include <cpl.h>

/*------------------------------------------------------------------------------
 *              Types
 *----------------------------------------------------------------------------*/
typedef struct {
    cpl_vector *data;
    cpl_vector *mask;
} kmclipm_vector;

/** @brief The type of median behavior:
    For an odd number of samples the behaviour is the same for both methods.
    For an even number of samples:
    - KMCLIPM_STATISTICAL: <br>
      The returned value is the lower of the two center elements of the sorted
      input vector.
    - KMCLIPM_ARITHMETIC <br>
      The arithmetic mean of the two center elements of the sorted input vector
      is calculated
*/
enum medianType {
    KMCLIPM_STATISTICAL,
    KMCLIPM_ARITHMETIC
};

/*------------------------------------------------------------------------------
 *              Declaration Block
 *----------------------------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#endif

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

kmclipm_vector* kmclipm_vector_new(
                                int n);
kmclipm_vector* kmclipm_vector_create(
                                cpl_vector *data);
kmclipm_vector* kmclipm_vector_create2(
                                cpl_vector *data,
                                cpl_vector *mask);
void            kmclipm_vector_delete(
                                kmclipm_vector *kv);
kmclipm_vector* kmclipm_vector_duplicate(
                                const kmclipm_vector *kv);
cpl_error_code  kmclipm_vector_set(
                                kmclipm_vector *kv,
                                int pos,
                                double val);
double          kmclipm_vector_get(
                                const kmclipm_vector *kv,
                                int pos,
                                int *rej);
cpl_vector*     kmclipm_vector_get_mask(
                                const kmclipm_vector *kv);
cpl_vector*     kmclipm_vector_get_bpm(
                                kmclipm_vector *kv);
cpl_error_code  kmclipm_vector_reject_from_mask(
                                kmclipm_vector *kv,
                                const cpl_vector *mask,
                                int keep);

int             kmclipm_vector_count_rejected(
                                const kmclipm_vector *kv);
int             kmclipm_vector_count_non_rejected(
                                const kmclipm_vector *kv);
int             kmclipm_vector_is_rejected(
                                const kmclipm_vector *kv,
                                int n);
cpl_error_code  kmclipm_vector_reject(
                                kmclipm_vector *kv,
                                int n);
kmclipm_vector* kmclipm_vector_extract(
                                const kmclipm_vector *kv,
                                int istart,
                                int istop);
cpl_vector*     kmclipm_vector_create_non_rejected(
                                const kmclipm_vector *kv);
cpl_error_code  kmclipm_vector_adapt_rejected(
                                kmclipm_vector *kv1,
                                kmclipm_vector *kv2);

cpl_error_code  kmclipm_vector_add(
                                kmclipm_vector *kv1,
                                const kmclipm_vector *kv2);
cpl_error_code  kmclipm_vector_subtract(
                                kmclipm_vector *kv1,
                                const kmclipm_vector *kv2);
cpl_error_code  kmclipm_vector_multiply(
                                kmclipm_vector *kv1,
                                const kmclipm_vector *kv2);
cpl_error_code  kmclipm_vector_divide(
                                kmclipm_vector *kv1,
                                const kmclipm_vector *kv2);
cpl_error_code  kmclipm_vector_add_scalar(
                                kmclipm_vector *kv,
                                double addend);
cpl_error_code  kmclipm_vector_subtract_scalar(
                                kmclipm_vector *kv,
                                double subtrahend);
cpl_error_code  kmclipm_vector_multiply_scalar(
                                kmclipm_vector *kv,
                                double factor);
cpl_error_code  kmclipm_vector_divide_scalar(
                                kmclipm_vector *kv,
                                double factor);
cpl_error_code  kmclipm_vector_abs(
                                kmclipm_vector *kv);

int             kmclipm_vector_get_size(
                                const kmclipm_vector *kv);
double          kmclipm_vector_get_mean(
                                const kmclipm_vector *kv);
double          kmclipm_vector_get_median(
                                const kmclipm_vector *kv,
                                const enum medianType type);
kmclipm_vector* kmclipm_vector_cut_percentian(
                                const kmclipm_vector *kv,
                                double percentage);
double          kmclipm_vector_get_sum(
                                const kmclipm_vector *kv);
double          kmclipm_vector_get_stdev(
                                const kmclipm_vector *kv);
double          kmclipm_vector_get_stdev_median(
                                const kmclipm_vector *kv);
double          kmclipm_vector_get_max(
                                const kmclipm_vector *kv,
                                int *pos);
double          kmclipm_vector_get_min(
                                const kmclipm_vector *kv,
                                int *pos);

cpl_error_code  kmclipm_vector_power(
                                kmclipm_vector *kv,
                                double exponent);

cpl_error_code  kmclipm_vector_fill(
                                kmclipm_vector *kv,
                                double val);

cpl_error_code  kmclipm_vector_flip(
                                kmclipm_vector* kv);

kmclipm_vector* kmclipm_vector_histogram(
                                const kmclipm_vector *kv,
                                int nbins);

kmclipm_vector* kmclipm_vector_load(
                                const char *filename,
                                int position);
cpl_error_code  kmclipm_vector_save(
                                const kmclipm_vector *kv,
                                const char *filename,
                                cpl_type_bpp bpp,
                                const cpl_propertylist *pl,
                                unsigned mode,
                                double rej_val);

cpl_error_code  kmclipm_vector_dump(
                                const kmclipm_vector *kv);
/*----------------------------------------------------------------------------*/

#ifdef __cplusplus
}   /* extern "C" */
#endif

/** @} */

#endif
