diff --git a/Framework/DataHandling/inc/MantidDataHandling/AsciiPointBase.h b/Framework/DataHandling/inc/MantidDataHandling/AsciiPointBase.h index cedc1218761dc677d013b341ab71323be3ae60b9..cd5c6c13436e8de031849dab69c963abfe115028 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/AsciiPointBase.h +++ b/Framework/DataHandling/inc/MantidDataHandling/AsciiPointBase.h @@ -71,6 +71,8 @@ protected: /// write the main content of the data virtual void data(std::ofstream &file, const std::vector<double> &XData, bool exportDeltaQ = true); + /// Retrieves the separator property + virtual void appendSeparatorProperty(); /// The separator character char m_sep; double m_qres = 0.0; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h index 3da2d33c37c3b854228b05d7529648d8537d4e42..5cd322be4f189b2b2f01a79de3c335f98e4e34de 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h @@ -54,8 +54,8 @@ private: std::string ext() override { return ".txt"; } /// return if the line should start with a separator bool leadingSep() override { return false; } - /// no extra properties required so override blank - void extraProps() override {} + /// only separator property required, nothing else + void extraProps() override { appendSeparatorProperty(); } /// no extra information required so override blank void extraHeaders(std::ofstream &file) override; }; diff --git a/Framework/DataHandling/src/AsciiPointBase.cpp b/Framework/DataHandling/src/AsciiPointBase.cpp index 69f457762bdb0e93c13a54e6ab34026fa95a0cb0..839c5b667b34765843ea29e5d0e80c8031cc3ccb 100644 --- a/Framework/DataHandling/src/AsciiPointBase.cpp +++ b/Framework/DataHandling/src/AsciiPointBase.cpp @@ -33,13 +33,6 @@ void AsciiPointBase::init() { FileProperty::Save, ext()), "The filename of the output file."); - std::vector<std::string> propOptions; - propOptions.push_back("comma"); - propOptions.push_back("space"); - propOptions.push_back("tab"); - declareProperty("Separator", "tab", - boost::make_shared<StringListValidator>(propOptions), - "The separator used for splitting data columns."); extraProps(); } @@ -143,5 +136,17 @@ void AsciiPointBase::outputval(double val, std::ofstream &file, file << "nan"; } } + +/** appends the separator property to the algorithm + */ +void AsciiPointBase::appendSeparatorProperty() { + std::vector<std::string> propOptions; + propOptions.push_back("comma"); + propOptions.push_back("space"); + propOptions.push_back("tab"); + declareProperty("Separator", "tab", + boost::make_shared<StringListValidator>(propOptions), + "The separator used for splitting data columns."); +} } // namespace DataHandling } // namespace Mantid diff --git a/Framework/DataHandling/src/SaveILLCosmosAscii.cpp b/Framework/DataHandling/src/SaveILLCosmosAscii.cpp index 9a9fd593e55237e75fdcd1a8d0afe13d64b7f241..14dc26d624879c976a0759dd9f6eaeb6727ebabb 100644 --- a/Framework/DataHandling/src/SaveILLCosmosAscii.cpp +++ b/Framework/DataHandling/src/SaveILLCosmosAscii.cpp @@ -21,6 +21,7 @@ void SaveILLCosmosAscii::extraProps() { declareProperty("UserContact", "", "Text to be written to the User-local contact field"); declareProperty("Title", "", "Text to be written to the Title field"); + appendSeparatorProperty(); } /** virtual method to add information to the file before the data diff --git a/Framework/DataHandling/src/SaveReflCustomAscii.cpp b/Framework/DataHandling/src/SaveReflCustomAscii.cpp index 8ccc780c31cf3cef3aa9b27fe6e3b5a51fb51b90..6b9a61892c157d851e748b78045e009ac348ee3d 100644 --- a/Framework/DataHandling/src/SaveReflCustomAscii.cpp +++ b/Framework/DataHandling/src/SaveReflCustomAscii.cpp @@ -22,6 +22,7 @@ void SaveReflCustomAscii::extraProps() { "WriteDeltaQ", false, "If true, the error on DeltaQ will be written as the fourth column."); declareProperty("Subtitle", false, "If true, subtitle added to header."); + appendSeparatorProperty(); } /** virtual method to add information to the file before the data diff --git a/Framework/DataHandling/src/SaveReflThreeColumnAscii.cpp b/Framework/DataHandling/src/SaveReflThreeColumnAscii.cpp index faa993c0663e641f0aff28018b629ef0c513f96d..29b9218c24ea1de02e57c71e0e2a5321bb4d0467 100644 --- a/Framework/DataHandling/src/SaveReflThreeColumnAscii.cpp +++ b/Framework/DataHandling/src/SaveReflThreeColumnAscii.cpp @@ -18,6 +18,7 @@ void SaveReflThreeColumnAscii::extraProps() { declareProperty("Title", "", "Text to be written to the Title field"); declareProperty(make_unique<ArrayProperty<std::string>>("LogList"), "List of logs to write to file."); + appendSeparatorProperty(); } /** virtual method to add information to the file before the data diff --git a/MantidQt/CustomInterfaces/CMakeLists.txt b/MantidQt/CustomInterfaces/CMakeLists.txt index 02dadacf30b3bbd7017881e210951342c95445cc..b4b5f0d6bf36d3cb06849fb20ba49ef853b59d47 100644 --- a/MantidQt/CustomInterfaces/CMakeLists.txt +++ b/MantidQt/CustomInterfaces/CMakeLists.txt @@ -123,7 +123,6 @@ set ( SRC_FILES src/Tomography/ImggFormats.cpp src/Tomography/ImggFormatsConvertPresenter.cpp src/Tomography/ImggFormatsConvertViewQtWidget.cpp - src/Tomography/SavuConfigDialog.cpp src/Tomography/StackOfImagesDirs.cpp src/Tomography/TomoPathsConfig.cpp src/Tomography/TomoReconPostprocSettings.cpp @@ -131,7 +130,11 @@ set ( SRC_FILES src/Tomography/TomoSystemSettings.cpp src/Tomography/TomoSystemSettingsLocal.cpp src/Tomography/TomoSystemSettingsRemote.cpp - src/Tomography/TomoToolConfigDialog.cpp + src/Tomography/TomoToolConfigDialogBase.cpp + src/Tomography/TomoToolConfigDialogTomoPy.cpp + src/Tomography/TomoToolConfigDialogCustom.cpp + src/Tomography/TomoToolConfigDialogSavu.cpp + src/Tomography/TomoToolConfigDialogAstra.cpp src/Tomography/TomographyIfaceModel.cpp src/Tomography/TomographyIfacePresenter.cpp src/Tomography/TomographyIfaceViewQtGUI.cpp @@ -302,7 +305,11 @@ set ( INC_FILES inc/MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h inc/MantidQtCustomInterfaces/Tomography/TomoSystemSettingsLocal.h inc/MantidQtCustomInterfaces/Tomography/TomoSystemSettingsRemote.h - inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialog.h + inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h + inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogTomoPy.h + inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogCustom.h + inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogSavu.h + inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogAstra.h inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h @@ -394,9 +401,9 @@ set ( MOC_FILES inc/MantidQtCustomInterfaces/Background.h inc/MantidQtCustomInterfaces/Muon/IALCPeakFittingView.h inc/MantidQtCustomInterfaces/Muon/IALCPeakFittingModel.h inc/MantidQtCustomInterfaces/Muon/MuonAnalysis.h - inc/MantidQtCustomInterfaces/Muon/MuonAnalysisFitDataPresenter.h + inc/MantidQtCustomInterfaces/Muon/MuonAnalysisFitDataPresenter.h inc/MantidQtCustomInterfaces/Muon/MuonAnalysisFitDataTab.h - inc/MantidQtCustomInterfaces/Muon/MuonAnalysisFitFunctionPresenter.h + inc/MantidQtCustomInterfaces/Muon/MuonAnalysisFitFunctionPresenter.h inc/MantidQtCustomInterfaces/Muon/MuonAnalysisHelper.h inc/MantidQtCustomInterfaces/Muon/MuonAnalysisOptionTab.h inc/MantidQtCustomInterfaces/Muon/MuonAnalysisResultTableTab.h @@ -418,7 +425,7 @@ set ( MOC_FILES inc/MantidQtCustomInterfaces/Background.h inc/MantidQtCustomInterfaces/Tomography/ImggFormatsConvertViewQtWidget.h inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h - inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialog.h + inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogSavu.h ) set ( UI_FILES inc/MantidQtCustomInterfaces/DataComparison.ui @@ -477,7 +484,7 @@ set ( UI_FILES inc/MantidQtCustomInterfaces/DataComparison.ui inc/MantidQtCustomInterfaces/Muon/ALCInterface.ui inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.ui inc/MantidQtCustomInterfaces/Muon/MuonAnalysis.ui - inc/MantidQtCustomInterfaces/Muon/MuonSequentialFitDialog.ui + inc/MantidQtCustomInterfaces/Muon/MuonSequentialFitDialog.ui inc/MantidQtCustomInterfaces/Reflectometry/ReflMainWindowWidget.ui inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabWidget.ui inc/MantidQtCustomInterfaces/Reflectometry/ReflSaveTabWidget.ui diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h index c1319fe981c0e024a06bdd0eab3d7df1e60e4bf3..a895e6de746feb2f7bbac64a4678945cca842ce3 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h @@ -10,6 +10,8 @@ #include "MantidQtCustomInterfaces/Tomography/TomoReconFiltersSettings.h" #include "MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h" +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h" + namespace MantidQt { namespace CustomInterfaces { @@ -141,15 +143,6 @@ public: */ virtual TomoSystemSettings systemSettings() const = 0; - /** - * Get the current reconstruction tool settings set by the - * user. This is about tool specific options (like reconstruction - * method, etc.). - * - * @return Settings for the set of supported tools. - */ - virtual TomoReconToolsUserSettings reconToolsSettings() const = 0; - /** * The filters settings defined by the user. These options are * general pre-/post-processing options. @@ -175,20 +168,6 @@ public: */ virtual std::string currentReconTool() const = 0; - /** - * Method/algorithm selected from the TomoPy list. - * - * @return name of the method as used in TomoPy - */ - virtual std::string astraMethod() const = 0; - - /** - * Method/algorithm selected from the Astra list. - * - * @return name of the method as used in Astra Toolbox - */ - virtual std::string tomopyMethod() const = 0; - /** * Updates buttons and banners related to the current login * status. For example, when we are logged in, the 'log in' button @@ -288,9 +267,9 @@ public: /** * Show a tool specific configuration dialog for the user to set it up * - * @param name human readable name of the tool, as a string + * @param dialog The pointer to the current dialog */ - virtual void showToolConfig(const std::string &name) = 0; + virtual void showToolConfig(TomoToolConfigDialogBase &dialog) = 0; /** * Refresh the table, tree etc. that displays info on the running/finished diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h index e41f5d8d065be38b627517bed1e8a475a139cf74..ee1ce8ecf66e87ad7e7352defbc1196fa9ca2c8a 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h @@ -56,6 +56,9 @@ struct MANTIDQT_CUSTOMINTERFACES_DLL TomoSystemSettings { /// path component for the reconstructed files (outputs) std::string m_outputPathCompReconst; + /// experiment reference from the Run tab + std::string m_experimentReference; + static const std::string g_defSamplesDirPrefix; static const std::string g_defFlatsDirPrefix; static const std::string g_defDarksDirPrefix; diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialog.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialog.h deleted file mode 100644 index 5196ca49bef979e5268b8dc9cbd68a5e1c20aca8..0000000000000000000000000000000000000000 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialog.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOG_H_ -#define MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOG_H_ - -#include "ui_TomoToolConfigAstra.h" -#include "ui_TomoToolConfigCustom.h" -#include "ui_TomoToolConfigSavu.h" -#include "ui_TomoToolConfigTomoPy.h" - -#include <QDialog> - -namespace MantidQt { -namespace CustomInterfaces { - -/** -Third party tool configuration dialog(s) for the tomographic reconstruction -GUI. - -Copyright © 2014,2015 ISIS Rutherford Appleton Laboratory, NScD -Oak Ridge National Laboratory & European Spallation Source - -This file is part of Mantid. - -Mantid is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -Mantid is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. - -File change history is stored at: <https://github.com/mantidproject/mantid> -Code Documentation is available at: <http://doxygen.mantidproject.org> -*/ - -class TomoToolConfigTomoPy : public QDialog { - Q_OBJECT - -public: - TomoToolConfigTomoPy(QWidget *parent = 0); -}; - -class TomoToolConfigSavu : public QMainWindow { - Q_OBJECT -public: - TomoToolConfigSavu(QWidget *parent = 0); - -private: - void initLayout(); -}; - -class TomoToolConfigAstra : public QDialog { - Q_OBJECT -public: - TomoToolConfigAstra(QWidget *parent = 0); - -private: - void initLayout(); -}; - -class TomoToolConfigCustom : public QDialog { - Q_OBJECT -public: - TomoToolConfigCustom(QWidget *parent = 0); - -private: - void initLayout(); -}; - -class TomoToolConfigDialog : public QDialog { - Q_OBJECT - -public: - TomoToolConfigDialog(QWidget *parent = 0); - -private: - void initLayout(); - -private slots: - void okClicked(); - void cancelClicked(); - -private: - QLabel *labelRun, *labelOpt; - QLineEdit *editRun, *editOpt; - QHBoxLayout *hRun, *hOpt, *hBut; - QGridLayout *layout; - QPushButton *okButton, *cancelButton; -}; -} -} - -#endif // MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOG_H_ diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogAstra.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogAstra.h new file mode 100644 index 0000000000000000000000000000000000000000..34fa4233bd4468bedfffe167aadcdbbfc623efcd --- /dev/null +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogAstra.h @@ -0,0 +1,38 @@ +#ifndef MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGASTRA_H_ +#define MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGASTRA_H_ + +#include "ui_TomoToolConfigAstra.h" +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h" + +namespace MantidQt { +namespace CustomInterfaces { +class TomoToolConfigDialogAstra : public TomoToolConfigDialogBase { +public: + TomoToolConfigDialogAstra() + : TomoToolConfigDialogBase(DEFAULT_TOOL_NAME, DEFAULT_TOOL_METHOD) {} + + ~TomoToolConfigDialogAstra() override { + if (m_dialog) { + delete m_dialog; + } + } + +private: + void initialiseDialog() override; + void setupMethodSelected() override; + void setupToolSettingsFromPaths() override; + void setupDialogUi() override; + int executeQt() override; + std::vector<std::pair<std::string, std::string>> getToolMethods() override; + + // initialised in .cpp file + static const std::string DEFAULT_TOOL_NAME; + static const std::string DEFAULT_TOOL_METHOD; + + QDialog *m_dialog = nullptr; + Ui::TomoToolConfigAstra m_astraUi; +}; + +} // CustomInterfaces +} // MantidQt +#endif // MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGASTRA_H_ diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h new file mode 100644 index 0000000000000000000000000000000000000000..4933973efc79da09842b464bd710e842537c9a61 --- /dev/null +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h @@ -0,0 +1,153 @@ +#ifndef MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGBASE_H_ +#define MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGBASE_H_ + +#include "MantidQtCustomInterfaces/Tomography/TomoPathsConfig.h" +#include "MantidQtCustomInterfaces/Tomography/TomoReconToolsUserSettings.h" + +#include <memory> + +namespace MantidQt { +namespace CustomInterfaces { + +/** +Third party tool configuration dialog(s) for the tomographic reconstruction +GUI. + +Copyright © 2014,2015 ISIS Rutherford Appleton Laboratory, NScD +Oak Ridge National Laboratory & European Spallation Source + +This file is part of Mantid. + +Mantid is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +Mantid is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +File change history is stored at: <https://github.com/mantidproject/mantid> +Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class TomoToolConfigDialogBase { +public: + TomoToolConfigDialogBase(const std::string toolName = "", + const std::string toolMethod = "") + : m_toolName(toolName), m_toolMethod(toolMethod), m_isInitialised(false) { + } + virtual ~TomoToolConfigDialogBase() {} + + /// public static function accessor to create dialogues + static std::unique_ptr<TomoToolConfigDialogBase> + getToolDialogFor(const std::string &toolName); + + /// Sets up the dialogue settings, but does not initialise a QDialog + void setupDialog(const std::string &runPath, const TomoPathsConfig &paths, + const std::string &pathOut, + const std::string &localOutNameAppendix) { + + setupPaths(runPath, paths, pathOut, localOutNameAppendix); + setupToolSettingsFromPaths(); + } + + /// initialises a QDialog and handles the returns + virtual int initialiseGUIandExecute() { + if (!isInitialised()) { + // set up the tool's method on the first run + // this prevents from creating and destroying many dialogues if the user + // decides to scroll quickly, and the dialogue is only initialised if the + // user clicks the "Setup" button. If the tool is not setup the default + // settings will be provided if the user clicks Reconstruct + initialiseDialog(); + setupDialogUi(); + setupMethodSelected(); + + m_isInitialised = true; + } + + const int res = this->executeQt(); + this->handleDialogResult(res); + return res; + } + + virtual bool isInitialised() const { return m_isInitialised; } + + std::string getSelectedToolMethod() const { return m_toolMethod; } + + /// return pointer and transfer ownership + std::shared_ptr<TomoRecToolConfig> getSelectedToolSettings() const { + return m_toolSettings; + } + + std::string getSelectedToolName() const { return m_toolName; } + +protected: + virtual void initialiseDialog() = 0; + + virtual void handleDialogResult(const int result); + + virtual void setScriptRunPath(const std::string run) { m_runPath = run; } + + virtual void setTomoPathsConfig(const TomoPathsConfig paths) { + m_paths = paths; + } + + virtual void setPathOut(const std::string pathOut) { m_pathOut = pathOut; } + + virtual void setLocalOutNameAppendix(const std::string localOutNameAppendix) { + m_localOutNameAppendix = localOutNameAppendix; + } + + virtual void setupPaths(const std::string &runPath, + const TomoPathsConfig &paths, + const std::string &pathOut, + const std::string &localOutNameAppendix) { + this->setScriptRunPath(runPath); + this->setTomoPathsConfig(paths); + this->setPathOut(pathOut); + this->setLocalOutNameAppendix(localOutNameAppendix); + } + + virtual void setupDialogUi() = 0; + + /// setup the selected method member variable + virtual void setupMethodSelected() = 0; + + /// setup the tool config with the correct paths, must be called after the + /// paths have been set! + virtual void setupToolSettingsFromPaths() = 0; + + /// provided virtual function to add Qt execute behaviour as necessary + virtual int executeQt() = 0; // this class doesn't inherit from Qt and doesnt + // have this->exec() + + // empty function body as not all tools have methods + virtual std::vector<std::pair<std::string, std::string>> getToolMethods() { + return {}; + } + + std::shared_ptr<TomoRecToolConfig> m_toolSettings; + + const std::string m_toolName; + + std::string m_toolMethod; + + std::string m_runPath; + + std::string m_localOutNameAppendix; + + std::string m_pathOut; + + TomoPathsConfig m_paths; + + bool m_isInitialised; +}; +} +} + +#endif // MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGBASE_H_ diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogCustom.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogCustom.h new file mode 100644 index 0000000000000000000000000000000000000000..98f493470a002e318d74510dfe88e05de05a4438 --- /dev/null +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogCustom.h @@ -0,0 +1,37 @@ +#ifndef MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGCUSTOM_H_ +#define MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGCUSTOM_H_ + +#include "ui_TomoToolConfigCustom.h" +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h" + +namespace MantidQt { +namespace CustomInterfaces { +class TomoToolConfigDialogCustom : public TomoToolConfigDialogBase { +public: + TomoToolConfigDialogCustom() + : TomoToolConfigDialogBase(DEFAULT_TOOL_NAME, DEFAULT_TOOL_METHOD) {} + ~TomoToolConfigDialogCustom() override { + if (m_dialog) { + delete m_dialog; + } + } + +private: + void initialiseDialog() override; + void setupMethodSelected() override; + void setupToolSettingsFromPaths() override; + void setupDialogUi() override; + void handleDialogResult(int result) override; + int executeQt() override; + + // initialised in .cpp file + static const std::string DEFAULT_TOOL_NAME; + static const std::string DEFAULT_TOOL_METHOD; + static std::string m_backupCommandLine; + + QDialog *m_dialog = nullptr; + Ui::TomoToolConfigCustom m_customUi; +}; +} // CustomInterfaces +} // MantidQt +#endif // MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGCUSTOM_H_ diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogSavu.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogSavu.h new file mode 100644 index 0000000000000000000000000000000000000000..fc6f242f53829f2589ae13815231c864e949aa86 --- /dev/null +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogSavu.h @@ -0,0 +1,71 @@ +#ifndef MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGSAVU_H_ +#define MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGSAVU_H_ + +#include "ui_TomoToolConfigSavu.h" +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h" +#include <MantidAPI/ITableWorkspace.h> + +namespace Mantid { +namespace API { +class TableRow; +} +} + +namespace MantidQt { +namespace CustomInterfaces { +class TomoToolConfigDialogSavu : public QMainWindow, + public TomoToolConfigDialogBase { + Q_OBJECT +public: + TomoToolConfigDialogSavu(QWidget *parent = 0); + +private: + void setupMethodSelected() override; + void setupToolSettingsFromPaths() override; + void setupDialogUi() override; + void initialiseDialog() override; + int executeQt() override; + + void initSavuWindow(); + void loadAvailablePlugins(); + void refreshAvailablePluginListUI(); + void refreshCurrentPluginListUI(); + void availablePluginSelected(); + + void createPluginTreeEntry(Mantid::API::TableRow &row); + void createPluginTreeEntries(Mantid::API::ITableWorkspace_sptr table); + void paramValModified(QTreeWidgetItem *item, int /*column*/); + void currentPluginSelected(); + std::string paramValStringFromArray(const Json::Value &jsonVal, + const std::string &name); + + std::string pluginParamValString(const Json::Value &jsonVal, + const std::string &name); + + void loadSavuTomoConfig(std::string &filePath, + Mantid::API::ITableWorkspace_sptr ¤tPlugins); + void moveUpClicked(); + void moveDownClicked(); + void removeClicked(); + void menuOpenClicked(); + void menuSaveClicked(); + void menuSaveAsClicked(); + QString tableWSRowToString(Mantid::API::ITableWorkspace_sptr table, size_t i); + void expandedItem(QTreeWidgetItem *item); + void transferClicked(); + std::string createUniqueNameHidden(); + + void userWarning(const std::string &err, const std::string &description); + void userError(const std::string &err, const std::string &description); + + static size_t g_nameSeqNo; + + Ui::TomoToolConfigSavu m_savuUi; + Mantid::API::ITableWorkspace_sptr m_availPlugins; + Mantid::API::ITableWorkspace_sptr m_currPlugins; + std::string m_currentParamPath; +}; + +} // CustomInterfaces +} // MantidQt +#endif // MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGSAVU_H_ diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogTomoPy.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogTomoPy.h new file mode 100644 index 0000000000000000000000000000000000000000..bdd5b63e3aa211faa15e7f212fb459f47bee1127 --- /dev/null +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogTomoPy.h @@ -0,0 +1,37 @@ +#ifndef MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGTOMOPY_H_ +#define MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGTOMOPY_H_ + +#include "ui_TomoToolConfigTomoPy.h" +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h" + +namespace MantidQt { +namespace CustomInterfaces { +class TomoToolConfigDialogTomoPy : public TomoToolConfigDialogBase { + +public: + TomoToolConfigDialogTomoPy() + : TomoToolConfigDialogBase(DEFAULT_TOOL_NAME, DEFAULT_TOOL_METHOD) {} + + ~TomoToolConfigDialogTomoPy() override { + if (m_dialog) { + delete m_dialog; + } + } + +private: + void initialiseDialog() override; + void setupMethodSelected() override; + void setupToolSettingsFromPaths() override; + void setupDialogUi() override; + int executeQt() override; + std::vector<std::pair<std::string, std::string>> getToolMethods() override; + // initialised in .cpp file + static const std::string DEFAULT_TOOL_NAME; + static const std::string DEFAULT_TOOL_METHOD; + + QDialog *m_dialog = nullptr; + Ui::TomoToolConfigTomoPy m_tomoPyUi; +}; +} // CustomInterfaces +} // MantidQt +#endif // MANTIDQTCUSTOMINTERFACES_TOMOTOOLCONFIGDIALOGTOMOPY_H_ diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h index 00ec970ea3b2ec0171fabc130ced425fa91034f3..aa603d6ac9695724ef6d6fdd84a795dba419228a 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h @@ -7,6 +7,7 @@ #include "MantidKernel/System.h" #include "MantidQtCustomInterfaces/Tomography/ImageStackPreParams.h" #include "MantidQtCustomInterfaces/Tomography/TomoPathsConfig.h" +#include "MantidQtCustomInterfaces/Tomography/TomoRecToolConfig.h" #include "MantidQtCustomInterfaces/Tomography/TomoReconFiltersSettings.h" #include "MantidQtCustomInterfaces/Tomography/TomoReconToolsUserSettings.h" #include "MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h" @@ -14,6 +15,10 @@ // Qt classes forward declarations class QMutex; +namespace Poco { +class Pipe; +} + namespace MantidQt { namespace CustomInterfaces { @@ -83,9 +88,52 @@ public: /// Username last logged in, if any. std::string loggedIn() const { return m_loggedInUser; } + // TODO: add companion currentComputeResource where LoggedIn() is in - void usingTool(const std::string &tool) { m_currentTool = tool; } - std::string usingTool() const { return m_currentTool; } + //-------------------------------------------- + // Current tool Settings + //-------------------------------------------- + void usingTool(const std::string &tool) { m_currentToolName = tool; } + std::string usingTool() const { return m_currentToolName; } + + void setCurrentToolMethod(std::string toolMethod) { + m_currentToolMethod = toolMethod; + } + std::string getCurrentToolMethod() const { return m_currentToolMethod; } + + void setCurrentToolSettings(std::shared_ptr<TomoRecToolConfig> settings) { + m_currentToolSettings = settings; + } + + //-------------------------------------------- + // Access to the system settings information + //-------------------------------------------- + // get the remote scripts base dir from the system settings + std::string getCurrentRemoteScriptsBasePath() const { + return m_systemSettings.m_remote.m_basePathReconScripts; + } + + /// get the local paths from the system settings + std::string getCurrentLocalScriptsBasePath() const { + return m_systemSettings.m_local.m_reconScriptsPath; + } + + std::string getExeternalInterpreterPath() const { + return m_systemSettings.m_local.m_externalInterpreterPath; + } + + /// get the experiment reference currently selected + std::string getCurrentExperimentReference() const { + return m_systemSettings.m_experimentReference; + } + + /// returns the scripts folder, used for remote path + std::string getTomoScriptFolderPath() const { return g_tomoScriptFolderPath; } + + /// returns the tomo script location path inside the scripts folder + std::string getTomoScriptLocationPath() const { + return g_mainReconstructionScript; + } /// ping the (remote) compute resource bool doPing(const std::string &compRes); @@ -102,6 +150,7 @@ public: std::vector<std::string> &cmds); /// Submit a new job to the (remote or local) compute resource void doSubmitReconstructionJob(const std::string &compRes); + /// Cancel a previously submitted job void doCancelJobs(const std::string &compRes, const std::vector<std::string> &id); @@ -110,33 +159,18 @@ public: void refreshLocalJobsInfo(); - void doRunReconstructionJobLocal(); - - void updateExperimentReference(const std::string ref) { - m_experimentRef = ref; - } + void setExperimentReference(const std::string ref) { m_experimentRef = ref; } /// Update to the current setings given by the user - void updateSystemSettings(const TomoSystemSettings &settings) { + void setSystemSettings(const TomoSystemSettings &settings) { m_systemSettings = settings; } - /// Update to the current setings given by the user - void updateReconToolsSettings(const TomoReconToolsUserSettings &ts) { - m_toolsSettings = ts; - } - - void updateTomopyMethod(const std::string &method) { - m_tomopyMethod = method; - } - - void updateAstraMethod(const std::string &method) { m_astraMethod = method; } - - void updatePrePostProcSettings(const TomoReconFiltersSettings &filters) { + void setPrePostProcSettings(const TomoReconFiltersSettings &filters) { m_prePostProcSettings = filters; } - void updateImageStackPreParams(const ImageStackPreParams &roiEtc) { + void setImageStackPreParams(const ImageStackPreParams &roiEtc) { m_imageStackPreParams = roiEtc; } @@ -149,15 +183,39 @@ public: /// for clean destruction void cleanup(); - std::string localComputeResource() const { return m_localCompName; } + std::string localComputeResource() const { return g_LocalResourceName; } - void updateTomoPathsConfig(const TomoPathsConfig &tc) { m_pathsConfig = tc; } + void setTomoPathsConfig(const TomoPathsConfig &tc) { m_pathsConfig = tc; } - // tools not yet available/supported - TODO + // Names of reconstruction tools + static const std::string g_TomoPyTool; + static const std::string g_AstraTool; + static const std::string g_customCmdTool; + // not supported yet static const std::string g_CCPiTool; static const std::string g_SavuTool; -private: + // Name of the remote compute resource + static const std::string g_SCARFName; + static const std::string g_LocalResourceName; + + // The main tomo_reconstruct.py or similar script (as it is distributed with + // Mantid). This is the entry point for reconstruction jobs. + static const std::string g_mainReconstructionScript; + static const std::string g_tomoScriptFolderPath; + +protected: // protected to expose everything to testing + std::string + constructSingleStringFromVector(const std::vector<std::string> args) const; + + void doRunReconstructionJobLocal(const std::string &run, + const std::string &allOpts, + const std::vector<std::string> &args); + + void doRunReconstructionJobRemote(const std::string &compRes, + const std::string &run, + const std::string &allOpts); + /// retrieve info from compute resource into status table void getJobStatusInfo(const std::string &compRes); @@ -167,22 +225,27 @@ private: void makeRunnableWithOptions(const std::string &comp, std::string &run, std::vector<std::string> &opt) const; - void checkWarningToolNotSetup(const std::string &tool, - const std::string &cmd) const; + bool checkIfToolIsSetupProperly(const std::string &tool, + const std::string &cmd) const; - std::vector<std::string> makeTomoRecScriptOptions(bool local) const; + void makeTomoRecScriptOptions(const bool local, + std::vector<std::string> &opts) const; void filtersCfgToCmdOpts(const TomoReconFiltersSettings &filters, - const ImageStackPreParams &corRegions, bool local, + const ImageStackPreParams &corRegions, + const bool local, std::vector<std::string> &opts) const; void splitCmdLine(const std::string &cmd, std::string &run, std::string &opts) const; + /// process the tool name to be appropriate for the command line arg + std::string prepareToolNameForArgs(const std::string &toolName) const; + void checkDataPathsSet() const; std::string adaptInputPathForExecution(const std::string &path, - bool local) const; + const bool local) const; std::string buildOutReconstructionDir(const std::string &samplesDir, bool) const; @@ -196,10 +259,13 @@ private: std::string buildOutReconstructionDirFromSamplesDir(const std::string &samplesDir) const; + /// Prints the streams from the Poco::launch process into mantid + void printProcessStreamsToMantidLog(const Poco::Pipe &outPipe, + const Poco::Pipe &errPipe); + +private: /// facility for the remote compute resource const std::string m_facility; - /// display name of the "local" compute resource - const std::string m_localCompName; /// Experiment reference (RBNumber for example) std::string m_experimentRef; @@ -225,21 +291,23 @@ private: /// reconstruction tools available on SCARF std::vector<std::string> m_SCARFtools; - // Name of the remote compute resource - static const std::string g_SCARFName; - - std::string m_currentTool; - TomoPathsConfig m_pathsConfig; // System settting including several paths and parameters (local and remote) TomoSystemSettings m_systemSettings; - // Settings for the third party (tomographic reconstruction) tools - TomoReconToolsUserSettings m_toolsSettings; + //-------------------------------- + // Current tool variables + //-------------------------------- + + // current tool's name, updated from the presenter on change + std::string m_currentToolName; - std::string m_tomopyMethod; - std::string m_astraMethod; + // the tool settings so we can use it for reconstruction params + std::shared_ptr<TomoRecToolConfig> m_currentToolSettings; + + // current tool's method, updated from the presenter on change + std::string m_currentToolMethod; // Settings for the pre-/post-processing filters TomoReconFiltersSettings m_prePostProcSettings; @@ -247,15 +315,6 @@ private: // Parameters set for the ROI, normalization region, etc. ImageStackPreParams m_imageStackPreParams; - // The main tomo_reconstruct.py or similar script (as it is distributed with - // Mantid). This is the entry point for reconstruction jobs. - static const std::string g_mainReconstructionScript; - - // Names of reconstruction tools - static const std::string g_TomoPyTool; - static const std::string g_AstraTool; - static const std::string g_customCmdTool; - // mutex for the job status info update operations // TODO: replace with std::mutex+std::lock_guard QMutex *m_statusMutex; diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h index dc05e618418840879027d8b208fba1c76f17825f..874f6587f3c90b40a97871cf7f4cc635c1605625 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h @@ -18,6 +18,7 @@ namespace MantidQt { namespace CustomInterfaces { class TomoPathsConfig; +class TomoToolConfigDialogBase; /** Tomography GUI. Presenter for the GUI (as in the MVP @@ -76,9 +77,6 @@ protected: void processSetupReconTool(); void processRunRecon(); - void subprocessRunReconRemote(); - void subprocessRunReconLocal(); - protected slots: /// It may be run on user request, or periodically from a timer/thread void processRefreshJobs(); @@ -105,10 +103,41 @@ protected: /// Starts a periodic query just to keep sessions alive when logged in void startKeepAliveMechanism(int period); + /// Stops/kills the periodic query (for example if the user logs out) void killKeepAliveMechanism(); + bool isLocalResourceSelected() const; + private: + /// creates the correct dialog pointer and sets it to the member variable + void createConfigDialogUsingToolName(const std::string &toolName); + + /// sets up the dialog and uses the settings to update the model + void + setupConfigDialogSettingsAndUpdateModel(TomoToolConfigDialogBase *dialog); + + /// configures up the dialog using the view + void setupConfigDialogSettings(TomoToolConfigDialogBase &dialog); + + /// does the actual path configuration for local resource + void setupConfigDialogSettingsForLocal(TomoToolConfigDialogBase &dialog); + + /// does the actual path configuration for remote resource + void setupConfigDialogSettingsForRemote(TomoToolConfigDialogBase &dialog); + + /// update all the model information after the tool's been changed + void updateModelAfterToolChanged(const TomoToolConfigDialogBase &dialog); + + /// update the model's current tool name using the dialog + void updateModelCurrentToolName(const TomoToolConfigDialogBase &dialog); + + /// update the model's current tool method using the dialog + void updateModelCurrentToolMethod(const TomoToolConfigDialogBase &dialog); + + /// update the model's current tool settings using the dialog + void updateModelCurrentToolSettings(const TomoToolConfigDialogBase &dialog); + /// Associated view for this presenter (MVP pattern) ITomographyIfaceView *const m_view; @@ -122,6 +151,11 @@ private: // for periodic update of the job status table/tree QTimer *m_keepAliveTimer; QThread *m_keepAliveThread; + + std::unique_ptr<TomoToolConfigDialogBase> m_configDialog; + + static const std::string g_defOutPathLocal; + static const std::string g_defOutPathRemote; }; } // namespace CustomInterfaces diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h index aab47dfbb71b0d65996c2d096e04e3af182447bc..0b81d276d5f507ecf84a48ce803325f0e3a4642e 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h @@ -12,7 +12,6 @@ #include "MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h" #include "MantidQtCustomInterfaces/Tomography/ImageROIViewQtWidget.h" #include "MantidQtCustomInterfaces/Tomography/ImggFormatsConvertViewQtWidget.h" -#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialog.h" #include "MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h" #include "ui_ImageSelectCoRAndRegions.h" @@ -21,24 +20,22 @@ #include "ui_TomographyIfaceQtTabFiltersSettings.h" #include "ui_TomographyIfaceQtTabRun.h" #include "ui_TomographyIfaceQtTabSetup.h" -#include "ui_TomographyIfaceQtTabVisualize.h" #include "ui_TomographyIfaceQtTabSystemSettings.h" - +#include "ui_TomographyIfaceQtTabVisualize.h" #include <boost/scoped_ptr.hpp> #include <json/json.h> // widgets used in this interface -class ImageROIViewQtWidget; - -// Qt classes forward declarations class QMutex; namespace MantidQt { - namespace API { class BatchAlgorithmRunner; } +} +// Qt classes forward declarations +namespace MantidQt { namespace CustomInterfaces { /** @@ -108,10 +105,6 @@ public: std::string getPassword() const override; - std::string astraMethod() const override { return m_astraMethod; } - - std::string tomopyMethod() const override { return m_tomopyMethod; } - void updateLoginControls(bool loggedIn) override; void enableLoggedActions(bool enable) override; @@ -135,11 +128,6 @@ public: TomoSystemSettings systemSettings() const override; - /// Get the current reconstruction tools settings set by the user - TomoReconToolsUserSettings reconToolsSettings() const override { - return m_toolsSettings; - } - TomoReconFiltersSettings prePostProcSettings() const override; std::string currentComputeResource() const override { @@ -235,19 +223,6 @@ private slots: // aggregation run finished void finishedAggBands(bool error); - // for the savu functionality - waiting for Savu - void menuSaveClicked(); - void menuSaveAsClicked(); - void availablePluginSelected(); - void currentPluginSelected(); - void transferClicked(); - void moveUpClicked(); - void moveDownClicked(); - void removeClicked(); - void menuOpenClicked(); - void paramValModified(QTreeWidgetItem *, int); - void expandedItem(QTreeWidgetItem *); - private: /// Setup the interface (tab UI) void initLayout() override; @@ -260,8 +235,6 @@ private: void doSetupSectionSystemSettings(); void doSetupGeneralWidgets(); - void doSetupSavu(); - /// Load default interface settings for each tab, normally on startup void readSettings(); /// for the energy bands tab/widget @@ -271,11 +244,12 @@ private: /// for the energy bands tab/widget void saveSettingsEnergy() const; - void updateSystemSettings(const TomoSystemSettings &setts); + void updateSystemSettingsTabFields(const TomoSystemSettings &setts); void updatePathsConfig(const TomoPathsConfig &cfg) override; - void showToolConfig(const std::string &name) override; + void showToolConfig( + MantidQt::CustomInterfaces::TomoToolConfigDialogBase &dialog) override; void closeEvent(QCloseEvent *ev) override; @@ -308,40 +282,6 @@ private: void sendLog(const std::string &msg); - // Begin of Savu related functionality. Waiting for the tool to become - // available. When that happens, this area of the code will grow and will - // need separation. They should find a better place to live. - ///@name Savu related methods - ///@{ - /// to load plugins (savu classification / API) - void loadAvailablePlugins(); - - /// refresh the list/tree of savu plugins - void refreshAvailablePluginListUI(); - - void refreshCurrentPluginListUI(); - - /// make a tree entry from a row of a table of savu plugins - void createPluginTreeEntry(Mantid::API::TableRow &row); - void createPluginTreeEntries(Mantid::API::ITableWorkspace_sptr table); - - std::string createUniqueNameHidden(); - - QString tableWSRowToString(Mantid::API::ITableWorkspace_sptr table, size_t i); - - void loadSavuTomoConfig(std::string &filePath, - Mantid::API::ITableWorkspace_sptr ¤tPlugins); - - std::string paramValStringFromArray(const Json::Value &jsonVal, - const std::string &name); - std::string pluginParamValString(const Json::Value &jsonVal, - const std::string &name); - ///@} - - static size_t g_nameSeqNo; - - // end of Savu related methods - static const std::string g_styleSheetOffline; static const std::string g_styleSheetOnline; @@ -361,12 +301,6 @@ private: ImageROIViewQtWidget *m_tabROIW; ImggFormatsConvertViewQtWidget *m_tabImggFormats; - /// Tool specific setup dialogs - Ui::TomoToolConfigAstra m_uiAstra; - Ui::TomoToolConfigCustom m_uiCustom; - Ui::TomoToolConfigSavu m_uiSavu; - Ui::TomoToolConfigTomoPy m_uiTomoPy; - std::vector<std::string> m_processingJobsIDs; std::string m_currentComputeRes; @@ -385,16 +319,8 @@ private: static const std::string g_defOutPathLocal; static const std::string g_defOutPathRemote; - static const std::string g_TomoPyTool; - static const std::string g_AstraTool; - static const std::string g_CCPiTool; - static const std::string g_SavuTool; - static const std::string g_customCmdTool; - TomoPathsConfig m_pathsConfig; - static const std::string g_defRemotePathScripts; - // several paths or path components related to where the files are found // (raw files, reconstructions, pre-post processed files, etc.) // These are the defaults @@ -423,13 +349,6 @@ private: /// the local and remote machines TomoSystemSettings m_systemSettings; - /// Settings for the third party (tomographic reconstruction) tools - TomoReconToolsUserSettings m_toolsSettings; - static const std::vector<std::pair<std::string, std::string>> - g_tomopy_methods; - std::string m_astraMethod; - std::string m_tomopyMethod; - // Basic representation of user settings, read/written on startup/close. // TODO: this could be done more sophisticated, with a class using // QDataStream and in/out stream operators for example. Keeping diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ToolConfigTomoPy.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ToolConfigTomoPy.h index febc98d72fc11a19b3136e703c237c6a31e79259..1af2c729ff351ffd68dbf146d687951bf99cdb26 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ToolConfigTomoPy.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ToolConfigTomoPy.h @@ -1,10 +1,8 @@ #ifndef MANTIDQTCUSTOMINTERFACES_TOMOGRAPHY_TOOLCONFIGTOMOPY_H_ #define MANTIDQTCUSTOMINTERFACES_TOMOGRAPHY_TOOLCONFIGTOMOPY_H_ -#include <string> - -#include "MantidKernel/System.h" #include "MantidQtCustomInterfaces/Tomography/TomoRecToolConfig.h" +#include "MantidQtCustomInterfaces/DllConfig.h" namespace MantidQt { namespace CustomInterfaces { diff --git a/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp b/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp index 3c5f31c71e021ce0c99b9884f008c446a8196705..f4ce56d9d490971dbe31f0d4214d2464ff41a283 100644 --- a/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp +++ b/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp @@ -1547,6 +1547,9 @@ QStringList ConvFit::getFunctionParameters(QString functionName) { } else { IFunction_sptr func = FunctionFactory::Instance().createFunction( currentFitFunction.toStdString()); + for (size_t i = 0; i < func->nParams(); i++) { + parameters << QString::fromStdString(func->parameterName(i)); + } } return parameters; } diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialog.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialog.cpp deleted file mode 100644 index 4496f36783a6646cee1d0d309af1272cb9590d6f..0000000000000000000000000000000000000000 --- a/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialog.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialog.h" - -namespace MantidQt { -namespace CustomInterfaces { - -TomoToolConfigTomoPy::TomoToolConfigTomoPy(QWidget *parent) : QDialog(parent) {} - -TomoToolConfigSavu::TomoToolConfigSavu(QWidget *parent) : QMainWindow(parent) {} - -TomoToolConfigAstra::TomoToolConfigAstra(QWidget *parent) : QDialog(parent) {} - -TomoToolConfigCustom::TomoToolConfigCustom(QWidget *parent) : QDialog(parent) {} - -TomoToolConfigDialog::TomoToolConfigDialog(QWidget *parent) : QDialog(parent) { - labelRun = new QLabel("Runnable script"); - editRun = new QLineEdit("/work/imat/"); - hRun = new QHBoxLayout(); - hRun->addWidget(labelRun); - hRun->addWidget(editRun); - - labelOpt = new QLabel("Command line options"); - editOpt = new QLineEdit("/work/imat"); - hOpt = new QHBoxLayout(); - hOpt->addWidget(labelOpt); - - hOpt->addWidget(editOpt); - - okButton = new QPushButton("Ok"); - cancelButton = new QPushButton("Cancel"); - hBut = new QHBoxLayout(); - hBut->insertStretch(0, 1); - hBut->addWidget(okButton); - hBut->addWidget(cancelButton); - - layout = new QGridLayout(); - layout->addLayout(hRun, 0, 0); - layout->addLayout(hOpt, 1, 0); - layout->addLayout(hOpt, 2, 0); - - connect(okButton, SIGNAL(clicked()), this, SLOT(okClicked())); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancelClicked())); -} - -void TomoToolConfigDialog::okClicked() {} - -void TomoToolConfigDialog::cancelClicked() {} - -} // namespace CustomInterfaces -} // namespace MantidQt diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogAstra.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogAstra.cpp new file mode 100644 index 0000000000000000000000000000000000000000..61cf5f5c3ef14c6dc0e5b85cb14adcfffc8ece1c --- /dev/null +++ b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogAstra.cpp @@ -0,0 +1,45 @@ +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogAstra.h" +#include "MantidQtCustomInterfaces/Tomography/ToolConfigAstraToolbox.h" +#include "MantidQtCustomInterfaces/Tomography/TomoReconToolsUserSettings.h" + +namespace MantidQt { +namespace CustomInterfaces { + +const std::string TomoToolConfigDialogAstra::DEFAULT_TOOL_NAME = "Astra"; +const std::string TomoToolConfigDialogAstra::DEFAULT_TOOL_METHOD = "FBP3D_CUDA"; + +void TomoToolConfigDialogAstra::setupDialogUi() { + m_astraUi.setupUi(m_dialog); + m_astraUi.comboBox_method->clear(); + const auto &methods = getToolMethods(); + for (auto &method : methods) { + m_astraUi.comboBox_method->addItem(QString::fromStdString(method.second)); + } +} + +void TomoToolConfigDialogAstra::initialiseDialog() { m_dialog = new QDialog; } + +void TomoToolConfigDialogAstra::setupToolSettingsFromPaths() { + m_toolSettings = std::make_shared<ToolConfigAstraToolbox>( + m_runPath, m_pathOut + m_localOutNameAppendix, m_paths.pathDarks(), + m_paths.pathOpenBeam(), m_paths.pathSamples()); +} + +void TomoToolConfigDialogAstra::setupMethodSelected() { + const auto &methods = getToolMethods(); + + const int mi = m_astraUi.comboBox_method->currentIndex(); + m_toolMethod = methods[mi].first; +} + +/** Calls the execute of the QDialog +*/ +int TomoToolConfigDialogAstra::executeQt() { return m_dialog->exec(); } + +std::vector<std::pair<std::string, std::string>> +TomoToolConfigDialogAstra::getToolMethods() { + return ToolConfigAstraToolbox::methods(); +} + +} // CustomInterfaces +} // MantidQt \ No newline at end of file diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogBase.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d95af10cf482b869de1302f72f7abe8a6bac7d9 --- /dev/null +++ b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogBase.cpp @@ -0,0 +1,36 @@ +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h" +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogTomoPy.h" +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogAstra.h" +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogSavu.h" +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogCustom.h" + +#include "MantidKernel/make_unique.h" + +namespace MantidQt { +namespace CustomInterfaces { + +std::unique_ptr<TomoToolConfigDialogBase> +TomoToolConfigDialogBase::getToolDialogFor(const std::string &toolName) { + + if (toolName == "TomoPy") { + return Mantid::Kernel::make_unique<TomoToolConfigDialogTomoPy>(); + } else if (toolName == "Astra") { + return Mantid::Kernel::make_unique<TomoToolConfigDialogAstra>(); + } else if (toolName == "Savu") { + return Mantid::Kernel::make_unique<TomoToolConfigDialogSavu>(); + } else if (toolName == "Custom command") { + return Mantid::Kernel::make_unique<TomoToolConfigDialogCustom>(); + } + // tool doesn't exist, return nullptr + return nullptr; +} + +void TomoToolConfigDialogBase::handleDialogResult(const int result) { + if (QDialog::Accepted == result) { + // setup the new settings if the user has Accepted + setupMethodSelected(); + setupToolSettingsFromPaths(); + } +} +} // namespace CustomInterfaces +} // namespace MantidQt diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogCustom.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogCustom.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f8e31af5914780682614b4320f419963f59165bc --- /dev/null +++ b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogCustom.cpp @@ -0,0 +1,71 @@ +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogCustom.h" +#include "MantidQtCustomInterfaces/Tomography/ToolConfigCustom.h" + +namespace MantidQt { +namespace CustomInterfaces { + +const std::string TomoToolConfigDialogCustom::DEFAULT_TOOL_NAME = + "Custom command"; + +// custom tool doesn't have a default method +const std::string TomoToolConfigDialogCustom::DEFAULT_TOOL_METHOD = ""; + +std::string TomoToolConfigDialogCustom::m_backupCommandLine = ""; + +/** Reads the current strings in the dialogue and creates +* the tool settings from them. If the dialogue is not initialised yet +* the strings will be empty, thus we put the default values +*/ +void TomoToolConfigDialogCustom::setupToolSettingsFromPaths() { + + if (m_isInitialised) { + // None of the other paths matter, because the user could've changed + // them, so ignore them and load the current ones on the dialogue + const std::string run = + m_customUi.lineEdit_runnable->text().toStdString(); // current path + const std::string opts = m_customUi.textEdit_cl_opts->toPlainText() + .toStdString(); // current commands + + // update the settings with the newest information + m_toolSettings = std::make_shared<ToolConfigCustom>(run, opts); + } else { + // create settings with the default values + m_toolSettings = std::make_shared<ToolConfigCustom>(m_runPath, "--help"); + } +} + +void TomoToolConfigDialogCustom::setupMethodSelected() { + + // sets the current runnable path, overriding the default one + m_customUi.lineEdit_runnable->setText(QString::fromStdString(m_runPath)); +} + +void TomoToolConfigDialogCustom::setupDialogUi() { + m_customUi.setupUi(m_dialog); + + if (m_backupCommandLine != "") { + m_customUi.textEdit_cl_opts->setText( + QString::fromStdString(m_backupCommandLine)); + } + + // get default options from command line + const std::string opts = + m_customUi.textEdit_cl_opts->toPlainText().toStdString(); + + // create the default settings + m_toolSettings = std::make_shared<ToolConfigCustom>(m_runPath, opts); +} + +void TomoToolConfigDialogCustom::initialiseDialog() { m_dialog = new QDialog; } + +void TomoToolConfigDialogCustom::handleDialogResult(int result) { + if (QDialog::Accepted == result) { + // if accepted we want to save the information + m_backupCommandLine = + m_customUi.textEdit_cl_opts->toPlainText().toStdString(); + setupToolSettingsFromPaths(); + } +} +int TomoToolConfigDialogCustom::executeQt() { return m_dialog->exec(); } +} // CustomInterfaces +} // MantidQt \ No newline at end of file diff --git a/MantidQt/CustomInterfaces/src/Tomography/SavuConfigDialog.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogSavu.cpp similarity index 58% rename from MantidQt/CustomInterfaces/src/Tomography/SavuConfigDialog.cpp rename to MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogSavu.cpp index 0c2f23c5077750a3f4b96d257f574c8a3294f734..31497f41dd006f5d391f4918118058d8367d5e20 100644 --- a/MantidQt/CustomInterfaces/src/Tomography/SavuConfigDialog.cpp +++ b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogSavu.cpp @@ -1,23 +1,87 @@ -#include "MantidAPI/AlgorithmManager.h" -#include "MantidAPI/ITableWorkspace.h" -#include "MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h" - -#include <boost/lexical_cast.hpp> +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogSavu.h" +#include "MantidQtCustomInterfaces/Tomography/TomoReconToolsUserSettings.h" +#include <MantidAPI/TableRow.h> +#include <MantidAPI/WorkspaceFactory.h> #include <Poco/String.h> - +#include <json/reader.h> +#include <MantidAPI/NotebookWriter.h> #include <QFileDialog> #include <QMessageBox> +#include <MantidAPI/AlgorithmManager.h> using namespace Mantid::API; namespace MantidQt { namespace CustomInterfaces { +TomoToolConfigDialogSavu::TomoToolConfigDialogSavu(QWidget *parent) + : QMainWindow(parent) { + // TODO init the 545231453t54 variables + m_availPlugins = Mantid::API::WorkspaceFactory::Instance().createTable(); + m_availPlugins->addColumns("str", "name", 4); + m_currPlugins = Mantid::API::WorkspaceFactory::Instance().createTable(); + m_currPlugins->addColumns("str", "name", 4); +} + +int TomoToolConfigDialogSavu::executeQt() { + this->show(); + QEventLoop el; + connect(this, SIGNAL(destroyed()), &el, SLOT(quit())); + return el.exec(); +} + +void TomoToolConfigDialogSavu::initialiseDialog() { + throw Mantid::Kernel::Exception::NotImplementedError( + "SAVU interface not implemented"); +} +void TomoToolConfigDialogSavu::setupMethodSelected() { + throw Mantid::Kernel::Exception::NotImplementedError( + "SAVU interface not implemented"); +} +void TomoToolConfigDialogSavu::setupToolSettingsFromPaths() { + throw Mantid::Kernel::Exception::NotImplementedError( + "SAVU interface not implemented"); +} + +void TomoToolConfigDialogSavu::setupDialogUi() { + m_savuUi.setupUi(this); + initSavuWindow(); + this->setWindowModality(Qt::ApplicationModal); +} + +void TomoToolConfigDialogSavu::initSavuWindow() { + // geometry, etc. niceties + // on the left (just plugin names) 1/2, right: 2/3 + QList<int> sizes{100, 200}; + m_savuUi.splitterPlugins->setSizes(std::move(sizes)); + + // Setup Parameter editor tab + loadAvailablePlugins(); + m_savuUi.treeCurrentPlugins->setHeaderHidden(true); + + // Connect slots + // Lists/trees + connect(m_savuUi.listAvailablePlugins, SIGNAL(itemSelectionChanged()), this, + SLOT(availablePluginSelected())); + connect(m_savuUi.treeCurrentPlugins, SIGNAL(itemSelectionChanged()), this, + SLOT(currentPluginSelected())); + connect(m_savuUi.treeCurrentPlugins, SIGNAL(itemExpanded(QTreeWidgetItem *)), + this, SLOT(expandedItem(QTreeWidgetItem *))); + + // Buttons + connect(m_savuUi.btnTransfer, SIGNAL(released()), this, + SLOT(transferClicked())); + connect(m_savuUi.btnMoveUp, SIGNAL(released()), this, SLOT(moveUpClicked())); + connect(m_savuUi.btnMoveDown, SIGNAL(released()), this, + SLOT(moveDownClicked())); + connect(m_savuUi.btnRemove, SIGNAL(released()), this, SLOT(removeClicked())); +} + // TODO: what's in this file should become a class of its own, // 'SavuConfigDialog' or similar -void TomographyIfaceViewQtGUI::loadAvailablePlugins() { +void TomoToolConfigDialogSavu::loadAvailablePlugins() { // TODO:: load actual plugins when we know them // creating a few relatively realistic choices for now (should crossh check // with the savu api when finalized). @@ -61,48 +125,49 @@ void TomographyIfaceViewQtGUI::loadAvailablePlugins() { // Reloads the GUI list of available plugins from the data object :: // Populating only through this ensures correct indexing. -void TomographyIfaceViewQtGUI::refreshAvailablePluginListUI() { +void TomoToolConfigDialogSavu::refreshAvailablePluginListUI() { // Table WS structure, id/params/name/cite - m_uiSavu.listAvailablePlugins->clear(); - for (size_t i = 0; i < m_availPlugins->rowCount(); ++i) { - QString str = + m_savuUi.listAvailablePlugins->clear(); + const size_t rowcount = m_availPlugins->rowCount(); + for (size_t i = 0; i < rowcount; ++i) { + const QString str = QString::fromStdString(m_availPlugins->cell<std::string>(i, 2)); - m_uiSavu.listAvailablePlugins->addItem(str); + m_savuUi.listAvailablePlugins->addItem(std::move(str)); } } // Reloads the GUI list of current plugins from the data object :: // Populating only through this ensures correct indexing. -void TomographyIfaceViewQtGUI::refreshCurrentPluginListUI() { +void TomoToolConfigDialogSavu::refreshCurrentPluginListUI() { // Table WS structure, id/params/name/cite - m_uiSavu.treeCurrentPlugins->clear(); + m_savuUi.treeCurrentPlugins->clear(); createPluginTreeEntries(m_currPlugins); } // Updates the selected plugin info from Available plugins list. -void TomographyIfaceViewQtGUI::availablePluginSelected() { - if (m_uiSavu.listAvailablePlugins->selectedItems().count() != 0) { - size_t idx = static_cast<size_t>( - m_uiSavu.listAvailablePlugins->currentIndex().row()); +void TomoToolConfigDialogSavu::availablePluginSelected() { + if (m_savuUi.listAvailablePlugins->selectedItems().count() != 0) { + const size_t idx = static_cast<size_t>( + m_savuUi.listAvailablePlugins->currentIndex().row()); if (idx < m_availPlugins->rowCount()) { - m_uiSavu.availablePluginDesc->setText( + m_savuUi.availablePluginDesc->setText( tableWSRowToString(m_availPlugins, idx)); } } } // Updates the selected plugin info from Current plugins list. -void TomographyIfaceViewQtGUI::currentPluginSelected() { - if (m_uiSavu.treeCurrentPlugins->selectedItems().count() != 0) { - auto currItem = m_uiSavu.treeCurrentPlugins->selectedItems()[0]; +void TomoToolConfigDialogSavu::currentPluginSelected() { + if (m_savuUi.treeCurrentPlugins->selectedItems().count() != 0) { + auto currItem = m_savuUi.treeCurrentPlugins->selectedItems()[0]; while (currItem->parent() != NULL) currItem = currItem->parent(); int topLevelIndex = - m_uiSavu.treeCurrentPlugins->indexOfTopLevelItem(currItem); + m_savuUi.treeCurrentPlugins->indexOfTopLevelItem(currItem); - m_uiSavu.currentPluginDesc->setText( + m_savuUi.currentPluginDesc->setText( tableWSRowToString(m_currPlugins, topLevelIndex)); } } @@ -134,7 +199,7 @@ private: }; // On user editing a parameter tree item, update the data object to match. -void TomographyIfaceViewQtGUI::paramValModified(QTreeWidgetItem *item, +void TomoToolConfigDialogSavu::paramValModified(QTreeWidgetItem *item, int /*column*/) { OwnTreeWidgetItem *ownItem = dynamic_cast<OwnTreeWidgetItem *>(item); if (!ownItem) @@ -142,7 +207,7 @@ void TomographyIfaceViewQtGUI::paramValModified(QTreeWidgetItem *item, int topLevelIndex = -1; if (ownItem->getRootParent() != NULL) { - topLevelIndex = m_uiSavu.treeCurrentPlugins->indexOfTopLevelItem( + topLevelIndex = m_savuUi.treeCurrentPlugins->indexOfTopLevelItem( ownItem->getRootParent()); } if (-1 == topLevelIndex) @@ -169,7 +234,7 @@ void TomographyIfaceViewQtGUI::paramValModified(QTreeWidgetItem *item, // When a top level item is expanded, also expand its child items - if tree // items -void TomographyIfaceViewQtGUI::expandedItem(QTreeWidgetItem *item) { +void TomoToolConfigDialogSavu::expandedItem(QTreeWidgetItem *item) { if (item->parent() == NULL) { for (int i = 0; i < item->childCount(); ++i) { item->child(i)->setExpanded(true); @@ -179,28 +244,31 @@ void TomographyIfaceViewQtGUI::expandedItem(QTreeWidgetItem *item) { // Adds one plugin from the available plugins list into the list of // current plugins -void TomographyIfaceViewQtGUI::transferClicked() { - if (0 == m_uiSavu.listAvailablePlugins->selectedItems().count()) +void TomoToolConfigDialogSavu::transferClicked() { + if (0 == m_savuUi.listAvailablePlugins->selectedItems().count()) return; - int idx = m_uiSavu.listAvailablePlugins->currentIndex().row(); + const int idx = m_savuUi.listAvailablePlugins->currentIndex().row(); + const size_t columnCount = m_currPlugins->columnCount(); + Mantid::API::TableRow row = m_currPlugins->appendRow(); - for (size_t j = 0; j < m_currPlugins->columnCount(); ++j) { + for (size_t j = 0; j < columnCount; ++j) { row << m_availPlugins->cell<std::string>(idx, j); } createPluginTreeEntry(row); } -void TomographyIfaceViewQtGUI::moveUpClicked() { - if (0 == m_uiSavu.treeCurrentPlugins->selectedItems().count()) +void TomoToolConfigDialogSavu::moveUpClicked() { + if (0 == m_savuUi.treeCurrentPlugins->selectedItems().count()) return; - size_t idx = - static_cast<size_t>(m_uiSavu.treeCurrentPlugins->currentIndex().row()); + const size_t idx = + static_cast<size_t>(m_savuUi.treeCurrentPlugins->currentIndex().row()); if (idx > 0 && idx < m_currPlugins->rowCount()) { // swap row, all columns - for (size_t j = 0; j < m_currPlugins->columnCount(); ++j) { - std::string swap = m_currPlugins->cell<std::string>(idx, j); + const size_t columnCount = m_currPlugins->columnCount(); + for (size_t j = 0; j < columnCount; ++j) { + const std::string swap = m_currPlugins->cell<std::string>(idx, j); m_currPlugins->cell<std::string>(idx, j) = m_currPlugins->cell<std::string>(idx - 1, j); m_currPlugins->cell<std::string>(idx - 1, j) = swap; @@ -209,17 +277,19 @@ void TomographyIfaceViewQtGUI::moveUpClicked() { } } -void TomographyIfaceViewQtGUI::moveDownClicked() { +void TomoToolConfigDialogSavu::moveDownClicked() { // TODO: this can be done with the same function as above... - if (0 == m_uiSavu.treeCurrentPlugins->selectedItems().count()) + if (0 == m_savuUi.treeCurrentPlugins->selectedItems().count()) return; - size_t idx = - static_cast<size_t>(m_uiSavu.treeCurrentPlugins->currentIndex().row()); + const size_t idx = + static_cast<size_t>(m_savuUi.treeCurrentPlugins->currentIndex().row()); if (idx < m_currPlugins->rowCount() - 1) { // swap all columns - for (size_t j = 0; j < m_currPlugins->columnCount(); ++j) { - std::string swap = m_currPlugins->cell<std::string>(idx, j); + + const size_t columnCount = m_currPlugins->columnCount(); + for (size_t j = 0; j < columnCount; ++j) { + const std::string swap = m_currPlugins->cell<std::string>(idx, j); m_currPlugins->cell<std::string>(idx, j) = m_currPlugins->cell<std::string>(idx + 1, j); m_currPlugins->cell<std::string>(idx + 1, j) = swap; @@ -228,18 +298,18 @@ void TomographyIfaceViewQtGUI::moveDownClicked() { } } -void TomographyIfaceViewQtGUI::removeClicked() { +void TomoToolConfigDialogSavu::removeClicked() { // Also clear ADS entries - if (0 == m_uiSavu.treeCurrentPlugins->selectedItems().count()) + if (0 == m_savuUi.treeCurrentPlugins->selectedItems().count()) return; - int idx = m_uiSavu.treeCurrentPlugins->currentIndex().row(); + const int idx = m_savuUi.treeCurrentPlugins->currentIndex().row(); m_currPlugins->removeRow(idx); refreshCurrentPluginListUI(); } -void TomographyIfaceViewQtGUI::menuOpenClicked() { +void TomoToolConfigDialogSavu::menuOpenClicked() { QString s = QFileDialog::getOpenFileName(0, "Open file", QDir::currentPath(), "NeXus files (*.nxs);;All files (*)", new QString("NeXus files (*.nxs)")); @@ -268,7 +338,37 @@ void TomographyIfaceViewQtGUI::menuOpenClicked() { } } -void TomographyIfaceViewQtGUI::menuSaveClicked() { +/** +* Load a savu tomo config file into the current plugin list, overwriting it. +* Uses the algorithm LoadSavuTomoConfig +*/ +void TomoToolConfigDialogSavu::loadSavuTomoConfig( + std::string &filePath, Mantid::API::ITableWorkspace_sptr ¤tPlugins) { + // try to load tomo reconstruction parametereization file + auto alg = Mantid::API::AlgorithmManager::Instance().createUnmanaged( + "LoadSavuTomoConfig"); + alg->initialize(); + alg->setPropertyValue("Filename", filePath); + alg->setPropertyValue("OutputWorkspace", createUniqueNameHidden()); + try { + alg->execute(); + } catch (std::runtime_error &e) { + throw std::runtime_error( + std::string("Error when trying to load tomographic reconstruction " + "parameter file: ") + + e.what()); + } + + // new processing plugins list + try { + currentPlugins = alg->getProperty("OutputWorkspace"); + } catch (std::exception &e) { + userError("Could not load config file", "Failed to load the file " + "with the following error: " + + std::string(e.what())); + } +} +void TomoToolConfigDialogSavu::menuSaveClicked() { if (m_currentParamPath.empty()) { menuSaveAsClicked(); return; @@ -296,8 +396,21 @@ void TomographyIfaceViewQtGUI::menuSaveClicked() { } } } +size_t TomoToolConfigDialogSavu::g_nameSeqNo = 0; + +// Build a unique (and hidden) name for the table ws +std::string TomoToolConfigDialogSavu::createUniqueNameHidden() { + std::string name; + do { + // with __ prefix => hidden + name = "__TomoConfigTableWS_Seq_" + + boost::lexical_cast<std::string>(g_nameSeqNo++); + } while (AnalysisDataService::Instance().doesExist(name)); + + return name; +} -void TomographyIfaceViewQtGUI::menuSaveAsClicked() { +void TomoToolConfigDialogSavu::menuSaveAsClicked() { QString s = QFileDialog::getSaveFileName(0, "Save file", QDir::currentPath(), "NeXus files (*.nxs);;All files (*)", new QString("NeXus files (*.nxs)")); @@ -309,7 +422,7 @@ void TomographyIfaceViewQtGUI::menuSaveAsClicked() { menuSaveClicked(); } -QString TomographyIfaceViewQtGUI::tableWSRowToString(ITableWorkspace_sptr table, +QString TomoToolConfigDialogSavu::tableWSRowToString(ITableWorkspace_sptr table, size_t i) { std::stringstream msg; msg << "ID: " << table->cell<std::string>(i, 0) @@ -320,11 +433,11 @@ QString TomographyIfaceViewQtGUI::tableWSRowToString(ITableWorkspace_sptr table, } /** - * Creates a treewidget item for a row of a table workspace. - * - * @param row Row from a table workspace with each row specfying a savu plugin - */ -void TomographyIfaceViewQtGUI::createPluginTreeEntry(TableRow &row) { +* Creates a treewidget item for a row of a table workspace. +* +* @param row Row from a table workspace with each row specfying a savu plugin +*/ +void TomoToolConfigDialogSavu::createPluginTreeEntry(TableRow &row) { QStringList idStr, nameStr, citeStr, paramsStr; idStr.push_back(QString::fromStdString("ID: " + row.cell<std::string>(0))); nameStr.push_back( @@ -389,27 +502,27 @@ void TomographyIfaceViewQtGUI::createPluginTreeEntry(TableRow &row) { layout->addWidget(paramContainerTree); pluginParamsItem->addChild(container); - m_uiSavu.treeCurrentPlugins->setItemWidget(container, 0, w); + m_savuUi.treeCurrentPlugins->setItemWidget(container, 0, w); } } pluginBaseItem->addChildren(items); - m_uiSavu.treeCurrentPlugins->addTopLevelItem(pluginBaseItem); + m_savuUi.treeCurrentPlugins->addTopLevelItem(pluginBaseItem); } /** - * This is a kind of .asString() method for arrays. It iterates - * through the array elements and builds the string enclosed by []. - * - * @param jsonVal Value of a parameter that seems to be an array - *(isArray()==true) - * @param name Name of the parameter (to give informative messages) - * - * @return String with a parameter value(s), enclosed by [] and - * separated by commas - */ +* This is a kind of .asString() method for arrays. It iterates +* through the array elements and builds the string enclosed by []. +* +* @param jsonVal Value of a parameter that seems to be an array +*(isArray()==true) +* @param name Name of the parameter (to give informative messages) +* +* @return String with a parameter value(s), enclosed by [] and +* separated by commas +*/ std::string -TomographyIfaceViewQtGUI::paramValStringFromArray(const Json::Value &jsonVal, +TomoToolConfigDialogSavu::paramValStringFromArray(const Json::Value &jsonVal, const std::string &name) { std::string s; s = "["; @@ -442,16 +555,16 @@ TomographyIfaceViewQtGUI::paramValStringFromArray(const Json::Value &jsonVal, } /** - * Build a string with the value of a parameter in a json - * string. Works for scalar and list/array values. - * - * @param jsonVal Value of a parameter that seems to be an array - * @param name Name of the parameter (to give informative messages) - * - * @return String with a parameter value - */ +* Build a string with the value of a parameter in a json +* string. Works for scalar and list/array values. +* +* @param jsonVal Value of a parameter that seems to be an array +* @param name Name of the parameter (to give informative messages) +* +* @return String with a parameter value +*/ std::string -TomographyIfaceViewQtGUI::pluginParamValString(const Json::Value &jsonVal, +TomoToolConfigDialogSavu::pluginParamValString(const Json::Value &jsonVal, const std::string &name) { std::string s; // string and numeric values can (normally) be converted to string but arrays @@ -474,13 +587,41 @@ TomographyIfaceViewQtGUI::pluginParamValString(const Json::Value &jsonVal, return s; } -void TomographyIfaceViewQtGUI::createPluginTreeEntries( - ITableWorkspace_sptr table) { +void TomoToolConfigDialogSavu::createPluginTreeEntries( + Mantid::API::ITableWorkspace_sptr table) { for (size_t i = 0; i < table->rowCount(); ++i) { - TableRow r = table->getRow(i); + Mantid::API::TableRow r = table->getRow(i); createPluginTreeEntry(r); } } +/** TODO move into a class, extract from here and QtView interface +* Show an error (serious) message to the user (pop up) +* +* @param err Basic error title +* @param description More detailed explanation, hints, additional +* information, etc. +*/ +void TomoToolConfigDialogSavu::userError(const std::string &err, + const std::string &description) { + QMessageBox::critical(this, QString::fromStdString(err), + QString::fromStdString(description), QMessageBox::Ok, + QMessageBox::Ok); +} + +/** +* Show a warning message to the user (pop up) +* +* @param err Basic error title +* @param description More detailed explanation, hints, additional +* information, etc. +*/ +void TomoToolConfigDialogSavu::userWarning(const std::string &err, + const std::string &description) { + QMessageBox::warning(this, QString::fromStdString(err), + QString::fromStdString(description), QMessageBox::Ok, + QMessageBox::Ok); +} + } // namespace CustomInterfaces } // namespace MantidQt diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogTomoPy.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogTomoPy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e20fafd4782e8e61a1469d7ace59ba25c7708055 --- /dev/null +++ b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogTomoPy.cpp @@ -0,0 +1,47 @@ +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogTomoPy.h" +#include "MantidQtCustomInterfaces/Tomography/ToolConfigTomoPy.h" + +namespace MantidQt { +namespace CustomInterfaces { + +const std::string TomoToolConfigDialogTomoPy::DEFAULT_TOOL_NAME = "TomoPy"; +const std::string TomoToolConfigDialogTomoPy::DEFAULT_TOOL_METHOD = "gridrec"; + +void TomoToolConfigDialogTomoPy::setupDialogUi() { + m_tomoPyUi.setupUi(m_dialog); + m_tomoPyUi.comboBox_method->clear(); + + const auto &methods = getToolMethods(); + for (auto &method : methods) { + m_tomoPyUi.comboBox_method->addItem(QString::fromStdString(method.second)); + } +} + +void TomoToolConfigDialogTomoPy::initialiseDialog() { m_dialog = new QDialog; } + +void TomoToolConfigDialogTomoPy::setupToolSettingsFromPaths() { + // TODO: for the output path, probably better to take the sample path, + // then up one level + m_toolSettings = std::make_shared<ToolConfigTomoPy>( + m_runPath, m_pathOut + m_localOutNameAppendix, m_paths.pathDarks(), + m_paths.pathOpenBeam(), m_paths.pathSamples()); +} +void TomoToolConfigDialogTomoPy::setupMethodSelected() { + // move to member/global variable and use more space OR keep here + const auto &methods = getToolMethods(); + + const int mi = m_tomoPyUi.comboBox_method->currentIndex(); + // TODO maybe comboBox_method->currentText? + m_toolMethod = methods[mi].first; +} + +/** Calls the execute of the QDialog +*/ +int TomoToolConfigDialogTomoPy::executeQt() { return m_dialog->exec(); } + +std::vector<std::pair<std::string, std::string>> +TomoToolConfigDialogTomoPy::getToolMethods() { + return ToolConfigTomoPy::methods(); +} +} // Custominterfaces +} // MantidQt diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp index c28ce60e4d593a7c7b820a0a3356a80b34da820b..e9e6b2a00e5ec9c33623f1b3d49c4cf96ba56464 100644 --- a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp +++ b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp @@ -1,11 +1,14 @@ -#include "MantidKernel/FacilityInfo.h" -#include "MantidQtAPI/AlgorithmRunner.h" +#include "MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h" #include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/MatrixWorkspace.h" -#include "MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidQtAPI/AlgorithmRunner.h" #include <Poco/Path.h> +#include <Poco/Pipe.h> +#include <Poco/PipeStream.h> #include <Poco/Process.h> +#include <Poco/StreamCopier.h> #include <QMutex> @@ -27,10 +30,13 @@ Mantid::Kernel::Logger g_log("TomographyGUI"); // names by which we know compute resourcess const std::string TomographyIfaceModel::g_SCARFName = "SCARF@STFC"; +const std::string TomographyIfaceModel::g_LocalResourceName = "Local"; const std::string TomographyIfaceModel::g_mainReconstructionScript = "/Imaging/IMAT/tomo_reconstruct.py"; +const std::string TomographyIfaceModel::g_tomoScriptFolderPath = "/scripts"; + // names by which we know image/tomography reconstruction tools (3rd party) const std::string TomographyIfaceModel::g_TomoPyTool = "TomoPy"; const std::string TomographyIfaceModel::g_AstraTool = "Astra"; @@ -44,23 +50,17 @@ const std::string TomographyIfaceModel::g_customCmdTool = "Custom command"; * compute resource. */ TomographyIfaceModel::TomographyIfaceModel() - : m_facility("ISIS"), m_localCompName("Local"), m_experimentRef("RB000000"), - m_loggedInUser(""), m_loggedInComp(""), m_computeRes(), - m_computeResStatus(), m_reconTools(), m_reconToolsStatus(), - m_jobsStatus(), m_SCARFtools(), m_toolsSettings(), - m_tomopyMethod("gridrec"), m_astraMethod("FBP3D_CUDA"), - m_prePostProcSettings(), m_imageStackPreParams(), m_statusMutex(NULL) { + : m_facility("ISIS"), m_experimentRef("RB000000"), m_loggedInUser(""), + m_loggedInComp(""), m_computeResStatus(), m_reconTools(), + m_reconToolsStatus(), m_jobsStatus(), m_prePostProcSettings(), + m_imageStackPreParams(), m_statusMutex(NULL) { - m_computeRes.push_back(g_SCARFName); - m_computeRes.push_back(m_localCompName); + m_computeRes = {g_SCARFName, g_LocalResourceName}; - m_SCARFtools.push_back(g_TomoPyTool); - m_SCARFtools.push_back(g_AstraTool); - m_SCARFtools.push_back(g_CCPiTool); - m_SCARFtools.push_back(g_SavuTool); - m_SCARFtools.push_back(g_customCmdTool); + m_SCARFtools = {g_TomoPyTool, g_AstraTool, g_CCPiTool, g_SavuTool, + g_customCmdTool}; - m_currentTool = m_SCARFtools.front(); + m_currentToolName = m_SCARFtools.front(); m_statusMutex = new QMutex(); } @@ -97,13 +97,8 @@ void TomographyIfaceModel::cleanup() { */ std::string TomographyIfaceModel::validateCompResource(const std::string &res) const { - if (res == m_localCompName) { - // Nothing yet - // throw std::runtime_error("There is no support for the local compute " - // "resource. You should not have got here."); - // all good at the moment - could do basic validation and checks for - // availability of absolutely necessary tools - return "local"; + if (res == g_LocalResourceName) { + return g_LocalResourceName; } if (m_computeRes.size() <= 0) { @@ -200,9 +195,7 @@ void TomographyIfaceModel::setupRunTool(const std::string &compRes) { // catch all the useable/relevant tools for the compute // resources. For the time being this is rather simple (just // SCARF) and will probably stay like this for a while. - std::string low = compRes; - std::transform(low.begin(), low.end(), low.begin(), tolower); - if ("local" == low || + if (g_LocalResourceName == compRes || ("ISIS" == m_facility && (compRes.empty() || g_SCARFName == compRes))) { m_reconTools = m_SCARFtools; } else { @@ -334,7 +327,117 @@ void TomographyIfaceModel::doQueryJobStatus(const std::string &compRes, } /** - * Handle the job submission request relies on a submit algorithm. + * Build the components of the command line to run on the remote or local + * compute resource. Produces a (normally full) path to a runnable, and + * the options (quite like $0 and $* in scripts). + * + * The local and remote command lines look a bit different: + * - local also has the interpreter path at the front: python /scriptPath/ + * --params.. + * - remote only has the script path: /scriptPathOnRemote/ --params.. + * + * @param comp Compute resource for which the command line is being prepared + * @param runnable Path to a runnable application (script, python module, etc.) + * @param opt Command line options to the application + */ +void TomographyIfaceModel::makeRunnableWithOptions( + const std::string &comp, std::string &runnable, + std::vector<std::string> &opt) const { + + if (!m_currentToolSettings) { + throw std::invalid_argument("Settings for tool not set up"); + } + + const std::string tool = usingTool(); + + const std::string cmd = m_currentToolSettings->toCommand(); + + const bool local = (g_LocalResourceName == comp) ? true : false; + + std::string longOpt; + // this gets the runnable from the whole string + splitCmdLine(cmd, runnable, longOpt); + // Special case. Just pass on user inputs. + // this stops from appending all the filters and other options + if (tool == g_customCmdTool) { + opt.resize(1); + // this will pass on all the arguments as a single member + opt[0] = longOpt; + return; + } + + if (local) { + std::string execScriptPath; + + // this variable holds the input paths, but is discarded for now + // until the command line building overhaul + std::string discardedInputPaths; + // this gets the path to the python script tomo_reconstruct.py + splitCmdLine(longOpt, execScriptPath, discardedInputPaths); + + checkIfToolIsSetupProperly(tool, cmd); + opt.emplace_back(execScriptPath); + } + + makeTomoRecScriptOptions(local, opt); +} + +/** + * Build the command line options string in the way the tomorec + * scripts (remote and local) expect it. + * + * @param local whether to adapt the options for a local run (as + * opposed to a remote compute resource) + * @param opts The vector of arguments in which the additional + * arguments will be inserted + * @return command options ready for the tomorec script + */ +void TomographyIfaceModel::makeTomoRecScriptOptions( + const bool local, std::vector<std::string> &opts) const { + // options with all the info from filters and regions + // 9 is the current number of arguments being added + opts.reserve(9); + + const std::string currentTool = usingTool(); + const std::string toolNameArg = prepareToolNameForArgs(currentTool); + + const std::string toolArgument = "--tool=" + toolNameArg; + + opts.emplace_back(toolArgument); + + opts.emplace_back("--algorithm=" + m_currentToolMethod); + + // TODO fix proper iterations reading from the interface + opts.emplace_back("--num-iter=5"); + + filtersCfgToCmdOpts(m_prePostProcSettings, m_imageStackPreParams, local, + opts); +} + +/** Processes the tool name so that it is appropriate for the command line when + * executed + */ +std::string TomographyIfaceModel::prepareToolNameForArgs( + const std::string &toolName) const { + + // the only processing we have for now is converting it to lower case + std::string outputString = toolName; // copy over the string + std::transform(toolName.cbegin(), toolName.cend(), outputString.begin(), + ::tolower); + return outputString; +} + +std::string TomographyIfaceModel::constructSingleStringFromVector( + const std::vector<std::string> args) const { + std::string allOpts; + for (const auto &arg : args) { + allOpts += arg + " "; + } + return allOpts; +} + +/** Handling the job submission request relies on a submit algorithm. + * @param compRes The resource to which the request will be made */ void TomographyIfaceModel::doSubmitReconstructionJob( const std::string &compRes) { @@ -355,6 +458,21 @@ void TomographyIfaceModel::doSubmitReconstructionJob( "(empty string). You need to setup the reconstruction tool."); } + std::string allOpts = constructSingleStringFromVector(args); + + logMsg("Running " + usingTool() + ", with binary: " + run + + ", with parameters: " + allOpts); + + if (g_LocalResourceName == compRes) { + doRunReconstructionJobLocal(run, allOpts, args); + } else { + doRunReconstructionJobRemote(compRes, run, allOpts); + } +} + +void TomographyIfaceModel::doRunReconstructionJobRemote( + const std::string &compRes, const std::string &run, + const std::string &allOpts) { // with SCARF we use one (pseudo)-transaction for every submission auto transAlg = Mantid::API::AlgorithmManager::Instance().createUnmanaged( "StartRemoteTransaction"); @@ -377,10 +495,6 @@ void TomographyIfaceModel::doSubmitReconstructionJob( submitAlg->setProperty("TaskName", "Mantid tomographic reconstruction job"); submitAlg->setProperty("TransactionID", tid); submitAlg->setProperty("ScriptName", run); - std::string allOpts; - for (const auto &option : args) { - allOpts += option + " "; - } submitAlg->setProperty("ScriptParams", allOpts); try { submitAlg->execute(); @@ -391,6 +505,57 @@ void TomographyIfaceModel::doSubmitReconstructionJob( } } +void TomographyIfaceModel::doRunReconstructionJobLocal( + const std::string &run, const std::string &allOpts, + const std::vector<std::string> &args) { + + // initialise to 0, if the launch fails then the id will not be changed + Poco::Process::PID pid = 0; + // Poco::Pipe outPipe; + // Poco::Pipe errPipe; + try { + Poco::ProcessHandle handle = Poco::Process::launch(run, args); + pid = handle.id(); + } catch (Poco::SystemException &sexc) { + g_log.error() << "Execution failed. Could not run the tool. Error details: " + << std::string(sexc.what()); + } + + Mantid::API::IRemoteJobManager::RemoteJobInfo info; + info.id = boost::lexical_cast<std::string>(pid); + info.name = pid > 0 ? "Mantid_Local" : "none"; + info.status = pid > 0 ? "Starting" : "Exit"; + info.cmdLine = run + " " + allOpts; + m_jobsStatusLocal.emplace_back(info); + + doRefreshJobsInfo(g_LocalResourceName); +} + +/** Converts the pipes to strings and prints them into the mantid logger stream +* +* @param outPipe Poco::Pipe that holds the output stream of the process +* @param errPipe Poco::Pipe that holds the error stream of the process +*/ +void TomographyIfaceModel::printProcessStreamsToMantidLog( + const Poco::Pipe &outPipe, const Poco::Pipe &errPipe) { + // if the launch is successful then print output streams + // into the g_log so the user can see the information/error + Poco::PipeInputStream outstr(outPipe); + Poco::PipeInputStream errstr(errPipe); + std::string outString; + std::string errString; + Poco::StreamCopier::copyToString(outstr, outString); + Poco::StreamCopier::copyToString(errstr, errString); + + // print normal output stream if not empty + if (!outString.empty()) + g_log.information(outString); + + // print error output stream if not empty + if (!errString.empty()) + g_log.error(errString); +} + void TomographyIfaceModel::doCancelJobs(const std::string &compRes, const std::vector<std::string> &ids) { for (size_t i = 0; i < ids.size(); i++) { @@ -414,7 +579,7 @@ void TomographyIfaceModel::doCancelJobs(const std::string &compRes, void TomographyIfaceModel::doRefreshJobsInfo(const std::string &compRes) { - if ("Local" == compRes) { + if (g_LocalResourceName == compRes) { refreshLocalJobsInfo(); return; } @@ -537,162 +702,6 @@ bool TomographyIfaceModel::processIsRunning(int pid) { #endif } -void TomographyIfaceModel::doRunReconstructionJobLocal() { - const std::string toolName = usingTool(); - try { - std::string run; - std::vector<std::string> args; - makeRunnableWithOptions("local", run, args); - - std::string allOpts; - for (const auto &option : args) { - allOpts += option + " "; - } - - logMsg("Running " + toolName + ", with binary: " + run + - ", with parameters: " + allOpts); - - // Mantid::Kernel::ConfigService::Instance().launchProcess(run, runArgs); - try { - Poco::ProcessHandle handle = Poco::Process::launch(run, args); - Poco::Process::PID pid = handle.id(); - Mantid::API::IRemoteJobManager::RemoteJobInfo info; - info.id = boost::lexical_cast<std::string>(pid); - info.name = "Mantid_Local"; - if (pid > 0) { - info.status = "Starting"; - } else { - info.status = "Exit"; - } - info.cmdLine = run + " " + allOpts; - m_jobsStatusLocal.emplace_back(info); - } catch (Poco::SystemException &sexc) { - g_log.error() - << "Execution failed. Could not run the tool. Error details: " - << std::string(sexc.what()); - Mantid::API::IRemoteJobManager::RemoteJobInfo info; - info.id = "none"; - info.name = "Mantid_Local"; - info.status = "Exit"; - info.cmdLine = run + " " + allOpts; - m_jobsStatusLocal.emplace_back(info); - } - } catch (std::runtime_error &rexc) { - logMsg("The execution of " + toolName + "failed. details: " + - std::string(rexc.what())); - g_log.error() - << "Execution failed. Coult not execute the tool. Error details: " - << std::string(rexc.what()); - } - - doRefreshJobsInfo("Local"); -} - -/** - * Build the components of the command line to run on the remote or local - * compute resource. Produces a (normally full) path to a runnable, and - * the options (quite like $0 and $* in scripts). - * - * @param comp Compute resource for which the command line is being prepared - * @param run Path to a runnable application (script, python module, etc.) - * @param opt Command line options to the application - */ -void TomographyIfaceModel::makeRunnableWithOptions( - const std::string &comp, std::string &run, - std::vector<std::string> &opt) const { - const std::string tool = usingTool(); - // Special case. Just pass on user inputs. - if (tool == g_customCmdTool) { - const std::string cmd = m_toolsSettings.custom.toCommand(); - - opt.resize(1); - splitCmdLine(cmd, run, opt[0]); - return; - } - - std::string cmd; - bool local = false; - // TODO this is still incomplete, not all tools ready - if ("local" == comp) { - local = true; - cmd = m_systemSettings.m_local.m_reconScriptsPath + - g_mainReconstructionScript; - } else if (tool == g_TomoPyTool) { - cmd = m_toolsSettings.tomoPy.toCommand(); - // this will make something like: - // run = "/work/imat/z-tests-fedemp/scripts/tomopy/imat_recon_FBP.py"; - // opt = "--input_dir " + base + currentPathFITS() + " " + "--dark " + - // base + - // currentPathDark() + " " + "--white " + base + currentPathFlat(); - } else if (tool == g_AstraTool) { - cmd = m_toolsSettings.astra.toCommand(); - // this will produce something like this: - // run = "/work/imat/scripts/astra/astra-3d-SIRT3D.py"; - // opt = base + currentPathFITS(); - } else { - throw std::runtime_error( - "Unable to use this tool. " - "I do not know how to submit jobs to use this tool: " + - tool + ". It seems that this interface is " - "misconfigured or there has been an unexpected " - "failure."); - } - - std::string longOpt; - splitCmdLine(cmd, run, longOpt); - checkWarningToolNotSetup(tool, cmd); - - if (local) { - run = m_systemSettings.m_local.m_externalInterpreterPath; - } else { - // intentionally not using local style paths, as this goes to a server with - // unix file system - run = m_systemSettings.m_remote.m_basePathReconScripts + - g_mainReconstructionScript; - } - opt = makeTomoRecScriptOptions(local); -} - -/** - * Build the command line options string in the way the tomorec - * scripts (remote and local) expect it. - * - * @param local whether to adapt the options for a local run (as - * opposed to a remote compute resource) - * - * @return command options ready for the tomorec script - */ -std::vector<std::string> -TomographyIfaceModel::makeTomoRecScriptOptions(bool local) const { - - // options with all the info from filters and regions - std::vector<std::string> opts; - - if (local) { - Poco::Path base(m_systemSettings.m_local.m_reconScriptsPath); - base.append(g_mainReconstructionScript); - opts.emplace_back(base.toString()); - } - - const std::string toolName = usingTool(); - if (g_TomoPyTool == toolName) { - opts.emplace_back("--tool=tomopy"); - opts.emplace_back("--algorithm=" + m_tomopyMethod); - } else if (g_AstraTool == toolName) { - opts.emplace_back("--tool=astra"); - opts.emplace_back("--algorithm=" + m_astraMethod); - } - - if (g_TomoPyTool != toolName || m_tomopyMethod != "gridred" || - m_tomopyMethod != "fbp") - opts.emplace_back("--num-iter=5"); - - filtersCfgToCmdOpts(m_prePostProcSettings, m_imageStackPreParams, local, - opts); - - return opts; -} - /** * This can produce a tool-specific warning that can be shown for * different tools when they are not fully setup (any required @@ -701,7 +710,7 @@ TomographyIfaceModel::makeTomoRecScriptOptions(bool local) const { * @param tool Name of the tool this warning applies to * @param cmd command/script/executable derived from the settings */ -void TomographyIfaceModel::checkWarningToolNotSetup( +bool TomographyIfaceModel::checkIfToolIsSetupProperly( const std::string &tool, const std::string &cmd) const { if (tool.empty() || cmd.empty()) { const std::string detail = @@ -714,6 +723,7 @@ void TomographyIfaceModel::checkWarningToolNotSetup( throw std::runtime_error("Cannot run the tool " + tool + " without setting it up." + detail); } + return true; } /** @@ -726,7 +736,7 @@ void TomographyIfaceModel::splitCmdLine(const std::string &cmd, if (cmd.empty()) return; - const auto pos = cmd.find(' '); + const auto pos = cmd.find(" "); if (std::string::npos == pos) return; @@ -835,16 +845,13 @@ std::string boxCoordinatesToCSV(const ImageStackPreParams::Box2D &coords) { */ void TomographyIfaceModel::filtersCfgToCmdOpts( const TomoReconFiltersSettings &filters, - const ImageStackPreParams &corRegions, bool local, + const ImageStackPreParams &corRegions, const bool local, std::vector<std::string> &opts) const { opts.emplace_back("--input-path=" + adaptInputPathForExecution( m_pathsConfig.pathSamples(), local)); - std::string alg = "alg"; - if (g_TomoPyTool == usingTool()) - alg = m_tomopyMethod; - else if (g_AstraTool == usingTool()) - alg = m_astraMethod; + + const std::string alg = getCurrentToolMethod(); // check the general enable option and the dataset specific enable if (filters.prep.normalizeByFlats && m_pathsConfig.m_pathOpenBeamEnabled) { @@ -863,6 +870,8 @@ void TomographyIfaceModel::filtersCfgToCmdOpts( std::string openList; std::string closeList; + // TODOMODL how to handle this? we still need to know what the resource is, + // because local is windows and remote is linux if (local) { openList = "["; closeList = "]"; @@ -895,7 +904,7 @@ void TomographyIfaceModel::filtersCfgToCmdOpts( // one name for this particular reconstruction, like: // out_reconstruction_TomoPy_gridrec_ const std::string reconName = - "reconstruction_" + m_currentTool + "_" + alg + "_" + timeAppendix; + "reconstruction_" + m_currentToolName + "_" + alg + "_" + timeAppendix; const std::string outOpt = outBase + "/" + reconName; @@ -959,7 +968,7 @@ void TomographyIfaceModel::filtersCfgToCmdOpts( */ std::string TomographyIfaceModel::adaptInputPathForExecution(const std::string &path, - bool local) const { + const bool local) const { if (local) return path; @@ -983,10 +992,6 @@ TomographyIfaceModel::adaptInputPathForExecution(const std::string &path, else result = result.substr(2); } - - // this appends the base path for the instrument data space on the - // remote (like '/work/imat' or similar) - result = m_systemSettings.m_remote.m_basePathTomoData + result; } return result; diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfacePresenter.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfacePresenter.cpp index e4988b9f90cc4de8b511a34232e417c732337853..3952b276cc2f7b9d45ec427618826f34558e1e3b 100644 --- a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfacePresenter.cpp +++ b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfacePresenter.cpp @@ -1,3 +1,4 @@ +#include "MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h" #include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/TableRow.h" @@ -6,7 +7,6 @@ #include "MantidKernel/FacilityInfo.h" #include "MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h" #include "MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h" -#include "MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h" #include <boost/lexical_cast.hpp> @@ -19,12 +19,28 @@ #include <QThread> #include <QTimer> +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h" + using namespace Mantid::API; using namespace MantidQt::CustomInterfaces; namespace MantidQt { namespace CustomInterfaces { +const std::string TomographyIfacePresenter::g_defOutPathLocal = +#ifdef _WIN32 + "D:/imat-data/"; +#else + "~/imat/"; +#endif + +const std::string TomographyIfacePresenter::g_defOutPathRemote = +#ifdef _WIN32 + "I:/imat/imat-data/"; +#else + "~/imat-data/"; +#endif + TomographyIfacePresenter::TomographyIfacePresenter(ITomographyIfaceView *view) : m_view(view), m_model(new TomographyIfaceModel()), m_statusMutex(NULL), m_keepAliveTimer(NULL), m_keepAliveThread(NULL) { @@ -134,7 +150,10 @@ void TomographyIfacePresenter::notify( } void TomographyIfacePresenter::processSystemSettingsUpdated() { - m_model->updateSystemSettings(m_view->systemSettings()); + m_model->setSystemSettings(m_view->systemSettings()); + + // update the tool information with the new system settings + setupConfigDialogSettingsAndUpdateModel(m_configDialog.get()); } void TomographyIfacePresenter::processSetupResourcesAndTools() { @@ -177,43 +196,187 @@ void TomographyIfacePresenter::processSetupResourcesAndTools() { void TomographyIfacePresenter::processCompResourceChanged() { const std::string comp = m_view->currentComputeResource(); + // TODOPRES find a better way to set up the run tool in model m_model->setupRunTool(comp); - if ("Local" == comp) { + if (isLocalResourceSelected()) { m_view->enableLoggedActions(true); } else { const bool status = !m_model->loggedIn().empty(); m_view->enableLoggedActions(status); } + + // this will udpate the tool after a resource change + setupConfigDialogSettingsAndUpdateModel(m_configDialog.get()); } +/** Called when the event ToolChanged fires. It gets the name for the current + * tabToolTip and first tries to create it (if valid tool name), and if that + * succeeds then updates the tool's settings to hold the current path and + * afterwards updates the model's information about the tool's current settings + */ void TomographyIfacePresenter::processToolChanged() { - const std::string tool = m_view->currentReconTool(); + const std::string toolName = m_view->currentReconTool(); // disallow reconstruct on tools that don't run yet: Savu and CCPi - if (TomographyIfaceModel::g_CCPiTool == tool) { + if (TomographyIfaceModel::g_CCPiTool == toolName) { m_view->enableRunReconstruct(false); m_view->enableConfigTool(false); - } else if (TomographyIfaceModel::g_SavuTool == tool) { + } else if (TomographyIfaceModel::g_SavuTool == toolName) { // for now, show setup dialog, but cannot run m_view->enableRunReconstruct(false); m_view->enableConfigTool(true); } else { // No need to be logged in anymore when local is selected - const bool runningLocally = "Local" == m_view->currentComputeResource(); + const bool runningLocally = isLocalResourceSelected(); m_view->enableRunReconstruct(runningLocally || !(m_model->loggedIn().empty())); m_view->enableConfigTool(true); } - m_model->usingTool(tool); + // return if empty string + if ("" == toolName) { + return; + } + + createConfigDialogUsingToolName(toolName); + // this will set the default settings for the dialog + setupConfigDialogSettingsAndUpdateModel(m_configDialog.get()); +} + +void TomographyIfacePresenter::setupConfigDialogSettingsAndUpdateModel( + TomoToolConfigDialogBase *dialog) { + + // this check prevents a crash on initialisation where Qt passes a tool name + // of "" and then we have a nullptr dialogue + if (dialog) { + setupConfigDialogSettings(*dialog); + updateModelAfterToolChanged(*dialog); + } +} + +/** Uses the static method in TomoToolConfigDialogBase to create the proper tool + * from the provided name + * @param toolName The string holding the tool's name + */ +void TomographyIfacePresenter::createConfigDialogUsingToolName( + const std::string &toolName) { + // free the previous dialogue pointer if any + m_configDialog.reset(); + m_configDialog = TomoToolConfigDialogBase::getToolDialogFor(toolName); +} + +/** Depending on whether local or remote resource is selected, do setup +* the tool's run path, the paths out, the reconstruction index and +* the localOutNameAppendix +* +* @param dialog The dialog pointer that will be set up +*/ +void TomographyIfacePresenter::setupConfigDialogSettings( + TomoToolConfigDialogBase &dialog) { + + if (isLocalResourceSelected()) { + setupConfigDialogSettingsForLocal(dialog); + } else { + setupConfigDialogSettingsForRemote(dialog); + } +} + +/** Configures the dialog settings for local reconstruction, this means settings + * the run command, the pathOut and the name of the output folder + * + * @param dialog The raw dialog pointer that will be configured. + */ +void TomographyIfacePresenter::setupConfigDialogSettingsForLocal( + TomoToolConfigDialogBase &dialog) { + const std::string run = m_model->getExeternalInterpreterPath() + " " + + m_model->getCurrentLocalScriptsBasePath() + + m_model->getTomoScriptLocationPath(); + + const TomoPathsConfig paths = m_view->currentPathsConfig(); + + const std::string pathOut = Poco::Path::expand( + g_defOutPathLocal + "/" + m_model->getCurrentExperimentReference()); + static size_t reconIdx = 1; + const std::string localOutNameAppendix = + std::string("/processed/") + "reconstruction_" + std::to_string(reconIdx); + + dialog.setupDialog(run, paths, pathOut, localOutNameAppendix); +} + +/** Configures the dialog settings for remote reconstruction, this means + * settings + * the run command, the pathOut and the name of the output folder + * + * Currently it does NOT take into account the remote, this is + * something that might be needed in the future if more remote reconstruction + * locations are added, as currently the only one is SCARF + * + * @param dialog The raw dialog pointer that will be configured. + */ +void TomographyIfacePresenter::setupConfigDialogSettingsForRemote( + TomoToolConfigDialogBase &dialog) { + // set up all the information we need for the dialog + const std::string run = m_model->getCurrentRemoteScriptsBasePath() + + m_model->getTomoScriptFolderPath() + + m_model->getTomoScriptLocationPath(); + + const TomoPathsConfig paths = m_view->currentPathsConfig(); + const std::string pathOut = Poco::Path::expand( + g_defOutPathLocal + "/" + m_model->getCurrentExperimentReference()); + static size_t reconIdx = 1; + const std::string localOutNameAppendix = + std::string("/processed/") + "reconstruction_" + std::to_string(reconIdx); + + dialog.setupDialog(run, paths, pathOut, localOutNameAppendix); +} + +/** Updated the model's information about the current tool + * The settings that are updated are: + * - the current tool name + * - the current tool method + * - the current tool settings + * + * @param dialog The raw dialog pointer that will be configured. + */ +void TomographyIfacePresenter::updateModelAfterToolChanged( + const TomoToolConfigDialogBase &dialog) { + + // if passed an empty string don't remove the name + updateModelCurrentToolName(dialog); + updateModelCurrentToolMethod(dialog); + updateModelCurrentToolSettings(dialog); +} + +/** Sets the model's current tool name by getting the tool name from the +* dialogue itself +*/ +void TomographyIfacePresenter::updateModelCurrentToolName( + const TomoToolConfigDialogBase &dialog) { + m_model->usingTool(dialog.getSelectedToolName()); +} +/** Sets the model's current tool method by coyping the +* string over to the model, getting it from the dialogue itself +*/ +void TomographyIfacePresenter::updateModelCurrentToolMethod( + const TomoToolConfigDialogBase &dialog) { + m_model->setCurrentToolMethod(dialog.getSelectedToolMethod()); +} + +/** Shares the pointer with the model's tool settings. We don't want a +* unique_ptr, because the dialogs don't die after they are closed, they die if +* the tool is changed or the whole interface is closed +*/ +void TomographyIfacePresenter::updateModelCurrentToolSettings( + const TomoToolConfigDialogBase &dialog) { + m_model->setCurrentToolSettings(dialog.getSelectedToolSettings()); } /** * Simply take the paths that the user has provided. */ void TomographyIfacePresenter::processTomoPathsChanged() { - m_model->updateTomoPathsConfig(m_view->currentPathsConfig()); + m_model->setTomoPathsConfig(m_view->currentPathsConfig()); } /** @@ -239,7 +402,7 @@ void TomographyIfacePresenter::processTomoPathsEditedByUser() { m_model->logMsg(msg); } - m_model->updateTomoPathsConfig(cfg); + m_model->setTomoPathsConfig(cfg); m_view->updatePathsConfig(cfg); } @@ -292,7 +455,7 @@ void TomographyIfacePresenter::processLogin() { std::string compRes = m_view->currentComputeResource(); // if local is selected, just take the first remote resource - if ("Local" == compRes) { + if (isLocalResourceSelected()) { compRes = "SCARF@STFC"; } try { @@ -349,7 +512,7 @@ void TomographyIfacePresenter::processLogout() { try { std::string compRes = m_view->currentComputeResource(); // if local is selected, just take the first remote resource - if ("Local" == compRes) { + if (isLocalResourceSelected()) { compRes = "SCARF@STFC"; } m_model->doLogout(compRes, m_view->getUsername()); @@ -362,19 +525,21 @@ void TomographyIfacePresenter::processLogout() { } void TomographyIfacePresenter::processSetupReconTool() { - if (TomographyIfaceModel::g_CCPiTool != m_view->currentReconTool()) { - m_view->showToolConfig(m_view->currentReconTool()); - m_model->updateReconToolsSettings(m_view->reconToolsSettings()); - - // TODO: this would make sense if the reconstruct action/button - // was only enabled after setting up at least one tool - // m_view->enableToolsSetupsActions(true); + const std::string ¤tReconTool = m_view->currentReconTool(); + + // this check prevents a crash on initialisation where Qt passes a tool name + // of "" and then we have a nullptr dialogue + auto dialog = m_configDialog.get(); + if (dialog) { + if (TomographyIfaceModel::g_CCPiTool != currentReconTool) { + // give pointer to showToolConfig, so it can run the dialogue + m_view->showToolConfig(*dialog); + updateModelAfterToolChanged(*dialog); + } } } void TomographyIfacePresenter::processRunRecon() { - // m_model->checkDataPathsSet(); - // TODO: validate data path with additional rules/constraints? TomoPathsConfig paths = m_view->currentPathsConfig(); if (paths.pathSamples().empty()) { m_view->userWarning("Sample images path not set!", @@ -385,38 +550,20 @@ void TomographyIfacePresenter::processRunRecon() { } // pre-/post processing steps and filters - m_model->updatePrePostProcSettings(m_view->prePostProcSettings()); + m_model->setPrePostProcSettings(m_view->prePostProcSettings()); // center of rotation and regions - m_model->updateImageStackPreParams(m_view->currentROIEtcParams()); - m_model->updateTomopyMethod(m_view->tomopyMethod()); - m_model->updateAstraMethod(m_view->astraMethod()); - const std::string &resource = m_view->currentComputeResource(); - if (m_model->localComputeResource() == resource) { - subprocessRunReconLocal(); - } else { - subprocessRunReconRemote(); - } - - processRefreshJobs(); -} - -void TomographyIfacePresenter::subprocessRunReconRemote() { - if (m_model->loggedIn().empty()) { - m_view->updateJobsInfoDisplay(m_model->jobsStatus(), - m_model->jobsStatusLocal()); - return; - } + m_model->setImageStackPreParams(m_view->currentROIEtcParams()); try { - m_model->doSubmitReconstructionJob(m_view->currentComputeResource()); } catch (std::exception &e) { m_view->userWarning("Issue when trying to start a job", e.what()); } + processRefreshJobs(); } -void TomographyIfacePresenter::subprocessRunReconLocal() { - m_model->doRunReconstructionJobLocal(); +bool TomographyIfacePresenter::isLocalResourceSelected() const { + return m_model->localComputeResource() == m_view->currentComputeResource(); } void TomographyIfacePresenter::processRefreshJobs() { @@ -428,8 +575,11 @@ void TomographyIfacePresenter::processRefreshJobs() { return; } + // TODOPRES is this necessary? if we're logged in, we will never refresh the + // jobs for 'Local', also will need to be removed if more remote resources are + // added std::string comp = m_view->currentComputeResource(); - if ("Local" == comp) { + if (isLocalResourceSelected()) { comp = "SCARF@STFC"; } m_model->doRefreshJobsInfo(comp); @@ -448,7 +598,7 @@ void TomographyIfacePresenter::processCancelJobs() { return; const std::string &resource = m_view->currentComputeResource(); - if (m_model->localComputeResource() != resource) { + if (!isLocalResourceSelected()) { m_model->doCancelJobs(resource, m_view->processingJobsIDs()); } } @@ -460,7 +610,10 @@ void TomographyIfacePresenter::processVisualizeJobs() { void TomographyIfacePresenter::doVisualize( const std::vector<std::string> &ids) { m_model->logMsg(" Visualizing results from job: " + ids.front()); - // TODO: open dialog, send to Paraview, etc. + m_view->userWarning("Visualizing not implemented", "Visualizing of the data " + "has not been implemented " + "yet and is unsupported"); + // TODOPRES: open dialog, send to Paraview, etc. } void TomographyIfacePresenter::processLogMsg() { diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp index 7947ea1b8c8001e5172ff8e751fc3bb8637e68a0..282736e9ab3d5c2766951136425302c5d2a8cc37 100644 --- a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp +++ b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp @@ -1,17 +1,18 @@ #include "MantidAPI/AlgorithmManager.h" -#include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/Run.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidQtAPI/AlgorithmInputHistory.h" #include "MantidQtAPI/HelpWindow.h" -#include "MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h" +#include "MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h" #include "MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h" +#include "MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h" #include "MantidQtCustomInterfaces/Tomography/ToolConfigAstraToolbox.h" #include "MantidQtCustomInterfaces/Tomography/ToolConfigCustom.h" -#include "MantidQtCustomInterfaces/Tomography/ToolConfigTomoPy.h" -#include "MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h" + +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h" using namespace Mantid::API; using namespace MantidQt::CustomInterfaces; @@ -62,8 +63,6 @@ const std::string TomographyIfaceViewQtGUI::g_styleSheetOnline = "QPushButton:pressed { background-color: rgb(120, 255, 120); " "}"; -size_t TomographyIfaceViewQtGUI::g_nameSeqNo = 0; - // For paths where Python third party tools are installed, if they're // not included in the system python path. For example you could have // put the AstraToolbox package in @@ -74,9 +73,6 @@ size_t TomographyIfaceViewQtGUI::g_nameSeqNo = 0; // c:/local/Anaconda/Lib/site-packages/ std::vector<std::string> TomographyIfaceViewQtGUI::g_defAddPathPython; -const std::string TomographyIfaceViewQtGUI::g_defRemotePathScripts = - "/work/imat/phase_commissioning"; - const std::string TomographyIfaceViewQtGUI::g_SCARFName = "SCARF@STFC"; const std::string TomographyIfaceViewQtGUI::g_defOutPathLocal = #ifdef _WIN32 @@ -85,7 +81,7 @@ const std::string TomographyIfaceViewQtGUI::g_defOutPathLocal = "~/imat/"; #endif -// TODO: could use ConfigService::isNetworkDrive(const std::string &) +// TODOVIEW: could use ConfigService::isNetworkDrive(const std::string &) const std::string TomographyIfaceViewQtGUI::g_defOutPathRemote = #ifdef _WIN32 "I:/imat/imat-data/"; @@ -125,13 +121,6 @@ const std::string TomographyIfaceViewQtGUI::g_defOctopusAppendPath = const std::string TomographyIfaceViewQtGUI::g_defProcessedSubpath = "processed"; -// names by which we know image/tomography reconstruction tools (3rd party) -const std::string TomographyIfaceViewQtGUI::g_TomoPyTool = "TomoPy"; -const std::string TomographyIfaceViewQtGUI::g_AstraTool = "Astra"; -const std::string TomographyIfaceViewQtGUI::g_CCPiTool = "CCPi CGLS"; -const std::string TomographyIfaceViewQtGUI::g_SavuTool = "Savu"; -const std::string TomographyIfaceViewQtGUI::g_customCmdTool = "Custom command"; - // phase or cycle component, like: phase_commissioning, cycle_15_4, cycle_16_1 const std::string TomographyIfaceViewQtGUI::g_defPathComponentPhase = "phase_commissioning"; @@ -165,24 +154,12 @@ DECLARE_SUBWINDOW(TomographyIfaceViewQtGUI) TomographyIfaceViewQtGUI::TomographyIfaceViewQtGUI(QWidget *parent) : UserSubWindow(parent), ITomographyIfaceView(), m_tabROIW(nullptr), m_tabImggFormats(nullptr), m_processingJobsIDs(), m_currentComputeRes(""), - m_currentReconTool(""), m_imgPath(""), m_logMsgs(), m_systemSettings(), - m_toolsSettings(), m_settings(), + m_currentReconTool("TomoPy"), m_imgPath(""), m_logMsgs(), + m_systemSettings(), m_settings(), m_settingsGroup("CustomInterfaces/Tomography"), m_settingsSubGroupEnergy(m_settingsGroup + "/EnergyBands"), m_aggAlgRunner(), m_availPlugins(), m_currPlugins(), m_currentParamPath(), - m_presenter(nullptr) { - - // defaults from the tools - m_tomopyMethod = ToolConfigTomoPy::methods().front().first; - m_astraMethod = ToolConfigAstraToolbox::methods().front().first; - - // TODO: find a better place for this Savu stuff when the tool is - // ready - see other TODOs - m_availPlugins = Mantid::API::WorkspaceFactory::Instance().createTable(); - m_availPlugins->addColumns("str", "name", 4); - m_currPlugins = Mantid::API::WorkspaceFactory::Instance().createTable(); - m_currPlugins->addColumns("str", "name", 4); -} + m_presenter(nullptr) {} TomographyIfaceViewQtGUI::~TomographyIfaceViewQtGUI() {} @@ -245,11 +222,6 @@ void TomographyIfaceViewQtGUI::initLayout() { } void TomographyIfaceViewQtGUI::doSetupGeneralWidgets() { - // Menu Items - connect(m_ui.actionOpen, SIGNAL(triggered()), this, SLOT(menuOpenClicked())); - connect(m_ui.actionSave, SIGNAL(triggered()), this, SLOT(menuSaveClicked())); - connect(m_ui.actionSaveAs, SIGNAL(triggered()), this, - SLOT(menuSaveAsClicked())); connect(m_ui.pushButton_help, SIGNAL(released()), this, SLOT(openHelpWin())); // note connection to the parent window, otherwise you'd be left @@ -374,7 +346,7 @@ void TomographyIfaceViewQtGUI::doSetupSectionFilters() { } void TomographyIfaceViewQtGUI::doSetupSectionVisualize() { - // TODO: take g_def values first time, when Qsettings are empty, then from + // TODOVIEW: take g_def values first time, when Qsettings are empty, then from // QSettings m_setupParaviewPath = g_defParaviewPath; m_setupProcessedSubpath = g_defProcessedSubpath; @@ -525,39 +497,6 @@ void TomographyIfaceViewQtGUI::setComputeResources( } } -// This is here while savu becomes available and we find a better place for savu -// stuff -void TomographyIfaceViewQtGUI::doSetupSavu() { - // geometry, etc. niceties - // on the left (just plugin names) 1/2, right: 2/3 - QList<int> sizes; - sizes.push_back(100); - sizes.push_back(200); - m_uiSavu.splitterPlugins->setSizes(sizes); - - // Setup Parameter editor tab - loadAvailablePlugins(); - m_uiSavu.treeCurrentPlugins->setHeaderHidden(true); - - // Connect slots - - // Lists/trees - connect(m_uiSavu.listAvailablePlugins, SIGNAL(itemSelectionChanged()), this, - SLOT(availablePluginSelected())); - connect(m_uiSavu.treeCurrentPlugins, SIGNAL(itemSelectionChanged()), this, - SLOT(currentPluginSelected())); - connect(m_uiSavu.treeCurrentPlugins, SIGNAL(itemExpanded(QTreeWidgetItem *)), - this, SLOT(expandedItem(QTreeWidgetItem *))); - - // Buttons - connect(m_uiSavu.btnTransfer, SIGNAL(released()), this, - SLOT(transferClicked())); - connect(m_uiSavu.btnMoveUp, SIGNAL(released()), this, SLOT(moveUpClicked())); - connect(m_uiSavu.btnMoveDown, SIGNAL(released()), this, - SLOT(moveDownClicked())); - connect(m_uiSavu.btnRemove, SIGNAL(released()), this, SLOT(removeClicked())); -} - void TomographyIfaceViewQtGUI::setReconstructionTools( const std::vector<std::string> &tools, const std::vector<bool> &enabled) { @@ -586,7 +525,7 @@ void TomographyIfaceViewQtGUI::setReconstructionTools( * cancel job, etc. */ void TomographyIfaceViewQtGUI::enableLoggedActions(bool enable) { - // TODO: this may not make sense anymore when/if the "Local" compute + // TODOVIEW: this may not make sense anymore when/if the "Local" compute // resource is used in the future (except when none of the tools // supported are available/detected on "Local") std::vector<QPushButton *> buttons; @@ -771,9 +710,9 @@ void TomographyIfaceViewQtGUI::readSettings() { TomoSystemSettings sysSettings; streamSys >> sysSettings; if (QDataStream::Ok == streamSys.status()) { - updateSystemSettings(sysSettings); + updateSystemSettingsTabFields(sysSettings); } else { - updateSystemSettings(TomoSystemSettings()); + updateSystemSettingsTabFields(TomoSystemSettings()); } // Get input paths (sample/dark/flats) @@ -970,65 +909,18 @@ void TomographyIfaceViewQtGUI::saveSettings() const { qs.endGroup(); } -/** - * Load a savu tomo config file into the current plugin list, overwriting it. - * Uses the algorithm LoadSavuTomoConfig - */ -void TomographyIfaceViewQtGUI::loadSavuTomoConfig( - std::string &filePath, Mantid::API::ITableWorkspace_sptr ¤tPlugins) { - // try to load tomo reconstruction parametereization file - auto alg = Mantid::API::AlgorithmManager::Instance().createUnmanaged( - "LoadSavuTomoConfig"); - alg->initialize(); - alg->setPropertyValue("Filename", filePath); - alg->setPropertyValue("OutputWorkspace", createUniqueNameHidden()); - try { - alg->execute(); - } catch (std::runtime_error &e) { - throw std::runtime_error( - std::string("Error when trying to load tomographic reconstruction " - "parameter file: ") + - e.what()); - } - - // new processing plugins list - try { - currentPlugins = alg->getProperty("OutputWorkspace"); - } catch (std::exception &e) { - userError("Could not load config file", "Failed to load the file " - "with the following error: " + - std::string(e.what())); - } -} - -// Build a unique (and hidden) name for the table ws -std::string TomographyIfaceViewQtGUI::createUniqueNameHidden() { - std::string name; - do { - // with __ prefix => hidden - name = "__TomoConfigTableWS_Seq_" + - boost::lexical_cast<std::string>(g_nameSeqNo++); - } while (AnalysisDataService::Instance().doesExist(name)); - - return name; -} - /// needs to at least update the 'tool' combo box void TomographyIfaceViewQtGUI::compResourceIndexChanged(int /* i */) { QComboBox *rt = m_uiTabRun.comboBox_run_compute_resource; if (!rt) return; - // TODO validateCompResource(rt->currentText().toStdString()); m_currentComputeRes = rt->currentText().toStdString(); m_presenter->notify(ITomographyIfacePresenter::CompResourceChanged); } void TomographyIfaceViewQtGUI::runToolIndexChanged(int /* i */) { QComboBox *rt = m_uiTabRun.comboBox_run_tool; - if (!rt) - return; - m_currentReconTool = rt->currentText().toStdString(); m_presenter->notify(ITomographyIfacePresenter::ToolChanged); } @@ -1101,7 +993,7 @@ void TomographyIfaceViewQtGUI::updatePathsConfig(const TomoPathsConfig &cfg) { * Updates the view/forms with new system settings (local and remote, * including multiple paths and path components) */ -void TomographyIfaceViewQtGUI::updateSystemSettings( +void TomographyIfaceViewQtGUI::updateSystemSettingsTabFields( const TomoSystemSettings &setts) { // paths and related m_uiTabSystemSettings.lineEdit_path_comp_1st->setText( @@ -1152,95 +1044,13 @@ void TomographyIfaceViewQtGUI::updateSystemSettings( /** * Displays and gets the results of a tool specific configuration dialog. * - * @param name Name of the (tomographic reconstruction) tool + * @param dialog The pointer to the current dialog */ -void TomographyIfaceViewQtGUI::showToolConfig(const std::string &name) { - QString run = "/work/imat/phase_commissioning/scripts/Imaging/IMAT/" - "tomo_reconstruct.py"; // m_uiAstra.lineEdit_runnable->text(); - static size_t reconIdx = 1; - - const std::string localOutNameAppendix = - std::string("/processed/") + "reconstruction_" + std::to_string(reconIdx); - - if (g_TomoPyTool == name) { - TomoToolConfigTomoPy tomopy; - m_uiTomoPy.setupUi(&tomopy); - m_uiTomoPy.comboBox_method->clear(); - const auto methods = ToolConfigTomoPy::methods(); - for (size_t i = 0; i < methods.size(); i++) { - m_uiTomoPy.comboBox_method->addItem( - QString::fromStdString(methods[i].second)); - } - int res = tomopy.exec(); - - if (QDialog::Accepted == res) { - // TODO: move this - int mi = m_uiTomoPy.comboBox_method->currentIndex(); - - TomoPathsConfig paths = currentPathsConfig(); - // TODO: for the output path, probably better to take the sample path, - // then up one level - m_toolsSettings.tomoPy = ToolConfigTomoPy( - run.toStdString(), - g_defOutPathLocal + "/" + - m_uiTabRun.lineEdit_experiment_reference->text().toStdString() + - localOutNameAppendix, - paths.pathDarks(), paths.pathOpenBeam(), paths.pathSamples()); - m_tomopyMethod = methods[mi].first; - } - } else if (g_AstraTool == name) { - TomoToolConfigAstra astra; - m_uiAstra.setupUi(&astra); - m_uiAstra.comboBox_method->clear(); - const auto methods = ToolConfigAstraToolbox::methods(); - for (size_t i = 0; i < methods.size(); i++) { - m_uiAstra.comboBox_method->addItem( - QString::fromStdString(methods[i].second)); - } - int res = astra.exec(); - - if (QDialog::Accepted == res) { - // TODO: move this - int mi = m_uiAstra.comboBox_method->currentIndex(); - - TomoPathsConfig paths = currentPathsConfig(); - // TODO: for the output path, probably better to take the sample path, - // then up one level - m_toolsSettings.astra = ToolConfigAstraToolbox( - run.toStdString(), - Poco::Path::expand( - g_defOutPathLocal + "/" + - m_uiTabRun.lineEdit_experiment_reference->text().toStdString() + - localOutNameAppendix), - paths.pathDarks(), paths.pathOpenBeam(), paths.pathSamples()); - m_astraMethod = methods[mi].first; - } - } else if (g_SavuTool == name) { - // TODO: savu not ready. This is a temporary kludge, it just shows - // the setup dialog so we can chat about it. - TomoToolConfigSavu savu; - m_uiSavu.setupUi(&savu); - doSetupSavu(); - savu.setWindowModality(Qt::ApplicationModal); - savu.show(); - QEventLoop el; - connect(this, SIGNAL(destroyed()), &el, SLOT(quit())); - el.exec(); - } else if (g_customCmdTool == name) { - TomoToolConfigCustom cmd; - m_uiCustom.setupUi(&cmd); - int res = cmd.exec(); - - if (QDialog::Accepted == res) { - // TODO: move this - QString run = m_uiCustom.lineEdit_runnable->text(); - QString opts = m_uiCustom.textEdit_cl_opts->toPlainText(); - - m_toolsSettings.custom = - ToolConfigCustom(run.toStdString(), opts.toStdString()); - } - } - // TODO: 'CCPi CGLS' tool maybe in the future. Tool not ready. +void TomographyIfaceViewQtGUI::showToolConfig( + TomoToolConfigDialogBase &dialog) { + + // execute also intiialises all the parts of the GUI + dialog.initialiseGUIandExecute(); } /** @@ -1447,7 +1257,7 @@ std::string TomographyIfaceViewQtGUI::getPassword() const { void TomographyIfaceViewQtGUI::flatsPathCheckStatusChanged(int status) { bool enable = 0 != status; // Alternative behavior, whereby disabling would also imply clearing: - // TODO: not totally clear at the moment what users will prefer + // TODOVIEW: not totally clear at the moment what users will prefer // if (!enable) { // m_pathsConfig.updatePathOpenBeam(""); // } else { @@ -1465,7 +1275,7 @@ void TomographyIfaceViewQtGUI::flatsPathCheckStatusChanged(int status) { void TomographyIfaceViewQtGUI::darksPathCheckStatusChanged(int status) { bool enable = 0 != status; // Alternative behavior, whereby disabling would also imply clearing: - // TODO: not totally clear at the moment what users will prefer + // TODOVIEW: not totally clear at the moment what users will prefer // if (!enable) { // m_pathsConfig.updatePathDarks(""); // } else { @@ -1607,7 +1417,7 @@ void TomographyIfaceViewQtGUI::showImage(const MatrixWorkspace_sptr &ws) { size_t width; try { width = boost::lexical_cast<size_t>(ws->run().getLogData("Axis1")->value()); - // TODO: add a settings option for this (like max mem allocation for + // TODOVIEW: add a settings option for this (like max mem allocation for // images)? if (width >= MAXDIM) width = MAXDIM; @@ -1715,7 +1525,7 @@ TomographyIfaceViewQtGUI::grabPrePostProcSettings() const { opts.prep.normalizeByAirRegion = m_uiTabFilters.checkBox_normalize_by_air_region->isChecked(); - // TODO + // TODOVIEW // m_uiTabFilters.checkBox_normalize_by_proton_charge is disabled for now opts.prep.normalizeByProtonCharge = false; @@ -1725,7 +1535,7 @@ TomographyIfaceViewQtGUI::grabPrePostProcSettings() const { opts.prep.normalizeByDarks = m_uiTabFilters.checkBox_normalize_by_darks->isChecked(); - // TODO + // TODOVIEW // m_uiTabFilters.checkBox_corrections_MCP_detector is disabled for now opts.prep.medianFilterWidth = static_cast<size_t>( @@ -1847,6 +1657,8 @@ TomographyIfaceViewQtGUI::grabSystemSettingsFromUser() const { setts.m_local.m_reconScriptsPath = m_uiTabSystemSettings.lineEdit_local_recon_scripts->text().toStdString(); + setts.m_experimentReference = + m_uiTabRun.lineEdit_experiment_reference->text().toStdString(); return setts; } @@ -1860,7 +1672,7 @@ void TomographyIfaceViewQtGUI::sendToParaviewClicked() { } /** - * Start a third party tool as a process. TODO: This is a very early + * Start a third party tool as a process. TODOVIEW: This is a very early * experimental implementation that should be moved out of this view. * * @param toolName Human understandable name of the tool/program @@ -1955,7 +1767,7 @@ void TomographyIfaceViewQtGUI::defaultDirLocalVisualizeClicked() { if (!model) return; - // TODO: this should be moved to presenter? + // TODOVIEW: this should be moved to presenter? std::string checkedPath = checkDefaultVisualizeDir( m_uiTabSystemSettings.lineEdit_on_local_data_drive_or_path->text() .toStdString(), @@ -1973,7 +1785,7 @@ void TomographyIfaceViewQtGUI::defaultDirRemoteVisualizeClicked() { if (!model) return; - // TODO: this should be moved to presenter? + // TODOVIEW: this should be moved to presenter? std::string checkedPath = checkDefaultVisualizeDir( m_uiTabSystemSettings.lineEdit_on_local_remote_data_drive_path->text() .toStdString(), @@ -2107,7 +1919,7 @@ void TomographyIfaceViewQtGUI::resetSystemSettings() { if (reply == QMessageBox::Yes) { // From factory defaults TomoSystemSettings defaults; - updateSystemSettings(defaults); + updateSystemSettingsTabFields(defaults); } } @@ -2188,7 +2000,7 @@ void TomographyIfaceViewQtGUI::closeEvent(QCloseEvent *event) { } if (answer == QMessageBox::AcceptRole) { - // TODO? cleanup(); + // TODOVIEW? cleanup(); m_presenter->notify(ITomographyIfacePresenter::ShutDown); event->accept(); } else { diff --git a/MantidQt/CustomInterfaces/test/TomographyIfaceModelTest.h b/MantidQt/CustomInterfaces/test/TomographyIfaceModelTest.h index 90b2182aace59ec6e3fb45e43297822f0345aac3..fcd419ae25dbce1df39991eff4b0bc9239b16d30 100644 --- a/MantidQt/CustomInterfaces/test/TomographyIfaceModelTest.h +++ b/MantidQt/CustomInterfaces/test/TomographyIfaceModelTest.h @@ -4,10 +4,14 @@ #include "MantidAPI/FrameworkManager.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidKernel/FacilityInfo.h" + #include "MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h" +#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h" + #include <cxxtest/TestSuite.h> +using namespace Mantid::API; using namespace MantidQt::CustomInterfaces; class TomographyIfaceModelTest : public CxxTest::TestSuite { @@ -107,7 +111,7 @@ public: model.setupRunTool("Local"); TSM_ASSERT_THROWS_NOTHING("Problem with experiment number", - model.updateExperimentReference("RB0001234")); + model.setExperimentReference("RB0001234")); auto sts = model.jobsStatus(); TSM_ASSERT_EQUALS("Unexpected number of jobs", sts.size(), 0); @@ -175,7 +179,7 @@ public: std::invalid_argument); } - void test_submitFailWrongResource() { + void test_submitFailEmptyTool() { TomographyIfaceModel model; model.setupComputeResource(); @@ -203,10 +207,10 @@ public: model.setupRunTool("Local"); model.usingTool("Custom command"); - TomoReconToolsUserSettings toolsSettings; - toolsSettings.custom = ToolConfigCustom("fail", "some params"); - model.updateReconToolsSettings(toolsSettings); - model.doRunReconstructionJobLocal(); + auto d = std::make_shared<ToolConfigCustom>("fail", + "/scriptpath/ --some params"); + model.setCurrentToolSettings(d); + model.doSubmitReconstructionJob("Local"); } void test_setupToolsTomoPy() { dryRunToolLocal("TomoPy", "gridrec"); } @@ -221,13 +225,218 @@ public: std::invalid_argument); } + // this currently just transforms the names to lower case + void test_prepareToolNameForArgs() { + + TestableTomographyIfaceModel model; + + const std::string exp1 = model.prepareToolNameForArgs("TomoPy"); + const std::string exp2 = model.prepareToolNameForArgs("Astra"); + const std::string exp3 = model.prepareToolNameForArgs("Savu"); + const std::string exp4 = model.prepareToolNameForArgs("Custom Command"); + + TS_ASSERT_EQUALS(exp1, "tomopy"); + TS_ASSERT_EQUALS(exp2, "astra"); + TS_ASSERT_EQUALS(exp3, "savu"); + TS_ASSERT_EQUALS(exp4, "custom command"); + // although custom command never reaches that function + } + + void test_makeRemoteRunnableWithOptionsCustom() { + std::string inputRunnable = "/scriptPath/"; + // the custom one just processes a single member + std::vector<std::string> inputArgsVector{ + "--some params --some other params"}; + + TestableTomographyIfaceModel model; + + std::string inputArgsString = + model.constructSingleStringFromVector(inputArgsVector); + + std::shared_ptr<TomoRecToolConfig> d = std::shared_ptr<TomoRecToolConfig>( + new ToolConfigCustom(inputRunnable, inputArgsString)); + + model.usingTool(TestableTomographyIfaceModel::g_customCmdTool); + model.setCurrentToolMethod("gridrec"); + + model.setCurrentToolSettings(d); + + const std::string resource = TestableTomographyIfaceModel::g_SCARFName; + + std::string actualRun; + std::vector<std::string> actualArgsVector; + model.makeRunnableWithOptions(resource, actualRun, actualArgsVector); + + std::string expectedRunnable = "/scriptPath/"; + // the space at the end is necessary, because of how + // constructSingleStringFromVector works + std::vector<std::string> expectedArgsVector{ + "--some params --some other params "}; + TS_ASSERT_EQUALS(actualRun, expectedRunnable); + + // checks size and elements + TS_ASSERT(actualArgsVector == expectedArgsVector); + } + + void test_makeLocalRunnableWithOptionsCustom() { + std::string inputRunnable = "python /scriptPath/"; + // the custom one just processes a single member + std::vector<std::string> inputArgsVector{ + "--some params --some other params"}; + + TestableTomographyIfaceModel model; + + std::string inputArgsString = + model.constructSingleStringFromVector(inputArgsVector); + + std::shared_ptr<TomoRecToolConfig> d = std::shared_ptr<TomoRecToolConfig>( + new ToolConfigCustom(inputRunnable, inputArgsString)); + + model.usingTool(TestableTomographyIfaceModel::g_customCmdTool); + model.setCurrentToolMethod("gridrec"); + + model.setCurrentToolSettings(d); + + const std::string resource = model.localComputeResource(); + + std::string actualRun; + std::vector<std::string> actualArgsVector; + model.makeRunnableWithOptions(resource, actualRun, actualArgsVector); + + std::string expectedRunnable = "python"; + // the space at the end is necessary, because of how + // constructSingleStringFromVector works + std::vector<std::string> expectedArgsVector{ + "/scriptPath/ --some params --some other params "}; + TS_ASSERT_EQUALS(actualRun, expectedRunnable); + // checks size and elements + TS_ASSERT(actualArgsVector == expectedArgsVector); + } + + void test_makeRemoteRunnableWithOptions() { + std::string expectedRunnable = + "/work/imat/phase_commissioning/scripts/Imaging/" + "IMAT/tomo_reconstruct.py"; + TomoPathsConfig pathConfig; + + const std::string pathOut = "/work/imat"; + static size_t reconIdx = 1; + const std::string localOutNameAppendix = std::string("/processed/") + + "reconstruction_" + + std::to_string(reconIdx); + + std::shared_ptr<TomoRecToolConfig> d = std::shared_ptr<TomoRecToolConfig>( + new ToolConfigTomoPy(expectedRunnable, pathOut + localOutNameAppendix, + pathConfig.pathDarks(), pathConfig.pathOpenBeam(), + pathConfig.pathSamples())); + + TestableTomographyIfaceModel model; + + model.usingTool(TestableTomographyIfaceModel::g_TomoPyTool); + model.setCurrentToolMethod("gridrec"); + + model.setCurrentToolSettings(d); + + const std::string resource = TestableTomographyIfaceModel::g_SCARFName; + + std::string actualRunnable; + std::vector<std::string> actualArgsVector; + model.makeRunnableWithOptions(resource, actualRunnable, actualArgsVector); + + std::vector<std::string> expectedArgsVector{ + "--tool=tomopy", "--algorithm=gridrec", "--num-iter=5", + "--input-path=" + pathConfig.pathSamples(), + "--input-path-flat=" + pathConfig.pathOpenBeam(), + "--input-path-dark=" + pathConfig.pathDarks(), + "--output=\"/work/imat/phase_commissioning/processed/" + "reconstruction_TomoPy_gridrec_2016October20_113701_413275000", + "--median-filter-size=3", "--cor=0.000000", "--rotation=0", + "--max-angle=360.000000", "--circular-mask=0.940000", + "--out-img-format=png"}; + doTestExpectedRunnableAndArguemnts(expectedRunnable, actualRunnable, + expectedArgsVector, actualArgsVector); + } + + void test_makeLocalRunnableWithOptions() { + std::string inputRunnable = "python " + "/work/imat/phase_commissioning/scripts/" + "Imaging/IMAT/tomo_reconstruct.py"; + + TomoPathsConfig pathConfig; + const std::string pathOut = "~/imat/RB000XXX"; + static size_t reconIdx = 1; + const std::string localOutNameAppendix = std::string("/processed/") + + "reconstruction_" + + std::to_string(reconIdx); + + std::shared_ptr<TomoRecToolConfig> d = std::shared_ptr<TomoRecToolConfig>( + new ToolConfigTomoPy(inputRunnable, pathOut + localOutNameAppendix, + pathConfig.pathDarks(), pathConfig.pathOpenBeam(), + pathConfig.pathSamples())); + + TestableTomographyIfaceModel model; + + model.usingTool(TestableTomographyIfaceModel::g_TomoPyTool); + model.setCurrentToolMethod("gridrec"); + + model.setCurrentToolSettings(d); + + const std::string resource = model.localComputeResource(); + + // should be just the externalInterpretor path + std::string actualRunnable; + std::vector<std::string> actualArgsVector; + model.makeRunnableWithOptions(resource, actualRunnable, actualArgsVector); + + std::string expectedRunnable = "python"; + std::vector<std::string> expectedArgsVector{ + "/work/imat/phase_commissioning/scripts/Imaging/IMAT/" + "tomo_reconstruct.py", + "--tool=tomopy", "--algorithm=gridrec", "--num-iter=5", + "--input-path=/work/imat/phase_commissioning/data", + "--input-path-flat=/work/imat/phase_commissioning/flat", + "--input-path-dark=/work/imat/phase_commissioning/dark", + "--output=/work/imat/phase_commissioning/processed/" + "reconstruction_TomoPy_gridrec_2016October20_113701_413275000", + "--median-filter-size=3", "--cor=0.000000", "--rotation=0", + "--max-angle=360.000000", "--circular-mask=0.940000", + "--out-img-format=png"}; + + doTestExpectedRunnableAndArguemnts(expectedRunnable, actualRunnable, + expectedArgsVector, actualArgsVector); + } + private: - void dryRunToolLocal(const std::string &tool, const std::string &method) { + // inner class to access the model's protected functions + class TestableTomographyIfaceModel : public TomographyIfaceModel { + friend class TomographyIfaceModelTest; + TestableTomographyIfaceModel() : TomographyIfaceModel() {} + }; + + void doTestExpectedRunnableAndArguemnts( + const std::string &expectedRunnable, const std::string &actualRunnable, + const std::vector<std::string> &expectedArguments, + const std::vector<std::string> &actualArguments) { + TSM_ASSERT_EQUALS("Local interpreter executable not properly separated", + actualRunnable, expectedRunnable); + TSM_ASSERT_EQUALS("Invalid argument size", expectedArguments.size(), + actualArguments.size()); + + for (size_t i = 0; i < expectedArguments.size(); ++i) { + // this is the --output one that varies depending on time, so just skip + if (expectedArguments[i].substr(0, 8) == "--output") { + continue; + } + TS_ASSERT_EQUALS(expectedArguments[i], actualArguments[i]); + } + } + void dryRunToolLocal(const std::string &tool, const std::string &method, + const std::string &resource = "Local") { TomographyIfaceModel model; model.setupComputeResource(); model.setupRunTool(model.localComputeResource()); model.usingTool(tool); - model.updateTomopyMethod(method); + model.setCurrentToolMethod(method); TSM_ASSERT_EQUALS("Unexpected number of reconstruction tools", model.reconTools().size(), 5); @@ -237,20 +446,15 @@ private: // default/empty paths, to make sure nothing will be found TomoPathsConfig paths; - model.updateTomoPathsConfig(paths); + model.setTomoPathsConfig(paths); // paths that don't make sense, so nothing gets executed even if you have a // local installation of tomopy available - TomoSystemSettings settings; - settings.m_local.m_basePathTomoData = "/never_find_anything/"; - settings.m_local.m_reconScriptsPath = "/dont_find_the_scripts/"; - model.updateSystemSettings(settings); - - TomoReconToolsUserSettings toolsSettings; - toolsSettings.tomoPy = - ToolConfigTomoPy("fail", "/out/", "/dark/", "/flat/", "/sample/"); - model.updateReconToolsSettings(toolsSettings); - model.doRunReconstructionJobLocal(); + std::shared_ptr<ToolConfigTomoPy> d( + new ToolConfigTomoPy("fail /not_exitant_script_path/", "/out/", + "/dark/", "/flat/", "/sample/")); + model.setCurrentToolSettings(d); + model.doSubmitReconstructionJob(resource); model.refreshLocalJobsInfo(); localSts = model.jobsStatusLocal(); diff --git a/MantidQt/CustomInterfaces/test/TomographyIfacePresenterTest.h b/MantidQt/CustomInterfaces/test/TomographyIfacePresenterTest.h index 954df7215e804a308554db800a20dae6ee6f1cab..4f30f6668928100b1aade576958511d7d6834ec3 100644 --- a/MantidQt/CustomInterfaces/test/TomographyIfacePresenterTest.h +++ b/MantidQt/CustomInterfaces/test/TomographyIfacePresenterTest.h @@ -5,8 +5,8 @@ #include "MantidAPI/MatrixWorkspace.h" #include "MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h" -#include <cxxtest/TestSuite.h> #include "TomographyViewMock.h" +#include <cxxtest/TestSuite.h> using namespace MantidQt::CustomInterfaces; using testing::TypedEq; @@ -26,8 +26,8 @@ public: } TomographyIfacePresenterTest() { - Mantid::API::FrameworkManager::Instance(); // make sure framework is - // initialized + // make sure the framework is initialized + Mantid::API::FrameworkManager::Instance(); } void setUp() override { @@ -120,7 +120,7 @@ public: // needs one tool at a very minimum EXPECT_CALL(mockView, currentReconTool()).Times(1).WillOnce(Return(g_ccpi)); // and basic tools settings - EXPECT_CALL(mockView, reconToolsSettings()).Times(0); + EXPECT_CALL(mockView, currentPathsConfig()).Times(0); // tool config not available EXPECT_CALL(mockView, showToolConfig(testing::_)).Times(0); @@ -133,31 +133,7 @@ public: testing::Mock::VerifyAndClearExpectations(&mockView)) } - // does not really fail, but it cannot do any of the expected updates - void test_setupReconToolUnsupportedTool() { - testing::NiceMock<MockTomographyIfaceView> mockView; - MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); - - EXPECT_CALL(mockView, systemSettings()).Times(0); - EXPECT_CALL(mockView, currentReconTool()) - .Times(1) - .WillRepeatedly(Return(g_ccpi)); - EXPECT_CALL(mockView, reconToolsSettings()).Times(0); - - // wrong tool => doesn't have a config dialog - EXPECT_CALL(mockView, showToolConfig(testing::_)).Times(0); - - // No errors/warnings - EXPECT_CALL(mockView, userError(testing::_, testing::_)).Times(0); - EXPECT_CALL(mockView, userWarning(testing::_, testing::_)).Times(0); - - pres.notify(ITomographyIfacePresenter::SetupReconTool); - TSM_ASSERT( - "Mock not used as expected. Some EXPECT_CALL conditions were not " - "satisfied.", - testing::Mock::VerifyAndClearExpectations(&mockView)) - } - + // setup reconstruction tool now in preseter, have a unit test void test_setupReconToolGood() { testing::NiceMock<MockTomographyIfaceView> mockView; MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); @@ -168,10 +144,10 @@ public: .Times(2) .WillRepeatedly(Return("TomoPy")); // and basic tools settings - TomoReconToolsUserSettings toolsSettings; - EXPECT_CALL(mockView, reconToolsSettings()) + TomoPathsConfig toolPaths; + EXPECT_CALL(mockView, currentPathsConfig()) .Times(1) - .WillOnce(Return(toolsSettings)); + .WillOnce(Return(toolPaths)); EXPECT_CALL(mockView, showToolConfig(testing::_)).Times(1); @@ -179,6 +155,7 @@ public: EXPECT_CALL(mockView, userError(testing::_, testing::_)).Times(0); EXPECT_CALL(mockView, userWarning(testing::_, testing::_)).Times(0); + pres.notify(ITomographyIfacePresenter::ToolChanged); pres.notify(ITomographyIfacePresenter::SetupReconTool); TSM_ASSERT( "Mock not used as expected. Some EXPECT_CALL conditions were not " @@ -201,34 +178,6 @@ public: testing::Mock::VerifyAndClearExpectations(&mockView)) } - void test_showImg_good() { - testing::NiceMock<MockTomographyIfaceView> mockView; - MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); - - const std::string path = "FITS_small_02.fits"; - // needs image file name - re-uses a FITS from the unit tests - ON_CALL(mockView, showImagePath()).WillByDefault(Return(path)); - EXPECT_CALL(mockView, showImagePath()).Times(1); - - EXPECT_CALL( - mockView, - showImage(testing::Matcher<const Mantid::API::MatrixWorkspace_sptr &>( - testing::_))).Times(1); - EXPECT_CALL(mockView, - showImage(testing::Matcher<const std::string &>(testing::_))) - .Times(0); - - // No errors, no warnings - EXPECT_CALL(mockView, userError(testing::_, testing::_)).Times(0); - EXPECT_CALL(mockView, userWarning(testing::_, testing::_)).Times(0); - - pres.notify(ITomographyIfacePresenter::ViewImg); - TSM_ASSERT( - "Mock not used as expected. Some EXPECT_CALL conditions were not " - "satisfied.", - testing::Mock::VerifyAndClearExpectations(&mockView)) - } - void test_valuesAtInit() { testing::NiceMock<MockTomographyIfaceView> mockView; MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); @@ -257,7 +206,6 @@ public: // would need compute resource and username if logged in EXPECT_CALL(mockView, getUsername()).Times(0); - EXPECT_CALL(mockView, currentComputeResource()).Times(0); EXPECT_CALL(mockView, updateLoginControls(testing::_)).Times(0); // No errors, no warnings @@ -275,24 +223,17 @@ public: testing::NiceMock<MockTomographyIfaceView> mockView; MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); - std::vector<std::string> tools; - tools.emplace_back("Astra Toolbox"); - tools.emplace_back("TomoPy"); - tools.push_back(g_ccpi); - tools.emplace_back("Savu"); - - TSM_ASSERT_EQUALS("There should be 4 tools in this test", tools.size(), 4); - // up to this index the tools are supported - const size_t indexToolsWork = 1; - for (size_t i = 0; i < 3; i++) { - EXPECT_CALL(mockView, currentReconTool()) + std::vector<std::string> tools{"Astra", "TomoPy"}; + + TomoPathsConfig toolPaths; + for (const auto &tool : tools) { + // expect the current paths config will be read only once + EXPECT_CALL(mockView, currentPathsConfig()) .Times(1) - .WillOnce(Return(tools[i])); - if (i <= indexToolsWork) { - EXPECT_CALL(mockView, currentComputeResource()).Times(1); - } else { - EXPECT_CALL(mockView, currentComputeResource()).Times(0); - } + .WillOnce(Return(toolPaths)); + + // expect the current reconstruction tool will be called only once + EXPECT_CALL(mockView, currentReconTool()).Times(1).WillOnce(Return(tool)); EXPECT_CALL(mockView, enableRunReconstruct(testing::_)).Times(1); EXPECT_CALL(mockView, enableConfigTool(testing::_)).Times(1); @@ -313,9 +254,6 @@ public: testing::NiceMock<MockTomographyIfaceView> mockView; MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); - EXPECT_CALL(mockView, currentComputeResource()) - .Times(1) - .WillOnce(Return(g_scarfName)); EXPECT_CALL(mockView, currentReconTool()).Times(0); // No errors, no warnings @@ -481,7 +419,7 @@ public: EXPECT_CALL(mockView, userError(testing::_, testing::_)).Times(0); EXPECT_CALL(mockView, userWarning(testing::_, testing::_)).Times(0); - EXPECT_CALL(mockView, userWarning(testing::_, testing::_)).Times(0); + // EXPECT_CALL(mockView, userWarning(testing::_, testing::_)).Times(0); pres.notify(ITomographyIfacePresenter::SetupResourcesAndTools); TSM_ASSERT( "Mock not used as expected. Some EXPECT_CALL conditions were not " @@ -514,7 +452,6 @@ public: testing::NiceMock<MockTomographyIfaceView> mockView; MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); - EXPECT_CALL(mockView, currentComputeResource()).Times(0); EXPECT_CALL(mockView, updateJobsInfoDisplay(testing::_, testing::_)) .Times(1); @@ -533,7 +470,6 @@ public: testing::NiceMock<MockTomographyIfaceView> mockView; MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); - EXPECT_CALL(mockView, currentComputeResource()).Times(0); EXPECT_CALL(mockView, updateJobsInfoDisplay(testing::_, testing::_)) .Times(1); @@ -729,10 +665,7 @@ public: testing::Mock::VerifyAndClearExpectations(&mockView)) } - // An attempt at testing a sequence of steps from the user. - // TODO: more interesting sessions should follow, but how to do it - // without loading too many and too big files? - void test_sillySession() { + void test_sillySessionLocal() { // the user does a few silly things... testing::NiceMock<MockTomographyIfaceView> mockView; MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); @@ -745,9 +678,7 @@ public: // user changes some paths pres.notify(ITomographyIfacePresenter::TomoPathsChanged); - EXPECT_CALL(mockView, currentComputeResource()) - .Times(2) .WillRepeatedly(Return(g_scarfName)); // user changes the compute resource @@ -757,11 +688,13 @@ public: .Times(2) .WillRepeatedly(Return("TomoPy")); - TomoReconToolsUserSettings toolsSettings; - EXPECT_CALL(mockView, reconToolsSettings()) + // and basic tools settings + EXPECT_CALL(mockView, currentPathsConfig()) .Times(1) - .WillOnce(Return(toolsSettings)); + .WillOnce(Return(TomoPathsConfig())); + // the tool changed event sets up the tool's paths + pres.notify(ITomographyIfacePresenter::ToolChanged); // user opens dialog and sets up a reconstruction tool pres.notify(ITomographyIfacePresenter::SetupReconTool); @@ -775,9 +708,67 @@ public: .Times(1) .WillOnce(Return(roiEtc)); - EXPECT_CALL(mockView, tomopyMethod()).Times(1).WillOnce(Return("")); + TomoReconFiltersSettings filters; + EXPECT_CALL(mockView, prePostProcSettings()) + .Times(1) + .WillOnce(Return(filters)); + + // No errors, no warnings + EXPECT_CALL(mockView, userError(testing::_, testing::_)).Times(0); + + // we get one warning from trying to submit a job to remote + EXPECT_CALL(mockView, userWarning(testing::_, testing::_)).Times(1); + + // finally, user tries to run a reconstruction job + pres.notify(ITomographyIfacePresenter::RunReconstruct); + TSM_ASSERT( + "Mock not used as expected. Some EXPECT_CALL conditions were not " + "satisfied.", + testing::Mock::VerifyAndClearExpectations(&mockView)) + } - EXPECT_CALL(mockView, astraMethod()).Times(1).WillOnce(Return("")); + void test_sillySessionLocalRemote() { + // the user does a few silly things... + testing::NiceMock<MockTomographyIfaceView> mockView; + MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); + + EXPECT_CALL(mockView, systemSettings()).Times(0); + + EXPECT_CALL(mockView, currentPathsConfig()) + .Times(1) + .WillOnce(Return(TomoPathsConfig())); + + // user changes some paths + pres.notify(ITomographyIfacePresenter::TomoPathsChanged); + EXPECT_CALL(mockView, currentComputeResource()) + .WillRepeatedly(Return("Local")); + + // user changes the compute resource + pres.notify(ITomographyIfacePresenter::CompResourceChanged); + + EXPECT_CALL(mockView, currentReconTool()) + .Times(2) + .WillRepeatedly(Return("TomoPy")); + + // and basic tools settings + EXPECT_CALL(mockView, currentPathsConfig()) + .Times(1) + .WillOnce(Return(TomoPathsConfig())); + + // the tool changed event sets up the tool's paths + pres.notify(ITomographyIfacePresenter::ToolChanged); + // user opens dialog and sets up a reconstruction tool + pres.notify(ITomographyIfacePresenter::SetupReconTool); + + TomoPathsConfig pathsCfg; + EXPECT_CALL(mockView, currentPathsConfig()) + .Times(1) + .WillOnce(Return(pathsCfg)); + + ImageStackPreParams roiEtc; + EXPECT_CALL(mockView, currentROIEtcParams()) + .Times(1) + .WillOnce(Return(roiEtc)); TomoReconFiltersSettings filters; EXPECT_CALL(mockView, prePostProcSettings()) @@ -812,6 +803,34 @@ public: testing::Mock::VerifyAndClearExpectations(&mockView)) } + void test_showImg_good() { + testing::NiceMock<MockTomographyIfaceView> mockView; + MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView); + + const std::string path = "FITS_small_02.fits"; + // needs image file name - re-uses a FITS from the unit tests + ON_CALL(mockView, showImagePath()).WillByDefault(Return(path)); + EXPECT_CALL(mockView, showImagePath()).Times(1); + + EXPECT_CALL( + mockView, + showImage(testing::Matcher<const Mantid::API::MatrixWorkspace_sptr &>( + testing::_))).Times(1); + EXPECT_CALL(mockView, + showImage(testing::Matcher<const std::string &>(testing::_))) + .Times(0); + + // No errors, no warnings + EXPECT_CALL(mockView, userError(testing::_, testing::_)).Times(0); + EXPECT_CALL(mockView, userWarning(testing::_, testing::_)).Times(0); + + pres.notify(ITomographyIfacePresenter::ViewImg); + TSM_ASSERT( + "Mock not used as expected. Some EXPECT_CALL conditions were not " + "satisfied.", + testing::Mock::VerifyAndClearExpectations(&mockView)) + } + private: // boost::shared_ptr boost::scoped_ptr<testing::NiceMock<MockTomographyIfaceView>> m_view; diff --git a/MantidQt/CustomInterfaces/test/TomographyViewMock.h b/MantidQt/CustomInterfaces/test/TomographyViewMock.h index 5c2b6de7ed042a732945b8b25955b42051dbb6d6..fc6fd704096b8e4ffdd232073ed5d0e1c52a7a4b 100644 --- a/MantidQt/CustomInterfaces/test/TomographyViewMock.h +++ b/MantidQt/CustomInterfaces/test/TomographyViewMock.h @@ -57,12 +57,6 @@ public: // std::string currentReconTool() const {} MOCK_CONST_METHOD0(currentReconTool, std::string()); - // std::string astraMethod() const {} - MOCK_CONST_METHOD0(astraMethod, std::string()); - - // std::string tomopyMethod() const {} - MOCK_CONST_METHOD0(tomopyMethod, std::string()); - // void updateLoginControls(bool loggedIn) {} MOCK_METHOD1(updateLoginControls, void(bool loggedIn)); @@ -97,7 +91,9 @@ public: MantidQt::CustomInterfaces::ImageStackPreParams()); // void showToolConfig(const std::string &name) {} - MOCK_METHOD1(showToolConfig, void(const std::string &name)); + MOCK_METHOD1( + showToolConfig, + void(MantidQt::CustomInterfaces::TomoToolConfigDialogBase &dialog)); // virtual void updateJobsInfoDisplay( const // std::vector<Mantid::API::IRemoteJobManager::RemoteJobInfo> @@ -115,11 +111,6 @@ public: MOCK_CONST_METHOD0(systemSettings, MantidQt::CustomInterfaces::TomoSystemSettings()); - // MantidQt::CustomInterfaces::TomoReconToolsUserSettings - // reconToolsSettings() const - MOCK_CONST_METHOD0(reconToolsSettings, - MantidQt::CustomInterfaces::TomoReconToolsUserSettings()); - // MantidQt::CustomInterfaces::TomoReconToolsUserSettings // prePostProcSettings() const MOCK_CONST_METHOD0(prePostProcSettings, diff --git a/buildconfig/CMake/Bootstrap.cmake b/buildconfig/CMake/Bootstrap.cmake index 2b0b240acb971a22089f6882679733cb2562bb70..cf21cd8d4a9d1d1e9bcd84f0e00d6a48588d668b 100644 --- a/buildconfig/CMake/Bootstrap.cmake +++ b/buildconfig/CMake/Bootstrap.cmake @@ -10,7 +10,7 @@ if( MSVC ) include ( ExternalProject ) set( EXTERNAL_ROOT ${PROJECT_SOURCE_DIR}/external ) set( THIRD_PARTY_GIT_URL "https://github.com/mantidproject/thirdparty-msvc2015.git" ) - set ( THIRD_PARTY_GIT_SHA1 f73d59f82eaa2ea990c33b76447dcf9dcb670885 ) + set ( THIRD_PARTY_GIT_SHA1 68ee6fc88cfaa1c369a5fe8460c52b7bd266d3ad ) set ( THIRD_PARTY_DIR ${EXTERNAL_ROOT}/src/ThirdParty ) # Generates a script to do the clone/update in tmp set ( _project_name ThirdParty ) diff --git a/buildconfig/CMake/DarwinSetup.cmake b/buildconfig/CMake/DarwinSetup.cmake index 432f8e32762df35afb29c078f0a5930b8a653f21..3599de27c11070389f5fdf40fdaf3871c018baea 100644 --- a/buildconfig/CMake/DarwinSetup.cmake +++ b/buildconfig/CMake/DarwinSetup.cmake @@ -174,6 +174,8 @@ endif () install ( DIRECTORY ${PYQT4_PYTHONPATH}/uic DESTINATION ${BIN_DIR}/PyQt4 ) +install ( FILES ${CMAKE_SOURCE_DIR}/images/MantidPlot.icns + DESTINATION MantidPlot.app/Contents/Resources/ ) # Add launcher script for mantid python install ( PROGRAMS ${CMAKE_BINARY_DIR}/mantidpython_osx_install DESTINATION MantidPlot.app/Contents/MacOS/ @@ -198,7 +200,7 @@ install ( FILES ${CMAKE_SOURCE_DIR}/images/MantidNotebook.icns DESTINATION MantidNotebook\ \(optional\).app/Contents/Resources/ ) set ( CPACK_DMG_BACKGROUND_IMAGE ${CMAKE_SOURCE_DIR}/images/osx-bundle-background.png ) -set ( CPACK_DMG_DS_STORE ${CMAKE_SOURCE_DIR}/installers/MacInstaller/osx_DS_Store) +set ( CPACK_DMG_DS_STORE_SETUP_SCRIPT ${CMAKE_SOURCE_DIR}/installers/MacInstaller/CMakeDMGSetup.scpt ) set ( MACOSX_BUNDLE_ICON_FILE MantidPlot.icns ) string (REPLACE " " "" CPACK_SYSTEM_NAME ${OSX_CODENAME}) diff --git a/docs/source/concepts/FittingMinimizers.rst b/docs/source/concepts/FittingMinimizers.rst index f84d77dc47f481a14b97f3e955dbc3e2a50be734..06aa60e2589f433ea0db807eca0732f9c0104548 100644 --- a/docs/source/concepts/FittingMinimizers.rst +++ b/docs/source/concepts/FittingMinimizers.rst @@ -1,4 +1,4 @@ -.. _FittingMinimizers: +.. _FittingMinimizers: Comparing Minimizers ==================== @@ -25,18 +25,16 @@ Several minimizers are included with Mantid and can be selected in the or when using the algorithm :ref:`Fit <algm-Fit>` The following options are available: -- `Simplex <https://en.wikipedia.org/wiki/Nelder%E2%80%93Mead_method>`__ -- `SteepestDescent <https://en.wikipedia.org/wiki/Gradient_descent>`__ -- `Conjugate gradient (Fletcher-Reeves imp.) <https://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method>`__ -- `Conjugate gradient (Polak-Ribiere imp.) <https://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method>`__ -- `BFGS (Broyden-Fletcher-Goldfarb-Shanno) <https://en.wikipedia.org/wiki/Broyden–Fletcher–Goldfarb–Shanno_algorithm>`__ -- `Levenberg-Marquardt <https://en.wikipedia.org/wiki/Levenberg-Marquardt_algorithm>`__ (default) +- `Simplex <../fitminimizers/Simplex.html>`__ +- `SteepestDescent <../fitminimizers/GradientDescent.html>`__ +- `Conjugate gradient (Fletcher-Reeves imp.) <../fitminimizers/FletcherReeves.html>`__ +- `Conjugate gradient (Polak-Ribiere imp.) <../fitminimizers/PolakRibiere.html>`__ +- `BFGS (Broyden-Fletcher-Goldfarb-Shanno) <../fitminimizers/BFGS.html>`__ +- `Levenberg-Marquardt <../fitminimizers/LevenbergMarquardt.html>`__ (default) - Levenberg-MarquardtMD A `Levenberg-Marquardt <https://en.wikipedia.org/wiki/Levenberg-Marquardt_algorithm>`__ implementation generalised to allow different cost functions, and supporting chunking techniques for large datasets. -- Damping - - A `Gauss-Newton <https://en.wikipedia.org/wiki/Gauss–Newton_algorithm#Improved_versions>`__ algorithm with damping. +- `Gauss-Newton <../fitminimizers/GaussNewton.html>`__ algorithm with damping. - :ref:`FABADA <FABADA>` - `Trust region <https://ccpforge.cse.rl.ac.uk/gf/project/ral_nlls>`__: a `trust diff --git a/docs/source/fitminimizers/BFGS.rst b/docs/source/fitminimizers/BFGS.rst new file mode 100644 index 0000000000000000000000000000000000000000..3b4ac8b143f804e6f63ec292f25b3119162608ff --- /dev/null +++ b/docs/source/fitminimizers/BFGS.rst @@ -0,0 +1,18 @@ +.. _BFGS + +BFGS (Broyden-Fletcher-Goldfarb-Shanno) minimizer +================================================= + +This minimizer is +explained at `Wikipedia <https://en.wikipedia.org/wiki/Broyden–Fletcher–Goldfarb–Shanno_algorithm>`__ + +It is listed in `a comparison of fitting minimizers <../concepts/FittingMinimizers.html>`__. + +It makes use of the +`GSL (GNU Scientific Library) library +<https://www.gnu.org/software/gsl/>`__, specifically the +`GSL routines for least-squares fitting +<https://www.gnu.org/software/gsl/manual/html_node/Least_002dSquares-Fitting.html#Least_002dSquares-Fitting>`__. + +.. categories:: FitMinimizers + diff --git a/docs/source/fitminimizers/FletcherReeves.rst b/docs/source/fitminimizers/FletcherReeves.rst new file mode 100644 index 0000000000000000000000000000000000000000..27ad14923a6801d5cbf5c3140161411872953d7a --- /dev/null +++ b/docs/source/fitminimizers/FletcherReeves.rst @@ -0,0 +1,18 @@ +.. _FletcherReeves + +Conjugate Gradient Minimizer (Fletcher-Reeves imp.) +=================================================== + +This minimizer an implementation of the nonlinear conjugate gradient method +explained at `Wikipedia <https://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method>`__ + +It is listed in `a comparison of fitting minimizers <../concepts/FittingMinimizers.html>`__. + +It makes use of the +`GSL (GNU Scientific Library) library +<https://www.gnu.org/software/gsl/>`__, specifically the +`GSL routines for least-squares fitting +<https://www.gnu.org/software/gsl/manual/html_node/Least_002dSquares-Fitting.html#Least_002dSquares-Fitting>`__. + +.. categories:: FitMinimizers + diff --git a/docs/source/fitminimizers/GaussNewton.rst b/docs/source/fitminimizers/GaussNewton.rst new file mode 100644 index 0000000000000000000000000000000000000000..d75d971c5bd0995b42b537f50bda7dee394f6ae0 --- /dev/null +++ b/docs/source/fitminimizers/GaussNewton.rst @@ -0,0 +1,19 @@ +.. _GaussNewton + +Damping Gauss-Newton minimizer +============================== + +This minimizer is +explained at `Wikipedia <https://en.wikipedia.org/wiki/Gauss–Newton_algorithm#Improved_versions>`__ +and has damping. + +It is listed in `a comparison of fitting minimizers <../concepts/FittingMinimizers.html>`__. + +It makes use of the +`GSL (GNU Scientific Library) library +<https://www.gnu.org/software/gsl/>`__, specifically the +`GSL routines for least-squares fitting +<https://www.gnu.org/software/gsl/manual/html_node/Least_002dSquares-Fitting.html#Least_002dSquares-Fitting>`__. + +.. categories:: FitMinimizers + diff --git a/docs/source/fitminimizers/GradientDescent.rst b/docs/source/fitminimizers/GradientDescent.rst new file mode 100644 index 0000000000000000000000000000000000000000..7e7e3dbff9d41a3f0e7242395fef5660485ad6aa --- /dev/null +++ b/docs/source/fitminimizers/GradientDescent.rst @@ -0,0 +1,16 @@ +.. _GradientDescent + +Steepest Descent Minimizer +========================== + +This minimizer is explained at - `Wikipedia <https://en.wikipedia.org/wiki/Gradient_descent>`__ as the gradient descent method. +It is listed in `a comparison of fitting minimizers <../concepts/FittingMinimizers.html>`__. + +It makes use of the +`GSL (GNU Scientific Library) library +<https://www.gnu.org/software/gsl/>`__, specifically the +`GSL routines for least-squares fitting +<https://www.gnu.org/software/gsl/manual/html_node/Least_002dSquares-Fitting.html#Least_002dSquares-Fitting>`__. + +.. categories:: FitMinimizers + diff --git a/docs/source/fitminimizers/LevenbergMarquardt.rst b/docs/source/fitminimizers/LevenbergMarquardt.rst new file mode 100644 index 0000000000000000000000000000000000000000..a6439fe4f7f56e94a16ec05a5cf552c6889ad434 --- /dev/null +++ b/docs/source/fitminimizers/LevenbergMarquardt.rst @@ -0,0 +1,16 @@ +.. _LevenbergMarquardt + +Levenberg-Marquardt Minimizer +============================= + +This minimizer is explained at - `Wikipedia <https://en.wikipedia.org/wiki/Levenberg-Marquardt_algorithm>`__ +It is the default minimizer and is listed in `a comparison of fitting minimizers <../concepts/FittingMinimizers.html>`__. + +It makes use of the +`GSL (GNU Scientific Library) library +<https://www.gnu.org/software/gsl/>`__, specifically the +`GSL routines for least-squares fitting +<https://www.gnu.org/software/gsl/manual/html_node/Least_002dSquares-Fitting.html#Least_002dSquares-Fitting>`__. + +.. categories:: FitMinimizers + diff --git a/docs/source/fitminimizers/PolakRibiere.rst b/docs/source/fitminimizers/PolakRibiere.rst new file mode 100644 index 0000000000000000000000000000000000000000..db1a6b2c5e1f9f53e252653a370fc87171bc9d7e --- /dev/null +++ b/docs/source/fitminimizers/PolakRibiere.rst @@ -0,0 +1,17 @@ +.. _PolakRiberiere + +Conjugate Gradient Minimizer (Polak-Ribiere imp.) +================================================= + +This minimizer an implementation of the nonlinear conjugate gradient method +explained at `Wikipedia <https://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method>`__ . + +It is listed in `a comparison of fitting minimizers <../concepts/FittingMinimizers.html>`__. + +It makes use of the +`GSL (GNU Scientific Library) library +<https://www.gnu.org/software/gsl/>`__, specifically the +`GSL routines for least-squares fitting +<https://www.gnu.org/software/gsl/manual/html_node/Least_002dSquares-Fitting.html#Least_002dSquares-Fitting>`__. + +.. categories:: FitMinimizers diff --git a/docs/source/fitminimizers/Simplex.rst b/docs/source/fitminimizers/Simplex.rst new file mode 100644 index 0000000000000000000000000000000000000000..441fe83b6e94f61d69693096dc8ced08c2b6e232 --- /dev/null +++ b/docs/source/fitminimizers/Simplex.rst @@ -0,0 +1,16 @@ +.. _Simplex + +Simplex Minimizer +================= + +This minimizer is explained at - `Wikipedia <https://en.wikipedia.org/wiki/Nelder%E2%80%93Mead_method>`__ as the Nelder-Mead method. +It is listed in `a comparison of fitting minimizers <../concepts/FittingMinimizers.html>`__. + +It makes use of the +`GSL (GNU Scientific Library) library +<https://www.gnu.org/software/gsl/>`__, specifically the +`GSL routines for least-squares fitting +<https://www.gnu.org/software/gsl/manual/html_node/Least_002dSquares-Fitting.html#Least_002dSquares-Fitting>`__. + +.. categories:: FitMinimizers + diff --git a/docs/source/fitminimizers/index.rst b/docs/source/fitminimizers/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..8f47df4615b2500589e4bca562ab85fcc657c298 --- /dev/null +++ b/docs/source/fitminimizers/index.rst @@ -0,0 +1,19 @@ +.. Fitting Minimizers master file + It contains a hidden root toctree directive so that Sphinx + has an internal index of all of the pages and doesn't + produce a plethora of warnings about most documents not being in + a toctree. + See http://sphinx-doc.org/tutorial.html#defining-document-structure + +.. _fitminimizers contents: + +================== +Fitting Minimizers +================== + +.. toctree:: + :glob: + :maxdepth: 1 + + * + diff --git a/docs/source/index.rst b/docs/source/index.rst index 811ae0a59a632041c461816234487915175e1753..c717b16cdfefc488505425a5db5e10168285e341 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -25,6 +25,7 @@ Mantid Documentation concepts/index interfaces/index fitfunctions/* + fitminimizers/index api/index release/index @@ -42,6 +43,7 @@ This is the documentation for Mantid |release|. * `Concepts <concepts/index.html>`_ * `Interfaces <interfaces/index.html>`_ * `Fit Functions <fitfunctions/index.html>`_ +* `Fit Minimizers <fitminimizers/index.html>`_ * `API <api/index.html>`_ - `Python <api/python/index.html>`_ - `C++ <http://doxygen.mantidproject.org/>`_ (Doxygen) diff --git a/docs/source/release/v3.9.0/framework.rst b/docs/source/release/v3.9.0/framework.rst index a55ab67fd23893eb62aecf6d78693a1f23636364..077071ab73796dd02b8e4b93ab1d3cfbe6d18c5a 100644 --- a/docs/source/release/v3.9.0/framework.rst +++ b/docs/source/release/v3.9.0/framework.rst @@ -18,11 +18,8 @@ Improved - :ref:`CalculateFlatBackground <algm-CalculateFlatBackground>` has now a new mode 'Moving Average' which takes the minimum of a moving window average as the flat background. - :ref:`StartLiveData <algm-StartLiveData>` and its dialog now support dynamic listener properties, based on the specific LiveListener being used. -<<<<<<< HEAD - :ref: All algorithms using `AsciiPointBase` now have a new property 'Separator' which allows the delimiter to be set to either comma, space or tab. This affects `SaveReflCustomAscii <algm-SaveReflCustomAscii>`, `SaveReflThreeColumnAscii <algm-SaveReflThreeColumnAscii>`, `SaveANSTOAscii <algm-SaveANSTOAscii>` and `SaveILLCosmosAscii <algm-SaveILLCosmosAscii>`. -======= - :ref:`ReplaceSpecialValues <algm_ReplaceSpecialValues>` now can replace 'small' values below a user specified threshold. ->>>>>>> origin/master Deprecated ########## diff --git a/images/osx-bundle-background.png b/images/osx-bundle-background.png index fa945f2dadba6aa69b1eafea2315551fe9d658d6..1b1d160a214be3dacea7b12cd273e7d5ba43b060 100644 Binary files a/images/osx-bundle-background.png and b/images/osx-bundle-background.png differ diff --git a/installers/MacInstaller/CMakeDMGSetup.scpt b/installers/MacInstaller/CMakeDMGSetup.scpt new file mode 100644 index 0000000000000000000000000000000000000000..37a2e9dde79f2a68c31733b110eaf0267bf9fb00 --- /dev/null +++ b/installers/MacInstaller/CMakeDMGSetup.scpt @@ -0,0 +1,59 @@ +on run argv + set image_name to item 1 of argv + + tell application "Finder" + tell disk image_name + + -- wait for the image to finish mounting + set open_attempts to 0 + repeat while open_attempts < 4 + try + open + delay 1 + set open_attempts to 5 + close + on error errStr number errorNumber + set open_attempts to open_attempts + 1 + delay 10 + end try + end repeat + delay 5 + + -- open the image the first time and save a DS_Store with just + -- background and icon setup + open + set current view of container window to icon view + set theViewOptions to the icon view options of container window + set background picture of theViewOptions to file ".background:background.png" + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 128 + delay 5 + close + + -- next setup the position of the app and Applications symlink + -- plus hide all the window decoration + open + update without registering applications + tell container window + set sidebar width to 0 + set statusbar visible to false + set toolbar visible to false + set the bounds to { 400, 000, 900, 517 } + set position of item "MantidPlot.app" to { 110, 220 } + set position of item "Applications" to { 380, 220 } + set position of item "MantidPython (optional)" to { 380, 400 } + set position of item "MantidNotebook (optional)" to { 110, 400 } + end tell + update without registering applications + delay 5 + close + + -- one last open and close so you can see everything looks correct + open + delay 5 + close + + end tell + delay 1 +end tell +end run diff --git a/installers/MacInstaller/osx_DS_Store b/installers/MacInstaller/osx_DS_Store deleted file mode 100644 index 0dc150247065eb3111939da1d68369963e5db36e..0000000000000000000000000000000000000000 Binary files a/installers/MacInstaller/osx_DS_Store and /dev/null differ