Mantid
Loading...
Searching...
No Matches
CoordinateConversion.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#pragma once
8
9#include "Types.h"
10#include <algorithm>
11#include <cmath>
12#include <iomanip>
13
14namespace morton_index {
26template <typename MortonT> bool morton_contains(const MortonT lower, const MortonT upper, const MortonT value) {
27 return lower <= value && value <= upper;
28}
29
30template <size_t ND, typename IntT, typename MortonT> MortonT calculateDefaultBound(IntT intBound) {
31 IntArray<ND, IntT> minCoord;
32 minCoord.fill(intBound);
34}
35
40template <int ND>
42 size_t maxBits(0);
43 for (size_t i = 0; i < ND; ++i) {
44 /* Calculate the required integer width to accurately represent coordinates
45 * on axis i. */
46 size_t bits = std::ceil(std::log2((bounds(i, 1) - bounds(i, 0)) / steps(i)));
47
48 /* Record highest bit width requirement */
49 maxBits = std::max(maxBits, bits);
50 }
51 return maxBits;
52}
53
62template <int ND> void ExpandBounds(MDSpaceBounds<ND> &bounds) {
63 for (size_t i = 0; i < ND; ++i) {
64 bounds(i, 0) = std::nexttoward(bounds(i, 0), std::numeric_limits<float>::lowest());
65 bounds(i, 1) = std::nexttoward(bounds(i, 1), std::numeric_limits<float>::max());
66 }
67}
68
72template <int ND> bool CheckCoordinatesInMDSpace(const MDSpaceBounds<ND> &bounds, const MDCoordinate<ND> &coord) {
73 for (size_t i = 0; i < coord.rows(); i++) {
74 const float coordValue = coord(i, 0);
75 const Eigen::Matrix<float, 1, 2> coordBounds = bounds.row(i);
76
77 if (coordValue < coordBounds[0] || coordValue > coordBounds[1]) {
78 return false;
79 }
80 }
81
82 return true;
83}
84
89template <int ND, typename IntT>
90Eigen::Array<IntT, ND, 1> ConvertCoordinatesToIntegerRange(const MDSpaceBounds<ND> &bounds, const float *crd) {
91 MDCoordinate<ND> coord(crd);
92 const MDCoordinate<ND> range = bounds.col(1) - bounds.col(0);
93 const MDCoordinate<ND> coordFactorOfRange = (coord - bounds.col(0)) / range;
94 const MDCoordinate<ND> n = coordFactorOfRange * std::numeric_limits<IntT>::max();
95 Eigen::Array<IntT, ND, 1> res = n.template cast<IntT>();
96 for (unsigned i = 0; i < ND; ++i)
97 if (coord[i] == bounds(i, 1))
98 res[i] = std::numeric_limits<IntT>::max();
99 else if (coord[i] == bounds(i, 0))
100 res[i] = 0;
101 return res;
102}
103
108template <int ND, typename IntT>
110 const Eigen::Array<IntT, ND, 1> &intCoord) {
111 const auto range = bounds.col(1) - bounds.col(0);
112 const auto coordFactorOfRange = intCoord.template cast<float>() / (float)std::numeric_limits<IntT>::max();
113 return bounds.col(0) + (coordFactorOfRange * range);
114}
115
119template <typename IntT> IntT ConvertCoordinateToIntegerRange(float value, float lower, float upper) {
120 const float coordFactorOfRange = (value - lower) / (upper - lower);
121 const float intValue = coordFactorOfRange * std::numeric_limits<IntT>::max();
122 return (IntT)intValue;
123}
124
128template <typename IntT> float ConvertCoordinateFromIntegerRange(IntT value, float lower, float upper) {
129 const float coordFactorOfRange = (float)value / (float)std::numeric_limits<IntT>::max();
130 return lower + (coordFactorOfRange * (upper - lower));
131}
132
133template <size_t nd, typename IntT, typename MortonT>
134MDCoordinate<nd> indexToCoordinates(const MortonT &idx, const MDSpaceBounds<nd> &space) {
135 return morton_index::ConvertCoordinatesFromIntegerRange<nd, IntT>(space,
137}
138
139template <size_t nd, typename IntT, typename MortonT, typename coord_t = float>
140MortonT coordinatesToIndex(coord_t *coord, const MDSpaceBounds<nd> &space) {
142 morton_index::ConvertCoordinatesToIntegerRange<nd, IntT>(space, coord));
143}
144
145} // namespace morton_index
double value
The value of the point.
Definition: FitMW.cpp:51
double lower
lower and upper bounds on the multiplier, if known
double upper
bool morton_contains(const MortonT lower, const MortonT upper, const MortonT value)
Checks if a point defined by a Morton number is within the box bounds (as defined by an upper and low...
MortonT coordinatesToIndex(coord_t *coord, const MDSpaceBounds< nd > &space)
MDCoordinate< ND > ConvertCoordinatesFromIntegerRange(const MDSpaceBounds< ND > &bounds, const Eigen::Array< IntT, ND, 1 > &intCoord)
Converts a point expressed as integer coordinates back to floating point, given bounds of the origina...
Eigen::Array< IntT, ND, 1 > ConvertCoordinatesToIntegerRange(const MDSpaceBounds< ND > &bounds, const float *crd)
Converts a point to integer range given a range of floating point coordinates.
void ExpandBounds(MDSpaceBounds< ND > &bounds)
Expands a coordinate space enough that floating point error cannot cause an overflow when mapping a v...
bool CheckCoordinatesInMDSpace(const MDSpaceBounds< ND > &bounds, const MDCoordinate< ND > &coord)
Checks that a coordinate is within the extents of an MD space.
size_t CalculateRequiredCoordinateIntegerWidth(const MDSpaceBounds< ND > &bounds, const MDSpaceSteps< ND > &steps)
Calculates the required width of the interleaved integer to accurately represent coordinates in a giv...
MortonT calculateDefaultBound(IntT intBound)
Eigen::Array< float, static_cast< int >(ND), 1 > MDCoordinate
Definition: Types.h:29
IntT ConvertCoordinateToIntegerRange(float value, float lower, float upper)
Converts a single floating point coordinate to an integer range.
float ConvertCoordinateFromIntegerRange(IntT value, float lower, float upper)
Converts a single integer coordinate to a floating point.
Eigen::Array< IntT, static_cast< int >(ND), 1 > IntArray
Definition: Types.h:27
MDCoordinate< nd > indexToCoordinates(const MortonT &idx, const MDSpaceBounds< nd > &space)
Eigen::Array< float, static_cast< int >(ND), 1 > MDSpaceSteps
Definition: Types.h:33
Eigen::Array< float, static_cast< int >(ND), 2 > MDSpaceBounds
Definition: Types.h:31
static MortonT interleave(const IntArray< ND, IntT > &coord)