/// <summary> /// 查找拐点:过零点 /// </summary> /// <param name="peak"></param> /// <returns></returns> private bool CalInflectionPoint(PeakArgs peak, out PointF IptfLI, out PointF IptfLR) { IptfLI = new PointF(float.MaxValue, float.MaxValue); IptfLR = new PointF(float.MaxValue, float.MaxValue); if (peak == null) { return(false); } if (this.PeakLocationParam == null) { return(false); } PointF[] zeroBuffer = GetZeroPointF(this.PeakLocationParam.Second_Order_Derivative , (int)peak.StartPoint.X , (int)peak.PeakPoint.X); PointF UP = CalZeroPointF(zeroBuffer); if (UP == PointF.Empty) { return(false); } IptfLI = UP; PointF[] zeroBufferR = GetZeroPointF(this.PeakLocationParam.Second_Order_Derivative , (int)peak.PeakPoint.X , (int)peak.EndPoint.X); UP = CalZeroPointF(zeroBufferR); if (UP == PointF.Empty) { return(false); } IptfLR = UP; return(true); }
/// <summary> /// 计算分离度:采用empower的做法 /// 相邻峰间的间隔与峰的宽度的比值 /// </summary> /// <returns></returns> protected virtual double CalResolution(PeakArgs front_peak, PeakArgs after_peak) { if (front_peak == null) { return(double.MaxValue); } if (after_peak == null) { return(double.MaxValue); } if (front_peak.EndPoint.X > after_peak.StartPoint.X) { return(double.MaxValue); } float _front_peak_width = front_peak.EndPoint.X - front_peak.StartPoint.X; float _after_peak_width = after_peak.EndPoint.X - after_peak.StartPoint.X; ////float E12 = afterPeak.PeakPoint.X - frontPeak.PeakPoint.X; ////return 2 * E12 / (W1 + W2); float E12 = after_peak.StartPoint.X - front_peak.EndPoint.X; float W = _front_peak_width > _after_peak_width ? _front_peak_width : _after_peak_width; return(W / E12); }
/// <summary> /// 计算峰宽 /// </summary> /// <param name="e"></param> /// <returns></returns> private double CalWidth(PeakArgs e) { if (e == null) { return(double.NaN); } return(e.EndPoint.X - e.StartPoint.X); }
/// <summary> /// 原始数据匹配处理峰数据接收 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void _RSD_OnPeakFound(object sender, PeakArgs e) { if (e == null) { return; } _RSDPeakList.Add(e); }
/// <summary> /// 查找分离峰特征点 /// </summary> /// <param name="peak"></param> /// <param name="startflag"></param> /// <param name="endflag"></param> private void GetPeakCharacteristicPoints(PeakArgs peak, string startflag, string endflag) { if (peak == null) { return; } if (startflag == null) { return; } if (endflag == null) { return; } peak.Type = PeakType.Detached; peak.CharacteristicPointsFlag = startflag + PeakFlag.U.ToString() + PeakFlag.I.ToString() + PeakFlag.A.ToString() + PeakFlag.I.ToString() + PeakFlag.U.ToString() + endflag; PointF iptfL = new PointF(float.MinValue, float.MinValue); PointF iptfR = new PointF(float.MinValue, float.MinValue); CalInflectionPoint(peak, out iptfL, out iptfR); if (iptfL.Y != 0f) { iptfL = PointF.Empty; } if (iptfR.Y != 0f) { iptfR = PointF.Empty; } PointF uptfL = new PointF(float.MaxValue, float.MaxValue); PointF uptfR = new PointF(float.MaxValue, float.MaxValue); CalUpstarePoint(peak, out uptfL, out uptfR); if (uptfL.X == float.MaxValue) { uptfL = PointF.Empty; } if (uptfR.X == float.MaxValue) { uptfR = PointF.Empty; } peak.CharacteristicPoints.Clear(); peak.CharacteristicPoints.Add(peak.StartPoint); peak.CharacteristicPoints.Add(uptfL); peak.CharacteristicPoints.Add(iptfL); peak.CharacteristicPoints.Add(peak.PeakPoint); peak.CharacteristicPoints.Add(iptfR); peak.CharacteristicPoints.Add(uptfR); peak.CharacteristicPoints.Add(peak.EndPoint); }
/// <summary> /// 峰列表后处理数据接收 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void _PRP_OnPeakFound(object sender, PeakArgs peak) { if (peak == null) { return; } #region delete //if (this._OriginalData == null) return; //if (this._OriginalData.Length == 0) return; //int _index = 0; //for (int i = 0; i < peak.CharacteristicPoints.Count; i++) //{ // _index = (int)(peak.CharacteristicPoints[i].X); // if (_index >= this._OriginalData.Length) return; // peak.CharacteristicPoints[i] = new PointF(_OriginalData[_index].X, _OriginalData[_index].Y); //} //_index = (int)(peak.StartPoint.X); //if (_index >= this._OriginalData.Length) return; //peak.StartPoint = new PointF(_OriginalData[_index].X, _OriginalData[_index].Y); //_index = (int)(peak.PeakPoint.X); //if (_index >= this._OriginalData.Length) return; //peak.PeakPoint = new PointF(_OriginalData[_index].X, _OriginalData[_index].Y); //_index = (int)(peak.EndPoint.X); //if (_index >= this._OriginalData.Length) return; //peak.EndPoint = new PointF(_OriginalData[_index].X, _OriginalData[_index].Y); #endregion #region OLD_CODE //if (peak == null) return; //if (this._srcDataMatchList == null) return; //if (this._srcDataMatchList.Count == 0) return; //for (int i = 0; i < peak.CharacteristicPoints.Count; i++) //{ // if (!_srcDataMatchList.ContainsKey(peak.CharacteristicPoints[i].X)) return; // peak.CharacteristicPoints[i] = new PointF(_srcDataMatchList[peak.CharacteristicPoints[i].X], peak.CharacteristicPoints[i].Y); //} //if (!_srcDataMatchList.ContainsKey(peak.StartPoint.X)) return; //peak.StartPoint = new PointF(_srcDataMatchList[peak.StartPoint.X], peak.StartPoint.Y); //if (!_srcDataMatchList.ContainsKey(peak.PeakPoint.X)) return; //peak.PeakPoint = new PointF(_srcDataMatchList[peak.PeakPoint.X], peak.PeakPoint.Y); //if (!_srcDataMatchList.ContainsKey(peak.EndPoint.X)) return; //peak.EndPoint = new PointF(_srcDataMatchList[peak.EndPoint.X], peak.EndPoint.Y); #endregion _PRPPeakList.Add(peak); }
/// <summary> /// 粗略计算峰高 /// </summary> /// <param name="e"></param> /// <returns></returns> private double CalHeight(PeakArgs e) { if (e == null) { return(double.NaN); } double H1 = Math.Abs(e.PeakPoint.Y - e.StartPoint.Y); double H2 = Math.Abs(e.PeakPoint.Y - e.EndPoint.Y); double H = H1 > H2 ? H1 : H2; return(H); }
/// <summary> /// 峰传出 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void OnPeakOut(object sender, PeakArgs e) { if (this._Onfoundpeak == null) { return; } if (e == null) { return; } this._Onfoundpeak(this, e); }
/// <summary> /// 根据抽样率和原始数据,还原抽样后的峰特征点 /// </summary> /// <param name="peak"></param> /// <param name="srcData"></param> /// <param name="SampleInterval"></param> /// <returns></returns> protected virtual bool RecoverPeakArges(PeakArgs peak) { if ((peak.CharacteristicPointsFlag == null) || (peak.CharacteristicPointsFlag == string.Empty)) { return(RecoverDataWithoutFlag(peak)); } if (peak.CharacteristicPointsFlag.Length != peak.CharacteristicPoints.Count) { return(RecoverDataWithoutFlag(peak)); } return(RecoverDataWithFlag(peak)); }
/// <summary> /// 复制峰对象 /// </summary> /// <param name="e"></param> /// <returns></returns> private PeakArgs CopyPeak(PeakArgs peak) { if (peak == null) { return(null); } PeakArgs _new_peak = new PeakArgs(); _new_peak.StartPoint = new PointF(peak.StartPoint.X, peak.StartPoint.Y); _new_peak.PeakPoint = new PointF(peak.PeakPoint.X, peak.PeakPoint.Y); _new_peak.EndPoint = new PointF(peak.EndPoint.X, peak.EndPoint.Y); return(_new_peak); }
/// <summary> /// 创建噪声峰 /// </summary> /// <param name="startPt"></param> /// <param name="endPt"></param> /// <returns></returns> private PeakArgs CreateNoisePeak(PointF startPt, PointF endPt) { PeakArgs _peak = new PeakArgs(); _peak.StartPoint = startPt; _peak.EndPoint = endPt; //float dt = endPt.X - startPt.X; //_peak.PeakPoint = new PointF(startPt .X +(float)(dt/2.0),endPt .Y); _peak.PeakPoint = startPt.Y > endPt.Y ? startPt : endPt; _peak.Type = PeakType.Noise; return(_peak); }
/// <summary> /// 进行峰判别 /// </summary> /// <param name="fd_data">输入数据</param> /// <param name="index"></param> /// <returns>检测到峰的标志:检测到峰后返回true,否则返回false</returns> protected virtual bool CheckPeak(PointF[] fd_data, int index) { switch (_mState) { case CheckStage.StartPointChecked: _mState = CheckStartingPoint(fd_data, index); if (_mState != CheckStage.PeakPointChecked) { break; } _mPeak.StartPoint = fd_data[index + 0]; break; case CheckStage.PeakPointChecked: _mState = CheckPeakPoint(fd_data, index); if (_mState != CheckStage.EndPointChecked) { break; } _mPeak.PeakPoint = fd_data[index + 1]; break; case CheckStage.EndPointChecked: _mState = CheckEndingPoint(fd_data, index); if (_mState != CheckStage.StartPointChecked) { break; } _mPeak.EndPoint = fd_data[index + 2]; if (_Onfoundpeak == null) { break; } PeakArgs _new_peak = CopyPeak(_mPeak); if (_new_peak == null) { break; } _Onfoundpeak(this, _new_peak); //触发事件,读取峰数据 break; } return(true); }
/// <summary> /// 计算两峰之间,峰谷与峰高的高度比 /// </summary> /// <param name="frontPeak"></param> /// <param name="arfterPeak"></param> /// <returns></returns> protected virtual double CalHeightRate(PeakArgs front_peak, PeakArgs after_peak) { if (front_peak.EndPoint.X != after_peak.StartPoint.X) { return(double.NaN); } if (front_peak.EndPoint.Y <= front_peak.StartPoint.Y || front_peak.EndPoint.Y <= after_peak.EndPoint.Y) { return(0); } float startY = front_peak.StartPoint.Y < after_peak.EndPoint.Y ? front_peak.StartPoint.Y : after_peak.EndPoint.Y; float H12 = front_peak.EndPoint.Y - startY; float H2 = after_peak.PeakPoint.Y - startY; float H1 = front_peak.PeakPoint.Y - startY; float Hmax = H1 > H2 ? H1 : H2; return(H12 / Hmax); }
/// <summary> /// 判峰执行 /// </summary> /// <returns></returns> public override bool Execute() { Init(); if (this.PeakLocationParam == null) { return(false); } if (this.PeakLocationParam.First_Order_Derivative == null) { return(false); } if (this.PeakLocationParam.First_Order_Derivative.Length < _mWindowSize) { return(false); } for (int i = 0; i < this.PeakLocationParam.First_Order_Derivative.Length - _mWindowSize + 1; i++) { CheckPeak(this.PeakLocationParam.First_Order_Derivative, i); } if (_mState == CheckStage.EndPointChecked) { _mPeak.EndPoint = this.PeakLocationParam.First_Order_Derivative[this.PeakLocationParam.First_Order_Derivative.Length - 1]; if (_Onfoundpeak != null) { PeakArgs _new_peak = CopyPeak(_mPeak); if (_new_peak != null) { _Onfoundpeak(this, _new_peak);//触发事件,读取峰数据 } } _mState = CheckStage.StartPointChecked; } return(true); }
/// <summary> /// 上坡点,极小值点,负值 /// </summary> /// <param name="peak">原始峰数据源</param> /// <param name="IptfLU">左上坡点</param> /// <param name="IptfRU">右上坡点</param> /// <param name="bFront"></param> /// <returns></returns> private bool CalUpstarePoint(PeakArgs peak, out PointF IptfLU, out PointF IptfRU) { IptfLU = new PointF(float.MaxValue, float.MaxValue); IptfRU = new PointF(float.MaxValue, float.MaxValue); if (peak == null) { return(false); } if (this.PeakLocationParam == null) { return(false); } GetMinimumPointF(this.PeakLocationParam.Second_Order_Derivative , (int)peak.StartPoint.X , (int)peak.PeakPoint.X , out IptfLU); GetMinimumPointF(this.PeakLocationParam.Second_Order_Derivative , (int)peak.PeakPoint.X , (int)peak.EndPoint.X , out IptfRU); return(true); }
///// <summary> ///// 查找数据 ///// </summary> ///// <param name="srcList"></param> ///// <param name="start"></param> ///// <param name="end"></param> ///// <returns></returns> //protected virtual List<PointF> FindDataList(PointF[] srcList, float startX, float endX) //{ // if(srcList ==null)return null ; // if(srcList.Length ==0)return null ; // if (endX >= srcList.Count()) return null; // List<PointF> list = new List<PointF>(); // for (int i =(int) startX; i <=(int) endX;i++ ) // { // list.Add(srcList [i]); // } // if (list.Count == 0) return null; // return list; //} ///// <summary> ///// 覆盖原始数据(目标峰必须具有CharacteristicPointsFlag) ///// 供RecoverPeakArges调用 ///// </summary> ///// <param name="peak"></param> ///// <returns></returns> //protected virtual bool RecoverDataWithFlag(PeakArgs peak) //{ // if (peak.CharacteristicPointsFlag == null) // return false; // if (peak.CharacteristicPointsFlag == string.Empty) // return false; // if (peak.CharacteristicPointsFlag.Length != peak.CharacteristicPoints.Count) return false; // peak.PeakPoint = PointF.Empty; // List<PointF> _feature_point = new List<PointF>(); // for (int i = 0; i < peak.CharacteristicPointsFlag.Length; i++) // { // PointF CharacteristicPoint = peak.CharacteristicPoints[i]; // if (CharacteristicPoint.IsEmpty) continue; // float _start_offset = (i == 0) ? 2 : (peak.CharacteristicPoints[i].X - peak.CharacteristicPoints[i - 1].X) / 2; // float _end_offset = (i < peak.CharacteristicPoints.Count - 1) ? (peak.CharacteristicPoints[i + 1].X - peak.CharacteristicPoints[i].X) / 2 : 2; // _start_offset = _start_offset > 20 ? 20 : _start_offset; // _end_offset = _end_offset > 20 ? 20 : _end_offset; // //_start_offset = _start_offset < 10 ? 10 : _start_offset; // //_end_offset = _end_offset < 10 ? 10 : _end_offset; // float _start_point = CharacteristicPoint.X - _start_offset; // float _end_point = CharacteristicPoint.X + _end_offset; // _start_point = _start_point < 0 ? 0 : _start_point; // _end_point = _end_point < 0 ? 0 : _end_point; // _end_point = _end_point <= _start_point ? _start_point + 1 : _end_point; // List<PointF> _curve_point = FindDataList(this.PeakLocationParam.SourceData, _start_point * this.PeakLocationParam.SampleInterval, (_end_point ) * this.PeakLocationParam.SampleInterval); // if (_curve_point == null) continue ; // if (_curve_point.Count == 0) continue; // string CharacteristicFlag = peak.CharacteristicPointsFlag.Substring(i, 1); // PeakFlag flag = (PeakFlag)Enum.Parse(typeof(PeakFlag), CharacteristicFlag); // PointF[] _key = FindValue(_curve_point); // if (_key == null) continue; // switch (flag) // { // case PeakFlag.O: // //peak.CharacteristicPoints.Add(_key[0]); // _feature_point.Add(_key[0]); // peak.StartPoint = _key[0]; // break; // case PeakFlag.I: // PointF ptf = FindData(this .PeakLocationParam .SourceData , CharacteristicPoint.X*this .PeakLocationParam.SampleInterval); // _feature_point.Add(ptf); // //peak.CharacteristicPoints.Add(ptf); // break; // case PeakFlag.A: // //peak.CharacteristicPoints.Add(_key[2]); // _feature_point.Add(_key[2]); // if (peak.PeakPoint.IsEmpty) // peak.PeakPoint = _key[2]; // if (_key[2].Y > peak.PeakPoint.Y) // peak.PeakPoint = _key[2]; // if (peak.PeakPoint.X < peak.StartPoint.X) // break; // break; // case PeakFlag.S: // //peak.CharacteristicPoints.Add(_key[0]); // _feature_point.Add(_key[0]); // break; // case PeakFlag.R: // //peak.CharacteristicPoints.Add(_key[1]); // _feature_point.Add(_key[1]); // break; // case PeakFlag.V: // //peak.CharacteristicPoints.Add(_key[0]); // _feature_point.Add(_key[0]); // break; // case PeakFlag.T: // //peak.CharacteristicPoints.Add(_key[0]); // _feature_point.Add(_key[0]); // peak.EndPoint = _key[0]; // break; // case PeakFlag.U: // ptf = FindData(this.PeakLocationParam.SourceData, CharacteristicPoint.X*this .PeakLocationParam.SampleInterval); // //peak.CharacteristicPoints.Add(ptf); // _feature_point.Add(ptf); // break; // } // } // peak.CharacteristicPoints = _feature_point; // //if (peak.CharacteristicPoints.Count != peak.CharacteristicPointsFlag.Length * 2) // // return false; // //peak.CharacteristicPoints.RemoveRange(0, peak.CharacteristicPointsFlag.Length); // return true; //} ///// <summary> ///// 查找最小值,中值,最大值 ///// </summary> ///// <param name="srcdata"></param> ///// <returns></returns> //private PointF[] FindValue(List<PointF> srcdata) //{ // if (srcdata == null) return null; // if (srcdata.Count == 0) return null; // PointF[] ResBuf = new PointF[3]; // IEnumerable<PointF> list = from ptf in srcdata orderby ptf.Y select ptf; // if (list == null) return null; // ResBuf[0] = list.First(); // ResBuf[1] = srcdata[srcdata.Count / 2]; // ResBuf[2] = list.Last(); // return ResBuf; //} #endregion /// <summary> /// 覆盖原始数据(没有特征标志的峰用此处理) /// 供RecoverPeakArges调用 /// </summary> /// <param name="peak"></param> /// <returns></returns> protected virtual bool RecoverDataWithoutFlag(PeakArgs peak) { peak.CharacteristicPointsFlag = string.Empty; peak.CharacteristicPoints.Clear(); peak.CharacteristicPointsFlag += PeakFlag.O.ToString(); peak.CharacteristicPoints.Add(peak.StartPoint); peak.CharacteristicPointsFlag += PeakFlag.A.ToString(); peak.CharacteristicPoints.Add(peak.PeakPoint); peak.CharacteristicPointsFlag += PeakFlag.T.ToString(); peak.CharacteristicPoints.Add(peak.EndPoint); if (RecoverDataWithFlag(peak)) { peak.CharacteristicPointsFlag = string.Empty; peak.CharacteristicPoints.Clear(); return(true); } else { return(false); } }
/// <summary> /// 构造单个的分离峰 /// </summary> /// <param name="peak"></param> /// <param name="MaxEList"></param> /// <param name="hisStartFlag"></param> /// <param name="MinEList"></param> /// <returns></returns> private PeakArgs CreateSinglePeak(PointF StartPoint, PointF PeakPoint, PointF EndPoint, string stargFlag, string endFlag) { if (stargFlag == null) { return(null); } if (endFlag == null) { return(null); } PeakArgs lastPeak = new PeakArgs(); lastPeak.StartPoint = StartPoint; lastPeak.PeakPoint = PeakPoint; lastPeak.EndPoint = EndPoint; lastPeak.CharacteristicPointsFlag = stargFlag + PeakFlag.I.ToString() + PeakFlag.A.ToString() + PeakFlag.I.ToString() + endFlag; return(lastPeak); }
/// <summary> /// 清空历史数据 /// </summary> public override void Init() { _mState = CheckStage.StartPointChecked; _mPeak = new PeakArgs(); }
/// <summary> /// 重写合并函数 /// </summary> /// <param name="srcList"></param> /// <param name="DetechedIndex"></param> /// <returns></returns> protected virtual List <PeakArgs> MergeFusionPeak(List <PeakArgs> input_peak_list, List <int> detached_peak_index) { if (input_peak_list == null) { return(null); } if (detached_peak_index == null) { return(null); } if (detached_peak_index[detached_peak_index.Count - 1] >= input_peak_list.Count) { return(null); } List <PeakArgs> _output_peak_list = new List <PeakArgs>(); int _current_index = -1; //合并到峰谷 for (int i = 0; i < detached_peak_index.Count; i++) { if (input_peak_list[i] == null) { continue; } PeakArgs _peak = new PeakArgs(); _peak.PeakPoint = input_peak_list[_current_index + 1].PeakPoint; _peak.StartPoint = input_peak_list[_current_index + 1].StartPoint; _peak.EndPoint = input_peak_list[detached_peak_index[i]].EndPoint; //_peak.CharacteristicPointsFlag = input_peak_list[_current_index + 1].CharacteristicPointsFlag; //_peak.CharacteristicPoints.AddRange(input_peak_list[_current_index + 1].CharacteristicPoints); _peak.Type = PeakType.Detached; _peak.CharacteristicPoints.Clear(); _peak.CharacteristicPointsFlag = ""; for (int j = _current_index + 1; j <= detached_peak_index[i]; j++) { if (input_peak_list[j].PeakPoint.Y > _peak.PeakPoint.Y) { _peak.PeakPoint = input_peak_list[j].PeakPoint; } _peak.CharacteristicPoints.Add(input_peak_list[j].StartPoint); _peak.CharacteristicPointsFlag += PeakFlag.V.ToString(); _peak.CharacteristicPoints.Add(input_peak_list[j].PeakPoint); _peak.CharacteristicPointsFlag += PeakFlag.A.ToString(); _peak.Type = PeakType.Mixed; } if (_peak.Type == PeakType.Mixed) { _peak.CharacteristicPoints.Add(input_peak_list[detached_peak_index[i]].EndPoint); _peak.CharacteristicPointsFlag += PeakFlag.T.ToString(); _peak.CharacteristicPointsFlag = _peak.CharacteristicPointsFlag.Substring(1); _peak.CharacteristicPointsFlag = PeakFlag.O.ToString() + _peak.CharacteristicPointsFlag; } _output_peak_list.Add(_peak); _current_index = detached_peak_index[i]; } return(_output_peak_list); }
/// <summary> /// 合并到峰谷,供Execute调用 /// </summary> /// <param name="srcList"></param> /// <param name="DetechedIndex"></param> /// <returns></returns> protected override List <PeakArgs> MergeFusionPeak(List <PeakArgs> input_peak_list, List <int> detached_peak_index) { if (input_peak_list == null) { return(null); } if (detached_peak_index == null) { return(null); } if (detached_peak_index[detached_peak_index.Count - 1] >= input_peak_list.Count) { return(null); } List <PeakArgs> _output_peak_list = new List <PeakArgs>(); int _current_index = -1; //合并到峰谷 for (int i = 0; i < detached_peak_index.Count; i++) { if (input_peak_list[i] == null) { continue; } PeakArgs _peak = new PeakArgs(); _peak.PeakPoint = input_peak_list[_current_index + 1].PeakPoint; _peak.StartPoint = input_peak_list[_current_index + 1].StartPoint; _peak.EndPoint = input_peak_list[detached_peak_index[i]].EndPoint; _peak.CharacteristicPointsFlag = input_peak_list[_current_index + 1].CharacteristicPointsFlag; _peak.CharacteristicPoints.AddRange(input_peak_list[_current_index + 1].CharacteristicPoints); _peak.Type = PeakType.Detached; //for (int j = _current_index + 2; j <= detached_peak_index[i]; j++) for (int j = _current_index + 1; j <= detached_peak_index[i]; j++) { if (input_peak_list[j].PeakPoint.Y > _peak.PeakPoint.Y) { _peak.PeakPoint = input_peak_list[j].PeakPoint; } if (input_peak_list[j].CharacteristicPoints == null) { continue; } if (input_peak_list[j].CharacteristicPoints.Count == 0) { continue; } if (input_peak_list[j].CharacteristicPointsFlag == null) { continue; } if (input_peak_list[j].CharacteristicPointsFlag.Length <= 0) { continue; } if (_peak.CharacteristicPoints.Count < 1) { continue; } if (_peak.CharacteristicPointsFlag == null) { continue; } if (_peak.CharacteristicPointsFlag.Length == 0) { continue; } _peak.CharacteristicPoints.RemoveAt(_peak.CharacteristicPoints.Count - 1); _peak.CharacteristicPoints.AddRange(input_peak_list[j].CharacteristicPoints); _peak.CharacteristicPointsFlag = _peak.CharacteristicPointsFlag.Substring(0, _peak.CharacteristicPointsFlag.Length - 1); _peak.CharacteristicPointsFlag += (PeakFlag.V.ToString() + input_peak_list[j].CharacteristicPointsFlag.Substring(1)); _peak.Type = PeakType.Mixed; } _output_peak_list.Add(_peak); _current_index = detached_peak_index[i]; } return(_output_peak_list); }
/// <summary> /// 执行操作 /// </summary> /// <returns></returns> public override bool Execute() { if (!ValidityCheck()) { return(false); } List <int> _detached_peak_index = new List <int>(); //查找峰组,分离峰群 for (int i = 0; i < this.PeakLocationParam.PeakList.Count - 1; i++) { double _resolution = CalResolution(PeakLocationParam.PeakList[i], PeakLocationParam.PeakList[i + 1]); if (_resolution < this.PeakLocationParam.Resolution) { _detached_peak_index.Add(i); } } if (_detached_peak_index.Count == 0) { _detached_peak_index.Add(this.PeakLocationParam.PeakList.Count - 1); } if (_detached_peak_index[_detached_peak_index.Count - 1] != this.PeakLocationParam.PeakList.Count - 1) { _detached_peak_index.Add(this.PeakLocationParam.PeakList.Count - 1); } int currentIndex = -1; //遍历峰列表,合并峰,将起点终点合并并作为谷点建立一个新的峰 for (int i = 0; i < _detached_peak_index.Count; i++) { for (int j = currentIndex + 1; j < _detached_peak_index[i]; j++) { if (this.PeakLocationParam.PeakList[j].PeakPoint.X < this.PeakLocationParam.PeakList[j].StartPoint.X) { this.PeakLocationParam.PeakList[j].PeakPoint = this.PeakLocationParam.PeakList[j].StartPoint; } if (this.PeakLocationParam.PeakList[j].PeakPoint.X > this.PeakLocationParam.PeakList[j].EndPoint.X) { this.PeakLocationParam.PeakList[j].PeakPoint = this.PeakLocationParam.PeakList[j].EndPoint; } this.PeakLocationParam.PeakList[j].EndPoint = this.PeakLocationParam.PeakList[j + 1].StartPoint; } currentIndex = _detached_peak_index[i]; } List <PeakArgs> _peak_list = MergeFusionPeak(this.PeakLocationParam.PeakList, _detached_peak_index); if (_peak_list == null) { return(false); } if (_peak_list.Count == 0) { return(false); } List <int> _noise_peak_index = new List <int>(); //遍历列表,查找噪声峰索引 for (int i = 0; i < _peak_list.Count - 1; i++) { if (_peak_list[i].EndPoint.X != _peak_list[i + 1].StartPoint.X) { _noise_peak_index.Add(i); } } List <PeakArgs> _noise_peak_list = new List <PeakArgs>(); //遍历噪声峰索引列表,构造噪声峰 PeakArgs _noise_peak = null; for (int i = 0; i < _noise_peak_index.Count; i++) { _noise_peak = CreateNoisePeak(_peak_list[_noise_peak_index[i]].EndPoint, _peak_list[_noise_peak_index[i] + 1].StartPoint); _noise_peak_list.Add(_noise_peak); } //_noise_peak_list.Add(CreateNoisePeak(new PointF(0f, this.PeakLocationParam.SourceData[0].Y), _peak_list[0].StartPoint)); _noise_peak_list.Add(CreateNoisePeak(this.PeakLocationParam.SourceData[0], _peak_list[0].StartPoint)); _peak_list.AddRange(_noise_peak_list); this.PeakLocationParam.PeakList = _peak_list; if (this._Onfoundpeak == null) { return(false); } foreach (PeakArgs _peak in this.PeakLocationParam.PeakList) { this._Onfoundpeak(this, _peak); } return(true); }
///// <summary> ///// 遍历融合峰,区分峰谷,肩峰和圆角峰 ///// </summary> ///// <returns></returns> //List<PeakArgs> MixedPeakTraversing(PeakArgs peak) //{ // if (peak == null) return null; // if (this.PeakLocationParam.SampleData == null) return null; // if (this._maxList == null) return null; // if (this._minList == null) return null; // if (this._mixedPeakMaxExtremumList == null) return null; // if (!this._mixedPeakMaxExtremumList.ContainsKey(peak.StartPoint.X.ToString())) return null; // List<PointF> MaxEList = this._mixedPeakMaxExtremumList[peak.StartPoint.X.ToString()]; // if (MaxEList == null) return null; // if (MaxEList.Count < 2) return null; // List<PeakArgs> singelPeakList = new List<PeakArgs>(); // string hisStartFlag = PeakFlag.O.ToString(); // //采用的算法是,在所有极大值范围内查找极小值并列表缓存; // //在两个极大值之间,取靠近第二个极大值的极小值做处理,判定是峰谷,或者肩峰 // List<PointF> MinEList = FindPointList(this._minList, MaxEList[0].X, MaxEList[MaxEList.Count - 1].X); // if (MinEList == null) return null; // if (MinEList.Count == 0) return null; // for (int i = 1; i < MaxEList.Count; i++) // { // PeakArgs midpeak = new PeakArgs(); // if ((i - 1) >= MinEList.Count) break; // if (i == 1) // { // midpeak.StartPoint = peak.StartPoint; // } // else // { // PointF _midptf =FindPoint(MinEList, MaxEList[i-1].X); // if (_midptf == PointF.Empty) continue; // midpeak.StartPoint = _midptf; // } // PointF midptf = FindPoint(MinEList, MaxEList[i].X); // if (midptf == PointF.Empty) continue; // if (midptf.Y > 0f)//判断圆角峰 // { // midpeak = CreateSingelPeak(midpeak.StartPoint, MaxEList[i - 1], midptf, hisStartFlag, PeakFlag.R.ToString()); // hisStartFlag = PeakFlag.R.ToString(); // singelPeakList.Add(midpeak); // } // else//判断峰谷和肩峰 // { // List<PointF> _mmidlist = FindPointList(this.PeakLocationParam.SampleData, MaxEList[i - 1].X, MaxEList[i].X); // if (_mmidlist == null) continue; // if (_mmidlist.Count == 0) continue; // List<PointF> minli = GetMinExtremum(_mmidlist.ToArray()); // if (minli.Count == 0) // { // //重新判断肩峰起点 // //二阶导数列表查找极值 // //List<PointF> fdMaxList = GetMaxExtremum(this.DistinguishedParameters.First_Order_Derivative ); // //List<PointF> fdMinList = GetMinExtremum(this.DistinguishedParameters.First_Order_Derivative); // //List<PointF> midMaxLsit = FindPointList(fdMaxList, 0f, MaxEList[i - 1].X); // //List<PointF> midMinList = FindPointList(fdMinList, 0f, MaxEList[i - 1].X); // //if (midMinList == null) continue; // //if (midMaxLsit == null) continue; // //if (midMinList.Count == 0) continue; // //if (midMaxLsit.Count == 0) continue; // //if (midMaxLsit.Last().X > midMinList.Last().X) // // midpeak.StartPoint = midMaxLsit.Last(); // //else // // midpeak.StartPoint = midMinList.Last(); // //end // midpeak = CreateSingelPeak(midpeak.StartPoint, MaxEList[i - 1], midptf, hisStartFlag, PeakFlag.S.ToString()); // hisStartFlag = PeakFlag.S.ToString(); // singelPeakList.Add(midpeak); // } // else // { // midpeak = CreateSingelPeak(midpeak.StartPoint, MaxEList[i - 1], midptf, hisStartFlag, PeakFlag.V.ToString()); // hisStartFlag = PeakFlag.V.ToString(); // singelPeakList.Add(midpeak); // } // } // } // PeakArgs lastPeak = CreateSingelPeak(MinEList[MinEList.Count - 1] // , MaxEList[MaxEList.Count - 1] // , peak.EndPoint, hisStartFlag // , PeakFlag.T.ToString()); // singelPeakList.Add(lastPeak); // return singelPeakList; //} #endregion #region NEW_CODE /// <summary> /// 遍历融合峰,区分峰谷,肩峰和圆角峰 /// </summary> /// <returns></returns> List <PeakArgs> MixedPeakTraversing(PeakArgs peak) { if (peak == null) { return(null); } if (this.PeakLocationParam.SampleData == null) { return(null); } if (this._maxList == null) { return(null); } if (this._minList == null) { return(null); } if (this._mixedPeakMaxExtremumList == null) { return(null); } if (!this._mixedPeakMaxExtremumList.ContainsKey(peak.StartPoint.X.ToString())) { return(null); } //找到混合峰的最大极值点列表 List <PointF> MaxEList = this._mixedPeakMaxExtremumList[peak.StartPoint.X.ToString()]; if (MaxEList == null) { return(null); } if (MaxEList.Count < 2) { return(null); } List <PeakArgs> singelPeakList = new List <PeakArgs>(); string hisStartFlag = PeakFlag.O.ToString(); //采用的算法是,在所有极大值范围内查找极小值并列表缓存; //在两个极大值之间,取靠近第二个极大值的极小值做处理,判定是峰谷,或者肩峰 //找出最大极值点之间的最小极值点 List <PointF> MinEList = FindPointList(this._minList, MaxEList[0].X, MaxEList[MaxEList.Count - 1].X); if (MinEList == null) { return(null); } if (MinEList.Count == 0) { return(null); } for (int i = 1; i < MaxEList.Count; i++) { PeakArgs midpeak = new PeakArgs(); if ((i - 1) >= MinEList.Count) { break; } if (i == 1) { midpeak.StartPoint = peak.StartPoint; } else { PointF _midptf = FindPoint(MinEList, MaxEList[i - 1].X); if (_midptf == PointF.Empty) { continue; } midpeak.StartPoint = _midptf; } PointF midptf = FindPoint(MinEList, MaxEList[i].X); if (midptf == PointF.Empty) { continue; } if (midptf.Y > 0f)//判断圆角峰 { midpeak = CreateSinglePeak(midpeak.StartPoint, MaxEList[i - 1], midptf, hisStartFlag, PeakFlag.R.ToString()); hisStartFlag = PeakFlag.R.ToString(); singelPeakList.Add(midpeak); } else//判断峰谷和肩峰 { PointF[] _curve_points = FindPeakCurve(this.PeakLocationParam.SampleData, (int)MaxEList[i - 1].X, (int)MaxEList[i].X); if (_curve_points == null) { continue; } if (_curve_points.Length == 0) { continue; } List <PointF> _mini_point_list = GetMinExtremum(_curve_points); if (_mini_point_list.Count == 0) { //重新判断肩峰起点 //二阶导数列表查找极值 #region //List<PointF> fdMaxList = GetMaxExtremum(this.DistinguishedParameters.First_Order_Derivative ); //List<PointF> fdMinList = GetMinExtremum(this.DistinguishedParameters.First_Order_Derivative); //List<PointF> midMaxLsit = FindPointList(fdMaxList, 0f, MaxEList[i - 1].X); //List<PointF> midMinList = FindPointList(fdMinList, 0f, MaxEList[i - 1].X); //if (midMinList == null) continue; //if (midMaxLsit == null) continue; //if (midMinList.Count == 0) continue; //if (midMaxLsit.Count == 0) continue; //if (midMaxLsit.Last().X > midMinList.Last().X) // midpeak.StartPoint = midMaxLsit.Last(); //else // midpeak.StartPoint = midMinList.Last(); //end #endregion midpeak = CreateSinglePeak(midpeak.StartPoint, MaxEList[i - 1], midptf, hisStartFlag, PeakFlag.S.ToString()); hisStartFlag = PeakFlag.S.ToString(); singelPeakList.Add(midpeak); } else { midpeak = CreateSinglePeak(midpeak.StartPoint, MaxEList[i - 1], midptf, hisStartFlag, PeakFlag.V.ToString()); hisStartFlag = PeakFlag.V.ToString(); singelPeakList.Add(midpeak); } } } PeakArgs lastPeak = CreateSinglePeak(MinEList[MinEList.Count - 1] , MaxEList[MaxEList.Count - 1] , peak.EndPoint, hisStartFlag , PeakFlag.T.ToString()); singelPeakList.Add(lastPeak); return(singelPeakList); }
/// <summary> /// 覆盖原始数据(目标峰必须具有CharacteristicPointsFlag) /// 供RecoverPeakArges调用 /// </summary> /// <param name="peak"></param> /// <returns></returns> protected virtual bool RecoverDataWithFlag(PeakArgs peak) { if (peak.CharacteristicPointsFlag == null) { return(false); } if (peak.CharacteristicPointsFlag == string.Empty) { return(false); } if (peak.CharacteristicPointsFlag.Length != peak.CharacteristicPoints.Count) { return(false); } peak.PeakPoint = PointF.Empty; List <PointF> _cpoint_list = new List <PointF>(); for (int i = 0; i < peak.CharacteristicPointsFlag.Length; i++) { PointF _cpoint = peak.CharacteristicPoints[i]; if (_cpoint.IsEmpty) { continue; } float _start_offset = (i == 0) ? 2 : (peak.CharacteristicPoints[i].X - peak.CharacteristicPoints[i - 1].X) / 2; float _end_offset = (i < peak.CharacteristicPoints.Count - 1) ? (peak.CharacteristicPoints[i + 1].X - peak.CharacteristicPoints[i].X) / 2 : 2; _start_offset = _start_offset > 20 ? 20 : _start_offset; _end_offset = _end_offset > 20 ? 20 : _end_offset; //_start_offset = _start_offset < 10 ? 10 : _start_offset; //_end_offset = _end_offset < 10 ? 10 : _end_offset; float _start_point = _cpoint.X - _start_offset; float _end_point = _cpoint.X + _end_offset; _start_point = _start_point < 0 ? 0 : _start_point; _end_point = _end_point < 0 ? 0 : _end_point; _end_point = _end_point <= _start_point ? _start_point + 1 : _end_point; PointF[] _curve_point = FindDataList(this.PeakLocationParam.SourceData, _start_point * this.PeakLocationParam.SampleInterval, (_end_point) * this.PeakLocationParam.SampleInterval); if (_curve_point == null) { continue; } if (_curve_point.Length == 0) { continue; } string CharacteristicFlag = peak.CharacteristicPointsFlag.Substring(i, 1); PeakFlag flag = (PeakFlag)Enum.Parse(typeof(PeakFlag), CharacteristicFlag); PointF[] _key_point = FindKeyPoint(_curve_point); if (_key_point == null) { continue; } switch (flag) { case PeakFlag.O: _cpoint_list.Add(_key_point[0]); peak.StartPoint = _key_point[0]; break; case PeakFlag.I: PointF _point = FindData(this.PeakLocationParam.SourceData, _cpoint.X * this.PeakLocationParam.SampleInterval); _cpoint_list.Add(_point); break; case PeakFlag.A: _cpoint_list.Add(_key_point[2]); if (peak.PeakPoint.IsEmpty) { peak.PeakPoint = _key_point[2]; } if (_key_point[2].Y > peak.PeakPoint.Y) { peak.PeakPoint = _key_point[2]; } if (peak.PeakPoint.X < peak.StartPoint.X) { break; } break; case PeakFlag.S: _cpoint_list.Add(_key_point[0]); break; case PeakFlag.R: _cpoint_list.Add(_key_point[1]); break; case PeakFlag.V: _cpoint_list.Add(_key_point[0]); break; case PeakFlag.T: _cpoint_list.Add(_key_point[0]); peak.EndPoint = _key_point[0]; break; case PeakFlag.U: _point = FindData(this.PeakLocationParam.SourceData, _cpoint.X * this.PeakLocationParam.SampleInterval); _cpoint_list.Add(_point); break; } } peak.CharacteristicPoints = _cpoint_list; return(true); }