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// }
232 step = stepmax;
233 TGeoVoxelFinder *voxels = fVolume->GetVoxels();
234 Int_t idaughter = -1; // nothing crossed
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
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();
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
const Bool_t kFALSE
Definition RtypesCore.h:92
double Double_t
Definition RtypesCore.h:59
const Bool_t kTRUE
Definition RtypesCore.h:91
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:37
Int_t GetEntriesFast() const
Definition TObjArray.h:64
void Add(TObject *obj)
Definition TObjArray.h:74
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:166
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:893
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:921
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:867
Short_t Abs(Short_t d)
Definition TMathBase.h:120
Statefull info for the current geometry level.
#define snext(osub1, osub2)
Definition triangle.c:1167