Mercurial > hg > webaudioevaluationtool
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"')) |