diff options
Diffstat (limited to 'src/argaze/utils/tobii_segment_data_plot_export.py')
-rw-r--r-- | src/argaze/utils/tobii_segment_data_plot_export.py | 141 |
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() |