Newer
Older
}
alg->setPropertyValue("InputWorkspace", tmpWSName);
alg->setProperty("WorkspaceIndex", workspaceIndex());
alg->setProperty("StartX", startX());
alg->setProperty("EndX", endX());
alg->setPropertyValue("Minimizer", minimizer());
alg->setPropertyValue("CostFunction", costFunction());
// If we are doing a simultaneous fit, set this up here
const int nWorkspaces = static_cast<int>(m_workspacesToFit.size());
if (nWorkspaces > 1) {
std::string extension = TFExtension();
alg->setPropertyValue("InputWorkspace", m_workspacesToFit[0]+extension);
for (int i = 1; i < nWorkspaces; i++) {
std::string suffix = boost::lexical_cast<std::string>(i);
alg->setPropertyValue("InputWorkspace_" + suffix, m_workspacesToFit[i]+extension);
alg->setProperty("WorkspaceIndex_" + suffix, workspaceIndex());
alg->setProperty("StartX_" + suffix, startX());
alg->setProperty("EndX_" + suffix, endX());
}
observeFinish(alg);
alg->executeAsync();
} catch (const std::exception &e) {
QString msg = "Fit algorithm failed.\n\n" + QString(e.what()) + "\n";
QMessageBox::critical(this, "Mantid - Error", msg);
std::string MuonFitPropertyBrowser :: TFExtension() const{
return (m_boolManager->value(m_TFAsymmMode)) ? UNNORM : "";
/**
* Show sequential fit dialog.
*/
void MuonFitPropertyBrowser::runSequentialFit() {
emit sequentialFitRequested();
}
/**
* Requests checks and updates prior to running a sequential fit
*/
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()) != nullptr;
}
void MuonFitPropertyBrowser::finishHandle(const IAlgorithm *alg) {
if (alg->name()=="CalculateMuonAsymmetry") {
finishHandleTF(alg);
}
else {
finishHandleNormal(alg);
}
}
void MuonFitPropertyBrowser::finishHandleTF(const IAlgorithm *alg) {
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
// 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()
// 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();
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
const QString wsName = QString::fromStdString(workspaceName());
std::string groupName;
const int index = wsName.indexOf(';');
if (index != -1) {
groupName = wsName.left(index).toStdString();
}
else {
groupName= wsName.toStdString();
}
WorkspaceGroup_sptr group;
if (ads.doesExist(groupName)) {
group = ads.retrieveWS<WorkspaceGroup>(groupName);
}
std::string wsNormalised =
wsName.toStdString() + "_NormalisedCovarianceMatrix";
std::string wsParameters = wsName.toStdString() + "_Parameters";
std::string wsWorkspace = wsName.toStdString() + "_Workspace";
std::vector<std::string> inputWorkspaces;
if (Mantid::API::AnalysisDataService::Instance().doesExist(wsNormalised)) {
inputWorkspaces.push_back(wsNormalised);
}
if (Mantid::API::AnalysisDataService::Instance().doesExist(wsParameters)) {
inputWorkspaces.push_back(wsParameters);
}
if (Mantid::API::AnalysisDataService::Instance().doesExist(wsWorkspace)) {
inputWorkspaces.push_back(wsWorkspace);
}
if (group) {
// Exists and is a group -> add missing workspaces to it
for (auto it = inputWorkspaces.begin(); it != inputWorkspaces.end(); ++it) {
if (!group->contains(*it)) {
group->add(*it);
}
}
}
else {
// Doesn't exist or isn't a group -> create/overwrite
IAlgorithm_sptr groupingAlg =
AlgorithmManager::Instance().create("GroupWorkspaces");
groupingAlg->setProperty("InputWorkspaces", inputWorkspaces);
groupingAlg->setPropertyValue("OutputWorkspace", groupName);
groupingAlg->execute();
}
void MuonFitPropertyBrowser::finishHandleNormal(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());
}
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
/**
* 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
*/
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) {
m_isMultiFittingMode = enabled;
// First, clear whatever model is currently set
this->clear();
// set default selection (all groups)
if (enabled) {
setAutoBackgroundName("");
this->clear(); // force update of composite function
} else { // clear current selection
if (m_autoBackground != "") {
setAutoBackgroundName(m_autoBackground);
addAutoBackground();
}
// 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);
if (enabled) {
setFitEnabled(false);
}
/**
* Returns true is the browser is set to multi fitting mode
* This works using the visibility state of the button group
* which is controlled in setMultiFittingMode
*/
bool MuonFitPropertyBrowser::isMultiFittingMode() const {
return m_isMultiFittingMode;
}
* 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);
// set new fit func
IAlgorithm_sptr alg = AlgorithmManager::Instance().create("ConvertFitFunctionForMuonTFAsymmetry");
// do not preserve the ties
if (AnalysisDataService::Instance().doesExist("MuonAnalysisTFNormalizations") && m_compositeFunction->nFunctions()>0) {
alg->initialize();
IFunction_sptr old = boost::dynamic_pointer_cast<IFunction>(
m_compositeFunction);
QStringList globals;
if (enabled && m_isMultiFittingMode) {
//manually set the function values
old= m_functionBrowser->getGlobalFunction();
globals= m_functionBrowser->getGlobalParameters();
}
else if (!enabled && !m_isMultiFittingMode) {
// to extract in single fit we have an extra composite -> so remove it
auto tmp = boost::dynamic_pointer_cast<CompositeFunction>(old);
old = tmp->getFunction(0);
}
alg->setProperty("InputFunction", old);
alg->setProperty("NormalizationTable", "MuonAnalysisTFNormalizations");
alg->setProperty("WorkspaceList", m_workspacesToFit);
std::string mode = (enabled) ? "Construct" : "Extract";
alg->setProperty("Mode",mode);
alg->execute();
IFunction_sptr func = alg->getProperty("OutputFunction");
//multiple fit
if (m_isMultiFittingMode) {
//update values in browser
auto tmp = boost::dynamic_pointer_cast<MultiDomainFunction>(func);
old = tmp->getFunction(0);
m_functionBrowser->setFunction(old);
//preserve global parameters
QStringList newGlobals;
const std::string INSERT_FUNCTION{ "f0.f1.f1." };
if (enabled) {
for (auto global : globals) {
newGlobals << QString::fromStdString(INSERT_FUNCTION) + global;
}
else {
for (auto global : globals) {
newGlobals << global.remove(0, 9);
}
m_functionBrowser->updateMultiDatasetParameters(*func);
m_functionBrowser->setGlobalParameters(newGlobals);
// if multi data set we need to do the fixes manually
auto originalNames = func->getParameterNames();
for (auto name : originalNames) {
auto index = func->parameterIndex(name);
if (func->isFixed(index)) {
auto index = name.find_first_of(".");
std::string domainStr = name.substr(1, index - 1);
int domain = std::stoi(domainStr);
//remove domain from name
auto newName = name.substr(index + 1);
//set fix
m_functionBrowser->setLocalParameterFixed(QString::fromStdString(newName), domain, true);
}//single fit
else {
FitPropertyBrowser::clear();
FitPropertyBrowser::addFunction(func->asString());
}
updateTFPlot();
//m_enumManager->setValue(m_workspace,j);
// 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);
/**
* Makes sure we have the TF plot in TFAsymm mode
*/
void MuonFitPropertyBrowser::updateTFPlot(){
//update plot
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) {
auto raw=option.find("_Raw");
if ( raw== std::string::npos) {
option += TFExtension();
}
else {
option.insert(raw,UNNORM);
}
}
// update plot
emit TFPlot(QString::fromStdString(option));
}
/**
* Adds an extra widget in between the fit buttons and the browser
* @param widget :: [input] Pointer to widget to add
*/
void MuonFitPropertyBrowser::addFitBrowserWidget(QWidget *widget, MantidQt::MantidWidgets::FunctionBrowser *functionBrowser) {
widget->setSizePolicy(QSizePolicy::Policy::Expanding,
QSizePolicy::Policy::Expanding);
if (m_widgetSplitter) {
m_widgetSplitter->addWidget(widget);
}
m_functionBrowser = functionBrowser;
/**
* 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) {
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();
}
/**
* 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() {
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) {
// has to go here to get the original value
int j = m_enumManager->value(m_periodsToFit);
auto selected = getChosenPeriods();
// delete period checkboxes
clearPeriodCheckboxes();
if (!m_periodsToFitOptions.empty()) {
m_periodsToFitOptions.clear();
m_periodsToFitOptions << ALL_PERIODS_LABEL;
m_periodsToFitOptions << CUSTOM_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 {
// for now always reset to all groups when data is changed
// the commented out code can be used to keep the selection when changing
// run - but has a bug
// if (j >= m_periodsToFitOptions.size()) {
// set all groups if the selection is no longer available (0 index)
j = 0;
//}
m_multiFitSettingsGroup->property()->insertSubProperty(m_periodsToFit,
m_showGroup);
m_multiFitSettingsGroup->property()->addSubProperty(m_showPeriods);
m_generateBtn->setDisabled(false);
updatePeriods(j); // , selected);
* 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);
}
* updates the period displays
*/
void MuonFitPropertyBrowser::updatePeriods() {
int j = m_enumManager->value(m_periodsToFit);
// auto selected = getChosenPeriods();
updatePeriods(j);
}
/**
* updates the period displays and conserves the selection
* if selection is niot available default to all periods
* @param j :: [input] index of selection in combobox
* selected is an input for changing runs and preserving selection (list of
* selected periods)
* currently has a bug
void MuonFitPropertyBrowser::updatePeriods(const int j) {
// this is for switching but has a bug at the moment
// const QStringList &selected) {
if (m_periodsToFitOptions.size() == 0) {
QMessageBox::warning(this, "Muon Analysis",
"Data not found. Please turn on the data archive, "
"using the Manage Directories button.");
m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions);
m_enumManager->setValue(m_periodsToFit, j);
if (m_periodsToFitOptions[j] == CUSTOM_LABEL) {
// currently the below does not work reliably (if period arithmatic is
// presemnt it gives bad results
/*
setChosenPeriods(selected);*/
// lets default to all periods for now
// explictly set all periods
setAllPeriods();
} else if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) {
// explictly set all periods
setAllPeriods();
} else { // single number
setChosenPeriods(m_periodsToFitOptions[j]);
}
}
/**
* Adds a new checkbox to the list of periods with given name
* It updates the display
* @param name :: [input] Name of period to add
*/
void MuonFitPropertyBrowser::addPeriodCheckboxToMap(const QString &name) {
if (m_periodBoxes.find(name) != m_periodBoxes.end()) {
// if the box already exists
return;
}
// has to go here to get the original value
int j = m_enumManager->value(m_periodsToFit);
// auto selected = getChosenPeriods();
addPeriodCheckbox(name);
updatePeriods(j);
/**
* Check if a period is valid
* @param name :: [input] Name of period to add
*/
bool MuonFitPropertyBrowser::isPeriodValid(const QString &name) {
// check period is sensible
// no frational periods
if (name.contains(".")) {
return false;
}
// wshould only ever have 1 minus sign
else if (name.count("-") > 1) {
return false;
} else {
std::vector<std::string> numbers;
std::string nameString = name.toStdString();
boost::algorithm::split(numbers, nameString, boost::is_any_of(","));
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
// loop over results
for (auto value : numbers) {
auto tmp = value.find("-");
if (tmp != std::string::npos) {
// find a minus sign
auto before = value.substr(0, tmp);
auto after = value.substr(tmp + 1);
} else {
try {
boost::lexical_cast<int>(value);
if (m_periodBoxes.find(QString::fromStdString(value)) ==
m_periodBoxes.end() &&
numbers.size() > 1) {
// if the box does not exist and there is more than 1 period in name
return false;
}
} catch (boost::bad_lexical_cast) {
// none int value
return false;
}
}
}
}
return true;
/**
* 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) {
// check period is sensible
// no frational periods
if (isPeriodValid(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);
}
/**
* 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