# Import libraries
import numpy as np

%config InlineBackend.figure_format = 'retina'
%matplotlib inline
import matplotlib.pyplot as plt

"""
Explanation: Scott Cole
6 May 2017
This notebook is to formalize the hypothesis that the neural response to a very fast movement in the preferred direction can be more similar to that of a movement in the opposite direction (perceptually: the wagon wheel effect).
The predicted neural response to a motion is computed by convolving the neural responses to static gratings
End of explanation
"""


kernel_fast = np.array([0, .5, 1, .8, .4, .2, .1, 0])
kernel_slow = np.hstack([np.arange(0,1,.15),np.arange(1,0,-.04)])

plt.figure(figsize=(5,6))
plt.subplot(2,1,1)
plt.plot(kernel_fast,'k')
plt.xlim((0,30))
plt.ylabel('Neural response\n(transient)',size=15)
plt.subplot(2,1,2)
plt.plot(kernel_slow,'k')
plt.xlim((0,30))
plt.xlabel('Time (a.u.)',size=20)
plt.ylabel('Neural response\n(sustained)',size=15)

"""
Explanation: 1. Define kernels of neuronal response to static gratings
The kernels plotted here represent the transient and sustained neural responses. (I believe these are firing rates in thalamic projection neurons in response to static gratings?)
End of explanation
"""


# Define times of sustained-response-inducing (slow)
# and transient-response-inducing (fast) stimuli
slow_event_time = 0
fast_event_time = 5

# Compute rasters of events
N = 60
slow_event_raster = np.zeros(N)
slow_event_raster[slow_event_time] = 1
fast_event_raster = np.zeros(N)
fast_event_raster[fast_event_time] = 1

# Compute trace of neural activity
slow_neural = np.convolve(slow_event_raster, kernel_slow, mode='full')
fast_neural = np.convolve(fast_event_raster, kernel_fast, mode='full')

neural_pref = np.copy(slow_neural)
neural_pref[:len(fast_neural)] += fast_neural

"""
Explanation: 2. Estimate neural response to preferred and opposite directions
In the preferred direction, the stimulus that induces a sustained response occurs before the stimulus that induces a transient response
Preferred direction
End of explanation
"""


# Define times of sustained-response-inducing (slow)
# and transient-response-inducing (fast) stimuli
fast_event_time = 0
slow_event_time = 5

# Compute rasters of events
slow_event_raster = np.zeros(N)
slow_event_raster[slow_event_time] = 1
fast_event_raster = np.zeros(N)
fast_event_raster[fast_event_time] = 1

# Compute trace of neural activity
slow_neural = np.convolve(slow_event_raster, kernel_slow, mode='full')
fast_neural = np.convolve(fast_event_raster, kernel_fast, mode='full')

neural_opp = np.copy(slow_neural)
neural_opp[:len(fast_neural)] += fast_neural

plt.plot(neural_pref,'k',label='preferred')
plt.plot(neural_opp,'r',label='opposite')
plt.legend(loc='best',title='Movement direction')
plt.xlabel('Time (a.u.)',size=20)
plt.ylabel('Neural response (a.u.)',size=20)
plt.xlim((0,N))

print('NOTE:')
print('Preferred direction movement: peaks of the transient and sustained responses align')
print('Opposite direction movement: transient peak preceds sustained neural response')

"""
Explanation: Opposite direction
End of explanation
"""


# Define times of sustained-response-inducing (slow)
# and transient-response-inducing (fast) stimuli
slow_event_time = 0
fast_event_time = 1

# Compute rasters of events
slow_event_raster = np.zeros(N)
slow_event_raster[slow_event_time] = 1
fast_event_raster = np.zeros(N)
fast_event_raster[fast_event_time] = 1

# Compute trace of neural activity
slow_neural = np.convolve(slow_event_raster, kernel_slow, mode='full')
fast_neural = np.convolve(fast_event_raster, kernel_fast, mode='full')

neural_pref_fast = np.copy(slow_neural)
neural_pref_fast[:len(fast_neural)] += fast_neural

plt.plot(neural_pref,'k',label='preferred')
plt.plot(neural_opp,'r',label='opposite')
plt.plot(neural_pref_fast,'b',label='preferred fast')
plt.legend(loc='best',title='Movement direction')
plt.xlabel('Time (a.u.)',size=20)
plt.ylabel('Neural response (a.u.)',size=20)
plt.xlim((0,N))

print('NOTE:\nThe maximum of the neural response is decreased when the preferred motion is very fast')

"""
Explanation: 3. Estimate neural response to fast movement in the preferred direction
End of explanation
"""


