public static PatientPhysioData GetFromLeftToRight(this PatientPhysioData _this, long leftMarkerId, long rightMarkerId) { Marker leftMarker = _this.GetMarkerByIdOrDefault(leftMarkerId); Marker rightMarker = _this.GetMarkerByIdOrDefault(rightMarkerId); // Вырезать данные и вернуть их. return(_this.CutPhysioDataFromLeftToRight(leftMarker, rightMarker)); }
/// <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)); }
/// <summary> /// Смещает метку канала на заданное кол-во микросекунд. /// Возвращает смещение в микросекундах, /// на которое реально была перемещена метка канала. /// </summary> /// <param name="markerId">Идентификатор метки</param> /// <param name="markerOffset">Смещение метки в микросекундах</param> /// <param name="channelName">Имя канала данных</param> public static double MoveChannelMarker( this PatientPhysioData _this, long markerId, long markerOffset, string channelName) { if (!_this.ContainsMarker(markerId)) { return(0); } var marker = _this.GetMarkerByIdOrDefault(markerId); var channelMarker = GetChannelMarkByChannelName(marker.ChannelMarks, channelName); if (null == channelMarker) { return(0); } var channel = _this.GetChannelData(channelName); if (null == channel) { return(0); } return(_this.MoveChannelMarker(channelMarker, markerOffset, channel)); }
/// <summary> /// Возвращает фрагмент сигнала из всех каналов нужного типа от маркера left до маркера right. /// </summary> /// <param name="physioSignalType">нужный тип физиологического сигнала.</param> /// <param name="leftMarkerId"></param> /// <param name="rightMarkerId"></param> /// <returns></returns> /// <remarks></remarks> public static IEnumerable <ChannelData> GetChannelDataBySignalType( this PatientPhysioData _this, SignalType physioSignalType, long leftMarkerId, long rightMarkerId) { // Берем сигналы нужного типа целиком var channels = _this.GetChannelDataBySignalType(physioSignalType); // Найти объекты-маркеры, соответствующие left_marker и right_marker Marker leftMarker = _this.GetMarkerByIdOrDefault(leftMarkerId); Marker rightMarker = _this.GetMarkerByIdOrDefault(rightMarkerId); var fragments = channels.Select( c => _this.CutChannelDataFromLeftToRight(c, leftMarker, rightMarker) ); return(fragments); }
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)); }
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); }
/// <summary> /// Смещает метку на заданное кол-во микросекунд. /// Максимальное положение метки на оси времени не контролируется. /// </summary> /// <param name="markerId">Идентификатор метки</param> /// <param name="markerOffset">Смещение метки в микросекундах</param> public static void MoveMarker( this PatientPhysioData _this, long markerId, long markerOffset) { if (!_this.ContainsMarker(markerId)) { return; } var marker = _this.GetMarkerByIdOrDefault(markerId); // нет смысла двигать маркер, если он установлен на "минус бесконечность" if (long.MinValue == marker.TimestampUsec) { return; } // метка не может быть установлена раньше начала записи данных if ((marker.TimestampUsec + markerOffset) < 0) { markerOffset = 0 - marker.TimestampUsec; } // модифицировать канальные метки, соответствующие данному маркеру // максимальное положение метки на оси времени не контролируется foreach (ChannelMark channelMark in marker.ChannelMarks) { var channelData = _this.Channels[channelMark.ChannelId]; System.Diagnostics.Debug.Assert(channelData != null); double channelMarkerOffset = _this.MoveChannelMarker(channelMark, markerOffset, channelData); // разница между требуемым смещением метки канала и реально полученным // может быть меньше нуля только тогда, когда требуемое новое положение метки // лежит на временной оси раньше начала данных канала. double markerOffsetDelta = ((double)markerOffset) - channelMarkerOffset; // дополняем смещение метки канала, невыходящее за границы временного интервала данных, // смещением до заданного нового положения метки синхронизации. channelMark.Offset += (long)Math.Floor(markerOffsetDelta); } // новое положение метки синхронизации marker.TimestampUsec += markerOffset; }
/// <summary> /// Возвращает время от начала измерения /// до создания данного маркера. /// </summary> /// <param name="markerId"></param> /// <returns></returns> public static TimeSpan GetAbsoluteTimeForMarker(this PatientPhysioData _this, long markerId) { Marker marker = _this.GetMarkerByIdOrDefault(markerId); return(new TimeSpan(marker.TimestampUsec * 10)); }