protected override void OnLoad(EventArgs e) { base.OnLoad(e); // skip if file is not specified if (!FileHandler.available()) { return; } // read sample rate sampleRate = FileHandler.readSampleRate(); slider1.sampleRate = sampleRate; // set default settings Settings set = Settings.instance(); slider1.seek = set.lastSeek; slider1.blocks = set.lastBlocks; slider1.perPage = set.perPage; slider1.page = (long)(slider1.seek / slider1.perPage); slider1.blocksCount = FileHandler.blocksCount(); }
public formMain() { InitializeComponent(); ribon1.add("Open", box.folder, true, () => { // open ecg file OpenFileDialog op = new OpenFileDialog(); op.Filter = "ECG Files (*.bin)|*.bin"; if (op.ShowDialog() == DialogResult.OK) { // store path to config Settings set = Settings.instance(); set.path = op.FileName; set.commit(); // load file FileHandler.begin(set.path); this.OnLoad(null); } }); ribon1.add("Print", box.mail, true, () => { // skip if file not loaded if (!FileHandler.available()) { return; } // open print form formPrint frm = new formPrint(this); frm.ShowDialog(); }); ribon1.add("Edit", box.edit, true, () => { // skip if file not loaded if (!FileHandler.available()) { return; } Settings set = Settings.instance(); // edit file information formStatistic sttc = new formStatistic(); sttc.mId.Text = FileHandler.id.id; sttc.mName.Text = FileHandler.id.name; sttc.mAge.Text = FileHandler.id.age; TimeSpan ts = TimeSpan.FromSeconds(FileHandler.id.starttimeSec); sttc.mTime.Text = zero(ts.Hours) + ":" + zero(ts.Minutes) + ":" + zero(ts.Seconds); if (sttc.ShowDialog() == DialogResult.OK) { // load ecg information data EcgStatistic ecg = new EcgStatistic(); ecg.id = sttc.mId.Text; ecg.name = sttc.mName.Text; ecg.age = sttc.mAge.Text; ecg.critical = FileHandler.id.critical; string[] tm = sttc.mTime.Text.Split(':'); int hh = int.Parse(tm[0]); int mm = int.Parse(tm[1]); int ss = int.Parse(tm[2]); ecg.starttimeSec = ss + mm * 60 + hh * 60 * 60; FileHandler.id = ecg; // save file information XmlClass <EcgStatistic> .Save(ecg, set.path + ".xml", SerializedFormat.Document); // refresh graph data graph1.ecgid = ecg; slider1.s2 = graph1.ecgid.starttimeSec; graph1.s2 = graph1.ecgid.starttimeSec + slider1.seek * 56.0f / sampleRate; graph1.Refresh(); slider1.Refresh(); } }); ribon1.add("Save", box.save, true, () => { // skip if file not loaded if (!FileHandler.available()) { return; } // save data SaveFileDialog op = new SaveFileDialog(); op.Filter = "ECG Files (*.bin)|*.bin"; if (op.ShowDialog() == DialogResult.OK) { FileHandler.save(op.FileName, slider1.seek, slider1.blocks); } }); ribon1.add("Analyses", box.heart, true, () => { if (!FileHandler.available()) { return; } // open analyse form formAnalyse frm = new formAnalyse(); frm.ShowDialog(); }); ribon1.add("Goto", box.ff, true, () => { // skip if file not loaded if (!FileHandler.available()) { return; } // goto time formTime tme = new formTime(); TimeSpan ts = TimeSpan.FromSeconds(FileHandler.id.starttimeSec + slider1.seek * 56.0f / slider1.sampleRate); tme.mDays.Value = ts.Days; tme.mTime.Text = zero(ts.Hours) + ":" + zero(ts.Minutes) + ":" + zero(ts.Seconds); if (tme.ShowDialog() == DialogResult.OK) { int days = (int)(tme.mDays.Value); string[] tm = tme.mTime.Text.Split(':'); int hh = int.Parse(tm[0]); int mm = int.Parse(tm[1]); int ss = int.Parse(tm[2]); // calculate seek seconds long sc = days * 24 * 60 * 60 + hh * 60 * 60 + mm * 60 + ss; // conver seconds to block number slider1.seek = (long)((float)(sc - FileHandler.id.starttimeSec) * (float)slider1.sampleRate / 56.0f) + 1; if (slider1.seek < 0) { slider1.seek = 0; } slider1.page = (long)((float)slider1.seek / (float)slider1.perPage); // refresh slider1.reload(); } }); ribon1.add("Process Button Presses", box.analyse, true, () => { // skip if file not loaded if (!FileHandler.available()) { return; } // open signal for analysing button presses formProcess frm = new formProcess(this); if (frm.ShowDialog() == DialogResult.OK) { if (frm.listBox1.SelectedIndex >= 0) { var aa = (formProcess.time)(frm.listBox1.Items[frm.listBox1.SelectedIndex]); slider1.seek = aa.block; slider1.reload(); } } }); ribon1.add("Settings", box.settings, false, () => { formSettings frm = new formSettings(this); frm.ShowDialog(); }); ribon1.add("About", box.i, false, () => { }); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); // skip if file not loaded if (!FileHandler.available()) { return; } // read sample rate from file sampleRate = FileHandler.readSampleRate(); graph1.sampleRate = sampleRate; slider1.sampleRate = sampleRate; // read settings Settings set = Settings.instance(); slider1.seek = set.lastSeek; slider1.blocks = set.lastBlocks; slider1.perPage = set.perPage; slider1.page = (long)(slider1.seek / slider1.perPage); slider1.blocksCount = FileHandler.blocksCount(); // config zoom and start point graph1.start = set.lastOffset; graph1.zoom = set.lastZoom; graph1.detection = set.detection; graph1.detectST = set.detectST; // load filtered samples graph1.samples = FileHandler.load(slider1); graph1.ecgid = FileHandler.id; slider1.critical = graph1.ecgid.critical; slider1.s2 = graph1.ecgid.starttimeSec; graph1.s2 = slider1.seek * 56.0f / slider1.sampleRate; slider1.Refresh(); graph1.Refresh(); // on scroll changes graph1.onChange = () => { if (!FileHandler.available()) { return; } set = Settings.instance(); set.lastOffset = graph1.start; set.lastZoom = graph1.zoom; set.commit(); }; // on slider position changes slider1.onChange = () => { if (!FileHandler.available()) { return; } set = Settings.instance(); set.lastSeek = slider1.seek; set.lastBlocks = slider1.blocks; set.perPage = slider1.perPage; graph1.samples = FileHandler.load(slider1); slider1.critical = FileHandler.id.critical; graph1.zoom = slider1.blocks * 56.0f / slider1.sampleRate; graph1.s2 = slider1.seek * 56.0f / slider1.sampleRate; if (slider1.seek < 0) { graph1.start = slider1.seek * 56.0f / slider1.sampleRate; } else { graph1.start = 0; } graph1.detection = set.detection; graph1.detectST = set.detectST; set.commit(); if (graph1.samples.Count < graph1.zoom * sampleRate) { graph1.zoom = (float)graph1.samples.Count / (float)sampleRate; } graph1.Refresh(); }; }
void run() { progressBar1.Minimum = 0; progressBar1.Maximum = 100; if (!FileHandler.available()) { return; } EcgStatistic set = FileHandler.id; if (set.critical == null) { set.critical = new List <long>(); } long len = FileHandler.blocksCount(); long i0 = 0; if (set.critical.Count > 2) { i0 = set.critical[set.critical.Count - 1] + 1; } for (long i = i0; i < len; i++) { FileHandler.setPosition(i); if (FileHandler.remainingBlocks() < 2) { break; } int sdm = FileHandler.io.ReadByte(); if (sdm == 170) { set.critical.Add(i); } progressBar1.Value = (int)((float)i / (float)len * 100.0f); progressBar1.Refresh(); } XmlClass <EcgStatistic> .Save(set, FileHandler.p + ".xml", SerializedFormat.Document); listBox1.Items.Clear(); if (set.critical != null) { foreach (var l in set.critical) { time t = new time(); t.block = l; t.sampleRate = main.graph1.sampleRate; t.s2 = FileHandler.id.starttimeSec; listBox1.Items.Add(t); } } progressBar1.Value = 0; progressBar1.Refresh(); MessageBox.Show("finish!"); }
/// <summary> /// load and filter signal /// </summary> /// <param name="slider">slider</param> /// <returns></returns> public static SignalSamples load(Slider slider) { // skip if file not exist if (!FileHandler.available()) { return(null); } // load samples Settings set = Settings.instance(); int sampleRate = FileHandler.readSampleRate(); SignalSamples samples = FileHandler.readBlocks(slider.seek, slider.blocks); samples = samples.Normalize(); samples.sampleRate = sampleRate; // find signal amplitude Signal deltaGreat = samples.FindMax() - samples.FindMin(); // 2x 12 hz filter if (set.noise12Hz) { samples.Filter(12, sampleRate / 2, 1.3f); samples.Filter(12, sampleRate / 2, 1.3f); } // 20 hz filter if (set.noise20Hz) { samples.Filter(20, sampleRate / 2, 1.3f); samples.Filter(20, sampleRate / 2, 1.3f); } // 45 hz filter if (set.noise45Hz) { samples.Filter(45, sampleRate / 2, 1.3f); } // 50hz or 60hz noise if (set.noiseCustom > 0) { samples.Filter(set.noiseCustom, sampleRate / 2, 1); } // notch filter if (set.noiseNotch) { samples = FilterNotch.Process(samples, 400, 0.1f); } // find signal loss enerrgy amplitude Signal deltaLess = samples.FindMax() - samples.FindMin(); // amplify loosed amplitude samples.Amplify(deltaGreat, deltaLess); // load file description FileHandler.id = XmlClass <EcgStatistic> .Load(FileHandler.p + ".xml", SerializedFormat.Document); return(samples); }
/// <summary> /// thread for faster analysing /// </summary> void run() { // skip if file not available if (!FileHandler.available()) { return; } progressBar1.Value = 0; // load sample rate sampleRate = FileHandler.readSampleRate(); // load samples samples = FileHandler.load(slider1); progressBar1.Value = 20; Application.DoEvents(); bool fst = false; // if signal was ecg if (decg.Checked) { // set samples graph1.samples = samples; graph1.sampleRate = sampleRate; graph1.ylabel = "mv"; } else { graph1.samples = new SignalSamples(); graph1.samples.sampleRate = 0; graph1.sampleRate = 0; bool stop = false; // initialize ecg arrays int[] tr = new int[3]; int[] offset = new int[3]; List <float>[] sigz = new List <float> [3]; EcgCharacteristics[] last = new EcgCharacteristics[3]; EcgCharacteristics[] now = new EcgCharacteristics[3]; // define ecg arrays for (int i = 0; i < 3; i++) { sigz[i] = new List <float>(); offset[i] = sampleRate; // detect first ecg signal last[i] = samples.FindDelta(i + 1, 0, offset[i]); tr[i] = 0; } // loop until signal is end do { for (int i = 0; i < 3; i++) { // detect second ecg signal now[i] = samples.FindDelta(i + 1, last[i].lastCharacteristic(), offset[i]); // find distrance between two pulses offset[i] = Math.Abs(now[i]["R"].idx - last[i]["R"].idx); // if the heart beat(pulse rate) between exact range if (offset[i] > 0 && offset[i] < sampleRate) { // find heart beat sample rate if (!fst) { graph1.samples.sampleRate += offset[i]; if (i == 2) { fst = true; } } float hpr = 0; // calculate ST line if (dst.Checked) { hpr = (now[i]["ST"].value - now[i]["Q"].value); } else if (dpr.Checked) // calculate heart beat { hpr = 60.0f / (float)(offset[i] / (float)sampleRate); } sigz[i].Add(hpr); } else { // if pulse rate was not reliable set offset as default sample rate offset[i] = sampleRate; } // if ecg data was not reliable try again if (now[i]["c"].idx <= 0 || now[i]["T"].idx <= 0) { tr[i]++; } // set last ecg signal if signal was out of range if (now[i].lastCharacteristic() <= last[i].lastCharacteristic()) { now[i]["c"].idx = last[i].lastCharacteristic() + offset[i]; } // skip if signal was out of range if (now[i].lastCharacteristic() + offset[i] > samples.Count) { tr[i] = 40; } // set last[i] = now[i]; } // return when data was end if (tr[0] > 30 && tr[1] > 30 && tr[2] > 30) { stop = true; } } while (!stop); // find maximum signal range int max = sigz[0].Count; for (int i = 0; i < 3; i++) { if (sigz[i].Count > max) { max = sigz[i].Count; } } // insert collected data as samples for (int i = 0; i < max; i++) { Signal sig = new Signal(); for (int j = 0; j < 3; j++) { if (i < sigz[j].Count) { sig[j + 1] = sigz[j][i]; } } graph1.samples.Add(sig); } // show results if (dpr.Checked) { graph1.ylabel = ""; } else if (dst.Checked) { graph1.ylabel = "mv"; } progressBar1.Value = 100; graph1.samples.sampleRate = (int)((float)sampleRate / (float)graph1.samples.sampleRate / 3.0f + 1); graph1.sampleRate = graph1.samples.sampleRate; graph1.samples.NoiseReduction(3); } graph1.zoom = (float)graph1.samples.Count / (float)graph1.sampleRate; graph1.Refresh(); working = false; }