class TestPreserveIndices(unittest.TestCase): def setUp(self): self.parameters = ['P4', 'P1', 'P3', 'P5', 'P2'] self.state_variables = ['SV3', 'SV5', 'SV4', 'SV2', 'SV1'] self.regimes = ['R2', 'R3', 'R1'] self.time_derivatives = {'R1': ['SV5', 'SV1', 'SV4', 'SV3', 'SV2'], 'R2': ['SV2', 'SV4'], 'R3': ['SV4', 'SV2', 'SV1']} self.aliases = ['A4', 'A3', 'A1', 'A2'] # Create a dynamics object with elements in a particular order self.d = Dynamics( name='d', parameters=[Parameter(p) for p in self.parameters], state_variables=[StateVariable(sv) for sv in self.state_variables], regimes=[Regime(name=r, time_derivatives=[ TimeDerivative(td, '{}/t'.format(td)) for td in self.time_derivatives[r]], transitions=[ OnCondition( 'SV1 > P5', target_regime_name=self.regimes[ self.regimes.index(r) - 1])]) for r in self.regimes], aliases=[Alias(a, 'P{}'.format(i + 1)) for i, a in enumerate(self.aliases)]) def test_clone(self): clone_d = self.d.clone() self._test_indices(clone_d) def test_serialization(self): for ext in ext_to_format: fname = mkstemp(suffix=ext)[1] try: self.d.write(fname, register=False, preserve_order=True) except NineMLSerializerNotImportedError: continue reread_d = nineml.read(fname + '#d') self._test_indices(reread_d) def _test_indices(self, dyn): # Set indices of parameters in non-ascending order so that they # can be differentiated from indices on read. for i, p in enumerate(self.parameters): self.assertEqual(dyn.index_of(dyn.parameter(p)), i) for i, sv in enumerate(self.state_variables): self.assertEqual(dyn.index_of(dyn.state_variable(sv)), i) for i, r in enumerate(self.regimes): self.assertEqual(dyn.index_of(dyn.regime(r)), i) for r, tds in self.time_derivatives.items(): regime = dyn.regime(r) for i, td in enumerate(tds): self.assertEquals( regime.index_of(regime.time_derivative(td)), i) for i, a in enumerate(self.aliases): self.assertEqual(dyn.index_of(dyn.alias(a)), i)
def test_equals_with_annotations_ns(self): a = Dynamics(name='D', parameters=[Parameter('P', dimension=un.dimensionless)], aliases=[Alias('A', 'P')]) b = a.clone() c = a.clone() d = a.clone() e = a.clone() a.parameter('P').annotations.set(('annot1', 'dummy_ns'), 'val1', 1.0) b.parameter('P').annotations.set(('annot1', 'dummy_ns'), 'val1', 1.0) c.parameter('P').annotations.set(('annot1', 'dummy_ns'), 'val1', 2.0) e.parameter('P').annotations.set(('annot1', 'dummy_ns2'), 'val1', 1.0) self.assertTrue(a.equals(b, annotations_ns=['dummy_ns'])) self.assertTrue(a.equals(c)) self.assertFalse(a.equals(c, annotations_ns=['dummy_ns'])) self.assertTrue(a.equals(d)) self.assertFalse(a.equals(d, annotations_ns=['dummy_ns'])) self.assertTrue(a.equals(e)) self.assertFalse(a.equals(e, annotations_ns=['dummy_ns']))
def test_equals_with_annotations_ns(self): a = Dynamics( name='D', parameters=[Parameter('P', dimension=un.dimensionless)], aliases=[Alias('A', 'P')]) b = a.clone() c = a.clone() d = a.clone() e = a.clone() a.parameter('P').annotations.set(('annot1', 'dummy_ns'), 'val1', 1.0) b.parameter('P').annotations.set(('annot1', 'dummy_ns'), 'val1', 1.0) c.parameter('P').annotations.set(('annot1', 'dummy_ns'), 'val1', 2.0) e.parameter('P').annotations.set(('annot1', 'dummy_ns2'), 'val1', 1.0) self.assertTrue(a.equals(b, annotations_ns=['dummy_ns'])) self.assertTrue(a.equals(c)) self.assertFalse(a.equals(c, annotations_ns=['dummy_ns'])) self.assertTrue(a.equals(d)) self.assertFalse(a.equals(d, annotations_ns=['dummy_ns'])) self.assertTrue(a.equals(e)) self.assertFalse(a.equals(e, annotations_ns=['dummy_ns']))
class DynamicsSubstituteAliasesTest(unittest.TestCase): def setUp(self): self.a = Dynamics( name='A', aliases=[ 'A1:=P1 / P2', 'A2 := ARP2 + P3', 'A3 := A4 * P4 * P5', 'A4:=P6 ** 2 + ADP1', 'A5:=SV1 * SV2 * P8', 'A6:=SV1 * P1 / P8', 'A7:=A1 / P8' ], regimes=[ Regime('dSV1/dt = -A1 / A2', 'dSV2/dt = -ADP1 / P7', 'dSV3/dt = -A1 * A3 / (A2 * C1)', transitions=[ OnCondition('SV1 > 10', target_regime_name='R2') ], aliases=[ Alias('A1', 'P1 / P2 * 2'), Alias('A5', 'SV1 * SV2 * P8 * 2') ], name='R1'), Regime('dSV1/dt = -A1 / A2', 'dSV3/dt = -A1 / A2 * A4', transitions=[ OnCondition('C2 > A6', state_assignments=[ StateAssignment('SV1', 'SV1 - A7') ], target_regime_name='R1') ], name='R2') ], analog_ports=[ AnalogReceivePort('ARP1', dimension=un.resistance), AnalogReceivePort('ARP2', dimension=un.charge), AnalogReducePort('ADP1', dimension=un.dimensionless), AnalogSendPort('A5', dimension=un.current) ], parameters=[ Parameter('P1', dimension=un.voltage), Parameter('P2', dimension=un.resistance), Parameter('P3', dimension=un.charge), Parameter('P4', dimension=old_div(un.length, un.current**2)), Parameter('P5', dimension=old_div(un.current**2, un.length)), Parameter('P6', dimension=un.dimensionless), Parameter('P7', dimension=un.time), Parameter('P8', dimension=un.current) ], constants=[ Constant('C1', value=10.0, units=un.unitless), Constant('C2', value=1.0, units=un.ohm) ]) self.ref_substituted_a = Dynamics( name='substituted_A', aliases=['A5:=SV1 * SV2 * P8'], regimes=[ Regime('dSV1/dt = -2 * (P1 / P2) / (ARP2 + P3)', 'dSV2/dt = -ADP1 / P7', ('dSV3/dt = -2 * (P1 / P2) * ((P6 ** 2 + ADP1) * P4 * ' 'P5) / ((ARP2 + P3) * C1)'), transitions=[ OnCondition('SV1 > 10', target_regime_name='R2') ], aliases=[Alias('A5', 'SV1 * SV2 * P8 * 2')], name='R1'), Regime('dSV1/dt = -(P1 / P2) / (ARP2 + P3)', 'dSV3/dt = -(P1 / P2) / (ARP2 + P3) * (P6 ** 2 + ADP1)', transitions=[ OnCondition('C2 > (SV1 * P1 / P8)', state_assignments=[ StateAssignment( 'SV1', 'SV1 - (P1 / P2) / P8') ], target_regime_name='R1') ], name='R2') ], analog_ports=[ AnalogReceivePort('ARP1', dimension=un.resistance), AnalogReceivePort('ARP2', dimension=un.charge), AnalogReducePort('ADP1', dimension=un.dimensionless), AnalogSendPort('A5', dimension=un.current) ], parameters=[ Parameter('P1', dimension=un.voltage), Parameter('P2', dimension=un.resistance), Parameter('P3', dimension=un.charge), Parameter('P4', dimension=old_div(un.length, un.current**2)), Parameter('P5', dimension=old_div(un.current**2, un.length)), Parameter('P6', dimension=un.dimensionless), Parameter('P7', dimension=un.time), Parameter('P8', dimension=un.current) ], constants=[ Constant('C1', value=10.0, units=un.unitless), Constant('C2', value=1.0, units=un.ohm) ]) def test_substitute_aliases(self): substituted_a = self.a.clone() substituted_a.name = 'substituted_A' DynamicsSubstituteAliases(substituted_a) self.assertEqual(substituted_a, self.ref_substituted_a, substituted_a.find_mismatch(self.ref_substituted_a))
class TestPreserveIndices(unittest.TestCase): def setUp(self): self.parameters = ['P4', 'P1', 'P3', 'P5', 'P2'] self.state_variables = ['SV3', 'SV5', 'SV4', 'SV2', 'SV1'] self.regimes = ['R2', 'R3', 'R1'] self.time_derivatives = { 'R1': ['SV5', 'SV1', 'SV4', 'SV3', 'SV2'], 'R2': ['SV2', 'SV4'], 'R3': ['SV4', 'SV2', 'SV1'] } self.aliases = ['A4', 'A3', 'A1', 'A2'] # Create a dynamics object with elements in a particular order self.d = Dynamics( name='d', parameters=[Parameter(p) for p in self.parameters], state_variables=[StateVariable(sv) for sv in self.state_variables], regimes=[ Regime(name=r, time_derivatives=[ TimeDerivative(td, '{}/t'.format(td)) for td in self.time_derivatives[r] ], transitions=[ OnCondition('SV1 > P5', target_regime_name=self.regimes[ self.regimes.index(r) - 1]) ]) for r in self.regimes ], aliases=[ Alias(a, 'P{}'.format(i + 1)) for i, a in enumerate(self.aliases) ]) def test_clone(self): clone_d = self.d.clone() self._test_indices(clone_d) def test_serialization(self): for ext in ext_to_format: fname = mkstemp(suffix=ext)[1] try: self.d.write(fname, register=False, preserve_order=True) except NineMLSerializerNotImportedError: continue reread_d = nineml.read(fname + '#d') self._test_indices(reread_d) def _test_indices(self, dyn): # Set indices of parameters in non-ascending order so that they # can be differentiated from indices on read. for i, p in enumerate(self.parameters): self.assertEqual(dyn.index_of(dyn.parameter(p)), i) for i, sv in enumerate(self.state_variables): self.assertEqual(dyn.index_of(dyn.state_variable(sv)), i) for i, r in enumerate(self.regimes): self.assertEqual(dyn.index_of(dyn.regime(r)), i) for r, tds in self.time_derivatives.items(): regime = dyn.regime(r) for i, td in enumerate(tds): self.assertEquals(regime.index_of(regime.time_derivative(td)), i) for i, a in enumerate(self.aliases): self.assertEqual(dyn.index_of(dyn.alias(a)), i)
def test_Constructor(self): d = Dynamics( name='D', aliases=['D1:=dp1', 'D2 := dIn1', 'D3 := SV1'], regimes=[ Regime('dSV1/dt = -SV1/(dp2*t)', name='r1', transitions=On('input', 'SV1=SV1+1'))], analog_ports=[RecvPort('dIn1'), SendPort('D1'), SendPort('D2')], parameters=['dp1', 'dp2'] ) c = Dynamics( name='C', aliases=['C1:=cp1', 'C2 := cIn1', 'C3 := SV1'], regimes=[ Regime( 'dSV1/dt = -SV1/(cp2*t)', transitions=[On('SV1>cp1', do=[OutputEvent('emit')]), On('spikein', do=[OutputEvent('emit')])], name='r1', ), Regime(name='r2', transitions=On('SV1>1', to='r1')) ], analog_ports=[RecvPort('cIn1'), RecvPort('cIn2'), SendPort('C1'), SendPort('C2')], parameters=['cp1', 'cp2'] ) # Test Cloner, no hierachy # Everything should be as before: c_clone = Cloner(as_class=Dynamics).visit(c) self.assertEqual(c_clone.name, 'C') self.assertEqual(set(c_clone.alias_names), set(['C1', 'C2', 'C3'])) # - Regimes and Transitions: self.assertEqual(set(c_clone.regime_names), set(['r1', 'r2'])) self.assertEqual(len(list(c_clone.regime('r1').on_events)), 1) self.assertEqual(len(list(c_clone.regime('r1').on_conditions)), 1) self.assertEqual(len(list(c_clone.regime('r2').on_events)), 0) self.assertEqual(len(list(c_clone.regime('r2').on_conditions)), 1) self.assertEqual(len(list(c_clone.regime('r2').on_conditions)), 1) # - Ports & Parameters: self.assertEqual( set(c_clone.analog_port_names), set(['cIn2', 'cIn1', 'C1', 'C2'])) self.assertEqual(set(c_clone.event_send_port_names), set(['emit'])) self.assertEqual(set(c_clone.event_receive_port_names), set(['spikein'])) self.assertEqual(set(c_clone.parameter_names), set(['cp1', 'cp2'])) self.assertEqual(set(c_clone.state_variable_names), set(['SV1'])) del c_clone # Test Cloner, 1 level of hierachy # Everything should be as before: b = MultiDynamics(name='B', sub_components={'c1': c, 'c2': c.clone()}, port_connections=[('c1', 'C1', 'c2', 'cIn1'), ('c2', 'emit', 'c1', 'spikein')], port_exposures=[('c2', 'cIn2', 'cIn2_c2'), ('c1', 'cIn1', 'cIn1_c1')]) b_clone = Cloner(as_class=Dynamics).visit(b)