Index: LICENSE.txt
===================================================================
--- LICENSE.txt	(revision c8de1bd3a32ee924a911d93971d09e354b72e587)
+++ LICENSE.txt	(revision f68e2a577f4f85a12c9f7fa45ab9b9f6f1db2983)
@@ -1,5 +1,12 @@
-This program is in the public domain.
+Copyright (c) 2009-2017, SasView Developers
+All rights reserved.
 
-Individual files may be copyright different authors, with licences that
-allow modification and redistribution in source or binary form with or
-without modification, and a disclaimer of warranty.
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Index: sasmodels/compare.py
===================================================================
--- sasmodels/compare.py	(revision 01ea374bc814f28bf21ab1f74e39c702d73755c2)
+++ sasmodels/compare.py	(revision c4e321550a7eecc695933ac3c012bddd93f534d7)
@@ -30,4 +30,5 @@
 
 import sys
+import os
 import math
 import datetime
@@ -40,5 +41,5 @@
 from . import kerneldll
 from . import exception
-from .data import plot_theory, empty_data1D, empty_data2D
+from .data import plot_theory, empty_data1D, empty_data2D, load_data
 from .direct_model import DirectModel
 from .convert import revert_name, revert_pars, constrain_new_to_old
@@ -85,4 +86,5 @@
     -help/-html shows the model docs instead of running the model
     -title="note" adds note to the plot title, after the model name
+    -data="path" uses q, dq from the data file
 
 Any two calculation engines can be selected for comparison:
@@ -747,4 +749,5 @@
     comp = opts['engines'][1] if have_comp else None
     data = opts['data']
+    use_data = have_base ^ have_comp
 
     # Plot if requested
@@ -763,5 +766,5 @@
     if have_base:
         if have_comp: plt.subplot(131)
-        plot_theory(data, base_value, view=view, use_data=False, limits=limits)
+        plot_theory(data, base_value, view=view, use_data=use_data, limits=limits)
         plt.title("%s t=%.2f ms"%(base.engine, base_time))
         #cbar_title = "log I"
@@ -769,6 +772,6 @@
         if have_base: plt.subplot(132)
         if not opts['is2d'] and have_base:
-            plot_theory(data, base_value, view=view, use_data=False, limits=limits)
-        plot_theory(data, comp_value, view=view, use_data=False, limits=limits)
+            plot_theory(data, base_value, view=view, use_data=use_data, limits=limits)
+        plot_theory(data, comp_value, view=view, use_data=use_data, limits=limits)
         plt.title("%s t=%.2f ms"%(comp.engine, comp_time))
         #cbar_title = "log I"
@@ -784,5 +787,5 @@
             err[err>cutoff] = cutoff
         #err,errstr = base/comp,"ratio"
-        plot_theory(data, None, resid=err, view=errview, use_data=False)
+        plot_theory(data, None, resid=err, view=errview, use_data=use_data)
         if view == 'linear':
             plt.xscale('linear')
@@ -834,5 +837,5 @@
 VALUE_OPTIONS = [
     # Note: random is both a name option and a value option
-    'cutoff', 'random', 'nq', 'res', 'accuracy', 'title',
+    'cutoff', 'random', 'nq', 'res', 'accuracy', 'title', 'data',
     ]
 
@@ -951,4 +954,5 @@
         'html'      : False,
         'title'     : None,
+        'data'      : None,
     }
     engines = []
@@ -971,5 +975,6 @@
         elif arg.startswith('-cutoff='):   opts['cutoff'] = float(arg[8:])
         elif arg.startswith('-random='):   opts['seed'] = int(arg[8:])
-        elif arg.startswith('-title'):     opts['title'] = arg[7:]
+        elif arg.startswith('-title='):    opts['title'] = arg[7:]
+        elif arg.startswith('-data='):     opts['data'] = arg[6:]
         elif arg == '-random':  opts['seed'] = np.random.randint(1000000)
         elif arg == '-preset':  opts['seed'] = -1
@@ -1113,5 +1118,8 @@
 
     # Create the computational engines
-    data, _ = make_data(opts)
+    if opts['data'] is not None:
+        data = load_data(os.path.expanduser(opts['data']))
+    else:
+        data, _ = make_data(opts)
     if n1:
         base = make_engine(model_info, data, engines[0], opts['cutoff'])
@@ -1143,10 +1151,13 @@
     show html docs for the model
     """
-    import wx  # type: ignore
-    from .generate import view_html_from_info
-    app = wx.App() if wx.GetApp() is None else None
-    view_html_from_info(opts['def'][0])
-    if app: app.MainLoop()
-
+    import os
+    from .generate import make_html
+    from . import rst2html
+
+    info = opts['def'][0]
+    html = make_html(info)
+    path = os.path.dirname(info.filename)
+    url = "file://"+path.replace("\\","/")[2:]+"/"
+    rst2html.view_html_qtapp(html, url)
 
 def explore(opts):
Index: sasmodels/data.py
===================================================================
--- sasmodels/data.py	(revision 40a87fa5096610e24c3ead10299f609e99f093f2)
+++ sasmodels/data.py	(revision a769b5498ef3f5b7e8381de3d1a999a46950a84b)
@@ -54,4 +54,8 @@
     if data is None:
         raise IOError("Data %r could not be loaded" % filename)
+    if hasattr(data, 'x'):
+        data.qmin, data.qmax = data.x.min(), data.x.max()
+        data.mask = (np.isnan(data.y) if data.y is not None
+                     else np.zeros_like(data.x, dtype='bool'))
     return data
 
@@ -348,5 +352,5 @@
     # data, but they already handle the masking and graph markup already, so
     # do not repeat.
-    if hasattr(data, 'lam'):
+    if hasattr(data, 'isSesans') and data.isSesans:
         _plot_result_sesans(data, None, None, use_data=True, limits=limits)
     elif hasattr(data, 'qx_data'):
@@ -376,5 +380,5 @@
     *Iq_calc* is the raw theory values without resolution smearing
     """
-    if hasattr(data, 'lam'):
+    if hasattr(data, 'isSesans') and data.isSesans:
         _plot_result_sesans(data, theory, resid, use_data=True, limits=limits)
     elif hasattr(data, 'qx_data'):
Index: sasmodels/direct_model.py
===================================================================
--- sasmodels/direct_model.py	(revision b397165ea71fa5026c955689596b9f7baf7bd132)
+++ sasmodels/direct_model.py	(revision a769b5498ef3f5b7e8381de3d1a999a46950a84b)
@@ -192,5 +192,5 @@
 
         # interpret data
-        if hasattr(data, 'lam'):
+        if hasattr(data, 'isSesans') and data.isSesans:
             self.data_type = 'sesans'
         elif hasattr(data, 'qx_data'):
Index: sasmodels/generate.py
===================================================================
--- sasmodels/generate.py	(revision 1e7b0db0b7b4315c62b59e1d659332bcbc962b8f)
+++ sasmodels/generate.py	(revision c4e321550a7eecc695933ac3c012bddd93f534d7)
@@ -928,5 +928,5 @@
     from . import rst2html
     url = "file://"+dirname(info.filename)+"/"
-    rst2html.wxview(make_html(info), url=url)
+    rst2html.view_html(make_html(info), url=url)
 
 def demo_time():
Index: sasmodels/rst2html.py
===================================================================
--- sasmodels/rst2html.py	(revision 0890871751ed39056683fe16b7c50393b3d469f3)
+++ sasmodels/rst2html.py	(revision c4e321550a7eecc695933ac3c012bddd93f534d7)
@@ -29,20 +29,4 @@
 from docutils.writers.html4css1 import HTMLTranslator
 from docutils.nodes import SkipNode
-
-def wxview(html, url="", size=(850, 540)):
-    import wx
-    from wx.html2 import WebView
-    frame = wx.Frame(None, -1, size=size)
-    view = WebView.New(frame)
-    view.SetPage(html, url)
-    frame.Show()
-    return frame
-
-def view_rst(filename):
-    from os.path import expanduser
-    with open(expanduser(filename)) as fid:
-        rst = fid.read()
-    html = rst2html(rst)
-    wxview(html)
 
 def rst2html(rst, part="whole", math_output="mathjax"):
@@ -155,13 +139,59 @@
     assert replace_dollar(u"a (again $in parens$) a") == u"a (again :math:`in parens`) a"
 
-def view_rst_app(filename):
+def load_rst_as_html(filename):
+    from os.path import expanduser
+    with open(expanduser(filename)) as fid:
+        rst = fid.read()
+    html = rst2html(rst)
+    return html
+
+def wxview(html, url="", size=(850, 540)):
+    import wx
+    from wx.html2 import WebView
+    frame = wx.Frame(None, -1, size=size)
+    view = WebView.New(frame)
+    view.SetPage(html, url)
+    frame.Show()
+    return frame
+
+def qtview(html, url=""):
+    try:
+        from PyQt5.QtWebKitWidgets import QWebView
+        from PyQt5.QtCore import QUrl
+    except ImportError:
+        from PyQt4.QtWebkit import QWebView
+        from PyQt4.QtCore import QUrl
+    helpView = QWebView()
+    helpView.setHtml(html, QUrl(url))
+    helpView.show()
+    return helpView
+
+def view_html_wxapp(html, url=""):
     import wx  # type: ignore
     app = wx.App()
-    view_rst(filename)
+    frame = wxview(html, url)
     app.MainLoop()
 
+def view_html_qtapp(html, url=""):
+    import sys
+    try:
+        from PyQt5.QtWidgets import QApplication
+    except ImportError:
+        from PyQt4.QtGui import QApplication
+    app = QApplication([])
+    frame = qtview(html, url)
+    sys.exit(app.exec_())
+
+def view_rst_app(filename, qt=False):
+    import os
+    html = load_rst_as_html(filename)
+    url="file://"+os.path.abspath(filename)+"/"
+    if qt:
+        view_html_qtapp(html, url)
+    else:
+        view_html_wxapp(html, url)
 
 if __name__ == "__main__":
     import sys
-    view_rst_app(sys.argv[1])
+    view_rst_app(sys.argv[1], qt=True)
 
