Geant4  10.00.p03
G4ITManager.icc
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 // $Id$
27 //
28 // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
29 //
30 // WARNING : This class is released as a prototype.
31 // It might strongly evolve or even disapear in the next releases.
32 //
33 // History:
34 // -----------
35 // 10 Oct 2011 M.Karamitros created
36 //
37 // -------------------------------------------------------------------
38 
39 TEMPLATE
40 G4ThreadLocal G4ITMANAGER * G4ITMANAGER::fInstance(0);
41 
42 TEMPLATE
43 G4ITMANAGER * G4ITMANAGER::Instance()
44 {
45  if(!fInstance)
46  fInstance = new G4ITManager();
47 
48  return fInstance;
49 }
50 
51 TEMPLATE
52 G4ITMANAGER::G4ITManager() : G4VITManager()
53 {
54  fType = T::ITType();
55  SetVerboseLevel(G4AllITManager::Instance()->GetVerboseLevel());
56  G4AllITManager::Instance()->RegisterManager(this);
57 }
58 
59 TEMPLATE
60 G4ITMANAGER::~G4ITManager()
61 {
62  {
63  typename BoxMap::iterator it;
64 
65  for(it = fBox.begin() ; it != fBox.end() ; it++)
66  {
67  if(it->second)
68  delete it->second;
69  }
70  fBox.clear();
71  }
72  {
73 
74  typename TreeMap::iterator it;
75 
76  for(it = fTree.begin() ; it != fTree.end() ; it++)
77  {
78  if(it->second)
79  delete it->second;
80  }
81 
82  fTree.clear();
83 
84  for(it = fPrevious_tree.begin() ; it != fPrevious_tree.end() ; it++)
85  {
86  if(it->second)
87  delete it->second;
88  }
89 
90  fPrevious_tree.clear();
91  }
92 }
93 
94 TEMPLATE
95 void G4ITMANAGER::iUpdatePositionMap()
96 {
97  fInstance->UpdatePositionMap();
98 }
99 
100 TEMPLATE
101 void G4ITMANAGER::Push(G4Track* track)
102 {
103  G4IT* aIT = GetIT(track) ;
104  aIT->RecordCurrentPositionNTime();
105 
106  const T& key = dynamic_cast<const T&>(*aIT);
107 
108  typename BoxMap::iterator it = fBox.find(key);
109 
110  if(it != fBox.end())
111  {
112  G4ITBox* theBox = it->second;
113  theBox->Push(aIT);
114  }
115  else
116  {
117  G4ITBox * itBox = new G4ITBox();
118  std::pair<typename BoxMap::iterator,bool> ret = fBox.insert(std::make_pair (T(key), itBox)) ;
119 
120  typename BoxMap::iterator box_placement = ret.first;
121  typename BoxMap::iterator last_placement = fBox.end();
122  last_placement--;
123 
124  if(box_placement != fBox.begin())
125  {
126  typename BoxMap::iterator previous_placement = ret.first;
127  previous_placement--;
128  G4ITBox* previous_box = previous_placement->second;
129  if(previous_box)
130  {
131  itBox->SetPreviousBox(previous_box);
132  previous_box->SetNextBox(itBox);
133  }
134  }
135  if(box_placement != last_placement)
136  {
137  typename BoxMap::iterator next_placement = ret.first;
138  next_placement++;
139  G4ITBox* next_box = next_placement->second;
140  if(next_box)
141  {
142  itBox->SetNextBox(next_placement->second);
143  next_box->SetPreviousBox(itBox);
144  }
145  }
146 
147  itBox -> Push(aIT);
148  }
149 
150  if(!(aIT->GetNode()))
151  {
152  G4KDNode* node = 0;
153  G4ThreeVector position = aIT->GetTrack()->GetPosition();
154 
155  typename TreeMap::iterator it_fTree = fTree.find(key);
156 
157  if(it_fTree != fTree.end())
158  {
159  node=it_fTree->second->Insert(position.x(),
160  position.y(),
161  position.z(),
162  aIT);
163  }
164  else
165  {
166  G4KDTree* aTree = new G4KDTree() ;
167  fTree.insert(std::make_pair(T(key),aTree));
168  node = aTree->Insert(position.x(),
169  position.y(),
170  position.z(),
171  aIT);
172  }
173 
174  aIT->SetNode(node);
175  }
176 
177 }
178 
179 TEMPLATE
180 void G4ITMANAGER::EraseABox(T* aIT)
181 {
182 // G4cout<<"G4ITMANAGER::EraseABox : " << aIT->GetName()<<G4endl;
183 
184  const T& key = dynamic_cast<const T&>(*aIT);
185  typename BoxMap::iterator it = fBox.find(key);
186  if(it != fBox.end())
187  {
188  fBox.erase(it);
189  }
190 }
191 
192 TEMPLATE
193 void G4ITMANAGER::EraseABox(G4ITBox* aStack)
194 {
195  typename BoxMap::iterator it;
196 
197  for ( it=fBox.begin() ; it != fBox.end(); it++)
198  {
199  if(it->second == aStack)
200  {
201  break;
202  }
203  }
204  fBox.erase(it);
205 }
206 
207 TEMPLATE
208 G4int G4ITMANAGER::NbElements(const G4IT* aIT)
209 {
210  const T& key = dynamic_cast<const T&>(*aIT);
211  typename BoxMap::iterator it = fBox.find(key);
212  if(it != fBox.end()) return it->second->GetNTrack();
213  return -1;
214 }
215 
216 
217 TEMPLATE
218 G4KDTreeResultHandle G4ITMANAGER::FindNearest(const G4ThreeVector& position, const T* key)
219 {
220  typename TreeMap::iterator it = fTree.find(*key);
221  if(it!= fTree.end())
222  return it->second->Nearest(position.x(),position.y(),position.z());
223  else
224  {
225  return 0;
226  }
227  return 0;
228 }
229 
230 TEMPLATE
231 G4KDTreeResultHandle G4ITMANAGER::FindNearest(const T* point0, const T* key)
232 {
233  if(*point0 == *key)
234  {
235  // DEBUG
236 // G4cout << "Equal keys !"<< G4endl;
237  G4KDNode* node0 = point0->GetNode() ;
238 
239  if(node0 == 0)
240  {
241  G4ExceptionDescription exceptionDescription
242  ("Bad request : no node found in the IT you are searching closest neighbourg for");
243  G4Exception("G4ITManager::FindNearest","ITManager002",
244  FatalErrorInArgument,exceptionDescription);
245  return 0; // coverity
246  }
247 
248  typename TreeMap::iterator it = fTree.find(*key);
249  if(it!= fTree.end())
250  {
251  G4KDTreeResultHandle output(it->second->Nearest(node0));
252 
253  if(!output)
254  {
255 // G4cout << "NO OUTPUT " << point0->GetName() << " " << key -> GetName() << G4endl;
256  return 0;
257  }
258 // G4cout << "OUTPUT" << G4endl;
259  return output;
260  }
261  else
262  {
263  // DEBUG
264 // G4cout << "Pas trouve dans la map"<< key->GetName() << G4endl;
265  return 0;
266  }
267  }
268  else
269  {
270  // DEBUG
271 // G4cout << "Not equal keys !"<< G4endl;
272  const G4ThreeVector& position = point0->GetTrack()->GetPosition() ;
273  typename TreeMap::iterator it = fTree.find(*key);
274  if(it!= fTree.end())
275  {
276  G4KDTreeResultHandle output(it->second->Nearest(position.x(),position.y(),position.z()));
277  if(!output)
278  {
279 // G4cout << "NO OUTPUT" << G4endl;
280  return 0;
281  }
282 
283 // G4cout << "OUTPUT" << G4endl;
284  return output;
285  }
286  else
287  {
288  // DEBUG
289 // G4cout << "Pas trouve dans la map : "<< key->GetName() << G4endl;
290  return 0;
291  }
292  }
293  return 0;
294 }
295 
296 TEMPLATE
297 G4KDTreeResultHandle G4ITMANAGER::FindNearestInRange(const G4ThreeVector& position, const T* key, G4double R)
298 {
299  typename TreeMap::iterator it = fTree.find(*key);
300  if(it!= fTree.end())
301  return it->second->NearestInRange(position.x(),position.y(),position.z(), R);
302  else
303  {
304  return 0;
305  }
306  return 0;
307 }
308 
309 TEMPLATE
310 G4KDTreeResultHandle G4ITMANAGER::FindNearestInRange(const T* point0, const T* key, G4double R)
311 {
312  if(*point0 == *key)
313  {
314  G4KDNode* node0 = point0->GetNode() ;
315  typename TreeMap::iterator it = fTree.find(*key);
316  if(it!= fTree.end())
317  return it->second->NearestInRange(node0, R);
318  else
319  {
320  return 0;
321  }
322  }
323  else
324  {
325  const G4ThreeVector& position = point0->GetTrack()->GetPosition() ;
326 
327  typename TreeMap::iterator it = fTree.find(*key);
328  if(it!= fTree.end())
329  return it->second->NearestInRange(position.x(),position.y(),position.z(), R);
330  else
331  {
332  return 0;
333  }
334  }
335  return 0;
336 }
337 
338 TEMPLATE
339 void G4ITMANAGER::UpdatePositionMap()
340 {
341  allbox_iterator allbox(this) ;
342 
343  if(allbox.GetBox() == 0) return;
344 
345  const G4ITBox* currentBox = 0 ;
346  const G4ITBox* buffBox = 0;
347  G4KDTree* currentTree = 0;
348  G4IT* currentIT = 0 ;
349 
350  typename TreeMap::iterator it_fTree ;
351 
352  if(!(fPrevious_tree.empty()))
353  {
354 
355  for(it_fTree = fPrevious_tree.begin() ; it_fTree != fPrevious_tree.end() ; it_fTree ++)
356  {
357  if(it_fTree->second)
358  delete (it_fTree->second) ;
359  }
360 
361  fPrevious_tree.clear();
362  }
363 
364  for(allbox.begin() ; !allbox.end() ; allbox++)
365  {
366  buffBox = allbox.GetBox() ;
367  currentIT = (*allbox);
368 
369  if(currentBox != buffBox)
370  {
371  currentTree = 0 ;
372  currentBox = buffBox;
373 
374  const T& key = dynamic_cast<const T&>(*currentIT);
375  it_fTree = fTree.find(key);
376 
377  if(it_fTree != fTree.end())
378  {
379  currentTree = it_fTree ->second ;
380  if(currentTree)
381  {
382  fPrevious_tree[key] = currentTree ;
383  // currentTree->Clear();
384  }
385  }
386 
387  // Re-initialize fTree
388  currentTree = new G4KDTree();
389  fTree[key] = currentTree ;
390  }
391 
392  const G4ThreeVector& position = currentIT-> GetTrack()->GetPosition();
393 
394  G4KDNode* node = currentTree->Insert(position.x(),
395  position.y(),
396  position.z(),
397  currentIT);
398 
399 // G4KDNode* node = currentTree->InsertMap(position.x(),
400 // position.y(),
401 // position.z(),
402 // currentIT);
403 
404  currentIT->SetNode(node);
405  }
406 
407  // currentTree->Build();
408 }