CurveCollection.cs 15.8 KB
Newer Older
1
using AutoMapper;
潘栩锋's avatar
潘栩锋 committed
2 3
using FLY.Thick.Base.Common;
using FLY.Thick.Base.IService;
4
using Newtonsoft.Json;
5 6 7 8
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
9

潘栩锋's avatar
潘栩锋 committed
10 11
namespace FLY.Thick.Base.Server
{
12
    public class CurveCollection : ICurveService
潘栩锋's avatar
潘栩锋 committed
13 14
    {
        #region 数据文件需要保存的数据项
15

潘栩锋's avatar
潘栩锋 committed
16 17 18
        /// <summary>
        /// AD曲线校正方式
        /// </summary>
19
        public CurveCorrectWay CorrectWay { get; set; } = CurveCorrectWay.OnePointIsScale;
潘栩锋's avatar
潘栩锋 committed
20

21
        public CurveType Flag { get; set; } = CurveType.E;
潘栩锋's avatar
潘栩锋 committed
22 23 24 25

        /// <summary>
        /// 输入的曲线, 排列顺序,Value 从 小到大
        /// </summary>
潘栩锋's avatar
潘栩锋 committed
26
        [PropertyChanged.DoNotCheckEquality]
27
        public CurveCell[] Curves { get; set; }
潘栩锋's avatar
潘栩锋 committed
28

潘栩锋's avatar
潘栩锋 committed
29 30 31
        #endregion


32
        public struct ExChange
潘栩锋's avatar
潘栩锋 committed
33
        {
34 35
            public ExChange(int orgAd, int currAd)
            {
36 37
                OrgAD = orgAd;
                CurrAD = currAd;
潘栩锋's avatar
潘栩锋 committed
38 39 40 41 42 43 44
            }
            public int OrgAD { get; set; }
            public int CurrAD { get; set; }
        }
        /// <summary>
        /// 真实样品校正点
        /// </summary>
潘栩锋's avatar
潘栩锋 committed
45 46
        List<ExChange> RevisingCurves = new List<ExChange>();

47
        private string param_path = "curve.json";
48
        public CurveCollection()
潘栩锋's avatar
潘栩锋 committed
49 50 51 52
        {
            SetDefault();
            ReviseCurve();
        }
53

潘栩锋's avatar
潘栩锋 committed
54 55 56 57 58 59
        public CurveCollection(string param_path)
        {
            if (!string.IsNullOrEmpty(param_path))
                this.param_path = param_path;

            SetDefault();
60 61
            if (!Load())
            {
62 63 64 65
                Save();
            }
            Curves = Curves.OrderBy(c => c.Value).ToArray();
            RevisingCurves.Clear();
潘栩锋's avatar
潘栩锋 committed
66
            ReviseCurve();
67

潘栩锋's avatar
潘栩锋 committed
68
        }
69
        void SetDefault()
潘栩锋's avatar
潘栩锋 committed
70 71 72
        {
            CorrectWay = CurveCorrectWay.OnePointIsScale;
            Flag = CurveType.E;
73 74
            Curves = new CurveCell[] {
                new CurveCell() { AD = 57564, Value = 0 },
75 76 77 78 79 80 81
                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  },
82
                new CurveCell() { AD = 1660, Value = 704 }
83
            };
潘栩锋's avatar
潘栩锋 committed
84
        }
85
        public void Apply(CurveCorrectWay correctWay, CurveType flag, CurveCell2[] curves)
潘栩锋's avatar
潘栩锋 committed
86
        {
87 88
            CorrectWay = correctWay;
            Flag = flag;
89 90

            Curves = curves.Select(c2 => new CurveCell() { AD = c2.AD, Value = c2.Value }).ToArray();
潘栩锋's avatar
潘栩锋 committed
91 92 93 94 95
            ClearExChange();
            ReviseCurve();

            Save();
        }
96

潘栩锋's avatar
潘栩锋 committed
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168

        #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);
                            }
169 170
                        }
                        break;
潘栩锋's avatar
潘栩锋 committed
171 172 173 174 175 176 177 178 179
                    default:
                        //case CurveCorrectWay.OnePointIsOffset:
                        {
                            int x = RevisingCurves[0].CurrAD - RevisingCurves[0].OrgAD;

                            foreach (CurveCell c in Curves)
                            {
                                c.RevisedAD = c.AD + x;
                            }
180 181
                        }
                        break;
潘栩锋's avatar
潘栩锋 committed
182 183 184 185 186 187 188 189 190 191 192
                }

                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;

193
                for (int i = 0, j = 1; i < Curves.Count(); i++)
潘栩锋's avatar
潘栩锋 committed
194 195 196 197 198 199 200 201
                {
                    double ux = uh - (adh - Curves[i].AD) * (uh - ul) / (adh - adl);
                    Curves[i].RevisedAD = (int)(Curves[i].AD * ux);
                }
                return true;
            }
        }

202
        #region Ad To Value
潘栩锋's avatar
潘栩锋 committed
203

204
        double AD2Value_E(int ad, AD2ValueFlag flag)
潘栩锋's avatar
潘栩锋 committed
205 206
        {
            int i;
207
            double value;
潘栩锋's avatar
潘栩锋 committed
208

209
            if (Curves.Count() < 1) return -1;
潘栩锋's avatar
潘栩锋 committed
210 211 212 213
            if (ad < 0) return -1;
            if (ad == 0) ad = 1;
            if (flag == AD2ValueFlag.NoRevised)
            {
214
                for (i = 0; i < Curves.Count(); i++)
潘栩锋's avatar
潘栩锋 committed
215 216 217 218 219 220 221 222 223
                {
                    if (ad < Curves[i].AD)
                        continue;
                    else
                        break;
                }
            }
            else
            {
224
                for (i = 0; i < Curves.Count(); i++)
潘栩锋's avatar
潘栩锋 committed
225 226 227 228 229 230 231
                {
                    if (ad < Curves[i].RevisedAD)
                        continue;
                    else
                        break;
                }
            }
232 233

            if (i >= Curves.Count())
234
                i = Curves.Count() - 1;
235
            if (i == 0)
236 237 238 239 240
                i = 1;

            var c0 = Curves[i - 1];
            var c1 = Curves[i];
            double ad0, ad1, ad2;
潘栩锋's avatar
潘栩锋 committed
241 242
            if (flag == AD2ValueFlag.NoRevised)
            {
243 244 245
                ad0 = Math.Log(c0.AD, Math.E);
                ad1 = Math.Log(c1.AD, Math.E);
                ad2 = Math.Log(ad, Math.E);
潘栩锋's avatar
潘栩锋 committed
246 247 248
            }
            else
            {
249 250 251
                ad0 = Math.Log(c0.RevisedAD, Math.E);
                ad1 = Math.Log(c1.RevisedAD, Math.E);
                ad2 = Math.Log(ad, Math.E);
潘栩锋's avatar
潘栩锋 committed
252
            }
253 254
            double u = (c1.Value - c0.Value) / (ad1 - ad0);
            value = (ad2 - ad0) * u + c0.Value;
潘栩锋's avatar
潘栩锋 committed
255

256
            return value;
潘栩锋's avatar
潘栩锋 committed
257
        }
258 259
        
        
260
        double AD2Value_Line(int ad, AD2ValueFlag flag)
潘栩锋's avatar
潘栩锋 committed
261 262
        {
            int i;
263
            double value;
潘栩锋's avatar
潘栩锋 committed
264

265
            if (Curves.Count() < 2) return -1;
潘栩锋's avatar
潘栩锋 committed
266 267 268 269 270 271 272 273 274 275 276
            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)//降序排列
                {
277
                    for (i = 0; i < Curves.Count(); i++)
潘栩锋's avatar
潘栩锋 committed
278 279 280 281 282 283 284 285 286
                    {
                        if (ad < Curves[i].AD)
                            continue;
                        else
                            break;
                    }
                }
                else
                {
287
                    for (i = 0; i < Curves.Count(); i++)
潘栩锋's avatar
潘栩锋 committed
288 289 290 291 292 293 294 295
                    {
                        if (ad > Curves[i].AD)
                            continue;
                        else
                            break;
                    }
                }
            }
296 297
            else
            {
潘栩锋's avatar
潘栩锋 committed
298 299
                if (isDescending)//降序排列
                {
300
                    for (i = 0; i < Curves.Count(); i++)
潘栩锋's avatar
潘栩锋 committed
301 302 303 304 305 306 307 308 309
                    {
                        if (ad < Curves[i].RevisedAD)
                            continue;
                        else
                            break;
                    }
                }
                else
                {
310
                    for (i = 0; i < Curves.Count(); i++)
潘栩锋's avatar
潘栩锋 committed
311 312 313 314 315 316 317
                    {
                        if (ad > Curves[i].RevisedAD)
                            continue;
                        else
                            break;
                    }
                }
318
            }
319

320 321
            if (i >= Curves.Count()) i = Curves.Count() - 1;
            if (i == 0) i = 1;
潘栩锋's avatar
潘栩锋 committed
322

323 324 325 326 327 328 329
            var c0 = Curves[i - 1];
            var c1 = Curves[i];
            double ad0, ad1, ad2 = ad;
            if (flag == AD2ValueFlag.NoRevised)
            {
                ad0 = c0.AD;
                ad1 = c1.AD;
潘栩锋's avatar
潘栩锋 committed
330
            }
331 332 333 334 335 336 337 338
            else
            {
                ad0 = c0.RevisedAD;
                ad1 = c1.RevisedAD;
            }
            double u = (c1.Value - c0.Value) / (ad1 - ad0);
            value = (ad2 - ad0) * u + c0.Value;
            return value;
潘栩锋's avatar
潘栩锋 committed
339
        }
340
        
潘栩锋's avatar
潘栩锋 committed
341

342
        public double AD2Value(int ad, AD2ValueFlag flag)
潘栩锋's avatar
潘栩锋 committed
343
        {
344
            double value;
潘栩锋's avatar
潘栩锋 committed
345 346 347
            switch (Flag)
            {
                case CurveType.Line:
348 349
                    value = AD2Value_Line(ad, flag);
                    break;
潘栩锋's avatar
潘栩锋 committed
350
                default:
351 352
                    value = AD2Value_E(ad, flag);
                    break;
潘栩锋's avatar
潘栩锋 committed
353
            }
354
            return value;
潘栩锋's avatar
潘栩锋 committed
355
        }
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
        #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
潘栩锋's avatar
潘栩锋 committed
458

459

潘栩锋's avatar
潘栩锋 committed
460 461
        public bool Load()
        {
462
            return CurveCollectionJsonDb.Load(this, param_path);
潘栩锋's avatar
潘栩锋 committed
463
        }
464
        public bool Save()
潘栩锋's avatar
潘栩锋 committed
465
        {
466
            return CurveCollectionJsonDb.Save(this, param_path);
潘栩锋's avatar
潘栩锋 committed
467
        }
468 469 470 471

        #region INotifyPropertyChanged 成员

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
潘栩锋's avatar
潘栩锋 committed
472
        #endregion
473
    }
潘栩锋's avatar
潘栩锋 committed
474 475


476 477 478
    public class CurveCollectionJsonDb
    {
        static Mapper Mapper { get; } = new AutoMapper.Mapper(new MapperConfiguration(c =>
潘栩锋's avatar
潘栩锋 committed
479
        {
480 481 482 483 484 485 486 487 488
            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());
            });
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
        }));
        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;
潘栩锋's avatar
潘栩锋 committed
508
        }
509 510 511 512 513 514 515 516 517 518 519
        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 编码失败
潘栩锋's avatar
潘栩锋 committed
520

521 522
            }
            return false;
潘栩锋's avatar
潘栩锋 committed
523

524
        }
潘栩锋's avatar
潘栩锋 committed
525

526 527 528 529 530 531 532
        /// <summary>
        /// AD曲线校正方式
        /// </summary>
        public CurveCorrectWay CorrectWay = CurveCorrectWay.OnePointIsScale;

        public CurveType Flag = CurveType.E;

533 534 535 536 537 538 539 540 541 542
        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 }
543
        };
潘栩锋's avatar
潘栩锋 committed
544 545
    }
}