Index: src/sas/qtgui/MainWindow/DataExplorer.py
===================================================================
--- src/sas/qtgui/MainWindow/DataExplorer.py	(revision 9463ca22fbd7a5dfabfd6ec8adf7690e1460bef6)
+++ src/sas/qtgui/MainWindow/DataExplorer.py	(revision fd7ef366aae1676b62ef944659ae3d38556a61fb)
@@ -4,5 +4,4 @@
 import time
 import logging
-import re
 
 from PyQt5 import QtCore
@@ -37,12 +36,4 @@
     # The controller which is responsible for managing signal slots connections
     # for the gui and providing an interface to the data model.
-
-    # This matches the ID of a plot created using FittingLogic._create1DPlot, e.g.
-    # "5 [P(Q)] modelname"
-    # or
-    # "4 modelname".
-    # Useful for determining whether the plot in question is for an intermediate result, such as P(Q) or S(Q) in the
-    # case of a product model; the identifier for this is held in square brackets, as in the example above.
-    theory_plot_ID_pattern = re.compile(r"^([0-9]+)\s+(\[(.*)\]\s+)?(.*)$")
 
     def __init__(self, parent=None, guimanager=None, manager=None):
@@ -394,4 +385,47 @@
         # Notify the GuiManager about the send request
         self._perspective().setData(data_item=selected_items, is_batch=self.chkBatch.isChecked())
+
+    def freezeCheckedData(self):
+        """
+        Convert checked results (fitted model, residuals) into separate dataset.
+        """
+        outer_index = -1
+        theories_copied = 0
+        orig_model_size = self.model.rowCount()
+        while outer_index < orig_model_size:
+            outer_index += 1
+            outer_item = self.model.item(outer_index)
+            if not outer_item:
+                continue
+            if not outer_item.isCheckable():
+                continue
+            # Look for checked inner items
+            inner_index = -1
+            while inner_index < outer_item.rowCount():
+               inner_item = outer_item.child(inner_index)
+               inner_index += 1
+               if not inner_item:
+                   continue
+               if not inner_item.isCheckable():
+                   continue
+               if inner_item.checkState() != QtCore.Qt.Checked:
+                   continue
+               self.model.beginResetModel()
+               theories_copied += 1
+               new_item = self.cloneTheory(inner_item)
+               self.model.appendRow(new_item)
+               self.model.endResetModel()
+
+        freeze_msg = ""
+        if theories_copied == 0:
+            return
+        elif theories_copied == 1:
+            freeze_msg = "1 theory copied to a separate data set"
+        elif theories_copied > 1:
+            freeze_msg = "%i theories copied to separate data sets" % theories_copied
+        else:
+            freeze_msg = "Unexpected number of theories copied: %i" % theories_copied
+            raise AttributeError(freeze_msg)
+        self.communicator.statusBarUpdateSignal.emit(freeze_msg)
 
     def freezeTheory(self, event):
@@ -538,5 +572,5 @@
             else:
                 # Don't plot intermediate results, e.g. P(Q), S(Q)
-                match = self.theory_plot_ID_pattern.match(plot_id)
+                match = GuiUtils.theory_plot_ID_pattern.match(plot_id)
                 # 2nd match group contains the identifier for the intermediate result, if present (e.g. "[P(Q)]")
                 if match and match.groups()[1] != None:
@@ -544,5 +578,6 @@
                 # 'sophisticated' test to generate standalone plot for residuals
                 if 'esiduals' in plot.title:
-                    self.plotData([(item, plot)], transform=False)
+                    plot.yscale='linear'
+                    self.plotData([(item, plot)])
                 else:
                     new_plots.append((item, plot))
@@ -825,4 +860,27 @@
         return wlist
 
+    def setItemsCheckability(self, model, dimension=None, checked=False):
+        """
+        For a given model, check or uncheck all items of given dimension
+        """
+        mode = QtCore.Qt.Checked if checked else QtCore.Qt.Unchecked
+
+        assert isinstance(checked, bool)
+
+        types = (None, Data1D, Data2D)
+        assert dimension in types
+
+        for index in range(model.rowCount()):
+            item = model.item(index)
+            if dimension is not None and not isinstance(GuiUtils.dataFromItem(item), dimension):
+                continue
+            if item.isCheckable() and item.checkState() != mode:
+                item.setCheckState(mode)
+            # look for all children
+            for inner_index in range(item.rowCount()):
+                child = item.child(inner_index)
+                if child.isCheckable() and child.checkState() != mode:
+                    child.setCheckState(mode)
+
     def selectData(self, index):
         """
@@ -835,72 +893,25 @@
         # Respond appropriately
         if index == 0:
-            # Select All
-            for index in range(self.model.rowCount()):
-                item = self.model.item(index)
-                if item.isCheckable() and item.checkState() == QtCore.Qt.Unchecked:
-                    item.setCheckState(QtCore.Qt.Checked)
+            self.setItemsCheckability(self.model, checked=True)
+
         elif index == 1:
             # De-select All
-            for index in range(self.model.rowCount()):
-                item = self.model.item(index)
-                if item.isCheckable() and item.checkState() == QtCore.Qt.Checked:
-                    item.setCheckState(QtCore.Qt.Unchecked)
+            self.setItemsCheckability(self.model, checked=False)
 
         elif index == 2:
             # Select All 1-D
-            for index in range(self.model.rowCount()):
-                item = self.model.item(index)
-                item.setCheckState(QtCore.Qt.Unchecked)
-
-                try:
-                    is1D = isinstance(GuiUtils.dataFromItem(item), Data1D)
-                except AttributeError:
-                    msg = "Bad structure of the data model."
-                    raise RuntimeError(msg)
-
-                if is1D:
-                    item.setCheckState(QtCore.Qt.Checked)
+            self.setItemsCheckability(self.model, dimension=Data1D, checked=True)
 
         elif index == 3:
             # Unselect All 1-D
-            for index in range(self.model.rowCount()):
-                item = self.model.item(index)
-
-                try:
-                    is1D = isinstance(GuiUtils.dataFromItem(item), Data1D)
-                except AttributeError:
-                    msg = "Bad structure of the data model."
-                    raise RuntimeError(msg)
-
-                if item.isCheckable() and item.checkState() == QtCore.Qt.Checked and is1D:
-                    item.setCheckState(QtCore.Qt.Unchecked)
+            self.setItemsCheckability(self.model, dimension=Data1D, checked=False)
 
         elif index == 4:
             # Select All 2-D
-            for index in range(self.model.rowCount()):
-                item = self.model.item(index)
-                item.setCheckState(QtCore.Qt.Unchecked)
-                try:
-                    is2D = isinstance(GuiUtils.dataFromItem(item), Data2D)
-                except AttributeError:
-                    msg = "Bad structure of the data model."
-                    raise RuntimeError(msg)
-
-                if is2D:
-                    item.setCheckState(QtCore.Qt.Checked)
+            self.setItemsCheckability(self.model, dimension=Data2D, checked=True)
 
         elif index == 5:
             # Unselect All 2-D
-            for index in range(self.model.rowCount()):
-                item = self.model.item(index)
-
-                try:
-                    is2D = isinstance(GuiUtils.dataFromItem(item), Data2D)
-                except AttributeError:
-                    msg = "Bad structure of the data model."
-                    raise RuntimeError(msg)
-
-                if item.isCheckable() and item.checkState() == QtCore.Qt.Checked and is2D:
-                    item.setCheckState(QtCore.Qt.Unchecked)
+            self.setItemsCheckability(self.model, dimension=Data2D, checked=False)
 
         else:
@@ -1270,2 +1281,22 @@
         self.theory_model.appendRow(model_item)
 
+    def deleteIntermediateTheoryPlotsByModelID(self, model_id):
+        """Given a model's ID, deletes all items in the theory item model which reference the same ID. Useful in the
+        case of intermediate results disappearing when changing calculations (in which case you don't want them to be
+        retained in the list)."""
+        items_to_delete = []
+        for r in range(self.theory_model.rowCount()):
+            item = self.theory_model.item(r, 0)
+            data = item.child(0).data()
+            if not hasattr(data, "id"):
+                return
+            match = GuiUtils.theory_plot_ID_pattern.match(data.id)
+            if match:
+                item_model_id = match.groups()[-1]
+                if item_model_id == model_id:
+                    # Only delete those identified as an intermediate plot
+                    if match.groups()[2] not in (None, ""):
+                        items_to_delete.append(item)
+
+        for item in items_to_delete:
+            self.theory_model.removeRow(item.row())
Index: src/sas/qtgui/MainWindow/GuiManager.py
===================================================================
--- src/sas/qtgui/MainWindow/GuiManager.py	(revision 0eff6153f4208fa47673e1006f3be34f6a55724a)
+++ src/sas/qtgui/MainWindow/GuiManager.py	(revision 0eff6153f4208fa47673e1006f3be34f6a55724a)
@@ -395,4 +395,5 @@
         self.communicate.perspectiveChangedSignal.connect(self.perspectiveChanged)
         self.communicate.updateTheoryFromPerspectiveSignal.connect(self.updateTheoryFromPerspective)
+        self.communicate.deleteIntermediateTheoryPlotsSignal.connect(self.deleteIntermediateTheoryPlotsByModelID)
         self.communicate.plotRequestedSignal.connect(self.showPlot)
         self.communicate.plotFromFilenameSignal.connect(self.showPlotFromFilename)
@@ -438,4 +439,5 @@
         self._workspace.actionImage_Viewer.triggered.connect(self.actionImage_Viewer)
         self._workspace.actionOrientation_Viewer.triggered.connect(self.actionOrientation_Viewer)
+        self._workspace.actionFreeze_Theory.triggered.connect(self.actionFreeze_Theory)
         # Fitting
         self._workspace.actionNew_Fit_Page.triggered.connect(self.actionNew_Fit_Page)
@@ -684,4 +686,10 @@
         self._workspace.addDockWidget(Qt.RightDockWidgetArea, self.ipDockWidget)
 
+    def actionFreeze_Theory(self):
+        """
+        Convert a child index with data into a separate top level dataset
+        """
+        self.filesWidget.freezeCheckedData()
+
     def actionOrientation_Viewer(self):
         """
@@ -879,4 +887,11 @@
         """
         self.filesWidget.updateTheoryFromPerspective(index)
+
+    def deleteIntermediateTheoryPlotsByModelID(self, model_id):
+        """
+        Catch the signal to delete items in the Theory item model which correspond to a model ID.
+        Send the request to the DataExplorer for updating the theory model.
+        """
+        self.filesWidget.deleteIntermediateTheoryPlotsByModelID(model_id)
 
     def updateModelFromDataOperationPanel(self, new_item, new_datalist_item):
Index: src/sas/qtgui/MainWindow/UI/DataExplorerUI.ui
===================================================================
--- src/sas/qtgui/MainWindow/UI/DataExplorerUI.ui	(revision d1fa2b8c9923877104df9e2260cf10b981a461d4)
+++ src/sas/qtgui/MainWindow/UI/DataExplorerUI.ui	(revision f4a6f2c6bed139ce9fb4392087c90deeb747659c)
@@ -44,5 +44,5 @@
            <property name="sizePolicy">
             <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-             <horstretch>5</horstretch>
+             <horstretch>0</horstretch>
              <verstretch>5</verstretch>
             </sizepolicy>
@@ -50,6 +50,6 @@
            <property name="minimumSize">
             <size>
-             <width>154</width>
-             <height>50</height>
+             <width>120</width>
+             <height>40</height>
             </size>
            </property>
@@ -64,5 +64,5 @@
            </property>
            <property name="styleSheet">
-            <string notr="true">font: 13pt &quot;MS Shell Dlg 2&quot;;</string>
+            <string notr="true">font: 11pt &quot;MS Shell Dlg 2&quot;;</string>
            </property>
            <property name="text">
@@ -75,6 +75,6 @@
            <property name="iconSize">
             <size>
-             <width>48</width>
-             <height>48</height>
+             <width>32</width>
+             <height>32</height>
             </size>
            </property>
@@ -183,5 +183,5 @@
            <property name="sizePolicy">
             <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-             <horstretch>5</horstretch>
+             <horstretch>0</horstretch>
              <verstretch>5</verstretch>
             </sizepolicy>
@@ -189,6 +189,6 @@
            <property name="minimumSize">
             <size>
-             <width>170</width>
-             <height>50</height>
+             <width>145</width>
+             <height>40</height>
             </size>
            </property>
@@ -201,5 +201,9 @@
            <property name="font">
             <font>
-             <pointsize>13</pointsize>
+             <family>MS Shell Dlg 2</family>
+             <pointsize>11</pointsize>
+             <weight>50</weight>
+             <italic>false</italic>
+             <bold>false</bold>
             </font>
            </property>
@@ -208,5 +212,5 @@
            </property>
            <property name="styleSheet">
-            <string notr="true">font: 13pt &quot;MS Shell Dlg 2&quot;;</string>
+            <string notr="true">font: 11pt &quot;MS Shell Dlg 2&quot;;</string>
            </property>
            <property name="text">
@@ -219,6 +223,6 @@
            <property name="iconSize">
             <size>
-             <width>48</width>
-             <height>48</height>
+             <width>32</width>
+             <height>32</height>
             </size>
            </property>
@@ -235,5 +239,5 @@
            <property name="font">
             <font>
-             <pointsize>12</pointsize>
+             <pointsize>11</pointsize>
             </font>
            </property>
Index: src/sas/qtgui/MainWindow/UI/MainWindowUI.ui
===================================================================
--- src/sas/qtgui/MainWindow/UI/MainWindowUI.ui	(revision aa1db44bef6b137ed4ef0e1b1e13a6c94ba6a928)
+++ src/sas/qtgui/MainWindow/UI/MainWindowUI.ui	(revision 6b5029659d0f8848859513403a8ef38c0481f7db)
@@ -64,4 +64,6 @@
     <addaction name="actionReport"/>
     <addaction name="actionReset"/>
+    <addaction name="separator"/>
+    <addaction name="actionFreeze_Theory"/>
    </widget>
    <widget class="QMenu" name="menuView">
@@ -535,4 +537,9 @@
    </property>
   </action>
+  <action name="actionFreeze_Theory">
+   <property name="text">
+    <string>Freeze Theory</string>
+   </property>
+  </action>
  </widget>
  <resources/>
Index: src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py
===================================================================
--- src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py	(revision 573c38349522bd3c640c76f26fd0bbed6d9c9139)
+++ src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py	(revision a24eacf3b3a9ca51fe5e34059e28454573779b5f)
@@ -71,5 +71,5 @@
         self.assertEqual(self.form.cmdFreeze.text(), "Freeze Theory")
         self.assertEqual(self.form.cmdSendTo.text(), "Send data to")
-        self.assertEqual(self.form.cmdSendTo.iconSize(), QSize(48, 48))
+        self.assertEqual(self.form.cmdSendTo.iconSize(), QSize(32, 32))
         self.assertIsInstance(self.form.cmdSendTo.icon(), QIcon)
         self.assertEqual(self.form.chkBatch.text(), "Batch mode")
@@ -352,5 +352,5 @@
         # Test the current selection
         self.assertTrue(item1D.checkState() == Qt.Checked)
-        self.assertTrue(item2D.checkState() == Qt.Unchecked)        
+        self.assertTrue(item2D.checkState() == Qt.Checked)
 
         # unselect 1d data
@@ -359,5 +359,5 @@
         # Test the current selection
         self.assertTrue(item1D.checkState() == Qt.Unchecked)
-        self.assertTrue(item2D.checkState() == Qt.Unchecked)        
+        self.assertTrue(item2D.checkState() == Qt.Checked)
 
         # select 2d data
