Skip to content

Commit 304ab27

Browse files
authored
Update overview_plot_dlc.py
1 parent a015e1e commit 304ab27

File tree

1 file changed

+179
-53
lines changed

1 file changed

+179
-53
lines changed

dlc/overview_plot_dlc.py

Lines changed: 179 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from 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

268305
def 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

341372
def 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

419450
def 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

667698
def 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

8921011
def interp_nans(y):
@@ -899,7 +1018,6 @@ def nan_helper(y):
8991018
return y2
9001019

9011020

902-
9031021
def add_panel_letter(k):
9041022

9051023
'''
@@ -912,21 +1030,21 @@ def add_panel_letter(k):
9121030

9131031

9141032
def 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

Comments
 (0)