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

          Line data    Source code
       1             : #include "SphereTrajectoryGenerator.h"
       2             : #include "PlanarDetectorDescriptor.h"
       3             : #include "Logger.h"
       4             : 
       5             : namespace elsa
       6             : {
       7           0 :     std::unique_ptr<DetectorDescriptor> SphereTrajectoryGenerator::createTrajectory(
       8             :         index_t numberOfPoses, const DataDescriptor& volumeDescriptor, index_t numberOfCircles,
       9             :         geometry::SourceToCenterOfRotation sourceToCenter,
      10             :         geometry::CenterOfRotationToDetector centerToDetector)
      11             :     {
      12             :         // pull in geometry namespace, to reduce cluttering
      13             :         using namespace geometry;
      14             : 
      15             :         // sanity check
      16           0 :         const auto dim = volumeDescriptor.getNumberOfDimensions();
      17             : 
      18           0 :         if (dim != 3)
      19           0 :             throw InvalidArgumentError("SphereTrajectoryGenerator: can only handle 3d");
      20             : 
      21           0 :         Logger::get("SphereTrajectoryGenerator")
      22           0 :             ->info("creating {}D trajectory with {} poses consisting of {} circular "
      23             :                    "trajectories",
      24             :                    dim, numberOfPoses, numberOfCircles);
      25             : 
      26           0 :         const auto [coeffs, spacing] =
      27           0 :             calculateSizeAndSpacingPerGeometry(volumeDescriptor, numberOfPoses);
      28             : 
      29             :         // Create vector and reserve the necessary size, minor optimization such that no new
      30             :         // allocations are necessary in the loop
      31           0 :         std::vector<Geometry> geometryList;
      32           0 :         geometryList.reserve(static_cast<std::size_t>(numberOfPoses));
      33             : 
      34             :         // compute the total circumference of all circular trajectories we are generating
      35           0 :         double circumference = 0;
      36           0 :         for (index_t i = 0; i < numberOfCircles; ++i) {
      37           0 :             circumference +=
      38           0 :                 M_PI * 2.0 * centerToDetector
      39           0 :                 * cos(M_PI * static_cast<double>(i + 1) / static_cast<double>(numberOfCircles + 2)
      40             :                       - M_PI_2);
      41             :         }
      42             : 
      43           0 :         auto circumferenceChangePerPose = circumference / static_cast<double>(numberOfPoses);
      44           0 :         index_t createdPoses = 0;
      45             : 
      46           0 :         for (index_t i = 0; i < numberOfCircles; ++i) {
      47           0 :             auto beta = M_PI * static_cast<double>(i + 1) / static_cast<double>(numberOfCircles + 2)
      48             :                         - M_PI_2;
      49             : 
      50             :             index_t posesInCircle;
      51           0 :             if (i == numberOfCircles - 1) {
      52           0 :                 posesInCircle = numberOfPoses - createdPoses;
      53             :             } else {
      54           0 :                 posesInCircle = static_cast<index_t>(
      55           0 :                     (2.0 * M_PI * static_cast<double>(centerToDetector) * cos(beta))
      56           0 :                     / circumferenceChangePerPose);
      57             :             }
      58             : 
      59           0 :             for (index_t poseIndex = 0; poseIndex < posesInCircle; ++poseIndex) {
      60           0 :                 auto gamma = M_PI * 2.0 * static_cast<double>(poseIndex)
      61           0 :                              / static_cast<double>(posesInCircle);
      62             : 
      63           0 :                 geometryList.emplace_back(sourceToCenter, centerToDetector,
      64           0 :                                           VolumeData3D{volumeDescriptor.getSpacingPerDimension(),
      65           0 :                                                        volumeDescriptor.getLocationOfOrigin()},
      66           0 :                                           SinogramData3D{Size3D{coeffs}, Spacing3D{spacing}},
      67           0 :                                           RotationAngles3D{Radian{static_cast<real_t>(gamma)},
      68           0 :                                                            Radian{static_cast<real_t>(beta)},
      69           0 :                                                            Radian{0}});
      70             :             }
      71             : 
      72           0 :             createdPoses += posesInCircle;
      73             :         }
      74             : 
      75           0 :         return std::make_unique<PlanarDetectorDescriptor>(coeffs, spacing, geometryList);
      76           0 :     }
      77             : 
      78             : } // namespace elsa

Generated by: LCOV version 1.14