repo time
Dependencies: mbed MAX14720 MAX30205 USBDevice
HspGuiSourceV301/HSPGui/Presenter/RawFileLogPresenter.cs@20:6d2af70c92ab, 2021-04-06 (annotated)
- Committer:
- darienf
- Date:
- Tue Apr 06 06:41:40 2021 +0000
- Revision:
- 20:6d2af70c92ab
another repo
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
darienf | 20:6d2af70c92ab | 1 | /******************************************************************************* |
darienf | 20:6d2af70c92ab | 2 | * Copyright (C) 2016 Maxim Integrated Products, Inc., All rights Reserved. |
darienf | 20:6d2af70c92ab | 3 | * |
darienf | 20:6d2af70c92ab | 4 | * This software is protected by copyright laws of the United States and |
darienf | 20:6d2af70c92ab | 5 | * of foreign countries. This material may also be protected by patent laws |
darienf | 20:6d2af70c92ab | 6 | * and technology transfer regulations of the United States and of foreign |
darienf | 20:6d2af70c92ab | 7 | * countries. This software is furnished under a license agreement and/or a |
darienf | 20:6d2af70c92ab | 8 | * nondisclosure agreement and may only be used or reproduced in accordance |
darienf | 20:6d2af70c92ab | 9 | * with the terms of those agreements. Dissemination of this information to |
darienf | 20:6d2af70c92ab | 10 | * any party or parties not specified in the license agreement and/or |
darienf | 20:6d2af70c92ab | 11 | * nondisclosure agreement is expressly prohibited. |
darienf | 20:6d2af70c92ab | 12 | * |
darienf | 20:6d2af70c92ab | 13 | * The above copyright notice and this permission notice shall be included |
darienf | 20:6d2af70c92ab | 14 | * in all copies or substantial portions of the Software. |
darienf | 20:6d2af70c92ab | 15 | * |
darienf | 20:6d2af70c92ab | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
darienf | 20:6d2af70c92ab | 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
darienf | 20:6d2af70c92ab | 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
darienf | 20:6d2af70c92ab | 19 | * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES |
darienf | 20:6d2af70c92ab | 20 | * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
darienf | 20:6d2af70c92ab | 21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
darienf | 20:6d2af70c92ab | 22 | * OTHER DEALINGS IN THE SOFTWARE. |
darienf | 20:6d2af70c92ab | 23 | * |
darienf | 20:6d2af70c92ab | 24 | * Except as contained in this notice, the name of Maxim Integrated |
darienf | 20:6d2af70c92ab | 25 | * Products, Inc. shall not be used except as stated in the Maxim Integrated |
darienf | 20:6d2af70c92ab | 26 | * Products, Inc. Branding Policy. |
darienf | 20:6d2af70c92ab | 27 | * |
darienf | 20:6d2af70c92ab | 28 | * The mere transfer of this software does not imply any licenses |
darienf | 20:6d2af70c92ab | 29 | * of trade secrets, proprietary technology, copyrights, patents, |
darienf | 20:6d2af70c92ab | 30 | * trademarks, maskwork rights, or any other form of intellectual |
darienf | 20:6d2af70c92ab | 31 | * property whatsoever. Maxim Integrated Products, Inc. retains all |
darienf | 20:6d2af70c92ab | 32 | * ownership rights. |
darienf | 20:6d2af70c92ab | 33 | ******************************************************************************* |
darienf | 20:6d2af70c92ab | 34 | */ |
darienf | 20:6d2af70c92ab | 35 | |
darienf | 20:6d2af70c92ab | 36 | using System; |
darienf | 20:6d2af70c92ab | 37 | using System.Collections.Generic; |
darienf | 20:6d2af70c92ab | 38 | using System.Linq; |
darienf | 20:6d2af70c92ab | 39 | using System.Text; |
darienf | 20:6d2af70c92ab | 40 | |
darienf | 20:6d2af70c92ab | 41 | using HealthSensorPlatform.View; |
darienf | 20:6d2af70c92ab | 42 | using HealthSensorPlatform.Model; |
darienf | 20:6d2af70c92ab | 43 | using HealthSensorPlatform.CustomControls; |
darienf | 20:6d2af70c92ab | 44 | |
darienf | 20:6d2af70c92ab | 45 | using RPCSupport; |
darienf | 20:6d2af70c92ab | 46 | using RPCSupport.Streaming; |
darienf | 20:6d2af70c92ab | 47 | |
darienf | 20:6d2af70c92ab | 48 | namespace HealthSensorPlatform.Presenter |
darienf | 20:6d2af70c92ab | 49 | { |
darienf | 20:6d2af70c92ab | 50 | public class RawFileLogPresenter |
darienf | 20:6d2af70c92ab | 51 | { |
darienf | 20:6d2af70c92ab | 52 | IRawFileLogView ecgLog; |
darienf | 20:6d2af70c92ab | 53 | IRawFileLogView bioZLog; |
darienf | 20:6d2af70c92ab | 54 | IRawFileLogView rToRLog; |
darienf | 20:6d2af70c92ab | 55 | IRawFileLogView paceLog; |
darienf | 20:6d2af70c92ab | 56 | IFormView formView; |
darienf | 20:6d2af70c92ab | 57 | IEcgView ecgView; |
darienf | 20:6d2af70c92ab | 58 | |
darienf | 20:6d2af70c92ab | 59 | bool fileLog = false; // user enabled file logging |
darienf | 20:6d2af70c92ab | 60 | bool streaming = false; // streaming data or flash log data, only save data from streaming |
darienf | 20:6d2af70c92ab | 61 | //bool flashLog = false; |
darienf | 20:6d2af70c92ab | 62 | |
darienf | 20:6d2af70c92ab | 63 | IDataLoggingView dataLogView; |
darienf | 20:6d2af70c92ab | 64 | |
darienf | 20:6d2af70c92ab | 65 | PaceData paceData; |
darienf | 20:6d2af70c92ab | 66 | |
darienf | 20:6d2af70c92ab | 67 | RToRCalculator rToRCalculator; |
darienf | 20:6d2af70c92ab | 68 | bool rToRFirst = true; // received first RR value for offset correction |
darienf | 20:6d2af70c92ab | 69 | |
darienf | 20:6d2af70c92ab | 70 | //bool ecgLeadOff; // DC Lead off data for ECG or BioZ Channel |
darienf | 20:6d2af70c92ab | 71 | DCLeadOff leadOff; // lead off status bits |
darienf | 20:6d2af70c92ab | 72 | ACLeadOff acLeadOff; // bioz lead off status bits |
darienf | 20:6d2af70c92ab | 73 | |
darienf | 20:6d2af70c92ab | 74 | int count = 0; |
darienf | 20:6d2af70c92ab | 75 | int bioZCount = 0; |
darienf | 20:6d2af70c92ab | 76 | //int ppgCount = 0; |
darienf | 20:6d2af70c92ab | 77 | //int accelCount = 0; |
darienf | 20:6d2af70c92ab | 78 | |
darienf | 20:6d2af70c92ab | 79 | string logFileDirectory = null; |
darienf | 20:6d2af70c92ab | 80 | |
darienf | 20:6d2af70c92ab | 81 | View.FileLogView.FileLogHeader fileLogHeader = new View.FileLogView.FileLogHeader(); |
darienf | 20:6d2af70c92ab | 82 | |
darienf | 20:6d2af70c92ab | 83 | public RawFileLogPresenter(IRawFileLogView ecg, IRawFileLogView bioZ, IRawFileLogView rToR, IRawFileLogView pace, IFormView formView, RPCClient rpcClient, IEcgView ecgView, IDataLoggingView dataLogView) |
darienf | 20:6d2af70c92ab | 84 | { |
darienf | 20:6d2af70c92ab | 85 | this.ecgLog = ecg; |
darienf | 20:6d2af70c92ab | 86 | this.bioZLog = bioZ; |
darienf | 20:6d2af70c92ab | 87 | this.rToRLog = rToR; |
darienf | 20:6d2af70c92ab | 88 | this.paceLog = pace; |
darienf | 20:6d2af70c92ab | 89 | this.formView = formView; |
darienf | 20:6d2af70c92ab | 90 | this.ecgView = ecgView; |
darienf | 20:6d2af70c92ab | 91 | |
darienf | 20:6d2af70c92ab | 92 | this.dataLogView = dataLogView; |
darienf | 20:6d2af70c92ab | 93 | |
darienf | 20:6d2af70c92ab | 94 | formView.FileLogEnable += new EventHandler<EnableEventArgs>(OnLogFileEnable); |
darienf | 20:6d2af70c92ab | 95 | ecgView.StreamingStartStop += new EventHandler<StreamingStartStopEventArgs>(OnStreamStart); |
darienf | 20:6d2af70c92ab | 96 | //dataLogView.LogDownloadStart += new EventHandler<EventArgs>(OnLogDownloadStart); |
darienf | 20:6d2af70c92ab | 97 | rpcClient.streaming.PartialArrayIntAvailable += new EventHandler<PartialArrayIntAvailableEventArgs>(OnStreamData); |
darienf | 20:6d2af70c92ab | 98 | } |
darienf | 20:6d2af70c92ab | 99 | |
darienf | 20:6d2af70c92ab | 100 | public void OnLogFileEnable(object sender, EnableEventArgs e) |
darienf | 20:6d2af70c92ab | 101 | { |
darienf | 20:6d2af70c92ab | 102 | fileLog = e.Enable; |
darienf | 20:6d2af70c92ab | 103 | |
darienf | 20:6d2af70c92ab | 104 | if (e.Enable) |
darienf | 20:6d2af70c92ab | 105 | { |
darienf | 20:6d2af70c92ab | 106 | bool result = false; |
darienf | 20:6d2af70c92ab | 107 | IRawFileLogView log = ecgLog; |
darienf | 20:6d2af70c92ab | 108 | string filePrefixName = String.Empty; |
darienf | 20:6d2af70c92ab | 109 | |
darienf | 20:6d2af70c92ab | 110 | switch(e.Stream) |
darienf | 20:6d2af70c92ab | 111 | { |
darienf | 20:6d2af70c92ab | 112 | case StreamType.Ecg: |
darienf | 20:6d2af70c92ab | 113 | log = ecgLog; |
darienf | 20:6d2af70c92ab | 114 | filePrefixName = "hsp-ecg"; |
darienf | 20:6d2af70c92ab | 115 | break; |
darienf | 20:6d2af70c92ab | 116 | case StreamType.RToR: |
darienf | 20:6d2af70c92ab | 117 | log = rToRLog; |
darienf | 20:6d2af70c92ab | 118 | filePrefixName = "hsp-rtor"; |
darienf | 20:6d2af70c92ab | 119 | break; |
darienf | 20:6d2af70c92ab | 120 | case StreamType.Pace: |
darienf | 20:6d2af70c92ab | 121 | log = paceLog; |
darienf | 20:6d2af70c92ab | 122 | filePrefixName = "hsp-pace"; |
darienf | 20:6d2af70c92ab | 123 | break; |
darienf | 20:6d2af70c92ab | 124 | case StreamType.BioZ: |
darienf | 20:6d2af70c92ab | 125 | log = bioZLog; |
darienf | 20:6d2af70c92ab | 126 | filePrefixName = "hsp-bioz"; |
darienf | 20:6d2af70c92ab | 127 | break; |
darienf | 20:6d2af70c92ab | 128 | } |
darienf | 20:6d2af70c92ab | 129 | |
darienf | 20:6d2af70c92ab | 130 | if (logFileDirectory != null) // Set starting directory to be the same as the last |
darienf | 20:6d2af70c92ab | 131 | log.FileDirectory = logFileDirectory; |
darienf | 20:6d2af70c92ab | 132 | |
darienf | 20:6d2af70c92ab | 133 | result = log.SelectCSVFile(filePrefixName); |
darienf | 20:6d2af70c92ab | 134 | log.Enable = result; |
darienf | 20:6d2af70c92ab | 135 | |
darienf | 20:6d2af70c92ab | 136 | if (result) // Save directory if success |
darienf | 20:6d2af70c92ab | 137 | logFileDirectory = log.FileDirectory; |
darienf | 20:6d2af70c92ab | 138 | |
darienf | 20:6d2af70c92ab | 139 | formView.LogFileItem(e.Stream, result); |
darienf | 20:6d2af70c92ab | 140 | } |
darienf | 20:6d2af70c92ab | 141 | else |
darienf | 20:6d2af70c92ab | 142 | { |
darienf | 20:6d2af70c92ab | 143 | switch (e.Stream) |
darienf | 20:6d2af70c92ab | 144 | { |
darienf | 20:6d2af70c92ab | 145 | case StreamType.Ecg: |
darienf | 20:6d2af70c92ab | 146 | ecgLog.Enable = false; |
darienf | 20:6d2af70c92ab | 147 | break; |
darienf | 20:6d2af70c92ab | 148 | case StreamType.RToR: |
darienf | 20:6d2af70c92ab | 149 | rToRLog.Enable = false; |
darienf | 20:6d2af70c92ab | 150 | break; |
darienf | 20:6d2af70c92ab | 151 | case StreamType.Pace: |
darienf | 20:6d2af70c92ab | 152 | paceLog.Enable = false; |
darienf | 20:6d2af70c92ab | 153 | break; |
darienf | 20:6d2af70c92ab | 154 | case StreamType.BioZ: |
darienf | 20:6d2af70c92ab | 155 | bioZLog.Enable = false; |
darienf | 20:6d2af70c92ab | 156 | break; |
darienf | 20:6d2af70c92ab | 157 | } |
darienf | 20:6d2af70c92ab | 158 | |
darienf | 20:6d2af70c92ab | 159 | formView.LogFileItem(e.Stream, false); |
darienf | 20:6d2af70c92ab | 160 | } |
darienf | 20:6d2af70c92ab | 161 | } |
darienf | 20:6d2af70c92ab | 162 | |
darienf | 20:6d2af70c92ab | 163 | public void OnStreamStart(object sender, StreamingStartStopEventArgs e) |
darienf | 20:6d2af70c92ab | 164 | { |
darienf | 20:6d2af70c92ab | 165 | streaming = e.state; |
darienf | 20:6d2af70c92ab | 166 | count = 0; |
darienf | 20:6d2af70c92ab | 167 | bioZCount = 0; |
darienf | 20:6d2af70c92ab | 168 | |
darienf | 20:6d2af70c92ab | 169 | if (e.state) |
darienf | 20:6d2af70c92ab | 170 | { |
darienf | 20:6d2af70c92ab | 171 | leadOff = new DCLeadOff { NegativeHigh = false, NegativeLow = false, PostiveHigh = false, PostiveLow = false }; |
darienf | 20:6d2af70c92ab | 172 | acLeadOff = new ACLeadOff { BioZOverRange = false, BioZUnderRange = false }; |
darienf | 20:6d2af70c92ab | 173 | |
darienf | 20:6d2af70c92ab | 174 | if (ecgLog != null && ecgLog.Enable && ecgView.EnableECG) |
darienf | 20:6d2af70c92ab | 175 | { |
darienf | 20:6d2af70c92ab | 176 | //ecgLog.WriteLine("% " + ecgView.HspSetting.EcgSettingString()); // TODO: What is the requirement for headers |
darienf | 20:6d2af70c92ab | 177 | ecgLog.WriteLine(fileLogHeader.Ecg); |
darienf | 20:6d2af70c92ab | 178 | } |
darienf | 20:6d2af70c92ab | 179 | |
darienf | 20:6d2af70c92ab | 180 | if (bioZLog != null && bioZLog.Enable && ecgView.EnableBioZ) |
darienf | 20:6d2af70c92ab | 181 | { |
darienf | 20:6d2af70c92ab | 182 | //ecgLog.WriteLine("% " + ecgView.HspSetting.BioZSettingString()); |
darienf | 20:6d2af70c92ab | 183 | bioZLog.WriteLine(fileLogHeader.BioZ); |
darienf | 20:6d2af70c92ab | 184 | } |
darienf | 20:6d2af70c92ab | 185 | |
darienf | 20:6d2af70c92ab | 186 | if (rToRLog != null && rToRLog.Enable && ecgView.EnableRToR) |
darienf | 20:6d2af70c92ab | 187 | { |
darienf | 20:6d2af70c92ab | 188 | rToRLog.WriteLine(fileLogHeader.RToR); |
darienf | 20:6d2af70c92ab | 189 | rToRCalculator = new RToRCalculator(ecgView.MasterClockField, ecgView.EcgArgs.Rate, ecgView.EcgArgs.Dlpf, ecgView.RToRArgs.Wndw); |
darienf | 20:6d2af70c92ab | 190 | } |
darienf | 20:6d2af70c92ab | 191 | |
darienf | 20:6d2af70c92ab | 192 | if (paceLog != null && paceLog.Enable && ecgView.EnablePace) |
darienf | 20:6d2af70c92ab | 193 | { |
darienf | 20:6d2af70c92ab | 194 | paceLog.WriteLine(fileLogHeader.Pace); |
darienf | 20:6d2af70c92ab | 195 | } |
darienf | 20:6d2af70c92ab | 196 | } |
darienf | 20:6d2af70c92ab | 197 | else |
darienf | 20:6d2af70c92ab | 198 | { |
darienf | 20:6d2af70c92ab | 199 | if (ecgLog != null) |
darienf | 20:6d2af70c92ab | 200 | ecgLog.Enable = false; |
darienf | 20:6d2af70c92ab | 201 | |
darienf | 20:6d2af70c92ab | 202 | if (bioZLog != null) |
darienf | 20:6d2af70c92ab | 203 | bioZLog.Enable = false; |
darienf | 20:6d2af70c92ab | 204 | |
darienf | 20:6d2af70c92ab | 205 | if (rToRLog != null) |
darienf | 20:6d2af70c92ab | 206 | rToRLog.Enable = false; |
darienf | 20:6d2af70c92ab | 207 | |
darienf | 20:6d2af70c92ab | 208 | if (paceLog != null) |
darienf | 20:6d2af70c92ab | 209 | paceLog.Enable = false; |
darienf | 20:6d2af70c92ab | 210 | } |
darienf | 20:6d2af70c92ab | 211 | } |
darienf | 20:6d2af70c92ab | 212 | |
darienf | 20:6d2af70c92ab | 213 | void fileLogStop() |
darienf | 20:6d2af70c92ab | 214 | { |
darienf | 20:6d2af70c92ab | 215 | fileLog = false; |
darienf | 20:6d2af70c92ab | 216 | stop(); |
darienf | 20:6d2af70c92ab | 217 | |
darienf | 20:6d2af70c92ab | 218 | } |
darienf | 20:6d2af70c92ab | 219 | |
darienf | 20:6d2af70c92ab | 220 | void stop() |
darienf | 20:6d2af70c92ab | 221 | { |
darienf | 20:6d2af70c92ab | 222 | if (ecgLog != null && ecgLog.Enable) |
darienf | 20:6d2af70c92ab | 223 | ecgLog.Enable = false; |
darienf | 20:6d2af70c92ab | 224 | |
darienf | 20:6d2af70c92ab | 225 | if (rToRLog != null && rToRLog.Enable) |
darienf | 20:6d2af70c92ab | 226 | rToRLog.Enable = false; |
darienf | 20:6d2af70c92ab | 227 | |
darienf | 20:6d2af70c92ab | 228 | if (paceLog != null && paceLog.Enable) |
darienf | 20:6d2af70c92ab | 229 | paceLog.Enable = false; |
darienf | 20:6d2af70c92ab | 230 | |
darienf | 20:6d2af70c92ab | 231 | if (bioZLog != null && bioZLog.Enable) |
darienf | 20:6d2af70c92ab | 232 | bioZLog.Enable = false; |
darienf | 20:6d2af70c92ab | 233 | |
darienf | 20:6d2af70c92ab | 234 | formView.LogFileItem(StreamType.Ecg, false); |
darienf | 20:6d2af70c92ab | 235 | formView.LogFileItem(StreamType.RToR, false); |
darienf | 20:6d2af70c92ab | 236 | formView.LogFileItem(StreamType.Pace, false); |
darienf | 20:6d2af70c92ab | 237 | formView.LogFileItem(StreamType.BioZ, false); |
darienf | 20:6d2af70c92ab | 238 | } |
darienf | 20:6d2af70c92ab | 239 | |
darienf | 20:6d2af70c92ab | 240 | private void OnStreamData(object sender, PartialArrayIntAvailableEventArgs e) |
darienf | 20:6d2af70c92ab | 241 | { |
darienf | 20:6d2af70c92ab | 242 | if (streaming) |
darienf | 20:6d2af70c92ab | 243 | { |
darienf | 20:6d2af70c92ab | 244 | switch (e.reportID) |
darienf | 20:6d2af70c92ab | 245 | { |
darienf | 20:6d2af70c92ab | 246 | case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_ECG: |
darienf | 20:6d2af70c92ab | 247 | if (ecgLog.Enable) |
darienf | 20:6d2af70c92ab | 248 | ProcessEcg(e.array1); |
darienf | 20:6d2af70c92ab | 249 | break; |
darienf | 20:6d2af70c92ab | 250 | case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_BIOZ: |
darienf | 20:6d2af70c92ab | 251 | if (bioZLog.Enable) |
darienf | 20:6d2af70c92ab | 252 | ProcessBioZ(e.array1); |
darienf | 20:6d2af70c92ab | 253 | break; |
darienf | 20:6d2af70c92ab | 254 | case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_PACE: |
darienf | 20:6d2af70c92ab | 255 | if (paceLog.Enable) |
darienf | 20:6d2af70c92ab | 256 | paceData = new PaceData(e.array1); |
darienf | 20:6d2af70c92ab | 257 | break; |
darienf | 20:6d2af70c92ab | 258 | case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_RTOR: |
darienf | 20:6d2af70c92ab | 259 | if (rToRLog.Enable) |
darienf | 20:6d2af70c92ab | 260 | ProcessRToR(e.array1[0]); |
darienf | 20:6d2af70c92ab | 261 | break; |
darienf | 20:6d2af70c92ab | 262 | case PartialArrayIntAvailableEventArgs.PACKET_END_OF_STREAM: |
darienf | 20:6d2af70c92ab | 263 | fileLogStop(); |
darienf | 20:6d2af70c92ab | 264 | break; |
darienf | 20:6d2af70c92ab | 265 | case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_LEADOFF_DC: |
darienf | 20:6d2af70c92ab | 266 | ProcessLeadOff(e.array1[0]); |
darienf | 20:6d2af70c92ab | 267 | break; |
darienf | 20:6d2af70c92ab | 268 | case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_LEADOFF_AC: |
darienf | 20:6d2af70c92ab | 269 | ProcessACLeadOff(e.array1[0]); |
darienf | 20:6d2af70c92ab | 270 | break; |
darienf | 20:6d2af70c92ab | 271 | } |
darienf | 20:6d2af70c92ab | 272 | } |
darienf | 20:6d2af70c92ab | 273 | } |
darienf | 20:6d2af70c92ab | 274 | |
darienf | 20:6d2af70c92ab | 275 | void ProcessBioZ(int[] rawData) |
darienf | 20:6d2af70c92ab | 276 | { |
darienf | 20:6d2af70c92ab | 277 | BioZFifo[] bioZFifo; |
darienf | 20:6d2af70c92ab | 278 | double sampleRate = ecgView.SampleRateBioZ; |
darienf | 20:6d2af70c92ab | 279 | double[] time = new double[rawData.Length]; |
darienf | 20:6d2af70c92ab | 280 | |
darienf | 20:6d2af70c92ab | 281 | bioZFifo = ConvertBioZ(rawData); |
darienf | 20:6d2af70c92ab | 282 | |
darienf | 20:6d2af70c92ab | 283 | for (int i = 0; i < time.Length; i++) |
darienf | 20:6d2af70c92ab | 284 | { |
darienf | 20:6d2af70c92ab | 285 | time[i] = bioZCount / sampleRate; |
darienf | 20:6d2af70c92ab | 286 | bioZCount++; |
darienf | 20:6d2af70c92ab | 287 | } |
darienf | 20:6d2af70c92ab | 288 | |
darienf | 20:6d2af70c92ab | 289 | if (ecgView.EnableDCLeadOff == false && ecgView.EnableBioZOverUnderRange == true) |
darienf | 20:6d2af70c92ab | 290 | bioZLog.DisplayBioZ(time, bioZFifo, acLeadOff); |
darienf | 20:6d2af70c92ab | 291 | else if (ecgView.EnableDCLeadOff == true && ecgView.EnableEcgDCLeadOff == false && ecgView.EnableBioZOverUnderRange == false) // && ecgLeadOff == false) |
darienf | 20:6d2af70c92ab | 292 | bioZLog.DisplayBioZ(time, bioZFifo, leadOff); |
darienf | 20:6d2af70c92ab | 293 | else if (ecgView.EnableDCLeadOff == true && ecgView.EnableEcgDCLeadOff == false && ecgView.EnableBioZOverUnderRange == true) |
darienf | 20:6d2af70c92ab | 294 | bioZLog.DisplayBioZ(time, bioZFifo, leadOff, acLeadOff); |
darienf | 20:6d2af70c92ab | 295 | else if ((ecgView.EnableDCLeadOff == false && ecgView.EnableBioZOverUnderRange == false) || |
darienf | 20:6d2af70c92ab | 296 | ecgView.EnableEcgDCLeadOff == true && ecgView.EnableEcgDCLeadOff == true && ecgView.EnableBioZOverUnderRange == false) |
darienf | 20:6d2af70c92ab | 297 | bioZLog.DisplayBioZ(time, bioZFifo); |
darienf | 20:6d2af70c92ab | 298 | } |
darienf | 20:6d2af70c92ab | 299 | |
darienf | 20:6d2af70c92ab | 300 | public BioZFifo[] ConvertBioZ(int[] data) |
darienf | 20:6d2af70c92ab | 301 | { |
darienf | 20:6d2af70c92ab | 302 | BioZFifo[] impedance = new BioZFifo[data.Length]; |
darienf | 20:6d2af70c92ab | 303 | EcgView.ChartInfo chartInfo = ecgView.BioZInfo; |
darienf | 20:6d2af70c92ab | 304 | int dataShift; |
darienf | 20:6d2af70c92ab | 305 | |
darienf | 20:6d2af70c92ab | 306 | for (int i = 0; i < data.Length; i++) |
darienf | 20:6d2af70c92ab | 307 | { |
darienf | 20:6d2af70c92ab | 308 | dataShift = data[i] >> chartInfo.Shift; |
darienf | 20:6d2af70c92ab | 309 | |
darienf | 20:6d2af70c92ab | 310 | // Two's Complement Conversions |
darienf | 20:6d2af70c92ab | 311 | if (dataShift > chartInfo.Threshold) |
darienf | 20:6d2af70c92ab | 312 | { |
darienf | 20:6d2af70c92ab | 313 | dataShift -= chartInfo.Offset; |
darienf | 20:6d2af70c92ab | 314 | } |
darienf | 20:6d2af70c92ab | 315 | |
darienf | 20:6d2af70c92ab | 316 | // 1.9734 = 1/2^19 * 1e-6 |
darienf | 20:6d2af70c92ab | 317 | impedance[i].Data = dataShift * 1.9073486328125 / |
darienf | 20:6d2af70c92ab | 318 | (chartInfo.Gain * ((chartInfo.CurrentGenerator == 0) ? 1 : chartInfo.CurrentGenerator)); |
darienf | 20:6d2af70c92ab | 319 | impedance[i].Code = data[i]; |
darienf | 20:6d2af70c92ab | 320 | impedance[i].BioZData = dataShift; |
darienf | 20:6d2af70c92ab | 321 | impedance[i].BTag = data[i] & 0x07; |
darienf | 20:6d2af70c92ab | 322 | } |
darienf | 20:6d2af70c92ab | 323 | |
darienf | 20:6d2af70c92ab | 324 | return impedance; |
darienf | 20:6d2af70c92ab | 325 | } |
darienf | 20:6d2af70c92ab | 326 | |
darienf | 20:6d2af70c92ab | 327 | void ProcessEcg(int[] rawData) |
darienf | 20:6d2af70c92ab | 328 | { |
darienf | 20:6d2af70c92ab | 329 | EcgFifo[] ecgFifo; |
darienf | 20:6d2af70c92ab | 330 | double ecgRate = ecgView.SampleRateEcg; |
darienf | 20:6d2af70c92ab | 331 | double[] ecgVoltage = new double[rawData.Length]; |
darienf | 20:6d2af70c92ab | 332 | double[] timeSecond = new double[rawData.Length]; |
darienf | 20:6d2af70c92ab | 333 | |
darienf | 20:6d2af70c92ab | 334 | ecgFifo = ConvertEcg(rawData); |
darienf | 20:6d2af70c92ab | 335 | |
darienf | 20:6d2af70c92ab | 336 | for (int i = 0; i < ecgFifo.Length; i++ ) |
darienf | 20:6d2af70c92ab | 337 | { |
darienf | 20:6d2af70c92ab | 338 | timeSecond[i] = count / ecgRate; |
darienf | 20:6d2af70c92ab | 339 | |
darienf | 20:6d2af70c92ab | 340 | // Look for Pace Events |
darienf | 20:6d2af70c92ab | 341 | if (paceLog.Enable) |
darienf | 20:6d2af70c92ab | 342 | { |
darienf | 20:6d2af70c92ab | 343 | //for (int j = 0; j < ecgFifo.Length; j++) |
darienf | 20:6d2af70c92ab | 344 | //{ |
darienf | 20:6d2af70c92ab | 345 | if (ecgFifo[i].PTag != 7) |
darienf | 20:6d2af70c92ab | 346 | { |
darienf | 20:6d2af70c92ab | 347 | PaceData.PaceRegister paceRegister = paceData.PaceGroup(ecgFifo[i].PTag); |
darienf | 20:6d2af70c92ab | 348 | List<double> timeMillsecondPace = new List<double>(); |
darienf | 20:6d2af70c92ab | 349 | List<PaceData.PaceEdge> paceEdges = new List<PaceData.PaceEdge>(); |
darienf | 20:6d2af70c92ab | 350 | |
darienf | 20:6d2af70c92ab | 351 | for (int k = 0; k < 6; k++) |
darienf | 20:6d2af70c92ab | 352 | { |
darienf | 20:6d2af70c92ab | 353 | PaceData.PaceEdge edge = paceRegister.Edge[k]; |
darienf | 20:6d2af70c92ab | 354 | |
darienf | 20:6d2af70c92ab | 355 | timeMillsecondPace.Add(count / ecgRate + ConvertPace(edge.Data)); |
darienf | 20:6d2af70c92ab | 356 | paceEdges.Add(edge); |
darienf | 20:6d2af70c92ab | 357 | |
darienf | 20:6d2af70c92ab | 358 | if (edge.Last == true) |
darienf | 20:6d2af70c92ab | 359 | break; |
darienf | 20:6d2af70c92ab | 360 | } |
darienf | 20:6d2af70c92ab | 361 | |
darienf | 20:6d2af70c92ab | 362 | paceLog.DisplayPace(timeMillsecondPace.ToArray(), paceEdges.ToArray()); |
darienf | 20:6d2af70c92ab | 363 | System.Diagnostics.Debug.Print("ECG PTag = " + ecgFifo[i].PTag); |
darienf | 20:6d2af70c92ab | 364 | } |
darienf | 20:6d2af70c92ab | 365 | //} |
darienf | 20:6d2af70c92ab | 366 | } |
darienf | 20:6d2af70c92ab | 367 | |
darienf | 20:6d2af70c92ab | 368 | count++; |
darienf | 20:6d2af70c92ab | 369 | } |
darienf | 20:6d2af70c92ab | 370 | |
darienf | 20:6d2af70c92ab | 371 | if (ecgView.EnableDCLeadOff && ecgView.EnableEcgDCLeadOff) |
darienf | 20:6d2af70c92ab | 372 | ecgLog.DisplayEcg(timeSecond, ecgFifo, leadOff); |
darienf | 20:6d2af70c92ab | 373 | else |
darienf | 20:6d2af70c92ab | 374 | ecgLog.DisplayEcg(timeSecond, ecgFifo); |
darienf | 20:6d2af70c92ab | 375 | |
darienf | 20:6d2af70c92ab | 376 | } |
darienf | 20:6d2af70c92ab | 377 | |
darienf | 20:6d2af70c92ab | 378 | public EcgFifo[] ConvertEcg(int[] data) |
darienf | 20:6d2af70c92ab | 379 | { |
darienf | 20:6d2af70c92ab | 380 | EcgFifo[] voltage = new EcgFifo[data.Length]; |
darienf | 20:6d2af70c92ab | 381 | EcgView.ChartInfo chartInfo = ecgView.EcgInfo; |
darienf | 20:6d2af70c92ab | 382 | int dataShift; |
darienf | 20:6d2af70c92ab | 383 | |
darienf | 20:6d2af70c92ab | 384 | for (int i = 0; i < data.Length; i++) |
darienf | 20:6d2af70c92ab | 385 | { |
darienf | 20:6d2af70c92ab | 386 | dataShift = data[i] >> chartInfo.Shift; |
darienf | 20:6d2af70c92ab | 387 | |
darienf | 20:6d2af70c92ab | 388 | // Two's Complement Conversions |
darienf | 20:6d2af70c92ab | 389 | if (dataShift > chartInfo.Threshold) |
darienf | 20:6d2af70c92ab | 390 | { |
darienf | 20:6d2af70c92ab | 391 | dataShift -= chartInfo.Offset; |
darienf | 20:6d2af70c92ab | 392 | } |
darienf | 20:6d2af70c92ab | 393 | |
darienf | 20:6d2af70c92ab | 394 | voltage[i].Data = 1000 * 7.62939453125e-6 * dataShift / chartInfo.Gain; |
darienf | 20:6d2af70c92ab | 395 | voltage[i].EcgData = dataShift; |
darienf | 20:6d2af70c92ab | 396 | voltage[i].Code = data[i]; |
darienf | 20:6d2af70c92ab | 397 | voltage[i].PTag = data[i] & 0x07; |
darienf | 20:6d2af70c92ab | 398 | voltage[i].ETag = (data[i] >> 3) & 0x07; |
darienf | 20:6d2af70c92ab | 399 | } |
darienf | 20:6d2af70c92ab | 400 | |
darienf | 20:6d2af70c92ab | 401 | return voltage; |
darienf | 20:6d2af70c92ab | 402 | } |
darienf | 20:6d2af70c92ab | 403 | |
darienf | 20:6d2af70c92ab | 404 | public double ConvertRToR(int data) |
darienf | 20:6d2af70c92ab | 405 | { |
darienf | 20:6d2af70c92ab | 406 | return ecgView.TimeResolution * 1000 * data * 512; |
darienf | 20:6d2af70c92ab | 407 | } |
darienf | 20:6d2af70c92ab | 408 | |
darienf | 20:6d2af70c92ab | 409 | public double ConvertPace(int data) |
darienf | 20:6d2af70c92ab | 410 | { |
darienf | 20:6d2af70c92ab | 411 | return data * ecgView.TimeResolution; |
darienf | 20:6d2af70c92ab | 412 | } |
darienf | 20:6d2af70c92ab | 413 | |
darienf | 20:6d2af70c92ab | 414 | public string PaceRegisterGroupToString(PaceData.PaceRegister paceRegister) |
darienf | 20:6d2af70c92ab | 415 | { |
darienf | 20:6d2af70c92ab | 416 | StringBuilder paceRegisterLogBuilder = new StringBuilder(); |
darienf | 20:6d2af70c92ab | 417 | for (int j = 0; j < 6; j++) |
darienf | 20:6d2af70c92ab | 418 | { |
darienf | 20:6d2af70c92ab | 419 | paceRegisterLogBuilder.Append(paceRegister.Edge[j].Data / (2 * ecgView.MasterClockFrequency)); |
darienf | 20:6d2af70c92ab | 420 | paceRegisterLogBuilder.Append(", "); |
darienf | 20:6d2af70c92ab | 421 | paceRegisterLogBuilder.Append(paceRegister.Edge[j].Polarity ? 'R' : 'F'); |
darienf | 20:6d2af70c92ab | 422 | paceRegisterLogBuilder.Append(", "); |
darienf | 20:6d2af70c92ab | 423 | paceRegisterLogBuilder.Append(paceRegister.Edge[j].Last ? 'Y' : 'N'); |
darienf | 20:6d2af70c92ab | 424 | paceRegisterLogBuilder.Append(", "); |
darienf | 20:6d2af70c92ab | 425 | } |
darienf | 20:6d2af70c92ab | 426 | |
darienf | 20:6d2af70c92ab | 427 | return paceRegisterLogBuilder.ToString(); |
darienf | 20:6d2af70c92ab | 428 | } |
darienf | 20:6d2af70c92ab | 429 | |
darienf | 20:6d2af70c92ab | 430 | void ProcessLeadOff(int data) |
darienf | 20:6d2af70c92ab | 431 | { |
darienf | 20:6d2af70c92ab | 432 | /* |
darienf | 20:6d2af70c92ab | 433 | if (bitShiftMask(data, 8)) // ECG lead off |
darienf | 20:6d2af70c92ab | 434 | ecgLeadOff = true; |
darienf | 20:6d2af70c92ab | 435 | else if (bitShiftMask(data, 9)) // BioZ lead off |
darienf | 20:6d2af70c92ab | 436 | ecgLeadOff = false; |
darienf | 20:6d2af70c92ab | 437 | */ |
darienf | 20:6d2af70c92ab | 438 | |
darienf | 20:6d2af70c92ab | 439 | leadOff = new DCLeadOff() |
darienf | 20:6d2af70c92ab | 440 | { |
darienf | 20:6d2af70c92ab | 441 | PostiveHigh = bitShiftMask(data, 3), |
darienf | 20:6d2af70c92ab | 442 | PostiveLow = bitShiftMask(data, 2), |
darienf | 20:6d2af70c92ab | 443 | NegativeHigh = bitShiftMask(data, 1), |
darienf | 20:6d2af70c92ab | 444 | NegativeLow = bitShiftMask(data, 0) |
darienf | 20:6d2af70c92ab | 445 | }; |
darienf | 20:6d2af70c92ab | 446 | |
darienf | 20:6d2af70c92ab | 447 | } |
darienf | 20:6d2af70c92ab | 448 | |
darienf | 20:6d2af70c92ab | 449 | void ProcessACLeadOff(int data) |
darienf | 20:6d2af70c92ab | 450 | { |
darienf | 20:6d2af70c92ab | 451 | acLeadOff = new ACLeadOff() |
darienf | 20:6d2af70c92ab | 452 | { |
darienf | 20:6d2af70c92ab | 453 | BioZUnderRange = bitShiftMask(data, 1), |
darienf | 20:6d2af70c92ab | 454 | BioZOverRange = bitShiftMask(data, 0), |
darienf | 20:6d2af70c92ab | 455 | }; |
darienf | 20:6d2af70c92ab | 456 | } |
darienf | 20:6d2af70c92ab | 457 | |
darienf | 20:6d2af70c92ab | 458 | private static bool bitShiftMask(int data, int index) |
darienf | 20:6d2af70c92ab | 459 | { |
darienf | 20:6d2af70c92ab | 460 | int state; |
darienf | 20:6d2af70c92ab | 461 | int mask = 1 << index; |
darienf | 20:6d2af70c92ab | 462 | state = ((data & mask) == mask) ? 1 : 0; |
darienf | 20:6d2af70c92ab | 463 | return state == 1; |
darienf | 20:6d2af70c92ab | 464 | } |
darienf | 20:6d2af70c92ab | 465 | |
darienf | 20:6d2af70c92ab | 466 | void ProcessRToR(int data) |
darienf | 20:6d2af70c92ab | 467 | { |
darienf | 20:6d2af70c92ab | 468 | if (rToRFirst) |
darienf | 20:6d2af70c92ab | 469 | { |
darienf | 20:6d2af70c92ab | 470 | rToRLog.DisplayRToR(data, rToRCalculator.Corrected(data, true) / 1000); |
darienf | 20:6d2af70c92ab | 471 | rToRFirst = false; |
darienf | 20:6d2af70c92ab | 472 | } |
darienf | 20:6d2af70c92ab | 473 | else |
darienf | 20:6d2af70c92ab | 474 | rToRLog.DisplayRToR(data, rToRCalculator.Corrected(data, false) / 1000); |
darienf | 20:6d2af70c92ab | 475 | } |
darienf | 20:6d2af70c92ab | 476 | } |
darienf | 20:6d2af70c92ab | 477 | } |