LCOV - code coverage report
Current view: top level - elsa/generators - ForbildPhantom.cpp (source / functions) Hit Total Coverage
Test: coverage-all.lcov Lines: 203 209 97.1 %
Date: 2024-12-21 07:37:52 Functions: 12 24 50.0 %

          Line data    Source code
       1             : #include "ForbildPhantom.h"
       2             : 
       3             : using namespace std;
       4             : 
       5             : namespace elsa::phantoms
       6             : {
       7             : 
       8             :     template <typename data_t>
       9             :     ForbildPhantom<data_t>::ForbildPhantom(index_t maxDimension, data_t phantomMaxSize,
      10             :                                            int maxOrderIndex)
      11             :         : maxDimension{maxDimension},
      12             :           phantomMaxSize{phantomMaxSize},
      13           3 :           maxOrderIndex{maxOrderIndex} {};
      14             : 
      15             :     template <typename data_t>
      16             :     index_t scaleForbildShift(index_t maxDimension, data_t value, data_t maxValue)
      17        2725 :     {
      18        2725 :         return std::lround((value + (maxValue / 2)) * static_cast<data_t>(maxDimension)
      19        2725 :                            / maxValue /* cm*/);
      20        2725 :     }
      21             : 
      22             :     template <typename data_t>
      23             :     data_t scaleForbild(index_t maxDimension, data_t value, data_t maxValue)
      24        1675 :     {
      25        1675 :         return value * static_cast<data_t>(maxDimension) / maxValue /* cm*/;
      26        1675 :     }
      27             : 
      28             :     template <typename data_t>
      29             :     void ForbildPhantom<data_t>::addEllipsoids(std::vector<std::array<data_t, 11>> datas)
      30           3 :     {
      31         159 :         for (auto data : datas) {
      32         159 :             data_t amplit = data[0];
      33         159 :             Vec3X<data_t> halfAxis(3);
      34         159 :             halfAxis << scaleForbild(maxDimension, data[1], phantomMaxSize),
      35         159 :                 scaleForbild(maxDimension, data[2], phantomMaxSize),
      36         159 :                 scaleForbild(maxDimension, data[3], phantomMaxSize);
      37             : 
      38         159 :             Vec3i center(3);
      39         159 :             center << scaleForbildShift(maxDimension, data[4], phantomMaxSize),
      40         159 :                 scaleForbildShift(maxDimension, data[5], phantomMaxSize),
      41         159 :                 scaleForbildShift(maxDimension, data[6], phantomMaxSize);
      42             : 
      43         159 :             Vec3X<data_t> euler(3);
      44         159 :             euler << data[7], data[8], data[9];
      45             : 
      46         159 :             int order = int(data[10]);
      47             : 
      48         159 :             if (std::abs(halfAxis[0]) < 0.5 || std::abs(halfAxis[1]) < 0.5
      49         159 :                 || std::abs(halfAxis[2]) < 0.5 || amplit < data_t(0)) {
      50         144 :                 Logger::get("ForbildPhantom::addEllipsoids")
      51         144 :                     ->warn("Ellipsoid will not be rendered, because of amplitude<0 or an invalid "
      52         144 :                            "half axis! amplitude {}, half axis ({},{},{}) ",
      53         144 :                            amplit, halfAxis[0], halfAxis[1], halfAxis[2]);
      54         144 :                 continue;
      55         144 :             }
      56             : 
      57          15 :             ellipsoids.insert_or_assign(order, Ellipsoid<data_t>{amplit, center, halfAxis, euler});
      58          15 :         }
      59           3 :     }
      60             : 
      61             :     template <typename data_t>
      62             :     void ForbildPhantom<data_t>::addEllipsoidsClippedX(std::vector<std::array<data_t, 12>> datas)
      63           1 :     {
      64           1 :         for (auto data : datas) {
      65           1 :             data_t amplit = data[0];
      66           1 :             Vec3X<data_t> halfAxis(3);
      67           1 :             halfAxis << scaleForbild(maxDimension, data[1], phantomMaxSize),
      68           1 :                 scaleForbild(maxDimension, data[2], phantomMaxSize),
      69           1 :                 scaleForbild(maxDimension, data[3], phantomMaxSize);
      70             : 
      71           1 :             Vec3i center(3);
      72           1 :             center << scaleForbildShift(maxDimension, data[4], phantomMaxSize),
      73           1 :                 scaleForbildShift(maxDimension, data[5], phantomMaxSize),
      74           1 :                 scaleForbildShift(maxDimension, data[6], phantomMaxSize);
      75             : 
      76           1 :             Vec3X<data_t> euler(3);
      77           1 :             euler << data[7], data[8], data[9];
      78             : 
      79           1 :             index_t clippedX = scaleForbildShift(maxDimension, data[10], phantomMaxSize);
      80             : 
      81           1 :             int order = int(data[11]);
      82             : 
      83           1 :             if (std::abs(halfAxis[0]) < 0.5 || std::abs(halfAxis[1]) < 0.5
      84           1 :                 || std::abs(halfAxis[2]) < 0.5 || amplit < data_t(0)) {
      85           0 :                 Logger::get("ForbildPhantom::addEllipsoidsClippedX")
      86           0 :                     ->warn("Ellipsoid will not be rendered, because of amplitude<0 or an invalid "
      87           0 :                            "half axis! amplitude {}, half axis ({},{},{})",
      88           0 :                            amplit, halfAxis[0], halfAxis[1], halfAxis[2]);
      89           0 :                 continue;
      90           0 :             }
      91           1 :             auto clippX = [clippedX, center](auto minMax) {
      92             :                 // minMax in object space
      93           1 :                 minMax[3] = data_t(clippedX) - data_t(center[INDEX_X]);
      94           1 :                 return minMax;
      95           1 :             };
      96             : 
      97           1 :             ellipsoidsClippedX.insert_or_assign(
      98           1 :                 order, std::pair{Ellipsoid<data_t>{amplit, center, halfAxis, euler}, clippX});
      99           1 :         }
     100           1 :     }
     101             : 
     102             :     template <typename data_t>
     103             :     void ForbildPhantom<data_t>::addSpheres(std::vector<std::array<data_t, 6>> datas)
     104           3 :     {
     105         409 :         for (auto data : datas) {
     106         409 :             data_t amplit = data[0];
     107         409 :             Vec3i center(3);
     108         409 :             center << scaleForbildShift(maxDimension, data[1], phantomMaxSize),
     109         409 :                 scaleForbildShift(maxDimension, data[2], phantomMaxSize),
     110         409 :                 scaleForbildShift(maxDimension, data[3], phantomMaxSize);
     111             : 
     112         409 :             data_t radius = scaleForbild(maxDimension, data[4], phantomMaxSize);
     113             : 
     114         409 :             int order = int(data[5]);
     115             : 
     116         409 :             if (radius < 0.5 || amplit < data_t(0)) {
     117         367 :                 Logger::get("ForbildPhantom::addSpheres")
     118         367 :                     ->warn("Sphere will not be rendered, because of amplitude<0 or an invalid "
     119         367 :                            "radius!"
     120         367 :                            " amplitude {}, radius {} ",
     121         367 :                            amplit, radius);
     122         367 :                 continue;
     123         367 :             }
     124             : 
     125          42 :             spheres.insert_or_assign(order, Sphere<data_t>{amplit, center, radius});
     126          42 :         }
     127           3 :     }
     128             : 
     129             :     template <typename data_t>
     130             :     void ForbildPhantom<data_t>::addEllipCylinders(std::vector<std::array<data_t, 9>> datas)
     131           3 :     {
     132           5 :         for (auto data : datas) {
     133             : 
     134           5 :             Orientation o = static_cast<Orientation>(std::lround(data[0]));
     135           5 :             data_t amplit = data[1];
     136           5 :             data_t length = scaleForbild(maxDimension, data[2], phantomMaxSize);
     137           5 :             Vec3i center;
     138           5 :             center << scaleForbildShift(maxDimension, data[3], phantomMaxSize),
     139           5 :                 scaleForbildShift(maxDimension, data[4], phantomMaxSize),
     140           5 :                 scaleForbildShift(maxDimension, data[5], phantomMaxSize);
     141             : 
     142           5 :             Vec2X<data_t> halfAxis;
     143           5 :             halfAxis << scaleForbild(maxDimension, data[6], phantomMaxSize),
     144           5 :                 scaleForbild(maxDimension, data[7], phantomMaxSize);
     145             : 
     146           5 :             int order = int(data[8]);
     147             : 
     148           5 :             if (std::abs(halfAxis[0]) < 0.5 || std::abs(halfAxis[1]) < 0.5 || amplit < data_t(0)
     149           5 :                 || length < 1.0) {
     150           1 :                 Logger::get("ForbildPhantom::addEllipCylinders")
     151           1 :                     ->warn("EllipCylinder will not be rendered, because of amplitude<0 or an "
     152           1 :                            "invalid "
     153           1 :                            "half axis! amplitude {}, half axis ({},{}), length {} ",
     154           1 :                            amplit, halfAxis[0], halfAxis[1], length);
     155           1 :                 continue;
     156           1 :             }
     157             : 
     158           4 :             ellipCylinder.insert_or_assign(
     159           4 :                 order, EllipCylinder<data_t>{o, amplit, center, halfAxis, length});
     160           4 :         }
     161           3 :     }
     162             : 
     163             :     template <typename data_t>
     164             :     void ForbildPhantom<data_t>::addEllipCylindersFree(std::vector<std::array<data_t, 11>> datas)
     165           3 :     {
     166           7 :         for (auto data : datas) {
     167             : 
     168           7 :             data_t amplit = data[0];
     169           7 :             data_t length = scaleForbild(maxDimension, data[1], phantomMaxSize);
     170           7 :             Vec3i center;
     171           7 :             center << scaleForbildShift(maxDimension, data[2], phantomMaxSize),
     172           7 :                 scaleForbildShift(maxDimension, data[3], phantomMaxSize),
     173           7 :                 scaleForbildShift(maxDimension, data[4], phantomMaxSize);
     174             : 
     175           7 :             Vec2X<data_t> halfAxis;
     176           7 :             halfAxis << scaleForbild(maxDimension, data[5], phantomMaxSize),
     177           7 :                 scaleForbild(maxDimension, data[6], phantomMaxSize);
     178             : 
     179           7 :             Vec3X<data_t> eulers;
     180           7 :             eulers << data[7], data[8], data[9];
     181             : 
     182           7 :             int order = int(data[10]);
     183             : 
     184           7 :             if (std::abs(halfAxis[0]) < 0.5 || std::abs(halfAxis[1]) < 0.5 || amplit < data_t(0)
     185           7 :                 || length < 1.0) {
     186           2 :                 Logger::get("ForbildPhantom::addEllipCylindersFree")
     187           2 :                     ->warn("EllipCylinderFree will not be rendered, because of amplitude<0 "
     188           2 :                            "or an "
     189           2 :                            "invalid "
     190           2 :                            "half axis! amplitude {}, half axis ({},{}), length {}, eulers "
     191           2 :                            "({},{},{}) ",
     192           2 :                            amplit, halfAxis[0], halfAxis[1], length, eulers[INDEX_A],
     193           2 :                            eulers[INDEX_B], eulers[INDEX_C]);
     194           2 :                 continue;
     195           2 :             }
     196             : 
     197           5 :             ellipCylinderFree.insert_or_assign(
     198           5 :                 order, EllipCylinderFree<data_t>{amplit, center, halfAxis, length, eulers});
     199           5 :         }
     200           3 :     }
     201             : 
     202             :     template <typename data_t>
     203             :     void ForbildPhantom<data_t>::addCylinders(std::vector<std::array<data_t, 8>> datas)
     204           3 :     {
     205          44 :         for (auto data : datas) {
     206             : 
     207          44 :             Orientation o = static_cast<Orientation>(std::lround(data[0]));
     208          44 :             data_t amplit = data[1];
     209          44 :             Vec3i center;
     210          44 :             center << scaleForbildShift(maxDimension, data[2], phantomMaxSize),
     211          44 :                 scaleForbildShift(maxDimension, data[3], phantomMaxSize),
     212          44 :                 scaleForbildShift(maxDimension, data[4], phantomMaxSize);
     213             : 
     214          44 :             data_t radius = scaleForbild(maxDimension, data[5], phantomMaxSize);
     215          44 :             data_t length = scaleForbild(maxDimension, data[6], phantomMaxSize);
     216             : 
     217          44 :             int order = int(data[7]);
     218             : 
     219          44 :             if (amplit < data_t(0) || radius < 0.5 || length < 1.0) {
     220           1 :                 Logger::get("ForbildPhantom::addCylinders")
     221           1 :                     ->warn("Cylinder will not be rendered, because of amplitude<0 or an "
     222           1 :                            "invalid "
     223           1 :                            "radius or invalid length! amplitude {}, radius {}, length {} ",
     224           1 :                            amplit, radius, length);
     225           1 :                 continue;
     226           1 :             }
     227             : 
     228          43 :             cylinders.insert_or_assign(order, Cylinder<data_t>{o, amplit, center, radius, length});
     229          43 :         }
     230           3 :     }
     231             : 
     232             :     template <typename data_t>
     233             :     void ForbildPhantom<data_t>::addCylindersFree(std::vector<std::array<data_t, 10>> datas)
     234           3 :     {
     235         187 :         for (auto data : datas) {
     236         187 :             data_t amplit = data[0];
     237         187 :             Vec3i center;
     238         187 :             center << scaleForbildShift(maxDimension, data[1], phantomMaxSize),
     239         187 :                 scaleForbildShift(maxDimension, data[2], phantomMaxSize),
     240         187 :                 scaleForbildShift(maxDimension, data[3], phantomMaxSize);
     241             : 
     242         187 :             data_t radius = scaleForbild(maxDimension, data[4], phantomMaxSize);
     243         187 :             data_t length = scaleForbild(maxDimension, data[5], phantomMaxSize);
     244             : 
     245         187 :             Vec3X<data_t> eulers;
     246         187 :             eulers << data[6], data[7], data[8];
     247             : 
     248         187 :             int order = int(data[9]);
     249             : 
     250         187 :             if (amplit < data_t(0) || radius < 0.5 || length < 1.0) {
     251           2 :                 Logger::get("ForbildPhantom::addCylinders")
     252           2 :                     ->warn("Cylinder will not be rendered, because of amplitude<0 or an "
     253           2 :                            "invalid "
     254           2 :                            "radius or invalid length! amplitude {}, radius {}, length {} ",
     255           2 :                            amplit, radius, length);
     256           2 :                 continue;
     257           2 :             }
     258             : 
     259         185 :             cylindersFree.insert_or_assign(
     260         185 :                 order, CylinderFree<data_t>{amplit, center, radius, length, eulers});
     261         185 :         }
     262           3 :     }
     263             : 
     264             :     template <typename data_t>
     265             :     void ForbildPhantom<data_t>::addBoxes(std::vector<std::array<data_t, 8>> datas)
     266           3 :     {
     267          96 :         for (auto data : datas) {
     268             : 
     269          96 :             data_t amplit = data[0];
     270          96 :             Vec3i center;
     271          96 :             center << scaleForbildShift(maxDimension, data[1], phantomMaxSize),
     272          96 :                 scaleForbildShift(maxDimension, data[2], phantomMaxSize),
     273          96 :                 scaleForbildShift(maxDimension, data[3], phantomMaxSize);
     274             : 
     275          96 :             Vec3X<data_t> edgeLengths;
     276          96 :             edgeLengths << scaleForbild(maxDimension, data[4], phantomMaxSize),
     277          96 :                 scaleForbild(maxDimension, data[5], phantomMaxSize),
     278          96 :                 scaleForbild(maxDimension, data[6], phantomMaxSize);
     279             : 
     280          96 :             int order = int(data[7]);
     281             : 
     282          96 :             if (std::abs(edgeLengths[0]) < 1 || std::abs(edgeLengths[1]) < 1
     283          96 :                 || std::abs(edgeLengths[2]) < 1 || amplit < data_t(0)) {
     284          56 :                 Logger::get("ForbildPhantom::addBoxes")
     285          56 :                     ->warn("Box will not be rendered, because of amplitude<0 or an invalid "
     286          56 :                            "edge lengths! amplitude {}, edge lengths ({},{},{}) ",
     287          56 :                            amplit, edgeLengths[0], edgeLengths[1], edgeLengths[2]);
     288          56 :                 continue;
     289          56 :             }
     290             : 
     291          40 :             boxes.insert_or_assign(order, Box<data_t>{amplit, center, edgeLengths});
     292          40 :         }
     293           3 :     }
     294             : 
     295             :     // ------------------------------------------
     296             :     // explicit template instantiation
     297             :     template class ForbildPhantom<float>;
     298             :     template class ForbildPhantom<double>;
     299             : 
     300             : } // namespace elsa::phantoms

Generated by: LCOV version 1.14