evaluate doubled detection
authorPaul Brossier <piem@altern.org>
Sun, 22 May 2005 11:50:49 +0000 (11:50 +0000)
committerPaul Brossier <piem@altern.org>
Sun, 22 May 2005 11:50:49 +0000 (11:50 +0000)
evaluate doubled detection

python/aubio/onsetcompare.py
python/aubioonset

index e15c01c..5e23942 100644 (file)
@@ -27,42 +27,52 @@ see http://en.wikipedia.org/wiki/Receiver_operating_characteristic
 
 from numarray import *
 
-def onset_roc(la, lb, eps):
-    """ thanks to nicolas wack for the rewrite"""
-    """ compute differences between two lists """
-    """ feature: scalable to huge lists """
-    n, m = len(la), len(lb)
-    if m == 0 :
-        return 0,0,0,n,0
-    missed, bad = 0, 0
-    # find missed ones first
-    for x in la:
+def onset_roc(ltru, lexp, eps):
+    """ compute differences between two lists 
+          orig = hits + missed + merged 
+          expc = hits + bad + doubled
+        returns orig, missed, merged, expc, bad, doubled 
+    """
+    orig, expc = len(ltru), len(lexp)
+    # if lexp is empty
+    if expc == 0 : return orig,orig,0,0,0,0
+    missed, bad, doubled, merged = 0, 0, 0, 0
+    # find missed and doubled ones first
+    for x in ltru:
         correspond = 0
-        for y in lb:
-            if abs(x-y) <= eps:
-                correspond += 1
-        if correspond == 0:
-            missed += 1
-    # then look for bad ones
-    for y in lb:
+        for y in lexp:
+            if abs(x-y) <= eps:    correspond += 1
+        if correspond == 0:        missed += 1
+        elif correspond > 1:       doubled += correspond - 1 
+    # then look for bad and merged ones
+    for y in lexp:
         correspond = 0
-        for x in la:
-            if abs(x-y) <= eps:
-               correspond += 1
-        if correspond == 0:
-            bad += 1
-    ok    = n - missed
-    hits  = m - bad
-    # at this point, we must have ok = hits. if not we had
-    #   - a case were one onset counted for two labels (ok>hits)
-    #   - a case were one labels matched two onsets (hits>ok)
-    # bad hack for now (fails if both above cases have happened):
-    if ok > hits: bad += ok-hits; ok = hits
-    if hits > ok: missed += hits-ok; hits = ok
-    total = n
-    return ok,bad,missed,total,hits
-    
-    
+        for x in ltru:
+            if abs(x-y) <= eps:    correspond += 1
+        if correspond == 0:        bad += 1
+        elif correspond > 1:       merged += correspond - 1
+    # check consistancy of the results
+    assert ( orig - missed - merged == expc - bad - doubled)
+    return orig, missed, merged, expc, bad, doubled 
+
+def onset_diffs(ltru, lexp, eps):
+    """ compute differences between two lists 
+          orig = hits + missed + merged 
+          expc = hits + bad + doubled
+        returns orig, missed, merged, expc, bad, doubled 
+    """
+    orig, expc = len(ltru), len(lexp)
+    # if lexp is empty
+    l = []
+    if expc == 0 : return l 
+    # find missed and doubled ones first
+    for x in ltru:
+        correspond = 0
+        for y in lexp:
+            if abs(x-y) <= eps:    l.append(y-x) 
+    # return list of diffs
+    return l 
+
 def notes_roc (la, lb, eps):
     """ creates a matrix of size len(la)*len(lb) then look for hit and miss
     in it within eps tolerance windows """
@@ -97,29 +107,3 @@ def load_onsets(filename) :
         l.append(float(line[0]))
     
     return l
-
-"""
-def onset_roc (la, lb, eps):
-    \"\"\" build a matrix of all possible differences between two lists \"\"\"
-    \"\"\" bug: not scalable to huge lists \"\"\"
-        n, m        = len(la), len(lb)
-    if m ==0 :
-        return 0,0,0,n,0
-        missed, bad = 0, 0
-        x           = resize(la[:],(m,n))
-        y           = transpose(resize(lb[:],(n,m)))
-        teps        = (abs(x-y) <= eps)
-        resmis      = add.reduce(teps,axis = 0)
-        for i in range(n) :
-        if resmis[i] == 0:
-            missed += 1
-    resbad = add.reduce(teps,axis=1)
-    for i in range(m) : 
-        if resbad[i] == 0:
-            bad += 1
-    ok    = n - missed
-    hits  = m - bad
-    total = n
-    return ok,bad,missed,total,hits
-"""
-
index 09fd918..dd27482 100755 (executable)
@@ -35,6 +35,9 @@ def parse_args():
         parser.add_option("-o","--outplot",
                           action="store", dest="outplot", default=None, 
                           help="be quiet [default=None]")
+        parser.add_option("-M","--mintol",
+                          action="store", dest="mintol", default=-70, 
+                          help="mintol [default=0.48]")
         (options, args) = parser.parse_args()
         if not len(args): 
                  print "no file name given\n", usage
@@ -49,4 +52,13 @@ silence   = float(options.silence)
 
 #onsets = getonsets(filename,threshold,silence,mode=options.mode)
 onsets = getonsetscausal(filename,threshold,silence,mode=options.mode)
-for i in onsets: print i*512./44100.
+
+# print all
+#for i in onsets: print i*512./44100.
+# prune doubled 
+last = -10.
+mintol   = float(options.mintol)
+for i in onsets: 
+        new = i*512./44100.
+        if (new - last > mintol): print "%f" % new 
+        last = new