node_network.py 5.66 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:
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
33
34
35
36
37
38
39
        
    def removeNode(self, node):
        if not isinstance(node,Node):
            raise exceptions.ValueError("node argument is not of type Node")
        
        if node not in self._nodes:
            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
90
91
92
93
        self._item = None
        self._network = None
        
    @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
103
        if (self._comp1 is not None) and (self._comp2 is not None):
            return True
        else:
            return False
      
    def remove(self):
        self._network.removeNode(self)
        self._item.scene().removeItem(self._item)
104
                      
Daniel Brown's avatar
Daniel Brown committed
105
106
107
108
109
110
111
112
113
114
115
116
117
    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(
118
119
120
                                    obj.name, self.__name,self._comp1.name,self._comp2.name))
            
            if self._comp1 == self._comp2:
121
                raise exceptions.RuntimeError("Cannot connect {0} to both sides of node".format(obj.name))            
Daniel Brown's avatar
Daniel Brown committed
122
123
124
        else:
            # we must have a detector as we check above            
            self._detectors.append(obj)
125
    
126
127
128
129
130
131
132
133
134
135
136
137
        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
138
139
140
141
142
143
    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]
        
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
    def amIConnected(self, obj):
        """
        Checks if obj is connected oto the node. Returns true or false in tuple
        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
166
167
168
169
170
171
172
    def __getname(self):
        return self.__name      
        
    name = property(__getname)
    
class DumpNode(Node):
    def __init__(self):
173
        Node.__init__(self, 'dump', None)
Daniel Brown's avatar
Daniel Brown committed
174
175