diff --git a/Framework/WorkflowAlgorithms/src/ConvolutionFitSequential.cpp b/Framework/WorkflowAlgorithms/src/ConvolutionFitSequential.cpp index 9775f12ec5beea8f564ea1987a70a25e2c835827..425fa8ef950657bd4e75cb118e9e36237fc43b86 100644 --- a/Framework/WorkflowAlgorithms/src/ConvolutionFitSequential.cpp +++ b/Framework/WorkflowAlgorithms/src/ConvolutionFitSequential.cpp @@ -178,8 +178,11 @@ void ConvolutionFitSequential::exec() { } outputWsName += backType + "_s"; outputWsName += std::to_string(specMin); - outputWsName += "_to_"; - outputWsName += std::to_string(specMax); + + if (specMin != specMax) { + outputWsName += "_to_"; + outputWsName += std::to_string(specMax); + } // Convert input workspace to get Q axis const std::string tempFitWsName = "__convfit_fit_ws"; @@ -346,8 +349,12 @@ void ConvolutionFitSequential::exec() { Progress renamerProg(this, 0.98, 1.0, specMax + 1); for (int i = specMin; i < specMax + 1; i++) { renamer->setProperty("InputWorkspace", groupWsNames.at(i - specMin)); - auto outName = outputWsName + "_"; - outName += std::to_string(i); + auto outName = outputWsName; + + // Check if multiple spectrum were fit. + if (specMin != specMax) { + outName += "_" + std::to_string(i); + } outName += "_Workspace"; renamer->setProperty("OutputWorkspace", outName); renamer->executeAsChildAlg(); diff --git a/Framework/WorkflowAlgorithms/test/ConvolutionFitSequentialTest.h b/Framework/WorkflowAlgorithms/test/ConvolutionFitSequentialTest.h index 98a519c364c9fc6b9dc58b6add538eb22e6d946e..f4658eae0a25e4b84a1f8e5a9efed4fa978deb3a 100644 --- a/Framework/WorkflowAlgorithms/test/ConvolutionFitSequentialTest.h +++ b/Framework/WorkflowAlgorithms/test/ConvolutionFitSequentialTest.h @@ -234,15 +234,15 @@ public: // Assert that output is in ADS TS_ASSERT_THROWS_NOTHING( AnalysisDataService::Instance().retrieveWS<ITableWorkspace>( - "SqwWs_conv_1LFixF_s0_to_0_Parameters")); + "SqwWs_conv_1LFixF_s0_Parameters")); TS_ASSERT_THROWS_NOTHING( AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( - "SqwWs_conv_1LFixF_s0_to_0_Result")); + "SqwWs_conv_1LFixF_s0_Result")); TS_ASSERT_THROWS_NOTHING( AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( - "SqwWs_conv_1LFixF_s0_to_0_Workspaces")); + "SqwWs_conv_1LFixF_s0_Workspaces")); AnalysisDataService::Instance().clear(); } diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h index 8a740ad624991b49c6b31cf19667e427e9238665..fb21cc26c6d01702e7992ed35642c44e94a0f452 100644 --- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h +++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h @@ -42,9 +42,9 @@ private slots: void fixItem(); void unFixItem(); void showTieCheckbox(QString); + void sequentialFitComplete(bool error); void singleFitComplete(bool error); void fitFunctionSelected(const QString &); - void algorithmComplete(bool error); void saveClicked(); void plotClicked(); void plotCurrentPreview(); @@ -73,6 +73,10 @@ private: void initFABADAOptions(); void showFABADA(bool advanced); void hideFABADA(); + Mantid::API::IAlgorithm_sptr sequentialFit(const std::string &specMin, + const std::string &specMax, + QString &outputWSName); + void algorithmComplete(bool error, const QString &outputWSName); Ui::ConvFit m_uiForm; QtStringPropertyManager *m_stringManager; diff --git a/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp b/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp index 9b63403d39b1f8cfa2606fe7621748b7a18c438c..b2aa7771878b3aa4247608388244c489a18f3ead 100644 --- a/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp +++ b/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp @@ -279,29 +279,46 @@ void ConvFit::initFABADAOptions() { */ void ConvFit::run() { // Get input from interface - const auto func = createFunction(m_uiForm.ckTieCentres->isChecked()); - const auto function = std::string(func->asString()); m_runMin = m_uiForm.spSpectraMin->value(); m_runMax = m_uiForm.spSpectraMax->value(); const auto specMin = m_uiForm.spSpectraMin->text().toStdString(); const auto specMax = m_uiForm.spSpectraMax->text().toStdString(); + auto cfs = sequentialFit(specMin, specMax, m_baseName); + + // Add to batch alg runner and execute + m_batchAlgoRunner->addAlgorithm(cfs); + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, + SLOT(sequentialFitComplete(bool))); + m_batchAlgoRunner->executeBatchAsync(); +} + +IAlgorithm_sptr ConvFit::sequentialFit(const std::string &specMin, + const std::string &specMax, + QString &outputWSName) { + const auto func = createFunction(m_uiForm.ckTieCentres->isChecked()); + const auto function = std::string(func->asString()); // Construct expected name - m_baseName = QString::fromStdString(m_cfInputWS->getName()); + outputWSName = QString::fromStdString(m_cfInputWS->getName()); + // Remove _red - const auto cutIndex = m_baseName.lastIndexOf("_"); + const auto cutIndex = outputWSName.lastIndexOf("_"); if (cutIndex != -1) { - m_baseName = m_baseName.left(cutIndex + 1); + outputWSName = outputWSName.left(cutIndex + 1); } + // Add fit specific suffix const auto bgType = backgroundString(); const auto fitType = fitTypeString(); - m_baseName += "conv_"; - m_baseName += fitType; - m_baseName += bgType; - m_baseName += QString::fromStdString(specMin); - m_baseName += "_to_"; - m_baseName += QString::fromStdString(specMax); + outputWSName += "conv_"; + outputWSName += fitType; + outputWSName += bgType; + outputWSName += QString::fromStdString(specMin); + + if (specMin != specMax) { + outputWSName += "_to_"; + outputWSName += QString::fromStdString(specMax); + } // Run ConvolutionFitSequential Algorithm auto cfs = AlgorithmManager::Instance().create("ConvolutionFitSequential"); @@ -319,13 +336,14 @@ void ConvFit::run() { minimizerString("$outputname_$wsindex").toStdString()); cfs->setProperty("MaxIterations", static_cast<int>(m_dblManager->value( m_properties["MaxIterations"]))); - cfs->setProperty("OutputWorkspace", (m_baseName.toStdString() + "_Result")); + cfs->setProperty("OutputWorkspace", (outputWSName.toStdString() + "_Result")); + return cfs; +} - // Add to batch alg runner and execute - m_batchAlgoRunner->addAlgorithm(cfs); - connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, - SLOT(algorithmComplete(bool))); - m_batchAlgoRunner->executeBatchAsync(); +void ConvFit::sequentialFitComplete(bool error) { + disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, + SLOT(sequentialFitComplete(bool))); + algorithmComplete(error, m_baseName); } /** @@ -411,20 +429,20 @@ void ConvFit::plotCurrentPreview() { * Handles completion of the ConvolutionFitSequential algorithm. * * @param error True if the algorithm was stopped due to error, false otherwise +* @param outputWSName The name of the output workspace created from running the +* algorithm. */ -void ConvFit::algorithmComplete(bool error) { - disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, - SLOT(algorithmComplete(bool))); +void ConvFit::algorithmComplete(bool error, const QString &outputWSName) { if (error) return; - const auto resultName = m_baseName.toStdString() + "_Result"; + const auto resultName = outputWSName.toStdString() + "_Result"; MatrixWorkspace_sptr resultWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(resultName); // Name for GroupWorkspace - const auto groupName = m_baseName.toStdString() + "_Workspaces"; + const auto groupName = outputWSName.toStdString() + "_Workspaces"; // Add Sample logs for ResolutionFiles const auto resFile = m_uiForm.dsResInput->getCurrentDataName().toStdString(); addSampleLogsToWorkspace(resultName, "resolution_filename", resFile, @@ -1234,46 +1252,9 @@ void ConvFit::singleFit() { SLOT(singleFit(bool))); // ensure algorithm was successful m_uiForm.ckPlotGuess->setChecked(false); + std::string specNo = m_uiForm.spPlotSpectrum->text().toStdString(); - CompositeFunction_sptr function = - createFunction(m_uiForm.ckTieCentres->isChecked()); - - // get output name - QString fitType = fitTypeString(); - QString bgType = backgroundString(); - - if (fitType == "") { - g_log.error("No fit type defined."); - } - m_singleFitOutputName = - runPythonCode( - QString( - "from IndirectCommon import getWSprefix\nprint getWSprefix('") + - m_cfInputWSName + QString("')\n")).trimmed(); - m_singleFitOutputName += - QString("conv_") + fitType + bgType + m_uiForm.spPlotSpectrum->text(); - int maxIterations = - static_cast<int>(m_dblManager->value(m_properties["MaxIterations"])); - - // Run fit algorithm - m_singleFitAlg = AlgorithmManager::Instance().create("Fit"); - m_singleFitAlg->initialize(); - m_singleFitAlg->setPropertyValue("Function", function->asString()); - m_singleFitAlg->setPropertyValue("InputWorkspace", - m_cfInputWSName.toStdString()); - m_singleFitAlg->setProperty<int>("WorkspaceIndex", - m_uiForm.spPlotSpectrum->text().toInt()); - m_singleFitAlg->setProperty<double>( - "StartX", m_dblManager->value(m_properties["StartX"])); - m_singleFitAlg->setProperty<double>( - "EndX", m_dblManager->value(m_properties["EndX"])); - m_singleFitAlg->setProperty("Output", m_singleFitOutputName.toStdString()); - m_singleFitAlg->setProperty("CreateOutput", true); - m_singleFitAlg->setProperty("OutputCompositeMembers", true); - m_singleFitAlg->setProperty("ConvolveMembers", true); - m_singleFitAlg->setProperty("MaxIterations", maxIterations); - m_singleFitAlg->setProperty( - "Minimizer", minimizerString(m_singleFitOutputName).toStdString()); + m_singleFitAlg = sequentialFit(specNo, specNo, m_singleFitOutputName); // Connection to singleFitComplete SLOT (post algorithm completion) m_batchAlgoRunner->addAlgorithm(m_singleFitAlg); @@ -1291,117 +1272,7 @@ void ConvFit::singleFitComplete(bool error) { // Disconnect signal for single fit complete disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(singleFitComplete(bool))); - - if (error) { - showMessageBox("Fit algorithm failed."); - return; - } - - // Plot the line on the mini plot - m_uiForm.ppPlot->removeSpectrum("Guess"); - const auto resultName = m_singleFitOutputName + "_Workspace"; - m_previewPlotData = - AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( - resultName.toStdString()); - m_uiForm.ppPlot->addSpectrum("Fit", resultName, 1, Qt::red); - m_uiForm.ppPlot->addSpectrum("Diff", resultName, 2, Qt::blue); - - IFunction_const_sptr outputFunc = m_singleFitAlg->getProperty("Function"); - - QString functionName = m_uiForm.cbFitType->currentText(); - - // Get params. - QMap<QString, double> parameters; - const std::vector<std::string> parNames = outputFunc->getParameterNames(); - std::vector<double> parVals; - - QStringList params = getFunctionParameters(functionName); - params.reserve(static_cast<int>(parNames.size())); - - for (size_t i = 0; i < parNames.size(); ++i) - parVals.push_back(outputFunc->getParameter(parNames[i])); - - for (size_t i = 0; i < parNames.size(); ++i) - parameters[QString(parNames[i].c_str())] = parVals[i]; - - // Populate Tree widget with values - // Background should always be f0 - m_dblManager->setValue(m_properties["BGA0"], parameters["f0.A0"]); - m_dblManager->setValue(m_properties["BGA1"], parameters["f0.A1"]); - - const int fitTypeIndex = m_uiForm.cbFitType->currentIndex(); - - int funcIndex = 0; - int subIndex = 0; - - // check if we're using a temperature correction - if (m_uiForm.ckTempCorrection->isChecked() && - !m_uiForm.leTempCorrection->text().isEmpty()) { - subIndex++; - } - - const bool usingDeltaFunc = m_blnManager->value(m_properties["UseDeltaFunc"]); - - // If using a delta function with any fit type or using two Lorentzians - const bool usingCompositeFunc = - ((usingDeltaFunc && fitTypeIndex > 0) || fitTypeIndex == 2); - - const QString prefBase = "f1.f1."; - - if (usingDeltaFunc) { - QString key = prefBase; - if (usingCompositeFunc) { - key += "f0."; - } - - m_dblManager->setValue(m_properties["DeltaHeight"], - parameters[key + "Height"]); - m_dblManager->setValue(m_properties["DeltaCentre"], - parameters[key + "Centre"]); - funcIndex++; - } - - QString pref = prefBase; - - if (usingCompositeFunc) { - pref += "f" + QString::number(funcIndex) + ".f" + - QString::number(subIndex) + "."; - } else { - pref += "f" + QString::number(subIndex) + "."; - } - - if (fitTypeIndex == 2) { - functionName = "Lorentzian 1"; - for (auto it = params.begin(); it != params.end() - 3; ++it) { - const QString functionParam = functionName + "." + *it; - const QString paramValue = pref + *it; - m_dblManager->setValue(m_properties[functionParam], - parameters[paramValue]); - } - funcIndex++; - pref = prefBase; - pref += "f" + QString::number(funcIndex) + ".f" + - QString::number(subIndex) + "."; - - functionName = "Lorentzian 2"; - - for (auto it = params.begin() + 3; it != params.end(); ++it) { - const QString functionParam = functionName + "." + *it; - const QString paramValue = pref + *it; - m_dblManager->setValue(m_properties[functionParam], - parameters[paramValue]); - } - - } else { - for (auto it = params.begin(); it != params.end(); ++it) { - const QString functionParam = functionName + "." + *it; - const QString paramValue = pref + *it; - m_dblManager->setValue(m_properties[functionParam], - parameters[paramValue]); - } - } - - m_pythonExportWsName = ""; + algorithmComplete(error, m_singleFitOutputName); } /** diff --git a/docs/source/release/v3.11.0/indirect_inelastic.rst b/docs/source/release/v3.11.0/indirect_inelastic.rst index 20a580a73e0fb3f7dd851066a391ae2fafb05eb9..78794c8dcecefc699dd6b5ea2f1765ebd60b63be 100644 --- a/docs/source/release/v3.11.0/indirect_inelastic.rst +++ b/docs/source/release/v3.11.0/indirect_inelastic.rst @@ -26,6 +26,7 @@ Jump Fit Improvements ------------ - The *S(Q, W)* interface now automatically replaces NaN values with 0. +- EISF is now generated when performing a Single Fit, with a delta function, in the ConvFit interface. - :ref:`FlatPlatePaalmanPingsCorrection <algm-FlatPlatePaalmanPingsCorrection>` now supports `Direct` and `Indirect` modes.