changeset 306:7576a4957680

Bug fixes in scripts: display plays in last timeline segment of each fragment (post last move); call sub-processes of generate_report.py in same folder (pass on argument); indentation in LaTeX file.
author Brecht De Man <b.deman@qmul.ac.uk>
date Wed, 16 Sep 2015 13:31:40 +0100
parents b71d91792528
children 9ef4bdff3ad4
files core.js scripts/generate_report.py scripts/score_plot.py scripts/timeline_view_movement.py
diffstat 4 files changed, 105 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/core.js	Tue Sep 15 10:20:50 2015 +0100
+++ b/core.js	Wed Sep 16 13:31:40 2015 +0100
@@ -670,7 +670,7 @@
 			} else {
 				popup.showPopup();
 				popup.popupContent.innerHTML = null;
-				popup.popupContent.textContent = "Thank you for performing this listening test";
+				popup.popupContent.textContent = "Thank you!";
 			}
 		};
 		xmlhttp.send(file);
--- a/scripts/generate_report.py	Tue Sep 15 10:20:50 2015 +0100
+++ b/scripts/generate_report.py	Wed Sep 16 13:31:40 2015 +0100
@@ -92,7 +92,7 @@
           
           '''
           
-footer = r'''\begin{thebibliography}{9}
+footer = '\n\t\t'+r'''\begin{thebibliography}{9}
          \bibitem{WAET} % reference to accompanying publication
         Nicholas Jillings, Brecht De Man, David Moffat and Joshua D. Reiss, 
         ``Web Audio Evaluation Tool: A browser-based listening test environment,'' 
@@ -104,9 +104,9 @@
 
 # generate images for later use
 if render_figures:
-    subprocess.call("python timeline_view_movement.py", shell=True)
-    subprocess.call("python score_parser.py", shell=True)
-    subprocess.call("python score_plot.py", shell=True)
+    subprocess.call("python timeline_view_movement.py "+folder_name, shell=True)
+    subprocess.call("python score_parser.py "+folder_name, shell=True)
+    subprocess.call("python score_plot.py "+folder_name, shell=True)
 
 # get every XML file in folder
 files_list = os.listdir(folder_name)
@@ -117,13 +117,13 @@
         root = tree.getroot()
         
         # PRINT name as section
-        body+= '\section{'+file[:-4].capitalize()+'}\n' # make section header from name without extension
+        body+= '\n\section{'+file[:-4].capitalize()+'}\n' # make section header from name without extension
         
         # reset for new subject
         total_duration = 0
         page_number = 0
         
-        individual_table = '' # table with stats for this individual test file
+        individual_table = '\n' # table with stats for this individual test file
         timeline_plots = '' # plots of timeline (movements and plays)
         
         # DEMO survey stats
@@ -137,7 +137,8 @@
         this_subjects_age = root.find("./posttest/number/[@id='age']")
         if this_subjects_age is not None:
             age.append(this_subjects_age.text)
-        
+    	#TODO add plot of age
+    	        
         # get list of all page names
         for audioholder in root.findall("./audioholder"):   # iterate over pages
             page_name = audioholder.get('id')               # get page name
@@ -183,27 +184,27 @@
             # PRINT alerts when elements not played or markers not moved
             # number of audio elements not played
             if len(not_played) > 1:
-                body += '\\emph{\\textbf{ATTENTION: '+str(len(not_played))+\
+                body += '\t\t\\emph{\\textbf{ATTENTION: '+str(len(not_played))+\
                         ' fragments were not listened to in '+page_name+'! }}'+\
                         ', '.join(not_played)+'\\\\ \n'
             if len(not_played) == 1: 
-                body += '\\emph{\\textbf{ATTENTION: one fragment was not listened to in '+page_name+'! }}'+\
+                body += '\t\t\\emph{\\textbf{ATTENTION: one fragment was not listened to in '+page_name+'! }}'+\
                         not_played[0]+'\\\\ \n'
             
             # number of audio element markers not moved
             if len(not_moved) > 1:
-                body += '\\emph{\\textbf{ATTENTION: '+str(len(not_moved))+\
+                body += '\t\t\\emph{\\textbf{ATTENTION: '+str(len(not_moved))+\
                         ' markers were not moved in '+page_name+'! }}'+\
                         ', '.join(not_moved)+'\\\\ \n'
             if len(not_moved) == 1: 
-                body += '\\emph{\\textbf{ATTENTION: one marker was not moved in '+page_name+'! }}'+\
+                body += '\t\t\\emph{\\textbf{ATTENTION: one marker was not moved in '+page_name+'! }}'+\
                         not_moved[0]+'\\\\ \n'
             
             # PRINT song-specific statistic
-            individual_table += page_name+'&'+\
+            individual_table += '\t\t'+page_name+'&'+\
                                 str(number_of_comments) + '/' +\
                                 str(number_of_comments+number_of_missing_comments)+'&'+\
-                                seconds2timestr(duration)+'\\\\'
+                                seconds2timestr(duration)+'\\\\\n'
             
             # get timeline for this audioholder
             img_path = 'timelines_movement/'+file[:-4]+'-'+page_name+'.pdf'
@@ -212,7 +213,7 @@
             if os.path.isfile(folder_name+'/'+img_path):
                 # SHOW timeline image
                 timeline_plots += '\\includegraphics[width=\\textwidth]{'+\
-                         folder_name+'/'+img_path+'}\n\n'
+                         folder_name+'/'+img_path+'}\n\t\t'
             
             # keep track of duration in function of page index
             if len(duration_order)>page_number:
@@ -261,10 +262,10 @@
             time_per_page_accum += duration # total duration (for average time spent per page)
 
         # PRINT table with statistics about this test
-        body += r'''\begin{tabular}{|p{3.5cm}|c|p{2.5cm}|}
+        body += '\t\t'+r'''\begin{tabular}{|p{3.5cm}|c|p{2.5cm}|}
                  \hline
                  \textbf{Song name} & \textbf{Comments} & \textbf{Duration} \\ \hline '''+\
-                 individual_table+\
+                 individual_table+'\t\t'+\
                  r'''\hline
                   \textbf{TOTAL} & & \textbf{'''+\
                   seconds2timestr(total_duration)+\
@@ -284,35 +285,34 @@
 
 # PRINT summary of everything (at start) 
 #       unnumbered so that number of sections equals number of files
-body += '\section*{Summary}\n\\addcontentsline{toc}{section}{Summary}'
+body += '\section*{Summary}\n\t\t\\addcontentsline{toc}{section}{Summary}\n'
 
 # PRINT table with statistics
-body += '\\begin{tabular}{ll}'
-body += r'Number of XML files: &' + str(number_of_XML_files) + r'\\'
-body += r'Number of pages: &' + str(number_of_pages) + r'\\'
-body += r'Number of fragments: &' + str(number_of_fragments) + r'\\'
+body += '\t\t\\begin{tabular}{ll}\n\t\t\t'
+body += r'Number of XML files: &' + str(number_of_XML_files) + r'\\'+'\n\t\t\t'
+body += r'Number of pages: &' + str(number_of_pages) + r'\\'+'\n\t\t\t'
+body += r'Number of fragments: &' + str(number_of_fragments) + r'\\'+'\n\t\t\t'
 body += r'Number of empty comments: &' + str(total_empty_comments) +\
-      " (" + str(round(100.0*total_empty_comments/number_of_fragments,2)) + r"\%)\\"
+      " (" + str(round(100.0*total_empty_comments/number_of_fragments,2)) + r"\%)\\"+'\n\t\t\t'
 body += r'Number of unplayed fragments: &' + str(total_not_played) +\
-      " (" + str(round(100.0*total_not_played/number_of_fragments,2)) + r"\%)\\"
+      " (" + str(round(100.0*total_not_played/number_of_fragments,2)) + r"\%)\\"+'\n\t\t\t'
 body += r'Number of unmoved markers: &' + str(total_not_moved) +\
-      " (" + str(round(100.0*total_not_moved/number_of_fragments,2)) + r"\%)\\"
-body += r'Average time per page: &' + seconds2timestr(time_per_page_accum/number_of_pages) + r"\\"
+      " (" + str(round(100.0*total_not_moved/number_of_fragments,2)) + r"\%)\\"+'\n\t\t\t'
+body += r'Average time per page: &' + seconds2timestr(time_per_page_accum/number_of_pages) + r"\\"+'\n\t\t'
 body += '\\end{tabular} \\vspace{1.5cm} \\\\ \n'
 
 # Average duration for first, second, ... page
-body += " \\vspace{.5cm} Average duration per page (see also Figure \\ref{fig:avgtimeperpage}): \\\\ \n"
+body += "\t\t\\vspace{.5cm} \n\n\t\tAverage duration per page (see also Figure \\ref{fig:avgtimeperpage}): \\\\ \n\t\t"
 body += r'''\begin{tabular}{lll}
-        \textbf{Page} & \textbf{Duration} & \textbf{\# subjects}\\
-        '''
+                    \textbf{Page} & \textbf{Duration} & \textbf{\# subjects}\\'''
 tpp_averages = [] # store average time per page
 for page_number in range(len(duration_order)): 
-    body += str(page_number+1) + "&" +\
+    body += '\n\t\t\t'+str(page_number+1) + "&" +\
         seconds2timestr(sum(duration_order[page_number])/len(duration_order[page_number])) +\
             "&"+str(len(duration_order[page_number]))+r"\\"
     tpp_averages.append(sum(duration_order[page_number])/len(duration_order[page_number]))
             
-body += '\\end{tabular} \\vspace{1.5cm} \\\\ \n'
+body += '\n\t\t\\end{tabular} \\vspace{1.5cm} \\\\ \n\n\t\t'
 
 # SHOW bar plot of average time per page
 plt.bar(range(1,len(duration_order)+1), np.array(tpp_averages)/60)
@@ -339,10 +339,10 @@
 combined_list = sorted(zip(*combined_list), key=operator.itemgetter(1, 2)) # sort
 
 # Show average duration for all songs
-body += r'''\vspace{.5cm} Average duration per audioholder (see also Figure \ref{fig:avgtimeperaudioholder}): \\
-        \begin{tabular}{llll}
-        \textbf{Audioholder} & \textbf{Duration} & \textbf{\# subjects} & \textbf{\# fragments} \\
-        '''
+body += r'''\vspace{.5cm}
+                Average duration per audioholder (see also Figure \ref{fig:avgtimeperaudioholder}): \\
+                \begin{tabular}{llll}
+                        \textbf{Audioholder} & \textbf{Duration} & \textbf{\# subjects} & \textbf{\# fragments} \\'''
 audioholder_names_ordered = []
 average_duration_audioholder_ordered = []
 number_of_subjects = []
@@ -350,11 +350,11 @@
     audioholder_names_ordered.append(combined_list[page_index][0])
     average_duration_audioholder_ordered.append(combined_list[page_index][1])
     number_of_subjects.append(combined_list[page_index][3])
-    body +=  combined_list[page_index][0] + "&" +\
+    body +=  '\n\t\t\t'+combined_list[page_index][0] + "&" +\
              seconds2timestr(combined_list[page_index][1]) + "&" +\
              str(combined_list[page_index][3]) + "&" +\
              str(combined_list[page_index][2]) + r"\\"
-body += '\\end{tabular}\n'
+body += '\n\t\t\\end{tabular}\n'
 
 # SHOW bar plot of average time per page
 plt.bar(range(1,len(audioholder_names_ordered)+1), np.array(average_duration_audioholder_ordered)/60)
@@ -379,7 +379,8 @@
 plt.close()
 
 # SHOW both figures
-body += r'''\begin{figure}[htbp]
+body += r'''
+         \begin{figure}[htbp]
          \begin{center}
          \includegraphics[width=.65\textwidth]{'''+\
          folder_name+"/time_per_page.pdf"+\
@@ -388,6 +389,7 @@
         \label{fig:avgtimeperpage}
          \end{center}
          \end{figure}
+         
          '''
 body += r'''\begin{figure}[htbp]
          \begin{center}
@@ -398,6 +400,7 @@
         \label{fig:avgtimeperaudioholder}
          \end{center}
          \end{figure}
+         
          '''
 body += r'''\begin{figure}[htbp]
          \begin{center}
@@ -408,6 +411,7 @@
         \label{fig:avgtimeperaudioholder}
          \end{center}
          \end{figure}
+         
          '''
 #TODO add error bars
 #TODO layout of figures
@@ -428,6 +432,7 @@
             \label{fig:avgtimeperpage}
              \end{center}
              \end{figure}
+             
              '''
 
 # DEMO pie chart of gender distribution among subjects
@@ -441,6 +446,7 @@
                                '/'+item.capitalize()+' ('+str(number)+'),\n'
 
 body += r'''
+        % Pie chart of gender distribution
         \def\angle{0}
         \def\radius{3}
         \def\cyclelist{{"orange","blue","red","green"}}
@@ -474,6 +480,7 @@
         \label{default}
         \end{center}
         \end{figure}
+        
         '''
 # problem: some people entered twice? 
 
--- a/scripts/score_plot.py	Tue Sep 15 10:20:50 2015 +0100
+++ b/scripts/score_plot.py	Wed Sep 16 13:31:40 2015 +0100
@@ -76,7 +76,7 @@
                 print "WARNING: The 'legend' option is only relevant to plots of "+\
                       "individual ratings"
             show_legend = True     # show all individual ratings
-        elif arg.isnumeric():
+        elif arg.isdigit():
             if not enable_confidence: 
                 print "WARNING: The numeric confidence value is only relevant when "+\
                       "confidence plot is enabled"
--- a/scripts/timeline_view_movement.py	Tue Sep 15 10:20:50 2015 +0100
+++ b/scripts/timeline_view_movement.py	Wed Sep 16 13:31:40 2015 +0100
@@ -137,7 +137,7 @@
                     
                     # assume not playing at start
                     currently_playing = False # keep track of whether fragment is playing during move event
-                    
+                                        
                     # draw all segments except final one
                     for event in move_events: 
                         # mark this plot as not empty
@@ -198,7 +198,6 @@
                         )
                         
                         # vertical line from previous to current position
-                        #TODO red if currently playing, orig color if not
                         plt.plot([new_time, new_time], # x-values
                             [previous_position, new_position], # y-values
                             # color depends on playing during move event or not:
@@ -210,14 +209,69 @@
                         previous_position = new_position
                         previous_time     = new_time
                     
-                    # draw final segment
+                    
+                    
+                    # draw final horizontal segment (or only segment if audioelement not moved)
                     # horizontal line from previous time to end of audioholder
-                    plt.plot([previous_time, audioholder_time-time_offset], # x-values
+                    
+                    # get play/stop events since last move until current move event
+                    stop_times = []
+                    start_times = []
+                    # is there a play and/or stop event between previous_time and new_time?
+                    for time in start_times_global:
+                        if time>previous_time and time<audioholder_time-time_offset:
+                            start_times.append(time)
+                    for time in stop_times_global:
+                        if time>previous_time and time<audioholder_time-time_offset:
+                            stop_times.append(time)
+                    # if no play/stop events between move events, find out whether playing
+                    
+                    segment_start = previous_time # first segment starts at previous move event
+                    
+                    # draw segments (horizontal line)
+                    while len(start_times)+len(stop_times)>0: # while still play/stop events left
+                        # mark this plot as not empty
+                        plot_empty = False
+                        if len(stop_times)<1: # upcoming event is 'play'
+                            # draw non-playing segment from segment_start to 'play'
+                            currently_playing = False
+                            segment_stop = start_times.pop(0) # remove and return first item
+                        elif len(start_times)<1: # upcoming event is 'stop'
+                            # draw playing segment (red) from segment_start to 'stop'
+                            currently_playing = True
+                            segment_stop = stop_times.pop(0) # remove and return first item
+                        elif start_times[0]<stop_times[0]: # upcoming event is 'play'
+                            # draw non-playing segment from segment_start to 'play'
+                            currently_playing = False
+                            segment_stop = start_times.pop(0) # remove and return first item
+                        else: # stop_times[0]<start_times[0]: upcoming event is 'stop'
+                            # draw playing segment (red) from segment_start to 'stop'
+                            currently_playing = True
+                            segment_stop = stop_times.pop(0) # remove and return first item
+                            
+                        # draw segment
+                        plt.plot([segment_start, segment_stop], # x-values
+                            [previous_position, previous_position], # y-values
+                            color='r' if currently_playing else colormap[increment%len(colormap)],
+                            linewidth=3
+                        )
+                        segment_start = segment_stop # move on to next segment
+                        currently_playing = not currently_playing # toggle to draw final segment correctly
+                    
+                    # draw final segment (horizontal line) from last 'segment_start' to current move event time
+                    plt.plot([segment_start, audioholder_time-time_offset], # x-values
                         [previous_position, previous_position], # y-values
-                        color=colormap[increment%len(colormap)],
+                        # color depends on playing during move event or not:
+                        color='r' if currently_playing else colormap[increment%len(colormap)], 
                         linewidth=3
                     )
                     
+#                     plt.plot([previous_time, audioholder_time-time_offset], # x-values
+#                         [previous_position, previous_position], # y-values
+#                         color=colormap[increment%len(colormap)],
+#                         linewidth=3
+#                     )
+                    
                     # display fragment name at end
                     plt.text(audioholder_time-time_offset,previous_position,\
                              audio_id,color=colormap[increment%len(colormap)]) #,rotation=45