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(nullptr),
47 fLastState(nullptr),
48 fPhysical(new TObjArray(256))
49{
50}
51
52////////////////////////////////////////////////////////////////////////////////
53/// Destructor
54
56{
57 if (fPhysical) {
59 delete fPhysical;
60 }
61 if (fPaths) {
62 fPaths->Delete();
63 delete fPaths;
64 }
65 delete fVolume;
66}
67
68////////////////////////////////////////////////////////////////////////////////
69/// Add a node normally to this world. Overlapping nodes not allowed
70
71void TGeoParallelWorld::AddNode(const char *path)
72{
73 if (fIsClosed)
74 Fatal("AddNode", "Cannot add nodes to a closed parallel geometry");
75 if (!fGeoManager->CheckPath(path)) {
76 Error("AddNode", "Path %s not valid.\nCannot add to parallel world!", path);
77 return;
78 }
79 fPaths->Add(new TObjString(path));
80}
81
82////////////////////////////////////////////////////////////////////////////////
83/// To use this optimization, the user should declare the full list of volumes
84/// which may overlap with any of the physical nodes of the parallel world. Better
85/// be done before misalignment
86
88{
89 if (activate)
92}
93
94////////////////////////////////////////////////////////////////////////////////
95/// To use this optimization, the user should declare the full list of volumes
96/// which may overlap with any of the physical nodes of the parallel world. Better
97/// be done before misalignment
98
99void TGeoParallelWorld::AddOverlap(const char *volname, Bool_t activate)
100{
101 if (activate)
104 TGeoVolume *vol;
105 while ((vol = (TGeoVolume *)next())) {
106 if (!strcmp(vol->GetName(), volname))
108 }
109}
110
111////////////////////////////////////////////////////////////////////////////////
112/// Print the overlaps which were detected during real tracking
113
115{
117 TGeoVolume *vol;
118 Int_t noverlaps = 0;
119 while ((vol = (TGeoVolume *)next())) {
120 if (vol->IsOverlappingCandidate()) {
121 if (noverlaps == 0)
122 Info("PrintDetectedOverlaps", "List of detected volumes overlapping with the PW");
123 noverlaps++;
124 printf("volume: %s at index: %d\n", vol->GetName(), vol->GetNumber());
125 }
126 }
127 return noverlaps;
128}
129
130////////////////////////////////////////////////////////////////////////////////
131/// Reset overlapflag for all volumes in geometry
132
134{
136 TGeoVolume *vol;
137 while ((vol = (TGeoVolume *)next()))
139}
140
141////////////////////////////////////////////////////////////////////////////////
142/// The main geometry must be closed.
143
145{
146 if (fIsClosed)
147 return kTRUE;
148 if (!fGeoManager->IsClosed())
149 Fatal("CloseGeometry", "Main geometry must be closed first");
150 if (!fPaths || !fPaths->GetEntriesFast()) {
151 Error("CloseGeometry", "List of paths is empty");
152 return kFALSE;
153 }
156 Info("CloseGeometry", "Parallel world %s contains %d prioritised objects", GetName(), fPaths->GetEntriesFast());
157 Int_t novlp = 0;
159 TGeoVolume *vol;
160 while ((vol = (TGeoVolume *)next()))
161 if (vol->IsOverlappingCandidate())
162 novlp++;
163 Info("CloseGeometry", "Number of declared overlaps: %d", novlp);
164 if (fUseOverlaps)
165 Info("CloseGeometry", "Parallel world will use declared overlaps");
166 else
167 Info("CloseGeometry", "Parallel world will detect overlaps with other volumes");
168 return kTRUE;
169}
170
171////////////////////////////////////////////////////////////////////////////////
172/// Refresh the node pointers and re-voxelize. To be called mandatory in case
173/// re-alignment happened.
174
176{
177 delete fVolume;
180 // Loop physical nodes and add them to the navigation helper volume
181 if (fPhysical) {
182 fPhysical->Delete();
183 delete fPhysical;
184 }
186 TGeoPhysicalNode *pnode;
187 TObjString *objs;
188 TIter next(fPaths);
189 Int_t copy = 0;
190 while ((objs = (TObjString *)next())) {
191 pnode = new TGeoPhysicalNode(objs->GetName());
192 fPhysical->AddAt(pnode, copy);
193 fVolume->AddNode(pnode->GetVolume(), copy++, new TGeoHMatrix(*pnode->GetMatrix()));
194 }
195 // Voxelize the volume
197 fVolume->Voxelize("ALL");
198}
199
200////////////////////////////////////////////////////////////////////////////////
201/// Finds physical node containing the point
202
204{
205 if (!fIsClosed)
206 Fatal("FindNode", "Parallel geometry must be closed first");
208 // Fast return if not in an overlapping candidate
209 TGeoVoxelFinder *voxels = fVolume->GetVoxels();
210 Int_t id;
211 Int_t ncheck = 0;
213 // get the list of nodes passing thorough the current voxel
214 TGeoNodeCache *cache = nav->GetCache();
215 TGeoStateInfo &info = *cache->GetMakePWInfo(nd);
216 Int_t *check_list = voxels->GetCheckList(point, ncheck, info);
217 // cache->ReleaseInfo(); // no hierarchical use
218 if (!check_list)
219 return nullptr;
220 // loop all nodes in voxel
221 TGeoNode *node;
222 Double_t local[3];
223 for (id = 0; id < ncheck; id++) {
224 node = fVolume->GetNode(check_list[id]);
225 node->MasterToLocal(point, local);
226 if (node->GetVolume()->Contains(local)) {
227 // We found a node containing the point
229 return fLastState;
230 }
231 }
232 return nullptr;
233}
234
235////////////////////////////////////////////////////////////////////////////////
236/// Same functionality as TGeoNavigator::FindNextDaughterBoundary for the
237/// parallel world
238
241{
242 if (!fIsClosed)
243 Fatal("FindNextBoundary", "Parallel geometry must be closed first");
244 TGeoPhysicalNode *pnode = nullptr;
246 // Fast return if not in an overlapping candidate
248 return nullptr;
249 // TIter next(fPhysical);
250 // Ignore the request if the current state in the main geometry matches the
251 // last touched physical node in the parallel geometry
253 return nullptr;
254 // while ((pnode = (TGeoPhysicalNode*)next())) {
255 // if (pnode->IsMatchingState(nav)) return 0;
256 // }
257 step = stepmax;
258 TGeoVoxelFinder *voxels = fVolume->GetVoxels();
259 Int_t idaughter = -1; // nothing crossed
261 Int_t i;
262 TGeoNode *current;
263 Double_t lpoint[3], ldir[3];
264 // const Double_t tolerance = TGeoShape::Tolerance();
265 if (nd < 5) {
266 // loop over daughters
267 for (i = 0; i < nd; i++) {
268 current = fVolume->GetNode(i);
269 // validate only within stepmax
270 if (voxels->IsSafeVoxel(point, i, stepmax))
271 continue;
272 current->MasterToLocal(point, lpoint);
273 current->MasterToLocalVect(dir, ldir);
274 Double_t snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, step);
275 if (snext < step) {
276 step = snext;
277 idaughter = i;
278 }
279 }
280 if (idaughter >= 0) {
281 pnode = (TGeoPhysicalNode *)fPhysical->At(idaughter);
282 return pnode;
283 }
284 step = TGeoShape::Big();
285 return nullptr;
286 }
287 // Get current voxel
288 Int_t ncheck = 0;
289 Int_t sumchecked = 0;
290 Int_t *vlist = nullptr;
291 TGeoNodeCache *cache = nav->GetCache();
292 TGeoStateInfo &info = *cache->GetMakePWInfo(nd);
293 // TGeoStateInfo &info = *cache->GetInfo();
294 // cache->ReleaseInfo(); // no hierarchical use
295 voxels->SortCrossedVoxels(point, dir, info);
296 while ((sumchecked < nd) && (vlist = voxels->GetNextVoxel(point, dir, ncheck, info))) {
297 for (i = 0; i < ncheck; i++) {
298 pnode = (TGeoPhysicalNode *)fPhysical->At(vlist[i]);
299 if (pnode->IsMatchingState(nav)) {
300 step = TGeoShape::Big();
301 return nullptr;
302 }
303 current = fVolume->GetNode(vlist[i]);
304 current->MasterToLocal(point, lpoint);
305 current->MasterToLocalVect(dir, ldir);
306 Double_t snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, step);
307 if (snext < step - 1.E-8) {
308 step = snext;
309 idaughter = vlist[i];
310 }
311 }
312 if (idaughter >= 0) {
313 pnode = (TGeoPhysicalNode *)fPhysical->At(idaughter);
314 // mark the overlap
317 // printf("object %s overlapping with pn: %s\n", fGeoManager->GetPath(), pnode->GetName());
318 }
319 return pnode;
320 }
321 }
322 step = TGeoShape::Big();
323 return nullptr;
324}
325
326////////////////////////////////////////////////////////////////////////////////
327/// Compute safety for the parallel world
328
330{
332 // Fast return if the state matches the last one recorded
334 return TGeoShape::Big();
335 // Fast return if not in an overlapping candidate
337 return TGeoShape::Big();
338 Double_t local[3];
339 Double_t safe = safmax;
340 Double_t safnext;
341 TGeoPhysicalNode *pnode = nullptr;
342 const Double_t tolerance = TGeoShape::Tolerance();
344 TGeoNode *current;
345 TGeoVoxelFinder *voxels = fVolume->GetVoxels();
346 //---> check fast unsafe voxels
347 Double_t *boxes = voxels->GetBoxes();
348 for (Int_t id = 0; id < nd; id++) {
349 Int_t ist = 6 * id;
350 Double_t dxyz = 0.;
351 Double_t dxyz0 = TMath::Abs(point[0] - boxes[ist + 3]) - boxes[ist];
352 if (dxyz0 > safe)
353 continue;
354 Double_t dxyz1 = TMath::Abs(point[1] - boxes[ist + 4]) - boxes[ist + 1];
355 if (dxyz1 > safe)
356 continue;
357 Double_t dxyz2 = TMath::Abs(point[2] - boxes[ist + 5]) - boxes[ist + 2];
358 if (dxyz2 > safe)
359 continue;
360 if (dxyz0 > 0)
361 dxyz += dxyz0 * dxyz0;
362 if (dxyz1 > 0)
363 dxyz += dxyz1 * dxyz1;
364 if (dxyz2 > 0)
365 dxyz += dxyz2 * dxyz2;
366 if (dxyz >= safe * safe)
367 continue;
368 pnode = (TGeoPhysicalNode *)fPhysical->At(id);
369 // Return if inside the current node
370 if (pnode->IsMatchingState(nav))
371 return TGeoShape::Big();
372 current = fVolume->GetNode(id);
373 current->MasterToLocal(point, local);
374 // Safety to current node
375 safnext = current->Safety(local, kFALSE);
376 if (safnext < tolerance)
377 return 0.;
378 if (safnext < safe)
379 safe = safnext;
380 }
381 return safe;
382}
383
384////////////////////////////////////////////////////////////////////////////////
385/// Check overlaps within a tolerance value.
386
388{
389 fVolume->CheckOverlaps(ovlp);
390}
391
392////////////////////////////////////////////////////////////////////////////////
393/// Draw the parallel world
394
396{
398}
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
char name[80]
Definition TGX11.cxx:110
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition TGeoMatrix.h:458
The manager class for any TGeo geometry.
Definition TGeoManager.h:44
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:56
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:39
TGeoVolume * GetVolume() const
Definition TGeoNode.h:99
Int_t GetNumber() const
Definition TGeoNode.h:93
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:566
virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const
Convert a vector from mother reference to local reference system.
Definition TGeoNode.cxx:574
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:682
Base class for a flat parallel geometry.
TGeoManager * fGeoManager
void Draw(Option_t *option) override
Draw the parallel world.
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.
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.
~TGeoParallelWorld() override
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:87
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const =0
virtual void ComputeBBox()=0
static Double_t Tolerance()
Definition TGeoShape.h:90
Volume assemblies.
Definition TGeoVolume.h:316
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition TGeoVolume.h:43
void Voxelize(Option_t *option)
build the voxels for this volume
Bool_t Contains(const Double_t *point) const
Definition TGeoVolume.h:104
virtual TGeoNode * AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=nullptr, Option_t *option="")
Add a TGeoNode to the list of nodes.
void Draw(Option_t *option="") override
draw top volume according to option
Int_t GetNdaughters() const
Definition TGeoVolume.h:362
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:184
TGeoShape * GetShape() const
Definition TGeoVolume.h:190
void CheckOverlaps(Double_t ovlp=0.1, Option_t *option="") const
Overlap checking tool.
void SetOverlappingCandidate(Bool_t flag)
Definition TGeoVolume.h:228
Bool_t IsOverlappingCandidate() const
Definition TGeoVolume.h:148
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
const char * GetName() const override
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 AddAt(TObject *obj, Int_t idx) override
Add object at position ids.
void Delete(Option_t *option="") override
Remove all objects from the array AND delete all heap based objects.
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
TObject * Remove(TObject *obj) override
Remove object from array.
void Add(TObject *obj) override
Definition TObjArray.h:68
Collectable string class.
Definition TObjString.h:28
const char * GetName() const override
Returns name of object.
Definition TObjString.h:38
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:976
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1004
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:950
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
Statefull info for the current geometry level.