node_network.py 9.09 KB
Newer Older
Daniel Brown's avatar
Daniel Brown committed
1
2
3
4
5
6
7
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 27 10:02:41 2013

@author: Daniel
"""
import exceptions
8
import pykat.gui.graphics
9
import pykat.exceptions as pkex
Daniel Brown's avatar
Daniel Brown committed
10
11
12
from pykat.components import Component
from pykat.detectors import Detector

13
class NodeNetwork(object):
Daniel Brown's avatar
Daniel Brown committed
14
15
16
17
18
19
20
21
22
    def __init__(self, kat):
        self._nodes = {}
        self.__kat = kat
        
    def createNode(self, node_name):
        if node_name == 'dump':
            return DumpNode()
            
        if node_name in self._nodes:
23
24
            # then this node already exists
            return self._nodes[node_name]
Daniel Brown's avatar
Daniel Brown committed
25
        else:
Daniel Brown's avatar
Daniel Brown committed
26
            n = Node(node_name, self)
27
            self.__add_node(n) # add node as a member of this object, e.g. kat.nodes.n
Daniel Brown's avatar
Daniel Brown committed
28
29
            self._nodes[node_name] = n
            return n
30
31
32
33
34
        
    def removeNode(self, node):
        if not isinstance(node,Node):
            raise exceptions.ValueError("node argument is not of type Node")
        
Daniel Brown's avatar
Daniel Brown committed
35
        if node.name not in self._nodes:
36
37
38
39
40
41
            raise exceptions.RuntimeError("Trying to remove node {0} when it has not been added".format(node.name))
        
        C = node.getComponents()
        
        if C[0][0] is not None or C[0][1] is not None:
            raise exceptions.RuntimeError("Cannot remove a node which is attached to components still")
Daniel Brown's avatar
Daniel Brown committed
42
            
43
44
45
        if len(C[1]) > 0:
            raise exceptions.RuntimeError("Cannot remove a node which is attached to detectors still")
        
46
        self.__remove_node(node)
47
48
        del self._nodes[node.name] 
        
Daniel Brown's avatar
Daniel Brown committed
49
50
    def hasNode(self, name):
        return (name in self._nodes)
51
52
53
54
    
    def getNodes(self):
        return self._nodes.copy()
    
Daniel Brown's avatar
Daniel Brown committed
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    def dumpInfo(self):
        
        for name in self._nodes:
            
            n = self._nodes[name]
            items = n.getComponents()
            comp = items[0][:]
            det = items[1]
            
            if comp[0] == None:
                comp1 = 'dump'
            else:
                comp1 = comp[0].name
            
            if comp[1] == None:
                comp2 = 'dump'
            else:
                comp2 = comp[1].name    
            
            detectors = ""
            
            if len(det) > 0:
                detectors = "Detectors: "
                
                for d in det:
                    detectors = detectors + d.name + " "
                
            print "node: {0} connected:{1} {2}->{3} {4}".format(
                    n.name,n.isConnected(),comp1, comp2, detectors)
84
85
86
87
88
       
    def __add_node(self, node):

        if not isinstance(node, Node):
            raise exceptions.ValueError("Argument is not of type Node")
Daniel Brown's avatar
Daniel Brown committed
89
        
90
91
92
93
94
        name = node.name
        fget = lambda self: self.__get_node(name)
        
        setattr(self.__class__, name, property(fget))
        setattr(self, '__node_' + name, node)                   
Daniel Brown's avatar
Daniel Brown committed
95
    
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    def __remove_node(self, node):
        if not isinstance(node, Node):
            raise exceptions.ValueError("Argument is not of type Node")
        
        name = node.name
        setattr(self, '__node_' + name)
        delattr(self.__class__, name)
        
    def __get_node(self, name):
        return getattr(self, '__node_' + name)        
        
class Node(object):
    class gauss_version:
        w0_z = 1
        z_zR = 2
        
112
    def __init__(self, name, network):
Daniel Brown's avatar
Daniel Brown committed
113
114
115
116
        self._comp1 = None
        self._comp2 = None
        self._detectors = []
        self.__name = name
117
        self._item = None
Daniel Brown's avatar
Daniel Brown committed
118
        self._network = network
119
120
        self.__gauss = None
        self.__gauss_version = None
121
122
123
        
    @property
    def network(self): return self._network
Daniel Brown's avatar
Daniel Brown committed
124
    
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
    @property
    def gauss(self): return self.__gauss
    
    def removeGauss():
        self.__gauss_version = None
        self.__gauss = None
        
    def gauss_w0_z(self, w0, z, w0y=None, zy=None):
        self.__gauss = []
        self.__gauss.append(w0)
        self.__gauss.append(z)
        
        if w0y != None and zy != None:
            self.__gauss.append(w0y)
            self.__gauss.append(zy)
            
        self.__gauss_version = Node.gauss_version.w0_z
        
    def getFinesseText(self):
        
        if not self.isConnected() or self.__gauss == None or self.__gauss_version == None:
            return None
            
            
        comp = ""
        
        if self._comp2 == None:
            comp = self._comp1.name
        else:
            comp = self._comp2.name
        
        rtn = []
        
        if self.__gauss_version == Node.gauss_version.w0_z:
            
            if len(self.__gauss) == 2:
                rtn.append("gauss gauss_{node} {comp} {node} {w0} {z}".format(node=self.name, comp=comp, w0=self.__gauss[0], z=self.__gauss[1]))
            elif len(self.__gauss) == 4:
                rtn.append("gauss gauss_{node} {comp} {node} {w0x} {zx} {w0y} {zy}".format(node=self.name, comp=comp, w0x=self.__gauss[0], zx=self.__gauss[1], w0y=self.__gauss[2], zy=self.__gauss[3]))
            else:
                raise pkex.BasePyKatException("Unexpected number of gaussian parameters")
        else:
            raise pkex.BasePyKatException("Unexpected gauss version")
            
        return rtn
        
Daniel Brown's avatar
Daniel Brown committed
171
    def isConnected(self):
172
173
174
175
176
177
178
        if (self._comp1 is not None) and (self._comp2 is not None):
            return True
        else:
            return False
      
    def remove(self):
        self._network.removeNode(self)
Daniel Brown's avatar
Daniel Brown committed
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
        
        if self._item != None:
            self._item.scene().removeItem(self._item)
    
    def disconnect(self, obj):
    
        if not (isinstance(obj,Component) or isinstance(obj,Detector)):
            raise exceptions.ValueError("Object is not a component or detector")
        
        if isinstance(obj, Component):
            
            if self._comp1 == obj:
                self._comp1 = None
            elif self._comp2 == obj:
                self._comp2 = None
            else:
                raise exceptions.RuntimeError("Cannot dettach {0} from node {1}".format(
                                    obj.name, self.__name))
          
        else:
            # we must have a detector as we check above            
            self._detectors.remove(obj)
    
        if self._item is not None:
            self._item.refresh()
            
    
Daniel Brown's avatar
Daniel Brown committed
206
207
208
209
210
211
212
213
214
215
216
217
218
    def connect(self, obj):

        if not (isinstance(obj,Component) or isinstance(obj,Detector)):
            raise exceptions.ValueError("Object is not a component or detector")
        
        if isinstance(obj, Component):
            
            if self._comp1 == None:
                self._comp1 = obj
            elif self._comp2 == None:
                self._comp2 = obj
            else:
                raise exceptions.RuntimeError("Cannot attach {0} to node {1} as it is already connected: {2} and {3}".format(
219
220
221
                                    obj.name, self.__name,self._comp1.name,self._comp2.name))
            
            if self._comp1 == self._comp2:
222
                raise exceptions.RuntimeError("Cannot connect {0} to both sides of node".format(obj.name))            
Daniel Brown's avatar
Daniel Brown committed
223
224
225
        else:
            # we must have a detector as we check above            
            self._detectors.append(obj)
226
    
227
228
229
230
231
232
233
234
235
236
237
238
        if self._item is not None:
            self._item.refresh()
            
    def getQGraphicsItem(self,dx=0,dy=0,nsize=8,parent=None):
        if self._item == None:
            self._item = pykat.gui.graphics.NodeQGraphicItem(self,
                                                             dx,dy,
                                                             -nsize/2,-nsize/2,
                                                             nsize,nsize,parent)
            
        return self._item
    
Daniel Brown's avatar
Daniel Brown committed
239
240
241
242
243
244
    def getComponents(self):
        ''' Returns a tuple with the first being the 2 components that 
        connect to the node. The second item is a list of the detectors at the
        node'''
        return [(self._comp1, self._comp2),self._detectors]
        
245
246
    def amIConnected(self, obj):
        """
Daniel Brown's avatar
Daniel Brown committed
247
        Checks if obj is connected to the node. Returns true or false in tuple
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
        with None or the other object and the node index which it is attached to
        """ 
        if obj == self._comp1:
            if self._comp2 == None:
                ix = -1
            else:
                ix = self._comp2.getNodes().index(self)
                
            return [True, self._comp2, ix]
        elif obj == self._comp2:
            if self._comp1 == None:
                ix = -1
            else:
                ix = self._comp1.getNodes().index(self)
                
            return [True, self._comp1, ix]
        else:
            return [False, None]
        
Daniel Brown's avatar
Daniel Brown committed
267
268
269
270
271
272
273
    def __getname(self):
        return self.__name      
        
    name = property(__getname)
    
class DumpNode(Node):
    def __init__(self):
274
        Node.__init__(self, 'dump', None)
Daniel Brown's avatar
Daniel Brown committed
275
276