mmcfilters
Public API documentation
Loading...
Searching...
No Matches
DistanceTransformProfiles.hpp
1#pragma once
2
3#include "DistanceTransformTypes.hpp"
4
5#include <cstddef>
6#include <cstdint>
7#include <limits>
8#include <span>
9#include <stdexcept>
10#include <utility>
11#include <vector>
12
13namespace mmcfilters {
14
17 public:
19 struct Span {
21 std::size_t offset = 0;
23 std::size_t size = 0;
24 };
25
33 DistanceTransformProfiles(DistanceTransformAccuracy accuracy, std::vector<DistanceTransformHistogramBin> bins, std::vector<Span> spans,
34 std::vector<std::uint8_t> alive)
35 : accuracy_(accuracy), bins_(std::move(bins)), spans_(std::move(spans)), alive_(std::move(alive)) {
36 if ((accuracy_ != DistanceTransformAccuracy::Exact && accuracy_ != DistanceTransformAccuracy::Approximate) || spans_.size() != alive_.size()) {
37 throw std::invalid_argument("DistanceTransformProfiles requires aligned node spans and liveness flags.");
38 }
39 for (std::size_t node = 0; node < spans_.size(); ++node) {
40 const Span span = spans_[node];
41 if (span.offset > bins_.size() || span.size > bins_.size() - span.offset || (alive_[node] != 0 && span.size == 0) ||
42 (alive_[node] == 0 && span.size != 0)) {
43 throw std::invalid_argument("DistanceTransformProfiles received an invalid node histogram span.");
44 }
45 std::int64_t previousDistance = -1;
46 for (std::size_t binIndex = span.offset; binIndex < span.offset + span.size; ++binIndex) {
48 if (bin.squaredDistance < 0 || bin.squaredDistance <= previousDistance || bin.count == 0) {
49 throw std::invalid_argument("DistanceTransformProfiles requires positive counts at strictly increasing non-negative levels.");
50 }
51 previousDistance = bin.squaredDistance;
52 }
53 }
54 }
55
57 [[nodiscard]] DistanceTransformAccuracy accuracy() const noexcept { return accuracy_; }
59 [[nodiscard]] std::size_t numNodeSlots() const noexcept { return spans_.size(); }
61 [[nodiscard]] std::size_t numBins() const noexcept { return bins_.size(); }
62
68 [[nodiscard]] std::span<const DistanceTransformHistogramBin> histogram(NodeId node) const {
69 const Span span = checkedSpan(node);
70 return std::span<const DistanceTransformHistogramBin>(bins_.data() + span.offset, span.size);
71 }
72
78 [[nodiscard]] std::vector<DistanceTransformSurvivalBin> survivalProfile(NodeId node) const {
79 const std::span<const DistanceTransformHistogramBin> nodeHistogram = histogram(node);
80 std::uint64_t total = 0;
82 if (bin.count > std::numeric_limits<std::uint64_t>::max() - total) {
83 throw std::overflow_error("Distance-transform survival profile exceeds the 64-bit count domain.");
84 }
85 total += bin.count;
86 }
87 std::vector<DistanceTransformSurvivalBin> result;
88 result.reserve(nodeHistogram.size());
89 std::uint64_t below = 0;
91 result.push_back({bin.squaredDistance, total - below});
92 below += bin.count;
93 }
94 return result;
95 }
96
98 private:
99 [[nodiscard]] Span checkedSpan(NodeId node) const {
100 if (node < 0 || static_cast<std::size_t>(node) >= spans_.size() || alive_[static_cast<std::size_t>(node)] == 0) {
101 throw std::out_of_range("Distance-transform profile access requires a live internal node id.");
102 }
103 return spans_[static_cast<std::size_t>(node)];
104 }
105
106 DistanceTransformAccuracy accuracy_ = DistanceTransformAccuracy::Exact;
107 std::vector<DistanceTransformHistogramBin> bins_;
108 std::vector<Span> spans_;
109 std::vector<std::uint8_t> alive_;
111};
112
113} // namespace mmcfilters
Compact CSR-like sparse distance histograms for every live tree node.
std::size_t numBins() const noexcept
Returns the number of bins stored across all live nodes.
DistanceTransformProfiles(DistanceTransformAccuracy accuracy, std::vector< DistanceTransformHistogramBin > bins, std::vector< Span > spans, std::vector< std::uint8_t > alive)
Constructs validated CSR-like profiles.
std::size_t numNodeSlots() const noexcept
Returns the number of addressable internal node slots.
DistanceTransformAccuracy accuracy() const noexcept
Returns the numerical backend used to produce the profiles.
std::span< const DistanceTransformHistogramBin > histogram(NodeId node) const
Returns the sorted sparse histogram for one live internal node.
std::vector< DistanceTransformSurvivalBin > survivalProfile(NodeId node) const
Computes counts at or above every represented squared-distance level.
Owning result for one computed scalar attribute layout and buffer.
One sparse squared-distance histogram level.
Offset and length of one node histogram in the flat bin array.
std::size_t offset
First bin belonging to the node in the flat bin buffer.
std::size_t size
Number of consecutive bins belonging to the node.