Example #1
0
    def test_flatten_first_level(self):
        # Signature: name(nested_list)
                # Flattens the first level of an iterable, ie
                #
                # >>> flatten_first_level( [ ['This','is'],['a','short'],['phrase'] ] ) #doctest: +NORMALIZE_WHITESPACE
                # ['This', 'is', 'a', 'short', 'phrase']
        from nineml.utility import flatten_first_level
        from nineml.exceptions import NineMLRuntimeError

        self.assertEqual(
            flatten_first_level([[1, 2], [3, 4, 5], [6]]),
            [1, 2, 3, 4, 5, 6]
        )

        self.assertEqual(
            flatten_first_level(((1, 2), (3, 4, 5), (6,))),
            [1, 2, 3, 4, 5, 6]
        )

        # Check nesting is not flattened:
        self.assertEqual(
            flatten_first_level([[1, ['a', 'b'], 2], [3, 4, ['c', 'd'], 5], [6]]),
            [1, ['a', 'b'], 2, 3, 4, ['c', 'd'], 5, 6]
        )

        self.assertRaises(NineMLRuntimeError, flatten_first_level, [None])
        self.assertRaises(NineMLRuntimeError, flatten_first_level, ['abbn'])
        self.assertRaises(NineMLRuntimeError, flatten_first_level, [True])
        self.assertRaises(NineMLRuntimeError, flatten_first_level, [None, None])
Example #2
0
    def __init__(self, component, componentname=None):
        assert isinstance(component, ComponentClass)

        # Is our component already flat??
        if component.is_flat():
            self.reducedcomponent = ClonerVisitor().visit(component)
            if component.was_flattened():
                self.reducedcomponent.set_flattener(component.flattener)
            return

        # New components name
        self.componentname = componentname if componentname else component.name

        # Make a clone of the component; in which all hierachical components
        # have their internal symbols prefixed:
        cloned_comp = ClonerVisitorPrefixNamespace().visit(component)

        # Make a list of all components, and those components with regimes:
        self.all_components = list(cloned_comp.query.recurse_all_components)
        self.componentswithregimes = [
            m for m in self.all_components if list(m.regimes)]

        # This will get filled in build_new_regime_space():
        # (It maps { (Regime,Regime,...,Regime) : Regime, (Regime,Regime,...,Regime) : Regime,}
        # Where the key tuple represents the regimes in the hierachical component,
        # corresponding to self.componentswithregimes.
        # And the values are the regimes in the new component.
        self.old_regime_tuple_to_new_regime_map = None

        # OK, Heavy-lifting Code:
        # ===================== #
        self.build_new_regime_space()

        # Build Our New Component
        self.reducedcomponent = ComponentClass(
            name=self.componentname,
            aliases=flatten_first_level(
                [m.aliases for m in self.all_components]),
            state_variables=flatten_first_level(
                [m.state_variables for m in self.all_components]),
            regimes=self.old_regime_tuple_to_new_regime_map.values(),
            analog_ports=flatten_first_level(
                [comp.analog_ports for comp in self.all_components]),
            event_ports=flatten_first_level(
                [comp.event_ports for comp in self.all_components]),
            parameters=flatten_first_level([m.parameters
                                            for m in self.all_components]))

        self.remap_analog_ports()

        # Attach this flattening information to the component:
        self.reducedcomponent.set_flattener(self)
Example #3
0
    def create_compound_regime(cls, regimetuple):

        # Copy accross all the odes from each regime.
        # We don't worry about transitions yet, we deal with them later.

        # We need to clone the time_derivatives:
        time_derivs = flatten_first_level([r.time_derivatives for r in regimetuple])
        time_derivs = [ClonerVisitor().visit(td) for td in time_derivs]

        return nineml.al.Regime(name=None, time_derivatives=time_derivs)
Example #4
0
    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()]
                del self.reducedcomponent._analog_receive_ports[
                                                     dst_addr.get_local_name()]
#                     expect_single([p 
#                                    for p in self.reducedcomponent.analog_receive_ports
#                                    if p.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)
Example #5
0
    def concat(cls, *args):
        """Concatenates all the Namespace Addresses.

        This method take all the arguments supplied, converts each one into a
        namespace object, then, produces a new namespace object which is the
        concatenation of all the arguments' namespaces.

        For example:

        >>> NamespaceAddress.concat('first.second','third.forth','fifth.sixth')
            NameSpaceAddress: '/first/second/third/forth/fifth/sixth'


        """

        # Turn all the arguments into NamespaceAddress Objects:
        args = [NamespaceAddress(a) for a in args]

        # Combine all the location tuples in each argument
        # into one long list.
        loc = flatten_first_level([list(a.loctuple) for a in args])

        # Create a namespace out of this long new tuple:
        return NamespaceAddress(loc=tuple(loc))