Newer
Older
void MuonFitPropertyBrowser::sequentialFit() {
emit preFitChecksRequested(true);
* Connect to the AnalysisDataService when shown
void MuonFitPropertyBrowser::showEvent(QShowEvent *e) {
(void)e;
observePostDelete();
populateWorkspaceNames();
}
/** Check if the workspace can be used in the fit. The accepted types are
* MatrixWorkspaces same size and that it isn't the generated raw file.
* @param ws :: The workspace
*/
bool MuonFitPropertyBrowser::isWorkspaceValid(Workspace_sptr ws) const {
QString workspaceName(QString::fromStdString(ws->getName()));
if ((workspaceName.contains("_Raw")) ||
(workspaceName.contains("MuonAnalysis")))
return false;
// Exclude fitting results
if (workspaceName.endsWith("_Workspace"))
return dynamic_cast<MatrixWorkspace *>(ws.get()) != 0;
}
void MuonFitPropertyBrowser::finishHandle(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("InputWorkspace")));
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());
}
// If fit was simultaneous, insert extra information into params table
const int nWorkspaces = static_cast<int>(m_workspacesToFit.size());
if (nWorkspaces > 1) {
finishAfterSimultaneousFit(alg, nWorkspaces);
FitPropertyBrowser::finishHandle(alg);
}
/**
* After a simultaneous fit, insert extra information into parameters table
* (i.e. what runs, groups, periods "f0", "f1" etc were)
* @param fitAlg :: [input] Pointer to fit algorithm that just finished
* @param nWorkspaces :: [input] Number of workspaces that were fitted
*/
void MuonFitPropertyBrowser::finishAfterSimultaneousFit(
const Mantid::API::IAlgorithm *fitAlg, const int nWorkspaces) const {
AnalysisDataServiceImpl &ads = AnalysisDataService::Instance();
try {
const std::string paramTableName = fitAlg->getProperty("OutputParameters");
const auto paramTable = ads.retrieveWS<ITableWorkspace>(paramTableName);
if (paramTable) {
Mantid::API::TableRow f0Row = paramTable->appendRow();
f0Row << "f0=" + fitAlg->getPropertyValue("InputWorkspace") << 0.0 << 0.0;
for (int i = 1; i < nWorkspaces; i++) {
const std::string suffix = boost::lexical_cast<std::string>(i);
const auto wsName =
fitAlg->getPropertyValue("InputWorkspace_" + suffix);
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 = fitAlg->getPropertyValue("Output");
const std::string &baseName = groupName;
// 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
*/
void MuonFitPropertyBrowser::addExtraWidget(QWidget *widget) {
widget->setSizePolicy(QSizePolicy::Policy::Expanding,
QSizePolicy::Policy::Expanding);
m_widgetSplitter->addWidget(widget);
* Called externally to set the function
* @param func :: [input] Fit function to use
void MuonFitPropertyBrowser::setFunction(const IFunction_sptr func) {
/**
* Set the list of workspaces to fit to the given list
* @param wsNames :: [input] List of workspace names to fit
*/
void MuonFitPropertyBrowser::setWorkspaceNames(const QStringList &wsNames) {
m_workspacesToFit.clear();
std::transform(wsNames.begin(), wsNames.end(),
std::back_inserter(m_workspacesToFit),
[](const QString &qs) { return qs.toStdString(); });
// Update listeners
emit workspacesToFitChanged(static_cast<int>(m_workspacesToFit.size()));
// Update norm
setNormalization();
/**
* Override in the case of simultaneous fits to use a special prefix.
* Otherwise, use the parent class method.
* @returns :: output name for Fit algorithm
*/
std::string MuonFitPropertyBrowser::outputName() const {
const int nWorkspaces = static_cast<int>(m_workspacesToFit.size());
if (nWorkspaces > 1) {
// simultaneous fit
return SIMULTANEOUS_PREFIX + m_simultaneousLabel;
} else {
// use parent class behaviour
return FitPropertyBrowser::outputName();
}
}
* Set multiple fitting mode on or off.
* If turned off, all parts of the fit property browser are shown and all extra
* widgets (like the function browser or data selector) are hidden, so it looks
* just like it used to before the changes in Mantid 3.8.
* If turned on, the "Function" and "Data" sections of the fit property browser
* are hidden and the extra widgets are shown.
* @param enabled :: [input] Whether to turn this mode on or off
*/
void MuonFitPropertyBrowser::setMultiFittingMode(bool enabled) {
// First, clear whatever model is currently set
this->clear();
// set default selection (all groups)
if (enabled) {
} else { // clear current selection
clearChosenGroups();
clearChosenPeriods();
// Show or hide "Function" and "Data" sections
m_browser->setItemVisible(m_functionsGroup, !enabled);
m_browser->setItemVisible(m_settingsGroup, !enabled);
m_browser->setItemVisible(m_multiFitSettingsGroup, enabled);
// Show or hide additional widgets
for (int i = 0; i < m_widgetSplitter->count(); ++i) {
if (auto *widget = m_widgetSplitter->widget(i)) {
widget->setVisible(enabled);
* Set TF asymmetry mode on or off.
* If turned off, the fit property browser looks like Mantid 3.8.
* If turned on, the fit menu has an extra button and
* normalization is shown in the data table
* @param enabled :: [input] Whether to turn this mode on or off
*/
void MuonFitPropertyBrowser::setTFAsymmMode(bool enabled) {
modifyFitMenu(m_fitActionTFAsymm, enabled);
// Show or hide the TFAsymmetry fit
if (enabled) {
m_settingsGroup->property()->addSubProperty(m_normalization);
m_multiFitSettingsGroup->property()->addSubProperty(m_normalization);
m_settingsGroup->property()->addSubProperty(m_keepNorm);
setNormalization();
} else {
m_settingsGroup->property()->removeSubProperty(m_normalization);
m_multiFitSettingsGroup->property()->removeSubProperty(m_normalization);
m_settingsGroup->property()->removeSubProperty(m_keepNorm);
/**
* The pre-fit checks have been successfully completed. Continue by emitting a
* signal to update the function and request the fit.
* @param sequential :: [input] Whether fit is sequential or not
*/
void MuonFitPropertyBrowser::continueAfterChecks(bool sequential) {
emit functionUpdateAndFitRequested(sequential);
/**
* Returns whether or not a guess is plotted
* @returns :: True if a plot guess is plotted, false if not.
*/
bool MuonFitPropertyBrowser::hasGuess() const {
auto *handler = getHandler();
if (handler) {
const bool hasPlot = handler->hasPlot(); // don't allow caller to modify
return hasPlot;
} else {
return false;
}
/**
* Sets group names and updates checkboxes on UI
* By default sets all unchecked
* @param groups :: [input] List of group names
*/
void MuonFitPropertyBrowser::setAvailableGroups(const QStringList &groups){
// m_enumManager->setValue(m_groupsToFit, 0);
auto selected = getChosenGroups();
if (groups.size() == m_groupBoxes.size()) {
auto existingGroups = m_groupBoxes.keys();
auto newGroups = groups;
qSort(existingGroups);
qSort(newGroups);
if (existingGroups == newGroups) {
return;
}
}
clearGroupCheckboxes();
QSettings settings;
//sets the same selection as before
for (const auto &group : selected) {
for (auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd();
++iter) {
if (iter.key().toStdString() == group.toStdString()) {
m_boolManager->setValue(iter.value(), true);
}
}
}
* @param group :: [input] Group/pair to select
void MuonFitPropertyBrowser::setChosenGroup(const QString &group) {
clearChosenGroups();
for (auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd();
++iter) {
if (iter.key() == group) {
m_boolManager->setValue(iter.value(), true);
}
}
* Clears all group names and checkboxes
* (ready to add new ones)
*/
void MuonFitPropertyBrowser::clearGroupCheckboxes() {
for (const auto &checkbox : m_groupBoxes) {
delete (checkbox);
}
m_groupBoxes.clear();
}
/**
* Add a new checkbox to the list of groups with given name
* The new checkbox is checked according to dropdown menu selection
* @param name :: [input] Name of group to add
*/
void MuonFitPropertyBrowser::addGroupCheckbox(const QString &name) {
m_groupBoxes.insert(name, m_boolManager->addProperty(name));
int j = m_enumManager->value(m_groupsToFit);
auto option = m_groupsToFitOptions[j].toStdString();
/*if (option == "All groups") {
setAllGroups();
} else if (option == "All Pairs") {
setAllPairs();
}
/**
* Returns a list of the selected groups (checked boxes)
* @returns :: list of selected groups
*/
QStringList MuonFitPropertyBrowser::getChosenGroups() const {
QStringList chosen;
for (auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd();
++iter) {
if (m_boolManager->value(iter.value()) == true) {
chosen.append(iter.key());
}
}
return chosen;
}
/**
* Clears the list of selected groups (unchecks boxes)
*/
void MuonFitPropertyBrowser::clearChosenGroups() const {
for (auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd();
++iter) {
m_boolManager->setValue(iter.value(), false);
}
void MuonFitPropertyBrowser::setAllGroups() {
clearChosenGroups();
for (auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd();
++iter) {
if (iter.key().toStdString() == group) {
m_boolManager->setValue(iter.value(), true);
}
}
}
*/
void MuonFitPropertyBrowser::setAllPairs() {
clearChosenGroups();
for (auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd();
++iter) {
bool isItGroup = false;
if (iter.key().toStdString() == group) {
isItGroup = true;
}
}
if (!isItGroup) {
m_boolManager->setValue(iter.value(), true);
}
}
/*
* Create a popup window to select a custom
* selection of groups/pairs
*/
void MuonFitPropertyBrowser::genGroupWindow() {
// reset group window
m_groupWindow = new QDialog(this);
QtGroupPropertyManager *groupManager =
new QtGroupPropertyManager(m_groupWindow);
QVBoxLayout *layout = new QVBoxLayout(m_groupWindow);
QtTreePropertyBrowser *groupBrowser = new QtTreePropertyBrowser();
QtProperty *groupSettings = groupManager->addProperty("Group/Pair selection");
for (auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd();
++iter) {
groupSettings->addSubProperty(m_groupBoxes.value(iter.key()));
m_boolManager->setValue(iter.value(), m_boolManager->value(iter.value()));
}
QtCheckBoxFactory *checkBoxFactory = new QtCheckBoxFactory(m_groupWindow);
groupBrowser->setFactoryForManager(m_boolManager, checkBoxFactory);
groupBrowser->addProperty(groupSettings);
layout->addWidget(groupBrowser);
m_groupWindow->setLayout(layout);
m_groupWindow->show();
/**
* Selects all periods
*/
void MuonFitPropertyBrowser::setAllPeriods() {
clearChosenPeriods();
for (auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd();
++iter) {
m_boolManager->setValue(iter.value(), true);
}
/**
* Sets checkboxes for periods
* @param numPeriods :: [input] Number of periods
*/
void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods) {
m_periodsToFitOptions << ALL_PERIODS_LABEL;
// create more boxes
for (size_t i = 0; i != numPeriods; i++) {
QString name = QString::number(i + 1);
addPeriodCheckbox(name);
}
if (m_periodsToFitOptions.size() == 1) {
m_generateBtn->setDisabled(true);
m_multiFitSettingsGroup->property()->removeSubProperty(m_periodsToFit);
m_multiFitSettingsGroup->property()->removeSubProperty(m_showPeriods);
m_enumManager->setValue(m_periodsToFit, 0);
clearChosenPeriods();
m_boolManager->setValue(m_periodBoxes.constBegin().value(), true);
} else {
// add custom back into list
m_multiFitSettingsGroup->property()->insertSubProperty(m_periodsToFit,
m_showGroup);
m_multiFitSettingsGroup->property()->addSubProperty(m_showPeriods);
m_generateBtn->setDisabled(false);
m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions);
}
* Sets period names and updates checkboxes on UI
* @param periods :: [input] List of period names
*/
void MuonFitPropertyBrowser::setAvailablePeriods(const QStringList &periods) {
// If it's the same list, do nothing
if (periods.size() == m_periodBoxes.size()) {
auto existingGroups = m_periodBoxes.keys();
auto newGroups = periods;
qSort(existingGroups);
qSort(newGroups);
if (existingGroups == newGroups) {
return;
}
}
clearPeriodCheckboxes();
* (ready to add new ones)
*/
void MuonFitPropertyBrowser::clearPeriodCheckboxes() {
for (auto iter = std::next(m_periodBoxes.constBegin());
}
}
m_periodsToFitOptions.clear();
m_periodsToFitOptions << "1";
m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions);
}
/**
* Clears the list of selected groups (unchecks boxes)
*/
void MuonFitPropertyBrowser::clearChosenPeriods() const {
for (auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd();
++iter) {
m_boolManager->setValue(iter.value(), false);
}
}
/**
* Add a new checkbox to the list of periods with given name
* The new checkbox is unchecked by default
* @param name :: [input] Name of period to add
*/
void MuonFitPropertyBrowser::addPeriodCheckbox(const QString &name) {
m_periodBoxes.insert(name, m_boolManager->addProperty(name));
int j = m_enumManager->value(m_periodsToFit);
// add new period to list will go after inital list
m_periodsToFitOptions << name;
auto active = getChosenPeriods();
m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions);
setChosenPeriods(active);
m_enumManager->setValue(m_periodsToFit, j);
if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) {
}
/**
* Returns a list of the selected periods (checked boxes)
* @returns :: list of selected periods
*/
QStringList MuonFitPropertyBrowser::getChosenPeriods() const {
QStringList chosen;
// if single period
if (m_periodsToFitOptions.size() == 1) {
chosen << "";
} else {
for (auto iter = m_periodBoxes.constBegin();
iter != m_periodBoxes.constEnd(); ++iter) {
if (m_boolManager->value(iter.value()) == true) {
chosen.append(iter.key());
}
}
}
return chosen;
* @param chosenPeriods :: list of selected periods
void MuonFitPropertyBrowser::setChosenPeriods(
const QStringList &chosenPeriods) {
clearChosenPeriods();
for (auto iter = m_periodBoxes.constBegin();
iter != m_periodBoxes.constEnd(); ++iter) {
if (iter.key() == selected) {
m_boolManager->setValue(iter.value(), true);
}
}
}
/**
* Ticks the selected periods
*/
void MuonFitPropertyBrowser::setChosenPeriods(const QString &period) {
clearChosenPeriods();
for (auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd();
++iter) {
if (iter.key() == period) {
m_boolManager->setValue(iter.value(), true);
}
}
* Create a pop up window to select a custom
* selection of periods
*/
void MuonFitPropertyBrowser::genPeriodWindow() {
// reset period window
m_periodWindow = new QDialog(this);
QtGroupPropertyManager *groupManager =
new QtGroupPropertyManager(m_periodWindow);
QVBoxLayout *layout = new QVBoxLayout(m_periodWindow);
QtTreePropertyBrowser *groupBrowser = new QtTreePropertyBrowser();
QtProperty *groupSettings = groupManager->addProperty("Period selection");
for (auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd();
++iter) {
groupSettings->addSubProperty(m_periodBoxes.value(iter.key()));
m_boolManager->setValue(iter.value(), m_boolManager->value(iter.value()));
}
QtCheckBoxFactory *checkBoxFactory = new QtCheckBoxFactory(m_periodWindow);
groupBrowser->setFactoryForManager(m_boolManager, checkBoxFactory);
groupBrowser->addProperty(groupSettings);
layout->addWidget(groupBrowser);
m_periodWindow->setLayout(layout);
m_periodWindow->show();
* a combination of periods
*/
void MuonFitPropertyBrowser::genCombinePeriodWindow() {
// reset combine window
m_comboWindow = new QDialog(this);
QVBoxLayout *layout = new QVBoxLayout(m_comboWindow);
QFormLayout *formLayout = new QFormLayout;
m_positiveCombo = new QLineEdit();
m_negativeCombo = new QLineEdit();
formLayout->addRow(new QLabel(tr("Combine:")), m_positiveCombo);
formLayout->addRow(new QLabel(tr(" - ")), m_negativeCombo);
layout->addLayout(formLayout);
QPushButton *applyBtn = new QPushButton("Apply");
connect(applyBtn, SIGNAL(released()), this, SLOT(combineBtnPressed()));
layout->addWidget(applyBtn);
m_comboWindow->setLayout(layout);
m_comboWindow->show();
/*
* Get the positive and negative parts of the
* combination of periods and produce a new
* tick box. Unticked by default.
*/
void MuonFitPropertyBrowser::combineBtnPressed() {
QString value = m_positiveCombo->text();
if (value.isEmpty()) {
g_log.error("There are no positive periods (top box)");
return;
}
if (!m_negativeCombo->text().isEmpty()) {
value.append("-").append(m_negativeCombo->text());
}
m_positiveCombo->clear();
m_negativeCombo->clear();
addPeriodCheckbox(value);
/**
* sets the label for a single fit and
* selects the relevant group/pair
void MuonFitPropertyBrowser::setSingleFitLabel(std::string name) {
clearChosenGroups();
clearChosenPeriods();
std::vector<std::string> splitName;
std::string tmpName = name;
boost::erase_all(tmpName, " ");
boost::split(splitName, tmpName, boost::is_any_of(";"));
// set single group/pair
QString group = QString::fromUtf8(splitName[2].c_str());
setChosenGroup(group);
if (splitName.size() == 6) {
QString period = QString::fromUtf8(splitName[4].c_str());
setChosenPeriods(period);
}
setOutputName(name);
// for single fit in multi fit mode
if (m_browser->isItemVisible(m_multiFitSettingsGroup)) {
updateGroupDisplay();
updatePeriodDisplay();
}
* or all pairs depending on if a group
* or pair is selected in the home tab
* @param isItGroup :: [input] if it is a group (true)
*/
void MuonFitPropertyBrowser::setAllGroupsOrPairs(const bool isItGroup) {
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
auto index = m_enumManager->value(m_groupsToFit);
QString name = m_groupsToFitOptions[index];
if (name == CUSTOM_LABEL) {
bool match = false;
auto vals = getChosenGroups();
auto tt = vals.size();
clearChosenGroups();
for (const auto &group : vals) {
for (auto iter = m_groupBoxes.constBegin(); iter != m_groupBoxes.constEnd();
++iter) {
auto a = iter.key().toStdString();
auto b = group.toStdString();
if (iter.key().toStdString() == group.toStdString()) {
m_boolManager->setValue(iter.value(), true);
match = true;
}
}
}
}
else if (name == ALL_GROUPS_LABEL) {
m_enumManager->setValue(m_groupsToFit, 0);
setAllGroups();
if (getChosenGroups().size() > 0) { return; }
}
else if (name == ALL_PAIRS_LABEL)
{ // all pairs is index 1
m_enumManager->setValue(m_groupsToFit, 1);
setAllPairs();
}
if (getChosenGroups().size() > 0) {
return;
}
else {
if (isItGroup) {
// all groups is index 0
m_enumManager->setValue(m_groupsToFit, 0);
setAllGroups();
}
else {
// all pairs is index 1
m_enumManager->setValue(m_groupsToFit, 1);
setAllPairs();
}
}
void MuonFitPropertyBrowser::setGroupNames(
std::vector<std::string> groupNames) {
m_groupsList = groupNames;
void MuonFitPropertyBrowser::setTFAsymm(bool state) {