/// <summary> /// Сохренение информации о выбранном расчетном годе /// </summary> /// <param name="fileName">имя файла</param> /// <param name="years">информация о выборе</param> public override void SaveCalcYearInfo(string fileName, CalculateYearInfo years) { using (ExcelPackage excelPackage = new ExcelPackage()) { //Set some properties of the Excel document excelPackage.Workbook.Properties.Author = "Wind Energy"; excelPackage.Workbook.Properties.Title = "Статистика наблюдений"; excelPackage.Workbook.Properties.Created = DateTime.Now; //Create the WorkSheet ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets.Add("Статистика наблюдений"); if (years.RecomendedYear != null) { worksheet.Cells[1, 1].Value = "Рекомендуется принять в качестве расчетного " + years.RecomendedYear.Year + " год"; } else { worksheet.Cells[1, 1].Value = "Не удалось выбрать расчетный год"; } worksheet.Cells[1, 1].Style.Font.Bold = true; worksheet.Cells[1, 1].Style.Fill.PatternType = ExcelFillStyle.Solid; worksheet.Cells[1, 1].Style.Fill.BackgroundColor.SetColor(Color.LightGray); //заголовок таблицы string[] header = new string[] { "Год", "Полнота ряда, %", "Интервал", "Отклонение от среднемноголетней скорости, м/с", "Отклонение от среднемноголетней скорости, %", "Отклонение повторяемости скорости", "Средняя скорость, м/с" }; for (int j = 1; j <= header.Length; j++) { worksheet.Cells[2, j].Value = header[j - 1]; } worksheet.Cells[2, 1, 2, header.Length].Style.Font.Bold = true; worksheet.Cells[2, 1, 2, header.Length].Style.Fill.PatternType = ExcelFillStyle.Solid; worksheet.Cells[2, 1, 2, header.Length].Style.Fill.BackgroundColor.SetColor(Color.LightGray); int i = 3; foreach (SinglePeriodInfo spi in years.Years) { worksheet.Cells[i, 1].Value = spi.Year; worksheet.Cells[i, 2].Value = Math.Round(spi.Completness, 1); worksheet.Cells[i, 3].Value = spi.Interval.Description(); worksheet.Cells[i, 4].Value = Math.Round(spi.SpeedDeviation, 2); worksheet.Cells[i, 5].Value = Math.Round(spi.SpeedDeviationPercent, 2); worksheet.Cells[i, 6].Value = Math.Round(spi.ExpectancyDeviation, 2); worksheet.Cells[i, 7].Value = Math.Round(spi.AverageSpeed, 2); i++; } //Save your file FileInfo fi = new FileInfo(fileName); excelPackage.SaveAs(fi); } }
/// <summary> /// сохранение информации о расчетном годе в файл /// </summary> /// <param name="fileName"></param> /// <param name="years"></param> public override void SaveCalcYearInfo(string fileName, CalculateYearInfo years) { StreamWriter sw = new StreamWriter(fileName, false, Encoding.UTF8); if (years.RecomendedYear != null) { sw.WriteLine("Рекомендуется принять в качестве расчетного " + years.RecomendedYear.Year + " год"); } string nline = "Год;Полнота ряда, %;Интервал;Отклонение от среднемноголетней скорости, м/с;Отклонение от среднемноголетней скорости, %;Отклонение повторяемости скорости;Средняя скорость, м/с"; sw.WriteLine(nline); foreach (SinglePeriodInfo spi in years.Years) { nline = string.Format("{0};{1:f2};{2};{3:f2};{4:f2};{5:f2};{6:f2}", spi.Year, spi.Completness, spi.Interval.Description(), spi.SpeedDeviation, spi.SpeedDeviationPercent, spi.ExpectancyDeviation, spi.AverageSpeed); sw.WriteLine(nline); } sw.Close(); }
/// <summary> /// создаёт окно с заданным рядом /// </summary> /// <param name="rang"></param> public FormCalcYear(RawRange rang) { InitializeComponent(); range = rang; try { years = YearCalculator.ProcessRange(range); dataGridViewExt1.DataSource = years.Years; dataGridViewExt1.ReadOnly = true; if (years.RecomendedYear != null) //если расчётный год найден { labelRecomendedYear.Text = "Рекомендуется в качестве расчетного принять " + years.RecomendedYear.Year + " год:"; labelAverageCalcYearSpeed.Text = "Средняя скорость: " + years.RecomendedYear.AverageSpeed.ToString("0.0") + " м/с"; labelCompletness.Text = "Полнота ряда: " + years.RecomendedYear.Completness.ToString("0.00") + " %"; labelExpectDeviation.Text = "Отклонение повторяемости скорости: " + years.RecomendedYear.ExpectancyDeviation.ToString("0.00") + "о.е."; labelInterval.Text = "Δt: " + years.RecomendedYear.Interval.Description() + ""; labelMaxSpeed.Text = "Максимальная скорость: " + years.RecomendedYear.Vmax.ToString("0.0") + " м/с"; labelSpeedDeviation.Text = "Отклонение скорости от многолетней: " + years.RecomendedYear.SpeedDeviation.ToString("0.00") + " м/с"; buttonOpenCalcYear.Visible = true; } else //если расчётный год не найден { _ = MessageBox.Show(this, "Не удалось найти расчётный год.\r\nРяд очень маленький или не содержит года необходимого качества"); labelAverageCalcYearSpeed.Text = "Средняя скорость: "; labelCompletness.Text = "Полнота ряда: "; labelExpectDeviation.Text = "Отклонение повторяемости скорости: "; labelInterval.Text = "Δt: "; labelMaxSpeed.Text = "Максимальная скорость: "; labelSpeedDeviation.Text = "Отклонение скорости от многолетней: "; } labelAverageYearsSpeed.Text = "Среднемноголетняя скорость: " + years.AverageSpeed.ToString("0.0") + " м/с"; } catch (ArgumentException wex) { _ = MessageBox.Show(this, wex.Message, "Выбор расчётного года", MessageBoxButtons.OK, MessageBoxIcon.Warning); Close(); } }
/// <summary> /// обработка ряда и получение расчётного года /// </summary> /// <param name="Range"></param> /// <returns></returns> public static CalculateYearInfo ProcessRange(RawRange Range) { if (Range == null || Range.Count < 3) { throw new ArgumentException("Ряд не может быть null или длиной меньше трёх наблюдений"); } List <RawItem> range = new List <RawItem>(Range); range.Sort(new DateTimeComparerRawItem()); if (range[range.Count - 1].Date - range[0].Date < TimeSpan.FromDays(366)) { throw new ArgumentException("Ряд должен быть длиной больше одного года"); } //среднемноголетняя скорость double averSpeed = range.Average((i) => i.Speed); if (double.IsNaN(averSpeed)) { throw new WindEnergyException("Ряд содержит недопустимые для расчета значения скорости"); } //разделяем исходный ряд по годам var years = range.GroupBy((i) => i.Date.Year).ToList().ConvertAll((gr) => new RawRange(gr.ToList())); //ОБРАБОТКА ВСЕХ РЯДОВ И ПОЛУЧЕНИЕ ИНФОРМАЦИИ CalculateYearInfo res = new CalculateYearInfo(); res.AverageSpeed = averSpeed; res.Range = Range; foreach (RawRange r in years) { QualityInfo qinfo = Qualifier.ProcessRange(r); //если null, то ряд очень маленький или не удалось расчитать параметры if (r == null || r[r.Count - 1].Date - r[0].Date < TimeSpan.FromDays(364)) { continue; } StatisticalRange <GradationItem> exp = StatisticEngine.GetExpectancy(range, Vars.Options.CurrentSpeedGradation); DeviationsInfo dinfo = StatisticEngine.ProcessRangeDeviations(r, averSpeed, exp); double aver = r.Average((t) => t.Speed); SinglePeriodInfo spinf = new SinglePeriodInfo() { Interval = qinfo.Intervals.Count == 1 ? qinfo.Intervals[0].Interval : StandartIntervals.Variable, Completness = qinfo.Completeness * 100, Vmax = r.Max((t) => t.Speed), Year = r[0].Date.Year, From = r[0].Date, To = r[r.Count - 1].Date, SpeedDeviation = dinfo.SpeedDeviation, ExpectancyDeviation = dinfo.ExpDeviation, AverageSpeed = aver, SpeedDeviationPercent = (dinfo.SpeedDeviation / averSpeed) * 100d }; res.Years.Add(spinf); } //ВЫБОР РАСЧЕТНОГО ГОДА //получаем года с одинаковым интервалом и полнотой больше 95% List <SinglePeriodInfo> accepts = (from t in res.Years where t.Interval != StandartIntervals.Variable && t.Interval != StandartIntervals.Missing && t.Completness > 95 select t).ToList(); //если даже таких годов не нашлось, то выходим if (accepts.Count == 0) { return(res); } //если только один год остался, то его и оставляем if (accepts.Count == 1) { res.RecomendedYear = accepts[0]; return(res); } //проверка по отклонению скорости var ac = accepts.OrderBy((t) => t.SpeedDeviation).ToList(); //в начале ряда остаются минимальные отклонения скорости double startsDev = ac[0].SpeedDeviation; //запоминаем сааамое мальнкое отклонение (с ним сравниваем остальные, чтоб найти похожие) var ac2 = ac.TakeWhile(e => e.SpeedDeviation - startsDev < Vars.Options.MinimalSpeedDeviation).ToList(); //остаются только ряды с очень похожим отклонением скоростей if (ac2.Count == 1) //если остался только один, то его оставляем { res.RecomendedYear = ac2[0]; return(res); } //проверка по отклонению повторяемости var ac3 = ac2.OrderBy((t) => t.ExpectancyDeviation); //выбираем минимальное отклонение по повторяемости res.RecomendedYear = ac3.ToList()[0]; return(res); }
/// <summary> /// сохранение информации о расчетном годе в файл /// </summary> /// <param name="fileName"></param> /// <param name="years"></param> public abstract void SaveCalcYearInfo(string fileName, CalculateYearInfo years);