1 |
blocknameindex = {} |
2 |
|
3 |
PORT_IN = 0 |
4 |
PORT_OUT = 1 |
5 |
PORT_INOUT = 11 |
6 |
|
7 |
class BlockInstance: |
8 |
""" |
9 |
Application-layer representation of an instance of a Block on the Canvas. |
10 |
Includes a reference to the BlockType as well as the block's name. |
11 |
Eventually, the instance will include a reference to the corresponding |
12 |
ASCEND object, allowing results from the ASCEND solver to be inspected via |
13 |
the Canvas GUI. |
14 |
""" |
15 |
# FIXME still need some way of setting *parameters* associated with a block. |
16 |
|
17 |
def __init__(self,blocktype,name=None): |
18 |
self.blocktype = blocktype; |
19 |
n = str(blocktype.type.getName()) |
20 |
if not blocknameindex.has_key(n): |
21 |
blocknameindex[n] = 0 |
22 |
blocknameindex[n] += 1 |
23 |
if name is None: |
24 |
name = self.get_default_name() |
25 |
self.name = name |
26 |
self.tab = 0 |
27 |
self.color_r = 1 |
28 |
self.color_g = 1 |
29 |
self.color_b = 1 |
30 |
self.instance = 0 |
31 |
self.ports = {} |
32 |
#self.stream = '' |
33 |
for n in self.blocktype.inputs: |
34 |
self.ports[n[0]] = PortInstance(self,n[0], n[1], PORT_IN) |
35 |
for n in self.blocktype.outputs: |
36 |
self.ports[n[0]] = PortInstance(self,n[0], n[1], PORT_OUT) |
37 |
self.params = {} |
38 |
for n in self.blocktype.params: |
39 |
self.params[n[0]] = (ParamInstance(self,n[0],n[1])) |
40 |
|
41 |
self.usercode = "" |
42 |
|
43 |
def get_default_name(self): |
44 |
n = str(self.blocktype.type.getName()) |
45 |
if not blocknameindex.has_key(n): |
46 |
print "the key '%s' is not in blocknameindex" % n |
47 |
|
48 |
return "%s%s" % (n, blocknameindex[n]) |
49 |
|
50 |
def __str__(self): |
51 |
return "\t%s IS_A %s;\n" % (self.name,self.blocktype.type.getName()) |
52 |
|
53 |
def reattach_ascend(self,ascwrap,notesdb): |
54 |
if type(self.blocktype.type) == str: |
55 |
self.blocktype.reattach_ascend(ascwrap, notesdb) |
56 |
|
57 |
for port in self.ports: |
58 |
self.ports[port].type = ascwrap.findType(self.ports[port].type) |
59 |
|
60 |
for param in self.params: |
61 |
self.params[param].type = ascwrap.findType(self.params[param].type) |
62 |
|
63 |
def __getstate__(self): |
64 |
#Return state values to pickle without blockinstance.instance |
65 |
state = self.__dict__.copy() |
66 |
del state['instance'] |
67 |
return(state) |
68 |
|
69 |
def __setstate__(self, state): |
70 |
#Restore state values from pickle |
71 |
self.__dict__ = state |
72 |
|
73 |
|
74 |
class PortInstance: |
75 |
""" |
76 |
Application-layer representation of a Port, which is a variable inside a |
77 |
MODEL which is connectable using the Canvas GUI. Class includes the name of |
78 |
the variable represented by the Port, but no type information, as that is |
79 |
currently difficult to extract from the ASCEND API. |
80 |
""" |
81 |
def __init__(self,blockinstance,name, type, io): |
82 |
self.blockinstance = blockinstance |
83 |
self.name = name |
84 |
self.type = type |
85 |
self.io = io |
86 |
|
87 |
def __getstate__(self): |
88 |
state = self.__dict__.copy() |
89 |
state['type'] = str(self.type) |
90 |
return(state) |
91 |
|
92 |
def __setstate__(self, state): |
93 |
self.__dict__ = state |
94 |
|
95 |
class ParamInstance: |
96 |
""" |
97 |
Application-layer representation of a Parameter, which is a variable inside a |
98 |
MODEL the value for which should be settable using the Canvas GUI. Currently |
99 |
we have no information about the type of the parameter (its units etc) |
100 |
because that data is still difficult to extract from the ASCEND API. |
101 |
""" |
102 |
def __init__(self,blockinstance,name,type): |
103 |
self.blockinstance = blockinstance |
104 |
self.name = name |
105 |
self.type = type |
106 |
self.fix = False |
107 |
self.value = self.get_initial_value() |
108 |
self.fix = self.set_initial_state() |
109 |
if self.type.getPreferredUnits(): |
110 |
self.units=str(self.type.getPreferredUnits().getName()) |
111 |
else: |
112 |
self.units=str(self.type.getDimensions().getDefaultUnits().getName()) |
113 |
if self.units == '1': |
114 |
self.units = '' |
115 |
|
116 |
def get_description(self): |
117 |
""" |
118 |
The parameter description (if it exists) is stored in the NOTE from the |
119 |
original MODEL file. This will go and get it (and saves us from storing |
120 |
it in the Pickle. |
121 |
""" |
122 |
# find the correct parameter |
123 |
desc = "" |
124 |
for p in self.blockinstance.blocktype.params: |
125 |
if p[0] == self.name: |
126 |
desc = p[2] |
127 |
return desc.split(":",2)[1].strip().split("=")[0].strip() |
128 |
|
129 |
def get_initial_value(self): |
130 |
''' |
131 |
This will get the initial parameter value |
132 |
given in the NOTE |
133 |
dp "param: pressure rise due to the pump = 10{atm}" IS_A delta_pressure; |
134 |
this methos will return 10{atm} |
135 |
''' |
136 |
|
137 |
desc = "" |
138 |
for p in self.blockinstance.blocktype.params: |
139 |
if p[0] == self.name: |
140 |
desc = p[2] |
141 |
|
142 |
temp = desc.split(":",2)[1].strip().split("=") |
143 |
|
144 |
|
145 |
if(len(temp)==1): |
146 |
return None # for no value |
147 |
|
148 |
temp2 = temp[1].split("[") |
149 |
|
150 |
# for free state |
151 |
# print len(temp2) |
152 |
if(len(temp2)>1): |
153 |
self.fix = False |
154 |
else: |
155 |
self.fix = True |
156 |
|
157 |
#print self.fix |
158 |
if(self.fix): |
159 |
return temp[1].strip().split("{")[0].strip() + temp[1].strip().split("{")[1].strip().split("}")[0].strip()# for fixed state |
160 |
else: |
161 |
return temp2[1].split("]")[0].strip() # for free state |
162 |
|
163 |
def set_initial_state(self): |
164 |
''' |
165 |
This will return initial state of the parameter i.e. FIX or FREE |
166 |
''' |
167 |
self.get_initial_value() |
168 |
if (self.fix): |
169 |
return True # for fix |
170 |
else: |
171 |
return False # for free |
172 |
|
173 |
|
174 |
def getValue(self): |
175 |
if self.value: |
176 |
return (str(self.value)) |
177 |
else: |
178 |
return(' '+str(self.units)) |
179 |
|
180 |
def setValue(self,conv,units): |
181 |
if self.value: |
182 |
self.value=self.value*conv |
183 |
self.units=units |
184 |
return(str(self.value)+' '+str(self.units)) |
185 |
else: |
186 |
self.units=units |
187 |
return(' '+str(self.units)) |
188 |
|
189 |
def __getstate__(self): |
190 |
state = self.__dict__.copy() |
191 |
state['type'] = str(self.type) |
192 |
return(state) |
193 |
|
194 |
def __setstate__(self, state): |
195 |
self.__dict__ = state |
196 |
|
197 |
class LineInstance: |
198 |
def __init__(self,fromport=None,toport=None): |
199 |
self.fromport = fromport |
200 |
self.toport = toport |
201 |
|
202 |
def __str__(self): |
203 |
""" |
204 |
Create a string for use in MODEL export. |
205 |
""" |
206 |
if self.fromport and self.toport: |
207 |
fromname = "%s.%s" % (self.fromport.blockinstance.name, self.fromport.name) |
208 |
toname = "%s.%s" % (self.toport.blockinstance.name, self.toport.name) |
209 |
return "\t%s, %s ARE_THE_SAME;\n" % (fromname, toname) |
210 |
return "" |
211 |
|
212 |
# TODO set up reversible properties...? |
213 |
|
214 |
# vim: set ts=4 noet: |