Warning, file /include/root/TGeoVoxelGrid.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef ROOT_TGeoVoxelGrid
0013 #define ROOT_TGeoVoxelGrid
0014
0015 #include <array>
0016 #include <cmath>
0017 #include <limits>
0018
0019
0020
0021 struct TGeoVoxelGridIndex {
0022 int ix{-1};
0023 int iy{-1};
0024 int iz{-1};
0025 size_t idx{std::numeric_limits<size_t>::max()};
0026 bool isValid() const { return idx != std::numeric_limits<size_t>::max(); }
0027 };
0028
0029
0030
0031
0032 template <typename T, typename S = float>
0033 class TGeoVoxelGrid {
0034 public:
0035 TGeoVoxelGrid(S xmin, S ymin, S zmin, S xmax, S ymax, S zmax, S Lx_, S Ly_, S Lz_)
0036 : fMinBound{xmin, ymin, zmin}, fMaxBound{xmax, ymax, zmax}, fLx(Lx_), fLy(Ly_), fLz(Lz_)
0037 {
0038
0039
0040 fNx = static_cast<int>((fMaxBound[0] - fMinBound[0]) / fLx);
0041 fNy = static_cast<int>((fMaxBound[1] - fMinBound[1]) / fLy);
0042 fNz = static_cast<int>((fMaxBound[2] - fMinBound[2]) / fLz);
0043
0044 finvLx = 1. / fLx;
0045 finvLy = 1. / fLy;
0046 finvLz = 1. / fLz;
0047
0048 fHalfDiag = std::sqrt(fLx / 2. * fLx / 2. + fLy / 2. * fLy / 2. + fLz / 2. * fLz / 2.);
0049
0050
0051 fGrid.resize(fNx * fNy * fNz);
0052 }
0053
0054 T &at(int i, int j, int k) { return fGrid[index(i, j, k)]; }
0055
0056
0057 bool inside(std::array<S, 3> const &p) const
0058 {
0059 for (int i = 0; i < 3; ++i) {
0060 if (p[i] < fMinBound[i] || p[i] > fMaxBound[i]) {
0061 return false;
0062 }
0063 }
0064 return true;
0065 }
0066
0067
0068 T &at(std::array<S, 3> const &P)
0069 {
0070 int i, j, k;
0071 pointToVoxelIndex(P, i, j, k);
0072 return fGrid[index(i, j, k)];
0073 }
0074
0075 T *at(TGeoVoxelGridIndex const &vi)
0076 {
0077 if (!vi.isValid()) {
0078 return nullptr;
0079 }
0080 return &fGrid[vi.idx];
0081 }
0082
0083
0084 void set(std::array<S, 3> const &p, const T &value)
0085 {
0086 int i, j, k;
0087 pointToVoxelIndex(p, i, j, k);
0088 fGrid[index(i, j, k)] = value;
0089 }
0090
0091
0092 void set(int i, int j, int k, const T &value)
0093 {
0094 fGrid[index(i, j, k)] = value;
0095 }
0096
0097 void set(TGeoVoxelGridIndex const &vi, const T &value) { fGrid[vi.idx] = value; }
0098
0099
0100 int getVoxelCountX() const { return fNx; }
0101 int getVoxelCountY() const { return fNy; }
0102 int getVoxelCountZ() const { return fNz; }
0103
0104
0105 std::array<S, 3> getVoxelMidpoint(TGeoVoxelGridIndex const &vi) const
0106 {
0107 const S midX = fMinBound[0] + (vi.ix + 0.5) * fLx;
0108 const S midY = fMinBound[1] + (vi.iy + 0.5) * fLy;
0109 const S midZ = fMinBound[2] + (vi.iz + 0.5) * fLz;
0110
0111 return {midX, midY, midZ};
0112 }
0113
0114 S getDiagonalLength() const { return fHalfDiag; }
0115
0116
0117
0118 void pointToVoxelIndex(std::array<S, 3> const &p, int &i, int &j, int &k) const
0119 {
0120 if (!inside(p)) {
0121 i = -1;
0122 j = -1;
0123 k = -1;
0124 }
0125
0126 i = static_cast<int>((p[0] - fMinBound[0]) * finvLx);
0127 j = static_cast<int>((p[1] - fMinBound[1]) * finvLy);
0128 k = static_cast<int>((p[2] - fMinBound[2]) * finvLz);
0129
0130
0131 i = std::min(i, fNx - 1);
0132 j = std::min(j, fNy - 1);
0133 k = std::min(k, fNz - 1);
0134 }
0135
0136
0137
0138 TGeoVoxelGridIndex pointToVoxelIndex(std::array<S, 3> const &p) const
0139 {
0140 if (!inside(p)) {
0141 return TGeoVoxelGridIndex();
0142 }
0143
0144 int i = static_cast<int>((p[0] - fMinBound[0]) * finvLx);
0145 int j = static_cast<int>((p[1] - fMinBound[1]) * finvLy);
0146 int k = static_cast<int>((p[2] - fMinBound[2]) * finvLz);
0147
0148
0149 i = std::min(i, fNz - 1);
0150 j = std::min(j, fNy - 1);
0151 k = std::min(k, fNz - 1);
0152
0153 return TGeoVoxelGridIndex{i, j, k, index(i, j, k)};
0154 }
0155
0156 TGeoVoxelGridIndex pointToVoxelIndex(S x, S y, S z) const { return pointToVoxelIndex(std::array<S, 3>{x, y, z}); }
0157
0158
0159 size_t index(int i, int j, int k) const { return i + fNx * (j + fNy * k); }
0160
0161 void indexToIndices(size_t idx, int &i, int &j, int &k) const
0162 {
0163 k = idx % fNz;
0164 j = (idx / fNz) % fNy;
0165 i = idx / (fNy * fNz);
0166 }
0167
0168
0169
0170 std::array<S, 3> fMinBound;
0171 std::array<S, 3> fMaxBound;
0172 S fLx, fLy, fLz;
0173 S finvLx, finvLy, finvLz;
0174 S fHalfDiag;
0175
0176 int fNx, fNy, fNz;
0177 std::vector<T> fGrid;
0178 };
0179
0180 #endif