Alexandria 2.31.0
SDC-CH common library for the Euclid project
Loading...
Searching...
No Matches
GridIndexHelper.icpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012-2021 Euclid Science Ground Segment
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License as published by the Free
6 * Software Foundation; either version 3.0 of the License, or (at your option)
7 * any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/**
20 * @file GridContainer/_impl/GridIndexHelper.icpp
21 * @date July 4, 2014
22 * @author Nikolaos Apostolakos
23 */
24
25#include "ElementsKernel/Exception.h"
26
27namespace Euclid {
28namespace GridContainer {
29
30template <typename... AxesTypes>
31GridIndexHelper<AxesTypes...>::GridIndexHelper(const std::tuple<GridAxis<AxesTypes>...>& axes_tuple)
32 : m_axes_sizes{GridConstructionHelper<AxesTypes...>::createAxesSizesVector(axes_tuple,
33 TemplateLoopCounter<sizeof...(AxesTypes)>{})}
34 , m_axes_index_factors{GridConstructionHelper<AxesTypes...>::createAxisIndexFactorVector(
35 axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})}
36 , m_axes_names{
37 GridConstructionHelper<AxesTypes...>::createAxesNamesVector(axes_tuple, TemplateLoopCounter<sizeof...(AxesTypes)>{})} {}
38
39template <typename... AxesTypes>
40size_t GridIndexHelper<AxesTypes...>::axisIndex(size_t axis, size_t array_index) const {
41 size_t index = array_index % m_axes_index_factors[axis + 1];
42 index = index / m_axes_index_factors[axis];
43 return index;
44}
45
46template <typename Coord>
47size_t calculateTotalIndex(const std::vector<size_t>& factors, Coord coord) {
48 return coord * factors[factors.size() - 2];
49}
50
51template <typename Coord, typename... RestCoords>
52size_t calculateTotalIndex(const std::vector<size_t>& factors, Coord coord, RestCoords... rest_coords) {
53 return coord * factors[factors.size() - sizeof...(RestCoords) - 2] + calculateTotalIndex(factors, rest_coords...);
54}
55
56template <typename... AxesTypes>
57size_t GridIndexHelper<AxesTypes...>::totalIndex(decltype(std::declval<GridAxis<AxesTypes>>().size())... coords) const {
58 return calculateTotalIndex(m_axes_index_factors, coords...);
59}
60
61template <typename Coord>
62void checkBounds(const std::vector<std::string>& axes_names, const std::vector<size_t>& axes_sizes, Coord coord) {
63 if (coord >= axes_sizes[axes_sizes.size() - 1]) {
64 throw Elements::Exception() << "Coordinate " << coord << " for axis " << axes_names[axes_sizes.size() - 1] << " (size "
65 << axes_sizes[axes_sizes.size() - 1] << ") is out of bound";
66 }
67}
68
69template <typename Coord, typename... RestCoords>
70void checkBounds(const std::vector<std::string>& axes_names, const std::vector<size_t>& axes_sizes, Coord coord,
71 RestCoords... rest_coords) {
72 if (coord >= axes_sizes[axes_sizes.size() - sizeof...(RestCoords) - 1]) {
73 throw Elements::Exception() << "Coordinate " << coord << " for axis "
74 << axes_names[axes_sizes.size() - sizeof...(RestCoords) - 1] << " (size "
75 << axes_sizes[axes_sizes.size() - sizeof...(RestCoords) - 1] << ") is out of bound";
76 }
77 checkBounds(axes_names, axes_sizes, rest_coords...);
78}
79
80template <typename... AxesTypes>
81size_t GridIndexHelper<AxesTypes...>::totalIndexChecked(decltype(std::declval<GridAxis<AxesTypes>>().size())... coords) const {
82 checkBounds(m_axes_names, m_axes_sizes, coords...);
83 return calculateTotalIndex(m_axes_index_factors, coords...);
84}
85
86template <typename... AxesTypes>
87template <typename Coord>
88void GridIndexHelper<AxesTypes...>::checkAllFixedAreZero(const std::map<size_t, size_t>& fixed_indices, Coord coord) const {
89 if (coord != 0) {
90 if (fixed_indices.find(m_axes_sizes.size() - 1) != fixed_indices.end()) {
91 throw Elements::Exception() << "Coordinate " << coord << " for axis " << m_axes_names[m_axes_sizes.size() - 1]
92 << " (size 1) is out of bound";
93 }
94 }
95}
96
97template <typename... AxesTypes>
98template <typename Coord, typename... RestCoords>
99void GridIndexHelper<AxesTypes...>::checkAllFixedAreZero(const std::map<size_t, size_t>& fixed_indices, Coord coord,
100 RestCoords... rest_coords) const {
101 if (coord != 0) {
102 size_t axis_index = m_axes_sizes.size() - sizeof...(RestCoords) - 1;
103 if (fixed_indices.find(axis_index) != fixed_indices.end()) {
104 throw Elements::Exception() << "Coordinate " << coord << " for axis " << m_axes_names[axis_index]
105 << " (size 1) is out of bound";
106 }
107 }
108 checkAllFixedAreZero(fixed_indices, rest_coords...);
109}
110
111} // namespace GridContainer
112} // end of namespace Euclid