Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4KDTree.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26/*
27 * G4KDTree.cc
28 *
29 * Created on: 22 oct. 2013
30 * Author: kara
31 */
32
33#include "globals.hh"
34#include <cstdio>
35#include <cmath>
36#include "G4KDTree.hh"
37#include "G4KDMap.hh"
38#include "G4KDNode.hh"
39#include "G4KDTreeResult.hh"
40#include <list>
41#include <iostream>
42
43using namespace std;
44
46{
47 G4ThreadLocalStatic G4Allocator<G4KDTree>* _instance = nullptr;
48 return _instance;
49}
50
51//______________________________________________________________________
52// KDTree methods
54 : fDim(k)
55 ,fKDMap(new G4KDMap(k))
56{}
57
59{
60 if(fRoot){
62 fRoot = nullptr;
63 }
64
65 if(fRect){
66 delete fRect;
67 fRect = nullptr;
68 }
69
70 if(fKDMap){
71 delete fKDMap;
72 fKDMap = nullptr;
73 }
74}
75
76void* G4KDTree::operator new(size_t)
77{
78 if(!fgAllocator()){
79 fgAllocator() = new G4Allocator<G4KDTree>;
80 }
81 return (void*) fgAllocator()->MallocSingle();
82}
83
84void G4KDTree::operator delete(void* aNode)
85{
86 fgAllocator()->FreeSingle((G4KDTree*) aNode);
87}
88
89void G4KDTree::Print(std::ostream& out) const
90{
91 if(fRoot){
92 fRoot->Print(out);
93 }
94}
95
97{
99 fRoot = nullptr;
100 fNbNodes = 0;
101
102 if(fRect)
103 {
104 delete fRect;
105 fRect = nullptr;
106 }
107}
108
110{
111 if(!node)
112 {
113 return;
114 }
115
116 if(node->GetLeft())
117 {
118 __Clear_Rec(node->GetLeft());
119 }
120 if(node->GetRight())
121 {
122 __Clear_Rec(node->GetRight());
123 }
124
125 delete node;
126}
127
129
131{
132 size_t Nnodes = fKDMap->GetSize();
133
134 G4cout << "********************" << G4endl;
135 G4cout << "template<typename PointT> G4KDTree<PointT>::Build" << G4endl;
136 G4cout << "Map size = " << Nnodes << G4endl;
137
139
140 if(root == nullptr)
141 {
142 return;
143 }
144
145 fRoot = root;
147 fRect = new HyperRect(fDim);
149
150 Nnodes--;
151
152 G4KDNode_Base* parent = fRoot;
153
154 for(size_t n = 0; n < Nnodes; n += fDim)
155 {
156 for(size_t dim = 0; dim < fDim; dim++)
157 {
158 G4KDNode_Base* node = fKDMap->PopOutMiddle(dim);
159 if(node)
160 {
161 parent->Insert(node);
163 fRect->Extend(*node);
164 parent = node;
165 }
166 }
167 }
168}
169
171{
172 if(!fRect)
173 {
174 return nullptr;
175 }
176
177 std::vector<G4KDNode_Base*> result;
178 G4double dist_sq = DBL_MAX;
179
180 /* Duplicate the bounding hyperrectangle, we will work on the copy */
181 auto newrect = new HyperRect(*fRect);
182
183 /* Search for the nearest neighbour recursively */
184 G4int nbresult = 0;
185
186 __NearestToNode(node, fRoot, *node, result, &dist_sq, newrect, nbresult);
187
188 /* Free the copy of the hyperrect */
189 delete newrect;
190
191 /* Store the result */
192 if(!result.empty())
193 {
194 G4KDTreeResultHandle rset(new G4KDTreeResult(this));
195 G4int j = 0;
196 while(j < nbresult)
197 {
198 rset->Insert(dist_sq, result[j]);
199 j++;
200 }
201 rset->Rewind();
202
203 return rset;
204 }
205 else
206 {
207 return nullptr;
208 }
209}
210
212 const G4double& range)
213{
214 if(!node)
215 {
216 return nullptr;
217 }
218 G4int ret(-1);
219
220 auto* rset = new G4KDTreeResult(this);
221
222 const G4double range_sq = sqr(range);
223
224 if((ret = __NearestInRange(fRoot, *node, range_sq, range, *rset, 0, node)) ==
225 -1)
226 {
227 delete rset;
228 return nullptr;
229 }
230 rset->Sort();
231 rset->Rewind();
232 return rset;
233}
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
Type * MallocSingle()
Definition: G4Allocator.hh:195
std::size_t GetSize()
Definition: G4KDMap.hh:112
void Insert(G4KDNode_Base *pos)
Definition: G4KDMap.cc:90
G4KDNode_Base * PopOutMiddle(std::size_t dimension)
Definition: G4KDMap.cc:137
G4KDNode_Base * GetRight()
Definition: G4KDNode.hh:82
G4KDNode_Base * Insert(PointT *point)
G4KDNode_Base * GetLeft()
Definition: G4KDNode.hh:81
void Print(std::ostream &out, G4int level=0) const
Definition: G4KDNode.cc:177
void SetMinMax(const Position &min, const Position &max)
Definition: G4KDTree.hh:139
void Extend(const Position &pos)
Definition: G4KDTree.hh:168
HyperRect * fRect
Definition: G4KDTree.hh:245
void __NearestToNode(G4KDNode_Base *source_node, G4KDNode_Base *node, const Position &pos, std::vector< G4KDNode_Base * > &result, G4double *result_dist_sq, HyperRect *fRect, G4int &nbresult)
G4KDTreeResultHandle Nearest(const Position &pos)
G4int __NearestInRange(G4KDNode_Base *node, const Position &pos, const G4double &range_sq, const G4double &range, G4KDTreeResult &list, G4int ordered, G4KDNode_Base *source_node=nullptr)
G4KDNode_Base * fRoot
Definition: G4KDTree.hh:246
void Print(std::ostream &out=G4cout) const
Definition: G4KDTree.cc:89
G4KDTreeResultHandle NearestInRange(const Position &pos, const G4double &range)
G4int fNbActiveNodes
Definition: G4KDTree.hh:249
void __InsertMap(G4KDNode_Base *node)
Definition: G4KDTree.cc:128
std::size_t fDim
Definition: G4KDTree.hh:247
~G4KDTree()
Definition: G4KDTree.cc:58
G4int fNbNodes
Definition: G4KDTree.hh:248
void Build()
Definition: G4KDTree.cc:130
static G4Allocator< G4KDTree > *& fgAllocator()
Definition: G4KDTree.cc:45
void __Clear_Rec(G4KDNode_Base *node)
Definition: G4KDTree.cc:109
void Clear()
Definition: G4KDTree.cc:96
G4KDTree(std::size_t dim=3)
Definition: G4KDTree.cc:53
G4KDMap * fKDMap
Definition: G4KDTree.hh:250
T sqr(const T &x)
Definition: templates.hh:128
#define DBL_MAX
Definition: templates.hh:62
#define G4ThreadLocalStatic
Definition: tls.hh:76