22e231a64734b7377fd684446b29984ab6d6a3c9
[aubio.git] / python / aubio / bench / node.py
1 from config import *
2 import commands,sys
3 import re
4
5 def runcommand(cmd,debug=0):
6         if VERBOSE >= VERBOSE_CMD or debug: print cmd
7         if debug: return 
8         status, output = commands.getstatusoutput(cmd)
9         if status == 0 or VERBOSE >= VERBOSE_OUT:
10                 output = output.split('\n')
11         if VERBOSE >= VERBOSE_OUT: 
12                 for i in output: 
13                         if i: print i
14         if not status == 0: 
15                 print 'error:',status,output
16                 print 'command returning error was',cmd
17                 #sys.exit(1)
18         if output == '' or output == ['']: return
19         return output 
20
21 def list_files(datapath,filter='f', maxdepth = -1):
22         if not os.path.exists(datapath):
23                 print
24                 print "ERR: no directory %s were found" % datapath
25                 sys.exit(1)
26         if maxdepth >= 0: maxstring = " -maxdepth %d " % maxdepth       
27         else: maxstring = ""
28         cmd = '%s' * 5 % ('find ',datapath,maxstring,' -type ',filter)
29         return runcommand(cmd)
30
31 def list_wav_files(datapath,maxdepth = -1):
32         return list_files(datapath, filter="f -name '*.wav'",maxdepth = maxdepth)
33
34 sndfile_filter = "f -name '*.wav' -o -name '*.aif' -o -name '*.aiff'"
35
36 def list_snd_files(datapath,maxdepth = -1):
37         return list_files(datapath, filter=sndfile_filter, 
38                 maxdepth = maxdepth)
39
40 def list_res_files(datapath,maxdepth = -1):
41         return list_files(datapath, filter="f -name '*.txt'", maxdepth = maxdepth)
42
43 def list_dirs(datapath):
44         return list_files(datapath, filter="d")
45
46 def mkdir(path):
47         cmd = '%s%s' % ('mkdir -p ',path)
48         return runcommand(cmd)
49
50 def act_on_data (action,datapath,respath=None,suffix='.txt',filter='f',sub='\.wav$',**keywords):
51         """ execute action(datafile,resfile) on all files in datapath """
52         dirlist = list_files(datapath,filter=filter)
53         if dirlist == ['']: dirlist = []
54         if respath:
55                 respath_in_datapath = re.split(datapath, respath,maxsplit=1)[1:]
56                 if(respath_in_datapath and suffix == ''): 
57                         print 'error: respath in datapath and no suffix used'
58         for i in dirlist:
59                 j = re.split(datapath, i,maxsplit=1)[1]
60                 j = re.sub(sub,'',j)
61                 #j = "%s%s%s"%(respath,j,suffix)
62                 if respath:
63                         j = "%s%s"%(respath,j)
64                         if sub != '':
65                                 j = re.sub(sub,suffix,j)
66                         else:
67                                 j = "%s%s" % (j,suffix)
68                 action(i,j,**keywords)
69
70 def act_on_results (action,datapath,respath,filter='d'):
71         """ execute action(respath) an all subdirectories in respath """
72         dirlist = list_files(datapath,filter='d')
73         respath_in_datapath = re.split(datapath, respath,maxsplit=1)[1:]
74         if(respath_in_datapath and not filter == 'd' and suffix == ''): 
75                 print 'warning: respath is in datapath'
76         for i in dirlist:
77                 s = re.split(datapath, i ,maxsplit=1)[1]
78                 action("%s%s%s"%(respath,'/',s))
79
80 def act_on_files (action,listfiles,listres=None,suffix='.txt',filter='f',sub='\.wav$',**keywords):
81         """ execute action(respath) an all subdirectories in respath """
82         if listres and len(listfiles) <= len(listres): 
83                 for i in range(len(listfiles)):
84                         action(listfiles[i],listres[i],**keywords)
85         else:
86                 for i in listfiles:
87                         action(i,None,**keywords)
88
89 class bench:
90         """ class to run benchmarks on directories """
91         def __init__(self,datadir,resdir=None,checkres=False,checkanno=False):
92                 self.datadir = datadir
93                 # path to write results path to
94                 self.resdir = resdir
95                 # list of annotation files
96                 self.reslist = []
97                 # list used to gather results
98                 self.results = []
99                 print "Checking data directory", self.datadir
100                 self.checkdata()
101                 if checkanno: self.checkanno()
102                 if checkres: self.checkres()
103         
104         def checkdata(self):
105                 if os.path.isfile(self.datadir):
106                         self.dirlist = os.path.dirname(self.datadir)
107                         print "DBG: found a file"
108                 elif os.path.isdir(self.datadir):
109                         self.dirlist = list_dirs(self.datadir)
110                         print "DBG: found a dir"
111                 # allow dir* matching through find commands?
112                 else:
113                         print "ERR: path not understood"
114                         sys.exit(1)
115                 print "Listing directories in data directory",
116                 if self.dirlist:
117                         print " (%d elements)" % len(self.dirlist)
118                 else:
119                         print " (0 elements)"
120                         print "ERR: no directory %s were found" % self.datadir
121                         sys.exit(1)
122                 print "Listing sound files in data directory",
123                 self.sndlist = list_snd_files(self.datadir)
124                 if self.sndlist:
125                         print " (%d elements)" % len(self.sndlist)
126                 else:
127                         print " (0 elements)"
128                         print "ERR: no sound files were found in", self.datadir
129                         sys.exit(1)
130         
131         def checkanno(self):
132                 print "Listing annotations in data directory",
133                 self.reslist = list_res_files(self.datadir)
134                 print " (%d elements)" % len(self.reslist)
135                 #for each in self.reslist: print each
136                 if not self.reslist or len(self.reslist) < len (self.sndlist):
137                         print "ERR: not enough annotations"
138                         return -1
139                 else:
140                         print "Found enough annotations"
141         
142         def checkres(self):
143                 print "Creating results directory"
144                 act_on_results(mkdir,self.datadir,self.resdir,filter='d')
145
146         def pretty_print(self,sep='|'):
147                 for i in self.printnames:
148                         print self.formats[i] % self.v[i], sep,
149                 print
150
151         def pretty_titles(self,sep='|'):
152                 for i in self.printnames:
153                         print self.formats[i] % i, sep,
154                 print
155
156         def dir_exec(self):
157                 """ run file_exec on every input file """
158                 self.l , self.labs = [], [] 
159                 self.v = {}
160                 for i in self.valuenames:
161                         self.v[i] = [] 
162                 for i in self.valuelists:
163                         self.v[i] = [] 
164                 act_on_files(self.file_exec,self.sndlist,self.reslist, \
165                         suffix='',filter=sndfile_filter)
166
167         def dir_eval(self):
168                 pass
169
170         def file_gettruth(self,input):
171                 """ get ground truth filenames """
172                 from os.path import isfile
173                 ftrulist = []
174                 # search for match as filetask.input,".txt" 
175                 ftru = '.'.join(input.split('.')[:-1])
176                 ftru = '.'.join((ftru,'txt'))
177                 if isfile(ftru):
178                         ftrulist.append(ftru)
179                 else:
180                         # search for matches for filetask.input in the list of results
181                         for i in range(len(self.reslist)):
182                                 check = '.'.join(self.reslist[i].split('.')[:-1])
183                                 check = '_'.join(check.split('_')[:-1])
184                                 if check == '.'.join(input.split('.')[:-1]):
185                                         ftrulist.append(self.reslist[i])
186                 return ftrulist
187
188         def file_exec(self,input,output):
189                 """ create filetask, extract data, evaluate """
190                 filetask = self.task(input,params=self.params)
191                 computed_data = filetask.compute_all()
192                 ftrulist = self.file_gettruth(filetask.input)
193                 for i in ftrulist:
194                         filetask.eval(computed_data,i,mode='rocloc',vmode='')
195                         """ append filetask.v to self.v """
196                         for i in self.valuenames:
197                                 self.v[i].append(filetask.v[i])
198                         for j in self.valuelists:
199                                 if filetask.v[j]:
200                                         for i in range(len(filetask.v[j])):
201                                                 self.v[j].append(filetask.v[j][i])
202         
203         def file_eval(self):
204                 pass
205         
206         def file_plot(self):
207                 pass
208
209         def dir_plot(self):
210                 pass
211         
212         def run_bench(self):
213                 for mode in self.modes:
214                         self.params.mode = mode
215                         self.dir_exec()
216                         self.dir_eval()
217                         self.dir_plot()