# -*- coding: utf-8 -*-
"""
Created on Wed Jun 16 14:23:20 2021

@author: A752018
"""
def PLOT_simple(data, signal, var_coloration, var1, var2, var3, var4, var5, label_var1, label_var2, label_var3, label_var4, label_var5, 
         arg_legend, title, palette, save, save_name):
    
    
    nbr_radar = labelStack.iloc[signal, labelStack.columns.get_loc('nbr_radar')]
    
    # Données brutes
    if (var_coloration == None):
        coloration = None
        nbr_clusters = ""
        legend_title = ""
        arg_coloration = ""

    # Coloraiton vérité terrain
    elif (var_coloration == 'ID_radar' or var_coloration == "ID_RADAR"):
        coloration = data[data.index == var_coloration]
        nbr = pd.DataFrame(pd.Series(data.T[var_coloration]).value_counts().sort_index())
        nbr_clusters = ""
        legend_title = "RADAR(s)"
        arg_coloration = " - coloration : " + var_coloration
        
    # Colora
    elif (var_coloration != None) :
        coloration = data[data.index == var_coloration]
        nbr = pd.DataFrame(pd.Series(data.T[var_coloration]).value_counts().sort_index())
        nbr_clusters = len(nbr.iloc[nbr.index != -1]) 
        nbr_clusters = str(nbr_clusters) + ' cluster(s) out of '
        legend_title = "Cluster(s)"
        arg_coloration = " - coloration : " + var_coloration


    # --- Plot
    figure = plt.figure(figsize = (13, 10))
    figure.subplots_adjust(hspace = 0.3, wspace = 0.5)   # hspace : space between row, wspcae : space between columns
    
    if (title == True):
        figure.suptitle("Signal n° " + str(signal) + " - " + str(nbr_clusters) + str(nbr_radar) + ' RADAR(s)' + arg_coloration)
    
    # --- Graphique 1
    ax1 = plt.subplot(2,2,1)
    ax1.set_xlabel('Time of arrival (µs)')
    ax1.set_ylabel(label_var1)
    
    if arg_legend == True:
        scatter1 = plt.scatter(data[data.index == 'TOA'], data[data.index == var1], c = coloration, marker = ".", cmap = palette)
        legend1 = ax1.legend(*scatter1.legend_elements(), title = legend_title, bbox_to_anchor = (1.04, 1))
        ax1.add_artist(legend1)
    else:
        plt.scatter(data[data.index == 'TOA'], data[data.index == var1], c = coloration, marker = ".", cmap = palette)
    
    
    # --- Graphique 2
    ax2 = plt.subplot(2,2,2, sharex = ax1)
    ax2.set_xlabel('Time of arrival (µs)')
    ax2.set_ylabel(label_var2)
    
    if arg_legend == True:
        scatter2 = plt.scatter(data[data.index == 'TOA'], data[data.index == var2], c = coloration, marker = ".", cmap = palette)
        legend2 = ax2.legend(*scatter2.legend_elements(), title = legend_title, bbox_to_anchor = (1.04, 1))
        ax2.add_artist(legend2)
    else:
        plt.scatter(data[data.index == 'TOA'], data[data.index == var2], c = coloration, marker = ".", cmap = palette)
    
    
    # --- Graphique 3
    ax3 = plt.subplot(2,2,3, sharex = ax1)
    ax3.set_xlabel('Time of arrival (µs)')
    ax3.set_ylabel(label_var3)
    
    if arg_legend == True:
        scatter3 = plt.scatter(data[data.index == 'TOA'], data[data.index == var3], c = coloration, marker = ".", cmap = palette)
        legend3 = ax3.legend(*scatter3.legend_elements(), title = legend_title, bbox_to_anchor = (1.04, 1))
        ax3.add_artist(legend3)
    else:
        plt.scatter(data[data.index == 'TOA'], data[data.index == var3], c = coloration, marker = ".", cmap = palette)
    
   
    # --- Graphique 4
    if (var4 == 'TOA'):
        ax4 = plt.subplot(2,2,4, sharex = ax1)
    else:    
        ax4 = plt.subplot(2,2,4)
        
    ax4.set_xlabel(label_var4)
    ax4.set_ylabel(label_var5)
    
    if arg_legend == True:
        scatter4 = plt.scatter(data[data.index == var4], data[data.index == var5], c = coloration, marker = ".", cmap = palette)
        legend4 = ax4.legend(*scatter4.legend_elements(), title = legend_title, bbox_to_anchor = (1.04, 1))
        ax4.add_artist(legend4)
    else:
        plt.scatter(data[data.index == var4], data[data.index == var5], c = coloration, marker = ".", cmap = palette)
        
    if (save == True):
        
        plt.savefig('output\\' + files_base + '\\' + save_name + '.png')
        




def clustering(data, hdb, normalisation, scale, var):
        
    mylist = pd.DataFrame(temp[['DI', 'FN']])
       
    #  --- Energie
    mylist['nrj'] = pd.DataFrame(data['LEVEL'] + (10 * np.log(data['DI'])))
    
    # --- FN / DI unif
    for variable in ('DI', 'FN'):
    
        tab = pd.DataFrame(data[variable])
        
        tab = tab.sort_values(by = variable, ascending = True)
        tab.index = range(0, len(tab))
    
        tab = np.array(tab[variable])
        tab = pd.DataFrame((np.ediff1d(tab, to_begin=0))) 
        
        tab.columns = [variable]
        tab = tab[tab[variable] != 0]
                
        if tab.empty == False:
            pas = min(tab[variable])
        else:
            pas = 0        
            
        # Modification des valeurs
        unif = pd.DataFrame(np.random.uniform(pas, -pas, len(data)))
        mylist[(variable + '_unif')] = pd.to_numeric(data[variable]) + unif[0]
        
        del tab, pas, unif, variable
    
    # Vérification de la positivité de la DI
    mylist['DI_unif'] = mylist['DI_unif'] - np.min(mylist['DI_unif']) + min(data['DI']) 
    
    # mylist['DI'] = data['DI']
    # mylist['FN'] = data['FN']
    if (var == 'Norm'):
        var = ['DI_unif', 'FN_unif']
    else:
        var = ['DI', 'FN']
   
    # --- Clustering : FN_unif / DI_unif
    if (normalisation == True):
        
        if (scale == 'Rs'):
            
            scale = RobustScaler(quantile_range=(5.0, 95.0)).fit(mylist[var])
            
        else:
            scale = StandardScaler().fit(mylist[var])
            
        tab = pd.DataFrame(scale.transform(mylist[var]))
        y_pred = pd.DataFrame(hdb.fit_predict(tab))
        
        del tab

        
    else:
        y_pred = pd.DataFrame(hdb.fit_predict(mylist[var]))
        
    mylist['cluster_unif'] = pd.DataFrame(np.int_(y_pred))
        
    data = pd.merge(data, mylist, left_index = True, right_index = True)
    
    del y_pred, mylist
    
    return data

#  ------------------------------------------------------------------------------------

#       Cas d'application 1

#  ------------------------------------------------------------------------------------
# From ScenarioFO
signal = 5
temp = mise_en_forme(signal, orientation = 'col') 
temp = temp[temp['TOA'] < 16]
temp = temp.sort_values(by=['TOA'])
temp.index = range(len(temp))

#  Création variable
temp['ID_radar'] = ""


# Boucle
for i in range(len(temp)):
    
    # --- D2
    if (temp.iloc[i, temp.columns.get_loc('FN_unif')] < 9700 ):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 1
        
    # --- B4
    else:
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 0

#  Check
pd.DataFrame(temp['ID_radar'].value_counts())

PLOT_simple(temp.T, var_coloration = 'cluster_unif', signal = signal, arg_legend = True, title = True, palette = 'tab20b',
          var1 = 'FN_unif', var2 = 'DI_unif', var3 = 'LEVEL', var4 = 'FN_unif', var5 = 'DI_unif',
                                      label_var1 = 'Frequency (MHz)', label_var2 = 'Pulse width (ns)', 
                                      label_var3 = 'Level (dBm)', label_var4 = 'Frequency (MHz)', label_var5 = 'Pulse width (ns)',
                                      save = mode_save, save_name = 'original_data')




#  --- Dendogrammes
#  TOA
k1_ot_toa, k1_dist_ot_toa = 3, 0.4297298238706681

PLOT_dendo(data = temp_without_outliers, signal = signal, linkage_matrix = Z_bin_ot_toa, var_clust = 'cluster_unif', value = True, 
         title = True, distance_cut = k1_dist_ot_toa, save = mode_save, save_name = 'dendo_ot_toa')



#  TOA + LEVEL
k1_ot_max_toa, k1_dist_ot_max_toa = 2, 0.3078449609289025

PLOT_dendo(data = temp_without_outliers, signal = signal, linkage_matrix = Z_bin_ot_max_toa, var_clust = 'cluster_unif', value = True, 
          title = True, distance_cut = k1_dist_ot_max_toa, save = mode_save, save_name = 'dendo_ot_max_toa')


# LEVEL
k1_ot_lvl, k1_dist_ot_lvl = 2, 5.517160217801721e-08

PLOT_dendo(data = temp_without_outliers, signal = signal, linkage_matrix = Z_bin_ot_lvl, var_clust = 'cluster_unif', value = True, 
         title = True, distance_cut = k1_dist_ot_lvl, save = mode_save, save_name = 'dendo_ot_lvl')




#  ------------------------------------------------------------------------------------

#       Cas d'application 2

#  ------------------------------------------------------------------------------------
# from ScenarioFO
# Sélection signal
signal = 3
temp = mise_en_forme(signal, orientation = 'col') 

#  Création variable
temp['ID_radar'] = -1


# Boucle
for i in range(len(temp)):
    
    # --- E10
    if(temp.iloc[i, temp.columns.get_loc('DI')] > 18):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 0
        
    elif(temp.iloc[i, temp.columns.get_loc('DI')] > 4 and temp.iloc[i, temp.columns.get_loc('DI')] < 6):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 0
        
    # --- S5_1
    elif(temp.iloc[i, temp.columns.get_loc('DI')] > 15 and temp.iloc[i, temp.columns.get_loc('DI')] < 17 and temp.iloc[i, temp.columns.get_loc('FN')] > 9362):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 1

    # --- P2
    elif(temp.iloc[i, temp.columns.get_loc('DI')] > 15 and temp.iloc[i, temp.columns.get_loc('DI')] < 17 and temp.iloc[i, temp.columns.get_loc('FN')] < 9362):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 2
        
    elif(temp.iloc[i, temp.columns.get_loc('DI')] > 7 and temp.iloc[i, temp.columns.get_loc('DI')] < 9):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 2

    # --- A5_1
    elif(temp.iloc[i, temp.columns.get_loc('DI')] < 0.4 and temp.iloc[i, temp.columns.get_loc('FN')] < 9300):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 3
        
    # --- A1 ?? au lieu de A7
    elif(temp.iloc[i, temp.columns.get_loc('DI')] < 0.4 and temp.iloc[i, temp.columns.get_loc('FN')] > 9380):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 4

#  Check
pd.DataFrame(temp['ID_radar'].value_counts())


PLOT_simple(temp.T, var_coloration = 'ID_radar', signal = signal, arg_legend = True, title = True, palette = 'tab20b',
              var1 = 'FN_unif', var2 = 'DI_unif', var3 = 'LEVEL', var4 = 'FN_unif', var5 = 'DI_unif',
                                          label_var1 = 'Frequency (MHz)', label_var2 = 'Pulse width (ns)', 
                                          label_var3 = 'Level (dBm)', label_var4 = 'Frequency (MHz)', label_var5 = 'Pulse width (ns)',
                                          save = mode_save, save_name = 'original_data')

#  --- Dendogrammes
#  TOA
k1_ot_toa, k1_dist_ot_toa = 4, 1.117
Z_bin_ot_toa2 = Z_bin_ot_toa.copy()


# Z_bin_ot_toa2.iloc[10, 2] = 0.1201
Z_bin_ot_toa2.iloc[11, 2] = 1.535
Z_bin_ot_toa2.iloc[12, 2] = 2.18


PLOT_dendo(data = temp_without_outliers, signal = signal, linkage_matrix = Z_bin_ot_toa2, var_clust = 'cluster_unif', value = True, 
         title = True, distance_cut = k1_dist_ot_toa, save = mode_save, save_name = 'dendo_ot_toa')



#  TOA + LEVEL
k1_ot_max_toa, k1_dist_ot_max_toa = 5, 0.748

Z_bin_ot_max_toa2 = Z_bin_ot_max_toa.copy()

Z_bin_ot_max_toa2.iloc[10, 2] = 0.977
Z_bin_ot_max_toa2.iloc[11, 2] = 1.164
Z_bin_ot_max_toa2.iloc[12, 2] = 2.592
Z_bin_ot_max_toa2.iloc[13, 2] = 2.791


PLOT_dendo(data = temp_without_outliers, signal = signal, linkage_matrix = Z_bin_ot_max_toa2, var_clust = 'cluster_unif', value = True, 
          title = True, distance_cut = k1_dist_ot_max_toa, save = mode_save, save_name = 'dendo_ot_max_toa')


# LEVEL
k1_ot_lvl, k1_dist_ot_lvl = 2, 0.75524607610568e-05

Z_bin_ot_lvl2 = Z_bin_ot_lvl.copy()

# Z_bin_ot_lvl2.iloc[11, 2] = 3.58732948540934e-06
Z_bin_ot_lvl2.iloc[12, 2] = 0.556865883680803e-05

PLOT_dendo(data = temp_without_outliers, signal = signal, linkage_matrix = Z_bin_ot_lvl2, var_clust = 'cluster_unif', value = True, 
         title = True, distance_cut = k1_dist_ot_lvl, save = mode_save, save_name = 'dendo_ot_lvl')

#  ------------------------------------------------------------------------------------

#       Cas d'application 3

#  ------------------------------------------------------------------------------------
# from ScenarioFO
# Sélection signal
signal = 2
temp = mise_en_forme(signal, orientation = 'col') 

#  Création variable
temp['ID_radar'] = -1


# Boucle
for i in range(len(temp)):
    
    # --- A8
    if(temp.iloc[i, temp.columns.get_loc('FN')] > 9505 and temp.iloc[i, temp.columns.get_loc('FN')] < 9515):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 0
                
    # --- A9
    elif(temp.iloc[i, temp.columns.get_loc('FN')] > 9400 and temp.iloc[i, temp.columns.get_loc('FN')] < 9410):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 1

    # --- D2
    elif(temp.iloc[i, temp.columns.get_loc('FN')] > 9595 and temp.iloc[i, temp.columns.get_loc('FN')] < 9650):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 2
        

    # --- B4
    elif(temp.iloc[i, temp.columns.get_loc('FN')] > 9750 and temp.iloc[i, temp.columns.get_loc('FN')] < 10000):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 3
        
    # --- A7
    elif(temp.iloc[i, temp.columns.get_loc('FN')] > 9190 and temp.iloc[i, temp.columns.get_loc('FN')] < 9270):
        temp.iloc[i, temp.columns.get_loc('ID_radar')] = 4
    
        
#  Check
pd.DataFrame(temp['ID_radar'].value_counts())


PLOT_simple(temp.T, var_coloration = 'ID_radar', signal = signal, arg_legend = True, title = True, palette = 'tab20',
              var1 = 'FN', var2 = 'DI', var3 = 'LEVEL', var4 = 'FN', var5 = 'DI',
                                          label_var1 = 'Frequency (MHz)', label_var2 = 'Pulse width (ns)', 
                                          label_var3 = 'Level (dBm)', label_var4 = 'Frequency (MHz)', label_var5 = 'Pulse width (ns)',
                                          save = mode_save, save_name = 'original_data')


# temp =  clustering(data = temp, hdb = hdb, normalisation = True)
#  --- Dendogrammes
#  LEVEL
k1_ot_lvl, k1_dist_ot_lvl = 4, 0.000002

Z_bin_ot_lvl2 = Z_bin_ot_lvl.copy()

Z_bin_ot_lvl2.iloc[11, 2] = 3.58732948540934e-06
Z_bin_ot_lvl2.iloc[12, 2] = 3.96573248540934e-06

PLOT_dendo(data = temp_without_outliers, signal = signal, linkage_matrix = Z_bin_ot_lvl2, var_clust = 'cluster_unif', value = True, 
         title = True, distance_cut = k1_dist_ot_lvl, save = mode_save, save_name = 'dendo_ot_lvl')


#  TOA
k1_ot_toa, k1_dist_ot_toa = 8, 0.0258

Z_bin_ot_toa2 = Z_bin_ot_toa.copy()

Z_bin_ot_toa2.iloc[6, 2] = 0.0371
Z_bin_ot_toa2.iloc[7, 2] = 0.0471
Z_bin_ot_toa2.iloc[8, 2] = 0.067
Z_bin_ot_toa2.iloc[9, 2] = 0.0757
Z_bin_ot_toa2.iloc[10, 2] = 0.1201
Z_bin_ot_toa2.iloc[11, 2] = 0.1356
Z_bin_ot_toa2.iloc[12, 2] = 0.1902


PLOT_dendo(data = temp_without_outliers, signal = signal, linkage_matrix = Z_bin_ot_toa2, var_clust = 'cluster_unif', value = True, 
         title = True, distance_cut = k1_dist_ot_toa, save = mode_save, save_name = 'dendo_ot_toa')

#  TOA + LEVEL
k1_ot_max_toa, k1_dist_ot_max_toa = 5, 0.05

Z_bin_ot_max_toa2 = Z_bin_ot_max_toa.copy()


Z_bin_ot_max_toa2.iloc[10, 2] = 0.1603
Z_bin_ot_max_toa2.iloc[11, 2] = 0.2364
Z_bin_ot_max_toa2.iloc[12, 2] = 0.461


PLOT_dendo(data = temp_without_outliers, signal = signal, linkage_matrix = Z_bin_ot_max_toa2, var_clust = 'cluster_unif', value = True, 
          title = True, distance_cut = k1_dist_ot_max_toa, save = mode_save, save_name = 'dendo_ot_max_toa')


