def _load_recorded_calibrations(self): notifications = fm.load_pldata_file(self._rec_dir, "notify") for topic, data in zip(notifications.topics, notifications.data): if topic == "notify.calibration.calibration_data": try: calib_result = model.CalibrationResult( mapping_plugin_name=data["mapper_name"], mapper_args=dict(data["mapper_args"]), ) except KeyError: # notifications from old recordings will not have these fields! continue mapping_method = "2d" if "2d" in data["calibration_method"] else "3d" # the unique id needs to be the same at every start or otherwise the # same calibrations would be added again and again. The timestamp is # the easiest datum that differs between calibrations but is the same # for every start unique_id = model.Calibration.create_unique_id_from_string( str(data["timestamp"]) ) calibration = model.Calibration( unique_id=unique_id, name=make_unique.by_number_at_end( "Recorded Calibration", self.item_names ), recording_uuid=self._recording_uuid, mapping_method=mapping_method, frame_index_range=self._get_recording_index_range(), minimum_confidence=0.8, is_offline_calibration=False, result=calib_result, ) self.add(calibration)
def _load_gaze_and_ts_from_disk(self): directory = self._gaze_mappings_directory for gaze_mapper in self._gaze_mappers: file_name = self._gaze_mapping_file_name(gaze_mapper) pldata = fm.load_pldata_file(directory, file_name) gaze_mapper.gaze = pldata.data gaze_mapper.gaze_ts = pldata.timestamps
def _load_from_file(self): directory = self._offline_data_folder_path file_name = self._pldata_file_name pldata = fm.load_pldata_file(directory, file_name) self.markers_bisector = pm.Mutable_Bisector(pldata.data, pldata.timestamps) for topic in set(pldata.topics): frame_index, num_markers = topic.split(".") self.frame_index_to_num_markers[int(frame_index)] = int(num_markers)
def load_annotations(self, file_name): annotation_pldata = fm.load_pldata_file(self.g_pool.rec_dir, file_name) annotations = pm.Mutable_Bisector( annotation_pldata.data, annotation_pldata.timestamps ) logger.info( "Loaded {} annotations from {}.pldata".format(len(annotations), file_name) ) return annotations
def load_data_with_offset(self): gaze = fm.load_pldata_file(self.g_pool.rec_dir, "gaze") self.g_pool.gaze_positions = pm.Bisector(gaze.data, gaze.timestamps) # self.g_pool.gaze_positions = deepcopy(self.g_pool.pupil_data['gaze']) # for gp in self.g_pool.gaze_positions: # gp['norm_pos'][0] += self.x_offset # gp['norm_pos'][1] += self.y_offset self.notify_all({"subject": "gaze_positions_changed"}) logger.debug("gaze positions changed")
def extract_surface_data(directory): surfaces = fm.load_pldata_file(directory, "surfaces") surfaces = pd.DataFrame(surfaces, index=surfaces._fields).T surfaces.set_index("timestamps", inplace=True) for name, surface in surfaces.groupby("topics"): export_gaze_positions_on_surface( directory, name.replace("surfaces.", ""), surface.data )
def copy_recorded_annotations(): logger.info("Version update: Copy recorded annotations.") notifications = fm.load_pldata_file(rec_dir, "notify") with fm.PLData_Writer(rec_dir, "annotation") as writer: for idx, topic in enumerate(notifications.topics): if topic == "notify.annotation": annotation = notifications.data[idx] ts = notifications.timestamps[idx] writer.append_serialized(ts, "annotation", annotation.serialized)
def extract_annotations_from_recorded_notifications(self): notifications = fm.load_pldata_file(self.g_pool.rec_dir, 'notify') annotation_ts = [] annotation_data = [] for idx, topic in enumerate(notifications.topics): if topic == 'notify.annotation': annotation_ts.append(notifications.timestamps[idx]) annotation_data.append(notifications.data[idx]) self.annotations = pm.Mutable_Bisector(annotation_data, annotation_ts) logger.info('Extracted {} annotations from recording.'.format( len(self.annotations)))
def __init__(self, g_pool): super().__init__(g_pool) pupil_data_file = fm.load_pldata_file(g_pool.rec_dir, "pupil") g_pool.pupil_positions = pm.Bisector(pupil_data_file.data, pupil_data_file.timestamps) g_pool.pupil_positions_by_id = self.create_pupil_positions_by_id_iterative( zip(pupil_data_file.topics, pupil_data_file.data, pupil_data_file.timestamps)) self._pupil_changed_announcer.announce_existing() logger.debug("pupil positions changed")
def __init__(self, g_pool): super().__init__(g_pool) pupil_data_file = fm.load_pldata_file(g_pool.rec_dir, "pupil") g_pool.pupil_positions = pm.Bisector(pupil_data_file.data, pupil_data_file.timestamps) g_pool.pupil_positions_by_id = self.create_pupil_positions_by_id( pupil_data_file.topics, pupil_data_file.data, pupil_data_file.timestamps) self.notify_all({"subject": "pupil_positions_changed"}) logger.debug("pupil positions changed")
def _load_from_file(self): directory = self._offline_data_folder_path file_name = self._pldata_file_name pldata = fm.load_pldata_file(directory, file_name) self.markers_bisector = pm.Mutable_Bisector(pldata.data, pldata.timestamps) if pldata.topics and pldata.topics[0] == "": self._load_frame_index_to_num_markers() else: # for backward compatibility for topic in set(pldata.topics): frame_index, num_markers = topic.split(".") self.frame_index_to_num_markers[int(frame_index)] = int(num_markers)
def __init__(self, g_pool): super().__init__(g_pool) pupil_data_file = fm.load_pldata_file(g_pool.rec_dir, "pupil") g_pool.pupil_positions = pm.Bisector( pupil_data_file.data, pupil_data_file.timestamps ) g_pool.pupil_positions_by_id = self.create_pupil_positions_by_id_iterative( zip( pupil_data_file.topics, pupil_data_file.data, pupil_data_file.timestamps ) ) self._pupil_changed_announcer.announce_existing() logger.debug("pupil positions changed")
def __init__(self, g_pool): super().__init__(g_pool) zmq_ctx = zmq.Context() self.data_sub = zmq_tools.Msg_Receiver( zmq_ctx, g_pool.ipc_sub_url, topics=("pupil", "notify.file_source.video_finished"), hwm=100_000, ) self.data_dir = os.path.join(g_pool.rec_dir, "offline_data") os.makedirs(self.data_dir, exist_ok=True) try: session_meta_data = fm.load_object( os.path.join(self.data_dir, self.session_data_name + ".meta")) assert session_meta_data.get( "version") == self.session_data_version except (AssertionError, FileNotFoundError): session_meta_data = {} session_meta_data["detection_method"] = "3d" session_meta_data["detection_status"] = ["unknown", "unknown"] self.detection_method = session_meta_data["detection_method"] self.detection_status = session_meta_data["detection_status"] pupil = fm.load_pldata_file(self.data_dir, self.session_data_name) ts_data_zip = zip(pupil.timestamps, pupil.data) ts_topic_zip = zip(pupil.timestamps, pupil.topics) self.pupil_positions = collections.OrderedDict(ts_data_zip) self.id_topics = collections.OrderedDict(ts_topic_zip) self.eye_video_loc = [None, None] self.eye_frame_num = [0, 0] for topic in self.id_topics.values(): eye_id = int(topic[-1]) self.eye_frame_num[eye_id] += 1 self.pause_switch = None self.detection_paused = False # start processes for eye_id in range(2): if self.detection_status[eye_id] != "complete": self.start_eye_process(eye_id) # either we did not start them or they failed to start (mono setup etc) # either way we are done and can publish if self.eye_video_loc == [None, None]: self.correlate_publish()
def __init__(self, g_pool): super().__init__(g_pool) zmq_ctx = zmq.Context() self.data_sub = zmq_tools.Msg_Receiver( zmq_ctx, g_pool.ipc_sub_url, topics=("pupil", "notify.file_source.video_finished"), hwm=100_000, ) self.data_dir = os.path.join(g_pool.rec_dir, "offline_data") os.makedirs(self.data_dir, exist_ok=True) try: session_meta_data = fm.load_object( os.path.join(self.data_dir, self.session_data_name + ".meta") ) assert session_meta_data.get("version") == self.session_data_version except (AssertionError, FileNotFoundError): session_meta_data = {} session_meta_data["detection_method"] = "3d" session_meta_data["detection_status"] = ["unknown", "unknown"] self.detection_method = session_meta_data["detection_method"] self.detection_status = session_meta_data["detection_status"] pupil = fm.load_pldata_file(self.data_dir, self.session_data_name) ts_data_zip = zip(pupil.timestamps, pupil.data) ts_topic_zip = zip(pupil.timestamps, pupil.topics) self.pupil_positions = collections.OrderedDict(ts_data_zip) self.id_topics = collections.OrderedDict(ts_topic_zip) self.eye_video_loc = [None, None] self.eye_frame_num = [0, 0] for topic in self.id_topics.values(): eye_id = int(topic[-1]) self.eye_frame_num[eye_id] += 1 self.pause_switch = None self.detection_paused = False # start processes for eye_id in range(2): if self.detection_status[eye_id] != "complete": self.start_eye_process(eye_id) # either we did not start them or they failed to start (mono setup etc) # either way we are done and can publish if self.eye_video_loc == [None, None]: self.correlate_publish()
def _load_recorded_calibrations(self): notifications = fm.load_pldata_file(self._rec_dir, "notify") for topic, data in zip(notifications.topics, notifications.data): if topic.startswith("notify."): # Remove "notify." prefix data = data._deep_copy_dict() data["subject"] = data["topic"][len("notify."):] del data["topic"] else: continue if (CalibrationResultNotification.calibration_format_version() != model.Calibration.version): logger.debug( f"Must update CalibrationResultNotification to match Calibration version" ) continue try: note = CalibrationResultNotification.from_dict(data) except ValueError as err: logger.debug(str(err)) continue calibration = self.__create_prerecorded_calibration( result_notification=note) self.add(calibration)
def load_from_file(cls, dir_path, filename) -> "PupilDataBisector": data = fm.load_pldata_file(dir_path, filename) return cls(data=data)
def _load_from_file(self): directory = self._offline_data_folder_path file_name = self._pldata_file_name pldata = fm.load_pldata_file(directory, file_name) self.pose_bisector = pm.Mutable_Bisector(pldata.data, pldata.timestamps)
def load_cached_annotations(self): annotations = fm.load_pldata_file(self.cache_dir, 'annotations') self.annotations = pm.Mutable_Bisector(annotations.data, annotations.timestamps) logger.info('Loaded {} annotations from cache.'.format( len(self.annotations)))
def _load_gaze_data(self): gaze = fm.load_pldata_file(self.g_pool.rec_dir, "gaze") return pm.Bisector(gaze.data, gaze.timestamps)
def init_bisector(cls, rec_dir): """ Abuse Bisector class for odometry data. """ odometry_data_file = load_pldata_file(rec_dir, "odometry") return pm.Bisector(odometry_data_file.data, odometry_data_file.timestamps)