using AutoMapper; using FLY.Thick.Base.Common; using FLY.Thick.Base.IService; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace FLY.Thick.Base.Server { public class CurveCollection : ICurveService { #region 数据文件需要保存的数据项 /// <summary> /// AD曲线校正方式 /// </summary> public CurveCorrectWay CorrectWay { get; set; } = CurveCorrectWay.OnePointIsScale; public CurveType Flag { get; set; } = CurveType.E; /// <summary> /// 输入的曲线, 排列顺序,Value 从 小到大 /// </summary> [PropertyChanged.DoNotCheckEquality] public CurveCell[] Curves { get; set; } #endregion public struct ExChange { public ExChange(int orgAd, int currAd) { OrgAD = orgAd; CurrAD = currAd; } public int OrgAD { get; set; } public int CurrAD { get; set; } } /// <summary> /// 真实样品校正点 /// </summary> List<ExChange> RevisingCurves = new List<ExChange>(); private string param_path = "curve.json"; public CurveCollection() { SetDefault(); ReviseCurve(); } public CurveCollection(string param_path) { if (!string.IsNullOrEmpty(param_path)) this.param_path = param_path; SetDefault(); if (!Load()) { Save(); } Curves = Curves.OrderBy(c => c.Value).ToArray(); RevisingCurves.Clear(); ReviseCurve(); } void SetDefault() { CorrectWay = CurveCorrectWay.OnePointIsScale; Flag = CurveType.E; //Curves = new CurveCell[] { // new CurveCell() { AD = 57564, Value = 0 }, // new CurveCell() { AD = 30850, Value = 88 }, // new CurveCell() { AD = 19000, Value = 176 }, // new CurveCell() { AD = 12528, Value = 264 }, // new CurveCell() { AD = 8409, Value = 352 }, // new CurveCell() { AD = 5650, Value = 440 }, // new CurveCell() { AD = 3779, Value = 528 }, // new CurveCell() { AD = 2513, Value = 616 }, // new CurveCell() { AD = 1660, Value = 704 } //}; Curves = new CurveCell[] { new CurveCell() { Value = 0, AD = 50300 }, new CurveCell() { Value = 19, AD = 46505 }, new CurveCell() { Value = 38, AD = 42999 }, new CurveCell() { Value = 58, AD = 39698 }, new CurveCell() { Value = 78, AD = 36646 }, new CurveCell() { Value = 98, AD = 33894 }, new CurveCell() { Value = 118, AD = 31229 }, new CurveCell() { Value = 137, AD = 28934 }, new CurveCell() { Value = 156, AD = 26818 }, new CurveCell() { Value = 175, AD = 24908 }, new CurveCell() { Value = 194, AD = 23220 }, new CurveCell() { Value = 213, AD = 21558 }, new CurveCell() { Value = 232, AD = 20057 }, new CurveCell() { Value = 251, AD = 18606 }, new CurveCell() { Value = 271, AD = 17283 }, new CurveCell() { Value = 290, AD = 16035 } }; } public void Apply(CurveCorrectWay correctWay, CurveType flag, CurveCell2[] curves) { CorrectWay = correctWay; Flag = flag; Curves = curves.Select(c2 => new CurveCell() { AD = c2.AD, Value = c2.Value }).ToArray(); ClearExChange(); ReviseCurve(); Save(); } #region ExChange public void ModifyExChange(List<ExChange> list) { RevisingCurves.Clear(); for (int i = 0; i < list.Count(); i++) { //检测RevisingCurves 正确性,避免 /0 溢出 if ((list[i].OrgAD <= 10) || (list[i].CurrAD <= 10)) { //异常 continue; } var v = from rc in RevisingCurves where rc.OrgAD == list[i].OrgAD select rc; if (v.Count() > 0) { //异常,重复了 continue; } RevisingCurves.Add(list[i]); } RevisingCurves.OrderByDescending(c => c.OrgAD); } public void ClearExChange() { RevisingCurves.Clear(); } #endregion public static bool CheckRevisingPointValid(int ad) { if (ad < 3) { return false; } else { return true; } } /// <summary> /// 根据样品值,修正曲线,只支持2个样品 /// </summary> /// <returns></returns> public bool ReviseCurve() { if (RevisingCurves.Count < 1)//没数据 { foreach (CurveCell c in Curves) { c.RevisedAD = c.AD; } return false; } if (RevisingCurves.Count == 1)//只有一个校正点 { switch (CorrectWay) { case CurveCorrectWay.OnePointIsScale: { double ux = ((double)RevisingCurves[0].CurrAD) / RevisingCurves[0].OrgAD; foreach (CurveCell c in Curves) { c.RevisedAD = (int)(c.AD * ux); } } break; default: //case CurveCorrectWay.OnePointIsOffset: { int x = RevisingCurves[0].CurrAD - RevisingCurves[0].OrgAD; foreach (CurveCell c in Curves) { c.RevisedAD = c.AD + x; } } break; } return true; } else { int adh = RevisingCurves[0].OrgAD; int adl = RevisingCurves[1].OrgAD; double uh = ((double)RevisingCurves[0].CurrAD) / adh; double ul = ((double)RevisingCurves[1].CurrAD) / adl; for (int i = 0, j = 1; i < Curves.Count(); i++) { double ux = uh - (adh - Curves[i].AD) * (uh - ul) / (adh - adl); Curves[i].RevisedAD = (int)(Curves[i].AD * ux); } return true; } } #region Ad To Value double AD2Value_E(int ad, AD2ValueFlag flag) { int i; double value; if (Curves.Count() < 1) return -1; if (ad < 0) return -1; if (ad == 0) ad = 1; if (flag == AD2ValueFlag.NoRevised) { for (i = 0; i < Curves.Count(); i++) { if (ad < Curves[i].AD) continue; else break; } } else { for (i = 0; i < Curves.Count(); i++) { if (ad < Curves[i].RevisedAD) continue; else break; } } if (i >= Curves.Count()) i = Curves.Count() - 1; if (i == 0) i = 1; var c0 = Curves[i - 1]; var c1 = Curves[i]; double ad0, ad1, ad2; if (flag == AD2ValueFlag.NoRevised) { ad0 = Math.Log(c0.AD, Math.E); ad1 = Math.Log(c1.AD, Math.E); ad2 = Math.Log(ad, Math.E); } else { ad0 = Math.Log(c0.RevisedAD, Math.E); ad1 = Math.Log(c1.RevisedAD, Math.E); ad2 = Math.Log(ad, Math.E); } double u = (c1.Value - c0.Value) / (ad1 - ad0); value = (ad2 - ad0) * u + c0.Value; return value; } double AD2Value_Line(int ad, AD2ValueFlag flag) { int i; double value; if (Curves.Count() < 2) return -1; if (ad < 0) return -1; if (ad == 0) ad = 1; bool isDescending = true;//降序排列 if (Curves[0].AD < Curves[1].AD) isDescending = false; //找 ad0<ad<adi if (flag == AD2ValueFlag.NoRevised) { if (isDescending)//降序排列 { for (i = 0; i < Curves.Count(); i++) { if (ad < Curves[i].AD) continue; else break; } } else { for (i = 0; i < Curves.Count(); i++) { if (ad > Curves[i].AD) continue; else break; } } } else { if (isDescending)//降序排列 { for (i = 0; i < Curves.Count(); i++) { if (ad < Curves[i].RevisedAD) continue; else break; } } else { for (i = 0; i < Curves.Count(); i++) { if (ad > Curves[i].RevisedAD) continue; else break; } } } if (i >= Curves.Count()) i = Curves.Count() - 1; if (i == 0) i = 1; var c0 = Curves[i - 1]; var c1 = Curves[i]; double ad0, ad1, ad2 = ad; if (flag == AD2ValueFlag.NoRevised) { ad0 = c0.AD; ad1 = c1.AD; } else { ad0 = c0.RevisedAD; ad1 = c1.RevisedAD; } double u = (c1.Value - c0.Value) / (ad1 - ad0); value = (ad2 - ad0) * u + c0.Value; return value; } public double AD2Value(int ad, AD2ValueFlag flag) { double value; switch (Flag) { case CurveType.Line: value = AD2Value_Line(ad, flag); break; default: value = AD2Value_E(ad, flag); break; } return value; } #endregion #region Value To Ad /// <summary> /// 基本没有用 /// </summary> /// <param name="value"></param> /// <param name="flag"></param> /// <returns></returns> public int Value2Ad(double value, AD2ValueFlag flag) { int ad; switch (Flag) { case CurveType.Line: ad = Value2Ad_Line(value, flag); break; default: ad = Value2Ad_E(value, flag); break; } return ad; } int Value2Ad_E(double value, AD2ValueFlag flag) { int i; int ad; if (Curves.Count() < 1) return -1; for (i = 0; i < Curves.Count(); i++) { if (value > Curves[i].Value) continue; else break; } if (i >= Curves.Count()) i = Curves.Count() - 1; if (i == 0) i = 1; var c0 = Curves[i - 1]; var c1 = Curves[i]; double ad0, ad1, ad2; if (flag == AD2ValueFlag.NoRevised) { ad0 = Math.Log(c0.AD, Math.E); ad1 = Math.Log(c1.AD, Math.E); //ad2 = Math.Log(ad, Math.E); } else { ad0 = Math.Log(c0.RevisedAD, Math.E); ad1 = Math.Log(c1.RevisedAD, Math.E); //ad2 = Math.Log(ad, Math.E); } double u = (c1.Value - c0.Value) / (ad1 - ad0); ad2 = (value - c0.Value) / u + ad0; ad = (int)Math.Round(Math.Pow(Math.E, ad2)); return ad; } int Value2Ad_Line(double value, AD2ValueFlag flag) { int i; int ad; if (Curves.Count() < 2) return -1; for (i = 0; i < Curves.Count(); i++) { if (value > Curves[i].Value) continue; else break; } if (i >= Curves.Count()) i = Curves.Count() - 1; if (i == 0) i = 1; var c0 = Curves[i - 1]; var c1 = Curves[i]; double ad0, ad1, ad2; if (flag == AD2ValueFlag.NoRevised) { ad0 = c0.AD; ad1 = c1.AD; } else { ad0 = c0.RevisedAD; ad1 = c1.RevisedAD; } double u = (c1.Value - c0.Value) / (ad1 - ad0); ad2 = (value - c0.Value) / u + ad0; ad = (int)Math.Round(ad2); return ad; } #endregion public bool Load() { return CurveCollectionJsonDb.Load(this, param_path); } public bool Save() { return CurveCollectionJsonDb.Save(this, param_path); } #region INotifyPropertyChanged 成员 public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; #endregion } public class CurveCollectionJsonDb { static Mapper Mapper { get; } = new AutoMapper.Mapper(new MapperConfiguration(c => { c.CreateMap<CurveCollection, CurveCollectionJsonDb>() .ForMember(s => s.Curves, opt => { opt.MapFrom(s => s.Curves == null ? null : s.Curves.Select(cu => new CurveCell2() { AD = cu.AD, Value = cu.Value }).ToArray()); }).ReverseMap().ForMember(s => s.Curves, opt => { opt.MapFrom(s => s.Curves == null ? null : s.Curves.Select(cu => new CurveCell() { AD = cu.AD, Value = cu.Value }).ToArray()); }); })); public static bool Load(CurveCollection src, string filePath) { try { if (File.Exists(filePath)) { string json = File.ReadAllText(filePath); var p = JsonConvert.DeserializeObject<CurveCollectionJsonDb>(json); Mapper.Map(p, src); return true; } } catch { //异常,没有json 解码失败 } return false; } public static bool Save(CurveCollection src, string filePath) { var p = Mapper.Map<CurveCollectionJsonDb>(src); try { File.WriteAllText(filePath, JsonConvert.SerializeObject(p, Formatting.Indented)); return true; } catch { //异常,没有json 编码失败 } return false; } /// <summary> /// AD曲线校正方式 /// </summary> public CurveCorrectWay CorrectWay = CurveCorrectWay.OnePointIsScale; public CurveType Flag = CurveType.E; public CurveCell2[] Curves = new CurveCell2[] { new CurveCell2() { AD = 57564, Value = 0 }, new CurveCell2() { AD = 30850, Value = 88 }, new CurveCell2() { AD = 19000, Value = 176 }, new CurveCell2() { AD = 12528, Value = 264 }, new CurveCell2() { AD = 8409, Value = 352 }, new CurveCell2() { AD = 5650, Value = 440 }, new CurveCell2() { AD = 3779, Value = 528 }, new CurveCell2() { AD = 2513, Value = 616 }, new CurveCell2() { AD = 1660, Value = 704 } }; } }