feat(nmNum): 增加第四种计算方式与拟合设置入口

- 复用采样界面和拟合窗口,修正切换时的布局偏移。
- 确认后暂存拟合设置并启用生成,批量拟合暂未接入。
- 拟合参数默认不选,禁用已参与采样的参数。
feature/Sensitivity-20261012
lvjunjie 7 days ago
parent 130607b030
commit 525b65ec2a

@ -16,6 +16,7 @@
#include <QTimer> #include <QTimer>
#include <QMessageBox> #include <QMessageBox>
#include <QApplication> #include <QApplication>
#include <QStringList>
#include "nmDataAnalyzeManager.h" #include "nmDataAnalyzeManager.h"
#include "nmDataReservoir.h" #include "nmDataReservoir.h"
@ -27,12 +28,23 @@
#include "nmSubWxs_global.h" #include "nmSubWxs_global.h"
// 敏感性窗口持有的临时拟合设置,确认后才替换,不写入当前模型。
struct nmSensitivityFitSettings
{
nmSensitivityFitSettings() : confirmed(false) {}
bool confirmed;
nmDataAutomaticFitting parameters;
QString targetWell;
QVector<double> initialValues;
};
class NM_SUB_WXS_EXPORT nmWxAutomaticFitting : public iDlgBase class NM_SUB_WXS_EXPORT nmWxAutomaticFitting : public iDlgBase
{ {
Q_OBJECT Q_OBJECT
public: public:
nmWxAutomaticFitting(QWidget *parent = 0); nmWxAutomaticFitting(QWidget *parent = 0, nmSensitivityFitSettings* settings = nullptr,
const QStringList& sampledParameters = QStringList());
~nmWxAutomaticFitting(); ~nmWxAutomaticFitting();
virtual QSize sizeHint() const; virtual QSize sizeHint() const;
@ -57,6 +69,7 @@ private:
void setupControlPanel(); void setupControlPanel();
void setupButtons(); void setupButtons();
void setAutomaticFittingValue(); void setAutomaticFittingValue();
void loadSensitivitySettings();
void setParameterRowVisible(QTableWidget* table, int row, bool visible); void setParameterRowVisible(QTableWidget* table, int row, bool visible);
void renumberVisibleParameterRows(QTableWidget* table); void renumberVisibleParameterRows(QTableWidget* table);
void updateParameterVisibility(QTableWidget* table, NM_SOLVER_MODEL_TYPE eType); void updateParameterVisibility(QTableWidget* table, NM_SOLVER_MODEL_TYPE eType);
@ -101,6 +114,8 @@ private:
// 数据成员 // 数据成员
nmDataReservoir reservoirData; nmDataReservoir reservoirData;
nmDataAutomaticFitting automaticFittingData; nmDataAutomaticFitting automaticFittingData;
nmSensitivityFitSettings* m_sensitivitySettings;
QStringList m_sampledParameters;
// 自动拟合相关成员 // 自动拟合相关成员
nmCalculationAutoFitPSO* m_autoFitterPSO; nmCalculationAutoFitPSO* m_autoFitterPSO;

@ -26,6 +26,7 @@ class SensitivityResultsModel;
class iGuiPlot; class iGuiPlot;
class QMenu; class QMenu;
class QAction; class QAction;
struct nmSensitivityFitSettings;
class NM_SUB_WXS_EXPORT nmWxSensitivityHistogramOptions : public iDlgBase class NM_SUB_WXS_EXPORT nmWxSensitivityHistogramOptions : public iDlgBase
{ {
@ -114,6 +115,7 @@ protected:
void onGenerateClicked(); void onGenerateClicked();
void onCancelClicked(); void onCancelClicked();
void onCalculationTypeChanged(int index); void onCalculationTypeChanged(int index);
void onImproveSettingsClicked();
void onTreeItemClicked(QTreeWidgetItem *item, int column); void onTreeItemClicked(QTreeWidgetItem *item, int column);
void onVariableParamChanged(); void onVariableParamChanged();
void onSamplingEditingFinished(); void onSamplingEditingFinished();
@ -145,6 +147,8 @@ private:
// UI 控件 // UI 控件
QComboBox *calculationTypeCombo; QComboBox *calculationTypeCombo;
QPushButton *m_improveSettingsButton;
QSharedPointer<nmSensitivityFitSettings> m_improveSettings;
QTreeWidget *variablesTree; QTreeWidget *variablesTree;
QStackedWidget *detailStack; QStackedWidget *detailStack;
QLabel *modelCountLabel; QLabel *modelCountLabel;

@ -79,11 +79,14 @@ void nmWxAutomaticFitting::setParameterRowVisible(QTableWidget* table, int row,
QCheckBox* checkBox = qobject_cast<QCheckBox*>(table->cellWidget(row, 1)); QCheckBox* checkBox = qobject_cast<QCheckBox*>(table->cellWidget(row, 1));
if(checkBox) { if(checkBox) {
checkBox->setEnabled(visible); // 与当前采样重叠的参数不能参与拟合,切换目标井时也保持互斥。
if(!visible) { const QString samplingNames[] = {"k", "Skin", "C", QString(QChar(0x03c6))};
const bool sampled = m_sensitivitySettings && row < 4 && m_sampledParameters.contains(samplingNames[row]);
checkBox->setEnabled(visible && !sampled);
if(!visible || sampled) {
checkBox->setChecked(false); checkBox->setChecked(false);
} else if(wasHidden) { } else if(wasHidden) {
checkBox->setChecked(true); checkBox->setChecked(!m_sensitivitySettings);
} }
} }
} }
@ -408,8 +411,11 @@ bool nmWxAutomaticFitting::validateParameterTable(QString& errorMessage, int par
return true; return true;
} }
nmWxAutomaticFitting::nmWxAutomaticFitting(QWidget *parent) nmWxAutomaticFitting::nmWxAutomaticFitting(QWidget *parent, nmSensitivityFitSettings* settings,
const QStringList& sampledParameters)
: iDlgBase(parent) : iDlgBase(parent)
, m_sensitivitySettings(settings)
, m_sampledParameters(sampledParameters)
, m_autoFitterPSO(nullptr) , m_autoFitterPSO(nullptr)
, m_autoFitterLM(nullptr) , m_autoFitterLM(nullptr)
, m_progressDialog(nullptr) , m_progressDialog(nullptr)
@ -429,6 +435,8 @@ nmWxAutomaticFitting::nmWxAutomaticFitting(QWidget *parent)
m_autoParameterRanges = true; m_autoParameterRanges = true;
setupUI(); setupUI();
// 敏感性入口使用“确定”保存设置,普通入口仍直接开始拟合。
if(m_sensitivitySettings) m_okBtn->setText(tr("OK"));
setWindowTitle(tr("Automatic fitting")); setWindowTitle(tr("Automatic fitting"));
setModal(true); setModal(true);
// 初始尺寸随所在屏幕变化,最小尺寸交给实际控件布局决定。 // 初始尺寸随所在屏幕变化,最小尺寸交给实际控件布局决定。
@ -439,11 +447,39 @@ nmWxAutomaticFitting::nmWxAutomaticFitting(QWidget *parent)
} }
// 每次打开都按当前模型参数生成范围,不沿用上次的上下限。 // 每次打开都按当前模型参数生成范围,不沿用上次的上下限。
initializeSuggestedParameterRanges(); initializeSuggestedParameterRanges();
if(m_sensitivitySettings && m_sensitivitySettings->confirmed) loadSensitivitySettings();
m_updatingParameterRanges = false; m_updatingParameterRanges = false;
DEBUG_UI("AutoFitting Constructor completed"); DEBUG_UI("AutoFitting Constructor completed");
} }
void nmWxAutomaticFitting::loadSensitivitySettings()
{
// 先恢复目标井,再覆盖默认范围与初值,保留上次确认的完整设置。
m_targetWellCombo->setCurrentIndex(m_targetWellCombo->findText(m_sensitivitySettings->targetWell));
automaticFittingData = m_sensitivitySettings->parameters;
m_autoParameterRanges = false;
m_algorithmCombo->setCurrentIndex(automaticFittingData.getAlgorithmName() == "LM" ? 1 : 0);
m_iterationEdit->setText(QString::number(automaticFittingData.getIterationCount().getValue().toInt()));
m_errorLimitEdit->setText(QString::number(automaticFittingData.getErrorTolerance().getValue().toDouble(), 'g', 10));
const int rows[] = {0, 1, 2, 3, 5, 6};
QCheckBox* checks[] = {m_kCheckBox, m_sCheckBox, m_cCheckBox, m_phiCheckBox, m_dfcCheckBox, m_fractureHalfLengthCheckBox};
const bool selected[] = {automaticFittingData.getPermeabilitySelected(), automaticFittingData.getSkinSelected(),
automaticFittingData.getWellboreStorageSelected(), automaticFittingData.getPorositySelected(),
automaticFittingData.getFractureConductivitySelected(), automaticFittingData.getFractureHalfLengthSelected()};
nmDataAttribute* lower[] = {&automaticFittingData.getPermeabilityMin(), &automaticFittingData.getSkinMin(),
&automaticFittingData.getWellboreStorageMin(), &automaticFittingData.getPorosityMin(),
&automaticFittingData.getFractureConductivityMin(), &automaticFittingData.getFractureHalfLengthMin()};
nmDataAttribute* upper[] = {&automaticFittingData.getPermeabilityMax(), &automaticFittingData.getSkinMax(),
&automaticFittingData.getWellboreStorageMax(), &automaticFittingData.getPorosityMax(),
&automaticFittingData.getFractureConductivityMax(), &automaticFittingData.getFractureHalfLengthMax()};
for(int i = 0; i < 6; ++i) {
checks[i]->setChecked(selected[i] && checks[i]->isEnabled());
setParameterRange(rows[i], lower[i]->getValue().toDouble(), upper[i]->getValue().toDouble());
m_parameterTable->item(rows[i], 3)->setText(QString::number(m_sensitivitySettings->initialValues[i], 'g', 10));
}
}
QSize nmWxAutomaticFitting::sizeHint() const QSize nmWxAutomaticFitting::sizeHint() const
{ {
// 沿用项目的可用屏幕尺寸计算方式,优先取父窗口所在屏幕,支持多显示器。 // 沿用项目的可用屏幕尺寸计算方式,优先取父窗口所在屏幕,支持多显示器。
@ -525,7 +561,7 @@ void nmWxAutomaticFitting::setupUI()
void nmWxAutomaticFitting::setupParameterTable() void nmWxAutomaticFitting::setupParameterTable()
{ {
// 每次打开时默认勾选全部参数,再按井型隐藏不可用参数。 // 敏感性设置首次打开时不预选参数,普通拟合仍默认全选,再按井型隐藏不可用参数。
m_parameterTable = new QTableWidget(7, 6, this); m_parameterTable = new QTableWidget(7, 6, this);
// 设置表头 // 设置表头
@ -564,7 +600,7 @@ void nmWxAutomaticFitting::setupParameterTable()
// 渗透率 (Permeability) // 渗透率 (Permeability)
m_parameterTable->setItem(0, 0, new QTableWidgetItem("1")); m_parameterTable->setItem(0, 0, new QTableWidgetItem("1"));
m_kCheckBox = new QCheckBox(tr("Permeability")); m_kCheckBox = new QCheckBox(tr("Permeability"));
m_kCheckBox->setChecked(true); m_kCheckBox->setChecked(!m_sensitivitySettings);
m_parameterTable->setCellWidget(0, 1, m_kCheckBox); m_parameterTable->setCellWidget(0, 1, m_kCheckBox);
m_parameterTable->setItem(0, 2, new QTableWidgetItem(QString::number(automaticFittingData.getPermeabilityMin().getValue().toDouble()))); m_parameterTable->setItem(0, 2, new QTableWidgetItem(QString::number(automaticFittingData.getPermeabilityMin().getValue().toDouble())));
m_parameterTable->setItem(0, 3, new QTableWidgetItem(QString::number(reservoirData.getPermeability().getValue().toDouble()))); m_parameterTable->setItem(0, 3, new QTableWidgetItem(QString::number(reservoirData.getPermeability().getValue().toDouble())));
@ -574,7 +610,7 @@ void nmWxAutomaticFitting::setupParameterTable()
// 表皮系数 (Skin) // 表皮系数 (Skin)
m_parameterTable->setItem(1, 0, new QTableWidgetItem("2")); m_parameterTable->setItem(1, 0, new QTableWidgetItem("2"));
m_sCheckBox = new QCheckBox(tr("Skin")); m_sCheckBox = new QCheckBox(tr("Skin"));
m_sCheckBox->setChecked(true); m_sCheckBox->setChecked(!m_sensitivitySettings);
m_parameterTable->setCellWidget(1, 1, m_sCheckBox); m_parameterTable->setCellWidget(1, 1, m_sCheckBox);
m_parameterTable->setItem(1, 2, new QTableWidgetItem(QString::number(automaticFittingData.getSkinMin().getValue().toDouble()))); m_parameterTable->setItem(1, 2, new QTableWidgetItem(QString::number(automaticFittingData.getSkinMin().getValue().toDouble())));
m_parameterTable->setItem(1, 3, new QTableWidgetItem()); m_parameterTable->setItem(1, 3, new QTableWidgetItem());
@ -584,7 +620,7 @@ void nmWxAutomaticFitting::setupParameterTable()
// 井筒储集系数 (Wellbore storage) // 井筒储集系数 (Wellbore storage)
m_parameterTable->setItem(2, 0, new QTableWidgetItem("3")); m_parameterTable->setItem(2, 0, new QTableWidgetItem("3"));
m_cCheckBox = new QCheckBox(tr("Wellbore storage")); m_cCheckBox = new QCheckBox(tr("Wellbore storage"));
m_cCheckBox->setChecked(true); m_cCheckBox->setChecked(!m_sensitivitySettings);
m_parameterTable->setCellWidget(2, 1, m_cCheckBox); m_parameterTable->setCellWidget(2, 1, m_cCheckBox);
m_parameterTable->setItem(2, 2, new QTableWidgetItem(QString::number(automaticFittingData.getWellboreStorageMin().getValue().toDouble()))); m_parameterTable->setItem(2, 2, new QTableWidgetItem(QString::number(automaticFittingData.getWellboreStorageMin().getValue().toDouble())));
m_parameterTable->setItem(2, 3, new QTableWidgetItem()); m_parameterTable->setItem(2, 3, new QTableWidgetItem());
@ -594,7 +630,7 @@ void nmWxAutomaticFitting::setupParameterTable()
// 孔隙度 (Porosity) // 孔隙度 (Porosity)
m_parameterTable->setItem(3, 0, new QTableWidgetItem("4")); m_parameterTable->setItem(3, 0, new QTableWidgetItem("4"));
m_phiCheckBox = new QCheckBox(tr("Porosity")); m_phiCheckBox = new QCheckBox(tr("Porosity"));
m_phiCheckBox->setChecked(true); m_phiCheckBox->setChecked(!m_sensitivitySettings);
m_parameterTable->setCellWidget(3, 1, m_phiCheckBox); m_parameterTable->setCellWidget(3, 1, m_phiCheckBox);
m_parameterTable->setItem(3, 2, new QTableWidgetItem(QString::number(automaticFittingData.getPorosityMin().getValue().toDouble()))); m_parameterTable->setItem(3, 2, new QTableWidgetItem(QString::number(automaticFittingData.getPorosityMin().getValue().toDouble())));
m_parameterTable->setItem(3, 3, new QTableWidgetItem(QString::number(reservoirData.getPorosity().getValue().toDouble()))); m_parameterTable->setItem(3, 3, new QTableWidgetItem(QString::number(reservoirData.getPorosity().getValue().toDouble())));
@ -607,7 +643,7 @@ void nmWxAutomaticFitting::setupParameterTable()
// 从当前目标井读取,其他裂缝几何参数保持固定,不进入自动拟合。 // 从当前目标井读取,其他裂缝几何参数保持固定,不进入自动拟合。
m_parameterTable->setItem(5, 0, new QTableWidgetItem("6")); m_parameterTable->setItem(5, 0, new QTableWidgetItem("6"));
m_dfcCheckBox = new QCheckBox(tr("Fracture conductivity")); m_dfcCheckBox = new QCheckBox(tr("Fracture conductivity"));
m_dfcCheckBox->setChecked(true); m_dfcCheckBox->setChecked(!m_sensitivitySettings);
m_parameterTable->setCellWidget(5, 1, m_dfcCheckBox); m_parameterTable->setCellWidget(5, 1, m_dfcCheckBox);
m_parameterTable->setItem(5, 2, new QTableWidgetItem(QString::number(automaticFittingData.getFractureConductivityMin().getValue().toDouble()))); m_parameterTable->setItem(5, 2, new QTableWidgetItem(QString::number(automaticFittingData.getFractureConductivityMin().getValue().toDouble())));
m_parameterTable->setItem(5, 3, new QTableWidgetItem()); m_parameterTable->setItem(5, 3, new QTableWidgetItem());
@ -617,7 +653,7 @@ void nmWxAutomaticFitting::setupParameterTable()
// 裂缝半长。该行与 Dfc 一样只对压裂井显示,初值从当前目标井读取。 // 裂缝半长。该行与 Dfc 一样只对压裂井显示,初值从当前目标井读取。
m_parameterTable->setItem(6, 0, new QTableWidgetItem("7")); m_parameterTable->setItem(6, 0, new QTableWidgetItem("7"));
m_fractureHalfLengthCheckBox = new QCheckBox(tr("Fracture half length")); m_fractureHalfLengthCheckBox = new QCheckBox(tr("Fracture half length"));
m_fractureHalfLengthCheckBox->setChecked(true); m_fractureHalfLengthCheckBox->setChecked(!m_sensitivitySettings);
m_parameterTable->setCellWidget(6, 1, m_fractureHalfLengthCheckBox); m_parameterTable->setCellWidget(6, 1, m_fractureHalfLengthCheckBox);
m_parameterTable->setItem(6, 2, new QTableWidgetItem(QString::number(automaticFittingData.getFractureHalfLengthMin().getValue().toDouble()))); m_parameterTable->setItem(6, 2, new QTableWidgetItem(QString::number(automaticFittingData.getFractureHalfLengthMin().getValue().toDouble())));
m_parameterTable->setItem(6, 3, new QTableWidgetItem()); m_parameterTable->setItem(6, 3, new QTableWidgetItem());
@ -799,17 +835,17 @@ void nmWxAutomaticFitting::onCellSelectionChanged(int currentRow, int currentCol
void nmWxAutomaticFitting::onReverseSelection() void nmWxAutomaticFitting::onReverseSelection()
{ {
// 更新反选逻辑,包含所有参数 // 只反选可用参数,不能通过反选勾上已参与采样的参数。
if(!m_parameterTable) { if(!m_parameterTable) {
return; return;
} }
if(!m_parameterTable->isRowHidden(0)) m_kCheckBox->setChecked(!m_kCheckBox->isChecked()); if(m_kCheckBox->isEnabled()) m_kCheckBox->setChecked(!m_kCheckBox->isChecked());
if(!m_parameterTable->isRowHidden(1)) m_sCheckBox->setChecked(!m_sCheckBox->isChecked()); if(m_sCheckBox->isEnabled()) m_sCheckBox->setChecked(!m_sCheckBox->isChecked());
if(!m_parameterTable->isRowHidden(2)) m_cCheckBox->setChecked(!m_cCheckBox->isChecked()); if(m_cCheckBox->isEnabled()) m_cCheckBox->setChecked(!m_cCheckBox->isChecked());
if(!m_parameterTable->isRowHidden(3)) m_phiCheckBox->setChecked(!m_phiCheckBox->isChecked()); if(m_phiCheckBox->isEnabled()) m_phiCheckBox->setChecked(!m_phiCheckBox->isChecked());
if(!m_parameterTable->isRowHidden(5)) m_dfcCheckBox->setChecked(!m_dfcCheckBox->isChecked()); if(m_dfcCheckBox->isEnabled()) m_dfcCheckBox->setChecked(!m_dfcCheckBox->isChecked());
if(!m_parameterTable->isRowHidden(6)) m_fractureHalfLengthCheckBox->setChecked(!m_fractureHalfLengthCheckBox->isChecked()); if(m_fractureHalfLengthCheckBox->isEnabled()) m_fractureHalfLengthCheckBox->setChecked(!m_fractureHalfLengthCheckBox->isChecked());
} }
void nmWxAutomaticFitting::onParameterTableItemChanged(QTableWidgetItem* item) void nmWxAutomaticFitting::onParameterTableItemChanged(QTableWidgetItem* item)
@ -843,6 +879,18 @@ void nmWxAutomaticFitting::onAccept()
// 校验通过后再保存参数设置,非法输入不会被静默裁剪。 // 校验通过后再保存参数设置,非法输入不会被静默裁剪。
setAutomaticFittingValue(); setAutomaticFittingValue();
if(m_sensitivitySettings) {
// 仅提交给敏感性窗口;取消、关闭及普通拟合均不经过此分支。
m_sensitivitySettings->parameters = automaticFittingData;
m_sensitivitySettings->targetWell = m_targetWellCombo->currentText();
m_sensitivitySettings->initialValues.clear();
const int rows[] = {0, 1, 2, 3, 5, 6};
for(int i = 0; i < 6; ++i)
m_sensitivitySettings->initialValues.append(m_parameterTable->item(rows[i], 3)->text().toDouble());
m_sensitivitySettings->confirmed = true;
accept();
return;
}
// 更新完成后,通知参数界面刷新 // 更新完成后,通知参数界面刷新
nmWxParameterProperty::notifyUpdateTable(); nmWxParameterProperty::notifyUpdateTable();
@ -1035,6 +1083,11 @@ void nmWxAutomaticFitting::setAutomaticFittingValue()
// 保存迭代参数 // 保存迭代参数
automaticFittingData.getIterationCount().setValue(m_iterationEdit->text().toInt()); automaticFittingData.getIterationCount().setValue(m_iterationEdit->text().toInt());
automaticFittingData.getErrorTolerance().setValue(m_errorLimitEdit->text().toDouble()); automaticFittingData.getErrorTolerance().setValue(m_errorLimitEdit->text().toDouble());
// 敏感性只收集设置,初值由调用方保存,不写回井和储层参数。
if(m_sensitivitySettings) {
automaticFittingData.setAlgorithmName(m_algorithmCombo->currentIndex() == 1 ? "LM" : "PSO");
return;
}
// 只写回可拟合的渗透率、孔隙度,含水饱和度沿用模型当前值。 // 只写回可拟合的渗透率、孔隙度,含水饱和度沿用模型当前值。
reservoirData.getPermeability().setValue(m_parameterTable->item(0, 3)->text().toDouble()); // 渗透率 reservoirData.getPermeability().setValue(m_parameterTable->item(0, 3)->text().toDouble()); // 渗透率

@ -1,6 +1,7 @@
#include "nmWxSensitive.h" #include "nmWxSensitive.h"
#include "nmDataAnalyzeManager.h" #include "nmDataAnalyzeManager.h"
#include "nmWxAutomaticFitting.h"
#include "nmDataSensitive.h" #include "nmDataSensitive.h"
#include "nmDataReservoir.h" #include "nmDataReservoir.h"
#include "nmDataWellBase.h" #include "nmDataWellBase.h"
@ -1467,7 +1468,7 @@ void nmWxSensitive::updateModelCount()
// 勾选、数量和方法修改后立即更新总次数,不等待 Generate。 // 勾选、数量和方法修改后立即更新总次数,不等待 Generate。
if (m_loading) return; if (m_loading) return;
m_sensitiveData.setCalculationType( m_sensitiveData.setCalculationType(
static_cast<nmDataSensitive::CalculationType>(calculationTypeCombo->currentIndex())); static_cast<nmDataSensitive::CalculationType>(calculationTypeCombo->itemData(calculationTypeCombo->currentIndex()).toInt()));
for (int group = 0; group < variablesTree->topLevelItemCount(); ++group) { for (int group = 0; group < variablesTree->topLevelItemCount(); ++group) {
QTreeWidgetItem* parent = variablesTree->topLevelItem(group); QTreeWidgetItem* parent = variablesTree->topLevelItem(group);
for (int child = 0; child < parent->childCount(); ++child) { for (int child = 0; child < parent->childCount(); ++child) {
@ -1490,7 +1491,9 @@ void nmWxSensitive::updateModelCount()
const bool monteCarlo = m_sensitiveData.getCalculationType() == nmDataSensitive::CALC_MONTE_CARLO; const bool monteCarlo = m_sensitiveData.getCalculationType() == nmDataSensitive::CALC_MONTE_CARLO;
modelCountLabel->setVisible(!monteCarlo); modelCountLabel->setVisible(!monteCarlo);
m_monteCarloCount->setVisible(monteCarlo); m_monteCarloCount->setVisible(monteCarlo);
generateButton->setEnabled(m_pDataManager && !overflow && count > 0 && !m_calculationRunning); // 第四种确认拟合设置后才开放生成,其他方法沿用原有条件。
generateButton->setEnabled(m_pDataManager && !overflow && count > 0 && !m_calculationRunning &&
(calculationTypeCombo->currentIndex() != 3 || !m_improveSettings.isNull()));
} }
bool nmWxSensitive::saveDataFromUI() bool nmWxSensitive::saveDataFromUI()
@ -1589,13 +1592,19 @@ void nmWxSensitive::setupUI()
QHBoxLayout *calcTypeLayout = new QHBoxLayout(); QHBoxLayout *calcTypeLayout = new QHBoxLayout();
QLabel *calcTypeLabel = new QLabel(tr("Calculation type:"), this); QLabel *calcTypeLabel = new QLabel(tr("Calculation type:"), this);
calculationTypeCombo = new QComboBox(this); calculationTypeCombo = new QComboBox(this);
calculationTypeCombo->addItem(tr("Deterministic")); calculationTypeCombo->addItem(tr("Deterministic"), nmDataSensitive::CALC_DETERMINISTIC);
calculationTypeCombo->addItem(tr("Deterministic multivariate")); calculationTypeCombo->addItem(tr("Deterministic multivariate"), nmDataSensitive::CALC_DETERMINISTIC_MULTIVARIATE);
calculationTypeCombo->addItem(tr("Monte-Carlo")); calculationTypeCombo->addItem(tr("Monte-Carlo"), nmDataSensitive::CALC_MONTE_CARLO);
//calculationTypeCombo->addItem(tr("Monte-Carlo + Improve")); // 第四种的采样界面和预览直接复用 Monte-Carlo,计算逻辑后续接入。
calculationTypeCombo->addItem(tr("Monte-Carlo + Improve"), nmDataSensitive::CALC_MONTE_CARLO);
m_improveSettingsButton = new QPushButton(tr("Improve Settings"), this);
// 按钮与下拉框等高,显示或隐藏时不撑高顶部布局。
m_improveSettingsButton->setFixedHeight(calculationTypeCombo->sizeHint().height());
m_improveSettingsButton->hide();
calcTypeLayout->addWidget(calcTypeLabel); calcTypeLayout->addWidget(calcTypeLabel);
calcTypeLayout->addWidget(calculationTypeCombo); calcTypeLayout->addWidget(calculationTypeCombo);
calcTypeLayout->addWidget(m_improveSettingsButton);
calcTypeLayout->addStretch(); calcTypeLayout->addStretch();
mainLayout->addLayout(calcTypeLayout); mainLayout->addLayout(calcTypeLayout);
@ -1717,6 +1726,8 @@ void nmWxSensitive::setupUI()
void nmWxSensitive::createConnections() void nmWxSensitive::createConnections()
{ {
// 复用已有拟合窗口作为第四种方法的设置入口。
connect(m_improveSettingsButton, SIGNAL(clicked()), this, SLOT(onImproveSettingsClicked()));
connect(m_monteCarloCount, SIGNAL(valueChanged(int)), this, SLOT(onVariableParamChanged())); connect(m_monteCarloCount, SIGNAL(valueChanged(int)), this, SLOT(onVariableParamChanged()));
connect(generateButton, SIGNAL(clicked()), connect(generateButton, SIGNAL(clicked()),
this, SLOT(onGenerateClicked())); this, SLOT(onGenerateClicked()));
@ -2108,7 +2119,7 @@ QWidget *nmWxSensitive::createVariablePage(const QString &varName)
void nmWxSensitive::updateValuesForPage(int idx) void nmWxSensitive::updateValuesForPage(int idx)
{ {
if (idx < 0 || idx >= m_numSpins.size()) return; if (idx < 0 || idx >= m_numSpins.size()) return;
const bool monteCarlo = calculationTypeCombo->currentIndex() == nmDataSensitive::CALC_MONTE_CARLO; const bool monteCarlo = calculationTypeCombo->itemData(calculationTypeCombo->currentIndex()).toInt() == nmDataSensitive::CALC_MONTE_CARLO;
m_modeCombos[idx]->setVisible(!monteCarlo); m_modeCombos[idx]->setVisible(!monteCarlo);
m_logChecks[idx]->setVisible(!monteCarlo); m_logChecks[idx]->setVisible(!monteCarlo);
m_numLabels[idx]->setVisible(!monteCarlo); m_numLabels[idx]->setVisible(!monteCarlo);
@ -2312,6 +2323,12 @@ void nmWxSensitive::onTreeItemChanged(QTreeWidgetItem* item, int column)
void nmWxSensitive::onGenerateClicked() void nmWxSensitive::onGenerateClicked()
{ {
// 第四种的批量拟合尚未接入,不能误用普通 Monte-Carlo 生成结果。
if(calculationTypeCombo->currentIndex() == 3) {
QMessageBox::information(this, tr("Sensitivity"),
tr("Monte-Carlo + Improve calculation is not implemented yet."));
return;
}
if(m_calculationRunning || !m_pDataManager || !saveDataFromUI()) return; if(m_calculationRunning || !m_pDataManager || !saveDataFromUI()) return;
QString error; QString error;
QScopedPointer<nmCalculationDllPebiSolverTask> task; QScopedPointer<nmCalculationDllPebiSolverTask> task;
@ -2427,13 +2444,30 @@ void nmWxSensitive::onResultsChanged()
void nmWxSensitive::onCalculationTypeChanged(int index) void nmWxSensitive::onCalculationTypeChanged(int index)
{ {
Q_UNUSED(index); m_improveSettingsButton->setVisible(index == 3);
// 复用现有参数页,切换方法只改变可见控件,不覆盖另一种方法的设置。 // 复用现有参数页,切换方法只改变可见控件,不覆盖另一种方法的设置。
if(m_loading) return; if(m_loading) return;
for(int i = 0; i < m_numSpins.size(); ++i) updateValuesForPage(i); for(int i = 0; i < m_numSpins.size(); ++i) updateValuesForPage(i);
updateModelCount(); updateModelCount();
} }
void nmWxSensitive::onImproveSettingsClicked()
{
// 在副本上编辑,只有确定才替换设置;取消保留上次确认的内容。
nmSensitivityFitSettings settings;
if(!m_improveSettings.isNull()) settings = *m_improveSettings;
// 将分析窗口当前勾选的采样参数传给拟合窗口,用于禁用重叠选项。
updateModelCount();
QStringList sampledParameters;
foreach(const nmDataSensitive::VariableSampling& variable, m_sensitiveData.getVariables())
if(variable.m_enabled) sampledParameters.append(variable.m_varName);
nmWxAutomaticFitting dialog(this, &settings, sampledParameters);
if(dialog.exec() == QDialog::Accepted) {
m_improveSettings = QSharedPointer<nmSensitivityFitSettings>(new nmSensitivityFitSettings(settings));
updateModelCount();
}
}
void nmWxSensitive::onTreeItemClicked(QTreeWidgetItem* item, int column) void nmWxSensitive::onTreeItemClicked(QTreeWidgetItem* item, int column)
{ {
Q_UNUSED(column); Q_UNUSED(column);

Loading…
Cancel
Save