def plot_trajectory(trajec): threshold_odor = 10 fig = plt.figure() ax = fig.add_subplot(111) frames_in_odor = np.where(trajec.odor > threshold_odor)[0] odor_blocks = hf.find_continuous_blocks(frames_in_odor, 5, return_longest_only=False) for block in [odor_blocks[3]]: #middle_of_block = int(np.mean(block)) if len(block) < 5: continue # find next saccade first_sac = None #second_sac = None #third_sac = None for sac in trajec.saccades: if sac[0] > block[0]: if first_sac is None: first_sac = sac break #elif second_sac is None: # if trajec.odor[sac[0]] < threshold_odor: # second_sac = sac #elif third_sac is None: # if trajec.odor[sac[0]] < threshold_odor: # third_sac = sac # break if first_sac is not None: next_sac = first_sac angle_of_saccade = tac.get_angle_of_saccade(trajec, next_sac) heading_prior_to_saccade = trajec.heading_smooth[next_sac[0]] if heading_prior_to_saccade < 0: heading_prior_to_saccade += np.pi else: heading_prior_to_saccade -= np.pi frame0 = np.max([next_sac[0]-20, 0]) frame1 = np.min([next_sac[0]+20, trajec.length-1]) frames = np.arange(frame0, frame1) ax.plot(trajec.positions[frames,0], trajec.positions[frames,1]) ax.plot(trajec.positions[frames[0],0], trajec.positions[frames[0],1], '.', color='green') #pos_before_sac = trajec.positions[next_sac[0], :] #heading_vector = pos_before_sac print 'raw heading prior: ', heading_prior_to_saccade*180/np.pi print 'raw heading after: ', trajec.heading_smooth[next_sac[-1]]*180/np.pi print 'raw angle of sac: ', angle_of_saccade*180/np.pi ax.set_aspect('equal') return next_sac
def get_time_to_saccade(dataset, keys, threshold_odor=25): time_to_saccade = [] for key in keys: trajec = dataset.trajecs[key] frames_in_odor = np.where(trajec.odor > threshold_odor)[0].tolist() if len(frames_in_odor) <= 0: continue odor_blocks = hf.find_continuous_blocks(frames_in_odor, 5) for block in odor_blocks: if len(block) < 1: continue for sac in trajec.saccades: if sac[0] > block[-1]: t_to_sac = (sac[0] - block[-1])/trajec.fps time_to_saccade.append(t_to_sac) break return time_to_saccade
def plot_odor_heading_book(pp, threshold_odor, path, config, dataset, keys=None): fig = plt.figure(figsize=(4,4)) ax = fig.add_subplot(111) saccade_angles_after_odor = [] heading_at_saccade_initiation = [] heading_after_saccade = [] for key in keys: trajec = dataset.trajecs[key] frames_in_odor = np.where(trajec.odor > threshold_odor)[0] odor_blocks = hf.find_continuous_blocks(frames_in_odor, 5, return_longest_only=False) for block in odor_blocks: middle_of_block = int(np.mean(block)) # find next saccade first_sac = None second_sac = None for sac in trajec.saccades: if sac[0] > middle_of_block: if first_sac is None: first_sac = sac elif second_sac is None: if trajec.odor[sac[0]] < threshold_odor: second_sac = sac break if first_sac is not None: next_sac = first_sac angle_of_saccade = tac.get_angle_of_saccade(trajec, next_sac) heading_prior_to_saccade = trajec.heading_smooth[next_sac[0]] # flip heading if heading_prior_to_saccade < 0: heading_prior_to_saccade += np.pi else: heading_prior_to_saccade -= np.pi # flip saccade angle if angle_of_saccade < 0: angle_of_saccade += np.pi else: angle_of_saccade -= np.pi saccade_angles_after_odor.append(angle_of_saccade) heading_at_saccade_initiation.append(heading_prior_to_saccade) heading_after_saccade.append(heading_prior_to_saccade + angle_of_saccade) saccade_angles_after_odor = np.array(saccade_angles_after_odor) heading_at_saccade_initiation = np.array(heading_at_saccade_initiation) heading_after_saccade = np.array(heading_after_saccade) ax.plot(heading_at_saccade_initiation*180./np.pi, saccade_angles_after_odor*180./np.pi, '.') #ax.plot(heading_at_saccade_initiation*180./np.pi, heading_after_saccade*180./np.pi, '.') xticks = [-180, -90, 0, 90, 180] yticks = [-180, -90, 0, 90, 180] fpl.adjust_spines(ax, ['left', 'bottom'], xticks=xticks, yticks=yticks) ax.set_xlabel('Heading before saccade') ax.set_ylabel('Angle of saccade') title_text = 'Odor: ' + trajec.odor_stimulus.title() ax.set_title(title_text) ax.text(0,-180, 'Upwind', horizontalalignment='center', verticalalignment='top') ax.text(90,-180, 'Starboard', horizontalalignment='center', verticalalignment='top') ax.text(-90,-180, 'Port', horizontalalignment='center', verticalalignment='top') ax.text(-180,90, 'Starboard', horizontalalignment='left', verticalalignment='center', rotation='vertical') ax.text(-180,-90, 'Port', horizontalalignment='left', verticalalignment='center', rotation='vertical') pp.savefig() plt.close('all') # angle of saccade histogram fig = plt.figure() ax = fig.add_subplot(111) fpl.histogram_stack(ax, [saccade_angles_after_odor*180./np.pi], bins=20, bin_width_ratio=0.9, colors=['red'], edgecolor='none', normed=True) ax.set_xlabel('Angle of Saccade') ax.set_ylabel('Occurences, normalized') xticks = [-180, -90, 0, 90, 180] fpl.adjust_spines(ax, ['left', 'bottom'], xticks=xticks) ax.set_title(title_text) pp.savefig() plt.close('all')
def plot_odor_heading_book(pp, threshold_odor, path, config, dataset, odor_stimulus, keys=None, axis='xy'): fig = plt.figure(figsize=(4,4)) ax = fig.add_subplot(111) saccade_angles_after_odor = [] heading_at_saccade_initiation = [] odor_at_saccade = [] saccade_number = [] if 1: for key in keys: trajec = dataset.trajecs[key] #if trajec.positions[0,0] < 0.2: # continue frames_in_odor = np.where(trajec.odor > threshold_odor)[0] odor_blocks = hf.find_continuous_blocks(frames_in_odor, 5, return_longest_only=False) b = 0 for block in odor_blocks: if len(block) < 5: continue first_sac = None if axis == 'xy': saccades = trajec.saccades elif axis == 'altitude': saccades = trajec.saccades_z for sac in saccades: if trajec.positions[sac[0],0] < -0.1 or trajec.positions[sac[0],0] > 0.9: continue if np.abs(trajec.positions[sac[0],1]) > 0.05: continue if trajec.positions[sac[0],2] > 0.05 or trajec.positions[sac[0],2] < -0.01: continue if sac[0] > block[0]: if first_sac is None: if trajec.time_fly[sac[0]] - trajec.time_fly[block[-1]] > 0.5: break first_sac = sac break if first_sac is not None: next_sac = first_sac if axis == 'xy': angle_of_saccade = tac.get_angle_of_saccade(trajec, next_sac) heading_prior_to_saccade = trajec.heading_smooth[next_sac[0]] elif axis == 'altitude': angle_of_saccade = tac.get_angle_of_saccade_z(trajec, next_sac) heading_prior_to_saccade = trajec.heading_altitude_smooth[next_sac[0]] saccade_angles_after_odor.append(angle_of_saccade) heading_at_saccade_initiation.append(heading_prior_to_saccade) odor_at_saccade.append(trajec.odor[next_sac[0]]) b += 1 saccade_number.append(b) saccade_angles_after_odor = np.array(saccade_angles_after_odor) heading_at_saccade_initiation = np.array(heading_at_saccade_initiation) odor_at_saccade = np.array(odor_at_saccade) saccade_number = np.array(saccade_number) print odor_stimulus, saccade_angles_after_odor.shape #ax.plot(heading_at_saccade_initiation*180./np.pi, saccade_angles_after_odor*180./np.pi, '.', markersize=3) fpl.scatter(ax, heading_at_saccade_initiation*180./np.pi, saccade_angles_after_odor*180./np.pi, color='black', radius=3, colornorm=[0,5]) xpts = np.linspace(-180,180, 100) ax.plot(xpts, -1*xpts, color='red', zorder=-10) #ax.plot(heading_at_saccade_initiation*180./np.pi, heading_after_saccade*180./np.pi, '.') xticks = [-180, -90, 0, 90, 180] yticks = [-180, -90, 0, 90, 180] fpl.adjust_spines(ax, ['left', 'bottom'], xticks=xticks, yticks=yticks) ax.set_xlabel('Heading before saccade') ax.set_ylabel('Angle of saccade') title_text = 'Odor: ' + odor_stimulus + ' Visual Stim: ' + trajec.visual_stimulus ax.set_title(title_text) ax.text(0,-180, 'Upwind', horizontalalignment='center', verticalalignment='top') ax.text(90,-180, 'Starboard', horizontalalignment='center', verticalalignment='top') ax.text(-90,-180, 'Port', horizontalalignment='center', verticalalignment='top') ax.text(-180,90, 'Starboard', horizontalalignment='left', verticalalignment='center', rotation='vertical') ax.text(-180,-90, 'Port', horizontalalignment='left', verticalalignment='center', rotation='vertical') pp.savefig() plt.close('all')
def plot_saccade_positions(pp, threshold_odor, path, config, dataset, odor_stimulus, keys=None): ax_xy, ax_xz, ax_yz = xyz_axis_grid.get_axes() if odor_stimulus is 'on': n = 0 for key in keys: if n > 1000: break trajec = dataset.trajecs[key] frames_in_odor = np.where(trajec.odor > threshold_odor)[0] odor_blocks = hf.find_continuous_blocks(frames_in_odor, 5, return_longest_only=False) for block in odor_blocks: if len(block) < 5: continue first_sac = None for sac in trajec.saccades: if trajec.positions[sac[0],0] < -0.1 or trajec.positions[sac[0],0] > 0.9: continue if np.abs(trajec.positions[sac[0],1]) > 0.05: continue if trajec.positions[sac[0],2] > 0.05 or trajec.positions[sac[0],2] < -0.01: continue if sac[0] > block[0]: if first_sac is None: first_sac = sac break if first_sac is not None: sac = first_sac n += 1 f = np.argmax(np.abs(trajec.heading_smooth_diff[sac])) + sac[0] ax_xy.plot(trajec.positions[f,0], trajec.positions[f,1], '.', color='black') ax_xz.plot(trajec.positions[f,0], trajec.positions[f,2], '.', color='black') ax_yz.plot(trajec.positions[f,1], trajec.positions[f,2], '.', color='black') if odor_stimulus is 'none': n = 0 for key in keys: if n > 1000: break trajec = dataset.trajecs[key] for sac in trajec.saccades: if trajec.positions[sac[0],0] < -0.1 or trajec.positions[sac[0],0] > 0.9: continue if np.abs(trajec.positions[sac[0],1]) > 0.05: continue if trajec.positions[sac[0],2] > 0.05 or trajec.positions[sac[0],2] < -0.01: continue n += 1 f = np.argmax(np.abs(trajec.heading_smooth_diff[sac])) + sac[0] ax_xy.plot(trajec.positions[f,0], trajec.positions[f,1], '.', color='black') ax_xz.plot(trajec.positions[f,0], trajec.positions[f,2], '.', color='black') ax_yz.plot(trajec.positions[f,1], trajec.positions[f,2], '.', color='black') xyz_axis_grid.set_spines_and_labels(ax_xy, ax_xz, ax_yz) pp.savefig() plt.close('all')
def plot_odor_heading_book(pp, threshold_odor, path, config, dataset, odor_stimulus, keys=None): fig = plt.figure(figsize=(8,5)) fig.subplots_adjust(wspace=0.2, hspace=0.3) ax_odor = fig.add_subplot(511) ax_wall = fig.add_subplot(512) ax_z = fig.add_subplot(513) ax_heading = fig.add_subplot(514) ax_speed = fig.add_subplot(515) axes = [ax_odor, ax_wall, ax_z, ax_heading, ax_speed] if odor_stimulus is 'pulsing': return if 1: #odor_stimulus is 'on': n = 0 for key in keys: if n > 1000: break trajec = dataset.trajecs[key] frames_in_odor = np.where(trajec.odor > threshold_odor)[0] odor_blocks = hf.find_continuous_blocks(frames_in_odor, 5, return_longest_only=False) for block in odor_blocks: if len(block) < 5: continue first_sac = None for sac in trajec.saccades: if trajec.positions[sac[0],0] < -0.1 or trajec.positions[sac[0],0] > 0.9: continue if np.abs(trajec.positions[sac[0],1]) > 0.05: continue if trajec.positions[sac[0],2] > 0.05 or trajec.positions[sac[0],2] < -0.01: continue if sac[0] > block[-1] and trajec.odor[sac[0]] < threshold_odor: if first_sac is None: first_sac = sac break if first_sac is not None: sac = first_sac n += 1 heading_prior_to_saccade = trajec.heading_smooth[sac[0]] #if np.abs(heading_prior_to_saccade) > 45*np.pi/180. and np.abs(heading_prior_to_saccade) < 135*np.pi/180.: if np.abs(heading_prior_to_saccade) < 15*np.pi/180.:# and np.abs(heading_prior_to_saccade) < 135*np.pi/180.: if 0: frame_of_saccade_middle = np.argmax(np.abs(trajec.heading_smooth_diff[sac])) + sac[0] time_of_sac = trajec.time_fly[frame_of_saccade_middle] if 1: frame_of_max_odor = np.argmax(trajec.odor[block])+block[0] time_of_sac = trajec.time_fly[frame_of_max_odor] frame0 = np.max([0,sac[0]-60]) frame1 = np.min([trajec.length-1,sac[-1]+100]) if frame0 > 0: frames = np.arange(frame0, frame1) # speed # in saccade: ax_speed.plot(trajec.time_fly[sac]-time_of_sac, trajec.speed[sac], 'crimson', linewidth=0.5, alpha=0.25) # before saccade frames_before_sac = np.arange(frames[0], sac[1]) ax_speed.plot(trajec.time_fly[frames_before_sac]-time_of_sac, trajec.speed[frames_before_sac], 'black', linewidth=0.5, alpha=0.25) # after saccade frames_after_sac = np.arange(sac[-2],frames[-1]) ax_speed.plot(trajec.time_fly[frames_after_sac]-time_of_sac, trajec.speed[frames_after_sac], 'black', linewidth=0.5, alpha=0.25) # wall # in saccade: ax_wall.plot(trajec.time_fly[sac]-time_of_sac, np.abs(trajec.positions[sac,1]), 'crimson', linewidth=0.5, alpha=0.25) # before saccade ax_wall.plot(trajec.time_fly[frames_before_sac]-time_of_sac, np.abs(trajec.positions[frames_before_sac,1]), 'black', linewidth=0.5, alpha=0.25) # after saccade ax_wall.plot(trajec.time_fly[frames_after_sac]-time_of_sac, np.abs(trajec.positions[frames_after_sac,1]), 'black', linewidth=0.5, alpha=0.25) # z # in saccade: ax_z.plot(trajec.time_fly[sac]-time_of_sac, (trajec.positions[sac,2]), 'crimson', linewidth=0.5, alpha=0.25) # before saccade ax_z.plot(trajec.time_fly[frames_before_sac]-time_of_sac, (trajec.positions[frames_before_sac,2]), 'black', linewidth=0.5, alpha=0.25) # after saccade ax_z.plot(trajec.time_fly[frames_after_sac]-time_of_sac, (trajec.positions[frames_after_sac,2]), 'black', linewidth=0.5, alpha=0.25) # heading heading = copy.copy(trajec.heading_smooth) for i, h in enumerate(heading): if h < 0: heading[i] += np.pi else: heading[i] -= np.pi #heading = floris_math.remove_angular_rollover(heading, np.pi) # in saccade: ax_heading.plot(trajec.time_fly[sac]-time_of_sac, np.abs(heading[sac]), 'crimson', linewidth=0.5, alpha=0.25) # before saccade ax_heading.plot(trajec.time_fly[frames_before_sac]-time_of_sac, np.abs(heading[frames_before_sac]), 'black', linewidth=0.5, alpha=0.25) # after saccade ax_heading.plot(trajec.time_fly[frames_after_sac]-time_of_sac, np.abs(heading[frames_after_sac]), 'black', linewidth=0.5, alpha=0.25) # odor # in saccade: ax_odor.plot(trajec.time_fly[sac]-time_of_sac, trajec.odor[sac], 'crimson', linewidth=0.5, alpha=0.25) # before saccade ax_odor.plot(trajec.time_fly[frames_before_sac]-time_of_sac, trajec.odor[frames_before_sac], 'black', linewidth=0.5, alpha=0.25) # after saccade ax_odor.plot(trajec.time_fly[frames_after_sac]-time_of_sac, trajec.odor[frames_after_sac], 'black', linewidth=0.5, alpha=0.25) ######################################3 for ax in axes: ax.set_xlim(-1,2) ax_speed.set_ylim(0,.8) yticks = [0,.4,.8] fpl.adjust_spines(ax_speed, ['left', 'bottom'], yticks=yticks) ax_speed.set_xlabel('time relative to saccade, sec') ax_speed.set_ylabel('speed, m/s') yticks = [0,125,250] fpl.adjust_spines(ax_odor, ['left'], yticks=yticks) ax_odor.set_ylabel('est. odor', horizontalalignment='center') yticks = [-.15, 0, .15] ax_wall.set_ylim(-.15, 0, .15) fpl.adjust_spines(ax_wall, ['left'], yticks=yticks) ax_wall.set_ylabel('y pos, m', horizontalalignment='center') yticks = [-.15, 0, .15] ax_z.set_ylim(-.15,0.15) fpl.adjust_spines(ax_z, ['left'], yticks=yticks) ax_z.set_ylabel('altitude, m') ax_heading.set_ylim(0, np.pi+np.pi/6.) yticks = [0, np.pi/2., np.pi] fpl.adjust_spines(ax_heading, ['left'], yticks=yticks) ax_heading.set_yticklabels(['upwind', 'crosswind', 'downwind']) ax_heading.set_ylabel('heading') title_str = 'Odor Stimulus: ' + odor_stimulus fig.suptitle(title_str) pp.savefig() plt.close('all')
def plot_odor_heading_book(pp, threshold_odor, path, config, dataset, keys=None): fig = plt.figure(figsize=(4,4)) ax = fig.add_subplot(111) saccades_odor = {'saccade_angles': [], 'heading_prior': []} saccades_control = {'saccade_angles': [], 'heading_prior': []} for key in keys: trajec = dataset.trajecs[key] frames_in_odor = np.where(trajec.odor > threshold_odor)[0] odor_blocks = hf.find_continuous_blocks(frames_in_odor, 5, return_longest_only=False) for block in odor_blocks: #middle_of_block = int(np.mean(block)) if len(block) < 5: continue # find next saccade first_sac = None #second_sac = None #third_sac = None for sac in trajec.saccades: if trajec.positions[sac[0],0] < -0.15 or trajec.positions[sac[0],0] > 0.9: continue if np.abs(trajec.positions[sac[0],1]) > 0.08: continue if np.abs(trajec.positions[sac[0],2]) > 0.08: continue if sac[0] > block[0]: if first_sac is None: first_sac = sac break #elif second_sac is None: # if trajec.odor[sac[0]] < threshold_odor: # second_sac = sac #elif third_sac is None: # if trajec.odor[sac[0]] < threshold_odor: # third_sac = sac # break if first_sac is not None: next_sac = first_sac angle_of_saccade = tac.get_angle_of_saccade(trajec, next_sac) heading_prior_to_saccade = trajec.heading_smooth[next_sac[0]] # flip heading if heading_prior_to_saccade < 0: heading_prior_to_saccade += np.pi else: heading_prior_to_saccade -= np.pi saccade_angles_after_odor.append(angle_of_saccade) heading_at_saccade_initiation.append(heading_prior_to_saccade) heading_after_saccade.append(heading_prior_to_saccade + angle_of_saccade) speed_at_saccade.append(trajec.speed[next_sac[0]]) saccade_angles_after_odor = np.array(saccade_angles_after_odor) heading_at_saccade_initiation = np.array(heading_at_saccade_initiation) heading_after_saccade = np.array(heading_after_saccade) speed_at_saccade = np.array(speed_at_saccade) ax.plot(heading_at_saccade_initiation*180./np.pi, saccade_angles_after_odor*180./np.pi, '.', markersize=4) #fpl.scatter(ax, heading_at_saccade_initiation*180./np.pi, saccade_angles_after_odor*180./np.pi, color=speed_at_saccade, radius=1) #ax.plot(heading_at_saccade_initiation*180./np.pi, heading_after_saccade*180./np.pi, '.') xticks = [-180, -90, 0, 90, 180] yticks = [-180, -90, 0, 90, 180] fpl.adjust_spines(ax, ['left', 'bottom'], xticks=xticks, yticks=yticks) ax.set_xlabel('Heading before saccade') ax.set_ylabel('Angle of saccade') title_text = 'Odor: ' + trajec.odor_stimulus.title() ax.set_title(title_text) ax.text(0,-180, 'Upwind', horizontalalignment='center', verticalalignment='top') ax.text(90,-180, 'Starboard', horizontalalignment='center', verticalalignment='top') ax.text(-90,-180, 'Port', horizontalalignment='center', verticalalignment='top') ax.text(-180,90, 'Starboard', horizontalalignment='left', verticalalignment='center', rotation='vertical') ax.text(-180,-90, 'Port', horizontalalignment='left', verticalalignment='center', rotation='vertical') pp.savefig() plt.close('all') # angle of saccade histogram if 0: fig = plt.figure(figsize=(4,4)) ax = fig.add_subplot(111) fpl.histogram_stack(ax, [np.array(time_to_saccade_cast)], bins=40, bin_width_ratio=0.9, colors=['red'], edgecolor='none', normed=True) ax.set_xlabel('Angle of Saccade') ax.set_ylabel('Occurences, normalized') #xticks = [-180, -90, 0, 90, 180] fpl.adjust_spines(ax, ['left', 'bottom']) ax.set_title(title_text) pp.savefig() plt.close('all')