LCOV - code coverage report
Current view: top level - generators - LimitedAngleTrajectoryGenerator.cpp (source / functions) Hit Total Coverage
Test: test_coverage.info.cleaned Lines: 0 36 0.0 %
Date: 2022-08-04 03:43:28 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #include "LimitedAngleTrajectoryGenerator.h"
       2             : #include "VolumeDescriptor.h"
       3             : #include "PlanarDetectorDescriptor.h"
       4             : #include "Logger.h"
       5             : 
       6             : #include <stdexcept>
       7             : 
       8             : namespace elsa
       9             : {
      10           0 :     std::unique_ptr<DetectorDescriptor> LimitedAngleTrajectoryGenerator::createTrajectory(
      11             :         index_t numberOfPoses,
      12             :         std::pair<elsa::geometry::Degree, elsa::geometry::Degree> missingWedgeAngles,
      13             :         const DataDescriptor& volumeDescriptor, index_t arcDegrees, real_t sourceToCenter,
      14             :         real_t centerToDetector, bool mirrored)
      15             :     {
      16             :         // pull in geometry namespace, to reduce cluttering
      17             :         using namespace geometry;
      18             : 
      19             :         // sanity check
      20           0 :         const auto dim = volumeDescriptor.getNumberOfDimensions();
      21           0 :         if (dim != 2) {
      22           0 :             throw InvalidArgumentError("LimitedAngleTrajectoryGenerator: can only handle 2D");
      23             :         }
      24             : 
      25           0 :         Logger::get("LimitedAngleTrajectoryGenerator")
      26           0 :             ->info("creating 2D trajectory with {} poses in an {} degree arc", numberOfPoses,
      27             :                    arcDegrees);
      28             : 
      29           0 :         const auto [coeffs, spacing] =
      30           0 :             calculateSizeAndSpacingPerGeometry(volumeDescriptor, numberOfPoses);
      31             : 
      32             :         // create vector and reserve the necessary size, minor optimization such that no new
      33             :         // allocations are necessary in the loop
      34           0 :         std::vector<Geometry> geometryList;
      35           0 :         geometryList.reserve(static_cast<std::size_t>(numberOfPoses));
      36             : 
      37           0 :         real_t wedgeArc = mirrored ? 2 * (missingWedgeAngles.second - missingWedgeAngles.first)
      38           0 :                                    : missingWedgeAngles.second - missingWedgeAngles.first;
      39             : 
      40           0 :         const real_t angleIncrement =
      41           0 :             (static_cast<real_t>(arcDegrees) - wedgeArc) / (static_cast<real_t>(numberOfPoses));
      42             : 
      43           0 :         for (index_t i = 0;; ++i) {
      44           0 :             Radian angle = Degree{static_cast<real_t>(i) * angleIncrement};
      45             : 
      46           0 :             if (angle.to_degree() >= static_cast<real_t>(arcDegrees)) {
      47           0 :                 break;
      48             :             }
      49             : 
      50           0 :             if (notInMissingWedge(angle, missingWedgeAngles, mirrored)) {
      51             :                 // use emplace_back, then no copy is created
      52           0 :                 geometryList.emplace_back(SourceToCenterOfRotation{sourceToCenter},
      53           0 :                                           CenterOfRotationToDetector{centerToDetector},
      54           0 :                                           Radian{angle},
      55           0 :                                           VolumeData2D{volumeDescriptor.getSpacingPerDimension(),
      56           0 :                                                        volumeDescriptor.getLocationOfOrigin()},
      57           0 :                                           SinogramData2D{Size2D{coeffs}, Spacing2D{spacing}});
      58             :             }
      59           0 :         }
      60             : 
      61           0 :         return std::make_unique<PlanarDetectorDescriptor>(coeffs, spacing, geometryList);
      62           0 :     }
      63             : 
      64           0 :     bool LimitedAngleTrajectoryGenerator::notInMissingWedge(
      65             :         elsa::geometry::Radian angle,
      66             :         std::pair<elsa::geometry::Degree, elsa::geometry::Degree> missingWedgeAngles, bool mirrored)
      67             :     {
      68           0 :         if (!mirrored) {
      69           0 :             return !(angle.to_degree() >= missingWedgeAngles.first
      70           0 :                      && angle.to_degree() <= missingWedgeAngles.second);
      71             :         } else {
      72           0 :             return !((angle.to_degree() >= missingWedgeAngles.first
      73           0 :                       && angle.to_degree() <= missingWedgeAngles.second)
      74           0 :                      || (angle.to_degree() >= (missingWedgeAngles.first + 180)
      75           0 :                          && angle.to_degree() <= (missingWedgeAngles.second + 180)));
      76             :         }
      77             :     }
      78             : } // namespace elsa

Generated by: LCOV version 1.14