%pylab inline
import datajoint as dj
from pipeline import preprocess, vis

"""
Explanation: Previous: Synchronization  ::: Next Process Movie 
Example: processing the Monet stimulus
In this notebook, we retrieve spikes inferred from the calcium traces and the synchronized visual stimuli of the type "Monet".
End of explanation
"""


(dj.ERD(vis.Monet)-2 + preprocess.Sync + vis.Trial).draw()

"""
Explanation: First, let get the trials with the Monet stimulus.  Let's review the relevant ERD below:
End of explanation
"""


trials = preprocess.Sync() * vis.Trial() & 'trial_idx between first_trial and last_trial'

"""
Explanation: The following query denotes all trials combined with synchronization information to the two-photon scan.
End of explanation
"""


(dj.ERD(preprocess.Spikes)-3+1).draw()

"""
Explanation: The preprocess.Sync table matches the calcium data with the visual stimuli. It identifies a sinlge two-photon recording and refers to the visual session vis.Session.
The query uses the fields first_trial and last_trial in preprocess.Sync to select the correct trials from the matching visual session.

Now the table preprocess.Spikes and its part table preprocess.Spikes.RateTrace contain spike rate traces inferred from calcium recordings processed in one way out of several options. 
Below is the relevant ERD:
End of explanation
"""


monet_datasets = preprocess.Spikes() & (trials & vis.Monet())

"""
Explanation: Thus the following query identifies all the datasets recorded with Monet trials:
End of explanation
"""


preprocess.Method() * preprocess.Method.Galvo()    # extraction methods for galvo microscopes

preprocess.SpikeMethod()

"""
Explanation: Some of these datasets represent the same recordings processed in different ways, which are enumerated in the lookup tables preprocess.Method and preprocess.SpikeMethod:
End of explanation
"""


monet_datasets = (preprocess.Spikes() & 
                  (trials & vis.Monet()) & 
                  dict(extract_method=2, spike_method=5))
monet_datasets

"""
Explanation: We restrict the datasets to one processing method:
End of explanation
"""


keys = list(monet_datasets.fetch.keys())     # keys for relevant datasets
key = keys[3]   #  identifies one dataset
dict(key)

"""
Explanation: Now let's fetch the primary key values of these datasets so that we can address them individually:
End of explanation
"""


time = (preprocess.Sync() & key).fetch1['frame_times'].squeeze()  # calcium scan frame times
traces = np.vstack((preprocess.Spikes.RateTrace() & key).fetch['rate_trace'])  # fetch traces
nslices = len(time)/traces.shape[1]   # number of slices in recording.
time = time[::nslices]   # keep only one timestamp per frame (ignore time offsets of slices)

"""
Explanation: Now let's fetch all the relevant information for the dataset identified by key:
End of explanation
"""


for trial_key in (trials & key).fetch.order_by('trial_idx').keys():
    print(dict(trial_key))

"""
Explanation: Now let's iterate through the visual trials:
End of explanation
"""


stimulus_info = (vis.Trial()*vis.Monet()*vis.MonetLookup() & trial_key).fetch1()

"""
Explanation: Now let's just look at the last trial addressed by trial_key (the last iteration of the loop above) and retrieve the stimulus movie shown during the trial:
End of explanation
"""


stimulus_info['flip_times'].flatten()   # the frame times of the visual stimulus

plt.imshow(stimulus_info['cached_movie'][:,:,100])   # show a frame from the movie
plt.grid(False)

"""
Explanation: The flip_times field contains the time stamps of the frames of the movie on the same clock and same units as the time retrieved earlier for calcium traces from preprocess.Sync:
End of explanation
"""


stimulus_info['params'][3]['direction'][0,0].flatten()   # radians

stimulus_info['params'][3]['onsets'][0,0].flatten()    # motion onset times (s)

stimulus_info['params'][3]['onsets'][0,0].flatten()    # motion offset times (s)

stimulus_info['params'][3]['frametimes'][0,0].flatten()  # movie frame times (s) within trial

"""
Explanation: The stimulus comprises periods of coherent motion.  The times and directions are contained in
End of explanation
"""


