node_network.py 6.49 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
Daniel Brown's avatar
Daniel Brown committed
9
10
11
from pykat.components import Component
from pykat.detectors import Detector

12
class NodeNetwork(object):
Daniel Brown's avatar
Daniel Brown committed
13
14
15
16
17
18
19
20
21
    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:
22
23
            # then this node already exists
            return self._nodes[node_name]
Daniel Brown's avatar
Daniel Brown committed
24
        else:
Daniel Brown's avatar
Daniel Brown committed
25
            n = Node(node_name, self)
Daniel Brown's avatar
Daniel Brown committed
26
27
            self._nodes[node_name] = n
            return n
28
29
30
31
32
        
    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
33
        if node.name not in self._nodes:
34
35
36
37
38
39
            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
40
            
41
42
43
44
45
        if len(C[1]) > 0:
            raise exceptions.RuntimeError("Cannot remove a node which is attached to detectors still")
        
        del self._nodes[node.name] 
        
Daniel Brown's avatar
Daniel Brown committed
46
47
    def hasNode(self, name):
        return (name in self._nodes)
48
49
50
51
    
    def getNodes(self):
        return self._nodes.copy()
    
Daniel Brown's avatar
Daniel Brown committed
52
53
54
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
    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)
        
82
class Node(object):
Daniel Brown's avatar
Daniel Brown committed
83
    
84
    def __init__(self, name, network):
Daniel Brown's avatar
Daniel Brown committed
85
86
87
88
        self._comp1 = None
        self._comp2 = None
        self._detectors = []
        self.__name = name
89
        self._item = None
Daniel Brown's avatar
Daniel Brown committed
90
        self._network = network
91
92
93
        
    @property
    def network(self): return self._network
Daniel Brown's avatar
Daniel Brown committed
94
95
    
    def isConnected(self):
96
97
98
99
100
101
102
        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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
        
        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
130
131
132
133
134
135
136
137
138
139
140
141
142
    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(
143
144
145
                                    obj.name, self.__name,self._comp1.name,self._comp2.name))
            
            if self._comp1 == self._comp2:
146
                raise exceptions.RuntimeError("Cannot connect {0} to both sides of node".format(obj.name))            
Daniel Brown's avatar
Daniel Brown committed
147
148
149
        else:
            # we must have a detector as we check above            
            self._detectors.append(obj)
150
    
151
152
153
154
155
156
157
158
159
160
161
162
        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
163
164
165
166
167
168
    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]
        
169
170
    def amIConnected(self, obj):
        """
Daniel Brown's avatar
Daniel Brown committed
171
        Checks if obj is connected to the node. Returns true or false in tuple
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
        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
191
192
193
194
195
196
197
    def __getname(self):
        return self.__name      
        
    name = property(__getname)
    
class DumpNode(Node):
    def __init__(self):
198
        Node.__init__(self, 'dump', None)
Daniel Brown's avatar
Daniel Brown committed
199
200