diff --git a/pykat/optics/maps.py b/pykat/optics/maps.py
index 5a1bf7eed8238b722deae82b4c70771b8fc42e66..f013a162ea5554df1eaddc2ca22356ce3b495bd4 100644
--- a/pykat/optics/maps.py
+++ b/pykat/optics/maps.py
@@ -52,7 +52,7 @@ class surfacemap(object):
         self.Rc = Rc
         self.zOffset = zOffset
         self.__interp = None
-        self._zernikesRemoved = {}
+        self._zernikeRemoved = {}
         self._betaRemoved = None
 		
         if data is None:
@@ -84,6 +84,7 @@ class surfacemap(object):
                     mapfile.write("%.15g " % self.data[i,j])
                 mapfile.write("\n")
 
+
     @property
     def betaRemoved(self):
         return self._betaRemoved
@@ -93,15 +94,15 @@ class surfacemap(object):
         self._betaRemoved = v
         
     @property
-    def zernikesRemoved(self):
-        return self._zernikesRemoved
+    def zernikeRemoved(self):
+        return self._zernikeRemoved
     
-    @zernikesRemoved.setter
-    def zernikesRemoved(self, v):
+    @zernikeRemoved.setter
+    def zernikeRemoved(self, v):
         '''
         v = tuple(m,n,amplitude)
         '''
-        self._zernikesRemoved["%i%i" % (v[0],v[1])] = v
+        self._zernikeRemoved["%i%i" % (v[0],v[1])] = v
 
     @property
     def data(self):
@@ -397,6 +398,41 @@ class surfacemap(object):
         
         return fig
 
+    def rms(self, w=None):
+        if w is None:
+            return math.sqrt((self.data[self.notNan]**2).sum())/self.notNan.sum()
+        else:
+            R = self.find_radius(unit='meters')
+            if w>=R:
+                return math.sqrt((self.data[self.notNan]**2).sum())/self.notNan.sum()
+            else:
+                rho = self.createPolarGrid()[0]
+                inside = np.zeros(self.data.shape,dtype=bool)
+                tmp = rho<w
+                inside[tmp] = self.notNan[tmp]
+                return math.sqrt((self.data[inside]**2).sum())/inside.sum()
+            
+    def avg(self, w=None):
+        if w is None:
+            tot = self.data[self.notNan].sum()
+            sgn = np.sign(tot)
+            return sgn*math.sqrt(sgn*tot)/self.notNan.sum()
+        else:
+            R = self.find_radius(unit='meters')
+            if w>=R:
+                tot = self.data[self.notNan].sum()
+                sgn = np.sign(tot)
+                return sgn*math.sqrt(sgn*tot)/self.notNan.sum()
+            else:
+                rho = self.createPolarGrid()[0]
+                inside = np.zeros(self.data.shape,dtype=bool)
+                tmp = rho<w
+                inside[tmp] = self.notNan[tmp]
+                tot = self.data[inside].sum()
+                sgn = np.sign(tot)
+                return sgn*math.sqrt(sgn*tot)/inside.sum()
+            
+            
     def find_radius(self, method = 'max', unit='points'):
         '''
         Estimates the radius of the mirror in the xy-plane. 
@@ -571,7 +607,7 @@ class surfacemap(object):
                 m = (k-1)*2
                 Z = A[k]*zernike(m, 2, rho, phi)
                 self.data[self.notNan] = self.data[self.notNan]-Z[self.notNan]
-                self.zernikesRemoved = (m, 2, A[k])
+                self.zernikeRemoved = (m, 2, A[k])
             # Estimating radius of curvature
             Rc = znm2Rc([a*self.scaling for a in A], R)
         elif zModes=='astigmatism' or zModes=='Astigmatism':
@@ -579,17 +615,17 @@ class surfacemap(object):
                 m = (k-1)*2
                 Z = A[k]*zernike(m, 2, rho, phi)
                 smap.data[self.notNan] = self.data[self.notNan]-Z[self.notNan]
-                self.zernikesRemoved = (m, 2, A[k])
+                self.zernikeRemoved = (m, 2, A[k])
             Rc = znm2Rc([a*self.scaling for a in A[::2]], R)
         elif zModes=='defocus' or zModes=='Defocus':
             Z = A[1]*zernike(0, 2, rho, phi)
             self.data[self.notNan] = self.data[self.notNan]-Z[self.notNan]
-            self.zernikesRemoved = (0, 2, A[1])
+            self.zernikeRemoved = (0, 2, A[1])
             Rc = znm2Rc(A[1]*self.scaling, R)
         
         self.Rc = Rc
         
-        return self.Rc, self.zernikesRemoved
+        return self.Rc, self.zernikeRemoved
 
 
     def rmSphericalSurf(self, Rc0, w=None, zOff=None, isCenter=[False,False]):
@@ -652,7 +688,7 @@ class surfacemap(object):
                 x0 = 0
                 y0 = 0
 
-            Z = self.createSphere(Rc,X,Y,zOff,x0,y0)
+            Z = self.createSurface(Rc,X,Y,zOff,x0,y0)
 
             if w is None:
                 # Mean squared difference between map and the created sphere.
@@ -691,14 +727,14 @@ class surfacemap(object):
             self.center = (self.center[0] + x0/self.step_size[0],
                            self.center[1] + y0/self.step_size[1])
             # Creating fitted sphere
-            Z = self.createSphere(self.Rc, X, Y, self.zOff, x0, y0)
+            Z = self.createSurface(self.Rc, X, Y, self.zOff, x0, y0)
             # Subtracting sphere from map
             self.data[self.notNan] = self.data[self.notNan]-Z[self.notNan]
             return self.Rc, self.zOff, self.center
         # Subtracting fitted sphere from mirror map.
         else:
             # Creating fitted sphere
-            Z = self.createSphere(self.Rc,X,Y,self.zOff)
+            Z = self.createSurface(self.Rc,X,Y,self.zOff)
             # Subtracting sphere from map
             self.data[self.notNan] = self.data[self.notNan]-Z[self.notNan]
             return self.Rc, self.zOff
@@ -818,9 +854,9 @@ class surfacemap(object):
         
         
     
-    def createSphere(self,Rc,X,Y,zOffset=0,x0=0,y0=0,xTilt=0,yTilt=0,isPlot=False):
+    def createSurface(self,Rc,X,Y,zOffset=0,x0=0,y0=0,xTilt=0,yTilt=0,isPlot=False):
         '''
-        Creating spherical surface.
+        Creating surface.
         
         Inputs: Rc, X, Y, zOffset=0, x0=0, y0=0, xTilt=0, yTilt=0, isPlot=False
         Rc      - Radius of curvature, and center of sphere on z-axis in case zOffset=0. [m]
@@ -841,8 +877,9 @@ class surfacemap(object):
         # Adjusting for tilts and offset
         Z = zOffset + (X*np.tan(xTilt) + Y*np.tan(yTilt))/self.scaling
         # Adjusting for spherical shape.
-        Z = Z + (Rc - np.sqrt(Rc**2 - (X-x0)**2 - (Y-y0)**2))/self.scaling
-
+        if Rc !=0 and Rc is not None:
+            Z = Z + (Rc - np.sign(Rc)*np.sqrt(Rc**2 - (X-x0)**2 - (Y-y0)**2))/self.scaling
+        
         if isPlot:
             import pylab
             pylab.clf()
@@ -866,7 +903,7 @@ class surfacemap(object):
         X,Y = np.meshgrid(self.x,self.y)
         phi = np.arctan2(Y,X)
         rho = np.sqrt(X**2 + Y**2)
-        return rho,phi
+        return rho, phi
 
     def preparePhaseMap(self, xyOffset=None, w=None):
         '''
@@ -874,9 +911,11 @@ class surfacemap(object):
         '''
         
         print('Preparing phase map for Finesse...')
+        
+        print(' rms = {:.3f} nm'.format(self.rms(w)))
+        print(' avg = {:.3f} nm'.format(self.avg(w)))
         # Factor that scales surface height to nm.
         nm_scaling = self.scaling*1.0e9
-        
         print(' Centering...')
         self.recenter()
         print('  New center (x0, y0) = ({:.2f}, {:.2f})'.
@@ -889,11 +928,15 @@ class surfacemap(object):
               format(before[1], before[0], self.size[1], self.size[0]))
         print('  New center (x0, y0) = ({:.2f}, {:.2f})'.
               format(self.center[0],self.center[1]))
+        print('  rms = {:.3f} nm'.format(self.rms(w)))
+        print('  avg = {:.3f} nm'.format(self.avg(w)))
+        
         
         # Radius of mirror in xy-plane.
         R = self.find_radius(unit='meters')
-
+        self.plot()
         print(' Removing curvatures...')
+        # --------------------------------------------------------
         if w is None:
             Rc, znm = self.remove_curvature(method='zernike', zModes = 'defocus')
             print('  Removed Z20 with amplitude A20 = {:.2f} nm'.format(znm['02'][2]))
@@ -903,26 +946,37 @@ class surfacemap(object):
             if w >= w_max:
                 w = w_max-max(self.step_size)
                 print('  Weigthing radius too large, setting w = {0:.4f} m'.format(w))
-            Rc, zOff = self.remove_curvature(method='sphere', w=w)
+            Rc, A0 = self.remove_curvature(method='sphere', w=w)
             # Equivalent Zernike (n=2,m=0) amplitude.
             A20 = Rc2znm(Rc,R)/self.scaling
+            self.zernikeRemoved = (0,2,A20)
             # Adding A20 to zOff because: Z(n=2,m=0) = A20*(r**2 - 1)
-            zOff = zOff+A20
-
+            A0 = A0+A20
             print('  Removed Rc = {0:.2f} m'.format(Rc) )
             print('  Equivalent Z(n=2,m=0) amplitude A20 = {0:.2f} nm'.format(A20))
-            
+           
+        print('  rms = {:.3e} nm'.format(self.rms(w)))
+        print('  avg = {:.3e} nm'.format(self.avg(w)))
+        
+        self.plot()
         
         print(' Removing offset...')
+        # --------------------------------------------------------
         if w is None:
             A00 = self.rmZernike(0,0)
             print('  Removed Z00 with amplitude A00 = {:.2f} nm'.format(A00) )
         else:
-            A0 = self.removeOffset(w)
-            zOff = zOff + A0
-            print('  Removed offset, A00 = {0:.4f} nm'.format(zOff))
+            zOff = self.removeOffset(w)
+            A0 = A0 + zOff
+            print('  Removed offset (A00) = {0:.4f} nm'.format(zOff))
+            
+        print('  rms = {:.3e} nm'.format(self.rms(w)))
+        print('  avg = {:.3e} nm'.format(self.avg(w)))
         
-        print(' Removing piston...')
+        self.plot()
+        
+        print(' Removing tilts...')
+        # --------------------------------------------------------
         if w is None:
             A1 = self.zernikeConvol(1)[1]
             rho,phi=self.createPolarGrid()
@@ -932,18 +986,102 @@ class surfacemap(object):
             Z.append(zernike(1,1,rho,phi))
             for k in range(2):
                 self.data[self.notNan] = self.data[self.notNan]-A1[k]*Z[k][self.notNan]
-                self.zernikesRemoved = (2*k-1,1,A1[k])
+                self.zernikeRemoved = (2*k-1,1,A1[k])
                 print('  Removed Z1{:d} with amplitude A1{:d} = {:.2f} nm'.
                       format(2*k-1,2*k-1,A1[k]) )
             ybeta = np.arctan(A1[0]*self.scaling/R)
             xbeta = np.arctan(A1[1]*self.scaling/R)
             self.betaRemoved = (xbeta,ybeta)
-            print('  Equivalent tilt in radians: ybeta = {:.2e} rad'.format(ybeta))
-            print('                              xbeta = {:.2e} rad'.format(xbeta))
+            print('  Equivalent tilt in radians: xbeta = {:.2e} rad'.format(xbeta))
+            print('                              ybeta = {:.2e} rad'.format(ybeta))
         else:
-            pass
+            X,Y = np.meshgrid(self.x,self.y)
+            r2 = X**2 + Y**2
+            
+            def f(p):
+                
+                # This is used in simtools, why?
+                #p[0] = p[0]*1.0e-9
+                #p[1] = p[1]*1.0e-9
+                
+                Z = self.createSurface(0,X,Y,p[2],0,0,p[0],p[1])
+                if w is None:
+                    res = math.sqrt(((self.data[self.notNan]-Z[self.notNan])**2).sum())/self.notNan.sum()
+                else:
+                    weight = 2/(math.pi*w**2) * np.exp(-2*r2[self.notNan]/w**2)
+                    res = math.sqrt((weight*(self.data[self.notNan]-Z[self.notNan])**2).sum())/weight.sum()
+                    
+                return res
 
+            xbeta = 0
+            ybeta = 0
+            offset = 0
+            params = [xbeta,ybeta,offset]
 
+            opts = {'xtol': 1.0e-8, 'ftol': 1.0e-8, 'maxiter': 2000, 'disp': False}
+            out = minimize(f, params, method='Nelder-Mead', options=opts)
+            
+            xbeta = out['x'][0]
+            ybeta = out['x'][1]
+            offset = out['x'][2]
+            
+            Z = self.createSurface(0,X,Y,offset,0,0,xbeta,ybeta)
+            self.data[self.notNan] = self.data[self.notNan] - Z[self.notNan]
+            self.betaRemoved = (xbeta, ybeta)
+            # Equivalent Zernike amplitude
+            A1 = R*np.tan(np.array([ybeta,xbeta]))/self.scaling
+            self.zernikeRemoved = (-1,1,A1[0])
+            self.zernikeRemoved = (1,1,A1[1])
+            A0 = A0 + offset
+            self.zernikeRemoved = (0,0,A0)
+            print('  Tilted surface removed:')
+            print('   xbeta    = {:.2e} rad'.format(xbeta))
+            print('   ybeta    = {:.2e} rad'.format(ybeta))
+            print('   z-offset = {:.2e} nm'.format(offset))
+            print('  Equivalent Zernike amplitudes:')
+            print('   A(1,-1) = {:.2f} nm'.format(A1[0]))
+            print('   A(1, 1) = {:.2f} nm'.format(A1[1]))
+
+           
+        print('  rms = {:.3e} nm'.format(self.rms(w)))
+        print('  avg = {:.3e} nm'.format(self.avg(w)))
+
+        self.plot()
+
+        if xyOffset is not None:
+            print(' Offsetting mirror center in the xy-plane...')
+            # --------------------------------------------------------
+            self.center = (self.center[0] + xyOffset[0]/self.step_size[0],
+                           self.center[1] + xyOffset[1]/self.step_size[1])
+            print('  New mirror center (x0, y0) = ({:.2f}, {:.2f})'.format(self.center[0],self.center[1]))
+            
+        print(' Writing phase map to file...')
+        # --------------------------------------------------------
+        filename = self.name + '_finesse.txt'
+        self.write_map(filename)
+        print('  Phase map written to file {:s}'.format(filename))
+        self.plot()
+
+        print(' Writing result information to file...')
+        filename = self.name + '_finesse_info.txt'
+        self.writeResults(filename)
+        print('  Result written to file {:s}'.format(filename))
+        # Add "create aperture map"
+        
+    
+    def writeResults(self, filename):
+        '''
+        Writing results to file. Not yet finished.
+        '''
+        import time
+        with open(filename,'w') as mapfile:
+            mapfile.write('---------------------------------------\n')
+            mapfile.write('Map:  {:s}\n'.format(self.name))
+            mapfile.write('Date:  {:s}\n'.format(time.strftime("%d/%m/%Y  %H:%M:%S")))
+            mapfile.write('---------------------------------------\n')
+            mapfile.write('Diameter:  {:.2f} cm\n'.format(self.find_radius(unit='meters')/100.0))
+            # mapfile.write('Offset (Z00):  {:.2f}'.format(self.zernikeRemoved['00'][2]))
+          
         
     def removeOffset(self, r):
         '''
@@ -969,7 +1107,7 @@ class surfacemap(object):
         rho = rho/R
         Z00 = zernike(0, 0, rho, phi)
         self.data[self.notNan] = self.data[self.notNan]-A0*Z00[self.notNan]
-        self.zernikesRemoved = (0, 0, A0)
+        self.zernikeRemoved = (0, 0, A0)
 
         return A0