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