16#include "MantidQtWidgets/Common/QtPropertyBrowser/StringEditorFactory.h"
22#if defined(__INTEL_COMPILER)
23#pragma warning disable 1125
24#elif defined(__GNUC__)
25#if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 6)
26#pragma GCC diagnostic push
28#pragma GCC diagnostic ignored "-Woverloaded-virtual"
30#include "MantidQtWidgets/Common/QtPropertyBrowser/DoubleEditorFactory.h"
31#include "MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h"
32#if defined(__INTEL_COMPILER)
33#pragma warning enable 1125
34#elif defined(__GNUC__)
35#if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 6)
36#pragma GCC diagnostic pop
47#include "MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h"
48#include "MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h"
50#include <Poco/ActiveResult.h>
65#include <QSignalMapper>
66#include <QTableWidgetItem>
71const QString CUSTOM_LABEL{
"Custom"};
72const QString ALL_GROUPS_LABEL{
"All Groups"};
73const QString ALL_PAIRS_LABEL{
"All Pairs"};
74const QString ALL_PERIODS_LABEL{
"All Periods"};
75const std::string UNNORM =
"_unNorm";
79namespace MantidWidgets {
91 :
FitPropertyBrowser(parent, mantidui), m_widgetSplitter(nullptr), m_mainSplitter(nullptr),
92 m_isMultiFittingMode(false) {}
98 QWidget *w =
new QWidget(
this);
101 settings.beginGroup(
"Mantid/FitBrowser");
104 QtProperty *functionsGroup =
m_groupManager->addProperty(
"Functions");
105 QtProperty *settingsGroup(
nullptr);
110 QSettings multiFitSettings;
111 multiFitSettings.beginGroup(
"");
114 QtProperty *multiFitSettingsGroup(
nullptr);
127 bool keepNorm = settings.value(
"Fix Normalization", QVariant(
false)).toBool();
136 <<
"Conjugate gradient (Fletcher-Reeves imp.)"
137 <<
"Conjugate gradient (Polak-Ribiere imp.)"
142 <<
"Ignore positive peaks";
146 bool plotDiff = settings.value(
"Plot Difference", QVariant(
true)).toBool();
150 m_evaluationType->setToolTip(
"Consider using Histogram fit which may produce more accurate results.");
154 int evaluationType = settings.value(
m_evaluationType->propertyName(), 0).toInt();
159 settingsGroup->addSubProperty(
m_startX);
160 settingsGroup->addSubProperty(
m_endX);
168 multiFitSettingsGroup->addSubProperty(
m_startX);
169 multiFitSettingsGroup->addSubProperty(
m_endX);
176 multiFitSettingsGroup->addSubProperty(
m_showGroup);
207 m_btnGroup =
new QGroupBox(tr(
"Reselect Data"));
208 auto *btnLayout =
new QHBoxLayout;
233 QtProperty *customSettingsGroup =
m_groupManager->addProperty(
"Settings");
236 bool data = settings.value(
"Fit To Raw Data", QVariant(
false)).toBool();
241 bool showParamErrors = settings.value(
m_showParamErrors->propertyName(),
true).toBool();
246 bool TFAsymmMode = settings.value(
"TF Asymmetry Mode", QVariant(
false)).toBool();
251 customSettingsGroup->addSubProperty(
m_plotDiff);
252 customSettingsGroup->addSubProperty(
m_rawData);
263 m_widgetSplitter->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding);
273 auto parentLayout = qobject_cast<QVBoxLayout *>(w->layout());
275 const int index = parentLayout->count() - 1;
276 constexpr int stretchFactor = 10;
279 parentLayout->setSpacing(0);
280 parentLayout->setMargin(0);
281 parentLayout->setContentsMargins(0, 0, 0, 0);
338 if (this->isVisible()) {
339 g_log.
error(
"No Data available. Please load Some data.");
349 if (option == ALL_GROUPS_LABEL) {
352 }
else if (option == ALL_PAIRS_LABEL) {
355 }
else if (option == CUSTOM_LABEL) {
364 if (option == CUSTOM_LABEL) {
367 }
else if (option == ALL_PERIODS_LABEL) {
372 if (option == iter.key()) {
393 for (
int k = 0; k < 4; k++) {
394 end = option.find_first_of(
";");
395 option = option.substr(end + 1, option.size());
397 end = option.find_first_of(
";");
398 QString selectedPeriod = QString::fromStdString(option.substr(0, end));
401 m_boolManager->setValue(iter.value(), selectedPeriod == iter.key());
408 for (
int k = 0; k < 2; k++) {
409 end = option.find_first_of(
";");
410 option = option.substr(end + 1, option.size());
412 end = option.find_first_of(
";");
414 boost::erase_all(option,
" ");
416 auto tmp = option.substr(0, end - 1);
417 QString selectedGroup = QString::fromStdString(
tmp);
420 m_boolManager->setValue(iter.value(), selectedGroup == iter.key());
445 tmp.replaceInStrings(QRegExp(
","),
"+");
468 }
else if (prop ==
m_endX) {
482 if (prop->propertyName() ==
"LowerBound") {
485 }
else if (prop->propertyName() ==
"UpperBound") {
504 std::string
tmp = name;
509 std::replace(
tmp.begin(),
tmp.end(),
' ',
';');
510 auto it = norms.find(
tmp);
511 if (it == norms.end()) {
512 label = QString::fromStdString(
"N/A");
514 label = QString::number(it->second);
540 std::string
tmp = name;
545 std::replace(
tmp.begin(),
tmp.end(),
' ',
';');
546 auto it = norms.find(
tmp);
547 if (it != norms.end()) {
552 table->addColumn(
"double",
"norm");
553 table->addColumn(
"int",
"spectra");
564 if (iter.value() == prop) {
573 if (iter.value() == prop) {
595 for (
auto fnName : names) {
596 QString qfnName = QString::fromStdString(fnName);
597 if (qfnName ==
"MultiBG")
601 const std::vector<std::string> categories = f->categories();
603 for (
const auto &category : categories) {
604 if ((category ==
"Muon") || (category ==
"General") || (category ==
"Background"))
622 if (wsName.find(UNNORM) == std::string::npos) {
623 auto raw = wsName.find(
"_Raw");
625 if (raw == std::string::npos) {
628 wsName.insert(raw, UNNORM);
631 if (
rawData() && wsName.find(
"_Raw") == std::string::npos) {
643 if (wsName.empty()) {
644 QMessageBox::critical(
this,
"Mantid - Error",
"Workspace name is not set");
675 alg->setProperty(
"InputFunction", std::dynamic_pointer_cast<IFunction>(
m_compositeFunction->getFunction(0)));
679 std::string
tmp = UNNORM;
681 std::for_each(unnorm.begin(), unnorm.end(), [
tmp, raw](std::string &wsName) {
682 if (wsName.find(UNNORM) == std::string::npos) {
683 auto rawIndex = wsName.find(
"_Raw");
685 if (rawIndex == std::string::npos) {
688 wsName.insert(rawIndex, UNNORM);
691 if (raw && wsName.find(
"_Raw") == std::string::npos) {
696 alg->setProperty(
"UnNormalizedWorkspaceList", unnorm);
698 alg->setProperty(
"NormalizationTable",
"MuonAnalysisTFNormalizations");
700 alg->setProperty(
"StartX",
startX());
701 alg->setProperty(
"EndX",
endX());
702 alg->setPropertyValue(
"Minimizer",
minimizer());
707 if (nWorkspaces == 1) {
712 alg->setPropertyValue(
"OutputFitWorkspace", output);
717 }
catch (
const std::exception &e) {
718 QString msg =
"CalculateMuonAsymmetry algorithm failed.\n\n" + QString(e.what()) +
"\n";
719 QMessageBox::critical(
this,
"Mantid - Error", msg);
727 std::map<std::string, double> norm;
728 if (AnalysisDataService::Instance().doesExist(
"MuonAnalysisTFNormalizations")) {
731 auto colNorm = table->getColumn(
"norm");
732 auto colName = table->getColumn(
"name");
733 for (
size_t j = 0; j < table->rowCount(); j++) {
734 norm[colName->cell<std::string>(j)] = ((*colNorm)[j]);
742void MuonFitPropertyBrowser::fit() { emit preFitChecksRequested(
false); }
747void MuonFitPropertyBrowser::runFit() {
748 std::string wsName = workspaceName();
749 if (wsName.empty()) {
750 QMessageBox::critical(
this,
"Mantid - Error",
"Workspace name is not set");
754 m_initialParameters.resize(compositeFunction()->nParams());
755 for (
size_t i = 0; i < compositeFunction()->nParams(); i++) {
756 m_initialParameters[i] = compositeFunction()->getParameter(i);
758 m_fitActionUndoFit->setEnabled(
true);
762 if (m_workspacesToFit.size() < 2) {
763 if (AnalysisDataService::Instance().doesExist(wsName +
"_NormalisedCovarianceMatrix")) {
764 FrameworkManager::Instance().deleteWorkspace(wsName +
"_NormalisedCovarianceMatrix");
766 if (AnalysisDataService::Instance().doesExist(wsName +
"_Parameters")) {
767 FrameworkManager::Instance().deleteWorkspace(wsName +
"_Parameters");
769 if (AnalysisDataService::Instance().doesExist(wsName +
"_Workspace")) {
770 FrameworkManager::Instance().deleteWorkspace(wsName +
"_Workspace");
776 if (m_compositeFunction->name() ==
"MultiBG") {
777 alg->setPropertyValue(
"Function",
"");
778 }
else if (m_compositeFunction->nFunctions() > 1) {
779 alg->setProperty(
"Function", std::dynamic_pointer_cast<IFunction>(m_compositeFunction));
781 alg->setProperty(
"Function", std::dynamic_pointer_cast<IFunction>(m_compositeFunction->getFunction(0)));
784 alg->setPropertyValue(
"InputWorkspace", wsName +
"_Raw");
786 alg->setPropertyValue(
"InputWorkspace", wsName);
787 alg->setProperty(
"WorkspaceIndex", workspaceIndex());
788 alg->setProperty(
"StartX", startX());
789 alg->setProperty(
"EndX", endX());
790 alg->setPropertyValue(
"Minimizer", minimizer());
791 alg->setPropertyValue(
"CostFunction", costFunction());
794 const int nWorkspaces =
static_cast<int>(m_workspacesToFit.size());
795 if (nWorkspaces > 1) {
796 alg->setPropertyValue(
"InputWorkspace", m_workspacesToFit[0]);
797 for (
int i = 1; i < nWorkspaces; i++) {
798 std::string suffix = boost::lexical_cast<std::string>(i);
799 alg->setPropertyValue(
"InputWorkspace_" + suffix, m_workspacesToFit[i]);
800 alg->setProperty(
"WorkspaceIndex_" + suffix, workspaceIndex());
801 alg->setProperty(
"StartX_" + suffix, startX());
802 alg->setProperty(
"EndX_" + suffix, endX());
805 setSingleFitLabel(wsName);
807 alg->setPropertyValue(
"Output", outputName());
811 }
catch (
const std::exception &e) {
812 QString msg =
"Fit algorithm failed.\n\n" + QString(e.what()) +
"\n";
813 QMessageBox::critical(
this,
"Mantid - Error", msg);
820void MuonFitPropertyBrowser::runSequentialFit() { emit sequentialFitRequested(); }
825void MuonFitPropertyBrowser::sequentialFit() { emit preFitChecksRequested(
true); }
830void MuonFitPropertyBrowser::showEvent(QShowEvent *e) {
833 populateWorkspaceNames();
841 QString workspaceName(QString::fromStdString(ws->getName()));
843 if ((workspaceName.contains(
"_Raw")) || (workspaceName.contains(
"MuonAnalysis")))
847 if (workspaceName.endsWith(
"_Workspace"))
853void MuonFitPropertyBrowser::setFitWorkspaces(
const std::string &input) {
855 if (AnalysisDataService::Instance().doesExist(outputName() +
"_Workspace")) {
857 auto inWs = AnalysisDataService::Instance().retrieveWS<
MatrixWorkspace>(input);
858 auto outWs = AnalysisDataService::Instance().retrieveWS<
MatrixWorkspace>(outputName() +
"_Workspace");
862 }
else if (AnalysisDataService::Instance().doesExist(outputName() +
"_Workspaces")) {
864 auto outGroup = AnalysisDataService::Instance().retrieveWS<
WorkspaceGroup>(outputName() +
"_Workspaces");
865 if (outGroup->size() == m_workspacesToFit.size()) {
866 for (
size_t i = 0; i < outGroup->size(); i++) {
867 auto outWs = std::dynamic_pointer_cast<MatrixWorkspace>(outGroup->getItem(i));
868 auto inWs = AnalysisDataService::Instance().retrieveWS<
MatrixWorkspace>(m_workspacesToFit[i]);
877void MuonFitPropertyBrowser::finishHandle(
const IAlgorithm *alg) {
878 if (alg->
name() ==
"CalculateMuonAsymmetry") {
881 finishHandleNormal(alg);
884void MuonFitPropertyBrowser::finishHandleTF(
const IAlgorithm *alg) {
886 setFitWorkspaces(
static_cast<std::string
>(alg->
getProperty(
"UnNormalizedWorkspaceList")));
888 auto status = QString::fromStdString(alg->
getPropertyValue(
"OutputStatus"));
889 emit fitResultsChanged(status);
890 FitPropertyBrowser::fitResultsChanged(status);
894 const int nWorkspaces =
static_cast<int>(m_workspacesToFit.size());
895 if (nWorkspaces > 1) {
896 std::string baseName = outputName();
897 finishAfterTFSimultaneousFit(alg, baseName);
901 std::vector<std::string> wsList = alg->
getProperty(
"UnNormalizedWorkspaceList");
902 emit fittingDone(QString::fromStdString(wsList[0]));
906 emit changeWindowTitle(QString(
"Fit Function (") +
"Chi-sq " +
" = " + QString::number(quality) +
", " + status +
908 if (nWorkspaces == 1) {
909 emit algorithmFinished(QString::fromStdString(wsList[0] +
"_workspace"));
912void MuonFitPropertyBrowser::finishHandleNormal(
const IAlgorithm *alg) {
914 setFitWorkspaces(
static_cast<std::string
>(alg->
getProperty(
"InputWorkspace")));
917 const int nWorkspaces =
static_cast<int>(m_workspacesToFit.size());
918 if (nWorkspaces > 1) {
919 finishAfterSimultaneousFit(alg, nWorkspaces);
922 FitPropertyBrowser::finishHandle(alg);
934 const int nWorkspaces)
const {
937 const std::string paramTableName = fitAlg->
getProperty(
"OutputParameters");
942 for (
int i = 1; i < nWorkspaces; i++) {
943 const std::string suffix = boost::lexical_cast<std::string>(i);
947 row <<
"f" + suffix +
"=" + wsName << 0.0 << 0.0;
952 g_log.
warning(
"Could not find output parameters table for simultaneous fit");
957 const std::string &baseName = groupName;
961 ads.
addOrReplace(groupName, std::make_shared<WorkspaceGroup>());
962 ads.
addToGroup(groupName, baseName +
"_NormalisedCovarianceMatrix");
963 ads.
addToGroup(groupName, baseName +
"_Parameters");
964 ads.
addToGroup(groupName, baseName +
"_Workspaces");
978 const std::string &baseName)
const {
981 std::vector<std::string> wsList = alg->
getProperty(
"UnNormalizedWorkspaceList");
982 std::string paramTableName = baseName +
"_Parameters";
985 for (
size_t i = 0; i < wsList.size(); i++) {
986 const std::string suffix = boost::lexical_cast<std::string>(i);
988 const auto wsName = wsList[i];
990 row <<
"f" + suffix +
"=" + wsName << 0.0 << 0.0;
995 g_log.
warning(
"Could not find output parameters table for simultaneous fit");
1000 std::string groupName = baseName;
1003 ads.
addOrReplace(groupName, std::make_shared<WorkspaceGroup>());
1004 ads.
addToGroup(groupName, baseName +
"_NormalisedCovarianceMatrix");
1005 ads.
addToGroup(groupName, baseName +
"_Parameters");
1006 ads.
addToGroup(groupName, baseName +
"_Workspaces");
1015void MuonFitPropertyBrowser::addExtraWidget(QWidget *widget) {
1016 widget->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding);
1017 if (m_widgetSplitter) {
1018 m_widgetSplitter->addWidget(widget);
1026void MuonFitPropertyBrowser::setFunction(
const IFunction_sptr func) { createCompositeFunction(func); }
1032void MuonFitPropertyBrowser::setWorkspaceNames(
const QStringList &wsNames) {
1033 m_workspacesToFit.clear();
1034 std::transform(wsNames.begin(), wsNames.end(), std::back_inserter(m_workspacesToFit),
1035 [](
const QString &qs) { return qs.toStdString(); });
1037 emit workspacesToFitChanged(
static_cast<int>(m_workspacesToFit.size()));
1047std::string MuonFitPropertyBrowser::outputName()
const {
1048 const int nWorkspaces =
static_cast<int>(m_workspacesToFit.size());
1049 if (nWorkspaces > 1) {
1051 return SIMULTANEOUS_PREFIX + m_simultaneousLabel;
1055 return FitPropertyBrowser::outputName();
1068void MuonFitPropertyBrowser::setMultiFittingMode(
bool enabled) {
1069 m_isMultiFittingMode = enabled;
1076 setAutoBackgroundName(
"");
1079 if (m_autoBackground !=
"") {
1080 setAutoBackgroundName(m_autoBackground);
1081 addAutoBackground();
1083 clearChosenGroups();
1084 clearChosenPeriods();
1087 m_browser->setItemVisible(m_functionsGroup, !enabled);
1088 m_browser->setItemVisible(m_settingsGroup, !enabled);
1089 m_browser->setItemVisible(m_multiFitSettingsGroup, enabled);
1090 m_btnGroup->setVisible(enabled);
1092 for (
int i = 0; i < m_widgetSplitter->count(); ++i) {
1093 if (
auto *widget = m_widgetSplitter->widget(i)) {
1094 widget->setVisible(enabled);
1098 setFitEnabled(
false);
1107bool MuonFitPropertyBrowser::isMultiFittingMode()
const {
return m_isMultiFittingMode; }
1108void MuonFitPropertyBrowser::ConvertFitFunctionForMuonTFAsymmetry(
bool enabled) {
1110 IAlgorithm_sptr alg = AlgorithmManager::Instance().create(
"ConvertFitFunctionForMuonTFAsymmetry");
1112 if (AnalysisDataService::Instance().doesExist(
"MuonAnalysisTFNormalizations") &&
1113 m_compositeFunction->nFunctions() > 0) {
1115 IFunction_sptr old = std::dynamic_pointer_cast<IFunction>(m_compositeFunction);
1117 QStringList globals;
1119 if (m_isMultiFittingMode) {
1121 old = m_functionBrowser->getGlobalFunction();
1122 globals = m_functionBrowser->getGlobalParameters();
1123 }
else if (!enabled && !m_isMultiFittingMode) {
1124 old = std::dynamic_pointer_cast<CompositeFunction>(old);
1126 alg->setProperty(
"InputFunction", old);
1127 alg->setProperty(
"NormalizationTable",
"MuonAnalysisTFNormalizations");
1128 alg->setProperty(
"WorkspaceList", m_workspacesToFit);
1129 std::string mode = (enabled) ?
"Construct" :
"Extract";
1130 alg->setProperty(
"Mode", mode);
1132 if (!alg->isExecuted()) {
1138 if (m_isMultiFittingMode) {
1140 if (func->getNumberDomains() > 1) {
1141 auto tmp = std::dynamic_pointer_cast<MultiDomainFunction>(func);
1142 old =
tmp->getFunction(0);
1146 m_functionBrowser->setFunction(old);
1148 QStringList newGlobals;
1149 const std::string INSERT_FUNCTION{
"f0.f1.f1."};
1151 for (
auto global : globals) {
1152 newGlobals << QString::fromStdString(INSERT_FUNCTION) + global;
1155 for (
auto global : globals) {
1156 newGlobals << global.remove(0, 9);
1159 m_functionBrowser->updateMultiDatasetParameters(*func);
1161 m_functionBrowser->setGlobalParameters(newGlobals);
1164 auto originalNames = func->getParameterNames();
1165 for (
auto name : originalNames) {
1166 auto index = func->parameterIndex(name);
1167 if (func->isFixed(
index) && func->getNumberDomains() > 1) {
1169 auto separatorIndex = name.find_first_of(
".");
1170 std::string domainStr = name.substr(1, separatorIndex - 1);
1171 int domain = std::stoi(domainStr);
1173 auto newName = name.substr(separatorIndex + 1);
1175 m_functionBrowser->setLocalParameterFixed(QString::fromStdString(newName), domain,
true);
1180 FitPropertyBrowser::clear();
1181 m_functionBrowser->setFunction(func);
1195void MuonFitPropertyBrowser::setTFAsymmMode(
bool enabled) {
1196 IFunction_sptr old = std::dynamic_pointer_cast<IFunction>(m_compositeFunction);
1197 if (old->nParams() > 0) {
1198 ConvertFitFunctionForMuonTFAsymmetry(enabled);
1201 m_settingsGroup->property()->addSubProperty(m_keepNorm);
1203 m_settingsGroup->property()->removeSubProperty(m_keepNorm);
1205 }
else if (enabled) {
1207 m_boolManager->setValue(m_TFAsymmMode,
false);
1208 QMessageBox::warning(
this,
"Muon Analysis",
1209 "No fitting function provided. TF Asymmetry mode "
1210 "requires a fitting function to be added before "
1211 "enabling. Please add a fitting function and enable "
1212 "TF Asymmetry Mode again.");
1215std::string MuonFitPropertyBrowser::TFExtension()
const {
return (m_boolManager->value(m_TFAsymmMode)) ? UNNORM :
""; }
1219void MuonFitPropertyBrowser::updateTFPlot() {
1221 int j = m_enumManager->value(m_workspace);
1222 std::string option = m_workspaceNames[j].toStdString();
1223 if (m_boolManager->value(m_TFAsymmMode) && option.find(UNNORM) == std::string::npos) {
1224 auto raw = option.find(
"_Raw");
1226 if (raw == std::string::npos) {
1227 option += TFExtension();
1229 option.insert(raw, UNNORM);
1233 emit TFPlot(QString::fromStdString(option));
1241void MuonFitPropertyBrowser::addFitBrowserWidget(QWidget *widget,
1243 widget->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding);
1244 if (m_widgetSplitter) {
1245 m_widgetSplitter->addWidget(widget);
1247 m_functionBrowser = functionBrowser;
1254void MuonFitPropertyBrowser::continueAfterChecks(
bool sequential) { emit functionUpdateAndFitRequested(sequential); }
1260bool MuonFitPropertyBrowser::hasGuess()
const {
1261 auto *handler = getHandler();
1263 const bool hasPlot = handler->hasPlot();
1274void MuonFitPropertyBrowser::setAvailableGroups(
const QStringList &groups) {
1276 auto selected = getChosenGroups();
1277 if (groups.size() == m_groupBoxes.size()) {
1278 auto existingGroups = m_groupBoxes.keys();
1279 auto newGroups = groups;
1280 qSort(existingGroups);
1282 if (existingGroups == newGroups) {
1286 clearGroupCheckboxes();
1288 for (
const auto &group : groups) {
1289 addGroupCheckbox(group);
1292 for (
const auto &group : selected) {
1294 for (
auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd(); ++iter) {
1295 if (iter.key().toStdString() == group.toStdString()) {
1296 m_boolManager->setValue(iter.value(),
true);
1305void MuonFitPropertyBrowser::setChosenGroup(
const QString &group) {
1306 clearChosenGroups();
1307 for (
auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd(); ++iter) {
1308 if (iter.key() == group) {
1309 m_boolManager->setValue(iter.value(),
true);
1317void MuonFitPropertyBrowser::clearGroupCheckboxes() {
1318 for (
const auto &checkbox : m_groupBoxes) {
1321 m_groupBoxes.clear();
1328void MuonFitPropertyBrowser::addGroupCheckbox(
const QString &name) {
1329 m_groupBoxes.insert(name, m_boolManager->addProperty(name));
1335QStringList MuonFitPropertyBrowser::getChosenGroups()
const {
1337 for (
auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd(); ++iter) {
1338 if (m_boolManager->value(iter.value()) ==
true) {
1339 chosen.append(iter.key());
1347void MuonFitPropertyBrowser::clearChosenGroups()
const {
1348 for (
auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd(); ++iter) {
1349 m_boolManager->setValue(iter.value(),
false);
1356void MuonFitPropertyBrowser::setAllGroups() {
1358 clearChosenGroups();
1359 for (
auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd(); ++iter) {
1360 for (
const auto &group : m_groupsList) {
1361 if (iter.key().toStdString() == group) {
1362 m_boolManager->setValue(iter.value(),
true);
1370void MuonFitPropertyBrowser::setAllPairs() {
1371 clearChosenGroups();
1372 for (
auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd(); ++iter) {
1373 const auto keyString = iter.key().toStdString();
1374 const bool isItGroup = std::any_of(m_groupsList.cbegin(), m_groupsList.cend(),
1375 [&keyString](
const auto &group) { return group == keyString; });
1377 m_boolManager->setValue(iter.value(),
true);
1386void MuonFitPropertyBrowser::genGroupWindow() {
1388 m_groupWindow =
new QDialog(
this);
1389 QtGroupPropertyManager *groupManager =
new QtGroupPropertyManager(m_groupWindow);
1390 QVBoxLayout *layout =
new QVBoxLayout(m_groupWindow);
1391 auto *groupBrowser =
new QtTreePropertyBrowser();
1392 QtProperty *groupSettings = groupManager->addProperty(
"Group/Pair selection");
1393 for (
auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd(); ++iter) {
1394 groupSettings->addSubProperty(m_groupBoxes.value(iter.key()));
1395 m_boolManager->setValue(iter.value(), m_boolManager->value(iter.value()));
1397 QtCheckBoxFactory *checkBoxFactory =
new QtCheckBoxFactory(m_groupWindow);
1398 groupBrowser->setFactoryForManager(m_boolManager, checkBoxFactory);
1399 groupBrowser->addProperty(groupSettings);
1400 layout->addWidget(groupBrowser);
1401 m_groupWindow->setLayout(layout);
1402 m_groupWindow->show();
1407void MuonFitPropertyBrowser::setAllPeriods() {
1409 for (
auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd(); ++iter) {
1410 m_boolManager->setValue(iter.value(),
true);
1418void MuonFitPropertyBrowser::setNumPeriods(
size_t numPeriods) {
1420 clearPeriodCheckboxes();
1421 if (!m_periodsToFitOptions.empty()) {
1422 m_periodsToFitOptions.clear();
1425 if (numPeriods > 1) {
1426 m_periodsToFitOptions << ALL_PERIODS_LABEL;
1427 m_periodsToFitOptions << CUSTOM_LABEL;
1431 for (
size_t i = 0; i != numPeriods; i++) {
1432 QString name = QString::number(i + 1);
1433 addPeriodCheckbox(name);
1436 if (m_periodsToFitOptions.size() == 1) {
1437 m_generateBtn->setDisabled(
true);
1438 m_multiFitSettingsGroup->property()->removeSubProperty(m_periodsToFit);
1439 m_multiFitSettingsGroup->property()->removeSubProperty(m_showPeriods);
1440 m_enumManager->setValue(m_periodsToFit, 0);
1441 clearChosenPeriods();
1442 m_boolManager->setValue(m_periodBoxes.constBegin().value(),
true);
1447 m_multiFitSettingsGroup->property()->insertSubProperty(m_periodsToFit, m_showGroup);
1448 m_multiFitSettingsGroup->property()->addSubProperty(m_showPeriods);
1449 m_generateBtn->setDisabled(
false);
1459void MuonFitPropertyBrowser::setAvailablePeriods(
const QStringList &periods) {
1461 if (periods.size() == m_periodBoxes.size()) {
1462 auto existingGroups = m_periodBoxes.keys();
1463 auto newGroups = periods;
1464 qSort(existingGroups);
1466 if (existingGroups == newGroups) {
1471 clearPeriodCheckboxes();
1473 for (
const auto &group : periods) {
1474 addPeriodCheckbox(group);
1481void MuonFitPropertyBrowser::clearPeriodCheckboxes() {
1482 if (m_periodBoxes.size() > 1) {
1483 for (
auto iter = std::next(m_periodBoxes.constBegin()); iter != m_periodBoxes.constEnd(); ++iter) {
1486 m_periodBoxes.clear();
1488 m_periodsToFitOptions.clear();
1489 m_periodsToFitOptions <<
"1";
1490 m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions);
1495void MuonFitPropertyBrowser::clearChosenPeriods()
const {
1496 for (
auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd(); ++iter) {
1497 m_boolManager->setValue(iter.value(),
false);
1503void MuonFitPropertyBrowser::updatePeriods() {
1504 int j = m_enumManager->value(m_periodsToFit);
1516void MuonFitPropertyBrowser::updatePeriods(
const int j) {
1519 if (m_periodsToFitOptions.size() == 0) {
1520 QMessageBox::warning(
this,
"Muon Analysis",
1521 "Data not found. Please turn on the data archive, "
1522 "using the Manage Directories button.");
1525 m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions);
1526 m_enumManager->setValue(m_periodsToFit, j);
1527 if (m_periodsToFitOptions[j] == CUSTOM_LABEL) {
1535 }
else if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) {
1539 setChosenPeriods(m_periodsToFitOptions[j]);
1547void MuonFitPropertyBrowser::addPeriodCheckboxToMap(
const QString &name) {
1548 if (m_periodBoxes.find(name) != m_periodBoxes.end()) {
1553 int j = m_enumManager->value(m_periodsToFit);
1555 addPeriodCheckbox(name);
1562bool MuonFitPropertyBrowser::isPeriodValid(
const QString &name) {
1565 if (name.contains(
".")) {
1569 else if (name.count(
"-") > 1) {
1572 std::vector<std::string> numbers;
1573 std::string nameString = name.toStdString();
1574 boost::algorithm::split(numbers, nameString, boost::is_any_of(
","));
1576 for (
auto value : numbers) {
1578 if (
tmp != std::string::npos) {
1580 auto before =
value.substr(0,
tmp);
1581 auto after =
value.substr(
tmp + 1);
1585 boost::lexical_cast<int>(
value);
1586 if (m_periodBoxes.find(QString::fromStdString(
value)) == m_periodBoxes.end() && numbers.size() > 1) {
1590 }
catch (
const boost::bad_lexical_cast &) {
1604void MuonFitPropertyBrowser::addPeriodCheckbox(
const QString &name) {
1607 if (isPeriodValid(name)) {
1608 m_periodBoxes.insert(name, m_boolManager->addProperty(name));
1609 int j = m_enumManager->value(m_periodsToFit);
1611 m_periodsToFitOptions << name;
1613 auto active = getChosenPeriods();
1614 m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions);
1615 setChosenPeriods(active);
1616 m_enumManager->setValue(m_periodsToFit, j);
1623QStringList MuonFitPropertyBrowser::getChosenPeriods()
const {
1626 if (m_periodsToFitOptions.size() == 1) {
1629 for (
auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd(); ++iter) {
1630 if (m_boolManager->value(iter.value()) ==
true) {
1631 chosen.append(iter.key());
1641void MuonFitPropertyBrowser::setChosenPeriods(
const QStringList &chosenPeriods) {
1642 clearChosenPeriods();
1643 for (
const auto &selected : chosenPeriods) {
1644 for (
auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd(); ++iter) {
1645 if (iter.key() == selected) {
1646 m_boolManager->setValue(iter.value(),
true);
1655void MuonFitPropertyBrowser::setChosenPeriods(
const QString &period) {
1656 clearChosenPeriods();
1657 for (
auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd(); ++iter) {
1658 if (iter.key() == period) {
1659 m_boolManager->setValue(iter.value(),
true);
1667void MuonFitPropertyBrowser::genPeriodWindow() {
1669 m_periodWindow =
new QDialog(
this);
1670 QtGroupPropertyManager *groupManager =
new QtGroupPropertyManager(m_periodWindow);
1671 QVBoxLayout *layout =
new QVBoxLayout(m_periodWindow);
1672 auto *groupBrowser =
new QtTreePropertyBrowser();
1673 QtProperty *groupSettings = groupManager->addProperty(
"Period selection");
1674 for (
auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd(); ++iter) {
1675 groupSettings->addSubProperty(m_periodBoxes.value(iter.key()));
1676 m_boolManager->setValue(iter.value(), m_boolManager->value(iter.value()));
1678 QtCheckBoxFactory *checkBoxFactory =
new QtCheckBoxFactory(m_periodWindow);
1679 groupBrowser->setFactoryForManager(m_boolManager, checkBoxFactory);
1680 groupBrowser->addProperty(groupSettings);
1681 layout->addWidget(groupBrowser);
1682 m_periodWindow->setLayout(layout);
1683 m_periodWindow->show();
1689void MuonFitPropertyBrowser::genCombinePeriodWindow() {
1691 m_comboWindow =
new QDialog(
this);
1692 QVBoxLayout *layout =
new QVBoxLayout(m_comboWindow);
1693 auto *formLayout =
new QFormLayout;
1694 m_positiveCombo =
new QLineEdit();
1695 m_negativeCombo =
new QLineEdit();
1696 formLayout->addRow(
new QLabel(tr(
"Combine:")), m_positiveCombo);
1697 formLayout->addRow(
new QLabel(tr(
" - ")), m_negativeCombo);
1698 layout->addLayout(formLayout);
1700 auto *applyBtn =
new QPushButton(
"Apply");
1702 connect(applyBtn, SIGNAL(released()),
this, SLOT(combineBtnPressed()));
1704 layout->addWidget(applyBtn);
1705 m_comboWindow->setLayout(layout);
1706 m_comboWindow->show();
1713void MuonFitPropertyBrowser::combineBtnPressed() {
1714 QString
value = m_positiveCombo->text();
1715 if (
value.isEmpty()) {
1716 g_log.
error(
"There are no positive periods (top box)");
1719 if (!m_negativeCombo->text().isEmpty()) {
1720 value.append(
"-").append(m_negativeCombo->text());
1722 m_positiveCombo->clear();
1723 m_negativeCombo->clear();
1724 addPeriodCheckbox(
value);
1725 int j = m_enumManager->value(m_periodsToFit);
1726 if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) {
1735void MuonFitPropertyBrowser::setSingleFitLabel(
const std::string &name) {
1736 clearChosenGroups();
1737 clearChosenPeriods();
1738 std::vector<std::string> splitName;
1739 std::string tmpName = name;
1740 boost::erase_all(tmpName,
" ");
1741 boost::split(splitName, tmpName, boost::is_any_of(
";"));
1743 QString group = QString::fromUtf8(splitName[2].c_str());
1744 setChosenGroup(group);
1746 if (splitName.size() == 6) {
1747 QString period = QString::fromUtf8(splitName[4].c_str());
1748 setChosenPeriods(period);
1750 setOutputName(name);
1752 if (m_browser->isItemVisible(m_multiFitSettingsGroup)) {
1753 updateGroupDisplay();
1754 updatePeriodDisplay();
1763void MuonFitPropertyBrowser::setAllGroupsOrPairs(
const bool isItGroup) {
1765 auto index = m_enumManager->value(m_groupsToFit);
1766 QString name = m_groupsToFitOptions[
index];
1767 if (name == CUSTOM_LABEL) {
1768 auto vals = getChosenGroups();
1769 clearChosenGroups();
1770 for (
const auto &group : vals) {
1772 for (
auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd(); ++iter) {
1773 if (iter.key().toStdString() == group.toStdString()) {
1774 m_boolManager->setValue(iter.value(),
true);
1778 }
else if (name == ALL_GROUPS_LABEL) {
1779 m_enumManager->setValue(m_groupsToFit, 0);
1781 if (getChosenGroups().size() > 0) {
1784 }
else if (name == ALL_PAIRS_LABEL) {
1785 m_enumManager->setValue(m_groupsToFit, 1);
1788 if (getChosenGroups().size() > 0) {
1794 m_enumManager->setValue(m_groupsToFit, 0);
1798 m_enumManager->setValue(m_groupsToFit, 1);
1803void MuonFitPropertyBrowser::setGroupNames(std::vector<std::string> groupNames) {
1804 m_groupsList = std::move(groupNames);
1806void MuonFitPropertyBrowser::setTFAsymm(
bool state) { m_boolManager->setValue(m_TFAsymmMode, state); }
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
void observeFinish(AlgorithmObserver &self, const boost::python::object &alg)
void observeFinish(const IAlgorithm_const_sptr &alg)
Connect to algorithm alg and observe its finish notification.
The Analysis data service stores instances of the Workspace objects and anything that derives from te...
void addOrReplace(const std::string &name, const std::shared_ptr< API::Workspace > &workspace) override
Overridden addOrReplace member to attach the name to the workspace when a workspace object is added t...
void addToGroup(const std::string &groupName, const std::string &wsName)
Add a workspace to a group.
std::shared_ptr< WSTYPE > retrieveWS(const std::string &name) const
Retrieve a workspace and cast it to the given WSTYPE.
void copyExperimentInfoFrom(const ExperimentInfo *other)
Copy everything from the given experiment object.
IAlgorithm is the interface implemented by the Algorithm base class.
virtual const std::string name() const =0
function to return a name of the algorithm, must be overridden in all algorithms
An interface to a background function.
An interface to a peak function, which extend the interface of IFunctionWithLocation by adding method...
ITableWorkspace is an implementation of Workspace in which the data are organised in columns of same ...
Base MatrixWorkspace Abstract Class.
TableRow represents a row in a TableWorkspace.
Class to hold a set of workspaces.
Exception for when an item is not found in a collection.
const char * what() const noexcept override
Writes out the range and limits.
virtual TypedValue getProperty(const std::string &name) const =0
Get the value of a property.
virtual std::string getPropertyValue(const std::string &name) const =0
Get the value of a property as a string.
The Logger class is in charge of the publishing messages from the framework through various channels.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
The AlgorithmProgressDialogPresenter keeps track of the running algorithms and displays a progress ba...
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class