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 : TEST_CASE("IdenticalBlocksDescriptor: Construction")
22 18 : {
23 18 : GIVEN("a 1D descriptor")
24 18 : {
25 6 : index_t size = 11;
26 6 : VolumeDescriptor dd(IndexVector_t::Constant(1, size));
27 :
28 6 : WHEN("creating 0 blocks") { REQUIRE_THROWS(IdenticalBlocksDescriptor(0, dd)); }
29 :
30 6 : WHEN("creating 5 blocks")
31 6 : {
32 5 : index_t blocks = 5;
33 5 : IdenticalBlocksDescriptor bd(blocks, dd);
34 :
35 5 : THEN("there are 5 blocks of the correct size")
36 5 : {
37 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
38 :
39 6 : for (index_t i = 0; i < blocks; ++i)
40 1 : REQUIRE_EQ(bd.getDescriptorOfBlock(i), dd);
41 :
42 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
43 1 : }
44 :
45 5 : THEN("the new IdenticalBlocksDescriptor has the correct sizes")
46 5 : {
47 1 : REQUIRE_EQ(bd.getNumberOfDimensions(), 2);
48 :
49 1 : 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 1 : }
59 :
60 5 : THEN("the new IdenticalBlocksDescriptor does index calculations correctly")
61 5 : {
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 1 : }
69 :
70 5 : THEN("the block offsets are correct")
71 5 : {
72 6 : for (index_t i = 0; i < blocks; ++i)
73 1 : REQUIRE_EQ(bd.getOffsetOfBlock(i), i * dd.getNumberOfCoefficients());
74 :
75 1 : REQUIRE_THROWS(bd.getOffsetOfBlock(blocks));
76 1 : }
77 :
78 5 : THEN("the block descriptor is different from a monolithic descriptor with the same "
79 5 : "dimensions")
80 5 : {
81 1 : IndexVector_t monoCoeffs(2);
82 1 : monoCoeffs << size, blocks;
83 1 : VolumeDescriptor mono(monoCoeffs);
84 1 : REQUIRE_NE(mono, bd);
85 1 : REQUIRE_NE(bd, mono);
86 1 : }
87 5 : }
88 6 : }
89 :
90 18 : GIVEN("a 2D descriptor")
91 18 : {
92 6 : IndexVector_t sizeVector(2);
93 6 : sizeVector << 11, 12;
94 6 : VolumeDescriptor dd(sizeVector);
95 :
96 6 : WHEN("creating 10 blocks")
97 6 : {
98 6 : index_t blocks = 10;
99 6 : IdenticalBlocksDescriptor bd(blocks, dd);
100 :
101 6 : THEN("there are 10 blocks of the correct size")
102 6 : {
103 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
104 :
105 11 : for (index_t i = 0; i < blocks; ++i)
106 1 : REQUIRE_EQ(bd.getDescriptorOfBlock(i), dd);
107 :
108 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
109 1 : }
110 :
111 6 : THEN("the new IdenticalBlocksDescriptor has the correct sizes")
112 6 : {
113 1 : REQUIRE_EQ(bd.getNumberOfDimensions(), 3);
114 :
115 1 : 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 1 : }
126 :
127 6 : THEN("the new IdenticalBlocksDescriptor does index calculations correctly")
128 6 : {
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 1 : }
137 :
138 6 : THEN("the block offsets are correct")
139 6 : {
140 11 : for (index_t i = 0; i < blocks; ++i)
141 1 : REQUIRE_EQ(bd.getOffsetOfBlock(i), i * dd.getNumberOfCoefficients());
142 :
143 1 : REQUIRE_THROWS(bd.getOffsetOfBlock(blocks));
144 1 : }
145 :
146 6 : THEN("the block descriptor is different from a monolithic descriptor with the same "
147 6 : "dimensions")
148 6 : {
149 1 : IndexVector_t monoCoeffs(3);
150 1 : monoCoeffs << sizeVector, blocks;
151 1 : VolumeDescriptor mono(monoCoeffs);
152 1 : REQUIRE_NE(mono, bd);
153 1 : REQUIRE_NE(bd, mono);
154 1 : }
155 :
156 6 : THEN("the block descriptor is different from an IdenticalBlocksDescriptor with the "
157 6 : "same dimensions, but with a different descriptor of each block")
158 6 : {
159 1 : IndexVector_t coeffsBlock = dd.getNumberOfCoefficientsPerDimension();
160 1 : VolumeDescriptor dd2(coeffsBlock.head(coeffsBlock.size() - 1));
161 1 : IdenticalBlocksDescriptor dd3(coeffsBlock[coeffsBlock.size() - 1], dd2);
162 1 : IdenticalBlocksDescriptor bd2(blocks, dd3);
163 1 : REQUIRE_NE(bd2, bd);
164 1 : REQUIRE_NE(bd, bd2);
165 1 : }
166 6 : }
167 6 : }
168 :
169 18 : GIVEN("a 3D descriptor")
170 18 : {
171 6 : IndexVector_t sizeVector(3);
172 6 : sizeVector << 101, 42, 57;
173 6 : VolumeDescriptor dd(sizeVector);
174 :
175 6 : WHEN("creating 25 blocks")
176 6 : {
177 6 : index_t blocks = 25;
178 6 : IdenticalBlocksDescriptor bd(blocks, dd);
179 :
180 6 : THEN("there are 25 blocks of the correct size")
181 6 : {
182 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
183 :
184 26 : for (index_t i = 0; i < blocks; ++i)
185 1 : REQUIRE_EQ(bd.getDescriptorOfBlock(i), dd);
186 :
187 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
188 1 : }
189 :
190 6 : THEN("the new IdenticalBlocksDescriptor has the correct sizes")
191 6 : {
192 1 : REQUIRE_EQ(bd.getNumberOfDimensions(), 4);
193 :
194 1 : 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 1 : }
205 :
206 6 : THEN("the new IdenticalBlocksDescriptor does index calculations correctly")
207 6 : {
208 1 : IndexVector_t coordinate(4);
209 1 : coordinate << sizeVector(0) - 33, sizeVector(1) - 11, sizeVector(2) - 17,
210 1 : 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 1 : }
218 :
219 6 : THEN("the block offsets are correct")
220 6 : {
221 26 : for (index_t i = 0; i < blocks; ++i)
222 1 : REQUIRE_EQ(bd.getOffsetOfBlock(i), i * dd.getNumberOfCoefficients());
223 :
224 1 : REQUIRE_THROWS(bd.getOffsetOfBlock(blocks));
225 1 : }
226 :
227 6 : THEN("the block descriptor is different from a monolithic descriptor with the same "
228 6 : "dimensions")
229 6 : {
230 1 : IndexVector_t monoCoeffs(4);
231 1 : monoCoeffs << sizeVector, blocks;
232 1 : VolumeDescriptor mono(monoCoeffs);
233 1 : REQUIRE_NE(mono, bd);
234 1 : REQUIRE_NE(bd, mono);
235 1 : }
236 :
237 6 : THEN("the block descriptor is different from an IdenticalBlocksDescriptor with the "
238 6 : "same dimensions, but with a different descriptor of each block")
239 6 : {
240 1 : IndexVector_t coeffsBlock = dd.getNumberOfCoefficientsPerDimension();
241 1 : VolumeDescriptor dd2(coeffsBlock.head(coeffsBlock.size() - 1));
242 1 : IdenticalBlocksDescriptor dd3(coeffsBlock[coeffsBlock.size() - 1], dd2);
243 1 : IdenticalBlocksDescriptor bd2(blocks, dd3);
244 1 : REQUIRE_NE(bd2, bd);
245 1 : REQUIRE_NE(bd, bd2);
246 1 : }
247 6 : }
248 6 : }
249 18 : }
250 :
251 : TEST_CASE("IdenticalBlocksDescriptor: Testing cloning")
252 3 : {
253 3 : GIVEN("a 1D IdenticalBlocksDescriptor")
254 3 : {
255 1 : IndexVector_t sizeVector(1);
256 1 : sizeVector << 13;
257 1 : VolumeDescriptor dd(sizeVector);
258 1 : index_t blocks = 21;
259 :
260 1 : WHEN("cloning the descriptor")
261 1 : {
262 1 : IdenticalBlocksDescriptor bd(blocks, dd);
263 1 : auto bdClone = bd.clone();
264 :
265 1 : THEN("it's a real clone")
266 1 : {
267 1 : REQUIRE_NE(bdClone.get(), &bd);
268 1 : REQUIRE_UNARY(is<IdenticalBlocksDescriptor>(bdClone.get()));
269 1 : REQUIRE_EQ(*bdClone, bd);
270 1 : }
271 1 : }
272 1 : }
273 :
274 3 : GIVEN("a 2D IdenticalBlocksDescriptor")
275 3 : {
276 1 : IndexVector_t sizeVector(2);
277 1 : sizeVector << 43, 112;
278 1 : VolumeDescriptor dd(sizeVector);
279 1 : index_t blocks = 77;
280 :
281 1 : WHEN("cloning the descriptor")
282 1 : {
283 1 : IdenticalBlocksDescriptor bd(blocks, dd);
284 1 : auto bdClone = bd.clone();
285 :
286 1 : THEN("it's a real clone")
287 1 : {
288 1 : REQUIRE_NE(bdClone.get(), &bd);
289 1 : REQUIRE_UNARY(is<IdenticalBlocksDescriptor>(bdClone.get()));
290 1 : REQUIRE_EQ(*bdClone, bd);
291 1 : }
292 1 : }
293 1 : }
294 :
295 3 : GIVEN("a 3D IdenticalBlocksDescriptor")
296 3 : {
297 1 : IndexVector_t sizeVector(3);
298 1 : sizeVector << 47, 11, 53;
299 1 : VolumeDescriptor dd(sizeVector);
300 1 : index_t blocks = 13;
301 :
302 1 : WHEN("cloning the descriptor")
303 1 : {
304 1 : IdenticalBlocksDescriptor bd(blocks, dd);
305 1 : auto bdClone = bd.clone();
306 :
307 1 : THEN("it's a real clone")
308 1 : {
309 1 : REQUIRE_NE(bdClone.get(), &bd);
310 1 : REQUIRE_UNARY(is<IdenticalBlocksDescriptor>(bdClone.get()));
311 1 : REQUIRE_EQ(*bdClone, bd);
312 1 : }
313 1 : }
314 1 : }
315 3 : }
316 :
317 : TEST_SUITE_END();
|