Geant4-11
G4DNAMesh.cc
Go to the documentation of this file.
1// ********************************************************************
2// * License and Disclaimer *
3// * *
4// * The Geant4 software is copyright of the Copyright Holders of *
5// * the Geant4 Collaboration. It is provided under the terms and *
6// * conditions of the Geant4 Software License, included in the file *
7// * LICENSE and available at http://cern.ch/geant4/license . These *
8// * include a list of copyright holders. *
9// * *
10// * Neither the authors of this software system, nor their employing *
11// * institutes,nor the agencies providing financial support for this *
12// * work make any representation or warranty, express or implied, *
13// * regarding this software system or assume any liability for its *
14// * use. Please see the license in the file LICENSE and URL above *
15// * for the full disclaimer and the limitation of liability. *
16// * *
17// * This code implementation is the result of the scientific and *
18// * technical work of the GEANT4 collaboration. *
19// * By using, copying, modifying or distributing the software (or *
20// * any work based on the software) you agree to acknowledge its *
21// * use in resulting scientific publications, and indicate your *
22// * acceptance of all terms of the Geant4 Software license. *
23// ********************************************************************
24//
25#include "G4DNAMesh.hh"
26#include <algorithm>
27#include <cassert>
28#include <ostream>
29
31 : fpBoundingMesh(&boundingBox)
32 , fResolution((2 * boundingBox.halfSideLengthInY() / pixel))
33{}
34
36
38{
39 auto iter = fMesh.find(key);
40 if(iter == fMesh.end())
41 {
42 G4Voxel::MapList maplist;
43 SetVoxelMapList(key, std::move(maplist));
44 return GetVoxelMapList(key);
45 }
46 else
47 {
48 return iter->second->GetMapList();
49 }
50}
51
53{
54 auto key = GetKey(index);
55 return GetVoxelMapList(key);
56}
57
59{
60 auto xmax = (unsigned int) (std::floor(
62 auto ymax = (unsigned int) (std::floor(
64 return index.z * ymax * xmax + index.y * xmax + index.x;
65}
66
68{
69 G4cout << "*********PrintMesh::Size : " << fMesh.size() << G4endl;
70 auto iter = fMesh.begin();
71 for(; iter != fMesh.end(); iter++)
72 {
73 auto index = iter->second->GetIndex();
74 PrintVoxel(index);
75 }
76 G4cout << G4endl;
77}
79{
80 G4int output = 0;
81 auto iter = fMesh.begin();
82 for(; iter != fMesh.end(); iter++)
83 {
84 auto node = dynamic_cast<G4Voxel*>(iter->second);
85 if(node == nullptr)
86 {
87 continue;
88 }
89 auto it = node->GetMapList().find(type);
90 if(it != node->GetMapList().end())
91 {
92 output += it->second;
93 }
94 }
95 return output;
96}
97
98void G4DNAMesh::PrintVoxel(const Index& index)
99{
100 G4cout << "*********PrintVoxel::";
101 G4cout << "key: " << GetKey(index) << " index : " << index
102 << " number of type : " << this->GetVoxelMapList(index).size()
103 << G4endl;
104
105 for(const auto& it : this->GetVoxelMapList(index))
106 {
107 G4cout << "_____________" << it.first->GetName() << " : " << it.second
108 << G4endl;
109 }
110 G4cout << G4endl;
111}
112
114{
115 auto index = GetIndex(key);
116 auto pVoxel = fMesh[key];
117 if(nullptr == pVoxel)
118 {
119 pVoxel = new G4Voxel(std::move(mapList), index, GetBoundingBox(index));
120 fMesh[key] = pVoxel;
121 }
122 else
123 {
124 assert(pVoxel->GetMapList().empty()); // check if map list is empty
125 pVoxel->SetMapList(std::move(mapList));
126 }
127}
128
130{
131 int dx = std::floor((position.x() - fpBoundingMesh->Getxlo()) / fResolution);
132 int dy = std::floor((position.y() - fpBoundingMesh->Getylo()) / fResolution);
133 int dz = std::floor((position.z() - fpBoundingMesh->Getzlo()) / fResolution);
134 assert(dx >= 0 && dy >= 0 && dz >= 0);
135 return G4Voxel::Index{ dx, dy, dz };
136}
137G4Voxel::Index G4DNAMesh::GetIndex(const Index& index, int pixels) const
138{
139 int xmax =
140 std::floor((fpBoundingMesh->Getxhi() - fpBoundingMesh->Getxlo()) / fResolution);
141 int ymax =
142 std::floor((fpBoundingMesh->Getyhi() - fpBoundingMesh->Getylo()) / fResolution);
143 int zmax =
144 std::floor((fpBoundingMesh->Getzhi() - fpBoundingMesh->Getzlo()) / fResolution);
145 int dx = (int) (index.x * pixels / xmax);
146 int dy = (int) (index.y * pixels / ymax);
147 int dz = (int) (index.z * pixels / zmax);
148 assert(dx >= 0 && dy >= 0 && dz >= 0);
149 return Index{ dx, dy, dz };
150}
151
153{
154 auto xlo = fpBoundingMesh->Getxlo() + index.x * fResolution;
155 auto ylo = fpBoundingMesh->Getylo() + index.y * fResolution;
156 auto zlo = fpBoundingMesh->Getzlo() + index.z * fResolution;
157
158 auto xhi = fpBoundingMesh->Getxlo() + (index.x + 1) * fResolution;
159 auto yhi = fpBoundingMesh->Getylo() + (index.y + 1) * fResolution;
160 auto zhi = fpBoundingMesh->Getzlo() + (index.z + 1) * fResolution;
161 return G4DNABoundingBox({ xhi, xlo, yhi, ylo, zhi, zlo });
162}
163
165{
166 G4int xmax =
167 std::floor((fpBoundingMesh->Getxhi() - fpBoundingMesh->Getxlo()) / fResolution);
168 G4int ymax =
169 std::floor((fpBoundingMesh->Getyhi() - fpBoundingMesh->Getylo()) / fResolution);
170 G4int id = key;
171 G4int x_ = id % xmax;
172 id /= xmax;
173 G4int y_ = id % ymax;
174 id /= ymax;
175 G4int z_ = id;
176
177 if(xmax != ymax)
178 {
179 G4cout << xmax << " " << ymax << " " << key << G4endl;
180 G4ExceptionDescription exceptionDescription;
181 exceptionDescription << "xmax != ymax";
182 G4Exception("G4DNAMesh::GetIndex", "G4DNAMesh006", FatalErrorInArgument,
183 exceptionDescription);
184 }
185
186 if(x_ < 0 || y_ < 0 || z_ < 0)
187 {
188 G4cout << xmax << " " << ymax << " " << key << G4endl;
189 G4cout << x_ << " " << y_ << " " << z_ << G4endl;
190 G4ExceptionDescription exceptionDescription;
191 exceptionDescription << "x_ < 0 || y_ < 0 || z_ < 0";
192 G4Exception("G4DNAMesh::GetIndex", "G4DNAMesh005", FatalErrorInArgument,
193 exceptionDescription);
194 }
195 return Index{ x_, y_, z_ };
196}
197
199{
200 if(fMesh.empty())
201 {
202 return;
203 }
204 for(auto iter : fMesh) // should use smart ptr
205 {
206 delete iter.second;
207 }
208 fMesh.clear();
209}
210
212{
213 return *fpBoundingMesh;
214}
215
217{
218 auto it = fMesh.find(key);
219 if(it != fMesh.end())
220 {
221 return it->second;
222 }
223 return nullptr;
224}
225
226[[maybe_unused]] G4Voxel* G4DNAMesh::GetVoxel(const Index& index)
227{
228 return GetVoxel(GetKey(index));
229}
230
231std::vector<G4Voxel::Index> // array is better ?
233{
234 std::vector<Index> neighbors;
235
236 auto xMax = (int) (std::floor(
238 auto yMax = (int) (std::floor(
240 auto zMax = (int) (std::floor(
242
243 auto xmin = (index.x - 1) < 0 ? 0 : (index.x - 1);
244 auto ymin = (index.y - 1) < 0 ? 0 : (index.y - 1);
245 auto zmin = (index.z - 1) < 0 ? 0 : (index.z - 1);
246
247 auto xmax = (index.x + 1) > xMax ? xMax : (index.x + 1);
248 auto ymax = (index.y + 1) > yMax ? yMax : (index.y + 1);
249 auto zmax = (index.z + 1) > zMax ? zMax : (index.z + 1);
250 for(int ix = xmin; ix <= xmax; ix++)
251 {
252 for(int iy = ymin; iy <= ymax; iy++)
253 {
254 for(int iz = zmin; iz <= zmax; iz++)
255 {
256 auto key = iz * yMax * xMax + iy * xMax + ix;
257 if(GetIndex(key) != index)
258 { // deleting the middle element
259 neighbors.push_back(GetIndex(key));
260 }
261 }
262 }
263 }
264 if(neighbors.empty())
265 {
266 G4ExceptionDescription exceptionDescription;
267 exceptionDescription << "neighbors.empty()";
268 G4Exception("G4DNAMesh::FindVoxelNeighbors", "G4DNAMesh001",
269 FatalErrorInArgument, exceptionDescription);
270 }
271
272 return neighbors;
273}
274
275std::vector<G4Voxel::Index> // array is better ?
277{
278 std::vector<Index> neighbors;
279 // auto key = GetKey(index);
280 auto xMax = (int) (std::floor(
282 auto yMax = (int) (std::floor(
284 auto zMax = (int) (std::floor(
286
287 if(index.x - 1 >= 0)
288 {
289 neighbors.emplace_back(Index(index.x - 1, index.y, index.z));
290 }
291 if(index.y - 1 >= 0)
292 {
293 neighbors.emplace_back(Index(index.x, index.y - 1, index.z));
294 }
295 if(index.z - 1 >= 0)
296 {
297 neighbors.emplace_back(Index(index.x, index.y, index.z - 1));
298 }
299 if(index.x + 1 < xMax)
300 {
301 neighbors.emplace_back(Index(index.x + 1, index.y, index.z));
302 }
303 if(index.y + 1 < yMax)
304 {
305 neighbors.emplace_back(Index(index.x, index.y + 1, index.z));
306 }
307 if(index.z + 1 < zMax)
308 {
309 neighbors.emplace_back(Index(index.x, index.y, index.z + 1));
310 }
311
312#ifdef DEBUG
313 G4cout << "Neighbors of : " << index << G4endl;
314 for(const auto& it : neighbors)
315 {
316 G4cout << it << G4endl;
317 }
318#endif
319
320 if(neighbors.size() > 6)
321 {
322 G4ExceptionDescription exceptionDescription;
323 exceptionDescription << "neighbors.size() > 6";
324 G4Exception("G4DNAMesh::FindVoxelNeighbors", "G4DNAMesh002",
325 FatalErrorInArgument, exceptionDescription);
326 }
327 return neighbors;
328}
329
331
333{
335 {
336 G4ExceptionDescription exceptionDescription;
337 exceptionDescription << "the position: " << position
338 << " is not in the box";
339 G4Exception("G4DNAMesh::GetKey", "G4DNAMesh010", FatalErrorInArgument,
340 exceptionDescription);
341 }
342
343 auto dx = std::floor((position.x() - fpBoundingMesh->Getxlo()) / fResolution);
344 auto dy = std::floor((position.y() - fpBoundingMesh->Getylo()) / fResolution);
345 auto dz = std::floor((position.z() - fpBoundingMesh->Getzlo()) / fResolution);
346 auto xmax =
347 std::floor((fpBoundingMesh->Getxhi() - fpBoundingMesh->Getxlo()) / fResolution);
348 auto ymax =
349 std::floor((fpBoundingMesh->Getyhi() - fpBoundingMesh->Getylo()) / fResolution);
350 return dz * ymax * xmax + dy * xmax + dx;
351}
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
G4double Getxlo() const
G4double Getyhi() const
G4double Getylo() const
G4double Getxhi() const
G4bool contains(const G4DNABoundingBox &other) const
G4double Getzlo() const
G4double Getzhi() const
void PrintVoxel(const Index &index)
Definition: G4DNAMesh.cc:98
void SetVoxelMapList(const Key &key, G4Voxel::MapList &&mapList)
Definition: G4DNAMesh.cc:113
~G4DNAMesh()
Definition: G4DNAMesh.cc:35
unsigned int Key
Definition: G4DNAMesh.hh:116
void PrintMesh()
Definition: G4DNAMesh.cc:67
G4double GetResolution() const
Definition: G4DNAMesh.cc:330
Key GetKey(const G4ThreeVector &pos) const
Definition: G4DNAMesh.cc:332
std::vector< Index > FindNeighboringVoxels(const Index &index) const
Definition: G4DNAMesh.cc:276
void Reset()
Definition: G4DNAMesh.cc:198
G4Voxel * GetVoxel(Key key)
Definition: G4DNAMesh.cc:216
std::vector< Index > FindVoxelNeighbors(const Index &index) const
Definition: G4DNAMesh.cc:232
G4Voxel::MapList & GetVoxelMapList(Key key)
Definition: G4DNAMesh.cc:37
const G4DNABoundingBox * fpBoundingMesh
Definition: G4DNAMesh.hh:153
VoxelMap fMesh
Definition: G4DNAMesh.hh:152
const G4DNABoundingBox & GetBoundingBox() const
Definition: G4DNAMesh.cc:211
G4double fResolution
Definition: G4DNAMesh.hh:154
G4int GetNumberOfType(G4Voxel::MolType type) const
Definition: G4DNAMesh.cc:78
Index GetIndex(Key key) const
Definition: G4DNAMesh.cc:164
G4DNAMesh(const G4DNABoundingBox &, G4int)
Definition: G4DNAMesh.cc:30
G4Voxel::Index Index
Definition: G4DNAMesh.hh:115
MapList & GetMapList()
Definition: G4DNAMesh.hh:89
std::map< MolType, size_t > MapList
Definition: G4DNAMesh.hh:77