Beispiel #1
0
        /// <summary>
        /// searching peaks using frames of 'framesize' width
        /// </summary>
        /// <param name="array"></param>
        /// <param name="framesize"></param>
        /// <param name="set_status"></param>
        /// <returns></returns>
        peak[] extract_peaks_using_frame(double[] array, int framesize, peak_status set_status)
        {
            peak[] peaks = null;
            int    i, j, offset, max_i, min_i, min_i2;
            int    n       = array.Length;
            int    peaks_n = (n + framesize - 1) / framesize;

            peaks = new peak[peaks_n];

            for (i = 0; i < peaks_n; ++i)
            {
                offset = i * framesize;
                max_i  = offset;
                for (j = 0; (j < framesize) && (j + offset < n); j++)
                {
                    if (array[max_i] < array[offset + j])
                    {
                        max_i = offset + j;
                    }
                }

                // calculate front's length and amplitude

                // find previous local minimum
                for (min_i = max_i - 1; (min_i >= 0) && (array[min_i] <= array[min_i + 1]); min_i--)
                {
                }
                ;
                if (min_i < 0)
                {
                    min_i = max_i;
                }

                // find next local minimum (for measuring after_fall_magnitude)
                for (min_i2 = max_i + 1; (min_i2 < array.Length - 1) && (array[min_i2] <= array[min_i2 - 1]); min_i2++)
                {
                }
                ;

                // we must pass the real minimum value to leave the cycle, so this little fixup is required
                --min_i2;

                peaks[i].front_amplitude      = array[max_i] - array[min_i];
                peaks[i].after_fall_magnitude = array[min_i2] -
                                                array[max_i];
                peaks[i].front_length = max_i - min_i;
                peaks[i].peak_length  = min_i2 - min_i;

                peaks[i].value    = array[max_i];
                peaks[i].position = max_i;
                peaks[i].status   = set_status;
            }

#if DEBUG
            // write peaks to file for analysis
            //System.Diagnostics.Debug.Fail("Write peaks to file for further analysis -- NOT IMPLEMENTED!");
#endif

            return(peaks);
        }
Beispiel #2
0
 void peaks_change_status(peak[] peaks, peak_status status_in, peak_status status_out)
 {
     for (int i = 0; i < peaks.Length; ++i)
     {
         if (peaks[i].status == status_in)
         {
             peaks[i].status = status_out;
         }
     }
 }
Beispiel #3
0
        /// <summary>
        /// Функция выясняет типичную ширину пика. downsample указывает погрешность ее определения,
        /// max_width - верхнюю границу поиска. downsample не должно быть меньше среднего расстояния
        /// между соседними точками, соответствующими одному пику.
        /// Возвращает ширину, или -1 в случае неудачи.
        /// </summary>
        /// <param name="peaks"></param>
        /// <param name="downsample">tolerance for peak width estimation</param>
        /// <param name="max_width">search upper boundary</param>
        /// <param name="status">peak status to be set</param>
        /// <returns></returns>
        int peaks_find_peak_width(peak[] peaks, int downsample, int max_width, peak_status status)
        {
            int    i, j;
            double w;
            int    n = peaks.Length;

            int bins_n = max_width / downsample + 1;

            if (bins_n <= 1)
            {
                // silly answer, but at least as good as the question was
                return(downsample * bins_n);
            }

            double[] bins = new double[bins_n];

            for (i = bins_n - 1; i >= 0; i--)
            {
                bins[i] = 0;
            }

            for (i = 0; i < n; i++)
            {
                if (peaks[i].status != status)
                {
                    continue;
                }
                for (j = i; (j < n) && (peaks[j].position - peaks[i].position <= max_width); j++)
                {
                    if (peaks[j].status == status)
                    {
                        bins[(peaks[j].position - peaks[i].position) / downsample] += 1; //peaks[j].value*peaks[i].value;
                    }
                }
            }
#if DEBUG
            array_print_indexed_to_file(bins, bins_n, 0, "width_stat.dat");
#endif


            for (i = 0; i < bins_n - 1; i++)
            {
                if (bins[i] < bins[0] * 0.2)
                {
                    break;
                }
            }

            w = i * 1.2f * bins[0] / (bins[0] - bins[i]) * downsample + 0.4f * downsample + 1;
#if DEBUG
            System.Console.Error.WriteLine("w={0}", w);
#endif
            return((int)w);
        }
Beispiel #4
0
        void peaks_threshold(peak[] peaks, double threshold, peak_status status, peak_status set_status)
        {
            int n = peaks.Length;

            for (n--; n >= 0; n--)
            {
                if ((peaks[n].value > threshold) && (peaks[n].status == status))
                {
                    peaks[n].status = set_status;
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Return number of peaks with spcecified status
        /// </summary>
        /// <param name="peaks"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        int peaks_count(peak[] peaks, peak_status status)
        {
            int c = 0;

            for (int n = peaks.Length - 1; n >= 0; --n)
            {
                if (peaks[n].status == status)
                {
                    ++c;
                }
            }
            return(c);
        }
Beispiel #6
0
        /// <summary>
        /// для каждого пика вычисляется средняя амплитуда ближайших пиков N пиков
        /// и пики с амплитудой, меньшей 0.3 средней величины удаляются.
        /// </summary>
        /// <param name="peaks"></param>
        /// <param name="source_status"></param>
        /// <param name="target_status"></param>
        private void refine_front_amplitude(peak[] peaks, peak_status source_status, peak_status target_status, double min_peak_to_average_ratio)
        {
            // усредняем по 'ave_count' пикам _ДО_ и 'ave_count - 1' пикам _ПОСЛЕ_ данного пика
            int ave_count = 4;

            // смещение для корректной обработки первых и последних интервалов
            int offset = 0;

            // сумма амплитуд пиков
            double sum_front_amp = 0;

            double[] average_amplitudes = new double[peaks.Length];

            for (int i = 0; i < peaks.Length; ++i)
            {
                if (i < ave_count)
                {
                    offset = ave_count - i;
                }
                else if (i > peaks.Length - ave_count)
                {
                    offset = peaks.Length - i - ave_count;
                }
                else
                {
                    offset = 0;
                }

                sum_front_amp = 0;
                int averaged_count = 0;
                for (int j = i - ave_count + offset; (j < i + ave_count + offset) && (j < peaks.Length); ++j)
                {
                    sum_front_amp += peaks[j].front_amplitude;
                    ++averaged_count;
                }
                average_amplitudes[i] = sum_front_amp / averaged_count;
            }

            for (int i = 0; i < peaks.Length; ++i)
            {
                if (peaks[i].front_amplitude > (average_amplitudes[i] * min_peak_to_average_ratio))
                {
                    if (peaks[i].status == source_status)
                    {
                        peaks[i].status = target_status;
                    }
                }
            }
        }
Beispiel #7
0
        double[] peaks_repackage(peak[] peaks, peak_status status)
        {
            int i, j, n;

            n = peaks_count(peaks, status);
            double[] result = new double[n];

            for (i = 0, j = 0; i < peaks.Length; i++)
            {
                if (peaks[i].status == status)
                {
                    result[j++] = peaks[i].position;
                }
            }
            return(result);
        }
Beispiel #8
0
        peak[] repackage_peaks(peak[] peaks, peak_status status)
        {
            int i, j, n;

            n = peaks_count(peaks, status);
            peak[] result = new peak[n];

            for (i = 0, j = 0; i < peaks.Length; i++)
            {
                if (peaks[i].status == status)
                {
                    result[j++] = new peak(peaks[i]);
                }
            }
            return(result);
        }
Beispiel #9
0
 void refine_front_after_fall_magnitude(peak[] peaks, peak_status source_status, peak_status target_status, int min_after_fall_magnitude, double min_relative_after_fall_magnitude)
 {
     for (int i = 0; i < peaks.Length; ++i)
     {
         // не требовать мощного спада после пика -- этот метод плохо себя проявил на некоторых записях
         if ( //(Math.Abs(peaks[i].after_fall_magnitude) >= min_after_fall_magnitude) &&
              //( (Math.Abs(peaks[i].after_fall_magnitude) / peaks[i].front_amplitude ) >= min_relative_after_fall_magnitude )
              // если спад в 2,5 и более раза больше пика -- значит, это точно инцезура
              // и этот фронт нельзя считать соответствующим сердечному сокращению (СС)
             Math.Abs(peaks[i].after_fall_magnitude) < (2.5 * Math.Abs(peaks[i].front_amplitude))
             )
         {
             if (peaks[i].status == source_status)
             {
                 peaks[i].status = target_status;
             }
         }
     }
 }
Beispiel #10
0
        private void refine_front_length(peak[] peaks, peak_status source_status, peak_status target_status, int min_front_length, int max_front_length)
        {
            double average_front_length = 0.0;

            for (int i = 0; i < peaks.Length; ++i)
            {
                average_front_length += ((double)peaks[i].front_length);
            }
            average_front_length /= ((double)peaks.Length);


            for (int i = 0; i < peaks.Length; ++i)
            {
                if ((peaks[i].front_length > min_front_length) && (peaks[i].front_length < max_front_length))
                {
                    if (peaks[i].status == source_status)
                    {
                        peaks[i].status = target_status;
                    }
                }
            }
        }
Beispiel #11
0
 /// <summary>
 /// помечает как "хорошие" все "последние" пики на каждом фронте.
 /// </summary>
 /// <param name="peaks"></param>
 /// <param name="source_status"></param>
 /// <param name="target_status"></param>
 private void refine_distance(peak[] peaks, peak_status source_status, peak_status target_status)
 {
     for (int i = 0; i < peaks.Length - 1; ++i)
     {
         if (peaks[i].status == source_status)
         {
             for (int j = i + 1; j < peaks.Length; ++j)
             {
                 if (peaks[j].position - peaks[j].front_length < peaks[i].position)
                 {
                     // peaks #i is not so good to update its status
                     break;
                 }
                 else
                 {
                     // peak #i is ok (not overlapped by the following peak's front)
                     peaks[i].status = target_status;
                     break;
                 }
             }
         }
     }
 }
Beispiel #12
0
        void peaks_reduce_close(peak[] peaks, int min_distance, peak_status status, peak_status set_status)
        {
            int  i, j = 0;
            bool is_first = true;

            for (i = 0; i < peaks.Length; i++)
            {
                if (peaks[i].status != status)
                {
                    continue;
                }

                if (is_first)
                {
                    is_first = false;
                    j        = i;
                    continue;
                }

                if (peaks[i].position - peaks[j].position < min_distance)
                {
                    if (peaks[i].value > peaks[j].value)
                    {
                        peaks[j].status = set_status;
                        j = i;
                    }
                    else
                    {
                        peaks[i].status = set_status;
                    }
                }
                else
                {
                    j = i;
                }
            }
        }
Beispiel #13
0
        int peaks_find_threshold(peak[] peaks, ref double t, peak_status status)
        {
            int i, j;

            double[] stat;
            double   sum, suml, s_max, s, p1, p2;
            int      i_max, n;

            n = peaks_count(peaks, status);
            System.Diagnostics.Debug.Assert(n >= 2); // FIXME

            stat = new double[n];

            for (i = 0, j = 0; i < n; i++)
            {
                if (peaks[i].status == status)
                {
                    stat[j++] = peaks[i].value;
                }
            }

            // we need to sort stat[] array...
            System.Array.Sort(stat);

#if DEBUG
            array_print_indexed_to_file(stat, stat.Length, 0, "stat.dat");
            for (i = 0; i < n; i++)
            {
                System.Console.Error.WriteLine("{0}", stat[i]);
            }
#endif

            sum = 0;
            for (i = 0; i < n; i++)
            {
                sum += stat[i];
            }
            // now we have sum of all peak values

            suml  = stat[0];
            i_max = 1;
            s_max = 0;
            for (i = 1; i < n - 1; i++)
            {
                p1 = suml * suml / i;
                p2 = (sum - suml) * (sum - suml) / (n - i);
                s  = p1 + p2;
#if DEBUG
                System.Console.Error.WriteLine("s = {0} {1} {2} {3}", i, s, p1, p2);
#endif
                if (s > s_max)
                {
                    s_max = s;
                    i_max = i;
                }
                suml += stat[i];
            }
#if DEBUG
            System.Console.Error.WriteLine("t = {0} {1}", i_max, stat[i_max]);
#endif
            t = (stat[i_max] + stat[i_max - 1]) * 0.5f;
            return(0);
        }
Beispiel #14
0
 private void peaks_refine_afterfall_to_front_ration(peak[] peaks, double max_after_fall_to_front_ratio, peak_status source_status, peak_status target_status)
 {
     for (int i = 0; i < peaks.Length; ++i)
     {
         if ((peaks[i].after_fall_magnitude / peaks[i].front_amplitude) > max_after_fall_to_front_ratio)
         {
             if (peaks[i].status == source_status)
             {
                 peaks[i].status = target_status;
             }
         }
     }
 }
Beispiel #15
0
 private void peaks_with_no_preceeding_local_minimum(double[] array, peak[] peaks, peak_status source_status, peak_status target_status)
 {
     for (int i = 0; i < peaks.Length; ++i)
     {
         if (PeakHasPreceedingLocalMinimum(array, peaks[i]))
         {
             if (peaks[i].status == source_status)
             {
                 peaks[i].status = target_status;
             }
         }
     }
 }