Index: INSTALL.txt
===================================================================
--- INSTALL.txt	(revision 26c9b85eb05ac83c648348fc7879e08e3225ceb1)
+++ INSTALL.txt	(revision 26c9b85eb05ac83c648348fc7879e08e3225ceb1)
@@ -0,0 +1,51 @@
+Quick Intro for Building Sasview
+================================
+
+Note - at the current time sasview will only run in gui form under Python 2.
+
+Before trying to install and run sasview you'll need to check what
+dependencies are required:
+
+$ python check_packages.py
+
+Many of these are available from PyPi, but some (e.g. h5py) may require more
+involvement to build and install. If you use the conda package manager then
+many of the pre-built dependencies are available there. This may be the easiest
+route if you are on windows.
+
+The build works in the pythonic way:
+
+$ python setup.py build      # will build the package underneath 'build/'
+$ python setup.py install    # will install the package into site-packages
+
+
+If you want to check the build without installing:
+
+$ python run.py              # will run the code in place (building the C code once, if required)
+
+On OSX or windows you may need to use:
+
+$ pythonw run.py
+
+
+Build scripts that are used on http://build.sasview.org/ are in
+build_tools. Make sure the build is run first obviously.
+
+$ build_tools/jenkins_linux_build.sh
+$ build_tools/jenkins_linux_test.sh
+$ build_tools/jenkins_linux_pylint.sh
+
+The scripts can be customized using environment variables, but 
+should do a reasonable job as is in a sane setup.
+
+
+
+To build just the Sphinx docs:
+build_sphinx.py
+
+
+More information can be found here:
+
+http://www.sasview.org/help.html
+http://www.sasview.org/faq.html
+http://www.sasview.org/trac/wiki/DevNotes
Index: LICENSE.TXT
===================================================================
--- LICENSE.TXT	(revision 7c05b63b782997e4f04fe015fe6ec523b26bdb7c)
+++ LICENSE.TXT	(revision a3e3ef589b5480f01cfe7c9d68b47e807fa7f49c)
@@ -1,3 +1,3 @@
-Copyright (c) 2009-2016, SasView Developers
+Copyright (c) 2009-2017, SasView Developers
 All rights reserved.
 
Index: cs/README-BUILD-TIPS.TXT
===================================================================
--- docs/README-BUILD-TIPS.TXT	(revision d09f0ae18fc84c04aebd2d791c2fca44dba326dd)
+++ 	(revision )
@@ -1,47 +1,0 @@
-Quick Intro for Building Sasview
-================================
-
-
-The build works in the usualy pythonic way:
-
-$ python setup.py build      # will build the package underneath 'build/'
-$ python setup.py install    # will install the package
-
-
-
-If you want to check the build without installing:
-
-$ python run.py              # will run the code in place (building the C code once, if required)
-
-
-
-To check all dependencies are met:
-
-$ python deps.py
-$ python check_packages.py 
-
-Both tell you different parts of the story, unfortunately.
-
-
-
-Build scripts that are used on http://build.sasview.org/ are in
-build_tools. Make sure the build is run first obviously.
-
-$ build_tools/jenkins_linux_build.sh
-$ build_tools/jenkins_linux_test.sh
-$ build_tools/jenkins_linux_pylint.sh
-
-The scripts can be customized using environment variables, but 
-should do a reasonable job as is in a sane setup.
-
-
-
-To build just the Sphinx docs:
-build_sphinx.py
-
-
-More information can be found here:
-
-http://www.sasview.org/help.html
-http://www.sasview.org/faq.html
-http://www.sasview.org/trac/wiki/DevNotes
Index: sasview/README.txt
===================================================================
--- sasview/README.txt	(revision 220b1e78c0098906e14ad2dd815fdf5a862912fd)
+++ sasview/README.txt	(revision 311d00ac4610077e51142b4b69182cd5b95f3211)
@@ -4,4 +4,61 @@
 1- Features
 ===========
+    - New in Version 4.1.0
+      ------------------
+      This incremental release brings a series of new features and improvements,
+      and a host of bug fixes. Of particular note are:
+      
+      - Correlation Function Analysis (Corfunc)
+      	This performs a correlation function analysis of one-dimensional SAXS/SANS data, 
+	or generates a model-independent volume fraction profile from the SANS from an 
+	adsorbed polymer/surfactant layer.
+
+	A correlation function may be interpreted in terms of an imaginary rod moving 
+	through the structure of the material. Î1D(R) is the probability that a rod of 
+	length R moving through the material has equal electron/neutron scattering 
+	length density at either end. Hence a frequently occurring spacing within a 
+	structure manifests itself as a peak.
+
+	A volume fraction profile \Phi(z) describes how the density of polymer 
+	segments/surfactant molecules varies with distance from an (assumed locally flat)
+	interface.
+
+      - Fitting of SESANS Data
+      	Data from Spin-Echo SANS measurements can now be loaded and fitted. The data will 
+	be plotted against the correct axes and models will automatically perform a Hankel 
+	transform in order to calculate SESANS from a SANS model.
+
+      - Documentation
+      	The documentation has undergone significant checking and updating.
+
+      - Improvements
+        - Correlation function (corfunc) analysis of 1D SAS data added from CCP13
+        - File converter tool for multi-file single column data sets
+        - SESANS data loading and direct fitting using the Hankel transformation
+        - Saving and loading of simultaneous and constrained fits now supported
+        - Save states from SasView v3.x.y now loaded using sasmodel model names
+        - Saving and loading of projects with 2D fits now supported
+        - Loading a project removes all existing data, fits, and plots
+        - Structure factor and form factor can be plotted independently
+        - OpenCL is disabled by default and can be enabled through a fit menu
+        - Data and theory fields are now independently expandable
+      - Bug Fixes
+        - Fixes #667: Models computed multiple times on parameters changes
+        - Fixes #673: Custom models override built in models of same name
+        - Fixes #678: Hard crash when running complex models on GPU
+        - Fixes $774: Old style plugin models unloadable
+        - Fixes #789: stacked disk scale doesn't match cylinder model
+        - Fixes #792: core_shell_fractal uses wrong effective radius
+        - Fixes #800: Plot range reset on plot redraws
+        - Fixes #811 and #825: 2D smearing broken
+        - Fixes #815: Integer model parameter handling
+        - Fixes #824: Cannot apply sector averaging when no detector data present
+        - Fixes #830: Cansas HDF5 reader fully compliant with NXCanSAS v1.0 format
+        - Fixes #835: Fractal model breaks with negative Q values
+        - Fixes #843: Multilayer vesicle does not define effective radius
+        - Fixes #858: Hayter MSA S(Q) returns errors
+        - Numerous grammatical and contexual errors in documention
+
+
     - New in Version 4.0.1
       ------------------
@@ -426,4 +483,42 @@
 ===============
 
+
+   4.1- All systems:
+      The conversion to sasmodels infrastructure is ongoing and should be
+      completed in the next release. In the meantime this leads to a few known
+      issues:
+        - The way that orientation is defined is being refactored to address
+        long standing issues and comments.  In release 4.1 however only models
+        with symmetry (e.g. a=b) have been converted to the new definitions.
+        The rest (a <> b <> c - e.g. parellelepiped) maintain the same
+        definition as before and will be converted in 4.2.  Note that
+        orientational distribution also makes much more sense in the new
+        framework.  The documentation should indicate which definition is being
+        used for a given model.
+        - The infrastructure currently handles internal conversion of old style
+        models so that user created models in previous versions should continue
+        to work for now. At some point in the future such support will go away.
+        Everyone is encouraged to convert to the new structure which should be
+        relatively straight forward and provides a number of benefits. 
+        - In that vein, the distributed models and those generated by the new
+        plugin model editor are in the new format, however those generated by
+        sum|multiply models are the old style sum|multiply models. This should
+        also disappear in the near future 
+        - The on the fly discovery of plugin models and changes thereto behave
+        inconsistently.  If a change to a plugin model does not seem to
+        register, the Load Plugin Models (under fitting -> Plugin Model
+        Operations) can be used.  However, after calling Load Plugin Models, the
+        active plugin will no longer be loaded (even though the GUI looks like
+        it is) unless it is a sum|multiply model which works properly.  All
+        others will need to be recalled from the model dropdown menu to reload
+        the model into the calculation engine.  While it might be annoying it
+        does not appear to prevent SasView from working..
+        - The model code and documentation review is ongoing. At this time the
+        core shell parellelepiped is known to have the C shell effectively fixed
+        at 0 (noted in documentation) while the triaxial ellipsoid does not seem
+        to reproduce the limit of the oblate or prolate ellipsoid. If errors are
+        found and corrected, corrected versions will be uploaded to the
+        marketplace. 
+   
    3.1- All systems:
         - The documentation window may take a few seconds to load the first time
Index: sasview/local_config.py
===================================================================
--- sasview/local_config.py	(revision 73cbeec4f3f2dfd3c530e5782984529dc2c133b2)
+++ sasview/local_config.py	(revision f9d1f609ce36aae44396ad86ba1db9146a4234b3)
@@ -33,21 +33,19 @@
 ''' remember to:'''
 _acknowledgement_preamble_bullet1 =\
-'''Acknowledge its use in your publications as suggested below;'''
+'''Acknowledge its use in your publications as :'''
 _acknowledgement_preamble_bullet2 =\
-'''Reference SasView as : M. Doucet, et al. SasView Version 4.0, Zenodo''' +\
-''', http://doi.org/10.5281/zenodo.159083;'''
+'''Reference SasView as:'''
 _acknowledgement_preamble_bullet3 =\
-'''Reference the model you used if appropriate (see documentation for refs);'''
+'''Reference the model you used if appropriate (see documentation for refs)'''
 _acknowledgement_preamble_bullet4 =\
 '''Send us your reference for our records: developers@sasview.org'''
 _acknowledgement_publications = \
-'''This work benefited from the use of the SasView application, originally developed under NSF Award 
-DMR-0520547. SasView also contains code developed with funding from the EU Horizon 2020 programme 
-under the SINE2020 project Grant No 654000, and by Patrick O'Brien & Adam Washington.'''
+'''This work benefited from the use of the SasView application, originally developed under NSF Award DMR-0520547. SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project Grant No 654000.'''
+_acknowledgement_citation = \
+'''M. Doucet et al. SasView Version 4.1, Zenodo, 10.5281/zenodo.438138'''
 
 _acknowledgement =  \
-'''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547, but is currently maintained 
-by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO and TU Delft. SasView also contains code developed with funding from the 
-EU Horizon 2020 programme under the SINE2020 project (Grant No 654000), and by Patrick O'Brien (pycrust) and Adam Washington (corfunc-py).'''
+'''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547,\n but is currently maintained by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO and TU Delft and the scattering community.\n\n SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project (Grant No 654000).\nA list of individual contributors can be found at: https://github.com/orgs/SasView/people
+'''
 
 _homepage = "http://www.sasview.org"
@@ -89,5 +87,5 @@
 _corner_image = os.path.join(icon_path, "angles_flat.png")
 _welcome_image = os.path.join(icon_path, "SVwelcome.png")
-_copyright = "(c) 2009 - 2016, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO and TU Delft"
+_copyright = "(c) 2009 - 2017, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO and TU Delft"
 marketplace_url = "http://marketplace.sasview.org/"
 
Index: setup.py
===================================================================
--- setup.py	(revision 1e13b539370619f0f420c675af3d469eec215af3)
+++ setup.py	(revision 27109e5cd4b7a9b36dd9bb6e66db62057374322b)
@@ -315,7 +315,12 @@
                                'test/1d_data/*',
                                'test/2d_data/*',
+                               'test/convertible_files/*',
+                               'test/coordinate_data/*',
+                               'test/image_data/*',
+                               'test/media/*',
+                               'test/other_files/*',
                                'test/save_states/*',
-                               'test/upcoming_formats/*',
-                                 'default_categories.json']
+                               'test/sesans_data/*'
+                               ]
 packages.append("sas.sasview")
 
Index: src/sas/sascalc/calculator/slit_length_calculator.py
===================================================================
--- src/sas/sascalc/calculator/slit_length_calculator.py	(revision b699768550de9d4b35b087234ec1d2a461922bab)
+++ src/sas/sascalc/calculator/slit_length_calculator.py	(revision bfba720913704ca9ad2c0e91e8f7a68846bf615a)
@@ -16,5 +16,5 @@
         # y data
         self.y = None
-        #default slit length
+        # default slit length
         self.slit_length = 0.0
 
@@ -42,5 +42,5 @@
         """
         # None data do nothing
-        if self.y == None or self.x == None:
+        if self.y is None or self.x is None:
             return
         # set local variable
@@ -54,5 +54,5 @@
         y_sum = 0.0
         y_max = 0.0
-        ind = 0.0
+        ind = 0
 
         # sum 10 or more y values until getting max_y,
@@ -70,5 +70,5 @@
         # defaults
         y_half_d = 0.0
-        ind = 0.0
+        ind = 0
         # find indices where it crosses y = y_half.
         while True:
@@ -81,9 +81,9 @@
 
         # y value and ind just before passed the spot of the half height
-        y_half_u = y[ind-1]
+        y_half_u = y[ind - 1]
 
         # get corresponding x values
         x_half_d = x[ind]
-        x_half_u = x[ind-1]
+        x_half_u = x[ind - 1]
 
         # calculate x at y = y_half using linear interpolation
@@ -91,7 +91,7 @@
             x_half = (x_half_d + x_half_u)/2.0
         else:
-            x_half = (x_half_u * (y_half - y_half_d)  \
-                       + x_half_d * (y_half_u - y_half)) \
-                        / (y_half_u - y_half_d)
+            x_half = ((x_half_u * (y_half - y_half_d)
+                       + x_half_d * (y_half_u - y_half))
+                       / (y_half_u - y_half_d))
 
         # Our slit length is half width, so just give half beam value
Index: src/sas/sascalc/dataloader/readers/cansas_reader.py
===================================================================
--- src/sas/sascalc/dataloader/readers/cansas_reader.py	(revision c221349bffb81e7d2d9ea29d4fc752f92190c7cc)
+++ src/sas/sascalc/dataloader/readers/cansas_reader.py	(revision 8434365120d0b226f06367f64c21b3bc835e1db5)
@@ -930,5 +930,6 @@
             self._write_data(datainfo, entry_node)
         # Transmission Spectrum Info
-        self._write_trans_spectrum(datainfo, entry_node)
+        # TODO: fix the writer to linearize all data, including T_spectrum
+        # self._write_trans_spectrum(datainfo, entry_node)
         # Sample info
         self._write_sample_info(datainfo, entry_node)
Index: src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py
===================================================================
--- src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py	(revision bbd0f37aa83b3764868742835a730122ba826585)
+++ src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py	(revision c94280cac80b38e0a4f88d651999c89b9bbb966d)
@@ -9,18 +9,20 @@
 import sys
 
-from sas.sascalc.dataloader.data_info import plottable_1D, plottable_2D, Data1D, Data2D, DataInfo, Process, Aperture
-from sas.sascalc.dataloader.data_info import Collimation, TransmissionSpectrum, Detector
+from sas.sascalc.dataloader.data_info import plottable_1D, plottable_2D,\
+    Data1D, Data2D, DataInfo, Process, Aperture, Collimation, \
+    TransmissionSpectrum, Detector
 from sas.sascalc.dataloader.data_info import combine_data_info_with_plottable
-
 
 
 class Reader():
     """
-    A class for reading in CanSAS v2.0 data files. The existing iteration opens Mantid generated HDF5 formatted files
-    with file extension .h5/.H5. Any number of data sets may be present within the file and any dimensionality of data
-    may be used. Currently 1D and 2D SAS data sets are supported, but future implementations will include 1D and 2D
-    SESANS data.
-
-    Any number of SASdata sets may be present in a SASentry and the data within can be either 1D I(Q) or 2D I(Qx, Qy).
+    A class for reading in CanSAS v2.0 data files. The existing iteration opens
+    Mantid generated HDF5 formatted files with file extension .h5/.H5. Any
+    number of data sets may be present within the file and any dimensionality
+    of data may be used. Currently 1D and 2D SAS data sets are supported, but
+    future implementations will include 1D and 2D SESANS data.
+
+    Any number of SASdata sets may be present in a SASentry and the data within
+    can be either 1D I(Q) or 2D I(Qx, Qy).
 
     Also supports reading NXcanSAS formatted HDF5 files
@@ -30,29 +32,29 @@
     """
 
-    ## CanSAS version
+    # CanSAS version
     cansas_version = 2.0
-    ## Logged warnings or messages
+    # Logged warnings or messages
     logging = None
-    ## List of errors for the current data set
+    # List of errors for the current data set
     errors = None
-    ## Raw file contents to be processed
+    # Raw file contents to be processed
     raw_data = None
-    ## Data info currently being read in
+    # Data info currently being read in
     current_datainfo = None
-    ## SASdata set currently being read in
+    # SASdata set currently being read in
     current_dataset = None
-    ## List of plottable1D objects that should be linked to the current_datainfo
+    # List of plottable1D objects that should be linked to the current_datainfo
     data1d = None
-    ## List of plottable2D objects that should be linked to the current_datainfo
+    # List of plottable2D objects that should be linked to the current_datainfo
     data2d = None
-    ## Data type name
+    # Data type name
     type_name = "CanSAS 2.0"
-    ## Wildcards
+    # Wildcards
     type = ["CanSAS 2.0 HDF5 Files (*.h5)|*.h5"]
-    ## List of allowed extensions
+    # List of allowed extensions
     ext = ['.h5', '.H5']
-    ## Flag to bypass extension check
-    allow_all = False
-    ## List of files to return
+    # Flag to bypass extension check
+    allow_all = True
+    # List of files to return
     output = None
 
@@ -64,7 +66,7 @@
         :return: List of Data1D/2D objects and/or a list of errors.
         """
-        ## Reinitialize the class when loading a new data file to reset all class variables
+        # Reinitialize when loading a new data file to reset all class variables
         self.reset_class_variables()
-        ## Check that the file exists
+        # Check that the file exists
         if os.path.isfile(filename):
             basename = os.path.basename(filename)
@@ -72,13 +74,13 @@
             # If the file type is not allowed, return empty list
             if extension in self.ext or self.allow_all:
-                ## Load the data file
+                # Load the data file
                 self.raw_data = h5py.File(filename, 'r')
-                ## Read in all child elements of top level SASroot
+                # Read in all child elements of top level SASroot
                 self.read_children(self.raw_data, [])
-                ## Add the last data set to the list of outputs
+                # Add the last data set to the list of outputs
                 self.add_data_set()
-                ## Close the data file
+                # Close the data file
                 self.raw_data.close()
-        ## Return data set(s)
+        # Return data set(s)
         return self.output
 
@@ -110,7 +112,7 @@
         """
 
-        ## Loop through each element of the parent and process accordingly
+        # Loop through each element of the parent and process accordingly
         for key in data.keys():
-            ## Get all information for the current key
+            # Get all information for the current key
             value = data.get(key)
             if value.attrs.get(u'canSAS_class') is not None:
@@ -126,10 +128,11 @@
                 self.parent_class = class_name
                 parent_list.append(key)
-                ## If this is a new sasentry, store the current data sets and create a fresh Data1D/2D object
+                # If a new sasentry, store the current data sets and create
+                # a fresh Data1D/2D object
                 if class_prog.match(u'SASentry'):
                     self.add_data_set(key)
                 elif class_prog.match(u'SASdata'):
                     self._initialize_new_data_set(parent_list)
-                ## Recursion step to access data within the group
+                # Recursion step to access data within the group
                 self.read_children(value, parent_list)
                 self.add_intermediate()
@@ -137,11 +140,11 @@
 
             elif isinstance(value, h5py.Dataset):
-                ## If this is a dataset, store the data appropriately
+                # If this is a dataset, store the data appropriately
                 data_set = data[key][:]
                 unit = self._get_unit(value)
 
-                ## I and Q Data
+                # I and Q Data
                 if key == u'I':
-                    if type(self.current_dataset) is plottable_2D:
+                    if isinstance(self.current_dataset, plottable_2D):
                         self.current_dataset.data = data_set
                         self.current_dataset.zaxis("Intensity", unit)
@@ -151,5 +154,5 @@
                     continue
                 elif key == u'Idev':
-                    if type(self.current_dataset) is plottable_2D:
+                    if isinstance(self.current_dataset, plottable_2D):
                         self.current_dataset.err_data = data_set.flatten()
                     else:
@@ -158,5 +161,5 @@
                 elif key == u'Q':
                     self.current_dataset.xaxis("Q", unit)
-                    if type(self.current_dataset) is plottable_2D:
+                    if isinstance(self.current_dataset, plottable_2D):
                         self.current_dataset.q = data_set.flatten()
                     else:
@@ -166,4 +169,10 @@
                     self.current_dataset.dx = data_set.flatten()
                     continue
+                elif key == u'dQw':
+                    self.current_dataset.dxw = data_set.flatten()
+                    continue
+                elif key == u'dQl':
+                    self.current_dataset.dxl = data_set.flatten()
+                    continue
                 elif key == u'Qy':
                     self.current_dataset.yaxis("Q_y", unit)
@@ -183,7 +192,21 @@
                     self.current_dataset.mask = data_set.flatten()
                     continue
+                # Transmission Spectrum
+                elif (key == u'T'
+                      and self.parent_class == u'SAStransmission_spectrum'):
+                    self.trans_spectrum.transmission = data_set.flatten()
+                    continue
+                elif (key == u'Tdev'
+                      and self.parent_class == u'SAStransmission_spectrum'):
+                    self.trans_spectrum.transmission_deviation = \
+                        data_set.flatten()
+                    continue
+                elif (key == u'lambda'
+                      and self.parent_class == u'SAStransmission_spectrum'):
+                    self.trans_spectrum.wavelength = data_set.flatten()
+                    continue
 
                 for data_point in data_set:
-                    ## Top Level Meta Data
+                    # Top Level Meta Data
                     if key == u'definition':
                         self.current_datainfo.meta_data['reader'] = data_point
@@ -201,28 +224,42 @@
                         self.current_datainfo.notes.append(data_point)
 
-                    ## Sample Information
-                    elif key == u'Title' and self.parent_class == u'SASsample': # CanSAS 2.0 format
+                    # Sample Information
+                    # CanSAS 2.0 format
+                    elif key == u'Title' and self.parent_class == u'SASsample':
                         self.current_datainfo.sample.name = data_point
-                    elif key == u'ID' and self.parent_class == u'SASsample': # NXcanSAS format
+                    # NXcanSAS format
+                    elif key == u'name' and self.parent_class == u'SASsample':
                         self.current_datainfo.sample.name = data_point
-                    elif key == u'thickness' and self.parent_class == u'SASsample':
+                    # NXcanSAS format
+                    elif key == u'ID' and self.parent_class == u'SASsample':
+                        self.current_datainfo.sample.name = data_point
+                    elif (key == u'thickness'
+                          and self.parent_class == u'SASsample'):
                         self.current_datainfo.sample.thickness = data_point
-                    elif key == u'temperature' and self.parent_class == u'SASsample':
+                    elif (key == u'temperature'
+                          and self.parent_class == u'SASsample'):
                         self.current_datainfo.sample.temperature = data_point
-                    elif key == u'transmission' and self.parent_class == u'SASsample':
+                    elif (key == u'transmission'
+                          and self.parent_class == u'SASsample'):
                         self.current_datainfo.sample.transmission = data_point
-                    elif key == u'x_position' and self.parent_class == u'SASsample':
+                    elif (key == u'x_position'
+                          and self.parent_class == u'SASsample'):
                         self.current_datainfo.sample.position.x = data_point
-                    elif key == u'y_position' and self.parent_class == u'SASsample':
+                    elif (key == u'y_position'
+                          and self.parent_class == u'SASsample'):
                         self.current_datainfo.sample.position.y = data_point
-                    elif key == u'polar_angle' and self.parent_class == u'SASsample':
+                    elif key == u'pitch' and self.parent_class == u'SASsample':
                         self.current_datainfo.sample.orientation.x = data_point
-                    elif key == u'azimuthal_angle' and self.parent_class == u'SASsample':
+                    elif key == u'yaw' and self.parent_class == u'SASsample':
+                        self.current_datainfo.sample.orientation.y = data_point
+                    elif key == u'roll' and self.parent_class == u'SASsample':
                         self.current_datainfo.sample.orientation.z = data_point
-                    elif key == u'details' and self.parent_class == u'SASsample':
+                    elif (key == u'details'
+                          and self.parent_class == u'SASsample'):
                         self.current_datainfo.sample.details.append(data_point)
 
-                    ## Instrumental Information
-                    elif key == u'name' and self.parent_class == u'SASinstrument':
+                    # Instrumental Information
+                    elif (key == u'name'
+                          and self.parent_class == u'SASinstrument'):
                         self.current_datainfo.instrument = data_point
                     elif key == u'name' and self.parent_class == u'SASdetector':
@@ -231,102 +268,134 @@
                         self.detector.distance = float(data_point)
                         self.detector.distance_unit = unit
-                    elif key == u'slit_length' and self.parent_class == u'SASdetector':
+                    elif (key == u'slit_length'
+                          and self.parent_class == u'SASdetector'):
                         self.detector.slit_length = float(data_point)
                         self.detector.slit_length_unit = unit
-                    elif key == u'x_position' and self.parent_class == u'SASdetector':
+                    elif (key == u'x_position'
+                          and self.parent_class == u'SASdetector'):
                         self.detector.offset.x = float(data_point)
                         self.detector.offset_unit = unit
-                    elif key == u'y_position' and self.parent_class == u'SASdetector':
+                    elif (key == u'y_position'
+                          and self.parent_class == u'SASdetector'):
                         self.detector.offset.y = float(data_point)
                         self.detector.offset_unit = unit
-                    elif key == u'polar_angle' and self.parent_class == u'SASdetector':
+                    elif (key == u'pitch'
+                          and self.parent_class == u'SASdetector'):
                         self.detector.orientation.x = float(data_point)
                         self.detector.orientation_unit = unit
-                    elif key == u'azimuthal_angle' and self.parent_class == u'SASdetector':
+                    elif key == u'roll' and self.parent_class == u'SASdetector':
                         self.detector.orientation.z = float(data_point)
                         self.detector.orientation_unit = unit
-                    elif key == u'beam_center_x' and self.parent_class == u'SASdetector':
+                    elif key == u'yaw' and self.parent_class == u'SASdetector':
+                        self.detector.orientation.y = float(data_point)
+                        self.detector.orientation_unit = unit
+                    elif (key == u'beam_center_x'
+                          and self.parent_class == u'SASdetector'):
                         self.detector.beam_center.x = float(data_point)
                         self.detector.beam_center_unit = unit
-                    elif key == u'beam_center_y' and self.parent_class == u'SASdetector':
+                    elif (key == u'beam_center_y'
+                          and self.parent_class == u'SASdetector'):
                         self.detector.beam_center.y = float(data_point)
                         self.detector.beam_center_unit = unit
-                    elif key == u'x_pixel_size' and self.parent_class == u'SASdetector':
+                    elif (key == u'x_pixel_size'
+                          and self.parent_class == u'SASdetector'):
                         self.detector.pixel_size.x = float(data_point)
                         self.detector.pixel_size_unit = unit
-                    elif key == u'y_pixel_size' and self.parent_class == u'SASdetector':
+                    elif (key == u'y_pixel_size'
+                          and self.parent_class == u'SASdetector'):
                         self.detector.pixel_size.y = float(data_point)
                         self.detector.pixel_size_unit = unit
-                    elif key == u'SSD' and self.parent_class == u'SAScollimation':
+                    elif (key == u'distance'
+                          and self.parent_class == u'SAScollimation'):
                         self.collimation.length = data_point
                         self.collimation.length_unit = unit
-                    elif key == u'name' and self.parent_class == u'SAScollimation':
+                    elif (key == u'name'
+                          and self.parent_class == u'SAScollimation'):
                         self.collimation.name = data_point
-
-                    ## Process Information
-                    elif key == u'name' and self.parent_class == u'SASprocess':
+                    elif (key == u'shape'
+                          and self.parent_class == u'SASaperture'):
+                        self.aperture.shape = data_point
+                    elif (key == u'x_gap'
+                          and self.parent_class == u'SASaperture'):
+                        self.aperture.size.x = data_point
+                    elif (key == u'y_gap'
+                          and self.parent_class == u'SASaperture'):
+                        self.aperture.size.y = data_point
+
+                    # Process Information
+                    elif (key == u'Title'
+                          and self.parent_class == u'SASprocess'): # CanSAS 2.0
                         self.process.name = data_point
-                    elif key == u'Title' and self.parent_class == u'SASprocess': # CanSAS 2.0 format
+                    elif (key == u'name'
+                          and self.parent_class == u'SASprocess'): # NXcanSAS
                         self.process.name = data_point
-                    elif key == u'name' and self.parent_class == u'SASprocess': # NXcanSAS format
-                        self.process.name = data_point
-                    elif key == u'description' and self.parent_class == u'SASprocess':
+                    elif (key == u'description'
+                          and self.parent_class == u'SASprocess'):
                         self.process.description = data_point
                     elif key == u'date' and self.parent_class == u'SASprocess':
                         self.process.date = data_point
+                    elif key == u'term' and self.parent_class == u'SASprocess':
+                        self.process.term = data_point
                     elif self.parent_class == u'SASprocess':
                         self.process.notes.append(data_point)
 
-                    ## Transmission Spectrum
-                    elif key == u'T' and self.parent_class == u'SAStransmission_spectrum':
-                        self.trans_spectrum.transmission.append(data_point)
-                    elif key == u'Tdev' and self.parent_class == u'SAStransmission_spectrum':
-                        self.trans_spectrum.transmission_deviation.append(data_point)
-                    elif key == u'lambda' and self.parent_class == u'SAStransmission_spectrum':
-                        self.trans_spectrum.wavelength.append(data_point)
-
-                    ## Source
-                    elif key == u'wavelength' and self.parent_class == u'SASdata':
+                    # Source
+                    elif (key == u'wavelength'
+                          and self.parent_class == u'SASdata'):
                         self.current_datainfo.source.wavelength = data_point
                         self.current_datainfo.source.wavelength_unit = unit
-                    elif key == u'incident_wavelength' and self.parent_class == u'SASsource':
+                    elif (key == u'incident_wavelength'
+                          and self.parent_class == 'SASsource'):
                         self.current_datainfo.source.wavelength = data_point
                         self.current_datainfo.source.wavelength_unit = unit
-                    elif key == u'wavelength_max' and self.parent_class == u'SASsource':
+                    elif (key == u'wavelength_max'
+                          and self.parent_class == u'SASsource'):
                         self.current_datainfo.source.wavelength_max = data_point
                         self.current_datainfo.source.wavelength_max_unit = unit
-                    elif key == u'wavelength_min' and self.parent_class == u'SASsource':
+                    elif (key == u'wavelength_min'
+                          and self.parent_class == u'SASsource'):
                         self.current_datainfo.source.wavelength_min = data_point
                         self.current_datainfo.source.wavelength_min_unit = unit
-                    elif key == u'wavelength_spread' and self.parent_class == u'SASsource':
-                        self.current_datainfo.source.wavelength_spread = data_point
-                        self.current_datainfo.source.wavelength_spread_unit = unit
-                    elif key == u'beam_size_x' and self.parent_class == u'SASsource':
+                    elif (key == u'incident_wavelength_spread'
+                          and self.parent_class == u'SASsource'):
+                        self.current_datainfo.source.wavelength_spread = \
+                            data_point
+                        self.current_datainfo.source.wavelength_spread_unit = \
+                            unit
+                    elif (key == u'beam_size_x'
+                          and self.parent_class == u'SASsource'):
                         self.current_datainfo.source.beam_size.x = data_point
                         self.current_datainfo.source.beam_size_unit = unit
-                    elif key == u'beam_size_y' and self.parent_class == u'SASsource':
+                    elif (key == u'beam_size_y'
+                          and self.parent_class == u'SASsource'):
                         self.current_datainfo.source.beam_size.y = data_point
                         self.current_datainfo.source.beam_size_unit = unit
-                    elif key == u'beam_shape' and self.parent_class == u'SASsource':
+                    elif (key == u'beam_shape'
+                          and self.parent_class == u'SASsource'):
                         self.current_datainfo.source.beam_shape = data_point
-                    elif key == u'radiation' and self.parent_class == u'SASsource':
+                    elif (key == u'radiation'
+                          and self.parent_class == u'SASsource'):
                         self.current_datainfo.source.radiation = data_point
-                    elif key == u'transmission' and self.parent_class == u'SASdata':
+                    elif (key == u'transmission'
+                          and self.parent_class == u'SASdata'):
                         self.current_datainfo.sample.transmission = data_point
 
-                    ## Everything else goes in meta_data
+                    # Everything else goes in meta_data
                     else:
-                        new_key = self._create_unique_key(self.current_datainfo.meta_data, key)
+                        new_key = self._create_unique_key(
+                            self.current_datainfo.meta_data, key)
                         self.current_datainfo.meta_data[new_key] = data_point
 
             else:
-                ## I don't know if this reachable code
+                # I don't know if this reachable code
                 self.errors.add("ShouldNeverHappenException")
 
     def add_intermediate(self):
         """
-        This method stores any intermediate objects within the final data set after fully reading the set.
-
-        :param parent: The NXclass name for the h5py Group object that just finished being processed
+        This method stores any intermediate objects within the final data set
+        after fully reading the set.
+
+        :param parent: The NXclass name for the h5py Group object that just
+                       finished being processed
         """
 
@@ -347,16 +416,17 @@
             self.aperture = Aperture()
         elif self.parent_class == u'SASdata':
-            if type(self.current_dataset) is plottable_2D:
+            if isinstance(self.current_dataset, plottable_2D):
                 self.data2d.append(self.current_dataset)
-            elif type(self.current_dataset) is plottable_1D:
+            elif isinstance(self.current_dataset, plottable_1D):
                 self.data1d.append(self.current_dataset)
 
     def final_data_cleanup(self):
         """
-        Does some final cleanup and formatting on self.current_datainfo and all data1D and data2D objects and then
-        combines the data and info into Data1D and Data2D objects
-        """
-
-        ## Type cast data arrays to float64
+        Does some final cleanup and formatting on self.current_datainfo and
+        all data1D and data2D objects and then combines the data and info into
+        Data1D and Data2D objects
+        """
+
+        # Type cast data arrays to float64
         if len(self.current_datainfo.trans_spectrum) > 0:
             spectrum_list = []
@@ -364,6 +434,8 @@
                 spectrum.transmission = np.delete(spectrum.transmission, [0])
                 spectrum.transmission = spectrum.transmission.astype(np.float64)
-                spectrum.transmission_deviation = np.delete(spectrum.transmission_deviation, [0])
-                spectrum.transmission_deviation = spectrum.transmission_deviation.astype(np.float64)
+                spectrum.transmission_deviation = np.delete(
+                    spectrum.transmission_deviation, [0])
+                spectrum.transmission_deviation = \
+                    spectrum.transmission_deviation.astype(np.float64)
                 spectrum.wavelength = np.delete(spectrum.wavelength, [0])
                 spectrum.wavelength = spectrum.wavelength.astype(np.float64)
@@ -372,10 +444,10 @@
             self.current_datainfo.trans_spectrum = spectrum_list
 
-        ## Append errors to dataset and reset class errors
+        # Append errors to dataset and reset class errors
         self.current_datainfo.errors = self.errors
         self.errors.clear()
 
-        ## Combine all plottables with datainfo and append each to output
-        ## Type cast data arrays to float64 and find min/max as appropriate
+        # Combine all plottables with datainfo and append each to output
+        # Type cast data arrays to float64 and find min/max as appropriate
         for dataset in self.data2d:
             dataset.data = dataset.data.astype(np.float64)
@@ -397,13 +469,16 @@
             zeros = np.ones(dataset.data.size, dtype=bool)
             try:
-                for i in range (0, dataset.mask.size - 1):
+                for i in range(0, dataset.mask.size - 1):
                     zeros[i] = dataset.mask[i]
             except:
                 self.errors.add(sys.exc_value)
             dataset.mask = zeros
-            ## Calculate the actual Q matrix
+            # Calculate the actual Q matrix
             try:
                 if dataset.q_data.size <= 1:
-                    dataset.q_data = np.sqrt(dataset.qx_data * dataset.qx_data + dataset.qy_data * dataset.qy_data)
+                    dataset.q_data = np.sqrt(dataset.qx_data
+                                             * dataset.qx_data
+                                             + dataset.qy_data
+                                             * dataset.qy_data)
             except:
                 dataset.q_data = None
@@ -415,5 +490,6 @@
                 dataset.data = dataset.data.flatten()
 
-            final_dataset = combine_data_info_with_plottable(dataset, self.current_datainfo)
+            final_dataset = combine_data_info_with_plottable(
+                dataset, self.current_datainfo)
             self.output.append(final_dataset)
 
@@ -435,11 +511,13 @@
             if dataset.dy is not None:
                 dataset.dy = dataset.dy.astype(np.float64)
-            final_dataset = combine_data_info_with_plottable(dataset, self.current_datainfo)
+            final_dataset = combine_data_info_with_plottable(
+                dataset, self.current_datainfo)
             self.output.append(final_dataset)
 
     def add_data_set(self, key=""):
         """
-        Adds the current_dataset to the list of outputs after preforming final processing on the data and then calls a
-        private method to generate a new data set.
+        Adds the current_dataset to the list of outputs after preforming final
+        processing on the data and then calls a private method to generate a
+        new data set.
 
         :param key: NeXus group name for current tree level
@@ -453,8 +531,9 @@
 
 
-    def _initialize_new_data_set(self, parent_list = None):
-        """
-        A private class method to generate a new 1D or 2D data object based on the type of data within the set.
-        Outside methods should call add_data_set() to be sure any existing data is stored properly.
+    def _initialize_new_data_set(self, parent_list=None):
+        """
+        A private class method to generate a new 1D or 2D data object based on
+        the type of data within the set. Outside methods should call
+        add_data_set() to be sure any existing data is stored properly.
 
         :param parent_list: List of names of parent elements
@@ -473,7 +552,8 @@
     def _find_intermediate(self, parent_list, basename=""):
         """
-        A private class used to find an entry by either using a direct key or knowing the approximate basename.
-
-        :param parent_list: List of parents to the current level in the HDF5 file
+        A private class used to find an entry by either using a direct key or
+        knowing the approximate basename.
+
+        :param parent_list: List of parents nodes in the HDF5 file
         :param basename: Approximate name of an entry to search for
         :return:
@@ -486,5 +566,5 @@
             top = top.get(parent)
         for key in top.keys():
-            if (key_prog.match(key)):
+            if key_prog.match(key):
                 entry = True
                 break
@@ -516,7 +596,7 @@
         """
         unit = value.attrs.get(u'units')
-        if unit == None:
+        if unit is None:
             unit = value.attrs.get(u'unit')
-        ## Convert the unit formats
+        # Convert the unit formats
         if unit == "1/A":
             unit = "A^{-1}"
Index: src/sas/sascalc/fit/BumpsFitting.py
===================================================================
--- src/sas/sascalc/fit/BumpsFitting.py	(revision 345e7e4a8c6f5977c8c07032553b5ab00bdf837d)
+++ src/sas/sascalc/fit/BumpsFitting.py	(revision 1a3072063148c066e9a1b64becf8ca13927ad656)
@@ -352,5 +352,5 @@
     except Exception as exc:
         best, fbest = None, numpy.NaN
-        errors = [str(exc), traceback.traceback.format_exc()]
+        errors = [str(exc), traceback.format_exc()]
     finally:
         mapper.stop_mapper(fitdriver.mapper)
Index: src/sas/sasgui/guiframe/acknowledgebox.py
===================================================================
--- src/sas/sasgui/guiframe/acknowledgebox.py	(revision c1fdf8485e681ba1145937521615515e6c3be688)
+++ src/sas/sasgui/guiframe/acknowledgebox.py	(revision 74c8cd08df1c5d3f23477827c0f272e88bbbea9d)
@@ -11,4 +11,5 @@
 import wx.richtext
 import wx.lib.hyperlink
+from wx.lib.expando import ExpandoTextCtrl
 import random
 import os.path
@@ -36,5 +37,4 @@
     Shows the current method for acknowledging SasView in
     scholarly publications.
-
     """
 
@@ -44,7 +44,9 @@
         wx.Dialog.__init__(self, *args, **kwds)
 
-        self.ack = wx.TextCtrl(self, style=wx.TE_LEFT|wx.TE_MULTILINE|wx.TE_BESTWRAP|wx.TE_READONLY|wx.TE_NO_VSCROLL)
+        self.ack = ExpandoTextCtrl(self, style=wx.TE_LEFT|wx.TE_MULTILINE|wx.TE_BESTWRAP|wx.TE_READONLY|wx.TE_NO_VSCROLL)
         self.ack.SetValue(config._acknowledgement_publications)
-        self.ack.SetMinSize((-1, 55))
+        #self.ack.SetMinSize((-1, 55))
+        self.citation = ExpandoTextCtrl(self, style=wx.TE_LEFT|wx.TE_MULTILINE|wx.TE_BESTWRAP|wx.TE_READONLY|wx.TE_NO_VSCROLL)
+        self.citation.SetValue(config._acknowledgement_citation)
         self.preamble = wx.StaticText(self, -1, config._acknowledgement_preamble)
         items = [config._acknowledgement_preamble_bullet1,
@@ -52,8 +54,8 @@
                  config._acknowledgement_preamble_bullet3,
                  config._acknowledgement_preamble_bullet4]
-        self.list1 = wx.StaticText(self, -1, "\t(1) " + items[0])
-        self.list2 = wx.StaticText(self, -1, "\t(2) " + items[1])
-        self.list3 = wx.StaticText(self, -1, "\t(3) " + items[2])
-        self.list4 = wx.StaticText(self, -1, "\t(4) " + items[3])
+        self.list1 = wx.StaticText(self, -1, "(1) " + items[0])
+        self.list2 = wx.StaticText(self, -1, "(2) " + items[1])
+        self.list3 = wx.StaticText(self, -1, "(3) " + items[2])
+        self.list4 = wx.StaticText(self, -1, "(4) " + items[3])
         self.static_line = wx.StaticLine(self, 0)
         self.__set_properties()
@@ -69,5 +71,5 @@
         self.SetTitle("Acknowledging SasView")
         #Increased size of box from (525, 225), SMK, 04/10/16
-        self.SetSize((600, 300))
+        self.SetClientSize((600, 320))
         # end wxGlade
 
@@ -81,9 +83,10 @@
         sizer_titles.Add(self.preamble, 0, wx.ALL|wx.EXPAND, 5)
         sizer_titles.Add(self.list1, 0, wx.ALL|wx.EXPAND, 5)
+        sizer_titles.Add(self.ack, 0, wx.ALL|wx.EXPAND, 5)
         sizer_titles.Add(self.list2, 0, wx.ALL|wx.EXPAND, 5)
+        sizer_titles.Add(self.citation, 0, wx.ALL|wx.EXPAND, 5)
         sizer_titles.Add(self.list3, 0, wx.ALL|wx.EXPAND, 5)
+        #sizer_titles.Add(self.static_line, 0, wx.ALL|wx.EXPAND, 0)
         sizer_titles.Add(self.list4, 0, wx.ALL|wx.EXPAND, 5)
-        sizer_titles.Add(self.static_line, 0, wx.ALL|wx.EXPAND, 0)
-        sizer_titles.Add(self.ack, 0, wx.ALL|wx.EXPAND, 5)
         sizer_main.Add(sizer_titles, -1, wx.ALL|wx.EXPAND, 5)
         self.SetAutoLayout(True)
@@ -91,4 +94,5 @@
         self.Layout()
         self.Centre()
+        #self.SetClientSize(sizer_main.GetSize())
         # end wxGlade
 
Index: src/sas/sasgui/guiframe/config.py
===================================================================
--- src/sas/sasgui/guiframe/config.py	(revision d85c194ea2f78cb2b9b3de9c969e1b8ebea6b6d2)
+++ src/sas/sasgui/guiframe/config.py	(revision f9d1f609ce36aae44396ad86ba1db9146a4234b3)
@@ -1,18 +1,20 @@
 """
-Application settings
+    Application settings
 """
+import time
 import os
-import time
 from sas.sasgui.guiframe.gui_style import GUIFRAME
+import sas.sasview
+import logging
+
 # Version of the application
-__appname__ = "DummyView"
-__version__ = '0.0.0'
-__build__ = '1'
+__appname__ = "SasView"
+__version__ = sas.sasview.__version__
+__build__ = sas.sasview.__build__
 __download_page__ = 'https://github.com/SasView/sasview/releases'
 __update_URL__ = 'http://www.sasview.org/latestversion.json'
 
-
 # Debug message flag
-__EVT_DEBUG__ = True
+__EVT_DEBUG__ = False
 
 # Flag for automated testing
@@ -29,9 +31,9 @@
 _acknowledgement_preamble =\
 '''To ensure the long term support and development of this software please''' +\
-''' remember to do the following.'''
+''' remember to:'''
 _acknowledgement_preamble_bullet1 =\
-'''Acknowledge its use in your publications as suggested below'''
+'''Acknowledge its use in your publications as :'''
 _acknowledgement_preamble_bullet2 =\
-'''Reference the following website: http://www.sasview.org'''
+'''Reference SasView as:'''
 _acknowledgement_preamble_bullet3 =\
 '''Reference the model you used if appropriate (see documentation for refs)'''
@@ -39,70 +41,89 @@
 '''Send us your reference for our records: developers@sasview.org'''
 _acknowledgement_publications = \
-'''This work benefited from the use of the SasView application, originally
-developed under NSF award DMR-0520547.
+'''This work benefited from the use of the SasView application, originally developed under NSF Award DMR-0520547. SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project Grant No 654000.'''
+_acknowledgement_citation = \
+'''M. Doucet et al. SasView Version 4.1, Zenodo, 10.5281/zenodo.438138'''
+
+_acknowledgement =  \
+'''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547,\n but is currently maintained by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO and TU Delft and the scattering community.\n\n SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project (Grant No 654000).\nA list of individual contributors can be found at: https://github.com/orgs/SasView/people
 '''
-_acknowledgement =  \
-'''This work originally developed as part of the DANSE project funded by the NSF
-under grant DMR-0520547, and currently maintained by NIST, UMD, ORNL, ISIS, ESS
-and ILL.
 
-'''
 _homepage = "http://www.sasview.org"
-_download = "http://sourceforge.net/projects/sasview/files/"
+_download = __download_page__
 _authors = []
 _paper = "http://sourceforge.net/p/sasview/tickets/"
 _license = "mailto:help@sasview.org"
-_nsf_logo = "images/nsf_logo.png"
-_danse_logo = "images/danse_logo.png"
-_inst_logo = "images/utlogo.gif"
-_nist_logo = "images/nist_logo.png"
-_umd_logo = "images/umd_logo.png"
-_sns_logo = "images/sns_logo.png"
-_isis_logo = "images/isis_logo.png"
-_ess_logo = "images/ess_logo.png"
-_ill_logo = "images/ill_logo.png"
+
+
+icon_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "images"))
+logging.info("icon path: %s" % icon_path)
+media_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "media"))
+test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "test"))
+
+_nist_logo = os.path.join(icon_path, "nist_logo.png")
+_umd_logo = os.path.join(icon_path, "umd_logo.png")
+_sns_logo = os.path.join(icon_path, "sns_logo.png")
+_ornl_logo = os.path.join(icon_path, "ornl_logo.png")
+_isis_logo = os.path.join(icon_path, "isis_logo.png")
+_ess_logo = os.path.join(icon_path, "ess_logo.png")
+_ill_logo = os.path.join(icon_path, "ill_logo.png")
+_ansto_logo = os.path.join(icon_path, "ansto_logo.png")
+_tudelft_logo = os.path.join(icon_path, "tudelft_logo.png")
+_nsf_logo = os.path.join(icon_path, "nsf_logo.png")
+_danse_logo = os.path.join(icon_path, "danse_logo.png")
+_inst_logo = os.path.join(icon_path, "utlogo.gif")
 _nist_url = "http://www.nist.gov/"
 _umd_url = "http://www.umd.edu/"
 _sns_url = "http://neutrons.ornl.gov/"
+_ornl_url = "http://neutrons.ornl.gov/"
 _nsf_url = "http://www.nsf.gov"
-_danse_url = "http://www.cacr.caltech.edu/projects/danse/release/index.html"
-_inst_url = "http://www.utk.edu"
 _isis_url = "http://www.isis.stfc.ac.uk/"
 _ess_url = "http://ess-scandinavia.eu/"
 _ill_url = "http://www.ill.eu/"
-_corner_image = "images/angles_flat.png"
-_welcome_image = "images/SVwelcome.png"
-_copyright = "(c) 2008, University of Tennessee"
-#edit the lists below of file state your plugin can read
-#for sasview this how you can edit these lists
-#PLUGIN_STATE_EXTENSIONS = ['.prv','.fitv', '.inv']
-#APPLICATION_STATE_EXTENSION = '.svs'
-#PLUGINS_WLIST = ['P(r) files (*.prv)|*.prv',
-#                  'Fitting files (*.fitv)|*.fitv',
-#                  'Invariant files (*.inv)|*.inv']
-#APPLICATION_WLIST = 'SasView files (*.svs)|*.svs'
-APPLICATION_WLIST = ''
-APPLICATION_STATE_EXTENSION = None
-PLUGINS_WLIST = []
-PLUGIN_STATE_EXTENSIONS = []
-SPLASH_SCREEN_PATH = "images/danse_logo.png"
-DEFAULT_STYLE = GUIFRAME.SINGLE_APPLICATION
-SPLASH_SCREEN_WIDTH = 500
-SPLASH_SCREEN_HEIGHT = 300
-WELCOME_PANEL_ON = False
-TUTORIAL_PATH = None
-SS_MAX_DISPLAY_TIME = 1500
-PLOPANEL_WIDTH = 350
-PLOPANEL_HEIGTH = 350
-GUIFRAME_WIDTH = 1000
-GUIFRAME_HEIGHT = 800
-CONTROL_WIDTH = -1
-CONTROL_HEIGHT = -1
-SetupIconFile_win = os.path.join("images", "ball.ico")
-SetupIconFile_mac = os.path.join("images", "ball.icns")
-DefaultGroupName = "DANSE"
-OutputBaseFilename = "setupGuiFrame"
+_ansto_url = "http://www.ansto.gov.au/"
+_tudelft_url = "http://www.tnw.tudelft.nl/en/cooperation/facilities/reactor-instituut-delft/"
+_danse_url = "http://www.cacr.caltech.edu/projects/danse/release/index.html"
+_inst_url = "http://www.utk.edu"
+_corner_image = os.path.join(icon_path, "angles_flat.png")
+_welcome_image = os.path.join(icon_path, "SVwelcome.png")
+_copyright = "(c) 2009 - 2017, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO and TU Delft"
+marketplace_url = "http://marketplace.sasview.org/"
+
+#edit the list of file state your plugin can read
+APPLICATION_WLIST = 'SasView files (*.svs)|*.svs'
+APPLICATION_STATE_EXTENSION = '.svs'
+GUIFRAME_WIDTH = 1150
+GUIFRAME_HEIGHT = 840
+PLUGIN_STATE_EXTENSIONS = ['.fitv', '.inv', '.prv', '.crf']
+PLUGINS_WLIST = ['Fitting files (*.fitv)|*.fitv',
+                 'Invariant files (*.inv)|*.inv',
+                 'P(r) files (*.prv)|*.prv',
+                 'Corfunc files (*.crf)|*.crf']
+PLOPANEL_WIDTH = 415
+PLOPANEL_HEIGTH = 370
 DATAPANEL_WIDTH = 235
 DATAPANEL_HEIGHT = 700
+SPLASH_SCREEN_PATH = os.path.join(icon_path, "SVwelcome_mini.png")
+TUTORIAL_PATH = os.path.join(media_path, "Tutorial.pdf")
+DEFAULT_STYLE = GUIFRAME.MULTIPLE_APPLICATIONS|GUIFRAME.MANAGER_ON\
+                    |GUIFRAME.CALCULATOR_ON|GUIFRAME.TOOLBAR_ON
+SPLASH_SCREEN_WIDTH = 512
+SPLASH_SCREEN_HEIGHT = 366
+SS_MAX_DISPLAY_TIME = 2000
+WELCOME_PANEL_ON = True
+WELCOME_PANEL_SHOW = False
+CLEANUP_PLOT = False
+# OPEN and SAVE project menu
+OPEN_SAVE_PROJECT_MENU = True
+#VIEW MENU
+VIEW_MENU = True
+#EDIT MENU
+EDIT_MENU = True
+
+SetupIconFile_win = os.path.join(icon_path, "ball.ico")
+SetupIconFile_mac = os.path.join(icon_path, "ball.icns")
+DefaultGroupName = "."
+OutputBaseFilename = "setupSasView"
+
 FIXED_PANEL = True
 DATALOADER_SHOW = True
@@ -113,26 +134,20 @@
 # set a default perspective
 DEFAULT_PERSPECTIVE = 'None'
-# OPEN and SAVE project menu
-OPEN_SAVE_PROJECT_MENU = True
-CLEANUP_PLOT = False
-# OPEN and SAVE project menu
-OPEN_SAVE_PROJECT_MENU = False
-#VIEW MENU
-VIEW_MENU = False
-#EDIT MENU
-EDIT_MENU = False
-import wx.lib.newevent
-(StatusBarEvent, EVT_STATUS) = wx.lib.newevent.NewEvent()
+
+# Time out for updating sasview
+UPDATE_TIMEOUT = 2
+
+#OpenCL option
+SAS_OPENCL = None
 
 def printEVT(message):
-    """
-    :TODO - need method documentation
-    """
     if __EVT_DEBUG__:
+        """
+        :TODO - Need method doc string
+        """
         print "%g:  %s" % (time.clock(), message)
-    
+
         if __EVT_DEBUG_2_FILE__:
             out = open(__EVT_DEBUG_FILENAME__, 'a')
             out.write("%10g:  %s\n" % (time.clock(), message))
             out.close()
-            
Index: src/sas/sasgui/perspectives/fitting/basepage.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/basepage.py	(revision 7a5aedda76976d4f6d7b04abfca1d59d2455dd6d)
+++ src/sas/sasgui/perspectives/fitting/basepage.py	(revision b301db9771a6b47f4e6cab8b5e980f14f16dc65a)
@@ -120,6 +120,5 @@
         self.dxw = None
         # pinhole smear
-        self.dx_min = None
-        self.dx_max = None
+        self.dx_percent = None
         # smear attrbs
         self.enable_smearer = None
@@ -849,6 +848,5 @@
         self.state.pinhole_smearer = \
                                 copy.deepcopy(self.pinhole_smearer.GetValue())
-        self.state.dx_max = copy.deepcopy(self.dx_max)
-        self.state.dx_min = copy.deepcopy(self.dx_min)
+        self.state.dx_percent = copy.deepcopy(self.dx_percent)
         self.state.dxl = copy.deepcopy(self.dxl)
         self.state.dxw = copy.deepcopy(self.dxw)
@@ -1247,10 +1245,9 @@
         # we have two more options for smearing
         if self.pinhole_smearer.GetValue():
-            self.dx_min = state.dx_min
-            self.dx_max = state.dx_max
-            if self.dx_min is not None:
-                self.smear_pinhole_min.SetValue(str(self.dx_min))
-            if self.dx_max is not None:
-                self.smear_pinhole_max.SetValue(str(self.dx_max))
+            self.dx_percent = state.dx_percent
+            if self.dx_percent is not None:
+                if state.dx_old:
+                    self.dx_percent = 100 * (self.dx_percent / self.data.x[0])
+                self.smear_pinhole_percent.SetValue("%.2f" % self.dx_percent)
             self.onPinholeSmear(event=None)
         elif self.slit_smearer.GetValue():
Index: src/sas/sasgui/perspectives/fitting/fitpage.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/fitpage.py	(revision 2d568f649389db3d59ceb4e0e7c433010da67d64)
+++ src/sas/sasgui/perspectives/fitting/fitpage.py	(revision d85f1d8ad367b855a9bd1434682c464411b1b00e)
@@ -29,5 +29,4 @@
 _BOX_WIDTH = 76
 _DATA_BOX_WIDTH = 300
-SMEAR_SIZE_L = 0.00
 SMEAR_SIZE_H = 0.00
 CUSTOM_MODEL = 'Plugin Models'
@@ -210,9 +209,8 @@
               "Please enter only the value of interest to customize smearing..."
         smear_message_new_psmear = \
-              "Please enter both; the dQ will be generated by interpolation..."
+              "Please enter a fixed percentage to be applied to all Q values..."
         smear_message_2d_x_title = "<dQp>[1/A]:"
         smear_message_2d_y_title = "<dQs>[1/A]:"
-        smear_message_pinhole_min_title = "dQ_low[1/A]:"
-        smear_message_pinhole_max_title = "dQ_high[1/A]:"
+        smear_message_pinhole_percent_title = "dQ[%]:"
         smear_message_slit_height_title = "Slit height[1/A]:"
         smear_message_slit_width_title = "Slit width[1/A]:"
@@ -307,12 +305,9 @@
         
         # textcntrl for custom resolution
-        self.smear_pinhole_max = ModelTextCtrl(self, wx.ID_ANY,
-                            size=(_BOX_WIDTH - 25, 20),
-                            style=wx.TE_PROCESS_ENTER,
-                            text_enter_callback=self.onPinholeSmear)
-        self.smear_pinhole_min = ModelTextCtrl(self, wx.ID_ANY,
-                            size=(_BOX_WIDTH - 25, 20),
-                            style=wx.TE_PROCESS_ENTER,
-                            text_enter_callback=self.onPinholeSmear)
+        self.smear_pinhole_percent = ModelTextCtrl(self, wx.ID_ANY,
+                                                   size=(_BOX_WIDTH - 25, 20),
+                                                   style=wx.TE_PROCESS_ENTER,
+                                                   text_enter_callback=
+                                                   self.onPinholeSmear)
         self.smear_slit_height = ModelTextCtrl(self, wx.ID_ANY,
                             size=(_BOX_WIDTH - 25, 20),
@@ -333,6 +328,5 @@
 
         # set default values for smear
-        self.smear_pinhole_max.SetValue(str(self.dx_max))
-        self.smear_pinhole_min.SetValue(str(self.dx_min))
+        self.smear_pinhole_percent.SetValue(str(self.dx_percent))
         self.smear_slit_height.SetValue(str(self.dxl))
         self.smear_slit_width.SetValue(str(self.dxw))
@@ -426,8 +420,7 @@
         self.smear_description_2d_y.SetToolTipString(
                                     " dQs(perpendicular) in q_phi direction.")
-        self.smear_description_pin_min = wx.StaticText(self, wx.ID_ANY,
-                        smear_message_pinhole_min_title, style=wx.ALIGN_LEFT)
-        self.smear_description_pin_max = wx.StaticText(self, wx.ID_ANY,
-                        smear_message_pinhole_max_title, style=wx.ALIGN_LEFT)
+        self.smear_description_pin_percent = wx.StaticText(self, wx.ID_ANY,
+                                            smear_message_pinhole_percent_title,
+                                            style=wx.ALIGN_LEFT)
         self.smear_description_slit_height = wx.StaticText(self, wx.ID_ANY,
                         smear_message_slit_height_title, style=wx.ALIGN_LEFT)
@@ -453,10 +446,7 @@
         self.sizer_new_smear.Add((15, -1))
         self.sizer_new_smear.Add(self.smear_description_2d_x, 0, wx.CENTER, 10)
-        self.sizer_new_smear.Add(self.smear_description_pin_min,
-                                 0, wx.CENTER, 10)
         self.sizer_new_smear.Add(self.smear_description_slit_height,
                                  0, wx.CENTER, 10)
 
-        self.sizer_new_smear.Add(self.smear_pinhole_min, 0, wx.CENTER, 10)
         self.sizer_new_smear.Add(self.smear_slit_height, 0, wx.CENTER, 10)
         self.sizer_new_smear.Add(self.smear_data_left, 0, wx.CENTER, 10)
@@ -464,10 +454,10 @@
         self.sizer_new_smear.Add(self.smear_description_2d_y,
                                  0, wx.CENTER, 10)
-        self.sizer_new_smear.Add(self.smear_description_pin_max,
+        self.sizer_new_smear.Add(self.smear_description_pin_percent,
                                  0, wx.CENTER, 10)
         self.sizer_new_smear.Add(self.smear_description_slit_width,
                                  0, wx.CENTER, 10)
 
-        self.sizer_new_smear.Add(self.smear_pinhole_max, 0, wx.CENTER, 10)
+        self.sizer_new_smear.Add(self.smear_pinhole_percent, 0, wx.CENTER, 10)
         self.sizer_new_smear.Add(self.smear_slit_width, 0, wx.CENTER, 10)
         self.sizer_new_smear.Add(self.smear_data_right, 0, wx.CENTER, 10)
@@ -1581,8 +1571,6 @@
         if self.dxw is None:
             self.dxw = ""
-        if self.dx_min is None:
-            self.dx_min = SMEAR_SIZE_L
-        if self.dx_max is None:
-            self.dx_max = SMEAR_SIZE_H
+        if self.dx_percent is None:
+            self.dx_percent = SMEAR_SIZE_H
 
     def _get_smear_info(self):
@@ -1646,6 +1634,5 @@
             self.smear_description_2d_y.Show(True)
             if self.pinhole_smearer.GetValue():
-                self.smear_pinhole_min.Show(True)
-                self.smear_pinhole_max.Show(True)
+                self.smear_pinhole_percent.Show(True)
         # smear from data
         elif self.enable_smearer.GetValue():
@@ -1658,6 +1645,5 @@
                     self.smear_description_slit_width.Show(True)
                 elif self.smear_type == 'Pinhole':
-                    self.smear_description_pin_min.Show(True)
-                    self.smear_description_pin_max.Show(True)
+                    self.smear_description_pin_percent.Show(True)
                 self.smear_description_smear_type.Show(True)
                 self.smear_description_type.Show(True)
@@ -1668,9 +1654,7 @@
             if self.smear_type == 'Pinhole':
                 self.smear_message_new_p.Show(True)
-                self.smear_description_pin_min.Show(True)
-                self.smear_description_pin_max.Show(True)
-
-            self.smear_pinhole_min.Show(True)
-            self.smear_pinhole_max.Show(True)
+                self.smear_description_pin_percent.Show(True)
+
+            self.smear_pinhole_percent.Show(True)
         # custom slit smear
         elif self.slit_smearer.GetValue():
@@ -1697,8 +1681,6 @@
         self.smear_data_left.Hide()
         self.smear_data_right.Hide()
-        self.smear_description_pin_min.Hide()
-        self.smear_pinhole_min.Hide()
-        self.smear_description_pin_max.Hide()
-        self.smear_pinhole_max.Hide()
+        self.smear_description_pin_percent.Hide()
+        self.smear_pinhole_percent.Hide()
         self.smear_description_slit_height.Hide()
         self.smear_slit_height.Hide()
@@ -2249,6 +2231,5 @@
             # event case of radio button
             if tcrtl.GetValue():
-                self.dx_min = 0.0
-                self.dx_max = 0.0
+                self.dx_percent = 0.0
                 is_new_pinhole = True
             else:
@@ -2287,21 +2268,12 @@
         """
         # get the values
-        pin_min = self.smear_pinhole_min.GetValue()
-        pin_max = self.smear_pinhole_max.GetValue()
-
-        # Check changes in slit width
+        pin_percent = self.smear_pinhole_percent.GetValue()
+
+        # Check changes in slit heigth
         try:
-            dx_min = float(pin_min)
+            dx_percent = float(pin_percent)
         except:
             return True
-        if self.dx_min != dx_min:
-            return True
-
-        # Check changes in slit heigth
-        try:
-            dx_max = float(pin_max)
-        except:
-            return True
-        if self.dx_max != dx_max:
+        if self.dx_percent != dx_percent:
             return True
         return False
@@ -2329,45 +2301,23 @@
         msg = None
 
-        get_pin_min = self.smear_pinhole_min
-        get_pin_max = self.smear_pinhole_max
-
-        if not check_float(get_pin_min):
-            get_pin_min.SetBackgroundColour("pink")
-            msg = "Model Error:wrong value entered!!!"
-        elif not check_float(get_pin_max):
-            get_pin_max.SetBackgroundColour("pink")
+        get_pin_percent = self.smear_pinhole_percent
+
+        if not check_float(get_pin_percent):
+            get_pin_percent.SetBackgroundColour("pink")
             msg = "Model Error:wrong value entered!!!"
         else:
             if len_data < 2:
                 len_data = 2
-            self.dx_min = float(get_pin_min.GetValue())
-            self.dx_max = float(get_pin_max.GetValue())
-            if self.dx_min < 0:
-                get_pin_min.SetBackgroundColour("pink")
+            self.dx_percent = float(get_pin_percent.GetValue())
+            if self.dx_percent < 0:
+                get_pin_percent.SetBackgroundColour("pink")
                 msg = "Model Error:This value can not be negative!!!"
-            elif self.dx_max < 0:
-                get_pin_max.SetBackgroundColour("pink")
-                msg = "Model Error:This value can not be negative!!!"
-            elif self.dx_min is not None and self.dx_max is not None:
+            elif self.dx_percent is not None:
+                percent = self.dx_percent/100
                 if self._is_2D():
-                    data.dqx_data[data.dqx_data == 0] = self.dx_min
-                    data.dqy_data[data.dqy_data == 0] = self.dx_max
-                elif self.dx_min == self.dx_max:
-                    data.dx[data.dx == 0] = self.dx_min
+                    data.dqx_data[data.dqx_data == 0] = percent * data.qx_data
+                    data.dqy_data[data.dqy_data == 0] = percent * data.qy_data
                 else:
-                    step = (self.dx_max - self.dx_min) / (len_data - 1)
-                    data.dx = numpy.arange(self.dx_min,
-                                           self.dx_max + step / 1.1,
-                                           step)
-            elif self.dx_min is not None:
-                if self._is_2D():
-                    data.dqx_data[data.dqx_data == 0] = self.dx_min
-                else:
-                    data.dx[data.dx == 0] = self.dx_min
-            elif self.dx_max is not None:
-                if self._is_2D():
-                    data.dqy_data[data.dqy_data == 0] = self.dx_max
-                else:
-                    data.dx[data.dx == 0] = self.dx_max
+                    data.dx = percent * data.x
             self.current_smearer = smear_selection(data, self.model)
             # 2D need to set accuracy
@@ -2379,6 +2329,5 @@
             wx.PostEvent(self._manager.parent, StatusEvent(status=msg))
         else:
-            get_pin_min.SetBackgroundColour("white")
-            get_pin_max.SetBackgroundColour("white")
+            get_pin_percent.SetBackgroundColour("white")
         # set smearing value whether or not the data contain the smearing info
 
Index: src/sas/sasgui/perspectives/fitting/fitting.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/fitting.py	(revision ddbac6633a1e7ec42b99bb39f46b9889ccf26084)
+++ src/sas/sasgui/perspectives/fitting/fitting.py	(revision 4c5098cac470ea0a367a8f92be0ed0ac428bcc12)
@@ -1755,13 +1755,12 @@
                                           data_id="Data  " + data.name + " unsmeared",
                                           dy=unsmeared_error)
-                
-            if sq_model is not None and pq_model is not None:
-                self.create_theory_1D(x, sq_model, page_id, model, data, state,
-                                      data_description=model.name + " S(q)",
-                                      data_id=str(page_id) + " " + data.name + " S(q)")
-                self.create_theory_1D(x, pq_model, page_id, model, data, state,
-                                      data_description=model.name + " P(q)",
-                                      data_id=str(page_id) + " " + data.name + " P(q)")
-
+            # Comment this out until we can get P*S models with correctly populated parameters
+            #if sq_model is not None and pq_model is not None:
+            #    self.create_theory_1D(x, sq_model, page_id, model, data, state,
+            #                          data_description=model.name + " S(q)",
+            #                          data_id=str(page_id) + " " + data.name + " S(q)")
+            #    self.create_theory_1D(x, pq_model, page_id, model, data, state,
+            #                          data_description=model.name + " P(q)",
+            #                          data_id=str(page_id) + " " + data.name + " P(q)")
 
             current_pg = self.fit_panel.get_page_by_id(page_id)
Index: src/sas/sasgui/perspectives/fitting/media/plugin.rst
===================================================================
--- src/sas/sasgui/perspectives/fitting/media/plugin.rst	(revision 5295cf5164af9572978a04500767b155d0356342)
+++ src/sas/sasgui/perspectives/fitting/media/plugin.rst	(revision 984f3fc674aba45cfbaea60989743bfcf9507987)
@@ -364,4 +364,7 @@
   - the limits will show up as the default limits for the fit making it easy,
     for example, to force the radius to always be greater than zero.
+
+  - these are hard limits defining the valid range of parameter values;
+    polydisperity distributions will be truncated at the limits.
 
 - **"type"** can be one of: "", "sld", "volume", or "orientation".
Index: src/sas/sasgui/perspectives/fitting/pagestate.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/pagestate.py	(revision 7160131266189ab2ccf927b6fde2648ec04b8260)
+++ src/sas/sasgui/perspectives/fitting/pagestate.py	(revision 27109e5cd4b7a9b36dd9bb6e66db62057374322b)
@@ -74,6 +74,5 @@
                             ["dq_l", "dq_l", "float"],
                             ["dq_r", "dq_r", "float"],
-                            ["dx_max", "dx_max", "float"],
-                            ["dx_min", "dx_min", "float"],
+                            ["dx_percent", "dx_percent", "float"],
                             ["dxl", "dxl", "float"],
                             ["dxw", "dxw", "float"]]
@@ -215,6 +214,6 @@
         self.dq_l = None
         self.dq_r = None
-        self.dx_max = None
-        self.dx_min = None
+        self.dx_percent = None
+        self.dx_old = False
         self.dxl = None
         self.dxw = None
@@ -343,6 +342,6 @@
         obj.dq_l = copy.deepcopy(self.dq_l)
         obj.dq_r = copy.deepcopy(self.dq_r)
-        obj.dx_max = copy.deepcopy(self.dx_max)
-        obj.dx_min = copy.deepcopy(self.dx_min)
+        obj.dx_percent = copy.deepcopy(self.dx_percent)
+        obj.dx_old = copy.deepcopy(self.dx_old)
         obj.dxl = copy.deepcopy(self.dxl)
         obj.dxw = copy.deepcopy(self.dxw)
@@ -562,6 +561,5 @@
         rep += "dq_l  : %s\n" % self.dq_l
         rep += "dq_r  : %s\n" % self.dq_r
-        rep += "dx_max  : %s\n" % str(self.dx_max)
-        rep += "dx_min : %s\n" % str(self.dx_min)
+        rep += "dx_percent  : %s\n" % str(self.dx_percent)
         rep += "dxl  : %s\n" % str(self.dxl)
         rep += "dxw : %s\n" % str(self.dxw)
@@ -821,5 +819,5 @@
 
         attr = newdoc.createAttribute("version")
-        import sasview
+        from sas import sasview
         attr.nodeValue = sasview.__version__
         # attr.nodeValue = '1.0'
@@ -1048,7 +1046,14 @@
                     setattr(self, item[0], parse_entry_helper(node, item))
 
+                dx_old_node = get_content('ns:%s' % 'dx_min', entry)
                 for item in LIST_OF_STATE_ATTRIBUTES:
-                    node = get_content('ns:%s' % item[0], entry)
-                    setattr(self, item[0], parse_entry_helper(node, item))
+                    if item[0] == "dx_percent" and dx_old_node is not None:
+                        dxmin = ["dx_min", "dx_min", "float"]
+                        setattr(self, item[0], parse_entry_helper(dx_old_node,
+                                                                  dxmin))
+                        self.dx_old = True
+                    else:
+                        node = get_content('ns:%s' % item[0], entry)
+                        setattr(self, item[0], parse_entry_helper(node, item))
 
                 for item in LIST_OF_STATE_PARAMETERS:
