Mantid
Loading...
Searching...
No Matches
SlicingAlgorithmDialog.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 +
12
13#include <QDir>
14#include <QFileDialog>
15#include <QIntValidator>
16#include <QSettings>
17
18using namespace Mantid::API;
19using namespace Mantid::Geometry;
20
21namespace MantidQt {
22namespace MantidWidgets {
23DECLARE_DIALOG(SliceMDDialog)
24DECLARE_DIALOG(BinMDDialog)
25
26
31
34 ui.setupUi(this);
35 this->setWindowTitle(m_algName);
36
38
39 // Tie core widgets to core properties.
40 tie(ui.workspace_selector, "InputWorkspace", ui.input_layout);
41 tie(ui.ck_axis_aligned, "AxisAligned");
42 tie(ui.txt_output, "OutputWorkspace", ui.output_layout);
43 tie(ui.txt_output_extents, "OutputExtents", ui.output_extents_layout);
44 tie(ui.txt_output_bins, "OutputBins", ui.output_bins_layout);
45 tie(ui.ck_normalisebasisvectors, "NormalizeBasisVectors");
46 tie(ui.ck_force_orthogonal, "ForceOrthogonal");
47 tie(ui.txt_translation, "Translation");
48
49 ui.txt_memory->setValidator(new QIntValidator(this));
50 ui.txt_resursion_depth->setValidator(new QIntValidator(this));
51
52 /*
53 Do not need to connect up Accept/Reject. This gets done automatically, and
54 the AlgorithmDialog base class
55 handles the slots.
56 */
57 connect(ui.workspace_selector, SIGNAL(activated(int)), this, SLOT(onWorkspaceChanged()));
58 connect(ui.ck_axis_aligned, SIGNAL(clicked(bool)), this, SLOT(onAxisAlignedChanged(bool)));
59 connect(ui.ck_max_from_input, SIGNAL(clicked(bool)), this, SLOT(onMaxFromInput(bool)));
60 connect(ui.ck_calculate, SIGNAL(clicked(bool)), this, SLOT(onCalculateChanged(bool)));
61 connect(ui.btn_browse, SIGNAL(clicked()), this, SLOT(onBrowse()));
62 connect(ui.btn_help, SIGNAL(clicked()), this, SLOT(helpClicked()));
63 connect(ui.btn_calculate, SIGNAL(clicked()), this, SLOT(onRebuildDimensions()));
64
65 // Configure workspace selector
66 ui.workspace_selector->setValidatingAlgorithm(m_algName);
67 ui.workspace_selector->clear();
68 auto names = AnalysisDataService::Instance().getObjectNames();
69 auto it = names.begin();
70 while (it != names.end()) {
72 std::dynamic_pointer_cast<IMDEventWorkspace>(AnalysisDataService::Instance().retrieve(*it));
73 if (ws) {
74 ui.workspace_selector->addItem((*it).c_str());
75 }
76 ++it;
77 }
78 QString lastUsedInputWorkspaceName = getHistoricalInputWorkspaceName();
79 int index = ui.workspace_selector->findText(lastUsedInputWorkspaceName);
80 if (index >= 0) {
81 ui.workspace_selector->setCurrentIndex(index);
82 }
83
84 // Derived algorithms may use this to apply any additional ties.
86
87 // Dynamically create the input dimensions.
89}
90
93
100 QString min, max, nbins, result;
101 QString name(dim->getName().c_str());
102 min.setNum(dim->getMinimum());
103 max.setNum(dim->getMaximum());
104 nbins.setNum(dim->getNBins());
105 result.append(name).append(",").append(min).append(",").append(max).append(",").append(nbins);
106 return result;
107}
108
123 // Deliberately return an empty string here, because it's not obvious how the
124 // basis vectors could be automatically formed.
125 return QString("");
126}
127
133 int itemCount = layout->count();
134 for (int i = 0; i < itemCount; ++i) {
135 QLayoutItem *pLayoutItem = layout->itemAt(i);
136 QWidget *pWidget = pLayoutItem->widget();
137 if (pWidget != nullptr) {
138 // The label text contains the property name.
139 auto *propertyLabel = dynamic_cast<QLabel *>(pWidget->layout()->itemAt(0)->widget());
140 untie(propertyLabel->text());
141 pWidget->setHidden(true);
142 this->layout()->removeItem(pLayoutItem);
143 }
144 }
145}
146
151 QLayout *alignedLayout = this->ui.axis_aligned_layout->layout();
152 QLayout *nonAlignedLayout = this->ui.non_axis_aligned_layout->layout();
153
154 cleanLayoutOfDimensions(alignedLayout);
155 cleanLayoutOfDimensions(nonAlignedLayout);
156}
157
162bool SlicingAlgorithmDialog::doAxisAligned() const { return ui.ck_axis_aligned->isChecked(); }
163
168QString SlicingAlgorithmDialog::getCurrentInputWorkspaceName() const { return ui.workspace_selector->currentText(); }
169
174QString SlicingAlgorithmDialog::getCurrentOutputWorkspaceName() const { return ui.txt_output->text(); }
175
181 return MantidQt::API::AlgorithmInputHistory::Instance().previousInput(m_algName, "InputWorkspace");
182}
183
190
191 const QString &currentWorkspaceName = getCurrentInputWorkspaceName();
192 const QString previousInputWorkspaceName =
193 MantidQt::API::AlgorithmInputHistory::Instance().previousInput(m_algName, "InputWorkspace");
194 if (currentWorkspaceName.isEmpty()) {
195 result = HasChanged; // Force a rebuild because the dialog cant find any
196 // eligable input workspaces. That's why there is an
197 // empty entry.
198 } else if (AnalysisDataService::Instance().doesExist(previousInputWorkspaceName.toStdString())) {
199 const auto oldWS =
200 AnalysisDataService::Instance().retrieveWS<IMDWorkspace>(previousInputWorkspaceName.toStdString());
201 const auto newWS = AnalysisDataService::Instance().retrieveWS<IMDWorkspace>(currentWorkspaceName.toStdString());
202 if (oldWS->getNumDims() != newWS->getNumDims()) {
203 result = HasChanged;
204 }
205 }
206
207 return result;
208}
209
219 const bool bForceForget) {
221 if (criticalChange == HasChanged || bForceForget) {
222 history = Forget;
223 } else {
225 }
226 return history;
227}
228
229/*
230Decide and command the type of dimension inputs to provide.
231@param bForceForget : Force the use of inputworkspace dimensions when
232configuring the dialog.
233*/
234void SlicingAlgorithmDialog::buildDimensionInputs(const bool bForceForget) {
236 const bool axisAligned = doAxisAligned();
237 ui.non_axis_aligned_layout->setEnabled(!axisAligned);
238
239 HistoryChanged criticalChange = this->hasDimensionHistoryChanged();
240 History useHistory = this->useHistory(criticalChange, bForceForget);
241
242 if (axisAligned) {
243 makeDimensionInputs("AlignedDim", this->ui.axis_aligned_layout->layout(), formattedAlignedDimensionInput,
244 useHistory);
245 } else {
246 makeDimensionInputs("BasisVector", this->ui.non_axis_aligned_layout->layout(), formatNonAlignedDimensionInput,
247 Remember);
248 }
249}
250
261void SlicingAlgorithmDialog::makeDimensionInputs(const QString &propertyPrefix, QLayout *owningLayout,
262 QString (*format)(const IMDDimension_const_sptr &), History history) {
263 // Remove excess dimensions from the tied properties and the stored property
264 // values
265 size_t indexRemoved = 0;
266 QString propertyNameRemoved = propertyPrefix;
267 propertyNameRemoved.append(QString().number(indexRemoved));
268 Mantid::Kernel::Property *propertyRemoved = getAlgorithmProperty(propertyNameRemoved);
269
270 while (propertyRemoved) {
271 untie(propertyNameRemoved);
272 removePropertyValue(propertyNameRemoved);
273
274 indexRemoved++;
275 propertyNameRemoved = propertyPrefix;
276 propertyNameRemoved.append(QString().number(indexRemoved));
277 propertyRemoved = getAlgorithmProperty(propertyNameRemoved);
278 }
279
280 const QString &txt = getCurrentInputWorkspaceName();
281 if (!txt.isEmpty()) {
283 std::dynamic_pointer_cast<IMDWorkspace>(AnalysisDataService::Instance().retrieve(txt.toStdString()));
284
285 size_t nDimensions = ws->getNumDims();
286
287 for (size_t index = 0; index < nDimensions; ++index) {
288 Mantid::Geometry::IMDDimension_const_sptr dim = ws->getDimension(index);
289
290 // Configure the label
291 QString propertyName = propertyPrefix;
292 propertyName.append(QString().number(index));
293
294 QLabel *dimensionLabel = new QLabel(propertyName);
295
296 // Configure the default input.
297 const QString dimensionInfo = format(dim);
298
299 auto *txtDimension = new QLineEdit(dimensionInfo);
300
301 // Create a widget to contain the dimension components.
302 auto *layout = new QHBoxLayout;
303 QWidget *w = new QWidget;
304 w->setLayout(layout);
305
306 tie(txtDimension, propertyName, layout, (history == Remember));
307
308 // Add components to the layout.
309 layout->addWidget(dimensionLabel);
310 layout->addWidget(txtDimension);
311
312 owningLayout->addWidget(w);
313 }
314 }
315}
316
319 QSettings settings;
320 settings.beginGroup("Mantid/SlicingAlgorithm");
321 settings.setValue("AlwaysCalculateExtents", (this->doAutoFillDimensions() ? 1 : 0));
322 settings.endGroup();
323}
324
329 QSettings settings;
330 settings.beginGroup("Mantid/SlicingAlgorithm");
331
332 const bool alwaysCalculateExtents = settings.value("AlwaysCalculateExtents", 1).toInt();
333 ui.ck_calculate->setChecked(alwaysCalculateExtents);
334
335 settings.endGroup();
336}
337
340
348}
349
356 const bool takeFromInputWorkspace = ui.ck_max_from_input->isChecked();
357 ui.txt_resursion_depth->setEnabled(!takeFromInputWorkspace);
358 ui.lbl_resursion_depth->setEnabled(!takeFromInputWorkspace);
359}
360
365
367 if (ui.ck_axis_aligned->isChecked())
369}
370
375 QFileDialog dialog;
376 dialog.setDirectory(QDir::homePath());
377 dialog.setNameFilter("Nexus files (*.nxs)");
378 if (dialog.exec()) {
379 ui.txt_filename->setText(dialog.selectedFiles().front());
380 }
381}
382
383/*
384Perform tasks that are almost identical for derived types except for visibility
385switch.
386@isSliceMD. Is the calling method from SliceMD.
387*/
389 ui.file_backend_layout->setVisible(isSliceMD);
390 ui.ck_max_from_input->setVisible(isSliceMD);
391 ui.lbl_resursion_depth->setVisible(isSliceMD);
392 ui.txt_resursion_depth->setVisible(isSliceMD);
393 ui.ck_parallel->setVisible(!isSliceMD);
394}
395
400bool SlicingAlgorithmDialog::doAutoFillDimensions() const { return ui.ck_calculate->isChecked(); }
401
402/*---------------------------------------------------------------------------------------------
403SliceMDDialog Methods
404---------------------------------------------------------------------------------------------*/
406 commonSliceMDSetup(true);
407
408 // Tie the widgets to properties
409 tie(ui.ck_max_from_input, "TakeMaxRecursionDepthFromInput");
410 tie(ui.txt_resursion_depth, "MaxRecursionDepth");
411 tie(ui.txt_filename, "OutputFilename");
412 tie(ui.txt_memory, "Memory");
413}
414
415/*---------------------------------------------------------------------------------------------
416End SliceMDDialog Methods
417---------------------------------------------------------------------------------------------*/
418
419/*---------------------------------------------------------------------------------------------
420BinMDDialog Methods
421---------------------------------------------------------------------------------------------*/
423 // Disable the stuff that doesn't relate to BinMD
424 commonSliceMDSetup(false);
425
426 tie(ui.ck_parallel, "Parallel");
427}
428
429/*---------------------------------------------------------------------------------------------
430End BinMDDialog Methods
431---------------------------------------------------------------------------------------------*/
432} // namespace MantidWidgets
433} // namespace MantidQt
#define DECLARE_DIALOG(classname)
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
std::vector< history_type > history
history information
This class should be the basis for all customised algorithm dialogs.
QString m_algName
The name of the algorithm.
virtual void helpClicked()
Help button clicked;.
void removePropertyValue(const QString &name)
Removes a property (name, value) pair from the stored map.
QWidget * tie(QWidget *widget, const QString &property, QLayout *parent_layout=nullptr, bool readHistory=true)
Tie a widget to a property.
Mantid::Kernel::Property * getAlgorithmProperty(const QString &propName) const
Get a pointer to the named property.
void untie(const QString &property)
Untie a widget to a property.
void customiseInitLayout() override
Give base classes the opportunity to do any custom overriding.
void customiseInitLayout() override
Give base classes the opportunity to do any custom overriding.
void onBrowse()
Handler for the onbrowse event.
void onWorkspaceChanged()
Event handler for the workspace changed event.
void onMaxFromInput(bool)
Event handler for changes so that recursion depth for the ouput workspace is either taken from the in...
void buildDimensionInputs(const bool bForceForget=false)
Build dimension inputs.
void initLayout() override
Initialize the layout.
QString getHistoricalInputWorkspaceName() const
Getter for the historical input workspace name.
HistoryChanged hasDimensionHistoryChanged() const
Determine if the dimension history has changed.
void cleanLayoutOfDimensions(QLayout *layout)
Cleans a given layout.
bool doAutoFillDimensions() const
Do auto fill dimension inputs on changes.
void commonSliceMDSetup(const bool)
Common slice md setup.
void onAxisAlignedChanged(bool)
Event handler for the axis changed event.
QString getCurrentOutputWorkspaceName() const
Gets the output workspace name provided.
History useHistory(const HistoryChanged &criticalChange, const bool bForceForget)
Determine if history should be used.
void clearExistingDimensions()
Clear out any exisiting dimension widgets.
virtual void customiseInitLayout()=0
Give base classes the opportunity to do any custom overriding.
bool doAxisAligned() const
Determine if axis aligned or non-axis aligned is required.
void onRebuildDimensions()
Event handler for the on-forced dimension rebuild event.
QString getCurrentInputWorkspaceName() const
Gets the input workspace name provided.
void makeDimensionInputs(const QString &propertyPrefix, QLayout *owningLayout, QString(*format)(const Mantid::Geometry::IMDDimension_const_sptr &), History history)
Build dimension inputs.
Basic MD Workspace Abstract Class.
Definition: IMDWorkspace.h:40
virtual size_t getNumDims() const
Definition: MDGeometry.cpp:148
Base class for properties.
Definition: Property.h:94
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
QString formatNonAlignedDimensionInput(const Mantid::Geometry::IMDDimension_const_sptr &)
Create a formatted string for the dimension input based on an existing dimension.
QString formattedAlignedDimensionInput(const Mantid::Geometry::IMDDimension_const_sptr &dim)
Create a formatted string for the dimension input based on an existing dimension.
The AlgorithmProgressDialogPresenter keeps track of the running algorithms and displays a progress ba...
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
std::shared_ptr< IMDWorkspace > IMDWorkspace_sptr
Shared pointer to the IMDWorkspace base class.
Definition: IMDWorkspace.h:146
std::shared_ptr< const IMDDimension > IMDDimension_const_sptr
Shared Pointer to const IMDDimension.
Definition: IMDDimension.h:101