LCOV - code coverage report
Current view: top level - elsa/core/tests - test_VolumeDescriptor.cpp (source / functions) Hit Total Coverage
Test: coverage-all.lcov Lines: 568 568 100.0 %
Date: 2023-01-26 04:22:16 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /**
       2             :  * @file test_VolumeDescriptor.cpp
       3             :  *
       4             :  * @brief Tests for VolumeDescriptor class
       5             :  *
       6             :  * @author Matthias Wieczorek - initial code
       7             :  * @author David Frank - rewrite to use doctest and BDD
       8             :  * @author Tobias Lasser - rewrite and added code coverage
       9             :  * @author Nikola Dinev - tests for automatic descriptor generation
      10             :  */
      11             : 
      12             : #include "doctest/doctest.h"
      13             : #include "Error.h"
      14             : #include "VolumeDescriptor.h"
      15             : #include "PartitionDescriptor.h"
      16             : #include "DescriptorUtils.h"
      17             : #include <stdexcept>
      18             : 
      19             : using namespace elsa;
      20             : using namespace doctest;
      21             : 
      22             : TEST_SUITE_BEGIN("core");
      23             : 
      24             : TEST_CASE("VolumeDescriptor: Constructing VolumeDescriptors")
      25          21 : {
      26          21 :     GIVEN("various 1D descriptor sizes")
      27          21 :     {
      28             :         // Double {{ and }} needed!
      29           7 :         IndexVector_t validNumCoeff{{20}};
      30           7 :         RealVector_t validSpacing{{2.5}};
      31           7 :         RealVector_t invalidSpacing{{3.5, 1.5}};
      32           7 :         IndexVector_t invalidNumCoeff{{-10}};
      33             : 
      34           7 :         WHEN("using a valid number of coefficients and no spacing")
      35           7 :         {
      36             :             // Origin of volume
      37           2 :             const RealVector_t origin = 0.5 * (validNumCoeff.cast<real_t>().array());
      38             : 
      39           2 :             const VolumeDescriptor dd(validNumCoeff);
      40             : 
      41           2 :             THEN("everything is set correctly")
      42           2 :             {
      43           1 :                 REQUIRE_EQ(dd.getNumberOfDimensions(), validNumCoeff.size());
      44           1 :                 REQUIRE_EQ(dd.getNumberOfCoefficients(), validNumCoeff.prod());
      45           1 :                 REQUIRE_EQ(dd.getNumberOfCoefficientsPerDimension(), validNumCoeff);
      46           1 :                 REQUIRE_EQ(dd.getSpacingPerDimension(), RealVector_t::Ones(1));
      47           1 :                 REQUIRE_EQ(dd.getLocationOfOrigin(), origin);
      48           1 :             }
      49             : 
      50           2 :             const VolumeDescriptor dd1({20});
      51             : 
      52           2 :             THEN("everything is set correctly")
      53           2 :             {
      54           1 :                 REQUIRE_EQ(dd.getNumberOfDimensions(), validNumCoeff.size());
      55           1 :                 REQUIRE_EQ(dd.getNumberOfCoefficients(), validNumCoeff.prod());
      56           1 :                 REQUIRE_EQ(dd.getNumberOfCoefficientsPerDimension(), validNumCoeff);
      57           1 :                 REQUIRE_EQ(dd.getSpacingPerDimension(), RealVector_t::Ones(1));
      58           1 :                 REQUIRE_EQ(dd.getLocationOfOrigin(), origin);
      59           1 :             }
      60           2 :         }
      61             : 
      62           7 :         WHEN("using an invalid number of coefficients and no spacing")
      63           7 :         {
      64           1 :             THEN("an exception is thrown")
      65           1 :             {
      66           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({-10}), InvalidArgumentError);
      67           1 :             }
      68           1 :         }
      69             : 
      70           7 :         WHEN("using an invalid number of coefficients and valid spacing")
      71           7 :         {
      72           1 :             THEN("an exception is thrown")
      73           1 :             {
      74             :                 // Try all possible combinations of constructors with initializer list
      75           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor(invalidNumCoeff, validSpacing),
      76           1 :                                   InvalidArgumentError);
      77           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({-10}, {2.5}), InvalidArgumentError);
      78           1 :             }
      79           1 :         }
      80             : 
      81           7 :         WHEN("using a valid number of coefficients and spacing")
      82           7 :         {
      83             :             // Origin of volume
      84           2 :             RealVector_t origin =
      85           2 :                 0.5 * (validNumCoeff.cast<real_t>().array() * validSpacing.array());
      86             : 
      87           2 :             const VolumeDescriptor dd1(validNumCoeff, validSpacing);
      88             : 
      89           2 :             THEN("everything is set correctly")
      90           2 :             {
      91           1 :                 REQUIRE_EQ(dd1.getNumberOfDimensions(), validNumCoeff.size());
      92           1 :                 REQUIRE_EQ(dd1.getNumberOfCoefficients(), validNumCoeff.prod());
      93           1 :                 REQUIRE_EQ(dd1.getNumberOfCoefficientsPerDimension(), validNumCoeff);
      94           1 :                 REQUIRE_EQ(dd1.getSpacingPerDimension(), validSpacing);
      95           1 :                 REQUIRE_EQ(dd1.getLocationOfOrigin(), origin);
      96           1 :             }
      97             : 
      98           2 :             const VolumeDescriptor dd2({20}, {2.5});
      99             : 
     100           2 :             THEN("everything is set correctly")
     101           2 :             {
     102           1 :                 REQUIRE_EQ(dd2.getNumberOfDimensions(), validNumCoeff.size());
     103           1 :                 REQUIRE_EQ(dd2.getNumberOfCoefficients(), validNumCoeff.prod());
     104           1 :                 REQUIRE_EQ(dd2.getNumberOfCoefficientsPerDimension(), validNumCoeff);
     105           1 :                 REQUIRE_EQ(dd2.getSpacingPerDimension(), validSpacing);
     106           1 :                 REQUIRE_EQ(dd2.getLocationOfOrigin(), origin);
     107           1 :             }
     108           2 :         }
     109             : 
     110           7 :         WHEN("using a valid number of coefficients and mismatched spacing")
     111           7 :         {
     112           1 :             THEN("an exception is thrown")
     113           1 :             {
     114             :                 // Try all possible combinations of constructors
     115           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor(validNumCoeff, invalidSpacing),
     116           1 :                                   InvalidArgumentError);
     117           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({20}, {3.5, 1.5}), InvalidArgumentError);
     118           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({20}, {-3.5}), InvalidArgumentError);
     119           1 :             }
     120           1 :         }
     121           7 :     }
     122             : 
     123          21 :     GIVEN("various 2D descriptor sizes")
     124          21 :     {
     125           7 :         IndexVector_t validNumCoeff{{12, 15}};
     126           7 :         RealVector_t validSpacing{{1.5, 2.5}};
     127           7 :         RealVector_t invalidSpacing{{1.5}};
     128           7 :         IndexVector_t invalidNumCoeff{{12, -1, 18}};
     129             : 
     130           7 :         WHEN("using a valid number of coefficients and no spacing")
     131           7 :         {
     132             :             // Origin of volume
     133           2 :             RealVector_t origin = 0.5 * (validNumCoeff.cast<real_t>().array());
     134             : 
     135           2 :             const VolumeDescriptor dd1(validNumCoeff);
     136             : 
     137           2 :             THEN("everything is set correctly")
     138           2 :             {
     139           1 :                 REQUIRE_EQ(dd1.getNumberOfDimensions(), validNumCoeff.size());
     140           1 :                 REQUIRE_EQ(dd1.getNumberOfCoefficients(), validNumCoeff.prod());
     141           1 :                 REQUIRE_EQ(dd1.getNumberOfCoefficientsPerDimension(), validNumCoeff);
     142           1 :                 REQUIRE_EQ(dd1.getSpacingPerDimension(), RealVector_t::Ones(2));
     143           1 :                 REQUIRE_EQ(dd1.getLocationOfOrigin(), origin);
     144           1 :             }
     145             : 
     146           2 :             const VolumeDescriptor dd2({12, 15});
     147             : 
     148           2 :             THEN("everything is set correctly")
     149           2 :             {
     150           1 :                 REQUIRE_EQ(dd2.getNumberOfDimensions(), validNumCoeff.size());
     151           1 :                 REQUIRE_EQ(dd2.getNumberOfCoefficients(), validNumCoeff.prod());
     152           1 :                 REQUIRE_EQ(dd2.getNumberOfCoefficientsPerDimension(), validNumCoeff);
     153           1 :                 REQUIRE_EQ(dd2.getSpacingPerDimension(), RealVector_t::Ones(2));
     154           1 :                 REQUIRE_EQ(dd2.getLocationOfOrigin(), origin);
     155           1 :             }
     156           2 :         }
     157             : 
     158           7 :         WHEN("using an invalid number of coefficients and no spacing")
     159           7 :         {
     160           1 :             THEN("an exception is thrown")
     161           1 :             {
     162           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({12, -1, 18}), InvalidArgumentError);
     163           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({12, -1}), InvalidArgumentError);
     164           1 :             }
     165           1 :         }
     166             : 
     167           7 :         WHEN("using an invalid number of coefficients and valid spacing")
     168           7 :         {
     169           1 :             IndexVector_t invalidNumCoeff2 = validNumCoeff;
     170           1 :             invalidNumCoeff2[0] = -1;
     171             : 
     172           1 :             THEN("an exception is thrown")
     173           1 :             {
     174           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor(invalidNumCoeff2, validSpacing),
     175           1 :                                   InvalidArgumentError);
     176             : 
     177           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({12, -1}, {1.5, 2.5}), InvalidArgumentError);
     178           1 :             }
     179           1 :         }
     180             : 
     181           7 :         WHEN("using a valid number of coefficients and spacing")
     182           7 :         {
     183             :             // Origin of volume
     184           2 :             RealVector_t origin =
     185           2 :                 0.5 * (validNumCoeff.cast<real_t>().array() * validSpacing.array());
     186             : 
     187           2 :             const VolumeDescriptor dd1(validNumCoeff, validSpacing);
     188             : 
     189           2 :             THEN("everything is set correctly")
     190           2 :             {
     191           1 :                 REQUIRE_EQ(dd1.getNumberOfDimensions(), validNumCoeff.size());
     192           1 :                 REQUIRE_EQ(dd1.getNumberOfCoefficients(), validNumCoeff.prod());
     193           1 :                 REQUIRE_EQ(dd1.getNumberOfCoefficientsPerDimension(), validNumCoeff);
     194           1 :                 REQUIRE_EQ(dd1.getSpacingPerDimension(), validSpacing);
     195           1 :                 REQUIRE_EQ(dd1.getLocationOfOrigin(), origin);
     196           1 :             }
     197             : 
     198           2 :             const VolumeDescriptor dd2({12, 15}, {1.5, 2.5});
     199             : 
     200           2 :             THEN("everything is set correctly")
     201           2 :             {
     202           1 :                 REQUIRE_EQ(dd2.getNumberOfDimensions(), validNumCoeff.size());
     203           1 :                 REQUIRE_EQ(dd2.getNumberOfCoefficients(), validNumCoeff.prod());
     204           1 :                 REQUIRE_EQ(dd2.getNumberOfCoefficientsPerDimension(), validNumCoeff);
     205           1 :                 REQUIRE_EQ(dd2.getSpacingPerDimension(), validSpacing);
     206           1 :                 REQUIRE_EQ(dd2.getLocationOfOrigin(), origin);
     207           1 :             }
     208           2 :         }
     209             : 
     210           7 :         WHEN("using a valid number of coefficients and mismatched spacing")
     211           7 :         {
     212           1 :             THEN("an exception is thrown")
     213           1 :             {
     214           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor(validNumCoeff, invalidSpacing),
     215           1 :                                   InvalidArgumentError);
     216           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({12, 15}, {-1.5, 2.0}), InvalidArgumentError);
     217           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({12, 15}, {1.5, 2.0, 3.5}),
     218           1 :                                   InvalidArgumentError);
     219           1 :             }
     220           1 :         }
     221           7 :     }
     222             : 
     223          21 :     GIVEN("various 3D descriptor sizes")
     224          21 :     {
     225           7 :         IndexVector_t validNumCoeff{{12, 15, 25}};
     226           7 :         RealVector_t validSpacing{{1.5, 2.5, 4.5}};
     227           7 :         RealVector_t invalidSpacing{{1.5, 2.5}};
     228           7 :         IndexVector_t invalidNumCoeff{{12, 15, -1}};
     229             : 
     230           7 :         WHEN("using a valid number of coefficients and no spacing")
     231           7 :         {
     232           2 :             RealVector_t origin = 0.5 * (validNumCoeff.cast<real_t>().array());
     233             : 
     234           2 :             const VolumeDescriptor dd1(validNumCoeff);
     235             : 
     236           2 :             THEN("everything is set correctly")
     237           2 :             {
     238           1 :                 REQUIRE_EQ(dd1.getNumberOfDimensions(), validNumCoeff.size());
     239           1 :                 REQUIRE_EQ(dd1.getNumberOfCoefficients(), validNumCoeff.prod());
     240           1 :                 REQUIRE_EQ(dd1.getNumberOfCoefficientsPerDimension(), validNumCoeff);
     241           1 :                 REQUIRE_EQ(dd1.getSpacingPerDimension(), RealVector_t::Ones(3));
     242           1 :                 REQUIRE_EQ(dd1.getLocationOfOrigin(), origin);
     243           1 :             }
     244             : 
     245           2 :             const VolumeDescriptor dd2({12, 15, 25});
     246             : 
     247           2 :             THEN("everything is set correctly")
     248           2 :             {
     249           1 :                 REQUIRE_EQ(dd2.getNumberOfDimensions(), validNumCoeff.size());
     250           1 :                 REQUIRE_EQ(dd2.getNumberOfCoefficients(), validNumCoeff.prod());
     251           1 :                 REQUIRE_EQ(dd2.getNumberOfCoefficientsPerDimension(), validNumCoeff);
     252           1 :                 REQUIRE_EQ(dd2.getSpacingPerDimension(), RealVector_t::Ones(3));
     253           1 :                 REQUIRE_EQ(dd2.getLocationOfOrigin(), origin);
     254           1 :             }
     255           2 :         }
     256             : 
     257           7 :         WHEN("using an invalid number of coefficients and no spacing")
     258           7 :         {
     259           1 :             THEN("an exception is thrown")
     260           1 :             {
     261           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({12, 15, -1}), InvalidArgumentError);
     262           1 :             }
     263           1 :         }
     264             : 
     265           7 :         WHEN("using an invalid number of coefficients and valid spacing")
     266           7 :         {
     267           1 :             THEN("an exception is thrown")
     268           1 :             {
     269           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor(invalidNumCoeff, validSpacing),
     270           1 :                                   InvalidArgumentError);
     271           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({12, 15, -1}, {1.5, 2.5, 4.5}),
     272           1 :                                   InvalidArgumentError);
     273           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({12, 15}, {1.5, 2.5, 4.5}),
     274           1 :                                   InvalidArgumentError);
     275           1 :             }
     276           1 :         }
     277             : 
     278           7 :         WHEN("using a valid number of coefficients and spacing")
     279           7 :         {
     280           2 :             RealVector_t origin =
     281           2 :                 0.5 * (validNumCoeff.cast<real_t>().array() * validSpacing.array());
     282             : 
     283           2 :             const VolumeDescriptor dd1(validNumCoeff, validSpacing);
     284             : 
     285           2 :             THEN("everything is set correctly")
     286           2 :             {
     287           1 :                 REQUIRE_EQ(dd1.getNumberOfDimensions(), validNumCoeff.size());
     288           1 :                 REQUIRE_EQ(dd1.getNumberOfCoefficients(), validNumCoeff.prod());
     289           1 :                 REQUIRE_EQ(dd1.getNumberOfCoefficientsPerDimension(), validNumCoeff);
     290           1 :                 REQUIRE_EQ(dd1.getSpacingPerDimension(), validSpacing);
     291           1 :                 REQUIRE_EQ(dd1.getLocationOfOrigin(), origin);
     292           1 :             }
     293             : 
     294           2 :             const VolumeDescriptor dd2({12, 15, 25}, {1.5, 2.5, 4.5});
     295             : 
     296           2 :             THEN("everything is set correctly")
     297           2 :             {
     298           1 :                 REQUIRE_EQ(dd2.getNumberOfDimensions(), validNumCoeff.size());
     299           1 :                 REQUIRE_EQ(dd2.getNumberOfCoefficients(), validNumCoeff.prod());
     300           1 :                 REQUIRE_EQ(dd2.getNumberOfCoefficientsPerDimension(), validNumCoeff);
     301           1 :                 REQUIRE_EQ(dd2.getSpacingPerDimension(), validSpacing);
     302           1 :                 REQUIRE_EQ(dd2.getLocationOfOrigin(), origin);
     303           1 :             }
     304           2 :         }
     305             : 
     306           7 :         WHEN("using a valid number of coefficients and mismatched spacing")
     307           7 :         {
     308           1 :             THEN("an exception is thrown")
     309           1 :             {
     310           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor(validNumCoeff, invalidSpacing),
     311           1 :                                   InvalidArgumentError);
     312           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({12, 15, 25}, {1.5, 2.5}), InvalidArgumentError);
     313           1 :                 REQUIRE_THROWS_AS(VolumeDescriptor({12, 15, 25}, {1.5, 2.5, -4.5}),
     314           1 :                                   InvalidArgumentError);
     315           1 :             }
     316           1 :         }
     317           7 :     }
     318          21 : }
     319             : 
     320             : TEST_CASE("VolumeDescriptor: Testing clone()")
     321           3 : {
     322           3 :     GIVEN("1D descriptors")
     323           3 :     {
     324           1 :         VolumeDescriptor dd({1, 17});
     325           1 :         VolumeDescriptor ddWithSpacing({1, 17}, {1, 2.75});
     326             : 
     327           1 :         WHEN("cloning the VolumeDescriptor")
     328           1 :         {
     329           1 :             auto ddClone = dd.clone();
     330           1 :             auto ddWithSpacingClone = ddWithSpacing.clone();
     331             : 
     332           1 :             THEN("everything matches")
     333           1 :             {
     334           1 :                 REQUIRE_NE(ddClone.get(), &dd);
     335           1 :                 REQUIRE_EQ(*ddClone, dd);
     336             : 
     337           1 :                 REQUIRE_NE(ddWithSpacingClone.get(), &ddWithSpacing);
     338           1 :                 REQUIRE_EQ(*ddWithSpacingClone, ddWithSpacing);
     339           1 :             }
     340           1 :         }
     341           1 :     }
     342             : 
     343           3 :     GIVEN("2D descriptors")
     344           3 :     {
     345           1 :         VolumeDescriptor dd({20, 25});
     346           1 :         VolumeDescriptor ddWithSpacing({20, 25}, {1.5, 3.5});
     347             : 
     348           1 :         WHEN("cloning the VolumeDescriptor")
     349           1 :         {
     350           1 :             auto ddClone = dd.clone();
     351           1 :             auto ddWithSpacingClone = ddWithSpacing.clone();
     352             : 
     353           1 :             THEN("everything matches")
     354           1 :             {
     355           1 :                 REQUIRE_NE(ddClone.get(), &dd);
     356           1 :                 REQUIRE_EQ(*ddClone, dd);
     357             : 
     358           1 :                 REQUIRE_NE(ddWithSpacingClone.get(), &ddWithSpacing);
     359           1 :                 REQUIRE_EQ(*ddWithSpacingClone, ddWithSpacing);
     360           1 :             }
     361           1 :         }
     362           1 :     }
     363             : 
     364           3 :     GIVEN("3D descriptors")
     365           3 :     {
     366           1 :         VolumeDescriptor dd({20, 25, 30});
     367           1 :         VolumeDescriptor ddWithSpacing({20, 25, 30}, {1.5, 3.5, 5.5});
     368             : 
     369           1 :         WHEN("cloning the VolumeDescriptor")
     370           1 :         {
     371           1 :             auto ddClone = dd.clone();
     372           1 :             auto ddWithSpacingClone = ddWithSpacing.clone();
     373             : 
     374           1 :             THEN("everything matches")
     375           1 :             {
     376           1 :                 REQUIRE_NE(ddClone.get(), &dd);
     377           1 :                 REQUIRE_EQ(*ddClone, dd);
     378             : 
     379           1 :                 REQUIRE_NE(ddWithSpacingClone.get(), &ddWithSpacing);
     380           1 :                 REQUIRE_EQ(*ddWithSpacingClone, ddWithSpacing);
     381           1 :             }
     382           1 :         }
     383           1 :     }
     384           3 : }
     385             : 
     386             : TEST_CASE("VolumeDescriptor: Testing calculation of Coordinates and indices")
     387           6 : {
     388           6 :     GIVEN("1D descriptors")
     389           6 :     {
     390           2 :         IndexVector_t numCoeffs{{11}};
     391             : 
     392           2 :         VolumeDescriptor dd(numCoeffs);
     393             : 
     394           2 :         WHEN("converting coordinates to indices")
     395           2 :         {
     396           1 :             IndexVector_t coordinate1(1);
     397           1 :             coordinate1 << 0;
     398           1 :             IndexVector_t coordinate2(1);
     399           1 :             coordinate2 << numCoeffs(0) - 1;
     400             : 
     401           1 :             IndexVector_t coordinateInvalid(2);
     402           1 :             coordinateInvalid << 2, 1;
     403             : 
     404           1 :             THEN("the index is correct")
     405           1 :             {
     406           1 :                 REQUIRE_EQ(dd.getIndexFromCoordinate(coordinate1), 0);
     407           1 :                 REQUIRE_EQ(dd.getIndexFromCoordinate(coordinate2), numCoeffs(0) - 1);
     408           1 :                 REQUIRE_THROWS_AS(dd.getIndexFromCoordinate(coordinateInvalid),
     409           1 :                                   InvalidArgumentError);
     410           1 :             }
     411           1 :         }
     412             : 
     413           2 :         WHEN("converting indices to coordinates")
     414           2 :         {
     415           1 :             index_t index1 = 0;
     416           1 :             index_t index2 = numCoeffs(0) - 1;
     417           1 :             index_t indexInvalid1 = -2;
     418           1 :             index_t indexInvalid2 = numCoeffs(0);
     419             : 
     420           1 :             THEN("the coordinate is correct")
     421           1 :             {
     422           1 :                 REQUIRE_EQ(dd.getCoordinateFromIndex(index1), IndexVector_t::Constant(1, 0));
     423           1 :                 REQUIRE_EQ(dd.getCoordinateFromIndex(index2),
     424           1 :                            IndexVector_t::Constant(1, numCoeffs(0) - 1));
     425           1 :                 REQUIRE_THROWS_AS(dd.getCoordinateFromIndex(indexInvalid1), InvalidArgumentError);
     426           1 :                 REQUIRE_THROWS_AS(dd.getCoordinateFromIndex(indexInvalid2), InvalidArgumentError);
     427           1 :             }
     428           1 :         }
     429           2 :     }
     430             : 
     431           6 :     GIVEN("2D descriptors")
     432           6 :     {
     433           2 :         IndexVector_t numCoeffs{{11, 15}};
     434           2 :         VolumeDescriptor dd(numCoeffs);
     435             : 
     436           2 :         WHEN("converting coordinates to indices")
     437           2 :         {
     438           1 :             IndexVector_t coordinate1(2);
     439           1 :             coordinate1 << 0, 0;
     440           1 :             IndexVector_t coordinate2(2);
     441           1 :             coordinate2 << 0, numCoeffs(1) - 1;
     442           1 :             IndexVector_t coordinate3(2);
     443           1 :             coordinate3 << numCoeffs(0) - 1, numCoeffs(1) - 1;
     444             : 
     445           1 :             IndexVector_t coordinateInvalid(1);
     446           1 :             coordinateInvalid << 5;
     447             : 
     448           1 :             THEN("the index is correct")
     449           1 :             {
     450           1 :                 REQUIRE_EQ(dd.getIndexFromCoordinate(coordinate1), 0);
     451           1 :                 REQUIRE_EQ(dd.getIndexFromCoordinate(coordinate2),
     452           1 :                            numCoeffs(0) * (numCoeffs(1) - 1));
     453           1 :                 REQUIRE_EQ(dd.getIndexFromCoordinate(coordinate3),
     454           1 :                            numCoeffs(0) - 1 + numCoeffs(0) * (numCoeffs(1) - 1));
     455           1 :                 REQUIRE_THROWS_AS(dd.getIndexFromCoordinate(coordinateInvalid),
     456           1 :                                   InvalidArgumentError);
     457           1 :             }
     458           1 :         }
     459             : 
     460           2 :         WHEN("converting indices to coordinates")
     461           2 :         {
     462           1 :             index_t index1 = 0;
     463           1 :             index_t index2 = numCoeffs(0) - 1;
     464           1 :             index_t index3 = numCoeffs(0) * (numCoeffs(1) - 1) + (numCoeffs(0) - 3);
     465           1 :             index_t indexInvalid1 = -1;
     466           1 :             index_t indexInvalid2 = numCoeffs(0) * numCoeffs(1);
     467             : 
     468           1 :             THEN("the coordinate is correct")
     469           1 :             {
     470           1 :                 IndexVector_t coordinate1(2);
     471           1 :                 coordinate1 << 0, 0;
     472           1 :                 REQUIRE_EQ(dd.getCoordinateFromIndex(index1), coordinate1);
     473             : 
     474           1 :                 IndexVector_t coordinate2(2);
     475           1 :                 coordinate2 << numCoeffs(0) - 1, 0;
     476           1 :                 REQUIRE_EQ(dd.getCoordinateFromIndex(index2), coordinate2);
     477             : 
     478           1 :                 IndexVector_t coordinate3(2);
     479           1 :                 coordinate3 << numCoeffs(0) - 3, numCoeffs(1) - 1;
     480           1 :                 REQUIRE_EQ(dd.getCoordinateFromIndex(index3), coordinate3);
     481             : 
     482           1 :                 REQUIRE_THROWS_AS(dd.getCoordinateFromIndex(indexInvalid1), InvalidArgumentError);
     483           1 :                 REQUIRE_THROWS_AS(dd.getCoordinateFromIndex(indexInvalid2), InvalidArgumentError);
     484           1 :             }
     485           1 :         }
     486           2 :     }
     487             : 
     488           6 :     GIVEN("3D descriptors")
     489           6 :     {
     490           2 :         IndexVector_t numCoeffs{{9, 13, 17}};
     491           2 :         VolumeDescriptor dd(numCoeffs);
     492             : 
     493           2 :         WHEN("converting coordinates to indices")
     494           2 :         {
     495           1 :             IndexVector_t coordinate1(3);
     496           1 :             coordinate1 << 0, 0, 0;
     497           1 :             IndexVector_t coordinate2(3);
     498           1 :             coordinate2 << numCoeffs(0) - 2, 0, 0;
     499           1 :             IndexVector_t coordinate3(3);
     500           1 :             coordinate3 << numCoeffs(0) - 5, numCoeffs(1) - 3, 0;
     501           1 :             IndexVector_t coordinate4(3);
     502           1 :             coordinate4 << numCoeffs(0) - 4, numCoeffs(1) - 2, numCoeffs(2) - 1;
     503             : 
     504           1 :             IndexVector_t coordinateInvalid(2);
     505           1 :             coordinateInvalid << 2, 2;
     506             : 
     507           1 :             THEN("the index is correct")
     508           1 :             {
     509           1 :                 REQUIRE_EQ(dd.getIndexFromCoordinate(coordinate1), 0);
     510           1 :                 REQUIRE_EQ(dd.getIndexFromCoordinate(coordinate2), numCoeffs(0) - 2);
     511           1 :                 REQUIRE_EQ(dd.getIndexFromCoordinate(coordinate3),
     512           1 :                            numCoeffs(0) - 5 + numCoeffs(0) * (numCoeffs(1) - 3));
     513           1 :                 REQUIRE_EQ(dd.getIndexFromCoordinate(coordinate4),
     514           1 :                            numCoeffs(0) - 4 + numCoeffs(0) * (numCoeffs(1) - 2)
     515           1 :                                + numCoeffs(0) * numCoeffs(1) * (numCoeffs(2) - 1));
     516           1 :                 REQUIRE_THROWS_AS(dd.getIndexFromCoordinate(coordinateInvalid),
     517           1 :                                   InvalidArgumentError);
     518           1 :             }
     519           1 :         }
     520             : 
     521           2 :         WHEN("converting indices to coordinates")
     522           2 :         {
     523           1 :             index_t index1 = 0;
     524           1 :             index_t index2 = numCoeffs(0) - 7;
     525           1 :             index_t index3 = numCoeffs(0) - 6 + numCoeffs(0) * (numCoeffs(1) - 8);
     526           1 :             index_t index4 = numCoeffs(0) - 5 + numCoeffs(0) * (numCoeffs(1) - 7)
     527           1 :                              + numCoeffs(0) * numCoeffs(1) * (numCoeffs(2) - 3);
     528           1 :             index_t indexInvalid1 = -3;
     529           1 :             index_t indexInvalid2 = numCoeffs(0) * numCoeffs(1) * numCoeffs(2);
     530             : 
     531           1 :             THEN("the coordinate is correct")
     532           1 :             {
     533           1 :                 IndexVector_t coordinate1(3);
     534           1 :                 coordinate1 << 0, 0, 0;
     535           1 :                 REQUIRE_EQ(dd.getCoordinateFromIndex(index1), coordinate1);
     536             : 
     537           1 :                 IndexVector_t coordinate2(3);
     538           1 :                 coordinate2 << numCoeffs(0) - 7, 0, 0;
     539           1 :                 REQUIRE_EQ(dd.getCoordinateFromIndex(index2), coordinate2);
     540             : 
     541           1 :                 IndexVector_t coordinate3(3);
     542           1 :                 coordinate3 << numCoeffs(0) - 6, numCoeffs(1) - 8, 0;
     543           1 :                 REQUIRE_EQ(dd.getCoordinateFromIndex(index3), coordinate3);
     544             : 
     545           1 :                 IndexVector_t coordinate4(3);
     546           1 :                 coordinate4 << numCoeffs(0) - 5, numCoeffs(1) - 7, numCoeffs(2) - 3;
     547           1 :                 REQUIRE_EQ(dd.getCoordinateFromIndex(index4), coordinate4);
     548             : 
     549           1 :                 REQUIRE_THROWS_AS(dd.getCoordinateFromIndex(indexInvalid1), InvalidArgumentError);
     550           1 :                 REQUIRE_THROWS_AS(dd.getCoordinateFromIndex(indexInvalid2), InvalidArgumentError);
     551           1 :             }
     552           1 :         }
     553           2 :     }
     554           6 : }
     555             : 
     556             : TEST_CASE("VolumeDescriptor: Finding the best common descriptor")
     557          10 : {
     558          10 :     IndexVector_t numCoeffs{{9, 13, 17}};
     559          10 :     VolumeDescriptor dd{numCoeffs};
     560             : 
     561          10 :     GIVEN("an empty descriptor list")
     562          10 :     {
     563           1 :         THEN("trying to determine the best common descriptor throws an error")
     564           1 :         {
     565           1 :             REQUIRE_THROWS_AS(bestCommon(std::vector<const DataDescriptor*>{}),
     566           1 :                               InvalidArgumentError);
     567           1 :         }
     568           1 :     }
     569             : 
     570          10 :     GIVEN("a single descriptor")
     571          10 :     {
     572           1 :         PartitionDescriptor pd{dd, 5};
     573           1 :         THEN("the best common descriptor is the descriptor itself")
     574           1 :         {
     575           1 :             auto common1 = bestCommon(dd);
     576           1 :             auto common2 = bestCommon(pd);
     577             : 
     578           1 :             REQUIRE_EQ(*common1, dd);
     579           1 :             REQUIRE_EQ(*common2, pd);
     580           1 :         }
     581           1 :     }
     582             : 
     583          10 :     GIVEN("two equal PartitionDescriptors")
     584          10 :     {
     585           1 :         PartitionDescriptor pd1{dd, 5};
     586           1 :         PartitionDescriptor pd2{dd, 5};
     587             : 
     588           1 :         THEN("the best common descriptor is the same as the input descriptors")
     589           1 :         {
     590           1 :             auto common = bestCommon(pd1, pd2);
     591           1 :             REQUIRE_EQ(pd1, *common);
     592           1 :             REQUIRE_EQ(pd2, *common);
     593           1 :         }
     594           1 :     }
     595             : 
     596          10 :     GIVEN("a PartitionDescriptor and its base")
     597          10 :     {
     598           1 :         PartitionDescriptor pd{dd, 5};
     599             : 
     600           1 :         THEN("the best common descriptor is the base descriptor")
     601           1 :         {
     602           1 :             auto common1 = bestCommon(pd, dd);
     603           1 :             auto common2 = bestCommon(dd, pd);
     604             : 
     605           1 :             REQUIRE_EQ(*common1, dd);
     606           1 :             REQUIRE_EQ(*common2, dd);
     607           1 :         }
     608           1 :     }
     609             : 
     610          10 :     GIVEN("a PartitionDescriptor and its base but with different spacing")
     611          10 :     {
     612           1 :         VolumeDescriptor dds2{numCoeffs, dd.getSpacingPerDimension() * 2};
     613           1 :         PartitionDescriptor pd{dd, 5};
     614           1 :         PartitionDescriptor pds2{dds2, 5};
     615             : 
     616           1 :         THEN("the best common descriptor is the base descriptor with default spacing")
     617           1 :         {
     618           1 :             auto common1 = bestCommon(pd, dds2);
     619           1 :             auto common2 = bestCommon(dds2, pd);
     620           1 :             auto common3 = bestCommon(pds2, dd);
     621           1 :             auto common4 = bestCommon(dd, pds2);
     622             : 
     623           1 :             REQUIRE_EQ(*common1, dd);
     624           1 :             REQUIRE_EQ(*common2, dd);
     625           1 :             REQUIRE_EQ(*common3, dd);
     626           1 :             REQUIRE_EQ(*common4, dd);
     627           1 :         }
     628           1 :     }
     629             : 
     630          10 :     GIVEN("two equal non-block descriptors")
     631          10 :     {
     632           1 :         VolumeDescriptor dd2{numCoeffs};
     633             : 
     634           1 :         THEN("the best common descriptor is the same as the input descriptors")
     635           1 :         {
     636           1 :             auto common = bestCommon(dd, dd2);
     637             : 
     638           1 :             REQUIRE_EQ(*common, dd);
     639           1 :         }
     640           1 :     }
     641             : 
     642          10 :     GIVEN("two non-block descriptors that differ only in spacing")
     643          10 :     {
     644           1 :         VolumeDescriptor dds2{numCoeffs, dd.getSpacingPerDimension() * 2};
     645           1 :         VolumeDescriptor dds3{numCoeffs, dd.getSpacingPerDimension() * 3};
     646             : 
     647           1 :         THEN("the best common descriptor is the base descriptor with default spacing")
     648           1 :         {
     649           1 :             auto common1 = bestCommon(dds2, dds3);
     650           1 :             auto common2 = bestCommon(dds3, dds2);
     651             : 
     652           1 :             REQUIRE_EQ(*common1, dd);
     653           1 :             REQUIRE_EQ(*common2, dd);
     654           1 :         }
     655           1 :     }
     656             : 
     657          10 :     GIVEN("two descriptors with same number of dimensions and size but different number of "
     658          10 :           "coefficients per dimensions")
     659          10 :     {
     660           1 :         IndexVector_t numCoeffs2 = numCoeffs.reverse();
     661             : 
     662           1 :         VolumeDescriptor dd2{numCoeffs2};
     663           1 :         VolumeDescriptor dds2{numCoeffs, dd.getSpacingPerDimension() * 2};
     664           1 :         VolumeDescriptor dd2s2{numCoeffs2, dd2.getSpacingPerDimension() * 2};
     665             : 
     666           1 :         THEN("the best common descriptor is the linearized descriptor with default spacing")
     667           1 :         {
     668           1 :             auto common1 = bestCommon(dd2, dd);
     669           1 :             auto common2 = bestCommon(dd, dd2);
     670           1 :             auto common3 = bestCommon(dds2, dd2s2);
     671           1 :             auto common4 = bestCommon(dd2s2, dds2);
     672             : 
     673           1 :             VolumeDescriptor expected{IndexVector_t::Constant(1, dd.getNumberOfCoefficients())};
     674           1 :             REQUIRE_EQ(*common1, expected);
     675           1 :             REQUIRE_EQ(*common2, expected);
     676           1 :             REQUIRE_EQ(*common3, expected);
     677           1 :             REQUIRE_EQ(*common4, expected);
     678           1 :         }
     679           1 :     }
     680             : 
     681          10 :     GIVEN("two descriptors with different number of dimensions but same size")
     682          10 :     {
     683           1 :         IndexVector_t numCoeffs2 = numCoeffs.head(numCoeffs.size() - 1);
     684           1 :         numCoeffs2[numCoeffs2.size() - 1] *= numCoeffs[numCoeffs.size() - 1];
     685           1 :         VolumeDescriptor dd2{numCoeffs2};
     686             : 
     687           1 :         THEN("the best common descriptor is the linearized descriptor with default spacing")
     688           1 :         {
     689           1 :             auto common1 = bestCommon(dd2, dd);
     690           1 :             auto common2 = bestCommon(dd, dd2);
     691             : 
     692           1 :             VolumeDescriptor expected{IndexVector_t::Constant(1, dd.getNumberOfCoefficients())};
     693           1 :             REQUIRE_EQ(*common1, expected);
     694           1 :             REQUIRE_EQ(*common2, expected);
     695           1 :         }
     696           1 :     }
     697             : 
     698          10 :     GIVEN("two descriptors with different sizes")
     699          10 :     {
     700           1 :         IndexVector_t numCoeffs2 = numCoeffs;
     701           1 :         numCoeffs2[0] += 1;
     702           1 :         VolumeDescriptor dd2{numCoeffs2};
     703             : 
     704           1 :         THEN("trying to determine the best common descriptor throws an error")
     705           1 :         {
     706           1 :             REQUIRE_THROWS_AS(bestCommon(dd2, dd), InvalidArgumentError);
     707           1 :             REQUIRE_THROWS_AS(bestCommon(dd, dd2), InvalidArgumentError);
     708           1 :         }
     709           1 :     }
     710          10 : }
     711             : 
     712             : TEST_SUITE_END();

Generated by: LCOV version 1.14