ref: 8d29cfe3df450227c100acf2c9051737b0dd95d7
dir: /python/test/bench/onset/bench-onset/
#! /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)