Grangeat-based 2D/3D image registration
Loading...
Searching...
No Matches
SinogramHEALPix.h
Go to the documentation of this file.
1#pragma once
2
3#include "Common.h"
4
5namespace reg23 {
6
21template <typename texture_t> class SinogramHEALPix : texture_t {
22public:
23 using Base = texture_t;
24 static_assert(Base::DIMENSIONALITY == 3, "The texture type of a `SinogramHEALPix` must have dimensionality 3.");
25 using IntType = typename Base::IntType;
26 using FloatType = typename Base::FloatType;
27 using SizeType = typename Base::SizeType;
28 using VectorType = typename Base::VectorType;
29 using AddressModeType = typename Base::AddressModeType;
30
31 SinogramHEALPix() = default;
32
38 }
39
40 // yes copy
41 SinogramHEALPix(const SinogramHEALPix &) = default;
42
44
45 // yes move
47
49
55 static SinogramHEALPix FromTensor(const at::Tensor &tensor, FloatType rSpacing) {
56 // tensor should be a 3D array of floats
57 TORCH_CHECK(tensor.sizes().size() == 3)
58 TORCH_CHECK(tensor.dtype() == at::kFloat)
59 const SizeType tensorSize = SizeType::FromIntArrayRef(tensor.sizes()).Flipped();
60 TORCH_CHECK((tensorSize.X() - 4) % 3 == 0)
61 TORCH_CHECK((tensorSize.Y() - 4) % 2 == 0)
62 TORCH_CHECK((tensorSize.X() - 4) / 3 == (tensorSize.Y() - 4) / 2)
63 return SinogramHEALPix{Base::FromTensor(tensor, {1.0, 1.0, rSpacing})};
64 }
65
73 TORCH_CHECK((sizeUVR.X() - 4) % 3 == 0)
74 TORCH_CHECK((sizeUVR.Y() - 4) % 2 == 0)
75 TORCH_CHECK((sizeUVR.X() - 4) / 3 == (sizeUVR.Y() - 4) / 2)
76 return SinogramHEALPix{Base{textureHandle, sizeUVR, {1.0, 1.0, rSpacing}, VectorType::Full(0)}};
77 }
78
84#if false
85 const FloatType nSideF = static_cast<FloatType>((Base::Size().X() - 4) / 3);
86
87 // to x_s, y_s
88 const FloatType phiAdjusted = rThetaPhi[2] + 0.5 * M_PI; // with pi/2 adjustment
89 const FloatType z = std::sin(rThetaPhi[1]); // sin instead of cos for adjustment
90 const FloatType zAbs = std::abs(z);
91 const bool equatorialZone = zAbs <= 2.0 / 3.0;
92 const FloatType sigma = Sign(z) * (2.0 - std::sqrt(3.0 * (1.0 - zAbs)));
95 : phiAdjusted - (std::abs(sigma) - 1.0) * (
96 std::fmod(phiAdjusted, 0.5 * M_PI) - 0.25 * M_PI);
97 const FloatType yS = equatorialZone ? 3.0 * M_PI * z / 8.0 : M_PI * sigma / 4.0;
98
99 // to x_p, y_p
100 const FloatType xP = 2.0 * nSideF * xS / M_PI;
101 const FloatType yP = nSideF * (1.0 - 2.0 * yS / M_PI);
102
103 // to u, v, r
104 FloatType r = rThetaPhi[0];
105 FloatType u = xP - yP + 1.5 * nSideF;
106 FloatType v = xP + yP - 0.5 * nSideF;
107 const bool vHigh = v >= 2.0 * nSideF;
108 const bool uHigh = u >= 2.0 * nSideF;
109 if (vHigh) {
110 // either in base pixel 6 or 9
111 v -= 2.0 * nSideF;
112 if (uHigh) {
113 // in base pixel 6
114 u -= 2.0 * nSideF;
115#ifdef __CUDACC__
116 cuda::
117#endif
118 std::swap(u, v); // theta is flipped for base pixel 6
119 r *= -1.0; // r is flipped for base pixel 6
120 } else {
121 // in base pixel 9
122 u += nSideF + 2.0; // the 2 adjusts for padding
123 v -= 2.0; // this adjusts for padding
124 }
125 }
126
127 // u,v,r is the order of the texture dimensions (X, Y, Z)
129 Vec<FloatType, 2>{u + 1.0, v + 3.0} / Base::Size().XY().template StaticCast<FloatType>();
130 // the 1 and 3 adjust for padding
131 const FloatType texCoordR = .5 + r / (static_cast<FloatType>(Base::Size().Z()) * Base::Spacing().Z());
132 return Base::Sample(VecCat(texCoordOrientation, texCoordR));
133#else
134 const FloatType nSideF = static_cast<FloatType>((Base::Size().X() - 4) / 3);
135
136 // to x_s, y_s
137 FloatType a = rThetaPhi[2] / M_PI + 0.5; // a is phiAdjusted/pi, == x_s/pi in equatorial zone
138 FloatType c = std::sin(rThetaPhi[1]); // c is z
139 FloatType d = std::abs(c); // d is abs(z)
140 FloatType e = static_cast<FloatType>(d > 2.0 / 3.0); // e is polarCap
141 FloatType f = Sign(c) * (2.0 - std::sqrt(3.0 * (1.0 - d))); // f is sigma
142 FloatType b = a - e * (std::abs(f) - 1.0) * (std::fmod(a, 0.5) - 0.25); // b is x_s/pi in both zones
143 a = (1.0 - e) * (3.0 * c / 8.0) + e * (f / 4.0); // a is now y_s/pi in both zones
144
145 // to x_p, y_p
146 c = 2.0 * b; // c is now x_p/n_side
147 d = 1.0 - 2.0 * a; // d is now y_p/n_side
148
149 // to u, v, r
150 a = c - d + 1.5; // a is now u/n_side
151 b = c + d - 0.5; // b is now v/n_side
152 c = static_cast<FloatType>(b >= 2.0); // c is v_high
153 b -= c * 2.0;
154 d = static_cast<FloatType>(a >= 2.0); // d is u_high
155 e = c * d; // e is both u_high and v_high
156 a -= e * 2.0;
157 f = 1. - e; // f is not u_high or not v_high
158 c *= 1. - d; // c is v_high and not u_high
159
160 d = f * a + e * b; // d is now u/n_side
161 b = f * b + e * a; // b is still v/n_side
162 f = rThetaPhi[0] - 2.0 * rThetaPhi[0] * e; // f is r
163
164 e = nSideF * d + c * (nSideF + 2.0); // e is now u
165 a = nSideF * b - c * 2.0; // a is now v
166
167 // u,v,r is the order of the texture dimensions (X, Y, Z)
169 Vec<FloatType, 2>{e + 1.0, a + 3.0} / Base::Size().XY().template StaticCast<FloatType>();
170 // the 1 and 3 adjust for padding
171 const FloatType texCoordR = .5 + f / (static_cast<FloatType>(Base::Size().Z()) * Base::Spacing().Z());
172 return Base::Sample(VecCat(texCoordOrientation, texCoordR));
173#endif
174 }
175};
176
177} // namespace reg23
General tools and structs.
#define __host__
Definition Global.h:17
#define __device__
Definition Global.h:22
A 3D texture stored for access by the CPU, structured for storing an even distribution of values over...
Definition SinogramHEALPix.h:21
typename Base::SizeType SizeType
Definition SinogramHEALPix.h:27
typename Base::VectorType VectorType
Definition SinogramHEALPix.h:28
static SinogramHEALPix FromTensor(const at::Tensor &tensor, FloatType rSpacing)
Definition SinogramHEALPix.h:55
texture_t Base
Definition SinogramHEALPix.h:23
static SinogramHEALPix FromCUDAHandle(int64_t textureHandle, const Vec< int64_t, 3 > &sizeUVR, FloatType rSpacing)
Definition SinogramHEALPix.h:72
typename Base::AddressModeType AddressModeType
Definition SinogramHEALPix.h:29
SinogramHEALPix(const SinogramHEALPix &)=default
typename Base::IntType IntType
Definition SinogramHEALPix.h:25
typename Base::FloatType FloatType
Definition SinogramHEALPix.h:26
SinogramHEALPix & operator=(SinogramHEALPix &&)=default
SinogramHEALPix(SinogramHEALPix &&)=default
SinogramHEALPix & operator=(const SinogramHEALPix &)=default
SinogramHEALPix(Base texture)
Construct the texture with data.
Definition SinogramHEALPix.h:37
__host__ __device__ float Sample(const VectorType &rThetaPhi) const
Definition SinogramHEALPix.h:83
A simple vector class derived from std::array<T, N>, providing overrides for all useful operators.
Definition Vec.h:21
__host__ __device__ constexpr Vec< T, 2 > XY() const
Construct a Vec from the first two elements.
Definition Vec.h:475
__host__ __device__ constexpr Vec< T,(Ns+...)> VecCat(const Vec< T, Ns > &... vecs)
reg23::Vec concatenation of any number of vectors
Definition Vec.h:841
__host__ __device__ T Sign(const T &x)
Definition Global.h:51
Vec< TextureAddressMode, DIMENSIONALITY > StringsToAddressModes(const std::array< std::string_view, DIMENSIONALITY > &strings)
Definition Texture.h:44
Definition GridSample3DCPU.cpp:6