Index: branches/mergetest/python/asapfitter.py
===================================================================
--- branches/mergetest/python/asapfitter.py	(revision 1785)
+++ branches/mergetest/python/asapfitter.py	(revision 1789)
@@ -1,7 +1,8 @@
 import _asap
 from asap import rcParams
-from asap import print_log_dec
+from asap import print_log, print_log_dec
 from asap import _n_bools
 from asap import mask_and
+from asap import asaplog
 
 class fitter:
@@ -59,5 +60,7 @@
             msg = "Please give a correct scan"
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -79,8 +82,10 @@
             lpoly:   use polynomial of the order given with linear least squares fit
             gauss:   fit the number of gaussian specified
+            lorentz: fit the number of lorentzian specified
         Example:
-            fitter.set_function(gauss=2) # will fit two gaussians
             fitter.set_function(poly=3)  # will fit a 3rd order polynomial via nonlinear method
             fitter.set_function(lpoly=3)  # will fit a 3rd order polynomial via linear method
+            fitter.set_function(gauss=2) # will fit two gaussians
+            fitter.set_function(lorentz=2) # will fit two lorentzians
         """
         #default poly order 0
@@ -102,8 +107,16 @@
             self.components = [ 3 for i in range(n) ]
             self.uselinear = False
+        elif kwargs.has_key('lorentz'):
+            n = kwargs.get('lorentz')
+            self.fitfunc = 'lorentz'
+            self.fitfuncs = [ 'lorentz' for i in range(n) ]
+            self.components = [ 3 for i in range(n) ]
+            self.uselinear = False
         else:
             msg = "Invalid function type."
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -135,5 +148,7 @@
             msg = "Fitter not yet initialised. Please set data & fit function"
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -145,5 +160,4 @@
                 self.y = self.data._getspectrum(row)
                 self.mask = mask_and(self.mask, self.data._getmask(row))
-                from asap import asaplog
                 asaplog.push("Fitting:")
                 i = row
@@ -155,5 +169,5 @@
                 asaplog.push(out,False)
         self.fitter.setdata(self.x, self.y, self.mask)
-        if self.fitfunc == 'gauss':
+        if self.fitfunc == 'gauss' or self.fitfunc == 'lorentz':
             ps = self.fitter.getparameters()
             if len(ps) == 0 or estimate:
@@ -171,9 +185,13 @@
         except RuntimeError, msg:
             if rcParams['verbose']:
-                print msg
+                #print msg
+                print_log()
+                asaplog.push(str(msg))
+                print_log('ERROR')
             else:
                 raise
         self._fittedrow = row
         self.fitted = True
+        print_log()
         return
 
@@ -228,9 +246,11 @@
             msg = "Please specify a fitting function first."
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
                 raise RuntimeError(msg)
-        if self.fitfunc == "gauss" and component is not None:
+        if (self.fitfunc == "gauss" or self.fitfunc == 'lorentz') and component is not None:
             if not self.fitted and sum(self.fitter.getparameters()) == 0:
                 pars = _n_bools(len(self.components)*3, False)
@@ -247,4 +267,5 @@
         if fixed is not None:
             self.fitter.setfixedparameters(fixed)
+        print_log()
         return
 
@@ -269,5 +290,7 @@
             msg = "Function only operates on Gaussian components."
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -280,23 +303,68 @@
             msg = "Please select a valid  component."
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
                 raise ValueError(msg)
 
+    def set_lorentz_parameters(self, peak, centre, fwhm,
+                             peakfixed=0, centrefixed=0,
+                             fwhmfixed=0,
+                             component=0):
+        """
+        Set the Parameters of a 'Lorentzian' component, set with set_function.
+        Parameters:
+            peak, centre, fwhm:  The gaussian parameters
+            peakfixed,
+            centrefixed,
+            fwhmfixed:           Optional parameters to indicate if
+                                 the paramters should be held fixed during
+                                 the fitting process. The default is to keep
+                                 all parameters flexible.
+            component:           The number of the component (Default is the
+                                 component 0)
+        """
+        if self.fitfunc != "lorentz":
+            msg = "Function only operates on Lorentzian components."
+            if rcParams['verbose']:
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
+                return
+            else:
+                raise ValueError(msg)
+        if 0 <= component < len(self.components):
+            d = {'params':[peak, centre, fwhm],
+                 'fixed':[peakfixed, centrefixed, fwhmfixed]}
+            self.set_parameters(d, component)
+        else:
+            msg = "Please select a valid  component."
+            if rcParams['verbose']:
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
+                return
+            else:
+                raise ValueError(msg)
+
     def get_area(self, component=None):
         """
-        Return the area under the fitted gaussian component.
-        Parameters:
-              component:   the gaussian component selection,
+        Return the area under the fitted gaussian/lorentzian component.
+        Parameters:
+              component:   the gaussian/lorentzian component selection,
                            default (None) is the sum of all components
         Note:
-              This will only work for gaussian fits.
+              This will only work for gaussian/lorentzian fits.
         """
         if not self.fitted: return
-        if self.fitfunc == "gauss":
+        if self.fitfunc == "gauss" or self.fitfunc == "lorentz":
             pars = list(self.fitter.getparameters())
             from math import log,pi,sqrt
-            fac = sqrt(pi/log(16.0))
+            if self.fitfunc == "gauss":
+                fac = sqrt(pi/log(16.0))
+            elif self.fitfunc == "lorentz":
+                fac = pi/2.0
             areas = []
             for i in range(len(self.components)):
@@ -321,5 +389,7 @@
             msg = "Not yet fitted."
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -328,5 +398,5 @@
         cerrs = errs
         if component is not None:
-            if self.fitfunc == "gauss":
+            if self.fitfunc == "gauss" or self.fitfunc == "lorentz":
                 i = 3*component
                 if i < len(errs):
@@ -344,5 +414,7 @@
             msg = "Not yet fitted."
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -353,5 +425,5 @@
         area = []
         if component is not None:
-            if self.fitfunc == "gauss":
+            if self.fitfunc == "gauss" or self.fitfunc == "lorentz":
                 i = 3*component
                 cpars = pars[i:i+3]
@@ -368,5 +440,5 @@
             cfixed = fixed
             cerrs = errs
-            if self.fitfunc == "gauss":
+            if self.fitfunc == "gauss" or self.fitfunc == "lorentz":
                 for c in range(len(self.components)):
                   a = self.get_area(c)
@@ -374,5 +446,7 @@
         fpars = self._format_pars(cpars, cfixed, errors and cerrs, area)
         if rcParams['verbose']:
-            print fpars
+            #print fpars
+            asaplog.push(fpars)
+            print_log()
         return {'params':cpars, 'fixed':cfixed, 'formatted': fpars,
                 'errors':cerrs}
@@ -391,5 +465,5 @@
                 c+=1
             out = out[:-1]  # remove trailing ','
-        elif self.fitfunc == 'gauss':
+        elif self.fitfunc == 'gauss' or self.fitfunc == 'lorentz':
             i = 0
             c = 0
@@ -415,5 +489,7 @@
         fixed = self.fitter.getfixedparameters()
         if rcParams['verbose']:
-            print self._format_pars(pars,fixed,None)
+            #print self._format_pars(pars,fixed,None)
+            asaplog.push(self._format_pars(pars,fixed,None))
+            print_log()
         return pars
 
@@ -425,5 +501,7 @@
             msg = "Not yet fitted."
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -438,5 +516,7 @@
             msg = "Not yet fitted."
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -444,5 +524,7 @@
         ch2 = self.fitter.getchi2()
         if rcParams['verbose']:
-            print 'Chi^2 = %3.3f' % (ch2)
+            #print 'Chi^2 = %3.3f' % (ch2)
+            asaplog.push( 'Chi^2 = %3.3f' % (ch2) )
+            print_log()
         return ch2
 
@@ -454,5 +536,7 @@
             msg = "Not yet fitted."
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -468,5 +552,7 @@
             msg = "Not yet fitted."
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -476,5 +562,7 @@
             msg = "Not a scantable"
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -482,4 +570,5 @@
         scan = self.data.copy()
         scan._setspectrum(self.fitter.getresidual())
+        print_log()
         return scan
 
@@ -525,10 +614,22 @@
 
         colours = ["#777777","#dddddd","red","orange","purple","green","magenta", "cyan"]
+        nomask=True
+        for i in range(len(m)):
+            nomask = nomask and m[i]
+        label0='Masked Region'
+        label1='Spectrum'
+        if ( nomask ):
+            label0=label1
+        else:
+            y = ma.masked_array( self.y, mask = m )
+            self._p.palette(1,colours)
+            self._p.set_line( label = label1 )
+            self._p.plot( self.x, y )
         self._p.palette(0,colours)
-        self._p.set_line(label='Spectrum')
+        self._p.set_line(label=label0)
         y = ma.masked_array(self.y,mask=logical_not(m))
         self._p.plot(self.x, y)
         if residual:
-            self._p.palette(1)
+            self._p.palette(7)
             self._p.set_line(label='Residual')
             y = ma.masked_array(self.get_residual(),
@@ -571,4 +672,5 @@
         if (not rcParams['plotter.gui']):
             self._p.save(filename)
+        print_log()
 
     @print_log_dec
@@ -583,5 +685,7 @@
             msg = "Data is not a scantable"
             if rcParams['verbose']:
-                print msg
+                #print msg
+                asaplog.push(msg)
+                print_log('ERROR')
                 return
             else:
@@ -593,5 +697,7 @@
             scan = self.data
         rows = xrange(scan.nrow())
-        from asap import asaplog
+        # Save parameters of baseline fits as a class attribute. 
+        # NOTICE: This does not reflect changes in scantable!
+        if len(rows) > 0: self.blpars=[]
         asaplog.push("Fitting:")
         for r in rows:
@@ -608,12 +714,16 @@
             self.fit()
             x = self.get_parameters()
+            fpar = self.get_parameters()
             if plot:
                 self.plot(residual=True)
                 x = raw_input("Accept fit ([y]/n): ")
                 if x.upper() == 'N':
+                    self.blpars.append(None)
                     continue
             scan._setspectrum(self.fitter.getresidual(), r)
+            self.blpars.append(fpar)
         if plot:
             self._p.unmap()
             self._p = None
+        print_log()
         return scan
