changeset 283:a1c1f032ff0a

Scripts: show which and how many markers not clicked or moved; option to plot timelines against 'audioholder time' (default) or 'total test time' (previously the only possibility)
author Brecht De Man <b.deman@qmul.ac.uk>
date Mon, 10 Aug 2015 18:45:45 +0200
parents 8020152a36af
children f32e58635091
files scripts/evaluation_stats.py scripts/score_plot.py scripts/timeline_view.py
diffstat 3 files changed, 68 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/evaluation_stats.py	Fri Jul 24 18:59:39 2015 +0100
+++ b/scripts/evaluation_stats.py	Mon Aug 10 18:45:45 2015 +0200
@@ -29,6 +29,8 @@
 number_of_pages      = 0
 number_of_fragments  = 0
 total_empty_comments = 0
+total_not_played     = 0
+total_not_moved      = 0
 time_per_page_accum  = 0
 
 # arrays initialisation
@@ -62,6 +64,14 @@
             
             number_of_comments = 0 # for this page
             number_of_missing_comments = 0 # for this page
+            not_played = 0 # for this page
+            not_moved = 0 # for this page
+            
+            # 'testTime' keeps total duration: subtract time so far for duration of this audioholder
+            duration = float(audioholder.find("./metric/metricresult[@id='testTime']").text) - total_duration
+            
+            # total duration of test
+            total_duration += duration
             
             # number of audio elements
             audioelements = audioholder.findall("./audioelement") # get audioelements
@@ -70,24 +80,39 @@
             # number of comments (interesting if comments not mandatory)
             for audioelement in audioelements:
                 response = audioelement.find("./comment/response")
+                was_played = audioelement.find("./metric/metricresult/[@name='elementFlagListenedTo']")
+                was_moved = audioelement.find("./metric/metricresult/[@name='elementFlagMoved']")
                 if response.text is not None and len(response.text) > 1: 
                     number_of_comments += 1
                 else: 
                     number_of_missing_comments += 1
-                    
+                if was_played is not None and was_played.text == 'false': 
+                    not_played += 1
+                if was_moved is not None and was_moved.text == 'false': 
+                    not_moved += 1
+            
+            # update global counters
             total_empty_comments += number_of_missing_comments
-            
-            # 'testTime' keeps total duration: subtract time so far for duration of this audioholder
-            duration = float(audioholder.find("./metric/metricresult[@id='testTime']").text) - total_duration
-            
-            # total duration of test
-            total_duration += duration
+            total_not_played += not_played
+            total_not_moved += not_moved
             
             # print audioholder id and duration
             print "    " + page_name + ": " + seconds2timestr(duration) + ", "\
                   + str(number_of_comments)+"/"\
                   +str(number_of_comments+number_of_missing_comments)+" comments"
             
+            # number of audio elements not played
+            if not_played > 1:
+                print 'ATTENTION: '+str(not_played)+' fragments were not listened to!'
+            if not_played == 1: 
+                print 'ATTENTION: one fragment was not listened to!'
+            
+            # number of audio element markers not moved
+            if not_moved > 1:
+                print 'ATTENTION: '+str(not_moved)+' markers were not moved!'
+            if not_moved == 1: 
+                print 'ATTENTION: one marker was not moved!'
+            
             # keep track of duration in function of page index
             if len(duration_order)>page_number:
                 duration_order[page_number].append(duration)
@@ -134,7 +159,12 @@
 print "Number of XML files: " + str(number_of_XML_files)
 print "Number of pages: " + str(number_of_pages)
 print "Number of fragments: " + str(number_of_fragments)
-print "Number of empty comments: " + str(total_empty_comments)
+print "Number of empty comments: " + str(total_empty_comments) +\
+      " (" + str(round(100.0*total_empty_comments/number_of_fragments,2)) + "%)"
+print "Number of unplayed fragments: " + str(total_not_played) +\
+      " (" + str(round(100.0*total_not_played/number_of_fragments,2)) + "%)"
+print "Number of unmoved markers: " + str(total_not_moved) +\
+      " (" + str(round(100.0*total_not_moved/number_of_fragments,2)) + "%)"
 print "Average time per page: " + seconds2timestr(time_per_page_accum/number_of_pages)
 
 # Pages and number of times tested
@@ -145,8 +175,9 @@
 print "Pages tested: " + str(count_list)
 
 # Average duration for first, second, ... page
+print "Average duration per page:"
 for page_number in range(len(duration_order)): 
-    print "Average duration page " + str(page_number+1) + ": " +\
+    print "        page " + str(page_number+1) + ": " +\
         seconds2timestr(sum(duration_order[page_number])/len(duration_order[page_number])) +\
             " ("+str(len(duration_order[page_number]))+" subjects)"
 
@@ -165,8 +196,9 @@
 combined_list = sorted(zip(*combined_list), key=operator.itemgetter(1, 2)) # sort
 
 # Show average duration for all songs
+print "Average duration per audioholder:"
 for page_index in range(len(page_names)):
-    print "Average duration audioholder " + combined_list[page_index][0] + ": " \
+    print "        "+combined_list[page_index][0] + ": " \
           + seconds2timestr(combined_list[page_index][1]) \
           + " (" + str(combined_list[page_index][3]) + " subjects, " \
           + str(combined_list[page_index][2]) + " fragments)"
@@ -180,3 +212,5 @@
 # show 'count' per page (in order)
 
 # clear up page_index <> page_count <> page_number confusion
+
+# LaTeX -> PDF print out
--- a/scripts/score_plot.py	Fri Jul 24 18:59:39 2015 +0100
+++ b/scripts/score_plot.py	Mon Aug 10 18:45:45 2015 +0200
@@ -72,9 +72,16 @@
         # PLOT OPTIONS
         elif arg == 'leg' or arg == 'legend' or arg == '-l':
             if not enable_individual: 
-                print "WARNING: The 'legend' option is only relevant to plots of individual ratings"
+                print "WARNING: The 'legend' option is only relevant to plots of "+\
+                      "individual ratings"
             show_legend = True     # show all individual ratings
-            
+        elif arg.isnumeric():
+            if not enable_confidence: 
+                print "WARNING: The numeric confidence value is only relevant when "+\
+                      "confidence plot is enabled"
+            if float(arg)>0 and float(arg)<1:
+                confidence = float(arg)
+        
          # FOLDER NAME
          else: 
             # assume it's the folder name
--- a/scripts/timeline_view.py	Fri Jul 24 18:59:39 2015 +0100
+++ b/scripts/timeline_view.py	Mon Aug 10 18:45:45 2015 +0200
@@ -31,6 +31,9 @@
 # Colormap for to cycle through
 colormap = ['b', 'r', 'g', 'c', 'm', 'y', 'k']
 
+# x-axis shows time per audioholder, not total test time
+show_audioholder_time = True
+
 
 # CODE
 
@@ -45,6 +48,8 @@
         root = tree.getroot()
         subject_id = file[:-4] # drop '.xml'
         
+        time_offset = 0 # test starts at zero
+        
         # ONE TIMELINE PER PAGE - make new plot per page
 
         # get list of all page names
@@ -78,25 +83,30 @@
                     listen_events = audioelement.findall("./metric/metricresult/[@name='elementListenTracker']/event")
                     for event in listen_events:
                         # get testtime: start and stop
-                        start_time = event.find('testtime').get('start')
-                        stop_time  = event.find('testtime').get('stop')
+                        start_time = float(event.find('testtime').get('start'))
+                        stop_time  = float(event.find('testtime').get('stop'))
                         # event lines:
-                        plt.plot([start_time, start_time], # x-values
+                        plt.plot([start_time-time_offset, start_time-time_offset], # x-values
                             [0, N_audioelements+1], # y-values
                             color='k'
                             )
-                        plt.plot([stop_time, stop_time], # x-values
+                        plt.plot([stop_time-time_offset, stop_time-time_offset], # x-values
                             [0, N_audioelements+1], # y-values
                             color='k'
                             )
                         # plot time: 
-                        plt.plot([start_time, stop_time], # x-values
+                        plt.plot([start_time-time_offset, stop_time-time_offset], # x-values
                             [N_audioelements-increment, N_audioelements-increment], # y-values
                             color=colormap[increment%len(colormap)],
                             linewidth=6
                             )
                         
                 increment+=1
+                
+            # subtract total audioholder length from subsequent audioholder event times
+            audioholder_time = audioholder.find("./metric/metricresult/[@id='testTime']")
+            if audioholder_time is not None and show_audioholder_time: 
+                time_offset = float(audioholder_time.text)
                                            
             #TODO: if 'nonsensical' or unknown: dashed line until next event
             #TODO: Vertical lines for fragment looping point