#! /usr/bin/python from aubio.bench.node import * from aubio.tasks import * def mmean(l): return sum(l)/float(len(l)) def stdev(l): smean = 0 lmean = mmean(l) for i in l: smean += (i-lmean)**2 smean *= 1. / len(l) return smean**.5 class benchonset(bench): """ list of values to store per file """ valuenames = ['orig','missed','Tm','expc','bad','Td'] """ list of lists to store per file """ valuelists = ['l','labs'] """ list of values to print per dir """ printnames = [ 'mode', 'thres', 'dist', 'prec', 'recl', 'Ttrue', 'Tfp', 'Tfn', 'Tm', 'Td', 'aTtrue', 'aTfp', 'aTfn', 'aTm', 'aTd', 'mean', 'smean', 'amean', 'samean'] """ per dir """ formats = {'mode': "%12s" , 'thres': "%5.4s", 'dist': "%5.4s", 'prec': "%5.4s", 'recl': "%5.4s", 'Ttrue': "%5.4s", 'Tfp': "%5.4s", 'Tfn': "%5.4s", 'Tm': "%5.4s", 'Td': "%5.4s", 'aTtrue':"%5.4s", 'aTfp': "%5.4s", 'aTfn': "%5.4s", 'aTm': "%5.4s", 'aTd': "%5.4s", 'mean': "%5.40s", 'smean': "%5.40s", 'amean': "%5.40s", 'samean': "%5.40s"} def dir_eval(self): """ evaluate statistical data over the directory """ totaltrue = sum(self.v['expc'])-sum(self.v['bad'])-sum(self.v['Td']) totalfp = sum(self.v['bad'])+sum(self.v['Td']) totalfn = sum(self.v['missed'])+sum(self.v['Tm']) self.P = 100*float(totaltrue)/max(totaltrue + totalfp,1) self.R = 100*float(totaltrue)/max(totaltrue + totalfn,1) if self.R < 0: self.R = 0 self.F = 2.* self.P*self.R / max(float(self.P+self.R),1) N = float(len(self.reslist)) self.v['mode'] = self.params.onsetmode self.v['thres'] = self.params.threshold self.v['thres'] = "%2.3f" % self.params.threshold self.v['dist'] = "%2.3f" % self.F self.v['prec'] = "%2.3f" % self.P self.v['recl'] = "%2.3f" % self.R self.v['Ttrue'] = totaltrue self.v['Tfp'] = totalfp self.v['Tfn'] = totalfn self.v['aTtrue'] = totaltrue/N self.v['aTfp'] = totalfp/N self.v['aTfn'] = totalfn/N self.v['aTm'] = sum(self.v['Tm'])/N self.v['aTd'] = sum(self.v['Td'])/N self.v['Tm'] = sum(self.v['Tm']) self.v['Td'] = sum(self.v['Td']) self.v['mean'] = mmean(self.v['l']) self.v['smean'] = stdev(self.v['l']) self.v['amean'] = mmean(self.v['labs']) self.v['samean'] = stdev(self.v['labs']) def run_bench(self,modes=['dual'],thresholds=[0.5]): self.modes = modes self.thresholds = thresholds self.pretty_titles() for mode in self.modes: self.params.onsetmode = mode for threshold in self.thresholds: self.params.threshold = threshold self.dir_exec() self.dir_eval() self.pretty_print() #print self.v def auto_learn(self,modes=['dual'],thresholds=[0.1,1.5]): """ simple dichotomia like algorithm to optimise threshold """ self.modes = modes self.pretty_titles() for mode in self.modes: steps = 11 lesst = thresholds[0] topt = thresholds[1] self.params.onsetmode = mode self.params.threshold = topt self.dir_exec() self.dir_eval() self.pretty_print() topF = self.F self.params.threshold = lesst self.dir_exec() self.dir_eval() self.pretty_print() lessF = self.F for i in range(steps): self.params.threshold = ( lesst + topt ) * .5 self.dir_exec() self.dir_eval() self.pretty_print() if self.F == 100.0 or self.F == topF: print "assuming we converged, stopping" break #elif abs(self.F - topF) < 0.01 : # print "done converging" # break if topF < self.F: #lessF = topF #lesst = topt topF = self.F topt = self.params.threshold elif lessF < self.F: lessF = self.F lesst = self.params.threshold if topt == lesst: lesst /= 2. def auto_learn2(self,modes=['dual'],thresholds=[0.00001,1.0]): """ simple dichotomia like algorithm to optimise threshold """ self.modes = modes self.pretty_titles([]) for mode in self.modes: steps = 10 step = 0.4 self.params.onsetmode = mode self.params.threshold = thresholds[0] cur = 0 for i in range(steps): self.dir_exec() self.dir_eval() self.pretty_print() new = self.P if self.R == 0.0: #print "Found maximum, highering" step /= 2. self.params.threshold -= step elif new == 100.0: #print "Found maximum, highering" step *= .99 self.params.threshold += step elif cur > new: #print "lower" step /= 2. self.params.threshold -= step elif cur < new: #print "higher" step *= .99 self.params.threshold += step else: print "Assuming we converged" break cur = new if __name__ == "__main__": import sys if len(sys.argv) > 1: datapath = sys.argv[1] else: print "ERR: a path is required"; sys.exit(1) modes = ['complex', 'energy', 'phase', 'specdiff', 'kl', 'mkl', 'dual'] #modes = [ 'mkl' ] thresholds = [ 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2] #thresholds = [1.5] #datapath = "%s%s" % (DATADIR,'/onset/DB/*/') respath = '/var/tmp/DB-testings' benchonset = benchonset(datapath,respath,checkres=True,checkanno=True) benchonset.params = taskparams() benchonset.task = taskonset benchonset.valuesdict = {} try: #benchonset.auto_learn2(modes=modes) benchonset.run_bench(modes=modes,thresholds=thresholds) except KeyboardInterrupt: sys.exit(1)