| 205 | | class _build_nineml_celltype(type): |
| 206 | | pass |
| 207 | | |
| 208 | | #class _build_nineml_celltype(type): |
| 209 | | # """ |
| 210 | | # Metaclass for building NineMLCellType subclasses |
| 211 | | # """ |
| 212 | | # def __new__(cls, name, bases, dct): |
| 213 | | # assert False |
| 214 | | # |
| 215 | | # # join the neuron and synapse components into a single component |
| 216 | | # combined_model = dct["neuron_model"] |
| 217 | | # for label in dct["synapse_models"].keys(): |
| 218 | | # port_map = dct["port_map"][label] |
| 219 | | # port_map = _add_prefix(dct["synapse_models"][label], label, port_map) |
| 220 | | # dct["weight_variables"][label] = label + "_" + dct["weight_variables"][label] |
| 221 | | # combined_model = join(combined_model, |
| 222 | | # dct["synapse_models"][label], |
| 223 | | # port_map, |
| 224 | | # name=name) |
| 225 | | # dct["combined_model"] = combined_model |
| 226 | | # # set class attributes required for a PyNN cell type class |
| 227 | | # dct["default_parameters"] = dict((name, 1.0) |
| 228 | | # for name in combined_model.parameters) |
| 229 | | # dct["default_initial_values"] = dict((name, 0.0) |
| 230 | | # for name in combined_model.state_variables) |
| 231 | | # dct["synapse_types"] = sorted(dct["synapse_models"]) # using alphabetical order may make things easier code generators |
| 232 | | # dct["injectable"] = True # need to determine this. How?? |
| 233 | | # dct["recordable"] = [port.name for port in combined_model.analog_ports] + ['spikes', 'regime'] |
| 234 | | # dct["standard_receptor_type"] = (dct["synapse_types"] == ('excitatory', 'inhibitory')) |
| 235 | | # dct["conductance_based"] = True # how to determine this?? |
| 236 | | # dct["model_name"] = name |
| 237 | | # logger.debug("Creating class '%s' with bases %s and dictionary %s" % (name, bases, dct)) |
| 238 | | # # generate and compile code, then load the mechanism into the simulator |
| 239 | | # dct["builder"](combined_model, dct["weight_variables"]) # weight variables should really be stored within combined_model |
| 240 | | # return type.__new__(cls, name, bases, dct) |
| 241 | | # |
| 242 | | # |
| 243 | | # |
| 244 | | #def join(c1, c2, port_map=[], name=None): |
| 245 | | # """Create a NineML component by joining the two given components.""" |
| 246 | | # logger.debug("Joining components %s and %s with port map %s" % (c1, c2, port_map)) |
| 247 | | # logger.debug("New component will have name '%s'" % name) |
| 248 | | # # combine bindings from c1 and c2 |
| 249 | | # bindings = {} |
| 250 | | # for b in chain(c1.bindings, c2.bindings): |
| 251 | | # bindings[b.name] = b |
| 252 | | # # combine ports (some will later be removed) |
| 253 | | # all_ports = c1.ports_map.copy() |
| 254 | | # all_ports.update(c2.ports_map) |
| 255 | | # # event ports do not be passed to the constructor, as they are attached to transitions |
| 256 | | # for port_name, port in all_ports.items(): |
| 257 | | # if isinstance(port, nineml.EventPort): |
| 258 | | # all_ports.pop(port_name) |
| 259 | | # # connect ports. |
| 260 | | # # currently, when ports are connected they disappear. It might be better to |
| 261 | | # # explicitly keep the ports in the new component but mark them as connected |
| 262 | | # for name1, name2 in port_map: |
| 263 | | # assert name1 in c1.ports_map, "%s is not in %s" % (name1, c1.ports_map.keys()) |
| 264 | | # assert name2 in c2.ports_map, "%s is not in %s" % (name2, c2.ports_map.keys()) |
| 265 | | # |
| 266 | | # port1 = c1.ports_map[name1] |
| 267 | | # port2 = c2.ports_map[name2] |
| 268 | | # assert port1.mode != port2.mode |
| 269 | | # if port1.mode == 'send': |
| 270 | | # send_port = port1 |
| 271 | | # recv_port = port2 |
| 272 | | # send_port_name = name1 |
| 273 | | # recv_port_name = name2 |
| 274 | | # else: |
| 275 | | # send_port = port2 |
| 276 | | # recv_port = port1 |
| 277 | | # send_port_name = name2 |
| 278 | | # recv_port_name = name1 |
| 279 | | # # when connecting ports in which the send port has an expression, need |
| 280 | | # # to create a binding for this expression in the new component |
| 281 | | # if send_port.expr: |
| 282 | | # func_args = c1.non_parameter_symbols.union(c2.non_parameter_symbols).intersection(send_port.expr.names) |
| 283 | | # lhs = "%s(%s)" % (send_port_name, ",".join(func_args)) |
| 284 | | # send_binding = nineml.Binding(lhs, send_port.expr.rhs) |
| 285 | | # bindings[send_binding.name] = send_binding |
| 286 | | # for eq in chain(c1.equations, c2.equations): |
| 287 | | # if send_port_name in eq.names: |
| 288 | | # eq.rhs = eq.rhs_name_transform({send_port_name: lhs}) |
| 289 | | # if recv_port.mode == 'reduce': |
| 290 | | # # need to retain reduce ports as they can be connected to in a future join |
| 291 | | # if recv_port_name in bindings: |
| 292 | | # # this reduce port has already been connected to, so combine using its reduce_op |
| 293 | | # reduce_binding = bindings[recv_port_name] |
| 294 | | # func_args = func_args.union(reduce_binding.args) |
| 295 | | # lhs = "%s(%s)" % (recv_port_name, ",".join(func_args)) |
| 296 | | # rhs = recv_port.reduce_op.join([reduce_binding.rhs, send_binding.lhs]) |
| 297 | | # else: |
| 298 | | # # this is the first time this reduce port has been connected to |
| 299 | | # lhs = "%s(%s)" % (recv_port_name, ",".join(func_args)) |
| 300 | | # rhs = send_binding.lhs |
| 301 | | # bindings[recv_port_name] = nineml.Binding(lhs, rhs) |
| 302 | | # recv_port.connected = True |
| 303 | | # else: |
| 304 | | # all_ports.pop(name1) |
| 305 | | # else: |
| 306 | | # if recv_port.mode == 'reduce': |
| 307 | | # raise NotImplementedError |
| 308 | | # else: |
| 309 | | # all_ports.pop(name1) |
| 310 | | # |
| 311 | | # if name1 != name2: |
| 312 | | # #c2.substitute(name2, name1) # need to implement this. Currently this all only works if name1 == name2 |
| 313 | | # # probably needs to happen sooner in the function |
| 314 | | # all_ports.pop(name2) |
| 315 | | # |
| 316 | | # # where parameters have become bindings due to connecting ports, replace |
| 317 | | # # bare names with function calls in the equations |
| 318 | | # for bname, binding in bindings.items(): |
| 319 | | # for eq in chain(c1.equations, c2.equations): |
| 320 | | # if bname in eq.names: |
| 321 | | # print "#### replacing %s by %s" % (bname, binding.lhs) |
| 322 | | # pattern = re.compile(r'%s(\([\w\, ]*\))?' % bname) |
| 323 | | # m = pattern.search(eq.rhs) |
| 324 | | # if m: |
| 325 | | # eq.rhs = pattern.sub(binding.lhs, eq.rhs) |
| 326 | | # else: |
| 327 | | # eq.rhs = eq.rhs_name_transform({bname: binding.lhs}) |
| 328 | | # |
| 329 | | # # create new regimes from all possible combinations of the regimes from the |
| 330 | | # # two components |
| 331 | | # regime_map = {} |
| 332 | | # for r1 in c1.regimes: |
| 333 | | # regime_map[r1.name] = {} |
| 334 | | # for r2 in c2.regimes: |
| 335 | | # if r1.name == r2.name: |
| 336 | | # new_name = r1.name |
| 337 | | # else: |
| 338 | | # new_name = "%s_AND_%s" % (r1.name, r2.name) |
| 339 | | # kwargs = {'name': new_name} |
| 340 | | # new_regime = nineml.Regime(*r1.nodes.union(r2.nodes), **kwargs) |
| 341 | | # regime_map[r1.name][r2.name] = new_regime |
| 342 | | # # create transitions between all the new regimes |
| 343 | | # transitions = [] |
| 344 | | # for r1 in c1.regimes: |
| 345 | | # for r2 in c2.regimes: |
| 346 | | # for t in r1.transitions: |
| 347 | | # new_transition = nineml.Transition(*t.nodes, |
| 348 | | # from_=regime_map[r1.name][r2.name], |
| 349 | | # to=regime_map[t.to.name][r2.name], |
| 350 | | # condition=t.condition) |
| 351 | | # transitions.append(new_transition) |
| 352 | | # for t in r2.transitions: |
| 353 | | # new_transition = nineml.Transition(*t.nodes, |
| 354 | | # from_=regime_map[r1.name][r2.name], |
| 355 | | # to=regime_map[r1.name][t.to.name], |
| 356 | | # condition=t.condition) |
| 357 | | # transitions.append(new_transition) |
| 358 | | # |
| 359 | | # regimes = [] |
| 360 | | # for d in regime_map.values(): |
| 361 | | # regimes.extend(d.values()) |
| 362 | | # name = name or "%s__%s" % (c1.name, c2.name) |
| 363 | | # return nineml.Component(name, |
| 364 | | # regimes=regimes, |
| 365 | | # transitions=transitions, |
| 366 | | # ports=all_ports.values(), |
| 367 | | # bindings=bindings.values()) |
| 368 | | # |
| 369 | | |