1#!/usr/local/bin/python3.8
2
3import unittest
4
5import gi
6gi.require_version('v_sim', '3.8')
7from gi.repository import GLib, v_sim
8
9import signals
10
11class TestNodeArray(unittest.TestCase):
12    def setUp(self):
13        super(TestNodeArray, self).setUp()
14        self.addTypeEqualityFunc(list, self.fuzzyList)
15        self.addTypeEqualityFunc(float, self.fuzzyFloat)
16
17    def fuzzyList(self, a, b, msg = None):
18        if len(a) > 0 and isinstance(a[0], float) and len(a) == len(b):
19            try:
20                for i, j in zip(a, b):
21                    self.fuzzyFloat(i, j, msg)
22            except (self.failureException):
23              raise self.failureException(msg if msg is not None else "" + "delta %s" % ([abs(i - j) for i, j in zip(a, b)]))
24            return
25        return self.assertListEqual(a, b, msg)
26
27    def fuzzyFloat(self, a, b, msg = None):
28        if abs(b-a) > 6e-8:
29            raise self.failureException(msg)
30
31    def test_population(self):
32        # Empty structure.
33        array = v_sim.Data.new()
34        self.assertEqual(array.getNElements(True), 0)
35        self.assertEqual(array.getNElements(False), 0)
36        self.assertEqual(array.getNNodes(), 0)
37
38        # Population allocation
39        array.allocateByNames((1, 2, 45), ("O", "H", "g"))
40        self.assertTrue(v_sim.Element.lookup("O") is not None)
41        self.assertTrue(v_sim.Element.lookup("H") is not None)
42        self.assertTrue(v_sim.Element.lookup("g") is not None)
43        self.assertEqual(array.getNElements(True), 0)
44        self.assertEqual(array.getNElements(False), 0)
45        self.assertEqual(array.getNNodes(), 0)
46        self.assertTrue(array.containsElement(v_sim.Element.lookup("O")))
47        self.assertTrue(array.containsElement(v_sim.Element.lookup("H")))
48        self.assertTrue(array.containsElement(v_sim.Element.lookup("g")))
49        self.assertEqual(array.getElementId(v_sim.Element.lookup("O")), 0)
50        self.assertEqual(array.getElementId(v_sim.Element.lookup("H")), 1)
51        self.assertEqual(array.getElementId(v_sim.Element.lookup("g")), 2)
52
53        # Population partial re-allocation
54        array.allocateByNames((1, 4), ("C", "H"))
55        self.assertTrue(v_sim.Element.lookup("C") is not None)
56        self.assertEqual(array.getNElements(True), 0)
57        self.assertEqual(array.getNElements(False), 0)
58        self.assertEqual(array.getNNodes(), 0)
59        self.assertTrue(array.containsElement(v_sim.Element.lookup("O")))
60        self.assertTrue(array.containsElement(v_sim.Element.lookup("H")))
61        self.assertTrue(array.containsElement(v_sim.Element.lookup("g")))
62        self.assertTrue(array.containsElement(v_sim.Element.lookup("C")))
63        self.assertEqual(array.getElementId(v_sim.Element.lookup("O")), 0)
64        self.assertEqual(array.getElementId(v_sim.Element.lookup("H")), 1)
65        self.assertEqual(array.getElementId(v_sim.Element.lookup("g")), 2)
66        self.assertEqual(array.getElementId(v_sim.Element.lookup("C")), 3)
67
68        # Node adding
69        node = array.getNewNode(v_sim.Element.lookup("O"))
70        self.assertTrue(node is not None)
71        self.assertEqual(node.xyz, [0., 0., 0.])
72        self.assertEqual(node.translation, [0., 0., 0.])
73        self.assertTrue(not node.getVisibility())
74        node.newValues((1,2,3))
75        self.assertEqual(node.number, 0)
76        self.assertEqual(node.xyz, [1., 2., 3.])
77        self.assertEqual(node.translation, [0., 0., 0.])
78        self.assertTrue(node.getVisibility())
79        self.assertEqual(array.getNElements(True), 1)
80        self.assertEqual(array.getNElements(False), 1)
81        self.assertEqual(array.getNNodes(), 1)
82        self.assertEqual(array.getNOriginalNodes(), 1)
83        self.assertTrue(array.getElement(node), v_sim.Element.lookup("O"))
84        self.assertEqual(array.getFromId(0), node)
85        self.assertTrue(array.getFromId(1) is None)
86        self.assertEqual(array.getOriginal(0), -1)
87        self.assertEqual(array.get_property("n-nodes"), 1)
88
89        node = array.getNewNodeForId(1)
90        self.assertTrue(node is not None)
91        node.newValues((2,0,0))
92        self.assertEqual(node.number, 1)
93        self.assertEqual(node.xyz, [2., 0., 0.])
94        self.assertEqual(node.translation, [0., 0., 0.])
95        self.assertTrue(node.getVisibility())
96        self.assertEqual(array.getNElements(True), 2)
97        self.assertEqual(array.getNElements(False), 2)
98        self.assertEqual(array.getNNodes(), 2)
99        self.assertEqual(array.getNOriginalNodes(), 2)
100        self.assertTrue(array.getElement(node), v_sim.Element.lookup("H"))
101        self.assertEqual(array.getFromId(1), node)
102        self.assertTrue(array.getFromId(0) is not None)
103        self.assertTrue(array.getFromId(2) is None)
104        self.assertEqual(array.getOriginal(1), -1)
105
106        node = array.copyNode(node)
107        self.assertTrue(node is not None)
108        node.newValues((-2,0,0))
109        self.assertEqual(node.number, 2)
110        self.assertEqual(node.xyz, [-2., 0., 0.])
111        self.assertEqual(node.translation, [0., 0., 0.])
112        self.assertTrue(node.getVisibility())
113        self.assertEqual(array.getNElements(True), 2)
114        self.assertEqual(array.getNElements(False), 2)
115        self.assertEqual(array.getNNodes(), 3)
116        self.assertEqual(array.getNOriginalNodes(), 2)
117        self.assertTrue(array.getElement(node), v_sim.Element.lookup("H"))
118        self.assertEqual(array.getFromId(2), node)
119        self.assertTrue(array.getFromId(1) is not None)
120        self.assertTrue(array.getFromId(3) is None)
121        self.assertEqual(array.getOriginal(2), 1)
122        self.assertTrue(array.setOriginal(2))
123        self.assertEqual(array.getOriginal(2), -1)
124        self.assertEqual(array.getNOriginalNodes(), 3)
125
126        # Node removal
127        array.removeNodes((0, 1))
128        self.assertEqual(array.getNElements(True), 1)
129        self.assertEqual(array.getNNodes(), 1)
130        self.assertTrue(array.getFromId(0) is None)
131        self.assertTrue(array.getFromId(1) is None)
132        self.assertTrue(array.getFromId(2) is not None)
133
134        node = array.copyNode(node)
135        self.assertTrue(array.getFromId(3) is not None)
136        array.removeAllDuplicateNodes()
137        self.assertTrue(array.getFromId(3) is None)
138        self.assertEqual(array.getNElements(True), 1)
139        self.assertEqual(array.getNNodes(), 1)
140
141        array.removeNodesOfElement(v_sim.Element.lookup("H"))
142        self.assertEqual(array.getNElements(True), 0)
143        self.assertEqual(array.getNNodes(), 0)
144
145    def test_populationSignals(self):
146      array = v_sim.Data.new()
147      with signals.Listener(array, "notify::n-nodes") as nodes:
148        with signals.Listener(array, "notify::elements") as elems:
149          with signals.Listener(array, "PopulationIncrease") as popInc:
150            with signals.Listener(array, "PopulationDecrease") as popDec:
151              self.assertEqual(nodes.triggered(), 0)
152              self.assertEqual(elems.triggered(), 0)
153              self.assertEqual(popInc.triggered(), 0)
154              self.assertEqual(popDec.triggered(), 0)
155
156              array.allocateByNames((1, 4), ("C", "H"))
157              self.assertEqual(nodes.triggered(), 0)
158              self.assertEqual(elems.triggered(), 1)
159              self.assertEqual(popInc.triggered(), 0)
160              self.assertEqual(popDec.triggered(), 0)
161              elems.reset()
162
163              array.getNewNodeForId(0)
164              self.assertEqual(nodes.triggered(), 1)
165              self.assertEqual(elems.triggered(), 0)
166              self.assertEqual(popInc.triggered(), 1)
167              self.assertEqual(popDec.triggered(), 0)
168              nodes.reset()
169              popInc.reset()
170
171              array.startAdding()
172              array.getNewNodeForId(1)
173              array.getNewNodeForId(1)
174              array.getNewNodeForId(1)
175              array.getNewNodeForId(1)
176              self.assertEqual(nodes.triggered(), 0)
177              self.assertEqual(popInc.triggered(), 0)
178              self.assertEqual(popDec.triggered(), 0)
179              array.completeAdding()
180              self.assertEqual(nodes.triggered(), 1)
181              self.assertEqual(popInc.triggered(), 1)
182              self.assertEqual(popDec.triggered(), 0)
183              nodes.reset()
184              popInc.reset()
185
186              array.removeNodes((1, 2))
187              self.assertEqual(nodes.triggered(), 1)
188              self.assertEqual(popInc.triggered(), 0)
189              self.assertEqual(popDec.triggered(), 1)
190
191              array.removeNodesOfElement(v_sim.Element.lookup("C"))
192              self.assertEqual(nodes.triggered(), 2)
193              self.assertEqual(popInc.triggered(), 0)
194              self.assertEqual(popDec.triggered(), 2)
195
196              array.freeNodes()
197              self.assertEqual(nodes.triggered(), 3)
198              self.assertEqual(elems.triggered(), 1)
199              self.assertEqual(popInc.triggered(), 0)
200              self.assertEqual(popDec.triggered(), 2) # freeNodes() does not emit PopulationDecrease
201
202    def test_nodeMovements(self):
203      array = v_sim.Data.new()
204      array.allocateByNames((1, 4), ("C", "H"))
205      array.getNewNodeForId(0).newValues(( 0, 0, 0))
206      array.getNewNodeForId(1).newValues((-1,-1,-1))
207      array.getNewNodeForId(1).newValues(( 1, 1,-1))
208      array.getNewNodeForId(1).newValues(( 1,-1, 1))
209      array.getNewNodeForId(1).newValues((-1, 1, 1))
210
211      with signals.Listener(array, "position-changed") as moves:
212        array.getFromId(0).setCoordinates((2.,2.,2.))
213        self.assertEqual(array.getFromId(0).xyz, [2.,2.,2.])
214        self.assertEqual(moves.triggered(), 0)
215
216        array.moveNode(0, (0.,0.,0.))
217        self.assertEqual(array.getFromId(0).xyz, [0.,0.,0.])
218        self.assertEqual(moves.triggered(), 1)
219        array.moveNodes((3,4), (4.,5.,6.,7.,8.,9.))
220        self.assertEqual(array.getFromId(3).xyz, [4.,5.,6.])
221        self.assertEqual(array.getFromId(4).xyz, [7.,8.,9.])
222        self.assertEqual(moves.triggered(), 2)
223        moves.reset()
224
225        array.shiftNode(0, (1,2,3))
226        self.assertEqual(array.getFromId(0).xyz, [1,2,3])
227        self.assertEqual(moves.triggered(), 1)
228        array.shiftNodes((3,4), (-3.,-2.,-1.))
229        self.assertEqual(array.getFromId(3).xyz, [1.,3.,5.])
230        self.assertEqual(array.getFromId(4).xyz, [4.,6.,8.])
231        self.assertEqual(moves.triggered(), 2)
232        moves.reset()
233
234        array.startMoving()
235        array.shiftNode(0, (-1,-2,-3))
236        array.moveNodes((3, 4), (1,-1,1,-1,1,1))
237        array.rotateNodes((1,2), (0,0,1), (0,0,0), 45);
238        self.assertEqual(moves.triggered(), 0)
239        array.completeMoving()
240        self.assertEqual(moves.triggered(), 1)
241        moves.reset()
242
243        array.rotateNodes((1,2), (0,0,1), (0,0,0), 45);
244        self.assertEqual(array.getFromId(1).xyz, [1.,-1.,-1.])
245        self.assertEqual(array.getFromId(2).xyz, [-1.,1.,-1.])
246        self.assertEqual(moves.triggered(), 1)
247
248if __name__ == '__main__':
249    unittest.main()
250