
import numpy as np
import matplotlib.pyplot as plt
from IPython import embed
from model import simulate, load_models
import matplotlib.gridspec as gridspec
from myfunctions import default_settings
"""
Dependencies:
numpy 
matplotlib
numba (optional, speeds simulation up: pre-compiles functions to machine code)
"""


def main():
    # tiny example program:
    #embed()
    parameters = load_models("models.csv")
    freq_all = [[]]*len(parameters)
    isis_all = [[]] * len(parameters)
    spikes_all = [[]] * len(parameters)
    period_all = [[]]* len(parameters)
    #for i in range(4):
    for i in range(len(parameters)):
        model_params = parameters[i]
        cell = model_params.pop('cell')
        print(cell)
        EODf = model_params.pop('EODf')


        # generate EOD-like stimulus
        deltat = model_params["deltat"]
        stimulus_length = 11.0  # in seconds
        time = np.arange(0, stimulus_length,deltat)
        # baseline EOD with amplitude 1:
        stimulus = np.sin(2 * np.pi * EODf * time)
        # das lasse ich eine sekunde integrieren dann weitere 10 sekunden integrieren und das nehmen
        spikes = simulate(stimulus, **model_params)
        period_all[i] = 1/EODf
        # cut off first second of response
        new_spikes = spikes[spikes >1]
        #spikes_all[i] = new_spikes*1
        freq,isis = calculate_isi_frequency(new_spikes, deltat)
        freq_all[i] = freq
        isis_all[i] = isis
        #embed()

    default_settings([0], intermediate_width=6.29*2, intermediate_length=10, ts=9, ls=9, fs=7)
    row = int(np.sqrt(len(parameters)))
    col =  int(np.ceil(np.sqrt(len(parameters))))
    grid = gridspec.GridSpec(row,col,hspace = 1, wspace = 0.5)
    ax = {}
    for i in range(len(freq_all)):
        ax[i] = plt.subplot(grid[i])
        plt.title('#'+str(i) +'B: '+str(int(np.mean(freq_all[i])))+'Hz')
        plt.hist(isis_all[i]/(1/EODf), bins = 100, density = True)
    ax[int(row*col-row/2)].set_xlabel('EOD multiples')
    plt.savefig('isi_model.pdf')
    plt.savefig('../highbeats_pdf/isi_model.pdf')
    plt.show()
    embed()



def calculate_isi_frequency(spikes, deltat):
    """
    calculates inter-spike interval frequency
    (wasn't tested a lot may give different length than time = np.arange(spikes[0], spikes[-1], deltat),
    or raise an index error for some inputs)

    :param spikes: spike time points
    :param deltat: integration time step of the model

    :return: the frequency trace:
                starts at the time of first spike
                ends at the time of the last spike.
    """

    isis = np.diff(spikes)
    freq_points = 1 / isis
    freq = np.zeros(int((spikes[-1] - spikes[0]) / deltat))

    current_idx = 0
    for i, isi in enumerate(isis):
        end_idx = int(current_idx + np.rint(isi / deltat))
        freq[current_idx:end_idx] = freq_points[i]
        current_idx = end_idx

    return freq,isis


if __name__ == '__main__':
    main()
