Mantid
Loading...
Searching...
No Matches
EditLocalParameterDialog.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8
12
13#include <QClipboard>
14#include <QMenu>
15#include <QMessageBox>
16#include <QRegularExpression>
17#include <limits>
18#include <utility>
19
20namespace {
21QString makeNumber(double d) { return QString::number(d, 'g', 16); }
22const int valueColumn = 0;
23const int roleColumn = 1;
24} // namespace
25
27
39EditLocalParameterDialog::EditLocalParameterDialog(QWidget *parent, const std::string &parName,
40 const std::vector<std::string> &datasetNames,
41 const std::vector<std::string> &datasetDomainNames,
42 const QList<double> &values, const QList<bool> &fixes,
43 const QStringList &ties, const QStringList &constraints)
44 : MantidDialog(parent), m_parName(parName), m_values(values), m_fixes(fixes), m_ties(std::move(ties)),
45 m_constraints(std::move(constraints)) {
46 assert(static_cast<std::size_t>(values.size()) == datasetDomainNames.size());
47 assert(static_cast<std::size_t>(fixes.size()) == datasetDomainNames.size());
48 assert(static_cast<std::size_t>(ties.size()) == datasetDomainNames.size());
49 assert(static_cast<std::size_t>(constraints.size()) == datasetDomainNames.size());
50 m_uiForm.setupUi(this);
51 setAttribute(Qt::WA_DeleteOnClose);
52 doSetup(parName, datasetNames, datasetDomainNames);
53}
54
63void EditLocalParameterDialog::doSetup(const std::string &parName, const std::vector<std::string> &datasetNames,
64 const std::vector<std::string> &datasetDomainNames) {
65 m_logFinder = std::make_unique<LogValueFinder>(stdVectorToQStringList(datasetNames));
66 // Populate list of logs
67 auto *logCombo = m_uiForm.logValueSelector->getLogComboBox();
68 for (const auto &logName : m_logFinder->getLogNames()) {
69 logCombo->addItem(QString::fromStdString(logName));
70 }
71
72 m_uiForm.logValueSelector->setCheckboxShown(true);
73 connect(m_uiForm.logValueSelector, SIGNAL(logOptionsEnabled(bool)), this, SIGNAL(logOptionsChecked(bool)));
74 QHeaderView *header = m_uiForm.tableWidget->horizontalHeader();
75 header->setSectionResizeMode(QHeaderView::Stretch);
76 connect(m_uiForm.tableWidget, SIGNAL(cellChanged(int, int)), this, SLOT(valueChanged(int, int)));
77 m_uiForm.lblParameterName->setText("Parameter: " + QString::fromStdString(parName));
78
79 for (int i = 0; i < static_cast<int>(datasetDomainNames.size()); i++) {
80 m_uiForm.tableWidget->insertRow(i);
81 auto cell = new QTableWidgetItem(makeNumber(m_values[i]));
82 m_uiForm.tableWidget->setItem(i, valueColumn, cell);
83 auto headerItem = new QTableWidgetItem(QString::fromStdString(datasetDomainNames[i]));
84 m_uiForm.tableWidget->setVerticalHeaderItem(i, headerItem);
85 cell = new QTableWidgetItem("");
86 auto flags = cell->flags();
87 flags ^= Qt::ItemIsEditable;
88 flags ^= Qt::ItemIsSelectable;
89 flags ^= Qt::ItemIsEnabled;
90 cell->setFlags(flags);
91 m_uiForm.tableWidget->setItem(i, roleColumn, cell);
93 }
94 auto deleg = new LocalParameterItemDelegate(this);
95 m_uiForm.tableWidget->setItemDelegateForColumn(valueColumn, deleg);
96 connect(deleg, SIGNAL(setAllValues(double)), this, SLOT(setAllValues(double)));
97 connect(deleg, SIGNAL(fixParameter(int, bool)), this, SLOT(fixParameter(int, bool)));
98 connect(deleg, SIGNAL(setAllFixed(bool)), this, SLOT(setAllFixed(bool)));
99 connect(deleg, SIGNAL(setTie(int, QString)), this, SLOT(setTie(int, QString)));
100 connect(deleg, SIGNAL(setTieAll(QString)), this, SLOT(setTieAll(QString)));
101 connect(deleg, SIGNAL(setConstraint(int, QString)), this, SLOT(setConstraint(int, QString)));
102 connect(deleg, SIGNAL(setConstraintAll(QString)), this, SLOT(setConstraintAll(QString)));
103 connect(deleg, SIGNAL(setValueToLog(int)), this, SLOT(setValueToLog(int)));
104 connect(deleg, SIGNAL(setAllValuesToLog()), this, SLOT(setAllValuesToLog()));
105
106 m_uiForm.tableWidget->installEventFilter(this);
107
108 connect(this, SIGNAL(finished(int)), this, SLOT(emitDialogFinished(int)));
109}
110
111void EditLocalParameterDialog::emitDialogFinished(int result) { emit dialogFinished(result, this); }
112
117 if (col == valueColumn) {
118 QString text = m_uiForm.tableWidget->item(row, col)->text();
119 try {
120 bool ok = false;
121 double value = text.toDouble(&ok);
122 if (ok) {
123 m_values[row] = value;
124 } else {
125 m_ties[row] = text;
126 }
127 } catch (std::exception &) {
128 // restore old value
129 m_uiForm.tableWidget->item(row, col)->setText(makeNumber(m_values[row]));
130 }
131 }
132}
133
137 auto n = m_values.size();
138 for (int i = 0; i < n; ++i) {
139 m_values[i] = value;
140 m_uiForm.tableWidget->item(i, valueColumn)->setText(makeNumber(value));
142 }
143}
144
147
150
152const QStringList &EditLocalParameterDialog::getTies() const { return m_ties; }
153
155const QStringList &EditLocalParameterDialog::getConstraints() const { return m_constraints; }
156
161 m_fixes[index] = fix;
162 m_ties[index] = "";
164}
165
170 m_ties[index] = std::move(tie);
171 m_fixes[index] = false;
173}
174
177void EditLocalParameterDialog::setTieAll(const QString &tie) {
178 for (int i = 0; i < m_ties.size(); ++i) {
179 m_ties[i] = tie;
180 m_fixes[i] = false;
182 }
183 redrawCells();
184}
185
186void EditLocalParameterDialog::setConstraint(int index, QString constraint) {
187 m_constraints[index] = std::move(constraint);
189}
190
191void EditLocalParameterDialog::setConstraintAll(const QString &constraint) {
192 for (int i = 0; i < m_constraints.size(); ++i) {
193 m_constraints[i] = constraint;
195 }
196 redrawCells();
197}
198
202 if (m_fixes.empty())
203 return;
204 for (int i = 0; i < m_fixes.size(); ++i) {
205 m_fixes[i] = fix;
206 m_ties[i] = "";
208 }
209 redrawCells();
210}
211
213bool EditLocalParameterDialog::eventFilter(QObject *obj, QEvent *ev) {
214 if (obj == m_uiForm.tableWidget && ev->type() == QEvent::ContextMenu) {
216 }
217 return QDialog::eventFilter(obj, ev);
218}
219
222 auto selection = m_uiForm.tableWidget->selectionModel()->selectedColumns();
223
224 bool hasSelection = false;
225
226 for (auto &index : selection) {
227 if (index.column() == valueColumn)
228 hasSelection = true;
229 }
230
231 if (!hasSelection)
232 return;
233
234 QMenu *menu = new QMenu(this);
235 {
236 QAction *action = new QAction("Copy", this);
237 action->setToolTip("Copy data to clipboard.");
238 connect(action, SIGNAL(triggered()), this, SLOT(copy()));
239 menu->addAction(action);
240 }
241 {
242 QAction *action = new QAction("Paste", this);
243 action->setToolTip("Paste data from clipboard.");
244 connect(action, SIGNAL(triggered()), this, SLOT(paste()));
245 auto text = QApplication::clipboard()->text();
246 action->setEnabled(!text.isEmpty());
247 menu->addAction(action);
248 }
249
250 menu->exec(QCursor::pos());
251}
252
256 QStringList text;
257 auto n = m_values.size();
258 for (int i = 0; i < n; ++i) {
259 text << makeNumber(m_values[i]);
260 }
261 QApplication::clipboard()->setText(text.join("\n"));
262}
263
266 auto text = QApplication::clipboard()->text();
267 auto vec = text.split(QRegularExpression("\\s|,"), Qt::SkipEmptyParts);
268 auto n = qMin(vec.size(), m_uiForm.tableWidget->rowCount());
269 // prepare for pasting data
270 auto deleg = static_cast<LocalParameterItemDelegate *>(m_uiForm.tableWidget->itemDelegateForColumn(valueColumn));
271 deleg->prepareForPastedData();
272 // insert data into table
273 for (int i = 0; i < n; ++i) {
274 auto str = vec[i];
275 bool ok;
276 m_values[i] = str.toDouble(&ok);
277 if (!ok)
278 str = "0";
279 m_uiForm.tableWidget->item(i, valueColumn)->setText(str);
280 }
281}
282
285 for (int i = 0; i < m_values.size(); ++i) {
286 // it's the only way I am able to make the table to repaint itself
287 auto text = makeNumber(m_values[i]);
288 m_uiForm.tableWidget->item(i, valueColumn)->setText(text + " ");
289 m_uiForm.tableWidget->item(i, valueColumn)->setText(text);
290 }
291}
292
295 auto cell = m_uiForm.tableWidget->item(index, roleColumn);
296 QString text;
297 if (m_fixes[index]) {
298 text = "fixed";
299 cell->setForeground(QBrush(Qt::red));
300 } else if (!m_ties[index].isEmpty()) {
301 text = "tied";
302 cell->setForeground(QBrush(Qt::blue));
303 } else {
304 text = "fitted";
305 cell->setForeground(QBrush(Qt::darkGreen));
306 }
307 if (!m_constraints[index].isEmpty()) {
308 text += ", " + m_constraints[index];
309 }
310 cell->setText(text);
311}
312
315 for (int j = 0; j < m_fixes.size(); ++j) {
316 if (j != i && m_fixes[j])
317 return true;
318 }
319 return false;
320}
321
324 for (int j = 0; j < m_fixes.size(); ++j) {
325 if (j != i && !m_fixes[j])
326 return false;
327 }
328 return true;
329}
330
333 for (int j = 0; j < m_fixes.size(); ++j) {
334 if (j != i && !m_ties[j].isEmpty())
335 return true;
336 }
337 return false;
338}
339
343 assert(i < m_values.size());
344
345 const auto &logName = m_uiForm.logValueSelector->getLog();
346 const auto &function = m_uiForm.logValueSelector->getFunction();
347
348 double value = std::numeric_limits<double>::quiet_NaN();
349 try {
350 value = m_logFinder->getLogValue(logName, function, i);
351 } catch (const std::invalid_argument &err) {
352 const auto &message = QString("Failed to get log value:\n\n %1").arg(err.what());
353 QMessageBox::critical(this, "Mantid - Error", message);
354 }
355 m_values[i] = value;
356 m_uiForm.tableWidget->item(i, valueColumn)->setText(makeNumber(value));
358}
359
362 const auto nValues = m_values.size();
363 for (int i = 0; i < nValues; ++i) {
364 setValueToLog(i);
365 }
366}
367
370bool EditLocalParameterDialog::isLogCheckboxTicked() const { return m_uiForm.logValueSelector->isCheckboxTicked(); }
371
372} // namespace MantidQt::MantidWidgets
double value
The value of the point.
Definition FitMW.cpp:51
std::map< DeltaEMode::Type, std::string > index
std::vector< T > const * vec
double obj
the value of the quadratic function
EditLocalParameterDialog(QWidget *parent, const std::string &parName, const std::vector< std::string > &datasetNames, const std::vector< std::string > &datasetDomainNames, const QList< double > &values, const QList< bool > &fixes, const QStringList &ties, const QStringList &constraints)
Constructor for EditLocalParameterDialog used in FunctionBrowser.
const QList< double > & getValues() const
Get the list of new parameter values.
std::unique_ptr< LogValueFinder > m_logFinder
Log value finder.
void setTieAll(const QString &)
Set the same tie to all parameters.
QList< bool > m_fixes
Cache for the "fixed" attribute.
void copy()
Copy all parameter values to the clipboard.
bool areAllOthersFixed(int i) const
Check if all other parameters are fixed.
void updateRoleColumn(int index)
Update the text in the role column.
void fixParameter(int, bool)
Fix/unfix a single parameter.
QStringList m_constraints
Cache for the constraints.
QList< double > m_values
Cache for new values. size() == number of spectra.
const QStringList & getConstraints() const
Get a list of the constraints.
bool areOthersTied(int i) const
Check if there are any other tied parameters.
bool eventFilter(QObject *obj, QEvent *ev) override
Event filter for managing the context menu.
void paste()
Paste a list of values from the clipboard.
bool isLogCheckboxTicked() const
Returns whether log checkbox is ticked or not.
void redrawCells()
Force the table to redraw its cells.
void dialogFinished(int, EditLocalParameterDialog *)
const QStringList & getTies() const
Get a list of the ties.
const QList< bool > & getFixes() const
Get a list with the "fixed" attribute.
void setTie(int, QString)
Set a new tie for a parameter.
void doSetup(const std::string &parName, const std::vector< std::string > &datasetDomains, const std::vector< std::string > &datasetDomainNames)
Common setup method used by both constructors Prerequisite: one of the constructors must have filled ...
bool areOthersFixed(int i) const
Check if there are any other fixed parameters.
void setAllValues(double)
Set all parameters to the same value.
void setAllValuesToLog()
Set value of each parameter to log value from respective workspace.
A custom item delegate - an object controlling display and editing of a cell in a table widget.
void prepareForPastedData()
Data is about to be pasted into the table.
QStringList EXPORT_OPT_MANTIDQT_COMMON stdVectorToQStringList(std::vector< std::string > const &vec)
STL namespace.