Enable persistence for Dataset, Labelset and 'model' objects
viz. KDTree, KMeans,KNN, Normalize, PCA and Standardize. Most changes in FluidManipulationClientnix
parent
1eabc42b24
commit
4b88b405d7
@ -1,64 +1,88 @@
|
||||
|
||||
FluidDataSetExistsError : Exception{
|
||||
}
|
||||
|
||||
FluidDataSet : FluidManipulationClient {
|
||||
|
||||
var <>synth, <>server, <>id;
|
||||
var <id;
|
||||
classvar serverCaches;
|
||||
|
||||
*kr{ |name|
|
||||
^this.new1('control',name);
|
||||
*initClass {
|
||||
serverCaches = FluidServerCache.new;
|
||||
}
|
||||
|
||||
*at{ |server, id|
|
||||
^serverCaches.tryPerform(\at, server,id)
|
||||
}
|
||||
|
||||
*new { |server,name|
|
||||
^super.new(server,name);
|
||||
if(this.at(server,name).notNil){
|
||||
FluidDataSetExistsError("A FluidDataset called % already exists.".format(name)).throw;
|
||||
}
|
||||
{^super.new(server,*FluidManipulationClient.prServerString(name)).init(name)}
|
||||
}
|
||||
|
||||
init { |name, dims|
|
||||
var ascii = name.ascii;
|
||||
this.id = name;
|
||||
// specialIndex = -1;
|
||||
inputs = [ascii.size].addAll(ascii)++dims++Done.none++FluidManipulationClient.nonBlocking;
|
||||
init {|name|
|
||||
id = name;
|
||||
this.cache;
|
||||
}
|
||||
|
||||
cache {
|
||||
serverCaches.initCache(server);
|
||||
serverCaches.put(server,id,this);
|
||||
}
|
||||
|
||||
asString {
|
||||
^"FluidDataSet(%)".format(id).asString;
|
||||
}
|
||||
|
||||
asUGenInput {
|
||||
^id.asString;
|
||||
}
|
||||
|
||||
addPoint{|label, buffer, action|
|
||||
this.pr_sendMsg(\addPoint,[label.asString,buffer.asUGenInput],action);
|
||||
this.prSendMsg(\addPoint,[label.asString,buffer.asUGenInput],action);
|
||||
}
|
||||
|
||||
getPoint{|label, buffer, action|
|
||||
this.pr_sendMsg(\getPoint,[label.asString,buffer.asUGenInput],action);
|
||||
this.prSendMsg(\getPoint,[label.asString,buffer.asUGenInput],action);
|
||||
}
|
||||
|
||||
updatePoint{|label, buffer, action|
|
||||
this.pr_sendMsg(\updatePoint,[label.asString,buffer.asUGenInput],action);
|
||||
this.prSendMsg(\updatePoint,[label.asString,buffer.asUGenInput],action);
|
||||
}
|
||||
|
||||
deletePoint{|label, action|
|
||||
this.pr_sendMsg(\deletePoint,[label.asString],action);
|
||||
this.prSendMsg(\deletePoint,[label.asString],action);
|
||||
}
|
||||
|
||||
cols {|action|
|
||||
this.pr_sendMsg(\cols,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
this.prSendMsg(\cols,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
}
|
||||
|
||||
read{|filename,action|
|
||||
this.pr_sendMsg(\read,[filename.asString],action);
|
||||
this.prSendMsg(\read,[filename.asString],action);
|
||||
}
|
||||
|
||||
write{|filename,action|
|
||||
this.pr_sendMsg(\write,[filename.asString],action);
|
||||
this.prSendMsg(\write,[filename.asString],action);
|
||||
}
|
||||
|
||||
size { |action|
|
||||
this.pr_sendMsg(\size,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
this.prSendMsg(\size,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
}
|
||||
|
||||
clear { |action|
|
||||
this.pr_sendMsg(\clear,[],action);
|
||||
this.prSendMsg(\clear,[],action);
|
||||
}
|
||||
|
||||
free { |action|
|
||||
this.pr_sendMsg(\free,[],action);
|
||||
serverCaches.remove(server,id);
|
||||
if(server.serverRunning){this.prSendMsg(\free,[],action)};
|
||||
super.free;
|
||||
}
|
||||
|
||||
*freeAll { |server|
|
||||
serverCaches.tryPerform(\clearCache,server);
|
||||
}
|
||||
}
|
||||
@ -1,27 +1,42 @@
|
||||
FluidKDTree : FluidManipulationClient {
|
||||
|
||||
var id;
|
||||
|
||||
*new {|server|
|
||||
var uid = UniqueID.next;
|
||||
^super.new(server,uid).init(uid);
|
||||
}
|
||||
|
||||
init {|uid|
|
||||
id = uid;
|
||||
}
|
||||
|
||||
fit{|dataset,action|
|
||||
this.pr_sendMsg(\fit,[dataset.asString],action);
|
||||
this.prSendMsg(\fit,[dataset.asUGenInput],action);
|
||||
}
|
||||
|
||||
kNearest{ |buffer, k,action|
|
||||
this.pr_sendMsg(\kNearest,[buffer.asUGenInput,k],action,k.collect{string(FluidMessageResponse,_,_)});
|
||||
this.prSendMsg(\kNearest,[buffer.asUGenInput,k],action,k.collect{string(FluidMessageResponse,_,_)});
|
||||
}
|
||||
|
||||
kNearestDist { |buffer, k,action|
|
||||
this.pr_sendMsg(\kNearestDist,[buffer.asUGenInput,k],action,[numbers(FluidMessageResponse,_,k,_)]);
|
||||
this.prSendMsg(\kNearestDist,[buffer.asUGenInput,k],action,[numbers(FluidMessageResponse,_,k,_)]);
|
||||
}
|
||||
|
||||
cols { |action|
|
||||
this.pr_sendMsg(\cols,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
this.prSendMsg(\cols,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
}
|
||||
|
||||
read{ |filename,action|
|
||||
this.pr_sendMsg(\read,[filename.asString],action);
|
||||
this.prSendMsg(\read,[filename.asString],action);
|
||||
}
|
||||
|
||||
write{ |filename,action|
|
||||
this.pr_sendMsg(\write,[filename.asString],action);
|
||||
this.prSendMsg(\write,[filename.asString],action);
|
||||
}
|
||||
|
||||
free { |action|
|
||||
if(server.serverRunning){this.prSendMsg(\free,[],action)};
|
||||
super.free;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,23 @@
|
||||
FluidKNN : FluidManipulationClient {
|
||||
|
||||
*new {|server|
|
||||
var uid = UniqueID.next;
|
||||
^super.new(server,uid).init(uid);
|
||||
}
|
||||
|
||||
init {|uid|
|
||||
id = uid;
|
||||
}
|
||||
|
||||
fit{|dataset, action|
|
||||
this.pr_sendMsg(\fit,[dataset.asString],action);
|
||||
this.prSendMsg(\fit,[dataset.asString],action);
|
||||
}
|
||||
|
||||
classifyPoint{ |buffer, labelset, k, action|
|
||||
this.pr_sendMsg(\classify,[buffer.asUGenInput, labelset.asString, k],action,[string(FluidMessageResponse,_,_)]);
|
||||
this.prSendMsg(\classify,[buffer.asUGenInput, labelset.asString, k],action,[string(FluidMessageResponse,_,_)]);
|
||||
}
|
||||
|
||||
regressPoint { |buffer,dataset, k, action|
|
||||
this.pr_sendMsg(\regress,[buffer.asUGenInput, dataset.asString,k],action,[number(FluidMessageResponse,_,_)]);
|
||||
this.prSendMsg(\regress,[buffer.asUGenInput, dataset.asString,k],action,[number(FluidMessageResponse,_,_)]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,55 +1,83 @@
|
||||
FluidLabelSetExistsError : Exception{
|
||||
}
|
||||
|
||||
FluidLabelSet : FluidManipulationClient {
|
||||
|
||||
var <> synth, <> server, <>id;
|
||||
var <id;
|
||||
classvar serverCaches;
|
||||
|
||||
*kr{ |name|
|
||||
^this.multiNew('control',name);
|
||||
*initClass {
|
||||
serverCaches = FluidServerCache.new;
|
||||
}
|
||||
|
||||
*at{ |server, id|
|
||||
^serverCaches.tryPerform(\at, server,id)
|
||||
}
|
||||
|
||||
*new { |server,name|
|
||||
^super.new(server,name);
|
||||
serverCaches.at(server,name) !? {
|
||||
FluidLabelSetExistsError("A FluidLabelSet called % already exists.".format(name)).throw;
|
||||
};
|
||||
^super.new(server,*FluidManipulationClient.prServerString(name)).init(name)
|
||||
}
|
||||
|
||||
init { |name|
|
||||
var ascii = name.ascii;
|
||||
this.id = name;
|
||||
inputs = [ascii.size].addAll(ascii)++Done.none++FluidManipulationClient.nonBlocking;
|
||||
this.cache;
|
||||
}
|
||||
|
||||
cache {
|
||||
serverCaches.initCache(server);
|
||||
serverCaches.put(server,id,this);
|
||||
}
|
||||
|
||||
asString {
|
||||
^"FluidLabelSet(%)".format(id).asString;
|
||||
}
|
||||
|
||||
asUGenInput{
|
||||
^id.asString;
|
||||
}
|
||||
|
||||
addLabel{|id, label, action|
|
||||
this.pr_sendMsg(\addLabel,[id.asString, label.asString],action);
|
||||
this.prSendMsg(\addLabel,[id.asString, label.asString],action);
|
||||
}
|
||||
|
||||
getLabel{|id, action|
|
||||
this.pr_sendMsg(\getLabel,[id.asString],action,[string(FluidMessageResponse,_,_)]);
|
||||
this.prSendMsg(\getLabel,[id.asString],action,[string(FluidMessageResponse,_,_)]);
|
||||
}
|
||||
|
||||
deleteLabel{|id, action|
|
||||
this.pr_sendMsg(\deleteLabel,[id.asString],action);
|
||||
this.prSendMsg(\deleteLabel,[id.asString],action);
|
||||
}
|
||||
|
||||
cols {|action|
|
||||
this.pr_sendMsg(\cols,[],action,[number(FluidMessageResponse,_,_)]);
|
||||
this.prSendMsg(\cols,[],action,[number(FluidMessageResponse,_,_)]);
|
||||
}
|
||||
|
||||
read{|filename,action|
|
||||
this.pr_sendMsg(\read,[filename.asString],action);
|
||||
this.prSendMsg(\read,[filename.asString],action);
|
||||
}
|
||||
|
||||
write{|filename,action|
|
||||
this.pr_sendMsg(\write,[filename.asString],action);
|
||||
this.prSendMsg(\write,[filename.asString],action);
|
||||
}
|
||||
|
||||
size { |action|
|
||||
this.pr_sendMsg(\size,[],action,[number(FluidMessageResponse,_,_)]);
|
||||
this.prSendMsg(\size,[],action,[number(FluidMessageResponse,_,_)]);
|
||||
}
|
||||
|
||||
clear { |action|
|
||||
this.pr_sendMsg(\clear,[],action);
|
||||
this.prSendMsg(\clear,[],action);
|
||||
}
|
||||
|
||||
free { |action|
|
||||
serverCaches.remove(server,id);
|
||||
if(server.serverRunning){this.prSendMsg(\free,[],action)};
|
||||
super.free;
|
||||
}
|
||||
|
||||
*freeAll { |server|
|
||||
serverCaches.tryPerform(\clearCache,server);
|
||||
}
|
||||
}
|
||||
@ -1,35 +1,36 @@
|
||||
FluidNormalize : FluidManipulationClient {
|
||||
|
||||
*kr{ |min = 0, max = 1|
|
||||
^this.multiNew('control',min, max, Done.none, super.nonBlocking);
|
||||
*new {|server|
|
||||
var uid = UniqueID.next;
|
||||
^super.new(server,uid).init(uid);
|
||||
}
|
||||
|
||||
*new { |server,min = 0 ,max = 1|
|
||||
^super.new(server,min,max);
|
||||
init {|uid|
|
||||
id = uid;
|
||||
}
|
||||
|
||||
fit{|dataset, action|
|
||||
this.pr_sendMsg(\fit,[dataset.asString],action);
|
||||
this.prSendMsg(\fit,[dataset.asString],action);
|
||||
}
|
||||
|
||||
normalize{|sourceDataset, destDataset, action|
|
||||
this.pr_sendMsg(\normalize,[sourceDataset.asString, destDataset.asString],action);
|
||||
this.prSendMsg(\normalize,[sourceDataset.asString, destDataset.asString],action);
|
||||
}
|
||||
|
||||
normalizePoint{|sourceBuffer, destBuffer, action|
|
||||
this.pr_sendMsg(\normalizePoint,[sourceBuffer.asUGenInput, destBuffer.asUGenInput],action);
|
||||
this.prSendMsg(\normalizePoint,[sourceBuffer.asUGenInput, destBuffer.asUGenInput],action);
|
||||
}
|
||||
|
||||
cols {|action|
|
||||
this.pr_sendMsg(\cols,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
this.prSendMsg(\cols,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
}
|
||||
|
||||
read{|filename,action|
|
||||
this.pr_sendMsg(\read,[filename.asString],action);
|
||||
this.prSendMsg(\read,[filename.asString],action);
|
||||
}
|
||||
|
||||
write{|filename,action|
|
||||
this.pr_sendMsg(\write,[filename.asString],action);
|
||||
this.prSendMsg(\write,[filename.asString],action);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,36 +1,46 @@
|
||||
FluidPCA : FluidManipulationClient {
|
||||
|
||||
|
||||
*new {|server|
|
||||
var uid = UniqueID.next;
|
||||
^super.new(server,uid).init(uid);
|
||||
}
|
||||
|
||||
init {|uid|
|
||||
id = uid;
|
||||
}
|
||||
|
||||
fit{|dataset, k, action|
|
||||
this.pr_sendMsg(\fit,[dataset.asString, k],action);
|
||||
this.prSendMsg(\fit,[dataset.asString, k],action);
|
||||
}
|
||||
|
||||
transform{|sourceDataset, destDataset, action|
|
||||
this.pr_sendMsg(\transform,[sourceDataset.asString, destDataset.asString],action);
|
||||
this.prSendMsg(\transform,[sourceDataset.asString, destDataset.asString],action);
|
||||
}
|
||||
|
||||
fitTransform{|sourceDataset, k, destDataset, action|
|
||||
this.pr_sendMsg(\fitTransform,[sourceDataset.asString,k, destDataset.asString],action);
|
||||
this.prSendMsg(\fitTransform,[sourceDataset.asString,k, destDataset.asString],action);
|
||||
}
|
||||
|
||||
|
||||
transformPoint{|sourceBuffer, destBuffer, action|
|
||||
this.pr_sendMsg(\transformPoint,[sourceBuffer.asUGenInput, destBuffer.asUGenInput],action);
|
||||
this.prSendMsg(\transformPoint,[sourceBuffer.asUGenInput, destBuffer.asUGenInput],action);
|
||||
}
|
||||
|
||||
cols {|action|
|
||||
this.pr_sendMsg(\cols,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
this.prSendMsg(\cols,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
}
|
||||
|
||||
rows {|action|
|
||||
this.pr_sendMsg(\rows,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
this.prSendMsg(\rows,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
}
|
||||
|
||||
read{|filename,action|
|
||||
this.pr_sendMsg(\read,[filename],action);
|
||||
this.prSendMsg(\read,[filename],action);
|
||||
}
|
||||
|
||||
write{|filename,action|
|
||||
this.pr_sendMsg(\write,[filename],action);
|
||||
this.prSendMsg(\write,[filename],action);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,27 +1,36 @@
|
||||
FluidStandardize : FluidManipulationClient {
|
||||
|
||||
*new {|server|
|
||||
var uid = UniqueID.next;
|
||||
^super.new(server,uid).init(uid);
|
||||
}
|
||||
|
||||
init {|uid|
|
||||
id = uid;
|
||||
}
|
||||
|
||||
fit{|dataset, action|
|
||||
this.pr_sendMsg(\fit,[dataset.asString],action);
|
||||
this.prSendMsg(\fit,[dataset.asString],action);
|
||||
}
|
||||
|
||||
standardize{|sourceDataset, destDataset, action|
|
||||
this.pr_sendMsg(\standardize,[sourceDataset.asString, destDataset.asString],action);
|
||||
this.prSendMsg(\standardize,[sourceDataset.asString, destDataset.asString],action);
|
||||
}
|
||||
|
||||
standardizePoint{|sourceBuffer, destBuffer, action|
|
||||
this.pr_sendMsg(\standardizePoint,[sourceBuffer.asUGenInput, destBuffer.asUGenInput],action);
|
||||
this.prSendMsg(\standardizePoint,[sourceBuffer.asUGenInput, destBuffer.asUGenInput],action);
|
||||
}
|
||||
|
||||
cols {|action|
|
||||
this.pr_sendMsg(\cols,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
this.prSendMsg(\cols,[],action,[numbers(FluidMessageResponse,_,1,_)]);
|
||||
}
|
||||
|
||||
read{|filename,action|
|
||||
this.pr_sendMsg(\read,[filename.asString],action);
|
||||
this.prSendMsg(\read,[filename.asString],action);
|
||||
}
|
||||
|
||||
write{|filename,action|
|
||||
this.pr_sendMsg(\write,[filename.asString],action);
|
||||
this.prSendMsg(\write,[filename.asString],action);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
|
||||
TestFluidCorpusManipulationServer : UnitTest
|
||||
{
|
||||
var waitForCounts, countsListener;
|
||||
|
||||
setUp{
|
||||
waitForCounts = Condition.new(false);
|
||||
countsListener = { |s,changed|
|
||||
if(changed == \counts) {
|
||||
waitForCounts.test = true;
|
||||
waitForCounts.signal;
|
||||
}
|
||||
};
|
||||
Server.default.addDependant(countsListener);
|
||||
}
|
||||
|
||||
tearDown{
|
||||
Server.default.removeDependant(countsListener);
|
||||
Server.default.quit;
|
||||
}
|
||||
|
||||
test_DataSetPersistence{
|
||||
var foo, bar, tree, testPoint;
|
||||
|
||||
foo = FluidDataSet(Server.default,\foo);
|
||||
|
||||
this.bootServer(Server.default);
|
||||
while {Server.default.serverRunning.not}{0.2.wait};
|
||||
waitForCounts.test = false;
|
||||
waitForCounts.wait;
|
||||
|
||||
this.assertEquals(Server.default.numSynths,1,"Dataset: One Synth present after deferred boot");
|
||||
|
||||
waitForCounts.test = false;
|
||||
foo.free;
|
||||
Server.default.freeAll;
|
||||
waitForCounts.wait;
|
||||
|
||||
this.assertEquals(Server.default.numSynths,0,"Dataset: One Synth present via cretation after boot");
|
||||
|
||||
//Uniqueness test (difficult to run with previous instance of foo, because
|
||||
//UnitTest.bootServer messes with Server alloctors and screws up the ID cache
|
||||
foo = FluidDataSet(Server.default,\foo);
|
||||
this.assertException({
|
||||
bar = FluidDataSet(Server.default,\foo);
|
||||
},FluidDataSetExistsError,"DataSetDuplicateError on reused name", onFailure:{
|
||||
"Exception fail".postln;
|
||||
});
|
||||
|
||||
waitForCounts.test = false;
|
||||
bar = FluidDataSet(Server.default,\bar);
|
||||
waitForCounts.wait;
|
||||
|
||||
this.assertEquals(Server.default.numSynths,2,"Dataset: Two Synths present after new Dataset added");
|
||||
|
||||
testPoint = Buffer.alloc(Server.default,8);
|
||||
Server.default.sync;
|
||||
testPoint.setn(0,[1,2,3,4,5,6,7,8]);
|
||||
Server.default.sync;
|
||||
foo.addPoint(\one,testPoint);
|
||||
Server.default.sync;
|
||||
foo.size({|size|
|
||||
this.assertEquals(size,1,"Dataset size is 1");
|
||||
});
|
||||
Server.default.sync;
|
||||
foo.cols({|cols|
|
||||
this.assertEquals(cols,8,"Dataset cols is 8");
|
||||
});
|
||||
|
||||
Server.default.sync;
|
||||
waitForCounts.test = false;
|
||||
|
||||
tree = FluidKDTree(Server.default);
|
||||
waitForCounts.wait;
|
||||
|
||||
this.assert(tree.synth.notNil,"Tree should have a valid synth");
|
||||
this.assertEquals(Server.default.numSynths,3,"Dataset: Three Synths remain after cmd-.");
|
||||
|
||||
tree.fit(foo);
|
||||
Server.default.sync;
|
||||
tree.cols({|cols|
|
||||
this.assertEquals(cols,8,"KDTree correct dims after fit")
|
||||
});
|
||||
Server.default.sync;
|
||||
|
||||
//Test cmd-period resistance
|
||||
waitForCounts.test = false;
|
||||
Server.default.freeAll;
|
||||
Server.default.sync;
|
||||
Server.default.sync;
|
||||
waitForCounts.wait;
|
||||
|
||||
this.assertEquals(Server.default.numSynths,3,"Dataset: Three Synths remain after cmd-.");
|
||||
foo.size({|size|
|
||||
this.assertEquals(size,1,"Dataset size is still 1 after Cmd-.");
|
||||
});
|
||||
Server.default.sync;
|
||||
foo.cols({|cols|
|
||||
this.assertEquals(cols,8,"Dataset cols is still 8 after Cmd-.");
|
||||
});
|
||||
Server.default.sync;
|
||||
tree.cols({|cols| this.assertEquals(cols,8,"KDTree correct dims after Cmd-.")});
|
||||
Server.default.sync;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue