SlideIO 2.0.0
Open-source library for reading of medical images
Loading...
Searching...
No Matches
dimensions.hpp
1// This file is part of slideio project.
2// It is subject to the license terms in the LICENSE file found in the top-level directory
3// of this distribution and at http://slideio.com/license.html.
4#pragma once
5#include "slideio/base/exceptions.hpp"
6#include <list>
7#include <map>
8#include <string>
9#include <array>
10
11
12namespace slideio
13{
14 template <std::size_t N = 3>
15 class Dimensions
16 {
17 public:
18 typedef std::array<int, N> Coordinates;
19 typedef std::array<int, N> Sizes;
20 typedef std::array<int, N> Increments;
21 typedef std::array<std::string, N> Labels;
22 Dimensions() = default;
23 Dimensions(const Labels& labels, const Sizes& dimensionSizes, const Increments& increments) {
24 init(labels, dimensionSizes, increments);
25 }
26 void init(const Labels& labels, const Sizes& dimensionSizes, const Increments& increments) {
27 m_order = labels;
28 m_sizes = dimensionSizes;
29 m_increments = increments;
30 m_dimensionMap.clear();
31 for (std::size_t i = 0; i < N; ++i) {
32 m_dimensionMap[m_order[i]] = static_cast<int>(i);
33 }
34 for (int i = 0; i < N; ++i) {
35 if (m_sizes[i] <= 0) {
36 RAISE_RUNTIME_ERROR << "Dimensions::init: dimension size must be greater than zero";
37 }
38 }
39 }
40 bool incrementCoordinates(Coordinates& coordinates) const {
41 for (std::size_t i = 0; i < N; ++i) {
42 int coord = coordinates[i] + m_increments[i];
43 if (coord < m_sizes[i]) {
44 coordinates[i] = coord;
45 return true;
46 }
47 coordinates[i] = 0;
48 }
49 return false; // all dimensions are at their max size
50 }
51 Coordinates createCoordinates(const std::list<std::pair<std::string, int>>& coordList) const {
52 Coordinates coordinates = {0};
53 for (const auto& dim : coordList) {
54 auto it = m_dimensionMap.find(dim.first);
55 if (it == m_dimensionMap.end()) {
56 RAISE_RUNTIME_ERROR << "Dimensions::createCoordinates: dimension: " << dim.first
57 << " not found in dimension map";
58 }
59 coordinates[it->second] = dim.second;
60 }
61 return coordinates;
62 }
63
64 const Labels& getOrder() const { return m_order; }
65 const Sizes& getSizes() const { return m_sizes; }
66 const Increments& getIncrements() const { return m_increments; }
67
68 int getDimensionSize(const std::string& label) const {
69 auto it = m_dimensionMap.find(label);
70 if (it == m_dimensionMap.end()) {
71 RAISE_RUNTIME_ERROR << "Dimensions::getDimensionSize: dimension: " << label
72 << " not found in dimension map";
73 }
74 return m_sizes[it->second];
75 }
76
77 int getDimensionIndex(const std::string& label) const {
78 auto it = m_dimensionMap.find(label);
79 if (it == m_dimensionMap.end()) {
80 RAISE_RUNTIME_ERROR << "Dimensions::getDimensionIndex: dimension: " << label
81 << " not found in dimension map";
82 }
83 return it->second;
84 }
85
86 int getNumDimensions() const { return N; }
87
88 static bool areCoordsEqual(const Coordinates& lhs, const Coordinates& rhs) {
89 for (std::size_t i = 0; i < N; ++i) {
90 if (lhs[i] != rhs[i]) {
91 return false;
92 }
93 }
94 return true;
95 }
96
97 static bool areCoordsLess(const Coordinates& lhs, const Coordinates& rhs) {
98 for (std::size_t i = N; i-- > 0;) {
99 if (lhs[i] < rhs[i]) {
100 return true;
101 } else if (lhs[i] > rhs[i]) {
102 return false;
103 }
104 }
105 return false;
106 }
107
108 static bool areCoordsGreater(const Coordinates& lhs, const Coordinates& rhs) {
109 return areCoordsLess(rhs, lhs);
110 }
111
112 private:
113 Labels m_order;
114 Sizes m_sizes;
115 Increments m_increments;
116 std::map<std::string, int> m_dimensionMap;
117 };
118
119}
Definition: exceptions.hpp:15