1818from scipy .stats import zscore
1919#Generate scatterplots, variances, 2-state AR-HMMs to summarize differences in behavior in different sessions. Develop a 1-page figure per session that provides a behavioral overview. Would be great to generate these figs for the RS sessions noted in repro-ephys slides above
2020#lickogram
21-
21+ import matplotlib
2222# https://github.com/lindermanlab/ssm
2323
2424
@@ -122,9 +122,9 @@ def get_dlc_XYs(eid, video_type):
122122 dataset_types = ['camera.dlc' , 'camera.times' ]
123123 a = one .list (eid ,'dataset-types' )
124124 # for newer iblib version do [x['dataset_type'] for x in a]
125- if not all ([(u in [x ['dataset_type' ] for x in a ]) for u in dataset_types ]):
126- print ('not all data available' )
127- return
125+ # if not all([(u in [x['dataset_type'] for x in a]) for u in dataset_types]):
126+ # print('not all data available')
127+ # return
128128
129129
130130 one .load (eid , dataset_types = dataset_types )
@@ -158,41 +158,71 @@ def get_dlc_XYs(eid, video_type):
158158 return Times , XYs
159159
160160
161+ def get_ME (eid , video_type ):
162+
163+ #video_type = 'left'
164+ one = ONE ()
165+ dataset_types = ['camera.ROIMotionEnergy' , 'camera.times' ]
166+ a = one .list (eid ,'dataset-types' )
167+ # for newer iblib version do [x['dataset_type'] for x in a]
168+ # if not all([(u in [x['dataset_type'] for x in a]) for u in dataset_types]):
169+ # print('not all data available')
170+ # return
171+
172+
173+ one .load (eid , dataset_types = dataset_types )
174+ local_path = one .path_from_eid (eid )
175+ alf_path = local_path / 'alf'
176+
177+ cam0 = alf .io .load_object (
178+ alf_path ,
179+ '%sCamera' %
180+ video_type ,
181+ namespace = 'ibl' )
182+
183+ ME = np .load (alf_path / f'{ video_type } Camera.ROIMotionEnergy.npy' )
184+
185+ Times = cam0 ['times' ]
186+
187+ return Times , ME
188+
161189
162190
163- def get_example_images ():
191+ def get_example_images (eid ):
164192
165193
166194 eids = get_repeated_sites ()
167195# eid = eids[23]
168196# video_type = 'body'
169197
198+ #eids = ['15f742e1-1043-45c9-9504-f1e8a53c1744']
199+ eids = ['4a45c8ba-db6f-4f11-9403-56e06a33dfa4' ]
170200 frts = {'body' :30 , 'left' :60 ,'right' :150 }
171201
172202 one = ONE ()
173203
174204
175- for eid in eids :
176- for video_type in frts :
177-
178- frame_idx = [20 * 60 * frts [video_type ]]
179- try :
205+ #for eid in eids:
206+ for video_type in frts :
207+
208+ frame_idx = [20 * 60 * frts [video_type ]]
209+ try :
210+
211+ r = one .list (eid , 'dataset_types' )
212+ recs = [x for x in r if f'{ video_type } Camera.raw.mp4'
213+ in x ['name' ]][0 ]['file_records' ]
214+ video_path = [x ['data_url' ] for x in recs
215+ if x ['data_url' ] is not None ][0 ]
180216
181- r = one .list (eid , 'dataset_types' )
182- recs = [x for x in r if f'{ video_type } Camera.raw.mp4'
183- in x ['name' ]][0 ]['file_records' ]
184- video_path = [x ['data_url' ] for x in recs
185- if x ['data_url' ] is not None ][0 ]
186-
187- frames = get_video_frames_preload (video_path ,
188- frame_idx ,
189- mask = np .s_ [:, :, 0 ])
190- np .save ('/home/mic/reproducible_dlc/example_images/'
191- f'{ eid } _{ video_type } .npy' , frames )
192- print (eid , video_type , 'done' )
193- except :
194- print (eid , video_type ,'error' )
195- continue
217+ frames = get_video_frames_preload (video_path ,
218+ frame_idx ,
219+ mask = np .s_ [:, :, 0 ])
220+ np .save ('/home/mic/reproducible_dlc/example_images/'
221+ f'{ eid } _{ video_type } .npy' , frames )
222+ print (eid , video_type , 'done' )
223+ except :
224+ print (eid , video_type ,'error' )
225+ continue
196226
197227
198228 #'/home/mic/reproducible_dlc/example_images'
@@ -212,8 +242,15 @@ def plot_paw_on_image(eid, video_type, XYs = None):
212242 Cs_l = {'paw_l' :'r' ,'paw_r' :'cyan' }
213243 Cs_r = {'paw_l' :'cyan' ,'paw_r' :'r' }
214244 #for video_type in ['left','right']:#,'body']:
215- r = np .load (f'/home/mic/reproducible_dlc/example_images/'
216- f'{ eid } _{ video_type } .npy' )[0 ]
245+ try :
246+ r = np .load (f'/home/mic/reproducible_dlc/example_images/'
247+ f'{ eid } _{ video_type } .npy' )[0 ]
248+ except :
249+ get_example_images (eid )
250+ r = np .load (f'/home/mic/reproducible_dlc/example_images/'
251+ f'{ eid } _{ video_type } .npy' )[0 ]
252+
253+
217254 if XYs == None :
218255 _ , XYs = get_dlc_XYs (eid , video_type )
219256 #ax = plt.subplot(1,2,k)
@@ -262,16 +299,11 @@ def plot_paw_on_image(eid, video_type, XYs = None):
262299 k += 1
263300 plt .tight_layout ()
264301 #plt.show()
265- #plt.legend()
302+ #plt.legend(loc='lower right' )
266303
267304
268305def paw_speed_PSTH (eid ):
269306
270- '''
271- lick PSTH
272- eid = 'd0ea3148-948d-4817-94f8-dcaf2342bbbe' is good
273- '''
274-
275307 rt = 2
276308 st = - 0.5
277309 fs = {'right' :150 ,'left' :60 }
@@ -331,11 +363,10 @@ def paw_speed_PSTH(eid):
331363
332364 ax = plt .gca ()
333365 ax .axvline (x = 0 , label = 'stimOn' , linestyle = '--' , c = 'g' )
334- plt .title ('paw speed PSTH \n '
335- 'right = paw closer to right cam' )
366+ plt .title ('paw speed PSTH' )
336367 plt .xlabel ('time [sec]' )
337368 plt .ylabel ('speed [px/sec]' )
338- plt .legend (fontsize = 10 )#bbox_to_anchor=(1.05, 1), loc='upper left')
369+ plt .legend ()#bbox_to_anchor=(1.05, 1), loc='upper left')
339370
340371
341372def nose_speed_PSTH (eid ,vtype = 'right' ):
@@ -413,7 +444,7 @@ def nose_speed_PSTH(eid,vtype='right'):
413444 f'{ vtype } vid' )
414445 plt .xlabel ('time [sec]' )
415446 plt .ylabel ('speed [px/sec]' )
416- plt .legend ()
447+ plt .legend (loc = 'lower right' )
417448
418449
419450def get_licks (XYs ):
@@ -492,7 +523,7 @@ def plot_licks(eid, combine=False):
492523 plt .title ('lick PSTH' )
493524 plt .xlabel ('time [sec]' )
494525 plt .ylabel ('lick events \n [a.u.]' )
495- plt .legend ()
526+ plt .legend (loc = 'lower right' )
496527 return licks_pos
497528
498529
@@ -580,7 +611,7 @@ def plot_wheel_position(eid):
580611 axes .set_ylim ([- 0.27 ,0.27 ])
581612 plt .xlabel ('time [sec]' )
582613 plt .ylabel ('wheel position [rad]' )
583- plt .legend ()
614+ plt .legend (loc = 'lower right' )
584615 plt .title ('wheel positions colored by choice' )
585616 plt .tight_layout ()
586617
@@ -661,7 +692,7 @@ def plot_sniffPSTH(eid,combine=False):
661692 plt .title ('sniff PSTH' )
662693 plt .xlabel ('time [sec]' )
663694 plt .ylabel ('sniff events \n [a.u.]' )
664- plt .legend ()
695+ plt .legend (loc = 'lower right' )
665696
666697
667698def get_pupil_diameter (XYs , smooth = True ):
@@ -830,7 +861,7 @@ def align_left_right_pupil(eid):
830861 plt .plot (timesL ,zscore (dRa ),label = 'right' )
831862 plt .title ('smoothed, aligned, z-scored right/left pupil diameter \n '
832863 f'{ eid } ' )
833- plt .legend ()
864+ plt .legend (loc = 'lower right' )
834865 plt .ylabel ('pupil diameter' )
835866 plt .xlabel ('time [sec]' )
836867
@@ -875,7 +906,7 @@ def pupil_diameter_PSTH(eid, s=None, times=None):
875906
876907
877908 MEAN = np .mean (D [stype ],axis = 0 )
878- STD = np .std (D [stype ],axis = 0 )
909+ STD = np .std (D [stype ],axis = 0 )/ np . sqrt ( len ( d ))
879910
880911 plt .plot (xs , MEAN , label = stype , color = cols [stype ])
881912 plt .fill_between (xs , MEAN + STD , MEAN - STD , color = cols [stype ],
@@ -886,7 +917,95 @@ def pupil_diameter_PSTH(eid, s=None, times=None):
886917 plt .title ('left cam pupil diameter PSTH' )
887918 plt .xlabel ('time [sec]' )
888919 plt .ylabel ('pupil diameter [px]' )
889- plt .legend ()
920+ plt .legend (loc = 'lower right' )
921+
922+
923+
924+
925+ def motion_energy_PSTH (eid ):
926+
927+ '''
928+ ME PSTH
929+ canonical session
930+ eid = '15f742e1-1043-45c9-9504-f1e8a53c1744'
931+ '''
932+
933+ rt = 4 # duration of window
934+ st = - 0.5 # lag of window wrt to stype
935+ stype = 'stimOn_times'
936+
937+ ME = {}
938+ one = ONE ()
939+ trials = one .load_object (eid ,'trials' )
940+ ts = trials .intervals [0 ][0 ]
941+ te = trials .intervals [- 1 ][1 ]
942+
943+ for video_type in ['left' ,'right' ,'body' ]:
944+ t ,m = get_ME (eid , video_type )
945+ m = zscore (m ,nan_policy = 'omit' )
946+
947+ sta , end = find_nearest (t ,ts ), find_nearest (t ,te )
948+ t = t [sta :end ]
949+ m = m [sta :end ]
950+
951+ ME [video_type ] = [t ,m ]
952+
953+ # align to body cam
954+ for video_type in ['left' ,'right' ]:
955+
956+ # align time series camera/neural
957+ interpolater = interp1d (
958+ ME [video_type ][0 ],
959+ np .arange (len (ME [video_type ][0 ])),
960+ kind = "cubic" ,
961+ fill_value = "extrapolate" )
962+
963+ idx_aligned = np .round (interpolater (ME ['body' ][0 ])).astype (int )
964+ ME [video_type ] = [ME ['body' ][0 ], ME [video_type ][1 ][idx_aligned ]]
965+
966+
967+ D = {}
968+
969+ fs = 30
970+ xs = np .arange (rt * fs ) # number of frames
971+ xs = np .concatenate ([- 1 * np .array (list (reversed (xs [:int (abs (st )* fs )]))),
972+ np .arange (rt * fs )[1 :1 + len (xs [int (abs (st )* fs ):])]])
973+ xs = xs / float (fs )
974+
975+ cols = {'left' :'r' ,'right' :'b' ,'body' :'g' }
976+
977+ for video_type in ME :
978+ # that's centered at feedback time
979+
980+
981+ D [video_type ] = []
982+
983+ times ,s = ME [video_type ]
984+
985+ trs = trials [stype ][20 :- 20 ]
986+ for i in trs :
987+
988+ start_idx = int (find_nearest (times ,i ) + st * 30 )
989+ end_idx = int (start_idx + rt * 30 )
990+
991+ D [video_type ].append (s [start_idx :end_idx ])
992+
993+
994+ MEAN = np .mean (D [video_type ],axis = 0 )
995+ STD = np .std (D [video_type ],axis = 0 )/ np .sqrt (len (trs ))
996+
997+
998+ plt .plot (xs , MEAN , label = video_type ,
999+ color = cols [video_type ], linewidth = 2 )
1000+ plt .fill_between (xs , MEAN + STD , MEAN - STD , color = cols [video_type ],
1001+ alpha = 0.2 )
1002+
1003+ ax = plt .gca ()
1004+ ax .axvline (x = 0 , label = 'stimOn' , linestyle = '--' , c = 'k' )
1005+ plt .title ('Motion Energy PSTH' )
1006+ plt .xlabel ('time [sec]' )
1007+ plt .ylabel ('z-scored motion energy [a.u.]' )
1008+ plt .legend (loc = 'lower right' )
8901009
8911010
8921011def interp_nans (y ):
@@ -899,7 +1018,6 @@ def nan_helper(y):
8991018 return y2
9001019
9011020
902-
9031021def add_panel_letter (k ):
9041022
9051023 '''
@@ -912,21 +1030,21 @@ def add_panel_letter(k):
9121030
9131031
9141032def plot_all (eid ):
915-
1033+ matplotlib . rcParams . update ({ 'font.size' : 15 })
9161034 # report eid = '4a45c8ba-db6f-4f11-9403-56e06a33dfa4'
9171035
918- nrows = 3
919- ncols = 2
1036+ nrows = 2
1037+ ncols = 4
9201038
9211039 plt .ion ()
9221040 one = ONE ()
9231041 plt .figure (figsize = (10 ,10 ))
9241042 plt .subplot (nrows ,ncols ,1 )
9251043 add_panel_letter (1 )
9261044 plot_paw_on_image (eid , 'left' )
927- p = one .path_from_eid (eid )
928- plt .title (' ' .join ([str (p ).split ('/' )[i ] for i in [5 ,7 ,8 ,9 ]]),
929- backgroundcolor = 'white' )
1045+ # p = one.path_from_eid(eid)
1046+ # plt.title(' '.join([str(p).split('/')[i] for i in [5,7,8,9]]),
1047+ # backgroundcolor= 'white')
9301048
9311049 plt .subplot (nrows ,ncols ,2 )
9321050 add_panel_letter (2 )
@@ -944,6 +1062,14 @@ def plot_all(eid):
9441062 plt .subplot (nrows ,ncols ,6 )
9451063 add_panel_letter (6 )
9461064 nose_speed_PSTH (eid )
1065+ plt .subplot (nrows ,ncols ,7 )
1066+ add_panel_letter (7 )
1067+ pupil_diameter_PSTH (eid )
1068+ plt .subplot (nrows ,ncols ,8 )
1069+ add_panel_letter (8 )
1070+ motion_energy_PSTH (eid )
1071+
1072+
9471073# plt.subplot(3,3,7)
9481074# plot_wheel_position(eid)
9491075# plt.subplot(3,3,8)
@@ -952,9 +1078,9 @@ def plot_all(eid):
9521078 #plot_sniffPSTH(eid)
9531079
9541080 plt .tight_layout ()
955- # p = one.path_from_eid(eid)
956- # plt.suptitle(' '.join([str(p).split('/')[i] for i in [5, 7,8,9 ]]),
957- # backgroundcolor= 'white')
1081+ p = one .path_from_eid (eid )
1082+ plt .suptitle (' ' .join ([str (p ).split ('/' )[i ] for i in [4 , 6 , 7 ,8 ]]),
1083+ backgroundcolor = 'white' )
9581084# plt.savefig(f'/home/mic/reproducible_dlc/{eid}.png')
9591085# plt.close()
9601086
0 commit comments