Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGeoVoxelGrid.h
Go to the documentation of this file.
1/// \author Sandro Wenzel <sandro.wenzel@cern.ch>
2/// \date 2024-02-22
3
4/*************************************************************************
5 * Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#ifndef ROOT_TGeoVoxelGrid
13#define ROOT_TGeoVoxelGrid
14
15#include <array>
16#include <cmath>
17#include <limits>
18#include <vector>
19
20// a simple structure to encode voxel indices, to address
21// individual voxels in the 3D grid.
23 int ix{-1};
24 int iy{-1};
25 int iz{-1};
26 size_t idx{std::numeric_limits<size_t>::max()};
27 bool isValid() const { return idx != std::numeric_limits<size_t>::max(); }
28};
29
30/// A finite 3D grid structure, mapping/binning arbitrary 3D cartesian points
31/// onto discrete "voxels". Each such voxel can store an object of type T.
32/// The precision of the voxel binning is done with S (float or double).
33template <typename T, typename S = float>
35public:
36 TGeoVoxelGrid(S xmin, S ymin, S zmin, S xmax, S ymax, S zmax, S Lx_, S Ly_, S Lz_)
37 : fMinBound{xmin, ymin, zmin}, fMaxBound{xmax, ymax, zmax}, fLx(Lx_), fLy(Ly_), fLz(Lz_)
38 {
39
40 // Calculate the number of voxels in each dimension
41 fNx = static_cast<int>((fMaxBound[0] - fMinBound[0]) / fLx);
42 fNy = static_cast<int>((fMaxBound[1] - fMinBound[1]) / fLy);
43 fNz = static_cast<int>((fMaxBound[2] - fMinBound[2]) / fLz);
44
45 finvLx = 1. / fLx;
46 finvLy = 1. / fLy;
47 finvLz = 1. / fLz;
48
49 fHalfDiag = std::sqrt(fLx / 2. * fLx / 2. + fLy / 2. * fLy / 2. + fLz / 2. * fLz / 2.);
50
51 // Resize the grid to hold the voxels
52 fGrid.resize(fNx * fNy * fNz);
53 }
54
55 T &at(int i, int j, int k) { return fGrid[index(i, j, k)]; }
56
57 // check if point is covered by voxel structure
58 bool inside(std::array<S, 3> const &p) const
59 {
60 for (int i = 0; i < 3; ++i) {
61 if (p[i] < fMinBound[i] || p[i] > fMaxBound[i]) {
62 return false;
63 }
64 }
65 return true;
66 }
67
68 // Access a voxel given a 3D point P
69 T &at(std::array<S, 3> const &P)
70 {
71 int i, j, k;
72 pointToVoxelIndex(P, i, j, k); // Convert point to voxel index
73 return fGrid[index(i, j, k)]; // Return reference to voxel's data
74 }
75
77 {
78 if (!vi.isValid()) {
79 return nullptr;
80 }
81 return &fGrid[vi.idx];
82 }
83
84 // Set the data of a voxel at point P
85 void set(std::array<S, 3> const &p, const T &value)
86 {
87 int i, j, k;
88 pointToVoxelIndex(p, i, j, k); // Convert point to voxel index
89 fGrid[index(i, j, k)] = value; // Set the value at the voxel
90 }
91
92 // Set the data of a voxel at point P
93 void set(int i, int j, int k, const T &value)
94 {
95 fGrid[index(i, j, k)] = value; // Set the value at the voxel
96 }
97
98 void set(TGeoVoxelGridIndex const &vi, const T &value) { fGrid[vi.idx] = value; }
99
100 // Get voxel dimensions
101 int getVoxelCountX() const { return fNx; }
102 int getVoxelCountY() const { return fNy; }
103 int getVoxelCountZ() const { return fNz; }
104
105 // returns the cartesian mid-point coordinates of a voxel given by a VoxelIndex
106 std::array<S, 3> getVoxelMidpoint(TGeoVoxelGridIndex const &vi) const
107 {
108 const S midX = fMinBound[0] + (vi.ix + 0.5) * fLx;
109 const S midY = fMinBound[1] + (vi.iy + 0.5) * fLy;
110 const S midZ = fMinBound[2] + (vi.iz + 0.5) * fLz;
111
112 return {midX, midY, midZ};
113 }
114
115 S getDiagonalLength() const { return fHalfDiag; }
116
117 // Convert a point p(x, y, z) to voxel indices (i, j, k)
118 // if point is outside set indices i,j,k to -1
119 void pointToVoxelIndex(std::array<S, 3> const &p, int &i, int &j, int &k) const
120 {
121 if (!inside(p)) {
122 i = -1;
123 j = -1;
124 k = -1;
125 }
126
127 i = static_cast<int>((p[0] - fMinBound[0]) * finvLx);
128 j = static_cast<int>((p[1] - fMinBound[1]) * finvLy);
129 k = static_cast<int>((p[2] - fMinBound[2]) * finvLz);
130
131 // Clamp the indices to valid ranges
132 i = std::min(i, fNx - 1);
133 j = std::min(j, fNy - 1);
134 k = std::min(k, fNz - 1);
135 }
136
137 // Convert a point p(x, y, z) to voxel index object
138 // if outside, an invalid index object will be returned
139 TGeoVoxelGridIndex pointToVoxelIndex(std::array<S, 3> const &p) const
140 {
141 if (!inside(p)) {
142 return TGeoVoxelGridIndex(); // invalid voxel index
143 }
144
145 int i = static_cast<int>((p[0] - fMinBound[0]) * finvLx);
146 int j = static_cast<int>((p[1] - fMinBound[1]) * finvLy);
147 int k = static_cast<int>((p[2] - fMinBound[2]) * finvLz);
148
149 // Clamp the indices to valid ranges
150 i = std::min(i, fNz - 1);
151 j = std::min(j, fNy - 1);
152 k = std::min(k, fNz - 1);
153
154 return TGeoVoxelGridIndex{i, j, k, index(i, j, k)};
155 }
156
157 TGeoVoxelGridIndex pointToVoxelIndex(S x, S y, S z) const { return pointToVoxelIndex(std::array<S, 3>{x, y, z}); }
158
159 // Convert voxel indices (i, j, k) to a linear index in the grid array
160 size_t index(int i, int j, int k) const { return i + fNx * (j + fNy * k); }
161
162 void indexToIndices(size_t idx, int &i, int &j, int &k) const
163 {
164 k = idx % fNz;
165 j = (idx / fNz) % fNy;
166 i = idx / (fNy * fNz);
167 }
168
169 // member data
170
171 std::array<S, 3> fMinBound;
172 std::array<S, 3> fMaxBound; // 3D bounds for grid structure
173 S fLx, fLy, fLz; // Voxel dimensions
174 S finvLx, finvLy, finvLz; // inverse voxel dimensions
175 S fHalfDiag; // cached value for voxel half diagonal length
176
177 int fNx, fNy, fNz; // Number of voxels in each dimension
178 std::vector<T> fGrid; // The actual voxel grid data container
179};
180
181#endif
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
float xmin
float ymin
float xmax
float ymax
A finite 3D grid structure, mapping/binning arbitrary 3D cartesian points onto discrete "voxels".
std::vector< T > fGrid
S getDiagonalLength() const
void indexToIndices(size_t idx, int &i, int &j, int &k) const
std::array< S, 3 > fMinBound
int getVoxelCountY() const
size_t index(int i, int j, int k) const
TGeoVoxelGridIndex pointToVoxelIndex(S x, S y, S z) const
int getVoxelCountX() const
std::array< S, 3 > getVoxelMidpoint(TGeoVoxelGridIndex const &vi) const
void set(TGeoVoxelGridIndex const &vi, const T &value)
int getVoxelCountZ() const
T & at(std::array< S, 3 > const &P)
T * at(TGeoVoxelGridIndex const &vi)
bool inside(std::array< S, 3 > const &p) const
T & at(int i, int j, int k)
std::array< S, 3 > fMaxBound
TGeoVoxelGrid(S xmin, S ymin, S zmin, S xmax, S ymax, S zmax, S Lx_, S Ly_, S Lz_)
TGeoVoxelGridIndex pointToVoxelIndex(std::array< S, 3 > const &p) const
void set(std::array< S, 3 > const &p, const T &value)
void set(int i, int j, int k, const T &value)
void pointToVoxelIndex(std::array< S, 3 > const &p, int &i, int &j, int &k) const
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
bool isValid() const