예제 #1
0
        float[] GetSecondLead(string fileName)
        {
            IECGFormat format = null;

            var fmt = "SCP-ECG";

            IECGReader reader = ECGConverter.Instance.getReader(fmt);
            ECGConfig  cfg    = ECGConverter.Instance.getConfig(fmt);

            format = reader.Read(fileName, 0, cfg);

            Signals _CurrentSignal;

            format.Signals.getSignals(out _CurrentSignal);

            if (_CurrentSignal != null)
            {
                for (int i = 0, en = _CurrentSignal.NrLeads; i < en; i++)
                {
                    ECGTool.NormalizeSignal(_CurrentSignal[i].Rhythm, _CurrentSignal.RhythmSamplesPerSecond);
                }
            }

            Signals sig = _CurrentSignal.CalculateTwelveLeads();

            return(Array.ConvertAll(sig.GetLeads()[1].Rhythm, x => (float)(x)));
        }
예제 #2
0
        /// <summary>
        /// Function to resample all leads.
        /// </summary>
        /// <param name="samplesPerSecond">samples per second to resample towards</param>
        public void Resample(int samplesPerSecond)
        {
            foreach (Signal sig in this._Lead)
            {
                if ((this.RhythmSamplesPerSecond != 0) &&
                    (this.RhythmAVM != 0) &&
                    (sig.Rhythm != null))
                {
                    ECGTool.ResampleLead(sig.Rhythm, this.RhythmSamplesPerSecond, samplesPerSecond, out sig.Rhythm);

                    sig.RhythmStart = (int)(((long)sig.RhythmStart * (long)samplesPerSecond) / (long)this.RhythmSamplesPerSecond);
                    sig.RhythmEnd   = (int)(((long)sig.RhythmEnd * (long)samplesPerSecond) / (long)this.RhythmSamplesPerSecond);
                }

                if ((this.MedianSamplesPerSecond != 0) &&
                    (this.MedianAVM != 0) &&
                    (sig.Median != null))
                {
                    ECGTool.ResampleLead(sig.Median, this.MedianSamplesPerSecond, samplesPerSecond, out sig.Median);
                }
            }

            if (this.QRSZone != null)
            {
                foreach (QRSZone zone in this.QRSZone)
                {
                    zone.Start    = (int)(((long)zone.Start * (long)samplesPerSecond) / (long)this.MedianSamplesPerSecond);
                    zone.Fiducial = (int)(((long)zone.Fiducial * (long)samplesPerSecond) / (long)this.MedianSamplesPerSecond);
                    zone.End      = (int)(((long)zone.End * (long)samplesPerSecond) / (long)this.MedianSamplesPerSecond);
                }
            }

            if ((this.RhythmSamplesPerSecond != 0) &&
                (this.RhythmAVM != 0))
            {
                this.RhythmSamplesPerSecond = samplesPerSecond;
            }

            if ((this.MedianSamplesPerSecond != 0) &&
                (this.MedianAVM != 0))
            {
                this.MedianFiducialPoint = (ushort)(((long)this.MedianFiducialPoint * (long)samplesPerSecond) / (long)this.MedianSamplesPerSecond);

                this.MedianSamplesPerSecond = samplesPerSecond;
            }
        }
예제 #3
0
        /// <summary>
        /// Set AVM for all signals
        /// </summary>
        /// <param name="avm">preferred multiplier</param>
        public void SetAVM(double avm)
        {
            if (avm != 0.0)
            {
                int nrLeads = this.NrLeads;

                for (int i = 0; i < nrLeads; i++)
                {
                    ECGTool.ChangeMultiplier(this[i].Rhythm, this.RhythmAVM, avm);
                    ECGTool.ChangeMultiplier(this[i].Median, this.MedianAVM, avm);
                }

                if (this.RhythmAVM != 0.0)
                {
                    this.RhythmAVM = avm;
                }

                if (this.MedianAVM != 0.0)
                {
                    this.MedianAVM = avm;
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Function to make a twelve leads signals object.
        /// </summary>
        /// <returns>returns twelve leads signals object or null</returns>
        public Signals CalculateTwelveLeads()
        {
            LeadType[] lt = new LeadType[] { LeadType.I, LeadType.II, LeadType.III,
                                             LeadType.aVR, LeadType.aVL, LeadType.aVF,
                                             LeadType.V1, LeadType.V2, LeadType.V3,
                                             LeadType.V4, LeadType.V5, LeadType.V6 };

            int nrSim = NrSimultaneosly();

            if (nrSim != _Lead.Length)
            {
                return(null);
            }

            Signal[] leads = null;

            if (nrSim == 12)
            {
                ArrayList pos_list = new ArrayList(lt);

                int       check_one = 0;
                ArrayList check_two = new ArrayList(lt);
                Signal[]  pos       = new Signal[12];

                for (int i = 0; i < nrSim; i++)
                {
                    if (_Lead[i].Type == lt[i])
                    {
                        check_one++;
                    }

                    int temp = check_two.IndexOf(_Lead[i].Type);
                    if (temp < 0)
                    {
                        return(null);
                    }

                    check_two.RemoveAt(temp);

                    pos[pos_list.IndexOf(_Lead[i].Type)] = _Lead[i];
                }

                if (check_one == 12)
                {
                    return(this);
                }

                if (check_two.Count == 0)
                {
                    for (int i = 0; i < pos.Length; i++)
                    {
                        if (pos[i] != null)
                        {
                            pos[i] = pos[i].Clone();
                        }
                    }

                    leads = pos;
                }
            }
            else
            {
                short[][]
                tempRhythm = null,
                tempMedian = null;

                Signal[] pos = new Signal[12];

                if (nrSim == 8)
                {
                    ArrayList pos_list = new ArrayList(lt);

                    ArrayList check = new ArrayList(
                        new LeadType[] { LeadType.I, LeadType.II,
                                         LeadType.V1, LeadType.V2, LeadType.V3,
                                         LeadType.V4, LeadType.V5, LeadType.V6 });

                    for (int i = 0; i < nrSim; i++)
                    {
                        int temp = check.IndexOf(_Lead[i].Type);
                        if (temp < 0)
                        {
                            return(null);
                        }

                        check.RemoveAt(temp);

                        pos[pos_list.IndexOf(_Lead[i].Type)] = _Lead[i];
                    }

                    if (check.Count == 0)
                    {
                        for (int i = 0; i < pos.Length; i++)
                        {
                            if (pos[i] != null)
                            {
                                pos[i] = pos[i].Clone();
                            }
                        }

                        tempRhythm    = new short[2][];
                        tempRhythm[0] = pos[0].Rhythm;
                        tempRhythm[1] = pos[1].Rhythm;

                        tempMedian    = new short[2][];
                        tempMedian[0] = pos[0].Median;
                        tempMedian[1] = pos[1].Median;
                    }
                }
                else if (nrSim == 9)
                {
                    ArrayList pos_list = new ArrayList(lt);

                    ArrayList check = new ArrayList(
                        new LeadType[] { LeadType.I, LeadType.II, LeadType.III,
                                         LeadType.V1, LeadType.V2, LeadType.V3,
                                         LeadType.V4, LeadType.V5, LeadType.V6 });

                    for (int i = 0; i < nrSim; i++)
                    {
                        int temp = check.IndexOf(_Lead[i].Type);
                        if (temp < 0)
                        {
                            return(null);
                        }

                        check.RemoveAt(temp);

                        pos[pos_list.IndexOf(_Lead[i].Type)] = _Lead[i];
                    }

                    if (check.Count == 0)
                    {
                        for (int i = 0; i < pos.Length; i++)
                        {
                            if (pos[i] != null)
                            {
                                pos[i] = pos[i].Clone();
                            }
                        }

                        tempRhythm    = new short[3][];
                        tempRhythm[0] = pos[0].Rhythm;
                        tempRhythm[1] = pos[1].Rhythm;
                        tempRhythm[2] = pos[2].Rhythm;

                        tempMedian    = new short[3][];
                        tempMedian[0] = pos[0].Median;
                        tempMedian[1] = pos[1].Median;
                        tempMedian[2] = pos[2].Median;
                    }
                }

                if ((tempRhythm != null) ||
                    (tempMedian != null))
                {
                    short[][] calcLeads;

                    if ((tempRhythm != null) &&
                        (tempRhythm[0] != null) &&
                        ECGTool.CalculateLeads(tempRhythm, tempRhythm[0].Length, out calcLeads) == 0)
                    {
                        for (int i = 0; i < calcLeads.Length; i++)
                        {
                            Signal sig = new Signal();
                            sig.Type        = lt[i + tempRhythm.Length];
                            sig.RhythmStart = pos[0].RhythmStart;
                            sig.RhythmEnd   = pos[0].RhythmEnd;
                            sig.Rhythm      = calcLeads[i];

                            pos[i + tempRhythm.Length] = sig;
                        }

                        if ((tempMedian != null) &&
                            (tempMedian[0] != null) &&
                            (ECGTool.CalculateLeads(tempMedian, tempMedian[0].Length, out calcLeads) == 0))
                        {
                            for (int i = 0; i < calcLeads.Length; i++)
                            {
                                pos[i + tempRhythm.Length].Median = calcLeads[i];
                            }
                        }

                        leads = pos;
                    }
                }
            }

            if (leads != null)
            {
                Signals sigs = this.Clone();

                sigs.NrLeads = (byte)leads.Length;

                for (int i = 0; i < leads.Length; i++)
                {
                    sigs._Lead[i] = leads[i];
                }

                return(sigs);
            }

            return(null);
        }
예제 #5
0
        /// <summary>
        /// Function to make a fifteen leads signals object.
        /// </summary>
        /// <returns>returns fifteen leads signals object or null</returns>
        public Signals CalculateFifteenLeads()
        {
            LeadType[] lt1 = new LeadType[] { LeadType.I, LeadType.II, LeadType.III,
                                              LeadType.aVR, LeadType.aVL, LeadType.aVF,
                                              LeadType.V1, LeadType.V2, LeadType.V3,
                                              LeadType.V4, LeadType.V5, LeadType.V6,
                                              LeadType.V3R, LeadType.V4R, LeadType.V7 };
            LeadType[] lt2 = new LeadType[] { LeadType.I, LeadType.II, LeadType.III,
                                              LeadType.aVR, LeadType.aVL, LeadType.aVF,
                                              LeadType.V1, LeadType.V2, LeadType.V3,
                                              LeadType.V4, LeadType.V5, LeadType.V6,
                                              LeadType.V7, LeadType.V8, LeadType.V9 };

            int nrSim = NrSimultaneosly();

            if (nrSim != _Lead.Length)
            {
                return(null);
            }

            Signal[] leads = null;

            if (nrSim == lt1.Length)
            {
                ArrayList pos_list1 = new ArrayList(lt1);
                ArrayList pos_list2 = new ArrayList(lt2);

                int       check_one1 = 0;
                int       check_one2 = 0;
                ArrayList check_two1 = new ArrayList(lt1);
                ArrayList check_two2 = new ArrayList(lt2);
                Signal[]  pos1       = new Signal[lt1.Length];
                Signal[]  pos2       = new Signal[lt2.Length];

                for (int i = 0; i < nrSim; i++)
                {
                    if (_Lead[i].Type == lt1[i])
                    {
                        check_one1++;
                    }

                    if (_Lead[i].Type == lt2[i])
                    {
                        check_one2++;
                    }

                    int temp = check_two1.IndexOf(_Lead[i].Type);
                    if (temp >= 0)
                    {
                        check_two1.RemoveAt(temp);

                        pos1[pos_list1.IndexOf(_Lead[i].Type)] = _Lead[i];
                    }
                    temp = check_two2.IndexOf(_Lead[i].Type);
                    if (temp >= 0)
                    {
                        check_two2.RemoveAt(temp);

                        pos2[pos_list2.IndexOf(_Lead[i].Type)] = _Lead[i];
                    }
                }

                if (check_one1 == lt1.Length)
                {
                    return(this);
                }
                if (check_one2 == lt2.Length)
                {
                    return(this);
                }

                if (check_two1.Count == 0)
                {
                    for (int i = 0; i < pos1.Length; i++)
                    {
                        if (pos1[i] != null)
                        {
                            pos1[i] = pos1[i].Clone();
                        }
                    }

                    leads = pos1;
                }
                else if (check_two2.Count == 0)
                {
                    for (int i = 0; i < pos2.Length; i++)
                    {
                        if (pos2[i] != null)
                        {
                            pos2[i] = pos2[i].Clone();
                        }
                    }

                    leads = pos2;
                }
            }
            else
            {
                LeadType[] lt = null;

                short[][]
                tempRhythm = null,
                tempMedian = null;

                Signal[] pos = null;

                if (nrSim == 11)
                {
                    Signal[] pos1 = new Signal[lt1.Length];
                    Signal[] pos2 = new Signal[lt2.Length];

                    ArrayList pos_list1 = new ArrayList(lt1);
                    ArrayList pos_list2 = new ArrayList(lt2);

                    ArrayList check1 = new ArrayList(
                        new LeadType[] { LeadType.I, LeadType.II,
                                         LeadType.V1, LeadType.V2, LeadType.V3,
                                         LeadType.V4, LeadType.V5, LeadType.V6,
                                         LeadType.V7, LeadType.V3R, LeadType.V4R });

                    ArrayList check2 = new ArrayList(
                        new LeadType[] { LeadType.I, LeadType.II,
                                         LeadType.V1, LeadType.V2, LeadType.V3,
                                         LeadType.V4, LeadType.V5, LeadType.V6,
                                         LeadType.V7, LeadType.V8, LeadType.V9 });

                    for (int i = 0; i < nrSim; i++)
                    {
                        int temp = check1.IndexOf(_Lead[i].Type);
                        if (temp >= 0)
                        {
                            check1.RemoveAt(temp);

                            pos1[pos_list1.IndexOf(_Lead[i].Type)] = _Lead[i];
                        }
                        temp = check2.IndexOf(_Lead[i].Type);
                        if (temp >= 0)
                        {
                            check2.RemoveAt(temp);

                            pos2[pos_list2.IndexOf(_Lead[i].Type)] = _Lead[i];
                        }
                    }

                    if (check1.Count == 0)
                    {
                        pos = pos1;
                        lt  = lt1;
                    }
                    else if (check2.Count == 0)
                    {
                        pos = pos2;
                        lt  = lt2;
                    }

                    if (pos != null)
                    {
                        for (int i = 0; i < pos.Length; i++)
                        {
                            if (pos[i] != null)
                            {
                                pos[i] = pos[i].Clone();
                            }
                        }

                        tempRhythm    = new short[2][];
                        tempRhythm[0] = pos1[0].Rhythm;
                        tempRhythm[1] = pos1[1].Rhythm;

                        tempMedian    = new short[2][];
                        tempMedian[0] = pos1[0].Median;
                        tempMedian[1] = pos1[1].Median;
                    }
                }
                else if (nrSim == 12)
                {
                    Signal[] pos1 = new Signal[lt1.Length];
                    Signal[] pos2 = new Signal[lt2.Length];

                    ArrayList pos_list1 = new ArrayList(lt1);
                    ArrayList pos_list2 = new ArrayList(lt2);

                    ArrayList check1 = new ArrayList(
                        new LeadType[] { LeadType.I, LeadType.II, LeadType.III,
                                         LeadType.V1, LeadType.V2, LeadType.V3,
                                         LeadType.V4, LeadType.V5, LeadType.V6,
                                         LeadType.V7, LeadType.V3R, LeadType.V4R });

                    ArrayList check2 = new ArrayList(
                        new LeadType[] { LeadType.I, LeadType.II, LeadType.III,
                                         LeadType.V1, LeadType.V2, LeadType.V3,
                                         LeadType.V4, LeadType.V5, LeadType.V6,
                                         LeadType.V7, LeadType.V8, LeadType.V9 });

                    for (int i = 0; i < nrSim; i++)
                    {
                        int temp = check1.IndexOf(_Lead[i].Type);
                        if (temp >= 0)
                        {
                            check1.RemoveAt(temp);

                            pos1[pos_list1.IndexOf(_Lead[i].Type)] = _Lead[i];
                        }
                        temp = check2.IndexOf(_Lead[i].Type);
                        if (temp >= 0)
                        {
                            check2.RemoveAt(temp);

                            pos2[pos_list2.IndexOf(_Lead[i].Type)] = _Lead[i];
                        }
                    }

                    if (check1.Count == 0)
                    {
                        pos = pos1;
                        lt  = lt1;
                    }
                    else if (check2.Count == 0)
                    {
                        pos = pos2;
                        lt  = lt2;
                    }

                    if (pos != null)
                    {
                        for (int i = 0; i < pos.Length; i++)
                        {
                            if (pos[i] != null)
                            {
                                pos[i] = pos[i].Clone();
                            }
                        }

                        tempRhythm    = new short[3][];
                        tempRhythm[0] = pos[0].Rhythm;
                        tempRhythm[1] = pos[1].Rhythm;
                        tempRhythm[2] = pos[2].Rhythm;

                        tempMedian    = new short[3][];
                        tempMedian[0] = pos[0].Median;
                        tempMedian[1] = pos[1].Median;
                        tempMedian[2] = pos[2].Median;
                    }
                }

                if ((tempRhythm != null) ||
                    (tempMedian != null))
                {
                    short[][] calcLeads;

                    if ((tempRhythm != null) &&
                        (tempRhythm[0] != null) &&
                        ECGTool.CalculateLeads(tempRhythm, tempRhythm[0].Length, out calcLeads) == 0)
                    {
                        for (int i = 0; i < calcLeads.Length; i++)
                        {
                            Signal sig = new Signal();
                            sig.Type        = lt[i + tempRhythm.Length];
                            sig.RhythmStart = pos[0].RhythmStart;
                            sig.RhythmEnd   = pos[0].RhythmEnd;
                            sig.Rhythm      = calcLeads[i];

                            pos[i + tempRhythm.Length] = sig;
                        }

                        if ((tempMedian != null) &&
                            (tempMedian[0] != null) &&
                            (ECGTool.CalculateLeads(tempMedian, tempMedian[0].Length, out calcLeads) == 0))
                        {
                            for (int i = 0; i < calcLeads.Length; i++)
                            {
                                pos[i + tempRhythm.Length].Median = calcLeads[i];
                            }
                        }

                        leads = pos;
                    }
                }
            }

            if (leads != null)
            {
                Signals sigs = this.Clone();

                sigs.NrLeads = (byte)leads.Length;

                for (int i = 0; i < leads.Length; i++)
                {
                    sigs._Lead[i] = leads[i];
                }

                return(sigs);
            }

            return(null);
        }
예제 #6
0
        /// <summary>
        /// Function to encode data in this section.
        /// </summary>
        /// <param name="data">Rhythm data to encode</param>
        /// <param name="tables">Huffman table to use during enconding</param>
        /// <param name="leadDefinition">Lead Definitions to use for encoding</param>
        /// <param name="difference">difference to use durring decoding</param>
        /// <returns>0 on succes</returns>
        public int EncodeData(short[][] data, SCPSection2 tables, SCPSection3 leadDefinition, SCPSection4 qrsLocations, int medianFreq, byte difference)
        {
            int localFreq = getSamplesPerSecond();

            if ((data != null) &&
                (tables != null) &&
                (leadDefinition != null) &&
                (localFreq > 0))
            {
                if ((medianFreq <= 0) ||
                    (medianFreq == localFreq))
                {
                    medianFreq = 1;
                    localFreq  = 1;
                }

                if ((_Bimodal == 0x1) &&
                    (qrsLocations == null))
                {
                    return(2);
                }

                ushort nrleads = leadDefinition.getNrLeads();
                _Data       = new byte[nrleads][];
                _DataLength = new ushort[nrleads];
                for (int loper = 0; loper < nrleads; loper++)
                {
                    if (data[loper] == null)
                    {
                        return(4);
                    }

                    short[] temp = data[loper];

                    int time = (leadDefinition.getLeadLength(loper) * localFreq) / medianFreq;
                    if (localFreq != medianFreq)
                    {
                        int rate = (medianFreq / localFreq);
                        // Bimodal part might be buggy unable to test.
                        if ((_Bimodal == 0x1) &&
                            ((medianFreq % localFreq) == 0) &&
                            (rate > 0) &&
                            (rate < 5))
                        {
                            // Calculate nr of samples stored in section.
                            time = 0;

                            int nrzones = qrsLocations.getNrProtectedZones();
                            for (int zone = 0; zone < nrzones; zone++)
                            {
                                int begin = (qrsLocations.getProtectedStart(zone) >= leadDefinition.getLeadStart(loper) ? qrsLocations.getProtectedStart(zone) : leadDefinition.getLeadStart(loper));
                                int end   = (qrsLocations.getProtectedEnd(zone) <= leadDefinition.getLeadEnd(loper) ? qrsLocations.getProtectedEnd(zone) : leadDefinition.getLeadEnd(loper));

                                begin = (end > begin ? end - begin + 1 : 0);

                                time += begin + (rate - (begin % rate));
                            }

                            time += ((leadDefinition.getLeadLength(loper) - time) * localFreq) / medianFreq;

                            int leadLength = leadDefinition.getLeadLength(loper);

                            time += ((leadLength - time) * localFreq) / medianFreq;

                            // Restructure bimodal data to length set in Section3.
                            temp = new short[time];

                            int time2Offset = leadDefinition.getLeadStart(loper);
                            int time1       = 0;
                            int time2       = 0;

                            while ((time1 < temp.Length) &&
                                   (time2 <= leadLength) &&
                                   (time2 < data[loper].Length))
                            {
                                int zone = 0;
                                int end  = qrsLocations.getNrProtectedZones();
                                for (; zone < end; zone++)
                                {
                                    if ((qrsLocations.getProtectedLength(zone) > 0) &&
                                        (time2 + time2Offset >= qrsLocations.getProtectedStart(zone)) &&
                                        (time2 + time2Offset <= qrsLocations.getProtectedEnd(zone)))
                                    {
                                        break;
                                    }
                                }

                                if (zone < end)
                                {
                                    temp[time1] = data[loper][time2++];
                                }
                                else
                                {
                                    int Sum = 0;
                                    for (int sumLoper = 0; sumLoper < rate; sumLoper++)
                                    {
                                        Sum += data[loper][time2 + sumLoper];
                                    }
                                    temp[time1] = (short)(Sum / rate);
                                    time2      += rate;
                                }

                                time1++;
                            }
                        }
                        else
                        {
                            _Bimodal = 0;
                            ECGTool.ResampleLead(temp, medianFreq, localFreq, out temp);
                        }
                    }

                    _Difference  = difference;
                    _Data[loper] = tables.Encode(temp, time, 0, _Difference);
                    if (_Data[loper] == null)
                    {
                        _Data       = null;
                        _DataLength = null;
                        return(8);
                    }
                    _DataLength[loper] = (ushort)_Data[loper].Length;
                    if ((_DataLength[loper] & 0x1) == 0x1)
                    {
                        _DataLength[loper]++;
                    }
                }
                return(0);
            }
            return(1);
        }
예제 #7
0
        /// <summary>
        /// Function to decode data in this section.
        /// </summary>
        /// <param name="tables">Huffman table to use during deconding</param>
        /// <param name="leadDefinition"></param>
        /// <returns>decoded leads</returns>
        public short[][] DecodeData(SCPSection2 tables, SCPSection3 leadDefinition, SCPSection4 qrsLocations, int medianFreq)
        {
            int localFreq = getSamplesPerSecond();

            if (Works() &&
                (tables != null) &&
                (tables.Works()) &&
                (leadDefinition != null) &&
                (leadDefinition.Works()) &&
                (leadDefinition.getNrLeads() == _Data.Length) &&
                (localFreq > 0))
            {
                if ((medianFreq <= 0) ||
                    (medianFreq == localFreq))
                {
                    medianFreq = 1;
                    localFreq  = 1;
                }

                if ((medianFreq < localFreq) &&
                    !leadDefinition.isMediansUsed() &&
                    (_Bimodal == 0x0))
                {
                    medianFreq = localFreq;
                }

                if (((medianFreq % localFreq) != 0) ||
                    ((medianFreq / localFreq) < 1) ||
                    ((medianFreq / localFreq) > 4))
                {
                    // make an exception for ECGs that don't use compression (like corpuls ECGs that are in violation of this rule).
                    if (_Bimodal == 0x0)
                    {
                        medianFreq = localFreq;
                    }
                    else
                    {
                        return(null);
                    }
                }

                if ((_Bimodal == 0x1) &&
                    (qrsLocations == null))
                {
                    return(null);
                }

                // Reset selected table.
                tables.ResetSelect();

                short[][] leads = new short[_Data.Length][];
                for (int loper = 0; loper < _Data.Length; loper++)
                {
                    int time = (leadDefinition.getLeadLength(loper) * localFreq) / medianFreq;

                    // Bimodal part might be buggy unable to test.
                    if ((localFreq != medianFreq) &&
                        (_Bimodal == 0x1))
                    {
                        int rate = medianFreq / localFreq;

                        // Calculate nr of samples stored in section.
                        time = 0;

                        int nrzones = qrsLocations.getNrProtectedZones();
                        for (int zone = 0; zone < nrzones; zone++)
                        {
                            int begin = (qrsLocations.getProtectedStart(zone) >= leadDefinition.getLeadStart(loper) ? qrsLocations.getProtectedStart(zone) : leadDefinition.getLeadStart(loper));
                            int end   = (qrsLocations.getProtectedEnd(zone) <= leadDefinition.getLeadEnd(loper) ? qrsLocations.getProtectedEnd(zone) : leadDefinition.getLeadEnd(loper));

                            begin = (end > begin ? end - begin + 1 : 0);

                            time += begin + (rate - (begin % rate));
                        }

                        time += ((leadDefinition.getLeadLength(loper) - time) * localFreq) / medianFreq;
                    }

                    leads[loper] = tables.Decode(_Data[loper], 0, _Data[loper].Length, time, _Difference);
                    // Check if lead was decoded
                    if (leads[loper] == null)
                    {
                        // return if lead decode failed.
                        return(null);
                    }

                    if (localFreq != medianFreq)
                    {
                        int rate = medianFreq / localFreq;
                        if (_Bimodal == 0x1)
                        {
                            int beginNonProtected = 0;
                            int endNonProtected   = qrsLocations.getProtectedStart(0);
                            // Restructure bimodal data to length set in Section3.
                            short[] temp = new short[leadDefinition.getLeadLength(loper)];

                            int time1Offset = leadDefinition.getLeadStart(loper);
                            int time1       = 0;
                            int time2       = 0;

                            int zone = 0;

                            while ((time1 < temp.Length) &&
                                   (time2 < leads[loper].Length))
                            {
                                if (((time1 + time1Offset) >= beginNonProtected) &&
                                    ((time1 + time1Offset) < endNonProtected))
                                {
                                    for (int begin = 0; begin < (rate >> 1); begin++)
                                    {
                                        temp[time1++] = leads[loper][time2];
                                    }

                                    if ((time2 + ((endNonProtected - (time1 + time1Offset)) / rate)) >= leads[loper].Length)
                                    {
                                        endNonProtected -= ((time2 + ((endNonProtected - (time1 + time1Offset)) / rate)) - leads[loper].Length) * rate;
                                    }

                                    endNonProtected -= rate + (rate >> 1);

                                    while ((time1 + time1Offset) < endNonProtected)
                                    {
                                        for (int i = 0; (i < rate) && (time1 < temp.Length); i++)
                                        {
                                            temp[time1++] = (short)(((leads[loper][time2 + 1] - leads[loper][time2]) / rate) * i + leads[loper][time2]);
                                        }
                                        time2++;
                                    }

                                    endNonProtected += rate + (rate >> 1);

                                    for (int end = 0; end < (rate >> 1); end++)
                                    {
                                        temp[time1++] = leads[loper][time2];
                                    }

                                    time2++;

                                    beginNonProtected = (zone == qrsLocations.getNrProtectedZones() ? temp.Length : qrsLocations.getProtectedEnd(zone));
                                }
                                else
                                {
                                    // This should never happen!!
                                    if (zone == qrsLocations.getNrProtectedZones())
                                    {
                                        break;
                                    }

                                    while (((time1 + time1Offset) < qrsLocations.getProtectedEnd(zone)) &&
                                           (time1 < temp.Length) &&
                                           (time2 < leads[loper].Length))
                                    {
                                        temp[time1++] = leads[loper][time2++];
                                    }
                                    zone++;
                                    endNonProtected = (zone == qrsLocations.getNrProtectedZones() ? temp.Length : qrsLocations.getProtectedStart(zone));
                                }
                            }

                            leads[loper] = temp;
                        }
                        else
                        {
                            ECGTool.ResampleLead(leads[loper], localFreq, medianFreq, out leads[loper]);
                        }
                    }
                }
                return(leads);
            }
            return(null);
        }
예제 #8
0
 public override void Anonymous(byte type)
 {
     ECGTool.Anonymous(Demographics, (char)type);
 }
예제 #9
0
        public int setSignals(Signals signals)
        {
            if ((signals != null) &&
                (signals.NrLeads > 0))
            {
                // Decide wich encoding to use.
                switch (_EncodingType)
                {
                case EncodingType.None:
                    ((SCPSection2)_Default[2]).UseNoHuffman();
                    break;

                case EncodingType.OptimizedHuffman:
                    // not implemented!
                    ((SCPSection2)_Default[2]).UseStandard();
                    break;

                case EncodingType.DefaultHuffman:
                default:
                    ((SCPSection2)_Default[2]).UseStandard();
                    break;
                }

                if (((ISignal)_Default[3]).setSignals(signals) != 0)
                {
                    return(2);
                }

                SCPSection5 median = (SCPSection5)_Default[5];
                median.setAVM(signals.MedianAVM);
                median.setSamplesPerSecond(signals.MedianSamplesPerSecond);

                SCPSection6 rhythm = (SCPSection6)_Default[6];
                rhythm.setAVM(signals.RhythmAVM);
                rhythm.setSamplesPerSecond(signals.RhythmSamplesPerSecond);

                short[][] rhythmData = new short[signals.NrLeads][];
                short[][] medianData = new short[signals.NrLeads][];
                for (int loper = 0; loper < signals.NrLeads; loper++)
                {
                    if (signals[loper].Rhythm == null)
                    {
                        return(4);
                    }
                    rhythmData[loper] = signals[loper].Rhythm;
                    if ((medianData == null) ||
                        (signals[loper].Median == null))
                    {
                        medianData = null;
                    }
                    else
                    {
                        medianData[loper] = signals[loper].Median;
                    }
                }

                if (medianData != null)
                {
                    if (((ISignal)_Default[4]).setSignals(signals) != 0)
                    {
                        return(8);
                    }

                    if (signals.MedianSamplesPerSecond < signals.RhythmSamplesPerSecond)
                    {
                        median.setSamplesPerSecond(signals.RhythmSamplesPerSecond);
                        ECGTool.ResampleSignal(medianData, signals.MedianSamplesPerSecond, signals.RhythmSamplesPerSecond, out medianData);
                    }

                    if (median.EncodeData(medianData, (SCPSection2)_Default[2], (ushort)((signals.MedianLength * signals.MedianSamplesPerSecond) / 1000), (_EncodingType == EncodingType.None ? (byte)0 : _DifferenceDataSection5Used)) != 0)
                    {
                        return(16);
                    }

                    if (signals.QRSZone != null)
                    {
                        if (signals.RhythmAVM <= signals.MedianAVM)
                        {
                            ECGTool.ChangeMultiplier(medianData, signals.MedianAVM, signals.RhythmAVM);
                        }
                        else
                        {
                            ECGTool.ChangeMultiplier(rhythmData, signals.RhythmAVM, signals.MedianAVM);
                            rhythm.setAVM(signals.MedianAVM);
                        }
                    }

                    ECGTool.ResampleSignal(rhythmData, signals.RhythmSamplesPerSecond, median.getSamplesPerSecond(), out rhythmData);

                    if (_QRSSubtractionSupport &&
                        (signals.QRSZone != null))
                    {
                        ((SCPSection3)_Default[3]).setMediansUsed(true);
                        ((SCPSection4)_Default[4]).SubtractMedians((SCPSection3)_Default[3], rhythmData, medianData);
                    }
                }

                if (_BimodalCompressionUsed &&
                    (_BimodalCompressionRate > 0) &&
                    (medianData != null) &&
                    (signals.QRSZone != null))
                {
                    // Bimodal Compression must be set in set section 6.
                    rhythm.setBimodal(true);
                    rhythm.setSamplesPerSecond(signals.MedianSamplesPerSecond / _BimodalCompressionRate);

                    // Determine QRS zones for bimodal compression
                    GlobalMeasurements global;
                    ((IGlobalMeasurement)_Default[7]).getGlobalMeasurements(out global);
                    ((SCPSection4)_Default[4]).setProtected(global, median.getSamplesPerSecond(), _BimodalCompressionRate, ((SCPSection3)_Default[3]).getMinBegin(), ((SCPSection3)_Default[3]).getMaxEnd());
                }

                if (rhythm.EncodeData(rhythmData, (SCPSection2)_Default[2], (SCPSection3)_Default[3], (SCPSection4)_Default[4], signals.MedianSamplesPerSecond, (_EncodingType == EncodingType.None ? (byte)0 : _DifferenceDataSection6Used)) != 0)
                {
                    return(32);
                }
                return(0);
            }
            return(1);
        }
예제 #10
0
        public int getSignalsToObj(Signals signals)
        {
            if (signals != null)
            {
                if (((ISignal)_Default[3]).getSignalsToObj(signals) != 0)
                {
                    return(2);
                }

                short[][] medianData = null;
                if (((ISignal)_Default[4]).getSignalsToObj(signals) == 0)
                {
                    SCPSection5 median = (SCPSection5)_Default[5];

                    if (median == null)
                    {
                        return(4);
                    }

                    medianData = median.DecodeData((SCPSection2)_Default[2], signals.MedianLength);

                    signals.MedianAVM = median.getAVM();
                    signals.MedianSamplesPerSecond = median.getSamplesPerSecond();

                    for (int loper = 0; loper < signals.NrLeads; loper++)
                    {
                        signals[loper].Median = medianData[loper];
                    }
                }
                else
                {
                    // this will make sure that Decoding of rhythm data will work also for strange files
                    signals.MedianAVM              = 0;
                    signals.MedianLength           = 0;
                    signals.MedianSamplesPerSecond = 0;
                }

                SCPSection6 rhythm     = (SCPSection6)_Default[6];
                short[][]   rhythmData = rhythm.DecodeData((SCPSection2)_Default[2], (SCPSection3)_Default[3], (SCPSection4)_Default[4], signals.MedianSamplesPerSecond);
                signals.RhythmAVM = rhythm.getAVM();

                if (rhythmData == null)
                {
                    return(8);
                }

                if ((medianData != null) &&
                    (((SCPSection3)_Default[3]).isMediansUsed()))
                {
                    // check this because corpuls ECG are in violation of this rule, but don't use median subtraction
                    if (((signals.MedianSamplesPerSecond % signals.RhythmSamplesPerSecond) != 0) ||
                        ((signals.MedianSamplesPerSecond / signals.RhythmSamplesPerSecond) < 1) ||
                        ((signals.MedianSamplesPerSecond / signals.RhythmSamplesPerSecond) > 4))
                    {
                        return(16);
                    }

                    if (signals.RhythmAVM <= signals.MedianAVM)
                    {
                        ECGTool.ChangeMultiplier(medianData, signals.MedianAVM, signals.RhythmAVM);
                        signals.MedianAVM = signals.RhythmAVM;
                    }
                    else
                    {
                        ECGTool.ChangeMultiplier(rhythmData, signals.RhythmAVM, signals.MedianAVM);
                        signals.RhythmAVM = signals.MedianAVM;
                    }

                    signals.RhythmSamplesPerSecond = signals.MedianSamplesPerSecond;

                    ((SCPSection4)_Default[4]).AddMedians((SCPSection3)_Default[3], rhythmData, medianData);
                }
                else
                {
                    signals.RhythmAVM = rhythm.getAVM();
                    signals.RhythmSamplesPerSecond = rhythm.getSamplesPerSecond();

                    // Begin: special correction for SCP-ECG by corpuls (part 2)
                    if ((_Default[5] != null) &&
                        _Default[5].Works())
                    {
                        SCPSection5 medianSpecial = (SCPSection5)_Default[5];

                        signals.MedianLength           = 1000;
                        signals.MedianAVM              = medianSpecial.getAVM();
                        signals.MedianSamplesPerSecond = medianSpecial.getSamplesPerSecond();

                        medianData = medianSpecial.DecodeData((SCPSection2)_Default[2], signals.MedianLength);

                        if (medianData != null)
                        {
                            for (int loper = 0; loper < signals.NrLeads; loper++)
                            {
                                signals[loper].Median = medianData[loper];
                            }
                        }
                        else
                        {
                            signals.MedianLength           = 0;
                            signals.MedianAVM              = 0;
                            signals.MedianSamplesPerSecond = 0;
                        }
                    }
                    // End: special correction for SCP-ECG by corpuls (part 2)
                }

                for (int loper = 0; loper < signals.NrLeads; loper++)
                {
                    signals[loper].Rhythm = rhythmData[loper];
                }

                return(0);
            }
            return(1);
        }
예제 #11
0
        public int setSignals(Signals signals)
        {
            if ((signals != null) &&
                (signals.NrLeads != 0) &&
                (signals.RhythmAVM > 0) &&
                (signals.RhythmSamplesPerSecond > 0))
            {
                if (_DummyHeader.setSignals(signals) != 0)
                {
                    return(2);
                }

                // Determine minimum start.
                int minstart = int.MaxValue;
                for (int lead = 0; lead < signals.NrLeads; lead++)
                {
                    if (signals[lead] != null)
                    {
                        minstart = Math.Min(minstart, signals[lead].RhythmStart);
                    }
                }

                int samplesBeforeResample = (int)(_DummyHeader.getNrSamplesPerLead() * signals.RhythmSamplesPerSecond) / 500;

                short[] position = new short[NeededLeads.Length];
                for (int find = 0; find < NeededLeads.Length; find++)
                {
                    int p = 0;
                    for (; p < signals.NrLeads; p++)
                    {
                        if ((signals[p] != null) &&
                            (signals[p].Type == NeededLeads[find]) &&
                            (signals[p].Rhythm != null))
                        {
                            break;
                        }
                    }
                    if (p == signals.NrLeads)
                    {
                        p = -1;
                    }
                    position[find] = (short)p;
                }

                short[][] data = new short[_DummyHeader.getNrLeads()][];
                for (int lead = 0; lead < _DummyHeader.getNrLeads(); lead++)
                {
                    if (position[lead] != -1)
                    {
                        data[lead] = new short[samplesBeforeResample];
                        for (int sample = signals[position[lead]].RhythmStart; sample < signals[position[lead]].RhythmEnd; sample++)
                        {
                            data[lead][sample - minstart] = signals[position[lead]].Rhythm[sample - signals[position[lead]].RhythmStart];
                        }
                    }
                }


                for (int lead = 0; lead < _DummyHeader.getNrLeads(); lead++)
                {
                    if (data[lead] == null)
                    {
                        if ((NeededLeads[lead] == LeadType.III) &&
                            (data[6] != null) &&
                            (data[7] != null))
                        {
                            data[lead] = ECGTool.CalculateLeadIII(data[6], 0, data[6].Length, data[7], 0, data[7].Length, data[6].Length);
                        }
                        else
                        {
                            return(4);
                        }
                    }
                }

                ECGTool.ResampleSignal(data, samplesBeforeResample, signals.RhythmSamplesPerSecond, 500, out data);
                ECGTool.ChangeMultiplier(data, signals.RhythmAVM, 2.5);

                if (_Data.Encode(data, (int)_DummyHeader.getNrSamplesPerLead()) != 0)
                {
                    return(8);
                }

                return(0);
            }
            return(1);
        }