private static List <MeasureModel> SmoothData(List <MeasureModel> m, int window) { List <MeasureModel> ret = new List <MeasureModel>(); for (int i = window; i < m.Count - window; i++) { MeasureModel average = new MeasureModel(); int a = 0; for (int d = i - window; d <= i + window; d++) { average.Value += m[d].Value; average.Time += m[d].Time; a++; } average.Value /= (window * 2.0 + 1); average.Time /= (window * 2.0 + 1); ret.Add(average); } return(ret); }
public AnalyzedResult Read(bool fillInZeros) { AnalyzedResult result = new AnalyzedResult(); using (FileStream fin = File.OpenRead(_fileName)) { using (BinaryReader br = new BinaryReader(fin)) { List <MeasureModel> irs = new List <MeasureModel>(); List <MeasureModel> rs = new List <MeasureModel>(); List <MeasureModel> gs = new List <MeasureModel>(); List <MeasureModel> ms = new List <MeasureModel>(); MeasureModel lastGoodBpm = null, lastGoodSpo2 = null, lastGoodAccel = null; bool hasAccel = false; DateTime start = new DateTime(1, 1, 1); try { while (br.BaseStream.Position < br.BaseStream.Length) { long filePosition = br.BaseStream.Position; long fileTime = br.ReadInt64(); double r = br.ReadDouble(); double ir = br.ReadDouble(); double g = br.ReadDouble(); double m = 0; byte marker = br.ReadByte(); if (marker != 0x69) { br.BaseStream.Seek(-1, SeekOrigin.Current); m = br.ReadDouble(); hasAccel = true; marker = br.ReadByte(); } if (marker == 0x69) { DateTime dt = DateTime.FromFileTime(fileTime); //File.AppendAllText("C:/users/ben/desktop/accelRaw.csv", $"{dt}, {m}\n"); if (start.Year == 1) { start = dt; } double seconds = (dt - start).TotalSeconds; irs.Add(new MeasureModel { Time = seconds, DateTime = dt, Value = ir, FilePosition = filePosition, }); rs.Add(new MeasureModel { Time = seconds, DateTime = dt, Value = r, FilePosition = filePosition, }); gs.Add(new MeasureModel { Time = seconds, DateTime = dt, Value = g, FilePosition = filePosition, }); if (hasAccel) { ms.Add(new MeasureModel { Time = seconds, DateTime = dt, Value = m, FilePosition = filePosition, }); } if (rs.Count == 100) { result.TotalRecordGroupsAnalyzed++; double spo2 = 0, bpm = 0, xyRatio = 0; if (Robert.Interop.Compute(irs.Select(n => n.Value).ToArray(), rs.Select(n => n.Value).ToArray(), ref spo2, ref bpm, ref xyRatio) && spo2 > 90 && spo2 < 100) { lastGoodSpo2 = new MeasureModel { Time = seconds, DateTime = dt, Value = spo2, FilePosition = filePosition, }; result.Spo2ReadSuccessCount++; result.Spo2List.Add(lastGoodSpo2); } else if (fillInZeros && lastGoodSpo2 != null) { lastGoodSpo2.DateTime = dt; lastGoodSpo2.Time = seconds; result.Spo2List.Add(lastGoodSpo2); } else { result.Spo2List.Add(new MeasureModel { Time = seconds, DateTime = dt, Value = 95, FilePosition = filePosition, }); } SignalProcessor.Mean(ref gs); SignalProcessor.LineLeveling(ref gs); List <MeasureModel> smoothed = null; bpm = SignalProcessor.ComputeBpm(gs, out smoothed); if (bpm > 0) { lastGoodBpm = new MeasureModel { Time = seconds, DateTime = dt, Value = bpm, FilePosition = filePosition, }; result.BpmReadSuccessCount++; result.BpmList.Add(lastGoodBpm); } else if (fillInZeros && lastGoodBpm != null) { lastGoodBpm.DateTime = dt; lastGoodBpm.Time = seconds; result.BpmList.Add(lastGoodBpm); } if (hasAccel) { result.AccelList.Add(new MeasureModel { Time = seconds, DateTime = dt, Value = ms.Average(n => n.Value), FilePosition = filePosition, }); } rs.Clear(); irs.Clear(); gs.Clear(); ms.Clear(); } } else { //throw new FormatException(); } } } catch (EndOfStreamException) { // just move along, sometimes we dont' flush all the way } } } return(result); }
public void Start(string comPort, int baudRate, int batchSize) { DateTime startTime = DateTime.Now; _batchSize = batchSize; if (_port == null) { _port = new SerialPort(comPort, baudRate); _port.DataReceived += (sender, e) => { //string line = _port.ReadExisting().Trim(); string line = _port.ReadLine().Trim(); if (line.StartsWith("R[")) { double r = 0, ir = 0, g = 0, x = 0, y = 0, z = 0; //R[972] IR[709] G[211] //-?[0-9]\d*(\.\d+)? Match match = Regex.Match(line, @"^R\[([0-9]+)\] IR\[([0-9]+)\] G\[([0-9]+)\] X\[(-?[0-9]\d*\.\d+?)\] Y\[(-?[0-9]\d*\.\d+?)\] Z\[(-?[0-9]\d*\.\d+?)\]"); if (match.Groups.Count == 7) { r = double.Parse(match.Groups[1].Value); ir = double.Parse(match.Groups[2].Value); g = double.Parse(match.Groups[3].Value); x = double.Parse(match.Groups[4].Value); y = double.Parse(match.Groups[5].Value); z = double.Parse(match.Groups[6].Value); double mag = Math.Sqrt(x * x + y * y + z * z) - 9.28; rs.Add(r); irs.Add(ir); gs.Add(g); mags.Add(mag); DateTime now = DateTime.Now; double timeStamp = (now - startTime).TotalSeconds; if ((now - _lastSend).TotalMilliseconds >= 50) { double rAverage = rs.Average(); double irAverage = irs.Average(); double gAverage = gs.Average(); double mAverage = mags.Average(); OnLineRead?.Invoke(rAverage, irAverage, gAverage, mAverage, timeStamp); irs.Clear(); rs.Clear(); gs.Clear(); mags.Clear(); } MeasureModel rModel = new MeasureModel { Time = timeStamp, Value = r, }; MeasureModel irModel = new MeasureModel { Time = timeStamp, Value = ir, }; MeasureModel gModel = new MeasureModel { Time = timeStamp, Value = g, }; MeasureModel mModel = new MeasureModel { Time = timeStamp, Value = mag, }; rBatch.Add(rModel); irBatch.Add(irModel); gBatch.Add(gModel); mBatch.Add(mModel); OnEveryLine?.Invoke(rModel, irModel, gModel, mModel, now); if (irBatch.Count >= _batchSize) { OnBatchCompleted?.Invoke(rBatch, irBatch, gBatch, mBatch); rBatch.Clear(); irBatch.Clear(); gBatch.Clear(); mBatch.Clear(); } _lastSend = now; } } }; _port.Open(); } }