commands.py 7.23 KB
Newer Older
Daniel Brown's avatar
Daniel Brown committed
1
2
3
4
5
6
7
8
9
10
11
12
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 28 11:58:09 2013

@author: Daniel
"""
import numpy
from numpy import min,max
import exceptions
from components import *
from structs import *
from pykat.param import Param, putter
13
import pykat.exceptions as pkex
Daniel Brown's avatar
Daniel Brown committed
14
from collections import namedtuple
Daniel Brown's avatar
Daniel Brown committed
15
from pykat.utilities.optics.gaussian_beams import gauss_param
Daniel Brown's avatar
Daniel Brown committed
16
17
18

class Command(object):

19
20
21
    tag = None
    __removed = False
        
Daniel Brown's avatar
Daniel Brown committed
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    def getFinesseText(self):
        """ Base class for individual finesse optical components """
        raise NotImplementedError("This function is not implemented")

    @staticmethod
    def parseFinesseText(text):
        raise NotImplementedError("This function is not implemented")

    def _on_kat_add(self, kat):
        """
        Called when this component has been added to a kat object
        """
        self._kat = kat

36
37
38
39
40
41
42
    def remove(self):
        self._kat.remove(self)
        self.__removed = True
    
    @property
    def removed(self): return self.__removed
    
Daniel Brown's avatar
Daniel Brown committed
43
44
class cavity(Command):
    def __init__(self, name, c1, n1, c2, n2):
45
46
        super(Command, self).__init__()
        
Daniel Brown's avatar
Daniel Brown committed
47
48
49
50
51
52
53
54
55
56
57
58
        self.__name = name
        self.__c1 = c1
        self.__c2 = c2
        self.__n1 = n1
        self.__n2 = n2

    def getFinesseText(self):
        return 'cav {0} {1} {2} {3} {4}'.format(self.__name, self.__c1, self.__n1, self.__c2, self.__n2);

class gauss(object):
    @staticmethod
    def parseFinesseText(text, kat):
59
        values = text.split()
60
        if not values[0].startswith("gauss") or (len(values) != 6 and len(values) != 8):
61
62
            raise exceptions.RuntimeError("'{0}' not a valid Finesse gauss command".format(text))        
        
63
64
65
66
        name = values[1]
        component = values[2]
        node = values[3]
        
Daniel Brown's avatar
Daniel Brown committed
67
        if values[0]:
68
            if len(values) == 6:
Daniel Brown's avatar
Daniel Brown committed
69
                gp = gauss_param(w0=values[-2], z=values[-1])
70
            elif len(values) == 8:
Daniel Brown's avatar
Daniel Brown committed
71
72
                gpx = gauss_param(w0=values[-4], z=values[-3])
                gpy = gauss_param(w0=values[-2], z=values[-1])
73
74
        elif values[0].endswith("*"):
            if len(values) == 6:
Daniel Brown's avatar
Daniel Brown committed
75
                gp = gauss_param(z=values[-2], zr=values[-1])
76
            elif len(values) == 8:
Daniel Brown's avatar
Daniel Brown committed
77
78
                gpx = gauss_param(z=values[-4], zr=values[-3])
                gpy = gauss_param(z=values[-2], zr=values[-1])
Daniel Brown's avatar
Daniel Brown committed
79
        elif values[0].endswith("**"):
80
            if len(values) == 6:
Daniel Brown's avatar
Daniel Brown committed
81
                gp = gauss_param(w=values[-2], rc=values[-1])
82
            elif len(values) == 8:
Daniel Brown's avatar
Daniel Brown committed
83
84
                gpx = gauss_param(w=values[-4], rc=values[-3])
                gpy = gauss_param(w=values[-2], rc=values[-1])
Daniel Brown's avatar
Daniel Brown committed
85
86
87
        else:
            raise pkex.BasePyKatException("Unexpected ending to gauss command '{0}'".format(text))
            
Daniel Brown's avatar
Daniel Brown committed
88
89
90
91
        if len(values) == 6:
            kat.nodes[node].setGauss(kat.components[component], gp)
        else:
            kat.nodes[node].setGauss(kat.components[component], gpx, gpy)
92
            
Daniel Brown's avatar
Daniel Brown committed
93
class tf(Command):
94
    fQ = namedtuple('fQ', ['f', 'Q'])
Daniel Brown's avatar
Daniel Brown committed
95
96
    
    def __init__(self, name, poles, zeros):
97
        super(Command, self).__init__()
Daniel Brown's avatar
Daniel Brown committed
98
99
        pass
      
Daniel Brown's avatar
Daniel Brown committed
100
class xaxis(Command):
101
102
103
104
105
    """
    The xaxis object is a unique object to each pykat.finesse.kat instance. It provides
    and interface to the xaxis command in FINESSE.
    """
    
106
107
108
    @property
    def name(self): return self._axis_type
    
109
    def __init__(self, scale, limits, param, steps, comp=None, axis_type="xaxis"):
110
111
112
113
114
115
116
117
118
        """
        Typical usage:
            xaxis(["lin" or "log"], [upper, lower], param, steps)
            
        param must be an object of the type pykat.param.Param whose
        isPutable() member returns true.
        
        steps is the number of points to compute between upper and lower limits.
        """
119
120
        super(Command, self).__init__()
        
Daniel Brown's avatar
Daniel Brown committed
121
122
123
124
125
126
        self._axis_type = axis_type

        self.x = putter("x1")
        self.mx = putter("mx1")

        if scale == "lin":
127
            scale = Scale.linear
Daniel Brown's avatar
Daniel Brown committed
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
        elif scale == "log":
            scale = Scale.logarithmic
        elif isinstance(scale, str):
            # else we have a string but not a recognisable one
            raise exceptions.ValueError("scale argument '{0}' is not valid, must be 'lin' or 'log'".format(scale))

        if scale != Scale.linear and scale != Scale.logarithmic:
            raise exceptions.ValueError("scale is not Scale.linear or Scale.logarithmic")

        self.scale = scale

        if numpy.size(limits) != 2 :
            raise exceptions.ValueError("limits input should be a 2x1 vector of limits for the xaxis")

        self.limits = numpy.array(SIfloat(limits)).astype(float)

        if steps <= 0 :
            raise exceptions.ValueError("steps value should be > 0")

        self.steps = int(steps)

        if isinstance(param, str):
            self.__param = param
151
152
153
154
            if comp == None:
                raise pkex.BasePyKatException("If parameter is set with a string, the comp argument must set the component name")
                
            self.__comp = comp
Daniel Brown's avatar
Daniel Brown committed
155
        elif not isinstance(param, Param) :
156
            raise pkex.BasePyKatException("param argument is not of type Param")
Daniel Brown's avatar
Daniel Brown committed
157
158
        else:
            self.__param = param
159
            self.__comp = param._owner().name
Daniel Brown's avatar
Daniel Brown committed
160

161
162
163
164
165
166
167
168
    @property
    def param(self): return self.__param
    @param.setter
    def param(self, value):
	if not isinstance(value, Param):
		raise pkex.BasePyKatException("param argument is not of type Param")
	else:
		self.__param = value
169
		self.__comp = value._owner().name
170

Daniel Brown's avatar
Daniel Brown committed
171
172
    @staticmethod
    def parseFinesseText(text):
173
        values = text.split()
Daniel Brown's avatar
Daniel Brown committed
174
175
176
177
178
179
180
181
182
183
184

        if values[0] != "xaxis" and values[0] != "xaxis*":
            raise exceptions.RuntimeError("'{0}' not a valid Finesse xaxis command".format(text))

        axis_type = values[0]

        values.pop(0) # remove initial value

        if len(values) != 6:
            raise exceptions.RuntimeError("xaxis Finesse code format incorrect '{0}'".format(text))

185
        return xaxis(values[2], [values[3], values[4]], values[1], values[5], comp=values[0], axis_type=axis_type)
Daniel Brown's avatar
Daniel Brown committed
186
187
188
189
190
191
192
193
194
195
196

    def getFinesseText(self):
        # store either the component name of the string provided
        comp_name = self.__comp.name if isinstance(self.__comp, Component) else self.__comp
        param_name = self.__param.name if isinstance(self.__param, Param) else self.__param

        return '{axis_type} {0} {1} {2} {3} {4} {5}'.format(
                comp_name, param_name, self.scale,
                min(self.limits), max(self.limits), self.steps, axis_type=self._axis_type);

class x2axis(xaxis):
197
198
    def __init__(self, scale, limits, param, steps, comp=None):
        xaxis.__init__(self, scale, limits, param, steps, comp=comp, axis_type="x2axis")
Daniel Brown's avatar
Daniel Brown committed
199
200
201
202
203
        self.x = putter("x2")
        self.mx = putter("mx2")

    @staticmethod
    def parseFinesseText(text):
204
        values = text.split()
Daniel Brown's avatar
Daniel Brown committed
205
206
207
208
209
210
211
212
213
214
215

        if values[0] != "x2axis" and values[0] != "x2axis*":
            raise exceptions.RuntimeError("'{0}' not a valid Finesse xaxis command".format(text))

        axis_type = values[0]

        values.pop(0) # remove initial value

        if len(values) != 6:
            raise exceptions.RuntimeError("xaxis Finesse code format incorrect '{0}'".format(text))

216
        return x2axis(values[2], [values[3], values[4]], values[1], values[5], comp=values[0])