comparison python/generate_report.py @ 2280:334b11f2b418

Merge branch 'master' of https://github.com/BrechtDeMan/WebAudioEvaluationTool
author www-data <www-data@sucuk.dcs.qmul.ac.uk>
date Wed, 20 Apr 2016 20:20:54 +0100
parents 17b7ab4f93f2
children 185232d01324
comparison
equal deleted inserted replaced
2277:372a355779de 2280:334b11f2b418
17 render_figures = True 17 render_figures = True
18 18
19 # XML results files location 19 # XML results files location
20 if len(sys.argv) == 1: 20 if len(sys.argv) == 1:
21 folder_name = "../saves/" # Looks in 'saves/' folder from 'scripts/' folder 21 folder_name = "../saves/" # Looks in 'saves/' folder from 'scripts/' folder
22 print "Use: python generate_report.py [results_folder] [no_render | -nr]" 22 print("Use: python generate_report.py [results_folder] [no_render | -nr]")
23 print "Using default path: " + folder_name 23 print("Using default path: " + folder_name)
24 elif len(sys.argv) == 2: 24 elif len(sys.argv) == 2:
25 folder_name = sys.argv[1] # First command line argument is folder 25 folder_name = sys.argv[1] # First command line argument is folder
26 elif len(sys.argv) == 3: 26 elif len(sys.argv) == 3:
27 folder_name = sys.argv[1] # First command line argument is folder 27 folder_name = sys.argv[1] # First command line argument is folder
28 assert sys.argv[2] in ('no_render','-nr'), "Second argument not recognised. \n" +\ 28 assert sys.argv[2] in ('no_render','-nr'), "Second argument not recognised. \n" +\
52 time_per_page_accum = 0 52 time_per_page_accum = 0
53 53
54 # arrays initialisation 54 # arrays initialisation
55 page_names = [] 55 page_names = []
56 real_page_names = [] # regardless of differing numbers of fragments 56 real_page_names = [] # regardless of differing numbers of fragments
57 subject_count = [] # subjects per audioholder name 57 subject_count = [] # subjects per page name
58 page_count = [] 58 page_count = []
59 duration_page = [] # duration of experiment in function of page content 59 duration_page = [] # duration of experiment in function of page content
60 duration_order = [] # duration of experiment in function of page number 60 duration_order = [] # duration of experiment in function of page number
61 fragments_per_page = [] # number of fragments for corresponding page 61 fragments_per_page = [] # number of fragments for corresponding page
62 62
148 if this_subjects_age is not None: 148 if this_subjects_age is not None:
149 age.append(this_subjects_age.text) 149 age.append(this_subjects_age.text)
150 #TODO add plot of age 150 #TODO add plot of age
151 151
152 # get list of all page names 152 # get list of all page names
153 for audioholder in root.findall("./page"): # iterate over pages 153 for page in root.findall("./page"): # iterate over pages
154 page_name = audioholder.get('id') # get page name 154 page_name = page.get('ref') # get page name
155 155
156 if page_name is None: # ignore 'empty' audio_holders 156 if page_name is None: # ignore 'empty' audio_holders
157 print "WARNING: " + file + " contains empty audio holder. (evaluation_stats.py)" 157 print("WARNING: " + file + " contains empty audio holder. (evaluation_stats.py)")
158 break # move on to next 158 break # move on to next
159 159
160 number_of_comments = 0 # for this page 160 number_of_comments = 0 # for this page
161 number_of_missing_comments = 0 # for this page 161 number_of_missing_comments = 0 # for this page
162 not_played = [] # for this page 162 not_played = [] # for this page
163 not_moved = [] # for this page 163 not_moved = [] # for this page
164 164
165 if audioholder.find("./metric/metricresult[@id='testTime']") is not None: # check if time is included 165 if page.find("./metric/metricresult[@id='testTime']") is not None: # check if time is included
166 # 'testTime' keeps total duration: subtract time so far for duration of this audioholder 166 # 'testTime' keeps total duration: subtract time so far for duration of this page
167 duration = float(audioholder.find("./metric/metricresult[@id='testTime']").text) - total_duration 167 duration = float(page.find("./metric/metricresult[@id='testTime']").text)# - total_duration
168 168
169 # total duration of test 169 # total duration of test
170 total_duration += duration 170 total_duration += duration
171 else: 171 else:
172 duration = float('nan') 172 duration = float('nan')
173 total_duration = float('nan') 173 total_duration = float('nan')
174 174
175 # number of audio elements 175 # number of audio elements
176 audioelements = audioholder.findall("./audioelement") # get audioelements 176 audioelements = page.findall("./audioelement") # get audioelements
177 number_of_fragments += len(audioelements) # add length of this list to total 177 number_of_fragments += len(audioelements) # add length of this list to total
178 178
179 # number of comments (interesting if comments not mandatory) 179 # number of comments (interesting if comments not mandatory)
180 for audioelement in audioelements: 180 for audioelement in audioelements:
181 response = audioelement.find("./comment/response") 181 response = audioelement.find("./comment/response")
182 was_played = audioelement.find("./metric/metricresult/[@name='elementFlagListenedTo']") 182 was_played = audioelement.find("./metric/metricResult/[@name='elementFlagListenedTo']")
183 was_moved = audioelement.find("./metric/metricresult/[@name='elementFlagMoved']") 183 was_moved = audioelement.find("./metric/metricResult/[@name='elementFlagMoved']")
184 if response.text is not None and len(response.text) > 1: 184 if response is not None and response.text is not None and len(response.text) > 1:
185 number_of_comments += 1 185 number_of_comments += 1
186 else: 186 else:
187 number_of_missing_comments += 1 187 number_of_missing_comments += 1
188 if was_played is not None and was_played.text == 'false': 188 if was_played is not None and was_played.text == 'false':
189 not_played.append(audioelement.get('id')) 189 not_played.append(audioelement.get('name'))
190 if was_moved is not None and was_moved.text == 'false': 190 if was_moved is not None and was_moved.text == 'false':
191 not_moved.append(audioelement.get('id')) 191 not_moved.append(audioelement.get('name'))
192 192
193 # update global counters 193 # update global counters
194 total_empty_comments += number_of_missing_comments 194 total_empty_comments += number_of_missing_comments
195 total_not_played += len(not_played) 195 total_not_played += len(not_played)
196 total_not_moved += len(not_moved) 196 total_not_moved += len(not_moved)
218 individual_table += '\t\t'+page_name+'&'+\ 218 individual_table += '\t\t'+page_name+'&'+\
219 str(number_of_comments) + '/' +\ 219 str(number_of_comments) + '/' +\
220 str(number_of_comments+number_of_missing_comments)+'&'+\ 220 str(number_of_comments+number_of_missing_comments)+'&'+\
221 seconds2timestr(duration)+'\\\\\n' 221 seconds2timestr(duration)+'\\\\\n'
222 222
223 # get timeline for this audioholder 223 # get timeline for this page
224 img_path = 'timelines_movement/'+file[:-4]+'-'+page_name+'.pdf' 224 img_path = 'timelines_movement/'+file[:-4]+'-'+page_name+'.pdf'
225 225
226 # check if available 226 # check if available
227 if os.path.isfile(folder_name+img_path): 227 if os.path.isfile(folder_name+img_path):
228 # SHOW timeline image 228 # SHOW timeline image
233 if len(duration_order)>page_number: 233 if len(duration_order)>page_number:
234 duration_order[page_number].append(duration) 234 duration_order[page_number].append(duration)
235 else: 235 else:
236 duration_order.append([duration]) 236 duration_order.append([duration])
237 237
238 # keep list of audioholder ids and count how many times each audioholder id 238 # keep list of page ids and count how many times each page id
239 # was tested, how long it took, and how many fragments there were 239 # was tested, how long it took, and how many fragments there were
240 # (if number of fragments is different, store as different audioholder id) 240 # (if number of fragments is different, store as different page id)
241 if page_name in page_names: 241 if page_name in page_names:
242 page_index = page_names.index(page_name) # get index 242 page_index = page_names.index(page_name) # get index
243 # check if number of audioelements the same 243 # check if number of audioelements the same
244 if len(audioelements) == fragments_per_page[page_index]: 244 if len(audioelements) == fragments_per_page[page_index]:
245 page_count[page_index] += 1 245 page_count[page_index] += 1
259 page_names.append(page_name) 259 page_names.append(page_name)
260 page_count.append(1) 260 page_count.append(1)
261 duration_page.append([duration]) 261 duration_page.append([duration])
262 fragments_per_page.append(len(audioelements)) 262 fragments_per_page.append(len(audioelements))
263 263
264 # number of subjects per audioholder regardless of differing numbers of 264 # number of subjects per page regardless of differing numbers of
265 # fragments (for inclusion in box plots) 265 # fragments (for inclusion in box plots)
266 if page_name in real_page_names: 266 if page_name in real_page_names:
267 page_index = real_page_names.index(page_name) # get index 267 page_index = real_page_names.index(page_name) # get index
268 subject_count[page_index] += 1 268 subject_count[page_index] += 1
269 else: 269 else:
352 combined_list = [page_names, average_duration_page, fragments_per_page, number_of_subjects_page] 352 combined_list = [page_names, average_duration_page, fragments_per_page, number_of_subjects_page]
353 combined_list = sorted(zip(*combined_list), key=operator.itemgetter(1, 2)) # sort 353 combined_list = sorted(zip(*combined_list), key=operator.itemgetter(1, 2)) # sort
354 354
355 # Show average duration for all songs 355 # Show average duration for all songs
356 body += r'''\vspace{.5cm} 356 body += r'''\vspace{.5cm}
357 Average duration per audioholder (see also Figure \ref{fig:avgtimeperaudioholder}): \\ 357 Average duration per page (see also Figure \ref{fig:avgtimeperpage}): \\
358 \begin{tabular}{llll} 358 \begin{tabular}{llll}
359 \textbf{Audioholder} & \textbf{Duration} & \textbf{\# subjects} & \textbf{\# fragments} \\''' 359 \textbf{Audioholder} & \textbf{Duration} & \textbf{\# subjects} & \textbf{\# fragments} \\'''
360 audioholder_names_ordered = [] 360 page_names_ordered = []
361 average_duration_audioholder_ordered = [] 361 average_duration_page_ordered = []
362 number_of_subjects = [] 362 number_of_subjects = []
363 for page_index in range(len(page_names)): 363 for page_index in range(len(page_names)):
364 audioholder_names_ordered.append(combined_list[page_index][0]) 364 page_names_ordered.append(combined_list[page_index][0])
365 average_duration_audioholder_ordered.append(combined_list[page_index][1]) 365 average_duration_page_ordered.append(combined_list[page_index][1])
366 number_of_subjects.append(combined_list[page_index][3]) 366 number_of_subjects.append(combined_list[page_index][3])
367 body += '\n\t\t\t'+combined_list[page_index][0] + "&" +\ 367 body += '\n\t\t\t'+combined_list[page_index][0] + "&" +\
368 seconds2timestr(combined_list[page_index][1]) + "&" +\ 368 seconds2timestr(combined_list[page_index][1]) + "&" +\
369 str(combined_list[page_index][3]) + "&" +\ 369 str(combined_list[page_index][3]) + "&" +\
370 str(combined_list[page_index][2]) + r"\\" 370 str(combined_list[page_index][2]) + r"\\"
371 body += '\n\t\t\\end{tabular}\n' 371 body += '\n\t\t\\end{tabular}\n'
372 372
373 # SHOW bar plot of average time per page 373 # SHOW bar plot of average time per page
374 plt.bar(range(1,len(audioholder_names_ordered)+1), np.array(average_duration_audioholder_ordered)/60) 374 plt.bar(range(1,len(page_names_ordered)+1), np.array(average_duration_page_ordered)/60)
375 plt.xlabel('Audioholder') 375 plt.xlabel('Audioholder')
376 plt.xlim(.8, len(audioholder_names_ordered)+1) 376 plt.xlim(.8, len(page_names_ordered)+1)
377 plt.xticks(np.arange(1,len(audioholder_names_ordered)+1)+.4, audioholder_names_ordered, rotation=90) 377 plt.xticks(np.arange(1,len(page_names_ordered)+1)+.4, page_names_ordered, rotation=90)
378 plt.ylabel('Average time [minutes]') 378 plt.ylabel('Average time [minutes]')
379 plt.savefig(folder_name+"time_per_audioholder.pdf", bbox_inches='tight') 379 plt.savefig(folder_name+"time_per_page.pdf", bbox_inches='tight')
380 plt.close() 380 plt.close()
381 381
382 # SHOW bar plot of average time per page 382 # SHOW bar plot of average time per page
383 plt.bar(range(1,len(audioholder_names_ordered)+1), number_of_subjects) 383 plt.bar(range(1,len(page_names_ordered)+1), number_of_subjects)
384 plt.xlabel('Audioholder') 384 plt.xlabel('Audioholder')
385 plt.xlim(.8, len(audioholder_names_ordered)+1) 385 plt.xlim(.8, len(page_names_ordered)+1)
386 plt.xticks(np.arange(1,len(audioholder_names_ordered)+1)+.4, audioholder_names_ordered, rotation=90) 386 plt.xticks(np.arange(1,len(page_names_ordered)+1)+.4, page_names_ordered, rotation=90)
387 plt.ylabel('Number of subjects') 387 plt.ylabel('Number of subjects')
388 ax = plt.gca() 388 ax = plt.gca()
389 ylims = ax.get_ylim() 389 ylims = ax.get_ylim()
390 yint = np.arange(int(np.floor(ylims[0])), int(np.ceil(ylims[1]))+1) 390 yint = np.arange(int(np.floor(ylims[0])), int(np.ceil(ylims[1]))+1)
391 plt.yticks(yint) 391 plt.yticks(yint)
392 plt.savefig(folder_name+"subjects_per_audioholder.pdf", bbox_inches='tight') 392 plt.savefig(folder_name+"subjects_per_page.pdf", bbox_inches='tight')
393 plt.close() 393 plt.close()
394 394
395 # SHOW both figures 395 # SHOW both figures
396 body += r''' 396 body += r'''
397 \begin{figure}[htbp] 397 \begin{figure}[htbp]
406 406
407 ''' 407 '''
408 body += r'''\begin{figure}[htbp] 408 body += r'''\begin{figure}[htbp]
409 \begin{center} 409 \begin{center}
410 \includegraphics[width=.65\textwidth]{'''+\ 410 \includegraphics[width=.65\textwidth]{'''+\
411 folder_name+'time_per_audioholder.pdf'+\ 411 folder_name+'time_per_page.pdf'+\
412 r'''} 412 r'''}
413 \caption{Average time spent per audioholder.} 413 \caption{Average time spent per page.}
414 \label{fig:avgtimeperaudioholder} 414 \label{fig:avgtimeperpage}
415 \end{center} 415 \end{center}
416 \end{figure} 416 \end{figure}
417 417
418 ''' 418 '''
419 body += r'''\begin{figure}[htbp] 419 body += r'''\begin{figure}[htbp]
420 \begin{center} 420 \begin{center}
421 \includegraphics[width=.65\textwidth]{'''+\ 421 \includegraphics[width=.65\textwidth]{'''+\
422 folder_name+'subjects_per_audioholder.pdf'+\ 422 folder_name+'subjects_per_page.pdf'+\
423 r'''} 423 r'''}
424 \caption{Number of subjects per audioholder.} 424 \caption{Number of subjects per page.}
425 \label{fig:subjectsperaudioholder} 425 \label{fig:subjectsperpage}
426 \end{center} 426 \end{center}
427 \end{figure} 427 \end{figure}
428 428
429 ''' 429 '''
430 #TODO add error bars 430 #TODO add error bars
431 #TODO layout of figures 431 #TODO layout of figures
432 432
433 # SHOW boxplot per audioholder 433 # SHOW boxplot per page
434 #TODO order in decreasing order of participants 434 #TODO order in decreasing order of participants
435 for audioholder_name in page_names: # get each name 435 for page_name in page_names: # get each name
436 # plot boxplot if exists (not so for the 'alt' names) 436 # plot boxplot if exists (not so for the 'alt' names)
437 if os.path.isfile(folder_name+'ratings/'+audioholder_name+'-ratings-box.pdf'): 437 if os.path.isfile(folder_name+'ratings/'+page_name+'-ratings-box.pdf'):
438 body += r'''\begin{figure}[htbp] 438 body += r'''\begin{figure}[htbp]
439 \begin{center} 439 \begin{center}
440 \includegraphics[width=.65\textwidth]{'''+\ 440 \includegraphics[width=.65\textwidth]{'''+\
441 folder_name+"ratings/"+audioholder_name+'-ratings-box.pdf'+\ 441 folder_name+"ratings/"+page_name+'-ratings-box.pdf'+\
442 r'''} 442 r'''}
443 \caption{Box plot of ratings for audioholder '''+\ 443 \caption{Box plot of ratings for page '''+\
444 audioholder_name+' ('+str(subject_count[real_page_names.index(audioholder_name)])+\ 444 page_name+' ('+str(subject_count[real_page_names.index(page_name)])+\
445 ''' participants).} 445 ''' participants).}
446 \label{fig:boxplot'''+audioholder_name.replace(" ", "")+'''} 446 \label{fig:boxplot'''+page_name.replace(" ", "")+'''}
447 \end{center} 447 \end{center}
448 \end{figure} 448 \end{figure}
449 449
450 ''' 450 '''
451 451
507 # clear up page_index <> page_count <> page_number confusion 507 # clear up page_index <> page_count <> page_number confusion
508 508
509 509
510 texfile = header+body+footer # add bits together 510 texfile = header+body+footer # add bits together
511 511
512 print 'pdflatex -output-directory="'+folder_name+'"" "'+ folder_name + 'Report.tex"' # DEBUG 512 # print('pdflatex -output-directory="'+folder_name+'"" "'+ folder_name + 'Report.tex"')# DEBUG
513 513
514 # write TeX file 514 # write TeX file
515 with open(folder_name + 'Report.tex','w') as f: 515 with open(folder_name + 'Report.tex','w') as f:
516 f.write(texfile) 516 f.write(texfile)
517 proc=subprocess.Popen(shlex.split('pdflatex -output-directory="'+folder_name+'" "'+ folder_name + 'Report.tex"')) 517 proc=subprocess.Popen(shlex.split('pdflatex -output-directory="'+folder_name+'" "'+ folder_name + 'Report.tex"'))