Index: src/sas/sasgui/guiframe/report_dialog.py
===================================================================
--- src/sas/sasgui/guiframe/report_dialog.py	(revision 91552b528f8c52835ef769f59e30707071f7f9b9)
+++ src/sas/sasgui/guiframe/report_dialog.py	(revision d0ce666faaf0f9284be2e607a0ac846cdd9a682b)
@@ -7,4 +7,5 @@
 import sys
 import wx.html as html
+from sas.sasgui.guiframe.report_image_handler import ReportImageHandler
 
 logger = logging.getLogger(__name__)
@@ -70,4 +71,6 @@
         button_close = wx.Button(self, wx.ID_OK, "Close")
         button_close.SetToolTipString("Close this report window.")
+        button_close.Bind(wx.EVT_BUTTON, self.onClose,
+                          id=button_close.GetId())
         hbox.Add(button_close)
         button_close.SetFocus()
@@ -117,5 +120,5 @@
 
 
-    def OnClose(self, event=None):
+    def onClose(self, event=None):
         """
         Close the Dialog
@@ -123,7 +126,7 @@
         """
         for fig in self.fig_urls:
-            self.imgRAM.RemoveFile(fig)
+            ReportImageHandler.remove_figure(fig)
 
-        self.Close()
+        self.Destroy()
 
     def HTML2PDF(self, data, filename):
Index: src/sas/sasgui/guiframe/report_image_handler.py
===================================================================
--- src/sas/sasgui/guiframe/report_image_handler.py	(revision d0ce666faaf0f9284be2e607a0ac846cdd9a682b)
+++ src/sas/sasgui/guiframe/report_image_handler.py	(revision d0ce666faaf0f9284be2e607a0ac846cdd9a682b)
@@ -0,0 +1,81 @@
+import wx
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+class ReportImageHandler:
+    # Singleton class that manages all report plot images
+    # To call the handler, call the static method set_figs
+
+    class _ReportImageHandler:
+
+        def __init__(self):
+            wx.FileSystem.AddHandler(wx.MemoryFSHandler())
+            self.img_holder = wx.MemoryFSHandler()
+            self.refs = {}
+            self.indices = []
+
+        def set_figs(self, figs, bitmaps, perspective):
+            """
+            Save figures and images to memory and return refernces
+            :param figs: A list of matplotlib Figures
+            :param bitmaps: A list of bitmaps
+            :param perspective: A String with the perspective name
+            :return: A tuple of a list of Figures and a list of memory refs
+            """
+            imgs = []
+            refs = []
+            if figs is None or len(figs) == 0:
+                figs = [None]
+            for fig in figs:
+                if fig is not None:
+                    ind = figs.index(fig)
+                    bitmap = bitmaps[ind]
+
+                # name of the fig
+                name = self.create_unique_name(perspective)
+                # AddFile, image can be retrieved with 'memory:filename'
+                ref = 'memory:' + name
+                self.refs[ref] = fig
+                self.img_holder.AddFile(name, bitmap, wx.BITMAP_TYPE_PNG)
+                refs.append(ref)
+                imgs.append(fig)
+            return imgs, refs
+
+        def create_unique_name(self, perspective, index=None):
+            """
+            Create a unique key for each item in memory
+            :param perspective: The perspective name as a string
+            :param index: The base index used for incrementing the name
+            :return: A unique file name not currently in use
+            """
+            if not index:
+                index = len(self.indices)
+            if index in self.indices:
+                name = self.create_unique_name(index + 1)
+            else:
+                self.indices.append(index)
+                name = 'img_{}_{:03d}.png'.format(str(perspective), index)
+            return name
+
+    instance = None
+
+    @staticmethod
+    def check_for_empty_instance():
+        if ReportImageHandler.instance is None:
+            ReportImageHandler.instance = \
+                ReportImageHandler._ReportImageHandler()
+
+    @staticmethod
+    def set_figs(figs, bitmaps, perspective):
+        ReportImageHandler.check_for_empty_instance()
+        return ReportImageHandler.instance.set_figs(figs, bitmaps, perspective)
+
+    @staticmethod
+    def remove_figure(fig_url):
+        try:
+            ReportImageHandler.check_for_empty_instance()
+            ReportImageHandler.instance.refs.pop(fig_url)
+        except Exception as e:
+            logger.warn(e)
Index: src/sas/sasgui/perspectives/calculator/media/slit_calculator_help.rst
===================================================================
--- src/sas/sasgui/perspectives/calculator/media/slit_calculator_help.rst	(revision 5ed76f8390eac56ff5d3779fd9c454d0c8fe1dc0)
+++ src/sas/sasgui/perspectives/calculator/media/slit_calculator_help.rst	(revision 346745a30813fd45fc6d6f85fe5dd51bb9790081)
@@ -11,9 +11,22 @@
 -----------
 
-This tool enables X-ray users to calculate the slit size (FWHM/2) for smearing
-based on their half beam profile data.
+This tool enables X-ray users to calculate the slit size (FWHM/2) for resolution 
+smearing purposes based on their half beam profile data (as Q vs Intensity; any 
+other data fields are ignored).
 
-*NOTE! Whilst it may have some more generic applicability, the calculator has
-only been tested with beam profile data from Anton-Paar SAXSess:sup:`TM` software.*
+Method
+------
+
+The tool works by sequentially summing 10 or more intensity values until a 
+maximum value is attained. It then locates the Q values for the points just before, 
+and just after, **half** of this maximum value and interpolates between them to get 
+an accurate value for the Q value for the half maximum.
+
+NOTE! Whilst it may have some more generic applicability, the calculator has
+only been tested with beam profile data from Anton-Paar SAXSess\ :sup:`TM`\  software.
+The beam profile file does not carry any information about the units of the 
+Q data. It is probably |nm^-1| but the resolution calculations assume the slit 
+height/width has units of |Ang^-1|. If the beam profile data is not in these 
+units then it, or the result, must be manually converted.
 
 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
@@ -27,14 +40,10 @@
 
    *NOTE! To see an example of the beam profile file format, visit the file
-   beam profile.DAT in your {installation_directory}/SasView/test folder.*
+   beam profile.DAT in your {installation_directory}/SasView/test_1d folder.*
 
 3) Once a data is loaded, the slit size is automatically computed and displayed
    in the tool window.
 
-*NOTE! The beam profile file does not carry any information about the units of
-the Q data. This calculator assumes the data has units of 1/\ |Ang|\ . If the
-data is not in these units it must be manually converted beforehand.*
-
 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
 
-.. note::  This help document was last changed by Steve King, 01May2015
+.. note::  This help document was last changed by Steve King, 09Sep2018
Index: src/sas/sasgui/perspectives/calculator/model_editor.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/model_editor.py	(revision d247504b93443ebd1ae217fdd11261a94c83c5c7)
+++ src/sas/sasgui/perspectives/calculator/model_editor.py	(revision 9bf40e7da42d4112c3098b54d9c3b12081500c84)
@@ -43,9 +43,9 @@
 if sys.platform.count("win32") > 0:
     FONT_VARIANT = 0
-    PNL_WIDTH = 450
+    PNL_WIDTH = 500
     PNL_HEIGHT = 320
 else:
     FONT_VARIANT = 1
-    PNL_WIDTH = 590
+    PNL_WIDTH = 500
     PNL_HEIGHT = 350
 M_NAME = 'Model'
@@ -495,16 +495,23 @@
         Choose the equation to use depending on whether we now have
         a sum or multiply model then create the appropriate string
+        
+        for the sum model the result will be:
+        scale_factor * (scale1 * model_1 + scale2 * model_2) + background
+        while for the multiply model it will just be:
+        scale_factor * (model_1* model_2) + background
         """
         name = ''
         if operator == '*':
             name = 'Multi'
-            factor = 'background'
+            factor_1 = ''
+            factor_2 = ''
         else:
             name = 'Sum'
-            factor = 'scale_factor'
+            factor_1 = 'scale_1 * '
+            factor_2 = 'scale_2 * '
 
         self._operator = operator
-        self.explanation = ("  Plugin_model = scale_factor * (model_1 {} "
-            "model_2) + background").format(operator)
+        self.explanation = ("  Plugin_model = scale_factor * ({}model_1 {} "
+            "{}model_2) + background").format(factor_1,operator,factor_2)
         self.explanationctr.SetLabel(self.explanation)
         self.name = name + M_NAME
Index: src/sas/sasgui/perspectives/fitting/basepage.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/basepage.py	(revision 8a51dea053e540915bf4b4f3fe86a6b09a456d4f)
+++ src/sas/sasgui/perspectives/fitting/basepage.py	(revision b43988196e5c4f2dfbf3ec5c9b66703d5656b08d)
@@ -31,4 +31,5 @@
 
 from sas.sasgui.guiframe.panel_base import PanelBase
+from sas.sasgui.guiframe.report_image_handler import ReportImageHandler
 from sas.sasgui.guiframe.utils import format_number, check_float, IdList, \
     check_int
@@ -651,34 +652,10 @@
         by plotting, putting it into wx.FileSystem image object
         """
-        images = []
-        refs = []
-
-        # For no figures in the list, prepare empty plot
-        if figs is None or len(figs) == 0:
-            figs = [None]
-
-        # Loop over the list of figures
-        # use wx.MemoryFSHandler
-        imgRAM = wx.MemoryFSHandler()
-        for fig in figs:
-            if fig is not None:
-                ind = figs.index(fig)
-                canvas = canvases[ind]
-
-            # store the image in wx.FileSystem Object
-            wx.FileSystem.AddHandler(wx.MemoryFSHandler())
-
-            # index of the fig
-            ind = figs.index(fig)
-
-            # AddFile, image can be retrieved with 'memory:filename'
-            name = 'img_fit%s.png' % ind
-            refs.append('memory:' + name)
-            imgRAM.AddFile(name, canvas.bitmap, wx.BITMAP_TYPE_PNG)
-            # append figs
-            images.append(fig)
-
-        return imgRAM, images, refs
-
+        bitmaps = []
+        for canvas in canvases:
+            bitmaps.append(canvas.bitmap)
+        imgs, refs = ReportImageHandler.set_figs(figs, bitmaps, 'fit')
+
+        return ReportImageHandler.instance, imgs, refs
 
     def on_save(self, event):
@@ -2801,17 +2778,21 @@
         Function called when 'Help' button is pressed next to model
         of interest.  This calls DocumentationWindow from
-        documentation_window.py. It will load the top level of the model
-        help documenation sphinx generated html if no model is presented.
-        If a model IS present then if documention for that model exists
-        it will load to that  point otherwise again it will go to the top.
-        For Wx2.8 and below is used (i.e. non-released through installer)
-        a browser is loaded and the top of the model documentation only is
-        accessible because webbrowser module does not pass anything after
-        the # to the browser.
+        documentation_window.py. It will load the top level of the html model
+        help documenation sphinx generated if either a plugin model (which
+        normally does not have an html help help file) is selected or if no
+        model is selected. Otherwise, if a regula model is selected, the
+        documention for that model will be sent to a browser window.
+
+        :todo the quick fix for no documentation in plugins is the if statment.
+        However, the right way to do this would be to check whether the hmtl
+        file exists and load the model docs if it does and the general docs if
+        it doesn't - this will become important if we ever figure out how to
+        build docs for plugins on the fly.  Sep 9, 2018 -PDB
 
         :param event: on Help Button pressed event
         """
 
-        if self.model is not None:
+        if (self.model is not None) and (self.categorybox.GetValue()
+                                         != "Plugin Models"):
             name = self.formfactorbox.GetValue()
             _TreeLocation = 'user/models/%s.html' % name
Index: src/sas/sasgui/perspectives/fitting/gpu_options.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/gpu_options.py	(revision 42a6e029d713dd90abf6af8ac04156c566900404)
+++ src/sas/sasgui/perspectives/fitting/gpu_options.py	(revision 388aefbfe7862efae1f1595105c7a8b53bb3e8e3)
@@ -139,4 +139,7 @@
 
         test_text = wx.StaticText(self, -1, "WARNING: Running tests can take a few minutes!")
+        test_text2 = wx.StaticText(self, -1, "NOTE: No test will run if No OpenCL is checked")
+        test_text.SetForegroundColour(wx.RED)
+        self.vbox.Add(test_text2, 0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 10)
         self.vbox.Add(test_text, 0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 10)
 
Index: src/sas/sasgui/perspectives/fitting/report_dialog.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/report_dialog.py	(revision 69a68979fe94b8f135a602e7f02b162e34616d53)
+++ src/sas/sasgui/perspectives/fitting/report_dialog.py	(revision 44e8f48e6ada97db8eb483009edc07705c6329a2)
@@ -72,14 +72,12 @@
         filename = basename + ext
 
-        # save figures
-        pictures = []
-        for num in range(self.nimages):
-            pic_name = basename + '_img%s.png' % num
-            # save the image for use with pdf writer
-            self.report_list[2][num].savefig(pic_name)
-            pictures.append(pic_name)
+        # save the images for use with pdf writer
+        pictures = [
+            '_'.join((basename, url.split(':')[1])) for url in self.fig_urls]
+        for i, pic in enumerate(pictures):
+            self.report_list[2][i].savefig(pic)
 
         # translate png references int html from in-memory name to on-disk name
-        html = self.report_html.replace("memory:img_fit", basename+'_img')
+        html = self.report_html.replace("memory:", basename+'_')
 
         #set file extensions
Index: src/sas/sasgui/perspectives/invariant/invariant_panel.py
===================================================================
--- src/sas/sasgui/perspectives/invariant/invariant_panel.py	(revision 2469df7fc9ffa047115c5bffe589ed307b12c363)
+++ src/sas/sasgui/perspectives/invariant/invariant_panel.py	(revision 44e8f48e6ada97db8eb483009edc07705c6329a2)
@@ -24,4 +24,5 @@
 from sas.sasgui.guiframe.panel_base import PanelBase
 from sas.sasgui.guiframe.documentation_window import DocumentationWindow
+from sas.sasgui.guiframe.report_image_handler import ReportImageHandler
 
 logger = logging.getLogger(__name__)
@@ -783,5 +784,8 @@
         report_img = self.state.image
         report_list = [report_html_str, report_text_str, report_img]
-        dialog = ReportDialog(report_list, None, -1, "")
+        ReportImageHandler.check_for_empty_instance()
+        imgRAM = ReportImageHandler.instance.img_holder
+        refs = [self.state.wximgbmp]
+        dialog = ReportDialog(report_list, imgRAM, refs, None, wx.ID_ANY, "")
         dialog.Show()
 
Index: src/sas/sasgui/perspectives/invariant/invariant_state.py
===================================================================
--- src/sas/sasgui/perspectives/invariant/invariant_state.py	(revision 2469df7fc9ffa047115c5bffe589ed307b12c363)
+++ src/sas/sasgui/perspectives/invariant/invariant_state.py	(revision fa412df39d3c5338c2c5f69fed935b428f385ebe)
@@ -12,4 +12,5 @@
 from lxml import etree
 from sas.sascalc.dataloader.readers.cansas_reader import Reader as CansasReader
+from sas.sasgui.guiframe.report_image_handler import ReportImageHandler
 from sas.sascalc.dataloader.readers.cansas_reader import get_content
 from sas.sasgui.guiframe.utils import format_number
@@ -611,12 +612,8 @@
         wximgbmp = wx.BitmapFromImage(wximg)
         # store the image in wx.FileSystem Object
-        wx.FileSystem.AddHandler(wx.MemoryFSHandler())
-        # use wx.MemoryFSHandler
-        self.imgRAM = wx.MemoryFSHandler()
-        # AddFile, image can be retrieved with 'memory:filename'
-        self.imgRAM.AddFile('img_inv.png', wximgbmp, wx.BITMAP_TYPE_PNG)
-
-        self.wximgbmp = 'memory:img_inv.png'
-        self.image = fig
+        imgs, refs = ReportImageHandler.set_figs([fig], [wximgbmp], 'inv')
+
+        self.wximgbmp = refs[0]
+        self.image = imgs[0]
 
 class Reader(CansasReader):
Index: src/sas/sasgui/perspectives/invariant/report_dialog.py
===================================================================
--- src/sas/sasgui/perspectives/invariant/report_dialog.py	(revision 959eb0181ad06828a748f04512f953aad5b31659)
+++ src/sas/sasgui/perspectives/invariant/report_dialog.py	(revision d0ce666faaf0f9284be2e607a0ac846cdd9a682b)
@@ -41,5 +41,5 @@
 
         # put image path in the report string
-        self.report_html = self.report_list[0] % "memory:img_inv.png"
+        self.report_html = self.report_list[0] % self.fig_urls[0]
         # layout
         self._setup_layout()
