Skip to content

Commit

Permalink
Merge branch 'master' into world_less
Browse files Browse the repository at this point in the history
  • Loading branch information
papr committed Feb 15, 2018
2 parents 7413ff4 + 1d59967 commit 8663b0a
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 90 deletions.
12 changes: 7 additions & 5 deletions pupil_src/launchables/eye.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,12 +297,10 @@ def toggle_general_settings(collapsed):
width *= 2
height *= 2
width += icon_bar_width
width, height = session_settings.get('window_size', (width, height))

width, height = session_settings.get(
'window_size', (width, height))
main_window = glfw.glfwCreateWindow(width, height, title, None, None)
window_pos = session_settings.get(
'window_position', window_position_default)
window_pos = session_settings.get('window_position', window_position_default)
glfw.glfwSetWindowPos(main_window, window_pos[0], window_pos[1])
glfw.glfwMakeContextCurrent(main_window)
cygl.utils.init()
Expand Down Expand Up @@ -659,11 +657,15 @@ def window_should_update():
session_settings['ui_config'] = g_pool.gui.configuration
session_settings['capture_settings'] = g_pool.capture.class_name, g_pool.capture.get_init_dict()
session_settings['capture_manager_settings'] = g_pool.capture_manager.class_name, g_pool.capture_manager.get_init_dict()
session_settings['window_size'] = glfw.glfwGetWindowSize(main_window)
session_settings['window_position'] = glfw.glfwGetWindowPos(main_window)
session_settings['version'] = str(g_pool.version)
session_settings['last_pupil_detector'] = g_pool.pupil_detector.__class__.__name__
session_settings['pupil_detector_settings'] = g_pool.pupil_detector.get_settings()

session_window_size = glfw.glfwGetWindowSize(main_window)
if 0 not in session_window_size:
session_settings['window_size'] = session_window_size

session_settings.close()

g_pool.capture.deinit_ui()
Expand Down
39 changes: 28 additions & 11 deletions pupil_src/launchables/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def player(rec_dir, ipc_pub_url, ipc_sub_url,
from system_timelines import System_Timelines
from blink_detection import Offline_Blink_Detection

assert VersionFormat(pyglui_version) >= VersionFormat('1.17'), 'pyglui out of date, please upgrade to newest version'
assert VersionFormat(pyglui_version) >= VersionFormat('1.18'), 'pyglui out of date, please upgrade to newest version'

runtime_plugins = import_runtime_plugins(os.path.join(user_dir, 'plugins'))
system_plugins = [Log_Display, Seek_Control, Plugin_Manager, System_Graphs, Batch_Export, System_Timelines]
Expand Down Expand Up @@ -219,11 +219,16 @@ def get_dt():

g_pool.capture.playback_speed = session_settings.get('playback_speed', 1.)

width, height = session_settings.get('window_size', g_pool.capture.frame_size)
width, height = g_pool.capture.frame_size
width += icon_bar_width
width, height = session_settings.get('window_size', (width, height))

window_pos = session_settings.get('window_position', window_position_default)
window_name = "Pupil Player: {} - {}".format(meta_info["Recording Name"],
os.path.split(rec_dir)[-1])

glfw.glfwInit()
main_window = glfw.glfwCreateWindow(width, height, "Pupil Player: "+meta_info["Recording Name"]+" - "
+ rec_dir.split(os.path.sep)[-1], None, None)
main_window = glfw.glfwCreateWindow(width, height, window_name, None, None)
glfw.glfwSetWindowPos(main_window, window_pos[0], window_pos[1])
glfw.glfwMakeContextCurrent(main_window)
cygl.utils.init()
Expand Down Expand Up @@ -275,17 +280,21 @@ def purge_plugins():
g_pool.plugins.clean()

def do_export(_):
export_range = g_pool.seek_control.trim_left, g_pool.seek_control.trim_right
export_dir = os.path.join(g_pool.rec_dir, 'exports', '{}-{}'.format(*export_range))
left_idx = g_pool.seek_control.trim_left
right_idx = g_pool.seek_control.trim_right
export_range = left_idx, right_idx + 1 # exclusive range.stop

export_dir = os.path.join(g_pool.rec_dir, g_pool.seek_control.get_folder_name_from_trims())

try:
os.makedirs(export_dir)
except OSError as e:
if e.errno != errno.EEXIST:
logger.error("Could not create export dir")
raise e
else:
overwrite_warning = "Previous export for range [{}-{}] already exists - overwriting."
logger.warning(overwrite_warning.format(*export_range))
overwrite_warning = "Previous export for range [{}] already exists - overwriting."
logger.warning(overwrite_warning.format(g_pool.seek_control.get_trim_range_string()))
else:
logger.info('Created export dir at "{}"'.format(export_dir))

Expand Down Expand Up @@ -322,9 +331,13 @@ def toggle_general_settings(collapsed):
vert_constr.append(g_pool.user_timelines)
g_pool.timelines.append(vert_constr)

def set_window_size():
f_width, f_height = g_pool.capture.frame_size
f_width += int(icon_bar_width * g_pool.gui.scale)
glfw.glfwSetWindowSize(main_window, f_width, f_height)

general_settings = ui.Growing_Menu('General', header_pos='headline')
general_settings.append(ui.Button('Reset window size',
lambda: glfw.glfwSetWindowSize(main_window, g_pool.capture.frame_size[0], g_pool.capture.frame_size[1])))
general_settings.append(ui.Button('Reset window size', set_window_size))
general_settings.append(ui.Selector('gui_user_scale', g_pool, setter=set_scale, selection=[.8, .9, 1., 1.1, 1.2]+list(np.arange(1.5, 5.1, .5)), label='Interface Size'))
general_settings.append(ui.Info_Text('Player Version: {}'.format(g_pool.version)))
general_settings.append(ui.Info_Text('Capture Version: {}'.format(meta_info['Capture Software Version'])))
Expand Down Expand Up @@ -496,9 +509,13 @@ def handle_notifications(n):
session_settings['min_data_confidence'] = g_pool.min_data_confidence
session_settings['gui_scale'] = g_pool.gui_user_scale
session_settings['ui_config'] = g_pool.gui.configuration
session_settings['window_size'] = glfw.glfwGetWindowSize(main_window)
session_settings['window_position'] = glfw.glfwGetWindowPos(main_window)
session_settings['version'] = str(g_pool.version)

session_window_size = glfw.glfwGetWindowSize(main_window)
if 0 not in session_window_size:
session_settings['window_size'] = session_window_size

session_settings.close()

# de-init all running plugins
Expand Down
10 changes: 8 additions & 2 deletions pupil_src/launchables/world.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,10 @@ def handle_notifications(n):
'actor': p.class_name,
'doc': p.on_notify.__doc__})

width, height = session_settings.get('window_size', (1280 + icon_bar_width, 720))

# window and gl setup
glfw.glfwInit()
width, height = session_settings.get('window_size', (1280+icon_bar_width, 720))
main_window = glfw.glfwCreateWindow(width, height, "Pupil Capture - World")
window_pos = session_settings.get('window_position', window_position_default)
glfw.glfwSetWindowPos(main_window, window_pos[0], window_pos[1])
Expand Down Expand Up @@ -355,6 +356,7 @@ def set_window_size():
f_width, f_height = g_pool.capture.frame_size
f_width += int(icon_bar_width*g_pool.gui.scale)
glfw.glfwSetWindowSize(main_window, f_width, f_height)

general_settings.append(ui.Button('Reset window size', set_window_size))
general_settings.append(ui.Selector('audio_mode', audio, selection=audio.audio_modes))
general_settings.append(ui.Selector('detection_mapping_mode',
Expand Down Expand Up @@ -507,13 +509,17 @@ def window_should_update():
session_settings['loaded_plugins'] = g_pool.plugins.get_initializers()
session_settings['gui_scale'] = g_pool.gui_user_scale
session_settings['ui_config'] = g_pool.gui.configuration
session_settings['window_size'] = glfw.glfwGetWindowSize(main_window)
session_settings['window_position'] = glfw.glfwGetWindowPos(main_window)
session_settings['version'] = str(g_pool.version)
session_settings['eye0_process_alive'] = eyes_are_alive[0].value
session_settings['eye1_process_alive'] = eyes_are_alive[1].value
session_settings['detection_mapping_mode'] = g_pool.detection_mapping_mode
session_settings['audio_mode'] = audio.audio_mode

session_window_size = glfw.glfwGetWindowSize(main_window)
if 0 not in session_window_size:
session_settings['window_size'] = session_window_size

session_settings.close()

# de-init all running plugins
Expand Down
2 changes: 1 addition & 1 deletion pupil_src/shared_modules/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def export_annotations(self, export_range, export_dir):
return

start, end = export_range
annotations_in_section = [a for a in self.annotations_list if start <= a['index'] <= end]
annotations_in_section = [a for a in self.annotations_list if start <= a['index'] < end]
csv_keys = self.parse_csv_keys(annotations_in_section)

with open(os.path.join(export_dir, 'annotations.csv'), 'w', encoding='utf-8', newline='') as csvfile:
Expand Down
39 changes: 23 additions & 16 deletions pupil_src/shared_modules/blink_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,15 @@ def __init__(self, g_pool, history_length=0.2, onset_confidence_threshold=0.5,
self.timestamps = []
g_pool.blinks = []
g_pool.blinks_by_frame = [[] for x in self.g_pool.timestamps]
self.cache = {'response_points': (), 'class_points': (), 'thresholds': ()}

def init_ui(self):
super().init_ui()
self.glfont = fs.Context()
self.glfont.add_font('opensans', ui.get_opensans_font_path())
self.glfont.set_font('opensans')
self.timeline = ui.Timeline('Blink Detection', self.draw_activation, self.draw_legend)
self.timeline.height *= 1.5
self.timeline.content_height *= 2
self.g_pool.user_timelines.append(self.timeline)

def deinit_ui(self):
Expand All @@ -172,6 +173,7 @@ def on_notify(self, notification):
logger.info('Pupil postions changed. Recalculating.')
self.recalculate()
elif notification['subject'] == 'blinks_changed':
self.cache_activation()
self.timeline.refresh()
elif notification['subject'] == "should_export":
self.export(notification['range'], notification['export_dir'])
Expand Down Expand Up @@ -199,7 +201,7 @@ def export(self, export_range, export_dir):
'filter_response', 'base_data')

start, end = export_range
blinks_in_section = [b for b in self.g_pool.blinks if start <= b['index'] <= end]
blinks_in_section = [b for b in self.g_pool.blinks if start <= b['index'] < end]

with open(os.path.join(export_dir, 'blinks.csv'), 'w',
encoding='utf-8', newline='') as csvfile:
Expand All @@ -225,6 +227,7 @@ def recalculate(self):
self.filter_response = []
self.response_classification = []
self.timestamps = []
self.consolidate_classifications()
return

conf_iter = (pp['confidence'] for pp in all_pp)
Expand Down Expand Up @@ -324,10 +327,16 @@ def blink_finished(idx):
self.g_pool.blinks_by_frame = blinks_by_frame
self.notify_all({'subject': 'blinks_changed', 'delay': .2})

def draw_activation(self, width, height, scale):
def cache_activation(self):
t0, t1 = self.g_pool.timestamps[0], self.g_pool.timestamps[-1]
response_points = tuple(zip(self.timestamps, self.filter_response))
if len(response_points) == 0:
self.cache['thresholds'] = ((t0, self.onset_confidence_threshold),
(t1, self.onset_confidence_threshold),
(t0, -self.offset_confidence_threshold),
(t1, -self.offset_confidence_threshold))

self.cache['response_points'] = tuple(zip(self.timestamps, self.filter_response))
if len(self.cache['response_points']) == 0:
self.cache['class_points'] = ()
return

class_points = deque([(t0, -.9)])
Expand All @@ -337,19 +346,17 @@ def draw_activation(self, width, height, scale):
class_points.append((b['end_timestamp'], .9))
class_points.append((b['end_timestamp'], -.9))
class_points.append((t1, -.9))
self.cache['class_points'] = tuple(class_points)

thresholds = [(t0, self.onset_confidence_threshold),
(t1, self.onset_confidence_threshold),
(t0, -self.offset_confidence_threshold),
(t1, -self.offset_confidence_threshold)]

def draw_activation(self, width, height, scale):
t0, t1 = self.g_pool.timestamps[0], self.g_pool.timestamps[-1]
with gl_utils.Coord_System(t0, t1, -1, 1):
draw_polyline(response_points, color=activity_color,
line_type=gl.GL_LINE_STRIP, thickness=1*scale)
draw_polyline(class_points, color=blink_color,
line_type=gl.GL_LINE_STRIP, thickness=1*scale)
draw_polyline(thresholds, color=threshold_color,
line_type=gl.GL_LINES, thickness=1*scale)
draw_polyline(self.cache['response_points'], color=activity_color,
line_type=gl.GL_LINE_STRIP, thickness=scale)
draw_polyline(self.cache['class_points'], color=blink_color,
line_type=gl.GL_LINE_STRIP, thickness=scale)
draw_polyline(self.cache['thresholds'], color=threshold_color,
line_type=gl.GL_LINES, thickness=scale)

def draw_legend(self, width, height, scale):
self.glfont.push_state()
Expand Down
40 changes: 27 additions & 13 deletions pupil_src/shared_modules/fixation_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import numpy as np
import cv2

from bisect import bisect_left, bisect_right
from scipy.spatial.distance import pdist
from collections import deque
from itertools import chain
Expand Down Expand Up @@ -239,13 +240,20 @@ def set_max_duration(new_value):
self.notify_all({'subject': 'fixation_detector.should_recalculate', 'delay': 1.})

def jump_next_fixation(_):
ts = self.last_frame_ts
for f in self.g_pool.fixations:
if f['timestamp'] > ts:
self.g_pool.capture.seek_to_frame(f['mid_frame_index'])
self.g_pool.new_seek = True
return
logger.error('No further fixation available')
cur_idx = self.last_frame_idx
all_idc = [f['mid_frame_index'] for f in self.g_pool.fixations]
# wrap-around index
tar_fix = bisect_right(all_idc, cur_idx) % len(all_idc)
self.g_pool.capture.seek_to_frame(self.g_pool.fixations[tar_fix]['mid_frame_index'])
self.g_pool.new_seek = True

def jump_prev_fixation(_):
cur_idx = self.last_frame_idx
all_idc = [f['mid_frame_index'] for f in self.g_pool.fixations]
# wrap-around index
tar_fix = (bisect_left(all_idc, cur_idx) - 1) % len(all_idc)
self.g_pool.capture.seek_to_frame(self.g_pool.fixations[tar_fix]['mid_frame_index'])
self.g_pool.new_seek = True

for help_block in self.__doc__.split('\n\n'):
help_str = help_block.replace('\n', ' ').replace(' ', '').strip()
Expand All @@ -263,17 +271,23 @@ def jump_next_fixation(_):
self.current_fixation_details = ui.Info_Text('')
self.menu.append(self.current_fixation_details)

self.add_button = ui.Thumb('jump_next_fixation', setter=jump_next_fixation,
self.next_fix_button = ui.Thumb('jump_next_fixation', setter=jump_next_fixation,
getter=lambda: False, label=chr(0xe044), hotkey='f',
label_font='pupil_icons')
self.add_button.status_text = 'Next Fixation'
self.g_pool.quickbar.append(self.add_button)
self.next_fix_button.status_text = 'Next Fixation'
self.g_pool.quickbar.append(self.next_fix_button)

self.prev_fix_button = ui.Thumb('jump_prev_fixation', setter=jump_prev_fixation,
getter=lambda: False, label=chr(0xe045), hotkey='F',
label_font='pupil_icons')
self.prev_fix_button.status_text = 'Previous Fixation'
self.g_pool.quickbar.append(self.prev_fix_button)

def deinit_ui(self):
self.remove_menu()
self.current_fixation_details = None
self.g_pool.quickbar.remove(self.add_button)
self.add_button = None
self.g_pool.quickbar.remove(self.next_fix_button)
self.next_fix_button = None

def cleanup(self):
if self.bg_task:
Expand Down Expand Up @@ -344,7 +358,7 @@ def recent_events(self, events):
if not frame:
return

self.last_frame_ts = frame.timestamp
self.last_frame_idx = frame.index
events['fixations'] = self.g_pool.fixations_by_frame[frame.index]
if self.show_fixations:
for f in self.g_pool.fixations_by_frame[frame.index]:
Expand Down
Loading

0 comments on commit 8663b0a

Please sign in to comment.