Skip to content

Commit 323231d

Browse files
authored
Update overview_plot_dlc.py
1 parent f833f65 commit 323231d

File tree

1 file changed

+145
-104
lines changed

1 file changed

+145
-104
lines changed

dlc/overview_plot_dlc.py

Lines changed: 145 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ def constant_reaction_time(eid, rt, st,stype='stim'):
105105
wheelMoves = one.load_object(eid, 'wheelMoves')
106106
trials = one.load_object(eid, 'trials')
107107
d = {} # dictionary, trial number and still interval
108-
108+
evts = ['goCue_times', 'feedback_times', 'probabilityLeft',
109+
'choice', 'feedbackType']
110+
109111
for tr in range(len(trials['intervals'])):
110112
if stype == 'motion':
111113
a = wheelMoves['intervals'][:,0]
@@ -115,9 +117,10 @@ def constant_reaction_time(eid, rt, st,stype='stim'):
115117
pl = trials['probabilityLeft'][tr]
116118
ft = trials['feedbackType'][tr]
117119

118-
if np.isnan(c):
119-
#print(f'feedback time is nan for trial {tr} and eid {eid}')
120-
continue
120+
121+
if any(np.isnan([trials[k][tr] for k in evts])):
122+
continue
123+
121124

122125
if c-b>10: # discard too long trials
123126
continue
@@ -270,10 +273,10 @@ def get_mean_positions(XYs):
270273
return mloc
271274

272275

273-
def plot_paw_on_image(eid, video_type, XYs = None):
276+
def plot_paw_on_image(eid, video_type='left', XYs = None):
274277

275278
#fig = plt.figure(figsize=(8,4))
276-
k = 1
279+
277280

278281
Cs_l = {'paw_l':'r','paw_r':'cyan'}
279282
Cs_r = {'paw_l':'cyan','paw_r':'r'}
@@ -286,54 +289,64 @@ def plot_paw_on_image(eid, video_type, XYs = None):
286289
r = np.load(f'/home/mic/reproducible_dlc/example_images/'
287290
f'{eid}_{video_type}.npy')[0]
288291

289-
290-
if XYs == None:
291-
_, XYs = get_dlc_XYs(eid, video_type)
292-
#ax = plt.subplot(1,2,k)
293-
294-
295-
ds = {'body':3,'left':6,'right':15}
296-
297-
if video_type == 'left':
298-
Cs = Cs_l
299-
else:
300-
Cs = Cs_r
301292

302-
for point in XYs:# ['paw_l','paw_r']:
303-
if point in ['tube_bottom', 'tube_top']:
304-
continue
305-
306-
# downsample; normalise number of points to be the same
307-
# across all sessions
308-
xs = XYs[point][0][0::ds[video_type]]
309-
ys = XYs[point][1][0::ds[video_type]]
310-
311-
plt.scatter(xs,ys, alpha = 0.05, s = 2,
312-
label = point)#, color = Cs[point])
313-
314-
# plot whisker pad rectangle
315-
mloc = get_mean_positions(XYs)
316-
p_nose = np.array(mloc['nose_tip'])
317-
p_pupil = np.array(mloc['pupil_top_r'])
318-
319-
# heuristic to find whisker area in side videos:
320-
# square with side length half the distance
321-
# between nose and pupil and anchored on midpoint
322-
323-
p_anchor = np.mean([p_nose,p_pupil],axis=0)
324-
squared_dist = np.sum((p_nose-p_pupil)**2, axis=0)
325-
dist = np.sqrt(squared_dist)
326-
whxy = [int(dist/2), int(dist/3),
327-
int(p_anchor[0] - dist/4), int(p_anchor[1])]
328-
329-
rect = patches.Rectangle((whxy[2], whxy[3]), whxy[0], whxy[1], linewidth=1,
330-
edgecolor='lime', facecolor='none')
331-
ax = plt.gca()
332-
ax.add_patch(rect)
333-
plt.imshow(r,cmap='gray')
334-
plt.axis('off')
335-
k+=1
336-
plt.tight_layout()
293+
try:
294+
if XYs == None:
295+
_, XYs = get_dlc_XYs(eid, video_type)
296+
297+
298+
299+
ds = {'body':3,'left':6,'right':15}
300+
301+
if video_type == 'left':
302+
Cs = Cs_l
303+
else:
304+
Cs = Cs_r
305+
306+
for point in XYs:# ['paw_l','paw_r']:
307+
if point in ['tube_bottom', 'tube_top']:
308+
continue
309+
310+
# downsample; normalise number of points to be the same
311+
# across all sessions
312+
xs = XYs[point][0][0::ds[video_type]]
313+
ys = XYs[point][1][0::ds[video_type]]
314+
315+
plt.scatter(xs,ys, alpha = 0.05, s = 2,
316+
label = point)#, color = Cs[point])
317+
318+
# plot whisker pad rectangle
319+
mloc = get_mean_positions(XYs)
320+
p_nose = np.array(mloc['nose_tip'])
321+
p_pupil = np.array(mloc['pupil_top_r'])
322+
323+
# heuristic to find whisker area in side videos:
324+
# square with side length half the distance
325+
# between nose and pupil and anchored on midpoint
326+
327+
p_anchor = np.mean([p_nose,p_pupil],axis=0)
328+
squared_dist = np.sum((p_nose-p_pupil)**2, axis=0)
329+
dist = np.sqrt(squared_dist)
330+
whxy = [int(dist/2), int(dist/3),
331+
int(p_anchor[0] - dist/4), int(p_anchor[1])]
332+
333+
rect = patches.Rectangle((whxy[2], whxy[3]), whxy[0], whxy[1], linewidth=1,
334+
edgecolor='lime', facecolor='none')
335+
ax = plt.gca()
336+
ax.add_patch(rect)
337+
338+
plt.axis('off')
339+
plt.tight_layout()
340+
plt.imshow(r,cmap='gray')
341+
plt.tight_layout()
342+
except:
343+
344+
plt.imshow(r,cmap='gray')
345+
ax = plt.gca()
346+
plt.text(.5, .5,'DLC is nan',color='r',fontweight='bold',
347+
bbox=dict(facecolor='white', alpha=0.5),
348+
fontsize=10,transform=ax.transAxes)
349+
plt.tight_layout()
337350
#plt.show()
338351
#plt.legend(loc='lower right')
339352

@@ -560,13 +573,39 @@ def plot_licks(eid, combine=False):
560573
plt.xlabel('time [sec]')
561574
plt.ylabel('lick events \n [a.u.]')
562575
plt.legend(loc='lower right')
563-
return licks_pos
576+
564577

565578

566-
def lick_raster(licks_pos):
579+
def lick_raster(eid):
567580

568581
#plt.figure(figsize=(4,4))
569582

583+
T_BIN = 0.02
584+
rt = 2
585+
st = -0.5
586+
times, XYs = get_dlc_XYs(eid, 'left')
587+
lick_times = times[get_licks(XYs)]
588+
589+
R, t, _ = bincount2D(lick_times, np.ones(len(lick_times)), T_BIN)
590+
D = R[0]
591+
592+
# that's centered at feedback time
593+
d = constant_reaction_time(eid, rt, st,stype='feedback')
594+
595+
licks_pos = []
596+
licks_neg = []
597+
598+
for i in d:
599+
600+
start_idx = find_nearest(t,d[i][0])
601+
end_idx = start_idx + int(d[i][1]/T_BIN)
602+
603+
# split by feedback type)
604+
if d[i][5] == 1:
605+
licks_pos.append(D[start_idx:end_idx])
606+
607+
licks_pos_ = np.array(licks_pos).mean(axis=0)
608+
570609
y_dims, x_dims = len(licks_pos), len(licks_pos[0])
571610
plt.imshow(licks_pos,aspect='auto', extent=[-0.5,1.5,y_dims,0],
572611
cmap='gray_r')
@@ -615,23 +654,21 @@ def plot_wheel_position(eid):
615654
end_idx = start_idx + int(d[i][1]/T_BIN)
616655

617656
wheel_pos = pos[start_idx:end_idx]
657+
if len(wheel_pos) == 1:
658+
print(i, [start_idx,end_idx])
659+
618660
wheel_pos = wheel_pos - wheel_pos[0]
619661

620662
if d[i][4] == -1:
621663
whe_left.append(wheel_pos)
622664
if d[i][4] == 1:
623665
whe_right.append(wheel_pos)
624666

625-
626-
# times = np.arange(len(whe_left[0]))*T_BIN
627-
#
628-
# return times
629667
xs = np.arange(len(whe_left[0]))*T_BIN
630668
times = np.concatenate([
631669
-1*np.array(list(reversed(xs[:int(len(xs)*abs(st/rt))]))),
632670
np.array(xs[:int(len(xs)*(1 - abs(st/rt)))])])
633-
634-
671+
635672

636673
for i in range(len(whe_left)):
637674
plt.plot(times, whe_left[i],c='#1f77b4', alpha =0.5, linewidth = 0.05)
@@ -960,8 +997,6 @@ def pupil_diameter_PSTH(eid, s=None, times=None):
960997
plt.legend(loc='lower right')
961998

962999

963-
964-
9651000
def motion_energy_PSTH(eid):
9661001

9671002
'''
@@ -1051,7 +1086,6 @@ def motion_energy_PSTH(eid):
10511086
except:
10521087
plt.title('No motion energy available!')
10531088

1054-
10551089

10561090
def interp_nans(y):
10571091

@@ -1078,48 +1112,60 @@ def plot_all(eid):
10781112
matplotlib.rcParams.update({'font.size': 10})
10791113
# report eid = '4a45c8ba-db6f-4f11-9403-56e06a33dfa4'
10801114

1115+
panels = {'plot_paw_on_image':plot_paw_on_image,
1116+
'plot_wheel_position':plot_wheel_position,
1117+
'paw_speed_PSTH':paw_speed_PSTH,
1118+
'plot_licks':plot_licks,
1119+
'lick_raster':lick_raster,
1120+
'nose_speed_PSTH':nose_speed_PSTH,
1121+
'pupil_diameter_PSTH':pupil_diameter_PSTH,
1122+
'motion_energy_PSTH':motion_energy_PSTH}
1123+
10811124
nrows = 2
10821125
ncols = 4
10831126

10841127
plt.ioff()
1085-
one = ONE()
1086-
plt.figure(figsize=(15,10))
1087-
plt.subplot(nrows,ncols,1)
1088-
add_panel_letter(1)
1089-
plot_paw_on_image(eid, 'left')
1090-
# p = one.path_from_eid(eid)
1091-
# plt.title(' '.join([str(p).split('/')[i] for i in [5,7,8,9]]),
1092-
# backgroundcolor= 'white')
1093-
1094-
plt.subplot(nrows,ncols,2)
1095-
add_panel_letter(2)
1096-
#plot_paw_on_image(eid, 'right')
1097-
plot_wheel_position(eid)
1098-
plt.subplot(nrows,ncols,3)
1099-
add_panel_letter(3)
1100-
paw_speed_PSTH(eid)
1101-
plt.subplot(nrows,ncols,4)
1102-
add_panel_letter(4)
1103-
licks_pos = plot_licks(eid)
1104-
plt.subplot(nrows,ncols,5)
1105-
add_panel_letter(5)
1106-
lick_raster(licks_pos)
1107-
plt.subplot(nrows,ncols,6)
1108-
add_panel_letter(6)
1109-
nose_speed_PSTH(eid)
1110-
plt.subplot(nrows,ncols,7)
1111-
add_panel_letter(7)
1112-
pupil_diameter_PSTH(eid)
1113-
plt.subplot(nrows,ncols,8)
1114-
add_panel_letter(8)
1115-
motion_energy_PSTH(eid)
1116-
1117-
#plt.subplot(3,3,9)
1118-
#plot_sniffPSTH(eid)
1128+
1129+
plt.figure(figsize=(15,10))
1130+
1131+
k = 1
1132+
for panel in panels:
1133+
plt.subplot(nrows,ncols,k)
1134+
add_panel_letter(k)
1135+
try:
1136+
panels[panel](eid)
1137+
except:
1138+
ax = plt.gca()
1139+
plt.text(.5, .5,f'error in \n {panel}',color='r',fontweight='bold',
1140+
bbox=dict(facecolor='white', alpha=0.5),
1141+
fontsize=10, transform=ax.transAxes)
1142+
k += 1
1143+
11191144

11201145
plt.tight_layout()
1146+
1147+
1148+
# print QC outcome in title and DLC task version
1149+
one = ONE()
1150+
task = one.alyx.rest('tasks', 'list', session=eid, name='EphysDLC')[0]
1151+
det = one.get_details(eid, True)['extended_qc']
11211152
p = one.path_from_eid(eid)
1122-
plt.suptitle(' '.join([str(p).split('/')[i] for i in [4,6,7,8]]),
1153+
s1 = ' '.join([str(p).split('/')[i] for i in [4,6,7,8]])
1154+
1155+
qcs = ['task','videoLeft','videoRight','videoBody',
1156+
'dlcLeft','dlcRight','dlcBody','behavior']
1157+
1158+
l = []
1159+
for q in qcs:
1160+
try:
1161+
l.append(q+':'+str(det[q]))
1162+
except:
1163+
continue
1164+
1165+
s2 = ' '.join(l)
1166+
1167+
1168+
plt.suptitle(s1+' QC '+s2+' '+'DLC version: '+str(task['version']),
11231169
backgroundcolor= 'white')
11241170
plt.tight_layout()
11251171
plt.tight_layout()
@@ -1141,8 +1187,3 @@ def plot_all(eid):
11411187
# 'ebe090af-5922-4fcd-8fc6-17b8ba7bad6d',
11421188
# '7f6b86f9-879a-4ea2-8531-294a221af5d0']
11431189

1144-
1145-
1146-
1147-
1148-

0 commit comments

Comments
 (0)