From d4bf294fcb4005adaab04fa7527f3e51a6a04069 Mon Sep 17 00:00:00 2001
From: Dan Nixon <dan@dan-nixon.com>
Date: Mon, 24 Nov 2014 16:24:42 +0000
Subject: [PATCH] Range and preview spectrum selectors on IDA

Refs #10626
---
 .../inc/MantidQtCustomInterfaces/ConvFit.h    |   4 +-
 .../inc/MantidQtCustomInterfaces/FuryFit.h    |   5 +-
 .../IndirectDataAnalysis.ui                   |  97 ++-----
 .../inc/MantidQtCustomInterfaces/MSDFit.h     |   4 +-
 .../MantidQt/CustomInterfaces/src/ConvFit.cpp | 125 +++++----
 .../MantidQt/CustomInterfaces/src/FuryFit.cpp | 241 ++++++++----------
 .../MantidQt/CustomInterfaces/src/MSDFit.cpp  |  38 ++-
 7 files changed, 238 insertions(+), 276 deletions(-)

diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvFit.h
index fa12f02b47c..7a3b8fe60ab 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvFit.h
+++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvFit.h
@@ -30,10 +30,12 @@ namespace IDA
   private slots:
     void typeSelection(int index);
     void bgTypeSelection(int index);
-    void newDataLoaded();
+    void newDataLoaded(const QString wsName);
     void plotInput();
     void plotGuess(QtProperty*);
     void singleFit();
+    void specMinChanged(int value);
+    void specMaxChanged(int value);
     void minChanged(double);
     void maxChanged(double);
     void backgLevel(double);
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/FuryFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/FuryFit.h
index a85db056ce0..2d30bde7ff6 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/FuryFit.h
+++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/FuryFit.h
@@ -38,7 +38,10 @@ namespace IDA
 
   private slots:
     void typeSelection(int index);
+    void newDataLoaded(const QString wsName);
     void plotInput();
+    void specMinChanged(int value);
+    void specMaxChanged(int value);
     void xMinSelected(double val);
     void xMaxSelected(double val);
     void backgroundSelected(double val);
@@ -57,7 +60,7 @@ namespace IDA
     void setDefaultParameters(const QString& name);
     QString fitTypeString() const;
     void constrainIntensities(Mantid::API::CompositeFunction_sptr func);
-    
+
     QtStringPropertyManager* m_stringManager;
     QtTreePropertyBrowser* m_ffTree; ///< FuryFit Property Browser
     QtDoublePropertyManager* m_ffRangeManager; ///< StartX and EndX for FuryFit
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataAnalysis.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataAnalysis.ui
index 33f0dd359c9..8f52c4665e7 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataAnalysis.ui
+++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataAnalysis.ui
@@ -561,83 +561,31 @@
           <property name="title">
            <string>Input</string>
           </property>
-          <layout class="QHBoxLayout" name="furyfit_layoutInput">
+          <layout class="QVBoxLayout" name="verticalLayout_7">
            <item>
-            <widget class="QComboBox" name="furyfit_cbInputType">
-             <item>
-              <property name="text">
-               <string>File</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>Workspace</string>
-              </property>
-             </item>
-            </widget>
-           </item>
-           <item>
-            <widget class="QStackedWidget" name="furyfit_swInput">
+            <widget class="MantidQt::MantidWidgets::DataSelector" name="furyfit_dsSampleInput" native="true">
              <property name="sizePolicy">
-              <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+              <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
                <horstretch>0</horstretch>
                <verstretch>0</verstretch>
               </sizepolicy>
              </property>
-             <property name="currentIndex">
-              <number>0</number>
+             <property name="workspaceSuffixes" stdset="0">
+              <stringlist>
+               <string>_iqt</string>
+              </stringlist>
+             </property>
+             <property name="fileBrowserSuffixes" stdset="0">
+              <stringlist>
+               <string>_iqt.nxs</string>
+              </stringlist>
+             </property>
+             <property name="showLoad" stdset="0">
+              <bool>false</bool>
+             </property>
+             <property name="autoLoad" stdset="0">
+              <bool>true</bool>
              </property>
-             <widget class="QWidget" name="furyfit_page_inputFile">
-              <layout class="QHBoxLayout" name="horizontalLayout_19">
-               <item>
-                <widget class="MantidQt::MantidWidgets::MWRunFiles" name="furyfit_inputFile" native="true">
-                 <property name="sizePolicy">
-                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-                   <horstretch>0</horstretch>
-                   <verstretch>41</verstretch>
-                  </sizepolicy>
-                 </property>
-                 <property name="findRunFiles" stdset="0">
-                  <bool>false</bool>
-                 </property>
-                 <property name="label" stdset="0">
-                  <string/>
-                 </property>
-                 <property name="multipleFiles" stdset="0">
-                  <bool>false</bool>
-                 </property>
-                 <property name="fileExtensions" stdset="0">
-                  <stringlist>
-                   <string>_iqt.nxs</string>
-                  </stringlist>
-                 </property>
-                </widget>
-               </item>
-               <item>
-                <widget class="QPushButton" name="furyfit_pbPlotInput">
-                 <property name="text">
-                  <string>Plot Input</string>
-                 </property>
-                </widget>
-               </item>
-              </layout>
-             </widget>
-             <widget class="QWidget" name="furyfit_page_inputWorkspace">
-              <layout class="QHBoxLayout" name="horizontalLayout_12">
-               <item>
-                <widget class="MantidQt::MantidWidgets::WorkspaceSelector" name="furyfit_wsIqt">
-                 <property name="WorkspaceTypes" stdset="0">
-                  <stringlist/>
-                 </property>
-                 <property name="Suffix" stdset="0">
-                  <stringlist>
-                   <string>_iqt</string>
-                  </stringlist>
-                 </property>
-                </widget>
-               </item>
-              </layout>
-             </widget>
             </widget>
            </item>
           </layout>
@@ -2734,11 +2682,6 @@
    <extends>QWidget</extends>
    <header>MantidQtMantidWidgets/MWRunFiles.h</header>
   </customwidget>
-  <customwidget>
-   <class>MantidQt::MantidWidgets::WorkspaceSelector</class>
-   <extends>QComboBox</extends>
-   <header>MantidQtMantidWidgets/WorkspaceSelector.h</header>
-  </customwidget>
   <customwidget>
    <class>MantidQt::MantidWidgets::DataSelector</class>
    <extends>QWidget</extends>
@@ -2757,7 +2700,6 @@
   <tabstop>fury_ckVerbose</tabstop>
   <tabstop>fury_ckPlot</tabstop>
   <tabstop>fury_ckSave</tabstop>
-  <tabstop>furyfit_cbInputType</tabstop>
   <tabstop>furyfit_cbFitType</tabstop>
   <tabstop>furyfit_ckConstrainIntensities</tabstop>
   <tabstop>furyfit_ckPlotGuess</tabstop>
@@ -2769,9 +2711,6 @@
   <tabstop>pbRun</tabstop>
   <tabstop>pbManageDirs</tabstop>
   <tabstop>leLogName</tabstop>
-  <tabstop>furyfit_inputFile</tabstop>
-  <tabstop>furyfit_pbPlotInput</tabstop>
-  <tabstop>furyfit_wsIqt</tabstop>
   <tabstop>furyfit_ckConstrainBeta</tabstop>
   <tabstop>furyfit_ckVerbose</tabstop>
   <tabstop>furyfit_ckSaveSeq</tabstop>
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MSDFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MSDFit.h
index 063b7eacc46..fd0951849ee 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MSDFit.h
+++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MSDFit.h
@@ -26,8 +26,10 @@ namespace IDA
   private slots:
     void singleFit();
     void plotFit(QString wsName);
-    void newDataLoaded();
+    void newDataLoaded(const QString wsName);
     void plotInput();
+    void specMinChanged(int value);
+    void specMaxChanged(int value);
     void minChanged(double val);
     void maxChanged(double val);
     void updateRS(QtProperty* prop, double val);
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ConvFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ConvFit.cpp
index cf3be48f87a..b7aea42f698 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/ConvFit.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/ConvFit.cpp
@@ -27,15 +27,15 @@ namespace CustomInterfaces
 {
 namespace IDA
 {
-  ConvFit::ConvFit(QWidget * parent) : 
+  ConvFit::ConvFit(QWidget * parent) :
     IDATab(parent),
-    m_stringManager(NULL), m_cfTree(NULL), 
+    m_stringManager(NULL), m_cfTree(NULL),
     m_fixedProps(),
     m_cfInputWS(), m_cfInputWSName(),
     m_confitResFileType()
   {
   }
-  
+
   void ConvFit::setup()
   {
     // Create Property Managers
@@ -58,7 +58,7 @@ namespace IDA
 
     // Create Range Selectors
     m_rangeSelectors["ConvFitRange"] = new MantidQt::MantidWidgets::RangeSelector(m_plots["ConvFitPlot"]);
-    m_rangeSelectors["ConvFitBackRange"] = new MantidQt::MantidWidgets::RangeSelector(m_plots["ConvFitPlot"], 
+    m_rangeSelectors["ConvFitBackRange"] = new MantidQt::MantidWidgets::RangeSelector(m_plots["ConvFitPlot"],
       MantidQt::MantidWidgets::RangeSelector::YSINGLE);
     m_rangeSelectors["ConvFitBackRange"]->setColour(Qt::darkGreen);
     m_rangeSelectors["ConvFitBackRange"]->setRange(0.0, 1.0);
@@ -124,8 +124,11 @@ namespace IDA
 
     // Replot input automatically when file / spec no changes
     connect(uiForm().confit_spPlotSpectrum, SIGNAL(valueChanged(int)), this, SLOT(plotInput()));
-    connect(uiForm().confit_dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(newDataLoaded()));
-    
+    connect(uiForm().confit_dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(newDataLoaded(const QString&)));
+
+    connect(uiForm().confit_spSpectraMin, SIGNAL(valueChanged(int)), this, SLOT(specMinChanged(int)));
+    connect(uiForm().confit_spSpectraMax, SIGNAL(valueChanged(int)), this, SLOT(specMaxChanged(int)));
+
     connect(uiForm().confit_cbFitType, SIGNAL(currentIndexChanged(int)), this, SLOT(typeSelection(int)));
     connect(uiForm().confit_cbBackground, SIGNAL(currentIndexChanged(int)), this, SLOT(bgTypeSelection(int)));
     connect(uiForm().confit_pbSingle, SIGNAL(clicked()), this, SLOT(singleFit()));
@@ -170,15 +173,9 @@ namespace IDA
       "endx = " + enX + "\n"
       "plot = '" + uiForm().confit_cbPlotOutput->currentText() + "'\n"
       "ties = " + ties + "\n"
-      "save = ";
-  
-    if(uiForm().confit_spSpectraMin->text() != "")
-      pyInput += "specMin = " + uiForm().confit_spSpectraMin->text() + "\n";
-
-    if(uiForm().confit_spSpectraMax->text() != "")
-      pyInput += "specMax = " + uiForm().confit_spSpectraMax->text() + "\n";
-
-    pyInput += uiForm().confit_ckSaveSeq->isChecked() ? "True\n" : "False\n";
+      "specMin = " + uiForm().confit_spSpectraMin->text() + "\n"
+      "specMax = " + uiForm().confit_spSpectraMax->text() + "\n"
+      "save = " + (uiForm().confit_ckSaveSeq->isChecked() ? "True\n" : "False\n");
 
     if ( m_blnManager->value(m_properties["Convolve"]) ) pyInput += "convolve = True\n";
     else pyInput += "convolve = False\n";
@@ -188,7 +185,7 @@ namespace IDA
 
     QString temperature = uiForm().confit_leTempCorrection->text();
     bool useTempCorrection = (!temperature.isEmpty() && uiForm().confit_ckTempCorrection->isChecked());
-    if ( useTempCorrection ) 
+    if ( useTempCorrection )
     {
       pyInput += "temp=" + temperature + "\n";
     }
@@ -196,8 +193,8 @@ namespace IDA
     {
       pyInput += "temp=None\n";
     }
-  
-    pyInput +=    
+
+    pyInput +=
       "bg = '" + bg + "'\n"
       "ftype = '" + ftype + "'\n"
       "confitSeq(input, func, startx, endx, ftype, bg, temp, specMin, specMax, convolve, Verbose=verbose, Plot=plot, Save=save)\n";
@@ -211,7 +208,7 @@ namespace IDA
   bool ConvFit::validate()
   {
     using Mantid::API::AnalysisDataService;
-    
+
     UserInputValidator uiv;
 
     uiv.checkDataSelectorIsValid("Sample", uiForm().confit_dsSampleInput);
@@ -241,20 +238,24 @@ namespace IDA
    * Called when new data has been loaded by the data selector.
    *
    * Configures ranges for spin boxes before raw plot is done.
+   *
+   * @param wsName Name of new workspace loaded
    */
-  void ConvFit::newDataLoaded()
+  void ConvFit::newDataLoaded(const QString wsName)
   {
-    if(uiForm().confit_dsSampleInput->getCurrentDataName() != m_cfInputWSName)
-    {      
-      m_cfInputWSName = uiForm().confit_dsSampleInput->getCurrentDataName();
-      m_cfInputWS = AnalysisDataService::Instance().retrieveWS<const MatrixWorkspace>(m_cfInputWSName.toStdString()); 
-    }
+    m_cfInputWSName = wsName;
+    m_cfInputWS = AnalysisDataService::Instance().retrieveWS<const MatrixWorkspace>(m_cfInputWSName.toStdString());
 
     int maxSpecIndex = static_cast<int>(m_cfInputWS->getNumberHistograms()) - 1;
 
     uiForm().confit_spPlotSpectrum->setMaximum(maxSpecIndex);
+    uiForm().confit_spPlotSpectrum->setMinimum(0);
+
     uiForm().confit_spSpectraMin->setMaximum(maxSpecIndex);
+    uiForm().confit_spSpectraMin->setMinimum(0);
+
     uiForm().confit_spSpectraMax->setMaximum(maxSpecIndex);
+    uiForm().confit_spSpectraMax->setMinimum(0);
     uiForm().confit_spSpectraMax->setValue(maxSpecIndex);
 
     plotInput();
@@ -283,7 +284,7 @@ namespace IDA
     }
 
     /**
-     * Takes an index, a sub index and a name, and constructs a double level 
+     * Takes an index, a sub index and a name, and constructs a double level
      * (nested) parameter name for use with function ties, etc.
      *
      * @param index    :: the index of the function in the first level.
@@ -338,10 +339,10 @@ namespace IDA
     // --- Composite / Linear Background ---
     // -------------------------------------
     func = Mantid::API::FunctionFactory::Instance().createFunction("LinearBackground");
-    comp->addFunction(func); 
+    comp->addFunction(func);
 
     const int bgType = uiForm().confit_cbBackground->currentIndex(); // 0 = Fixed Flat, 1 = Fit Flat, 2 = Fit all
-  
+
     if ( bgType == 0 || ! m_properties["BGA0"]->subProperties().isEmpty() )
     {
       comp->tie("f0.A0", m_properties["BGA0"]->valueText().toStdString() );
@@ -369,10 +370,10 @@ namespace IDA
     // --------------------------------------------
     func = Mantid::API::FunctionFactory::Instance().createFunction("Resolution");
     conv->addFunction(func);
-    
+
     //add resolution file
     if (uiForm().confit_dsResInput->isFileSelectorVisible())
-    {    
+    {
       std::string resfilename = uiForm().confit_dsResInput->getFullFilePath().toStdString();
       Mantid::API::IFunction::Attribute attr(resfilename);
       func->setAttribute("FileName", attr);
@@ -416,7 +417,7 @@ namespace IDA
     std::string prefix1;
     std::string prefix2;
 
-    int fitTypeIndex = uiForm().confit_cbFitType->currentIndex();  
+    int fitTypeIndex = uiForm().confit_cbFitType->currentIndex();
 
     // Add 1st Lorentzian
     if(fitTypeIndex > 0)
@@ -424,7 +425,7 @@ namespace IDA
       //if temperature not included then product is lorentzian * 1
       //create product function for temp * lorentzian
       auto product = boost::dynamic_pointer_cast<Mantid::API::CompositeFunction>(Mantid::API::FunctionFactory::Instance().createFunction("ProductFunction"));
-      
+
       if(useTempCorrection)
       {
         createTemperatureCorrection(product);
@@ -444,7 +445,7 @@ namespace IDA
       //if temperature not included then product is lorentzian * 1
       //create product function for temp * lorentzian
       auto product = boost::dynamic_pointer_cast<Mantid::API::CompositeFunction>(Mantid::API::FunctionFactory::Instance().createFunction("ProductFunction"));
-    
+
       if(useTempCorrection)
       {
         createTemperatureCorrection(product);
@@ -454,7 +455,7 @@ namespace IDA
       subIndex = product->addFunction(func);
       index = model->addFunction(product);
       prefix2 = createParName(index, subIndex);
-      
+
       populateFunction(func, model, m_properties["Lorentzian2"], prefix2, false);
     }
 
@@ -478,7 +479,7 @@ namespace IDA
     //create temperature correction function to multiply with the lorentzians
     Mantid::API::IFunction_sptr tempFunc;
     QString temperature = uiForm().confit_leTempCorrection->text();
-    
+
     //create user function for the exponential correction
     // (x*temp) / 1-exp(-(x*temp))
     tempFunc = Mantid::API::FunctionFactory::Instance().createFunction("UserFunction");
@@ -526,7 +527,7 @@ namespace IDA
 
       resolution = 0;
     }
-      
+
     return resolution;
   }
 
@@ -600,7 +601,7 @@ namespace IDA
 
     return fitType;
   }
-  
+
   /**
    * Generate a string to describe the background selected by the user.
    * Used when naming the resultant workspaces.
@@ -620,7 +621,7 @@ namespace IDA
       return "FitF_s";
     case 2:
       return "FitL_s";
-    default: 
+    default:
       return "";
     }
   }
@@ -629,7 +630,7 @@ namespace IDA
   {
     m_cfTree->removeProperty(m_properties["Lorentzian1"]);
     m_cfTree->removeProperty(m_properties["Lorentzian2"]);
-  
+
     switch ( index )
     {
     case 0:
@@ -644,7 +645,7 @@ namespace IDA
       m_cfTree->addProperty(m_properties["Lorentzian2"]);
       m_rangeSelectors["ConvFitHWHM"]->setVisible(true);
       break;
-    }    
+    }
   }
 
   void ConvFit::bgTypeSelection(int index)
@@ -795,7 +796,7 @@ namespace IDA
     }
 
     QString outputNm = runPythonCode(QString("from IndirectCommon import getWSprefix\nprint getWSprefix('") + m_cfInputWSName + QString("')\n")).trimmed();
-    outputNm += QString("conv_") + ftype + bg + uiForm().confit_spPlotSpectrum->text();  
+    outputNm += QString("conv_") + ftype + bg + uiForm().confit_spPlotSpectrum->text();
     std::string output = outputNm.toStdString();
 
     Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("Fit");
@@ -810,7 +811,7 @@ namespace IDA
     alg->setProperty("OutputCompositeMembers", true);
     alg->setProperty("ConvolveMembers", true);
     alg->execute();
-   
+
     if ( ! alg->isExecuted() )
     {
       showMessageBox("Fit algorithm failed.");
@@ -847,7 +848,7 @@ namespace IDA
 		int subIndex = 0;
 
 		//check if we're using a temperature correction
-		if (uiForm().confit_ckTempCorrection->isChecked() && 
+		if (uiForm().confit_ckTempCorrection->isChecked() &&
 				!uiForm().confit_leTempCorrection->text().isEmpty())
 		{
 				subIndex++;
@@ -864,7 +865,7 @@ namespace IDA
 			{
 				key += "f0.";
 			}
-			
+
 			key += "Height";
 
       m_dblManager->setValue(m_properties["DeltaHeight"], parameters[key]);
@@ -903,6 +904,30 @@ namespace IDA
     }
   }
 
+  /**
+   * Handles the user entering a new minimum spectrum index.
+   *
+   * Prevents the user entering an overlapping spectra range.
+   *
+   * @param value Minimum spectrum index
+   */
+  void ConvFit::specMinChanged(int value)
+  {
+    uiForm().confit_spSpectraMax->setMinimum(value);
+  }
+
+  /**
+   * Handles the user entering a new maximum spectrum index.
+   *
+   * Prevents the user entering an overlapping spectra range.
+   *
+   * @param value Maximum spectrum index
+   */
+  void ConvFit::specMaxChanged(int value)
+  {
+    uiForm().confit_spSpectraMin->setMaximum(value);
+  }
+
   void ConvFit::minChanged(double val)
   {
     m_dblManager->setValue(m_properties["StartX"], val);
@@ -953,14 +978,14 @@ namespace IDA
     // Add/remove some properties to display only relevant options
     if ( prop == m_properties["UseDeltaFunc"] )
     {
-      if ( checked ) 
-      { 
+      if ( checked )
+      {
         m_properties["DeltaFunction"]->addSubProperty(m_properties["DeltaHeight"]);
         uiForm().confit_cbPlotOutput->addItem("Height");
         uiForm().confit_cbPlotOutput->addItem("EISF");
       }
-      else 
-      { 
+      else
+      {
         m_properties["DeltaFunction"]->removeSubProperty(m_properties["DeltaHeight"]);
         uiForm().confit_cbPlotOutput->removeItem(uiForm().confit_cbPlotOutput->count()-1);
         uiForm().confit_cbPlotOutput->removeItem(uiForm().confit_cbPlotOutput->count()-1);
@@ -986,7 +1011,7 @@ namespace IDA
     // is it already fixed?
     bool fixed = prop->propertyManager() != m_dblManager;
 
-    if ( fixed && prop->propertyManager() != m_stringManager ) 
+    if ( fixed && prop->propertyManager() != m_stringManager )
       return;
 
     // Create the menu
@@ -1034,7 +1059,7 @@ namespace IDA
 
     QtProperty* prop = item->property();
     if ( prop->subProperties().empty() )
-    { 
+    {
       item = item->parent();
       prop = item->property();
     }
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/FuryFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/FuryFit.cpp
index e42348ee962..4b82337600e 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/FuryFit.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/FuryFit.cpp
@@ -15,13 +15,15 @@
 #include <qwt_plot.h>
 #include <qwt_plot_curve.h>
 
+using namespace Mantid::API;
+
 namespace MantidQt
 {
 namespace CustomInterfaces
 {
 namespace IDA
 {
-  FuryFit::FuryFit(QWidget * parent) : 
+  FuryFit::FuryFit(QWidget * parent) :
     IDATab(parent),
     m_stringManager(NULL), m_ffTree(NULL),
     m_ffRangeManager(NULL),
@@ -31,21 +33,21 @@ namespace IDA
     m_ties()
   {
   }
-      
+
   void FuryFit::setup()
   {
     m_stringManager = new QtStringPropertyManager(m_parentWidget);
 
     m_ffTree = new QtTreePropertyBrowser(m_parentWidget);
     uiForm().furyfit_properties->addWidget(m_ffTree);
-  
+
     // Setup FuryFit Plot Window
     m_plots["FuryFitPlot"] = new QwtPlot(m_parentWidget);
     m_plots["FuryFitPlot"]->setAxisFont(QwtPlot::xBottom, m_parentWidget->font());
     m_plots["FuryFitPlot"]->setAxisFont(QwtPlot::yLeft, m_parentWidget->font());
     uiForm().furyfit_vlPlot->addWidget(m_plots["FuryFitPlot"]);
     m_plots["FuryFitPlot"]->setCanvasBackground(QColor(255,255,255));
-  
+
     m_rangeSelectors["FuryFitRange"] = new MantidQt::MantidWidgets::RangeSelector(m_plots["FuryFitPlot"]);
     connect(m_rangeSelectors["FuryFitRange"], SIGNAL(minValueChanged(double)), this, SLOT(xMinSelected(double)));
     connect(m_rangeSelectors["FuryFitRange"], SIGNAL(maxValueChanged(double)), this, SLOT(xMaxSelected(double)));
@@ -58,7 +60,7 @@ namespace IDA
 
     // setupTreePropertyBrowser
     m_ffRangeManager = new QtDoublePropertyManager(m_parentWidget);
-  
+
     m_ffTree->setFactoryForManager(m_dblManager, doubleEditorFactory());
     m_ffTree->setFactoryForManager(m_ffRangeManager, doubleEditorFactory());
 
@@ -77,7 +79,7 @@ namespace IDA
 
     m_properties["Exponential1"] = createExponential("Exponential1");
     m_properties["Exponential2"] = createExponential("Exponential2");
-  
+
     m_properties["StretchedExp"] = createStretchedExp("StretchedExp");
 
     m_ffRangeManager->setMinimum(m_properties["BackgroundA0"], 0);
@@ -98,17 +100,16 @@ namespace IDA
     connect(m_dblManager, SIGNAL(propertyChanged(QtProperty*)), this, SLOT(plotGuess(QtProperty*)));
 
     // Signal/slot ui connections
-    connect(uiForm().furyfit_inputFile, SIGNAL(fileEditingFinished()), this, SLOT(plotInput()));
+    connect(uiForm().furyfit_dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(newDataLoaded(const QString&)));
     connect(uiForm().furyfit_cbFitType, SIGNAL(currentIndexChanged(int)), this, SLOT(typeSelection(int)));
-    connect(uiForm().furyfit_spPlotSpectrum, SIGNAL(editingFinished()), this, SLOT(plotInput()));
-    connect(uiForm().furyfit_cbInputType, SIGNAL(currentIndexChanged(int)), uiForm().furyfit_swInput, SLOT(setCurrentIndex(int)));  
     connect(uiForm().furyfit_pbSingle, SIGNAL(clicked()), this, SLOT(singleFit()));
 
-    //plot input connections
-    connect(uiForm().furyfit_inputFile, SIGNAL(filesFound()), this, SLOT(plotInput()));
-    connect(uiForm().furyfit_wsIqt, SIGNAL(currentIndexChanged(int)), this, SLOT(plotInput()));
-    connect(uiForm().furyfit_pbPlotInput, SIGNAL(clicked()), this, SLOT(plotInput()));
-    connect(uiForm().furyfit_cbInputType, SIGNAL(currentIndexChanged(int)), this, SLOT(plotInput()));
+    connect(uiForm().furyfit_dsSampleInput, SIGNAL(filesFound()), this, SLOT(plotInput()));
+
+    connect(uiForm().furyfit_spPlotSpectrum, SIGNAL(valueChanged(int)), this, SLOT(plotInput()));
+
+    connect(uiForm().furyfit_spSpectraMin, SIGNAL(valueChanged(int)), this, SLOT(specMinChanged(int)));
+    connect(uiForm().furyfit_spSpectraMax, SIGNAL(valueChanged(int)), this, SLOT(specMaxChanged(int)));
 
     // Set a custom handler for the QTreePropertyBrowser's ContextMenu event
     m_ffTree->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -124,16 +125,16 @@ namespace IDA
 
     const bool constrainBeta = uiForm().furyfit_ckConstrainBeta->isChecked();
     const bool constrainIntens = uiForm().furyfit_ckConstrainIntensities->isChecked();
-    Mantid::API::CompositeFunction_sptr func = createFunction();
+    CompositeFunction_sptr func = createFunction();
     func->tie("f0.A1", "0");
-    
+
     if ( constrainIntens )
     {
       constrainIntensities(func);
     }
-    
+
     func->applyTies();
-    
+
     std::string function = std::string(func->asString());
     QString pyInput = "from IndirectDataAnalysis import furyfitSeq, furyfitMult\n"
       "input = '" + m_ffInputWSName + "'\n"
@@ -163,38 +164,15 @@ namespace IDA
     {
       pyInput += "furyfitMult(input, func, ftype, startx, endx, spec_min=spec_min, spec_max=spec_max, intensities_constrained=constrain_intens, Save=save, Plot=plot, Verbose=verbose)\n";
     }
-  
+
     QString pyOutput = runPythonCode(pyInput);
   }
 
   bool FuryFit::validate()
   {
-    using namespace Mantid::API;
-
     UserInputValidator uiv;
 
-    switch( uiForm().furyfit_cbInputType->currentIndex() )
-    {
-    case 0:
-      uiv.checkMWRunFilesIsValid("Input", uiForm().furyfit_inputFile); 
-
-      //file should already be loaded by this point, but attempt to recover if not.
-      if(!AnalysisDataService::Instance().doesExist(m_ffInputWSName.toStdString()))
-      {
-        //attempt to reload the nexus file.
-        QString filename = uiForm().furyfit_inputFile->getFirstFilename();
-        QFileInfo fi(filename);
-        QString wsname = fi.baseName();
-
-        loadFile(filename, wsname);
-        m_ffInputWSName = wsname;
-        m_ffInputWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsname.toStdString());
-      }
-
-      break;
-    case 1:
-      uiv.checkWorkspaceSelectorIsNotEmpty("Input", uiForm().furyfit_wsIqt); break;
-    }
+    uiv.checkDataSelectorIsValid("Sample", uiForm().furyfit_dsSampleInput);
 
     auto range = std::make_pair(m_ffRangeManager->value(m_properties["StartX"]), m_ffRangeManager->value(m_properties["EndX"]));
     uiv.checkValidRange("Ranges", range);
@@ -207,21 +185,48 @@ namespace IDA
 
   void FuryFit::loadSettings(const QSettings & settings)
   {
-    uiForm().furyfit_inputFile->readSettings(settings.group());
+    uiForm().furyfit_dsSampleInput->readSettings(settings.group());
   }
 
-  Mantid::API::CompositeFunction_sptr FuryFit::createFunction(bool tie)
+  /**
+   * Called when new data has been loaded by the data selector.
+   *
+   * Configures ranges for spin boxes before raw plot is done.
+   *
+   * @param wsName Name of new workspace loaded
+   */
+  void FuryFit::newDataLoaded(const QString wsName)
   {
-    Mantid::API::CompositeFunction_sptr result( new Mantid::API::CompositeFunction );
+    m_ffInputWSName = wsName;
+    m_ffInputWS = AnalysisDataService::Instance().retrieveWS<const MatrixWorkspace>(m_ffInputWSName.toStdString());
+
+    int maxSpecIndex = static_cast<int>(m_ffInputWS->getNumberHistograms()) - 1;
+
+    uiForm().furyfit_spPlotSpectrum->setMaximum(maxSpecIndex);
+    uiForm().furyfit_spPlotSpectrum->setMinimum(0);
+
+    uiForm().furyfit_spSpectraMin->setMaximum(maxSpecIndex);
+    uiForm().furyfit_spSpectraMin->setMinimum(0);
+
+    uiForm().furyfit_spSpectraMax->setMaximum(maxSpecIndex);
+    uiForm().furyfit_spSpectraMax->setMinimum(0);
+    uiForm().furyfit_spSpectraMax->setValue(maxSpecIndex);
+
+    plotInput();
+  }
+
+  CompositeFunction_sptr FuryFit::createFunction(bool tie)
+  {
+    CompositeFunction_sptr result( new CompositeFunction );
     QString fname;
     const int fitType = uiForm().furyfit_cbFitType->currentIndex();
 
-    Mantid::API::IFunction_sptr func = Mantid::API::FunctionFactory::Instance().createFunction("LinearBackground");
+    IFunction_sptr func = FunctionFactory::Instance().createFunction("LinearBackground");
     func->setParameter("A0", m_ffRangeManager->value(m_properties["BackgroundA0"]));
     result->addFunction(func);
     result->tie("f0.A1", "0");
     if ( tie ) { result->tie("f0.A0", m_properties["BackgroundA0"]->valueText().toStdString()); }
-  
+
     if ( fitType == 2 ) { fname = "StretchedExp"; }
     else { fname = "Exponential1"; }
 
@@ -239,15 +244,15 @@ namespace IDA
     return result;
   }
 
-  Mantid::API::IFunction_sptr FuryFit::createUserFunction(const QString & name, bool tie)
+  IFunction_sptr FuryFit::createUserFunction(const QString & name, bool tie)
   {
-    Mantid::API::IFunction_sptr result = Mantid::API::FunctionFactory::Instance().createFunction("UserFunction");  
+    IFunction_sptr result = FunctionFactory::Instance().createFunction("UserFunction");
     std::string formula;
 
     if ( name.startsWith("Exp") ) { formula = "Intensity*exp(-(x/Tau))"; }
     else { formula = "Intensity*exp(-(x/Tau)^Beta)"; }
 
-    Mantid::API::IFunction::Attribute att(formula);  
+    IFunction::Attribute att(formula);
     result->setAttribute("Formula", att);
 
     QList<QtProperty*> props = m_properties[name]->subProperties();
@@ -255,7 +260,7 @@ namespace IDA
     {
       std::string name = props[i]->propertyName().toStdString();
       result->setParameter(name, m_dblManager->value(props[i]));
-      
+
       //add tie if parameter is fixed
       if ( tie || ! props[i]->subProperties().isEmpty() )
       {
@@ -263,7 +268,7 @@ namespace IDA
         result->tie(name, value);
       }
     }
-    
+
     result->applyTies();
     return result;
   }
@@ -320,7 +325,7 @@ namespace IDA
     m_ffTree->addProperty(m_properties["StartX"]);
     m_ffTree->addProperty(m_properties["EndX"]);
     m_ffTree->addProperty(m_properties["LinearBackground"]);
-    
+
     //option should only be available with a single stretched exponential
     uiForm().furyfit_ckConstrainBeta->setEnabled((index == 2));
     if (!uiForm().furyfit_ckConstrainBeta->isEnabled())
@@ -351,7 +356,7 @@ namespace IDA
       {
         uiForm().furyfit_cbPlotOutput->addItem("Beta");
       }
-      
+
       break;
     case 3:
       m_ffTree->addProperty(m_properties["Exponential1"]);
@@ -371,82 +376,16 @@ namespace IDA
 
   void FuryFit::plotInput()
   {
-    using namespace Mantid::API;
-    switch ( uiForm().furyfit_cbInputType->currentIndex() )
-    {
-    case 0: // "File"
-      {
-        if ( ! uiForm().furyfit_inputFile->isValid() )
-        {
-          return;
-        }
-        else
-        {
-          QFileInfo fi(uiForm().furyfit_inputFile->getFirstFilename());
-          QString wsname = fi.baseName();
-          if ( (m_ffInputWS == NULL) || ( wsname != m_ffInputWSName ) )
-          {
-            m_ffInputWSName = wsname;
-            QString filename = uiForm().furyfit_inputFile->getFirstFilename();
-            // get the output workspace
-            loadFile(filename, m_ffInputWSName);
-            m_ffInputWS = AnalysisDataService::Instance().retrieveWS<const MatrixWorkspace>(m_ffInputWSName.toStdString());
-            if(!m_ffInputWS)
-            {
-              return;
-            }
-          }
-        }
-      }
-      break;
-    case 1: // Workspace
-      {
-        m_ffInputWSName = uiForm().furyfit_wsIqt->currentText();
-        if(m_ffInputWSName.isEmpty())
-        {
-          return;
-        }
-        try
-        {
-          m_ffInputWS = AnalysisDataService::Instance().retrieveWS<const MatrixWorkspace>(m_ffInputWSName.toStdString());
-        }
-        catch ( Mantid::Kernel::Exception::NotFoundError & )
-        {
-          QString msg = "Workspace: '" + m_ffInputWSName + "' could not be "
-            "found in the Analysis Data Service.";
-          showMessageBox(msg);
-          return;
-        }
-      }
-      break;
-    }
-
-    int specNo = uiForm().furyfit_spPlotSpectrum->text().toInt();
-    int nHist = static_cast<int>(m_ffInputWS->getNumberHistograms());
-    int specMin = 0;
-    int specMax = nHist - 1;
-
-    if( specNo < 0 || specNo >= nHist )
-    {
-      if (specNo < 0)
-      {
-        specNo = 0;
-      }
-      else
-      {
-        specNo = nHist-1;
-      }
-      /* uiForm().furyfit_spPlotSpectrum->setText(QString::number(specNo)); */
-    }
-
+    int specNo = uiForm().furyfit_spPlotSpectrum->value();
     plotMiniPlot(m_ffInputWS, specNo, "FuryFitPlot", "FF_DataCurve");
+
     try
     {
       const std::pair<double, double> range = getCurveRange("FF_DataCurve");
       m_rangeSelectors["FuryFitRange"]->setRange(range.first, range.second);
       m_ffRangeManager->setRange(m_properties["StartX"], range.first, range.second);
       m_ffRangeManager->setRange(m_properties["EndX"], range.first, range.second);
-      
+
       setDefaultParameters("Exponential1");
       setDefaultParameters("Exponential2");
       setDefaultParameters("StretchedExp");
@@ -479,6 +418,30 @@ namespace IDA
     m_dblManager->setValue(m_properties[name+".Beta"], 1.0);
   }
 
+  /**
+   * Handles the user entering a new minimum spectrum index.
+   *
+   * Prevents the user entering an overlapping spectra range.
+   *
+   * @param value Minimum spectrum index
+   */
+  void FuryFit::specMinChanged(int value)
+  {
+    uiForm().furyfit_spSpectraMax->setMinimum(value);
+  }
+
+  /**
+   * Handles the user entering a new maximum spectrum index.
+   *
+   * Prevents the user entering an overlapping spectra range.
+   *
+   * @param value Maximum spectrum index
+   */
+  void FuryFit::specMaxChanged(int value)
+  {
+    uiForm().furyfit_spSpectraMin->setMaximum(value);
+  }
+
   void FuryFit::xMinSelected(double val)
   {
     m_ffRangeManager->setValue(m_properties["StartX"], val);
@@ -514,8 +477,8 @@ namespace IDA
       m_dblManager->setValue(m_properties["Exponential2.Intensity"], 1.0-val);
       m_dblManager->setValue(m_properties["StretchedExp.Intensity"], 1.0-val);
     }
-    else if( prop == m_properties["Exponential1.Intensity"] 
-      || prop == m_properties["Exponential2.Intensity"] 
+    else if( prop == m_properties["Exponential1.Intensity"]
+      || prop == m_properties["Exponential2.Intensity"]
       || prop == m_properties["StretchedExp.Intensity"])
     {
       m_rangeSelectors["FuryFitBackground"]->setMinimum(1.0-val);
@@ -525,7 +488,7 @@ namespace IDA
     }
   }
 
-  void FuryFit::constrainIntensities(Mantid::API::CompositeFunction_sptr func)
+  void FuryFit::constrainIntensities(CompositeFunction_sptr func)
   {
     std::string paramName = "f1.Intensity";
     size_t index = func->parameterIndex(paramName);
@@ -541,7 +504,7 @@ namespace IDA
       else
       {
         std::string paramValue = boost::lexical_cast<std::string>(func->getParameter(paramName));
-        func->tie(paramName, paramValue); 
+        func->tie(paramName, paramValue);
         func->tie("f0.A0", "1-"+paramName);
       }
       break;
@@ -598,7 +561,7 @@ namespace IDA
     std::string output = outputNm.toStdString();
 
     // Create the Fit Algorithm
-    Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("Fit");
+    IAlgorithm_sptr alg = AlgorithmManager::Instance().create("Fit");
     alg->initialize();
     alg->setPropertyValue("Function", function->asString());
     alg->setPropertyValue("InputWorkspace", m_ffInputWSName.toStdString());
@@ -623,7 +586,7 @@ namespace IDA
     m_curves["FF_FitCurve"]->setPen(fitPen);
     replot("FuryFitPlot");
 
-    Mantid::API::IFunction_sptr outputFunc = alg->getProperty("Function");
+    IFunction_sptr outputFunc = alg->getProperty("Function");
 
     // Get params.
     QMap<QString,double> parameters;
@@ -637,13 +600,13 @@ namespace IDA
       parameters[QString(parNames[i].c_str())] = parVals[i];
 
     m_ffRangeManager->setValue(m_properties["BackgroundA0"], parameters["f0.A0"]);
-  
+
     if ( fitType != 2 )
     {
       // Exp 1
       m_dblManager->setValue(m_properties["Exponential1.Intensity"], parameters["f1.Intensity"]);
       m_dblManager->setValue(m_properties["Exponential1.Tau"], parameters["f1.Tau"]);
-    
+
       if ( fitType == 1 )
       {
         // Exp 2
@@ -651,14 +614,14 @@ namespace IDA
         m_dblManager->setValue(m_properties["Exponential2.Tau"], parameters["f2.Tau"]);
       }
     }
-  
+
     if ( fitType > 1 )
     {
       // Str
       QString fval;
       if ( fitType == 2 ) { fval = "f1."; }
       else { fval = "f2."; }
-    
+
       m_dblManager->setValue(m_properties["StretchedExp.Intensity"], parameters[fval+"Intensity"]);
       m_dblManager->setValue(m_properties["StretchedExp.Tau"], parameters[fval+"Tau"]);
       m_dblManager->setValue(m_properties["StretchedExp.Beta"], parameters[fval+"Beta"]);
@@ -672,7 +635,7 @@ namespace IDA
       return;
     }
 
-    Mantid::API::CompositeFunction_sptr function = createFunction(true);
+    CompositeFunction_sptr function = createFunction(true);
 
     // Create the double* array from the input workspace
     const size_t binIndxLow = m_ffInputWS->binIndexOf(m_ffRangeManager->value(m_properties["StartX"]));
@@ -693,8 +656,8 @@ namespace IDA
         inputXData[i] = XValues[binIndxLow+i];
     }
 
-    Mantid::API::FunctionDomain1DVector domain(inputXData);
-    Mantid::API::FunctionValues outputData(domain);
+    FunctionDomain1DVector domain(inputXData);
+    FunctionValues outputData(domain);
     function->function(domain, outputData);
 
     QVector<double> dataX;
@@ -731,7 +694,7 @@ namespace IDA
     // is it already fixed?
     bool fixed = prop->propertyManager() != m_dblManager;
 
-    if ( fixed && prop->propertyManager() != m_stringManager ) 
+    if ( fixed && prop->propertyManager() != m_stringManager )
       return;
 
     // Create the menu
@@ -778,7 +741,7 @@ namespace IDA
 
     QtProperty* prop = item->property();
     if ( prop->subProperties().empty() )
-    { 
+    {
       item = item->parent();
       prop = item->property();
     }
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MSDFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MSDFit.cpp
index 36ad46bb448..cd8ce5d0ecb 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/MSDFit.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MSDFit.cpp
@@ -52,9 +52,12 @@ namespace IDA
     connect(m_rangeSelectors["MSDRange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double)));
     connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateRS(QtProperty*, double)));
 
-    connect(uiForm().msd_dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(newDataLoaded()));
+    connect(uiForm().msd_dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(newDataLoaded(const QString&)));
     connect(uiForm().msd_pbSingle, SIGNAL(clicked()), this, SLOT(singleFit()));
     connect(uiForm().msd_spPlotSpectrum, SIGNAL(valueChanged(int)), this, SLOT(plotInput()));
+
+    connect(uiForm().msd_spSpectraMin, SIGNAL(valueChanged(int)), this, SLOT(specMinChanged(int)));
+    connect(uiForm().msd_spSpectraMax, SIGNAL(valueChanged(int)), this, SLOT(specMaxChanged(int)));
   }
 
   void MSDFit::run()
@@ -107,7 +110,7 @@ namespace IDA
   bool MSDFit::validate()
   {
     UserInputValidator uiv;
-    
+
     uiv.checkDataSelectorIsValid("Sample input", uiForm().msd_dsSampleInput);
 
     auto range = std::make_pair(m_dblManager->value(m_properties["Start"]), m_dblManager->value(m_properties["End"]));
@@ -147,11 +150,12 @@ namespace IDA
    * Called when new data has been loaded by the data selector.
    *
    * Configures ranges for spin boxes before raw plot is done.
+   *
+   * @param wsName Name of new workspace loaded
    */
-  void MSDFit::newDataLoaded()
+  void MSDFit::newDataLoaded(const QString wsName)
   {
-    QString wsname = uiForm().msd_dsSampleInput->getCurrentDataName();
-    auto ws = Mantid::API::AnalysisDataService::Instance().retrieveWS<const MatrixWorkspace>(wsname.toStdString());
+    auto ws = Mantid::API::AnalysisDataService::Instance().retrieveWS<const MatrixWorkspace>(wsName.toStdString());
     int maxSpecIndex = static_cast<int>(ws->getNumberHistograms()) - 1;
 
     uiForm().msd_spPlotSpectrum->setMaximum(maxSpecIndex);
@@ -186,6 +190,30 @@ namespace IDA
     m_currentWsName = wsname;
   }
 
+  /**
+   * Handles the user entering a new minimum spectrum index.
+   *
+   * Prevents the user entering an overlapping spectra range.
+   *
+   * @param value Minimum spectrum index
+   */
+  void MSDFit::specMinChanged(int value)
+  {
+    uiForm().msd_spSpectraMax->setMinimum(value);
+  }
+
+  /**
+   * Handles the user entering a new maximum spectrum index.
+   *
+   * Prevents the user entering an overlapping spectra range.
+   *
+   * @param value Maximum spectrum index
+   */
+  void MSDFit::specMaxChanged(int value)
+  {
+    uiForm().msd_spSpectraMin->setMaximum(value);
+  }
+
   void MSDFit::minChanged(double val)
   {
     m_dblManager->setValue(m_properties["Start"], val);
-- 
GitLab