Developer documentation
Version 3.0.3-105-gd3941f44
permute_axes.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __adapter_permute_axes_h__
18#define __adapter_permute_axes_h__
19
20#include "adapter/base.h"
21
22namespace MR
23{
24 namespace Adapter
25 {
26
27 template <class ImageType>
29 public Base<PermuteAxes<ImageType>,ImageType>
31 public:
32
33 using base_type = Base<PermuteAxes<ImageType>, ImageType>;
34 using value_type = typename ImageType::value_type;
35
36 using base_type::size;
37 using base_type::parent;
38
39 PermuteAxes (const ImageType& original, const vector<int>& axes) :
40 base_type (original),
41 axes_ (axes) {
42 for (int i = 0; i < static_cast<int> (parent().ndim()); ++i) {
43 for (size_t a = 0; a < axes_.size(); ++a) {
44 if (axes_[a] >= int (parent().ndim()))
45 throw Exception ("axis " + str(axes_[a]) + " exceeds image dimensionality");
46 if (axes_[a] == i)
47 goto next_axis;
48 }
49 if (parent().size (i) != 1)
50 throw Exception ("omitted axis \"" + str (i) + "\" has dimension greater than 1");
51next_axis:
52 continue;
53 }
54
55 int non_existent_index = -1;
56 for (auto& a : axes_) {
57 if (a < 0) {
58 a = non_existent_index--;
59 non_existent_axes.push_back (0);
60 }
61 }
62 }
63
64 size_t ndim () const {
65 return axes_.size();
66 }
67 ssize_t size (size_t axis) const {
68 return axes_[axis] < 0 ? 1 : parent().size (axes_[axis]);
69 }
70 default_type spacing (size_t axis) const {
71 return axes_[axis] < 0 ? std::numeric_limits<default_type>::quiet_NaN() : parent().spacing (axes_[axis]);
72 }
73 ssize_t stride (size_t axis) const {
74 return axes_[axis] < 0 ? 0 : parent().stride (axes_[axis]);
75 }
76
77 void reset () { parent().reset(); }
78
79 ssize_t get_index (size_t axis) const { const auto a = axes_[axis]; return a < 0 ? non_existent_axes[-1-a] : parent().index (a); }
80 void move_index (size_t axis, ssize_t increment) {
81 const auto a = axes_[axis];
82 if (a < 0) non_existent_axes[-1-a] += increment;
83 else parent().index (a) += increment;
84 }
85
86 private:
87 vector<int> axes_;
88 vector<size_t> non_existent_axes;
89
90 };
91
92 }
93}
94
95#endif
96
97
MR::default_type value_type
Definition: typedefs.h:33
Definition: base.h:24
double default_type
the default type used throughout MRtrix
Definition: types.h:228
std::string str(const T &value, int precision=0)
Definition: mrtrix.h:247
int axis
#define MEMALIGN(...)
Definition: types.h:185