Index: src/sas/qtgui/Perspectives/Fitting/FittingOptions.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingOptions.py	(revision ff3b293197970c44a7188c9d3c2fd7fa7a83536e)
+++ src/sas/qtgui/Perspectives/Fitting/FittingOptions.py	(revision 8873ab7132159e0dd7fa868c07e4eee16ed4d9ff)
@@ -64,4 +64,6 @@
         default_index = self.cbAlgorithm.findText(default_name)
         self.cbAlgorithm.setCurrentIndex(default_index)
+        # previous algorithm choice
+        self.previous_index = default_index
 
         # Assign appropriate validators
@@ -121,5 +123,19 @@
 
         # Convert the name into widget instance
-        widget_to_activate = eval(widget_name)
+        try:
+            widget_to_activate = eval(widget_name)
+        except AttributeError:
+            # We don't yet have this optimizer.
+            # Show message
+            msg = "This algorithm has not yet been implemented in SasView.\n"
+            msg += "Please choose a different algorithm"
+            QtWidgets.QMessageBox.warning(self,
+                                        'Warning',
+                                        msg,
+                                        QtWidgets.QMessageBox.Ok)
+            # Move the index to previous position
+            self.cbAlgorithm.setCurrentIndex(self.previous_index)
+            return
+
         index_for_this_id = self.stackedWidget.indexOf(widget_to_activate)
 
@@ -133,4 +149,7 @@
         # OK has to be reinitialized to True
         self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(True)
+
+        # keep reference
+        self.previous_index = index
 
     def onApply(self):
@@ -143,5 +162,9 @@
             # e.g. 'samples' for 'dream' is 'self.samples_dream'
             widget_name = 'self.'+option+'_'+self.current_fitter_id
-            line_edit = eval(widget_name)
+            try:
+                line_edit = eval(widget_name)
+            except AttributeError:
+                # Skip bumps monitors
+                continue
             if line_edit is None or not isinstance(line_edit, QtWidgets.QLineEdit):
                 continue
@@ -165,6 +188,13 @@
                 return
             try:
-                new_value = widget.currentText() if isinstance(widget, QtWidgets.QComboBox) \
-                    else float(widget.text())
+                if isinstance(widget, QtWidgets.QComboBox):
+                    new_value = widget.currentText()
+                else:
+                    try:
+                        new_value = int(widget.text())
+                    except ValueError:
+                        new_value = float(widget.text())
+                #new_value = widget.currentText() if isinstance(widget, QtWidgets.QComboBox) \
+                #    else float(widget.text())
                 self.config.values[self.current_fitter_id][option] = new_value
             except ValueError:
Index: src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py	(revision 44decedba675106f665c7d21f373030dd758fce3)
+++ src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py	(revision 44decedba675106f665c7d21f373030dd758fce3)
@@ -24,6 +24,5 @@
 poly_header_tooltips = ['Select parameter for fitting',
                         'Enter polydispersity ratio (Std deviation/mean).\n'+
-                        'For angles this can be either std deviation or full width (for uniform distributions) in degrees',
-                        'STD: standard deviation from the mean value',
+                        'For angles this can be either std deviation or half width (for uniform distributions) in degrees',
                         'Enter minimum value for parameter',
                         'Enter maximum value for parameter',
Index: src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision d8d81eac092827346a21664178ff98dc3773a632)
+++ src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision d8d81eac092827346a21664178ff98dc3773a632)
@@ -1085,7 +1085,16 @@
             if not self.rowHasConstraint(row):
                 return
+            constr = self.getConstraintForRow(row)
             func = self.getConstraintForRow(row).func
-            if func is not None:
-                self.communicate.statusBarUpdateSignal.emit("Active constrain: "+func)
+            if constr.func is not None:
+                # inter-parameter constraint
+                update_text = "Active constraint: "+func
+            elif constr.param == rows[0].data():
+                # current value constraint
+                update_text = "Value constrained to: " + str(constr.value)
+            else:
+                # ill defined constraint
+                return
+            self.communicate.statusBarUpdateSignal.emit(update_text)
 
     def replaceConstraintName(self, old_name, new_name=""):
@@ -1124,4 +1133,5 @@
             # Create default datasets if no data passed
             self.createDefaultDataset()
+            self.theory_item = None # ensure theory is recalc. before plot, see showTheoryPlot()
 
     def respondToModelStructure(self, model=None, structure_factor=None):
@@ -1835,10 +1845,13 @@
         self.cmdPlot.setText("Show Plot")
         # Force data recalculation so existing charts are updated
-        self.showPlot()
+        if not self.data_is_loaded:
+            self.showTheoryPlot()
+        else:
+            self.showPlot()
         # This is an important processEvent.
         # This allows charts to be properly updated in order
         # of plots being applied.
         QtWidgets.QApplication.processEvents()
-        self.recalculatePlotData()
+        self.recalculatePlotData() # recalc+plot theory again (2nd)
 
     def onSmearingOptionsUpdate(self):
@@ -1856,4 +1869,14 @@
         self.calculateQGridForModel()
 
+    def showTheoryPlot(self):
+        """
+        Show the current theory plot in MPL
+        """
+        # Show the chart if ready
+        if self.theory_item is None:
+            self.recalculatePlotData()
+        elif self.model_data:
+            self._requestPlots(self.model_data.filename, self.theory_item.model())
+
     def showPlot(self):
         """
@@ -1861,7 +1884,27 @@
         """
         # Show the chart if ready
-        data_to_show = self.data if self.data_is_loaded else self.model_data
-        if data_to_show is not None:
-            self.communicate.plotRequestedSignal.emit([data_to_show], self.tab_id)
+        data_to_show = self.data
+        # Any models for this page
+        current_index = self.all_data[self.data_index]
+        item = self._requestPlots(self.data.filename, current_index.model())
+        if item:
+            # fit+data has not been shown - show just data
+            self.communicate.plotRequestedSignal.emit([item, data_to_show], self.tab_id)
+
+    def _requestPlots(self, item_name, item_model):
+        """
+        Emits plotRequestedSignal for all plots found in the given model under the provided item name.
+        """
+        fitpage_name = "" if self.tab_id is None else "M"+str(self.tab_id)
+        plots = GuiUtils.plotsFromFilename(item_name, item_model)
+        # Has the fitted data been shown?
+        data_shown = False
+        item = None
+        for item, plot in plots.items():
+            if fitpage_name in plot.name:
+                data_shown = True
+                self.communicate.plotRequestedSignal.emit([item, plot], self.tab_id)
+        # return the last data item seen, if nothing was plotted; supposed to be just data)
+        return None if data_shown else item
 
     def onOptionsUpdate(self):
@@ -2093,4 +2136,7 @@
         self.kernel_module = self.models[model_name]()
 
+        # Change the model name to a monicker
+        self.kernel_module.name = self.modelName()
+
         # Explicitly add scale and background with default values
         temp_undo_state = self.undo_supported
@@ -2125,4 +2171,5 @@
             # Structure factor is the only selected model; build it and show all its params
             self.kernel_module = self.models[structure_factor]()
+            self.kernel_module.name = self.modelName()
             s_params = self.kernel_module._model_info.parameters
             s_params_orig = s_params
@@ -2135,4 +2182,6 @@
 
             self.kernel_module = MultiplicationModel(p_kernel, s_kernel)
+            # Modify the name to correspond to shown items
+            self.kernel_module.name = self.modelName()
             all_params = self.kernel_module._model_info.parameters.kernel_parameters
             all_param_names = [param.name for param in all_params]
@@ -2440,6 +2489,9 @@
         # Bring the GUI to normal state
         self.enableInteractiveElements()
-
+        if return_data is None:
+            self.calculateDataFailed("Results not available.")
+            return
         fitted_data = self.logic.new1DPlot(return_data, self.tab_id)
+
         residuals = self.calculateResiduals(fitted_data)
         self.model_data = fitted_data
Index: src/sas/qtgui/Perspectives/Fitting/UI/ComplexConstraintUI.ui
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/UI/ComplexConstraintUI.ui	(revision 305114c33963ce5b43f94d3b16fc71e316f72e3a)
+++ src/sas/qtgui/Perspectives/Fitting/UI/ComplexConstraintUI.ui	(revision 17381739dbc25805ef89bbec1e92e0915e6429a5)
@@ -7,6 +7,6 @@
     <x>0</x>
     <y>0</y>
-    <width>463</width>
-    <height>234</height>
+    <width>367</width>
+    <height>199</height>
    </rect>
   </property>
@@ -135,5 +135,5 @@
     <widget class="QLabel" name="lblWarning">
      <property name="text">
-      <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#ff0000;&quot;&gt;Warning! Polydisperse parameter selected.&lt;br/&gt;&lt;/span&gt;Constraints involving polydisperse parameters only apply to&lt;br/&gt;starting values and are nor re-applied during size or angle polydispersity&lt;br/&gt;integrations. To do which requires creating a custom model.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+      <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#ff0000;&quot;&gt;Warning! Polydisperse parameter selected.&lt;br/&gt;&lt;/span&gt;Constraints involving polydisperse parameters only apply to&lt;br/&gt;starting values and are not re-applied during size or angle polydispersity&lt;br/&gt;integrations. To do so requires creating a custom model.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
      </property>
     </widget>
Index: src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui	(revision a2e8ea5835531d69e27d5e97068263c4672284f9)
+++ src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui	(revision fc5d2d7fa9cd52ca6b9a8d7082da6eddf35b1d34)
@@ -7,5 +7,5 @@
     <x>0</x>
     <y>0</y>
-    <width>566</width>
+    <width>651</width>
     <height>646</height>
    </rect>
Index: src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui	(revision aa88b7608334fcb6430789a4ab5dddee40fb538a)
+++ src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui	(revision 17381739dbc25805ef89bbec1e92e0915e6429a5)
@@ -10,6 +10,6 @@
     <x>0</x>
     <y>0</y>
-    <width>436</width>
-    <height>217</height>
+    <width>369</width>
+    <height>201</height>
    </rect>
   </property>
@@ -121,5 +121,5 @@
     <widget class="QLabel" name="lblWarning">
      <property name="text">
-      <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#ff0000;&quot;&gt;Warning! Polydisperse parameter selected.&lt;br/&gt;&lt;/span&gt;Constraints involving polydisperse parameters only apply to&lt;br/&gt;starting values and are nor re-applied during size or angle polydispersity&lt;br/&gt;integrations. To do which requires creating a custom model.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+      <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#ff0000;&quot;&gt;Warning! Polydisperse parameter selected.&lt;br/&gt;&lt;/span&gt;Constraints involving polydisperse parameters only apply to&lt;br/&gt;starting values and are not re-applied during size or angle polydispersity&lt;br/&gt;integrations. To do so requires creating a custom model.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
      </property>
     </widget>
Index: src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py	(revision 1a15adaa1bbde7cbb9a5f5ff55d61f53d3b88ca7)
+++ src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py	(revision 8faac15efe65037d4192289834f31929c1c24d83)
@@ -397,6 +397,5 @@
         header_tooltips = ['Select parameter for fitting',
                             'Enter polydispersity ratio (Std deviation/mean).\n'+
-                            'For angles this can be either std deviation or full width (for uniform distributions) in degrees',
-                            'STD: standard deviation from the mean value',
+                            'For angles this can be either std deviation or half width (for uniform distributions) in degrees',
                             'Enter minimum value for parameter',
                             'Enter maximum value for parameter',
@@ -620,5 +619,5 @@
         # Set to 0
         self.widget.lstParams.indexWidget(func_index).setCurrentIndex(0)
-        self.assertEqual(self.widget._model_model.rowCount(), last_row - 2) # 2 fewer rows than default
+        self.assertEqual(self.widget._model_model.rowCount(), last_row - 2)
 
     def testPlotTheory(self):
@@ -658,5 +657,5 @@
         self.assertEqual(spy.count(), 0)
 
-    def testPlotData(self):
+    def notestPlotData(self):
         """
         See that data item can produce a chart
Index: src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py
===================================================================
--- src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py	(revision aed053275d5f293f1f6495be4c78e4b18fc52b41)
+++ src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py	(revision dee9e5f369951654b0c4ceb6506475a3cd8ed1f9)
@@ -233,4 +233,5 @@
 
         plot_data = GuiUtils.plotsFromCheckedItems(self._manager.filesWidget.model)
+        #self.communicate.plotRequestedSignal.emit([item, plot], self.tab_id)
 
         self._manager.filesWidget.plotData(plot_data)
@@ -347,4 +348,7 @@
                 extrapolated_data.name = title
                 extrapolated_data.title = title
+                extrapolated_data.style = "Line"
+                extrapolated_data.has_errors = False
+                extrapolated_data.plot_role = Data1D.ROLE_DEFAULT
 
                 # copy labels and units of axes for plotting
@@ -378,4 +382,7 @@
                 high_out_data.name = title
                 high_out_data.title = title
+                high_out_data.style = "Line"
+                high_out_data.has_errors = False
+                high_out_data.plot_role = Data1D.ROLE_DEFAULT
 
                 # copy labels and units of axes for plotting
Index: src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py	(revision b0ba43ee4b198d4f5a834c93888985b18c20c071)
+++ src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py	(revision 9f2f713821e7ee39c15ba219bdc789d46dd08254)
@@ -42,5 +42,5 @@
         self.parent = parent
 
-        self.setWindowTitle("Dââ Explorer")
+        self.setWindowTitle("Dmax Explorer")
 
         self.pr_state = pr_state
@@ -116,5 +116,5 @@
         bck = []
         chi2 = []
-
+        plotable_xs = [] #Introducing this to make sure size of x and y for plotting is the same.8
         try:
             dmin = float(self.model.item(W.DMIN).text())
@@ -128,4 +128,5 @@
 
         original = self.pr_state.d_max
+
         for x in xs:
             self.pr_state.d_max = x
@@ -140,4 +141,5 @@
                 bck.append(self.pr_state.background)
                 chi2.append(self.pr_state.chi2)
+                plotable_xs.append(x)
             except Exception as ex:
                 # This inversion failed, skip this D_max value
@@ -155,6 +157,5 @@
             logger.error(msg)
 
-        plotter = self.model.item(W.VARIABLE).text()
-        y_label = y_unit = ""
+        plotter = self.dependentVariable.currentText()
         x_label = "D_{max}"
         x_unit = "A"
@@ -188,7 +189,7 @@
             y_unit = "a.u."
 
-        data = Data1D(xs, ys)
+        data = Data1D(plotable_xs, ys)
         if self.hasPlot:
-            self.plot.removePlot(None)
+            self.plot.removePlot(data.name)
         self.hasPlot = True
         data.title = plotter
Index: src/sas/qtgui/Perspectives/Inversion/InversionLogic.py
===================================================================
--- src/sas/qtgui/Perspectives/Inversion/InversionLogic.py	(revision 6da860acc5670055935e7bdc8678d3827d1a057f)
+++ src/sas/qtgui/Perspectives/Inversion/InversionLogic.py	(revision 3c4f02ecca04eb32797cdd49ced17d153b1d653f)
@@ -111,4 +111,7 @@
             new_plot.title = title
 
+        new_plot.symbol = 'Line'
+        new_plot.hide_error = True
+
         return new_plot
 
Index: src/sas/qtgui/Perspectives/Inversion/InversionPerspective.py
===================================================================
--- src/sas/qtgui/Perspectives/Inversion/InversionPerspective.py	(revision 855e7ad5de338b4dcd85cdca7ed61d089b9c320d)
+++ src/sas/qtgui/Perspectives/Inversion/InversionPerspective.py	(revision dee9e5f369951654b0c4ceb6506475a3cd8ed1f9)
@@ -44,4 +44,6 @@
     estimateSignal = QtCore.pyqtSignal(tuple)
     estimateNTSignal = QtCore.pyqtSignal(tuple)
+    estimateDynamicNTSignal = QtCore.pyqtSignal(tuple)
+    estimateDynamicSignal = QtCore.pyqtSignal(tuple)
     calculateSignal = QtCore.pyqtSignal(tuple)
 
@@ -53,4 +55,6 @@
 
         self._manager = parent
+        #Needed for Batch fitting
+        self._parent = parent
         self.communicate = parent.communicator()
         self.communicate.dataDeletedSignal.connect(self.removeData)
@@ -110,4 +114,7 @@
         # Set up the Widget Map
         self.setupMapper()
+
+        #Hidding calculate all buton
+        self.calculateAllButton.setVisible(False)
         # Set base window state
         self.setupWindow()
@@ -120,5 +127,5 @@
 
     def allowBatch(self):
-        return True
+        return False
 
     def setClosable(self, value=True):
@@ -195,6 +202,10 @@
         self.model.itemChanged.connect(self.model_changed)
         self.estimateNTSignal.connect(self._estimateNTUpdate)
+        self.estimateDynamicNTSignal.connect(self._estimateDynamicNTUpdate)
+        self.estimateDynamicSignal.connect(self._estimateDynamicUpdate)
         self.estimateSignal.connect(self._estimateUpdate)
         self.calculateSignal.connect(self._calculateUpdate)
+
+        self.maxDistanceInput.textEdited.connect(self.performEstimateDynamic)
 
     def setupMapper(self):
@@ -310,6 +321,5 @@
                                             and not self.isCalculating)
         self.removeButton.setEnabled(self.logic.data_is_loaded)
-        self.explorerButton.setEnabled(self.logic.data_is_loaded
-                                       and np.all(self.logic.data.dy != 0))
+        self.explorerButton.setEnabled(self.logic.data_is_loaded)
         self.stopButton.setVisible(self.isCalculating)
         self.regConstantSuggestionButton.setEnabled(
@@ -454,12 +464,20 @@
             # Create initial internal mappings
             self.logic.data = GuiUtils.dataFromItem(data)
+            if not isinstance(self.logic.data, Data1D):
+                msg = "P(r) perspective works for 1D data only"
+                logger.warning(msg)
+                continue
             # Estimate q range
             qmin, qmax = self.logic.computeDataRange()
             self._calculator.set_qmin(qmin)
             self._calculator.set_qmax(qmax)
+            if np.size(self.logic.data.dy) == 0 or np.all(self.logic.data.dy) == 0:
+                self.logic.data.dy = self._calculator.add_errors(self.logic.data.y)
             self.updateDataList(data)
             self.populateDataComboBox(self.logic.data.filename, data)
         self.dataList.setCurrentIndex(len(self.dataList) - 1)
-        self.setCurrentData(data)
+        #Checking for 1D again to mitigate the case when 2D data is last on the data list
+        if isinstance(self.logic.data, Data1D):
+            self.setCurrentData(data)
 
     def updateDataList(self, dataRef):
@@ -502,4 +520,15 @@
         self.dataPlot = self._dataList[data_ref].get(DICT_KEYS[2])
         self.performEstimate()
+
+    def updateDynamicGuiValues(self):
+        pr = self._calculator
+        alpha = self._calculator.suggested_alpha
+        self.model.setItem(WIDGETS.W_MAX_DIST,
+                            QtGui.QStandardItem("{:.4g}".format(pr.get_dmax())))
+        self.regConstantSuggestionButton.setText("{:-3.2g}".format(alpha))
+        self.noOfTermsSuggestionButton.setText(
+             "{:n}".format(self.nTermsSuggested))
+
+        self.enableButtons()
 
     def updateGuiValues(self):
@@ -521,7 +550,4 @@
         self.model.setItem(WIDGETS.W_MAX_DIST,
                            QtGui.QStandardItem("{:.4g}".format(pr.get_dmax())))
-        self.regConstantSuggestionButton.setText("{:-3.2g}".format(alpha))
-        self.noOfTermsSuggestionButton.setText(
-            "{:n}".format(self.nTermsSuggested))
 
         if isinstance(pr.chi2, np.ndarray):
@@ -547,10 +573,12 @@
             self.prPlot.plot_role = Data1D.ROLE_RESIDUAL
             GuiUtils.updateModelItemWithPlot(self._data, self.prPlot, title)
+            self.communicate.plotRequestedSignal.emit([self._data,self.prPlot], None)
         if self.dataPlot is not None:
             title = self.dataPlot.name
             self.dataPlot.plot_role = Data1D.ROLE_DEFAULT
+            self.dataPlot.symbol = "Line"
+            self.dataPlot.show_errors = False
             GuiUtils.updateModelItemWithPlot(self._data, self.dataPlot, title)
-        if self.dataPlot is not None or self.prPlot is not None:
-            self.communicate.plotRequestedSignal.emit([self.logic.data], None)
+            self.communicate.plotRequestedSignal.emit([self._data,self.dataPlot], None)
         self.enableButtons()
 
@@ -636,6 +664,7 @@
 
         pr = self._calculator.clone()
-        nfunc = self.getNFunc()
-        self.calcThread = CalcPr(pr, nfunc,
+        #Making sure that nfunc and alpha parameters are correctly initialized
+        pr.suggested_alpha = self._calculator.alpha
+        self.calcThread = CalcPr(pr, self.nTermsSuggested,
                                  error_func=self._threadError,
                                  completefn=self._calculateCompleted,
@@ -670,4 +699,29 @@
                                              error_func=self._threadError,
                                              completefn=self._estimateNTCompleted,
+                                             updatefn=None)
+        self.estimationThreadNT.queue()
+        self.estimationThreadNT.ready(2.5)
+
+    def performEstimateDynamicNT(self):
+        """
+        Perform parameter estimation
+        """
+        from .Thread import EstimateNT
+
+        self.updateCalculator()
+
+        # If a thread is already started, stop it
+        self.stopEstimateNTThread()
+
+        pr = self._calculator.clone()
+        # Skip the slit settings for the estimation
+        # It slows down the application and it doesn't change the estimates
+        pr.slit_height = 0.0
+        pr.slit_width = 0.0
+        nfunc = self.getNFunc()
+
+        self.estimationThreadNT = EstimateNT(pr, nfunc,
+                                             error_func=self._threadError,
+                                             completefn=self._estimateDynamicNTCompleted,
                                              updatefn=None)
         self.estimationThreadNT.queue()
@@ -696,4 +750,21 @@
         self.estimationThread.ready(2.5)
 
+    def performEstimateDynamic(self):
+        """
+            Perform parameter estimation
+        """
+        from .Thread import EstimatePr
+
+        # If a thread is already started, stop it
+        self.stopEstimationThread()
+
+        self.estimationThread = EstimatePr(self._calculator.clone(),
+                                           self.getNFunc(),
+                                           error_func=self._threadError,
+                                           completefn=self._estimateDynamicCompleted,
+                                           updatefn=None)
+        self.estimationThread.queue()
+        self.estimationThread.ready(2.5)
+
     def stopEstimationThread(self):
         """ Stop the estimation thread if it exists and is running """
@@ -708,4 +779,8 @@
         ''' Send a signal to the main thread for model update'''
         self.estimateSignal.emit((alpha, message, elapsed))
+
+    def _estimateDynamicCompleted(self, alpha, message, elapsed):
+        ''' Send a signal to the main thread for model update'''
+        self.estimateDynamicSignal.emit((alpha, message, elapsed))
 
     def _estimateUpdate(self, output_tuple):
@@ -723,8 +798,28 @@
             logger.info(message)
         self.performEstimateNT()
+        self.performEstimateDynamicNT()
+
+    def _estimateDynamicUpdate(self, output_tuple):
+        """
+        Parameter estimation completed,
+        display the results to the user
+
+        :param alpha: estimated best alpha
+        :param elapsed: computation time
+        """
+        alpha, message, elapsed = output_tuple
+        self._calculator.alpha = alpha
+        self._calculator.elapsed += self._calculator.elapsed
+        if message:
+            logger.info(message)
+        self.performEstimateDynamicNT()
 
     def _estimateNTCompleted(self, nterms, alpha, message, elapsed):
         ''' Send a signal to the main thread for model update'''
         self.estimateNTSignal.emit((nterms, alpha, message, elapsed))
+
+    def _estimateDynamicNTCompleted(self, nterms, alpha, message, elapsed):
+        ''' Send a signal to the main thread for model update'''
+        self.estimateDynamicNTSignal.emit((nterms, alpha, message, elapsed))
 
     def _estimateNTUpdate(self, output_tuple):
@@ -750,4 +845,26 @@
             self.startThread()
 
+    def _estimateDynamicNTUpdate(self, output_tuple):
+        """
+        Parameter estimation completed,
+        display the results to the user
+
+        :param alpha: estimated best alpha
+        :param nterms: estimated number of terms
+        :param elapsed: computation time
+        """
+        nterms, alpha, message, elapsed = output_tuple
+        self._calculator.elapsed += elapsed
+        self._calculator.suggested_alpha = alpha
+        self.nTermsSuggested = nterms
+        # Save useful info
+        self.updateDynamicGuiValues()
+        if message:
+            logger.info(message)
+        if self.isBatch:
+            self.acceptAlpha()
+            self.acceptNoTerms()
+            self.startThread()
+
     def _calculateCompleted(self, out, cov, pr, elapsed):
         ''' Send a signal to the main thread for model update'''
Index: src/sas/qtgui/Perspectives/Inversion/UI/DMaxExplorer.ui
===================================================================
--- src/sas/qtgui/Perspectives/Inversion/UI/DMaxExplorer.ui	(revision 8f83719fd67e6a72acdcd666e7bf1e2326b52cd0)
+++ src/sas/qtgui/Perspectives/Inversion/UI/DMaxExplorer.ui	(revision cfd61f23d91bd633d84aa6a5cfb03c97e0512189)
@@ -7,6 +7,6 @@
     <x>0</x>
     <y>0</y>
-    <width>394</width>
-    <height>426</height>
+    <width>586</width>
+    <height>538</height>
    </rect>
   </property>
@@ -21,10 +21,4 @@
        <property name="orientation">
         <enum>Qt::Vertical</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>20</width>
-         <height>305</height>
-        </size>
        </property>
       </spacer>
Index: src/sas/qtgui/Perspectives/Inversion/UI/TabbedInversionUI.ui
===================================================================
--- src/sas/qtgui/Perspectives/Inversion/UI/TabbedInversionUI.ui	(revision 72ecbdf22c121ae7a0f43b886ce56a9b503fed04)
+++ src/sas/qtgui/Perspectives/Inversion/UI/TabbedInversionUI.ui	(revision 68dc287336e67e72e8509168de3021b5af3676ab)
@@ -7,6 +7,6 @@
     <x>0</x>
     <y>0</y>
-    <width>390</width>
-    <height>409</height>
+    <width>446</width>
+    <height>480</height>
    </rect>
   </property>
@@ -740,5 +740,5 @@
       <widget class="QPushButton" name="calculateAllButton">
        <property name="enabled">
-        <bool>true</bool>
+        <bool>false</bool>
        </property>
        <property name="sizePolicy">
Index: src/sas/qtgui/Perspectives/Inversion/UnitTesting/InversionPerspectiveTest.py
===================================================================
--- src/sas/qtgui/Perspectives/Inversion/UnitTesting/InversionPerspectiveTest.py	(revision 144fe21c4befe53963fef06a9091c7d69d0b3b41)
+++ src/sas/qtgui/Perspectives/Inversion/UnitTesting/InversionPerspectiveTest.py	(revision ccd2b87ed4046bfd64dc45b580c48032d91271b8)
@@ -99,5 +99,5 @@
     def baseBatchState(self):
         """ Testing the base batch fitting state """
-        self.assertTrue(self.widget.allowBatch())
+        self.assertFalse(self.widget.allowBatch())
         self.assertFalse(self.widget.isBatch)
         self.assertFalse(self.widget.calculateAllButton.isEnabled())
@@ -304,5 +304,5 @@
         self.assertIsNotNone(self.widget.dmaxWindow)
         self.assertTrue(self.widget.dmaxWindow.isVisible())
-        self.assertTrue(self.widget.dmaxWindow.windowTitle() == "Dââ Explorer")
+        self.assertTrue(self.widget.dmaxWindow.windowTitle() == "Dmax Explorer")
 
 
