aboutsummaryrefslogtreecommitdiff
path: root/src/argaze/utils/tobii_segment_data_plot_export.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/argaze/utils/tobii_segment_data_plot_export.py')
-rw-r--r--src/argaze/utils/tobii_segment_data_plot_export.py141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/argaze/utils/tobii_segment_data_plot_export.py b/src/argaze/utils/tobii_segment_data_plot_export.py
new file mode 100644
index 0000000..69f88e3
--- /dev/null
+++ b/src/argaze/utils/tobii_segment_data_plot_export.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python
+
+import argparse
+import os
+import json
+
+from argaze import DataStructures
+from argaze import GazeFeatures
+from argaze.TobiiGlassesPro2 import TobiiEntities, TobiiVideo
+from argaze.utils import MiscFeatures
+
+import pandas
+import matplotlib.pyplot as mpyplot
+import matplotlib.patches as mpatches
+
+def main():
+ """
+ """
+
+ # Manage arguments
+ parser = argparse.ArgumentParser(description=main.__doc__.split('-')[0])
+ parser.add_argument('-s', '--segment_path', metavar='SEGMENT_PATH', type=str, default=None, help='segment path')
+ parser.add_argument('-r', '--time_range', metavar=('START_TIME', 'END_TIME'), nargs=2, type=float, default=(0., None), help='start and end time (in second)')
+ parser.add_argument('-o', '--output', metavar='OUT', type=str, default=None, help='destination folder path (segment folder by default)')
+ args = parser.parse_args()
+
+ if args.segment_path != None:
+
+ # Manage destination path
+ destination_path = '.'
+ if args.output != None:
+
+ if not os.path.exists(os.path.dirname(args.output)):
+
+ os.makedirs(os.path.dirname(args.output))
+ print(f'{os.path.dirname(args.output)} folder created')
+
+ destination_path = args.output
+
+ else:
+
+ destination_path = args.segment_path
+
+ # Export into a dedicated time range folder
+ if args.time_range[1] != None:
+ timerange_path = f'[{int(args.time_range[0])}s - {int(args.time_range[1])}s]'
+ else:
+ timerange_path = f'[all]'
+
+ destination_path = f'{destination_path}/{timerange_path}'
+
+ if not os.path.exists(destination_path):
+
+ os.makedirs(destination_path)
+ print(f'{destination_path} folder created')
+
+ data_plots_filepath = f'{destination_path}/data_plot.svg'
+
+ # Load a tobii segment
+ tobii_segment = TobiiEntities.TobiiSegment(args.segment_path, int(args.time_range[0] * 1e6), int(args.time_range[1] * 1e6) if args.time_range[1] != None else None)
+
+ # Load a tobii segment video
+ tobii_segment_video = tobii_segment.load_video()
+ print(f'Video properties:\n\tduration: {tobii_segment_video.duration / 1e6} s\n\twidth: {tobii_segment_video.width} px\n\theight: {tobii_segment_video.height} px')
+
+ # Load a tobii segment data
+ tobii_segment_data = tobii_segment.load_data()
+
+ print(f'Loaded data count:')
+ for name in tobii_segment_data.keys():
+ print(f'\t{name}: {len(tobii_segment_data[name])} data')
+
+ # Edit figure
+ figure_width = min( 4 * tobii_segment_video.duration / 1e6, 56) # maximal width to display: 56 inches at 144 dpi < 2^16 pixels
+ data_sample = 8064 # 56 inches * 144 dpi = 8064 data can be displayed at max
+ figure = mpyplot.figure(figsize=(figure_width, 35), dpi=144)
+
+ # Plot pupil diameter data
+ subplot = figure.add_subplot(711)
+ subplot.set_title('Pupil diameter', loc='left')
+ subplot.set_ylim(0, 10)
+ patches = tobii_segment_data['PupilDiameter'].plot(names=['value'], colors=['#FFD800'], samples=data_sample)
+ subplot.legend(handles=patches, loc='upper left')
+
+ # Annotate events
+ df_ts_events = tobii_segment_data['Event'].as_dataframe()
+
+ if len(df_ts_events) > 0:
+
+ for ts, event_type, event_tag in zip(df_ts_events.index, df_ts_events.type, df_ts_events.tag):
+ subplot.annotate(f'{event_type}\n{event_tag}', xy=(ts, 7), horizontalalignment="left", verticalalignment="top")
+ subplot.vlines(ts, 0, 6, color="tab:red", linewidth=1)
+
+ # Plot pupil center data
+ subplot = figure.add_subplot(712)
+ subplot.set_title('Pupil center', loc='left')
+ subplot.set_ylim(-40, -20)
+ patches = tobii_segment_data['PupilCenter'].plot(names=['x','y','z'], colors=['#276FB6','#9427B6','#888888'], split={'value':['x','y','z']}, samples=data_sample)
+ subplot.legend(handles=patches, loc='upper left')
+
+ # Plot gaze position data
+ subplot = figure.add_subplot(713)
+ subplot.set_title('Gaze position', loc='left')
+ subplot.set_ylim(0., 1.)
+ patches = tobii_segment_data['GazePosition'].plot(names=['x','y'], colors=['#276FB6','#9427B6'], split={'value':['x','y']}, samples=data_sample)
+ subplot.legend(handles=patches, loc='upper left')
+
+ # Plot gaze direction data
+ subplot = figure.add_subplot(714)
+ subplot.set_title('Gaze direction', loc='left')
+ patches = tobii_segment_data['GazeDirection'].plot(names=['x','y','z'], colors=['#276FB6','#9427B6','#888888'], split={'value':['x','y','z']}, samples=data_sample)
+ subplot.legend(handles=patches, loc='upper left')
+
+ # Plot gaze direction data
+ subplot = figure.add_subplot(715)
+ subplot.set_title('Gaze position 3D', loc='left')
+ patches = tobii_segment_data['GazePosition3D'].plot(names=['x','y','z'], colors=['#276FB6','#9427B6','#888888'], split={'value':['x','y','z']}, samples=data_sample)
+ subplot.legend(handles=patches, loc='upper left')
+
+ # Plot accelerometer data
+ subplot = figure.add_subplot(716)
+ subplot.set_title('Accelerometer', loc='left')
+ patches = tobii_segment_data['Accelerometer'].plot(names=['x','y','z'], colors=['#276FB6','#9427B6','#888888'], split={'value':['x','y','z']}, samples=data_sample)
+ subplot.legend(handles=patches, loc='upper left')
+
+ # Plot accelerometer data
+ subplot = figure.add_subplot(717)
+ subplot.set_title('Gyroscope', loc='left')
+ patches = tobii_segment_data['Gyroscope'].plot(names=['x','y','z'], colors=['#276FB6','#9427B6','#888888'], split={'value':['x','y','z']}, samples=data_sample)
+ subplot.legend(handles=patches, loc='upper left')
+
+ # Export figure
+ mpyplot.tight_layout()
+ mpyplot.savefig(data_plots_filepath)
+ mpyplot.close('all')
+
+ print(f'\nData plots saved into {data_plots_filepath}')
+
+if __name__ == '__main__':
+
+ main()