diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp index 7a4a592d47f1f4ef518fc733668b8c64baae2e1e..726eaa68c4a38fd1689c99e0fdd1757e25ba20ce 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp @@ -455,11 +455,11 @@ std::string MuonAnalysis::addItem(ItemType itemType, int tableRow, std::vector<std::string> wsNames = {wsName, wsRawName}; // Create workspace and a raw (unbinned) version of it auto ws = createAnalysisWorkspace(itemType, tableRow, plotType, wsName); - moveUnNormWS(wsName, wsNames); + moveUnNormWS(wsName, wsNames,false); auto wsRaw = createAnalysisWorkspace(itemType, tableRow, plotType, wsRawName, true); - moveUnNormWS(wsRawName, wsNames); + moveUnNormWS(wsName, wsNames,true);//raw // Make sure they end up in the ADS ads.addOrReplace(wsName, ws); ads.addOrReplace(wsRawName, wsRaw); @@ -469,9 +469,12 @@ std::string MuonAnalysis::addItem(ItemType itemType, int tableRow, } void MuonAnalysis::moveUnNormWS(const std::string &name, - std::vector<std::string> &wsNames) { + std::vector<std::string> &wsNames,bool raw) { AnalysisDataServiceImpl &ads = AnalysisDataService::Instance(); - const std::string unnorm = "_unNorm"; + std::string unnorm = "_unNorm"; + if (raw) { + unnorm += "_Raw"; + } if (ads.doesExist("tmp_unNorm")) { ads.rename("tmp_unNorm", name + unnorm); wsNames.push_back(name + unnorm); diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.h b/qt/scientific_interfaces/Muon/MuonAnalysis.h index 38ad81af44730e52a7b4b9bc52ae57f825e500aa..c76ac9b0a80db74518aa5e3b7b2dec27e06da947 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.h +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.h @@ -266,7 +266,7 @@ private slots: void updateNormalization(QString name); private: - void moveUnNormWS(const std::string &name, std::vector<std::string> &wsNames); + void moveUnNormWS(const std::string &name, std::vector<std::string> &wsNames,bool raw); bool getIfTFAsymmStore() const; /// Initialize local Python environment void initLocalPython() override; diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp index 26e70eb1899c26d7d1fe4cf37a0811a85e7e4a2b..50a6ae418bbbf8349875a372497e92c407409515 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp @@ -238,9 +238,19 @@ void MuonAnalysisFitDataPresenter::createWorkspacesToFit( if (Mantid::API::AnalysisDataService::Instance().doesExist( "tmp_unNorm")) { const std::string unnorm = "_unNorm"; + std::string wsName = name; + auto raw = wsName.find("_Raw"); + + if (raw == std::string::npos) { + wsName += unnorm; + } + else { + wsName.insert(raw, unnorm); + } + Mantid::API::AnalysisDataService::Instance().rename("tmp_unNorm", - name + unnorm); - MuonAnalysisHelper::groupWorkspaces(groupLabel, {name + unnorm}); + wsName); + MuonAnalysisHelper::groupWorkspaces(groupLabel, {wsName}); } } } diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FitPropertyBrowser.h index 0d052a1f7babeadf63c132599fa3b57ea518d6cd..876966aa87f56d4ac2522fda210ab5aaf28855b4 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/FitPropertyBrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FitPropertyBrowser.h @@ -396,7 +396,8 @@ protected: void setWorkspaceProperties(); /// Adds the workspace index property to the browser. virtual void addWorkspaceIndexToBrowser(); - + /// Set the parameters to the fit outcome + void getFitResults(); /// Create a double property and set some settings QtProperty * addDoubleProperty(const QString &name, @@ -503,8 +504,7 @@ private: virtual bool isWorkspaceValid(Mantid::API::Workspace_sptr) const; /// Find QtBrowserItem for a property prop among the chidren of QtBrowserItem *findItem(QtBrowserItem *parent, QtProperty *prop) const; - /// Set the parameters to the fit outcome - void getFitResults(); + /// disable undo when the function changes void disableUndo(); /// Enable/disable the Fit button; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h index 7ca8a75d3960b0b51bfcfd3d248dc03ea857b95a..e3cc2591321503259e28c435936b737a7fc17e29 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h @@ -189,6 +189,8 @@ private: /// workspaces void finishAfterSimultaneousFit(const Mantid::API::IAlgorithm *fitAlg, const int nWorkspaces) const; + void finishAfterTFSimultaneousFit(const Mantid::API::IAlgorithm *alg, const std::string baseName) const; + std::string getUnnormName(const std::string wsName); void setTFAsymmMode(bool state); void clearGroupCheckboxes(); diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index a129050336e3a227fa6effc165b87bd10d34f374..434ad246d6952c6825b3c7fc4142875d220d8e8c 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -663,18 +663,35 @@ void MuonFitPropertyBrowser::populateFunctionNames() { } } } +std::string MuonFitPropertyBrowser::getUnnormName(std::string wsName) { + if (wsName.find(UNNORM) == std::string::npos) { + auto raw = wsName.find("_Raw"); + + if (raw == std::string::npos) { + wsName += TFExtension(); + } + else { + wsName.insert(raw, UNNORM); + } + } + if (rawData() && wsName.find("_Raw") == std::string::npos) { + wsName += "_Raw"; + } + return wsName; +} + /** * Creates an instance of Fit algorithm, sets its properties and launches it. */ void MuonFitPropertyBrowser::doTFAsymmFit() { - std::string wsName = workspaceName(); + std::string wsName = workspaceName(); + wsName = getUnnormName(wsName); if (wsName.empty()) { QMessageBox::critical(this, "Mantid - Error", "Workspace name is not set"); return; } try { - auto fa = m_compositeFunction->asString(); m_initialParameters.resize(compositeFunction()->nParams()); for (size_t i = 0; i < compositeFunction()->nParams(); i++) { m_initialParameters[i] = compositeFunction()->getParameter(i); @@ -699,22 +716,41 @@ void MuonFitPropertyBrowser::doTFAsymmFit() { IAlgorithm_sptr alg = AlgorithmManager::Instance().create("CalculateMuonAsymmetry"); alg->initialize(); - + auto fa = m_compositeFunction->asString(); + if (m_compositeFunction->nFunctions() > 1) { + + alg->setProperty("InputFunction", boost::dynamic_pointer_cast<IFunction>( + m_compositeFunction)); + } + else { alg->setProperty("InputFunction", boost::dynamic_pointer_cast<IFunction>( m_compositeFunction->getFunction(0))); - - std::string tmpWSName = wsName; - if (rawData()) { - tmpWSName += "_Raw"; } + std::string tmpWSName = wsName; + if (m_boolManager->value(m_TFAsymmMode) && tmpWSName.find(UNNORM)) { tmpWSName += TFExtension(); } - + if (rawData()) { + tmpWSName += "_Raw"; + } auto unnorm = m_workspacesToFit; std::string tmp = UNNORM; - std::for_each(unnorm.begin(), unnorm.end(),[tmp](std::string& str) {str += UNNORM; }); + bool raw = rawData(); + std::for_each(unnorm.begin(), unnorm.end(),[tmp,raw](std::string& wsName) { if (wsName.find(UNNORM) == std::string::npos) { + auto rawIndex = wsName.find("_Raw"); + + if (rawIndex == std::string::npos) { + wsName += UNNORM; + } + else { + wsName.insert(rawIndex, UNNORM); + } + } + if (raw && wsName.find("_Raw") == std::string::npos) { + wsName += "_Raw"; + } }); alg->setProperty("UnNormalizedWorkspaceList", unnorm); alg->setProperty("ReNormalizedWorkspaceList", m_workspacesToFit); @@ -727,10 +763,13 @@ void MuonFitPropertyBrowser::doTFAsymmFit() { // If we are doing a simultaneous fit, set this up here const int nWorkspaces = static_cast<int>(m_workspacesToFit.size()); + std::string output = outputName(); if (nWorkspaces == 1) { setSingleFitLabel(wsName); + output = getUnnormName(output); } - alg->setPropertyValue("OutputFitWorkspace", outputName()); + + alg->setPropertyValue("OutputFitWorkspace", output); observeFinish(alg); alg->execute(); @@ -1052,13 +1091,61 @@ void MuonFitPropertyBrowser::finishHandle(const IAlgorithm *alg) { } } void MuonFitPropertyBrowser::finishHandleTF(const IAlgorithm *alg) { + + // Copy experiment info to output workspace + if (AnalysisDataService::Instance().doesExist(outputName() + "_Workspace")) { + // Input workspace should be a MatrixWorkspace according to isWorkspaceValid + auto inWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( + static_cast<std::string>(alg->getProperty("UnNormalizedWorkspaceList"))); + auto outWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( + outputName() + "_Workspace"); + if (inWs && outWs) { + outWs->copyExperimentInfoFrom(inWs.get()); + } + } + else if (AnalysisDataService::Instance().doesExist(outputName() + + "_Workspaces")) { + // Output workspace was a group + auto outGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( + outputName() + "_Workspaces"); + if (outGroup->size() == m_workspacesToFit.size()) { + for (size_t i = 0; i < outGroup->size(); i++) { + auto outWs = + boost::dynamic_pointer_cast<MatrixWorkspace>(outGroup->getItem(i)); + auto inWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( + m_workspacesToFit[i]); + if (inWs && outWs) { + outWs->copyExperimentInfoFrom(inWs.get()); + } + } + } + } + + auto tfsdaf = alg->getPropertyValue("OutputStatus"); auto status = QString::fromStdString(alg->getPropertyValue("OutputStatus")); emit fitResultsChanged(status); + FitPropertyBrowser::fitResultsChanged(status); //need to add errors and values to browser //m_functionBrowser->setParamError() - // need to work out magic grouping - auto &ads = AnalysisDataService::Instance(); + // If fit was simultaneous, insert extra information into params table + // and group the output workspaces + const int nWorkspaces = static_cast<int>(m_workspacesToFit.size()); + if (nWorkspaces > 1) { + std::string baseName = outputName(); + finishAfterTFSimultaneousFit(alg, baseName); + getFitResults(); + std::vector<std::string> wsList = alg->getProperty("UnNormalizedWorkspaceList"); + emit fittingDone(QString::fromStdString(wsList[0])); + } + else { + getFitResults(); + std::vector<std::string> wsList = alg->getProperty("UnNormalizedWorkspaceList"); + emit fittingDone(QString::fromStdString(wsList[0])); + emit algorithmFinished(QString::fromStdString(wsList[0] + "_workspace")); + } + // magic grouping code + /*auto &ads = AnalysisDataService::Instance(); const QString wsName = QString::fromStdString(workspaceName()); std::string groupName; const int index = wsName.indexOf(';'); @@ -1103,7 +1190,7 @@ void MuonFitPropertyBrowser::finishHandleTF(const IAlgorithm *alg) { groupingAlg->setProperty("InputWorkspaces", inputWorkspaces); groupingAlg->setPropertyValue("OutputWorkspace", groupName); groupingAlg->execute(); - } + }*/ } void MuonFitPropertyBrowser::finishHandleNormal(const IAlgorithm *alg) { // Copy experiment info to output workspace @@ -1151,6 +1238,7 @@ void MuonFitPropertyBrowser::finishHandleNormal(const IAlgorithm *alg) { * @param fitAlg :: [input] Pointer to fit algorithm that just finished * @param nWorkspaces :: [input] Number of workspaces that were fitted */ +// need own version of this void MuonFitPropertyBrowser::finishAfterSimultaneousFit( const Mantid::API::IAlgorithm *fitAlg, const int nWorkspaces) const { AnalysisDataServiceImpl &ads = AnalysisDataService::Instance(); @@ -1190,6 +1278,52 @@ void MuonFitPropertyBrowser::finishAfterSimultaneousFit( } } +/** +* After a simultaneous fit, insert extra information into parameters table +* (i.e. what runs, groups, periods "f0", "f1" etc were) +* and group the output workspaces +* @param fitAlg :: [input] Pointer to fit algorithm that just finished +* @param nWorkspaces :: [input] Number of workspaces that were fitted +*/ +// need own version of this +void MuonFitPropertyBrowser::finishAfterTFSimultaneousFit( + const Mantid::API::IAlgorithm *alg, const std::string baseName) const { + AnalysisDataServiceImpl &ads = AnalysisDataService::Instance(); + try { + std::vector<std::string> wsList = alg->getProperty("UnNormalizedWorkspaceList"); + std::string paramTableName = baseName + "_Parameters"; + const auto paramTable = ads.retrieveWS<ITableWorkspace>(paramTableName); + if (paramTable) { + for (int i = 0; i < wsList.size(); i++) { + const std::string suffix = boost::lexical_cast<std::string>(i); + + const auto wsName = + wsList[i]; + Mantid::API::TableRow row = paramTable->appendRow(); + row << "f" + suffix + "=" + wsName << 0.0 << 0.0; + } + } + } + catch (const Mantid::Kernel::Exception::NotFoundError &) { + // Not a fatal error, but shouldn't happen + g_log.warning( + "Could not find output parameters table for simultaneous fit"); + } + + // Group output together + + std::string groupName = baseName; + // Create a group for label + try { + ads.addOrReplace(groupName, boost::make_shared<WorkspaceGroup>()); + ads.addToGroup(groupName, baseName + "_NormalisedCovarianceMatrix"); + ads.addToGroup(groupName, baseName + "_Parameters"); + ads.addToGroup(groupName, baseName + "_Workspaces"); + } + catch (const Mantid::Kernel::Exception::NotFoundError &err) { + g_log.warning(err.what()); + } +} /** * Adds an extra widget in between the fit buttons and the browser * @param widget :: [input] Pointer to widget to add @@ -1405,7 +1539,14 @@ void MuonFitPropertyBrowser::updateTFPlot(){ int j = m_enumManager->value(m_workspace); std::string option = m_workspaceNames[j].toStdString(); if (m_boolManager->value(m_TFAsymmMode) && option.find(UNNORM)==std::string::npos) { - option += TFExtension(); + auto raw=option.find("_Raw"); + + if ( raw== std::string::npos) { + option += TFExtension(); + } + else { + option.insert(raw,UNNORM); + } } // update plot emit TFPlot(QString::fromStdString(option));