Files
spark/src/DataStreamSuite/DataStream/Primitives/Derivative/DerivativeStream.cs
T

100 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BCG
{
public class DerivativeStream : ViewStream
{
private IBlueTableSchema mySchema;
private string myDerivandColumn;
private string myOutputColumn;
private string myKeyColumn;
private DateTime myLastPacketArrival = DateTime.MinValue;
private ViewStream myDataSource;
private IDictionary<string, double> myPreviousValues;
public DerivativeStream(ViewStream input, string keyColumn, string columnToDifferentiate, string outputColName)
{
myDerivandColumn = columnToDifferentiate;
myOutputColumn = outputColName;
myKeyColumn = keyColumn;
myDataSource = input;
}
protected override void myOnFirstSubscriber()
{
myDataSource.onChange += myDataSource_onChange;
}
protected override void myOnLastSubscriber()
{
myDataSource.onChange -= myDataSource_onChange;
}
void myDataSource_onChange(object newValue)
{
DataPacket dp = (DataPacket)newValue;
if (myLastPacketArrival == DateTime.MinValue)
mySchema = myBuildOutputSchema(dp.schema);
else
{
DateTime now = DateTime.Now;
BlueTable thisVersion = new BlueTable(mySchema);
double timeScale = 1.0 / (now - myLastPacketArrival).TotalSeconds;
foreach (IBlueRow r in dp.newRows)
thisVersion.addRow(myMakeRow(r, timeScale));
if (myLastValue == null)
myFireEvent(new DataPacket(thisVersion, new BlueTable(mySchema), new BlueTable(mySchema)));
else
{
IBlueRowCollection deleted, added;
BlueDataUtility.computeDifferences(thisVersion, ((DataPacket)myLastValue).newRows, out deleted, out added);
myFireEvent(new DataPacket(thisVersion, added, deleted));
}
}
myStoreNewPacketInfo(dp);
}
protected IBlueRow myMakeRow(IBlueRow r, double timeScale)
{
object[] outValues = new object[mySchema.columnInfo.Length];
r.Values.CopyTo(outValues, 0);
object derivand = r[myDerivandColumn];
double lastValue = default(double);
if (myPreviousValues.TryGetValue(r[myKeyColumn].ToString(), out lastValue) && derivand != null && derivand != DBNull.Value)
outValues[mySchema.columnInfo.Length - 1] = (Convert.ToDouble(derivand) - lastValue) * timeScale;
else
outValues[mySchema.columnInfo.Length - 1] = 0.0;
return new BlueRow(mySchema, outValues);
}
protected IBlueTableSchema myBuildOutputSchema(IBlueTableSchema inSchema)
{
ColumnInfo[] cols = new ColumnInfo[inSchema.columnInfo.Length + 1];
inSchema.columnInfo.CopyTo(cols, 0);
cols[cols.Length - 1] = new ColumnInfo(myOutputColumn, cols.Length - 1, typeof(double));
return new BlueTableSchema("derviative of " + inSchema.tableName, cols);
}
protected void myStoreNewPacketInfo(DataPacket dp)
{
myPreviousValues = new Dictionary<string, double>();
myLastPacketArrival = DateTime.Now;
foreach (IBlueRow row in dp.newRows)
{
object derivand = row[myDerivandColumn];
if (derivand != null && derivand != DBNull.Value)
myPreviousValues[row[myKeyColumn].ToString()] = Convert.ToDouble(derivand);
}
}
}
}