Index: prview/perspectives/pr/inversion_panel.py
===================================================================
--- prview/perspectives/pr/inversion_panel.py	(revision f3d51f6ec6277f40c94acc80d658917deab47a7a)
+++ prview/perspectives/pr/inversion_panel.py	(revision 32dffae4e1afdd03ed92e8646e5c3335bb00a7fb)
@@ -150,5 +150,5 @@
             self.osc_ctl.SetValue("%-5.2g" % value)
         elif name=='alpha_estimate':
-            self.alpha_estimate_ctl.SetValue("%-5.2g" % value)
+            self.alpha_estimate_ctl.SetValue("%-3.1g" % value)
         elif name=='plotname':
             self.plot_data.SetValue(str(value))
@@ -226,4 +226,14 @@
         boxsizer2.SetMinSize((320,50))
         
+        explanation  = "P(r) is found by fitting a set of base functions to I(Q). "
+        explanation += "The minimization involves a regularization term to ensure "
+        explanation += "a smooth P(r). The alpha parameter gives the size of that "  
+        explanation += "term. The suggested value is the value above which the"
+        explanation += "output P(r) will have only one peak."
+        label_explain = wx.StaticText(self, -1, explanation, size=(280,80))
+        boxsizer2.Add(label_explain,  wx.LEFT|wx.BOTTOM, 5)
+        
+        
+        
         label_nfunc = wx.StaticText(self, -1, "Number of terms")
         label_nfunc.SetMinSize((120,20))
@@ -233,8 +243,12 @@
         
         self.nfunc_ctl = wx.TextCtrl(self, -1, size=(60,20))
+        self.nfunc_ctl.SetToolTipString("Number of terms in the expansion.")
         self.alpha_ctl = wx.TextCtrl(self, -1, size=(60,20))
+        self.alpha_ctl.SetToolTipString("Control parameter for the size of the regularization term.")
         self.dmax_ctl  = wx.TextCtrl(self, -1, size=(60,20))
+        self.dmax_ctl.SetToolTipString("Maximum distance between any two points in the system.")
         self.alpha_estimate_ctl  = wx.TextCtrl(self, -1, size=(60,20))
         self.alpha_estimate_ctl.Enable(False)
+        self.alpha_estimate_ctl.SetToolTipString("Value of alpha below which P(r) may have multiple peaks.")
         
         # EVT_TEXT would trigger an event for each character entered
@@ -247,15 +261,15 @@
 
         iy = 0
-        sizer_params.Add(label_sugg, (iy,2), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        iy += 1
-        sizer_params.Add(label_nfunc, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        sizer_params.Add(self.nfunc_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        iy += 1
-        sizer_params.Add(label_alpha, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        sizer_params.Add(self.alpha_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        sizer_params.Add(self.alpha_estimate_ctl,   (iy,2), (1,1), wx.RIGHT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        iy += 1
-        sizer_params.Add(label_dmax, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        sizer_params.Add(self.dmax_ctl,   (iy,1), (1,1), wx.RIGHT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
+        sizer_params.Add(label_sugg,       (iy,2), (1,1), wx.LEFT, 15)
+        iy += 1
+        sizer_params.Add(label_nfunc,      (iy,0), (1,1), wx.LEFT, 15)
+        sizer_params.Add(self.nfunc_ctl,   (iy,1), (1,1), wx.RIGHT, 0)
+        iy += 1
+        sizer_params.Add(label_alpha,      (iy,0), (1,1), wx.LEFT, 15)
+        sizer_params.Add(self.alpha_ctl,   (iy,1), (1,1), wx.RIGHT, 0)
+        sizer_params.Add(self.alpha_estimate_ctl, (iy,2), (1,1), wx.LEFT, 15)
+        iy += 1
+        sizer_params.Add(label_dmax, (iy,0), (1,1), wx.LEFT, 15)
+        sizer_params.Add(self.dmax_ctl,   (iy,1), (1,1), wx.RIGHT, 0)
 
         boxsizer2.Add(sizer_params, 0)
@@ -275,8 +289,13 @@
         self.time_ctl = wx.TextCtrl(self, -1, size=(60,20))
         self.time_ctl.SetEditable(False)
+        self.time_ctl.SetToolTipString("Computation time for the last inversion, in seconds.")
+        
         self.chi2_ctl = wx.TextCtrl(self, -1, size=(60,20))
         self.chi2_ctl.SetEditable(False)
+        self.chi2_ctl.SetToolTipString("Chi^2 over degrees of freedom.")
+        
         self.osc_ctl = wx.TextCtrl(self, -1, size=(60,20))
         self.osc_ctl.SetEditable(False)
+        self.osc_ctl.SetToolTipString("Oscillation parameter. P(r) for a sphere has an oscillation parameter of 1.1.")
         
         sizer_res = wx.GridBagSizer(5,5)
@@ -302,4 +321,5 @@
         id = wx.NewId()
         button_OK = wx.Button(self, id, "Compute")
+        button_OK.SetToolTipString("Perform P(r) inversion.")
         self.Bind(wx.EVT_BUTTON, self._on_invert, id = id)   
         #button_Cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
Index: prview/perspectives/pr/pars_dialog.py
===================================================================
--- prview/perspectives/pr/pars_dialog.py	(revision f3d51f6ec6277f40c94acc80d658917deab47a7a)
+++ 	(revision )
@@ -1,165 +1,0 @@
-#!/usr/bin/env python
-
-# version
-__id__ = "$Id: aboutdialog.py 1193 2007-05-03 17:29:59Z dmitriy $"
-__revision__ = "$Revision: 1193 $"
-
-import wx
-
-
-class ParsDialog(wx.Dialog):
-    """
-        Dialog box to let the user edit detector settings
-    """
-    
-    def __init__(self, *args, **kwds):
-
-        kwds["style"] = wx.DEFAULT_DIALOG_STYLE
-        wx.Dialog.__init__(self, *args, **kwds)
-        
-        self.label_nfunc = wx.StaticText(self, -1, "Number of terms")
-        self.label_alpha = wx.StaticText(self, -1, "Regularization constant")
-        self.label_dmax  = wx.StaticText(self, -1, "Max distance [A]")
-        self.label_file  = wx.StaticText(self, -1, "Input file")
-        
-        # Npts, q max
-        self.nfunc_ctl = wx.TextCtrl(self, -1, size=(60,20))
-        self.alpha_ctl = wx.TextCtrl(self, -1, size=(60,20))
-        self.dmax_ctl  = wx.TextCtrl(self, -1, size=(60,20))
-        self.file_ctl  = wx.TextCtrl(self, -1, size=(120,20))
-
-        self.static_line_3 = wx.StaticLine(self, -1)
-        
-        
-        self.button_OK = wx.Button(self, wx.ID_OK, "OK")
-        self.Bind(wx.EVT_BUTTON, self.checkValues, self.button_OK)
-        
-        self.button_Cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
-        
-        self.button_load = wx.Button(self, 1, "Choose file")
-        self.Bind(wx.EVT_BUTTON, self._load_file, id = 1)        
-
-        self.__set_properties()
-        self.__do_layout()
-
-        self.Fit()
-        
-    def _load_file(self, evt):
-        import os
-        path = None
-        dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.txt", wx.OPEN)
-        if dlg.ShowModal() == wx.ID_OK:
-            path = dlg.GetPath()
-            mypath = os.path.basename(path)
-        dlg.Destroy()
-        
-        if path and os.path.isfile(path):
-            self.file_ctl.SetValue(str(path))
-
-        
-    def checkValues(self, event):
-        flag = True
-        try:
-            float(self.alpha_ctl.GetValue())
-            self.alpha_ctl.SetBackgroundColour(wx.WHITE)
-            self.alpha_ctl.Refresh()
-        except:
-            flag = False
-            self.alpha_ctl.SetBackgroundColour("pink")
-            self.alpha_ctl.Refresh()
-            
-        try:
-            float(self.dmax_ctl.GetValue())
-            self.dmax_ctl.SetBackgroundColour(wx.WHITE)
-            self.dmax_ctl.Refresh()
-        except:
-            flag = False
-            self.dmax_ctl.SetBackgroundColour("pink")
-            self.dmax_ctl.Refresh()
-            
-        try:
-            int(self.nfunc_ctl.GetValue())
-            self.nfunc_ctl.SetBackgroundColour(wx.WHITE)
-            self.nfunc_ctl.Refresh()
-        except:
-            flag = False
-            self.nfunc_ctl.SetBackgroundColour("pink")
-            self.nfunc_ctl.Refresh()
-        
-        if flag:
-            event.Skip(True)
-    
-    def setContent(self, nfunc, alpha, dmax, file):
-        self.nfunc_ctl.SetValue(str(nfunc))
-        self.alpha_ctl.SetValue(str(alpha))
-        self.dmax_ctl.SetValue(str(dmax))
-        self.file_ctl.SetValue(str(file))
-
-    def getContent(self):
-        nfunc = int(self.nfunc_ctl.GetValue())
-        alpha = float(self.alpha_ctl.GetValue())
-        dmax = float(self.dmax_ctl.GetValue())
-        file = self.file_ctl.GetValue()
-        return nfunc, alpha, dmax, file
-
-    def __set_properties(self):
-        self.SetTitle("P(r) inversion parameters")
-        self.SetSize((600, 595))
-
-    def __do_layout(self):
-        sizer_main = wx.BoxSizer(wx.VERTICAL)
-        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
-        sizer_params = wx.GridBagSizer(5,5)
-
-        iy = 0
-        sizer_params.Add(self.label_nfunc, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        sizer_params.Add(self.nfunc_ctl,   (iy,1), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-        iy += 1
-        sizer_params.Add(self.label_alpha, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        sizer_params.Add(self.alpha_ctl,   (iy,1), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-        iy += 1
-        sizer_params.Add(self.label_dmax, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        sizer_params.Add(self.dmax_ctl,   (iy,1), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-        iy += 1
-        sizer_params.Add(self.label_file, (iy,0), (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        sizer_params.Add(self.file_ctl,   (iy,1), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-
-        sizer_main.Add(sizer_params, 0, wx.EXPAND|wx.ALL, 10)
-        sizer_main.Add(self.static_line_3, 0, wx.EXPAND, 0)
-        
-        
-        sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-        sizer_button.Add(self.button_load, 0, wx.LEFT|wx.ADJUST_MINSIZE, 10)
-        sizer_button.Add(self.button_OK, 0, wx.LEFT|wx.ADJUST_MINSIZE, 10)
-        sizer_button.Add(self.button_Cancel, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
-        
-        
-        sizer_main.Add(sizer_button, 0, wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
-        self.SetAutoLayout(True)
-        self.SetSizer(sizer_main)
-        self.Layout()
-        self.Centre()
-        # end wxGlade
-
-
-# end of class DialogAbout
-
-##### testing code ############################################################
-class MyApp(wx.App):
-    def OnInit(self):
-        wx.InitAllImageHandlers()
-        dialog = ParsDialog(None, -1, "")
-        self.SetTopWindow(dialog)
-        dialog.setContent(10, 0.05)
-        nfunc, alpha = dialog.getContent()
-        print nfunc, alpha
-        dialog.Destroy()
-        return 1
-
-# end of class MyApp
-
-if __name__ == "__main__":
-    app = MyApp(0)
-    app.MainLoop()
-    
-##### end of testing code #####################################################    
Index: prview/perspectives/pr/pr.py
===================================================================
--- prview/perspectives/pr/pr.py	(revision f3d51f6ec6277f40c94acc80d658917deab47a7a)
+++ prview/perspectives/pr/pr.py	(revision 32dffae4e1afdd03ed92e8646e5c3335bb00a7fb)
@@ -291,5 +291,5 @@
         wx.PostEvent(self.parent, StatusEvent(status=error))
     
-    def _estimate_completed(self, alpha, elapsed):
+    def _estimate_completed(self, alpha, message, elapsed):
         """
             Parameter estimation completed, 
@@ -301,4 +301,6 @@
         self.elapsed = elapsed
         self.control_panel.alpha_estimate = alpha
+        if not message==None:
+            wx.PostEvent(self.parent, StatusEvent(status=str(message)))
     
     def _completed(self, out, cov, pr, elapsed):
@@ -322,4 +324,5 @@
         self.control_panel.oscillation = pr.oscillations(out)
         #print "OSCILL", pr.oscillations(out)
+        print "PEAKS:", pr.get_peaks(out)
         
         for i in range(len(out)):
@@ -428,8 +431,8 @@
         
     def perform_estimate(self):
-        print "ESTIMATE"
         from pr_thread import EstimatePr
         from copy import deepcopy
         
+        wx.PostEvent(self.parent, StatusEvent(status=''))
         # If a thread is already started, stop it
         if self.estimation_thread != None and self.estimation_thread.isrunning():
@@ -548,4 +551,4 @@
             [Somehow openGL needs this call]
         """
-        pass
-    
+        self.parent.set_perspective(self.perspective)
+    
Index: prview/perspectives/pr/pr_thread.py
===================================================================
--- prview/perspectives/pr/pr_thread.py	(revision f3d51f6ec6277f40c94acc80d658917deab47a7a)
+++ prview/perspectives/pr/pr_thread.py	(revision 32dffae4e1afdd03ed92e8646e5c3335bb00a7fb)
@@ -75,12 +75,9 @@
         except KeyboardInterrupt:
             printEVT("P(r) calc interrupted")
-            raise KeyboardInterrupt
+            raise KeyboardInterrupt    
         
     def compute(self):
         import time
-        try:
-            
-            print "Alpha  Oscill"
-            
+        try:            
             self.starttime = time.time()
             # If the current alpha is zero, try
@@ -89,44 +86,60 @@
                 self.pr.alpha = 0.0001
                  
+            # Perform inversion to find the largest alpha
             out, cov = self.pr.lstsq(self.nfunc)
             elapsed = time.time()-self.starttime
-            
+            initial_alpha = self.pr.alpha
+            initial_peaks = self.pr.get_peaks(out)
 
-            # Take the default and try to find 
-            # a better value
-            best_alpha = self.pr.alpha
-            best_osc   = self.pr.oscillations(out) 
-            
-            print best_alpha, best_osc
-            
-            alpha = self.pr.suggested_alpha
-            print "initial:", alpha
+            # Try the inversion with the estimated alpha
+            self.pr.alpha = self.pr.suggested_alpha
+            out, cov = self.pr.lstsq(self.nfunc)
 
-            # Look at smaller values
-            for i in range(5):
-                self.pr.alpha = (0.1)**(i)*alpha
-                out, cov = self.pr.lstsq(self.nfunc)
-                osc = self.pr.oscillations(out) 
-                print self.pr.alpha, osc
-                if  osc < best_osc:
-                    best_osc = osc
-                    best_alpha = alpha
-            
-            ## Look at larger values
-            #for i in range(4):
-            #    self.pr.alpha = (10.0)**(i+1)*alpha
-            #    out, cov = self.pr.lstsq(self.nfunc)
-            #    osc = self.pr.oscillations(out) 
-            #    print self.pr.alpha, osc
-            #    if  osc < best_osc:
-            #        best_osc = osc
-            #        best_alpha = alpha
-            
-            
-            self.complete(alpha=best_alpha, elapsed=elapsed)
-            
-            
-            
-            
+            npeaks = self.pr.get_peaks(out)
+            # if more than one peak to start with
+            # just return the estimate
+            if npeaks>1:
+                message = "Your P(r) is not smooth, please check your inversion parameters"
+                self.complete(alpha=self.pr.suggested_alpha, message=message, elapsed=elapsed)
+            else:
+                
+                # Look at smaller values
+                # We assume that for the suggested alpha, we have 1 peak
+                # if not, send a message to change parameters
+                alpha = self.pr.suggested_alpha
+                best_alpha = self.pr.suggested_alpha
+                found = False
+                for i in range(10):
+                    self.pr.alpha = (0.33)**(i+1)*alpha
+                    out, cov = self.pr.lstsq(self.nfunc)
+                    #osc = self.pr.oscillations(out) 
+                    #print self.pr.alpha, osc
+                    
+                    peaks = self.pr.get_peaks(out)
+                    print self.pr.alpha, peaks
+                    if peaks>1:
+                        found = True
+                        break
+                    best_alpha = self.pr.alpha
+                    
+                # If we didn't find a turning point for alpha and
+                # the initial alpha already had only one peak,
+                # just return that
+                if not found and initial_peaks==1 and initial_alpha<best_alpha:
+                    best_alpha = initial_alpha
+                    
+                # Check whether the size makes sense
+                message=None
+                
+                if not found:
+                    message = "None"
+                elif best_alpha>=0.5*self.pr.suggested_alpha:
+                    # best alpha is too big, return a 
+                    # reasonable value
+                    message  = "The estimated alpha for your system is too large. "
+                    message += "Try increasing your maximum distance."
+                
+                self.complete(alpha=best_alpha, message=None, elapsed=elapsed)
+
         except:
             if not self.error_func==None:
Index: prview/perspectives/pr/requirements.txt
===================================================================
--- prview/perspectives/pr/requirements.txt	(revision f3d51f6ec6277f40c94acc80d658917deab47a7a)
+++ prview/perspectives/pr/requirements.txt	(revision 32dffae4e1afdd03ed92e8646e5c3335bb00a7fb)
@@ -18,2 +18,3 @@
 14. Clean up the InversionDialog
 15. Add online help for inputs and outputs (especially figures of merit)
+16. Add help text to the interface (description of what we are minimizing, to explain alpha and nfunc).
