lx
2025-08-07 9827a8864ba0df0a4e148b4a7ac3225df7b80728
ErrorAnalysis.UI/FrmMain.cs
@@ -21,6 +21,7 @@
        private List<COModelTable> _models;
        private Dictionary<string, string> _filters;
        private COModelTable _model;
        private ReportModel _reportModel;
        public FrmMain()
        {
@@ -85,7 +86,6 @@
                });
            }
        }
        private void btnAnalysis_Click(object sender, EventArgs e)
        {
            var curModels = GetFilterResult();
@@ -136,15 +136,32 @@
                return;
            }
            if (!decimal.TryParse(nudOilDensity.Value.ToString(), out decimal oilDensity) || nudOilDensity.Value <= 0)
            {
                MessageBox.Show("Please enter a reasonable oil density");
                return;
            }
            if (!double.TryParse(nudYieldCounting.Value.ToString(), out double yieldCounting) || nudYieldCounting.Value <= 0)
            {
                MessageBox.Show("Please enter a reasonable yield counting");
                return;
            }
            if (curModels.Count == 1)
                _model = curModels[0];
            _model = curModels.FirstOrDefault(m => m.GravelFillPercent == nudGravelFIllPercent.Value.ToString());
            _model = curModels.FirstOrDefault(m => m.GravelFillPercent == nudGravelFIllPercent.Value.ToString() && m.OilDensity == oilDensity);
            if (_model == null)
                _model = curModels.First();
            nudOilDensity.Value = _model.OilDensity.Value;
            nudGravelFIllPercent.Value = Convert.ToDecimal(_model.GravelFillPercent);
            if (cmbTargetLoggingIntervalUnit.Text == "ft")
                targetLoggingInterval = UnitConvert.Ft2M(targetLoggingInterval);
            txtAnalysisResult.Clear();
            if (rdoLockSpeed.Checked)
            {
                if (!double.TryParse(nudSpeed.Value.ToString(), out double speed) || nudSpeed.Value <= 0)
@@ -152,13 +169,23 @@
                    MessageBox.Show("Please enter a reasonable speed");
                    return;
                }
                var calcSpeed = cmbSpeedUnit.Text == "ft/hr" ? UnitConvert.FtHr2MMin(speed) : UnitConvert.MHR2MMin(speed);
                var calcSpeed = cmbSpeedUnit.Text == "ft/hr" ? UnitConvert.FtHr2MS(speed) : UnitConvert.MHR2MS(speed);
                var result = ErrorRatioCalc.GetErrorRatioResult(_model.ModelID, porosity, sw, depth, true, calcSpeed, targetErrorRatio / 100, out _);
                var result = ErrorRatioCalc.GetErrorRatioResult(_model.ModelID, porosity, sw, depth, true, calcSpeed, yieldCounting, targetErrorRatio / 100, out _);
                Plot(result);
                double totalTime = Math.Round((targetLoggingInterval / calcSpeed / 60), 2);
                txtAnalysisResult.Text = $"A total of {result.ErrorRatios.Count} passes are recommended to maintain a {Math.Round(result.ErrorRatios.Min(r => r.ErrorRatioValue) * 100, 2)}% error rate. With the tool operating at {speed} {cmbSpeedUnit.Text}, the estimated total job duration is {totalTime.ToString()} hours.";
                double totalTime = Math.Round((targetLoggingInterval / calcSpeed / 60 / 60), 2);
                var errorRate = Math.Round(result.ErrorRatios.Min(r => r.ErrorRatioValue) * 100, 2);
                txtAnalysisResult.AppendText("A total of ");
                AppendText(txtAnalysisResult, result.ErrorRatios.Count.ToString(), ColorTranslator.FromHtml("#8B0000"));
                txtAnalysisResult.AppendText(" passes are recommended to maintain a ");
                AppendText(txtAnalysisResult, $"{errorRate}%", ColorTranslator.FromHtml("#8B0000"));
                txtAnalysisResult.AppendText(" error rate. With the tool operating at ");
                AppendText(txtAnalysisResult, $"{speed} {cmbSpeedUnit.Text}", ColorTranslator.FromHtml("#8B0000"));
                txtAnalysisResult.AppendText(" the estimated total job duration is ");
                AppendText(txtAnalysisResult, $"{totalTime} hours.", ColorTranslator.FromHtml("#8B0000"));
                _reportModel = CreateReportModel(totalTime.ToString(), result.ErrorRatios.Count.ToString(), Math.Round(UnitConvert.MS2FtHr(calcSpeed), 2).ToString(), errorRate.ToString());
            }
            else
            {
@@ -168,13 +195,30 @@
                    return;
                }
                double speed;
                var result = ErrorRatioCalc.GetErrorRatioResult(_model.ModelID, porosity, sw, depth, false, 0, targetErrorRatio / 100, out speed, pass);
                var result = ErrorRatioCalc.GetErrorRatioResult(_model.ModelID, porosity, sw, depth, false, 0, yieldCounting, targetErrorRatio / 100, out speed, pass);
                Plot(result);
                double totalTime = Math.Round((targetLoggingInterval / speed / 60), 2);
                txtAnalysisResult.Text = $"A total of {result.ErrorRatios.Count} passes are recommended to maintain a {Math.Round(result.ErrorRatios.Min(r => r.ErrorRatioValue) * 100, 2)}% error rate. With the tool operating at {Math.Round(UnitConvert.MMin2FtHr(speed), 2)} ft/hr, the estimated total job duration is {totalTime.ToString()} hours.";
                double totalTime = Math.Round((targetLoggingInterval / speed / 60 / 60), 2);
                var errorRate = Math.Round(result.ErrorRatios.Min(r => r.ErrorRatioValue) * 100, 2);
                var speedFr = Math.Round(UnitConvert.MS2FtHr(speed), 2);
                txtAnalysisResult.AppendText("A total of ");
                AppendText(txtAnalysisResult, result.ErrorRatios.Count.ToString(), ColorTranslator.FromHtml("#8B0000"));
                txtAnalysisResult.AppendText(" passes are recommended to maintain a ");
                AppendText(txtAnalysisResult, $"{errorRate}%", ColorTranslator.FromHtml("#8B0000"));
                txtAnalysisResult.AppendText(" error rate. With the tool operating at ");
                AppendText(txtAnalysisResult, $"{speedFr} ft/hr", ColorTranslator.FromHtml("#8B0000"));
                txtAnalysisResult.AppendText(" the estimated total job duration is ");
                AppendText(txtAnalysisResult, $"{totalTime} hours.", ColorTranslator.FromHtml("#8B0000"));
                _reportModel = CreateReportModel(totalTime.ToString(), result.ErrorRatios.Count.ToString(), speedFr.ToString(), errorRate.ToString());
            }
        }
        private void btnReport_Click(object sender, EventArgs e)
        {
            new Report(_reportModel).ShowDialog();
        }
        #endregion
@@ -251,10 +295,10 @@
                    cmb.Text = currentItems[0];
            }
            holdCmbInit();
            LinkageModelProperty();
        }
        private void LinkageModelProperty()
        private void holdCmbInit()
        {
            cmbCasingHoldUp.Items.Clear();
            _filters.Remove("CasingFluid");
@@ -264,6 +308,59 @@
            _filters.Remove("TubeFluid");
            cmbLithology.Items.Clear();
            _filters.Remove("Lithology");
            var curModels = GetFilterResult();
            if (curModels.Count == 0)
                return;
            var casingFulids = curModels.Select(x => x.CasingFluid == "999" ? "none" : x.CasingFluid == "100" ? "oil" : x.CasingFluid == "200" ? "gas" : "water").Distinct().ToArray();
            if (casingFulids.Length == 1 && casingFulids[0] == "none")
            {
                cmbCasingHoldUp.Enabled = false;
                nudCasingHoldUp.Enabled = false;
            }
            else
            {
                cmbCasingHoldUp.Enabled = true;
                nudCasingHoldUp.Enabled = true;
                cmbCasingHoldUp.Items.AddRange(casingFulids);
            }
            var screenFulids = curModels.Select(x => x.ScreenFluid == "999" ? "none" : x.ScreenFluid == "100" ? "oil" : x.ScreenFluid == "200" ? "gas" : "water").Distinct().ToArray();
            if (screenFulids.Length == 1 && screenFulids[0] == "none")
            {
                cmbScreenHoldUp.Enabled = false;
                nudScreenHoldUp.Enabled = false;
            }
            else
            {
                cmbScreenHoldUp.Enabled = true;
                nudScreenHoldUp.Enabled = true;
                cmbScreenHoldUp.Items.AddRange(screenFulids);
            }
            var tubeFluids = curModels.Select(x => x.TubeFluid == "999" ? "none" : x.TubeFluid == "100" ? "oil" : x.TubeFluid == "200" ? "gas" : "water").Distinct().ToArray();
            if (tubeFluids.Length == 1 && tubeFluids[0] == "none")
            {
                cmbTubeHoldUp.Enabled = false;
                nudTubeHoldUp.Enabled = false;
            }
            else
            {
                cmbTubeHoldUp.Enabled = true;
                nudTubeHoldUp.Enabled = true;
                cmbTubeHoldUp.Items.AddRange(tubeFluids);
            }
        }
        private void LinkageModelProperty()
        {
            var curLithology = cmbLithology.Text;
            cmbLithology.Items.Clear();
            _filters.Remove("Lithology");
            var curModels = GetFilterResult();
            if (curModels.Count == 0)
                return;
@@ -292,53 +389,10 @@
            if (vshs.Length == 1)
                nudVSH.Value = Convert.ToDecimal(vshs[0]);
            var casingFulids = curModels.Select(x => x.CasingFluid == "0" ? "water" : x.CasingFluid == "100" ? "oil" : x.CasingFluid == "200" ? "gas" : "none").Distinct().ToArray();
            if (casingFulids.Length == 1 && casingFulids[0] == "999")
            {
                cmbCasingHoldUp.Enabled = false;
                nudCasingHoldUp.Enabled = false;
            }
            else
            {
                cmbCasingHoldUp.Enabled = true;
                nudCasingHoldUp.Enabled = true;
                cmbCasingHoldUp.Items.AddRange(casingFulids);
            }
            var screenFulids = curModels.Select(x => x.ScreenFluid == "0" ? "water" : x.ScreenFluid == "100" ? "oil" : x.ScreenFluid == "200" ? "gas" : "none").Distinct().ToArray();
            if (screenFulids.Length == 1 && screenFulids[0] == "none")
            {
                cmbScreenHoldUp.Enabled = false;
                nudScreenHoldUp.Enabled = false;
            }
            else
            {
                cmbScreenHoldUp.Enabled = true;
                nudScreenHoldUp.Enabled = true;
                cmbScreenHoldUp.Items.AddRange(screenFulids);
            }
            var tubeFluids = curModels.Select(x => x.TubeFluid == "0" ? "water" : x.TubeFluid == "100" ? "oil" : x.TubeFluid == "200" ? "gas" : "none").Distinct().ToArray();
            if (tubeFluids.Length == 1 && tubeFluids[0] == "none")
            {
                cmbTubeHoldUp.Enabled = false;
                nudTubeHoldUp.Enabled = false;
            }
            else
            {
                cmbTubeHoldUp.Enabled = true;
                nudTubeHoldUp.Enabled = true;
                cmbTubeHoldUp.Items.AddRange(tubeFluids);
            }
            var lithology = curModels.Select(x => x.Lithology).Distinct().ToArray();
            var curLithology = cmbLithology.Text;
            cmbLithology.Items.AddRange(lithology);
            cmbLithology.Text = curLithology;
            if (cmbLithology.Items.Contains(curLithology))
                cmbLithology.Text = curLithology;
            if (lithology.Length == 1)
                cmbLithology.SelectedIndex = 0;
@@ -396,6 +450,7 @@
                }
            }
            LinkageModelProperty();
            //foreach (var cmb in allCmb)
            //{
            //    if (cmb.Name != control.Name)
@@ -411,15 +466,6 @@
            //    }
            //}
            var lithology = curModels.Select(x => x.Lithology).Distinct().ToArray();
            cmbLithology.Items.Clear();
            cmbLithology.Items.AddRange(lithology);
            if (_filters.ContainsKey("Lithology") && lithology.Contains(_filters["Lithology"]))
                cmbLithology.Text = _filters["Lithology"];
            else
                _filters.Remove("Lithology");
        }
        private void cmbLithology_SelectedIndexChanged(object sender, EventArgs e)
        {
@@ -457,7 +503,6 @@
            return result;
        }
        private void Plot(ErrorRatioResult errorResult)
        {
            pnlCOPic.Controls.Clear();
@@ -523,5 +568,57 @@
            plotView.Dock = DockStyle.Fill;
            pnlErrorRatioPic.Controls.Add(plotView);
        }
        private ReportModel CreateReportModel(string duration, string pass, string speed, string soPrecision)
        {
            return new ReportModel
            {
                BHSalinity = nudBHSalinity.Value.ToString(),
                BIT = cmbBit.Text,
                CasingFluid = cmbCasingHoldUp.Text,
                CasingHoldUp = nudCasingHoldUp.Value.ToString(),
                CasingID = cmbCasingID.Text,
                CasingOD = cmbCasingOD.Text,
                CementBond = nudCementBond.Text,
                DepthAveraging = nudDepth.Value.ToString(),
                Duration = duration,
                GasSalinity = nudGasDensity.Value.ToString(),
                GravelFillPercent = nudGravelFIllPercent.Value.ToString(),
                Lithology = cmbLithology.Text,
                OilSalinity = nudOilDensity.Value.ToString(),
                Pass = pass,
                Porosity = nudPorosity.Value.ToString(),
                ReserviorSalinity = nudReservoirSalinity.Value.ToString(),
                ScreenFluid = cmbScreenHoldUp.Text,
                ScreenHoldUp = nudScreenHoldUp.Value.ToString(),
                ScreenID = cmbScreenID.Text,
                ScreenOD = cmbScreenOD.Text,
                SoPrecisionRequired = soPrecision,
                Speed = speed,
                TargetLoggingInterval = nudTargetLoggingInterval.Value.ToString(),
                TubeFluid = cmbTubeHoldUp.Text,
                TubeHoldUp = nudTubeHoldUp.Value.ToString(),
                TubeID = cmbTubeID.Text,
                TubeOD = cmbTubeOD.Text,
                VSH = nudVSH.Value.ToString(),
                WaterSaturation = nudSw.Value.ToString()
            };
        }
        private void AppendText(RichTextBox rtb, string text, Color color, Font font = null, bool isNewLine = false)
        {
            rtb.SuspendLayout();
            rtb.SelectionStart = rtb.TextLength;
            rtb.SelectionLength = 0;
            rtb.SelectionColor = color;
            if (font != null)
                rtb.SelectionFont = font;
            rtb.AppendText(isNewLine ? $"{text}{Environment.NewLine}" : text);
            rtb.SelectionColor = rtb.ForeColor;
            rtb.ScrollToCaret();
            rtb.ResumeLayout();
        }
    }
}