/// <summary> /// Возвращает фрагмент сигнала, соответствующий периоду первого стимула; /// по возможности сглаженный со стабилизированной амплитудой, /// </summary> /// <param name="ismid"></param> /// <param name="all_data">data package to which returned channel data belongs</param> /// <param name="begin_mark">beginning of the relevant signal</param> /// <param name="end_mark">end of the relevant signal in the returned signal's buffer</param> /// <returns></returns> private ChannelData GetSignal( HrvRawData ismid, ref PatientPhysioData all_data, ref long begin_mark, ref long end_mark) { var data = ismid.PhysioData; // and we must have at least some physio data System.Diagnostics.Debug.Assert(data != null); all_data = data; ChannelData result = null; // first, we take all the data var ecg_data = data.GetChannelDataBySignalType(SignalType.ECG); var ppg_data = data.GetChannelDataBySignalType(SignalType.PPG); // select appropriate signal using 'a priori' information about priority of signal types result = GetPreferredSignal(ecg_data, ppg_data); if (result == null) { return(null); } begin_mark = ismid.PhSyncBegin; end_mark = ismid.PhSyncEnd; // Возвращаем результат return(result); }
private void SelectAndProcessSignal( bool rejectLowQualitySignalAreas, HrvRawData ismid, out double[] out_hrv_marks, out ChannelData out_channel_data, out ChannelData out_adc_data) { long begin = 0; long end = 0; out_hrv_marks = null; out_channel_data = null; PatientPhysioData all_data = null; ChannelData data = GetSignal(ismid, ref all_data, ref begin, ref end); if (rejectLowQualitySignalAreas) { // BUG: this is for Rushydro only, until there is a solution // to mask lower-quality portions of the signal at the beginning all_data.MoveMarker(begin, 12000000L); } out_adc_data = new ChannelData(data); if (data == null) { return; } if (data.PhysioSignalType == SignalType.PPG) { //int[] unfiltered_data_array = data.GetData(); int[] data_buffer = data.Data; // обрабатываем данные с помощью стандартного процессора // (фильтруем, стабилизируем амплитуду и находим фронты) // обрабатываем все данные, и даже нерелевантные, чтобы не повредить релевантные данные // (в процессе инициализации фильтра сигнал выглядит довольно страшно) double[] hrv_marks = Pulse.PpgPulseDetectorHelper.ProcessPpgData( data.SamplingRate, data_buffer, (int)data.BitsPerSample, data.DeviceTypeName); // избавляемся от лишних данных и лишних отметок пульса, // корректируя положение релевантных отметок ChannelData relevant_data = all_data.GetChannelDataFromLeftToRight(data, begin, end); long left_marker_data_count = all_data.GetChannelDataCountForMarker(data, begin); if (left_marker_data_count < 0) { left_marker_data_count = 0; } long right_marker_data_count = all_data.GetChannelDataCountForMarker(data, end); if (right_marker_data_count < 0) { right_marker_data_count = data.Data.Length; } var relevant_hrv_marks = new List <double>(hrv_marks.Length); for (int i = 0; i < hrv_marks.Length; ++i) { // добавляем в список только те отметки, которые попали между левым и правым маркером if ((hrv_marks[i] >= left_marker_data_count) && (hrv_marks[i] <= right_marker_data_count)) { relevant_hrv_marks.Add(hrv_marks[i] - ((double)left_marker_data_count)); } } out_hrv_marks = relevant_hrv_marks.ToArray(); out_channel_data = relevant_data; } else if (data.PhysioSignalType == SignalType.ECG) { // not implemented so far return; } else { // other signal types not supported return; } }