Index: src/sas/sasgui/perspectives/fitting/models.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/models.py	(revision 7673ecd9d5adcefdfa1fc6a6d1ff0649f8e63bc8)
+++ src/sas/sasgui/perspectives/fitting/models.py	(revision e3ae090acafb0a35e27298bc8dd1e99d1ffab206)
@@ -181,4 +181,5 @@
             try:
                 model = load_custom_model(path)
+                plugins[model.name] = model
             except Exception:
                 msg = traceback.format_exc()
@@ -187,6 +188,5 @@
                 logging.warning("Failed to load plugin %r. See %s for details"
                                 % (path, PLUGIN_LOG))
-            plugins[model.name] = model
-
+            
     return plugins
 
Index: src/sas/sasgui/plottools/LineModel.py
===================================================================
--- src/sas/sasgui/plottools/LineModel.py	(revision d7bb5267934b5676c90b1655346a3793a8022965)
+++ src/sas/sasgui/plottools/LineModel.py	(revision e3ae090acafb0a35e27298bc8dd1e99d1ffab206)
@@ -1,5 +1,12 @@
 #!/usr/bin/env python
 """
-Provide Line function (y= A + Bx)
+Provide Line function (y= Ax + B). Until July 10, 2016 this function provided
+(y= A + Bx).  This however was contrary to all the other code using it which 
+assumed (y= mx+b) or in this nomenclature (y=Ax + B). This lead to some
+contortions in the code and worse incorrect calculations until now for at least
+some of the functions.  This seemed the easiest to fix particularly since this
+function should disappear in a future iteration (see notes in fitDialog)
+
+                -PDB   July 10, 2016
 """
 
@@ -10,9 +17,9 @@
     Class that evaluates a linear model.
 
-    f(x) = A + Bx
+    f(x) = Ax + B
 
     List of default parameters:
-    A = 0.0
-    B = 0.0
+    A = 1.0
+    B = 1.0
     """
 
@@ -53,9 +60,15 @@
 
         """
-        return  self.params['A'] + (x * self.params['B'])
+        return  (self.params['A'] * x) + self.params['B']
 
     def run(self, x=0.0):
         """
         Evaluate the model
+
+        :note: This is the function called by fitDialog to calculate the
+        the y(xmin) and y(xmax), but the only difference between this and
+        runXY is when the if statement is true. I however cannot see what that
+        function is for.  It needs to be documented here or removed.
+        -PDB 7/10/16 
 
         :param x: simple value
@@ -74,5 +87,10 @@
     def runXY(self, x=0.0):
         """
-        Evaluate the model
+        Evaluate the model.
+        
+        :note: This is to be what is called by fitDialog for the actual fit
+        but the only difference between this and run is when the if 
+        statement is true. I however cannot see what that function
+        is for.  It needs to be documented here or removed. -PDB 7/10/16 
 
         :param x: simple value
Index: src/sas/sasgui/plottools/PlotPanel.py
===================================================================
--- src/sas/sasgui/plottools/PlotPanel.py	(revision 16b769b0ee7796dc2a4819159984096a14089bd4)
+++ src/sas/sasgui/plottools/PlotPanel.py	(revision e3ae090acafb0a35e27298bc8dd1e99d1ffab206)
@@ -646,4 +646,9 @@
                 dlg.setFitRange(self.xminView, self.xmaxView,
                                 self.xmin, self.xmax)
+            # It would be nice for this to NOT be modal (i.e. Show).
+            # Not sure about other ramifications - for example
+            # if a second linear fit is started before the first is closed.
+            # consider for future - being able to work on the plot while
+            # seing the fit values would be very nice  -- PDB 7/10/16
             dlg.ShowModal()
 
Index: src/sas/sasgui/plottools/PropertyDialog.py
===================================================================
--- src/sas/sasgui/plottools/PropertyDialog.py	(revision d7bb5267934b5676c90b1655346a3793a8022965)
+++ src/sas/sasgui/plottools/PropertyDialog.py	(revision e3ae090acafb0a35e27298bc8dd1e99d1ffab206)
@@ -78,5 +78,9 @@
         self.view.Insert("XS Guinier ln(y*x) vs x^(2)", 3)
         self.view.Insert("Porod y*x^(4) vs x^(4)", 4)
-        self.view.Insert("Kratky y*x^(2) vs x", 5)
+        # This did not work in 3.1.2 and does not work now.
+        # prefer to fix (should not be too hard) but for the moment
+        # am removing as an option the user sees so they don't get
+        # disappointed.    PDB 7/10/2016 
+        # self.view.Insert("Kratky y*x^(2) vs x", 5)
         self.SetSizer(vbox)
         self.Fit()
Index: src/sas/sasgui/plottools/fitDialog.py
===================================================================
--- src/sas/sasgui/plottools/fitDialog.py	(revision d7bb5267934b5676c90b1655346a3793a8022965)
+++ src/sas/sasgui/plottools/fitDialog.py	(revision e3ae090acafb0a35e27298bc8dd1e99d1ffab206)
@@ -20,5 +20,6 @@
 def format_number(value, high=False):
     """
-    Return a float in a standardized, human-readable formatted string
+    Return a float in a standardized, human-readable formatted string.
+    This is used to output readable (e.g. x.xxxe-y) values to the panel.
     """
     try:
@@ -40,5 +41,24 @@
         """
         Dialog window pops- up when select Linear fit on Context menu
-        Displays fitting parameters
+        Displays fitting parameters. This class handles the linearized
+        fitting and derives and displays specialized output parameters based
+        on the scale choice of the plot calling it.
+        
+        :note1: The fitting is currently a bit convoluted as besides using
+        plottools.transform.py to handle all the conversions, it uses
+        LineModel to define a linear model and calculate a number of
+        things like residuals etc as well as the function itself given an x
+        value. It also uses fittings.py to set up the defined LineModel for
+        fitting and then send it to the SciPy NLLSQ method.  As these are by
+        definition "linear nodels" it would make more sense to just call
+        a linear solver such as scipy.stats.linregress or bumps.wsolve directly.
+        This would considerably simplify the code and remove the need I think
+        for LineModel.py and possibly fittins.py altogether.   -PDB 7/10/16
+        
+        :note2: The linearized fits do not take resolution into account. This
+        means that for poor resolution such as slit smearing the answers will
+        be completely wrong --- Rg would be OK but I0 would be orders of
+        magnitude off.  Eventually we should fix this to account properly for
+        resolution.   -PDB  7/10/16
         """
         wx.Dialog.__init__(self, parent, title=title,
@@ -50,41 +70,112 @@
         # Registered owner for close event
         self._registered_close = None
-
         # dialog panel self call function to plot the fitting function
+        # calls the calling PlotPanel method onFitDisplay
         self.push_data = push_data
-        # dialog self plottable
+        # dialog self plottable - basically the plot we are working with
+        # passed in by the caller
         self.plottable = plottable
+        # is this a Guinier fit
         self.rg_on = False
-        # Receive transformations of x and y
+        # Receive transformations of x and y - basically transform is passed
+        # as caller method that returns its current value for these
         self.xLabel, self.yLabel, self.Avalue, self.Bvalue, \
                self.ErrAvalue, self.ErrBvalue, self.Chivalue = self.transform()
 
-        # Dialog interface
+        # Now set up the dialog interface
+        self.layout()
+        # Receives the type of model for the fitting
+        from LineModel import LineModel
+        self.model = LineModel()
+        # Display the fittings values
+        self.default_A = self.model.getParam('A')
+        self.default_B = self.model.getParam('B')
+        self.cstA = fittings.Parameter(self.model, 'A', self.default_A)
+        self.cstB = fittings.Parameter(self.model, 'B', self.default_B)
+
+        # Set default value of parameter in the dialog panel
+        if self.Avalue == None:
+            self.tcA.SetValue(format_number(self.default_A))
+        else:
+            self.tcA.SetLabel(format_number(self.Avalue))
+        if self.Bvalue == None:
+            self.tcB.SetValue(format_number(self.default_B))
+        else:
+            self.tcB.SetLabel(format_number(self.Bvalue))
+        if self.ErrAvalue == None:
+            self.tcErrA.SetLabel(format_number(0.0))
+        else:
+            self.tcErrA.SetLabel(format_number(self.ErrAvalue))
+        if self.ErrBvalue == None:
+            self.tcErrB.SetLabel(format_number(0.0))
+        else:
+            self.tcErrB.SetLabel(format_number(self.ErrBvalue))
+        if self.Chivalue == None:
+            self.tcChi.SetLabel(format_number(0.0))
+        else:
+            self.tcChi.SetLabel(format_number(self.Chivalue))
+        if self.plottable.x != []:
+            # store the values of View in self.x,self.y,self.dx,self.dy
+            self.x, self.y, self.dx, \
+                     self.dy = self.plottable.returnValuesOfView()
+            try:
+                self.mini = self.floatForwardTransform(min(self.x))
+            except:
+                self.mini = "Invalid"
+            try:
+                self.maxi = self.floatForwardTransform(max(self.x))
+            except:
+                self.maxi = "Invalid"
+
+            self.initXmin.SetValue(format_number(min(self.plottable.x)))
+            self.initXmax.SetValue(format_number(max(self.plottable.x)))
+            self.mini = min(self.x)
+            self.maxi = max(self.x)
+            self.xminFit.SetValue(format_number(self.mini))
+            self.xmaxFit.SetValue(format_number(self.maxi))
+
+    def layout(self):
+        """
+        Sets up the panel layout for the linear fit including all the
+        labels, text entry boxes, and buttons.
+
+        """
+
+        # set up sizers first. 
+        # vbox is the panel sizer and is a vertical sizer
+        # The first element of the panel is sizer which is a gridbagsizer
+        # and contains most of the text fields
+        # this is followed by a line separator added to vbox
+        # and finally the sizer_button (a horizontal sizer) adds the buttons
         vbox = wx.BoxSizer(wx.VERTICAL)
         sizer = wx.GridBagSizer(5, 5)
+        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
+        
+        #size of string boxes in pixels
         _BOX_WIDTH = 100
-
-        self.tcA = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
+        _BOX_HEIGHT = 20
+        #now set up all the text fields
+        self.tcA = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT))
         self.tcA.SetToolTipString("Fit value for the slope parameter.")
-        self.tcErrA = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
+        self.tcErrA = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT))
         self.tcErrA.SetToolTipString("Error on the slope parameter.")
-        self.tcB = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
+        self.tcB = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT))
         self.tcA.SetToolTipString("Fit value for the constant parameter.")
-        self.tcErrB = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
+        self.tcErrB = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT))
         self.tcErrB.SetToolTipString("Error on the constant parameter.")
-        self.tcChi = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
+        self.tcChi = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT))
         self.tcChi.SetToolTipString("Chi^2 over degrees of freedom.")
-        self.xminFit = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
+        self.xminFit = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT))
         msg = "Enter the minimum value on "
         msg += "the x-axis to be included in the fit."
         self.xminFit.SetToolTipString(msg)
-        self.xmaxFit = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
+        self.xmaxFit = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT))
         msg = "Enter the maximum value on "
         msg += " the x-axis to be included in the fit."
         self.xmaxFit.SetToolTipString(msg)
-        self.initXmin = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
+        self.initXmin = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT))
         msg = "Minimum value on the x-axis for the plotted data."
         self.initXmin.SetToolTipString(msg)
-        self.initXmax = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
+        self.initXmax = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, _BOX_HEIGHT))
         msg = "Maximum value on the x-axis for the plotted data."
         self.initXmax.SetToolTipString(msg)
@@ -98,12 +189,8 @@
         self.initXmax.SetBackgroundColour(_BACKGROUND_COLOR)
 
-        # Buttons on the bottom
+        #set some flags for specific types of fits like Guinier (Rg) and
+        #Porod (bg) -- this will determine WHAT boxes show up in the
+        #sizer layout and depends on the active axis transform
         self.bg_on = False
-        self.static_line_1 = wx.StaticLine(self, -1)
-        self.btFit = wx.Button(self, -1, 'Fit')
-        self.btFit.Bind(wx.EVT_BUTTON, self._onFit)
-        self.btFit.SetToolTipString("Perform fit.")
-        self.btClose = wx.Button(self, wx.ID_CANCEL, 'Close')
-        self.btClose.Bind(wx.EVT_BUTTON, self._on_close)
         if RG_ON:
             if (self.yLabel == "ln(y)" or self.yLabel == "ln(y*x)") and \
@@ -112,16 +199,26 @@
             if (self.xLabel == "x^(4)") and (self.yLabel == "y*x^(4)"):
                 self.bg_on = True
-        # Intro
-        explanation = "Perform fit for y(x) = ax + b"
+
+        # Finally set up static text strings
+        warning = "WARNING! Resolution is NOT accounted for. \n"
+        warning += "Thus slit smeared data will give very wrong answers!"
+        self.textwarn = wx.StaticText(self, -1, warning)
+        self.textwarn.SetForegroundColour(wx.RED)
+        explanation = "Perform fit for y(x) = ax + b \n"
         if self.bg_on:
             param_a = 'Background (= Parameter a)'
         else:
             param_a = 'Parameter a'
-        vbox.Add(sizer)
+
+
+        #Now set this all up in the GridBagSizer sizer
         ix = 0
-        iy = 1
+        iy = 0
+        sizer.Add(self.textwarn, (iy, ix),
+                  (2, 3), wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
+        iy += 2
         sizer.Add(wx.StaticText(self, -1, explanation), (iy, ix),
                   (1, 1), wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
-        iy += 2
+        iy += 1
         sizer.Add(wx.StaticText(self, -1, param_a), (iy, ix),
                   (1, 1), wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
@@ -281,68 +378,30 @@
                       wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 0)
 
+        #Now add some space before the separation line
         iy += 1
-        ix = 1
-
-        vbox.Add(self.static_line_1, 0, wx.EXPAND, 0)
-        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
+        ix = 0
+        sizer.Add((20,20), (iy, ix), (1, 1),
+                      wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 0)
+
+        # Buttons on the bottom
+        self.btFit = wx.Button(self, -1, 'Fit')
+        self.btFit.Bind(wx.EVT_BUTTON, self._onFit)
+        self.btFit.SetToolTipString("Perform fit.")
+        self.btClose = wx.Button(self, wx.ID_CANCEL, 'Close')
+        self.btClose.Bind(wx.EVT_BUTTON, self._on_close)
         sizer_button.Add((20, 20), 1, wx.EXPAND | wx.ADJUST_MINSIZE, 0)
-        sizer_button.Add(self.btFit, 0, wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE, 10)
+        sizer_button.Add(self.btFit, 0,
+                         wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE, 10)
         sizer_button.Add(self.btClose, 0,
                          wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE, 10)
+        
+        vbox.Add(sizer)
+        self.static_line_1 = wx.StaticLine(self, -1)        
+        vbox.Add(self.static_line_1, 0, wx.EXPAND, 0)
         vbox.Add(sizer_button, 0, wx.EXPAND | wx.BOTTOM | wx.TOP, 10)
 
-        sizer.Add(self.btFit, (iy, ix), (1, 1), wx.LEFT | wx.ADJUST_MINSIZE, 0)
         # panel.SetSizer(sizer)
         self.SetSizer(vbox)
         self.Centre()
-        # Receives the type of model for the fitting
-        from LineModel import LineModel
-        self.model = LineModel()
-        # Display the fittings values
-        self.default_A = self.model.getParam('A')
-        self.default_B = self.model.getParam('B')
-        self.cstA = fittings.Parameter(self.model, 'A', self.default_A)
-        self.cstB = fittings.Parameter(self.model, 'B', self.default_B)
-
-        # Set default value of parameter in fit dialog
-        if self.Avalue == None:
-            self.tcA.SetValue(format_number(self.default_A))
-        else:
-            self.tcA.SetLabel(format_number(self.Avalue))
-        if self.Bvalue == None:
-            self.tcB.SetValue(format_number(self.default_B))
-        else:
-            self.tcB.SetLabel(format_number(self.Bvalue))
-        if self.ErrAvalue == None:
-            self.tcErrA.SetLabel(format_number(0.0))
-        else:
-            self.tcErrA.SetLabel(format_number(self.ErrAvalue))
-        if self.ErrBvalue == None:
-            self.tcErrB.SetLabel(format_number(0.0))
-        else:
-            self.tcErrB.SetLabel(format_number(self.ErrBvalue))
-        if self.Chivalue == None:
-            self.tcChi.SetLabel(format_number(0.0))
-        else:
-            self.tcChi.SetLabel(format_number(self.Chivalue))
-        if self.plottable.x != []:
-            # store the values of View in self.x,self.y,self.dx,self.dy
-            self.x, self.y, self.dx, \
-                     self.dy = self.plottable.returnValuesOfView()
-            try:
-                self.mini = self.floatForwardTransform(min(self.x))
-            except:
-                self.mini = "Invalid"
-            try:
-                self.maxi = self.floatForwardTransform(max(self.x))
-            except:
-                self.maxi = "Invalid"
-
-            self.initXmin.SetValue(format_number(min(self.plottable.x)))
-            self.initXmax.SetValue(format_number(max(self.plottable.x)))
-            self.mini = min(self.x)
-            self.maxi = max(self.x)
-            self.xminFit.SetValue(format_number(self.mini))
-            self.xmaxFit.SetValue(format_number(self.maxi))
 
     def register_close(self, owner):
@@ -371,5 +430,5 @@
         the button Fit.Computes chisqr ,
         A and B parameters of the best linear fit y=Ax +B
-        Push a plottable to
+        Push a plottable to the caller
         """
         tempx = []
@@ -389,4 +448,8 @@
                 xmin = xminView
                 xmax = xmaxView
+                # Set the qmin and qmax in the panel that matches the
+                # transformed min and max
+                self.initXmin.SetValue(format_number(self.floatInvTransform(xmin)))
+                self.initXmax.SetValue(format_number(self.floatInvTransform(xmax)))
                 # Store the transformed values of view x, y,dy
                 # in variables  before the fit
@@ -485,6 +548,6 @@
                     tempy.append(y_model)
                 # Set the fit parameter display when  FitDialog is opened again
-                self.Avalue = cstB
-                self.Bvalue = cstA
+                self.Avalue = cstA
+                self.Bvalue = cstB
                 self.ErrAvalue = errA
                 self.ErrBvalue = errB
@@ -494,5 +557,5 @@
 
                 # Display the fitting value on the Fit Dialog
-                self._onsetValues(cstB, cstA, errA, errB, chisqr)
+                self._onsetValues(cstA, cstB, errA, errB, chisqr)
 
     def _onsetValues(self, cstA, cstB, errA, errB, Chi):
@@ -501,4 +564,5 @@
         """
         rg = None
+        _diam = None
         self.tcA.SetValue(format_number(cstA))
         self.tcB.SetValue(format_number(cstB))
@@ -516,26 +580,27 @@
             if self.Rgerr_tctr.IsShown():
                 if rg != None and rg != 0:
-                    value = format_number(3 * float(cstA) / (2 * rg))
+                    value = format_number(3 * float(errA) / (2 * rg))
                 else:
                     value = ''
                 self.Rgerr_tctr.SetValue(value)
                 if self.I0err_tctr.IsShown():
-                    val = numpy.abs(numpy.exp(cstB) - numpy.exp(cstB + errB))
+                    val = numpy.abs(numpy.exp(cstB) * errB)
                     self.I0err_tctr.SetValue(format_number(val))
             if self.Diameter_tctr.IsShown():
-                rg = 4 * numpy.sqrt(-float(cstA))
-                value = format_number(rg)
+                rg = numpy.sqrt(-2 * float(cstA))
+                _diam = 4 * numpy.sqrt(-float(cstA))
+                value = format_number(_diam)
                 self.Diameter_tctr.SetValue(value)
             if self.Diametererr_tctr.IsShown():
                 if rg != None and rg != 0:
-                    value = format_number(8 * float(cstA) / rg)
+                    value = format_number(8 * float(errA) / _diam)
                 else:
                     value = ''
                 self.Diametererr_tctr.SetValue(value)
             if self.RgQmin_tctr.IsShown():
-                value = format_number(rg * self.mini)
+                value = format_number(rg * self.floatInvTransform(self.mini))
                 self.RgQmin_tctr.SetValue(value)
             if self.RgQmax_tctr.IsShown():
-                value = format_number(rg * self.maxi)
+                value = format_number(rg * self.floatInvTransform(self.maxi))
                 self.RgQmax_tctr.SetValue(value)
 
@@ -610,6 +675,8 @@
     def floatInvTransform(self, x):
         """
-        transform a float.It is use to determine the x.View min and x.View
-        max for values not in x
+        transform a float.It is used to determine the x.View min and x.View
+        max for values not in x.  Also used to properly calculate RgQmin,
+        RgQmax and to update qmin and qmax in the linear range boxes on the
+        panel.
 
         """
@@ -617,10 +684,16 @@
         # functionality work without rewritting the whole code
         # with good design (which really should be done...).
-        if self.xLabel == "x^(2)":
+        if self.xLabel == "x":
+            return x
+        elif self.xLabel == "x^(2)":
             return math.sqrt(x)
+        elif self.xLabel == "x^(4)":
+            return math.sqrt(math.sqrt(x))
         elif self.xLabel == "log10(x)":
             return math.pow(10, x)
         elif self.xLabel == "ln(x)":
             return math.exp(x)
+        elif self.xLabel == "log10(x^(4))":
+            return math.sqrt(math.sqrt(math.pow(10, x)))
         return x
 
Index: src/sas/sasgui/plottools/fittings.py
===================================================================
--- src/sas/sasgui/plottools/fittings.py	(revision d7bb5267934b5676c90b1655346a3793a8022965)
+++ src/sas/sasgui/plottools/fittings.py	(revision e3ae090acafb0a35e27298bc8dd1e99d1ffab206)
@@ -1,3 +1,16 @@
 """
+This module is used to fit a set of x,y data to a model passed to it. It is
+used to calculate the slope and intercepts for the linearized fits.  Two things
+should be noted:
+
+First, this fitting module uses the NLLSQ module of SciPy rather than a linear
+fit.  This along with a few other modules could probably be removed if we
+move to a linear regression approach.
+
+Second, this infrastructure does not allow for resolution smearing of the 
+the models.  Hence the results are not that accurate even for pinhole
+collimation of SANS but may be good for SAXS.  It is completely wrong for 
+slit smeared data. 
+
 """
 from scipy import optimize
@@ -6,5 +19,6 @@
 class Parameter(object):
     """
-    Class to handle model parameters
+    Class to handle model parameters - sets the parameters and their
+    initial value from the model based to it.
     """
     def __init__(self, model, name, value=None):
