maps.py 4.59 KB
Newer Older
1
from pykat.utilities.romhom import makeReducedBasis, makeEmpiricalInterpolant, makeWeights
Daniel Brown's avatar
Daniel Brown committed
2
import numpy as np
3
import math
Daniel Brown's avatar
Daniel Brown committed
4
5
        
        
Daniel Brown's avatar
Daniel Brown committed
6
class surfacemap(object):
7
8
9
10
11
12
13
    def __init__(self, name, maptype, size, center, step_size, scaling, data=None):
        
        self.name = name
        self.type = maptype
        self.center = center
        self.step_size = step_size
        self.scaling = scaling
Daniel Brown's avatar
Daniel Brown committed
14
15
16
17
18
19

        if data == None:
            self.data = np.zeros(size)
        else:
            self.data = data

20
        self._rom_weights = None
21
22
23
24
25
26
27
        
    def write_map(self, filename):
        with open(filename,'w') as mapfile:
            
            mapfile.write("% Surface map\n")
            mapfile.write("% Name: {0}\n".format(self.name))
            mapfile.write("% Type: {0}\n".format(self.type))
28
            mapfile.write("% Size: {0} {1}\n".format(self.data.shape[0], self.data.shape[1]))
29
30
31
32
33
34
35
36
37
38
            mapfile.write("% Optical center (x,y): {0} {1}\n".format(self.center[0], self.center[1]))
            mapfile.write("% Step size (x,y): {0} {1}\n".format(self.step_size[0], self.step_size[1]))
            mapfile.write("% Scaling: {0}\n".format(float(self.scaling)))
            mapfile.write("\n\n")
            
            for i in range(0, self.data.shape[0]):
                for j in range(0, self.data.shape[1]):
                    mapfile.write("%.15g " % self.data[i,j])
                mapfile.write("\n")
    
Daniel Brown's avatar
Daniel Brown committed
39
40
    @property
    def x(self):
Daniel Brown's avatar
Daniel Brown committed
41
        return self.step_size[0] * (np.array(range(1, self.data.shape[0]+1)) - self.center[0])
Daniel Brown's avatar
Daniel Brown committed
42
43
44
        
    @property
    def y(self):
Daniel Brown's avatar
Daniel Brown committed
45
        return self.step_size[1] * (np.array(range(1, self.data.shape[1]+1))- self.center[1])
46
47
48
49
50

    @property
    def size(self):
        return self.data.shape
            
51
52
    @property
    def offset(self):
Daniel Brown's avatar
Daniel Brown committed
53
        return np.array(self.step_size)*(self.center - np.array(self.size)/2)
54
55
56
57
    
    @property
    def ROMWeights(self):
        return self._rom_weights
58
59
60
61
62
    
    def z_xy(self, wavelength=1064e-9):
        
        if "phase" in self.type:
            k = math.pi * 2 / wavelength
Daniel Brown's avatar
Daniel Brown committed
63
            return np.exp(2j * k * self.scaling * self.data)
64
65
66
        else:
            raise BasePyKatException("Map type needs handling")
        
Daniel Brown's avatar
Daniel Brown committed
67

68
    def generateROMWeights(self, isModeMatched=True, verbose=False):
Daniel Brown's avatar
Daniel Brown committed
69
70
71
72
73
74
75
76
77
78
        xm = self.x[self.x<0]
        ym = self.y[self.y<0]
        
        EI = {}
        
        if len(xm) > 0: EI["xm"] = makeEmpiricalInterpolant(makeReducedBasis(xm, isModeMatched=isModeMatched))
        if len(ym) > 0: EI["ym"] = makeEmpiricalInterpolant(makeReducedBasis(ym, isModeMatched=isModeMatched))
        
        EI["limits"] = EI["xm"].limits
        
79
        self._rom_weights = makeWeights(self, EI, verbose=verbose)
80
        
81
        return self.ROMWeights, EI
82
        
83
    def plot(self, show=True, clabel=None):
84
85
86
        
        import pylab
        
87
        # 100 factor for scaling to cm
Daniel Brown's avatar
Daniel Brown committed
88
89
        xrange = 100*self.x
        yrange = 100*self.y
90
91
92
93
94
        
        fig = pylab.figure()
        axes = pylab.imshow(self.data, extent=[min(xrange),max(xrange),min(yrange),max(yrange)])
        pylab.xlabel('x [cm]')
        pylab.ylabel('y [cm]')
95

96
        pylab.title('Surface map {0}, type {1}'.format(self.name, self.type))
97
        
98
        cbar = fig.colorbar(axes)
99
100
101
102
103
104
105
106
        
        if clabel != None:
            cbar.set_label(clabel)
                
        if show:
            pylab.show()
            
        return fig
107

Daniel Brown's avatar
Daniel Brown committed
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

class tiltmap(surfacemap):
    
    def __init__(self, name, size, step_size, tilt):
        surfacemap.__init__(self, name, "phase", size, (np.array(size)+1)/2.0, step_size, 1)
        self.tilt = tilt
        
    @property
    def tilt(self):
        return self.__tilt
    
    @tilt.setter
    def tilt(self, value):
        self.__tilt = value
        
        xx, yy = np.meshgrid(self.x, self.y)
        
125
        self.data = xx * self.tilt[1] + yy * self.tilt[0]
Daniel Brown's avatar
Daniel Brown committed
126
127
        
        
128
        
129
130
131
132
133
134
135
136
137
138
139
140
141
def read_map(filename):
    with open(filename, 'r') as f:
        
        f.readline()
        name = f.readline().split(':')[1].strip()
        maptype = f.readline().split(':')[1].strip()
        size = tuple(map(lambda x: int(x), f.readline().split(':')[1].strip().split()))
        center = tuple(map(lambda x: float(x), f.readline().split(':')[1].strip().split()))
        step = tuple(map(lambda x: float(x), f.readline().split(':')[1].strip().split()))
        scaling = float(f.readline().split(':')[1].strip())
        
        
        
Daniel Brown's avatar
Daniel Brown committed
142
    data = np.loadtxt(filename, dtype=np.float64,ndmin=2,comments='%')    
143
144
145
146
147
148
        
    return surfacemap(name,maptype,size,center,step,scaling,data)