def load_single_internal_maths_block(self, element, checkOnlyBlock=True): if checkOnlyBlock: elements = list(element.iterchildren(tag=etree.Element)) if len(elements) != 1: print elements assert False, 'Unexpected tags found' assert (len(element.findall(MATHML + "MathML")) + len(element.findall(NINEML + "MathInline")) + len(element.findall(NINEML + "Value")) + len(element.findall(NINEML + "Piecewise"))) == 1 if element.findall(NINEML + "MathInline"): mblock = expect_single(element.findall(NINEML + 'MathInline')).text.strip() elif element.findall(MATHML + "MathML"): mblock = self.load_mathml(expect_single(element.findall(MATHML + "MathML"))) elif element.findall(NINEML + "Value"): mblock = self.load_value(expect_single(element.findall(NINEML + "Value"))) elif element.findall(NINEML + "Piecewise"): mblock = self.load_piecewise(expect_single(element.findall(NINEML + "Piecewise"))) return mblock
def ode_for(regime, variable): """ Yields the TimeDerivative for the given variable in the regime """ odes = [eq for eq in regime.time_derivatives if eq.dependent_variable == variable.name] if len(odes) == 0: odes.append(al.TimeDerivative(dependent_variable = variable, rhs = "0.0")) return expect_single(odes)
def load_oncondition(self, element): subblocks = ('Trigger', 'StateAssignment', 'EventOut') subnodes = self.loadBlocks(element, blocks=subblocks) target_regime = element.get('target_regime', None) trigger = expect_single(subnodes["Trigger"]) return al.OnCondition(trigger=trigger, state_assignments=subnodes["StateAssignment"], event_outputs=subnodes["EventOut"], target_regime_name=target_regime)
def load_componentclass(self, element): blocks = ('Parameter', 'RandomDistribution') subnodes = self.loadBlocks(element, blocks=blocks) random_distribution = expect_single(subnodes["RandomDistribution"]) return ComponentClass(name=element.get('name'), random_distribution=random_distribution, parameters=subnodes["Parameter"])
def load_piecewise(self, piecewise): pieces = [] for elem in piecewise.findall(NINEML + "Piece"): pieces.append([e.text.strip() for e in elem.findall(NINEML + "MathInline")]) otherwise = piecewise.findall(NINEML + "Otherwise") assert len(otherwise) < 2 if len(otherwise): elem = expect_single(otherwise[0].findall(NINEML + "MathInline")) pieces.append([elem.text.strip(), 'otherwise']) return pieces
def remap_analog_ports(self): new_analog_ports = flatten_first_level( [comp.analog_ports for comp in self.all_components]) new_analog_ports = dict([(p.name, p) for p in new_analog_ports]) # Handle port mappings: # portconnections = [ (NS -> NS), (NS -> NS ), (NS -> NS) ] portconnections = [ model.portconnections for model in self.all_components] portconnections = list(itertools.chain(* portconnections)) # ONLY ANALOG PORTS portconnections = [pc for pc in portconnections if pc[ 0].get_local_name() in new_analog_ports] # A. Handle Receive Ports: for src_addr, dst_addr in portconnections[:]: srcport = new_analog_ports[src_addr.get_local_name()] dstport = new_analog_ports[dst_addr.get_local_name()] if dstport.mode == 'recv': ExpandPortDefinition(originalname=dstport.name, targetname=srcport.name).visit( self.reducedcomponent) del new_analog_ports[dst_addr.get_local_name()] self.reducedcomponent._analog_ports.remove( expect_single([p for p in self.reducedcomponent.analog_ports if p.name == dst_addr.get_local_name()])) portconnections.remove((src_addr, dst_addr)) # B. Handle Reduce Ports: # 1/ Make a map { reduce_port -> [send_port1, send_port2, send_port3], # ...} reduce_connections = defaultdict(list) for src, dst in portconnections: dstport = new_analog_ports[dst.get_local_name()] srcport = new_analog_ports[src.get_local_name()] if dstport.mode == 'reduce': reduce_connections[dstport].append(srcport) # 2/ Substitute each reduce port in turn: for dstport, srcport_list in reduce_connections.iteritems(): src_subs = [s.name for s in srcport_list] terms = [dstport.name] + src_subs reduce_expr = dstport.reduce_op.join(terms) # globalRemapPort( dstport.name, reduce_expr ) ExpandPortDefinition(originalname=dstport.name, targetname=reduce_expr).visit( self.reducedcomponent)
def load_single_internal_maths_block(self, element, checkOnlyBlock=True): if checkOnlyBlock: elements = list(element.iterchildren(tag=etree.Element)) if len(elements) != 1: print elements assert False, 'Unexpected tags found' assert len(element.findall(NINEML + "MathML")) == 0 assert len(element.findall(NINEML + "MathInline")) == 1 return expect_single(element.findall(NINEML + 'MathInline')).text
def load_componentclass(self, element): blocks = ('Parameter', 'AnalogPort', 'EventPort', 'Dynamics', 'Subnode', 'ConnectPorts', 'Component') subnodes = self.loadBlocks(element, blocks=blocks) dynamics = expect_single(subnodes["Dynamics"]) return al.ComponentClass(name=element.get('name'), parameters=subnodes["Parameter"], analog_ports=subnodes["AnalogPort"], event_ports=subnodes["EventPort"], dynamics=dynamics, subnodes=dict(subnodes['Subnode']), portconnections=subnodes["ConnectPorts"])
def test_expect_single(self): # Signature: name(lst, error_func=None) # Retrieve a single element from an iterable. # # This function tests whether an iterable contains just a single element and # if so returns that element. Otherwise it raises an Exception. # # :param lst: An iterable # # :param error_func: An exception object or a callable. ``error_func`` will be # raised or called in case there is not exactly one element in ``lst``. If # ``error_func`` is ``None``, a ``NineMLRuntimeError`` exception will be # raised. # # # :rtype: the element in the list, ``lst[0]``, provided ``len(lst)==1`` # # # # >>> expect_single( ['hello'] ) # 'hello' # # >>> expect_single( [1] ) # 1 # # >>> expect_single( [] ) #doctest: +SKIP # NineMLRuntimeError: expect_single() recieved an iterable of length: 0 # # >>> expect_single( [None,None] ) #doctest: +SKIP # NineMLRuntimeError: expect_single() recieved an iterable of length: 2 # # >>> expect_single( [], lambda: raise_exception( RuntimeError('Aggh') ) #doctest: +SKIP # RuntimeError: Aggh # # >>> #Slightly more tersly: # >>> expect_single( [], RuntimeError('Aggh') ) #doctest: +SKIP # RuntimeError: Aggh from nineml.utility import expect_single from nineml.exceptions import NineMLRuntimeError # Empty Objects should raise: self.assertRaises(NineMLRuntimeError, expect_single, []) self.assertRaises(NineMLRuntimeError, expect_single, tuple()) self.assertRaises(NineMLRuntimeError, expect_single, set()) # Dictionaries should raise: self.assertRaises(NineMLRuntimeError, expect_single, {}) self.assertRaises(NineMLRuntimeError, expect_single, {1: None}) self.assertRaises(NineMLRuntimeError, expect_single, {1: None, 2: True}) # Strings should raise: self.assertRaises(NineMLRuntimeError, expect_single, "") self.assertRaises(NineMLRuntimeError, expect_single, "A") self.assertRaises(NineMLRuntimeError, expect_single, "AA") # Two items should raise: self.assertRaises(NineMLRuntimeError, expect_single, [None, None]) self.assertRaises(NineMLRuntimeError, expect_single, [True, False]) self.assertRaises(NineMLRuntimeError, expect_single, [True, True]) self.assertRaises(NineMLRuntimeError, expect_single, ["Hello", "World"]) # Some good cases: self.assertEqual(expect_single([None]), None) self.assertEqual(expect_single([1]), 1) self.assertEqual(expect_single([2]), 2) self.assertEqual(expect_single(['2']), '2') self.assertEqual(expect_single(['hello']), 'hello')
def load_randomdistribution(self, element): blocks = ('StandardLibrary',) subnodes = self.loadBlocks(element, blocks=blocks) #TODO: Only implemented built-in distributions at this stage return expect_single(subnodes['StandardLibrary'])