Logo ROOT   6.12/07
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 /** \class TGeoParallelWorld
12 \ingroup Geometry_classes
13 Base class for a flat parallel geometry.
14 
15  The parallel geometry can be composed by both normal volumes added
16 using the AddNode interface (not implemented yet) or by physical nodes
17 which will use as position their actual global matrix with respect to the top
18 volume of the main geometry.
19 
20  All these nodes are added as daughters to the "top" volume of
21 the parallel world which acts as a navigation helper in this parallel
22 world. The parallel world has to be closed before calling any navigation
23 method.
24 */
25 
26 #include "TGeoParallelWorld.h"
27 #include "TObjString.h"
28 #include "TGeoManager.h"
29 #include "TGeoVolume.h"
30 #include "TGeoVoxelFinder.h"
31 #include "TGeoMatrix.h"
32 #include "TGeoPhysicalNode.h"
33 #include "TGeoNavigator.h"
34 
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Default constructor
39 
41  : TNamed(name,""),
42  fGeoManager(mgr),
43  fPaths(new TObjArray(256)),
44  fUseOverlaps(kFALSE),
45  fIsClosed(kFALSE),
46  fVolume(0),
47  fLastState(0),
48  fPhysical(new TObjArray(256))
49 {
50 }
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 /// Destructor
54 
56 {
57  if (fPhysical) {fPhysical->Delete(); delete fPhysical;}
58  if (fPaths) {fPaths->Delete(); delete fPaths;}
59  delete fVolume;
60 }
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// Add a node normally to this world. Overlapping nodes not allowed
64 
65 void TGeoParallelWorld::AddNode(const char *path)
66 {
67  if (fIsClosed) Fatal("AddNode", "Cannot add nodes to a closed parallel geometry");
68  if (!fGeoManager->CheckPath(path)) {
69  Error("AddNode", "Path %s not valid.\nCannot add to parallel world!", path);
70  return;
71  }
72  fPaths->Add(new TObjString(path));
73 }
74 
75 ////////////////////////////////////////////////////////////////////////////////
76 /// To use this optimization, the user should declare the full list of volumes
77 /// which may overlap with any of the physical nodes of the parallel world. Better
78 /// be done before misalignment
79 
81 {
82  if (activate) fUseOverlaps = kTRUE;
84 }
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// To use this optimization, the user should declare the full list of volumes
88 /// which may overlap with any of the physical nodes of the parallel world. Better
89 /// be done before misalignment
90 
91 void TGeoParallelWorld::AddOverlap(const char *volname, Bool_t activate)
92 {
93  if (activate) fUseOverlaps = kTRUE;
95  TGeoVolume *vol;
96  while ((vol=(TGeoVolume*)next())) {
97  if (!strcmp(vol->GetName(), volname)) vol->SetOverlappingCandidate(kTRUE);
98  }
99 }
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 /// Print the overlaps which were detected during real tracking
103 
105 {
107  TGeoVolume *vol;
108  Int_t noverlaps = 0;
109  while ((vol=(TGeoVolume*)next())) {
110  if (vol->IsOverlappingCandidate()) {
111  if (noverlaps==0) Info("PrintDetectedOverlaps", "List of detected volumes overlapping with the PW");
112  noverlaps++;
113  printf("volume: %s at index: %d\n", vol->GetName(), vol->GetNumber());
114  }
115  }
116  return noverlaps;
117 }
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 /// Reset overlapflag for all volumes in geometry
121 
123 {
125  TGeoVolume *vol;
126  while ((vol=(TGeoVolume*)next())) vol->SetOverlappingCandidate(kFALSE);
127 }
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 /// The main geometry must be closed.
131 
133 {
134  if (fIsClosed) return kTRUE;
135  if (!fGeoManager->IsClosed()) Fatal("CloseGeometry", "Main geometry must be closed first");
136  if (!fPaths || !fPaths->GetEntriesFast()) {
137  Error("CloseGeometry", "List of paths is empty");
138  return kFALSE;
139  }
141  fIsClosed = kTRUE;
142  Info("CloseGeometry", "Parallel world %s contains %d prioritised objects", GetName(), fPaths->GetEntriesFast());
143  Int_t novlp = 0;
145  TGeoVolume *vol;
146  while ((vol=(TGeoVolume*)next())) if (vol->IsOverlappingCandidate()) novlp++;
147  Info("CloseGeometry", "Number of declared overlaps: %d", novlp);
148  if (fUseOverlaps) Info("CloseGeometry", "Parallel world will use declared overlaps");
149  else Info("CloseGeometry", "Parallel world will detect overlaps with other volumes");
150  return kTRUE;
151 }
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 /// Refresh the node pointers and re-voxelize. To be called mandatory in case
155 /// re-alignment happened.
156 
158 {
159  delete fVolume;
162  // Loop physical nodes and add them to the navigation helper volume
163  if (fPhysical) {fPhysical->Delete(); delete fPhysical;}
165  TGeoPhysicalNode *pnode;
166  TObjString *objs;
167  TIter next(fPaths);
168  Int_t copy = 0;
169  while ((objs = (TObjString*)next())) {
170  pnode = new TGeoPhysicalNode(objs->GetName());
171  fPhysical->AddAt(pnode, copy);
172  fVolume->AddNode(pnode->GetVolume(), copy++, new TGeoHMatrix(*pnode->GetMatrix()));
173  }
174  // Voxelize the volume
176  fVolume->Voxelize("ALL");
177 }
178 
179 ////////////////////////////////////////////////////////////////////////////////
180 /// Finds physical node containing the point
181 
183 {
184  if (!fIsClosed) Fatal("FindNode", "Parallel geometry must be closed first");
186  // Fast return if not in an overlapping candidate
187  TGeoVoxelFinder *voxels = fVolume->GetVoxels();
188  Int_t id;
189  Int_t ncheck = 0;
190  Int_t nd = fVolume->GetNdaughters();
191  // get the list of nodes passing thorough the current voxel
192  TGeoNodeCache *cache = nav->GetCache();
193  TGeoStateInfo &info = *cache->GetMakePWInfo(nd);
194  Int_t *check_list = voxels->GetCheckList(point, ncheck, info);
195 // cache->ReleaseInfo(); // no hierarchical use
196  if (!check_list) return 0;
197  // loop all nodes in voxel
198  TGeoNode *node;
199  Double_t local[3];
200  for (id=0; id<ncheck; id++) {
201  node = fVolume->GetNode(check_list[id]);
202  node->MasterToLocal(point, local);
203  if (node->GetVolume()->Contains(local)) {
204  // We found a node containing the point
206  return fLastState;
207  }
208  }
209  return 0;
210 }
211 
212 ////////////////////////////////////////////////////////////////////////////////
213 /// Same functionality as TGeoNavigator::FindNextDaughterBoundary for the
214 /// parallel world
215 
217  Double_t &step, Double_t stepmax)
218 {
219  if (!fIsClosed) Fatal("FindNextBoundary", "Parallel geometry must be closed first");
220  TGeoPhysicalNode *pnode = 0;
222  // Fast return if not in an overlapping candidate
223  if (fUseOverlaps && !nav->GetCurrentVolume()->IsOverlappingCandidate()) return 0;
224 // TIter next(fPhysical);
225  // Ignore the request if the current state in the main geometry matches the
226  // last touched physical node in the parallel geometry
227  if (fLastState && fLastState->IsMatchingState(nav)) return 0;
228 // while ((pnode = (TGeoPhysicalNode*)next())) {
229 // if (pnode->IsMatchingState(nav)) return 0;
230 // }
232  step = stepmax;
233  TGeoVoxelFinder *voxels = fVolume->GetVoxels();
234  Int_t idaughter = -1; // nothing crossed
235  Int_t nd = fVolume->GetNdaughters();
236  Int_t i;
237  TGeoNode *current;
238  Double_t lpoint[3], ldir[3];
239 // const Double_t tolerance = TGeoShape::Tolerance();
240  if (nd<5) {
241  // loop over daughters
242  for (i=0; i<nd; i++) {
243  current = fVolume->GetNode(i);
244  // validate only within stepmax
245  if (voxels->IsSafeVoxel(point, i, stepmax)) continue;
246  current->MasterToLocal(point, lpoint);
247  current->MasterToLocalVect(dir, ldir);
248  snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, step);
249  if (snext < step) {
250  step = snext;
251  idaughter = i;
252  }
253  }
254  if (idaughter>=0) {
255  pnode = (TGeoPhysicalNode*)fPhysical->At(idaughter);
256  return pnode;
257  }
258  step = TGeoShape::Big();
259  return 0;
260  }
261  // Get current voxel
262  Int_t ncheck = 0;
263  Int_t sumchecked = 0;
264  Int_t *vlist = 0;
265  TGeoNodeCache *cache = nav->GetCache();
266  TGeoStateInfo &info = *cache->GetMakePWInfo(nd);
267 // TGeoStateInfo &info = *cache->GetInfo();
268 // cache->ReleaseInfo(); // no hierarchical use
269  voxels->SortCrossedVoxels(point, dir, info);
270  while ((sumchecked<nd) && (vlist=voxels->GetNextVoxel(point, dir, ncheck, info))) {
271  for (i=0; i<ncheck; i++) {
272  pnode = (TGeoPhysicalNode*)fPhysical->At(vlist[i]);
273  if (pnode->IsMatchingState(nav)) {
274  step = TGeoShape::Big();
275  return 0;
276  }
277  current = fVolume->GetNode(vlist[i]);
278  current->MasterToLocal(point, lpoint);
279  current->MasterToLocalVect(dir, ldir);
280  snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, step);
281  if (snext < step - 1.E-8) {
282  step = snext;
283  idaughter = vlist[i];
284  }
285  }
286  if (idaughter>=0) {
287  pnode = (TGeoPhysicalNode*)fPhysical->At(idaughter);
288  // mark the overlap
291 // printf("object %s overlapping with pn: %s\n", fGeoManager->GetPath(), pnode->GetName());
292  }
293  return pnode;
294  }
295  }
296  step = TGeoShape::Big();
297  return 0;
298 }
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 /// Compute safety for the parallel world
302 
304 {
306  // Fast return if the state matches the last one recorded
307  if (fLastState && fLastState->IsMatchingState(nav)) return TGeoShape::Big();
308  // Fast return if not in an overlapping candidate
310  Double_t local[3];
311  Double_t safe = safmax;
312  Double_t safnext;
313  TGeoPhysicalNode *pnode = 0;
314  const Double_t tolerance = TGeoShape::Tolerance();
315  Int_t nd = fVolume->GetNdaughters();
316  TGeoNode *current;
317  TGeoVoxelFinder *voxels = fVolume->GetVoxels();
318  //---> check fast unsafe voxels
319  Double_t *boxes = voxels->GetBoxes();
320  for (Int_t id=0; id<nd; id++) {
321  Int_t ist = 6*id;
322  Double_t dxyz = 0.;
323  Double_t dxyz0 = TMath::Abs(point[0]-boxes[ist+3])-boxes[ist];
324  if (dxyz0 > safe) continue;
325  Double_t dxyz1 = TMath::Abs(point[1]-boxes[ist+4])-boxes[ist+1];
326  if (dxyz1 > safe) continue;
327  Double_t dxyz2 = TMath::Abs(point[2]-boxes[ist+5])-boxes[ist+2];
328  if (dxyz2 > safe) continue;
329  if (dxyz0>0) dxyz+=dxyz0*dxyz0;
330  if (dxyz1>0) dxyz+=dxyz1*dxyz1;
331  if (dxyz2>0) dxyz+=dxyz2*dxyz2;
332  if (dxyz >= safe*safe) continue;
333  pnode = (TGeoPhysicalNode*)fPhysical->At(id);
334  // Return if inside the current node
335  if (pnode->IsMatchingState(nav)) return TGeoShape::Big();
336  current = fVolume->GetNode(id);
337  current->MasterToLocal(point, local);
338  // Safety to current node
339  safnext = current->Safety(local, kFALSE);
340  if (safnext < tolerance) return 0.;
341  if (safnext < safe) safe = safnext;
342  }
343  return safe;
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 /// Check overlaps within a tolerance value.
348 
350 {
351  fVolume->CheckOverlaps(ovlp);
352 }
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// Draw the parallel world
356 
358 {
359  fVolume->Draw(option);
360 }
361 
Statefull info for the current geometry level.
Definition: TGeoStateInfo.h:21
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
virtual ~TGeoParallelWorld()
Destructor.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
The manager class for any TGeo geometry.
Definition: TGeoManager.h:38
#define snext(osub1, osub2)
Definition: triangle.c:1167
Volume assemblies.
Definition: TGeoVolume.h:307
void Voxelize(Option_t *option)
build the voxels for this volume
Double_t Safety(Double_t point[3], Double_t safmax=1.E30)
Compute safety for the parallel world.
Collectable string class.
Definition: TObjString.h:28
const char Option_t
Definition: RtypesCore.h:62
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:355
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.
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter 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:561
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition: TGeoVolume.h:48
virtual void Draw(Option_t *option="")
draw top volume according to option
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:703
Matrix class used for computing global transformations Should NOT be used for node definition...
Definition: TGeoMatrix.h:420
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
TGeoNodeCache * GetCache() const
TGeoStateInfo * GetMakePWInfo(Int_t nd)
Get the PW info, if none create one.
Definition: TGeoCache.cxx:153
TGeoPhysicalNode * FindNode(Double_t point[3])
Finds physical node containing the point.
Int_t PrintDetectedOverlaps() const
Print the overlaps which were detected during real tracking.
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
virtual void SortCrossedVoxels(const Double_t *point, const Double_t *dir, TGeoStateInfo &td)
get the list in the next voxel crossed by a ray
TGeoVoxelFinder * GetVoxels() const
Getter for optimization structure.
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
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:91
Int_t GetNdaughters() const
Definition: TGeoVolume.h:350
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TGeoVolume * fVolume
Closed flag.
TGeoVolume * GetCurrentVolume() const
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...
Special pool of reusable nodes.
Definition: TGeoCache.h:53
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
Physical nodes are the actual &#39;touchable&#39; objects in the geometry, representing a path of positioned ...
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:984
const char * GetName() const
Returns name of object.
Definition: TObjString.h:39
Int_t GetNumber() const
Definition: TGeoNode.h:92
Double_t * GetBoxes() const
void RefreshPhysicalNodes()
Refresh the node pointers and re-voxelize.
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
Bool_t CheckPath(const char *path) const
Check if a geometry path is valid without changing the state of the current navigator.
void CheckOverlaps(Double_t ovlp=0.1, Option_t *option="") const
Overlap checking tool.
Definition: TGeoVolume.cxx:641
TObjArray * fPhysical
Last PN touched.
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.
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:253
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
constexpr Double_t E()
Definition: TMath.h:74
Bool_t Contains(const Double_t *point) const
Definition: TGeoVolume.h:112
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:553
const Bool_t kFALSE
Definition: RtypesCore.h:88
#define ClassImp(name)
Definition: Rtypes.h:359
double Double_t
Definition: RtypesCore.h:55
Bool_t CloseGeometry()
The main geometry must be closed.
Finder class handling voxels.
virtual void ComputeBBox()=0
static Double_t Big()
Definition: TGeoShape.h:88
Class providing navigation API for TGeo geometries.
Definition: TGeoNavigator.h:33
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition: TGeoNode.h:39
TGeoNavigator * GetCurrentNavigator() const
Returns current navigator for the calling thread.
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:665
TObjArray * GetListOfVolumes() const
Definition: TGeoManager.h:465
Bool_t IsOverlappingCandidate() const
Definition: TGeoVolume.h:149
void SetOverlappingCandidate(Bool_t flag)
Definition: TGeoVolume.h:218
void Add(TObject *obj)
Definition: TObjArray.h:73
Bool_t IsMatchingState(TGeoNavigator *nav) const
Checks if a given navigator state matches this physical node.
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:908
Bool_t IsClosed() const
Definition: TGeoManager.h:282
TGeoShape * GetShape() const
Definition: TGeoVolume.h:191
Base class for a flat parallel geometry.
const Bool_t kTRUE
Definition: RtypesCore.h:87
TGeoVolume * GetVolume() const
Definition: TGeoNode.h:94
void ResetOverlaps() const
Reset overlapflag for all volumes in geometry.
char name[80]
Definition: TGX11.cxx:109
TGeoPhysicalNode * fLastState
helper volume