Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
13Base class for a flat parallel geometry.
14
15 The parallel geometry can be composed by both normal volumes added
16using the AddNode interface (not implemented yet) or by physical nodes
17which will use as position their actual global matrix with respect to the top
18volume of the main geometry.
19
20 All these nodes are added as daughters to the "top" volume of
21the parallel world which acts as a navigation helper in this parallel
22world. The parallel world has to be closed before calling any navigation
23method.
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
65void 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
91void 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 }
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;
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// }
231 step = stepmax;
232 TGeoVoxelFinder *voxels = fVolume->GetVoxels();
233 Int_t idaughter = -1; // nothing crossed
235 Int_t i;
236 TGeoNode *current;
237 Double_t lpoint[3], ldir[3];
238// const Double_t tolerance = TGeoShape::Tolerance();
239 if (nd<5) {
240 // loop over daughters
241 for (i=0; i<nd; i++) {
242 current = fVolume->GetNode(i);
243 // validate only within stepmax
244 if (voxels->IsSafeVoxel(point, i, stepmax)) continue;
245 current->MasterToLocal(point, lpoint);
246 current->MasterToLocalVect(dir, ldir);
247 Double_t snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, step);
248 if (snext < step) {
249 step = snext;
250 idaughter = i;
251 }
252 }
253 if (idaughter>=0) {
254 pnode = (TGeoPhysicalNode*)fPhysical->At(idaughter);
255 return pnode;
256 }
257 step = TGeoShape::Big();
258 return 0;
259 }
260 // Get current voxel
261 Int_t ncheck = 0;
262 Int_t sumchecked = 0;
263 Int_t *vlist = 0;
264 TGeoNodeCache *cache = nav->GetCache();
265 TGeoStateInfo &info = *cache->GetMakePWInfo(nd);
266// TGeoStateInfo &info = *cache->GetInfo();
267// cache->ReleaseInfo(); // no hierarchical use
268 voxels->SortCrossedVoxels(point, dir, info);
269 while ((sumchecked<nd) && (vlist=voxels->GetNextVoxel(point, dir, ncheck, info))) {
270 for (i=0; i<ncheck; i++) {
271 pnode = (TGeoPhysicalNode*)fPhysical->At(vlist[i]);
272 if (pnode->IsMatchingState(nav)) {
273 step = TGeoShape::Big();
274 return 0;
275 }
276 current = fVolume->GetNode(vlist[i]);
277 current->MasterToLocal(point, lpoint);
278 current->MasterToLocalVect(dir, ldir);
279 Double_t snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, step);
280 if (snext < step - 1.E-8) {
281 step = snext;
282 idaughter = vlist[i];
283 }
284 }
285 if (idaughter>=0) {
286 pnode = (TGeoPhysicalNode*)fPhysical->At(idaughter);
287 // mark the overlap
290// printf("object %s overlapping with pn: %s\n", fGeoManager->GetPath(), pnode->GetName());
291 }
292 return pnode;
293 }
294 }
295 step = TGeoShape::Big();
296 return 0;
297}
298
299////////////////////////////////////////////////////////////////////////////////
300/// Compute safety for the parallel world
301
303{
305 // Fast return if the state matches the last one recorded
307 // Fast return if not in an overlapping candidate
309 Double_t local[3];
310 Double_t safe = safmax;
311 Double_t safnext;
312 TGeoPhysicalNode *pnode = 0;
313 const Double_t tolerance = TGeoShape::Tolerance();
315 TGeoNode *current;
316 TGeoVoxelFinder *voxels = fVolume->GetVoxels();
317 //---> check fast unsafe voxels
318 Double_t *boxes = voxels->GetBoxes();
319 for (Int_t id=0; id<nd; id++) {
320 Int_t ist = 6*id;
321 Double_t dxyz = 0.;
322 Double_t dxyz0 = TMath::Abs(point[0]-boxes[ist+3])-boxes[ist];
323 if (dxyz0 > safe) continue;
324 Double_t dxyz1 = TMath::Abs(point[1]-boxes[ist+4])-boxes[ist+1];
325 if (dxyz1 > safe) continue;
326 Double_t dxyz2 = TMath::Abs(point[2]-boxes[ist+5])-boxes[ist+2];
327 if (dxyz2 > safe) continue;
328 if (dxyz0>0) dxyz+=dxyz0*dxyz0;
329 if (dxyz1>0) dxyz+=dxyz1*dxyz1;
330 if (dxyz2>0) dxyz+=dxyz2*dxyz2;
331 if (dxyz >= safe*safe) continue;
332 pnode = (TGeoPhysicalNode*)fPhysical->At(id);
333 // Return if inside the current node
334 if (pnode->IsMatchingState(nav)) return TGeoShape::Big();
335 current = fVolume->GetNode(id);
336 current->MasterToLocal(point, local);
337 // Safety to current node
338 safnext = current->Safety(local, kFALSE);
339 if (safnext < tolerance) return 0.;
340 if (safnext < safe) safe = safnext;
341 }
342 return safe;
343}
344
345////////////////////////////////////////////////////////////////////////////////
346/// Check overlaps within a tolerance value.
347
349{
350 fVolume->CheckOverlaps(ovlp);
351}
352
353////////////////////////////////////////////////////////////////////////////////
354/// Draw the parallel world
355
357{
358 fVolume->Draw(option);
359}
360
const Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
const Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:364
XFontStruct * id
Definition TGX11.cxx:109
char name[80]
Definition TGX11.cxx:110
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition TGeoMatrix.h:421
The manager class for any TGeo geometry.
Definition TGeoManager.h:45
TObjArray * GetListOfVolumes() const
TGeoNavigator * GetCurrentNavigator() const
Returns current navigator for the calling thread.
Bool_t IsClosed() const
Bool_t CheckPath(const char *path) const
Check if a geometry path is valid without changing the state of the current navigator.
Class providing navigation API for TGeo geometries.
TGeoVolume * GetCurrentVolume() const
TGeoNodeCache * GetCache() const
Special pool of reusable nodes.
Definition TGeoCache.h:58
TGeoStateInfo * GetMakePWInfo(Int_t nd)
Get the PW info, if none create one.
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition TGeoNode.h:41
TGeoVolume * GetVolume() const
Definition TGeoNode.h:97
Int_t GetNumber() const
Definition TGeoNode.h:95
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:518
virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const
Convert a vector from mother reference to local reference system.
Definition TGeoNode.cxx:526
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:630
Base class for a flat parallel geometry.
TGeoManager * fGeoManager
Double_t Safety(Double_t point[3], Double_t safmax=1.E30)
Compute safety for the parallel world.
TObjArray * fPhysical
Last PN touched.
Bool_t CloseGeometry()
The main geometry must be closed.
void AddNode(const char *path)
Add a node normally to this world. Overlapping nodes not allowed.
void Draw(Option_t *option)
Draw the parallel world.
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.
void ResetOverlaps() const
Reset overlapflag for all volumes in geometry.
TGeoPhysicalNode * FindNode(Double_t point[3])
Finds physical node containing the point.
virtual ~TGeoParallelWorld()
Destructor.
TGeoVolume * fVolume
Closed flag.
Int_t PrintDetectedOverlaps() const
Print the overlaps which were detected during real tracking.
void CheckOverlaps(Double_t ovlp=0.001)
Check overlaps within a tolerance value.
TGeoPhysicalNode * fLastState
helper volume
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 RefreshPhysicalNodes()
Refresh the node pointers and re-voxelize.
Physical nodes are the actual 'touchable' objects in the geometry, representing a path of positioned ...
Bool_t IsMatchingState(TGeoNavigator *nav) const
Checks if a given navigator state matches this physical node.
TGeoHMatrix * GetMatrix(Int_t level=-1) const
Return global matrix for node at LEVEL.
TGeoVolume * GetVolume(Int_t level=-1) const
Return volume associated with node at LEVEL in the branch.
static Double_t Big()
Definition TGeoShape.h:88
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
virtual void ComputeBBox()=0
static Double_t Tolerance()
Definition TGeoShape.h:91
Volume assemblies.
Definition TGeoVolume.h:305
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition TGeoVolume.h:49
void Voxelize(Option_t *option)
build the voxels for this volume
Bool_t Contains(const Double_t *point) const
Definition TGeoVolume.h:109
Int_t GetNdaughters() const
Definition TGeoVolume.h:351
virtual TGeoNode * AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a TGeoNode to the list of nodes.
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
TGeoVoxelFinder * GetVoxels() const
Getter for optimization structure.
Int_t GetNumber() const
Definition TGeoVolume.h:183
TGeoShape * GetShape() const
Definition TGeoVolume.h:189
virtual void Draw(Option_t *option="")
draw top volume according to option
void CheckOverlaps(Double_t ovlp=0.1, Option_t *option="") const
Overlap checking tool.
void SetOverlappingCandidate(Bool_t flag)
Definition TGeoVolume.h:216
Bool_t IsOverlappingCandidate() const
Definition TGeoVolume.h:147
Finder class handling voxels.
Double_t * GetBoxes() const
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
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")...
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 SortCrossedVoxels(const Double_t *point, const Double_t *dir, TGeoStateInfo &td)
get the list in the next voxel crossed by a ray
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
void Add(TObject *obj)
Definition TObjArray.h:68
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
virtual TObject * Remove(TObject *obj)
Remove object from array.
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
TObject * At(Int_t idx) const
Definition TObjArray.h:164
Collectable string class.
Definition TObjString.h:28
const char * GetName() const
Returns name of object.
Definition TObjString.h:38
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:991
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:937
Short_t Abs(Short_t d)
Definition TMathBase.h:120
Statefull info for the current geometry level.
#define snext(osub1, osub2)
Definition triangle.c:1168