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