changeset 151:d5a5a0d7ce30

Return Series for fixed-rate single-valued results from plugin; allow more than one plot per chart, with series plot
author Chris Cannam
date Mon, 29 Apr 2013 22:14:28 +0100
parents e65bdec6470e
children 34b7e3c649db
files yetilab/plot/plot.yeti yetilab/vamp/vamp.yeti yetilab/vamp/vamppost.yeti
diffstat 3 files changed, 51 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/yetilab/plot/plot.yeti	Mon Apr 29 17:24:54 2013 +0100
+++ b/yetilab/plot/plot.yeti	Mon Apr 29 22:14:28 2013 +0100
@@ -34,7 +34,7 @@
     end;
     new FMapper());
 
-plotMatrix matrix =
+plotMatrix chart matrix is ~Chart -> 'a -> () =
    (mapper = newMatrixMapper matrix;
     size = matrix.size;
     xrange = new Range(0, size.columns - 1);
@@ -46,15 +46,11 @@
     surface#setFaceDisplayed(true);
     surface#setWireframeDisplayed(true);
     surface#setWireframeColor(Color#BLACK);
-//    chart = new Chart(Quality#Fastest, "swing");
-    chart = new Chart(Quality#Nicest);
     chart#getScene()#getGraph()#add(surface);
-    ChartLauncher#openChart(chart);
     ());
 
-plotCurve curve =
-   (chart = new Chart(Quality#Nicest);
-    scene = chart#getScene();
+plotCurve chart curve is ~Chart -> 'a -> () =
+   (scene = chart#getScene();
     xx = map (.time) curve;
     yy = map (.value) curve;
     line = new FlatLine2d(xx as ~float[], yy as ~float[], 0);
@@ -72,14 +68,12 @@
     axes#setZAxeLabel("unit goes here"); //!!!
     axes#setYTickLabelDisplayed(false);
 */
-    ChartLauncher#openChart(chart);
     ());
 
-plotSeries series =
-   (chart = new Chart(Quality#Nicest);
-    scene = chart#getScene();
-    xx = [0..length series - 1];
-    yy = list series;
+plotSeries chart { start, step, values } is ~Chart -> 'a -> () =
+   (scene = chart#getScene();
+    xx = map do i: start + step * i done [0..length values - 1];
+    yy = list values;
     line = new FlatLine2d(xx as ~float[], yy as ~float[], 0);
     line#setWireframeDisplayed(true);
     line#setWireframeColor(Color#BLACK);
@@ -95,25 +89,31 @@
     axes#setZAxeLabel("unit goes here"); //!!!
     axes#setYTickLabelDisplayed(false);
 */
-    ChartLauncher#openChart(chart);
     ());
 
-plotStructure structure =
-    case structure of
-    Grid matrix:
-        plotMatrix matrix;
-    Curve curve:
-        plotCurve curve;
-    Series series:
-        plotSeries series;
-    _: failWith "Cannot plot this structure (only grids implemented so far)";
-    esac;
+plot structures =
+   (chart = new Chart(Quality#Nicest);
+    for structures
+       \case of
+        Grid matrix:
+            plotMatrix chart matrix;
+        Curve curve:
+            plotCurve chart curve;
+        Series series:
+            plotSeries chart series;
+        other:
+            failWith "Unable to plot \(other)";
+        esac;
+    ChartLauncher#openChart(chart);
+    chart);
 
 {
     newMatrixMapper,
     newMatrixLogMapper,
     newMapper,
     plotMatrix, 
-    plotStructure,
+    plotCurve,
+    plotSeries,
+    plot,
 }
 
--- a/yetilab/vamp/vamp.yeti	Mon Apr 29 17:24:54 2013 +0100
+++ b/yetilab/vamp/vamp.yeti	Mon Apr 29 22:14:28 2013 +0100
@@ -142,10 +142,15 @@
     elif od#hasFixedBinCount and od#binCount == 1 then
         case computes of
         Event e:
-            if strEnds? e "Segment" then Segmentation ();
-            else Curve ();
+            if strEnds? e "Segment" 
+            then Segmentation ()
+            else Curve ()
             fi;
-        _: Curve ();
+        _:
+            if od#sampleType != OutputDescriptor$SampleType#VariableSampleRate
+            then Series ()
+            else Curve ()
+            fi;
         esac;
     elif od#hasFixedBinCount and
          od#sampleType != OutputDescriptor$SampleType#VariableSampleRate then
--- a/yetilab/vamp/vamppost.yeti	Mon Apr 29 17:24:54 2013 +0100
+++ b/yetilab/vamp/vamppost.yeti	Mon Apr 29 22:14:28 2013 +0100
@@ -12,6 +12,7 @@
         case pending of
         feature::rest:
             stamped = feature with
+            //!!! how do we ensure feature timestamps are rationals where possible?
                { timestamp = Time ((n * config.stepSize) / config.sampleRate) };
             stamped :. \(fill' n rest features);
         _:
@@ -68,8 +69,20 @@
     _: failWith "Internal error: timestamps not filled";
     esac;
 
+structureSeries features =
+    if empty? features then { start = 0, step = 0, values = [] }
+    else 
+        t0 = timeOf (head features);
+        t1 = if empty? (tail features) then t0
+             else timeOf (head (tail features)) fi;
+        {
+            start = t0,
+            step = t1 - t0,
+            values = map do f: (bl.data f.values)[0] done features;
+        }
+    fi;
+
 structureCurve features =
-//!!! need to return sample type as well -- or will caller read that from output elsewhere if they need it?
     map do f: {
         time = timeOf f,
         value = (bl.data f.values)[0],
@@ -126,10 +139,12 @@
         _: 0;
         esac;
     case type of
-    Curve ():               // No duration, one value
-        Curve (structureCurve features);
+    Series ():              // No duration, one value, not variable rate
+        Series (structureSeries features);
     Grid ():                // No duration, >1 value, not variable rate
         Grid (structureGrid binCount features);
+    Curve ():               // No duration, one value, variable rate
+        Curve (structureCurve features);
     Instants ():            // Zero-valued features
         Instants (structureInstants features);
     Notes ():               // Duration, at least one value (pitch or freq)