using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FLY.HeatingHelper { /// <summary> /// IThickHeatData定义一个Thick和Heat数据的维护对象的接口,屏蔽了数据保存的方式,对于用SQLite或SQLServer或 /// 文件等,应该用不同的类实现,但必须实现这个接口 /// 注意:1.实现该接口的类是一个维护运行时数据的类,并不负责数据的保存 /// 2.实现该接口的类的对象在创建时从“数据库”中提取最近数据,然后根据数据检测风环移位和加热失效问题 /// </summary> public interface IThickHeatData : INotifyPropertyChanged { #region 用于UI的接口(数据库数据选择接口) /// <summary> /// 数据库路径(含数据库名) /// </summary> string DBPath { get; set; } /// <summary> /// 数据库中存在的数据范围 /// </summary> DateTime TotalDataFrom { get; } DateTime TotalDataTo { get; } /// <summary> /// DataTo和DataSpan确定数据的起始位置,对象中存在的数据范围 /// </summary> DateTime LoadDataFrom { get; set; } DateTime LoadDataTo { get; set; } int LoadDataMinID { get; } int LoadDataMaxID { get; } /// <summary> /// 加载数据时是否过滤掉加热相同的连续数据 /// </summary> bool IsDataFilter { get; set; } /// <summary> /// 重新设定加载数据的缺省范围 /// </summary> void SetLoadDaTaDefault(); /// <summary> /// 加载元数据,主要包括数据的范围,即TotalDataFrom和TotalDataTo /// </summary> /// <returns></returns> int LoadMetaDataFromDB(); /// <summary> /// 根据上面的设定加载数据,reload=0自动判断是否是否重新加载所有数据, /// reload=1强制重新加载所有数据 /// reload=-1只加载之后产生的数据 /// </summary> /// <returns></returns> int LoadDataFromDB(int reload); #endregion /// <summary> /// 风环偏差值 /// </summary> int AirRingShift { get; } StateCode State { get; } int CalculateFromToByClass(int selected_class, ref int from, ref int to); #region 一些辅助计算的函数 /// <summary> /// 计算两个frame的加热和厚度差的协相关向量。 /// </summary> double[] CalculateCorrelVector(double[] heats, double[] thicks); Tuple<int, double> CalculateAirRingShiftFromCorelVector(double[] correlVec); #endregion #region 获取数据接口 /// <summary> /// 获取厚度和加热的值 /// </summary> /// <param name="idx"></param> /// <returns></returns> double[] GetThicks(int idx, int from, int to); double[] GetHeats(int idx, int from, int to); double[] GetThicks(int idx, int newResetBolt, double newAngle); int GetResetBolt(int idx); double GetRotAngle(int idx); int NormalBolt(int bolt, int boltcnt); List<DateTime> Dat_Times { get; } List<double> Dat_Sigmas { get; } List<double> Dat_Means { get; } int GetIndexFromID(int id); int GetRelativeID(int id, int relative); /// <summary> /// 依据数据ID获取数据时间 /// </summary> /// <param name="id"></param> /// <returns></returns> DateTime? GetDateTimeByID(int id); #endregion int BoltCnt { get; } double[] HeatEffect { get; set; } #region 整体分析和局部分析的功能接口(数据处理) List<HeatBoltAnalystItem> SearchFeaturedBoltsItem(int startIdx, int endIdx, int searchNum, int maxFrameInterval, int heatRating, int neglectHeatRate, int Separation, int shiftRange); List<HeatBoltAnalystItem> FilterFeaturedBoltsItem(List<HeatBoltAnalystItem> items, double similarityThredhold); void StartSearchMaxSimilarity(int startIdx, int endIdx, int searchNum, int frameInterval, MaxSimilarityResult result, ProgressChangedEventHandler report, RunWorkerCompletedEventHandler runcomplete, int midbolt, double searchRange, bool SearchRotAngle, bool isAsync); /// <summary> /// /// </summary> /// <param name="idxL"></param> /// <param name="idxB"></param> /// <param name="searchRange"></param> /// <param name="SearchRotAngle"></param> /// <returns>返回值:Tuple<偏转数,相关系数,旋转角度变化量></returns> Tuple<int, double, double> SearchMaxSimilarity(int idxL, int idxB, double searchRange, bool SearchRotAngle); #endregion #region 数据库数据变化后自动运行 List<ThickHeatEvent> AutoDetectEvents { get; } /// <summary> /// 自动运行是否旋转角度 /// </summary> bool HasRotateAngleSearched { get; set; } /// <summary> /// 搜索旋转角度的范围,例如15,则在当前度数下搜索正负15度 /// </summary> double SearchingAngle { get; set; } /// <summary> /// 检查数据库,当数据库有新数据时,更新DataTo属性,并读取新数据到对象中。该函数可以一定时间间隔执行。 /// </summary> void RefreshData(); int DataChanged { get; set; } //bool IsDataReady { get; } bool BeginUse(bool isAsync = true); void EndUse(); #endregion } public enum StateCode { STC_NODAT, // 没有数据 STC_IDLE, // 空闲 STC_READING, // 读取数据 STC_UPDATING // 检查新数据 } #region 厚度加热数据自动处理结果事件 public class ThickHeatEvent { public ThickHeatEventCode EvtCode; public object EvtData; } public enum ThickHeatEventCode { EVC_RingShift, EVC_HeatBoltItem, } public class MaxSimilarityResult { public int frameIdx1; public int frameIdx2; public int frameShift; public double similarity; public double deltaAngle; public double ThickToHeatFactor; } public class HeatBoltAnalystItem { public int FrameIdx1 { get; set; } public int FrameIdx2 { get; set; } public int StartBolt { get; set; } public int EndBolt { get; set; } /// <summary> /// 偏差的位置 /// </summary> public int DisPos { get; set; } public double Similarity { get; set; } public void Clone(HeatBoltAnalystItem from) { FrameIdx1 = from.FrameIdx1; FrameIdx2 = from.FrameIdx2; StartBolt = from.StartBolt; EndBolt = from.EndBolt; DisPos = from.DisPos; Similarity = from.Similarity; } } #endregion #region DataHelper public class DataHelper { public static double[] VectorAdd(double[] a, double[] b) { int cnt = a.Count(); double[] result = new double[cnt]; for (int i = 0; i < cnt; i++) { if (double.IsNaN(a[i]) || double.IsNaN(b[i])) { result[i] = double.NaN; } else { result[i] = a[i] + b[i]; } } return result; } public static double[] VectorSub(double[] a, double[] b) { int cnt = a.Count(); double[] result = new double[cnt]; for(int i = 0; i < cnt; i++) { if (double.IsNaN(a[i]) || double.IsNaN(b[i])) { result[i] = double.NaN; } else { result[i] = a[i] - b[i]; } } return result; } } #endregion }