"""This file contains R functions not found on Python or global functions needed in the program

Marjorie ROSCIAN CCI 2017-2018"""

import numpy as np
from numpy.core.multiarray import ndarray
from sklearn.decomposition import PCA


def remove_id_column(data):
    """ This function removes the first column of the dataset because it is the id of the cell"""

    for cell in np.arange(0, data.size):
        remove = data[cell][:, 0]
        new_data = np.delete(data[cell], remove)

    return new_data


def norm_coeff(coeff, nb_bases):
    # Normalisation
    # Comment if don't need
    # The threshold value (10) has been chosen with dataset observation and must bee review for other dataset

    for num in np.arange(0, nb_bases):
        if max(coeff) > 10:
            coeff[num] = coeff[num]/coeff[0]
        else:
            coeff = np.repeat(0, nb_bases)
    return coeff


def center_coeff(coeff, nb_bases):
    # Centering
    # Comment if don't need
    # Centering the coefficients is useful to principal component analysis

    for num in np.arange(0, nb_bases):
        coeff[num] = coeff[num] - np.mean(coeff)

    return coeff


def sort_each_profil(data, nb_bases, nb_col):
    """ This function sorts every profil for all dataset
    MAX np_col = 5
    Input : data is the entire dataset to be sorted
    Output : fws, sws, flo, flr,FLY are vectors containing all values for all cells of the chosen profil
"""

    print("CAUTION : This function can sort 5 profils maximum. Check Analysis.FunctionUtils.py for more information")

    # Initialisation
    fws = np.zeros((len(data), nb_bases))
    sws = np.zeros((len(data), nb_bases))
    flo = np.zeros((len(data), nb_bases))
    flr = np.zeros((len(data), nb_bases))
    fly = np.zeros((len(data), nb_bases))

    # Sort each column in a different ndarray
    for cell in np.arange(0, len(data)):
        for profil in np.arange(0, nb_col):
            if profil == 0:
                fws[cell] = data[cell][:, 0]
            if profil == 1:
                sws[cell] = data[cell][:, 1]
            if profil == 2:
                flo[cell] = data[cell][:, 2]
            if profil == 3:
                flr[cell] = data[cell][:, 3]
            if profil == 4:
                fly[cell] = data[cell][:, 4]

    return fws, sws, flo, flr, fly


def pca_norm(data):
    """This function divides each Fourier coefficient by the square root of the first singular value of the PCA
        Input : data is the result of the calcul of Fourier series
        Output : the dataset normalised in 4 or 5 ndarrays
    """

    pca = PCA()
    pca.fit(data[0])
    fws_norm = np.array(data[0] / np.sqrt(pca.singular_values_[0]))

    pca.fit(data[1])
    sws_norm = np.array(data[1] / np.sqrt(pca.singular_values_[0]))

    pca.fit(data[2])
    flo_norm = np.array(data[2] / np.sqrt(pca.singular_values_[0]))

    pca.fit(data[3])
    flr_norm = np.array(data[3] / np.sqrt(pca.singular_values_[0]))

    if data[4] in data:
        pca.fit(data[4])
        fly_norm = np.array(data[4] / np.sqrt(pca.singular_values_[0]))  # type: ndarray

    return fws_norm, sws_norm, flo_norm, flr_norm, fly_norm


def area(data_matrix, step):
    """ This function computes the area under the curve
        Input : data_matrix is the value of the curve
                step is the number of step you want to count
        Ouput : area_value is the value of the area under the curve
        Other :
    """
    data_matrix = np.array(data_matrix)
    area_value = 0

    for y in np.arange(0, data_matrix.size):
        area_value = area_value + data_matrix[y] * 1/step

    return area_value
