Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGeoManager.cxx
Go to the documentation of this file.
1// @(#)root/geom:$Id$
2// Author: Andrei Gheata 25/10/01
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TGeoManager
13\ingroup Geometry_classes
14
15The manager class for any TGeo geometry. Provides user
16interface for geometry creation, navigation, state querying,
17visualization, IO, geometry checking and other utilities.
18
19## General architecture
20
21 The ROOT geometry package is a tool designed for building, browsing,
22tracking and visualizing a detector geometry. The code is independent from
23other external MC for simulation, therefore it does not contain any
24constraints related to physics. However, the package defines a number of
25hooks for tracking, such as media, materials, magnetic field or track state flags,
26in order to allow interfacing to tracking MC's. The final goal is to be
27able to use the same geometry for several purposes, such as tracking,
28reconstruction or visualization, taking advantage of the ROOT features
29related to bookkeeping, I/O, histogramming, browsing and GUI's.
30
31 The geometrical modeler is the most important component of the package and
32it provides answers to the basic questions like "Where am I ?" or "How far
33from the next boundary ?", but also to more complex ones like "How far from
34the closest surface ?" or "Which is the next crossing along a helix ?".
35
36 The architecture of the modeler is a combination between a GEANT-like
37containment scheme and a normal CSG binary tree at the level of shapes. An
38important common feature of all detector geometry descriptions is the
39mother-daughter concept. This is the most natural approach when tracking
40is concerned and imposes a set of constraints to the way geometry is defined.
41Constructive solid geometry composition is used only in order to create more
42complex shapes from an existing set of primitives through boolean operations.
43This feature is not implemented yet but in future full definition of boolean
44expressions will be supported.
45
46 Practically every geometry defined in GEANT style can be mapped by the modeler.
47The basic components used for building the logical hierarchy of the geometry
48are called "volumes" and "nodes". Volumes (sometimes called "solids") are fully
49defined geometrical objects having a given shape and medium and possibly
50containing a list of nodes. Nodes represent just positioned instances of volumes
51inside a container volume and they are not directly defined by user. They are
52automatically created as a result of adding one volume inside other or dividing
53a volume. The geometrical transformation hold by nodes is always defined with
54respect to their mother (relative positioning). Reflection matrices are allowed.
55All volumes have to be fully aware of their containees when the geometry is
56closed. They will build additional structures (voxels) in order to fasten-up
57the search algorithms. Finally, nodes can be regarded as bidirectional links
58between containers and containees objects.
59
60 The structure defined in this way is a graph structure since volumes are
61replicable (same volume can become daughter node of several other volumes),
62every volume becoming a branch in this graph. Any volume in the logical graph
63can become the actual top volume at run time (see TGeoManager::SetTopVolume()).
64All functionalities of the modeler will behave in this case as if only the
65corresponding branch starting from this volume is the registered geometry.
66
67\image html geom_graf.jpg
68
69 A given volume can be positioned several times in the geometry. A volume
70can be divided according default or user-defined patterns, creating automatically
71the list of division nodes inside. The elementary volumes created during the
72dividing process follow the same scheme as usual volumes, therefore it is possible
73to position further geometrical structures inside or to divide them further more
74(see TGeoVolume::Divide()).
75
76 The primitive shapes supported by the package are basically the GEANT3
77shapes (see class TGeoShape), arbitrary wedges with eight vertices on two parallel
78planes. All basic primitives inherits from class TGeoBBox since the bounding box
79of a solid is essential for the tracking algorithms. They also implement the
80virtual methods defined in the virtual class TGeoShape (point and segment
81classification). User-defined primitives can be directly plugged into the modeler
82provided that they override these methods. Composite shapes will be soon supported
83by the modeler. In order to build a TGeoCompositeShape, one will have to define
84first the primitive components. The object that handle boolean
85operations among components is called TGeoBoolCombinator and it has to be
86constructed providing a string boolean expression between the components names.
87
88
89## Example for building a simple geometry
90
91Begin_Macro(source)
92../../../tutorials/visualisation/geom/rootgeom.C
93End_Macro
94
95## TGeoManager - the manager class for the geometry package.
96
97 TGeoManager class is embedding all the API needed for building and tracking
98a geometry. It defines a global pointer (gGeoManager) in order to be fully
99accessible from external code. The mechanism of handling multiple geometries
100at the same time will be soon implemented.
101
102 TGeoManager is the owner of all geometry objects defined in a session,
103therefore users must not try to control their deletion. It contains lists of
104media, materials, transformations, shapes and volumes. Logical nodes (positioned
105volumes) are created and destroyed by the TGeoVolume class. Physical
106nodes and their global transformations are subjected to a caching mechanism
107due to the sometimes very large memory requirements of logical graph expansion.
108The caching mechanism is triggered by the total number of physical instances
109of volumes and the cache manager is a client of TGeoManager. The manager class
110also controls the painter client. This is linked with ROOT graphical libraries
111loaded on demand in order to control visualization actions.
112
113## Rules for building a valid geometry
114
115 A given geometry can be built in various ways, but there are mandatory steps
116that have to be followed in order to be validated by the modeler. There are
117general rules : volumes needs media and shapes in order to be created,
118both container and containee volumes must be created before linking them together,
119and the relative transformation matrix must be provided. All branches must
120have an upper link point otherwise they will not be considered as part of the
121geometry. Visibility or tracking properties of volumes can be provided both
122at build time or after geometry is closed, but global visualization settings
123(see TGeoPainter class) should not be provided at build time, otherwise the
124drawing package will be loaded. There is also a list of specific rules :
125positioned daughters should not extrude their mother or intersect with sisters
126unless this is specified (see TGeoVolume::AddNodeOverlap()), the top volume
127(containing all geometry tree) must be specified before closing the geometry
128and must not be positioned - it represents the global reference frame. After
129building the full geometry tree, the geometry must be closed
130(see TGeoManager::CloseGeometry()). Voxelization can be redone per volume after
131this process.
132
133
134 Below is the general scheme of the manager class.
135
136\image html geom_mgr.jpg
137
138## An interactive session
139
140 Provided that a geometry was successfully built and closed (for instance the
141previous example rootgeom.C ), the manager class will register
142itself to ROOT and the logical/physical structures will become immediately browsable.
143The ROOT browser will display starting from the geometry folder : the list of
144transformations and media, the top volume and the top logical node. These last
145two can be fully expanded, any intermediate volume/node in the browser being subject
146of direct access context menu operations (right mouse button click). All user
147utilities of classes TGeoManager, TGeoVolume and TGeoNode can be called via the
148context menu.
149
150\image html geom_browser.jpg
151
152### Drawing the geometry
153
154 Any logical volume can be drawn via TGeoVolume::Draw() member function.
155This can be directly accessed from the context menu of the volume object
156directly from the browser.
157 There are several drawing options that can be set with
158TGeoManager::SetVisOption(Int_t opt) method :
159
160#### opt=0
161 only the content of the volume is drawn, N levels down (default N=3).
162 This is the default behavior. The number of levels to be drawn can be changed
163 via TGeoManager::SetVisLevel(Int_t level) method.
164
165\image html geom_frame0.jpg
166
167#### opt=1
168 the final leaves (e.g. daughters with no containment) of the branch
169 starting from volume are drawn down to the current number of levels.
170 WARNING : This mode is memory consuming
171 depending of the size of geometry, so drawing from top level within this mode
172 should be handled with care for expensive geometries. In future there will be
173 a limitation on the maximum number of nodes to be visualized.
174
175\image html geom_frame1.jpg
176
177#### opt=2
178 only the clicked volume is visualized. This is automatically set by
179 TGeoVolume::DrawOnly() method
180
181#### opt=3 - only a given path is visualized. This is automatically set by
182 TGeoVolume::DrawPath(const char *path) method
183
184 The current view can be exploded in cartesian, cylindrical or spherical
185coordinates :
186 TGeoManager::SetExplodedView(Int_t opt). Options may be :
187- 0 - default (no bombing)
188- 1 - cartesian coordinates. The bomb factor on each axis can be set with
189 TGeoManager::SetBombX(Double_t bomb) and corresponding Y and Z.
190- 2 - bomb in cylindrical coordinates. Only the bomb factors on Z and R
191 are considered
192 \image html geom_frameexp.jpg
193
194- 3 - bomb in radial spherical coordinate : TGeoManager::SetBombR()
195
196Volumes themselves support different visualization settings :
197 - TGeoVolume::SetVisibility() : set volume visibility.
198 - TGeoVolume::VisibleDaughters() : set daughters visibility.
199All these actions automatically updates the current view if any.
200
201### Checking the geometry
202
203 Several checking methods are accessible from the volume context menu. They
204generally apply only to the visible parts of the drawn geometry in order to
205ease geometry checking, and their implementation is in the TGeoChecker class
206from the painting package.
207
208#### Checking a given point.
209 Can be called from TGeoManager::CheckPoint(Double_t x, Double_t y, Double_t z).
210This method is drawing the daughters of the volume containing the point one
211level down, printing the path to the deepest physical node holding this point.
212It also computes the closest distance to any boundary. The point will be drawn
213in red, as well as a sphere having this closest distance as radius. In case a
214non-zero distance is given by the user as fifth argument of CheckPoint, this
215distance will be used as radius of the safety sphere.
216
217\image html geom_checkpoint.jpg
218
219#### Shooting random points.
220 Can be called from TGeoVolume::RandomPoints() (context menu function) and
221it will draw this volume with current visualization settings. Random points
222are generated in the bounding box of the top drawn volume. The points are
223classified and drawn with the color of their deepest container. Only points
224in visible nodes will be drawn.
225
226\image html geom_random1.jpg
227
228
229#### Raytracing.
230 Can be called from TGeoVolume::RandomRays() (context menu of volumes) and
231will shoot rays from a given point in the local reference frame with random
232directions. The intersections with displayed nodes will appear as segments
233having the color of the touched node. Drawn geometry will be then made invisible
234in order to enhance rays.
235
236\image html geom_random2.jpg
237*/
238
239#include <atomic>
240#include <cstdlib>
241#include <iostream>
242#include <fstream>
243
244#include "TROOT.h"
245#include "TGeoManager.h"
246#include "TStyle.h"
247#include "TVirtualPad.h"
248#include "TBrowser.h"
249#include "TFile.h"
250#include "TKey.h"
251#include "THashList.h"
252#include "TClass.h"
253#include "ThreadLocalStorage.h"
254#include "TBufferText.h"
255
256#include "TGeoVoxelFinder.h"
257#include "TGeoElement.h"
258#include "TGeoMaterial.h"
259#include "TGeoMedium.h"
260#include "TGeoMatrix.h"
261#include "TGeoNode.h"
262#include "TGeoPhysicalNode.h"
263#include "TGeoPara.h"
264#include "TGeoParaboloid.h"
265#include "TGeoTube.h"
266#include "TGeoEltu.h"
267#include "TGeoHype.h"
268#include "TGeoCone.h"
269#include "TGeoSphere.h"
270#include "TGeoArb8.h"
271#include "TGeoPgon.h"
272#include "TGeoTrd1.h"
273#include "TGeoTrd2.h"
274#include "TGeoTorus.h"
275#include "TGeoXtru.h"
276#include "TGeoCompositeShape.h"
277#include "TGeoBoolNode.h"
278#include "TGeoBuilder.h"
279#include "TVirtualGeoPainter.h"
280#include "TVirtualGeoChecker.h"
281#include "TPluginManager.h"
282#include "TVirtualGeoTrack.h"
283#include "TQObject.h"
284#include "TMath.h"
285#include "TEnv.h"
286#include "TGeoParallelWorld.h"
287#include "TGeoRegion.h"
288#include "TGDMLMatrix.h"
289#include "TGeoOpticalSurface.h"
290#include "TGeoColorScheme.h"
291
292// statics and globals
293
295
296std::mutex TGeoManager::fgMutex;
308
309namespace {
310
311struct TGeoManagerThreadState {
312 const TGeoManager *fManager = nullptr;
313 TGeoNavigator *fNavigator = nullptr;
314 ULong64_t fNavigatorGeneration = 0;
315 Int_t fThreadId = -1;
316 ULong64_t fThreadIdGeneration = 0;
317};
318
319TGeoManagerThreadState &GetGeoManagerThreadState()
320{
321 TTHREAD_TLS(TGeoManagerThreadState) state;
322 return state;
323}
324
325// Thread-local navigator pointers and thread ordinals cannot be reset by the thread deleting a manager.
326// Advancing this generation on destructive/global state transitions makes every thread refresh on its next access.
327std::atomic<ULong64_t> gGeoManagerThreadStateGeneration{1};
328
330{
331 gGeoManagerThreadStateGeneration.fetch_add(1, std::memory_order_release);
332}
333
334} // namespace
335
336////////////////////////////////////////////////////////////////////////////////
337/// Default constructor.
338
340{
341 if (!fgThreadId)
345 fTmin = 0.;
346 fTmax = 999.;
347 fPhiCut = kFALSE;
348 fPhimin = 0;
349 fPhimax = 360;
354 fClosed = kFALSE;
356 fBits = nullptr;
357 fCurrentNavigator = nullptr;
358 fMaterials = nullptr;
359 fHashPNE = nullptr;
360 fArrayPNE = nullptr;
361 fMatrices = nullptr;
362 fNodes = nullptr;
363 fOverlaps = nullptr;
364 fRegions = nullptr;
365 fNNodes = 0;
366 fMaxVisNodes = 10000;
367 fVolumes = nullptr;
368 fPhysicalNodes = nullptr;
369 fShapes = nullptr;
370 fGVolumes = nullptr;
371 fGShapes = nullptr;
372 fTracks = nullptr;
373 fMedia = nullptr;
374 fNtracks = 0;
375 fNpdg = 0;
376 fPdgNames = nullptr;
377 fGDMLMatrices = nullptr;
378 fOpticalSurfaces = nullptr;
379 fSkinSurfaces = nullptr;
380 fBorderSurfaces = nullptr;
381 memset(fPdgId, 0, 1024 * sizeof(Int_t));
382 // TObjArray *fNavigators; ///<! list of navigators
383 fCurrentTrack = nullptr;
384 fCurrentVolume = nullptr;
385 fTopVolume = nullptr;
386 fTopNode = nullptr;
387 fMasterVolume = nullptr;
388 fPainter = nullptr;
389 fChecker = nullptr;
392 fVisDensity = 0.;
393 fVisLevel = 3;
394 fVisOption = 1;
395 fExplodedView = 0;
396 fNsegments = 20;
397 fNLevel = 0;
398 fUniqueVolumes = nullptr;
399 fClippingShape = nullptr;
402 fGLMatrix = nullptr;
403 fPaintVolume = nullptr;
404 fUserPaintVolume = nullptr;
405 fElementTable = nullptr;
406 fHashVolumes = nullptr;
407 fHashGVolumes = nullptr;
408 fSizePNEId = 0;
409 fNPNEId = 0;
410 fKeyPNEId = nullptr;
411 fValuePNEId = nullptr;
413 fRaytraceMode = 0;
414 fMaxThreads = 0;
416 fParallelWorld = nullptr;
418 } else {
419 Init();
421 gGeoIdentity = new TGeoIdentity("Identity");
423 }
424}
425
426////////////////////////////////////////////////////////////////////////////////
427/// Constructor.
428
429TGeoManager::TGeoManager(const char *name, const char *title) : TNamed(name, title)
430{
431 if (!gROOT->GetListOfGeometries()->FindObject(this))
432 gROOT->GetListOfGeometries()->Add(this);
433 if (!gROOT->GetListOfBrowsables()->FindObject(this))
434 gROOT->GetListOfBrowsables()->Add(this);
435 Init();
436 gGeoIdentity = new TGeoIdentity("Identity");
438 if (fgVerboseLevel > 0)
439 Info("TGeoManager", "Geometry %s, %s created", GetName(), GetTitle());
440}
441
442////////////////////////////////////////////////////////////////////////////////
443/// Initialize manager class.
444
446{
447 if (gGeoManager) {
448 Warning("Init", "Deleting previous geometry: %s/%s", gGeoManager->GetName(), gGeoManager->GetTitle());
449 delete gGeoManager;
450 if (fgLock)
451 Fatal("Init", "New geometry created while the old one locked !!!");
452 }
453
454 gGeoManager = this;
455 if (!fgThreadId)
458 fTmin = 0.;
459 fTmax = 999.;
460 fPhiCut = kFALSE;
461 fPhimin = 0;
462 fPhimax = 360;
467 fClosed = kFALSE;
469 fBits = new UChar_t[50000]; // max 25000 nodes per volume
470 fCurrentNavigator = nullptr;
471 fHashPNE = new THashList(256, 3);
472 fArrayPNE = nullptr;
473 fMaterials = new THashList(200, 3);
474 fMatrices = new TObjArray(256);
475 fNodes = new TObjArray(30);
476 fOverlaps = new TObjArray(256);
477 fRegions = new TObjArray(256);
478 fNNodes = 0;
479 fMaxVisNodes = 10000;
480 fVolumes = new TObjArray(256);
481 fPhysicalNodes = new TObjArray(256);
482 fShapes = new TObjArray(256);
483 fGVolumes = new TObjArray(256);
484 fGShapes = new TObjArray(256);
485 fTracks = new TObjArray(256);
486 fMedia = new THashList(200, 3);
487 fNtracks = 0;
488 fNpdg = 0;
489 fPdgNames = nullptr;
490 fGDMLMatrices = new TObjArray();
492 fSkinSurfaces = new TObjArray();
494 memset(fPdgId, 0, 1024 * sizeof(Int_t));
495 fCurrentTrack = nullptr;
496 fCurrentVolume = nullptr;
497 fTopVolume = nullptr;
498 fTopNode = nullptr;
499 fMasterVolume = nullptr;
500 fPainter = nullptr;
501 fChecker = nullptr;
504 fVisDensity = 0.;
505 fVisLevel = 3;
506 fVisOption = 1;
507 fExplodedView = 0;
508 fNsegments = 20;
509 fNLevel = 0;
510 fUniqueVolumes = new TObjArray(256);
511 fClippingShape = nullptr;
514 fGLMatrix = new TGeoHMatrix();
515 fPaintVolume = nullptr;
516 fUserPaintVolume = nullptr;
517 fElementTable = nullptr;
518 fHashVolumes = nullptr;
519 fHashGVolumes = nullptr;
520 fSizePNEId = 0;
521 fNPNEId = 0;
522 fKeyPNEId = nullptr;
523 fValuePNEId = nullptr;
525 fRaytraceMode = 0;
526 fMaxThreads = 0;
528 fParallelWorld = nullptr;
530}
531
532////////////////////////////////////////////////////////////////////////////////
533/// Destructor
534
536{
537 if (gGeoManager != this)
538 gGeoManager = this;
540
541 if (gROOT->GetListOfFiles()) { // in case this function is called from TROOT destructor
542 gROOT->GetListOfGeometries()->Remove(this);
543 gROOT->GetListOfBrowsables()->Remove(this);
544 }
545 // TSeqCollection *brlist = gROOT->GetListOfBrowsers();
546 // TIter next(brlist);
547 // TBrowser *browser = 0;
548 // while ((browser=(TBrowser*)next())) browser->RecursiveRemove(this);
551 delete TGeoBuilder::Instance(this);
552 if (fBits)
553 delete[] fBits;
556 if (fOverlaps) {
557 fOverlaps->Delete();
559 }
560 if (fRegions) {
561 fRegions->Delete();
563 }
564 if (fMaterials) {
567 }
569 if (fMedia) {
570 fMedia->Delete();
572 }
573 if (fHashVolumes) {
574 fHashVolumes->Clear("nodelete");
576 }
577 if (fHashGVolumes) {
578 fHashGVolumes->Clear("nodelete");
580 }
581 if (fHashPNE) {
582 fHashPNE->Delete();
584 }
585 if (fArrayPNE) {
586 delete fArrayPNE;
587 }
588 if (fVolumes) {
589 fVolumes->Delete();
591 }
592 if (fShapes) {
593 fShapes->Delete();
595 }
596 if (fPhysicalNodes) {
599 }
600 if (fMatrices) {
601 fMatrices->Delete();
603 }
604 if (fTracks) {
605 fTracks->Delete();
607 }
609 if (fPdgNames) {
610 fPdgNames->Delete();
612 }
613 if (fGDMLMatrices) {
616 }
617 if (fOpticalSurfaces) {
620 }
621 if (fSkinSurfaces) {
624 }
625 if (fBorderSurfaces) {
628 }
630 CleanGarbage();
634 if (fSizePNEId) {
635 delete[] fKeyPNEId;
636 delete[] fValuePNEId;
637 }
638 delete fParallelWorld;
640 gGeoIdentity = nullptr;
641 gGeoManager = nullptr;
642}
643
644////////////////////////////////////////////////////////////////////////////////
645/// Add a material to the list. Returns index of the material in list.
646
648{
649 return TGeoBuilder::Instance(this)->AddMaterial((TGeoMaterial *)material);
650}
651
652////////////////////////////////////////////////////////////////////////////////
653/// Add an illegal overlap/extrusion to the list.
654
661
662////////////////////////////////////////////////////////////////////////////////
663/// Add a new region of volumes.
670
671////////////////////////////////////////////////////////////////////////////////
672/// Add a user-defined property. Returns true if added, false if existing.
673
675{
676 auto pos = fProperties.insert(ConstPropMap_t::value_type(property, value));
677 if (!pos.second) {
678 Warning("AddProperty", "Property \"%s\" already exists with value %g", property, (pos.first)->second);
679 return false;
680 }
681 return true;
682}
683
684////////////////////////////////////////////////////////////////////////////////
685/// Get a user-defined property
686
688{
689 auto pos = fProperties.find(property);
690 if (pos == fProperties.end()) {
691 if (error)
692 *error = kTRUE;
693 return 0.;
694 }
695 if (error)
696 *error = kFALSE;
697 return pos->second;
698}
699
700////////////////////////////////////////////////////////////////////////////////
701/// Get a user-defined property from a given index
702
704{
705 // This is a quite inefficient way to access map elements, but needed for the GDML writer to
706 if (i >= fProperties.size()) {
707 if (error)
708 *error = kTRUE;
709 return 0.;
710 }
711 size_t pos = 0;
712 auto it = fProperties.begin();
713 while (pos < i) {
714 ++it;
715 ++pos;
716 }
717 if (error)
718 *error = kFALSE;
719 name = (*it).first;
720 return (*it).second;
721}
722
723////////////////////////////////////////////////////////////////////////////////
724/// Add a matrix to the list. Returns index of the matrix in list.
725
727{
728 return TGeoBuilder::Instance(this)->AddTransformation((TGeoMatrix *)matrix);
729}
730
731////////////////////////////////////////////////////////////////////////////////
732/// Add a shape to the list. Returns index of the shape in list.
733
735{
736 return TGeoBuilder::Instance(this)->AddShape((TGeoShape *)shape);
737}
738
739////////////////////////////////////////////////////////////////////////////////
740/// Add a track to the list of tracks. Use this for primaries only. For secondaries,
741/// add them to the parent track. The method create objects that are registered
742/// to the analysis manager but have to be cleaned-up by the user via ClearTracks().
743
750
751////////////////////////////////////////////////////////////////////////////////
752/// Add a track to the list of tracks
753
760
761////////////////////////////////////////////////////////////////////////////////
762/// Makes a primary track but do not attach it to the list of tracks. The track
763/// can be attached as daughter to another one with TVirtualGeoTrack::AddTrack
764
770
771////////////////////////////////////////////////////////////////////////////////
772/// Add a volume to the list. Returns index of the volume in list.
773
775{
776 if (!volume) {
777 Error("AddVolume", "invalid volume");
778 return -1;
779 }
781 if (!uid)
782 uid++;
783 if (!fCurrentVolume) {
784 fCurrentVolume = volume;
785 fUniqueVolumes->AddAtAndExpand(volume, uid);
786 } else {
787 if (!strcmp(volume->GetName(), fCurrentVolume->GetName())) {
788 uid = fCurrentVolume->GetNumber();
789 } else {
790 fCurrentVolume = volume;
791 Int_t olduid = GetUID(volume->GetName());
792 if (olduid < 0) {
793 fUniqueVolumes->AddAtAndExpand(volume, uid);
794 } else {
795 uid = olduid;
796 }
797 }
798 }
799 volume->SetNumber(uid);
800 if (!fHashVolumes) {
801 fHashVolumes = new THashList(256, 3);
802 fHashGVolumes = new THashList(256, 3);
803 }
804 TObjArray *list = fVolumes;
805 if (!volume->GetShape() || volume->IsRunTime() || volume->IsVolumeMulti()) {
806 list = fGVolumes;
807 fHashGVolumes->Add(volume);
808 } else {
809 fHashVolumes->Add(volume);
810 }
811 Int_t index = list->GetEntriesFast();
812 list->AddAtAndExpand(volume, index);
813 return uid;
814}
815
816////////////////////////////////////////////////////////////////////////////////
817/// Add a navigator in the list of navigators. If it is the first one make it
818/// current navigator.
819
821{
822 if (fMultiThread) {
824 fgMutex.lock();
825 }
826 std::thread::id threadId = std::this_thread::get_id();
827 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
828 TGeoNavigatorArray *array = nullptr;
829 if (it != fNavigators.end())
830 array = it->second;
831 else {
832 array = new TGeoNavigatorArray(this);
833 fNavigators.insert(NavigatorsMap_t::value_type(threadId, array));
834 }
835 TGeoNavigator *nav = array->AddNavigator();
836 if (fClosed)
837 nav->GetCache()->BuildInfoBranch();
838 if (fMultiThread) {
839 auto &state = GetGeoManagerThreadState();
840 state.fManager = this;
841 state.fNavigator = nav;
842 state.fNavigatorGeneration = gGeoManagerThreadStateGeneration.load(std::memory_order_acquire);
843 fgMutex.unlock();
844 }
845 return nav;
846}
847
848////////////////////////////////////////////////////////////////////////////////
849/// Returns current navigator for the calling thread.
850
852{
853 if (!fMultiThread)
854 return fCurrentNavigator;
855 auto &state = GetGeoManagerThreadState();
856 const auto generation = gGeoManagerThreadStateGeneration.load(std::memory_order_acquire);
857 if (state.fNavigator && state.fManager == this && state.fNavigatorGeneration == generation)
858 return state.fNavigator;
859
860 std::lock_guard<std::mutex> lock(fgMutex);
861 std::thread::id threadId = std::this_thread::get_id();
862 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
863 if (it == fNavigators.end()) {
864 state.fManager = this;
865 state.fNavigator = nullptr;
866 state.fNavigatorGeneration = generation;
867 return nullptr;
868 }
869 TGeoNavigatorArray *array = it->second;
870 state.fManager = this;
871 state.fNavigator = array->GetCurrentNavigator();
872 state.fNavigatorGeneration = generation;
873 return state.fNavigator;
874}
875
876////////////////////////////////////////////////////////////////////////////////
877/// Get list of navigators for the calling thread.
878
880{
881 std::unique_lock<std::mutex> lock(fgMutex, std::defer_lock);
882 if (fMultiThread)
883 lock.lock();
884 std::thread::id threadId = std::this_thread::get_id();
885 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
886 if (it == fNavigators.end())
887 return nullptr;
888 TGeoNavigatorArray *array = it->second;
889 return array;
890}
891
892////////////////////////////////////////////////////////////////////////////////
893/// Switch to another existing navigator for the calling thread.
894
896{
897 std::unique_lock<std::mutex> lock(fgMutex, std::defer_lock);
898 if (fMultiThread)
899 lock.lock();
900 std::thread::id threadId = std::this_thread::get_id();
901 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
902 if (it == fNavigators.end()) {
903 Error("SetCurrentNavigator", "No navigator defined for this thread\n");
904 std::cout << " thread id: " << threadId << std::endl;
905 return kFALSE;
906 }
907 TGeoNavigatorArray *array = it->second;
909 if (!nav) {
910 Error("SetCurrentNavigator", "Navigator %d not existing for this thread\n", index);
911 std::cout << " thread id: " << threadId << std::endl;
912 return kFALSE;
913 }
914 if (fMultiThread) {
915 auto &state = GetGeoManagerThreadState();
916 state.fManager = this;
917 state.fNavigator = nav;
918 state.fNavigatorGeneration = gGeoManagerThreadStateGeneration.load(std::memory_order_acquire);
919 } else {
921 }
922 return kTRUE;
923}
924
925////////////////////////////////////////////////////////////////////////////////
926/// Set the lock for navigators.
927
932
933////////////////////////////////////////////////////////////////////////////////
934/// Clear all navigators.
935
937{
939 if (fMultiThread)
940 fgMutex.lock();
941 TGeoNavigatorArray *arr = nullptr;
942 for (NavigatorsMap_t::iterator it = fNavigators.begin(); it != fNavigators.end(); ++it) {
943 arr = (*it).second;
944 if (arr)
945 delete arr;
946 }
947 fNavigators.clear();
948 if (fMultiThread)
949 fgMutex.unlock();
950}
951
952////////////////////////////////////////////////////////////////////////////////
953/// Clear a single navigator.
954
956{
957 if (fMultiThread)
958 fgMutex.lock();
959 for (NavigatorsMap_t::iterator it = fNavigators.begin(); it != fNavigators.end(); ++it) {
960 TGeoNavigatorArray *arr = (*it).second;
961 if (arr) {
962 if ((TGeoNavigator *)arr->Remove((TObject *)nav)) {
964 delete nav;
965 if (!arr->GetEntries())
966 fNavigators.erase(it);
967 if (fMultiThread)
968 fgMutex.unlock();
969 return;
970 }
971 }
972 }
973 Error("Remove navigator", "Navigator %p not found", nav);
974 if (fMultiThread)
975 fgMutex.unlock();
976}
977
978////////////////////////////////////////////////////////////////////////////////
979/// Enable multi-threaded navigation for at most `nthreads` worker threads.
980/// The geometry must be closed and navigation must not be active when this method is called.
981/// This enables ROOT thread safety and prepares the manager and geometry objects for concurrent navigation.
982
984{
985 if (!fClosed) {
986 Error("SetMaxThreads", "Cannot set maximum number of threads before closing the geometry");
987 return;
988 }
989 if (!fMultiThread) {
991 std::thread::id threadId = std::this_thread::get_id();
992 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
993 if (it != fNavigators.end()) {
994 TGeoNavigatorArray *array = it->second;
995 fNavigators.erase(it);
996 fNavigators.insert(NavigatorsMap_t::value_type(threadId, array));
997 }
998 }
999 if (fMaxThreads) {
1002 }
1004 fMaxThreads = nthreads + 1;
1005 if (fMaxThreads > 0) {
1008 }
1009}
1010
1011////////////////////////////////////////////////////////////////////////////////
1012
1014{
1015 if (!fMaxThreads)
1016 return;
1017 fgMutex.lock();
1018 TIter next(fVolumes);
1019 TGeoVolume *vol;
1020 while ((vol = (TGeoVolume *)next()))
1021 vol->ClearThreadData();
1022 fgMutex.unlock();
1023}
1024
1025////////////////////////////////////////////////////////////////////////////////
1026/// Create thread private data for all geometry objects.
1027
1029{
1030 if (!fMaxThreads)
1031 return;
1032 fgMutex.lock();
1033 TIter next(fVolumes);
1034 TGeoVolume *vol;
1035 while ((vol = (TGeoVolume *)next()))
1037 fgMutex.unlock();
1038}
1039
1040////////////////////////////////////////////////////////////////////////////////
1041/// Clear the current map of threads. This will be filled again by the calling
1042/// threads via ThreadId calls.
1043
1045{
1048 return;
1049 fgMutex.lock();
1050 if (!fgThreadId->empty())
1051 fgThreadId->clear();
1052 fgNumThreads = 0;
1053 fgMutex.unlock();
1054}
1055
1056////////////////////////////////////////////////////////////////////////////////
1057/// Translates the current thread id to an ordinal number. This can be used to
1058/// manage data which is specific for a given thread.
1059
1061{
1062 auto &state = GetGeoManagerThreadState();
1063 const auto generation = gGeoManagerThreadStateGeneration.load(std::memory_order_acquire);
1064 if (state.fThreadId > -1 && state.fThreadIdGeneration == generation)
1065 return state.fThreadId;
1067 state.fThreadId = 0;
1068 state.fThreadIdGeneration = generation;
1069 return 0;
1070 }
1071 std::thread::id threadId = std::this_thread::get_id();
1072 std::lock_guard<std::mutex> lock(fgMutex);
1074 if (it != fgThreadId->end()) {
1075 state.fThreadId = it->second;
1076 state.fThreadIdGeneration = generation;
1077 return state.fThreadId;
1078 }
1079 (*fgThreadId)[threadId] = fgNumThreads;
1080 state.fThreadId = fgNumThreads++;
1081 state.fThreadIdGeneration = generation;
1082 return state.fThreadId;
1083}
1084
1085////////////////////////////////////////////////////////////////////////////////
1086/// Describe how to browse this object.
1087
1089{
1090 if (!b)
1091 return;
1092 if (fMaterials)
1093 b->Add(fMaterials, "Materials");
1094 if (fMedia)
1095 b->Add(fMedia, "Media");
1096 if (fMatrices)
1097 b->Add(fMatrices, "Local transformations");
1098 if (fOverlaps)
1099 b->Add(fOverlaps, "Illegal overlaps");
1100 if (fTracks)
1101 b->Add(fTracks, "Tracks");
1102 if (fMasterVolume)
1103 b->Add(fMasterVolume, "Master Volume", fMasterVolume->IsVisible());
1104 if (fTopVolume)
1105 b->Add(fTopVolume, "Top Volume", fTopVolume->IsVisible());
1106 if (fTopNode)
1107 b->Add(fTopNode);
1108 TString browserImp(gEnv->GetValue("Browser.Name", "TRootBrowserLite"));
1109 TQObject::Connect(browserImp.Data(), "Checked(TObject*,Bool_t)", "TGeoManager", this,
1110 "SetVisibility(TObject*,Bool_t)");
1111}
1112
1113////////////////////////////////////////////////////////////////////////////////
1114/// Append a pad for this geometry.
1115
1121
1122////////////////////////////////////////////////////////////////////////////////
1123/// Set visibility for a volume.
1124
1126{
1127 if (obj->IsA() == TGeoVolume::Class()) {
1128 TGeoVolume *vol = (TGeoVolume *)obj;
1129 vol->SetVisibility(vis);
1130 } else {
1131 if (obj->InheritsFrom(TGeoNode::Class())) {
1132 TGeoNode *node = (TGeoNode *)obj;
1133 node->SetVisibility(vis);
1134 } else
1135 return;
1136 }
1138}
1139
1140////////////////////////////////////////////////////////////////////////////////
1141/// Get the new 'bombed' translation vector according current exploded view mode.
1142
1144{
1145 if (fPainter)
1147 return;
1148}
1149
1150////////////////////////////////////////////////////////////////////////////////
1151/// Get the new 'unbombed' translation vector according current exploded view mode.
1152
1154{
1155 if (fPainter)
1157 return;
1158}
1159
1160////////////////////////////////////////////////////////////////////////////////
1161/// Backup the current state without affecting the cache stack.
1162
1167
1168////////////////////////////////////////////////////////////////////////////////
1169/// Restore a backed-up state without affecting the cache stack.
1170
1175
1176////////////////////////////////////////////////////////////////////////////////
1177/// Register a matrix to the list of matrices. It will be cleaned-up at the
1178/// destruction TGeoManager.
1179
1181{
1182 return TGeoBuilder::Instance(this)->RegisterMatrix((TGeoMatrix *)matrix);
1183}
1184
1185////////////////////////////////////////////////////////////////////////////////
1186/// Replaces all occurrences of VORIG with VNEW in the geometry tree. The volume VORIG
1187/// is not replaced from the list of volumes, but all node referencing it will reference
1188/// VNEW instead. Returns number of occurrences changed.
1189
1191{
1192 Int_t nref = 0;
1193 if (!vorig || !vnew)
1194 return nref;
1195 TGeoMedium *morig = vorig->GetMedium();
1197 if (morig)
1198 checkmed = kTRUE;
1199 TGeoMedium *mnew = vnew->GetMedium();
1200 // Try to limit the damage produced by incorrect usage.
1201 if (!mnew && !vnew->IsAssembly()) {
1202 Error("ReplaceVolume", "Replacement volume %s has no medium and it is not an assembly", vnew->GetName());
1203 return nref;
1204 }
1205 if (mnew && checkmed) {
1206 if (mnew->GetId() != morig->GetId())
1207 Warning("ReplaceVolume", "Replacement volume %s has different medium than original volume %s", vnew->GetName(),
1208 vorig->GetName());
1209 checkmed = kFALSE;
1210 }
1211
1212 // Medium checking now performed only if replacement is an assembly and old volume a real one.
1213 // Check result is dependent on positioning.
1215 Int_t i, j, nd;
1216 Int_t ierr = 0;
1217 TGeoVolume *vol;
1218 TGeoNode *node;
1220 for (i = 0; i < nvol; i++) {
1221 vol = (TGeoVolume *)fVolumes->At(i);
1222 if (!vol)
1223 continue;
1224 if (vol == vorig || vol == vnew)
1225 continue;
1226 nd = vol->GetNdaughters();
1227 for (j = 0; j < nd; j++) {
1228 node = vol->GetNode(j);
1229 if (node->GetVolume() == vorig) {
1230 if (checkmed) {
1231 mnew = node->GetMotherVolume()->GetMedium();
1232 if (mnew && mnew->GetId() != morig->GetId())
1233 ierr++;
1234 }
1235 nref++;
1236 if (node->IsOverlapping()) {
1237 node->SetOverlapping(kFALSE);
1238 Info("ReplaceVolume", "%s replaced with assembly and declared NON-OVERLAPPING!", node->GetName());
1239 }
1240 node->SetVolume(vnew);
1241 voxels = node->GetMotherVolume()->GetVoxels();
1242 if (voxels)
1243 voxels->SetNeedRebuild();
1244 } else {
1245 if (node->GetMotherVolume() == vorig) {
1246 nref++;
1247 node->SetMotherVolume(vnew);
1248 if (node->IsOverlapping()) {
1249 node->SetOverlapping(kFALSE);
1250 Info("ReplaceVolume", "%s inside substitute assembly %s declared NON-OVERLAPPING!", node->GetName(),
1251 vnew->GetName());
1252 }
1253 }
1254 }
1255 }
1256 }
1257 if (ierr)
1258 Warning("ReplaceVolume",
1259 "Volumes should not be replaced with assemblies if they are positioned in containers having a different "
1260 "medium ID.\n %i occurrences for assembly replacing volume %s",
1261 ierr, vorig->GetName());
1262 return nref;
1263}
1264
1265////////////////////////////////////////////////////////////////////////////////
1266/// Rebuild the voxel structures that are flagged as needing rebuild.
1267
1269{
1271 TGeoVolume *vol;
1273 for (Int_t i = 0; i < nvol; i++) {
1274 vol = (TGeoVolume *)fVolumes->At(i);
1275 if (!vol)
1276 continue;
1277 voxels = vol->GetVoxels();
1278 if (voxels && voxels->NeedRebuild()) {
1279 voxels->Voxelize();
1280 vol->FindOverlaps(); // after voxelization, check overlaps again
1281 }
1282 }
1283}
1284
1285////////////////////////////////////////////////////////////////////////////////
1286/// Transform all volumes named VNAME to assemblies. The volumes must be virtual.
1287
1289{
1291 if (!toTransform) {
1292 Warning("TransformVolumeToAssembly", "Volume %s not found", vname);
1293 return 0;
1294 }
1296 Int_t count = 0;
1298 Bool_t replace = kTRUE;
1300 while (index < indmax) {
1301 if (replace) {
1302 replace = kFALSE;
1304 if (transformed) {
1306 count++;
1307 } else {
1308 if (toTransform->IsAssembly())
1309 Warning("TransformVolumeToAssembly", "Volume %s already assembly", toTransform->GetName());
1310 if (!toTransform->GetNdaughters())
1311 Warning("TransformVolumeToAssembly", "Volume %s has no daughters, cannot transform",
1312 toTransform->GetName());
1313 if (toTransform->IsVolumeMulti())
1314 Warning("TransformVolumeToAssembly", "Volume %s divided, cannot transform", toTransform->GetName());
1315 }
1316 }
1317 index++;
1318 if (index >= indmax)
1319 return count;
1321 if (!strcmp(toTransform->GetName(), vname))
1322 replace = kTRUE;
1323 }
1324 return count;
1325}
1326
1327////////////////////////////////////////////////////////////////////////////////
1328/// Create a new volume by dividing an existing one (GEANT3 like)
1329///
1330/// Divides MOTHER into NDIV divisions called NAME
1331/// along axis IAXIS starting at coordinate value START
1332/// and having size STEP. The created volumes will have tracking
1333/// media ID=NUMED (if NUMED=0 -> same media as MOTHER)
1334/// The behavior of the division operation can be triggered using OPTION :
1335///
1336/// OPTION (case insensitive) :
1337/// - N - divide all range in NDIV cells (same effect as STEP<=0) (GSDVN in G3)
1338/// - NX - divide range starting with START in NDIV cells (GSDVN2 in G3)
1339/// - S - divide all range with given STEP. NDIV is computed and divisions will be centered
1340/// in full range (same effect as NDIV<=0) (GSDVS, GSDVT in G3)
1341/// - SX - same as DVS, but from START position. (GSDVS2, GSDVT2 in G3)
1342
1343TGeoVolume *TGeoManager::Division(const char *name, const char *mother, Int_t iaxis, Int_t ndiv, Double_t start,
1345{
1346 return TGeoBuilder::Instance(this)->Division(name, mother, iaxis, ndiv, start, step, numed, option);
1347}
1348
1349////////////////////////////////////////////////////////////////////////////////
1350/// Create rotation matrix named 'mat<index>'.
1351///
1352/// - index rotation matrix number
1353/// - theta1 polar angle for axis X
1354/// - phi1 azimuthal angle for axis X
1355/// - theta2 polar angle for axis Y
1356/// - phi2 azimuthal angle for axis Y
1357/// - theta3 polar angle for axis Z
1358/// - phi3 azimuthal angle for axis Z
1359///
1360
1366
1367////////////////////////////////////////////////////////////////////////////////
1368/// Create material with given A, Z and density, having an unique id.
1369
1372{
1373 return TGeoBuilder::Instance(this)->Material(name, a, z, dens, uid, radlen, intlen);
1374}
1375
1376////////////////////////////////////////////////////////////////////////////////
1377/// Create mixture OR COMPOUND IMAT as composed by THE BASIC nelem
1378/// materials defined by arrays A,Z and WMAT, having an unique id.
1379
1382{
1383 return TGeoBuilder::Instance(this)->Mixture(name, a, z, dens, nelem, wmat, uid);
1384}
1385
1386////////////////////////////////////////////////////////////////////////////////
1387/// Create mixture OR COMPOUND IMAT as composed by THE BASIC nelem
1388/// materials defined by arrays A,Z and WMAT, having an unique id.
1389
1392{
1393 return TGeoBuilder::Instance(this)->Mixture(name, a, z, dens, nelem, wmat, uid);
1394}
1395
1396////////////////////////////////////////////////////////////////////////////////
1397/// Create tracking medium
1398///
1399/// - numed tracking medium number assigned
1400/// - name tracking medium name
1401/// - nmat material number
1402/// - isvol sensitive volume flag
1403/// - ifield magnetic field
1404/// - fieldm max. field value (kilogauss)
1405/// - tmaxfd max. angle due to field (deg/step)
1406/// - stemax max. step allowed
1407/// - deemax max. fraction of energy lost in a step
1408/// - epsil tracking precision (cm)
1409/// - stmin min. step due to continuous processes (cm)
1410///
1411/// - ifield = 0 if no magnetic field; ifield = -1 if user decision in guswim;
1412/// - ifield = 1 if tracking performed with g3rkuta; ifield = 2 if tracking
1413/// performed with g3helix; ifield = 3 if tracking performed with g3helx3.
1414///
1415
1422
1423////////////////////////////////////////////////////////////////////////////////
1424/// Create a node called `<name_nr>` pointing to the volume called `<name>`
1425/// as daughter of the volume called `<mother>` (gspos). The relative matrix is
1426/// made of : a translation (x,y,z) and a rotation matrix named `<matIROT>`.
1427/// In case npar>0, create the volume to be positioned in mother, according
1428/// its actual parameters (gsposp).
1429/// - NAME Volume name
1430/// - NUMBER Copy number of the volume
1431/// - MOTHER Mother volume name
1432/// - X X coord. of the volume in mother ref. sys.
1433/// - Y Y coord. of the volume in mother ref. sys.
1434/// - Z Z coord. of the volume in mother ref. sys.
1435/// - IROT Rotation matrix number w.r.t. mother ref. sys.
1436/// - ISONLY ONLY/MANY flag
1437
1440{
1441 TGeoBuilder::Instance(this)->Node(name, nr, mother, x, y, z, irot, isOnly, upar, npar);
1442}
1443
1444////////////////////////////////////////////////////////////////////////////////
1445/// Create a node called `<name_nr>` pointing to the volume called `<name>`
1446/// as daughter of the volume called `<mother>` (gspos). The relative matrix is
1447/// made of : a translation (x,y,z) and a rotation matrix named `<matIROT>`.
1448/// In case npar>0, create the volume to be positioned in mother, according
1449/// its actual parameters (gsposp).
1450/// - NAME Volume name
1451/// - NUMBER Copy number of the volume
1452/// - MOTHER Mother volume name
1453/// - X X coord. of the volume in mother ref. sys.
1454/// - Y Y coord. of the volume in mother ref. sys.
1455/// - Z Z coord. of the volume in mother ref. sys.
1456/// - IROT Rotation matrix number w.r.t. mother ref. sys.
1457/// - ISONLY ONLY/MANY flag
1458
1461{
1462 TGeoBuilder::Instance(this)->Node(name, nr, mother, x, y, z, irot, isOnly, upar, npar);
1463}
1464
1465////////////////////////////////////////////////////////////////////////////////
1466/// Create a volume in GEANT3 style.
1467/// - NAME Volume name
1468/// - SHAPE Volume type
1469/// - NMED Tracking medium number
1470/// - NPAR Number of shape parameters
1471/// - UPAR Vector containing shape parameters
1472
1473TGeoVolume *TGeoManager::Volume(const char *name, const char *shape, Int_t nmed, Float_t *upar, Int_t npar)
1474{
1475 return TGeoBuilder::Instance(this)->Volume(name, shape, nmed, upar, npar);
1476}
1477
1478////////////////////////////////////////////////////////////////////////////////
1479/// Create a volume in GEANT3 style.
1480/// - NAME Volume name
1481/// - SHAPE Volume type
1482/// - NMED Tracking medium number
1483/// - NPAR Number of shape parameters
1484/// - UPAR Vector containing shape parameters
1485
1487{
1488 return TGeoBuilder::Instance(this)->Volume(name, shape, nmed, upar, npar);
1489}
1490
1491////////////////////////////////////////////////////////////////////////////////
1492/// Assigns uid's for all materials,media and matrices.
1493
1495{
1496 Int_t index = 1;
1497 TIter next(fMaterials);
1499 while ((mater = (TGeoMaterial *)next())) {
1500 mater->SetUniqueID(index++);
1502 }
1503 index = 1;
1505 TGeoMedium *med;
1506 while ((med = (TGeoMedium *)next1())) {
1507 med->SetUniqueID(index++);
1509 }
1510 index = 1;
1512 TGeoShape *shape;
1513 while ((shape = (TGeoShape *)next2())) {
1514 shape->SetUniqueID(index++);
1515 if (shape->IsComposite())
1516 ((TGeoCompositeShape *)shape)->GetBoolNode()->RegisterMatrices();
1517 }
1518
1521 while ((matrix = (TGeoMatrix *)next3())) {
1522 matrix->RegisterYourself();
1523 }
1525 index = 1;
1526 while ((matrix = (TGeoMatrix *)next4())) {
1527 matrix->SetUniqueID(index++);
1529 }
1531 TGeoVolume *vol;
1532 while ((vol = (TGeoVolume *)next5()))
1533 vol->UnmarkSaved();
1534}
1535
1536////////////////////////////////////////////////////////////////////////////////
1537/// Reset all attributes to default ones. Default attributes for visualization
1538/// are those defined before closing the geometry.
1539
1541{
1542 if (gPad)
1543 delete gPad;
1544 gPad = nullptr;
1545 SetVisOption(0);
1546 SetVisLevel(3);
1547 SetExplodedView(0);
1549 if (!gStyle)
1550 return;
1551 TIter next(fVolumes);
1552 TGeoVolume *vol = nullptr;
1553 while ((vol = (TGeoVolume *)next())) {
1554 if (!vol->IsVisTouched())
1555 continue;
1556 vol->SetVisTouched(kFALSE);
1557 }
1558}
1559////////////////////////////////////////////////////////////////////////////////
1560/// Closing geometry implies checking the geometry validity, fixing shapes
1561/// with negative parameters (run-time shapes)building the cache manager,
1562/// voxelizing all volumes, counting the total number of physical nodes and
1563/// registering the manager class to the browser.
1564
1566{
1567 if (fClosed) {
1568 Warning("CloseGeometry", "geometry already closed");
1569 return;
1570 }
1571 if (!fMasterVolume) {
1572 Error("CloseGeometry", "you MUST call SetTopVolume() first !");
1573 return;
1574 }
1575 if (!gROOT->GetListOfGeometries()->FindObject(this))
1576 gROOT->GetListOfGeometries()->Add(this);
1577 if (!gROOT->GetListOfBrowsables()->FindObject(this))
1578 gROOT->GetListOfBrowsables()->Add(this);
1579 // TSeqCollection *brlist = gROOT->GetListOfBrowsers();
1580 // TIter next(brlist);
1581 // TBrowser *browser = 0;
1582 // while ((browser=(TBrowser*)next())) browser->Refresh();
1583 TString opt(option);
1584 opt.ToLower();
1585 // Bool_t dummy = opt.Contains("d");
1586 Bool_t nodeid = opt.Contains("i");
1587 // Create a geometry navigator if not present
1588 TGeoNavigator *nav = nullptr;
1589 Int_t nnavigators = 0;
1590 // Check if the geometry is streamed from file
1591 if (fIsGeomReading) {
1592 if (fgVerboseLevel > 0)
1593 Info("CloseGeometry", "Geometry loaded from file...");
1595 if (!fElementTable)
1597 if (!fTopNode) {
1598 if (!fMasterVolume) {
1599 Error("CloseGeometry", "Master volume not streamed");
1600 return;
1601 }
1603 if (fStreamVoxels && fgVerboseLevel > 0)
1604 Info("CloseGeometry", "Voxelization retrieved from file");
1605 }
1606 // Create a geometry navigator if not present
1607 if (!GetCurrentNavigator())
1610 if (!opt.Contains("nv")) {
1611 Voxelize("ALL");
1612 }
1613 CountLevels();
1614 for (Int_t i = 0; i < nnavigators; i++) {
1616 nav->GetCache()->BuildInfoBranch();
1617 if (nodeid)
1618 nav->GetCache()->BuildIdArray();
1619 }
1620 if (!fHashVolumes) {
1623 fHashVolumes = new THashList(nvol + 1, 3);
1624 fHashGVolumes = new THashList(ngvol + 1, 3);
1625 Int_t i;
1626 for (i = 0; i < ngvol; i++)
1628 for (i = 0; i < nvol; i++)
1630 }
1631 fClosed = kTRUE;
1632 if (fParallelWorld) {
1633 if (fgVerboseLevel > 0)
1634 Info("CloseGeometry", "Recreating parallel world %s ...", fParallelWorld->GetName());
1636 }
1637
1638 if (fgVerboseLevel > 0)
1639 Info("CloseGeometry", "%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast() - 1,
1640 GetTitle());
1641 if (fgVerboseLevel > 0)
1642 Info("CloseGeometry", "----------------modeler ready----------------");
1643 return;
1644 }
1645
1646 // Create a geometry navigator if not present
1647 if (!GetCurrentNavigator())
1651 CheckGeometry();
1652 if (fgVerboseLevel > 0)
1653 Info("CloseGeometry", "Counting nodes...");
1654 fNNodes = CountNodes();
1655 fNLevel = fMasterVolume->CountNodes(1, 3) + 1;
1656 if (fNLevel < 30)
1657 fNLevel = 100;
1658
1659 // BuildIdArray();
1660 // avoid voxelization if requested to speed up geometry startup
1661 if (!opt.Contains("nv")) {
1662 Voxelize("ALL");
1663 } else {
1664 TGeoVolume *vol;
1665 TIter next(fVolumes);
1666 while ((vol = (TGeoVolume *)next())) {
1667 vol->SortNodes();
1668 }
1669 }
1670 if (fgVerboseLevel > 0)
1671 Info("CloseGeometry", "Building cache...");
1672 CountLevels();
1673 for (Int_t i = 0; i < nnavigators; i++) {
1675 nav->GetCache()->BuildInfoBranch();
1676 if (nodeid)
1677 nav->GetCache()->BuildIdArray();
1678 }
1679 fClosed = kTRUE;
1680 if (fgVerboseLevel > 0) {
1681 Info("CloseGeometry", "%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast() - 1,
1682 GetTitle());
1683 Info("CloseGeometry", "----------------modeler ready----------------");
1684 }
1685}
1686
1687////////////////////////////////////////////////////////////////////////////////
1688/// Clear the list of overlaps.
1689
1691{
1692 if (fOverlaps) {
1693 fOverlaps->Delete();
1694 delete fOverlaps;
1695 }
1696 fOverlaps = new TObjArray();
1697}
1698
1699////////////////////////////////////////////////////////////////////////////////
1700/// Remove a shape from the list of shapes.
1701
1703{
1704 if (fShapes->FindObject(shape))
1705 fShapes->Remove((TGeoShape *)shape);
1706 delete shape;
1707}
1708
1709////////////////////////////////////////////////////////////////////////////////
1710/// Clean temporary volumes and shapes from garbage collection.
1711
1713{
1714 if (!fGVolumes && !fGShapes)
1715 return;
1716 Int_t i, nentries;
1717 if (fGVolumes) {
1719 TGeoVolume *vol = nullptr;
1720 for (i = 0; i < nentries; i++) {
1721 vol = (TGeoVolume *)fGVolumes->At(i);
1722 if (vol)
1723 vol->SetFinder(nullptr);
1724 }
1725 fGVolumes->Delete();
1726 delete fGVolumes;
1727 fGVolumes = nullptr;
1728 }
1729 if (fGShapes) {
1730 fGShapes->Delete();
1731 delete fGShapes;
1732 fGShapes = nullptr;
1733 }
1734}
1735
1736////////////////////////////////////////////////////////////////////////////////
1737/// Change current path to point to the node having this id.
1738/// Node id has to be in range : 0 to fNNodes-1 (no check for performance reasons)
1739
1741{
1742 GetCurrentNavigator()->CdNode(nodeid);
1743}
1744
1745////////////////////////////////////////////////////////////////////////////////
1746/// Get the unique ID of the current node.
1747
1752
1753////////////////////////////////////////////////////////////////////////////////
1754/// Make top level node the current node. Updates the cache accordingly.
1755/// Determine the overlapping state of current node.
1756
1758{
1760}
1761
1762////////////////////////////////////////////////////////////////////////////////
1763/// Go one level up in geometry. Updates cache accordingly.
1764/// Determine the overlapping state of current node.
1765
1767{
1769}
1770
1771////////////////////////////////////////////////////////////////////////////////
1772/// Make a daughter of current node current. Can be called only with a valid
1773/// daughter index (no check). Updates cache accordingly.
1774
1779
1780////////////////////////////////////////////////////////////////////////////////
1781/// Do a cd to the node found next by FindNextBoundary
1782
1784{
1786}
1787
1788////////////////////////////////////////////////////////////////////////////////
1789/// Browse the tree of nodes starting from fTopNode according to pathname.
1790/// Changes the path accordingly.
1791
1792Bool_t TGeoManager::cd(const char *path)
1793{
1794 return GetCurrentNavigator()->cd(path);
1795}
1796
1797////////////////////////////////////////////////////////////////////////////////
1798/// Check if a geometry path is valid without changing the state of the current navigator.
1799
1800Bool_t TGeoManager::CheckPath(const char *path) const
1801{
1802 return GetCurrentNavigator()->CheckPath(path);
1803}
1804
1805////////////////////////////////////////////////////////////////////////////////
1806/// Convert all reflections in geometry to normal rotations + reflected shapes.
1807
1809{
1810 if (!fTopNode)
1811 return;
1812 if (fgVerboseLevel > 0)
1813 Info("ConvertReflections", "Converting reflections in: %s - %s ...", GetName(), GetTitle());
1815 TGeoNode *node;
1819 while ((node = next())) {
1820 matrix = node->GetMatrix();
1821 if (matrix->IsReflection()) {
1822 // printf("%s before\n", node->GetName());
1823 // matrix->Print();
1825 mclone->RegisterYourself();
1826 // Reflect just the rotation component
1827 mclone->ReflectZ(kFALSE, kTRUE);
1828 nodematrix = (TGeoNodeMatrix *)node;
1829 nodematrix->SetMatrix(mclone);
1830 // printf("%s after\n", node->GetName());
1831 // node->GetMatrix()->Print();
1833 node->SetVolume(reflected);
1834 }
1835 }
1836 if (fgVerboseLevel > 0)
1837 Info("ConvertReflections", "Done");
1838}
1839
1840////////////////////////////////////////////////////////////////////////////////
1841/// Count maximum number of nodes per volume, maximum depth and maximum
1842/// number of xtru vertices.
1843
1845{
1846 if (!fTopNode) {
1847 Error("CountLevels", "Top node not defined.");
1848 return;
1849 }
1852 if (fMasterVolume->GetRefCount() > 1)
1854 if (fgVerboseLevel > 1 && fixrefs)
1855 Info("CountLevels", "Fixing volume reference counts");
1856 TGeoNode *node;
1857 Int_t maxlevel = 1;
1859 Int_t maxvertices = 1;
1860 while ((node = next())) {
1861 if (fixrefs) {
1862 node->GetVolume()->Grab();
1863 for (Int_t ibit = 10; ibit < 14; ibit++) {
1864 node->SetBit(BIT(ibit + 4), node->TestBit(BIT(ibit)));
1865 // node->ResetBit(BIT(ibit)); // cannot overwrite old crap for reproducibility
1866 }
1867 }
1868 if (node->GetNdaughters() > maxnodes)
1869 maxnodes = node->GetNdaughters();
1870 if (next.GetLevel() > maxlevel)
1871 maxlevel = next.GetLevel();
1872 if (node->GetVolume()->GetShape()->IsA() == TGeoXtru::Class()) {
1873 TGeoXtru *xtru = (TGeoXtru *)node->GetVolume()->GetShape();
1874 if (xtru->GetNvert() > maxvertices)
1875 maxvertices = xtru->GetNvert();
1876 }
1877 }
1881 if (fgVerboseLevel > 0)
1882 Info("CountLevels", "max level = %d, max placements = %d", fgMaxLevel, fgMaxDaughters);
1883}
1884
1885////////////////////////////////////////////////////////////////////////////////
1886/// Count the total number of nodes starting from a volume, nlevels down.
1887
1889{
1890 TGeoVolume *top;
1891 if (!vol) {
1892 top = fTopVolume;
1893 } else {
1894 top = (TGeoVolume *)vol;
1895 }
1896 Int_t count = top->CountNodes(nlevels, option);
1897 return count;
1898}
1899
1900////////////////////////////////////////////////////////////////////////////////
1901/// Set default angles for a given view.
1902
1904{
1905 if (fPainter)
1907}
1908
1909////////////////////////////////////////////////////////////////////////////////
1910/// Draw current point in the same view.
1911
1913{
1914 if (fPainter)
1915 fPainter->DrawCurrentPoint(color);
1916}
1917
1918////////////////////////////////////////////////////////////////////////////////
1919/// Draw animation of tracks
1920
1922{
1925 if (tmin < 0 || tmin >= tmax || nframes < 1)
1926 return;
1928 box[0] = box[1] = box[2] = 0;
1929 box[3] = box[4] = box[5] = 100;
1930 Double_t dt = (tmax - tmin) / Double_t(nframes);
1931 Double_t delt = 2E-9;
1932 Double_t t = tmin;
1933 Int_t i, j;
1934 TString opt(option);
1935 Bool_t save = kFALSE, geomanim = kFALSE;
1936 TString fname;
1937 if (opt.Contains("/S"))
1938 save = kTRUE;
1939
1940 if (opt.Contains("/G"))
1941 geomanim = kTRUE;
1942 SetTminTmax(0, 0);
1943 DrawTracks(opt.Data());
1944 Double_t start[6] = {0, 0, 0, 0, 0, 0};
1945 Double_t end[6] = {0, 0, 0, 0, 0, 0};
1946 Double_t dd[6] = {0, 0, 0, 0, 0, 0};
1947 Double_t dlat = 0, dlong = 0, dpsi = 0;
1948 if (geomanim) {
1949 fPainter->EstimateCameraMove(tmin + 5 * dt, tmin + 15 * dt, start, end);
1950 for (i = 0; i < 3; i++) {
1951 start[i + 3] = 20 + 1.3 * start[i + 3];
1952 end[i + 3] = 20 + 0.9 * end[i + 3];
1953 }
1954 for (i = 0; i < 6; i++) {
1955 dd[i] = (end[i] - start[i]) / 10.;
1956 }
1957 memcpy(box, start, 6 * sizeof(Double_t));
1959 dlong = (-206 - dlong) / Double_t(nframes);
1960 dlat = (126 - dlat) / Double_t(nframes);
1961 dpsi = (75 - dpsi) / Double_t(nframes);
1963 }
1964
1965 for (i = 0; i < nframes; i++) {
1966 if (t - delt < 0)
1967 SetTminTmax(t - delt, t);
1968 else
1969 gGeoManager->SetTminTmax(t - delt, t);
1970 if (geomanim) {
1971 for (j = 0; j < 6; j++)
1972 box[j] += dd[j];
1974 } else {
1975 ModifiedPad();
1976 }
1977 if (save) {
1978 fname = TString::Format("anim%04d.gif", i);
1979 gPad->Print(fname);
1980 }
1981 t += dt;
1982 }
1984}
1985
1986////////////////////////////////////////////////////////////////////////////////
1987/// Draw tracks over the geometry, according to option. By default, only
1988/// primaries are drawn. See TGeoTrack::Draw() for additional options.
1989
1991{
1993 // SetVisLevel(1);
1994 // SetVisOption(1);
1996 for (Int_t i = 0; i < fNtracks; i++) {
1997 track = GetTrack(i);
1998 if (track)
1999 track->Draw(option);
2000 }
2002 ModifiedPad();
2003}
2004
2005////////////////////////////////////////////////////////////////////////////////
2006/// Draw current path
2007
2008void TGeoManager::DrawPath(const char *path, Option_t *option)
2009{
2010 if (!fTopVolume)
2011 return;
2013 GetGeomPainter()->DrawPath(path, option);
2014}
2015
2016////////////////////////////////////////////////////////////////////////////////
2017/// Draw random points in the bounding box of a volume.
2018
2023
2024////////////////////////////////////////////////////////////////////////////////
2025/// Check time of finding "Where am I" for n points.
2026
2031
2032////////////////////////////////////////////////////////////////////////////////
2033/// Geometry overlap checker based on sampling.
2034
2035void TGeoManager::TestOverlaps(const char *path)
2036{
2038}
2039
2040////////////////////////////////////////////////////////////////////////////////
2041/// Fill volume names of current branch into an array.
2042
2044{
2046}
2047
2048////////////////////////////////////////////////////////////////////////////////
2049/// Get name for given pdg code;
2050
2052{
2053 static char defaultname[5] = {"XXX"};
2054 if (!fPdgNames || !pdg)
2055 return defaultname;
2056 for (Int_t i = 0; i < fNpdg; i++) {
2057 if (fPdgId[i] == pdg)
2058 return fPdgNames->At(i)->GetName();
2059 }
2060 return defaultname;
2061}
2062
2063////////////////////////////////////////////////////////////////////////////////
2064/// Set a name for a particle having a given pdg.
2065
2067{
2068 if (!pdg)
2069 return;
2070 if (!fPdgNames) {
2071 fPdgNames = new TObjArray(1024);
2072 }
2073 if (!strcmp(name, GetPdgName(pdg)))
2074 return;
2075 // store pdg name
2076 if (fNpdg > 1023) {
2077 Warning("SetPdgName", "No more than 256 different pdg codes allowed");
2078 return;
2079 }
2080 fPdgId[fNpdg] = pdg;
2081 TNamed *pdgname = new TNamed(name, "");
2083}
2084
2085////////////////////////////////////////////////////////////////////////////////
2086/// Get GDML matrix with a given name;
2087
2089{
2091}
2092
2093////////////////////////////////////////////////////////////////////////////////
2094/// Add GDML matrix;
2096{
2097 if (GetGDMLMatrix(mat->GetName())) {
2098 Error("AddGDMLMatrix", "Matrix %s already added to manager", mat->GetName());
2099 return;
2100 }
2102}
2103
2104////////////////////////////////////////////////////////////////////////////////
2105/// Get optical surface with a given name;
2106
2111
2112////////////////////////////////////////////////////////////////////////////////
2113/// Add optical surface;
2115{
2116 if (GetOpticalSurface(optsurf->GetName())) {
2117 Error("AddOpticalSurface", "Surface %s already added to manager", optsurf->GetName());
2118 return;
2119 }
2121}
2122
2123////////////////////////////////////////////////////////////////////////////////
2124/// Get skin surface with a given name;
2125
2130
2131////////////////////////////////////////////////////////////////////////////////
2132/// Add skin surface;
2134{
2135 if (GetSkinSurface(surf->GetName())) {
2136 Error("AddSkinSurface", "Surface %s already added to manager", surf->GetName());
2137 return;
2138 }
2140}
2141
2142////////////////////////////////////////////////////////////////////////////////
2143/// Get border surface with a given name;
2144
2149
2150////////////////////////////////////////////////////////////////////////////////
2151/// Add border surface;
2153{
2154 if (GetBorderSurface(surf->GetName())) {
2155 Error("AddBorderSurface", "Surface %s already added to manager", surf->GetName());
2156 return;
2157 }
2159}
2160
2161////////////////////////////////////////////////////////////////////////////////
2162/// Fill node copy numbers of current branch into an array.
2163
2168
2169////////////////////////////////////////////////////////////////////////////////
2170/// Fill node copy numbers of current branch into an array.
2171
2176
2177////////////////////////////////////////////////////////////////////////////////
2178/// Retrieve cartesian and radial bomb factors.
2179
2181{
2182 if (fPainter) {
2184 return;
2185 }
2186 bombx = bomby = bombz = bombr = 1.3;
2187}
2188
2189////////////////////////////////////////////////////////////////////////////////
2190/// Return maximum number of daughters of a volume used in the geometry.
2191
2196
2197////////////////////////////////////////////////////////////////////////////////
2198/// Return maximum number of levels used in the geometry.
2199
2201{
2202 return fgMaxLevel;
2203}
2204
2205////////////////////////////////////////////////////////////////////////////////
2206/// Return maximum number of vertices for an xtru shape used.
2207
2212
2213////////////////////////////////////////////////////////////////////////////////
2214/// Returns number of threads that were set to use geometry.
2215
2220
2221////////////////////////////////////////////////////////////////////////////////
2222/// Return stored current matrix (global matrix of the next touched node).
2223
2225{
2226 if (!GetCurrentNavigator())
2227 return nullptr;
2228 return GetCurrentNavigator()->GetHMatrix();
2229}
2230
2231////////////////////////////////////////////////////////////////////////////////
2232/// Returns current depth to which geometry is drawn.
2233
2235{
2236 return fVisLevel;
2237}
2238
2239////////////////////////////////////////////////////////////////////////////////
2240/// Returns current depth to which geometry is drawn.
2241
2243{
2244 return fVisOption;
2245}
2246
2247////////////////////////////////////////////////////////////////////////////////
2248/// Find level of virtuality of current overlapping node (number of levels
2249/// up having the same tracking media.
2250
2255
2256////////////////////////////////////////////////////////////////////////////////
2257/// Search the track hierarchy to find the track with the
2258/// given id
2259///
2260/// if 'primsFirst' is true, then:
2261/// first tries TGeoManager::GetTrackOfId, then does a
2262/// recursive search if that fails. this would be faster
2263/// if the track is somehow known to be a primary
2264
2266{
2267 TVirtualGeoTrack *trk = nullptr;
2268 trk = GetTrackOfId(id);
2269 if (trk)
2270 return trk;
2271 // need recursive search
2272 TIter next(fTracks);
2274 while ((prim = (TVirtualGeoTrack *)next())) {
2275 trk = prim->FindTrackWithId(id);
2276 if (trk)
2277 return trk;
2278 }
2279 return nullptr;
2280}
2281
2282////////////////////////////////////////////////////////////////////////////////
2283/// Get track with a given ID.
2284
2286{
2288 for (Int_t i = 0; i < fNtracks; i++) {
2289 if ((track = (TVirtualGeoTrack *)fTracks->UncheckedAt(i))) {
2290 if (track->GetId() == id)
2291 return track;
2292 }
2293 }
2294 return nullptr;
2295}
2296
2297////////////////////////////////////////////////////////////////////////////////
2298/// Get parent track with a given ID.
2299
2301{
2303 while ((track = track->GetMother())) {
2304 if (track->GetId() == id)
2305 return track;
2306 }
2307 return nullptr;
2308}
2309
2310////////////////////////////////////////////////////////////////////////////////
2311/// Get index for track id, -1 if not found.
2312
2314{
2316 for (Int_t i = 0; i < fNtracks; i++) {
2317 if ((track = (TVirtualGeoTrack *)fTracks->UncheckedAt(i))) {
2318 if (track->GetId() == id)
2319 return i;
2320 }
2321 }
2322 return -1;
2323}
2324
2325////////////////////////////////////////////////////////////////////////////////
2326/// Go upwards the tree until a non-overlapping node
2327
2332
2333////////////////////////////////////////////////////////////////////////////////
2334/// Go upwards the tree until a non-overlapping node
2335
2340
2341////////////////////////////////////////////////////////////////////////////////
2342/// Set default volume colors according to A of material
2343///
2344/// If called with no argument, it uses the new default "natural" scheme
2345/// (including name-based material overrides) and falls back to Z-binned colors.
2346
2348{
2350 const TGeoColorScheme *scheme = cs ? cs : &defaultCS;
2351
2352 TGeoVolume *vol = nullptr;
2353 TIter next(fVolumes);
2354
2355 while ((vol = (TGeoVolume *)next())) {
2356 // Ask scheme for a color (>=0 means "use it")
2357 const Int_t c = scheme->Color(vol);
2358 if (c >= 0)
2359 vol->SetLineColor(c);
2360
2361 // Ask scheme for transparency ([0..100] means "use it")
2362 const Int_t t = scheme->Transparency(vol);
2363 if (t >= 0)
2364 vol->SetTransparency(t);
2365 }
2366 ModifiedPad();
2367}
2368
2369////////////////////////////////////////////////////////////////////////////////
2370/// Compute safe distance from the current point. This represent the distance
2371/// from POINT to the closest boundary.
2372
2374{
2375 return GetCurrentNavigator()->Safety(inside);
2376}
2377
2378////////////////////////////////////////////////////////////////////////////////
2379/// Set volume attributes in G3 style.
2380
2381void TGeoManager::SetVolumeAttribute(const char *name, const char *att, Int_t val)
2382{
2383 TGeoVolume *volume;
2384 Bool_t all = kFALSE;
2385 if (strstr(name, "*"))
2386 all = kTRUE;
2387 Int_t ivo = 0;
2388 TIter next(fVolumes);
2389 TString chatt = att;
2390 chatt.ToLower();
2391 while ((volume = (TGeoVolume *)next())) {
2392 if (strcmp(volume->GetName(), name) && !all)
2393 continue;
2394 ivo++;
2395 if (chatt.Contains("colo"))
2396 volume->SetLineColor(val);
2397 if (chatt.Contains("lsty"))
2398 volume->SetLineStyle(val);
2399 if (chatt.Contains("lwid"))
2400 volume->SetLineWidth(val);
2401 if (chatt.Contains("fill"))
2402 volume->SetFillColor(val);
2403 if (chatt.Contains("seen"))
2404 volume->SetVisibility(val);
2405 }
2407 while ((volume = (TGeoVolume *)next1())) {
2408 if (strcmp(volume->GetName(), name) && !all)
2409 continue;
2410 ivo++;
2411 if (chatt.Contains("colo"))
2412 volume->SetLineColor(val);
2413 if (chatt.Contains("lsty"))
2414 volume->SetLineStyle(val);
2415 if (chatt.Contains("lwid"))
2416 volume->SetLineWidth(val);
2417 if (chatt.Contains("fill"))
2418 volume->SetFillColor(val);
2419 if (chatt.Contains("seen"))
2420 volume->SetVisibility(val);
2421 }
2422 if (!ivo) {
2423 Warning("SetVolumeAttribute", "volume: %s does not exist", name);
2424 }
2425}
2426
2427////////////////////////////////////////////////////////////////////////////////
2428/// Set factors that will "bomb" all translations in cartesian and cylindrical coordinates.
2429
2435
2436////////////////////////////////////////////////////////////////////////////////
2437/// Set a user-defined shape as clipping for ray tracing.
2438
2440{
2442 if (shape) {
2443 if (fClippingShape && (fClippingShape != shape))
2445 fClippingShape = shape;
2446 }
2447 painter->SetClippingShape(shape);
2448}
2449
2450////////////////////////////////////////////////////////////////////////////////
2451/// set the maximum number of visible nodes.
2452
2454{
2456 if (maxnodes > 0 && fgVerboseLevel > 0)
2457 Info("SetMaxVisNodes", "Automatic visible depth for %d visible nodes", maxnodes);
2458 if (!fPainter)
2459 return;
2461 Int_t level = fPainter->GetVisLevel();
2462 if (level != fVisLevel)
2463 fVisLevel = level;
2464}
2465
2466////////////////////////////////////////////////////////////////////////////////
2467/// make top volume visible on screen
2468
2474
2475////////////////////////////////////////////////////////////////////////////////
2476/// Assign a given node to be checked for overlaps. Any other overlaps will be ignored.
2477
2482
2483////////////////////////////////////////////////////////////////////////////////
2484/// Set the number of points to be generated on the shape outline when checking
2485/// for overlaps.
2486
2491
2492////////////////////////////////////////////////////////////////////////////////
2493/// set drawing mode :
2494/// - option=0 (default) all nodes drawn down to vislevel
2495/// - option=1 leaves and nodes at vislevel drawn
2496/// - option=2 path is drawn
2497/// - option=4 visibility changed
2498
2500{
2501 if ((option >= 0) && (option < 3))
2503 if (fPainter)
2505}
2506
2507////////////////////////////////////////////////////////////////////////////////
2508/// Set visualization option (leaves only OR all volumes)
2509
2511{
2512 if (flag)
2513 SetVisOption(1);
2514 else
2515 SetVisOption(0);
2516}
2517
2518////////////////////////////////////////////////////////////////////////////////
2519/// Set density threshold. Volumes with densities lower than this become
2520/// transparent.
2521
2528
2529////////////////////////////////////////////////////////////////////////////////
2530/// set default level down to which visualization is performed
2531
2533{
2534 if (level > 0) {
2535 fVisLevel = level;
2536 fMaxVisNodes = 0;
2537 if (fgVerboseLevel > 0)
2538 Info("SetVisLevel", "Automatic visible depth disabled");
2539 if (fPainter)
2541 } else {
2543 }
2544}
2545
2546////////////////////////////////////////////////////////////////////////////////
2547/// Sort overlaps by decreasing overlap distance. Extrusions comes first.
2548
2550{
2551 fOverlaps->Sort();
2552}
2553
2554////////////////////////////////////////////////////////////////////////////////
2555/// Optimize voxelization type for all volumes. Save best choice in a macro.
2556
2558{
2559 if (!fTopNode) {
2560 Error("OptimizeVoxels", "Geometry must be closed first");
2561 return;
2562 }
2563 std::ofstream out;
2565 if (fname.IsNull())
2566 fname = "tgeovox.C";
2567 out.open(fname, std::ios::out);
2568 if (!out.good()) {
2569 Error("OptimizeVoxels", "cannot open file");
2570 return;
2571 }
2572 // write header
2573 TDatime t;
2575 sname.ReplaceAll(".C", "");
2576 out << sname.Data() << "()" << std::endl;
2577 out << "{" << std::endl;
2578 out << "//=== Macro generated by ROOT version " << gROOT->GetVersion() << " : " << t.AsString() << std::endl;
2579 out << "//=== Voxel optimization for " << GetTitle() << " geometry" << std::endl;
2580 out << "//===== <run this macro JUST BEFORE closing the geometry>" << std::endl;
2581 out << " TGeoVolume *vol = 0;" << std::endl;
2582 out << " // parse all voxelized volumes" << std::endl;
2583 TGeoVolume *vol = nullptr;
2585 TIter next(fVolumes);
2586 while ((vol = (TGeoVolume *)next())) {
2587 if (!vol->GetVoxels())
2588 continue;
2589 out << " vol = gGeoManager->GetVolume(\"" << vol->GetName() << "\");" << std::endl;
2590 cyltype = vol->OptimizeVoxels();
2591 if (cyltype) {
2592 out << " vol->SetCylVoxels();" << std::endl;
2593 } else {
2594 out << " vol->SetCylVoxels(kFALSE);" << std::endl;
2595 }
2596 }
2597 out << "}" << std::endl;
2598 out.close();
2599}
2600////////////////////////////////////////////////////////////////////////////////
2601/// Parse a string boolean expression and do a syntax check. Find top
2602/// level boolean operator and returns its type. Fill the two
2603/// substrings to which this operator applies. The returned integer is :
2604/// - -1 : parse error
2605/// - 0 : no boolean operator
2606/// - 1 : union - represented as '+' in expression
2607/// - 2 : difference (subtraction) - represented as '-' in expression
2608/// - 3 : intersection - represented as '*' in expression.
2609/// Parentheses should be used to avoid ambiguities. For instance :
2610/// - A+B-C will be interpreted as (A+B)-C which is not the same as A+(B-C)
2611/// eliminate not needed parentheses
2612
2614{
2616 Int_t len = startstr.Length();
2617 Int_t i;
2618 TString e0 = "";
2619 expr3 = "";
2620 // eliminate blanks
2621 for (i = 0; i < len; i++) {
2622 if (startstr(i) == ' ')
2623 continue;
2624 e0 += startstr(i, 1);
2625 }
2626 Int_t level = 0;
2627 Int_t levmin = 999;
2628 Int_t boolop = 0;
2629 Int_t indop = 0;
2630 Int_t iloop = 1;
2631 Int_t lastop = 0;
2632 Int_t lastdp = 0;
2633 Int_t lastpp = 0;
2635 // check/eliminate parentheses
2636 while (iloop == 1) {
2637 iloop = 0;
2638 lastop = 0;
2639 lastdp = 0;
2640 lastpp = 0;
2641 len = e0.Length();
2642 for (i = 0; i < len; i++) {
2643 if (e0(i) == '(') {
2644 if (!level)
2645 iloop++;
2646 level++;
2647 continue;
2648 }
2649 if (e0(i) == ')') {
2650 level--;
2651 if (level == 0)
2652 lastpp = i;
2653 continue;
2654 }
2655 if ((e0(i) == '+') || (e0(i) == '-') || (e0(i) == '*')) {
2656 lastop = i;
2657 if (level < levmin) {
2658 levmin = level;
2659 indop = i;
2660 }
2661 continue;
2662 }
2663 if ((e0(i) == ':') && (level == 0)) {
2664 lastdp = i;
2665 continue;
2666 }
2667 }
2668 if (level != 0) {
2669 if (gGeoManager)
2670 gGeoManager->Error("Parse", "parentheses does not match");
2671 return -1;
2672 }
2673 if (iloop == 1 && (e0(0) == '(') && (e0(len - 1) == ')')) {
2674 // eliminate extra parentheses
2675 e0 = e0(1, len - 2);
2676 continue;
2677 }
2678 if (foundmat)
2679 break;
2680 if (((lastop == 0) && (lastdp > 0)) || ((lastpp > 0) && (lastdp > lastpp) && (indop < lastpp))) {
2681 expr3 = e0(lastdp + 1, len - lastdp);
2682 e0 = e0(0, lastdp);
2683 foundmat = kTRUE;
2684 iloop = 1;
2685 continue;
2686 } else
2687 break;
2688 }
2689 // loop expression and search parentheses/operators
2690 levmin = 999;
2691 for (i = 0; i < len; i++) {
2692 if (e0(i) == '(') {
2693 level++;
2694 continue;
2695 }
2696 if (e0(i) == ')') {
2697 level--;
2698 continue;
2699 }
2700 // Take LAST operator at lowest level (revision 28/07/08)
2701 if (level <= levmin) {
2702 if (e0(i) == '+') {
2703 boolop = 1; // union
2704 levmin = level;
2705 indop = i;
2706 }
2707 if (e0(i) == '-') {
2708 boolop = 2; // difference
2709 levmin = level;
2710 indop = i;
2711 }
2712 if (e0(i) == '*') {
2713 boolop = 3; // intersection
2714 levmin = level;
2715 indop = i;
2716 }
2717 }
2718 }
2719 if (indop == 0) {
2720 expr1 = e0;
2721 return indop;
2722 }
2723 expr1 = e0(0, indop);
2724 expr2 = e0(indop + 1, len - indop);
2725 return boolop;
2726}
2727
2728////////////////////////////////////////////////////////////////////////////////
2729/// Save current attributes in a macro
2730
2732{
2733 if (!fTopNode) {
2734 Error("SaveAttributes", "geometry must be closed first\n");
2735 return;
2736 }
2737 std::ofstream out;
2739 if (fname.IsNull())
2740 fname = "tgeoatt.C";
2741 out.open(fname, std::ios::out);
2742 if (!out.good()) {
2743 Error("SaveAttributes", "cannot open file");
2744 return;
2745 }
2746 // write header
2747 TDatime t;
2749 sname.ReplaceAll(".C", "");
2750 out << sname.Data() << "()" << std::endl;
2751 out << "{" << std::endl;
2752 out << "//=== Macro generated by ROOT version " << gROOT->GetVersion() << " : " << t.AsString() << std::endl;
2753 out << "//=== Attributes for " << GetTitle() << " geometry" << std::endl;
2754 out << "//===== <run this macro AFTER loading the geometry in memory>" << std::endl;
2755 // save current top volume
2756 out << " TGeoVolume *top = gGeoManager->GetVolume(\"" << fTopVolume->GetName() << "\");" << std::endl;
2757 out << " TGeoVolume *vol = 0;" << std::endl;
2758 out << " TGeoNode *node = 0;" << std::endl;
2759 out << " // clear all volume attributes and get painter" << std::endl;
2760 out << " gGeoManager->ClearAttributes();" << std::endl;
2761 out << " gGeoManager->GetGeomPainter();" << std::endl;
2762 out << " // set visualization modes and bomb factors" << std::endl;
2763 out << " gGeoManager->SetVisOption(" << GetVisOption() << ");" << std::endl;
2764 out << " gGeoManager->SetVisLevel(" << GetVisLevel() << ");" << std::endl;
2765 out << " gGeoManager->SetExplodedView(" << GetBombMode() << ");" << std::endl;
2768 out << " gGeoManager->SetBombFactors(" << bombx << "," << bomby << "," << bombz << "," << bombr << ");"
2769 << std::endl;
2770 out << " // iterate volumes container and set new attributes" << std::endl;
2771 // out << " TIter next(gGeoManager->GetListOfVolumes());"<<std::endl;
2772 TGeoVolume *vol = nullptr;
2774
2775 TIter next(fVolumes);
2776 while ((vol = (TGeoVolume *)next())) {
2777 vol->SetVisStreamed(kFALSE);
2778 }
2779 out << " // draw top volume with new settings" << std::endl;
2780 out << " top->Draw();" << std::endl;
2781 out << "}" << std::endl;
2782 out.close();
2783}
2784
2785////////////////////////////////////////////////////////////////////////////////
2786/// Returns the deepest node containing fPoint, which must be set a priori.
2787
2792
2793////////////////////////////////////////////////////////////////////////////////
2794/// Cross next boundary and locate within current node
2795/// The current point must be on the boundary of fCurrentNode.
2796
2801
2802////////////////////////////////////////////////////////////////////////////////
2803/// Compute distance to next boundary within STEPMAX. If no boundary is found,
2804/// propagate current point along current direction with fStep=STEPMAX. Otherwise
2805/// propagate with fStep=SNEXT (distance to boundary) and locate/return the next
2806/// node.
2807
2812
2813////////////////////////////////////////////////////////////////////////////////
2814/// Find distance to next boundary and store it in fStep. Returns node to which this
2815/// boundary belongs. If PATH is specified, compute only distance to the node to which
2816/// PATH points. If STEPMAX is specified, compute distance only in case fSafety is smaller
2817/// than this value. STEPMAX represent the step to be made imposed by other reasons than
2818/// geometry (usually physics processes). Therefore in this case this method provides the
2819/// answer to the question : "Is STEPMAX a safe step ?" returning a NULL node and filling
2820/// fStep with a big number.
2821/// In case frombdr=kTRUE, the isotropic safety is set to zero.
2822///
2823/// Note : safety distance for the current point is computed ONLY in case STEPMAX is
2824/// specified, otherwise users have to call explicitly TGeoManager::Safety() if
2825/// they want this computed for the current point.
2826
2828{
2829 // convert current point and direction to local reference
2831}
2832
2833////////////////////////////////////////////////////////////////////////////////
2834/// Computes as fStep the distance to next daughter of the current volume.
2835/// The point and direction must be converted in the coordinate system of the current volume.
2836/// The proposed step limit is fStep.
2837
2842
2843////////////////////////////////////////////////////////////////////////////////
2844/// Reset current state flags.
2845
2850
2851////////////////////////////////////////////////////////////////////////////////
2852/// Returns deepest node containing current point.
2853
2858
2859////////////////////////////////////////////////////////////////////////////////
2860/// Returns deepest node containing current point.
2861
2866
2867////////////////////////////////////////////////////////////////////////////////
2868/// Computes fast normal to next crossed boundary, assuming that the current point
2869/// is close enough to the boundary. Works only after calling FindNextBoundary.
2870
2875
2876////////////////////////////////////////////////////////////////////////////////
2877/// Computes normal vector to the next surface that will be or was already
2878/// crossed when propagating on a straight line from a given point/direction.
2879/// Returns the normal vector cosines in the MASTER coordinate system. The dot
2880/// product of the normal and the current direction is positive defined.
2881
2883{
2884 return GetCurrentNavigator()->FindNormal(forward);
2885}
2886
2887////////////////////////////////////////////////////////////////////////////////
2888/// Checks if point (x,y,z) is still in the current node.
2889
2894
2895////////////////////////////////////////////////////////////////////////////////
2896/// Check if a new point with given coordinates is the same as the last located one.
2897
2902
2903////////////////////////////////////////////////////////////////////////////////
2904/// True if current node is in phi range
2905
2907{
2908 if (!fPhiCut)
2909 return kTRUE;
2910 const Double_t *origin;
2912 return kFALSE;
2913 origin = ((TGeoBBox *)GetCurrentNavigator()->GetCurrentVolume()->GetShape())->GetOrigin();
2914 Double_t point[3];
2915 LocalToMaster(origin, &point[0]);
2916 Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
2917 if (phi < 0)
2918 phi += 360.;
2919 if ((phi >= fPhimin) && (phi <= fPhimax))
2920 return kFALSE;
2921 return kTRUE;
2922}
2923
2924////////////////////////////////////////////////////////////////////////////////
2925/// Initialize current point and current direction vector (normalized)
2926/// in MARS. Return corresponding node.
2927
2929{
2930 return GetCurrentNavigator()->InitTrack(point, dir);
2931}
2932
2933////////////////////////////////////////////////////////////////////////////////
2934/// Initialize current point and current direction vector (normalized)
2935/// in MARS. Return corresponding node.
2936
2941
2942////////////////////////////////////////////////////////////////////////////////
2943/// Inspects path and all flags for the current state.
2944
2949
2950////////////////////////////////////////////////////////////////////////////////
2951/// Get path to the current node in the form /node0/node1/...
2952
2953const char *TGeoManager::GetPath() const
2954{
2955 return GetCurrentNavigator()->GetPath();
2956}
2957
2958////////////////////////////////////////////////////////////////////////////////
2959/// Get total size of geometry in bytes.
2960
2962{
2963 Int_t count = 0;
2964 TIter next(fVolumes);
2965 TGeoVolume *vol;
2966 while ((vol = (TGeoVolume *)next()))
2967 count += vol->GetByteCount();
2970 while ((matrix = (TGeoMatrix *)next1()))
2971 count += matrix->GetByteCount();
2974 while ((mat = (TGeoMaterial *)next2()))
2975 count += mat->GetByteCount();
2977 TGeoMedium *med;
2978 while ((med = (TGeoMedium *)next3()))
2979 count += med->GetByteCount();
2980 if (fgVerboseLevel > 0)
2981 Info("GetByteCount", "Total size of logical tree : %i bytes", count);
2982 return count;
2983}
2984
2985////////////////////////////////////////////////////////////////////////////////
2986/// Make a default painter if none present. Returns pointer to it.
2987
2989{
2990 if (!fPainter) {
2991 const char *kind = nullptr;
2992 if (gPad)
2993 kind = gPad->IsWeb() ? "web" : "root";
2994 else
2995 kind = gEnv->GetValue("GeomPainter.Name", "");
2996
2997 if (!kind || !*kind)
2998 kind = (gROOT->IsWebDisplay() && !gROOT->IsWebDisplayBatch()) ? "web" : "root";
2999
3000 if (auto h = gROOT->GetPluginManager()->FindHandler("TVirtualGeoPainter", kind)) {
3001 if (h->LoadPlugin() == -1) {
3002 Error("GetGeomPainter", "could not load plugin for %s geo_painter", kind);
3003 return nullptr;
3004 }
3005 fPainter = (TVirtualGeoPainter *)h->ExecPlugin(1, this);
3006 if (!fPainter) {
3007 Error("GetGeomPainter", "could not create %s geo_painter", kind);
3008 return nullptr;
3009 }
3010 } else {
3011 Error("GetGeomPainter", "not found plugin %s for geo_painter", kind);
3012 }
3013 }
3014 return fPainter;
3015}
3016
3017////////////////////////////////////////////////////////////////////////////////
3018/// Make a default checker if none present. Returns pointer to it.
3019
3021{
3022 if (!fChecker) {
3023 if (auto h = gROOT->GetPluginManager()->FindHandler("TVirtualGeoChecker", "root")) {
3024 if (h->LoadPlugin() == -1) {
3025 Error("GetGeomChecker", "could not load plugin for geo_checker");
3026 return nullptr;
3027 }
3028 fChecker = (TVirtualGeoChecker *)h->ExecPlugin(1, this);
3029 if (!fChecker) {
3030 Error("GetGeomChecker", "could not create geo_checker");
3031 return nullptr;
3032 }
3033 } else {
3034 Error("GetGeomChecker", "not found plugin for geo_checker");
3035 }
3036 }
3037 return fChecker;
3038}
3039
3040////////////////////////////////////////////////////////////////////////////////
3041/// Search for a named volume. All trailing blanks stripped.
3042
3044{
3045 TString sname = name;
3046 sname = sname.Strip();
3047 TGeoVolume *vol = (TGeoVolume *)fVolumes->FindObject(sname.Data());
3048 return vol;
3049}
3050
3051////////////////////////////////////////////////////////////////////////////////
3052/// Fast search for a named volume. All trailing blanks stripped.
3053
3055{
3056 if (!fHashVolumes) {
3059 fHashVolumes = new THashList(nvol + 1, 3);
3060 fHashGVolumes = new THashList(ngvol + 1, 3);
3061 Int_t i;
3062 for (i = 0; i < ngvol; i++)
3064 for (i = 0; i < nvol; i++)
3066 }
3067 TString sname = name;
3068 sname = sname.Strip();
3069 THashList *list = fHashVolumes;
3070 if (multi)
3071 list = fHashGVolumes;
3072 TGeoVolume *vol = (TGeoVolume *)list->FindObject(sname.Data());
3073 return vol;
3074}
3075
3076////////////////////////////////////////////////////////////////////////////////
3077/// Retrieve unique id for a volume name. Return -1 if name not found.
3078
3080{
3081 TGeoManager *geom = (TGeoManager *)this;
3082 TGeoVolume *vol = geom->FindVolumeFast(volname, kFALSE);
3083 if (!vol)
3084 vol = geom->FindVolumeFast(volname, kTRUE);
3085 if (!vol)
3086 return -1;
3087 return vol->GetNumber();
3088}
3089
3090////////////////////////////////////////////////////////////////////////////////
3091/// Find if a given material duplicates an existing one.
3092
3094{
3096 if (index <= 0)
3097 return nullptr;
3099 for (Int_t i = 0; i < index; i++) {
3101 if (other == mat)
3102 continue;
3103 if (other->IsEq(mat))
3104 return other;
3105 }
3106 return nullptr;
3107}
3108
3109////////////////////////////////////////////////////////////////////////////////
3110/// Search for a named material. All trailing blanks stripped.
3111
3113{
3115 sname = sname.Strip();
3117 return mat;
3118}
3119
3120////////////////////////////////////////////////////////////////////////////////
3121/// Search for a named tracking medium. All trailing blanks stripped.
3122
3124{
3126 sname = sname.Strip();
3128 return med;
3129}
3130
3131////////////////////////////////////////////////////////////////////////////////
3132/// Search for a tracking medium with a given ID.
3133
3135{
3136 TIter next(fMedia);
3137 TGeoMedium *med;
3138 while ((med = (TGeoMedium *)next())) {
3139 if (med->GetId() == numed)
3140 return med;
3141 }
3142 return nullptr;
3143}
3144
3145////////////////////////////////////////////////////////////////////////////////
3146/// Return material at position id.
3147
3149{
3151 return nullptr;
3153 return mat;
3154}
3155
3156////////////////////////////////////////////////////////////////////////////////
3157/// Return index of named material.
3158
3160{
3161 TIter next(fMaterials);
3163 Int_t id = 0;
3165 sname = sname.Strip();
3166 while ((mat = (TGeoMaterial *)next())) {
3167 if (!strcmp(mat->GetName(), sname.Data()))
3168 return id;
3169 id++;
3170 }
3171 return -1; // fail
3172}
3173
3174////////////////////////////////////////////////////////////////////////////////
3175/// Randomly shoot nrays and plot intersections with surfaces for current
3176/// top node.
3177
3183
3184////////////////////////////////////////////////////////////////////////////////
3185/// Remove material at given index.
3186
3188{
3189 TObject *obj = fMaterials->At(index);
3190 if (obj)
3191 fMaterials->Remove(obj);
3192}
3193
3194////////////////////////////////////////////////////////////////////////////////
3195/// Sets all pointers TGeoVolume::fField to NULL. User data becomes decoupled
3196/// from geometry. Deletion has to be managed by users.
3197
3199{
3200 TIter next(fVolumes);
3201 TGeoVolume *vol;
3202 while ((vol = (TGeoVolume *)next()))
3203 vol->SetField(nullptr);
3204}
3205
3206////////////////////////////////////////////////////////////////////////////////
3207/// Change raytracing mode.
3208
3215
3216////////////////////////////////////////////////////////////////////////////////
3217/// Restore the master volume of the geometry.
3218
3220{
3222 return;
3223 if (fMasterVolume)
3225}
3226
3227////////////////////////////////////////////////////////////////////////////////
3228/// Voxelize all non-divided volumes.
3229
3231{
3232 TGeoVolume *vol;
3233 // TGeoVoxelFinder *vox = 0;
3234 if (!fStreamVoxels && fgVerboseLevel > 0)
3235 Info("Voxelize", "Voxelizing...");
3236 // Int_t nentries = fVolumes->GetSize();
3237 TIter next(fVolumes);
3238 while ((vol = (TGeoVolume *)next())) {
3239 if (!fIsGeomReading)
3240 vol->SortNodes();
3241 if (!fStreamVoxels) {
3242 vol->Voxelize(option);
3243 }
3244 if (!fIsGeomReading)
3245 vol->FindOverlaps();
3246 }
3247}
3248
3249////////////////////////////////////////////////////////////////////////////////
3250/// Send "Modified" signal to painter.
3251
3253{
3254 if (!fPainter)
3255 return;
3257}
3258
3259////////////////////////////////////////////////////////////////////////////////
3260/// Make an TGeoArb8 volume.
3261
3263{
3264 return TGeoBuilder::Instance(this)->MakeArb8(name, medium, dz, vertices);
3265}
3266
3267////////////////////////////////////////////////////////////////////////////////
3268/// Make in one step a volume pointing to a box shape with given medium.
3269
3274
3275////////////////////////////////////////////////////////////////////////////////
3276/// Make in one step a volume pointing to a parallelepiped shape with given medium.
3277
3279 Double_t alpha, Double_t theta, Double_t phi)
3280{
3281 return TGeoBuilder::Instance(this)->MakePara(name, medium, dx, dy, dz, alpha, theta, phi);
3282}
3283
3284////////////////////////////////////////////////////////////////////////////////
3285/// Make in one step a volume pointing to a sphere shape with given medium
3286
3292
3293////////////////////////////////////////////////////////////////////////////////
3294/// Make in one step a volume pointing to a torus shape with given medium.
3295
3301
3302////////////////////////////////////////////////////////////////////////////////
3303/// Make in one step a volume pointing to a tube shape with given medium.
3304
3309
3310////////////////////////////////////////////////////////////////////////////////
3311/// Make in one step a volume pointing to a tube segment shape with given medium.
3312/// The segment will be from phiStart to phiEnd, the angles are expressed in degree
3313
3319
3320////////////////////////////////////////////////////////////////////////////////
3321/// Make in one step a volume pointing to a tube shape with given medium
3322
3324{
3325 return TGeoBuilder::Instance(this)->MakeEltu(name, medium, a, b, dz);
3326}
3327
3328////////////////////////////////////////////////////////////////////////////////
3329/// Make in one step a volume pointing to a tube shape with given medium
3330
3336
3337////////////////////////////////////////////////////////////////////////////////
3338/// Make in one step a volume pointing to a tube shape with given medium
3339
3344
3345////////////////////////////////////////////////////////////////////////////////
3346/// Make in one step a volume pointing to a tube segment shape with given medium
3347
3354
3355////////////////////////////////////////////////////////////////////////////////
3356/// Make in one step a volume pointing to a cone shape with given medium.
3357
3363
3364////////////////////////////////////////////////////////////////////////////////
3365/// Make in one step a volume pointing to a cone segment shape with given medium
3366
3372
3373////////////////////////////////////////////////////////////////////////////////
3374/// Make in one step a volume pointing to a polycone shape with given medium.
3375
3377{
3378 return TGeoBuilder::Instance(this)->MakePcon(name, medium, phi, dphi, nz);
3379}
3380
3381////////////////////////////////////////////////////////////////////////////////
3382/// Make in one step a volume pointing to a polygone shape with given medium.
3383
3384TGeoVolume *
3386{
3387 return TGeoBuilder::Instance(this)->MakePgon(name, medium, phi, dphi, nedges, nz);
3388}
3389
3390////////////////////////////////////////////////////////////////////////////////
3391/// Make in one step a volume pointing to a TGeoTrd1 shape with given medium.
3392
3393TGeoVolume *
3398
3399////////////////////////////////////////////////////////////////////////////////
3400/// Make in one step a volume pointing to a TGeoTrd2 shape with given medium.
3401
3407
3408////////////////////////////////////////////////////////////////////////////////
3409/// Make in one step a volume pointing to a trapezoid shape with given medium.
3410
3414{
3415 return TGeoBuilder::Instance(this)->MakeTrap(name, medium, dz, theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2,
3416 alpha2);
3417}
3418
3419////////////////////////////////////////////////////////////////////////////////
3420/// Make in one step a volume pointing to a twisted trapezoid shape with given medium.
3421
3429
3430////////////////////////////////////////////////////////////////////////////////
3431/// Make a TGeoXtru-shaped volume with nz planes
3432
3434{
3435 return TGeoBuilder::Instance(this)->MakeXtru(name, medium, nz);
3436}
3437
3438////////////////////////////////////////////////////////////////////////////////
3439/// Creates an alignable object with unique name corresponding to a path
3440/// and adds it to the list of alignables. An optional unique ID can be
3441/// provided, in which case PN entries can be searched fast by uid.
3442
3444{
3445 if (!CheckPath(path))
3446 return nullptr;
3447 if (!fHashPNE)
3448 fHashPNE = new THashList(256, 3);
3449 if (!fArrayPNE)
3450 fArrayPNE = new TObjArray(256);
3452 if (entry) {
3453 Error("SetAlignableEntry", "An alignable object with name %s already existing. NOT ADDED !", unique_name);
3454 return nullptr;
3455 }
3456 entry = new TGeoPNEntry(unique_name, path);
3458 fHashPNE->Add(entry);
3460 if (uid >= 0) {
3462 if (!added)
3463 Error("SetAlignableEntry", "A PN entry: has already uid=%i", uid);
3464 }
3465 return entry;
3466}
3467
3468////////////////////////////////////////////////////////////////////////////////
3469/// Retrieves an existing alignable object.
3470
3472{
3473 if (!fHashPNE)
3474 return nullptr;
3475 return (TGeoPNEntry *)fHashPNE->FindObject(name);
3476}
3477
3478////////////////////////////////////////////////////////////////////////////////
3479/// Retrieves an existing alignable object at a given index.
3480
3482{
3483 if (!fArrayPNE && !InitArrayPNE())
3484 return nullptr;
3485 return (TGeoPNEntry *)fArrayPNE->At(index);
3486}
3487
3488////////////////////////////////////////////////////////////////////////////////
3489/// Retrieves an existing alignable object having a preset UID.
3490
3492{
3493 if (!fNPNEId || (!fArrayPNE && !InitArrayPNE()))
3494 return nullptr;
3496 if (index < 0 || fKeyPNEId[index] != uid)
3497 return nullptr;
3499}
3500
3501////////////////////////////////////////////////////////////////////////////////
3502/// Retrieves number of PN entries with or without UID.
3503
3505{
3506 if (!fHashPNE)
3507 return 0;
3508 if (with_uid)
3509 return fNPNEId;
3510 return fHashPNE->GetSize();
3511}
3512
3513////////////////////////////////////////////////////////////////////////////////
3514/// Insert a PN entry in the sorted array of indexes.
3515
3517{
3518 if (!fSizePNEId) {
3519 // Create the arrays.
3520 fSizePNEId = 128;
3521 fKeyPNEId = new Int_t[fSizePNEId];
3522 memset(fKeyPNEId, 0, fSizePNEId * sizeof(Int_t));
3524 memset(fValuePNEId, 0, fSizePNEId * sizeof(Int_t));
3525 fKeyPNEId[fNPNEId] = uid;
3527 return kTRUE;
3528 }
3529 // Search id in the existing array and return false if it already exists.
3531 if (index > 0 && fKeyPNEId[index] == uid)
3532 return kFALSE;
3533 // Resize the arrays and insert the value
3534 Bool_t resize = (fNPNEId == fSizePNEId) ? kTRUE : kFALSE;
3535 if (resize) {
3536 // Double the size of the array
3537 fSizePNEId *= 2;
3538 // Create new arrays of keys and values
3539 Int_t *keys = new Int_t[fSizePNEId];
3540 memset(keys, 0, fSizePNEId * sizeof(Int_t));
3541 Int_t *values = new Int_t[fSizePNEId];
3542 memset(values, 0, fSizePNEId * sizeof(Int_t));
3543 // Copy all keys<uid in the new keys array (0 to index)
3544 memcpy(keys, fKeyPNEId, (index + 1) * sizeof(Int_t));
3545 memcpy(values, fValuePNEId, (index + 1) * sizeof(Int_t));
3546 // Insert current key at index+1
3547 keys[index + 1] = uid;
3548 values[index + 1] = ientry;
3549 // Copy all remaining keys from the old to new array
3550 memcpy(&keys[index + 2], &fKeyPNEId[index + 1], (fNPNEId - index - 1) * sizeof(Int_t));
3551 memcpy(&values[index + 2], &fValuePNEId[index + 1], (fNPNEId - index - 1) * sizeof(Int_t));
3552 delete[] fKeyPNEId;
3553 fKeyPNEId = keys;
3554 delete[] fValuePNEId;
3555 fValuePNEId = values;
3556 fNPNEId++;
3557 return kTRUE;
3558 }
3559 // Insert the value in the existing arrays
3560 Int_t i;
3561 for (i = fNPNEId - 1; i > index; i--) {
3562 fKeyPNEId[i + 1] = fKeyPNEId[i];
3563 fValuePNEId[i + 1] = fValuePNEId[i];
3564 }
3565 fKeyPNEId[index + 1] = uid;
3566 fValuePNEId[index + 1] = ientry;
3567 fNPNEId++;
3568 return kTRUE;
3569}
3570
3571////////////////////////////////////////////////////////////////////////////////
3572/// Make a physical node from the path pointed by an alignable object with a given name.
3573
3575{
3577 if (!entry) {
3578 Error("MakeAlignablePN", "No alignable object named %s found !", name);
3579 return nullptr;
3580 }
3581 return MakeAlignablePN(entry);
3582}
3583
3584////////////////////////////////////////////////////////////////////////////////
3585/// Make a physical node from the path pointed by a given alignable object.
3586
3588{
3589 if (!entry) {
3590 Error("MakeAlignablePN", "No alignable object specified !");
3591 return nullptr;
3592 }
3593 const char *path = entry->GetTitle();
3594 if (!cd(path)) {
3595 Error("MakeAlignablePN", "Alignable object %s poins to invalid path: %s", entry->GetName(), path);
3596 return nullptr;
3597 }
3598 TGeoPhysicalNode *node = MakePhysicalNode(path);
3599 entry->SetPhysicalNode(node);
3600 return node;
3601}
3602
3603////////////////////////////////////////////////////////////////////////////////
3604/// Makes a physical node corresponding to a path. If PATH is not specified,
3605/// makes physical node matching current modeller state.
3606
3608{
3609 TGeoPhysicalNode *node;
3610 if (path) {
3611 if (!CheckPath(path)) {
3612 Error("MakePhysicalNode", "path: %s not valid", path);
3613 return nullptr;
3614 }
3615 node = new TGeoPhysicalNode(path);
3616 } else {
3617 node = new TGeoPhysicalNode(GetPath());
3618 }
3619 fPhysicalNodes->Add(node);
3620 return node;
3621}
3622
3623////////////////////////////////////////////////////////////////////////////////
3624/// Refresh physical nodes to reflect the actual geometry paths after alignment
3625/// was applied. Optionally locks physical nodes (default).
3626
3628{
3631 while ((pn = (TGeoPhysicalNode *)next()))
3632 pn->Refresh();
3635 if (lock)
3636 LockGeometry();
3637}
3638
3639////////////////////////////////////////////////////////////////////////////////
3640/// Clear the current list of physical nodes, so that we can start over with a new list.
3641/// If MUSTDELETE is true, delete previous nodes.
3642
3650
3651////////////////////////////////////////////////////////////////////////////////
3652/// Make an assembly of volumes.
3653
3655{
3656 return TGeoBuilder::Instance(this)->MakeVolumeAssembly(name);
3657}
3658
3659////////////////////////////////////////////////////////////////////////////////
3660/// Make a TGeoVolumeMulti handling a list of volumes.
3661
3663{
3664 return TGeoBuilder::Instance(this)->MakeVolumeMulti(name, medium);
3665}
3666
3667////////////////////////////////////////////////////////////////////////////////
3668/// Set type of exploding view (see TGeoPainter::SetExplodedView())
3669
3671{
3672 if ((ibomb >= 0) && (ibomb < 4))
3674 if (fPainter)
3676}
3677
3678////////////////////////////////////////////////////////////////////////////////
3679/// Set cut phi range
3680
3682{
3683 if ((phimin == 0) && (phimax == 360)) {
3684 fPhiCut = kFALSE;
3685 return;
3686 }
3687 fPhiCut = kTRUE;
3688 fPhimin = phimin;
3689 fPhimax = phimax;
3690}
3691
3692////////////////////////////////////////////////////////////////////////////////
3693/// Set number of segments for approximating circles in drawing.
3694
3696{
3697 if (fNsegments == nseg)
3698 return;
3699 if (nseg > 2)
3700 fNsegments = nseg;
3701 if (fPainter)
3704}
3705
3706////////////////////////////////////////////////////////////////////////////////
3707/// Get number of segments approximating circles
3708
3710{
3711 return fNsegments;
3712}
3713
3714////////////////////////////////////////////////////////////////////////////////
3715/// Invalidate mesh caches built by composite shapes
3716
3718{
3720 TGeoShape *shape;
3721 while ((shape = (TGeoShape *)next_shape())) {
3722 if (shape->IsComposite())
3723 ((TGeoCompositeShape *)shape)->InvalidateMeshCaches();
3724 }
3725}
3726
3727////////////////////////////////////////////////////////////////////////////////
3728/// Now just a shortcut for GetElementTable.
3729
3735
3736////////////////////////////////////////////////////////////////////////////////
3737/// Returns material table. Creates it if not existing.
3738
3745
3746////////////////////////////////////////////////////////////////////////////////
3747/// Make a rectilinear step of length fStep from current point (fPoint) on current
3748/// direction (fDirection). If the step is imposed by geometry, is_geom flag
3749/// must be true (default). The cross flag specifies if the boundary should be
3750/// crossed in case of a geometry step (default true). Returns new node after step.
3751/// Set also on boundary condition.
3752
3754{
3755 return GetCurrentNavigator()->Step(is_geom, cross);
3756}
3757
3758////////////////////////////////////////////////////////////////////////////////
3759/// shoot npoints randomly in a box of 1E-5 around current point.
3760/// return minimum distance to points outside
3761
3766
3767////////////////////////////////////////////////////////////////////////////////
3768/// Set the top volume and corresponding node as starting point of the geometry.
3769
3771{
3772 if (fTopVolume == vol)
3773 return;
3774
3775 TSeqCollection *brlist = gROOT->GetListOfBrowsers();
3776 TIter next(brlist);
3777 TBrowser *browser = nullptr;
3778
3779 if (fTopVolume)
3780 fTopVolume->SetTitle("");
3781 fTopVolume = vol;
3782 vol->SetTitle("Top volume");
3783 if (fTopNode) {
3785 fTopNode = nullptr;
3786 while ((browser = (TBrowser *)next()))
3787 browser->RecursiveRemove(topn);
3788 delete topn;
3789 } else {
3790 fMasterVolume = vol;
3793 if (fgVerboseLevel > 0)
3794 Info("SetTopVolume", "Top volume is %s. Master volume is %s", fTopVolume->GetName(), fMasterVolume->GetName());
3795 }
3796 // fMasterVolume->FindMatrixOfDaughterVolume(vol);
3797 // fCurrentMatrix->Print();
3799 fTopNode->SetName(TString::Format("%s_1", vol->GetName()));
3800 fTopNode->SetNumber(1);
3801 fTopNode->SetTitle("Top logical node");
3802 fNodes->AddAt(fTopNode, 0);
3803 if (!GetCurrentNavigator()) {
3805 return;
3806 }
3807 Int_t nnavigators = 0;
3809 if (!arr)
3810 return;
3811 nnavigators = arr->GetEntriesFast();
3812 for (Int_t i = 0; i < nnavigators; i++) {
3813 TGeoNavigator *nav = (TGeoNavigator *)arr->At(i);
3814 nav->ResetAll();
3815 if (fClosed)
3816 nav->GetCache()->BuildInfoBranch();
3817 }
3818}
3819
3820////////////////////////////////////////////////////////////////////////////////
3821/// Define different tracking media.
3822
3824{
3825 /*
3826 Int_t nmat = fMaterials->GetSize();
3827 if (!nmat) {printf(" No materials !\n"); return;}
3828 Int_t *media = new Int_t[nmat];
3829 memset(media, 0, nmat*sizeof(Int_t));
3830 Int_t imedia = 1;
3831 TGeoMaterial *mat, *matref;
3832 mat = (TGeoMaterial*)fMaterials->At(0);
3833 if (mat->GetMedia()) {
3834 for (Int_t i=0; i<nmat; i++) {
3835 mat = (TGeoMaterial*)fMaterials->At(i);
3836 mat->Print();
3837 }
3838 return;
3839 }
3840 mat->SetMedia(imedia);
3841 media[0] = imedia++;
3842 mat->Print();
3843 for (Int_t i=0; i<nmat; i++) {
3844 mat = (TGeoMaterial*)fMaterials->At(i);
3845 for (Int_t j=0; j<i; j++) {
3846 matref = (TGeoMaterial*)fMaterials->At(j);
3847 if (mat->IsEq(matref)) {
3848 mat->SetMedia(media[j]);
3849 break;
3850 }
3851 if (j==(i-1)) {
3852 // different material
3853 mat->SetMedia(imedia);
3854 media[i] = imedia++;
3855 mat->Print();
3856 }
3857 }
3858 }
3859 */
3860}
3861
3862////////////////////////////////////////////////////////////////////////////////
3863/// Check pushes and pulls needed to cross the next boundary with respect to the
3864/// position given by FindNextBoundary. If radius is not mentioned the full bounding
3865/// box will be sampled.
3866
3871
3872////////////////////////////////////////////////////////////////////////////////
3873/// Check the boundary errors reference file created by CheckBoundaryErrors method.
3874/// The shape for which the crossing failed is drawn with the starting point in red
3875/// and the extrapolated point to boundary (+/- failing push/pull) in yellow.
3876
3881
3882////////////////////////////////////////////////////////////////////////////////
3883/// Classify a given point. See TGeoChecker::CheckPoint().
3884
3889
3890////////////////////////////////////////////////////////////////////////////////
3891/// Test for shape navigation methods. Summary for test numbers:
3892/// - 1: DistFromInside/Outside. Sample points inside the shape. Generate
3893/// directions randomly in cos(theta). Compute DistFromInside and move the
3894/// point with bigger distance. Compute DistFromOutside back from new point.
3895/// Plot d-(d1+d2)
3896///
3897
3902
3903////////////////////////////////////////////////////////////////////////////////
3904/// Geometry checking.
3905/// - if option contains 'o': Optional overlap checkings (by sampling and by mesh).
3906/// - if option contains 'b': Optional boundary crossing check + timing per volume.
3907///
3908/// STAGE 1: extensive overlap checking by sampling per volume. Stdout need to be
3909/// checked by user to get report, then TGeoVolume::CheckOverlaps(0.01, "s") can
3910/// be called for the suspicious volumes.
3911///
3912/// STAGE 2: normal overlap checking using the shapes mesh - fills the list of
3913/// overlaps.
3914///
3915/// STAGE 3: shooting NRAYS rays from VERTEX and counting the total number of
3916/// crossings per volume (rays propagated from boundary to boundary until
3917/// geometry exit). Timing computed and results stored in a histo.
3918///
3919/// STAGE 4: shooting 1 mil. random rays inside EACH volume and calling
3920/// FindNextBoundary() + Safety() for each call. The timing is normalized by the
3921/// number of crossings computed at stage 2 and presented as percentage.
3922/// One can get a picture on which are the most "burned" volumes during
3923/// transportation from geometry point of view. Another plot of the timing per
3924/// volume vs. number of daughters is produced.
3925
3927{
3928 TString opt(option);
3929 opt.ToLower();
3930 if (!opt.Length()) {
3931 Error("CheckGeometryFull", "The option string must contain a letter. See method documentation.");
3932 return;
3933 }
3934 Bool_t checkoverlaps = opt.Contains("o");
3935 Bool_t checkcrossings = opt.Contains("b");
3936 Double_t vertex[3];
3937 vertex[0] = vx;
3938 vertex[1] = vy;
3939 vertex[2] = vz;
3941}
3942
3943////////////////////////////////////////////////////////////////////////////////
3944/// Perform last checks on the geometry
3945
3947{
3948 if (fgVerboseLevel > 0)
3949 Info("CheckGeometry", "Fixing runtime shapes...");
3950 TIter next(fShapes);
3952 TGeoShape *shape;
3953 TGeoVolume *vol;
3955 while ((shape = (TGeoShape *)next())) {
3956 if (shape->IsRunTimeShape()) {
3958 }
3959 if (fIsGeomReading)
3960 shape->AfterStreamer();
3963 shape->ComputeBBox();
3964 }
3965 if (has_runtime)
3967 else if (fgVerboseLevel > 0)
3968 Info("CheckGeometry", "...Nothing to fix");
3969 // Compute bounding box for assemblies
3971 while ((vol = (TGeoVolume *)nextv())) {
3972 if (vol->IsAssembly())
3973 vol->GetShape()->ComputeBBox();
3974 else if (vol->GetMedium() == dummy) {
3975 Warning("CheckGeometry", "Volume \"%s\" has no medium: assigned dummy medium and material", vol->GetName());
3976 vol->SetMedium(dummy);
3977 }
3978 }
3979}
3980
3981////////////////////////////////////////////////////////////////////////////////
3982/// Check all geometry for illegal overlaps within a limit OVLP.
3983
3985{
3986 if (!fTopNode) {
3987 Error("CheckOverlaps", "Top node not set");
3988 return;
3989 }
3991}
3992
3993////////////////////////////////////////////////////////////////////////////////
3994/// Check all geometry for illegal overlaps within a limit OVLP.
3995
3997{
3998 if (!fTopNode) {
3999 Error("CheckOverlaps", "Top node not set");
4000 return;
4001 }
4003}
4004
4005////////////////////////////////////////////////////////////////////////////////
4006/// Prints the current list of overlaps.
4007
4009{
4010 if (!fOverlaps)
4011 return;
4013 if (!novlp)
4014 return;
4015 TGeoManager *geom = (TGeoManager *)this;
4016 geom->GetGeomChecker()->PrintOverlaps();
4017}
4018
4019////////////////////////////////////////////////////////////////////////////////
4020/// Estimate weight of volume VOL with a precision SIGMA(W)/W better than PRECISION.
4021/// Option can be "v" - verbose (default)
4022
4024{
4025 if (!GetGeomChecker())
4026 return 0.;
4027 TString opt(option);
4028 opt.ToLower();
4029 Double_t weight;
4030 TGeoVolume *volume = fTopVolume;
4031 if (opt.Contains("v")) {
4032 if (opt.Contains("a")) {
4033 if (fgVerboseLevel > 0)
4034 Info("Weight", "Computing analytically weight of %s", volume->GetName());
4035 weight = volume->WeightA();
4036 if (fgVerboseLevel > 0)
4037 Info("Weight", "Computed weight: %f [kg]\n", weight);
4038 return weight;
4039 }
4040 if (fgVerboseLevel > 0) {
4041 Info("Weight", "Estimating weight of %s with %g %% precision", fTopVolume->GetName(), 100. * precision);
4042 printf(" event weight err\n");
4043 printf("========================================\n");
4044 }
4045 }
4046 weight = fChecker->Weight(precision, option);
4047 return weight;
4048}
4049
4050////////////////////////////////////////////////////////////////////////////////
4051/// computes the total size in bytes of the branch starting with node.
4052/// The option can specify if all the branch has to be parsed or only the node
4053
4054ULong_t TGeoManager::SizeOf(const TGeoNode * /*node*/, Option_t * /*option*/)
4055{
4056 return 0;
4057}
4058
4059////////////////////////////////////////////////////////////////////////////////
4060/// Stream an object of class TGeoManager.
4061
4063{
4064 if (R__b.IsReading()) {
4065 R__b.ReadClassBuffer(TGeoManager::Class(), this);
4067 CloseGeometry();
4070 } else {
4071 R__b.WriteClassBuffer(TGeoManager::Class(), this);
4072 }
4073}
4074
4075////////////////////////////////////////////////////////////////////////////////
4076/// Execute mouse actions on this manager.
4077
4079{
4080 if (!fPainter)
4081 return;
4082 fPainter->ExecuteManagerEvent(this, event, px, py);
4083}
4084
4085////////////////////////////////////////////////////////////////////////////////
4086/// Export this geometry to a file
4087///
4088/// - Case 1: root file or root/xml file
4089/// if filename end with ".root". The key will be named name
4090/// By default the geometry is saved without the voxelisation info.
4091/// Use option 'v" to save the voxelisation info.
4092/// if filename end with ".xml" a root/xml file is produced.
4093///
4094/// - Case 2: C++ script
4095/// if filename end with ".C"
4096///
4097/// - Case 3: gdml file
4098/// if filename end with ".gdml"
4099/// NOTE that to use this option, the PYTHONPATH must be defined like
4100/// export PYTHONPATH=$ROOTSYS/lib:$ROOTSYS/geom/gdml
4101///
4102
4104{
4106 if (sfile.Contains(".C")) {
4107 // Save geometry as a C++ script
4108 if (fgVerboseLevel > 0)
4109 Info("Export", "Exporting %s %s as C++ code", GetName(), GetTitle());
4111 return 1;
4112 }
4113 if (sfile.Contains(".gdml")) {
4114 // Save geometry as a gdml file
4115 if (fgVerboseLevel > 0)
4116 Info("Export", "Exporting %s %s as gdml code", GetName(), GetTitle());
4117 // C++ version
4118 TString cmd;
4119 cmd = TString::Format("TGDMLWrite::StartGDMLWriting(gGeoManager,\"%s\",\"%s\")", filename, option);
4120 gROOT->ProcessLineFast(cmd);
4121 return 1;
4122 }
4123 if (sfile.Contains(".root") || sfile.Contains(".xml")) {
4124 // Save geometry as a root file
4125 TFile *f = TFile::Open(filename, "recreate");
4126 if (!f || f->IsZombie()) {
4127 Error("Export", "Cannot open file");
4128 return 0;
4129 }
4131 if (keyname.IsNull())
4132 keyname = GetName();
4133 TString opt = option;
4134 opt.ToLower();
4135 if (opt.Contains("v")) {
4137 if (fgVerboseLevel > 0)
4138 Info("Export", "Exporting %s %s as root file. Optimizations streamed.", GetName(), GetTitle());
4139 } else {
4141 if (fgVerboseLevel > 0)
4142 Info("Export", "Exporting %s %s as root file. Optimizations not streamed.", GetName(), GetTitle());
4143 }
4144
4148 if (sfile.Contains(".xml")) {
4151 }
4153 if (sfile.Contains(".xml")) {
4156 }
4157
4159 delete f;
4160 return nbytes;
4161 }
4162 return 0;
4163}
4164
4165////////////////////////////////////////////////////////////////////////////////
4166/// Lock current geometry so that no other geometry can be imported.
4167
4169{
4170 fgLock = kTRUE;
4171}
4172
4173////////////////////////////////////////////////////////////////////////////////
4174/// Unlock current geometry.
4175
4177{
4178 fgLock = kFALSE;
4179}
4180
4181////////////////////////////////////////////////////////////////////////////////
4182/// Check lock state.
4183
4185{
4186 return fgLock;
4187}
4188
4189////////////////////////////////////////////////////////////////////////////////
4190/// Set verbosity level (static function).
4191/// - 0 - suppress messages related to geom-painter visibility level
4192/// - 1 - default value
4193
4198
4199////////////////////////////////////////////////////////////////////////////////
4200/// Return current verbosity level (static function).
4201
4206
4207////////////////////////////////////////////////////////////////////////////////
4208/// static function
4209/// Import a geometry from a gdml or ROOT file
4210///
4211/// - Case 1: gdml
4212/// if filename ends with ".gdml" the foreign geometry described with gdml
4213/// is imported executing some python scripts in $ROOTSYS/gdml.
4214/// NOTE that to use this option, the PYTHONPATH must be defined like
4215/// export PYTHONPATH=$ROOTSYS/lib:$ROOTSYS/gdml
4216///
4217/// - Case 2: root file (.root) or root/xml file (.xml)
4218/// Import in memory from filename the geometry with key=name.
4219/// if name="" (default), the first TGeoManager object in the file is returned.
4220///
4221/// Note that this function deletes the current gGeoManager (if one)
4222/// before importing the new object.
4223
4224TGeoManager *TGeoManager::Import(const char *filename, const char *name, Option_t * /*option*/)
4225{
4226 if (fgLock) {
4227 ::Warning("TGeoManager::Import", "TGeoMananager in lock mode. NOT IMPORTING new geometry");
4228 return nullptr;
4229 }
4230 if (!filename)
4231 return nullptr;
4232 if (fgVerboseLevel > 0)
4233 ::Info("TGeoManager::Import", "Reading geometry from file: %s", filename);
4234
4235 if (gGeoManager)
4236 delete gGeoManager;
4237 gGeoManager = nullptr;
4238
4239 if (strstr(filename, ".gdml")) {
4240 // import from a gdml file
4241 new TGeoManager("GDMLImport", "Geometry imported from GDML");
4242 TString cmd = TString::Format("TGDMLParse::StartGDML(\"%s\")", filename);
4243 TGeoVolume *world = (TGeoVolume *)gROOT->ProcessLineFast(cmd);
4244
4245 if (world == nullptr) {
4246 delete gGeoManager;
4247 gGeoManager = nullptr;
4248 ::Error("TGeoManager::Import", "Cannot read file %s", filename);
4249 } else {
4253 }
4254 } else {
4255 // import from a root file
4257 // in case a web file is specified, use the cacheread option to cache
4258 // this file in the cache directory
4259 TFile *f = nullptr;
4260 if (strstr(filename, "http"))
4261 f = TFile::Open(filename, "CACHEREAD");
4262 else
4264 if (!f || f->IsZombie()) {
4265 ::Error("TGeoManager::Import", "Cannot open file");
4266 return nullptr;
4267 }
4268 if (name && strlen(name) > 0) {
4269 gGeoManager = (TGeoManager *)f->Get(name);
4270 } else {
4271 TIter next(f->GetListOfKeys());
4272 TKey *key;
4273 while ((key = (TKey *)next())) {
4274 if (strcmp(key->GetClassName(), "TGeoManager") != 0)
4275 continue;
4276 gGeoManager = (TGeoManager *)key->ReadObj();
4277 break;
4278 }
4279 }
4280 delete f;
4281 }
4282 if (!gGeoManager)
4283 return nullptr;
4284 if (!gROOT->GetListOfGeometries()->FindObject(gGeoManager))
4285 gROOT->GetListOfGeometries()->Add(gGeoManager);
4286 if (!gROOT->GetListOfBrowsables()->FindObject(gGeoManager))
4287 gROOT->GetListOfBrowsables()->Add(gGeoManager);
4289 return gGeoManager;
4290}
4291
4292////////////////////////////////////////////////////////////////////////////////
4293/// Update element flags when geometry is loaded from a file.
4294
4296{
4297 if (!fElementTable)
4298 return;
4299 TIter next(fMaterials);
4301 TGeoMixture *mix;
4303 Int_t i, nelem;
4304 while ((mat = (TGeoMaterial *)next())) {
4305 if (mat->IsMixture()) {
4306 mix = (TGeoMixture *)mat;
4307 nelem = mix->GetNelements();
4308 for (i = 0; i < nelem; i++) {
4309 elem = mix->GetElement(i);
4310 if (!elem)
4311 continue;
4313 if (!elem_table)
4314 continue;
4315 if (elem != elem_table) {
4316 elem_table->SetDefined(elem->IsDefined());
4317 elem_table->SetUsed(elem->IsUsed());
4318 } else {
4319 elem_table->SetDefined();
4320 }
4321 }
4322 } else {
4323 elem = mat->GetElement();
4324 if (!elem)
4325 continue;
4327 if (!elem_table)
4328 continue;
4329 if (elem != elem_table) {
4330 elem_table->SetDefined(elem->IsDefined());
4331 elem_table->SetUsed(elem->IsUsed());
4332 } else {
4333 elem_table->SetUsed();
4334 }
4335 }
4336 }
4337}
4338
4339////////////////////////////////////////////////////////////////////////////////
4340/// Initialize PNE array for fast access via index and unique-id.
4341
4343{
4344 if (fHashPNE) {
4346 TIter next(fHashPNE);
4347 TObject *obj;
4348 while ((obj = next())) {
4349 fArrayPNE->Add(obj);
4350 }
4351 return kTRUE;
4352 }
4353 return kFALSE;
4354}
4355
4356////////////////////////////////////////////////////////////////////////////////
4357/// Get time cut for drawing tracks.
4358
4360{
4361 tmin = fTmin;
4362 tmax = fTmax;
4363 return fTimeCut;
4364}
4365
4366////////////////////////////////////////////////////////////////////////////////
4367/// Set time cut interval for drawing tracks. If called with no arguments, time
4368/// cut will be disabled.
4369
4371{
4372 fTmin = tmin;
4373 fTmax = tmax;
4374 if (tmin == 0 && tmax == 999)
4375 fTimeCut = kFALSE;
4376 else
4377 fTimeCut = kTRUE;
4378 if (fTracks && !IsAnimatingTracks())
4379 ModifiedPad();
4380}
4381
4382////////////////////////////////////////////////////////////////////////////////
4383/// Convert coordinates from master volume frame to top.
4384
4389
4390////////////////////////////////////////////////////////////////////////////////
4391/// Convert coordinates from top volume frame to master.
4392
4397
4398////////////////////////////////////////////////////////////////////////////////
4399/// Create a parallel world for prioritised navigation. This can be populated
4400/// with physical nodes and can be navigated independently using its API.
4401/// In case the flag SetUseParallelWorldNav is set, any navigation query in the
4402/// main geometry is checked against the parallel geometry, which gets priority
4403/// in case of overlaps with the main geometry volumes.
4404
4410
4411////////////////////////////////////////////////////////////////////////////////
4412/// Activate/deactivate usage of parallel world navigation. Can only be done if
4413/// there is a parallel world. Activating navigation will automatically close
4414/// the parallel geometry.
4415
4417{
4418 if (!fParallelWorld) {
4419 Error("SetUseParallelWorldNav", "No parallel world geometry defined. Use CreateParallelWorld.");
4420 return;
4421 }
4422 if (!flag) {
4423 fUsePWNav = flag;
4424 return;
4425 }
4426 if (!fClosed) {
4427 Error("SetUseParallelWorldNav", "The geometry must be closed first");
4428 return;
4429 }
4430 // Closing the parallel world geometry is mandatory
4432 fUsePWNav = kTRUE;
4433}
4434
4441
4446
4448{
4449 if (fgDefaultUnits == new_value) {
4450 gGeometryLocked = true;
4451 return;
4452 } else if (gGeometryLocked) {
4453 ::Fatal("TGeoManager", "The system of units may only be changed once, \n"
4454 "BEFORE any elements and materials are created! \n"
4455 "Alternatively unlock the default units at own risk.");
4456 } else if (new_value == kG4Units) {
4457 ::Info("TGeoManager", "Changing system of units to Geant4 units (mm, ns, MeV).");
4458 } else if (new_value == kRootUnits) {
4459 ::Info("TGeoManager", "Changing system of units to ROOT units (cm, s, GeV).");
4460 }
4462}
4463
4468
#define SafeDelete(p)
Definition RConfig.hxx:507
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
cudaEvent_t event
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char)
Definition RtypesCore.h:53
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
Definition RtypesCore.h:70
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:61
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:72
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Definition RtypesCore.h:85
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
#define BIT(n)
Definition Rtypes.h:90
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
R__EXTERN TEnv * gEnv
Definition TEnv.h:126
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
char name[80]
Definition TGX11.cxx:142
@ kNatural
Natural, material-inspired colors (default)
TGeoManager * gGeoManager
static Bool_t gGeometryLocked
R__EXTERN TGeoManager * gGeoManager
R__EXTERN TGeoIdentity * gGeoIdentity
Definition TGeoMatrix.h:538
int nentries
#define gROOT
Definition TROOT.h:417
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define gPad
const_iterator end() const
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition TAttFill.h:40
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
static const char * GetFloatFormat()
return current printf format for float members, default "%e"
static void SetFloatFormat(const char *fmt="%e")
set printf format for float/double members, default "%e" to change format only for doubles,...
static const char * GetDoubleFormat()
return current printf format for double members, default "%.14e"
static void SetDoubleFormat(const char *fmt="%.14e")
set printf format for double members, default "%.14e" use it after SetFloatFormat,...
Buffer base class used for serializing objects.
Definition TBuffer.h:43
@ kRealNew
Definition TClass.h:110
@ kDummyNew
Definition TClass.h:110
static ENewType IsCallingNew()
Static method returning the defConstructor flag passed to TClass::New().
Definition TClass.cxx:6070
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition TDatime.h:37
const char * AsString() const
Return the date & time as a string (ctime() format).
Definition TDatime.cxx:98
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:511
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:130
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:3801
This class is used in the process of reading and writing the GDML "matrix" tag.
Definition TGDMLMatrix.h:33
Bool_t IsVisTouched() const
Definition TGeoAtt.h:91
void SetVisStreamed(Bool_t vis=kTRUE)
Mark attributes as "streamed to file".
Definition TGeoAtt.cxx:127
void SetVisTouched(Bool_t vis=kTRUE)
Mark visualization attributes as "modified".
Definition TGeoAtt.cxx:137
void SetVisBranch()
Set branch type visibility.
Definition TGeoAtt.cxx:65
Box class.
Definition TGeoBBox.h:18
static TGeoBuilder * Instance(TGeoManager *geom)
Return pointer to singleton.
Strategy object for assigning colors and transparency to geometry volumes.
Class describing rotation + translation.
Definition TGeoMatrix.h:318
Composite shapes are Boolean combinations of two or more shape components.
table of elements
TGeoElement * GetElement(Int_t z)
Base class for chemical elements.
Definition TGeoElement.h:31
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition TGeoMatrix.h:459
An identity transformation.
Definition TGeoMatrix.h:407
A geometry iterator.
Definition TGeoNode.h:249
Int_t GetLevel() const
Definition TGeoNode.h:295
The manager class for any TGeo geometry.
Definition TGeoManager.h:46
static void UnlockGeometry()
Unlock current geometry.
Double_t fPhimax
! highest range for phi cut
Definition TGeoManager.h:68
TGeoVolume * MakeCone(const char *name, TGeoMedium *medium, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
Make in one step a volume pointing to a cone shape with given medium.
void AnimateTracks(Double_t tmin=0, Double_t tmax=5E-8, Int_t nframes=200, Option_t *option="/*")
Draw animation of tracks.
void AddSkinSurface(TGeoSkinSurface *surf)
Add skin surface;.
TGeoVolume * MakeXtru(const char *name, TGeoMedium *medium, Int_t nz)
Make a TGeoXtru-shaped volume with nz planes.
Double_t * FindNormalFast()
Computes fast normal to next crossed boundary, assuming that the current point is close enough to the...
TGeoVolume * MakePcon(const char *name, TGeoMedium *medium, Double_t phi, Double_t dphi, Int_t nz)
Make in one step a volume pointing to a polycone shape with given medium.
Int_t fRaytraceMode
! Raytrace mode: 0=normal, 1=pass through, 2=transparent
Double_t fVisDensity
Definition TGeoManager.h:74
TGeoNavigator * AddNavigator()
Add a navigator in the list of navigators.
TVirtualGeoTrack * GetTrackOfId(Int_t id) const
Get track with a given ID.
TGeoMaterial * FindDuplicateMaterial(const TGeoMaterial *mat) const
Find if a given material duplicates an existing one.
TGeoVolume * Division(const char *name, const char *mother, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed=0, Option_t *option="")
Create a new volume by dividing an existing one (GEANT3 like)
TGeoVolume * Volume(const char *name, const char *shape, Int_t nmed, Float_t *upar, Int_t npar=0)
Create a volume in GEANT3 style.
Int_t ReplaceVolume(TGeoVolume *vorig, TGeoVolume *vnew)
Replaces all occurrences of VORIG with VNEW in the geometry tree.
void DoRestoreState()
Restore a backed-up state without affecting the cache stack.
Int_t GetCurrentNodeId() const
Get the unique ID of the current node.
TGeoPNEntry * GetAlignableEntry(const char *name) const
Retrieves an existing alignable object.
TGeoVolume * fMasterVolume
TVirtualGeoTrack * FindTrackWithId(Int_t id) const
Search the track hierarchy to find the track with the given id.
TObjArray * fArrayPNE
! array of physical node entries
void TestOverlaps(const char *path="")
Geometry overlap checker based on sampling.
static EDefaultUnits GetDefaultUnits()
void RemoveMaterial(Int_t index)
Remove material at given index.
void Matrix(Int_t index, Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2, Double_t theta3, Double_t phi3)
Create rotation matrix named 'mat<index>'.
TGeoElementTable * GetElementTable()
Returns material table. Creates it if not existing.
Int_t fNtracks
Definition TGeoManager.h:79
THashList * fHashPNE
static Int_t fgVerboseLevel
! Verbosity level for Info messages (no IO).
Definition TGeoManager.h:56
void Init()
Initialize manager class.
Bool_t InitArrayPNE() const
Initialize PNE array for fast access via index and unique-id.
TObjArray * fPhysicalNodes
virtual ULong_t SizeOf(const TGeoNode *node, Option_t *option)
computes the total size in bytes of the branch starting with node.
TObjArray * fUniqueVolumes
static UInt_t fgExportPrecision
! Precision to be used in ASCII exports
Definition TGeoManager.h:60
TObjArray * fRegions
void Node(const char *name, Int_t nr, const char *mother, Double_t x, Double_t y, Double_t z, Int_t irot, Bool_t isOnly, Float_t *upar, Int_t npar=0)
Create a node called <name_nr> pointing to the volume called <name> as daughter of the volume called ...
TObjArray * fGShapes
! list of runtime shapes
TGeoVolume * fPaintVolume
! volume currently painted
TGeoSkinSurface * GetSkinSurface(const char *name) const
Get skin surface with a given name;.
void UpdateElements()
Update element flags when geometry is loaded from a file.
TGeoManager()
Default constructor.
void CheckOverlapsBySampling(Double_t ovlp, Int_t npoints)
Check all geometry for illegal overlaps within a limit OVLP.
TVirtualGeoChecker * GetGeomChecker()
Make a default checker if none present. Returns pointer to it.
static TClass * Class()
ConstPropMap_t fProperties
TGeoVolume * MakeTube(const char *name, TGeoMedium *medium, Double_t rmin, Double_t rmax, Double_t dz)
Make in one step a volume pointing to a tube shape with given medium.
void CdUp()
Go one level up in geometry.
void DoBackupState()
Backup the current state without affecting the cache stack.
TList * fMaterials
void CheckBoundaryErrors(Int_t ntracks=1000000, Double_t radius=-1.)
Check pushes and pulls needed to cross the next boundary with respect to the position given by FindNe...
TObjArray * fVolumes
Int_t * fValuePNEId
TGeoPNEntry * GetAlignableEntryByUID(Int_t uid) const
Retrieves an existing alignable object having a preset UID.
void AddGDMLMatrix(TGDMLMatrix *mat)
Add GDML matrix;.
Bool_t fTimeCut
Definition TGeoManager.h:90
static void SetExportPrecision(UInt_t prec)
void AddBorderSurface(TGeoBorderSurface *surf)
Add border surface;.
void RebuildVoxels()
Rebuild the voxel structures that are flagged as needing rebuild.
void SetClippingShape(TGeoShape *clip)
Set a user-defined shape as clipping for ray tracing.
TGeoVolume * fCurrentVolume
! current volume
void ClearOverlaps()
Clear the list of overlaps.
TGeoVolume * MakeCons(const char *name, TGeoMedium *medium, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
Make in one step a volume pointing to a cone segment shape with given medium.
THashList * fHashGVolumes
! hash list of group volumes providing fast search
TVirtualGeoChecker * fChecker
! current checker
Definition TGeoManager.h:97
Int_t fVisOption
Definition TGeoManager.h:76
static std::mutex fgMutex
! mutex for navigator booking in MT mode
Definition TGeoManager.h:54
Bool_t IsInPhiRange() const
True if current node is in phi range.
virtual Bool_t cd(const char *path="")
Browse the tree of nodes starting from fTopNode according to pathname.
TGeoNode * SearchNode(Bool_t downwards=kFALSE, const TGeoNode *skipnode=nullptr)
Returns the deepest node containing fPoint, which must be set a priori.
TGeoMaterial * Material(const char *name, Double_t a, Double_t z, Double_t dens, Int_t uid, Double_t radlen=0, Double_t intlen=0)
Create material with given A, Z and density, having an unique id.
void LocalToMaster(const Double_t *local, Double_t *master) const
Double_t fPhimin
! lowest range for phi cut
Definition TGeoManager.h:67
static Bool_t fgLockNavigators
! Lock existing navigators
void SaveAttributes(const char *filename="tgeoatt.C")
Save current attributes in a macro.
void RestoreMasterVolume()
Restore the master volume of the geometry.
Bool_t fDrawExtra
! flag that the list of physical nodes has to be drawn
Definition TGeoManager.h:91
TGeoVolume * MakeArb8(const char *name, TGeoMedium *medium, Double_t dz, Double_t *vertices=nullptr)
Make an TGeoArb8 volume.
virtual Int_t Export(const char *filename, const char *name="", Option_t *option="vg")
Export this geometry to a file.
TGeoNode * FindNextDaughterBoundary(Double_t *point, Double_t *dir, Int_t &idaughter, Bool_t compmatrix=kFALSE)
Computes as fStep the distance to next daughter of the current volume.
Int_t GetUID(const char *volname) const
Retrieve unique id for a volume name. Return -1 if name not found.
TGeoShape * fClippingShape
! clipping shape for raytracing
TGeoNavigator * GetCurrentNavigator() const
Returns current navigator for the calling thread.
THashList * fHashVolumes
! hash list of volumes providing fast search
TObjArray * fMatrices
Definition TGeoManager.h:99
static Int_t GetNumThreads()
Returns number of threads that were set to use geometry.
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
void ClearNavigators()
Clear all navigators.
Int_t AddTransformation(const TGeoMatrix *matrix)
Add a matrix to the list. Returns index of the matrix in list.
TObjArray * fOpticalSurfaces
TVirtualGeoTrack * GetParentTrackOfId(Int_t id) const
Get parent track with a given ID.
void CdNode(Int_t nodeid)
Change current path to point to the node having this id.
UChar_t * fBits
! bits used for voxelization
static Int_t GetMaxLevels()
Return maximum number of levels used in the geometry.
Double_t fTmin
! lower time limit for tracks drawing
Definition TGeoManager.h:69
static Bool_t IsLocked()
Check lock state.
TGeoVolume * fTopVolume
! top level volume in geometry
TGeoVolume * fUserPaintVolume
!
TVirtualGeoPainter * GetGeomPainter()
Make a default painter if none present. Returns pointer to it.
void GetBranchOnlys(Int_t *isonly) const
Fill node copy numbers of current branch into an array.
TGeoNode * GetCurrentNode() const
Int_t AddTrack(Int_t id, Int_t pdgcode, TObject *particle=nullptr)
Add a track to the list of tracks.
void SetVisOption(Int_t option=0)
set drawing mode :
void SetPdgName(Int_t pdg, const char *name)
Set a name for a particle having a given pdg.
TObjArray * fBorderSurfaces
Int_t GetNAlignable(Bool_t with_uid=kFALSE) const
Retrieves number of PN entries with or without UID.
void RefreshPhysicalNodes(Bool_t lock=kTRUE)
Refresh physical nodes to reflect the actual geometry paths after alignment was applied.
static Bool_t fgLock
! Lock preventing a second geometry to be loaded
Definition TGeoManager.h:55
TGeoVolume * MakePara(const char *name, TGeoMedium *medium, Double_t dx, Double_t dy, Double_t dz, Double_t alpha, Double_t theta, Double_t phi)
Make in one step a volume pointing to a parallelepiped shape with given medium.
void TopToMaster(const Double_t *top, Double_t *master) const
Convert coordinates from top volume frame to master.
TObjArray * fShapes
void AddOpticalSurface(TGeoOpticalSurface *optsurf)
Add optical surface;.
static void SetDefaultUnits(EDefaultUnits new_value)
Bool_t fLoopVolumes
! flag volume lists loop
Definition TGeoManager.h:85
Int_t AddMaterial(const TGeoMaterial *material)
Add a material to the list. Returns index of the material in list.
void ClearAttributes()
Reset all attributes to default ones.
static Int_t fgMaxDaughters
! Maximum number of daughters
Definition TGeoManager.h:58
Bool_t fUsePWNav
void SetRTmode(Int_t mode)
Change raytracing mode.
Bool_t CheckPath(const char *path) const
Check if a geometry path is valid without changing the state of the current navigator.
void InspectState() const
Inspects path and all flags for the current state.
void ConvertReflections()
Convert all reflections in geometry to normal rotations + reflected shapes.
void SetVisLevel(Int_t level=3)
set default level down to which visualization is performed
TGeoNode * FindNextBoundary(Double_t stepmax=TGeoShape::Big(), const char *path="", Bool_t frombdr=kFALSE)
Find distance to next boundary and store it in fStep.
static TGeoManager * Import(const char *filename, const char *name="", Option_t *option="")
static function Import a geometry from a gdml or ROOT file
TGeoPhysicalNode * MakePhysicalNode(const char *path=nullptr)
Makes a physical node corresponding to a path.
void CountLevels()
Count maximum number of nodes per volume, maximum depth and maximum number of xtru vertices.
Int_t fMaxThreads
! Max number of threads
Bool_t fIsGeomReading
! flag set when reading geometry
Definition TGeoManager.h:87
TGeoVolume * MakeTorus(const char *name, TGeoMedium *medium, Double_t r, Double_t rmin, Double_t rmax, Double_t phi1=0, Double_t dphi=360)
Make in one step a volume pointing to a torus shape with given medium.
TGeoHMatrix * GetHMatrix()
Return stored current matrix (global matrix of the next touched node).
TGeoParallelWorld * fParallelWorld
void RegisterMatrix(const TGeoMatrix *matrix)
Register a matrix to the list of matrices.
TVirtualGeoTrack * GetTrack(Int_t index)
static Int_t GetMaxDaughters()
Return maximum number of daughters of a volume used in the geometry.
static void ClearThreadsMap()
Clear the current map of threads.
Int_t AddVolume(TGeoVolume *volume)
Add a volume to the list. Returns index of the volume in list.
TVirtualGeoPainter * fPainter
! current painter
Definition TGeoManager.h:96
void SetVolumeAttribute(const char *name, const char *att, Int_t val)
Set volume attributes in G3 style.
const char * GetPdgName(Int_t pdg) const
Get name for given pdg code;.
void CheckGeometryFull(Int_t ntracks=1000000, Double_t vx=0., Double_t vy=0., Double_t vz=0., Option_t *option="ob")
Geometry checking.
Bool_t fIsNodeSelectable
! flag that nodes are the selected objects in pad rather than volumes
Definition TGeoManager.h:95
TGeoNode * Step(Bool_t is_geom=kTRUE, Bool_t cross=kTRUE)
Make a rectilinear step of length fStep from current point (fPoint) on current direction (fDirection)...
Bool_t GotoSafeLevel()
Go upwards the tree until a non-overlapping node.
Bool_t fActivity
! switch ON/OFF volume activity (default OFF - all volumes active))
Definition TGeoManager.h:94
void GetBranchNames(Int_t *names) const
Fill volume names of current branch into an array.
static ThreadsMap_t * fgThreadId
! Thread id's map
void CloseGeometry(Option_t *option="d")
Closing geometry implies checking the geometry validity, fixing shapes with negative parameters (run-...
TVirtualGeoTrack * MakeTrack(Int_t id, Int_t pdgcode, TObject *particle)
Makes a primary track but do not attach it to the list of tracks.
Int_t GetTrackIndex(Int_t id) const
Get index for track id, -1 if not found.
Int_t fNNodes
Definition TGeoManager.h:71
void OptimizeVoxels(const char *filename="tgeovox.C")
Optimize voxelization type for all volumes. Save best choice in a macro.
TGeoVolume * GetVolume(const char *name) const
Search for a named volume. All trailing blanks stripped.
void SetAnimateTracks(Bool_t flag=kTRUE)
Bool_t fIsGeomCleaning
! flag to notify that the manager is being destructed
Definition TGeoManager.h:88
void DefaultColors(const TGeoColorScheme *cs=nullptr)
Set default volume colors according to A of material.
Bool_t IsSameLocation() const
TGeoNode * FindNextBoundaryAndStep(Double_t stepmax=TGeoShape::Big(), Bool_t compsafe=kFALSE)
Compute distance to next boundary within STEPMAX.
TGeoVolume * MakeTrd2(const char *name, TGeoMedium *medium, Double_t dx1, Double_t dx2, Double_t dy1, Double_t dy2, Double_t dz)
Make in one step a volume pointing to a TGeoTrd2 shape with given medium.
Double_t * FindNormal(Bool_t forward=kTRUE)
Computes normal vector to the next surface that will be or was already crossed when propagating on a ...
virtual Int_t GetByteCount(Option_t *option=nullptr)
Get total size of geometry in bytes.
TGeoVolume * MakeGtra(const char *name, TGeoMedium *medium, Double_t dz, Double_t theta, Double_t phi, Double_t twist, Double_t h1, Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2, Double_t tl2, Double_t alpha2)
Make in one step a volume pointing to a twisted trapezoid shape with given medium.
TGeoElementTable * fElementTable
! table of elements
static void SetNavigatorsLock(Bool_t flag)
Set the lock for navigators.
static Int_t fgMaxXtruVert
! Maximum number of Xtru vertices
Definition TGeoManager.h:59
TGeoNode * FindNode(Bool_t safe_start=kTRUE)
Returns deepest node containing current point.
Int_t GetVisOption() const
Returns current depth to which geometry is drawn.
static void LockGeometry()
Lock current geometry so that no other geometry can be imported.
TGeoVolume * MakeBox(const char *name, TGeoMedium *medium, Double_t dx, Double_t dy, Double_t dz)
Make in one step a volume pointing to a box shape with given medium.
void CheckShape(TGeoShape *shape, Int_t testNo, Int_t nsamples, Option_t *option)
Test for shape navigation methods.
static Int_t fgMaxLevel
! Maximum level in geometry
Definition TGeoManager.h:57
void PrintOverlaps() const
Prints the current list of overlaps.
TGeoVolume * MakeTrd1(const char *name, TGeoMedium *medium, Double_t dx1, Double_t dx2, Double_t dy, Double_t dz)
Make in one step a volume pointing to a TGeoTrd1 shape with given medium.
TGeoVolume * MakeSphere(const char *name, TGeoMedium *medium, Double_t rmin, Double_t rmax, Double_t themin=0, Double_t themax=180, Double_t phimin=0, Double_t phimax=360)
Make in one step a volume pointing to a sphere shape with given medium.
void ResetUserData()
Sets all pointers TGeoVolume::fField to NULL.
TGeoVolume * FindVolumeFast(const char *name, Bool_t multi=kFALSE)
Fast search for a named volume. All trailing blanks stripped.
TList * fMedia
Bool_t GetTminTmax(Double_t &tmin, Double_t &tmax) const
Get time cut for drawing tracks.
TGeoNode * InitTrack(const Double_t *point, const Double_t *dir)
Initialize current point and current direction vector (normalized) in MARS.
ThreadsMap_t::const_iterator ThreadsMapIt_t
Bool_t fMatrixTransform
! flag for using GL matrix
Definition TGeoManager.h:92
void SetVisibility(TObject *obj, Bool_t vis)
Set visibility for a volume.
void SetTopVolume(TGeoVolume *vol)
Set the top volume and corresponding node as starting point of the geometry.
Bool_t fMatrixReflection
! flag for GL reflections
Definition TGeoManager.h:93
TGeoPNEntry * SetAlignableEntry(const char *unique_name, const char *path, Int_t uid=-1)
Creates an alignable object with unique name corresponding to a path and adds it to the list of align...
void ClearShape(const TGeoShape *shape)
Remove a shape from the list of shapes.
void ModifiedPad() const
Send "Modified" signal to painter.
void BombTranslation(const Double_t *tr, Double_t *bombtr)
Get the new 'bombed' translation vector according current exploded view mode.
TGeoNavigator * fCurrentNavigator
! current navigator
static Bool_t LockDefaultUnits(Bool_t new_value)
Int_t fMaxVisNodes
Definition TGeoManager.h:80
TGeoMedium * GetMedium(const char *medium) const
Search for a named tracking medium. All trailing blanks stripped.
Bool_t InsertPNEId(Int_t uid, Int_t ientry)
Insert a PN entry in the sorted array of indexes.
Int_t fVisLevel
Definition TGeoManager.h:77
void ViewLeaves(Bool_t flag=kTRUE)
Set visualization option (leaves only OR all volumes)
TGeoVolume * MakeCtub(const char *name, TGeoMedium *medium, Double_t rmin, Double_t rmax, Double_t dz, Double_t phi1, Double_t phi2, Double_t lx, Double_t ly, Double_t lz, Double_t tx, Double_t ty, Double_t tz)
Make in one step a volume pointing to a tube segment shape with given medium.
void SetTminTmax(Double_t tmin=0, Double_t tmax=999)
Set time cut interval for drawing tracks.
NavigatorsMap_t fNavigators
! Map between thread id's and navigator arrays
void GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
Fill node copy numbers of current branch into an array.
Bool_t fPhiCut
Definition TGeoManager.h:89
TGeoNode * CrossBoundaryAndLocate(Bool_t downwards, TGeoNode *skipnode)
Cross next boundary and locate within current node The current point must be on the boundary of fCurr...
void DrawTracks(Option_t *option="")
Draw tracks over the geometry, according to option.
void Streamer(TBuffer &) override
Stream an object of class TGeoManager.
void BuildDefaultMaterials()
Now just a shortcut for GetElementTable.
void SetMaxThreads(Int_t nthreads)
Enable multi-threaded navigation for at most nthreads worker threads.
TGeoMedium * Medium(const char *name, Int_t numed, Int_t nmat, Int_t isvol, Int_t ifield, Double_t fieldm, Double_t tmaxfd, Double_t stemax, Double_t deemax, Double_t epsil, Double_t stmin)
Create tracking medium.
void SetExplodedView(Int_t iopt=0)
Set type of exploding view (see TGeoPainter::SetExplodedView())
Double_t Weight(Double_t precision=0.01, Option_t *option="va")
Estimate weight of volume VOL with a precision SIGMA(W)/W better than PRECISION.
void ClearPhysicalNodes(Bool_t mustdelete=kFALSE)
Clear the current list of physical nodes, so that we can start over with a new list.
static Int_t Parse(const char *expr, TString &expr1, TString &expr2, TString &expr3)
Parse a string boolean expression and do a syntax check.
void GetBombFactors(Double_t &bombx, Double_t &bomby, Double_t &bombz, Double_t &bombr) const
Retrieve cartesian and radial bomb factors.
Double_t GetProperty(const char *name, Bool_t *error=nullptr) const
Get a user-defined property.
TObjArray * fTracks
Bool_t IsAnimatingTracks() const
const char * GetPath() const
Get path to the current node in the form /node0/node1/...
static Int_t fgNumThreads
! Number of registered threads
TObjArray * fGDMLMatrices
TGeoPhysicalNode * MakeAlignablePN(const char *name)
Make a physical node from the path pointed by an alignable object with a given name.
void SetCheckedNode(TGeoNode *node)
Assign a given node to be checked for overlaps. Any other overlaps will be ignored.
Int_t AddOverlap(const TNamed *ovlp)
Add an illegal overlap/extrusion to the list.
void CreateThreadData() const
Create thread private data for all geometry objects.
Int_t fNsegments
Definition TGeoManager.h:78
TObjArray * fOverlaps
TGeoNode * SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil=1E-5, const char *g3path="")
shoot npoints randomly in a box of 1E-5 around current point.
Bool_t IsMultiThread() const
TGDMLMatrix * GetGDMLMatrix(const char *name) const
Get GDML matrix with a given name;.
Double_t fTmax
! upper time limit for tracks drawing
Definition TGeoManager.h:70
void InvalidateMeshCaches()
Invalidate mesh caches built by composite shapes.
Int_t TransformVolumeToAssembly(const char *vname)
Transform all volumes named VNAME to assemblies. The volumes must be virtual.
Bool_t fMultiThread
! Flag for multi-threading
TGeoVolume * MakePgon(const char *name, TGeoMedium *medium, Double_t phi, Double_t dphi, Int_t nedges, Int_t nz)
Make in one step a volume pointing to a polygone shape with given medium.
TGeoVolume * MakeTrap(const char *name, TGeoMedium *medium, Double_t dz, Double_t theta, Double_t phi, Double_t h1, Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2, Double_t tl2, Double_t alpha2)
Make in one step a volume pointing to a trapezoid shape with given medium.
void DrawCurrentPoint(Int_t color=2)
Draw current point in the same view.
static void SetVerboseLevel(Int_t vl)
Return current verbosity level (static function).
TGeoOpticalSurface * GetOpticalSurface(const char *name) const
Get optical surface with a given name;.
void SetNsegments(Int_t nseg)
Set number of segments for approximating circles in drawing.
static UInt_t GetExportPrecision()
Bool_t IsSamePoint(Double_t x, Double_t y, Double_t z) const
Check if a new point with given coordinates is the same as the last located one.
void SetNmeshPoints(Int_t npoints=1000)
Set the number of points to be generated on the shape outline when checking for overlaps.
void CheckBoundaryReference(Int_t icheck=-1)
Check the boundary errors reference file created by CheckBoundaryErrors method.
static Int_t GetVerboseLevel()
Set verbosity level (static function).
Int_t GetVisLevel() const
Returns current depth to which geometry is drawn.
static EDefaultUnits fgDefaultUnits
! Default units in GDML if not explicit in some tags
Definition TGeoManager.h:61
virtual void Edit(Option_t *option="")
Append a pad for this geometry.
Bool_t AddProperty(const char *property, Double_t value)
Add a user-defined property. Returns true if added, false if existing.
~TGeoManager() override
Destructor.
TObjArray * fNodes
Int_t CountNodes(const TGeoVolume *vol=nullptr, Int_t nlevels=10000, Int_t option=0)
Count the total number of nodes starting from a volume, nlevels down.
TGeoMaterial * GetMaterial(const char *matname) const
Search for a named material. All trailing blanks stripped.
void CheckGeometry(Option_t *option="")
Perform last checks on the geometry.
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute mouse actions on this manager.
TGeoVolumeAssembly * MakeVolumeAssembly(const char *name)
Make an assembly of volumes.
Int_t GetBombMode() const
Int_t AddRegion(TGeoRegion *region)
Add a new region of volumes.
void SelectTrackingMedia()
Define different tracking media.
void CdNext()
Do a cd to the node found next by FindNextBoundary.
void CdTop()
Make top level node the current node.
Double_t Safety(Bool_t inside=kFALSE)
Compute safe distance from the current point.
Int_t * fKeyPNEId
void DefaultAngles()
Set default angles for a given view.
TGeoMaterial * Mixture(const char *name, Float_t *a, Float_t *z, Double_t dens, Int_t nelem, Float_t *wmat, Int_t uid)
Create mixture OR COMPOUND IMAT as composed by THE BASIC nelem materials defined by arrays A,...
std::map< std::thread::id, Int_t > ThreadsMap_t
void CheckPoint(Double_t x=0, Double_t y=0, Double_t z=0, Option_t *option="", Double_t safety=0.)
Classify a given point. See TGeoChecker::CheckPoint().
void SetUseParallelWorldNav(Bool_t flag)
Activate/deactivate usage of parallel world navigation.
void Browse(TBrowser *b) override
Describe how to browse this object.
void Test(Int_t npoints=1000000, Option_t *option="")
Check time of finding "Where am I" for n points.
Int_t GetSafeLevel() const
Go upwards the tree until a non-overlapping node.
TObjArray * fGVolumes
! list of runtime volumes
void SetBombFactors(Double_t bombx=1.3, Double_t bomby=1.3, Double_t bombz=1.3, Double_t bombr=1.3)
Set factors that will "bomb" all translations in cartesian and cylindrical coordinates.
TGeoNode * fTopNode
! top physical node
void UnbombTranslation(const Double_t *tr, Double_t *bombtr)
Get the new 'unbombed' translation vector according current exploded view mode.
void ResetState()
Reset current state flags.
void RandomPoints(const TGeoVolume *vol, Int_t npoints=10000, Option_t *option="")
Draw random points in the bounding box of a volume.
TGeoParallelWorld * CreateParallelWorld(const char *name)
Create a parallel world for prioritised navigation.
Int_t GetMaterialIndex(const char *matname) const
Return index of named material.
void CdDown(Int_t index)
Make a daughter of current node current.
TGeoNavigatorArray * GetListOfNavigators() const
Get list of navigators for the calling thread.
static Int_t GetMaxXtruVert()
Return maximum number of vertices for an xtru shape used.
void RandomRays(Int_t nrays=1000, Double_t startx=0, Double_t starty=0, Double_t startz=0, const char *target_vol=nullptr, Bool_t check_norm=kFALSE)
Randomly shoot nrays and plot intersections with surfaces for current top node.
void SetAllIndex()
Assigns uid's for all materials,media and matrices.
TObjArray * fSkinSurfaces
void SetVisDensity(Double_t dens=0.01)
Set density threshold.
Int_t fExplodedView
Definition TGeoManager.h:75
Bool_t fClosed
! flag that geometry is closed
Definition TGeoManager.h:84
Int_t GetNsegments() const
Get number of segments approximating circles.
void SetPhiRange(Double_t phimin=0., Double_t phimax=360.)
Set cut phi range.
TGeoHMatrix * fGLMatrix
TVirtualGeoTrack * fCurrentTrack
! current track
Definition TGeoManager.h:81
TObjArray * fPdgNames
void DrawPath(const char *path, Option_t *option="")
Draw current path.
TObjArray * GetListOfPhysicalNodes()
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
Bool_t SetCurrentNavigator(Int_t index)
Switch to another existing navigator for the calling thread.
void SetTopVisible(Bool_t vis=kTRUE)
make top volume visible on screen
TGeoVolume * MakeHype(const char *name, TGeoMedium *medium, Double_t rin, Double_t stin, Double_t rout, Double_t stout, Double_t dz)
Make in one step a volume pointing to a tube shape with given medium.
TGeoVolume * MakeParaboloid(const char *name, TGeoMedium *medium, Double_t rlo, Double_t rhi, Double_t dz)
Make in one step a volume pointing to a tube shape with given medium.
Int_t AddShape(const TGeoShape *shape)
Add a shape to the list. Returns index of the shape in list.
void SetMaxVisNodes(Int_t maxnodes=10000)
set the maximum number of visible nodes.
void CleanGarbage()
Clean temporary volumes and shapes from garbage collection.
void Voxelize(Option_t *option=nullptr)
Voxelize all non-divided volumes.
Int_t GetVirtualLevel()
Find level of virtuality of current overlapping node (number of levels up having the same tracking me...
TGeoBorderSurface * GetBorderSurface(const char *name) const
Get border surface with a given name;.
void ClearThreadData() const
Int_t fSizePNEId
void CheckOverlaps(Double_t ovlp=0.1, Option_t *option="")
Check all geometry for illegal overlaps within a limit OVLP.
TGeoVolume * MakeTubs(const char *name, TGeoMedium *medium, Double_t rmin, Double_t rmax, Double_t dz, Double_t phi1, Double_t phi2)
Make in one step a volume pointing to a tube segment shape with given medium.
Int_t fPdgId[1024]
Definition TGeoManager.h:83
void SortOverlaps()
Sort overlaps by decreasing overlap distance. Extrusions comes first.
TGeoVolume * MakeEltu(const char *name, TGeoMedium *medium, Double_t a, Double_t b, Double_t dz)
Make in one step a volume pointing to a tube shape with given medium.
void RemoveNavigator(const TGeoNavigator *nav)
Clear a single navigator.
void MasterToTop(const Double_t *master, Double_t *top) const
Convert coordinates from master volume frame to top.
Bool_t fStreamVoxels
Definition TGeoManager.h:86
Base class describing materials.
Geometrical transformation package.
Definition TGeoMatrix.h:39
@ kGeoSavePrimitive
Definition TGeoMatrix.h:49
Media are used to store properties related to tracking and which are useful only when using geometry ...
Definition TGeoMedium.h:23
@ kMedSavePrimitive
Definition TGeoMedium.h:25
Mixtures of elements.
Int_t GetNelements() const override
TGeoElement * GetElement(Int_t i=0) const override
Retrieve the pointer to the element corresponding to component I.
TGeoNavigator * AddNavigator()
Add a new navigator to the array.
TGeoNavigator * GetCurrentNavigator() const
TGeoNavigator * SetCurrentNavigator(Int_t inav)
Class providing navigation API for TGeo geometries.
void CdUp()
Go one level up in geometry.
void DoBackupState()
Backup the current state without affecting the cache stack.
void DoRestoreState()
Restore a backed-up state without affecting the cache stack.
TGeoNode * CrossBoundaryAndLocate(Bool_t downwards, TGeoNode *skipnode)
Cross next boundary and locate within current node The current point must be on the boundary of fCurr...
TGeoHMatrix * GetHMatrix()
Return stored current matrix (global matrix of the next touched node).
void LocalToMaster(const Double_t *local, Double_t *master) const
void CdNext()
Do a cd to the node found next by FindNextBoundary.
Double_t Safety(Bool_t inside=kFALSE)
Compute safe distance from the current point.
Bool_t GotoSafeLevel()
Go upwards the tree until a non-overlapping node.
Bool_t cd(const char *path="")
Browse the tree of nodes starting from top node according to pathname.
Bool_t IsSameLocation(Double_t x, Double_t y, Double_t z, Bool_t change=kFALSE)
Checks if point (x,y,z) is still in the current node.
void MasterToLocal(const Double_t *master, Double_t *local) const
Int_t GetVirtualLevel()
Find level of virtuality of current overlapping node (number of levels up having the same tracking me...
TGeoNode * InitTrack(const Double_t *point, const Double_t *dir)
Initialize current point and current direction vector (normalized) in MARS.
void InspectState() const
Inspects path and all flags for the current state.
TGeoNode * Step(Bool_t is_geom=kTRUE, Bool_t cross=kTRUE)
Make a rectiliniar step of length fStep from current point (fPoint) on current direction (fDirection)...
TGeoVolume * GetCurrentVolume() const
void ResetState()
Reset current state flags.
TGeoNode * FindNextDaughterBoundary(Double_t *point, Double_t *dir, Int_t &idaughter, Bool_t compmatrix=kFALSE)
Computes as fStep the distance to next daughter of the current volume.
void GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
Fill node copy numbers of current branch into an array.
Bool_t CheckPath(const char *path) const
Check if a geometry path is valid without changing the state of the navigator.
TGeoNode * FindNextBoundary(Double_t stepmax=TGeoShape::Big(), const char *path="", Bool_t frombdr=kFALSE)
Find distance to next boundary and store it in fStep.
TGeoNode * FindNode(Bool_t safe_start=kTRUE)
Returns deepest node containing current point.
TGeoNode * FindNextBoundaryAndStep(Double_t stepmax=TGeoShape::Big(), Bool_t compsafe=kFALSE)
Compute distance to next boundary within STEPMAX.
void CdTop()
Make top level node the current node.
Int_t GetCurrentNodeId() const
Double_t * FindNormalFast()
Computes fast normal to next crossed boundary, assuming that the current point is close enough to the...
void GetBranchOnlys(Int_t *isonly) const
Fill node copy numbers of current branch into an array.
TGeoNode * SearchNode(Bool_t downwards=kFALSE, const TGeoNode *skipnode=nullptr)
Returns the deepest node containing fPoint, which must be set a priori.
void CdNode(Int_t nodeid)
Change current path to point to the node having this id.
Bool_t IsSamePoint(Double_t x, Double_t y, Double_t z) const
Check if a new point with given coordinates is the same as the last located one.
void CdDown(Int_t index)
Make a daughter of current node current.
const char * GetPath() const
Get path to the current node in the form /node0/node1/...
Int_t GetSafeLevel() const
Go upwards the tree until a non-overlapping node.
Double_t * FindNormal(Bool_t forward=kTRUE)
Computes normal vector to the next surface that will be or was already crossed when propagating on a ...
void GetBranchNames(Int_t *names) const
Fill volume names of current branch into an array.
A node containing local transformation.
Definition TGeoNode.h:155
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition TGeoNode.h:39
Bool_t IsOverlapping() const
Definition TGeoNode.h:108
TGeoVolume * GetVolume() const
Definition TGeoNode.h:100
void SaveAttributes(std::ostream &out)
save attributes for this node
Definition TGeoNode.cxx:563
void SetVolume(TGeoVolume *volume)
Definition TGeoNode.h:118
void CheckOverlapsBySampling(Double_t ovlp=0.1, Int_t npoints=1000000)
Check overlaps bigger than OVLP hierarchically, starting with this node.
Definition TGeoNode.cxx:198
void CheckShapes()
check for wrong parameters in shapes
Definition TGeoNode.cxx:453
void SetOverlapping(Bool_t flag=kTRUE)
Definition TGeoNode.h:121
Int_t GetNdaughters() const
Definition TGeoNode.h:92
virtual TGeoMatrix * GetMatrix() const =0
void SetVisibility(Bool_t vis=kTRUE) override
Set visibility of the node (obsolete).
Definition TGeoNode.cxx:842
void SetMotherVolume(TGeoVolume *mother)
Definition TGeoNode.h:126
static TClass * Class()
TGeoVolume * GetMotherVolume() const
Definition TGeoNode.h:91
void SetNumber(Int_t number)
Definition TGeoNode.h:119
void CheckOverlaps(Double_t ovlp=0.1, Option_t *option="")
Check overlaps bigger than OVLP hierarchically, starting with this node.
Definition TGeoNode.cxx:246
This is a wrapper class to G4OpticalSurface.
The knowledge of the path to the objects that need to be misaligned is essential since there is no ot...
Base class for a flat parallel geometry.
Bool_t CloseGeometry()
The main geometry must be closed.
void RefreshPhysicalNodes()
Refresh the node pointers and re-voxelize.
Bool_t IsClosed() const
Physical nodes are the actual 'touchable' objects in the geometry, representing a path of positioned ...
Regions are groups of volumes having a common set of user tracking cuts.
Definition TGeoRegion.h:36
Base abstract class for all shapes.
Definition TGeoShape.h:25
virtual Bool_t IsComposite() const
Definition TGeoShape.h:139
Bool_t IsRunTimeShape() const
Definition TGeoShape.h:152
virtual void ComputeBBox()=0
virtual void AfterStreamer()
Definition TGeoShape.h:101
@ kGeoClosedShape
Definition TGeoShape.h:59
TClass * IsA() const override
Definition TGeoShape.h:181
Bool_t TestShapeBit(UInt_t f) const
Definition TGeoShape.h:177
Volume assemblies.
Definition TGeoVolume.h:319
static TGeoVolumeAssembly * MakeAssemblyFromVolume(TGeoVolume *vol)
Make a clone of volume VOL but which is an assembly.
Volume families.
Definition TGeoVolume.h:269
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition TGeoVolume.h:45
Double_t WeightA() const
Analytical computation of the weight.
virtual void ClearThreadData() const
void SetVisibility(Bool_t vis=kTRUE) override
set visibility of this volume
void SetNumber(Int_t number)
Definition TGeoVolume.h:248
void SetLineWidth(Width_t lwidth) override
Set the line width.
TGeoMedium * GetMedium() const
Definition TGeoVolume.h:178
Int_t GetRefCount() const
Definition TGeoVolume.h:134
void SortNodes()
sort nodes by decreasing volume of the bounding box.
void Voxelize(Option_t *option)
build the voxels for this volume
Bool_t IsRunTime() const
Definition TGeoVolume.h:112
virtual void CreateThreadData(Int_t nthreads)
virtual Int_t GetByteCount() const
get the total size in bytes for this volume
Bool_t OptimizeVoxels()
Perform an extensive sampling to find which type of voxelization is most efficient.
virtual Bool_t IsVolumeMulti() const
Definition TGeoVolume.h:113
Int_t CountNodes(Int_t nlevels=1000, Int_t option=0)
Count total number of subnodes starting from this volume, nlevels down.
void UnmarkSaved()
Reset SavePrimitive bits.
void SetFinder(TGeoPatternFinder *finder)
Definition TGeoVolume.h:247
Int_t GetNdaughters() const
Definition TGeoVolume.h:371
void Grab()
Definition TGeoVolume.h:139
static TClass * Class()
void SetTransparency(Char_t transparency=0)
Definition TGeoVolume.h:386
void Release()
Definition TGeoVolume.h:140
void FindOverlaps() const
loop all nodes marked as overlaps and find overlapping brothers
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
virtual void SetMedium(TGeoMedium *medium)
Definition TGeoVolume.h:245
TGeoVoxelFinder * GetVoxels() const
Getter for optimization structure.
static TGeoMedium * DummyMedium()
void SetLineColor(Color_t lcolor) override
Set the line color.
Int_t GetNumber() const
Definition TGeoVolume.h:187
TGeoShape * GetShape() const
Definition TGeoVolume.h:193
void SaveAs(const char *filename="", Option_t *option="") const override
Save geometry having this as top volume as a C++ macro.
void SetField(TObject *field)
Definition TGeoVolume.h:234
static void CreateDummyMedium()
Create a dummy medium.
void SetLineStyle(Style_t lstyle) override
Set the line style.
virtual Bool_t IsAssembly() const
Returns true if the volume is an assembly or a scaled assembly.
TGeoVolume * MakeReflectedVolume(const char *newname="") const
Make a copy of this volume which is reflected with respect to XY plane.
virtual Bool_t IsVisible() const
Definition TGeoVolume.h:158
Finder class handling voxels.
A TGeoXtru shape is represented by the extrusion of an arbitrary polygon with fixed outline between s...
Definition TGeoXtru.h:25
static TClass * Class()
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
void Clear(Option_t *option="") override
Remove all objects from the list.
TObject * FindObject(const char *name) const override
Find object using its name.
void AddLast(TObject *obj) override
Add object at the end of the list.
Definition THashList.cxx:94
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
virtual const char * GetClassName() const
Definition TKey.h:77
virtual TObject * ReadObj()
To read a TObject* from the file.
Definition TKey.cxx:804
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:708
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:952
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:600
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:487
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:173
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
TNamed()
Definition TNamed.h:38
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:149
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
Int_t IndexOf(const TObject *obj) const override
void AddAt(TObject *obj, Int_t idx) override
Add object at position ids.
virtual void Sort(Int_t upto=kMaxInt)
If objects in array are sortable (i.e.
void Clear(Option_t *option="") override
Remove all objects from the array.
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
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:170
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:90
TObject * Remove(TObject *obj) override
Remove object from array.
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
void Add(TObject *obj) override
Definition TObjArray.h:68
Mother of all ROOT objects.
Definition TObject.h:42
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:461
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1082
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:424
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:203
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition TObject.cxx:987
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:886
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:548
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1124
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:897
virtual TClass * IsA() const
Definition TObject.h:248
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1070
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot.
Definition TQObject.cxx:865
Sequenceable collection abstract base class.
virtual Int_t IndexOf(const TObject *obj) const
Return index of object in collection.
Basic string class.
Definition TString.h:137
Ssiz_t Length() const
Definition TString.h:426
void ToLower()
Change string to lower-case.
Definition TString.cxx:1190
const char * Data() const
Definition TString.h:385
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2460
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:642
Abstract class for geometry checkers.
virtual void CheckPoint(Double_t x=0, Double_t y=0, Double_t z=0, Option_t *option="", Double_t safety=0.)=0
virtual void CheckGeometryFull(Bool_t checkoverlaps=kTRUE, Bool_t checkcrossings=kTRUE, Int_t nrays=10000, const Double_t *vertex=nullptr)=0
virtual void CheckShape(TGeoShape *shape, Int_t testNo, Int_t nsamples, Option_t *option)=0
virtual void RandomPoints(TGeoVolume *vol, Int_t npoints, Option_t *option)=0
void SetNmeshPoints(Int_t npoints=1000)
Set number of points to be generated on the shape outline when checking for overlaps.
virtual void Test(Int_t npoints, Option_t *option)=0
virtual void CheckBoundaryReference(Int_t icheck=-1)=0
virtual Double_t Weight(Double_t precision=0.01, Option_t *option="v")=0
virtual void CheckBoundaryErrors(Int_t ntracks=1000000, Double_t radius=-1.)=0
virtual TGeoNode * SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil, const char *g3path)=0
virtual void SetSelectedNode(TGeoNode *node)=0
virtual void TestOverlaps(const char *path)=0
virtual void RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol=nullptr, Bool_t check_norm=kFALSE)=0
Abstract class for geometry painters.
virtual void SetTopVisible(Bool_t vis=kTRUE)=0
virtual Int_t GetVisLevel() const =0
virtual void DrawPath(const char *path, Option_t *option="")=0
virtual void ModifiedPad(Bool_t update=kFALSE) const =0
virtual void GetViewAngles(Double_t &, Double_t &, Double_t &)
virtual TVirtualGeoTrack * AddTrack(Int_t id, Int_t pdgcode, TObject *particle)=0
virtual void SetExplodedView(Int_t iopt=0)=0
virtual Bool_t IsRaytracing() const =0
virtual void DrawCurrentPoint(Int_t color)=0
virtual void GrabFocus(Int_t nfr=0, Double_t dlong=0, Double_t dlat=0, Double_t dpsi=0)=0
virtual void SetVisOption(Int_t option=0)=0
virtual Double_t * GetViewBox()=0
virtual void EstimateCameraMove(Double_t, Double_t, Double_t *, Double_t *)
virtual void SetNsegments(Int_t nseg=20)=0
virtual Int_t CountVisibleNodes()=0
virtual void DefaultAngles()=0
virtual void UnbombTranslation(const Double_t *tr, Double_t *bombtr)=0
virtual void EditGeometry(Option_t *option="")=0
virtual void GetBombFactors(Double_t &bombx, Double_t &bomby, Double_t &bombz, Double_t &bombr) const =0
virtual void BombTranslation(const Double_t *tr, Double_t *bombtr)=0
virtual void ExecuteManagerEvent(TGeoManager *geom, Int_t event, Int_t px, Int_t py)=0
virtual void SetBombFactors(Double_t bombx=1.3, Double_t bomby=1.3, Double_t bombz=1.3, Double_t bombr=1.3)=0
Base class for user-defined tracks attached to a geometry.
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
TH1F * h1
Definition legend1.C:5
void EnableThreadSafety()
Enable support for multi-threading within the ROOT code in particular, enables the global mutex to ma...
Definition TROOT.cxx:579
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Definition TMath.h:659
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:329
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition TMath.h:75