diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresenter.h index 5ab432c55e1b622cce46de93ecaf4685c9f3fa2a..8d140deb7a449893162646b49ffb7f857836c8f6 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresenter.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresenter.h @@ -160,7 +160,7 @@ private: std::string outputCalibFilename(const std::string &vanNo, const std::string &ceriaNo, - const std::string &bankName=""); + const std::string &bankName = ""); void parseCalibrateFilename(const std::string &path, std::string &instName, std::string &vanNo, std::string &ceriaNo); @@ -178,7 +178,7 @@ private: std::string buildCalibrateSuggestedFilename(const std::string &vanNo, const std::string &ceriaNo, - const std::string &bankName="") const; + const std::string &bankName = "") const; //@} @@ -309,6 +309,12 @@ private: std::string plotDifcZeroWorkspace(const std::string &customisedBankName) const; + void writeOutCalibFile(const std::string &outFilename, + const std::vector<double> &difc, + const std::vector<double> &tzero, + const std::vector<std::string> &bankNames, + const std::string &templateFile = ""); + /// keep track of the paths the user "browses to", to add them in /// the file search path void recordPathBrowsedTo(const std::string &filename); diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionViewQtGUI.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionViewQtGUI.h index 361b1cec75459341277e0b54039825a5df4f95da..91fb65d216be7454155100dab45c62932ede3684 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionViewQtGUI.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionViewQtGUI.h @@ -113,11 +113,7 @@ public: void newCalibLoaded(const std::string &vanadiumNo, const std::string &ceriaNo, const std::string &fname) override; - void writeOutCalibFile(const std::string &outFilename, - const std::vector<double> &difc, - const std::vector<double> &tzero, - const std::vector<std::string> &bankNames, - const std::string &templateFile) override; + std::string enggRunPythonCode(const std::string &pyCode) override; void enableTabs(bool enable) override; diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionView.h index e3d069c755c5c93d6f9fdffdb32beadf8c227c6d..e4050b2f0a49f17c7d65564b92ad2cd143584e95 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionView.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionView.h @@ -213,20 +213,17 @@ public: const std::string &fname) = 0; /** - * Write a GSAS file. Temporarily here until we have a more final - * way of generating these files. - * - * @param outFilename output file name - * @param difc difc values (one per bank) - * @param tzero tzero values (one per bank) - * @param templateFile name of the template file to use (from the - * templates distributed with the Engg scripts and files) - */ - virtual void writeOutCalibFile(const std::string &outFilename, - const std::vector<double> &difc, - const std::vector<double> &tzero, - const std::vector<std::string> &bankNames, - const std::string &templateFile = "") = 0; + * Run Python code received as a script string. This is used for + * example to write GSAS instrument parameters file, or other code + * included with the Engg scripts. Temporarily here until we have a + * more final way of generating these files. A SaveGSAS algorithm + * that can handle ENGIN-X files would be ideal. + * + * @param pyCode Python script as a string + * + * @return status string from running the code + */ + virtual std::string enggRunPythonCode(const std::string &pyCode) = 0; /** * Enable/disable all the sections or tabs of the interface. To be diff --git a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp index b74d4eebb63cbcd1cb70cf511d4566a06e114d35..30881505649fe1b2719507f149e39714133d6966 100644 --- a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp +++ b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp @@ -1472,7 +1472,7 @@ void EnggDiffractionPresenter::doCalib(const EnggDiffCalibSettings &cs, // 2nd: because runPythonCode does this by emitting a signal that goes to // MantidPlot, it has to be done in the view (which is a UserSubWindow). // First write the all banks parameters file - m_view->writeOutCalibFile(outFullPath.toString(), difc, tzero, bankNames); + writeOutCalibFile(outFullPath.toString(), difc, tzero, bankNames); // Then write one individual file per bank, using different templates and the // specific bank name as suffix for (size_t bankIdx = 0; bankIdx < difc.size(); ++bankIdx) { @@ -1485,9 +1485,8 @@ void EnggDiffractionPresenter::doCalib(const EnggDiffCalibSettings &cs, templateFile = "template_ENGINX_241391_236516_South_bank.prm"; } - m_view->writeOutCalibFile(bankOutputFullPath.toString(), {difc[bankIdx]}, - {tzero[bankIdx]}, {bankNames[bankIdx]}, - templateFile); + writeOutCalibFile(bankOutputFullPath.toString(), {difc[bankIdx]}, + {tzero[bankIdx]}, {bankNames[bankIdx]}, templateFile); } g_log.notice() << "Calibration file written as " << outFullPath.toString() << std::endl; @@ -3049,6 +3048,60 @@ Poco::Path EnggDiffractionPresenter::outFilesDir(std::string addToDir) { return saveDir; } +/** + * To write the calibration/instrument parameter for GSAS. + * + * @param outFilename name of the output .par/.prm/.iparm file for GSAS + * @param difc list of GSAS DIFC values to include in the file + * @param tzero list of GSAS TZERO values to include in the file + * @param bankNames list of bank names corresponding the the difc/tzero + * @param templateFile a template file where to replace the difc/zero + * values. An empty default implies using an "all-banks" template. + */ +void EnggDiffractionPresenter::writeOutCalibFile( + const std::string &outFilename, const std::vector<double> &difc, + const std::vector<double> &tzero, const std::vector<std::string> &bankNames, + const std::string &templateFile) { + // TODO: this is horrible and should be changed to avoid running + // Python code. Update this as soon as we have a more stable way of + // generating IPARM/PRM files. + + // Writes a file doing this: + // write_ENGINX_GSAS_iparam_file(output_file, difc, zero, ceria_run=241391, + // vanadium_run=236516, template_file=None): + + // this replace is to prevent issues with network drives on windows: + const std::string safeOutFname = + boost::replace_all_copy(outFilename, "\\", "/"); + std::string pyCode = "import EnggUtils\n"; + pyCode += "import os\n"; + // normalize apparently not needed after the replace, but to be double-safe: + pyCode += "GSAS_iparm_fname = os.path.normpath('" + safeOutFname + "')\n"; + pyCode += "bank_names = []\n"; + pyCode += "Difcs = []\n"; + pyCode += "Zeros = []\n"; + std::string templateFileVal = "None"; + if (!templateFile.empty()) { + templateFileVal = "'" + templateFile + "'"; + } + pyCode += "template_file = " + templateFileVal + "\n"; + for (size_t i = 0; i < difc.size(); i++) { + pyCode += "bank_names.append('" + bankNames[i] + "')\n"; + pyCode += + "Difcs.append(" + boost::lexical_cast<std::string>(difc[i]) + ")\n"; + pyCode += + "Zeros.append(" + boost::lexical_cast<std::string>(tzero[i]) + ")\n"; + } + pyCode += + "EnggUtils.write_ENGINX_GSAS_iparam_file(output_file=GSAS_iparm_fname, " + "bank_names=bank_names, difc=Difcs, tzero=Zeros, " + "template_file=template_file) \n"; + + const auto status = m_view->enggRunPythonCode(pyCode); + g_log.information() << "Saved output calibration file via Python. Status: " + << status << std::endl; +} + /** * Note down a directory that needs to be added to the data search * path when looking for run files. This simply uses a vector and adds diff --git a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionViewQtGUI.cpp b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionViewQtGUI.cpp index 75b5bfb784a7e0bf9f4b91952bafbd5e7af02809..651fd101e43bec2581263ac74f9192f3a91e73bc 100644 --- a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionViewQtGUI.cpp +++ b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionViewQtGUI.cpp @@ -960,54 +960,12 @@ void EnggDiffractionViewQtGUI::resetFocus() { m_uiTabFocus.lineEdit_texture_grouping_file->setText(""); } -void EnggDiffractionViewQtGUI::writeOutCalibFile( - const std::string &outFilename, const std::vector<double> &difc, - const std::vector<double> &tzero, const std::vector<std::string> &bankNames, - const std::string &templateFile) { - // TODO: move most of this to the presenter - // TODO: this is horrible and should not last much here. - // Avoid running Python code. Update this as soon as we have a more stable - // way of generating IPARM/PRM files. - // Writes a file doing this: - // write_ENGINX_GSAS_iparam_file(output_file, difc, zero, ceria_run=241391, - // vanadium_run=236516, template_file=None): - - // this replace is to prevent issues with network drives on windows: - const std::string safeOutFname = - boost::replace_all_copy(outFilename, "\\", "/"); - std::string pyCode = "import EnggUtils\n"; - pyCode += "import os\n"; - // normalize apparently not needed after the replace, but to be double-safe: - pyCode += "GSAS_iparm_fname = os.path.normpath('" + safeOutFname + "')\n"; - pyCode += "bank_names = []\n"; - pyCode += "Difcs = []\n"; - pyCode += "Zeros = []\n"; - std::string templateFileVal = "None"; - if (!templateFile.empty()) { - templateFileVal = "'" + templateFile + "'"; - } - pyCode += "template_file = " + templateFileVal + "\n"; - for (size_t i = 0; i < difc.size(); i++) { - pyCode += "bank_names.append('" + bankNames[i] + "')\n"; - pyCode += - "Difcs.append(" + boost::lexical_cast<std::string>(difc[i]) + ")\n"; - pyCode += - "Zeros.append(" + boost::lexical_cast<std::string>(tzero[i]) + ")\n"; - } - pyCode += - "EnggUtils.write_ENGINX_GSAS_iparam_file(output_file=GSAS_iparm_fname, " - "bank_names=bank_names, difc=Difcs, tzero=Zeros, " - "template_file=template_file) \n"; - +std::string +EnggDiffractionViewQtGUI::enggRunPythonCode(const std::string &pyCode) { std::string status = runPythonCode(QString::fromStdString(pyCode), false).toStdString(); - // g_log.information() - // << "Saved output calibration file through Python. Status: " << status - // << std::endl; - m_logMsgs.push_back( - "Run Python code to save output file, with status string: " + status); - m_presenter->notify(IEnggDiffractionPresenter::LogMsg); + return status; } std::string EnggDiffractionViewQtGUI::askExistingCalibFilename() { diff --git a/MantidQt/CustomInterfaces/test/EnggDiffractionViewMock.h b/MantidQt/CustomInterfaces/test/EnggDiffractionViewMock.h index 58f7a800dca3bd0adaf9263f9bcfc9db4ab51520..648a5e88ab509679ed4d925d9c333da80285ac00 100644 --- a/MantidQt/CustomInterfaces/test/EnggDiffractionViewMock.h +++ b/MantidQt/CustomInterfaces/test/EnggDiffractionViewMock.h @@ -79,12 +79,8 @@ public: MOCK_METHOD3(newCalibLoaded, void(const std::string &, const std::string &, const std::string &)); - // virtual void writeOutCalibFile(const std::string &outFilename, - // const std::vector<double> &difc, - // const std::vector<double> &tzero) - MOCK_METHOD3(writeOutCalibFile, - void(const std::string &, const std::vector<double> &, - const std::vector<double> &)); + // virtual std::string enggRunPythonCode(const std::string &pyCode) + MOCK_METHOD1(enggRunPythonCode, std::string(const std::string &)); // virtual void enableTabs(bool enable); MOCK_METHOD1(enableTabs, void(bool)); @@ -165,7 +161,8 @@ public: // virtual void setDataVector MOCK_METHOD2(setDataVector, - void(std::vector<boost::shared_ptr<QwtData>> &data, bool focused)); + void(std::vector<boost::shared_ptr<QwtData>> &data, + bool focused)); // virtual void plotVanCurvesCalibOutput(); MOCK_METHOD0(plotVanCurvesCalibOutput, void());