diff --git a/pykat/optics/maps.py b/pykat/optics/maps.py
index d9becc3dca1766e375e5e0c8434d41cb6b1989da..c792d0a29574f9ac42aa9e1fa67e2c36fe77fc8c 100644
--- a/pykat/optics/maps.py
+++ b/pykat/optics/maps.py
@@ -13,14 +13,29 @@ from __future__ import absolute_import
 from __future__ import division
 from __future__ import print_function
 
-from pykat.optics.romhom import makeReducedBasis, makeEmpiricalInterpolant, makeWeights, makeWeightsNew
+from pykat.optics.romhom import makeWeightsNew
 from scipy.interpolate import interp2d, interp1d
 from pykat.maths.zernike import *        
 
 import numpy as np
 import math
 import pickle
-		   
+
+class MirrorROQWeights:
+    
+    def __init__(self, rFront, rBack, tFront, tBack):
+        self.rFront = rFront
+        self.rBack = rBack
+        self.tFront = tFront
+        self.tBack = tBack
+    
+    def writeToFile(self, romfilename):
+        with open(romfilename + ".rom", "w+") as f:
+            if self.rFront is not None: self.rFront.writeToFile(f=f)
+            if self.rBack  is not None: self.rBack.writeToFile(f=f)
+            if self.tFront is not None: self.tFront.writeToFile(f=f)
+            if self.tBack  is not None: self.tBack.writeToFile(f=f)
+                    
 class surfacemap(object):
     def __init__(self, name, maptype, size, center, step_size, scaling, data=None):
         
@@ -111,7 +126,7 @@ class surfacemap(object):
     def ROMWeights(self):
         return self._rom_weights
     
-    def z_xy(self, x=None, y=None, wavelength=1064e-9, direction="11", nr1=1.0, nr2=1.0):
+    def z_xy(self, x=None, y=None, wavelength=1064e-9, direction="reflection_front", nr1=1.0, nr2=1.0):
         """
         For this given map the field perturbation is computed. This data
         is used in computing the coupling coefficient. It returns a grid
@@ -119,13 +134,21 @@ class surfacemap(object):
         of the field.
         
             x, y      : Points to interpolate at, 'None' for no interpolation.
+            
             wavelength: Wavelength of light in vacuum [m]
-            direction : 11 (reflection front)
-                        12 (transmission front to back)
-                        21 (transmission back to front)
-                        22 (reflection back)
+            
+            direction : Sets which distortion to return, as beams travelling
+                        in different directions will see different distortions.
+                        Options are:
+                                "reflection_front"
+                                "transmission_front" (front to back)
+                                "transmission_back" (back to front)
+                                "reflection_back"
+                                
             nr1       : refractive index on front side
+            
             nr2       : refractive index on back side
+            
         """
         
         assert(nr1 >= 1)
@@ -138,35 +161,35 @@ class surfacemap(object):
                 self.__interp = interp2d(self.x, self.y, self.data * self.scaling)
                 
             data = self.__interp(x, y)
-            
-        if direction == "11" or direction == "22":
+        
+        if direction == "reflection_front" or direction == "reflection_back":
             if "phase" in self.type:
-                k = math.pi * nr1 * 2 / wavelength
+                k = math.pi * 2 / wavelength
                 
-                if direction == "11":
-                    return np.exp(-2j * k * data)
+                if direction == "reflection_front":
+                    return np.exp(-2j * nr1 * k * data)
                 else:
-                    return np.exp(2j * k * data[:, ::-1])
+                    return np.exp(2j * nr2 * k * data[:,::-1])
                 
             elif "absorption" in self.type:
-                if direction == "11":
+                if direction == "reflection_front":
                     return np.sqrt(1.0 - data)
                 else:
                     return np.sqrt(1.0 - data[:, ::-1])
             else:
                 raise BasePyKatException("Map type needs handling")
                 
-        elif direction == "12" or direction == "21":
+        elif direction == "transmission_front" or direction == "transmission_back":
             if "phase" in self.type:
                 k = math.pi * 2 / wavelength
                 
-                if direction == "12":
-                    return np.exp((nr1-nr2)*k * data)
+                if direction == "transmission_front":
+                    return np.exp((nr1-nr2) * k * data)
                 else:
-                    return np.exp((nr1-nr2)*k * data[:, ::-1])
+                    return np.exp((nr2-nr1) * k * data[:, ::-1])
                 
             elif "absorption" in self.type:
-                if direction == "12":
+                if direction == "transmission_front":
                     return np.sqrt(1.0 - data)
                 else:
                     return np.sqrt(1.0 - data[:, ::-1])
@@ -178,7 +201,8 @@ class surfacemap(object):
         
 
     
-    def generateROMWeights(self, EIxFilename, EIyFilename=None, verbose=False, interpolate=False, newtonCotesOrder=8):
+    def generateROMWeights(self, EIxFilename, EIyFilename=None, nr1=1.0, nr2=1.0, verbose=False, interpolate=False, newtonCotesOrder=8):
+        
         if interpolate == True:
             # Use EI nodes to interpolate if we
             with open(EIxFilename, 'rb') as f:
@@ -200,9 +224,42 @@ class surfacemap(object):
             
             self.interpolate(nx, ny)
         
-        self._rom_weights = makeWeightsNew(self, EIxFilename, EIyFilename, verbose=verbose, newtonCotesOrderMapWeight=newtonCotesOrder)
-        return self.ROMWeights
-
+        w_refl_front, w_refl_back, w_tran_front, w_tran_back = (None, None, None, None)
+        
+        if "reflection" in self.type or "both" in self.type:
+            w_refl_front = makeWeightsNew(self, EIxFilename, EIyFilename,
+                                      verbose=verbose, newtonCotesOrderMapWeight=newtonCotesOrder,
+                                      direction="reflection_front")
+            
+            w_refl_front.nr1 = nr1
+            w_refl_front.nr2 = nr2
+            
+            w_refl_back = makeWeightsNew(self, EIxFilename, EIyFilename,
+                                      verbose=verbose, newtonCotesOrderMapWeight=newtonCotesOrder,
+                                      direction="reflection_back")
+            
+            w_refl_back.nr1 = nr1
+            w_refl_back.nr2 = nr2
+
+        if "transmission" in self.type or "both" in self.type:                                      
+            w_tran_front = makeWeightsNew(self, EIxFilename, EIyFilename,
+                                      verbose=verbose, newtonCotesOrderMapWeight=newtonCotesOrder,
+                                      direction="transmission_front")
+
+            w_refl_front.nr1 = nr1
+            w_refl_front.nr2 = nr2
+                                            
+            w_tran_back  = makeWeightsNew(self, EIxFilename, EIyFilename,
+                                      verbose=verbose, newtonCotesOrderMapWeight=newtonCotesOrder,
+                                      direction="transmission_back")
+            
+            w_refl_back.nr1 = nr1
+            w_refl_back.nr2 = nr2
+            
+        self._rom_weights = MirrorROQWeights(w_refl_front, w_refl_back, w_tran_front, w_tran_back)
+        
+        return self._rom_weights
+            
     def interpolate(self, nx, ny, **kwargs):
         """
         Interpolates the map for some new x and y values.
@@ -307,6 +364,28 @@ class mergedmap:
         self.__center = value
         self.__interp = None
     
+    @property
+    def type(self):
+        hasR = False
+        hasT = False
+        
+        _type = ""
+        
+        for m in self.__maps:
+            if "reflection" in m.type: hasR = True
+            
+            if "transmission" in m.type: hasT = True
+            
+            if "both" in m.type:
+                hasR = True
+                hasT = True
+        
+        if hasR and not hasT: _type += "reflection "
+        elif hasR and not hasT: _type += "transmission "
+        elif hasR and hasT: _type += "both "
+        
+        return _type
+        
     @property
     def step_size(self):
         return self.__step_size
@@ -345,7 +424,7 @@ class mergedmap:
     def ROMWeights(self):
         return self._rom_weights
     
-    def z_xy(self, wavelength=1064e-9, direction="reflection", nr1=1.0, nr2=1.0):
+    def z_xy(self, wavelength=1064e-9, direction="reflection_front", nr1=1.0, nr2=1.0):
         
         z_xy = np.ones(self.size, dtype=np.complex128)
         
@@ -357,7 +436,7 @@ class mergedmap:
         else:
             return z_xy * self.weighting
         
-    def generateROMWeights(self, EIxFilename, EIyFilename=None, verbose=False, interpolate=False, newtonCotesOrder=8):
+    def generateROMWeights(self, EIxFilename, EIyFilename=None, verbose=False, interpolate=False, newtonCotesOrder=8, nr1=1, nr2=1):
         if interpolate == True:
             # Use EI nodes to interpolate if we
             with open(EIxFilename, 'rb') as f:
@@ -379,9 +458,41 @@ class mergedmap:
             
             self.interpolate(nx, ny)
         
-        self._rom_weights = makeWeightsNew(self, EIxFilename, EIyFilename, verbose=verbose, newtonCotesOrderMapWeight=newtonCotesOrder)
+        w_refl_front, w_refl_back, w_tran_front, w_tran_back = (None, None, None, None)
+        
+        if "reflection" in self.type or "both" in self.type:
+            w_refl_front = makeWeightsNew(self, EIxFilename, EIyFilename,
+                                      verbose=verbose, newtonCotesOrderMapWeight=newtonCotesOrder,
+                                      direction="reflection_front")
+            
+            w_refl_front.nr1 = nr1
+            w_refl_front.nr2 = nr2
+            
+            w_refl_back = makeWeightsNew(self, EIxFilename, EIyFilename,
+                                      verbose=verbose, newtonCotesOrderMapWeight=newtonCotesOrder,
+                                      direction="reflection_back")
+            
+            w_refl_back.nr1 = nr1
+            w_refl_back.nr2 = nr2
+
+        if "transmission" in self.type or "both" in self.type:                                      
+            w_tran_front = makeWeightsNew(self, EIxFilename, EIyFilename,
+                                      verbose=verbose, newtonCotesOrderMapWeight=newtonCotesOrder,
+                                      direction="transmission_front")
+
+            w_refl_front.nr1 = nr1
+            w_refl_front.nr2 = nr2
+                                            
+            w_tran_back  = makeWeightsNew(self, EIxFilename, EIyFilename,
+                                      verbose=verbose, newtonCotesOrderMapWeight=newtonCotesOrder,
+                                      direction="transmission_back")
+            
+            w_refl_back.nr1 = nr1
+            w_refl_back.nr2 = nr2
+            
+        self._rom_weights = MirrorROQWeights(w_refl_front, w_refl_back, w_tran_front, w_tran_back)
         
-        return self.ROMWeights
+        return self._rom_weights
 
     def interpolate(self, nx, ny, **kwargs):
         """
diff --git a/pykat/optics/romhom.py b/pykat/optics/romhom.py
index ce21548da02bbd35b0ae9cbb32df5f7c74911e6e..67e81716ee9d046aedb1544cddd3fc48dd9031fa 100644
--- a/pykat/optics/romhom.py
+++ b/pykat/optics/romhom.py
@@ -21,35 +21,52 @@ from pykat.maths import newton_weights
 from scipy.integrate import newton_cotes
 from multiprocessing import Process, Queue, Array, Value, Event
 
-
 EmpiricalInterpolant = collections.namedtuple('EmpiricalInterpolant', 'B nodes node_indices limits x worst_error')
 ReducedBasis = collections.namedtuple('ReducedBasis', 'RB limits x')
 ROMLimits = collections.namedtuple('ROMLimits', 'zmin zmax w0min w0max R mapSamples max_order')
                        
 class ROMWeights:
     
-    def __init__(self, w_ij_Q1, w_ij_Q2, w_ij_Q3, w_ij_Q4, EIx, EIy):
+    def __init__(self, w_ij_Q1, w_ij_Q2, w_ij_Q3, w_ij_Q4, EIx, EIy, nr1=1, nr2=1, direction="reflection_front"):
         self.w_ij_Q1 = w_ij_Q1
         self.w_ij_Q2 = w_ij_Q2
         self.w_ij_Q3 = w_ij_Q3
         self.w_ij_Q4 = w_ij_Q4
         
+        self.nr1 = nr1
+        self.nr2 = nr2
+        
+        self.direction = direction 
+        
         self.EIx = EIx
         self.EIy = EIy
         
-    def writeToFile(self, filename):
+    def writeToFile(self, filename=None, f=None):
         """
         Writes this map's ROM weights to a file
         that can be used with Finesse. The filename
         is appended with '.rom' internally.
+        
+        Specify either a filename to write the data too, the existing file is overwritten.
+        Or provide an open file object to be written too.
         """
-        f = open(filename + ".rom", 'w+')
         
+        if filename is None and f is None:
+            raise ValueError("'filename' or open file object 'f' should be specified")
+        
+        if f is None:
+            f = open(filename + ".rom", 'w+')
+        
+        f.write("direction=%s\n" % self.direction)
         f.write("zmin=%16.16e\n" % self.EIx.limits.zmin)
         f.write("zmax=%16.16e\n" % self.EIx.limits.zmax)
         f.write("w0min=%16.16e\n" % self.EIx.limits.w0min)
         f.write("w0max=%16.16e\n" % self.EIx.limits.w0max)
         f.write("maxorder=%i\n" % self.EIx.limits.max_order)
+        f.write("R=%16.16e\n" % self.EIx.limits.R)
+        f.write("mapSamples=%i\n" % self.EIx.limits.mapSamples)
+        f.write("nr1=%16.16e\n" % self.nr1)
+        f.write("nr2=%16.16e\n" % self.nr2)
         
         f.write("xnodes=%i\n" % len(self.EIx.nodes))
         
@@ -80,47 +97,10 @@ class ROMWeights:
         
         for v in self.w_ij_Q4.flatten():
             f.write("%s\n" % repr(complex(v))[1:-1])
-            
-        f.close()
 
-class ROMWeightsFull:
-    
-    def __init__(self, w_ij, EI, limits):
-        self.w_ij = w_ij
-        
-        self.EI = EI
-        self.limits = limits
-        
-    def writeToFile(self, filename):
-        """
-        Writes this map's ROM weights to a file
-        that can be used with Finesse. The filename
-        is appended with '.rom' internally.
-        """
-        f = open(filename + ".rom", 'w+')
-        
-        f.write("zmin=%16.16e\n" % self.limits.zmin)
-        f.write("zmax=%16.16e\n" % self.limits.zmax)
-        f.write("w0min=%16.16e\n" % self.limits.w0min)
-        f.write("w0max=%16.16e\n" % self.limits.w0max)
-        f.write("maxorder=%i\n" % self.limits.max_order)
-        
-        f.write("xnodes=%i\n" % len(self.EI["x"].nodes))
-        
-        for v in self.EI["x"].nodes.flatten():
-            f.write("%s\n" % repr(float(v)))
-        
-        f.write("ynodes=%i\n" % len(self.EI["y"].nodes))
-        
-        for v in self.EI["y"].nodes.flatten():
-            f.write("%s\n" % repr(float(v)))
-            
-        f.write(repr(self.w_ij.shape) + "\n")
-        
-        for v in self.w_ij.flatten():
-            f.write("%s\n" % repr(complex(v))[1:-1])
-        
-        f.close()
+        if filename is not None:
+            f.close()
+
         
 def combs(a, r):
     """
@@ -174,305 +154,11 @@ def u_star_u(re_q1, re_q2, w0_1, w0_2, n1, n2, x, x2=None):
 def u_star_u_mm(z, w0, n1, n2, x):
     return u(z, w0, n1, x) * u(z, w0, n2, x).conjugate()
     
-################################################################################################
-################################################################################################
-################################################################################################
-
-def makeReducedBasis(x, isModeMatched=True, tolerance = 1e-12, sigma = 1, greedyfile=None):
-    
-    if greedyfile is not None:
-        greedypts = str(greedyfile)
-    else:
-        if isModeMatched:
-            greedypts = 'matched20.txt'
-        else:
-            greedypts = 'mismatched20.txt'
-    
-    greedyfile = os.path.join(pykat.__path__[0],'optics','greedypoints',greedypts)
-    
-    # Two potential different formats
-    try:
-        limits = np.loadtxt(greedyfile, usecols=(3,))[:5]
-    except IndexError:
-        limits = np.loadtxt(greedyfile, usecols=(1,))[:5]
-    
-    romlimits = ROMLimits(w0min=limits[0], w0max=limits[1], zmin=limits[2], zmax=limits[3], max_order=limits[4])
-    
-    w_min = limits[0]
-    w_max = limits[1]
-
-    re_q_min = limits[2]
-    re_q_max = limits[3]
-    
-    max_order = int(limits[4])
-    
-    indices = range(0, max_order+1)
-    nm_pairs = combs(indices, 2)
-    
-    dx = x[1] - x[0]
-    
-    params = np.loadtxt(greedyfile, skiprows=5)
-
-    TS_size = len(params) # training space of TS_size number of waveforms
-    
-    #### allocate memory for training space ####
-
-    TS = np.zeros(TS_size*len(x), dtype = complex).reshape(TS_size, len(x)) # store training space in TS_size X len(x) array
-
-    IDx = 0 #TS index 
-
-    for i in range(len(params)):
-        if isModeMatched:
-            q1 = beam_param(w0=float(params[i][0]), z=float(params[i][1]))
-            q2 = q1
-            n = int(params[i][2])
-            m = int(params[i][3])
-        else:
-            q1 = beam_param(w0=float(params[i][0]), z=float(params[i][2]))
-            q2 = beam_param(w0=float(params[i][1]), z=float(params[i][3]))            
-            n = int(params[i][4])
-            m = int(params[i][5])
-            
-        w0_1 = q1.w0
-        w0_2 = q2.w0
-        re_q1 = q1.z
-        re_q2 = q2.z
-            
-        TS[IDx] = u_star_u(re_q1, re_q2, w0_1, w0_2, n, m, x)
-        
-        # normalize
-        norm = np.sqrt(abs(np.vdot(dx * TS[IDx], TS[IDx])))
-    
-        if norm != 0:
-            TS[IDx] /= norm 
-            IDx += 1
-        else:
-            np.delete(TS, IDx)	
-
-    #### Begin greedy: see Field et al. arXiv:1308.3565v2 #### 
-
-    RB_matrix = [TS[0]] # seed greedy algorithm (arbitrary)
-
-    proj_coefficients = np.zeros(TS_size*TS_size, dtype = complex).reshape(TS_size, TS_size)
-    projections = np.zeros(TS_size*len(x), dtype = complex).reshape(TS_size, len(x))
-
-    iter = 0
-    
-    while sigma > tolerance:
-    #for k in range(TS_size-1):
-    	# go through training set and find worst projection error
-    	projections = project_onto_basis(dx, RB_matrix, TS, projections, proj_coefficients, iter)
-    	residual = TS - projections
-        
-    	projection_errors = [np.vdot(dx* residual[i], residual[i]) for i in range(len(residual))]
-    	sigma = abs(max(projection_errors))
-    	index = np.argmax(projection_errors) 
-        
-    	#Gram-Schmidt to get the next basis and normalize
-    	next_basis = TS[index] - projections[index]
-    	next_basis /= np.sqrt(abs(np.vdot(dx* next_basis, next_basis)))
-
-    	RB_matrix.append(next_basis)		
-        
-    	iter += 1
-        
-        
-    return ReducedBasis(RB=np.array(RB_matrix), limits=romlimits, x=x)
-    
-def makeEmpiricalInterpolant(RB, sort=False):
-
-    e_x = RB.RB
-    x = RB.x
-    
-    node_indices = []
-    x_nodes = []
-    V = np.zeros((len(e_x), len(e_x)), dtype = complex)
-    
-    # seed EIM algorithm
-    node_indices.append( int(np.argmax( np.abs(e_x[0]) ))) 
-    x_nodes.append(x[node_indices]) 
-    
-    for i in range(1, len(e_x)): 
-        #build empirical interpolant for e_iter
-        for j in range(len(node_indices)):  
-            for k in range(len(node_indices)):  
-                V[k][j] = e_x[j][node_indices[k]]  
-            
-        invV = inv(V[0:len(node_indices), 0:len(node_indices)])  
-        B = B_matrix(invV, e_x) 
-        
-        interpolant = emp_interp(B, e_x[i], node_indices) 
-        res = interpolant - e_x[i] 
-
-        index = int(np.argmax(np.abs(res))) 
-        node_indices.append(index) 
-        x_nodes.append( x[index] )
-    
-    # make B matrix with all the indices
-    for j in range(len(node_indices)):
-        for k in range(len(node_indices)):
-            V[k][j] = e_x[j][node_indices[k]]
-
-    invV = inv(V[0:len(node_indices), 0:len(node_indices)])
-    B = np.array(B_matrix(invV, e_x))
-    
-    node_indices = np.array(node_indices, dtype=np.int32)
-    nodes = np.array(x_nodes, dtype=np.float64)
-    
-    if sort:
-        print (sort)
-        ix = np.argsort(nodes)
-        nodes = nodes[ix]
-        node_indices = node_indices[ix]
-        B = B[ix, :]
-    
-    return EmpiricalInterpolant(B=B, nodes=nodes, node_indices=node_indices, limits=RB.limits, x=RB.x)
-    
-
-def makeWeights(smap, EI, verbose=True, useSymmetry=True, newtonCotesOrder=1):
-    
-    if useSymmetry:
-        # get full A_xy
-        A_xy = smap.z_xy()
-    
-        xm = smap.x[smap.x < 0]
-        xp = smap.x[smap.x > 0]
-    
-        ym = smap.y[smap.y < 0]
-        yp = smap.y[smap.y > 0]
-    
-        Q1xy = np.ix_(smap.x < 0, smap.y > 0)
-        Q2xy = np.ix_(smap.x > 0, smap.y > 0)
-        Q3xy = np.ix_(smap.x > 0, smap.y < 0)
-        Q4xy = np.ix_(smap.x < 0, smap.y < 0)
-    
-        # get A_xy in the four quadrants of the x-y plane
-        A_xy_Q1 = A_xy[Q1xy]
-        A_xy_Q2 = A_xy[Q2xy]
-        A_xy_Q3 = A_xy[Q3xy]
-        A_xy_Q4 = A_xy[Q4xy]
-    
-        # Not sure if there is a neater way to select the x=0,y=0 cross elements
-        A_xy_0  = np.hstack([A_xy[:,smap.x==0].flatten(), A_xy[smap.y==0,:].flatten()])
-    
-        full_x = smap.x
-        full_y = smap.y
-
-        dx = full_x[1] - full_x[0]
-        dy = full_y[1] - full_y[0]
-
-        if verbose:
-            count  = 4*len(EI["x"].B) * len(EI["y"].B)
-            p = ProgressBar(maxval=count, widgets=["Computing weights: ", Percentage(), Bar(), ETA()])
-    
-        n = 0
-    
-        # make integration weights
-        Bx = EI["x"].B
-        By = EI["y"].B[:,::-1]
-        w_ij_Q1 = np.zeros((len(Bx),len(By)), dtype = complex)
-
-        from pykat.optics.knm import newton_weights
-        
-        wx = newton_weights(xm, newtonCotesOrder)
-        wy = newton_weights(ym, newtonCotesOrder)
-        
-        for i in range(len(Bx)):
-            for j in range(len(By)):
-                B_ij_Q1 = np.outer(wx*Bx[i], wy*By[j])
-                w_ij_Q1[i][j] = dx*dy*np.einsum('ij,ij', B_ij_Q1, A_xy_Q1)	
-            
-                if verbose:
-                    p.update(n)
-                    n+=1
-
-        Bx = EI["x"].B[:,::-1]
-        By = EI["y"].B[:,::-1]
-        w_ij_Q2 = np.zeros((len(Bx),len(By)), dtype = complex)
-    
-        for i in range(len(Bx)):
-            for j in range(len(By)):
-                B_ij_Q2 = np.outer(wx*Bx[i], wy*By[j])
-                w_ij_Q2[i][j] = dx*dy*np.einsum('ij,ij', B_ij_Q2, A_xy_Q2)
-            
-                if verbose:
-                    p.update(n)
-                    n+=1
-
-        Bx = EI["x"].B[:,::-1]
-        By = EI["y"].B
-        w_ij_Q3 = np.zeros((len(Bx),len(By)), dtype = complex)
-    
-        for i in range(len(Bx)):
-            for j in range(len(By)):
-                B_ij_Q3 = np.outer(wx*Bx[i], wy*By[j])
-                w_ij_Q3[i][j] = dx*dy*np.einsum('ij,ij', B_ij_Q3, A_xy_Q3)
-
-                if verbose:
-                    p.update(n)
-                    n+=1
-
-        Bx = EI["x"].B
-        By = EI["y"].B
-        w_ij_Q4 = np.zeros((len(Bx),len(By)), dtype = complex)
-    
-        for i in range(len(Bx)):
-            for j in range(len(By)):
-                B_ij_Q4 = np.outer(wx*Bx[i], wy*By[j])
-                w_ij_Q4[i][j] = dx*dy*np.einsum('ij,ij', B_ij_Q4, A_xy_Q4)
-
-                if verbose:
-                    p.update(n)
-                    n+=1
-        if verbose:
-            p.finish()
-        
-        return ROMWeights(w_ij_Q1=w_ij_Q1, w_ij_Q2=w_ij_Q2, w_ij_Q3=w_ij_Q3, w_ij_Q4=w_ij_Q4, EI=EI, limits=EI["x"].limits)
-        
-    else:
-        # get full A_xy
-        A_xy = smap.z_xy()
-
-        full_x = smap.x
-        full_y = smap.y
-
-        dx = full_x[1] - full_x[0]
-        dy = full_y[1] - full_y[0]
-
-        if verbose:
-            count  = len(EI["x"].B) * len(EI["y"].B)
-            p = ProgressBar(maxval=count, widgets=["Computing weights: ", Percentage(), Bar(), ETA()])
-
-        n = 0
-
-        # make integration weights
-        Bx = EI["x"].B
-        By = EI["y"].B
-        
-        w_ij = np.zeros((len(Bx), len(By)), dtype = complex)
-
-        for i in range(len(Bx)):
-            for j in range(len(By)):
-                B_ij = np.outer(Bx[i], By[j])
-                w_ij[i][j] = dx*dy*np.einsum('ij,ij', B_ij, A_xy)	
-    
-                if verbose:
-                    p.update(n)
-                    n+=1
-                    
-        if verbose:
-            p.finish()
-
-        return ROMWeightsFull(w_ij=w_ij, EI=EI, limits=EI["x"].limits)
-
 
-###################################################################################################
-###################################################################################################
 ###################################################################################################
 # !!! New ROM code below that doesn't need supercomputer
 ###################################################################################################
-###################################################################################################
-###################################################################################################
+
 def _compute_TS(queue, oqueue, x, w):
     while True:
         msg = queue.get()
@@ -829,7 +515,8 @@ def MakeROMFromHDF5(hdf5Filename, greedyFilename=None, EIFilename=None, tol=1e-1
     return EI
     
     
-def makeWeightsNew(smap, EIxFilename, EIyFilename=None, verbose=True, newtonCotesOrderMapWeight=8):
+def makeWeightsNew(smap, EIxFilename, EIyFilename=None, verbose=True, newtonCotesOrderMapWeight=8, direction="reflection_front"):
+    
     with open("%s" % EIxFilename, 'rb') as f:
         EIx = pickle.load(f)
         
@@ -839,8 +526,10 @@ def makeWeightsNew(smap, EIxFilename, EIyFilename=None, verbose=True, newtonCote
         with open("%s" % EIyFilename, 'rb') as f:
             EIy = pickle.load(f)
     
-    A_xy = smap.z_xy() * np.outer(newton_weights(smap.x, newtonCotesOrderMapWeight), 
-                                  newton_weights(smap.y, newtonCotesOrderMapWeight))
+    W_nc = np.outer(newton_weights(smap.x, newtonCotesOrderMapWeight), 
+                    newton_weights(smap.y, newtonCotesOrderMapWeight))
+                    
+    A_xy = smap.z_xy(direction=direction)[::-1, :].T.conj() * W_nc.T
     
     xm = smap.x[smap.x <= 0]
     xp = smap.x[smap.x >= 0]
@@ -939,4 +628,4 @@ def makeWeightsNew(smap, EIxFilename, EIyFilename=None, verbose=True, newtonCote
     if verbose:
         p.finish()
     
-    return ROMWeights(w_ij_Q1=w_ij_Q1, w_ij_Q2=w_ij_Q2, w_ij_Q3=w_ij_Q3, w_ij_Q4=w_ij_Q4, EIx=EIx, EIy=EIy)
\ No newline at end of file
+    return ROMWeights(w_ij_Q1=w_ij_Q1, w_ij_Q2=w_ij_Q2, w_ij_Q3=w_ij_Q3, w_ij_Q4=w_ij_Q4, EIx=EIx, EIy=EIy, direction=direction)
\ No newline at end of file