public void Split(List <SampleValue> outSamples, SampleValue inSample, Style style) { if (!Exec.IsExecuting()) { throw new ExecutionEnded(""); } //Gui.Log("Device: SPLIT " + Style.FormatSequence(outSamples, ", ", x => x.FormatSymbol(style)) + " = " + inSample.FormatSymbol(style)); Place[,] area = FreeAreaInColumn(zone["mixing"], minRow: placement.PlaceOf(inSample, style).Row(), rows: 1, cols: 2 * outSamples.Count - 1); // find free columns in "mixing" block, on the same row placement.MoveHorFirst(inSample, area[0, 0], clearance: 1, style); double volume = inSample.Volume(); for (int i = outSamples.Count - 1; i >= 1; i--) { volume = volume - outSamples[i].Volume(); SampleValue tempSample = new SampleValue(inSample.symbol, null, new NumberValue(volume), new NumberValue(1), true); placement.SplitHor(tempSample, outSamples[i], area[0, 0], area[0, 1], style); placement.FollowRoute(placement.PathHorFirst(placement.PlaceOf(outSamples[i], style), area[0, 2 * i]), clearance: 0, style); } placement.Clear(area[0, 0], style, log: false); placement.Place(outSamples[0], area[0, 0], style, log: false); List <Place>[] routes = new List <Place> [outSamples.Count]; for (int i = 0; i < outSamples.Count; i++) { Place place = FreePlaceInColumn(zone["staging"], minRow: 0, currentlyAt: area[0, 2 * i], skipNo: i); routes[i] = placement.PathVerFirst(placement.PlaceOf(outSamples[i], style), place); } placement.FollowRoutes(routes, clearance: 1, style); }
public static SampleValue Mix(Symbol symbol, List <SampleValue> samples, Netlist netlist, Style style) { double sumVolume = 0.0; double sumTemperature = 0.0; bool needLna = false; foreach (SampleValue sample in samples) { sample.Consume(null, 0, null, netlist, style); sumVolume += sample.Volume(); sumTemperature += sample.Volume() * sample.Temperature(); needLna = needLna || sample.stateMap.state.lna; } NumberValue volume = new NumberValue(sumVolume); NumberValue temperature = new NumberValue(sumTemperature / sumVolume); SampleValue result = new SampleValue(symbol, new StateMap(symbol, new List <SpeciesValue> { }, new State(0, lna: needLna)), volume, temperature, produced: true); foreach (SampleValue sample in samples) { result.stateMap.Mix(sample.stateMap, volume.value, sample.Volume(), style); // mix adding the means and covariances, scaled by volume result.AddReports(sample.RelevantReports(style)); } return(result); }
public static Dictionary<int, long> ProcessZeroCrossings( SampleValue[] samples, bool positiveTrigger = false, int offset = 0, int? crossingsCount = null, int averageCount = 4) { AverageValue averageValue = new AverageValue(averageCount); var crossings = new Dictionary<int, long>(); bool crossSet = false; int sampleSize = samples.Length; for (int i = 0; i < sampleSize; i++) { averageValue.Value = samples[i].Value; if (i > averageValue.SampleSize) { var fvalue = averageValue.Value; var averageIndex = i - averageValue.SampleSize / 2; samples[averageIndex].Value = (int)fvalue; if (crossingsCount.HasValue && crossings.Count < crossingsCount.Value) { if (!crossSet && ((!positiveTrigger && (fvalue > offset)) || (positiveTrigger && (fvalue < offset)))) { crossSet = true; } if (crossSet && ((!positiveTrigger && (fvalue < offset)) || (positiveTrigger && (fvalue > offset)))) { crossings.Add(averageIndex, samples[i].Tick); crossSet = false; } } } } return crossings; }
public static void Amount(SampleValue sample, AmountEntry amountEntry, Style style) { if (device == null || (!style.chartOutput) || Exec.IsVesselVariant(sample)) { return; } }
public static VariableItem Create(string name, SampleValue <bool> value) { return(new VariableItem() { Name = name, Value = value.Value ? "On" : "Off", Date = value.Time.ToString() }); }
public static VariableItem Create(string name, SampleValue <double> value) { return(new VariableItem() { Name = name, Value = value.Value.ToString(), Date = value.Time.ToString() }); }
public void StepPhase(int phase, Direction direction, Place from, Place to, Style style) { if (phase == 0) { from.SetAnimation(phase0[(int)direction]); } else if (phase == 1) { from.SetAnimation(phase1[(int)direction]); } else if (phase == 2) { SampleValue sample = Extract(from, style, log: false); Place(sample, to, style, log: false); to.SetAnimation(phase2[(int)direction]); } else if (phase == 3) { to.SetAnimation(phase3[(int)direction]); } else { throw new Error("ERROR: StepPhase"); } }
public ReportEntry(Symbol timecourse, Flow flow, string asLabel, SampleValue sample) { this.timecourse = timecourse; this.flow = flow; this.asLabel = asLabel; this.sample = sample; }
public void Mix(SampleValue outSample, List <SampleValue> inSamples, Style style) { if (!Exec.IsExecuting()) { throw new ExecutionEnded(""); } //Gui.Log("Device: MIX " + outSample.FormatSymbol(style) + " = " + Style.FormatSequence(inSamples, ", ", x => x.FormatSymbol(style))); Place[,] area = FreeAreaInColumn(zone["mixing"], minRow: placement.PlaceOf(inSamples[0], style).Row(), rows: 1, cols: 2 * inSamples.Count - 1); // find free columns in "mixing" block, on the same row List <Place>[] routes = new List <Place> [inSamples.Count]; for (int i = 0; i < inSamples.Count; i++) { routes[i] = placement.PathHorFirst(placement.PlaceOf(inSamples[i], style), area[0, 2 * i]); } placement.FollowRoutes(routes, clearance: 1, style); for (int i = 1; i < inSamples.Count; i++) { placement.FollowRoute(placement.PathHorFirst(placement.PlaceOf(inSamples[i], style), area[0, 1]), clearance: 0, style); SampleValue accumulator = placement.SampleOf(area[0, 0]); SampleValue tempSample = new SampleValue(outSample.symbol, null, new NumberValue(accumulator.Volume() + inSamples[i].Volume()), new NumberValue(1), true); placement.MixHor(tempSample, area[0, 0], area[0, 1], style); } placement.Clear(area[0, 0], style, log: false); placement.Place(outSample, area[0, 0], style, log: false); Place staging = FreePlaceInColumn(zone["staging"], minRow: 0, currentlyAt: area[0, 0], skipNo: 0); placement.MoveVerFirst(outSample, staging, clearance: 1, style); }
public void CheckIsPlaced(SampleValue sample, Style style) { if (!IsPlaced(sample)) { throw new Error("Sample not found on device: '" + sample.FormatSymbol(style) + "'" + (sample.IsConsumed() ? " (sample is already consumed)" : "")); } }
public static void Sample(SampleValue sample, Style style) { if (device == null || (!style.chartOutput) || Exec.IsVesselVariant(sample)) { return; } device.Sample(sample, style); }
public AmountEntry(SpeciesValue species, NumberValue initial, NumberValue initialVariance, string dimension, SampleValue sample) { this.species = species; this.initial = initial; this.initialVariance = initialVariance; this.dimension = dimension; this.sample = sample; }
public static void NormalizeToAverage(SampleValue[] samples, int average) { int sampleSize = samples.Length; for (int i = 1; i < sampleSize; i++) { samples[i].Value = samples[i].Value - average; } }
public bool IsAt(SampleValue sample, Place place) { if ((!IsOccupied(place)) || (!IsPlaced(sample))) { return(false); } return(placeToSample[place] == sample); }
public TriggerEntry(SpeciesValue target, Flow condition, Flow assignment, Flow assignmentVariance, string dimension, SampleValue sample) { this.target = target; this.condition = condition; this.assignment = assignment; this.assignmentVariance = assignmentVariance; this.dimension = dimension; this.sample = sample; }
public SampleValue Clear(Place place, Style style, bool log = true) { CheckIsOccupied(place); //if (log) Gui.Log("Device: Clear " + place.Format(style)); SampleValue sample = SampleOf(place); Remove(sample, style, log); return(sample); }
public static SampleValue MassCompileSample(Symbol outSymbol, SampleValue inSample, Netlist netlist, Style style) { //inSample.Consume(null, 0, null, netlist, style); // this prevents simulating a sample and its massaction version in succession List <ReactionValue> inReactions = inSample.RelevantReactions(netlist, style); CRN inCrn = new CRN(inSample, inReactions); Gui.Log(Environment.NewLine + inCrn.FormatNice(style)); (Lst <Polynomize.ODE> odes, Lst <Polynomize.Equation> eqs) = Polynomize.FromCRN(inCrn); (Lst <Polynomize.PolyODE> polyOdes, Lst <Polynomize.Equation> polyEqs) = Polynomize.PolynomizeODEs(odes, eqs.Reverse(), style); Gui.Log("Polynomize:" + Environment.NewLine + Polynomize.PolyODE.Format(polyOdes, style) + "Initial:" + Environment.NewLine + Polynomize.Equation.Format(polyEqs, style)); (Lst <Polynomize.PolyODE> posOdes, Lst <Polynomize.Equation> posEqs, Dictionary <Symbol, SpeciesFlow> dict, Lst <Positivize.Subst> substs) = Positivize.PositivizeODEs(polyOdes, polyEqs, style); Gui.Log("Positivize:" + Environment.NewLine + Polynomize.PolyODE.Format(posOdes, style) + "Initial:" + Environment.NewLine + Polynomize.Equation.Format(posEqs, style)); Lst <ReactionValue> outReactions = Hungarize.ToReactions(posOdes, style); Gui.Log("Hungarize:" + Environment.NewLine + outReactions.FoldR((r, s) => { return(r.FormatNormal(style) + Environment.NewLine + s); }, "") + "Initial:" + Environment.NewLine + Polynomize.Equation.Format(posEqs, style)); SampleValue outSample = new SampleValue(outSymbol, new StateMap(outSymbol, new List <SpeciesValue> { }, new State(0, lna: inSample.stateMap.state.lna)), new NumberValue(inSample.Volume()), new NumberValue(inSample.Temperature()), produced: true); netlist.Emit(new SampleEntry(outSample)); posOdes.Each(ode => { Flow initFlow = Polynomize.Equation.ToFlow(ode.var, posEqs, style).Normalize(style); double init; if (initFlow is NumberFlow num) { init = num.value; } else { throw new Error("Cannot generate a simulatable sample because initial values contain constants (but the symbolic version has been generated assuming constants are nonnegative)."); } if (init < 0) { throw new Error("Negative initial value of Polynomized ODE for: " + Polynomize.Lookup(ode.var, eqs, style).Format(style) + " = " + init + Environment.NewLine + Polynomize.Equation.Format(eqs, style)); } outSample.stateMap.AddDimensionedSpecies(new SpeciesValue(ode.var.species, -1.0), init, 0.0, "M", outSample.Volume(), style); }); outReactions.Each(reaction => { netlist.Emit(new ReactionEntry(reaction)); }); substs.Each(subst => { ReportEntry report = new ReportEntry(null, OpFlow.Op(subst.plus, "-", subst.minus), null, outSample); outSample.AddReport(report); }); foreach (KeyValuePair <Symbol, SpeciesFlow> keypair in dict) { ReportEntry report = new ReportEntry(null, keypair.Value, null, outSample); outSample.AddReport(report); } ; return(outSample); }
public void Contains_ValueIsReferenceType_ChecksForReferenceEquality() { ICache<string, SampleValue> cache = new Cache<string, SampleValue>(_timerInterval); SampleValue value = new SampleValue(); ICacheItem<SampleValue> cacheItem = new NonExpiringCacheItem<SampleValue>(value); KeyValuePair<string, SampleValue> keyValuePair = new KeyValuePair<string, SampleValue>(_key, value); cache.Add(_key, cacheItem); bool result = cache.Contains(keyValuePair); Assert.True(result); }
// disappear public void Appear(SampleValue sample, Place place, Style style) { Place(sample, place, style); place.SetAnimation(Animation.SizeQuarter); KGui.gui.GuiDeviceUpdate(); Thread.Sleep(device.stepDelay); place.SetAnimation(Animation.SizeHalf); KGui.gui.GuiDeviceUpdate(); Thread.Sleep(device.phaseDelay); place.SetAnimation(Animation.None); KGui.gui.GuiDeviceUpdate(); Thread.Sleep(device.stepDelay); }
public void Contains_ValueIsReferenceType_ChecksForReferenceEquality() { ICache <string, SampleValue> cache = new Cache <string, SampleValue>(_timerInterval); SampleValue value = new SampleValue(); ICacheItem <SampleValue> cacheItem = new NonExpiringCacheItem <SampleValue>(value); KeyValuePair <string, SampleValue> keyValuePair = new KeyValuePair <string, SampleValue>(_key, value); cache.Add(_key, cacheItem); bool result = cache.Contains(keyValuePair); Assert.True(result); }
// === DEVICE PROTOCOL OPERATIONS === // public void Sample(SampleValue sample, Style style) { if (!Exec.IsExecuting()) { throw new ExecutionEnded(""); } //Gui.Log("Device: NEW DROPLET " + sample.FormatSymbol(style)); Place source = ReservePlaceInColumn(zone["staging"]); placement.Appear(sample, source, style); //placement.Place(sample, source, style); //KGui.gui.GuiDeviceUpdate(); }
// mix Top and Bot into Top public void MixVer(SampleValue sample, Place placeTop, Place placeBot, Style style) { placeTop.SetAnimation(Animation.PullBot); placeBot.SetAnimation(Animation.PullTop); KGui.gui.GuiDeviceUpdate(); Thread.Sleep(device.phaseDelay); Clear(placeTop, style); Clear(placeBot, style); placeTop.SetAnimation(Animation.None); placeBot.SetAnimation(Animation.None); Place(sample, placeTop, style); KGui.gui.GuiDeviceUpdate(); Thread.Sleep(device.stepDelay); }
// mix Lft and Rht into Lft public void MixHor(SampleValue sample, Place placeLft, Place placeRht, Style style) { placeLft.SetAnimation(Animation.PullRht); placeRht.SetAnimation(Animation.PullLft); KGui.gui.GuiDeviceUpdate(); Thread.Sleep(device.phaseDelay); Clear(placeLft, style); Clear(placeRht, style); placeLft.SetAnimation(Animation.None); placeRht.SetAnimation(Animation.None); Place(sample, placeLft, style); KGui.gui.GuiDeviceUpdate(); Thread.Sleep(device.stepDelay); }
public ExecutionInstance(SampleValue vessel, Netlist netlist, Style style, DateTime startTime, DateTime evalTime) { this.Id = id; id++; this.vessel = vessel; this.environment = new NullEnv(); this.netlist = netlist; this.style = style; this.lastCRN = null; this.startTime = startTime; this.evalTime = evalTime; this.endTime = DateTime.MinValue; this.graphCache = new Dictionary <string, AdjacencyGraph <Vertex, Edge <Vertex> > >(); this.layoutCache = new Dictionary <string, object>(); this.rejected = 0; }
public static void Split(List <SampleValue> outSamples, SampleValue inSample, Style style) { if (device == null || (!style.chartOutput) || Exec.IsVesselVariant(inSample)) { return; } foreach (SampleValue outSample in outSamples) { if (Exec.IsVesselVariant(outSample)) { return; } } device.Split(outSamples, inSample, style); }
// split Lft into Lft and Rht public void SplitHor(SampleValue splitLft, SampleValue splitRht, Place placeLft, Place placeRht, Style style) { placeLft.SetAnimation(Animation.PullRht); KGui.gui.GuiDeviceUpdate(); Thread.Sleep(device.phaseDelay); placeLft.SetAnimation(Animation.SplitRht); KGui.gui.GuiDeviceUpdate(); Thread.Sleep(device.stepDelay); Clear(placeLft, style, log: false); placeLft.SetAnimation(Animation.None); Place(splitLft, placeLft, style); placeRht.SetAnimation(Animation.None); Place(splitRht, placeRht, style); KGui.gui.GuiDeviceUpdate(); Thread.Sleep(device.stepDelay); }
public Place Remove(SampleValue sample, Style style, bool log = true) { lock (KDeviceHandler.device) { if (!Exec.IsExecuting()) { throw new ExecutionEnded(""); } CheckIsPlaced(sample, style); Place place = sampleToPlace[sample]; //if (log) Gui.Log("Device: Remove " + sample.FormatSymbol(style) + " from " + place.Format(style)); sampleToPlace.Remove(sample); placeToSample.Remove(place); sampleToStyle.Remove(sample); return(place); } }
public SampleValue Extract(Place place, Style style, bool log = true) { lock (KDeviceHandler.device) { if (!Exec.IsExecuting()) { throw new ExecutionEnded(""); } CheckIsOccupied(place); SampleValue sample = placeToSample[place]; //if (log) Gui.Log("Device: Extract " + sample.FormatSymbol(style) + " from " + place.Format(style)); sampleToPlace.Remove(sample); placeToSample.Remove(place); sampleToStyle.Remove(sample); return(sample); } }
public static List <SampleValue> Concentrate(List <Symbol> symbols, double volume, List <SampleValue> inSamples, Netlist netlist, Style style) { List <SampleValue> outSamples = new List <SampleValue> { }; for (int i = 0; i < symbols.Count; i++) { inSamples[i].Consume(null, 0, null, netlist, style); double temperature = inSamples[i].Temperature(); SampleValue outSample = new SampleValue(symbols[i], new StateMap(symbols[i], new List <SpeciesValue> { }, new State(0, lna: inSamples[i].stateMap.state.lna)), new NumberValue(volume), new NumberValue(temperature), produced: true); outSample.stateMap.Mix(inSamples[i].stateMap, volume, inSamples[i].Volume(), style); // same as Mix, but in this case we can also have volume < inSamples[i].Volume() outSample.AddReports(inSamples[i].RelevantReports(style)); outSamples.Add(outSample); } return(outSamples); }
public static List <SampleValue> Split(List <Symbol> symbols, SampleValue sample, List <NumberValue> proportions, Netlist netlist, Style style) { sample.Consume(null, 0, null, netlist, style); List <SampleValue> result = new List <SampleValue> { }; for (int i = 0; i < symbols.Count; i++) { NumberValue iVolume = new NumberValue(sample.Volume() * proportions[i].value); NumberValue iTemperature = new NumberValue(sample.Temperature()); SampleValue iResult = new SampleValue(symbols[i], new StateMap(symbols[i], new List <SpeciesValue> { }, new State(0, lna: sample.stateMap.state.lna)), iVolume, iTemperature, produced: true); iResult.stateMap.Split(sample.stateMap, style); iResult.AddReports(sample.RelevantReports(style)); result.Add(iResult); } return(result); }
public static void ProcessStats(SampleValue[] samples, ref int average, ref int min, ref int max) { average = 0; int sampleSize = samples.Length; for (int i = 0; i < sampleSize - 1; i++) { if (samples[i].Value < min) { min = samples[i].Value; } if (samples[i].Value > max) { max = samples[i].Value; } average += samples[i].Value; } average = average / sampleSize; }
public void Place(SampleValue sample, Place place, Style style, bool log = true) { lock (KDeviceHandler.device) { if (!Exec.IsExecuting()) { throw new ExecutionEnded(""); } if (IsPlaced(sample)) { throw new Error("ERROR Device.Placement.Place"); } if (IsOccupied(place)) { throw new Error("ERROR Device.Placement.Place"); } //if (log) Gui.Log("Device: Place " + sample.FormatSymbol(style) + " into " + place.Format(style)); sampleToPlace[sample] = place; placeToSample[place] = sample; sampleToStyle[sample] = style; } }
private bool trivial; // try to identify trivial stoichiometry (no change to any species), but not guaranteed public CRN(SampleValue sample, List <ReactionValue> reactions, bool precomputeLNA = false) { this.sample = sample; this.temperature = sample.Temperature(); this.reactions = reactions; this.trivial = true; List <SpeciesValue> species = sample.stateMap.species; this.stoichio = new Matrix(new double[species.Count, this.reactions.Count]); for (int s = 0; s < species.Count; s++) { for (int r = 0; r < reactions.Count; r++) { stoichio[s, r] = reactions[r].NetStoichiometry(species[s].symbol); if (stoichio[s, r] != 0) { this.trivial = false; } } } this.driftFactor = null; if (precomputeLNA) { driftFactor = new double[species.Count, species.Count, reactions.Count]; for (int i = 0; i < species.Count; i++) { for (int j = 0; j < species.Count; j++) { for (int r = 0; r < reactions.Count; r++) { driftFactor[i, j, r] = stoichio[i, r] * stoichio[j, r]; } } } if (Exec.lastExecution != null) { KGui.gui.GuiOutputAppendText(Exec.lastExecution.PartialElapsedTime("After precomputeLNA")); } } }
private byte[] DecodeBlock(int n) { if (n >= DataSize / BlockAlign) return null; if (CacheNo == n) return Cache; int pos = DataPosition + n * BlockAlign; if (pos >= fs.Length) return null; fs.Position = pos; var data = ReadBytes(BlockAlign); var ms = new MemoryStream(); var bw = new BinaryWriter(ms); var v = new SampleValue[Channels]; for (int ch = 0; ch < Channels; ch++) { v[ch] = new SampleValue(data, ch * 4); bw.Write(v[ch].Value); } int ch4 = Channels * 4; for (int i = ch4; i < BlockAlign; i += ch4) { for (int j = 0; j < 4; j++) { for (int ch = 0; ch < Channels; ch++) bw.Write(v[ch].Next(data[i + j + ch * 4] & 0xf)); for (int ch = 0; ch < Channels; ch++) bw.Write(v[ch].Next(data[i + j + ch * 4] >> 4)); } } CacheNo = n; Cache = ms.ToArray(); bw.Close(); ms.Close(); return Cache; }
private byte[] DecodeBlock(Stream s, int src) { if (src >= _dataSize / _blockAlign) return null; if (_cacheNo == src) return _cache; int pos = _offset + (src * _blockAlign); //4 = compression ratio if (pos >= s.Length) return null; s.Position = pos; byte[] data = ReadBytes(s, _blockAlign); using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) { SampleValue[] v = new SampleValue[_outChannels]; for (int ch = 0; ch < _outChannels; ch++) { v[ch] = new SampleValue(data, ch * 4); //bw.Write(v[ch].PredictedValue); } int ch4 = _outChannels * 4; if (_outChannels == 1) //mono { for (int i = ch4; i < _blockAlign; i++) { bw.Write(v[0].DecodeNext(data[i] & 0xf)); bw.Write(v[0].DecodeNext(data[i] >> 4)); } } else { for (int i = ch4; i < _blockAlign; i += ch4) { for (int j = 0; j < 4; j++) { for (int ch = 0; ch < _outChannels; ch++) bw.Write(v[ch].DecodeNext(data[i + j + ch * 4] & 0xf)); for (int ch = 0; ch < _outChannels; ch++) bw.Write(v[ch].DecodeNext(data[i + j + ch * 4] >> 4)); } } } _cacheNo = src; _cache = ms.ToArray(); } } return _cache; }
private byte[] EncodeBlock(Stream s) { if (s.Position >= s.Length) return null; byte[] outBuff = new byte[_imaBlockAlign]; int imaBlockAlign = _imaBlockAlign; if (_inChannels > _outChannels) //convert to mono imaBlockAlign *= 2; int ch4 = _inChannels * 4; byte[] inBuff = new byte[(imaBlockAlign - ch4) * 4]; //*4 for compression ratio if (s.Read(inBuff, 0, inBuff.Length) < inBuff.Length) return null; //work like xbadpcm and copy end using (MemoryStream ms = new MemoryStream(inBuff)) { using (BinaryReader br = new BinaryReader(ms)) { if (_inChannels > _outChannels) //convert to mono { ch4 = _outChannels * 4; MemoryStream mso = new MemoryStream(inBuff); BinaryWriter bw = new BinaryWriter(mso); for (int i = 0; i < inBuff.Length / 4; i++) bw.Write((short)(((int)br.ReadInt16() + (int)br.ReadInt16()) / 2)); mso.Close(); bw.Close(); br.BaseStream.Position = 0; } SampleValue[] v = new SampleValue[_outChannels]; for (int ch = 0; ch < _outChannels; ch++) { //write last stored. This is a guess BitConverter.GetBytes(_predictedValues[ch]).CopyTo(outBuff, (ch << 2)); outBuff[(ch << 2) + 2] = (byte)_stepIndexes[ch]; v[ch] = new SampleValue(_predictedValues[ch], _stepIndexes[ch]); } if (_outChannels == 1) //mono { for (int i = ch4; i < _imaBlockAlign; i++) outBuff[i] = (byte)((v[0].EncodeNext(br.ReadInt16()) & 0xf) | (v[0].EncodeNext(br.ReadInt16()) << 0x4)); } else { int opt; for (int i = ch4; i < _imaBlockAlign; i += ch4) { for (int j = 0; j < 4; j++) { opt = i + j; for (int ch = 0; ch < _outChannels; ch++) outBuff[opt + (ch << 2)] = (byte)(v[ch].EncodeNext(br.ReadInt16()) & 0xf); for (int ch = 0; ch < _outChannels; ch++) outBuff[opt + (ch << 2)] |= (byte)(v[ch].EncodeNext(br.ReadInt16()) << 0x4); } } } //Store last values, Who knows if this is correct? for (int ch = 0; ch < _outChannels; ch++) { _predictedValues[ch] = v[ch].PredictedValue; _stepIndexes[ch] = v[ch].StepIndex; } } } return outBuff; }
public /*interface DevicePainter*/ void Draw(KDeviceHandler.KDevice device, int canvasX, int canvasY, int canvasWidth, int canvasHeight) { (float margin, float padRadius, float deviceWidth, float deviceHeight) = device.FittedDimensions(canvasWidth, canvasHeight); float strokeWidth = padRadius / 10.0f; float accentStrokeWidth = 1.5f * strokeWidth; float textStrokeWidth = accentStrokeWidth / 2.0f; float deviceX = canvasX + (canvasWidth - deviceWidth) / 2.0f; float deviceY = canvasY + (canvasHeight - deviceHeight) / 2.0f; // don't lock device here, it will dedlock if (device.sizeChanged || cachedBackground == null || cachedBackground.Width != canvasWidth || cachedBackground.Height != canvasHeight) { cachedBackground = new SKBitmap(canvasWidth, canvasHeight); using (var backgroundCanvas = new SKCanvas(cachedBackground)) { DrawDevice(device, backgroundCanvas, canvasX, canvasY, canvasWidth, canvasHeight, deviceX, deviceY, deviceWidth, deviceHeight, padRadius, margin, device.pinchPan); } device.sizeChanged = false; } if (!device.sizeChanged) { canvas.DrawBitmap(cachedBackground, 0, 0); // do not apply pinchPan: background bitmap is alread scaled by it } if (device.displayPinchOrigin) { // same as: GraphSharp.GraphLayout.CanvasDrawCircle(canvas, pinchOrigin, 20, false, SKColors.LightGray); using (var paint = FillPaint(SKColors.LightGray)) { DrawCircle(device.pinchOrigin, 20, paint); } //using (var paint = new SKPaint()) { // paint.TextSize = 10; paint.IsAntialias = true; paint.Color = SKColors.LightGray; paint.IsStroke = false; // canvas.DrawCircle(device.pinchOrigin.X, device.pinchOrigin.Y, 20, paint); //} } using (var dropletFillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = device.dropletColor, IsAntialias = true }) using (var dropletBiggieFillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = device.dropletBiggieColor, IsAntialias = true }) { KDeviceHandler.Place[,] places = device.places; KDeviceHandler.Placement placement = device.placement; for (int row = 0; row < places.GetLength(0); row++) { for (int col = 0; col < places.GetLength(1); col++) { KDeviceHandler.Place place = places[row, col]; if (place != null && placement.IsOccupied(place)) { SampleValue sample = placement.SampleOf(place); float volumeRadius = padRadius * (float)Math.Sqrt((sample.Volume()) * 1000000.0); // normal radius = 1μL float diameter = 2 * padRadius; SKPaint fillPaint = dropletFillPaint; bool biggie = false; if (volumeRadius > 2 * padRadius) { biggie = true; volumeRadius = 2 * padRadius; fillPaint = dropletBiggieFillPaint; } SKPoint here = new SKPoint(deviceX + margin + padRadius + col * diameter, deviceY + margin + padRadius + row * diameter); SKPoint rht = new SKPoint(deviceX + margin + padRadius + (col + 1) * diameter, deviceY + margin + padRadius + row * diameter); SKPoint lft = new SKPoint(deviceX + margin + padRadius + (col - 1) * diameter, deviceY + margin + padRadius + row * diameter); SKPoint bot = new SKPoint(deviceX + margin + padRadius + col * diameter, deviceY + margin + padRadius + (row + 1) * diameter); SKPoint top = new SKPoint(deviceX + margin + padRadius + col * diameter, deviceY + margin + padRadius + (row - 1) * diameter); string label = sample.symbol.Raw(); // sample.FormatSymbol(placement.StyleOf(sample, style)) if (place.IsAnimation(KDeviceHandler.Animation.None)) { DrawDroplet(canvas, label, biggie, here, padRadius, volumeRadius, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SizeHalf)) { DrawDroplet(canvas, label, biggie, here, padRadius, volumeRadius / 2, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SizeQuarter)) { DrawDroplet(canvas, label, biggie, here, padRadius, volumeRadius / 4, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.PullRht)) { DrawDropletPulledHor(canvas, label, biggie, here, rht, KDeviceHandler.Direction.Rht, padRadius, volumeRadius * 5 / 6, volumeRadius * 5 / 12, volumeRadius * 1 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SplitRht)) { DrawDropletPulledHor(canvas, label, biggie, here, rht, KDeviceHandler.Direction.Rht, padRadius, volumeRadius * 2 / 3, volumeRadius * 1 / 3, volumeRadius * 2 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.PullLft)) { DrawDropletPulledHor(canvas, label, biggie, lft, here, KDeviceHandler.Direction.Lft, padRadius, volumeRadius * 1 / 3, volumeRadius * 5 / 12, volumeRadius * 5 / 6, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SplitLft)) { DrawDropletPulledHor(canvas, label, biggie, lft, here, KDeviceHandler.Direction.Lft, padRadius, volumeRadius * 2 / 3, volumeRadius * 1 / 3, volumeRadius * 2 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.PullBot)) { DrawDropletPulledVer(canvas, label, biggie, here, bot, KDeviceHandler.Direction.Bot, padRadius, volumeRadius * 5 / 6, volumeRadius * 5 / 12, volumeRadius * 1 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SplitBot)) { DrawDropletPulledVer(canvas, label, biggie, here, bot, KDeviceHandler.Direction.Bot, padRadius, volumeRadius * 2 / 3, volumeRadius * 1 / 3, volumeRadius * 2 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.PullTop)) { DrawDropletPulledVer(canvas, label, biggie, top, here, KDeviceHandler.Direction.Top, padRadius, volumeRadius * 1 / 3, volumeRadius * 5 / 12, volumeRadius * 5 / 6, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SplitTop)) { DrawDropletPulledVer(canvas, label, biggie, top, here, KDeviceHandler.Direction.Top, padRadius, volumeRadius * 2 / 3, volumeRadius * 1 / 3, volumeRadius * 2 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } } } } } canvas.Flush(); }