changeset 2275:3ca6e3fb66f4

Merge branch 'master' of https://github.com/BrechtDeMan/WebAudioEvaluationTool
author www-data <www-data@sucuk.dcs.qmul.ac.uk>
date Wed, 20 Apr 2016 18:20:58 +0100
parents 64bdcd9ad9a4 (current diff) 2b5990868aa7 (diff)
children 372a355779de
files
diffstat 6 files changed, 75 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/README.md	Wed Apr 20 17:22:18 2016 +0100
+++ b/README.md	Wed Apr 20 18:20:58 2016 +0100
@@ -16,6 +16,14 @@
 Please refer to ['docs/Instructions/Instructions.pdf'](https://github.com/BrechtDeMan/WebAudioEvaluationTool/raw/master/docs/Instructions/Instructions.pdf).
 
 
+## Dependencies
+
+Runs out of the box on any web server with PHP (tested on PHP 5.1<=), no third party software needed. 
+
+Alternatively, a local server (no web server or internet connection needed!) and optional Python analysis scripts run on Python 2.7 or 3.x. 
+Plots rendered using [matplotlib](http://matplotlib.org), [NumPy](http://matplotlib.org) and [SciPy](http://scipy.org). 
+
+
 ## Academic use
 
 ### Citing
@@ -37,6 +45,7 @@
 
 Please refer to LICENSE.txt ([GNU General Public License](http://www.gnu.org/licenses/gpl-3.0.en.html)).
 
+
 ## Other use
 
 Other licensing schemes are available - please contact the authors regarding non-academic use. 
--- a/docs/Instructions/Instructions.tex	Wed Apr 20 17:22:18 2016 +0100
+++ b/docs/Instructions/Instructions.tex	Wed Apr 20 18:20:58 2016 +0100
@@ -316,14 +316,14 @@
 		From \cite{waetwac}. 
 
 		% TODO: add labels like (\textbf{\texttt{horizontal-sliders}}) to show which type of interface can be created using which template
-
+		
 		\begin{itemize}
 			\item AB Test / Pairwise comparison~\cite{lipshitz1981great,david1963method}: Two stimuli presented simultaneously, participant selects a preferred stimulus.
 			\item ABC/HR (ITU-R BS. 1116)~\cite{recommendation19971116} (Mean Opinion Score: MOS): each stimulus has a continuous scale (5-1), labeled as Imperceptible, Perceptible but not annoying, Slightly annoying, Annoying, Very annoying.
 			\item -50 to 50 Bipolar with Ref: each stimulus has a continuous scale -50 to 50 with default values as 0 in middle and a reference.
 			\item Absolute Category Rating (ACR) Scale~\cite{rec1996p}: Likert but labels are Bad, Poor, Fair, Good, Excellent 
 			\item ABX Test~\cite{clark1982high}: Two stimuli are presented along with a reference and the participant has to select a preferred stimulus, often the closest to the reference.
-			\item APE \cite{ape}: Multiple stimuli on one or more axes for inter-sample rating.
+			\item APE~\cite{ape}: Multiple stimuli on one or more axes for inter-sample rating.
 			%\item APE style 2D \cite{ape}: Multiple stimuli on a 2D plane for inter-sample rating (e.g. Valence Arousal). % TO BE IMPLEMENTED 
 			\item Comparison Category Rating (CCR) Scale~\cite{rec1996p}: ACR \& DCR but 7 point scale, with reference: Much better, Better, Slightly better, About the same, Slightly worse, Worse, Much worse.
 			\item Degredation Category Rating (DCR) Scale~\cite{rec1996p}: ABC \& Likert but labels are (5) Inaudible, (4) Audible but not annoying, (3) Slightly annoying, (2) Annoying, (1) Very annoying.
@@ -335,6 +335,7 @@
 			\item 9 Point Hedonic Category Rating Scale~\cite{peryam1952advanced}: each stimulus has a seven point scale with values: Like extremely, Like very much, Like moderate, Like slightly, Neither like nor dislike, Dislike extremely, Dislike very much, Dislike moderate, Dislike slightly. There is also a provided reference.
 		\end{itemize}
 
+
 	\subsection{Building your own interface}
 
 		\subsubsection{Nodes to familiarise}
--- a/python/comment_parser.py	Wed Apr 20 17:22:18 2016 +0100
+++ b/python/comment_parser.py	Wed Apr 20 18:20:58 2016 +0100
@@ -14,19 +14,19 @@
 # XML results files location
 if len(sys.argv) == 1:
     folder_name = "../saves"    # Looks in 'saves/' folder from 'scripts/' folder
-    print "Use: python  comment_parser.py [XML_files_location]"
-    print "Using default path: " + folder_name
+    print("Use: python comment_parser.py [XML_files_location]")
+    print("Using default path: " + folder_name)
 elif len(sys.argv) == 2:
     folder_name = sys.argv[1]   # First command line argument is folder
 
 # check if folder_name exists
 if not os.path.exists(folder_name):
     #the file is not there
-    print "Folder '"+folder_name+"' does not exist."
+    print("Folder '"+folder_name+"' does not exist.")
     sys.exit() # terminate script execution
 elif not os.access(os.path.dirname(folder_name), os.W_OK):
     #the file does exist but write privileges are not given
-    print "No write privileges in folder '"+folder_name+"'."
+    print("No write privileges in folder '"+folder_name+"'.")
 
 
 # CODE
@@ -45,11 +45,11 @@
             page_name = audioholder.get('ref')               # get page name
             
             if page_name is None: # ignore 'empty' audio_holders
-                print "WARNING: " + file + " contains empty page. (comment_parser.py)"
+                print("WARNING: " + file + " contains empty page. (comment_parser.py)")
                 break
                 
             if audioholder.get("state") != "complete":
-                print "WARNING: " + file + "test page " + page_name + " is not complete, skipping."
+                print("WARNING: " + file + "test page " + page_name + " is not complete, skipping.")
             else:
                 # create folder [page_name] if not yet created
                 if not os.path.exists(folder_name + "/" + page_name):
@@ -79,9 +79,9 @@
                            commentstr = ''
 
                         # anonymous comments:
-                        #writer.writerow([commentstr.encode("utf-8")]) 
+                        #writer.writerow([commentstr])  # .encode("utf-8")
                         # comments with (file) name:
-                        writer.writerow([file[:-4]] + [commentstr.encode("utf-8")]) 
+                        writer.writerow([file[:-4]] + [commentstr]) 
 
                     #TODO Replace 'new line' in comment with something else?
                         
--- a/python/score_plot.py	Wed Apr 20 17:22:18 2016 +0100
+++ b/python/score_plot.py	Wed Apr 20 18:20:58 2016 +0100
@@ -31,34 +31,34 @@
 # XML results files location
 if len(sys.argv) == 1: # no extra arguments
     enable_boxplot    = True # show box plot
-    print "Use: python score_plot.py [rating folder] [plot_type] [-l/-legend]"
-    print "Type 'python score_plot.py -h' for help."
-    print "Using default path: " + rating_folder + " with boxplot."
+    print("Use: python score_plot.py [rating folder] [plot_type] [-l/-legend]")
+    print("Type 'python score_plot.py -h' for help.")
+    print("Using default path: " + rating_folder + " with boxplot.")
 else:
     for arg in sys.argv: # go over all arguments
         if arg == '-h':
             # show help
             #TODO: replace with contents of helpfile score_plot.info (or similar)
-            print "Use: python score_plot.py [rating_folder] [plot_type] [-l] [confidence]"
-            print "   rating_folder:"
-            print "            folder where output of 'score_parser' can be found, and"
-            print "            where plots will be stored."
-            print "            By default, '../saves/ratings/' is used."
-            print ""
-            print "PLOT TYPES"
-            print " Can be used in combination."
-            print "    box | boxplot | -b"
-            print "            Enables the boxplot" 
-            print "    conf | confidence | -c"
-            print "            Enables the confidence interval plot" 
-            print "    ind | individual | -i"
-            print "            Enables plot of individual ratings" 
-            print ""
-            print "PLOT OPTIONS"
-            print "    leg | legend | -l"
-            print "            For individual plot: show legend with individual file names"
-            print "    numeric value between 0 and 1, e.g. 0.95"
-            print "            For confidence interval plot: confidence value"
+            print("Use: python score_plot.py [rating_folder] [plot_type] [-l] [confidence]")
+            print("   rating_folder:")
+            print("            folder where output of 'score_parser' can be found, and")
+            print("            where plots will be stored.")
+            print("            By default, '../saves/ratings/' is used.")
+            print("")
+            print("PLOT TYPES")
+            print(" Can be used in combination.")
+            print("    box | boxplot | -b")
+            print("            Enables the boxplot" )
+            print("    conf | confidence | -c")
+            print("            Enables the confidence interval plot" )
+            print("    ind | individual | -i")
+            print("            Enables plot of individual ratings" )
+            print("")
+            print("PLOT OPTIONS")
+            print("    leg | legend | -l")
+            print("            For individual plot: show legend with individual file names")
+            print("    numeric value between 0 and 1, e.g. 0.95")
+            print("            For confidence interval plot: confidence value")
             assert False, ""# stop immediately after showing help #TODO cleaner way
             
         # PLOT TYPES
@@ -73,17 +73,17 @@
         # 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.isdigit():
             if not enable_confidence: 
-                print "WARNING: The numeric confidence value is only relevant when "+\
-                      "confidence plot is enabled"
+                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)
             else: 
-                print "WARNING: The confidence value needs to be between 0 and 1"
+                print("WARNING: The confidence value needs to be between 0 and 1")
         
         # FOLDER NAME
         else: 
@@ -97,11 +97,11 @@
 # check if folder_name exists
 if not os.path.exists(rating_folder):
     #the file is not there
-    print "Folder '"+rating_folder+"' does not exist."
+    print("Folder '"+rating_folder+"' does not exist.")
     sys.exit() # terminate script execution
 elif not os.access(os.path.dirname(rating_folder), os.W_OK):
     #the file does exist but write rating_folder are not given
-    print "No write privileges in folder '"+rating_folder+"'."
+    print("No write privileges in folder '"+rating_folder+"'.")
 
 
 # CONFIGURATION
@@ -119,28 +119,25 @@
     if file.endswith(".csv"):
         page_name = file[:-4] # file name (without extension) is page ID
 
-        # get header
+        # get header (as text)
+        with open(rating_folder+file, 'rt') as readfile: # read this csv file
+            filereader = csv.reader(readfile, delimiter=',')
+            headerrow = next(filereader) # use headerrow as X-axis
+            headerrow = headerrow[1:]
+
+        # read ratings into matrix (as bytes)
         with open(rating_folder+file, 'rb') as readfile: # read this csv file
             filereader = csv.reader(readfile, delimiter=',')
-            headerrow = filereader.next() # use headerrow as X-axis
-            headerrow = headerrow[1:]
-
-        # read ratings into matrix
-#         ratings = np.loadtxt(open(rating_folder+file,"rb"),
-#                             delimiter=",",
-#                             skiprows=1,
-#                             usecols=range(1,len(headerrow)+1)
-#                             )
             ratings = np.genfromtxt(readfile,
                                    delimiter=",",
-                                   #skip_header = 1,
+                                   skip_header = 1,
                                    converters = {3: lambda s: float(s or 'Nan')},
-                                   usecols=range(1,len(headerrow)+1)
+                                   usecols=list(range(1,len(headerrow)+1))
                                    )
         
         # assert at least 2 subjects (move on to next file if violated)
         if ratings.shape[0]<2:
-            print "WARNING: Just one subject for " + page_name + ". Moving on to next file."
+            print("WARNING: Just one subject for " + page_name + ". Moving on to next file.")
             break
 
         # BOXPLOT
@@ -183,9 +180,9 @@
             increment = 0
             linehandles = []
             legendnames = []
-            with open(rating_folder+file, 'rb') as readfile: # read this csv file
+            with open(rating_folder+file, 'r') as readfile: # read this csv file
                 filereader = csv.reader(readfile, delimiter=',')
-                headerrow = filereader.next() # use headerrow as X-axis
+                headerrow = next(filereader) # use headerrow as X-axis
                 headerrow = headerrow[1:]
                 for row in filereader:
                     subject_id = row[0][:-4] # read from beginning of line
--- a/python/timeline_view.py	Wed Apr 20 17:22:18 2016 +0100
+++ b/python/timeline_view.py	Wed Apr 20 18:20:58 2016 +0100
@@ -14,19 +14,19 @@
 # XML results files location
 if len(sys.argv) == 1:
     folder_name = "../saves"    # Looks in 'saves/' folder from 'scripts/' folder
-    print "Use: python timeline_view.py [XML_files_location]"
-    print "Using default path: " + folder_name
+    print("Use: python timeline_view.py [XML_files_location]")
+    print("Using default path: " + folder_name)
 elif len(sys.argv) == 2:
     folder_name = sys.argv[1]   # First command line argument is folder
 
 # check if folder_name exists
 if not os.path.exists(folder_name):
     #the file is not there
-    print "Folder '"+folder_name+"' does not exist."
+    print("Folder '"+folder_name+"' does not exist.")
     sys.exit() # terminate script execution
 elif not os.access(os.path.dirname(folder_name), os.W_OK):
     #the file does exist but write privileges are not given
-    print "No write privileges in folder '"+folder_name+"'."
+    print("No write privileges in folder '"+folder_name+"'.")
 
 
 # CONFIGURATION 
@@ -76,11 +76,11 @@
             plot_empty = True                               # check if any data is plotted
             
             if page_name is None: # ignore 'empty' audio_holders
-                print "WARNING: " + file + " contains empty page. (comment_parser.py)"
+                print("WARNING: " + file + " contains empty page. (comment_parser.py)")
                 break
                 
             if audioholder.get("state") != "complete":
-                print "WARNING: " + file + "test page " + page_name + " is not complete, skipping."
+                print("WARNING: " + file + "test page " + page_name + " is not complete, skipping.")
                 break;
             # SORT AUDIO ELEMENTS ALPHABETICALLY
             audioelements = audioholder.findall("./audioelement")
--- a/python/timeline_view_movement.py	Wed Apr 20 17:22:18 2016 +0100
+++ b/python/timeline_view_movement.py	Wed Apr 20 18:20:58 2016 +0100
@@ -15,19 +15,19 @@
 # XML results files location
 if len(sys.argv) == 1:
     folder_name = "../saves"    # Looks in 'saves/' folder from 'scripts/' folder
-    print "Use: python timeline_view_movement.py [XML_files_location]"
-    print "Using default path: " + folder_name
+    print("Use: python timeline_view_movement.py [XML_files_location]")
+    print("Using default path: " + folder_name)
 elif len(sys.argv) == 2:
     folder_name = sys.argv[1]   # First command line argument is folder
 
 # check if folder_name exists
 if not os.path.exists(folder_name):
     #the file is not there
-    print "Folder '"+folder_name+"' does not exist."
+    print("Folder '"+folder_name+"' does not exist.")
     sys.exit() # terminate script execution
 elif not os.access(os.path.dirname(folder_name), os.W_OK):
     #the file does exist but write privileges are not given
-    print "No write privileges in folder '"+folder_name+"'."
+    print("No write privileges in folder '"+folder_name+"'.")
 
 
 # CONFIGURATION 
@@ -72,7 +72,7 @@
             plot_empty = True                               # check if any data is plotted
             
             if page_name is None: # ignore 'empty' audio_holders
-                print "Skipping empty page name from "+subject_id+"."
+                print("Skipping empty page name from "+subject_id+".")
                 break
                 
             # subtract total page length from subsequent page event times
@@ -80,7 +80,7 @@
             if page_time_temp is not None: 
                 page_time = float(page_time_temp.text)
             else: 
-                print "Skipping page without total time specified from "+subject_id+"."
+                print("Skipping page without total time specified from "+subject_id+".")
                 break
 
             # get audioelements
@@ -111,7 +111,7 @@
                     # break if no initial position or move events registered
                     initial_position_temp = audioelement.find("./metric/metricResult/[@name='elementInitialPosition']")
                     if initial_position_temp is None:
-                        print "Skipping "+page_name+" from "+subject_id+": does not have initial positions specified."
+                        print("Skipping "+page_name+" from "+subject_id+": does not have initial positions specified.")
                         break
                     
                     # get move events, initial and eventual position