import nixio as nix
import os
from IPython import embed
#from utility import *
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib.mlab as ml
import scipy.integrate as si
from scipy.ndimage import gaussian_filter
from IPython import embed
from myfunctions import *
from myfunctions import auto_rows
from functionssimulation import  default_settings
import matplotlib.gridspec as gridspec

def ps_df(data, d = '2019-09-23-ad-invivo-1', wish_df = 310, window = 'no',sampling_rate = 40000):

    #nfft = 4096
    #trial_cut = 0.1
    #freq_step = sampling_rate / nfft
    data_cell = data[data['dataset'] == d]#
    dfs = np.unique(data_cell['df'])
    df_here = dfs[np.argmin(np.abs(dfs - wish_df))]
    dfs310 = data_cell[data_cell['df'] == df_here]
    #pp = [[]]*len(dfs310)
    pp = []
    ppp = []
    trial_cut = 0.1
    for i in range(len(dfs310)):
        duration = dfs310.iloc[i]['durations']
        #cut_vec = np.arange(0, duration, trial_cut)
        cut_vec = np.arange(0, duration, trial_cut)
        #spikes_cut = spikes[(spikes > 0.05) & (spikes < 0.95)]
        #for j, cut in enumerate(cut_vec):
        #    # print(j)
        #    spike_times = dfs310.iloc[i]['spike_times']
        #    spikes = spike_times - spike_times[0]
        #    spikes_cut = spikes[(spikes > cut) & (spikes < cut_vec[j + 1])]
        #    if cut == cut_vec[-2]:
        #        #counter_cut += 1
        #        break
        #    if len(spikes_cut) < 10:
        #        #counter_spikes += 1
        #        break
        #    spikes_mat = np.zeros(int(trial_cut * sampling_rate) + 1)
        #    spikes_idx = np.round((spikes_cut - trial_cut * j) * sampling_rate)
        #    for spike in spikes_idx:
        #        spikes_mat[int(spike)] = 1#
        #
        #    #spikes_mat = np.zeros(int(spikes[-1]* sampling_rate + 5))
        #    #spikes_idx = np.round((spikes) * sampling_rate)
        #    #for spike in spikes_idx:
        #    #    spikes_mat[int(spike)] = 1
        #    spikes_mat = spikes_mat * sampling_rate
        #    if type(window) != str:
        #        spikes_mat = gaussian_filter(spikes_mat, sigma=window)
        #        # smoothened_spikes_mat05 = gaussian_filter(spikes_mat, sigma=window05) * sampling_rate
        #        # smoothened_spikes_mat2 = gaussian_filter(spikes_mat, sigma=window2) * sampling_rate
        #    else:
        #        smoothened = spikes_mat * 1
        #    nfft = 4096
        #    p, f = ml.psd(spikes_mat - np.mean(spikes_mat), Fs=sampling_rate, NFFT=nfft, noverlap=nfft / 2)
        #    pp.append(p)
        spike_times = dfs310.iloc[i]['spike_times']
        if len(spike_times) < 3:
            counter_spikes += 1
            break

        spikes = spike_times - spike_times[0]
        spikes_cut = spikes[(spikes > 0.05) & (spikes < 0.95)]
        if len(spikes_cut) < 3:
            counter_cut += 1
            break
        spikes_mat = np.zeros(int(spikes[-1] * sampling_rate + 5))
        spikes_idx = np.round((spikes) * sampling_rate)
        for spike in spikes_idx:
            spikes_mat[int(spike)] = 1
        spikes_mat = spikes_mat * sampling_rate
        if type(window) != str:
            spikes_mat = gaussian_filter(spikes_mat, sigma=window)
            # smoothened_spikes_mat05 = gaussian_filter(spikes_mat, sigma=window05) * sampling_rate
            # smoothened_spikes_mat2 = gaussian_filter(spikes_mat, sigma=window2) * sampling_rate
        else:
            spikes_mat = spikes_mat*1
        nfft = 4096
        p, f = ml.psd(spikes_mat - np.mean(spikes_mat), Fs=sampling_rate, NFFT=nfft, noverlap=nfft / 2)
        ppp.append(p)
        #spike_times = data_cell.iloc[i]['spike_times']#

        #if len(spike_times) < 3:
        #    counter_spikes += 1
        #    break

        #spikes = spike_times - spike_times[0]

        # cut trial into snippets of 100 ms
        #cut_vec = np.arange(0, duration, trial_cut)
        #spikes_cut = spikes[(spikes > 0.05) & (spikes < 0.95)]

        #if len(spikes_cut) < 3:
        #    counter_cut += 1
        #    break
        #spikes_new = spikes_cut - spikes_cut[0]

        #spikes_mat = np.zeros(int(spikes_new[-1] * sampling_rate) + 2)
        # spikes_mat = np.zeros(int(trial_cut * sampling_rate) + 1)
        #spikes_idx = np.round((spikes_new) * sampling_rate)
        #for spike in spikes_idx:
        #    spikes_mat[int(spike)] = 1
        #spikes_mat = spikes_mat * sampling_rate

        #nfft = 4096
        #p, f = ml.psd(smoothened - np.mean(smoothened), Fs=sampling_rate, NFFT=nfft, noverlap=nfft / 2)
        #ppp.append(p)
    #p_mean = np.mean(pp,axis = 0)
    p_mean2 = np.mean(ppp, axis=0)
    #ref = (np.max(p_mean2))
    #
    db = 10 * np.log10(p_mean2 / np.max(p_mean2))
    #ref = (np.max(p_mean2))
    #db2 = 10 * np.log10(p_mean2 / ref)
    #embed()
    return df_here,p_mean2,f,db



def plot_example_ps(grid,input = ['2019-10-21-aa-invivo-1'],sigma = [0.00005,0.00025,0.0005, 0.002]):
    sampling_rate = 40000
    colors = ['#BA2D22', '#F47F17', '#AAB71B', '#3673A4', '#53379B']
    plt.rcParams['lines.linewidth'] = 1.5
    plt.rcParams['lines.markersize'] = 6
    #data = pd.read_pickle('data_beat.pkl')
    #iter = np.unique(data['dataset'])
    iter = ['2019-05-07-by-invivo-1']
    iter = ['2019-09-23-ad-invivo-1']
    iter = input
    for cell in iter:
        data = pd.read_pickle('data_beat.pkl')
        beat_results = pd.read_pickle('beat_results_smoothed.pkl')
        #embed()
        eodf = int(beat_results[beat_results['dataset'] == cell]['eodf'].iloc[0])
        df = [[]] * (len(sigma) + 1)
        p = [[]] * (len(sigma) + 1)
        f = [[]] * (len(sigma) + 1)
        db = [[]] * (len(sigma) + 1)
        sigmaf = [[]] * (len(sigma) + 1)
        gauss = [[]] * (len(sigma) + 1)
        wish_df = 150
        df[0], p[0], f[0], db[0] = ps_df(data, d=cell, wish_df= wish_df, window='no', sampling_rate=sampling_rate)
        for i in range(len(sigma)):
            df[1+i], p[1+i], f[1+i], db[1+i] = ps_df(data, d=cell, wish_df= wish_df, window =  sigma[i]*sampling_rate,sampling_rate = sampling_rate)
            sigmaf[i + 1] = 1 / (2 * np.pi * sigma[i])
            gauss[i + 1] = np.exp(-(f[1+i] ** 2 / (2 * sigmaf[i + 1] ** 2)))
        db = 'no'
        stepsize = f[0][1] - f[0][0]
        if db == 'db':
            p = db


        # fig.suptitle(d, labelpad = 25)
        #print(d)
        ax = {}
        ax[0] = plt.subplot(grid[0])
        ax[0].plot(f[0], p[0], color=colors[0])
        ax[0].plot(eodf - 1, np.max(p[0][int(eodf / stepsize) - 5:int(eodf / stepsize) + 5]) * 0.95, color='k',
                   marker='o', linestyle='None', label='EODf')  # = '+str(int(eodf))+' Hz')
        #embed()
        ax[0].fill_between(f[1], [max(p[0])]*len(f[1]), facecolor='lightgrey', edgecolor='grey')
        ax[0].plot(df[0], np.max(p[0][int(abs(df[0]) / stepsize) - 5:int(abs(df[0]) / stepsize) + 5]) * 0.95,
                   color=colors[1], marker='o', linestyle='None', label='Df')
        ax[0].plot(df[0] + eodf, p[0][int((df[0] + eodf) / stepsize) + 1], color=colors[2], marker='o', linestyle='None',
                   label='stimulus')
        ax[0].legend(bbox_to_anchor=(0.4, 1, 0.6, .1), loc='lower left',
                     ncol=3, mode="expand", borderaxespad=0.)
        ax[0].set_xlim([0, 2000])
        wide = 2
        for i in range(len(sigma)):
            ax[i+1] = plt.subplot(grid[i+1])
            plot_filter(ax, i+1, f[1+i], p, colors, gauss[1+i], eodf, stepsize, wide, df[1+i])
            ax[i+1].set_xlim([0, 2000])
        #embed()
        #if db == 'db':
        #    ax[0].set_ylim([np.min([p]),0])#p[0][,p[1][0:2000],p[2][0:2000],p[3][0:2000]
        #else:
        #    ax[0].set_ylim([ 0,np.max([p])])
        ax[int(len(df))-1].set_xlabel('frequency [Hz]')
        # ax[1].set_ylabel(r'power [Hz$^2$/Hz]')
        ax[0].ticklabel_format(axis='y', style='sci', scilimits=[0, 0])


        #print(df[3])
        for i in range(len(df)):
            ax[i].spines['right'].set_visible(False)
            ax[i].spines['top'].set_visible(False)
        cols = grid.ncols
        rows = grid.nrows
        ax[int(cols*(rows/2))-1].set_ylabel('               power spectral density [Hz²/Hz]')
        #ax[2].set_ylabel('Hz²/Hz')
        #ax[3].set_ylabel('Hz²/Hz')
        #ax[0].set_ylabel('Hz²/Hz')
        for i in range(len(df)):
            ax[i].axvline(x = eodf/2, color = 'black', linestyle = 'dashed')
        plt.tight_layout()
        #fig.label_axes()

def plot_filter(ax, ax_nr,  f, p4, colors, gauss3, eodf, stepsize, wide, df):
    ax[ax_nr].plot(f, p4[ax_nr], color=colors[0])
    ax[ax_nr].fill_between(f, max(p4[0]) * gauss3 ** 2, facecolor='lightgrey', edgecolor='grey')
    ax[ax_nr].plot(eodf, np.max(p4[ax_nr][int(eodf / stepsize) - wide:int(eodf / stepsize) + wide]) * 0.95, color='k', marker='o',
               linestyle='None')
    ax[ax_nr].plot(abs(df), np.max(p4[ax_nr][int(abs(df) / stepsize) - wide:int(abs(df) / stepsize) + wide]) * 0.95,
               color=colors[1], marker='o', linestyle='None')
    ax[ax_nr].plot(df + eodf,
               np.max(p4[ax_nr][int((df + eodf) / stepsize) - wide:int((df + eodf) / stepsize) + wide]) * 0.95,
               color=colors[2], marker='o', linestyle='None')
    return ax



def plot_amp(ax, mean1, dev,name = 'amp',nr = 1):
    np.unique(mean1['type'])
    all_means = mean1[mean1['type'] == name +' mean']
    original = all_means[all_means['dev'] == 'original']
    #m005 = all_means[all_means['dev'] == '005']
    m05 = all_means[all_means['dev'] == '05']
    m2 = all_means[all_means['dev'] == '2']
    # fig, ax = plt.subplots(nrows=4, ncols = 3, sharex=True)
    versions = [original, m05, m2] #m005,
    for i in range(len(versions)):
        keys = [k for k in versions[i]][2::]
        try:
            data = np.array(versions[i][keys])[0]
        except:
            break
        axis = np.arange(0, len(data), 1)
        axis_new = axis * 1
        similarity = [keys, data]
        sim = np.argsort(similarity[0])
        # similarity[sim]
        all_means = mean1[mean1['type'] == name+' std']
        std = all_means[all_means['dev'] == dev[i]]
        std = np.array(std[keys])[0]
        #ax[1, 1].set_ylabel('Modulation depth')
        #ax[nr,i].set_title(dev[i] + ' ms')
        all_means = mean1[mean1['type'] == name+' 95']
        std95 = all_means[all_means['dev'] == dev[i]]
        std95 = np.array(std95[keys])[0]
        all_means = mean1[mean1['type'] == name+' 05']
        std05 = all_means[all_means['dev'] == dev[i]]
        std05 = np.array(std05[keys])[0]
        ax[nr,i].fill_between(np.array(keys)[sim], list(std95[sim]), list(std05[sim]),
                              color='gainsboro')
        ax[nr,i].fill_between(np.array(keys)[sim], list(data[sim] + std[sim]), list(data[sim] - std[sim]),
                              color='darkgrey')

        # ax[i].plot(data_tob.ff, data_tob.fe, color='grey', linestyle='--', label='AMf')
        ax[nr,i].plot(np.array(keys)[sim], data[sim], color='black')
        # ax[0].plot(data1.x, data1.freq20, color=colors[1], label='20 %')
    #embed()
    return ax

def create_beat_corr(hz_range, eod_fr):
    beat_corr = hz_range%eod_fr
    beat_corr[beat_corr>eod_fr/2] = eod_fr[beat_corr>eod_fr/2] - beat_corr[beat_corr>eod_fr/2]
    return beat_corr


def plot_mean_cells(grid, sigma = ['original','05','2'],lw = 0.7):
    mean1 = pd.read_pickle('mean.pkl')

    colors = ['#BA2D22', '#F47F17', '#AAB71B', '#3673A4', '#53379B']
    inch_factor = 2.54

    half_page_width = 7.9 / inch_factor
    intermediate_width = 12 / inch_factor
    whole_page_width = 16 * 2 / inch_factor

    small_length = 6 / inch_factor
    intermediate_length = 12 * 1.5 / inch_factor
    max_length = 25 / inch_factor
    whole_page_width = 6.7
    intermediate_length = 3.7

    #plt.rcParams['figure.figsize'] = (whole_page_width, intermediate_length)
    plt.rcParams['font.size'] = 11
    plt.rcParams['axes.titlesize'] = 12
    plt.rcParams['axes.labelsize'] = 12
    plt.rcParams['lines.linewidth'] = 1.5
    plt.rcParams['lines.markersize'] = 8
    plt.rcParams['legend.loc'] = 'upper right'
    plt.rcParams["legend.frameon"] = False

    # load data for plot

    # data1 = pd.read_csv('ma_allcells_unsmoothed.csv')
    # data2 = pd.read_csv('ma_allcells_05.csv')
    # data3 = pd.read_csv('ma_allcells_2.csv')
    # data_tob = pd.read_csv('ma_toblerone.csv')

    # smothed = df_beat[df_beat['dev'] == 'original']
    # data1 = smothed[smothed['type'] == 'amp']

    x = np.arange(0, 2550, 50)
    corr = create_beat_corr(x, np.array([500] * len(x)))

    np.unique(mean1['type'])
    all_means = mean1[mean1['type'] == 'max mean']

    #versions = [[]]*len(dev)
    #for i in range(len(dev)):
    version =[[]]*len(sigma)
    version2 = [[]] * len(sigma)
    dev = [[]] * len(sigma)
    all_means2 = mean1[mean1['type'] == 'amp max' + ' mean']
    for i in range(len(sigma)):
        try:
            version[i] = all_means[all_means['dev'] == sigma[i]]
            version2[i] = all_means2[all_means2['dev'] == sigma[i]]
        except:
            version[i] = []
        print(sigma[i])
        dev[i] = sigma[i]
        #if sigma[i] == 'original':
        #    titles[i] = 'binary'
        #else:
        #    titles[i] = str(np.float(sigma[i])/1000

    #original = all_means[all_means['dev'] == 'original']
    # m005 = all_means[all_means['dev'] == '005']

    #m2 = all_means[all_means['dev'] == '2']
    # fig, ax = plt.subplots(nrows=4, ncols = 3, sharex=True)
    #versions = [original, m05, m2]  # m005,
    #dev = ['original',  '05', '2']#'005',
    titels = ['binary','0.005 ms','0.25 ms','0.5 ms','2 ms']
    #fig, ax = plt.subplots(nrows=2, ncols=len(sigma), sharex=True)
    #plt.subplot(axis)
    #grid = gridspec.GridSpec(2, 3, wspace=0.0, height_ratios=[6, 2], width_ratios=[1,0.5,3], hspace=0.2)

    #versions = [original,  m05, m2]#m005,
    ax = {}
    for i in range(len(version)):
        if len(version[i])>0:
            print(i)
            plots = gridspec.GridSpecFromSubplotSpec(2, 1,
                                                    subplot_spec=grid[i], wspace=0, hspace=0.5)
            keys = [k for k in version[i]][2::]
            try:
                data = np.array(version[i][keys])[0]
            except:
                #embed()
                break
            axis = np.arange(0, len(data), 1)
            axis_new = axis * 1
            similarity = [keys, data]
            sim = np.argsort(similarity[0])
            # similarity[sim]
            all_means = mean1[mean1['type'] == 'max std']
            std = all_means[all_means['dev'] == dev[i]]
            std = np.array(std[keys])[0]
            #ax[0,i].set_title(dev[i] +' ms')
            ax[0] = plt.subplot(plots[0])
            ax[0].set_title(titels[i])
            ax[0].set_ylabel('MPF [EODf]')
            all_means = mean1[mean1['type'] == 'max 95']
            std95 = all_means[all_means['dev'] == dev[i]]
            std95 = np.array(std95[keys])[0]
            all_means = mean1[mean1['type'] == 'max 05']
            std05 = all_means[all_means['dev'] == dev[i]]
            std05 = np.array(std05[keys])[0]
            #std[np.where(list(data[sim] + std[sim])>std95[sim])] = std95[sim][np.where(list(data[sim] + std[sim])>std95[sim])]
            #embed()
            ax[0].fill_between(np.array(keys)[sim], list(std95[sim]), list(std05[sim]),
                                  color='mistyrose')
            #embed()

            ax[0].fill_between(np.array(keys)[sim], list(data[sim] + std[sim]), list(data[sim] - std[sim]), color='pink')

            ax[0].plot(x / 500, corr / 500 + 1, color='grey', linestyle='--', label='AMf')
            ax[0].plot(np.array(keys)[sim], data[sim], color='red', linewidht = lw)
            # plt.fill_between(np.array([0,1]),np.array([0,0]),np.array([1,1]))

            #embed()
            ax[1] = plt.subplot(plots[1])
            name = 'amp max'
            np.unique(mean1['type'])
            keys = [k for k in version2[i]][2::]
            try:
                data = np.array(version2[i][keys])[0]
            except:
                break
            axis = np.arange(0, len(data), 1)
            axis_new = axis * 1
            similarity = [keys, data]
            sim = np.argsort(similarity[0])
            # similarity[sim]
            all_means = mean1[mean1['type'] == name + ' std']
            std = all_means[all_means['dev'] == dev[i]]
            std = np.array(std[keys])[0]
            # ax[1, 1].set_ylabel('Modulation depth')
            # ax[nr,i].set_title(dev[i] + ' ms')
            all_means = mean1[mean1['type'] == name + ' 95']
            std95 = all_means[all_means['dev'] == dev[i]]
            std95 = np.array(std95[keys])[0]
            all_means = mean1[mean1['type'] == name + ' 05']
            std05 = all_means[all_means['dev'] == dev[i]]
            std05 = np.array(std05[keys])[0]
            ax[1].fill_between(np.array(keys)[sim], list(std95[sim]), list(std05[sim]),
                                   color='gainsboro')
            ax[1].fill_between(np.array(keys)[sim], list(data[sim] + std[sim]), list(data[sim] - std[sim]),
                                   color='darkgrey')

            # ax[i].plot(data_tob.ff, data_tob.fe, color='grey', linestyle='--', label='AMf')
            ax[1].plot(np.array(keys)[sim], data[sim], color='black')
            # ax[0].plot(data1.x, data1.freq20, color=colors[1], label='20 %')
            # ax[0].plot(data1.x, data1.freq20, color=colors[1], label='20 %')
            ax[0].spines['right'].set_visible(False)
            ax[0].spines['top'].set_visible(False)
            ax[1].spines['right'].set_visible(False)
            ax[1].spines['top'].set_visible(False)
    ax[1].legend(bbox_to_anchor=(0.7, 1, 0.7, .1), loc='lower left',
                    ncol=3, mode="expand", borderaxespad=0.)

    #ax = plot_amp(ax, mean1, dev,name = 'amp',nr = 2)
    ax[0].legend(bbox_to_anchor=(0.3, 1, 0.7, .1), loc='lower left',
                    ncol=3, mode="expand", borderaxespad=0.)
    #ax = plot_amp(ax,mean1, dev,name='amp max', nr=1)
    # ax[1].plot(data_tob.ff, data_tob.fe, color='grey', linestyle='--')
    # ax[1].plot(data2.x, transfer_array, color=colors[0])
    # ax[1].plot(data2.x, data2.freq20, color=colors[1])

    # ax[2].plot(data_tob.ff, data_tob.fe, color='grey', linestyle='--')
    # ax[2].plot(data3.x, transfer_array, color=colors[0])
    # ax[2].plot(data3.x,  color=colors[1])

    # ax[2].plot(data_tob.ff, transfer_array, color='grey', linestyle='--')
    # ax[2].plot(data4.x, transfer_array, color=colors[0])
    # ax[2].plot(data3.x,  color=colors[1])

    ax[0].set_ylabel('MPF [EODf]')
    #ax[1, 0].set_ylabel('Modulation depth')
    ax[1].set_ylabel('Modulation Peak')
    #ax[2, 0].set_ylabel('Whole modulation ')



    #for i in range(3):
    ax[0].set_xlabel('stimulus frequency [EODf]')
    #ax[2, 1].set_xlabel('stimulus frequency [EODf]')
    plt.subplots_adjust(bottom = 0.13)
    #fig.tight_layout()
    # fig.label_axes()





if __name__ == "__main__":
    data = ['2019-10-21-aa-invivo-1']
    #fig, ax = plt.subplots(nrows=5, sharex=True, sharey=True)
    trans = True
    sigma = [0.0005, 0.002]  # 0.00005,0.00025,
    if trans == True:
        col = 1
        row = 2
        col_small = len(sigma)+1
        row_small = 1
        l = 6
        t = 'horizontal'
        wd = [1]
        hd = [1,2.5]
        left = 1
        right = 0
    else:
        col = 2
        row = 1
        row_small = len(sigma)+1
        col_small = 1
        t = 'vertical'
        l = 9
        wd = [4, 4]
        hd = [1]
        left = 0
        right = 1
    default_settings(data, intermediate_width=7.4, intermediate_length=6, ts=6, ls=10, fs=10)
    grid = gridspec.GridSpec(row, col, wspace=0.35,height_ratios = hd, width_ratios=wd, hspace=0.2)#,

    axis = gridspec.GridSpecFromSubplotSpec(row_small,col_small,
                                             subplot_spec=grid[0,0], wspace=0.15, hspace=0.1)
    plot_example_ps(axis,input = ['2019-10-21-aa-invivo-1'],sigma = sigma)
    #plt.show()
    #embed()
    #fig.savefig()
    axis = gridspec.GridSpecFromSubplotSpec(row_small,col_small,
                                             subplot_spec=grid[left,right], wspace=0.15, hspace=0.3)
    #embed()
    plot_mean_cells(axis, sigma = ['original','05','2'])#'005','025',
    plt.savefig('temporalplot.pdf')
    plt.savefig('../highbeats_pdf/temporalplot.pdf')
    plt.savefig('temporalplot'+t+'.pdf')
    plt.show()
    # plt.savefig('../results/Ramona/ma_powerspecs_negative_df' + d + '.pdf')
    # plt.show()
    # plt.close()
    # embed()
    # plot_single_tublerones() # original beat_activity