Commit 51381721 authored by Anthony Lim's avatar Anthony Lim
Browse files

refs #26726 generalised ALFView and use MWRunFiles

parent eb3904b4
......@@ -101,7 +101,7 @@ mtd_add_qt_tests(TARGET_NAME MantidQtScientificInterfacesTest
Qwt5
MTD_QT_LINK_LIBS
MantidScientificInterfacesGeneral
MantidScientificInterfacesDirect
MantidScientificInterfacesDirect
MantidScientificInterfacesMuon
MantidScientificInterfacesISISReflectometry
MantidScientificInterfacesEnggDiffraction
......
......@@ -18,7 +18,6 @@
namespace MantidQt {
namespace CustomInterfaces {
using namespace Mantid;
DECLARE_SUBWINDOW(ALFView)
......@@ -27,10 +26,9 @@ Mantid::Kernel::Logger g_log("ALFView");
ALFView::ALFView(QWidget *parent)
: UserSubWindow(parent), m_view(nullptr), m_presenter(nullptr) {
m_view = new ALFView_view(this);
m_model = new ALFView_model();
m_presenter = new ALFView_presenter(m_view, m_model);
m_view = new ALFView_view(m_model->getInstrument(), this);
m_presenter = new ALFView_presenter(m_view,m_model);
}
void ALFView::initLayout() {
......
......@@ -15,14 +15,17 @@
namespace MantidQt {
namespace CustomInterfaces {
/** ALCInterface : Custom interface for Avoided Level Crossing analysis
/** ALFView : Custom interface for looking at ALF data
*/
class MANTIDQT_DIRECT_DLL ALFView : public API::UserSubWindow {
Q_OBJECT
public:
ALFView(QWidget *parent = nullptr);
~ALFView(){};
~ALFView() {
delete m_presenter;
delete m_model;
};
static std::string name() { return "ALF View"; }
static QString categoryInfo() { return "Direct"; }
......@@ -30,6 +33,9 @@ protected:
void initLayout() override;
private:
//std::unique_ptr<ALFView_view> m_view;
//std::unique_ptr<ALFView_model> m_model;
//std::unique_ptr<ALFView_presenter> m_presenter;
ALFView_view *m_view;
ALFView_model *m_model;
ALFView_presenter *m_presenter;
......
#include "ALFView_model.h"
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
......@@ -6,6 +5,7 @@
// & Institut Laue - Langevin
// SPDX - License - Identifier: GPL - 3.0 +
#include "ALFView_model.h"
#include "MantidAPI/Algorithm.h"
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/AnalysisDataService.h"
......@@ -19,20 +19,23 @@
#include <utility>
namespace {
const std::string tmpName = "ALF_tmp";
const std::string instrumentName = "ALF";
const std::string wsName = "ALFData";
const std::string TMPNAME = "ALF_tmp";
const std::string INSTRUMENTNAME = "ALF";
const std::string WSNAME = "ALFData";
const int ERRORCODE = -999;
} // namespace
using namespace Mantid::API;
namespace MantidQt {
namespace CustomInterfaces {
void ALFView_model::loadEmptyInstrument() {
Mantid::API::IAlgorithm_sptr alg =
auto alg =
Mantid::API::AlgorithmManager::Instance().create("LoadEmptyInstrument");
alg->initialize();
alg->setProperty("OutputWorkspace", wsName);
alg->setProperty("InstrumentName", instrumentName);
alg->setProperty("OutputWorkspace", WSNAME);
alg->setProperty("InstrumentName", INSTRUMENTNAME);
alg->execute();
}
/*
......@@ -42,15 +45,14 @@ void ALFView_model::loadEmptyInstrument() {
* @return int:: the run number
*/
int ALFView_model::loadData(const std::string &name) {
Mantid::API::IAlgorithm_sptr alg =
Mantid::API::AlgorithmManager::Instance().create("Load");
auto alg = AlgorithmManager::Instance().create("Load");
alg->initialize();
alg->setProperty("Filename", name);
alg->setProperty("OutputWorkspace", tmpName); // write to tmp ws
alg->setProperty("OutputWorkspace", TMPNAME); // write to tmp ws
alg->execute();
Mantid::API::MatrixWorkspace_sptr ws =
Mantid::API::AnalysisDataService::Instance()
.retrieveWS<Mantid::API::MatrixWorkspace>(tmpName);
auto ws =
AnalysisDataService::Instance()
.retrieveWS<MatrixWorkspace>(TMPNAME);
return ws->getRunNumber();
}
/*
......@@ -59,14 +61,14 @@ int ALFView_model::loadData(const std::string &name) {
* @return pair<bool,bool>:: If the instrument is ALF, if it is d-spacing
*/
std::map<std::string, bool> ALFView_model::isDataValid() {
Mantid::API::MatrixWorkspace_sptr ws =
Mantid::API::AnalysisDataService::Instance()
.retrieveWS<Mantid::API::MatrixWorkspace>(tmpName);
auto ws =
AnalysisDataService::Instance()
.retrieveWS<MatrixWorkspace>(TMPNAME);
bool isItALF = false;
bool isItDSpace = false;
if (ws->getInstrument()->getName() == instrumentName) {
if (ws->getInstrument()->getName() == INSTRUMENTNAME) {
isItALF = true;
}
auto axis = ws->getAxis(0);
......@@ -85,40 +87,44 @@ std::map<std::string, bool> ALFView_model::isDataValid() {
* If already d-space does nothing.
*/
void ALFView_model::transformData() {
Mantid::API::IAlgorithm_sptr normAlg =
Mantid::API::AlgorithmManager::Instance().create("NormaliseByCurrent");
auto normAlg =
AlgorithmManager::Instance().create("NormaliseByCurrent");
normAlg->initialize();
normAlg->setProperty("InputWorkspace", wsName);
normAlg->setProperty("OutputWorkspace", wsName);
normAlg->setProperty("InputWorkspace", WSNAME);
normAlg->setProperty("OutputWorkspace", WSNAME);
normAlg->execute();
Mantid::API::IAlgorithm_sptr dSpacingAlg =
Mantid::API::AlgorithmManager::Instance().create("ConvertUnits");
auto dSpacingAlg =
AlgorithmManager::Instance().create("ConvertUnits");
dSpacingAlg->initialize();
dSpacingAlg->setProperty("InputWorkspace", wsName);
dSpacingAlg->setProperty("InputWorkspace", WSNAME);
dSpacingAlg->setProperty("Target", "dSpacing");
dSpacingAlg->setProperty("OutputWorkspace", wsName);
dSpacingAlg->setProperty("OutputWorkspace", WSNAME);
dSpacingAlg->execute();
}
void ALFView_model::rename() {
Mantid::API::AnalysisDataService::Instance().rename(tmpName, wsName);
AnalysisDataService::Instance().rename(TMPNAME, WSNAME);
}
void ALFView_model::remove() {
Mantid::API::AnalysisDataService::Instance().remove(tmpName);
AnalysisDataService::Instance().remove(TMPNAME);
}
int ALFView_model::currentRun() {
try {
Mantid::API::MatrixWorkspace_sptr ws =
Mantid::API::AnalysisDataService::Instance()
.retrieveWS<Mantid::API::MatrixWorkspace>(wsName);
auto ws =
AnalysisDataService::Instance()
.retrieveWS<MatrixWorkspace>(WSNAME);
return ws->getRunNumber();
} catch (...) {
return -999; // special error code
return ERRORCODE;
}
}
bool ALFView_model::isErrorCode(const int run) { return (run == ERRORCODE); }
std::string ALFView_model::getInstrument() { return INSTRUMENTNAME; }
} // namespace CustomInterfaces
} // namespace MantidQt
......@@ -21,7 +21,10 @@ public:
void rename();
void remove();
int currentRun();
}; // namespace CustomInterfaces
bool isErrorCode(const int run);
std::string getInstrument();
};
} // namespace CustomInterfaces
} // namespace MantidQt
......
......@@ -17,9 +17,9 @@ namespace CustomInterfaces {
ALFView_presenter::ALFView_presenter(ALFView_view *view, ALFView_model *model)
: m_view(view), m_model(model), m_currentRun(0), m_loadRunObserver(nullptr),
m_browseObserver(nullptr) {
m_loadRunObserver = new loadObserver();
m_browseObserver = new generalObserver();
m_currentFile("")
{
m_loadRunObserver = new VoidObserver();
m_model->loadEmptyInstrument();
}
......@@ -29,57 +29,44 @@ void ALFView_presenter::initLayout() {
std::function<void()> loadBinder =
std::bind(&ALFView_presenter::loadRunNumber, this);
m_loadRunObserver->setSlot(loadBinder);
// connect to browse run
m_view->observeBrowse(m_browseObserver);
std::function<void(std::string)> browseBinder = std::bind(
&ALFView_presenter::loadBrowsedFile, this, std::placeholders::_1);
m_browseObserver->setSlot(browseBinder);
}
void ALFView_presenter::loadAndAnalysis(const std::string &run) {
int runNumber = m_model->loadData(run);
auto bools = m_model->isDataValid();
if (bools["IsValidInstrument"]) {
m_model->rename();
m_currentRun = runNumber;
} else {
m_model->remove();
}
// if the displayed run number is out of sinc
if (m_view->getRunNumber() != m_currentRun) {
m_view->setRunQuietly(QString::number(m_currentRun));
void ALFView_presenter::loadAndAnalysis(const std::string &pathToRun) {
try {
int runNumber = m_model->loadData(pathToRun);
auto bools = m_model->isDataValid();
if (bools["IsValidInstrument"]) {
m_model->rename();
m_currentRun = runNumber;
m_currentFile = pathToRun;
} else {
// reset to the previous data
std::string message =
"Not the corrct instrument, expected " + m_model->getInstrument();
m_view->warningBox(message);
m_model->remove();
}
// make displayed run number be in sinc
m_view->setRunQuietly(std::to_string(m_currentRun));
if (bools["IsValidInstrument"] && !bools["IsItDSpace"]) {
m_model->transformData();
}
} catch (...) {
m_view->setRunQuietly(std::to_string(m_currentRun));
}
if (bools["IsValidInstrument"] && !bools["IsItDSpace"]) {
m_model->transformData();
}
}
void ALFView_presenter::loadRunNumber() {
int newRun = m_view->getRunNumber();
auto pathToRun = m_view->getFile();
const int currentRunInADS = m_model->currentRun();
if (currentRunInADS == newRun) {
if (pathToRun == "" ||m_currentFile == pathToRun) {
return;
}
const std::string runNumber = "ALF" + std::to_string(newRun);
// check its a valid run number
try {
Mantid::API::FileFinder::Instance().findRuns(runNumber)[0];
} catch (...) {
m_view->setRunQuietly(QString::number(m_currentRun));
// if file has been deleted we should replace it
if (currentRunInADS == -999) {
loadAndAnalysis("ALF" + std::to_string(m_currentRun));
}
return;
}
loadAndAnalysis(runNumber);
loadAndAnalysis(pathToRun);
}
void ALFView_presenter::loadBrowsedFile(const std::string fileName) {
m_model->loadData(fileName);
loadAndAnalysis(fileName);
}
} // namespace CustomInterfaces
} // namespace MantidQt
\ No newline at end of file
......@@ -11,32 +11,32 @@
#include "ALFView_view.h"
#include "DllConfig.h"
#include "MantidQtWidgets/Common/UserSubWindow.h"
#include "observerPattern.h"
#include "MantidQtWidgets/Common/ObserverPattern.h"
#include <string>
namespace MantidQt {
namespace CustomInterfaces {
/** ALCInterface : Custom interface for Avoided Level Crossing analysis
*/
class MANTIDQT_DIRECT_DLL ALFView_presenter : public QObject {
Q_OBJECT
public:
ALFView_presenter(ALFView_view *view, ALFView_model *model);
ALFView_presenter(ALFView_view *view,
ALFView_model *model);
~ALFView_presenter(){};
void initLayout();
private slots:
void loadRunNumber();
void loadBrowsedFile(const std::string);
private:
void loadAndAnalysis(const std::string &run);
ALFView_view *m_view;
ALFView_view *m_view;
ALFView_model *m_model;
int m_currentRun;
loadObserver *m_loadRunObserver;
generalObserver *m_browseObserver;
std::string m_currentFile;
VoidObserver *m_loadRunObserver;
};
} // namespace CustomInterfaces
} // namespace MantidQt
......
......@@ -9,61 +9,59 @@
#include <QFileDialog>
#include <QGridLayout>
#include <QLineEdit>
#include <QMessageBox>
#include <QRegExpValidator>
#include <QSplitter>
#include <QSpinBox>
#include <QVBoxLayout>
namespace MantidQt {
namespace CustomInterfaces {
ALFView_view::ALFView_view(QWidget *parent)
: QWidget(parent), m_run(nullptr), m_loadRunObservable(nullptr),
m_browseObservable(nullptr) {
QSplitter *MainLayout = new QSplitter(Qt::Vertical, this);
QWidget *loadBar = new QWidget();
m_loadRunObservable = new observable();
m_browseObservable = new observable();
generateLoadWidget(loadBar);
MainLayout->addWidget(loadBar);
// MainLayout->addWidget(widgetSplitter);
// this->addWidget(MainLayout);
ALFView_view::ALFView_view(const std::string instrument, QWidget *parent)
: QSplitter(Qt::Vertical, parent), m_loadRunObservable(nullptr),
m_files(nullptr), m_instrument(QString::fromStdString(instrument)) {
generateLoadWidget();
this->addWidget(m_files);
}
void ALFView_view::generateLoadWidget(QWidget *loadBar) {
m_run = new QLineEdit("0");
m_run->setValidator(new QRegExpValidator(QRegExp("[0-9]*"), m_run));
connect(m_run, SIGNAL(editingFinished()), this, SLOT(runChanged()));
m_browse = new QPushButton("Browse");
connect(m_browse, SIGNAL(clicked()), this, SLOT(browse()));
void ALFView_view::generateLoadWidget() {
m_loadRunObservable = new Observable();
QHBoxLayout *loadLayout = new QHBoxLayout(loadBar);
loadLayout->addWidget(m_run);
loadLayout->addWidget(m_browse);
m_files = new API::MWRunFiles(this);
m_files->allowMultipleFiles(false);
m_files->setInstrumentOverride(m_instrument);
m_files->isForRunFiles(true);
connect(m_files, SIGNAL(fileFindingFinished()), this, SLOT(fileLoaded()));
}
int ALFView_view::getRunNumber() { return m_run->text().toInt(); }
std::string ALFView_view::getFile() {
auto name = m_files->getFilenames();
if (name.size() > 0)
return name[0].toStdString();
return "";
}
void ALFView_view::setRunQuietly(const QString runNumber) {
m_run->blockSignals(true);
m_run->setText(runNumber);
m_run->blockSignals(false);
void ALFView_view::setRunQuietly(const std::string runNumber) {
m_files->setText(QString::fromStdString(runNumber));
}
void ALFView_view::runChanged() {
m_loadRunObservable->notify();
} // emit newRun(); }
void ALFView_view::fileLoaded() {
if (m_files->getText().isEmpty())
return;
void ALFView_view::browse() {
auto file =
QFileDialog::getOpenFileName(this, "Open a file", "", "File (*.nxs)");
if (file.isEmpty()) {
if (!m_files->isValid()) {
warningBox(m_files->getFileProblem());
return;
}
// emit browsedToRun(file.toStdString());
m_browseObservable->notify(file.toStdString());
m_loadRunObservable->notify();
}
void ALFView_view::warningBox(const std::string message) {
warningBox(QString::fromStdString(message));
}
void ALFView_view::warningBox(const QString message) {
QMessageBox::warning(this, m_instrument + " view", message);
}
} // namespace CustomInterfaces
} // namespace MantidQt
\ No newline at end of file
......@@ -8,44 +8,42 @@
#define MANTIDQT_CUSTOMINTERFACES_ALFVIEW_VIEW_H_
#include "DllConfig.h"
#include "observerPattern.h"
#include "MantidQtWidgets/Common/ObserverPattern.h"
#include "MantidQtWidgets/Common/MWRunFiles.h"
#include "MantidQtWidgets/InstrumentView/InstrumentWidget.h"
#include <string>
#include <QLineEdit>
#include <QObject>
#include <QPushButton>
#include <string>
#include <QSplitter>
#include <QString>
namespace MantidQt {
namespace CustomInterfaces {
class ALFView_view : public QWidget {
class ALFView_view : public QSplitter {
Q_OBJECT
public:
explicit ALFView_view(QWidget *parent = nullptr);
int getRunNumber();
void setRunQuietly(const QString runNumber);
void observeLoadRun(observer *listener) {
explicit ALFView_view(const std::string instrument, QWidget *parent = nullptr);
std::string getFile();
void setRunQuietly(const std::string runNumber);
void observeLoadRun(Observer *listener) {
m_loadRunObservable->attach(listener);
};
void observeBrowse(observer *listner) {
m_browseObservable->attach(listner);
};
void warningBox(const std::string message);
public slots:
void runChanged();
void browse();
signals:
void newRun();
void browsedToRun(std::string);
public slots:
void fileLoaded();
private:
void generateLoadWidget(QWidget *loadBar);
QLineEdit *m_run;
QPushButton *m_browse;
observable *m_loadRunObservable;
observable *m_browseObservable;
void generateLoadWidget();
void warningBox(const QString message);
Observable *m_loadRunObservable;
API::MWRunFiles *m_files;
QString m_instrument;
};
} // namespace CustomInterfaces
} // namespace MantidQt
......
......@@ -10,54 +10,67 @@
#include <set>
#include <string>
class observable;
/**
* Simple classes for observer and observable pattern.
* These can be used to replace signals and slots for mocking
**/
class observer {
class Observable;
class Observer {
public:
virtual void update() = 0;
virtual void update(std::string arg) = 0;
};
class observable {
std::set<observer *> m_observers;
/**
* Simple observable class. This is used
* to signify if a change has been made and then needs to
* notify its observers.
**/
class Observable {
std::set<Observer *> m_observers;
public:
void attach(observer *listener) { m_observers.insert(listener); };
void detach(observer *listener) { m_observers.erase(listener); };
/**
* @param listener :: want to be notified when this observer changes
**/
void attach(Observer *listener) { m_observers.insert(listener); };
/**
* @param listener :: no longer want to be notified when this observer changes
**/
void detach(Observer *listener) { m_observers.erase(listener); };
/**
* Update all of the observers that a change has been made
**/
void notify() {
for (auto &listener : m_observers) {
listener->update();
}
};
void notify(std ::string arg) {
for (auto &listener : m_observers) {
listener->update(arg);
}
};
};
class loadObserver : public observer {
/**
* Simple observer class (for void functions/slots). This is used
* to update when a change has been made on an observerable.
**/
class VoidObserver : public Observer {
public:
loadObserver() : m_slot(nullptr){};
~loadObserver(){};
VoidObserver() : m_slot(nullptr){};
~VoidObserver(){};
/**
* Sets the function/slot for the oberver
* @param func:: the void function we want to call when the observer
* sends a notify signal
**/
void setSlot(std::function<void()> &func) { m_slot = func; };
/**
* Calls the function/slot
**/
void update() override { m_slot(); };
void update(std::string) override { m_slot(); };
private:
std::function<void()> m_slot;
};