Skip to content
Snippets Groups Projects
EnggDiffractionViewQtGUI.cpp 51.9 KiB
Newer Older
#include "MantidKernel/ConfigService.h"
#include "MantidQtAPI/AlgorithmRunner.h"
#include "MantidQtAPI/AlgorithmInputHistory.h"
#include "MantidQtAPI/HelpWindow.h"
#include "MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionViewQtGUI.h"
#include "MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresenter.h"
#include "MantidQtMantidWidgets/MWRunFiles.h"

using namespace Mantid::API;
using namespace MantidQt::CustomInterfaces;

#include <boost/lexical_cast.hpp>

#include "Poco/DirectoryIterator.h"

#include <QCheckBox>
#include <QCloseEvent>
#include <QMessageBox>
#include <QSettings>
#include <qwt_symbol.h>

namespace MantidQt {
namespace CustomInterfaces {

// Add this class to the list of specialised dialogs in this namespace
DECLARE_SUBWINDOW(EnggDiffractionViewQtGUI)
const double EnggDiffractionViewQtGUI::g_defaultRebinWidth = -0.0005;
int EnggDiffractionViewQtGUI::m_currentType = 0;
int EnggDiffractionViewQtGUI::m_currentRunMode = 0;
int EnggDiffractionViewQtGUI::m_currentCropCalibBankName = 0;
int EnggDiffractionViewQtGUI::m_bank_Id = 0;

const std::string EnggDiffractionViewQtGUI::g_iparmExtStr =
    "GSAS instrument parameters, IPARM file: PRM, PAR, IPAR, IPARAM "
    "(*.prm *.par *.ipar *.iparam);;"
    "Other extensions/all files (*.*)";

const std::string EnggDiffractionViewQtGUI::g_pixelCalibExt =
    "Comma separated values text file with calibration table, CSV"
    "Nexus file with calibration table: NXS, NEXUS"
    "(*.nxs *.nexus);;"
    "Supported formats: CSV, NXS "
    "(*.csv *.nxs *.nexus);;"
    "Other extensions/all files (*.*)";
const std::string EnggDiffractionViewQtGUI::g_DetGrpExtStr =
    "Detector Grouping File: CSV "
    "(*.csv *.txt);;"
    "Other extensions/all files (*.*)";

const std::string EnggDiffractionViewQtGUI::m_settingsGroup =
    "CustomInterfaces/EnggDiffractionView";
* Default constructor.
*
* @param parent Parent window (most likely the Mantid main app window).
*/
EnggDiffractionViewQtGUI::EnggDiffractionViewQtGUI(QWidget *parent)
    : UserSubWindow(parent), IEnggDiffractionView(), m_currentInst("ENGINX"),
      m_currentCalibFilename(""), m_focusedDataVector(), m_fittedDataVector(),
      m_presenter(NULL) {}
EnggDiffractionViewQtGUI::~EnggDiffractionViewQtGUI() {
  for (auto curves : m_focusedDataVector) {
    curves->detach();
    delete curves;
  }

  for (auto curves : m_fittedDataVector) {
    curves->detach();
    delete curves;
  }

void EnggDiffractionViewQtGUI::initLayout() {
  // setup container ui
  m_ui.setupUi(this);
  // add tab contents and set up their ui's
  QWidget *wCalib = new QWidget(m_ui.tabMain);
  m_uiTabCalib.setupUi(wCalib);
  m_ui.tabMain->addTab(wCalib, QString("Calibration"));

  QWidget *wFocus = new QWidget(m_ui.tabMain);
  m_uiTabFocus.setupUi(wFocus);
  m_ui.tabMain->addTab(wFocus, QString("Focus"));

  QWidget *wPreproc = new QWidget(m_ui.tabMain);
  m_uiTabPreproc.setupUi(wPreproc);
  m_ui.tabMain->addTab(wPreproc, QString("Pre-processing"));

  QWidget *wFitting = new QWidget(m_ui.tabMain);
  m_uiTabFitting.setupUi(wFitting);
  m_ui.tabMain->addTab(wFitting, QString("Fitting"));

  QWidget *wSettings = new QWidget(m_ui.tabMain);
  m_uiTabSettings.setupUi(wSettings);
  m_ui.tabMain->addTab(wSettings, QString("Settings"));
  QComboBox *inst = m_ui.comboBox_instrument;
  m_currentInst = inst->currentText().toStdString();
  // basic UI setup, connect signals, etc.
  doSetupGeneralWidgets();
  doSetupTabFitting();
  doSetupTabSettings();

  // presenter that knows how to handle a IEnggDiffractionView should take care
  // of all the logic
  // note that the view needs to know the concrete presenter
  m_presenter.reset(new EnggDiffractionPresenter(this));

  // it will know what compute resources and tools we have available:
  // This view doesn't even know the names of compute resources, etc.
  m_presenter->notify(IEnggDiffractionPresenter::Start);
  m_presenter->notify(IEnggDiffractionPresenter::RBNumberChange);
void EnggDiffractionViewQtGUI::doSetupTabCalib() {
  // Last available runs. This (as well as the empty defaults just
  // above) should probably be made persistent - and encapsulated into a
  // CalibrationParameters or similar class/structure
  const std::string vanadiumRun = "236516";
  const std::string ceriaRun = "241391";
  m_uiTabCalib.lineEdit_new_vanadium_num->setUserInput(
      QString::fromStdString(vanadiumRun));
  m_uiTabCalib.lineEdit_new_ceria_num->setUserInput(
      QString::fromStdString(ceriaRun));
  m_uiTabCalib.lineEdit_cropped_run_num->setUserInput(
      QString::fromStdString(ceriaRun));

  // push button signals/slots
  connect(m_uiTabCalib.pushButton_load_calib, SIGNAL(released()), this,
          SLOT(loadCalibrationClicked()));

  connect(m_uiTabCalib.pushButton_new_calib, SIGNAL(released()), this,
          SLOT(calibrateClicked()));
  connect(m_uiTabCalib.pushButton_new_cropped_calib, SIGNAL(released()), this,
          SLOT(CroppedCalibrateClicked()));

  connect(m_uiTabCalib.comboBox_calib_cropped_bank_name,
          SIGNAL(currentIndexChanged(int)), this,
          SLOT(calibspecNoChanged(int)));
  connect(m_uiTabCalib.lineEdit_new_ceria_num, SIGNAL(fileTextChanged(QString)),
          this, SLOT(updateCroppedCalibRun()));
  connect(m_uiTabCalib.comboBox_calib_cropped_bank_name,
          SIGNAL(currentIndexChanged(int)), this, SLOT(enableSpecNos()));
void EnggDiffractionViewQtGUI::doSetupTabFocus() {

  connect(m_uiTabFocus.pushButton_focus, SIGNAL(released()), this,
          SLOT(focusClicked()));

  connect(m_uiTabFocus.pushButton_focus_cropped, SIGNAL(released()), this,
          SLOT(focusCroppedClicked()));

  connect(m_uiTabFocus.pushButton_texture_browse_grouping_file,
          SIGNAL(released()), this, SLOT(browseTextureDetGroupingFile()));

  connect(m_uiTabFocus.pushButton_focus_texture, SIGNAL(released()), this,
          SLOT(focusTextureClicked()));

  connect(m_uiTabFocus.pushButton_reset, SIGNAL(released()), this,
          SLOT(focusResetClicked()));

  connect(m_uiTabFocus.pushButton_stopFocus, SIGNAL(released()), this,
  connect(m_uiTabFocus.comboBox_PlotData, SIGNAL(currentIndexChanged(int)),
          this, SLOT(plotRepChanged(int)));

  connect(m_uiTabFocus.comboBox_Multi_Runs, SIGNAL(currentIndexChanged(int)),
          this, SLOT(multiRunModeChanged(int)));

  connect(m_uiTabFocus.checkBox_FocusedWS, SIGNAL(clicked()), this,
          SLOT(plotFocusStatus()));
}

void EnggDiffractionViewQtGUI::doSetupTabPreproc() {
  connect(m_uiTabPreproc.pushButton_rebin_time, SIGNAL(released()), this,
          SLOT(rebinTimeClicked()));

  connect(m_uiTabPreproc.pushButton_rebin_multiperiod, SIGNAL(released()), this,
          SLOT(rebinMultiperiodClicked()));
}

void EnggDiffractionViewQtGUI::doSetupTabFitting() {
  connect(m_uiTabFitting.pushButton_fitting_browse_run_num, SIGNAL(released()),
          this, SLOT(browseFitFocusedRun()));
  connect(m_uiTabFitting.comboBox_bank, SIGNAL(currentIndexChanged(int)), this,
          SLOT(fittingBankIdChanged(int)));
  connect(m_uiTabFitting.comboBox_bank, SIGNAL(currentIndexChanged(int)), this,
          SLOT(setListWidgetBank(int)));

  connect(m_uiTabFitting.pushButton_fitting_browse_peaks, SIGNAL(released()),
          this, SLOT(browsePeaksToFit()));

  connect(m_uiTabFitting.pushButton_fit, SIGNAL(released()), this,
  connect(m_uiTabFitting.listWidget_fitting_bank_preview,
          SIGNAL(currentRowChanged(int)), this,
          SLOT(fittingListWidgetBank(int)));
  connect(m_uiTabFitting.listWidget_fitting_bank_preview,
          SIGNAL(currentRowChanged(int)), this, SLOT(setBankIdComboBox(int)));
  connect(m_uiTabFitting.lineEdit_pushButton_run_num, SIGNAL(editingFinished()),
	  SLOT(fittingRunNoChanged()));

  m_uiTabFitting.dataPlot->setCanvasBackground(Qt::white);
  m_uiTabFitting.dataPlot->setAxisTitle(QwtPlot::xBottom,
                                        "Time-of-flight (us)");
  m_uiTabFitting.dataPlot->setAxisTitle(QwtPlot::yLeft, "Counts (us)^-1");
  QFont font("MS Shell Dlg 2", 8);
  m_uiTabFitting.dataPlot->setAxisFont(QwtPlot::xBottom, font);
  m_uiTabFitting.dataPlot->setAxisFont(QwtPlot::yLeft, font);
void EnggDiffractionViewQtGUI::doSetupTabSettings() {
  // line edits that display paths and the like
  m_uiTabSettings.lineEdit_input_dir_calib->setText(
      QString::fromStdString(m_calibSettings.m_inputDirCalib));
  m_uiTabSettings.lineEdit_input_dir_raw->setText(
      QString::fromStdString(m_calibSettings.m_inputDirRaw));
  m_uiTabSettings.lineEdit_pixel_calib_filename->setText(
      QString::fromStdString(m_calibSettings.m_pixelCalibFilename));
  m_uiTabSettings.lineEdit_template_gsas_prm->setText(
      QString::fromStdString(m_calibSettings.m_templateGSAS_PRM));
  m_calibSettings.m_forceRecalcOverwrite = false;
  m_uiTabSettings.checkBox_force_recalculate_overwrite->setChecked(
      m_calibSettings.m_forceRecalcOverwrite);
  m_uiTabSettings.lineEdit_dir_focusing->setText(
      QString::fromStdString(m_focusDir));

  // push button signals/slots
  connect(m_uiTabSettings.pushButton_browse_input_dir_calib, SIGNAL(released()),
          this, SLOT(browseInputDirCalib()));

  connect(m_uiTabSettings.pushButton_browse_input_dir_raw, SIGNAL(released()),
          this, SLOT(browseInputDirRaw()));

  connect(m_uiTabSettings.pushButton_browse_pixel_calib_filename,
          SIGNAL(released()), this, SLOT(browsePixelCalibFilename()));

  connect(m_uiTabSettings.pushButton_browse_template_gsas_prm,
          SIGNAL(released()), this, SLOT(browseTemplateGSAS_PRM()));
  connect(m_uiTabSettings.pushButton_browse_dir_focusing, SIGNAL(released()),
          this, SLOT(browseDirFocusing()));
void EnggDiffractionViewQtGUI::doSetupGeneralWidgets() {
  // change instrument
  connect(m_ui.comboBox_instrument, SIGNAL(currentIndexChanged(int)), this,
          SLOT(instrumentChanged(int)));
  connect(m_ui.pushButton_help, SIGNAL(released()), this, SLOT(openHelpWin()));
  // note connection to the parent window, otherwise an empty frame window
  // may remain open and visible after this close
  connect(m_ui.pushButton_close, SIGNAL(released()), this->parent(),
          SLOT(close()));

  connect(m_ui.lineEdit_RBNumber, SIGNAL(editingFinished()), this,
          SLOT(RBNumberChanged()));
void EnggDiffractionViewQtGUI::readSettings() {
  QSettings qs;
  qs.beginGroup(QString::fromStdString(m_settingsGroup));

  m_ui.lineEdit_RBNumber->setText(
      qs.value("user-params-RBNumber", "").toString());
  m_uiTabCalib.lineEdit_current_vanadium_num->setText(
      qs.value("user-params-current-vanadium-num", "").toString());
  m_uiTabCalib.lineEdit_current_ceria_num->setText(
      qs.value("user-params-current-ceria-num", "").toString());
  QString calibFname = qs.value("current-calib-filename", "").toString();
  m_uiTabCalib.lineEdit_current_calib_filename->setText(calibFname);
  m_currentCalibFilename = calibFname.toStdString();

  m_uiTabCalib.lineEdit_new_vanadium_num->setText(
      qs.value("user-params-new-vanadium-num", "").toString());
  m_uiTabCalib.lineEdit_new_ceria_num->setText(
      qs.value("user-params-new-ceria-num", "").toString());

  m_uiTabCalib.groupBox_calib_cropped->setChecked(
      qs.value("user-params-calib-cropped-group-checkbox", false).toBool());
  m_uiTabCalib.lineEdit_cropped_run_num->setText(
      qs.value("user-params-new-ceria-num", "").toString());

  m_uiTabCalib.lineEdit_cropped_run_num->setReadOnly(true);

  m_uiTabCalib.comboBox_calib_cropped_bank_name->setCurrentIndex(0);
  m_uiTabCalib.lineEdit_cropped_spec_nos->setText(
      qs.value("user-params-calib-cropped-spectrum-nos", "").toString());

  m_uiTabCalib.lineEdit_cropped_customise_bank_name->setText(
      qs.value("user-params-calib-cropped-customise-name", "cropped")
          .toString());
  m_uiTabCalib.checkBox_PlotData_Calib->setChecked(
      qs.value("user-param-calib-plot-data", true).toBool());

  m_uiTabFocus.lineEdit_run_num->setUserInput(
      qs.value("user-params-focus-runno", "").toString());

  qs.beginReadArray("user-params-focus-bank_i");
  qs.setArrayIndex(0);
  m_uiTabFocus.checkBox_focus_bank1->setChecked(
      qs.value("value", true).toBool());
  m_uiTabFocus.checkBox_focus_bank2->setChecked(
      qs.value("value", true).toBool());
  m_uiTabFocus.lineEdit_cropped_run_num->setUserInput(
      qs.value("user-params-focus-cropped-runno", "").toString());

  m_uiTabFocus.lineEdit_cropped_spec_nos->setText(
      qs.value("user-params-focus-cropped-spectrum-nos", "").toString());

  m_uiTabFocus.lineEdit_texture_run_num->setUserInput(
      qs.value("user-params-focus-texture-runno", "").toString());

  m_uiTabFocus.lineEdit_texture_grouping_file->setText(
      qs.value("user-params-focus-texture-detector-grouping-file", "")
          .toString());

  m_uiTabFocus.groupBox_cropped->setChecked(
      qs.value("user-params-focus-cropped-group-checkbox", false).toBool());

  m_uiTabFocus.groupBox_texture->setChecked(
      qs.value("user-params-focus-texture-group-checkbox", false).toBool());
  m_uiTabFocus.checkBox_FocusedWS->setChecked(
      qs.value("user-params-focus-plot-ws", true).toBool());

  m_uiTabFocus.comboBox_PlotData->setCurrentIndex(0);

  m_uiTabFocus.comboBox_Multi_Runs->setCurrentIndex(0);

  // pre-processing (re-binning)
  m_uiTabPreproc.MWRunFiles_preproc_run_num->setUserInput(
      qs.value("user-params-preproc-runno", "").toString());

  m_uiTabPreproc.doubleSpinBox_time_bin->setValue(
      qs.value("user-params-time-bin", 0.1).toDouble());

  m_uiTabPreproc.spinBox_nperiods->setValue(
      qs.value("user-params-nperiods", 2).toInt());

  m_uiTabPreproc.doubleSpinBox_step_time->setValue(
      qs.value("user-params-step-time", 1).toDouble());

  // user params - fitting
  m_uiTabFitting.lineEdit_pushButton_run_num->setText(
      qs.value("user-params-fitting-focused-file", "").toString());
  m_uiTabFitting.comboBox_bank->setCurrentIndex(0);
  m_uiTabFitting.lineEdit_fitting_peaks->setText(
      qs.value("user-params-fitting-peaks-to-fit", "").toString());
  m_uiTabFitting.listWidget_fitting_bank_preview->setCurrentRow(0);
  QString lastPath =
      MantidQt::API::AlgorithmInputHistory::Instance().getPreviousDirectory();
  // TODO: as this is growing, it should become << >> operators on
  m_calibSettings.m_inputDirCalib =
      qs.value("input-dir-calib-files", lastPath).toString().toStdString();
  m_calibSettings.m_inputDirRaw =
      qs.value("input-dir-raw-files", lastPath).toString().toStdString();
  const std::string fullCalib = guessDefaultFullCalibrationPath();
  m_calibSettings.m_pixelCalibFilename =
      qs.value("pixel-calib-filename", QString::fromStdString(fullCalib))
          .toString()
          .toStdString();
  // 'advanced' block
  m_calibSettings.m_forceRecalcOverwrite =
      qs.value("force-recalc-overwrite", false).toBool();
  const std::string templ = guessGSASTemplatePath();
  m_calibSettings.m_templateGSAS_PRM =
      qs.value("template-gsas-prm", QString::fromStdString(templ))
          .toString()
          .toStdString();
  m_calibSettings.m_forceRecalcOverwrite =
      qs.value("rebin-calib", g_defaultRebinWidth).toBool();
  // 'focusing' block
  m_focusDir = qs.value("focus-dir").toString().toStdString();

  restoreGeometry(qs.value("interface-win-geometry").toByteArray());
  qs.endGroup();
}

void EnggDiffractionViewQtGUI::saveSettings() const {
  QSettings qs;
  qs.beginGroup(QString::fromStdString(m_settingsGroup));

  qs.setValue("user-params-RBNumber", m_ui.lineEdit_RBNumber->text());
  qs.setValue("user-params-current-vanadium-num",
              m_uiTabCalib.lineEdit_current_vanadium_num->text());
  qs.setValue("user-params-current-ceria-num",
              m_uiTabCalib.lineEdit_current_ceria_num->text());
  qs.setValue("current-calib-filename",
              m_uiTabCalib.lineEdit_current_calib_filename->text());

  qs.setValue("user-params-new-vanadium-num",
              m_uiTabCalib.lineEdit_new_vanadium_num->getText());
  qs.setValue("user-params-new-ceria-num",
              m_uiTabCalib.lineEdit_new_ceria_num->getText());
  qs.setValue("user-params-calib-cropped-group-checkbox",
              m_uiTabCalib.groupBox_calib_cropped->isChecked());
  qs.setValue("user-params-calib-cropped-spectrum-nos",
              m_uiTabCalib.lineEdit_cropped_spec_nos->text());

  qs.setValue("user-params-calib-cropped-customise-name",
              m_uiTabCalib.lineEdit_cropped_customise_bank_name->text());

  qs.setValue("user-param-calib-plot-data",
              m_uiTabCalib.checkBox_PlotData_Calib->isChecked());

  qs.setValue("user-params-focus-runno",
              m_uiTabFocus.lineEdit_run_num->getText());

  qs.beginWriteArray("user-params-focus-bank_i");
  qs.setArrayIndex(0);
  qs.setValue("value", m_uiTabFocus.checkBox_focus_bank1->isChecked());
  qs.setArrayIndex(1);
  qs.setValue("value", m_uiTabFocus.checkBox_focus_bank2->isChecked());
  qs.endArray();

  qs.setValue("user-params-focus-cropped-runno",
              m_uiTabFocus.lineEdit_cropped_run_num->getText());
  qs.setValue("user-params-focus-cropped-spectrum-nos",
              m_uiTabFocus.lineEdit_cropped_spec_nos->text());

  qs.setValue("user-params-focus-texture-runno",
              m_uiTabFocus.lineEdit_texture_run_num->getText());
  qs.setValue("user-params-focus-texture-detector-grouping-file",
              m_uiTabFocus.lineEdit_texture_grouping_file->text());

  qs.setValue("user-params-focus-cropped-group-checkbox",
              m_uiTabFocus.groupBox_cropped->isChecked());

  qs.setValue("user-params-focus-texture-group-checkbox",
              m_uiTabFocus.groupBox_texture->isChecked());
  qs.setValue("value", m_uiTabFocus.checkBox_FocusedWS->isChecked());
  // pre-processing (re-binning)
  qs.setValue("user-params-preproc-runno",
              m_uiTabPreproc.MWRunFiles_preproc_run_num->getText());

  qs.setValue("user-params-time-bin",
              m_uiTabPreproc.doubleSpinBox_time_bin->value());

  qs.setValue("user-params-nperiods", m_uiTabPreproc.spinBox_nperiods->value());

  qs.value("user-params-step-time",
           m_uiTabPreproc.doubleSpinBox_step_time->value());


  qs.setValue("user-params-fitting-focused-file",
              m_uiTabFitting.lineEdit_pushButton_run_num->text());
  qs.setValue("user-params-fitting-peaks-to-fit",
              m_uiTabFitting.lineEdit_fitting_peaks->text());

  // TODO: this should become << >> operators on EnggDiffCalibSettings
  qs.setValue("input-dir-calib-files",
              QString::fromStdString(m_calibSettings.m_inputDirCalib));
  qs.setValue("input-dir-raw-files",
              QString::fromStdString(m_calibSettings.m_inputDirRaw));
  qs.setValue("pixel-calib-filename",
              QString::fromStdString(m_calibSettings.m_pixelCalibFilename));
  // 'advanced' block
  qs.setValue("force-recalc-overwrite", m_calibSettings.m_forceRecalcOverwrite);
  qs.setValue("template-gsas-prm",
              QString::fromStdString(m_calibSettings.m_templateGSAS_PRM));
  qs.setValue("rebin-calib", m_calibSettings.m_rebinCalibrate);
  qs.setValue("focus-dir", QString::fromStdString(m_focusDir));
  qs.setValue("interface-win-geometry", saveGeometry());
  qs.endGroup();
}

std::string EnggDiffractionViewQtGUI::guessGSASTemplatePath() const {
  // Inside the mantid installation target directory:
  // scripts/Engineering/template_ENGINX_241391_236516_North_and_South_banks.par
  Poco::Path templ =
      Mantid::Kernel::ConfigService::Instance().getInstrumentDirectory();
  templ = templ.makeParent();
  templ.append("scripts");
  templ.append("Engineering");
  templ.append("template_ENGINX_241391_236516_North_and_South_banks.par");
  return templ.toString();
}
std::string EnggDiffractionViewQtGUI::guessDefaultFullCalibrationPath() const {
  // Inside the mantid installation target directory:
  // scripts/Engineering/ENGINX_full_pixel_calibration_vana194547_ceria193749.csv
  Poco::Path templ =
      Mantid::Kernel::ConfigService::Instance().getInstrumentDirectory();
  templ = templ.makeParent();
  templ.append("scripts");
  templ.append("Engineering");
  templ.append("ENGINX_full_pixel_calibration_vana194547_ceria193749.csv");
  return templ.toString();
}
void EnggDiffractionViewQtGUI::userWarning(const std::string &err,
                                           const std::string &description) {
  QMessageBox::warning(this, QString::fromStdString(err),
                       QString::fromStdString(description), QMessageBox::Ok,
                       QMessageBox::Ok);
}

void EnggDiffractionViewQtGUI::userError(const std::string &err,
                                         const std::string &description) {
  QMessageBox::critical(this, QString::fromStdString(err),
                        QString::fromStdString(description), QMessageBox::Ok,
                        QMessageBox::Ok);
}

std::string EnggDiffractionViewQtGUI::askNewCalibrationFilename(
    const std::string &suggestedFname) {
  // append dir (basename) + filename
  QString prevPath = QString::fromStdString(m_calibSettings.m_inputDirCalib);
  if (prevPath.isEmpty()) {
    prevPath =
        MantidQt::API::AlgorithmInputHistory::Instance().getPreviousDirectory();
  }
  QDir path(prevPath);
  QString suggestion = path.filePath(QString::fromStdString(suggestedFname));
  QString choice = QFileDialog::getSaveFileName(
      this, tr("Please select the name of the calibration file"), suggestion,
      QString::fromStdString(g_iparmExtStr));
std::string EnggDiffractionViewQtGUI::getRBNumber() const {
  return m_ui.lineEdit_RBNumber->text().toStdString();
std::string EnggDiffractionViewQtGUI::currentVanadiumNo() const {
  return m_uiTabCalib.lineEdit_current_vanadium_num->text().toStdString();
}

std::string EnggDiffractionViewQtGUI::currentCeriaNo() const {
  return m_uiTabCalib.lineEdit_current_ceria_num->text().toStdString();
std::vector<std::string> EnggDiffractionViewQtGUI::newVanadiumNo() const {
  return qListToVector(m_uiTabCalib.lineEdit_new_vanadium_num->getFilenames(),
                       m_uiTabCalib.lineEdit_new_vanadium_num->isValid());
std::vector<std::string> EnggDiffractionViewQtGUI::newCeriaNo() const {
  return qListToVector(m_uiTabCalib.lineEdit_new_ceria_num->getFilenames(),
                       m_uiTabCalib.lineEdit_new_ceria_num->isValid());
std::string EnggDiffractionViewQtGUI::currentCalibFile() const {
  return m_uiTabCalib.lineEdit_current_calib_filename->text().toStdString();
}

void EnggDiffractionViewQtGUI::newCalibLoaded(const std::string &vanadiumNo,
                                              const std::string &ceriaNo,
                                              const std::string &fname) {

  m_uiTabCalib.lineEdit_current_vanadium_num->setText(
  m_uiTabCalib.lineEdit_current_ceria_num->setText(
      QString::fromStdString(ceriaNo));
  m_uiTabCalib.lineEdit_current_calib_filename->setText(
      QString::fromStdString(fname));

  if (!fname.empty()) {
    MantidQt::API::AlgorithmInputHistory::Instance().setPreviousDirectory(
        QString::fromStdString(fname));
  }
void EnggDiffractionViewQtGUI::enableCalibrateAndFocusActions(bool enable) {
  // calibrate
  m_uiTabCalib.groupBox_make_new_calib->setEnabled(enable);
  m_uiTabCalib.groupBox_current_calib->setEnabled(enable);
  m_uiTabCalib.groupBox_calib_cropped->setEnabled(enable);
  m_uiTabCalib.pushButton_new_cropped_calib->setEnabled(enable);
  m_ui.pushButton_close->setEnabled(enable);
  m_uiTabCalib.checkBox_PlotData_Calib->setEnabled(enable);

  // focus
  m_uiTabFocus.lineEdit_run_num->setEnabled(enable);

  m_uiTabFocus.groupBox_cropped->setEnabled(enable);
  m_uiTabFocus.groupBox_texture->setEnabled(enable);

  m_uiTabFocus.pushButton_focus->setEnabled(enable);
  m_uiTabFocus.checkBox_FocusedWS->setEnabled(enable);
  m_uiTabFocus.checkBox_SaveOutputFiles->setEnabled(enable);
  m_uiTabFocus.comboBox_Multi_Runs->setEnabled(enable);

  m_uiTabFocus.pushButton_focus->setEnabled(enable);
  m_uiTabFocus.pushButton_stopFocus->setDisabled(enable);

  // pre-processing
  m_uiTabPreproc.MWRunFiles_preproc_run_num->setEnabled(enable);
  m_uiTabPreproc.pushButton_rebin_time->setEnabled(enable);
  m_uiTabPreproc.pushButton_rebin_multiperiod->setEnabled(enable);
  m_uiTabFitting.pushButton_fitting_browse_run_num->setEnabled(enable);
  m_uiTabFitting.lineEdit_pushButton_run_num->setEnabled(enable);
  m_uiTabFitting.pushButton_fitting_browse_peaks->setEnabled(enable);
  m_uiTabFitting.lineEdit_fitting_peaks->setEnabled(enable);
  m_uiTabFitting.pushButton_fit->setEnabled(enable);
void EnggDiffractionViewQtGUI::enableTabs(bool enable) {
  for (int ti = 0; ti < m_ui.tabMain->count(); ++ti) {
    m_ui.tabMain->setTabEnabled(ti, enable);
  }
}

std::vector<std::string> EnggDiffractionViewQtGUI::currentPreprocRunNo() const {
  return qListToVector(
      m_uiTabPreproc.MWRunFiles_preproc_run_num->getFilenames(),
      m_uiTabPreproc.MWRunFiles_preproc_run_num->isValid());
}

double EnggDiffractionViewQtGUI::rebinningTimeBin() const {
  return m_uiTabPreproc.doubleSpinBox_time_bin->value();
}

size_t EnggDiffractionViewQtGUI::rebinningPulsesNumberPeriods() const {
  return m_uiTabPreproc.spinBox_nperiods->value();
}

double EnggDiffractionViewQtGUI::rebinningPulsesTime() const {
  return m_uiTabPreproc.doubleSpinBox_step_time->value();
void EnggDiffractionViewQtGUI::setBankDir(QString path) {
  std::string dir = path.toStdString();
  Poco::Path fpath(dir);

  std::string bank1Dir;
  std::string bank2Dir;
Shahroz Ahmed's avatar
Shahroz Ahmed committed
    std::string fileName = fpath.getBaseName();
	std::string fileDir = fpath.parent().toString();
    if (fileName.find("bank_1") != std::string::npos && m_bank_Id == 0) {
      bank1Dir = path;
    } else {
		bank1Dir =fittingRunNoFactory("1", fileName, bank1Dir, fileDir);
    }

    if (fileName.find("bank_2") != std::string::npos && m_bank_Id == 1) {
      bank2Dir = path;
    } else {
		bank2Dir = fittingRunNoFactory("2", fileName, bank2Dir, fileDir);
    }
    if (fileName.find("bank_3") != std::string::npos && m_bank_Id == 2) {
      bank3Dir = path;
    } else {
		bank3Dir = fittingRunNoFactory("3", fileName, bank3Dir, fileDir);
    }
  if (m_bank_Id == 0) {
    setfittingRunNo(QString::fromUtf8(bank1Dir.c_str()));
  } else if (m_bank_Id == 1) {
    setfittingRunNo(QString::fromUtf8(bank2Dir.c_str()));
  } else if (m_bank_Id == 2) {
    setfittingRunNo(QString::fromUtf8(bank3Dir.c_str()));
  }
}

std::string EnggDiffractionViewQtGUI::fittingRunNoFactory(
    std::string bank, std::string fileName, std::string &bankDir, std::string fileDir) {

Shahroz Ahmed's avatar
Shahroz Ahmed committed
  std::string genDir = fileName.substr(0, fileName.size() - 1);
  Poco::Path bankFile(genDir + bank + ".nxs");
  if (bankFile.isFile()) {
    bankDir = fileDir + genDir + bank + ".nxs";
  }
  return bankDir;
std::string EnggDiffractionViewQtGUI::readPeaksFile(std::string fileDir) {
  std::string fileData = "";
  std::string line;
  std::string comma = ", ";

  std::ifstream peakFile(fileDir);

  if (peakFile.is_open()) {
    while (std::getline(peakFile, line)) {
      fileData += line;
      if (!peakFile.eof())
        fileData += comma;
void EnggDiffractionViewQtGUI::setDataVector(
    std::vector<boost::shared_ptr<QwtData>> &data, bool focused) {
  if (focused) {
    dataCurvesFactory(data, m_focusedDataVector, focused);
  } else {
    dataCurvesFactory(data, m_fittedDataVector, focused);
  }
}
void EnggDiffractionViewQtGUI::dataCurvesFactory(
    std::vector<boost::shared_ptr<QwtData>> &data,
    std::vector<QwtPlotCurve *> &dataVector, bool focused) {
  for (auto curves : dataVector) {
    if (curves) {
      curves->detach();
      delete curves;
    }
  }

  if (dataVector.size() > 0)
    dataVector.clear();
  // dark colours could be removed so the colored peaks stand out more
  const QColor QPenList[16] = {
      Qt::white,      Qt::red,     Qt::darkRed,     Qt::green,
      Qt::darkGreen,  Qt::blue,    Qt::darkBlue,    Qt::cyan,
      Qt::darkCyan,   Qt::magenta, Qt::darkMagenta, Qt::yellow,
      Qt::darkYellow, Qt::gray,    Qt::darkGray,    Qt::lightGray};
  for (size_t i = 0; i < data.size(); i++) {
    auto *peak = data[i].get();

    QwtPlotCurve *dataCurve = new QwtPlotCurve();
    dataCurve->setStyle(QwtPlotCurve::Lines);
    if (!focused) {
      auto randIndex = std::rand() % 15;
      dataCurve->setPen(QPen(QPenList[randIndex], 1));
    }
    dataCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
    dataVector.push_back(dataCurve);
    dataVector[i]->setData(*peak);
    dataVector[i]->attach(m_uiTabFitting.dataPlot);

  m_uiTabFitting.dataPlot->replot();
void EnggDiffractionViewQtGUI::plotFocusedSpectrum(const std::string &wsName) {
      "win=plotSpectrum('" + wsName + "', 0, error_bars=False, type=0)";
  std::string status =
      runPythonCode(QString::fromStdString(pyCode), false).toStdString();
  m_logMsgs.emplace_back("Plotted output focused data, with status string " +
                         status);
  m_presenter->notify(IEnggDiffractionPresenter::LogMsg);
}

void EnggDiffractionViewQtGUI::plotWaterfallSpectrum(
    const std::string &wsName) {
  // parameter of list ?
  std::string pyCode =
      "plotSpectrum('" + wsName +
      "', 0, error_bars=False, type=0, waterfall=True, window=win)";
  std::string status =
      runPythonCode(QString::fromStdString(pyCode), false).toStdString();
  m_logMsgs.emplace_back("Plotted output focused data, with status string " +
                         status);
  m_presenter->notify(IEnggDiffractionPresenter::LogMsg);
}

void EnggDiffractionViewQtGUI::plotReplacingWindow(const std::string &wsName,
                                                   const std::string &spectrum,
                                                   const std::string &type) {
  std::string pyCode = "win=plotSpectrum('" + wsName + "', " + spectrum +
                       ", error_bars=False, type=" + type +
                       ", window=win, clearWindow=True)";
  std::string status =
      runPythonCode(QString::fromStdString(pyCode), false).toStdString();

  m_logMsgs.emplace_back("Plotted output focused data, with status string " +
                         status);
  m_presenter->notify(IEnggDiffractionPresenter::LogMsg);
}

void EnggDiffractionViewQtGUI::plotVanCurvesCalibOutput() {
      "van_curves_ws = workspace(\"engggui_vanadium_curves_ws\")\n"
      "win = plotSpectrum(van_curves_ws, [0, 1, 2])";
      runPythonCode(QString::fromStdString(pyCode), false).toStdString();

  m_logMsgs.push_back(
      "Plotted output calibration vanadium curves, with status string " +
      status);
  m_presenter->notify(IEnggDiffractionPresenter::LogMsg);
void EnggDiffractionViewQtGUI::plotDifcZeroCalibOutput(
    const std::string &pyCode) {

  std::string status =
      runPythonCode(QString::fromStdString(pyCode), false).toStdString();

  m_logMsgs.push_back(
      "Plotted output calibration ceria peaks, with status string " + status);
  m_presenter->notify(IEnggDiffractionPresenter::LogMsg);
}

void EnggDiffractionViewQtGUI::resetFocus() {
  m_uiTabFocus.lineEdit_run_num->setText("");
  m_uiTabFocus.checkBox_focus_bank1->setChecked(true);
  m_uiTabFocus.checkBox_focus_bank2->setChecked(true);

  m_uiTabFocus.lineEdit_cropped_run_num->setText("");
  m_uiTabFocus.lineEdit_cropped_spec_nos->setText("");
  m_uiTabFocus.groupBox_cropped->setChecked(false);
  m_uiTabFocus.groupBox_texture->setChecked(false);

  m_uiTabFocus.lineEdit_texture_run_num->setText("");
  m_uiTabFocus.lineEdit_texture_grouping_file->setText("");
}

void EnggDiffractionViewQtGUI::writeOutCalibFile(
    const std::string &outFilename, const std::vector<double> &difc,
    const std::vector<double> &tzero) {
  // TODO: this is horrible and should not last much here.
  // Avoid running Python code
  // Update this as soon as we have a more stable way of generating IPARM
  // files
  // Writes a file doing this:
  // write_ENGINX_GSAS_iparam_file(output_file, difc, zero, ceria_run=241391,
  // vanadium_run=236516, template_file=None):

  // this replace is to prevent issues with network drives on windows:
Shahroz Ahmed's avatar
Shahroz Ahmed committed
  const std::string safeOutFname =
      boost::replace_all_copy(outFilename, "\\", "/");
  std::string pyCode = "import EnggUtils\n";
  pyCode += "import os\n";
  // normalize apparently not needed after the replace, but to be double-safe:
  pyCode += "GSAS_iparm_fname= os.path.normpath('" + safeOutFname + "')\n";
  pyCode += "Difcs = []\n";
  pyCode += "Zeros = []\n";
  for (size_t i = 0; i < difc.size(); i++) {
    pyCode +=
        "Difcs.append(" + boost::lexical_cast<std::string>(difc[i]) + ")\n";
    pyCode +=
        "Zeros.append(" + boost::lexical_cast<std::string>(tzero[i]) + ")\n";
  }
  pyCode += "EnggUtils.write_ENGINX_GSAS_iparam_file(GSAS_iparm_fname, Difcs, "
            "Zeros) \n";

  std::string status =
      runPythonCode(QString::fromStdString(pyCode), false).toStdString();

  // g_log.information()
  //     << "Saved output calibration file through Python. Status: " << status
  //     << std::endl;
  m_logMsgs.push_back(
      "Run Python code to save output file, with status string: " + status);
  m_presenter->notify(IEnggDiffractionPresenter::LogMsg);
std::string EnggDiffractionViewQtGUI::askExistingCalibFilename() {
  QString prevPath = QString::fromStdString(m_calibSettings.m_inputDirCalib);
  if (prevPath.isEmpty()) {
        MantidQt::API::AlgorithmInputHistory::Instance().getPreviousDirectory();
  }

  QString filename =
      QFileDialog::getOpenFileName(this, tr("Open calibration file"), prevPath,
                                   QString::fromStdString(g_iparmExtStr));
  if (!filename.isEmpty()) {
    MantidQt::API::AlgorithmInputHistory::Instance().setPreviousDirectory(
        filename);
  }

  return filename.toStdString();
}
void EnggDiffractionViewQtGUI::loadCalibrationClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::LoadExistingCalib);
}

void EnggDiffractionViewQtGUI::calibrateClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::CalcCalib);
}
void EnggDiffractionViewQtGUI::CroppedCalibrateClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::CropCalib);
}

void EnggDiffractionViewQtGUI::focusClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::FocusRun);
void EnggDiffractionViewQtGUI::focusCroppedClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::FocusCropped);
}

void EnggDiffractionViewQtGUI::focusTextureClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::FocusTexture);
}

void EnggDiffractionViewQtGUI::focusResetClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::ResetFocus);
void EnggDiffractionViewQtGUI::focusStopClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::StopFocus);
void EnggDiffractionViewQtGUI::rebinTimeClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::RebinTime);
}

void EnggDiffractionViewQtGUI::rebinMultiperiodClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::RebinMultiperiod);
void EnggDiffractionViewQtGUI::fitClicked() {
  m_presenter->notify(IEnggDiffractionPresenter::FitPeaks);
}

void EnggDiffractionViewQtGUI::browseInputDirCalib() {
  QString prevPath = QString::fromStdString(m_calibSettings.m_inputDirCalib);
  if (prevPath.isEmpty()) {
    prevPath =
        MantidQt::API::AlgorithmInputHistory::Instance().getPreviousDirectory();
  }
  QString dir = QFileDialog::getExistingDirectory(
      this, tr("Open Directory"), prevPath,
      QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);

  if (dir.isEmpty()) {
    return;
  }