Example #1
0
        /// <summary>
        /// Возвращает время от получения первого отсчета в данном канале
        /// до создания данного маркера
        /// </summary>
        /// <param name="markerId"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        public static TimeSpan GetChannelTimeForMarker(
            this PatientPhysioData _this, long markerId, ChannelData channel)
        {
            Marker marker = _this.GetMarkerByIdOrDefault(markerId);

            System.Diagnostics.Debug.Assert(marker != null);
            ChannelMark cm = GetChannelMarkByChannelName(marker.ChannelMarks, channel.ChannelId);

            // Длина канала в микросекундах
            double channelDataMicroseconds = ((double)channel.Data.Length) / channel.BitsPerSample * OneM;
            // Положение метки относительно начала данных канала в микросекундах
            double channelMarkerMicroseconds = ((double)cm.Count) / channel.BitsPerSample * OneM + (double)cm.Offset;

            if (channelMarkerMicroseconds < 0)
            {
                System.Diagnostics.Debug.Assert(false);
                // такая ситуация может возникнуть в двух случаях
                // 1. когда метка поставлена в начале отсчета временной шкалы измерения,
                // а за время выполнения цикла создания меток каналов в одном из каналов
                // появились новые данные, при этом смещение метки канала будет отрицательным,
                // а абсолютное значение смещения может быть больше чем (cm.Count / channel.BitsPerSample * 1000000.0)
                // 2. когда метка ставится на канал, в котором еще нет данных

                channelMarkerMicroseconds = 0;
            }

            // исправить
            //return new System.TimeSpan( (marker.TimestampUsec - cm.Offset) * 10 );
            // на
            return(new TimeSpan((long)Math.Floor(Math.Min(channelMarkerMicroseconds, channelDataMicroseconds)) * 10));
        }
Example #2
0
        /// <summary>
        /// защита от неправильного использования отсутствует,
        /// поэтому нельзя делать эту функцию public
        /// </summary>
        public static ChannelData CutChannelDataFromLeftToRight(
            this PatientPhysioData _this, ChannelData channel_data, Marker left_marker, Marker right_marker)
        {
            System.Diagnostics.Debug.Assert(channel_data != null);

            lock (channel_data)
            {
                int left_index  = 0;
                int right_index = channel_data.Data.Length - 1;

                if (left_marker != null)
                {
                    ChannelMark lcm = GetChannelMarkByChannelName(left_marker.ChannelMarks, channel_data.ChannelId);
                    System.Diagnostics.Debug.Assert(lcm != null);
                    double offsetInSeconds = ((double)lcm.Offset) / OneM;
                    long   offsetInSamples = (long)Math.Floor(offsetInSeconds * channel_data.SamplingRate);

                    left_index = (int)Math.Max(lcm.Count + offsetInSamples - 1, left_index);
                }

                if (right_marker != null)
                {
                    ChannelMark rcm = GetChannelMarkByChannelName(right_marker.ChannelMarks, channel_data.ChannelId);
                    System.Diagnostics.Debug.Assert(rcm != null);

                    double offsetInSeconds = ((double)rcm.Offset) / OneM;
                    long   offsetInSamples = (long)Math.Floor(offsetInSeconds * channel_data.SamplingRate);

                    right_index = (int)Math.Min(rcm.Count + offsetInSamples - 1, right_index);
                }

                return(new ChannelData(channel_data, left_index, right_index));
            }
        }
Example #3
0
 public static ChannelData GetChannelDataFromLeftToRight(
     this PatientPhysioData _this,
     ChannelData channelData,
     long leftMarkerId,
     long rightMarkerId)
 {
     return(_this.GetChannelDataFromLeftToRight(channelData, leftMarkerId, 0, rightMarkerId, 0));
 }
Example #4
0
        public ChannelData(ChannelData src)
        {
            BitsPerSample    = src.BitsPerSample;
            ChannelId        = src.ChannelId;
            DeviceTypeName   = src.DeviceTypeName;
            SamplingRate     = src.SamplingRate;
            PhysioSignalType = src.PhysioSignalType;

            Data = new int[src.Data.Length];
            Array.Copy(src.Data, Data, src.Data.Length);

            Timestamps = new Dictionary <long, long>(src.Timestamps);
        }
Example #5
0
        public static long GetChannelDataCountForMarker(
            this PatientPhysioData _this, ChannelData data, long markerId)
        {
            Marker marker = _this.GetMarkerByIdOrDefault(markerId);

            if (null != marker)
            {
                ChannelMark m = GetChannelMarkByChannelName(marker.ChannelMarks, data.ChannelId);
                if (null != m)
                {
                    return(m.Count + ((long)(((double)m.Offset) * data.SamplingRate / OneM)));
                }
            }
            return(-1);
        }
Example #6
0
        public static ChannelData GetChannelDataFromLeftToRight(
            this PatientPhysioData _this,
            ChannelData channelData,
            long leftMarkerId,
            long leftMarkerOffset,
            long rightMarkerId,
            long rightMarkerOffset)
        {
            if (null == channelData)
            {
                return(null);
            }

            Marker leftMarker  = _this.GetMarkerByIdOrDefault(leftMarkerId);
            Marker rightMarker = _this.GetMarkerByIdOrDefault(rightMarkerId);

            // Вырезать данные и вернуть их.
            return(_this.CutChannelDataFromLeftToRight(channelData, leftMarker, rightMarker));
        }
Example #7
0
        /// <summary>
        /// Смещает метку канала на заданное кол-во микросекунд.
        /// Возвращает смещение в микросекундах,
        /// на которое реально была перемещена метка канала.
        /// </summary>
        /// <param name="marker">Метка канала</param>
        /// <param name="offset">Смещение метки в микросекундах</param>
        /// <param name="channel">Канал данных</param>
        public static double MoveChannelMarker(
            this PatientPhysioData _this,
            ChannelMark marker,
            long offset,
            ChannelData channel)
        {
            // Частота оцифровки канала
            double samplingRate = channel.SamplingRate;
            // Кол-во данных канала
            double dataCount = channel.Data.Length;
            // Длина канала в микросекундах
            double dataMicroseconds = dataCount / samplingRate * OneM;


            // Положение метки во времени относительно начала данных канала в микросекундах
            double markerPosition = ((double)marker.Count) / samplingRate * OneM + (double)marker.Offset;

            // Новое положение метки на канале в микросекундах
            double newMarkerPosition = markerPosition + (double)offset;

            if (newMarkerPosition < 0)
            {
                newMarkerPosition = 0;
            }
            else if (newMarkerPosition > dataMicroseconds)
            {
                newMarkerPosition = dataMicroseconds;
            }

            // Новое кол-во отсчетов метки
            marker.Count = (long)Math.Floor(newMarkerPosition * samplingRate / OneM);
            // Новое смещение метки	в микросекундах
            marker.Offset = (long)Math.Floor(newMarkerPosition - ((double)marker.Count) / samplingRate * OneM);


            // Новое положение метки на канале с учетом Math.Floor
            newMarkerPosition = ((double)marker.Count) / samplingRate * OneM + (double)marker.Offset;

            // Смещение в микросекундах, на которое реально была перемещена метка канала
            return(newMarkerPosition - markerPosition);
        }
Example #8
0
        /// <summary>
        /// Конструктор копий, позволяющий вырезать фрагмент данных
        /// </summary>
        /// <param name="src"></param>
        /// <param name="leftIndex"></param>
        /// <param name="rightIndex"></param>
        public ChannelData(ChannelData src, int leftIndex, int rightIndex)
        {
            lock (src)
            {
                if (leftIndex > rightIndex)
                {
                    throw new ArgumentException(
                              $"{nameof(leftIndex)}={leftIndex} must be less than or equal to {nameof(rightIndex)}={rightIndex}");
                }

                BitsPerSample    = src.BitsPerSample;
                ChannelId        = src.ChannelId;
                SamplingRate     = src.SamplingRate;
                DeviceTypeName   = src.DeviceTypeName;
                PhysioSignalType = src.PhysioSignalType;

                int newCount = rightIndex - leftIndex + 1;
                Data = new int[newCount];

                Array.Copy(src.Data, leftIndex, Data, 0, newCount);

                // Не добавляем метки времени, не попавшие
                // между leftIndex и rightIndex включительно
                Timestamps = new Dictionary <long, long>();
                if (src.Timestamps != null)
                {
                    foreach (long timestamp in src.Timestamps.Keys)
                    {
                        long count = src.Timestamps[timestamp];
                        if ((leftIndex < count) && (count <= (rightIndex + 1)))
                        {
                            Timestamps[timestamp] = (long)(count - leftIndex);
                        }
                    }
                }
            }
        }
Example #9
0
        /// <summary>
        /// Смещает метку канала на заданное кол-во микросекунд.
        /// Возвращает смещение в микросекундах,
        /// на которое реально была перемещена метка канала.
        /// </summary>
        /// <param name="markerId">Идентификатор метки</param>
        /// <param name="markerOffset">Смещение метки в микросекундах</param>
        /// <param name="channel">Канал данных</param>
        public static double MoveChannelMarker(this PatientPhysioData _this, long markerId, long markerOffset, ChannelData channel)
        {
            if (!_this.ContainsMarker(markerId))
            {
                return(0);
            }

            var marker = _this.GetMarkerByIdOrDefault(markerId);

            if (null == marker)
            {
                return(0);
            }

            var channelMarker = GetChannelMarkByChannelName(marker.ChannelMarks, channel.ChannelId);

            if (null == channelMarker)
            {
                return(0);
            }

            return(_this.MoveChannelMarker(channelMarker, markerOffset, channel));
        }
 public static float[] GetDataAsFloat(this ChannelData _this)
 {
     return(_this.Data.Select(sample => (float)sample).ToArray());
 }