Line data Source code
1 : /**
2 : * @file test_IdenticalBlocksDescriptor.cpp
3 : *
4 : * @brief Tests for IdenticalBlocksDescriptor class
5 : *
6 : * @author David Frank - initial version
7 : * @author Nikola Dinev - various enhancements
8 : * @author Tobias Lasser - rewrite and added code coverage
9 : */
10 :
11 : #include "doctest/doctest.h"
12 :
13 : #include "IdenticalBlocksDescriptor.h"
14 : #include "TypeCasts.hpp"
15 :
16 : using namespace elsa;
17 : using namespace doctest;
18 :
19 : TEST_SUITE_BEGIN("core");
20 :
21 18 : TEST_CASE("IdenticalBlocksDescriptor: Construction")
22 : {
23 24 : GIVEN("a 1D descriptor")
24 : {
25 6 : index_t size = 11;
26 12 : VolumeDescriptor dd(IndexVector_t::Constant(1, size));
27 :
28 8 : WHEN("creating 0 blocks") { REQUIRE_THROWS(IdenticalBlocksDescriptor(0, dd)); }
29 :
30 11 : WHEN("creating 5 blocks")
31 : {
32 5 : index_t blocks = 5;
33 10 : IdenticalBlocksDescriptor bd(blocks, dd);
34 :
35 6 : THEN("there are 5 blocks of the correct size")
36 : {
37 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
38 :
39 6 : for (index_t i = 0; i < blocks; ++i)
40 5 : REQUIRE_EQ(bd.getDescriptorOfBlock(i), dd);
41 :
42 2 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
43 : }
44 :
45 6 : THEN("the new IdenticalBlocksDescriptor has the correct sizes")
46 : {
47 1 : REQUIRE_EQ(bd.getNumberOfDimensions(), 2);
48 :
49 2 : IndexVector_t correctSize(2);
50 1 : correctSize << dd.getNumberOfCoefficients(), blocks;
51 1 : REQUIRE_EQ(bd.getNumberOfCoefficientsPerDimension(), correctSize);
52 1 : REQUIRE_EQ(bd.getNumberOfCoefficients(), correctSize.prod());
53 :
54 1 : RealVector_t correctSpacing(2);
55 1 : correctSpacing(0) = dd.getSpacingPerDimension()(0);
56 1 : correctSpacing(1) = 1.0;
57 1 : REQUIRE_EQ(bd.getSpacingPerDimension(), correctSpacing);
58 : }
59 :
60 6 : THEN("the new IdenticalBlocksDescriptor does index calculations correctly")
61 : {
62 1 : IndexVector_t coordinate(2);
63 1 : coordinate << dd.getNumberOfCoefficients() - 1, blocks - 1;
64 1 : index_t index = coordinate(0) + coordinate(1) * dd.getNumberOfCoefficients();
65 :
66 1 : REQUIRE_EQ(bd.getIndexFromCoordinate(coordinate), index);
67 1 : REQUIRE_EQ(bd.getCoordinateFromIndex(index), coordinate);
68 : }
69 :
70 6 : THEN("the block offsets are correct")
71 : {
72 6 : for (index_t i = 0; i < blocks; ++i)
73 5 : REQUIRE_EQ(bd.getOffsetOfBlock(i), i * dd.getNumberOfCoefficients());
74 :
75 2 : REQUIRE_THROWS(bd.getOffsetOfBlock(blocks));
76 : }
77 :
78 6 : THEN("the block descriptor is different from a monolithic descriptor with the same "
79 : "dimensions")
80 : {
81 2 : IndexVector_t monoCoeffs(2);
82 1 : monoCoeffs << size, blocks;
83 2 : VolumeDescriptor mono(monoCoeffs);
84 1 : REQUIRE_NE(mono, bd);
85 1 : REQUIRE_NE(bd, mono);
86 : }
87 : }
88 : }
89 :
90 24 : GIVEN("a 2D descriptor")
91 : {
92 12 : IndexVector_t sizeVector(2);
93 6 : sizeVector << 11, 12;
94 12 : VolumeDescriptor dd(sizeVector);
95 :
96 12 : WHEN("creating 10 blocks")
97 : {
98 6 : index_t blocks = 10;
99 12 : IdenticalBlocksDescriptor bd(blocks, dd);
100 :
101 7 : THEN("there are 10 blocks of the correct size")
102 : {
103 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
104 :
105 11 : for (index_t i = 0; i < blocks; ++i)
106 10 : REQUIRE_EQ(bd.getDescriptorOfBlock(i), dd);
107 :
108 2 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
109 : }
110 :
111 7 : THEN("the new IdenticalBlocksDescriptor has the correct sizes")
112 : {
113 1 : REQUIRE_EQ(bd.getNumberOfDimensions(), 3);
114 :
115 2 : IndexVector_t correctSize(3);
116 1 : correctSize << sizeVector(0), sizeVector(1), blocks;
117 1 : REQUIRE_EQ(bd.getNumberOfCoefficientsPerDimension(), correctSize);
118 1 : REQUIRE_EQ(bd.getNumberOfCoefficients(), correctSize.prod());
119 :
120 1 : RealVector_t correctSpacing(3);
121 1 : correctSpacing(0) = dd.getSpacingPerDimension()(0);
122 1 : correctSpacing(1) = dd.getSpacingPerDimension()(1);
123 1 : correctSpacing(2) = 1.0;
124 1 : REQUIRE_EQ(bd.getSpacingPerDimension(), correctSpacing);
125 : }
126 :
127 7 : THEN("the new IdenticalBlocksDescriptor does index calculations correctly")
128 : {
129 1 : IndexVector_t coordinate(3);
130 1 : coordinate << sizeVector(0) - 3, sizeVector(1) - 7, blocks - 2;
131 1 : index_t index = coordinate(0) + coordinate(1) * sizeVector(0)
132 1 : + coordinate(2) * sizeVector(0) * sizeVector(1);
133 :
134 1 : REQUIRE_EQ(bd.getIndexFromCoordinate(coordinate), index);
135 1 : REQUIRE_EQ(bd.getCoordinateFromIndex(index), coordinate);
136 : }
137 :
138 7 : THEN("the block offsets are correct")
139 : {
140 11 : for (index_t i = 0; i < blocks; ++i)
141 10 : REQUIRE_EQ(bd.getOffsetOfBlock(i), i * dd.getNumberOfCoefficients());
142 :
143 2 : REQUIRE_THROWS(bd.getOffsetOfBlock(blocks));
144 : }
145 :
146 7 : THEN("the block descriptor is different from a monolithic descriptor with the same "
147 : "dimensions")
148 : {
149 2 : IndexVector_t monoCoeffs(3);
150 1 : monoCoeffs << sizeVector, blocks;
151 2 : VolumeDescriptor mono(monoCoeffs);
152 1 : REQUIRE_NE(mono, bd);
153 1 : REQUIRE_NE(bd, mono);
154 : }
155 :
156 7 : THEN("the block descriptor is different from an IdenticalBlocksDescriptor with the "
157 : "same dimensions, but with a different descriptor of each block")
158 : {
159 2 : IndexVector_t coeffsBlock = dd.getNumberOfCoefficientsPerDimension();
160 2 : VolumeDescriptor dd2(coeffsBlock.head(coeffsBlock.size() - 1));
161 2 : IdenticalBlocksDescriptor dd3(coeffsBlock[coeffsBlock.size() - 1], dd2);
162 2 : IdenticalBlocksDescriptor bd2(blocks, dd3);
163 1 : REQUIRE_NE(bd2, bd);
164 1 : REQUIRE_NE(bd, bd2);
165 : }
166 : }
167 : }
168 :
169 24 : GIVEN("a 3D descriptor")
170 : {
171 12 : IndexVector_t sizeVector(3);
172 6 : sizeVector << 101, 42, 57;
173 12 : VolumeDescriptor dd(sizeVector);
174 :
175 12 : WHEN("creating 25 blocks")
176 : {
177 6 : index_t blocks = 25;
178 12 : IdenticalBlocksDescriptor bd(blocks, dd);
179 :
180 7 : THEN("there are 25 blocks of the correct size")
181 : {
182 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
183 :
184 26 : for (index_t i = 0; i < blocks; ++i)
185 25 : REQUIRE_EQ(bd.getDescriptorOfBlock(i), dd);
186 :
187 2 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
188 : }
189 :
190 7 : THEN("the new IdenticalBlocksDescriptor has the correct sizes")
191 : {
192 1 : REQUIRE_EQ(bd.getNumberOfDimensions(), 4);
193 :
194 2 : IndexVector_t correctSize(4);
195 1 : correctSize << sizeVector(0), sizeVector(1), sizeVector(2), blocks;
196 1 : REQUIRE_EQ(bd.getNumberOfCoefficientsPerDimension(), correctSize);
197 1 : REQUIRE_EQ(bd.getNumberOfCoefficients(), correctSize.prod());
198 :
199 1 : RealVector_t correctSpacing(4);
200 4 : for (index_t i = 0; i < 3; ++i)
201 3 : correctSpacing(i) = dd.getSpacingPerDimension()(i);
202 1 : correctSpacing(3) = 1.0;
203 1 : REQUIRE_EQ(bd.getSpacingPerDimension(), correctSpacing);
204 : }
205 :
206 7 : THEN("the new IdenticalBlocksDescriptor does index calculations correctly")
207 : {
208 1 : IndexVector_t coordinate(4);
209 2 : coordinate << sizeVector(0) - 33, sizeVector(1) - 11, sizeVector(2) - 17,
210 2 : blocks - 19;
211 1 : index_t index = coordinate(0) + coordinate(1) * sizeVector(0)
212 1 : + coordinate(2) * sizeVector(0) * sizeVector(1)
213 1 : + coordinate(3) * sizeVector(0) * sizeVector(1) * sizeVector(2);
214 :
215 1 : REQUIRE_EQ(bd.getIndexFromCoordinate(coordinate), index);
216 1 : REQUIRE_EQ(bd.getCoordinateFromIndex(index), coordinate);
217 : }
218 :
219 7 : THEN("the block offsets are correct")
220 : {
221 26 : for (index_t i = 0; i < blocks; ++i)
222 25 : REQUIRE_EQ(bd.getOffsetOfBlock(i), i * dd.getNumberOfCoefficients());
223 :
224 2 : REQUIRE_THROWS(bd.getOffsetOfBlock(blocks));
225 : }
226 :
227 7 : THEN("the block descriptor is different from a monolithic descriptor with the same "
228 : "dimensions")
229 : {
230 2 : IndexVector_t monoCoeffs(4);
231 1 : monoCoeffs << sizeVector, blocks;
232 2 : VolumeDescriptor mono(monoCoeffs);
233 1 : REQUIRE_NE(mono, bd);
234 1 : REQUIRE_NE(bd, mono);
235 : }
236 :
237 7 : THEN("the block descriptor is different from an IdenticalBlocksDescriptor with the "
238 : "same dimensions, but with a different descriptor of each block")
239 : {
240 2 : IndexVector_t coeffsBlock = dd.getNumberOfCoefficientsPerDimension();
241 2 : VolumeDescriptor dd2(coeffsBlock.head(coeffsBlock.size() - 1));
242 2 : IdenticalBlocksDescriptor dd3(coeffsBlock[coeffsBlock.size() - 1], dd2);
243 2 : IdenticalBlocksDescriptor bd2(blocks, dd3);
244 1 : REQUIRE_NE(bd2, bd);
245 1 : REQUIRE_NE(bd, bd2);
246 : }
247 : }
248 : }
249 18 : }
250 :
251 3 : TEST_CASE("IdenticalBlocksDescriptor: Testing cloning")
252 : {
253 4 : GIVEN("a 1D IdenticalBlocksDescriptor")
254 : {
255 2 : IndexVector_t sizeVector(1);
256 1 : sizeVector << 13;
257 2 : VolumeDescriptor dd(sizeVector);
258 1 : index_t blocks = 21;
259 :
260 2 : WHEN("cloning the descriptor")
261 : {
262 2 : IdenticalBlocksDescriptor bd(blocks, dd);
263 2 : auto bdClone = bd.clone();
264 :
265 2 : THEN("it's a real clone")
266 : {
267 1 : REQUIRE_NE(bdClone.get(), &bd);
268 1 : REQUIRE_UNARY(is<IdenticalBlocksDescriptor>(bdClone.get()));
269 1 : REQUIRE_EQ(*bdClone, bd);
270 : }
271 : }
272 : }
273 :
274 4 : GIVEN("a 2D IdenticalBlocksDescriptor")
275 : {
276 2 : IndexVector_t sizeVector(2);
277 1 : sizeVector << 43, 112;
278 2 : VolumeDescriptor dd(sizeVector);
279 1 : index_t blocks = 77;
280 :
281 2 : WHEN("cloning the descriptor")
282 : {
283 2 : IdenticalBlocksDescriptor bd(blocks, dd);
284 2 : auto bdClone = bd.clone();
285 :
286 2 : THEN("it's a real clone")
287 : {
288 1 : REQUIRE_NE(bdClone.get(), &bd);
289 1 : REQUIRE_UNARY(is<IdenticalBlocksDescriptor>(bdClone.get()));
290 1 : REQUIRE_EQ(*bdClone, bd);
291 : }
292 : }
293 : }
294 :
295 4 : GIVEN("a 3D IdenticalBlocksDescriptor")
296 : {
297 2 : IndexVector_t sizeVector(3);
298 1 : sizeVector << 47, 11, 53;
299 2 : VolumeDescriptor dd(sizeVector);
300 1 : index_t blocks = 13;
301 :
302 2 : WHEN("cloning the descriptor")
303 : {
304 2 : IdenticalBlocksDescriptor bd(blocks, dd);
305 2 : auto bdClone = bd.clone();
306 :
307 2 : THEN("it's a real clone")
308 : {
309 1 : REQUIRE_NE(bdClone.get(), &bd);
310 1 : REQUIRE_UNARY(is<IdenticalBlocksDescriptor>(bdClone.get()));
311 1 : REQUIRE_EQ(*bdClone, bd);
312 : }
313 : }
314 : }
315 3 : }
316 :
317 : TEST_SUITE_END();
|