ROOT  6.06/09
Reference Guide
TGeoParallelWorld.cxx
Go to the documentation of this file.
1 // Author: Andrei Gheata 17/02/04
2 
3 /*************************************************************************
4  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
11 //_____________________________________________________________________________
12 // TGeoParallelWorld - base class for a flat parallel geometry.
13 // The parallel geometry can be composed by both normal volumes added
14 // using the AddNode interface (not implemented yet) or by physical nodes
15 // which will use as position their actual global matrix with respect to the top
16 // volume of the main geometry.
17 // All these nodes are added as daughters to the "top" volume of
18 // the parallel world which acts as a navigation helper in this parallel
19 // world. The parallel world has to be closed before calling any navigation
20 // method.
21 //_____________________________________________________________________________
22 
23 #include "TGeoParallelWorld.h"
24 #include "TObjString.h"
25 #include "TGeoManager.h"
26 #include "TGeoVolume.h"
27 #include "TGeoVoxelFinder.h"
28 #include "TGeoMatrix.h"
29 #include "TGeoPhysicalNode.h"
30 #include "TGeoNavigator.h"
31 
33 
34 ////////////////////////////////////////////////////////////////////////////////
35 /// Default constructor
36 
38  : TNamed(name,""),
39  fGeoManager(mgr),
40  fPaths(new TObjArray(256)),
41  fUseOverlaps(kFALSE),
42  fIsClosed(kFALSE),
43  fVolume(0),
44  fLastState(0),
45  fPhysical(new TObjArray(256))
46 {
47 }
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 /// Destructor
51 
53 {
54  if (fPhysical) {fPhysical->Delete(); delete fPhysical;}
55  if (fPaths) {fPaths->Delete(); delete fPaths;}
56  delete fVolume;
57 }
58 
59 ////////////////////////////////////////////////////////////////////////////////
60 /// Add a node normally to this world. Overlapping nodes not allowed
61 
62 void TGeoParallelWorld::AddNode(const char *path)
63 {
64  if (fIsClosed) Fatal("AddNode", "Cannot add nodes to a closed parallel geometry");
65  if (!fGeoManager->CheckPath(path)) {
66  Error("AddNode", "Path %s not valid.\nCannot add to parallel world!", path);
67  return;
68  }
69  fPaths->Add(new TObjString(path));
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// To use this optimization, the user should declare the full list of volumes
74 /// which may overlap with any of the physical nodes of the parallel world. Better
75 /// be done before misalignment
76 
78 {
79  if (activate) fUseOverlaps = kTRUE;
81 }
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// To use this optimization, the user should declare the full list of volumes
85 /// which may overlap with any of the physical nodes of the parallel world. Better
86 /// be done before misalignment
87 
88 void TGeoParallelWorld::AddOverlap(const char *volname, Bool_t activate)
89 {
90  if (activate) fUseOverlaps = kTRUE;
92  TGeoVolume *vol;
93  while ((vol=(TGeoVolume*)next())) {
94  if (!strcmp(vol->GetName(), volname)) vol->SetOverlappingCandidate(kTRUE);
95  }
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Print the overlaps which were detected during real tracking
100 
102 {
104  TGeoVolume *vol;
105  Int_t noverlaps = 0;
106  while ((vol=(TGeoVolume*)next())) {
107  if (vol->IsOverlappingCandidate()) {
108  if (noverlaps==0) Info("PrintDetectedOverlaps", "List of detected volumes overlapping with the PW");
109  noverlaps++;
110  printf("volume: %s at index: %d\n", vol->GetName(), vol->GetNumber());
111  }
112  }
113  return noverlaps;
114 }
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 /// Reset overlapflag for all volumes in geometry
118 
120 {
122  TGeoVolume *vol;
123  while ((vol=(TGeoVolume*)next())) vol->SetOverlappingCandidate(kFALSE);
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// The main geometry must be closed.
128 
130 {
131  if (fIsClosed) return kTRUE;
132  if (!fGeoManager->IsClosed()) Fatal("CloseGeometry", "Main geometry must be closed first");
133  if (!fPaths || !fPaths->GetEntriesFast()) {
134  Error("CloseGeometry", "List of paths is empty");
135  return kFALSE;
136  }
138  fIsClosed = kTRUE;
139  Info("CloseGeometry", "Parallel world %s contains %d prioritised objects", GetName(), fPaths->GetEntriesFast());
140  Int_t novlp = 0;
142  TGeoVolume *vol;
143  while ((vol=(TGeoVolume*)next())) if (vol->IsOverlappingCandidate()) novlp++;
144  Info("CloseGeometry", "Number of declared overlaps: %d", novlp);
145  if (fUseOverlaps) Info("CloseGeometry", "Parallel world will use declared overlaps");
146  else Info("CloseGeometry", "Parallel world will detect overlaps with other volumes");
147  return kTRUE;
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Refresh the node pointers and re-voxelize. To be called mandatory in case
152 /// re-alignment happened.
153 
155 {
156  delete fVolume;
159  // Loop physical nodes and add them to the navigation helper volume
160  if (fPhysical) {fPhysical->Delete(); delete fPhysical;}
162  TGeoPhysicalNode *pnode;
163  TObjString *objs;
164  TIter next(fPaths);
165  Int_t copy = 0;
166  while ((objs = (TObjString*)next())) {
167  pnode = new TGeoPhysicalNode(objs->GetName());
168  fPhysical->AddAt(pnode, copy);
169  fVolume->AddNode(pnode->GetVolume(), copy++, new TGeoHMatrix(*pnode->GetMatrix()));
170  }
171  // Voxelize the volume
173  fVolume->Voxelize("ALL");
174 }
175 
176 ////////////////////////////////////////////////////////////////////////////////
177 /// Finds physical node containing the point
178 
180 {
181  if (!fIsClosed) Fatal("FindNode", "Parallel geometry must be closed first");
183  // Fast return if not in an overlapping candidate
184  TGeoVoxelFinder *voxels = fVolume->GetVoxels();
185  Int_t id;
186  Int_t ncheck = 0;
187  Int_t nd = fVolume->GetNdaughters();
188  // get the list of nodes passing thorough the current voxel
189  TGeoNodeCache *cache = nav->GetCache();
190  TGeoStateInfo &info = *cache->GetMakePWInfo(nd);
191  Int_t *check_list = voxels->GetCheckList(point, ncheck, info);
192 // cache->ReleaseInfo(); // no hierarchical use
193  if (!check_list) return 0;
194  // loop all nodes in voxel
195  TGeoNode *node;
196  Double_t local[3];
197  for (id=0; id<ncheck; id++) {
198  node = fVolume->GetNode(check_list[id]);
199  node->MasterToLocal(point, local);
200  if (node->GetVolume()->Contains(local)) {
201  // We found a node containing the point
203  return fLastState;
204  }
205  }
206  return 0;
207 }
208 
209 ////////////////////////////////////////////////////////////////////////////////
210 /// Same functionality as TGeoNavigator::FindNextDaughterBoundary for the
211 /// parallel world
212 
214  Double_t &step, Double_t stepmax)
215 {
216  if (!fIsClosed) Fatal("FindNextBoundary", "Parallel geometry must be closed first");
217  TGeoPhysicalNode *pnode = 0;
219  // Fast return if not in an overlapping candidate
220  if (fUseOverlaps && !nav->GetCurrentVolume()->IsOverlappingCandidate()) return 0;
221 // TIter next(fPhysical);
222  // Ignore the request if the current state in the main geometry matches the
223  // last touched physical node in the parallel geometry
224  if (fLastState && fLastState->IsMatchingState(nav)) return 0;
225 // while ((pnode = (TGeoPhysicalNode*)next())) {
226 // if (pnode->IsMatchingState(nav)) return 0;
227 // }
229  step = stepmax;
230  TGeoVoxelFinder *voxels = fVolume->GetVoxels();
231  Int_t idaughter = -1; // nothing crossed
232  Int_t nd = fVolume->GetNdaughters();
233  Int_t i;
234  TGeoNode *current;
235  Double_t lpoint[3], ldir[3];
236 // const Double_t tolerance = TGeoShape::Tolerance();
237  if (nd<5) {
238  // loop over daughters
239  for (i=0; i<nd; i++) {
240  current = fVolume->GetNode(i);
241  // validate only within stepmax
242  if (voxels->IsSafeVoxel(point, i, stepmax)) continue;
243  current->MasterToLocal(point, lpoint);
244  current->MasterToLocalVect(dir, ldir);
245  snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, step);
246  if (snext < step) {
247  step = snext;
248  idaughter = i;
249  }
250  }
251  if (idaughter>=0) {
252  pnode = (TGeoPhysicalNode*)fPhysical->At(idaughter);
253  return pnode;
254  }
255  step = TGeoShape::Big();
256  return 0;
257  }
258  // Get current voxel
259  Int_t ncheck = 0;
260  Int_t sumchecked = 0;
261  Int_t *vlist = 0;
262  TGeoNodeCache *cache = nav->GetCache();
263  TGeoStateInfo &info = *cache->GetMakePWInfo(nd);
264 // TGeoStateInfo &info = *cache->GetInfo();
265 // cache->ReleaseInfo(); // no hierarchical use
266  voxels->SortCrossedVoxels(point, dir, info);
267  while ((sumchecked<nd) && (vlist=voxels->GetNextVoxel(point, dir, ncheck, info))) {
268  for (i=0; i<ncheck; i++) {
269  pnode = (TGeoPhysicalNode*)fPhysical->At(vlist[i]);
270  if (pnode->IsMatchingState(nav)) {
271  step = TGeoShape::Big();
272  return 0;
273  }
274  current = fVolume->GetNode(vlist[i]);
275  current->MasterToLocal(point, lpoint);
276  current->MasterToLocalVect(dir, ldir);
277  snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, step);
278  if (snext < step - 1.E-8) {
279  step = snext;
280  idaughter = vlist[i];
281  }
282  }
283  if (idaughter>=0) {
284  pnode = (TGeoPhysicalNode*)fPhysical->At(idaughter);
285  // mark the overlap
288 // printf("object %s overlapping with pn: %s\n", fGeoManager->GetPath(), pnode->GetName());
289  }
290  return pnode;
291  }
292  }
293  step = TGeoShape::Big();
294  return 0;
295 }
296 
297 ////////////////////////////////////////////////////////////////////////////////
298 /// Compute safety for the parallel world
299 
301 {
303  // Fast return if the state matches the last one recorded
304  if (fLastState && fLastState->IsMatchingState(nav)) return TGeoShape::Big();
305  // Fast return if not in an overlapping candidate
307  Double_t local[3];
308  Double_t safe = safmax;
309  Double_t safnext;
310  TGeoPhysicalNode *pnode = 0;
311  const Double_t tolerance = TGeoShape::Tolerance();
312  Int_t nd = fVolume->GetNdaughters();
313  TGeoNode *current;
314  TGeoVoxelFinder *voxels = fVolume->GetVoxels();
315  //---> check fast unsafe voxels
316  Double_t *boxes = voxels->GetBoxes();
317  for (Int_t id=0; id<nd; id++) {
318  Int_t ist = 6*id;
319  Double_t dxyz = 0.;
320  Double_t dxyz0 = TMath::Abs(point[0]-boxes[ist+3])-boxes[ist];
321  if (dxyz0 > safe) continue;
322  Double_t dxyz1 = TMath::Abs(point[1]-boxes[ist+4])-boxes[ist+1];
323  if (dxyz1 > safe) continue;
324  Double_t dxyz2 = TMath::Abs(point[2]-boxes[ist+5])-boxes[ist+2];
325  if (dxyz2 > safe) continue;
326  if (dxyz0>0) dxyz+=dxyz0*dxyz0;
327  if (dxyz1>0) dxyz+=dxyz1*dxyz1;
328  if (dxyz2>0) dxyz+=dxyz2*dxyz2;
329  if (dxyz >= safe*safe) continue;
330  pnode = (TGeoPhysicalNode*)fPhysical->At(id);
331  // Return if inside the current node
332  if (pnode->IsMatchingState(nav)) return TGeoShape::Big();
333  current = fVolume->GetNode(id);
334  current->MasterToLocal(point, local);
335  // Safety to current node
336  safnext = current->Safety(local, kFALSE);
337  if (safnext < tolerance) return 0.;
338  if (safnext < safe) safe = safnext;
339  }
340  return safe;
341 }
342 
343 ////////////////////////////////////////////////////////////////////////////////
344 /// Check overlaps within a tolerance value.
345 
347 {
348  fVolume->CheckOverlaps(ovlp);
349 }
350 
351 ////////////////////////////////////////////////////////////////////////////////
352 /// Draw the parallel world
353 
355 {
356  fVolume->Draw(option);
357 }
358 
const char * GetName() const
Returns name of object.
Definition: TObjString.h:42
ClassImp(TGeoParallelWorld) TGeoParallelWorld
Default constructor.
An array of TObjects.
Definition: TObjArray.h:39
virtual ~TGeoParallelWorld()
Destructor.
#define snext(osub1, osub2)
Definition: triangle.c:1167
void Voxelize(Option_t *option)
build the voxels for this volume
TGeoVolume * GetVolume() const
Definition: TGeoNode.h:106
Double_t Safety(Double_t point[3], Double_t safmax=1.E30)
Compute safety for the parallel world.
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
Collectable string class.
Definition: TObjString.h:32
const char Option_t
Definition: RtypesCore.h:62
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
computes the closest distance from given point to this shape
Definition: TGeoNode.cxx:666
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:328
virtual Int_t * GetCheckList(const Double_t *point, Int_t &nelem, TGeoStateInfo &td)
get the list of daughter indices for which point is inside their bbox
void AddNode(const char *path)
Add a node normally to this world. Overlapping nodes not allowed.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
virtual void Draw(Option_t *option="")
draw top volume according to option
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:652
TGeoPhysicalNode * FindNextBoundary(Double_t point[3], Double_t dir[3], Double_t &step, Double_t stepmax=1.E30)
Same functionality as TGeoNavigator::FindNextDaughterBoundary for the parallel world.
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
TGeoStateInfo * GetMakePWInfo(Int_t nd)
Get the PW info, if none create one.
Definition: TGeoCache.cxx:162
TGeoPhysicalNode * FindNode(Double_t point[3])
Finds physical node containing the point.
Int_t GetEntriesFast() const
Definition: TObjArray.h:66
virtual void SortCrossedVoxels(const Double_t *point, const Double_t *dir, TGeoStateInfo &td)
get the list in the next voxel crossed by a ray
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Int_t GetNdaughters() const
Definition: TGeoVolume.h:362
virtual Int_t * GetNextVoxel(const Double_t *point, const Double_t *dir, Int_t &ncheck, TGeoStateInfo &td)
get the list of new candidates for the next voxel crossed by current ray printf("### GetNextVoxel\n")...
static Double_t Tolerance()
Definition: TGeoShape.h:101
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:946
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
Bool_t IsClosed() const
Definition: TGeoManager.h:283
TGeoVolume * fVolume
Closed flag.
Bool_t IsOverlappingCandidate() const
Definition: TGeoVolume.h:162
void AddOverlap(TGeoVolume *vol, Bool_t activate=kTRUE)
To use this optimization, the user should declare the full list of volumes which may overlap with any...
void CheckOverlaps(Double_t ovlp=0.001)
Check overlaps within a tolerance value.
void Draw(Option_t *option)
Draw the parallel world.
XFontStruct * id
Definition: TGX11.cxx:108
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Int_t GetNumber() const
Definition: TGeoNode.h:104
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a TGeoNode to the list of nodes.
Definition: TGeoVolume.cxx:948
void ResetOverlaps() const
Reset overlapflag for all volumes in geometry.
Bool_t CheckPath(const char *path) const
Check if a geometry path is valid without changing the state of the current navigator.
TObjArray * GetListOfVolumes() const
Definition: TGeoManager.h:465
Bool_t Contains(const Double_t *point) const
Definition: TGeoVolume.h:125
Int_t PrintDetectedOverlaps() const
Print the overlaps which were detected during real tracking.
void RefreshPhysicalNodes()
Refresh the node pointers and re-voxelize.
Double_t E()
Definition: TMath.h:54
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
TGeoNodeCache * GetCache() const
Bool_t IsSafeVoxel(const Double_t *point, Int_t inode, Double_t minsafe) const
Computes squared distance from POINT to the voxel(s) containing node INODE.
TGeoNavigator * GetCurrentNavigator() const
Returns current navigator for the calling thread.
TObjArray * fPhysical
Last PN touched.
void CheckOverlaps(Double_t ovlp=0.1, Option_t *option="") const
Overlap checking tool.
Definition: TGeoVolume.cxx:603
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:238
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const =0
TGeoManager * fGeoManager
TGeoShape * GetShape() const
Definition: TGeoVolume.h:204
double Double_t
Definition: RtypesCore.h:55
TGeoVoxelFinder * GetVoxels() const
Getter for optimization structure.
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
Bool_t CloseGeometry()
The main geometry must be closed.
virtual void ComputeBBox()=0
static Double_t Big()
Definition: TGeoShape.h:98
#define name(a, b)
Definition: linkTestLib0.cpp:5
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
Convert the point coordinates from mother reference to local reference system.
Definition: TGeoNode.cxx:552
Double_t * GetBoxes() const
void SetOverlappingCandidate(Bool_t flag)
Definition: TGeoVolume.h:231
void Add(TObject *obj)
Definition: TObjArray.h:75
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
const Bool_t kTRUE
Definition: Rtypes.h:91
TGeoVolume * GetCurrentVolume() const
TGeoPhysicalNode * fLastState
helper volume
Bool_t IsMatchingState(TGeoNavigator *nav) const
Checks if a given navigator state matches this physical node.
virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const
Convert a vector from mother reference to local reference system.
Definition: TGeoNode.cxx:560