Logo ROOT  
Reference Guide
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/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 $ROOTSYS/tutorials/geom/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.
214
215\image html geom_checkpoint.jpg
216
217#### Shooting random points.
218 Can be called from TGeoVolume::RandomPoints() (context menu function) and
219it will draw this volume with current visualization settings. Random points
220are generated in the bounding box of the top drawn volume. The points are
221classified and drawn with the color of their deepest container. Only points
222in visible nodes will be drawn.
223
224\image html geom_random1.jpg
225
226
227#### Raytracing.
228 Can be called from TGeoVolume::RandomRays() (context menu of volumes) and
229will shoot rays from a given point in the local reference frame with random
230directions. The intersections with displayed nodes will appear as segments
231having the color of the touched node. Drawn geometry will be then made invisible
232in order to enhance rays.
233
234\image html geom_random2.jpg
235*/
236
237#include <cstdlib>
238#include <iostream>
239#include <fstream>
240
241#include "TROOT.h"
242#include "TGeoManager.h"
243#include "TStyle.h"
244#include "TVirtualPad.h"
245#include "TBrowser.h"
246#include "TFile.h"
247#include "TKey.h"
248#include "THashList.h"
249#include "TClass.h"
250#include "ThreadLocalStorage.h"
251#include "TBufferText.h"
252
253#include "TGeoVoxelFinder.h"
254#include "TGeoElement.h"
255#include "TGeoMaterial.h"
256#include "TGeoMedium.h"
257#include "TGeoMatrix.h"
258#include "TGeoNode.h"
259#include "TGeoPhysicalNode.h"
260#include "TGeoPara.h"
261#include "TGeoParaboloid.h"
262#include "TGeoTube.h"
263#include "TGeoEltu.h"
264#include "TGeoHype.h"
265#include "TGeoCone.h"
266#include "TGeoSphere.h"
267#include "TGeoArb8.h"
268#include "TGeoPgon.h"
269#include "TGeoTrd1.h"
270#include "TGeoTrd2.h"
271#include "TGeoTorus.h"
272#include "TGeoXtru.h"
273#include "TGeoCompositeShape.h"
274#include "TGeoBoolNode.h"
275#include "TGeoBuilder.h"
276#include "TVirtualGeoPainter.h"
277#include "TPluginManager.h"
278#include "TVirtualGeoTrack.h"
279#include "TQObject.h"
280#include "TMath.h"
281#include "TEnv.h"
282#include "TGeoParallelWorld.h"
283#include "TGeoRegion.h"
284#include "TGDMLMatrix.h"
285#include "TGeoOpticalSurface.h"
286
287// statics and globals
288
290
292
293std::mutex TGeoManager::fgMutex;
305
306////////////////////////////////////////////////////////////////////////////////
307/// Default constructor.
308
310{
314 fTmin = 0.;
315 fTmax = 999.;
316 fPhiCut = kFALSE;
317 fPhimin = 0;
318 fPhimax = 360;
323 fClosed = kFALSE;
325 fBits = 0;
327 fMaterials = 0;
328 fHashPNE = 0;
329 fArrayPNE = 0;
330 fMatrices = 0;
331 fNodes = 0;
332 fOverlaps = 0;
333 fRegions = 0;
334 fNNodes = 0;
335 fMaxVisNodes = 10000;
336 fVolumes = 0;
337 fPhysicalNodes = 0;
338 fShapes = 0;
339 fGVolumes = 0;
340 fGShapes = 0;
341 fTracks = 0;
342 fMedia = 0;
343 fNtracks = 0;
344 fNpdg = 0;
345 fPdgNames = 0;
346 fGDMLMatrices = 0;
348 fSkinSurfaces = 0;
349 fBorderSurfaces = 0;
350 memset(fPdgId, 0, 1024*sizeof(Int_t));
351// TObjArray *fNavigators; //! list of navigators
352 fCurrentTrack = 0;
353 fCurrentVolume = 0;
354 fTopVolume = 0;
355 fTopNode = 0;
356 fMasterVolume = 0;
357 fPainter = 0;
360 fVisDensity = 0.;
361 fVisLevel = 3;
362 fVisOption = 1;
363 fExplodedView = 0;
364 fNsegments = 20;
365 fNLevel = 0;
366 fUniqueVolumes = 0;
367 fClippingShape = 0;
370 fGLMatrix = 0;
371 fPaintVolume = 0;
373 fElementTable = 0;
374 fHashVolumes = 0;
375 fHashGVolumes = 0;
376 fSizePNEId = 0;
377 fNPNEId = 0;
378 fKeyPNEId = 0;
379 fValuePNEId = 0;
381 fRaytraceMode = 0;
382 fMaxThreads = 0;
384 fParallelWorld = 0;
386 } else {
387 Init();
390 }
391}
392
393////////////////////////////////////////////////////////////////////////////////
394/// Constructor.
395
396TGeoManager::TGeoManager(const char *name, const char *title)
397 :TNamed(name, title)
398{
399 if (!gROOT->GetListOfGeometries()->FindObject(this)) gROOT->GetListOfGeometries()->Add(this);
400 if (!gROOT->GetListOfBrowsables()->FindObject(this)) gROOT->GetListOfBrowsables()->Add(this);
401 Init();
402 gGeoIdentity = new TGeoIdentity("Identity");
404 if (fgVerboseLevel>0) Info("TGeoManager","Geometry %s, %s created", GetName(), GetTitle());
405}
406
407////////////////////////////////////////////////////////////////////////////////
408/// Initialize manager class.
409
411{
412 if (gGeoManager) {
413 Warning("Init","Deleting previous geometry: %s/%s",gGeoManager->GetName(),gGeoManager->GetTitle());
414 delete gGeoManager;
415 if (fgLock) Fatal("Init", "New geometry created while the old one locked !!!");
416 }
417
418 gGeoManager = this;
421 fTmin = 0.;
422 fTmax = 999.;
423 fPhiCut = kFALSE;
424 fPhimin = 0;
425 fPhimax = 360;
430 fClosed = kFALSE;
432 fBits = new UChar_t[50000]; // max 25000 nodes per volume
434 fHashPNE = new THashList(256,3);
435 fArrayPNE = 0;
436 fMaterials = new THashList(200,3);
437 fMatrices = new TObjArray(256);
438 fNodes = new TObjArray(30);
439 fOverlaps = new TObjArray(256);
440 fRegions = new TObjArray(256);
441 fNNodes = 0;
442 fMaxVisNodes = 10000;
443 fVolumes = new TObjArray(256);
444 fPhysicalNodes = new TObjArray(256);
445 fShapes = new TObjArray(256);
446 fGVolumes = new TObjArray(256);
447 fGShapes = new TObjArray(256);
448 fTracks = new TObjArray(256);
449 fMedia = new THashList(200,3);
450 fNtracks = 0;
451 fNpdg = 0;
452 fPdgNames = 0;
453 fGDMLMatrices = new TObjArray();
455 fSkinSurfaces = new TObjArray();
457 memset(fPdgId, 0, 1024*sizeof(Int_t));
458 fCurrentTrack = 0;
459 fCurrentVolume = 0;
460 fTopVolume = 0;
461 fTopNode = 0;
462 fMasterVolume = 0;
463 fPainter = 0;
466 fVisDensity = 0.;
467 fVisLevel = 3;
468 fVisOption = 1;
469 fExplodedView = 0;
470 fNsegments = 20;
471 fNLevel = 0;
472 fUniqueVolumes = new TObjArray(256);
473 fClippingShape = 0;
476 fGLMatrix = new TGeoHMatrix();
477 fPaintVolume = 0;
479 fElementTable = 0;
480 fHashVolumes = 0;
481 fHashGVolumes = 0;
482 fSizePNEId = 0;
483 fNPNEId = 0;
484 fKeyPNEId = 0;
485 fValuePNEId = 0;
487 fRaytraceMode = 0;
488 fMaxThreads = 0;
490 fParallelWorld = 0;
492}
493
494////////////////////////////////////////////////////////////////////////////////
495/// Destructor
496
498{
499 if (gGeoManager != this) gGeoManager = this;
501
502 if (gROOT->GetListOfFiles()) { //in case this function is called from TROOT destructor
503 gROOT->GetListOfGeometries()->Remove(this);
504 gROOT->GetListOfBrowsables()->Remove(this);
505 }
506// TSeqCollection *brlist = gROOT->GetListOfBrowsers();
507// TIter next(brlist);
508// TBrowser *browser = 0;
509// while ((browser=(TBrowser*)next())) browser->RecursiveRemove(this);
512 delete TGeoBuilder::Instance(this);
513 if (fBits) delete [] fBits;
521 if (fHashVolumes) { fHashVolumes->Clear("nodelete"); SafeDelete(fHashVolumes); }
524 if (fArrayPNE) {delete fArrayPNE;}
537 CleanGarbage();
540 if (fSizePNEId) {
541 delete [] fKeyPNEId;
542 delete [] fValuePNEId;
543 }
544 delete fParallelWorld;
546 gGeoIdentity = 0;
547 gGeoManager = 0;
548}
549
550////////////////////////////////////////////////////////////////////////////////
551/// Add a material to the list. Returns index of the material in list.
552
554{
555 return TGeoBuilder::Instance(this)->AddMaterial((TGeoMaterial*)material);
556}
557
558////////////////////////////////////////////////////////////////////////////////
559/// Add an illegal overlap/extrusion to the list.
560
562{
564 fOverlaps->Add((TObject*)ovlp);
565 return size;
566}
567
568////////////////////////////////////////////////////////////////////////////////
569/// Add a new region of volumes.
571{
573 fRegions->Add(region);
574 return size;
575}
576
577////////////////////////////////////////////////////////////////////////////////
578/// Add a user-defined property. Returns true if added, false if existing.
579
581{
582 auto pos = fProperties.insert(ConstPropMap_t::value_type(property, value));
583 if (!pos.second) {
584 Warning("AddProperty", "Property \"%s\" already exists with value %g", property, (pos.first)->second);
585 return false;
586 }
587 return true;
588}
589
590////////////////////////////////////////////////////////////////////////////////
591/// Get a user-defined property
592
594{
595 auto pos = fProperties.find(property);
596 if (pos == fProperties.end()) {
597 if (error) *error = kTRUE;
598 return 0.;
599 }
600 if (error) *error = kFALSE;
601 return pos->second;
602}
603
604////////////////////////////////////////////////////////////////////////////////
605/// Get a user-defined property from a given index
606
608{
609 // This is a quite inefficient way to access map elements, but needed for the GDML writer to
610 if (i >= fProperties.size()) {
611 if (error) *error = kTRUE;
612 return 0.;
613 }
614 size_t pos = 0;
615 auto it = fProperties.begin();
616 while (pos < i) { ++it; ++pos; }
617 if (error) *error = kFALSE;
618 name = (*it).first;
619 return (*it).second;
620}
621
622////////////////////////////////////////////////////////////////////////////////
623/// Add a matrix to the list. Returns index of the matrix in list.
624
626{
627 return TGeoBuilder::Instance(this)->AddTransformation((TGeoMatrix*)matrix);
628}
629
630////////////////////////////////////////////////////////////////////////////////
631/// Add a shape to the list. Returns index of the shape in list.
632
634{
635 return TGeoBuilder::Instance(this)->AddShape((TGeoShape*)shape);
636}
637
638////////////////////////////////////////////////////////////////////////////////
639/// Add a track to the list of tracks. Use this for primaries only. For secondaries,
640/// add them to the parent track. The method create objects that are registered
641/// to the analysis manager but have to be cleaned-up by the user via ClearTracks().
642
644{
646 fTracks->AddAtAndExpand(GetGeomPainter()->AddTrack(id,pdgcode,particle),fNtracks++);
647 return index;
648}
649
650////////////////////////////////////////////////////////////////////////////////
651/// Add a track to the list of tracks
652
654{
657 return index;
658}
659
660////////////////////////////////////////////////////////////////////////////////
661/// Makes a primary track but do not attach it to the list of tracks. The track
662/// can be attached as daughter to another one with TVirtualGeoTrack::AddTrack
663
665{
666 TVirtualGeoTrack *track = GetGeomPainter()->AddTrack(id,pdgcode,particle);
667 return track;
668}
669
670////////////////////////////////////////////////////////////////////////////////
671/// Add a volume to the list. Returns index of the volume in list.
672
674{
675 if (!volume) {
676 Error("AddVolume", "invalid volume");
677 return -1;
678 }
680 if (!uid) uid++;
681 if (!fCurrentVolume) {
682 fCurrentVolume = volume;
683 fUniqueVolumes->AddAtAndExpand(volume,uid);
684 } else {
685 if (!strcmp(volume->GetName(), fCurrentVolume->GetName())) {
686 uid = fCurrentVolume->GetNumber();
687 } else {
688 fCurrentVolume = volume;
689 Int_t olduid = GetUID(volume->GetName());
690 if (olduid<0) {
691 fUniqueVolumes->AddAtAndExpand(volume,uid);
692 } else {
693 uid = olduid;
694 }
695 }
696 }
697 volume->SetNumber(uid);
698 if (!fHashVolumes) {
699 fHashVolumes = new THashList(256);
700 fHashGVolumes = new THashList(256);
701 }
702 TObjArray *list = fVolumes;
703 if (!volume->GetShape() || volume->IsRunTime() || volume->IsVolumeMulti()) {
704 list = fGVolumes;
705 fHashGVolumes->Add(volume);
706 } else {
707 fHashVolumes->Add(volume);
708 }
709 Int_t index = list->GetEntriesFast();
710 list->AddAtAndExpand(volume,index);
711 return uid;
712}
713
714////////////////////////////////////////////////////////////////////////////////
715/// Add a navigator in the list of navigators. If it is the first one make it
716/// current navigator.
717
719{
720 if (fMultiThread) { TGeoManager::ThreadId(); fgMutex.lock(); }
721 std::thread::id threadId = std::this_thread::get_id();
722 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
723 TGeoNavigatorArray *array = 0;
724 if (it != fNavigators.end()) array = it->second;
725 else {
726 array = new TGeoNavigatorArray(this);
727 fNavigators.insert(NavigatorsMap_t::value_type(threadId, array));
728 }
729 TGeoNavigator *nav = array->AddNavigator();
730 if (fClosed) nav->GetCache()->BuildInfoBranch();
731 if (fMultiThread) fgMutex.unlock();
732 return nav;
733}
734
735////////////////////////////////////////////////////////////////////////////////
736/// Returns current navigator for the calling thread.
737
739{
740 TTHREAD_TLS(TGeoNavigator*) tnav = 0;
741 if (!fMultiThread) return fCurrentNavigator;
742 TGeoNavigator *nav = tnav; // TTHREAD_TLS_GET(TGeoNavigator*,tnav);
743 if (nav) return nav;
744 std::thread::id threadId = std::this_thread::get_id();
745 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
746 if (it == fNavigators.end()) return 0;
747 TGeoNavigatorArray *array = it->second;
748 nav = array->GetCurrentNavigator();
749 tnav = nav; // TTHREAD_TLS_SET(TGeoNavigator*,tnav,nav);
750 return nav;
751}
752
753////////////////////////////////////////////////////////////////////////////////
754/// Get list of navigators for the calling thread.
755
757{
758 std::thread::id threadId = std::this_thread::get_id();
759 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
760 if (it == fNavigators.end()) return 0;
761 TGeoNavigatorArray *array = it->second;
762 return array;
763}
764
765////////////////////////////////////////////////////////////////////////////////
766/// Switch to another existing navigator for the calling thread.
767
769{
770 std::thread::id threadId = std::this_thread::get_id();
771 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
772 if (it == fNavigators.end()) {
773 Error("SetCurrentNavigator", "No navigator defined for this thread\n");
774 std::cout << " thread id: " << threadId << std::endl;
775 return kFALSE;
776 }
777 TGeoNavigatorArray *array = it->second;
779 if (!nav) {
780 Error("SetCurrentNavigator", "Navigator %d not existing for this thread\n", index);
781 std::cout << " thread id: " << threadId << std::endl;
782 return kFALSE;
783 }
785 return kTRUE;
786}
787
788////////////////////////////////////////////////////////////////////////////////
789/// Set the lock for navigators.
790
792{
793 fgLockNavigators = flag;
794}
795
796////////////////////////////////////////////////////////////////////////////////
797/// Clear all navigators.
798
800{
801 if (fMultiThread) fgMutex.lock();
802 TGeoNavigatorArray *arr = 0;
803 for (NavigatorsMap_t::iterator it = fNavigators.begin();
804 it != fNavigators.end(); ++it) {
805 arr = (*it).second;
806 if (arr) delete arr;
807 }
808 fNavigators.clear();
809 if (fMultiThread) fgMutex.unlock();
810}
811
812////////////////////////////////////////////////////////////////////////////////
813/// Clear a single navigator.
814
816{
817 if (fMultiThread) fgMutex.lock();
818 for (NavigatorsMap_t::iterator it = fNavigators.begin(); it != fNavigators.end(); ++it) {
819 TGeoNavigatorArray *arr = (*it).second;
820 if (arr) {
821 if ((TGeoNavigator*)arr->Remove((TObject*)nav)) {
822 delete nav;
823 if (!arr->GetEntries()) fNavigators.erase(it);
824 if (fMultiThread) fgMutex.unlock();
825 return;
826 }
827 }
828 }
829 Error("Remove navigator", "Navigator %p not found", nav);
830 if (fMultiThread) fgMutex.unlock();
831}
832
833////////////////////////////////////////////////////////////////////////////////
834/// Set maximum number of threads for navigation.
835
837{
838 if (!fClosed) {
839 Error("SetMaxThreads", "Cannot set maximum number of threads before closing the geometry");
840 return;
841 }
842 if (!fMultiThread) {
844 std::thread::id threadId = std::this_thread::get_id();
845 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
846 if (it != fNavigators.end()) {
847 TGeoNavigatorArray *array = it->second;
848 fNavigators.erase(it);
849 fNavigators.insert(NavigatorsMap_t::value_type(threadId, array));
850 }
851 }
852 if (fMaxThreads) {
855 }
856 fMaxThreads = nthreads+1;
857 if (fMaxThreads>0) {
860 }
861}
862
863////////////////////////////////////////////////////////////////////////////////
864
866{
867 if (!fMaxThreads) return;
868 fgMutex.lock();
869 TIter next(fVolumes);
870 TGeoVolume *vol;
871 while ((vol=(TGeoVolume*)next())) vol->ClearThreadData();
872 fgMutex.unlock();
873}
874
875////////////////////////////////////////////////////////////////////////////////
876/// Create thread private data for all geometry objects.
877
879{
880 if (!fMaxThreads) return;
881 fgMutex.lock();
882 TIter next(fVolumes);
883 TGeoVolume *vol;
884 while ((vol=(TGeoVolume*)next())) vol->CreateThreadData(fMaxThreads);
885 fgMutex.unlock();
886}
887
888////////////////////////////////////////////////////////////////////////////////
889/// Clear the current map of threads. This will be filled again by the calling
890/// threads via ThreadId calls.
891
893{
894 if (gGeoManager && !gGeoManager->IsMultiThread()) return;
895 fgMutex.lock();
896 if (!fgThreadId->empty()) fgThreadId->clear();
897 fgNumThreads = 0;
898 fgMutex.unlock();
899}
900
901////////////////////////////////////////////////////////////////////////////////
902/// Translates the current thread id to an ordinal number. This can be used to
903/// manage data which is specific for a given thread.
904
906{
907 TTHREAD_TLS(Int_t) tid = -1;
908 Int_t ttid = tid; // TTHREAD_TLS_GET(Int_t,tid);
909 if (ttid > -1) return ttid;
910 if (gGeoManager && !gGeoManager->IsMultiThread()) return 0;
911 std::thread::id threadId = std::this_thread::get_id();
912 TGeoManager::ThreadsMapIt_t it = fgThreadId->find(threadId);
913 if (it != fgThreadId->end()) return it->second;
914 // Map needs to be updated.
915 fgMutex.lock();
916 (*fgThreadId)[threadId] = fgNumThreads;
917 tid = fgNumThreads; // TTHREAD_TLS_SET(Int_t,tid,fgNumThreads);
918 ttid = fgNumThreads++;
919 fgMutex.unlock();
920 return ttid;
921}
922
923////////////////////////////////////////////////////////////////////////////////
924/// Describe how to browse this object.
925
927{
928 if (!b) return;
929 if (fMaterials) b->Add(fMaterials, "Materials");
930 if (fMedia) b->Add(fMedia, "Media");
931 if (fMatrices) b->Add(fMatrices, "Local transformations");
932 if (fOverlaps) b->Add(fOverlaps, "Illegal overlaps");
933 if (fTracks) b->Add(fTracks, "Tracks");
934 if (fMasterVolume) b->Add(fMasterVolume, "Master Volume", fMasterVolume->IsVisible());
935 if (fTopVolume) b->Add(fTopVolume, "Top Volume", fTopVolume->IsVisible());
936 if (fTopNode) b->Add(fTopNode);
937 TString browserImp(gEnv->GetValue("Browser.Name", "TRootBrowserLite"));
938 TQObject::Connect(browserImp.Data(), "Checked(TObject*,Bool_t)",
939 "TGeoManager", this, "SetVisibility(TObject*,Bool_t)");
940}
941
942////////////////////////////////////////////////////////////////////////////////
943/// Append a pad for this geometry.
944
946 AppendPad("");
948}
949
950////////////////////////////////////////////////////////////////////////////////
951/// Set visibility for a volume.
952
954{
955 if(obj->IsA() == TGeoVolume::Class()) {
956 TGeoVolume *vol = (TGeoVolume *) obj;
957 vol->SetVisibility(vis);
958 } else {
959 if (obj->InheritsFrom(TGeoNode::Class())) {
960 TGeoNode *node = (TGeoNode *) obj;
961 node->SetVisibility(vis);
962 } else return;
963 }
965}
966
967////////////////////////////////////////////////////////////////////////////////
968/// Get the new 'bombed' translation vector according current exploded view mode.
969
971{
972 if (fPainter) fPainter->BombTranslation(tr, bombtr);
973 return;
974}
975
976////////////////////////////////////////////////////////////////////////////////
977/// Get the new 'unbombed' translation vector according current exploded view mode.
978
980{
981 if (fPainter) fPainter->UnbombTranslation(tr, bombtr);
982 return;
983}
984
985////////////////////////////////////////////////////////////////////////////////
986/// Backup the current state without affecting the cache stack.
987
989{
991}
992
993////////////////////////////////////////////////////////////////////////////////
994/// Restore a backed-up state without affecting the cache stack.
995
997{
999}
1000
1001////////////////////////////////////////////////////////////////////////////////
1002/// Register a matrix to the list of matrices. It will be cleaned-up at the
1003/// destruction TGeoManager.
1004
1006{
1007 return TGeoBuilder::Instance(this)->RegisterMatrix((TGeoMatrix*)matrix);
1008}
1009
1010////////////////////////////////////////////////////////////////////////////////
1011/// Replaces all occurrences of VORIG with VNEW in the geometry tree. The volume VORIG
1012/// is not replaced from the list of volumes, but all node referencing it will reference
1013/// VNEW instead. Returns number of occurrences changed.
1014
1016{
1017 Int_t nref = 0;
1018 if (!vorig || !vnew) return nref;
1019 TGeoMedium *morig = vorig->GetMedium();
1020 Bool_t checkmed = kFALSE;
1021 if (morig) checkmed = kTRUE;
1022 TGeoMedium *mnew = vnew->GetMedium();
1023 // Try to limit the damage produced by incorrect usage.
1024 if (!mnew && !vnew->IsAssembly()) {
1025 Error("ReplaceVolume","Replacement volume %s has no medium and it is not an assembly",
1026 vnew->GetName());
1027 return nref;
1028 }
1029 if (mnew && checkmed) {
1030 if (mnew->GetId() != morig->GetId())
1031 Warning("ReplaceVolume","Replacement volume %s has different medium than original volume %s",
1032 vnew->GetName(), vorig->GetName());
1033 checkmed = kFALSE;
1034 }
1035
1036 // Medium checking now performed only if replacement is an assembly and old volume a real one.
1037 // Check result is dependent on positioning.
1038 Int_t nvol = fVolumes->GetEntriesFast();
1039 Int_t i,j,nd;
1040 Int_t ierr = 0;
1041 TGeoVolume *vol;
1042 TGeoNode *node;
1043 TGeoVoxelFinder *voxels;
1044 for (i=0; i<nvol; i++) {
1045 vol = (TGeoVolume*)fVolumes->At(i);
1046 if (!vol) continue;
1047 if (vol==vorig || vol==vnew) continue;
1048 nd = vol->GetNdaughters();
1049 for (j=0; j<nd; j++) {
1050 node = vol->GetNode(j);
1051 if (node->GetVolume() == vorig) {
1052 if (checkmed) {
1053 mnew = node->GetMotherVolume()->GetMedium();
1054 if (mnew && mnew->GetId()!=morig->GetId()) ierr++;
1055 }
1056 nref++;
1057 if (node->IsOverlapping()) {
1058 node->SetOverlapping(kFALSE);
1059 Info("ReplaceVolume","%s replaced with assembly and declared NON-OVERLAPPING!",node->GetName());
1060 }
1061 node->SetVolume(vnew);
1062 voxels = node->GetMotherVolume()->GetVoxels();
1063 if (voxels) voxels->SetNeedRebuild();
1064 } else {
1065 if (node->GetMotherVolume() == vorig) {
1066 nref++;
1067 node->SetMotherVolume(vnew);
1068 if (node->IsOverlapping()) {
1069 node->SetOverlapping(kFALSE);
1070 Info("ReplaceVolume","%s inside substitute assembly %s declared NON-OVERLAPPING!",node->GetName(),vnew->GetName());
1071 }
1072 }
1073 }
1074 }
1075 }
1076 if (ierr) Warning("ReplaceVolume", "Volumes should not be replaced with assemblies if they are positioned in containers having a different medium ID.\n %i occurrences for assembly replacing volume %s",
1077 ierr, vorig->GetName());
1078 return nref;
1079}
1080
1081////////////////////////////////////////////////////////////////////////////////
1082/// Transform all volumes named VNAME to assemblies. The volumes must be virtual.
1083
1085{
1086 TGeoVolume *toTransform = FindVolumeFast(vname);
1087 if (!toTransform) {
1088 Warning("TransformVolumeToAssembly", "Volume %s not found", vname);
1089 return 0;
1090 }
1091 Int_t index = fVolumes->IndexOf(toTransform);
1092 Int_t count = 0;
1093 Int_t indmax = fVolumes->GetEntries();
1094 Bool_t replace = kTRUE;
1095 TGeoVolume *transformed;
1096 while (index<indmax) {
1097 if (replace) {
1098 replace = kFALSE;
1099 transformed = TGeoVolumeAssembly::MakeAssemblyFromVolume(toTransform);
1100 if (transformed) {
1101 ReplaceVolume(toTransform, transformed);
1102 count++;
1103 } else {
1104 if (toTransform->IsAssembly())
1105 Warning("TransformVolumeToAssembly", "Volume %s already assembly", toTransform->GetName());
1106 if (!toTransform->GetNdaughters())
1107 Warning("TransformVolumeToAssembly", "Volume %s has no daughters, cannot transform", toTransform->GetName());
1108 if (toTransform->IsVolumeMulti())
1109 Warning("TransformVolumeToAssembly", "Volume %s divided, cannot transform", toTransform->GetName());
1110 }
1111 }
1112 index++;
1113 if (index >= indmax) return count;
1114 toTransform = (TGeoVolume*)fVolumes->At(index);
1115 if (!strcmp(toTransform->GetName(),vname)) replace = kTRUE;
1116 }
1117 return count;
1118}
1119
1120////////////////////////////////////////////////////////////////////////////////
1121/// Create a new volume by dividing an existing one (GEANT3 like)
1122///
1123/// Divides MOTHER into NDIV divisions called NAME
1124/// along axis IAXIS starting at coordinate value START
1125/// and having size STEP. The created volumes will have tracking
1126/// media ID=NUMED (if NUMED=0 -> same media as MOTHER)
1127/// The behavior of the division operation can be triggered using OPTION :
1128///
1129/// OPTION (case insensitive) :
1130/// - N - divide all range in NDIV cells (same effect as STEP<=0) (GSDVN in G3)
1131/// - NX - divide range starting with START in NDIV cells (GSDVN2 in G3)
1132/// - S - divide all range with given STEP. NDIV is computed and divisions will be centered
1133/// in full range (same effect as NDIV<=0) (GSDVS, GSDVT in G3)
1134/// - SX - same as DVS, but from START position. (GSDVS2, GSDVT2 in G3)
1135
1136TGeoVolume *TGeoManager::Division(const char *name, const char *mother, Int_t iaxis,
1137 Int_t ndiv, Double_t start, Double_t step, Int_t numed, Option_t *option)
1138{
1139 return TGeoBuilder::Instance(this)->Division(name, mother, iaxis, ndiv, start, step, numed, option);
1140}
1141
1142////////////////////////////////////////////////////////////////////////////////
1143/// Create rotation matrix named 'mat<index>'.
1144///
1145/// - index rotation matrix number
1146/// - theta1 polar angle for axis X
1147/// - phi1 azimuthal angle for axis X
1148/// - theta2 polar angle for axis Y
1149/// - phi2 azimuthal angle for axis Y
1150/// - theta3 polar angle for axis Z
1151/// - phi3 azimuthal angle for axis Z
1152///
1153
1155 Double_t theta2, Double_t phi2,
1156 Double_t theta3, Double_t phi3)
1157{
1158 TGeoBuilder::Instance(this)->Matrix(index, theta1, phi1, theta2, phi2, theta3, phi3);
1159}
1160
1161////////////////////////////////////////////////////////////////////////////////
1162/// Create material with given A, Z and density, having an unique id.
1163
1165{
1166 return TGeoBuilder::Instance(this)->Material(name, a, z, dens, uid, radlen, intlen);
1167
1168}
1169
1170////////////////////////////////////////////////////////////////////////////////
1171/// Create mixture OR COMPOUND IMAT as composed by THE BASIC nelem
1172/// materials defined by arrays A,Z and WMAT, having an unique id.
1173
1175 Int_t nelem, Float_t *wmat, Int_t uid)
1176{
1177 return TGeoBuilder::Instance(this)->Mixture(name, a, z, dens, nelem, wmat, uid);
1178}
1179
1180////////////////////////////////////////////////////////////////////////////////
1181/// Create mixture OR COMPOUND IMAT as composed by THE BASIC nelem
1182/// materials defined by arrays A,Z and WMAT, having an unique id.
1183
1185 Int_t nelem, Double_t *wmat, Int_t uid)
1186{
1187 return TGeoBuilder::Instance(this)->Mixture(name, a, z, dens, nelem, wmat, uid);
1188}
1189
1190////////////////////////////////////////////////////////////////////////////////
1191/// Create tracking medium
1192///
1193/// - numed tracking medium number assigned
1194/// - name tracking medium name
1195/// - nmat material number
1196/// - isvol sensitive volume flag
1197/// - ifield magnetic field
1198/// - fieldm max. field value (kilogauss)
1199/// - tmaxfd max. angle due to field (deg/step)
1200/// - stemax max. step allowed
1201/// - deemax max. fraction of energy lost in a step
1202/// - epsil tracking precision (cm)
1203/// - stmin min. step due to continuous processes (cm)
1204///
1205/// - ifield = 0 if no magnetic field; ifield = -1 if user decision in guswim;
1206/// - ifield = 1 if tracking performed with g3rkuta; ifield = 2 if tracking
1207/// performed with g3helix; ifield = 3 if tracking performed with g3helx3.
1208///
1209
1210TGeoMedium *TGeoManager::Medium(const char *name, Int_t numed, Int_t nmat, Int_t isvol,
1211 Int_t ifield, Double_t fieldm, Double_t tmaxfd,
1212 Double_t stemax, Double_t deemax, Double_t epsil,
1213 Double_t stmin)
1214{
1215 return TGeoBuilder::Instance(this)->Medium(name, numed, nmat, isvol, ifield, fieldm, tmaxfd, stemax, deemax, epsil, stmin);
1216}
1217
1218////////////////////////////////////////////////////////////////////////////////
1219/// Create a node called `<name_nr>` pointing to the volume called `<name>`
1220/// as daughter of the volume called `<mother>` (gspos). The relative matrix is
1221/// made of : a translation (x,y,z) and a rotation matrix named `<matIROT>`.
1222/// In case npar>0, create the volume to be positioned in mother, according
1223/// its actual parameters (gsposp).
1224/// - NAME Volume name
1225/// - NUMBER Copy number of the volume
1226/// - MOTHER Mother volume name
1227/// - X X coord. of the volume in mother ref. sys.
1228/// - Y Y coord. of the volume in mother ref. sys.
1229/// - Z Z coord. of the volume in mother ref. sys.
1230/// - IROT Rotation matrix number w.r.t. mother ref. sys.
1231/// - ISONLY ONLY/MANY flag
1232
1233void TGeoManager::Node(const char *name, Int_t nr, const char *mother,
1234 Double_t x, Double_t y, Double_t z, Int_t irot,
1235 Bool_t isOnly, Float_t *upar, Int_t npar)
1236{
1237 TGeoBuilder::Instance(this)->Node(name, nr, mother, x, y, z, irot, isOnly, upar, npar);
1238}
1239
1240////////////////////////////////////////////////////////////////////////////////
1241/// Create a node called `<name_nr>` pointing to the volume called `<name>`
1242/// as daughter of the volume called `<mother>` (gspos). The relative matrix is
1243/// made of : a translation (x,y,z) and a rotation matrix named `<matIROT>`.
1244/// In case npar>0, create the volume to be positioned in mother, according
1245/// its actual parameters (gsposp).
1246/// - NAME Volume name
1247/// - NUMBER Copy number of the volume
1248/// - MOTHER Mother volume name
1249/// - X X coord. of the volume in mother ref. sys.
1250/// - Y Y coord. of the volume in mother ref. sys.
1251/// - Z Z coord. of the volume in mother ref. sys.
1252/// - IROT Rotation matrix number w.r.t. mother ref. sys.
1253/// - ISONLY ONLY/MANY flag
1254
1255void TGeoManager::Node(const char *name, Int_t nr, const char *mother,
1256 Double_t x, Double_t y, Double_t z, Int_t irot,
1257 Bool_t isOnly, Double_t *upar, Int_t npar)
1258{
1259 TGeoBuilder::Instance(this)->Node(name, nr, mother, x, y, z, irot, isOnly, upar, npar);
1260
1261}
1262
1263////////////////////////////////////////////////////////////////////////////////
1264/// Create a volume in GEANT3 style.
1265/// - NAME Volume name
1266/// - SHAPE Volume type
1267/// - NMED Tracking medium number
1268/// - NPAR Number of shape parameters
1269/// - UPAR Vector containing shape parameters
1270
1271TGeoVolume *TGeoManager::Volume(const char *name, const char *shape, Int_t nmed,
1272 Float_t *upar, Int_t npar)
1273{
1274 return TGeoBuilder::Instance(this)->Volume(name, shape, nmed, upar, npar);
1275}
1276
1277////////////////////////////////////////////////////////////////////////////////
1278/// Create a volume in GEANT3 style.
1279/// - NAME Volume name
1280/// - SHAPE Volume type
1281/// - NMED Tracking medium number
1282/// - NPAR Number of shape parameters
1283/// - UPAR Vector containing shape parameters
1284
1285TGeoVolume *TGeoManager::Volume(const char *name, const char *shape, Int_t nmed,
1286 Double_t *upar, Int_t npar)
1287{
1288 return TGeoBuilder::Instance(this)->Volume(name, shape, nmed, upar, npar);
1289}
1290
1291////////////////////////////////////////////////////////////////////////////////
1292/// Assigns uid's for all materials,media and matrices.
1293
1295{
1296 Int_t index = 1;
1297 TIter next(fMaterials);
1298 TGeoMaterial *mater;
1299 while ((mater=(TGeoMaterial*)next())) {
1300 mater->SetUniqueID(index++);
1302 }
1303 index = 1;
1304 TIter next1(fMedia);
1305 TGeoMedium *med;
1306 while ((med=(TGeoMedium*)next1())) {
1307 med->SetUniqueID(index++);
1309 }
1310 index = 1;
1311 TIter next2(fShapes);
1312 TGeoShape *shape;
1313 while ((shape=(TGeoShape*)next2())) {
1314 shape->SetUniqueID(index++);
1315 if (shape->IsComposite()) ((TGeoCompositeShape*)shape)->GetBoolNode()->RegisterMatrices();
1316 }
1317
1318 TIter next3(fMatrices);
1319 TGeoMatrix *matrix;
1320 while ((matrix=(TGeoMatrix*)next3())) {
1321 matrix->RegisterYourself();
1322 }
1323 TIter next4(fMatrices);
1324 index = 1;
1325 while ((matrix=(TGeoMatrix*)next4())) {
1326 matrix->SetUniqueID(index++);
1328 }
1329 TIter next5(fVolumes);
1330 TGeoVolume *vol;
1331 while ((vol=(TGeoVolume*)next5())) vol->UnmarkSaved();
1332}
1333
1334////////////////////////////////////////////////////////////////////////////////
1335/// Reset all attributes to default ones. Default attributes for visualization
1336/// are those defined before closing the geometry.
1337
1339{
1340 if (gPad) delete gPad;
1341 gPad = 0;
1342 SetVisOption(0);
1343 SetVisLevel(3);
1344 SetExplodedView(0);
1346 if (!gStyle) return;
1347 TIter next(fVolumes);
1348 TGeoVolume *vol = 0;
1349 while ((vol=(TGeoVolume*)next())) {
1350 if (!vol->IsVisTouched()) continue;
1351 vol->SetVisTouched(kFALSE);
1352 }
1353}
1354////////////////////////////////////////////////////////////////////////////////
1355/// Closing geometry implies checking the geometry validity, fixing shapes
1356/// with negative parameters (run-time shapes)building the cache manager,
1357/// voxelizing all volumes, counting the total number of physical nodes and
1358/// registering the manager class to the browser.
1359
1361{
1362 if (fClosed) {
1363 Warning("CloseGeometry", "geometry already closed");
1364 return;
1365 }
1366 if (!fMasterVolume) {
1367 Error("CloseGeometry","you MUST call SetTopVolume() first !");
1368 return;
1369 }
1370 if (!gROOT->GetListOfGeometries()->FindObject(this)) gROOT->GetListOfGeometries()->Add(this);
1371 if (!gROOT->GetListOfBrowsables()->FindObject(this)) gROOT->GetListOfBrowsables()->Add(this);
1372// TSeqCollection *brlist = gROOT->GetListOfBrowsers();
1373// TIter next(brlist);
1374// TBrowser *browser = 0;
1375// while ((browser=(TBrowser*)next())) browser->Refresh();
1376 TString opt(option);
1377 opt.ToLower();
1378// Bool_t dummy = opt.Contains("d");
1379 Bool_t nodeid = opt.Contains("i");
1380 // Create a geometry navigator if not present
1381 TGeoNavigator *nav = 0;
1382 Int_t nnavigators = 0;
1383 // Check if the geometry is streamed from file
1384 if (fIsGeomReading) {
1385 if (fgVerboseLevel>0) Info("CloseGeometry","Geometry loaded from file...");
1388 if (!fTopNode) {
1389 if (!fMasterVolume) {
1390 Error("CloseGeometry", "Master volume not streamed");
1391 return;
1392 }
1394 if (fStreamVoxels && fgVerboseLevel>0) Info("CloseGeometry","Voxelization retrieved from file");
1395 }
1396 // Create a geometry navigator if not present
1398 nnavigators = GetListOfNavigators()->GetEntriesFast();
1399 if (!opt.Contains("nv")) {
1400 Voxelize("ALL");
1401 }
1402 CountLevels();
1403 for (Int_t i=0; i<nnavigators; i++) {
1404 nav = (TGeoNavigator*)GetListOfNavigators()->At(i);
1405 nav->GetCache()->BuildInfoBranch();
1406 if (nodeid) nav->GetCache()->BuildIdArray();
1407 }
1408 if (!fHashVolumes) {
1409 Int_t nvol = fVolumes->GetEntriesFast();
1410 Int_t ngvol = fGVolumes->GetEntriesFast();
1411 fHashVolumes = new THashList(nvol+1);
1412 fHashGVolumes = new THashList(ngvol+1);
1413 Int_t i;
1414 for (i=0; i<ngvol; i++) fHashGVolumes->AddLast(fGVolumes->At(i));
1415 for (i=0; i<nvol; i++) fHashVolumes->AddLast(fVolumes->At(i));
1416 }
1417 fClosed = kTRUE;
1418 if (fParallelWorld) {
1419 if (fgVerboseLevel>0) Info("CloseGeometry","Recreating parallel world %s ...",fParallelWorld->GetName());
1421 }
1422
1423 if (fgVerboseLevel>0) Info("CloseGeometry","%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast()-1, GetTitle());
1424 if (fgVerboseLevel>0) Info("CloseGeometry","----------------modeler ready----------------");
1425 return;
1426 }
1427
1428 // Create a geometry navigator if not present
1430 nnavigators = GetListOfNavigators()->GetEntriesFast();
1432 CheckGeometry();
1433 if (fgVerboseLevel>0) Info("CloseGeometry","Counting nodes...");
1434 fNNodes = CountNodes();
1436 if (fNLevel<30) fNLevel = 100;
1437
1438 // BuildIdArray();
1439 // avoid voxelization if requested to speed up geometry startup
1440 if (!opt.Contains("nv")) {
1441 Voxelize("ALL");
1442 } else {
1443 TGeoVolume *vol;
1444 TIter next(fVolumes);
1445 while ((vol = (TGeoVolume *)next())) {
1446 vol->SortNodes();
1447 }
1448 }
1449 if (fgVerboseLevel>0) Info("CloseGeometry","Building cache...");
1450 CountLevels();
1451 for (Int_t i=0; i<nnavigators; i++) {
1452 nav = (TGeoNavigator*)GetListOfNavigators()->At(i);
1453 nav->GetCache()->BuildInfoBranch();
1454 if (nodeid) nav->GetCache()->BuildIdArray();
1455 }
1456 fClosed = kTRUE;
1457 if (fgVerboseLevel>0) {
1458 Info("CloseGeometry","%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast()-1, GetTitle());
1459 Info("CloseGeometry","----------------modeler ready----------------");
1460 }
1461}
1462
1463////////////////////////////////////////////////////////////////////////////////
1464/// Clear the list of overlaps.
1465
1467{
1468 if (fOverlaps) {
1469 fOverlaps->Delete();
1470 delete fOverlaps;
1471 }
1472 fOverlaps = new TObjArray();
1473}
1474
1475////////////////////////////////////////////////////////////////////////////////
1476/// Remove a shape from the list of shapes.
1477
1479{
1480 if (fShapes->FindObject(shape)) fShapes->Remove((TGeoShape*)shape);
1481 delete shape;
1482}
1483
1484////////////////////////////////////////////////////////////////////////////////
1485/// Clean temporary volumes and shapes from garbage collection.
1486
1488{
1489 if (!fGVolumes && !fGShapes) return;
1490 Int_t i,nentries;
1491 if (fGVolumes) {
1493 TGeoVolume *vol = 0;
1494 for (i=0; i<nentries; i++) {
1495 vol=(TGeoVolume*)fGVolumes->At(i);
1496 if (vol) vol->SetFinder(0);
1497 }
1498 fGVolumes->Delete();
1499 delete fGVolumes;
1500 fGVolumes = 0;
1501 }
1502 if (fGShapes) {
1503 fGShapes->Delete();
1504 delete fGShapes;
1505 fGShapes = 0;
1506 }
1507}
1508
1509////////////////////////////////////////////////////////////////////////////////
1510/// Change current path to point to the node having this id.
1511/// Node id has to be in range : 0 to fNNodes-1 (no check for performance reasons)
1512
1514{
1515 GetCurrentNavigator()->CdNode(nodeid);
1516}
1517
1518////////////////////////////////////////////////////////////////////////////////
1519/// Get the unique ID of the current node.
1520
1522{
1524}
1525
1526////////////////////////////////////////////////////////////////////////////////
1527/// Make top level node the current node. Updates the cache accordingly.
1528/// Determine the overlapping state of current node.
1529
1531{
1533}
1534
1535////////////////////////////////////////////////////////////////////////////////
1536/// Go one level up in geometry. Updates cache accordingly.
1537/// Determine the overlapping state of current node.
1538
1540{
1542}
1543
1544////////////////////////////////////////////////////////////////////////////////
1545/// Make a daughter of current node current. Can be called only with a valid
1546/// daughter index (no check). Updates cache accordingly.
1547
1549{
1551}
1552
1553////////////////////////////////////////////////////////////////////////////////
1554/// Do a cd to the node found next by FindNextBoundary
1555
1557{
1559}
1560
1561////////////////////////////////////////////////////////////////////////////////
1562/// Browse the tree of nodes starting from fTopNode according to pathname.
1563/// Changes the path accordingly.
1564
1565Bool_t TGeoManager::cd(const char *path)
1566{
1567 return GetCurrentNavigator()->cd(path);
1568}
1569
1570////////////////////////////////////////////////////////////////////////////////
1571/// Check if a geometry path is valid without changing the state of the current navigator.
1572
1573Bool_t TGeoManager::CheckPath(const char *path) const
1574{
1575 return GetCurrentNavigator()->CheckPath(path);
1576}
1577
1578////////////////////////////////////////////////////////////////////////////////
1579/// Convert all reflections in geometry to normal rotations + reflected shapes.
1580
1582{
1583 if (!fTopNode) return;
1584 if (fgVerboseLevel>0) Info("ConvertReflections", "Converting reflections in: %s - %s ...", GetName(), GetTitle());
1586 TGeoNode *node;
1587 TGeoNodeMatrix *nodematrix;
1588 TGeoMatrix *matrix, *mclone;
1589 TGeoVolume *reflected;
1590 while ((node=next())) {
1591 matrix = node->GetMatrix();
1592 if (matrix->IsReflection()) {
1593// printf("%s before\n", node->GetName());
1594// matrix->Print();
1595 mclone = new TGeoCombiTrans(*matrix);
1596 mclone->RegisterYourself();
1597 // Reflect just the rotation component
1598 mclone->ReflectZ(kFALSE, kTRUE);
1599 nodematrix = (TGeoNodeMatrix*)node;
1600 nodematrix->SetMatrix(mclone);
1601// printf("%s after\n", node->GetName());
1602// node->GetMatrix()->Print();
1603 reflected = node->GetVolume()->MakeReflectedVolume();
1604 node->SetVolume(reflected);
1605 }
1606 }
1607 if (fgVerboseLevel>0) Info("ConvertReflections", "Done");
1608}
1609
1610////////////////////////////////////////////////////////////////////////////////
1611/// Count maximum number of nodes per volume, maximum depth and maximum
1612/// number of xtru vertices.
1613
1615{
1616 if (!fTopNode) {
1617 Error("CountLevels", "Top node not defined.");
1618 return;
1619 }
1621 Bool_t fixrefs = fIsGeomReading && (fMasterVolume->GetRefCount()==1);
1623 if (fgVerboseLevel>1 && fixrefs) Info("CountLevels", "Fixing volume reference counts");
1624 TGeoNode *node;
1625 Int_t maxlevel = 1;
1626 Int_t maxnodes = fTopVolume->GetNdaughters();
1627 Int_t maxvertices = 1;
1628 while ((node=next())) {
1629 if (fixrefs) {
1630 node->GetVolume()->Grab();
1631 for (Int_t ibit=10; ibit<14; ibit++) {
1632 node->SetBit(BIT(ibit+4), node->TestBit(BIT(ibit)));
1633// node->ResetBit(BIT(ibit)); // cannot overwrite old crap for reproducibility
1634 }
1635 }
1636 if (node->GetNdaughters() > maxnodes)
1637 maxnodes = node->GetNdaughters();
1638 if (next.GetLevel()>maxlevel) maxlevel = next.GetLevel();
1639 if (node->GetVolume()->GetShape()->IsA()==TGeoXtru::Class()) {
1640 TGeoXtru *xtru = (TGeoXtru*)node->GetVolume()->GetShape();
1641 if (xtru->GetNvert()>maxvertices) maxvertices = xtru->GetNvert();
1642 }
1643 }
1644 fgMaxLevel = maxlevel;
1645 fgMaxDaughters = maxnodes;
1646 fgMaxXtruVert = maxvertices;
1647 if (fgVerboseLevel>0) Info("CountLevels", "max level = %d, max placements = %d", fgMaxLevel, fgMaxDaughters);
1648}
1649
1650////////////////////////////////////////////////////////////////////////////////
1651/// Count the total number of nodes starting from a volume, nlevels down.
1652
1654{
1655 TGeoVolume *top;
1656 if (!vol) {
1657 top = fTopVolume;
1658 } else {
1659 top = (TGeoVolume*)vol;
1660 }
1661 Int_t count = top->CountNodes(nlevels, option);
1662 return count;
1663}
1664
1665////////////////////////////////////////////////////////////////////////////////
1666/// Set default angles for a given view.
1667
1669{
1671}
1672
1673////////////////////////////////////////////////////////////////////////////////
1674/// Draw current point in the same view.
1675
1677{
1678 if (fPainter) fPainter->DrawCurrentPoint(color);
1679}
1680
1681////////////////////////////////////////////////////////////////////////////////
1682/// Draw animation of tracks
1683
1685{
1688 if (tmin<0 || tmin>=tmax || nframes<1) return;
1690 box[0] = box[1] = box[2] = 0;
1691 box[3] = box[4] = box[5] = 100;
1692 Double_t dt = (tmax-tmin)/Double_t(nframes);
1693 Double_t delt = 2E-9;
1694 Double_t t = tmin;
1695 Int_t i, j;
1696 TString opt(option);
1697 Bool_t save = kFALSE, geomanim=kFALSE;
1698 TString fname;
1699 if (opt.Contains("/S")) save = kTRUE;
1700
1701 if (opt.Contains("/G")) geomanim = kTRUE;
1702 SetTminTmax(0,0);
1703 DrawTracks(opt.Data());
1704 Double_t start[6] = {0,0,0,0,0,0};
1705 Double_t end[6] = {0,0,0,0,0,0};
1706 Double_t dd[6] = {0,0,0,0,0,0};
1707 Double_t dlat=0, dlong=0, dpsi=0;
1708 if (geomanim) {
1709 fPainter->EstimateCameraMove(tmin+5*dt, tmin+15*dt, start, end);
1710 for (i=0; i<3; i++) {
1711 start[i+3] = 20 + 1.3*start[i+3];
1712 end[i+3] = 20 + 0.9*end[i+3];
1713 }
1714 for (i=0; i<6; i++) {
1715 dd[i] = (end[i]-start[i])/10.;
1716 }
1717 memcpy(box, start, 6*sizeof(Double_t));
1718 fPainter->GetViewAngles(dlong,dlat,dpsi);
1719 dlong = (-206-dlong)/Double_t(nframes);
1720 dlat = (126-dlat)/Double_t(nframes);
1721 dpsi = (75-dpsi)/Double_t(nframes);
1723 }
1724
1725 for (i=0; i<nframes; i++) {
1726 if (t-delt<0) SetTminTmax(t-delt,t);
1727 else gGeoManager->SetTminTmax(t-delt,t);
1728 if (geomanim) {
1729 for (j=0; j<6; j++) box[j]+=dd[j];
1730 fPainter->GrabFocus(1,dlong,dlat,dpsi);
1731 } else {
1732 ModifiedPad();
1733 }
1734 if (save) {
1735 fname = TString::Format("anim%04d.gif", i);
1736 gPad->Print(fname);
1737 }
1738 t += dt;
1739 }
1741}
1742
1743////////////////////////////////////////////////////////////////////////////////
1744/// Draw tracks over the geometry, according to option. By default, only
1745/// primaries are drawn. See TGeoTrack::Draw() for additional options.
1746
1748{
1749 TVirtualGeoTrack *track;
1750 //SetVisLevel(1);
1751 //SetVisOption(1);
1753 for (Int_t i=0; i<fNtracks; i++) {
1754 track = GetTrack(i);
1755 if (track) track->Draw(option);
1756 }
1758 ModifiedPad();
1759}
1760
1761////////////////////////////////////////////////////////////////////////////////
1762/// Draw current path
1763
1764void TGeoManager::DrawPath(const char *path, Option_t *option)
1765{
1766 if (!fTopVolume) return;
1768 GetGeomPainter()->DrawPath(path, option);
1769}
1770
1771////////////////////////////////////////////////////////////////////////////////
1772/// Draw random points in the bounding box of a volume.
1773
1775{
1776 GetGeomPainter()->RandomPoints((TGeoVolume*)vol, npoints, option);
1777}
1778
1779////////////////////////////////////////////////////////////////////////////////
1780/// Check time of finding "Where am I" for n points.
1781
1783{
1784 GetGeomPainter()->Test(npoints, option);
1785}
1786
1787////////////////////////////////////////////////////////////////////////////////
1788/// Geometry overlap checker based on sampling.
1789
1790void TGeoManager::TestOverlaps(const char* path)
1791{
1793}
1794
1795////////////////////////////////////////////////////////////////////////////////
1796/// Fill volume names of current branch into an array.
1797
1799{
1801}
1802
1803////////////////////////////////////////////////////////////////////////////////
1804/// Get name for given pdg code;
1805
1806const char *TGeoManager::GetPdgName(Int_t pdg) const
1807{
1808 static char defaultname[5] = { "XXX" };
1809 if (!fPdgNames || !pdg) return defaultname;
1810 for (Int_t i=0; i<fNpdg; i++) {
1811 if (fPdgId[i]==pdg) return fPdgNames->At(i)->GetName();
1812 }
1813 return defaultname;
1814}
1815
1816////////////////////////////////////////////////////////////////////////////////
1817/// Set a name for a particle having a given pdg.
1818
1819void TGeoManager::SetPdgName(Int_t pdg, const char *name)
1820{
1821 if (!pdg) return;
1822 if (!fPdgNames) {
1823 fPdgNames = new TObjArray(1024);
1824 }
1825 if (!strcmp(name, GetPdgName(pdg))) return;
1826 // store pdg name
1827 if (fNpdg>1023) {
1828 Warning("SetPdgName", "No more than 256 different pdg codes allowed");
1829 return;
1830 }
1831 fPdgId[fNpdg] = pdg;
1832 TNamed *pdgname = new TNamed(name, "");
1833 fPdgNames->AddAtAndExpand(pdgname, fNpdg++);
1834}
1835
1836////////////////////////////////////////////////////////////////////////////////
1837/// Get GDML matrix with a given name;
1838
1840{
1842}
1843
1844////////////////////////////////////////////////////////////////////////////////
1845/// Add GDML matrix;
1847{
1848 if (GetGDMLMatrix(mat->GetName())) {
1849 Error("AddGDMLMatrix", "Matrix %s already added to manager", mat->GetName());
1850 return;
1851 }
1852 fGDMLMatrices->Add(mat);
1853}
1854
1855////////////////////////////////////////////////////////////////////////////////
1856/// Get optical surface with a given name;
1857
1859{
1861}
1862
1863////////////////////////////////////////////////////////////////////////////////
1864/// Add optical surface;
1866{
1867 if (GetOpticalSurface(optsurf->GetName())) {
1868 Error("AddOpticalSurface", "Surface %s already added to manager", optsurf->GetName());
1869 return;
1870 }
1871 fOpticalSurfaces->Add(optsurf);
1872}
1873
1874////////////////////////////////////////////////////////////////////////////////
1875/// Get skin surface with a given name;
1876
1878{
1880}
1881
1882////////////////////////////////////////////////////////////////////////////////
1883/// Add skin surface;
1885{
1886 if (GetSkinSurface(surf->GetName())) {
1887 Error("AddSkinSurface", "Surface %s already added to manager", surf->GetName());
1888 return;
1889 }
1890 fSkinSurfaces->Add(surf);
1891}
1892
1893////////////////////////////////////////////////////////////////////////////////
1894/// Get border surface with a given name;
1895
1897{
1899}
1900
1901////////////////////////////////////////////////////////////////////////////////
1902/// Add border surface;
1904{
1905 if (GetBorderSurface(surf->GetName())) {
1906 Error("AddBorderSurface", "Surface %s already added to manager", surf->GetName());
1907 return;
1908 }
1909 fBorderSurfaces->Add(surf);
1910}
1911
1912////////////////////////////////////////////////////////////////////////////////
1913/// Fill node copy numbers of current branch into an array.
1914
1915void TGeoManager::GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
1916{
1917 GetCurrentNavigator()->GetBranchNumbers(copyNumbers, volumeNumbers);
1918}
1919
1920////////////////////////////////////////////////////////////////////////////////
1921/// Fill node copy numbers of current branch into an array.
1922
1924{
1926}
1927
1928////////////////////////////////////////////////////////////////////////////////
1929/// Retrieve cartesian and radial bomb factors.
1930
1931void TGeoManager::GetBombFactors(Double_t &bombx, Double_t &bomby, Double_t &bombz, Double_t &bombr) const
1932{
1933 if (fPainter) {
1934 fPainter->GetBombFactors(bombx, bomby, bombz, bombr);
1935 return;
1936 }
1937 bombx = bomby = bombz = bombr = 1.3;
1938}
1939
1940////////////////////////////////////////////////////////////////////////////////
1941/// Return maximum number of daughters of a volume used in the geometry.
1942
1944{
1945 return fgMaxDaughters;
1946}
1947
1948////////////////////////////////////////////////////////////////////////////////
1949/// Return maximum number of levels used in the geometry.
1950
1952{
1953 return fgMaxLevel;
1954}
1955
1956////////////////////////////////////////////////////////////////////////////////
1957/// Return maximum number of vertices for an xtru shape used.
1958
1960{
1961 return fgMaxXtruVert;
1962}
1963
1964////////////////////////////////////////////////////////////////////////////////
1965/// Returns number of threads that were set to use geometry.
1966
1968{
1969 return fgNumThreads;
1970}
1971
1972////////////////////////////////////////////////////////////////////////////////
1973/// Return stored current matrix (global matrix of the next touched node).
1974
1976{
1977 if (!GetCurrentNavigator()) return NULL;
1978 return GetCurrentNavigator()->GetHMatrix();
1979}
1980
1981////////////////////////////////////////////////////////////////////////////////
1982/// Returns current depth to which geometry is drawn.
1983
1985{
1986 return fVisLevel;
1987}
1988
1989////////////////////////////////////////////////////////////////////////////////
1990/// Returns current depth to which geometry is drawn.
1991
1993{
1994 return fVisOption;
1995}
1996
1997////////////////////////////////////////////////////////////////////////////////
1998/// Find level of virtuality of current overlapping node (number of levels
1999/// up having the same tracking media.
2000
2002{
2004}
2005
2006////////////////////////////////////////////////////////////////////////////////
2007/// Search the track hierarchy to find the track with the
2008/// given id
2009///
2010/// if 'primsFirst' is true, then:
2011/// first tries TGeoManager::GetTrackOfId, then does a
2012/// recursive search if that fails. this would be faster
2013/// if the track is somehow known to be a primary
2014
2016{
2017 TVirtualGeoTrack* trk = 0;
2018 trk = GetTrackOfId(id);
2019 if (trk) return trk;
2020 // need recursive search
2021 TIter next(fTracks);
2022 TVirtualGeoTrack* prim;
2023 while ((prim = (TVirtualGeoTrack*)next())) {
2024 trk = prim->FindTrackWithId(id);
2025 if (trk) return trk;
2026 }
2027 return NULL;
2028}
2029
2030////////////////////////////////////////////////////////////////////////////////
2031/// Get track with a given ID.
2032
2034{
2035 TVirtualGeoTrack *track;
2036 for (Int_t i=0; i<fNtracks; i++) {
2037 if ((track = (TVirtualGeoTrack *)fTracks->UncheckedAt(i))) {
2038 if (track->GetId() == id) return track;
2039 }
2040 }
2041 return 0;
2042}
2043
2044////////////////////////////////////////////////////////////////////////////////
2045/// Get parent track with a given ID.
2046
2048{
2050 while ((track=track->GetMother())) {
2051 if (track->GetId()==id) return track;
2052 }
2053 return 0;
2054}
2055
2056////////////////////////////////////////////////////////////////////////////////
2057/// Get index for track id, -1 if not found.
2058
2060{
2061 TVirtualGeoTrack *track;
2062 for (Int_t i=0; i<fNtracks; i++) {
2063 if ((track = (TVirtualGeoTrack *)fTracks->UncheckedAt(i))) {
2064 if (track->GetId() == id) return i;
2065 }
2066 }
2067 return -1;
2068}
2069
2070////////////////////////////////////////////////////////////////////////////////
2071/// Go upwards the tree until a non-overlapping node
2072
2074{
2076}
2077
2078////////////////////////////////////////////////////////////////////////////////
2079/// Go upwards the tree until a non-overlapping node
2080
2082{
2084}
2085
2086////////////////////////////////////////////////////////////////////////////////
2087/// Set default volume colors according to A of material
2088
2090{
2091 const Int_t nmax = 110;
2092 Int_t col[nmax];
2093 for (Int_t i=0;i<nmax;i++) col[i] = kGray;
2094
2095 //here we should create a new TColor with the same rgb as in the default
2096 //ROOT colors used below
2097 col[ 3] = kYellow-10;
2098 col[ 4] = col[ 5] = kGreen-10;
2099 col[ 6] = col[ 7] = kBlue-7;
2100 col[ 8] = col[ 9] = kMagenta-3;
2101 col[10] = col[11] = kRed-10;
2102 col[12] = kGray+1;
2103 col[13] = kBlue-10;
2104 col[14] = kOrange+7;
2105 col[16] = kYellow+1;
2106 col[20] = kYellow-10;
2107 col[24] = col[25] = col[26] = kBlue-8;
2108 col[29] = kOrange+9;
2109 col[79] = kOrange-2;
2110
2111 TGeoVolume *vol;
2112 TIter next(fVolumes);
2113 while ((vol=(TGeoVolume*)next())) {
2114 TGeoMedium *med = vol->GetMedium();
2115 if (!med) continue;
2116 TGeoMaterial *mat = med->GetMaterial();
2117 Int_t matZ = (Int_t)mat->GetZ();
2118 vol->SetLineColor(col[matZ]);
2119 if (mat->GetDensity()<0.1) vol->SetTransparency(60);
2120 }
2121}
2122
2123////////////////////////////////////////////////////////////////////////////////
2124/// Compute safe distance from the current point. This represent the distance
2125/// from POINT to the closest boundary.
2126
2128{
2129 return GetCurrentNavigator()->Safety(inside);
2130}
2131
2132////////////////////////////////////////////////////////////////////////////////
2133/// Set volume attributes in G3 style.
2134
2135void TGeoManager::SetVolumeAttribute(const char *name, const char *att, Int_t val)
2136{
2137 TGeoVolume *volume;
2138 Bool_t all = kFALSE;
2139 if (strstr(name,"*")) all=kTRUE;
2140 Int_t ivo=0;
2141 TIter next(fVolumes);
2142 TString chatt = att;
2143 chatt.ToLower();
2144 while ((volume=(TGeoVolume*)next())) {
2145 if (strcmp(volume->GetName(), name) && !all) continue;
2146 ivo++;
2147 if (chatt.Contains("colo")) volume->SetLineColor(val);
2148 if (chatt.Contains("lsty")) volume->SetLineStyle(val);
2149 if (chatt.Contains("lwid")) volume->SetLineWidth(val);
2150 if (chatt.Contains("fill")) volume->SetFillColor(val);
2151 if (chatt.Contains("seen")) volume->SetVisibility(val);
2152 }
2153 TIter next1(fGVolumes);
2154 while ((volume=(TGeoVolume*)next1())) {
2155 if (strcmp(volume->GetName(), name) && !all) continue;
2156 ivo++;
2157 if (chatt.Contains("colo")) volume->SetLineColor(val);
2158 if (chatt.Contains("lsty")) volume->SetLineStyle(val);
2159 if (chatt.Contains("lwid")) volume->SetLineWidth(val);
2160 if (chatt.Contains("fill")) volume->SetFillColor(val);
2161 if (chatt.Contains("seen")) volume->SetVisibility(val);
2162 }
2163 if (!ivo) {
2164 Warning("SetVolumeAttribute","volume: %s does not exist",name);
2165 }
2166}
2167
2168////////////////////////////////////////////////////////////////////////////////
2169/// Set factors that will "bomb" all translations in cartesian and cylindrical coordinates.
2170
2172{
2173 if (fPainter) fPainter->SetBombFactors(bombx, bomby, bombz, bombr);
2174}
2175
2176////////////////////////////////////////////////////////////////////////////////
2177/// Set a user-defined shape as clipping for ray tracing.
2178
2180{
2182 if (shape) {
2184 fClippingShape = shape;
2185 }
2186 painter->SetClippingShape(shape);
2187}
2188
2189////////////////////////////////////////////////////////////////////////////////
2190/// set the maximum number of visible nodes.
2191
2193 fMaxVisNodes = maxnodes;
2194 if (maxnodes>0 && fgVerboseLevel>0)
2195 Info("SetMaxVisNodes","Automatic visible depth for %d visible nodes", maxnodes);
2196 if (!fPainter) return;
2198 Int_t level = fPainter->GetVisLevel();
2199 if (level != fVisLevel) fVisLevel = level;
2200}
2201
2202////////////////////////////////////////////////////////////////////////////////
2203/// make top volume visible on screen
2204
2207 fPainter->SetTopVisible(vis);
2208}
2209
2210////////////////////////////////////////////////////////////////////////////////
2211/// Assign a given node to be checked for overlaps. Any other overlaps will be ignored.
2212
2215}
2216
2217////////////////////////////////////////////////////////////////////////////////
2218/// Set the number of points to be generated on the shape outline when checking
2219/// for overlaps.
2220
2222{
2223 GetGeomPainter()->SetNmeshPoints(npoints);
2224}
2225
2226////////////////////////////////////////////////////////////////////////////////
2227/// set drawing mode :
2228/// - option=0 (default) all nodes drawn down to vislevel
2229/// - option=1 leaves and nodes at vislevel drawn
2230/// - option=2 path is drawn
2231/// - option=4 visibility changed
2232
2234 if ((option>=0) && (option<3)) fVisOption=option;
2236}
2237
2238////////////////////////////////////////////////////////////////////////////////
2239/// Set visualization option (leaves only OR all volumes)
2240
2242{
2243 if (flag) SetVisOption(1);
2244 else SetVisOption(0);
2245}
2246
2247////////////////////////////////////////////////////////////////////////////////
2248/// Set density threshold. Volumes with densities lower than this become
2249/// transparent.
2250
2252{
2253 fVisDensity = density;
2255}
2256
2257////////////////////////////////////////////////////////////////////////////////
2258/// set default level down to which visualization is performed
2259
2261 if (level>0) {
2262 fVisLevel = level;
2263 fMaxVisNodes = 0;
2264 if (fgVerboseLevel>0)
2265 Info("SetVisLevel","Automatic visible depth disabled");
2267 } else {
2269 }
2270}
2271
2272////////////////////////////////////////////////////////////////////////////////
2273/// Sort overlaps by decreasing overlap distance. Extrusions comes first.
2274
2276{
2277 fOverlaps->Sort();
2278}
2279
2280////////////////////////////////////////////////////////////////////////////////
2281/// Optimize voxelization type for all volumes. Save best choice in a macro.
2282
2284{
2285 if (!fTopNode) {
2286 Error("OptimizeVoxels","Geometry must be closed first");
2287 return;
2288 }
2289 std::ofstream out;
2290 TString fname = filename;
2291 if (fname.IsNull()) fname = "tgeovox.C";
2292 out.open(fname, std::ios::out);
2293 if (!out.good()) {
2294 Error("OptimizeVoxels", "cannot open file");
2295 return;
2296 }
2297 // write header
2298 TDatime t;
2299 TString sname(fname);
2300 sname.ReplaceAll(".C", "");
2301 out << sname.Data()<<"()"<<std::endl;
2302 out << "{" << std::endl;
2303 out << "//=== Macro generated by ROOT version "<< gROOT->GetVersion()<<" : "<<t.AsString()<<std::endl;
2304 out << "//=== Voxel optimization for " << GetTitle() << " geometry"<<std::endl;
2305 out << "//===== <run this macro JUST BEFORE closing the geometry>"<<std::endl;
2306 out << " TGeoVolume *vol = 0;"<<std::endl;
2307 out << " // parse all voxelized volumes"<<std::endl;
2308 TGeoVolume *vol = 0;
2309 Bool_t cyltype;
2310 TIter next(fVolumes);
2311 while ((vol=(TGeoVolume*)next())) {
2312 if (!vol->GetVoxels()) continue;
2313 out<<" vol = gGeoManager->GetVolume(\""<<vol->GetName()<<"\");"<<std::endl;
2314 cyltype = vol->OptimizeVoxels();
2315 if (cyltype) {
2316 out<<" vol->SetCylVoxels();"<<std::endl;
2317 } else {
2318 out<<" vol->SetCylVoxels(kFALSE);"<<std::endl;
2319 }
2320 }
2321 out << "}" << std::endl;
2322 out.close();
2323}
2324////////////////////////////////////////////////////////////////////////////////
2325/// Parse a string boolean expression and do a syntax check. Find top
2326/// level boolean operator and returns its type. Fill the two
2327/// substrings to which this operator applies. The returned integer is :
2328/// - -1 : parse error
2329/// - 0 : no boolean operator
2330/// - 1 : union - represented as '+' in expression
2331/// - 2 : difference (subtraction) - represented as '-' in expression
2332/// - 3 : intersection - represented as '*' in expression.
2333/// Parentheses should be used to avoid ambiguities. For instance :
2334/// - A+B-C will be interpreted as (A+B)-C which is not the same as A+(B-C)
2335/// eliminate not needed parentheses
2336
2337Int_t TGeoManager::Parse(const char *expr, TString &expr1, TString &expr2, TString &expr3)
2338{
2339 TString startstr(expr);
2340 Int_t len = startstr.Length();
2341 Int_t i;
2342 TString e0 = "";
2343 expr3 = "";
2344 // eliminate blanks
2345 for (i=0; i< len; i++) {
2346 if (startstr(i)==' ') continue;
2347 e0 += startstr(i, 1);
2348 }
2349 Int_t level = 0;
2350 Int_t levmin = 999;
2351 Int_t boolop = 0;
2352 Int_t indop = 0;
2353 Int_t iloop = 1;
2354 Int_t lastop = 0;
2355 Int_t lastdp = 0;
2356 Int_t lastpp = 0;
2357 Bool_t foundmat = kFALSE;
2358 // check/eliminate parentheses
2359 while (iloop==1) {
2360 iloop = 0;
2361 lastop = 0;
2362 lastdp = 0;
2363 lastpp = 0;
2364 len = e0.Length();
2365 for (i=0; i<len; i++) {
2366 if (e0(i)=='(') {
2367 if (!level) iloop++;
2368 level++;
2369 continue;
2370 }
2371 if (e0(i)==')') {
2372 level--;
2373 if (level==0) lastpp=i;
2374 continue;
2375 }
2376 if ((e0(i)=='+') || (e0(i)=='-') || (e0(i)=='*')) {
2377 lastop = i;
2378 if (level<levmin) {
2379 levmin = level;
2380 indop = i;
2381 }
2382 continue;
2383 }
2384 if ((e0(i)==':') && (level==0)) {
2385 lastdp = i;
2386 continue;
2387 }
2388 }
2389 if (level!=0) {
2390 if (gGeoManager) gGeoManager->Error("Parse","parentheses does not match");
2391 return -1;
2392 }
2393 if (iloop==1 && (e0(0)=='(') && (e0(len-1)==')')) {
2394 // eliminate extra parentheses
2395 e0=e0(1, len-2);
2396 continue;
2397 }
2398 if (foundmat) break;
2399 if (((lastop==0) && (lastdp>0)) || ((lastpp>0) && (lastdp>lastpp) && (indop<lastpp))) {
2400 expr3 = e0(lastdp+1, len-lastdp);
2401 e0=e0(0, lastdp);
2402 foundmat = kTRUE;
2403 iloop = 1;
2404 continue;
2405 } else break;
2406 }
2407 // loop expression and search parentheses/operators
2408 levmin = 999;
2409 for (i=0; i<len; i++) {
2410 if (e0(i)=='(') {
2411 level++;
2412 continue;
2413 }
2414 if (e0(i)==')') {
2415 level--;
2416 continue;
2417 }
2418 // Take LAST operator at lowest level (revision 28/07/08)
2419 if (level<=levmin) {
2420 if (e0(i)=='+') {
2421 boolop = 1; // union
2422 levmin = level;
2423 indop = i;
2424 }
2425 if (e0(i)=='-') {
2426 boolop = 2; // difference
2427 levmin = level;
2428 indop = i;
2429 }
2430 if (e0(i)=='*') {
2431 boolop = 3; // intersection
2432 levmin = level;
2433 indop = i;
2434 }
2435 }
2436 }
2437 if (indop==0) {
2438 expr1=e0;
2439 return indop;
2440 }
2441 expr1 = e0(0, indop);
2442 expr2 = e0(indop+1, len-indop);
2443 return boolop;
2444}
2445
2446
2447////////////////////////////////////////////////////////////////////////////////
2448/// Save current attributes in a macro
2449
2451{
2452 if (!fTopNode) {
2453 Error("SaveAttributes","geometry must be closed first\n");
2454 return;
2455 }
2456 std::ofstream out;
2457 TString fname(filename);
2458 if (fname.IsNull()) fname = "tgeoatt.C";
2459 out.open(fname, std::ios::out);
2460 if (!out.good()) {
2461 Error("SaveAttributes", "cannot open file");
2462 return;
2463 }
2464 // write header
2465 TDatime t;
2466 TString sname(fname);
2467 sname.ReplaceAll(".C", "");
2468 out << sname.Data()<<"()"<<std::endl;
2469 out << "{" << std::endl;
2470 out << "//=== Macro generated by ROOT version "<< gROOT->GetVersion()<<" : "<<t.AsString()<<std::endl;
2471 out << "//=== Attributes for " << GetTitle() << " geometry"<<std::endl;
2472 out << "//===== <run this macro AFTER loading the geometry in memory>"<<std::endl;
2473 // save current top volume
2474 out << " TGeoVolume *top = gGeoManager->GetVolume(\""<<fTopVolume->GetName()<<"\");"<<std::endl;
2475 out << " TGeoVolume *vol = 0;"<<std::endl;
2476 out << " TGeoNode *node = 0;"<<std::endl;
2477 out << " // clear all volume attributes and get painter"<<std::endl;
2478 out << " gGeoManager->ClearAttributes();"<<std::endl;
2479 out << " gGeoManager->GetGeomPainter();"<<std::endl;
2480 out << " // set visualization modes and bomb factors"<<std::endl;
2481 out << " gGeoManager->SetVisOption("<<GetVisOption()<<");"<<std::endl;
2482 out << " gGeoManager->SetVisLevel("<<GetVisLevel()<<");"<<std::endl;
2483 out << " gGeoManager->SetExplodedView("<<GetBombMode()<<");"<<std::endl;
2484 Double_t bombx, bomby, bombz, bombr;
2485 GetBombFactors(bombx, bomby, bombz, bombr);
2486 out << " gGeoManager->SetBombFactors("<<bombx<<","<<bomby<<","<<bombz<<","<<bombr<<");"<<std::endl;
2487 out << " // iterate volumes container and set new attributes"<<std::endl;
2488// out << " TIter next(gGeoManager->GetListOfVolumes());"<<std::endl;
2489 TGeoVolume *vol = 0;
2491
2492 TIter next(fVolumes);
2493 while ((vol=(TGeoVolume*)next())) {
2494 vol->SetVisStreamed(kFALSE);
2495 }
2496 out << " // draw top volume with new settings"<<std::endl;
2497 out << " top->Draw();"<<std::endl;
2498 out << " gPad->x3d();"<<std::endl;
2499 out << "}" << std::endl;
2500 out.close();
2501}
2502
2503////////////////////////////////////////////////////////////////////////////////
2504/// Returns the deepest node containing fPoint, which must be set a priori.
2505
2507{
2508 return GetCurrentNavigator()->SearchNode(downwards, skipnode);
2509}
2510
2511////////////////////////////////////////////////////////////////////////////////
2512/// Cross next boundary and locate within current node
2513/// The current point must be on the boundary of fCurrentNode.
2514
2516{
2517 return GetCurrentNavigator()->CrossBoundaryAndLocate(downwards, skipnode);
2518}
2519
2520////////////////////////////////////////////////////////////////////////////////
2521/// Compute distance to next boundary within STEPMAX. If no boundary is found,
2522/// propagate current point along current direction with fStep=STEPMAX. Otherwise
2523/// propagate with fStep=SNEXT (distance to boundary) and locate/return the next
2524/// node.
2525
2527{
2528 return GetCurrentNavigator()->FindNextBoundaryAndStep(stepmax, compsafe);
2529}
2530
2531////////////////////////////////////////////////////////////////////////////////
2532/// Find distance to next boundary and store it in fStep. Returns node to which this
2533/// boundary belongs. If PATH is specified, compute only distance to the node to which
2534/// PATH points. If STEPMAX is specified, compute distance only in case fSafety is smaller
2535/// than this value. STEPMAX represent the step to be made imposed by other reasons than
2536/// geometry (usually physics processes). Therefore in this case this method provides the
2537/// answer to the question : "Is STEPMAX a safe step ?" returning a NULL node and filling
2538/// fStep with a big number.
2539/// In case frombdr=kTRUE, the isotropic safety is set to zero.
2540///
2541/// Note : safety distance for the current point is computed ONLY in case STEPMAX is
2542/// specified, otherwise users have to call explicitly TGeoManager::Safety() if
2543/// they want this computed for the current point.
2544
2545TGeoNode *TGeoManager::FindNextBoundary(Double_t stepmax, const char *path, Bool_t frombdr)
2546{
2547 // convert current point and direction to local reference
2548 return GetCurrentNavigator()->FindNextBoundary(stepmax,path, frombdr);
2549}
2550
2551////////////////////////////////////////////////////////////////////////////////
2552/// Computes as fStep the distance to next daughter of the current volume.
2553/// The point and direction must be converted in the coordinate system of the current volume.
2554/// The proposed step limit is fStep.
2555
2557{
2558 return GetCurrentNavigator()->FindNextDaughterBoundary(point, dir, idaughter, compmatrix);
2559}
2560
2561////////////////////////////////////////////////////////////////////////////////
2562/// Reset current state flags.
2563
2565{
2567}
2568
2569////////////////////////////////////////////////////////////////////////////////
2570/// Returns deepest node containing current point.
2571
2573{
2574 return GetCurrentNavigator()->FindNode(safe_start);
2575}
2576
2577////////////////////////////////////////////////////////////////////////////////
2578/// Returns deepest node containing current point.
2579
2581{
2582 return GetCurrentNavigator()->FindNode(x, y, z);
2583}
2584
2585////////////////////////////////////////////////////////////////////////////////
2586/// Computes fast normal to next crossed boundary, assuming that the current point
2587/// is close enough to the boundary. Works only after calling FindNextBoundary.
2588
2590{
2592}
2593
2594////////////////////////////////////////////////////////////////////////////////
2595/// Computes normal vector to the next surface that will be or was already
2596/// crossed when propagating on a straight line from a given point/direction.
2597/// Returns the normal vector cosines in the MASTER coordinate system. The dot
2598/// product of the normal and the current direction is positive defined.
2599
2601{
2603}
2604
2605////////////////////////////////////////////////////////////////////////////////
2606/// Checks if point (x,y,z) is still in the current node.
2607
2609{
2610 return GetCurrentNavigator()->IsSameLocation(x,y,z,change);
2611}
2612
2613////////////////////////////////////////////////////////////////////////////////
2614/// Check if a new point with given coordinates is the same as the last located one.
2615
2617{
2618 return GetCurrentNavigator()->IsSamePoint(x,y,z);
2619}
2620
2621////////////////////////////////////////////////////////////////////////////////
2622/// True if current node is in phi range
2623
2625{
2626 if (!fPhiCut) return kTRUE;
2627 const Double_t *origin;
2629 origin = ((TGeoBBox*)GetCurrentNavigator()->GetCurrentVolume()->GetShape())->GetOrigin();
2630 Double_t point[3];
2631 LocalToMaster(origin, &point[0]);
2632 Double_t phi = TMath::ATan2(point[1], point[0])*TMath::RadToDeg();
2633 if (phi<0) phi+=360.;
2634 if ((phi>=fPhimin) && (phi<=fPhimax)) return kFALSE;
2635 return kTRUE;
2636}
2637
2638////////////////////////////////////////////////////////////////////////////////
2639/// Initialize current point and current direction vector (normalized)
2640/// in MARS. Return corresponding node.
2641
2643{
2644 return GetCurrentNavigator()->InitTrack(point, dir);
2645}
2646
2647////////////////////////////////////////////////////////////////////////////////
2648/// Initialize current point and current direction vector (normalized)
2649/// in MARS. Return corresponding node.
2650
2652{
2653 return GetCurrentNavigator()->InitTrack(x,y,z,nx,ny,nz);
2654}
2655
2656////////////////////////////////////////////////////////////////////////////////
2657/// Inspects path and all flags for the current state.
2658
2660{
2662}
2663
2664////////////////////////////////////////////////////////////////////////////////
2665/// Get path to the current node in the form /node0/node1/...
2666
2667const char *TGeoManager::GetPath() const
2668{
2669 return GetCurrentNavigator()->GetPath();
2670}
2671
2672////////////////////////////////////////////////////////////////////////////////
2673/// Get total size of geometry in bytes.
2674
2676{
2677 Int_t count = 0;
2678 TIter next(fVolumes);
2679 TGeoVolume *vol;
2680 while ((vol=(TGeoVolume*)next())) count += vol->GetByteCount();
2681 TIter next1(fMatrices);
2682 TGeoMatrix *matrix;
2683 while ((matrix=(TGeoMatrix*)next1())) count += matrix->GetByteCount();
2684 TIter next2(fMaterials);
2685 TGeoMaterial *mat;
2686 while ((mat=(TGeoMaterial*)next2())) count += mat->GetByteCount();
2687 TIter next3(fMedia);
2688 TGeoMedium *med;
2689 while ((med=(TGeoMedium*)next3())) count += med->GetByteCount();
2690 if (fgVerboseLevel>0) Info("GetByteCount","Total size of logical tree : %i bytes", count);
2691 return count;
2692}
2693
2694////////////////////////////////////////////////////////////////////////////////
2695/// Make a default painter if none present. Returns pointer to it.
2696
2698{
2699 if (!fPainter) {
2700 const char *kind = "root";
2701 if (gROOT->IsWebDisplay() && !gROOT->IsWebDisplayBatch()) kind = "web";
2702 if (auto h = gROOT->GetPluginManager()->FindHandler("TVirtualGeoPainter", kind)) {
2703 if (h->LoadPlugin() == -1) {
2704 Error("GetGeomPainter", "could not load plugin for %s geo_painter", kind);
2705 return nullptr;
2706 }
2707 fPainter = (TVirtualGeoPainter*)h->ExecPlugin(1,this);
2708 if (!fPainter) {
2709 Error("GetGeomPainter", "could not create %s geo_painter", kind);
2710 return nullptr;
2711 }
2712 } else {
2713 Error("GetGeomPainter", "not found plugin %s for geo_painter", kind);
2714 }
2715 }
2716 return fPainter;
2717}
2718
2719////////////////////////////////////////////////////////////////////////////////
2720/// Search for a named volume. All trailing blanks stripped.
2721
2723{
2724 TString sname = name;
2725 sname = sname.Strip();
2726 TGeoVolume *vol = (TGeoVolume*)fVolumes->FindObject(sname.Data());
2727 return vol;
2728}
2729
2730////////////////////////////////////////////////////////////////////////////////
2731/// Fast search for a named volume. All trailing blanks stripped.
2732
2734{
2735 if (!fHashVolumes) {
2736 Int_t nvol = fVolumes->GetEntriesFast();
2737 Int_t ngvol = fGVolumes->GetEntriesFast();
2738 fHashVolumes = new THashList(nvol+1);
2739 fHashGVolumes = new THashList(ngvol+1);
2740 Int_t i;
2741 for (i=0; i<ngvol; i++) fHashGVolumes->AddLast(fGVolumes->At(i));
2742 for (i=0; i<nvol; i++) fHashVolumes->AddLast(fVolumes->At(i));
2743 }
2744 TString sname = name;
2745 sname = sname.Strip();
2746 THashList *list = fHashVolumes;
2747 if (multi) list = fHashGVolumes;
2748 TGeoVolume *vol = (TGeoVolume*)list->FindObject(sname.Data());
2749 return vol;
2750}
2751
2752////////////////////////////////////////////////////////////////////////////////
2753/// Retrieve unique id for a volume name. Return -1 if name not found.
2754
2755Int_t TGeoManager::GetUID(const char *volname) const
2756{
2757 TGeoManager *geom = (TGeoManager*)this;
2758 TGeoVolume *vol = geom->FindVolumeFast(volname, kFALSE);
2759 if (!vol) vol = geom->FindVolumeFast(volname, kTRUE);
2760 if (!vol) return -1;
2761 return vol->GetNumber();
2762}
2763
2764////////////////////////////////////////////////////////////////////////////////
2765/// Find if a given material duplicates an existing one.
2766
2768{
2769 Int_t index = fMaterials->IndexOf(mat);
2770 if (index <= 0) return 0;
2771 TGeoMaterial *other;
2772 for (Int_t i=0; i<index; i++) {
2773 other = (TGeoMaterial*)fMaterials->At(i);
2774 if (other == mat) continue;
2775 if (other->IsEq(mat)) return other;
2776 }
2777 return 0;
2778}
2779
2780////////////////////////////////////////////////////////////////////////////////
2781/// Search for a named material. All trailing blanks stripped.
2782
2783TGeoMaterial *TGeoManager::GetMaterial(const char *matname) const
2784{
2785 TString sname = matname;
2786 sname = sname.Strip();
2788 return mat;
2789}
2790
2791////////////////////////////////////////////////////////////////////////////////
2792/// Search for a named tracking medium. All trailing blanks stripped.
2793
2794TGeoMedium *TGeoManager::GetMedium(const char *medium) const
2795{
2796 TString sname = medium;
2797 sname = sname.Strip();
2798 TGeoMedium *med = (TGeoMedium*)fMedia->FindObject(sname.Data());
2799 return med;
2800}
2801
2802////////////////////////////////////////////////////////////////////////////////
2803/// Search for a tracking medium with a given ID.
2804
2806{
2807 TIter next(fMedia);
2808 TGeoMedium *med;
2809 while ((med=(TGeoMedium*)next())) {
2810 if (med->GetId()==numed) return med;
2811 }
2812 return 0;
2813}
2814
2815////////////////////////////////////////////////////////////////////////////////
2816/// Return material at position id.
2817
2819{
2820 if (id<0 || id >= fMaterials->GetSize()) return 0;
2821 TGeoMaterial *mat = (TGeoMaterial*)fMaterials->At(id);
2822 return mat;
2823}
2824
2825////////////////////////////////////////////////////////////////////////////////
2826/// Return index of named material.
2827
2828Int_t TGeoManager::GetMaterialIndex(const char *matname) const
2829{
2830 TIter next(fMaterials);
2831 TGeoMaterial *mat;
2832 Int_t id = 0;
2833 TString sname = matname;
2834 sname = sname.Strip();
2835 while ((mat = (TGeoMaterial*)next())) {
2836 if (!strcmp(mat->GetName(),sname.Data()))
2837 return id;
2838 id++;
2839 }
2840 return -1; // fail
2841}
2842
2843////////////////////////////////////////////////////////////////////////////////
2844/// Randomly shoot nrays and plot intersections with surfaces for current
2845/// top node.
2846
2847void TGeoManager::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm)
2848{
2849 GetGeomPainter()->RandomRays(nrays, startx, starty, startz, target_vol, check_norm);
2850}
2851
2852////////////////////////////////////////////////////////////////////////////////
2853/// Remove material at given index.
2854
2856{
2857 TObject *obj = fMaterials->At(index);
2858 if (obj) fMaterials->Remove(obj);
2859}
2860
2861////////////////////////////////////////////////////////////////////////////////
2862/// Sets all pointers TGeoVolume::fField to NULL. User data becomes decoupled
2863/// from geometry. Deletion has to be managed by users.
2864
2866{
2867 TIter next(fVolumes);
2868 TGeoVolume *vol;
2869 while ((vol=(TGeoVolume*)next())) vol->SetField(0);
2870}
2871
2872////////////////////////////////////////////////////////////////////////////////
2873/// Change raytracing mode.
2874
2876{
2879}
2880
2881////////////////////////////////////////////////////////////////////////////////
2882/// Restore the master volume of the geometry.
2883
2885{
2886 if (fTopVolume == fMasterVolume) return;
2888}
2889
2890////////////////////////////////////////////////////////////////////////////////
2891/// Voxelize all non-divided volumes.
2892
2894{
2895 TGeoVolume *vol;
2896// TGeoVoxelFinder *vox = 0;
2897 if (!fStreamVoxels && fgVerboseLevel>0) Info("Voxelize","Voxelizing...");
2898// Int_t nentries = fVolumes->GetSize();
2899 TIter next(fVolumes);
2900 while ((vol = (TGeoVolume*)next())) {
2901 if (!fIsGeomReading) vol->SortNodes();
2902 if (!fStreamVoxels) {
2903 vol->Voxelize(option);
2904 }
2905 if (!fIsGeomReading) vol->FindOverlaps();
2906 }
2907}
2908
2909////////////////////////////////////////////////////////////////////////////////
2910/// Send "Modified" signal to painter.
2911
2913{
2914 if (!fPainter) return;
2916}
2917
2918////////////////////////////////////////////////////////////////////////////////
2919/// Make an TGeoArb8 volume.
2920
2922 Double_t dz, Double_t *vertices)
2923{
2924 return TGeoBuilder::Instance(this)->MakeArb8(name, medium, dz, vertices);
2925}
2926
2927////////////////////////////////////////////////////////////////////////////////
2928/// Make in one step a volume pointing to a box shape with given medium.
2929
2931 Double_t dx, Double_t dy, Double_t dz)
2932{
2933 return TGeoBuilder::Instance(this)->MakeBox(name, medium, dx, dy, dz);
2934}
2935
2936////////////////////////////////////////////////////////////////////////////////
2937/// Make in one step a volume pointing to a parallelepiped shape with given medium.
2938
2940 Double_t dx, Double_t dy, Double_t dz,
2941 Double_t alpha, Double_t theta, Double_t phi)
2942{
2943 return TGeoBuilder::Instance(this)->MakePara(name, medium, dx, dy, dz, alpha, theta, phi);
2944}
2945
2946////////////////////////////////////////////////////////////////////////////////
2947/// Make in one step a volume pointing to a sphere shape with given medium
2948
2950 Double_t rmin, Double_t rmax, Double_t themin, Double_t themax,
2951 Double_t phimin, Double_t phimax)
2952{
2953 return TGeoBuilder::Instance(this)->MakeSphere(name, medium, rmin, rmax, themin, themax, phimin, phimax);
2954}
2955
2956////////////////////////////////////////////////////////////////////////////////
2957/// Make in one step a volume pointing to a torus shape with given medium.
2958
2960 Double_t rmin, Double_t rmax, Double_t phi1, Double_t dphi)
2961{
2962 return TGeoBuilder::Instance(this)->MakeTorus(name, medium, r, rmin, rmax, phi1, dphi);
2963}
2964
2965////////////////////////////////////////////////////////////////////////////////
2966/// Make in one step a volume pointing to a tube shape with given medium.
2967
2969 Double_t rmin, Double_t rmax, Double_t dz)
2970{
2971 return TGeoBuilder::Instance(this)->MakeTube(name, medium, rmin, rmax, dz);
2972}
2973
2974////////////////////////////////////////////////////////////////////////////////
2975/// Make in one step a volume pointing to a tube segment shape with given medium.
2976/// The segment will be from phiStart to phiEnd, the angles are expressed in degree
2977
2979 Double_t rmin, Double_t rmax, Double_t dz,
2980 Double_t phiStart, Double_t phiEnd)
2981{
2982 return TGeoBuilder::Instance(this)->MakeTubs(name, medium, rmin, rmax, dz, phiStart, phiEnd);
2983}
2984
2985////////////////////////////////////////////////////////////////////////////////
2986/// Make in one step a volume pointing to a tube shape with given medium
2987
2990{
2991 return TGeoBuilder::Instance(this)->MakeEltu(name, medium, a, b, dz);
2992}
2993
2994////////////////////////////////////////////////////////////////////////////////
2995/// Make in one step a volume pointing to a tube shape with given medium
2996
2998 Double_t rin, Double_t stin, Double_t rout, Double_t stout, Double_t dz)
2999{
3000 return TGeoBuilder::Instance(this)->MakeHype(name, medium, rin, stin, rout, stout, dz);
3001}
3002
3003////////////////////////////////////////////////////////////////////////////////
3004/// Make in one step a volume pointing to a tube shape with given medium
3005
3007 Double_t rlo, Double_t rhi, Double_t dz)
3008{
3009 return TGeoBuilder::Instance(this)->MakeParaboloid(name, medium, rlo, rhi, dz);
3010}
3011
3012////////////////////////////////////////////////////////////////////////////////
3013/// Make in one step a volume pointing to a tube segment shape with given medium
3014
3016 Double_t rmin, Double_t rmax, Double_t dz, Double_t phi1, Double_t phi2,
3017 Double_t lx, Double_t ly, Double_t lz, Double_t tx, Double_t ty, Double_t tz)
3018{
3019 return TGeoBuilder::Instance(this)->MakeCtub(name, medium, rmin, rmax, dz, phi1, phi2, lx, ly, lz, tx, ty, tz);
3020}
3021
3022////////////////////////////////////////////////////////////////////////////////
3023/// Make in one step a volume pointing to a cone shape with given medium.
3024
3026 Double_t dz, Double_t rmin1, Double_t rmax1,
3027 Double_t rmin2, Double_t rmax2)
3028{
3029 return TGeoBuilder::Instance(this)->MakeCone(name, medium, dz, rmin1, rmax1, rmin2, rmax2);
3030}
3031
3032////////////////////////////////////////////////////////////////////////////////
3033/// Make in one step a volume pointing to a cone segment shape with given medium
3034
3036 Double_t dz, Double_t rmin1, Double_t rmax1,
3037 Double_t rmin2, Double_t rmax2,
3038 Double_t phi1, Double_t phi2)
3039{
3040 return TGeoBuilder::Instance(this)->MakeCons(name, medium, dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
3041}
3042
3043////////////////////////////////////////////////////////////////////////////////
3044/// Make in one step a volume pointing to a polycone shape with given medium.
3045
3047 Double_t phi, Double_t dphi, Int_t nz)
3048{
3049 return TGeoBuilder::Instance(this)->MakePcon(name, medium, phi, dphi, nz);
3050}
3051
3052////////////////////////////////////////////////////////////////////////////////
3053/// Make in one step a volume pointing to a polygone shape with given medium.
3054
3056 Double_t phi, Double_t dphi, Int_t nedges, Int_t nz)
3057{
3058 return TGeoBuilder::Instance(this)->MakePgon(name, medium, phi, dphi, nedges, nz);
3059}
3060
3061////////////////////////////////////////////////////////////////////////////////
3062/// Make in one step a volume pointing to a TGeoTrd1 shape with given medium.
3063
3065 Double_t dx1, Double_t dx2, Double_t dy, Double_t dz)
3066{
3067 return TGeoBuilder::Instance(this)->MakeTrd1(name, medium, dx1, dx2, dy, dz);
3068}
3069
3070////////////////////////////////////////////////////////////////////////////////
3071/// Make in one step a volume pointing to a TGeoTrd2 shape with given medium.
3072
3074 Double_t dx1, Double_t dx2, Double_t dy1, Double_t dy2,
3075 Double_t dz)
3076{
3077 return TGeoBuilder::Instance(this)->MakeTrd2(name, medium, dx1, dx2, dy1, dy2, dz);
3078}
3079
3080////////////////////////////////////////////////////////////////////////////////
3081/// Make in one step a volume pointing to a trapezoid shape with given medium.
3082
3084 Double_t dz, Double_t theta, Double_t phi, Double_t h1,
3085 Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
3086 Double_t tl2, Double_t alpha2)
3087{
3088 return TGeoBuilder::Instance(this)->MakeTrap(name, medium, dz, theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2);
3089}
3090
3091////////////////////////////////////////////////////////////////////////////////
3092/// Make in one step a volume pointing to a twisted trapezoid shape with given medium.
3093
3095 Double_t dz, Double_t theta, Double_t phi, Double_t twist, Double_t h1,
3096 Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
3097 Double_t tl2, Double_t alpha2)
3098{
3099 return TGeoBuilder::Instance(this)->MakeGtra(name, medium, dz, theta, phi, twist, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2);
3100}
3101
3102////////////////////////////////////////////////////////////////////////////////
3103/// Make a TGeoXtru-shaped volume with nz planes
3104
3106{
3107 return TGeoBuilder::Instance(this)->MakeXtru(name, medium, nz);
3108}
3109
3110////////////////////////////////////////////////////////////////////////////////
3111/// Creates an alignable object with unique name corresponding to a path
3112/// and adds it to the list of alignables. An optional unique ID can be
3113/// provided, in which case PN entries can be searched fast by uid.
3114
3115TGeoPNEntry *TGeoManager::SetAlignableEntry(const char *unique_name, const char *path,
3116 Int_t uid)
3117{
3118 if (!CheckPath(path)) return NULL;
3119 if (!fHashPNE) fHashPNE = new THashList(256,3);
3120 if (!fArrayPNE) fArrayPNE = new TObjArray(256);
3121 TGeoPNEntry *entry = GetAlignableEntry(unique_name);
3122 if (entry) {
3123 Error("SetAlignableEntry", "An alignable object with name %s already existing. NOT ADDED !", unique_name);
3124 return 0;
3125 }
3126 entry = new TGeoPNEntry(unique_name, path);
3127 Int_t ientry = fHashPNE->GetSize();
3128 fHashPNE->Add(entry);
3129 fArrayPNE->AddAtAndExpand(entry, ientry);
3130 if (uid>=0) {
3131 Bool_t added = InsertPNEId(uid, ientry);
3132 if (!added) Error("SetAlignableEntry", "A PN entry: has already uid=%i", uid);
3133 }
3134 return entry;
3135}
3136
3137////////////////////////////////////////////////////////////////////////////////
3138/// Retrieves an existing alignable object.
3139
3141{
3142 if (!fHashPNE) return 0;
3144}
3145
3146////////////////////////////////////////////////////////////////////////////////
3147/// Retrieves an existing alignable object at a given index.
3148
3150{
3151 if (!fArrayPNE && !InitArrayPNE()) return 0;
3152 return (TGeoPNEntry*)fArrayPNE->At(index);
3153}
3154
3155////////////////////////////////////////////////////////////////////////////////
3156/// Retrieves an existing alignable object having a preset UID.
3157
3159{
3160 if (!fNPNEId || (!fArrayPNE && !InitArrayPNE())) return NULL;
3162 if (index<0 || fKeyPNEId[index]!=uid) return NULL;
3164}
3165
3166////////////////////////////////////////////////////////////////////////////////
3167/// Retrieves number of PN entries with or without UID.
3168
3170{
3171 if (!fHashPNE) return 0;
3172 if (with_uid) return fNPNEId;
3173 return fHashPNE->GetSize();
3174}
3175
3176////////////////////////////////////////////////////////////////////////////////
3177/// Insert a PN entry in the sorted array of indexes.
3178
3180{
3181 if (!fSizePNEId) {
3182 // Create the arrays.
3183 fSizePNEId = 128;
3184 fKeyPNEId = new Int_t[fSizePNEId];
3185 memset(fKeyPNEId, 0, fSizePNEId*sizeof(Int_t));
3187 memset(fValuePNEId, 0, fSizePNEId*sizeof(Int_t));
3188 fKeyPNEId[fNPNEId] = uid;
3189 fValuePNEId[fNPNEId++] = ientry;
3190 return kTRUE;
3191 }
3192 // Search id in the existing array and return false if it already exists.
3194 if (index>0 && fKeyPNEId[index]==uid) return kFALSE;
3195 // Resize the arrays and insert the value
3196 Bool_t resize = (fNPNEId==fSizePNEId)?kTRUE:kFALSE;
3197 if (resize) {
3198 // Double the size of the array
3199 fSizePNEId *= 2;
3200 // Create new arrays of keys and values
3201 Int_t *keys = new Int_t[fSizePNEId];
3202 memset(keys, 0, fSizePNEId*sizeof(Int_t));
3203 Int_t *values = new Int_t[fSizePNEId];
3204 memset(values, 0, fSizePNEId*sizeof(Int_t));
3205 // Copy all keys<uid in the new keys array (0 to index)
3206 memcpy(keys, fKeyPNEId, (index+1)*sizeof(Int_t));
3207 memcpy(values, fValuePNEId, (index+1)*sizeof(Int_t));
3208 // Insert current key at index+1
3209 keys[index+1] = uid;
3210 values[index+1] = ientry;
3211 // Copy all remaining keys from the old to new array
3212 memcpy(&keys[index+2], &fKeyPNEId[index+1], (fNPNEId-index-1)*sizeof(Int_t));
3213 memcpy(&values[index+2], &fValuePNEId[index+1], (fNPNEId-index-1)*sizeof(Int_t));
3214 delete [] fKeyPNEId;
3215 fKeyPNEId = keys;
3216 delete [] fValuePNEId;
3217 fValuePNEId = values;
3218 fNPNEId++;
3219 return kTRUE;
3220 }
3221 // Insert the value in the existing arrays
3222 Int_t i;
3223 for (i=fNPNEId-1; i>index; i--) {
3224 fKeyPNEId[i+1] = fKeyPNEId[i];
3225 fValuePNEId[i+1] = fValuePNEId[i];
3226 }
3227 fKeyPNEId[index+1] = uid;
3228 fValuePNEId[index+1] = ientry;
3229 fNPNEId++;
3230 return kTRUE;
3231}
3232
3233////////////////////////////////////////////////////////////////////////////////
3234/// Make a physical node from the path pointed by an alignable object with a given name.
3235
3237{
3239 if (!entry) {
3240 Error("MakeAlignablePN","No alignable object named %s found !", name);
3241 return 0;
3242 }
3243 return MakeAlignablePN(entry);
3244}
3245
3246////////////////////////////////////////////////////////////////////////////////
3247/// Make a physical node from the path pointed by a given alignable object.
3248
3250{
3251 if (!entry) {
3252 Error("MakeAlignablePN","No alignable object specified !");
3253 return 0;
3254 }
3255 const char *path = entry->GetTitle();
3256 if (!cd(path)) {
3257 Error("MakeAlignablePN", "Alignable object %s poins to invalid path: %s",
3258 entry->GetName(), path);
3259 return 0;
3260 }
3261 TGeoPhysicalNode *node = MakePhysicalNode(path);
3262 entry->SetPhysicalNode(node);
3263 return node;
3264}
3265
3266////////////////////////////////////////////////////////////////////////////////
3267/// Makes a physical node corresponding to a path. If PATH is not specified,
3268/// makes physical node matching current modeller state.
3269
3271{
3272 TGeoPhysicalNode *node;
3273 if (path) {
3274 if (!CheckPath(path)) {
3275 Error("MakePhysicalNode", "path: %s not valid", path);
3276 return NULL;
3277 }
3278 node = new TGeoPhysicalNode(path);
3279 } else {
3280 node = new TGeoPhysicalNode(GetPath());
3281 }
3282 fPhysicalNodes->Add(node);
3283 return node;
3284}
3285
3286////////////////////////////////////////////////////////////////////////////////
3287/// Refresh physical nodes to reflect the actual geometry paths after alignment
3288/// was applied. Optionally locks physical nodes (default).
3289
3291{
3293 TGeoPhysicalNode *pn;
3294 while ((pn=(TGeoPhysicalNode*)next())) pn->Refresh();
3296 if (lock) LockGeometry();
3297}
3298
3299////////////////////////////////////////////////////////////////////////////////
3300/// Clear the current list of physical nodes, so that we can start over with a new list.
3301/// If MUSTDELETE is true, delete previous nodes.
3302
3304{
3305 if (mustdelete) fPhysicalNodes->Delete();
3306 else fPhysicalNodes->Clear();
3307}
3308
3309////////////////////////////////////////////////////////////////////////////////
3310/// Make an assembly of volumes.
3311
3313{
3315}
3316
3317////////////////////////////////////////////////////////////////////////////////
3318/// Make a TGeoVolumeMulti handling a list of volumes.
3319
3321{
3322 return TGeoBuilder::Instance(this)->MakeVolumeMulti(name, medium);
3323}
3324
3325////////////////////////////////////////////////////////////////////////////////
3326/// Set type of exploding view (see TGeoPainter::SetExplodedView())
3327
3329{
3330 if ((ibomb>=0) && (ibomb<4)) fExplodedView = ibomb;
3331 if (fPainter) fPainter->SetExplodedView(ibomb);
3332}
3333
3334////////////////////////////////////////////////////////////////////////////////
3335/// Set cut phi range
3336
3338{
3339 if ((phimin==0) && (phimax==360)) {
3340 fPhiCut = kFALSE;
3341 return;
3342 }
3343 fPhiCut = kTRUE;
3344 fPhimin = phimin;
3345 fPhimax = phimax;
3346}
3347
3348////////////////////////////////////////////////////////////////////////////////
3349/// Set number of segments for approximating circles in drawing.
3350
3352{
3353 if (fNsegments==nseg) return;
3354 if (nseg>2) fNsegments = nseg;
3355 if (fPainter) fPainter->SetNsegments(nseg);
3356}
3357
3358////////////////////////////////////////////////////////////////////////////////
3359/// Get number of segments approximating circles
3360
3362{
3363 return fNsegments;
3364}
3365
3366////////////////////////////////////////////////////////////////////////////////
3367/// Now just a shortcut for GetElementTable.
3368
3370{
3373}
3374
3375////////////////////////////////////////////////////////////////////////////////
3376/// Returns material table. Creates it if not existing.
3377
3379{
3381 return fElementTable;
3382}
3383
3384////////////////////////////////////////////////////////////////////////////////
3385/// Make a rectilinear step of length fStep from current point (fPoint) on current
3386/// direction (fDirection). If the step is imposed by geometry, is_geom flag
3387/// must be true (default). The cross flag specifies if the boundary should be
3388/// crossed in case of a geometry step (default true). Returns new node after step.
3389/// Set also on boundary condition.
3390
3392{
3393 return GetCurrentNavigator()->Step(is_geom, cross);
3394}
3395
3396////////////////////////////////////////////////////////////////////////////////
3397/// shoot npoints randomly in a box of 1E-5 around current point.
3398/// return minimum distance to points outside
3399
3401 const char* g3path)
3402{
3403 return GetGeomPainter()->SamplePoints(npoints, dist, epsil, g3path);
3404}
3405
3406////////////////////////////////////////////////////////////////////////////////
3407/// Set the top volume and corresponding node as starting point of the geometry.
3408
3410{
3411 if (fTopVolume==vol) return;
3412
3413 TSeqCollection *brlist = gROOT->GetListOfBrowsers();
3414 TIter next(brlist);
3415 TBrowser *browser = 0;
3416
3417 if (fTopVolume) fTopVolume->SetTitle("");
3418 fTopVolume = vol;
3419 vol->SetTitle("Top volume");
3420 if (fTopNode) {
3421 TGeoNode *topn = fTopNode;
3422 fTopNode = 0;
3423 while ((browser=(TBrowser*)next())) browser->RecursiveRemove(topn);
3424 delete topn;
3425 } else {
3426 fMasterVolume = vol;
3429 if (fgVerboseLevel>0) Info("SetTopVolume","Top volume is %s. Master volume is %s", fTopVolume->GetName(),
3431 }
3432// fMasterVolume->FindMatrixOfDaughterVolume(vol);
3433// fCurrentMatrix->Print();
3435 fTopNode->SetName(TString::Format("%s_1",vol->GetName()));
3436 fTopNode->SetNumber(1);
3437 fTopNode->SetTitle("Top logical node");
3438 fNodes->AddAt(fTopNode, 0);
3439 if (!GetCurrentNavigator()) {
3441 return;
3442 }
3443 Int_t nnavigators = 0;
3445 if (!arr) return;
3446 nnavigators = arr->GetEntriesFast();
3447 for (Int_t i=0; i<nnavigators; i++) {
3448 TGeoNavigator *nav = (TGeoNavigator*)arr->At(i);
3449 nav->ResetAll();
3450 if (fClosed) nav->GetCache()->BuildInfoBranch();
3451 }
3452}
3453
3454////////////////////////////////////////////////////////////////////////////////
3455/// Define different tracking media.
3456
3458{
3459/*
3460 Int_t nmat = fMaterials->GetSize();
3461 if (!nmat) {printf(" No materials !\n"); return;}
3462 Int_t *media = new Int_t[nmat];
3463 memset(media, 0, nmat*sizeof(Int_t));
3464 Int_t imedia = 1;
3465 TGeoMaterial *mat, *matref;
3466 mat = (TGeoMaterial*)fMaterials->At(0);
3467 if (mat->GetMedia()) {
3468 for (Int_t i=0; i<nmat; i++) {
3469 mat = (TGeoMaterial*)fMaterials->At(i);
3470 mat->Print();
3471 }
3472 return;
3473 }
3474 mat->SetMedia(imedia);
3475 media[0] = imedia++;
3476 mat->Print();
3477 for (Int_t i=0; i<nmat; i++) {
3478 mat = (TGeoMaterial*)fMaterials->At(i);
3479 for (Int_t j=0; j<i; j++) {
3480 matref = (TGeoMaterial*)fMaterials->At(j);
3481 if (mat->IsEq(matref)) {
3482 mat->SetMedia(media[j]);
3483 break;
3484 }
3485 if (j==(i-1)) {
3486 // different material
3487 mat->SetMedia(imedia);
3488 media[i] = imedia++;
3489 mat->Print();
3490 }
3491 }
3492 }
3493*/
3494}
3495
3496////////////////////////////////////////////////////////////////////////////////
3497/// Check pushes and pulls needed to cross the next boundary with respect to the
3498/// position given by FindNextBoundary. If radius is not mentioned the full bounding
3499/// box will be sampled.
3500
3502{
3503 GetGeomPainter()->CheckBoundaryErrors(ntracks, radius);
3504}
3505
3506////////////////////////////////////////////////////////////////////////////////
3507/// Check the boundary errors reference file created by CheckBoundaryErrors method.
3508/// The shape for which the crossing failed is drawn with the starting point in red
3509/// and the extrapolated point to boundary (+/- failing push/pull) in yellow.
3510
3512{
3514}
3515
3516////////////////////////////////////////////////////////////////////////////////
3517/// Classify a given point. See TGeoChecker::CheckPoint().
3518
3520{
3522}
3523
3524////////////////////////////////////////////////////////////////////////////////
3525/// Test for shape navigation methods. Summary for test numbers:
3526/// - 1: DistFromInside/Outside. Sample points inside the shape. Generate
3527/// directions randomly in cos(theta). Compute DistFromInside and move the
3528/// point with bigger distance. Compute DistFromOutside back from new point.
3529/// Plot d-(d1+d2)
3530///
3531
3533{
3534 GetGeomPainter()->CheckShape(shape, testNo, nsamples, option);
3535}
3536
3537////////////////////////////////////////////////////////////////////////////////
3538/// Geometry checking.
3539/// - if option contains 'o': Optional overlap checkings (by sampling and by mesh).
3540/// - if option contains 'b': Optional boundary crossing check + timing per volume.
3541///
3542/// STAGE 1: extensive overlap checking by sampling per volume. Stdout need to be
3543/// checked by user to get report, then TGeoVolume::CheckOverlaps(0.01, "s") can
3544/// be called for the suspicious volumes.
3545///
3546/// STAGE 2: normal overlap checking using the shapes mesh - fills the list of
3547/// overlaps.
3548///
3549/// STAGE 3: shooting NRAYS rays from VERTEX and counting the total number of
3550/// crossings per volume (rays propagated from boundary to boundary until
3551/// geometry exit). Timing computed and results stored in a histo.
3552///
3553/// STAGE 4: shooting 1 mil. random rays inside EACH volume and calling
3554/// FindNextBoundary() + Safety() for each call. The timing is normalized by the
3555/// number of crossings computed at stage 2 and presented as percentage.
3556/// One can get a picture on which are the most "burned" volumes during
3557/// transportation from geometry point of view. Another plot of the timing per
3558/// volume vs. number of daughters is produced.
3559
3561{
3562 TString opt(option);
3563 opt.ToLower();
3564 if (!opt.Length()) {
3565 Error("CheckGeometryFull","The option string must contain a letter. See method documentation.");
3566 return;
3567 }
3568 Bool_t checkoverlaps = opt.Contains("o");
3569 Bool_t checkcrossings = opt.Contains("b");
3570 Double_t vertex[3];
3571 vertex[0] = vx;
3572 vertex[1] = vy;
3573 vertex[2] = vz;
3574 GetGeomPainter()->CheckGeometryFull(checkoverlaps,checkcrossings,ntracks,vertex);
3575}
3576
3577////////////////////////////////////////////////////////////////////////////////
3578/// Perform last checks on the geometry
3579
3581{
3582 if (fgVerboseLevel>0) Info("CheckGeometry","Fixing runtime shapes...");
3583 TIter next(fShapes);
3584 TIter nextv(fVolumes);
3585 TGeoShape *shape;
3586 TGeoVolume *vol;
3587 Bool_t has_runtime = kFALSE;
3588 while ((shape = (TGeoShape*)next())) {
3589 if (shape->IsRunTimeShape()) {
3590 has_runtime = kTRUE;
3591 }
3592 if (fIsGeomReading) shape->AfterStreamer();
3595 }
3596 if (has_runtime) fTopNode->CheckShapes();
3597 else if (fgVerboseLevel>0) Info("CheckGeometry","...Nothing to fix");
3598 // Compute bounding box for assemblies
3600 while ((vol = (TGeoVolume*)nextv())) {
3601 if (vol->IsAssembly()) vol->GetShape()->ComputeBBox();
3602 else if (vol->GetMedium() == dummy) {
3603 Warning("CheckGeometry", "Volume \"%s\" has no medium: assigned dummy medium and material", vol->GetName());
3604 vol->SetMedium(dummy);
3605 }
3606 }
3607}
3608
3609////////////////////////////////////////////////////////////////////////////////
3610/// Check all geometry for illegal overlaps within a limit OVLP.
3611
3613{
3614 if (!fTopNode) {
3615 Error("CheckOverlaps","Top node not set");
3616 return;
3617 }
3619}
3620
3621////////////////////////////////////////////////////////////////////////////////
3622/// Prints the current list of overlaps.
3623
3625{
3626 if (!fOverlaps) return;
3627 Int_t novlp = fOverlaps->GetEntriesFast();
3628 if (!novlp) return;
3629 TGeoManager *geom = (TGeoManager*)this;
3630 geom->GetGeomPainter()->PrintOverlaps();
3631}
3632
3633////////////////////////////////////////////////////////////////////////////////
3634/// Estimate weight of volume VOL with a precision SIGMA(W)/W better than PRECISION.
3635/// Option can be "v" - verbose (default)
3636
3638{
3640 TString opt(option);
3641 opt.ToLower();
3642 Double_t weight;
3643 TGeoVolume *volume = fTopVolume;
3644 if (opt.Contains("v")) {
3645 if (opt.Contains("a")) {
3646 if (fgVerboseLevel>0) Info("Weight", "Computing analytically weight of %s", volume->GetName());
3647 weight = volume->WeightA();
3648 if (fgVerboseLevel>0) Info("Weight", "Computed weight: %f [kg]\n", weight);
3649 return weight;
3650 }
3651 if (fgVerboseLevel>0) {
3652 Info("Weight", "Estimating weight of %s with %g %% precision", fTopVolume->GetName(), 100.*precision);
3653 printf(" event weight err\n");
3654 printf("========================================\n");
3655 }
3656 }
3657 weight = fPainter->Weight(precision, option);
3658 return weight;
3659}
3660
3661////////////////////////////////////////////////////////////////////////////////
3662/// computes the total size in bytes of the branch starting with node.
3663/// The option can specify if all the branch has to be parsed or only the node
3664
3665ULong_t TGeoManager::SizeOf(const TGeoNode * /*node*/, Option_t * /*option*/)
3666{
3667 return 0;
3668}
3669
3670////////////////////////////////////////////////////////////////////////////////
3671/// Stream an object of class TGeoManager.
3672
3674{
3675 if (R__b.IsReading()) {
3676 R__b.ReadClassBuffer(TGeoManager::Class(), this);
3678 CloseGeometry();
3681 } else {
3683 }
3684}
3685
3686////////////////////////////////////////////////////////////////////////////////
3687/// Execute mouse actions on this manager.
3688
3690{
3691 if (!fPainter) return;
3692 fPainter->ExecuteManagerEvent(this, event, px, py);
3693}
3694
3695////////////////////////////////////////////////////////////////////////////////
3696/// Export this geometry to a file
3697///
3698/// - Case 1: root file or root/xml file
3699/// if filename end with ".root". The key will be named name
3700/// By default the geometry is saved without the voxelisation info.
3701/// Use option 'v" to save the voxelisation info.
3702/// if filename end with ".xml" a root/xml file is produced.
3703///
3704/// - Case 2: C++ script
3705/// if filename end with ".C"
3706///
3707/// - Case 3: gdml file
3708/// if filename end with ".gdml"
3709/// NOTE that to use this option, the PYTHONPATH must be defined like
3710/// export PYTHONPATH=$ROOTSYS/lib:$ROOTSYS/geom/gdml
3711///
3712
3714{
3715 TString sfile(filename);
3716 if (sfile.Contains(".C")) {
3717 //Save geometry as a C++ script
3718 if (fgVerboseLevel>0) Info("Export","Exporting %s %s as C++ code", GetName(), GetTitle());
3720 return 1;
3721 }
3722 if (sfile.Contains(".gdml")) {
3723 //Save geometry as a gdml file
3724 if (fgVerboseLevel>0) Info("Export","Exporting %s %s as gdml code", GetName(), GetTitle());
3725 //C++ version
3726 TString cmd ;
3727 cmd = TString::Format("TGDMLWrite::StartGDMLWriting(gGeoManager,\"%s\",\"%s\")", filename, option);
3728 gROOT->ProcessLineFast(cmd);
3729 return 1;
3730 }
3731 if (sfile.Contains(".root") || sfile.Contains(".xml")) {
3732 //Save geometry as a root file
3733 TFile *f = TFile::Open(filename,"recreate");
3734 if (!f || f->IsZombie()) {
3735 Error("Export","Cannot open file");
3736 return 0;
3737 }
3738 TString keyname = name;
3739 if (keyname.IsNull()) keyname = GetName();
3740 TString opt = option;
3741 opt.ToLower();
3742 if (opt.Contains("v")) {
3744 if (fgVerboseLevel>0) Info("Export","Exporting %s %s as root file. Optimizations streamed.", GetName(), GetTitle());
3745 } else {
3747 if (fgVerboseLevel>0) Info("Export","Exporting %s %s as root file. Optimizations not streamed.", GetName(), GetTitle());
3748 }
3749
3750 const char *precision_dbl = TBufferText::GetDoubleFormat();
3751 const char *precision_flt = TBufferText::GetFloatFormat();
3752 TString new_format_dbl = TString::Format("%%.%dg", TGeoManager::GetExportPrecision());
3753 if (sfile.Contains(".xml")) {
3754 TBufferText::SetDoubleFormat(new_format_dbl.Data());
3755 TBufferText::SetFloatFormat(new_format_dbl.Data());
3756 }
3757 Int_t nbytes = Write(keyname);
3758 if (sfile.Contains(".xml")) {
3759 TBufferText::SetFloatFormat(precision_dbl);
3760 TBufferText::SetDoubleFormat(precision_flt);
3761 }
3762
3764 delete f;
3765 return nbytes;
3766 }
3767 return 0;
3768}
3769
3770////////////////////////////////////////////////////////////////////////////////
3771/// Lock current geometry so that no other geometry can be imported.
3772
3774{
3775 fgLock = kTRUE;
3776}
3777
3778////////////////////////////////////////////////////////////////////////////////
3779/// Unlock current geometry.
3780
3782{
3783 fgLock = kFALSE;
3784}
3785
3786////////////////////////////////////////////////////////////////////////////////
3787/// Check lock state.
3788
3790{
3791 return fgLock;
3792}
3793
3794////////////////////////////////////////////////////////////////////////////////
3795/// Set verbosity level (static function).
3796/// - 0 - suppress messages related to geom-painter visibility level
3797/// - 1 - default value
3798
3800{
3801 return fgVerboseLevel;
3802}
3803
3804////////////////////////////////////////////////////////////////////////////////
3805/// Return current verbosity level (static function).
3806
3808{
3809 fgVerboseLevel = vl;
3810}
3811
3812////////////////////////////////////////////////////////////////////////////////
3813///static function
3814///Import a geometry from a gdml or ROOT file
3815///
3816/// - Case 1: gdml
3817/// if filename ends with ".gdml" the foreign geometry described with gdml
3818/// is imported executing some python scripts in $ROOTSYS/gdml.
3819/// NOTE that to use this option, the PYTHONPATH must be defined like
3820/// export PYTHONPATH=$ROOTSYS/lib:$ROOTSYS/gdml
3821///
3822/// - Case 2: root file (.root) or root/xml file (.xml)
3823/// Import in memory from filename the geometry with key=name.
3824/// if name="" (default), the first TGeoManager object in the file is returned.
3825///
3826/// Note that this function deletes the current gGeoManager (if one)
3827/// before importing the new object.
3828
3829TGeoManager *TGeoManager::Import(const char *filename, const char *name, Option_t * /*option*/)
3830{
3831 if (fgLock) {
3832 ::Warning("TGeoManager::Import", "TGeoMananager in lock mode. NOT IMPORTING new geometry");
3833 return nullptr;
3834 }
3835 if (!filename) return 0;
3836 if (fgVerboseLevel>0) ::Info("TGeoManager::Import","Reading geometry from file: %s",filename);
3837
3838 if (gGeoManager) delete gGeoManager;
3839 gGeoManager = nullptr;
3840
3841 if (strstr(filename,".gdml")) {
3842 // import from a gdml file
3843 new TGeoManager("GDMLImport", "Geometry imported from GDML");
3844 TString cmd = TString::Format("TGDMLParse::StartGDML(\"%s\")", filename);
3845 TGeoVolume* world = (TGeoVolume*)gROOT->ProcessLineFast(cmd);
3846
3847 if(world == nullptr) {
3848 delete gGeoManager;
3849 gGeoManager = nullptr;
3850 ::Error("TGeoManager::Import", "Cannot read file %s", filename);
3851 }
3852 else {
3853 gGeoManager->SetTopVolume(world);
3856 }
3857 } else {
3858 // import from a root file
3860 // in case a web file is specified, use the cacheread option to cache
3861 // this file in the cache directory
3862 TFile *f = nullptr;
3863 if (strstr(filename,"http")) f = TFile::Open(filename,"CACHEREAD");
3864 else f = TFile::Open(filename);
3865 if (!f || f->IsZombie()) {
3866 ::Error("TGeoManager::Import", "Cannot open file");
3867 return nullptr;
3868 }
3869 if (name && strlen(name) > 0) {
3870 gGeoManager = (TGeoManager*)f->Get(name);
3871 } else {
3872 TIter next(f->GetListOfKeys());
3873 TKey *key;
3874 while ((key = (TKey*)next())) {
3875 if (strcmp(key->GetClassName(),"TGeoManager") != 0) continue;
3876 gGeoManager = (TGeoManager*)key->ReadObj();
3877 break;
3878 }
3879 }
3880 delete f;
3881 }
3882 if (!gGeoManager) return 0;
3883 if (!gROOT->GetListOfGeometries()->FindObject(gGeoManager)) gROOT->GetListOfGeometries()->Add(gGeoManager);
3884 if (!gROOT->GetListOfBrowsables()->FindObject(gGeoManager)) gROOT->GetListOfBrowsables()->Add(gGeoManager);
3886 return gGeoManager;
3887}
3888
3889////////////////////////////////////////////////////////////////////////////////
3890/// Update element flags when geometry is loaded from a file.
3891
3893{
3894 if (!fElementTable) return;
3895 TIter next(fMaterials);
3896 TGeoMaterial *mat;
3897 TGeoMixture *mix;
3898 TGeoElement *elem, *elem_table;
3899 Int_t i, nelem;
3900 while ((mat=(TGeoMaterial*)next())) {
3901 if (mat->IsMixture()) {
3902 mix = (TGeoMixture*)mat;
3903 nelem = mix->GetNelements();
3904 for (i=0; i<nelem; i++) {
3905 elem = mix->GetElement(i);
3906 if (!elem) continue;
3907 elem_table = fElementTable->GetElement(elem->Z());
3908 if (!elem_table) continue;
3909 if (elem != elem_table) {
3910 elem_table->SetDefined(elem->IsDefined());
3911 elem_table->SetUsed(elem->IsUsed());
3912 } else {
3913 elem_table->SetDefined();
3914 }
3915 }
3916 } else {
3917 elem = mat->GetElement();
3918 if (!elem) continue;
3919 elem_table = fElementTable->GetElement(elem->Z());
3920 if (!elem_table) continue;
3921 if (elem != elem_table) {
3922 elem_table->SetDefined(elem->IsDefined());
3923 elem_table->SetUsed(elem->IsUsed());
3924 } else {
3925 elem_table->SetUsed();
3926 }
3927 }
3928 }
3929}
3930
3931////////////////////////////////////////////////////////////////////////////////
3932/// Initialize PNE array for fast access via index and unique-id.
3933
3935{
3936 if (fHashPNE) {
3938 TIter next(fHashPNE);
3939 TObject *obj;
3940 while ((obj = next())) {
3941 fArrayPNE->Add(obj);
3942 }
3943 return kTRUE;
3944 }
3945 return kFALSE;
3946}
3947
3948////////////////////////////////////////////////////////////////////////////////
3949/// Get time cut for drawing tracks.
3950
3952{
3953 tmin = fTmin;
3954 tmax = fTmax;
3955 return fTimeCut;
3956}
3957
3958////////////////////////////////////////////////////////////////////////////////
3959/// Set time cut interval for drawing tracks. If called with no arguments, time
3960/// cut will be disabled.
3961
3963{
3964 fTmin = tmin;
3965 fTmax = tmax;
3966 if (tmin==0 && tmax==999) fTimeCut = kFALSE;
3967 else fTimeCut = kTRUE;
3969}
3970
3971////////////////////////////////////////////////////////////////////////////////
3972/// Convert coordinates from master volume frame to top.
3973
3974void TGeoManager::MasterToTop(const Double_t *master, Double_t *top) const
3975{
3976 GetCurrentNavigator()->MasterToLocal(master, top);
3977}
3978
3979////////////////////////////////////////////////////////////////////////////////
3980/// Convert coordinates from top volume frame to master.
3981
3982void TGeoManager::TopToMaster(const Double_t *top, Double_t *master) const
3983{
3984 GetCurrentNavigator()->LocalToMaster(top, master);
3985}
3986
3987////////////////////////////////////////////////////////////////////////////////
3988/// Create a parallel world for prioritised navigation. This can be populated
3989/// with physical nodes and can be navigated independently using its API.
3990/// In case the flag SetUseParallelWorldNav is set, any navigation query in the
3991/// main geometry is checked against the parallel geometry, which gets priority
3992/// in case of overlaps with the main geometry volumes.
3993
3995{
3997 return fParallelWorld;
3998}
3999
4000////////////////////////////////////////////////////////////////////////////////
4001/// Activate/deactivate usage of parallel world navigation. Can only be done if
4002/// there is a parallel world. Activating navigation will automatically close
4003/// the parallel geometry.
4004
4006{
4007 if (!fParallelWorld) {
4008 Error("SetUseParallelWorldNav", "No parallel world geometry defined. Use CreateParallelWorld.");
4009 return;
4010 }
4011 if (!flag) {
4012 fUsePWNav = flag;
4013 return;
4014 }
4015 if (!fClosed) {
4016 Error("SetUseParallelWorldNav", "The geometry must be closed first");
4017 return;
4018 }
4019 // Closing the parallel world geometry is mandatory
4021}
4022
4024 Bool_t val = gGeometryLocked;
4025 gGeometryLocked = new_value;
4026 return val;
4027}
4028
4030{
4031 return fgDefaultUnits;
4032}
4033
4035{
4036 if ( fgDefaultUnits == new_value ) {
4037 return;
4038 }
4039 else if ( gGeometryLocked ) {
4040 ::Fatal("TGeoManager","The system of units may only be changed once, \n"
4041 "BEFORE any elements and materials are created! \n"
4042 "Alternatively unlock the default units at own risk.");
4043 }
4044 else if ( new_value == kG4Units ) {
4045 ::Info("TGeoManager","Changing system of units to Geant4 units (mm, ns, MeV).");
4046 }
4047 else if ( new_value == kRootUnits ) {
4048 ::Info("TGeoManager","Changing system of units to ROOT units (cm, s, GeV).");
4049 }
4050 fgDefaultUnits = new_value;
4051}
#define SafeDelete(p)
Definition: RConfig.hxx:534
#define f(i)
Definition: RSha256.hxx:104
#define h(i)
Definition: RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition: RtypesCore.h:63
int Int_t
Definition: RtypesCore.h:45
unsigned char UChar_t
Definition: RtypesCore.h:38
const Bool_t kFALSE
Definition: RtypesCore.h:101
unsigned int UInt_t
Definition: RtypesCore.h:46
float Float_t
Definition: RtypesCore.h:57
double Double_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:100
unsigned long ULong_t
Definition: RtypesCore.h:55
const char Option_t
Definition: RtypesCore.h:66
#define BIT(n)
Definition: Rtypes.h:85
#define ClassImp(name)
Definition: Rtypes.h:375
@ kGray
Definition: Rtypes.h:65
@ kRed
Definition: Rtypes.h:66
@ kOrange
Definition: Rtypes.h:67
@ kGreen
Definition: Rtypes.h:66
@ kMagenta
Definition: Rtypes.h:66
@ kBlue
Definition: Rtypes.h:66
@ kYellow
Definition: Rtypes.h:66
R__EXTERN TEnv * gEnv
Definition: TEnv.h:170
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 Float_t Float_t b
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:110
TGeoManager * gGeoManager
static Bool_t gGeometryLocked
R__EXTERN TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.h:478
int nentries
Definition: THbookFile.cxx:91
#define gROOT
Definition: TROOT.h:404
R__EXTERN TStyle * gStyle
Definition: TStyle.h:414
#define gPad
Definition: TVirtualPad.h:288
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
void RecursiveRemove(TObject *obj) override
Recursively remove obj from browser.
Definition: TBrowser.cxx:391
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
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Bool_t IsReading() const
Definition: TBuffer.h:86
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
@ kRealNew
Definition: TClass.h:107
@ kDummyNew
Definition: TClass.h:107
static ENewType IsCallingNew()
Static method returning the defConstructor flag passed to TClass::New().
Definition: TClass.cxx:5890
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:184
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:102
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:491
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:54
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:4019
This class is used in the process of reading and writing the GDML "matrix" tag.
Definition: TGDMLMatrix.h:34
Bool_t IsVisTouched() const
Definition: TGeoAtt.h:96
void SetVisStreamed(Bool_t vis=kTRUE)
Mark attributes as "streamed to file".
Definition: TGeoAtt.cxx:123
void SetVisTouched(Bool_t vis=kTRUE)
Mark visualization attributes as "modified".
Definition: TGeoAtt.cxx:131
void SetVisBranch()
Set branch type visibility.
Definition: TGeoAtt.cxx:67
Box class.
Definition: TGeoBBox.h:18
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 ...
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 * 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.
TGeoVolume * MakeXtru(const char *name, TGeoMedium *medium, Int_t nz)
Make a TGeoXtru-shaped volume with nz planes.
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.
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.
Int_t AddShape(TGeoShape *shape)
Add a shape to the list. Returns index of the shape in list.
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.
static TGeoBuilder * Instance(TGeoManager *geom)
Return pointer to singleton.
Definition: TGeoBuilder.cxx:74
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.
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.
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.
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.
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.
Int_t AddTransformation(TGeoMatrix *matrix)
Add a matrix to the list. Returns index of the matrix in list.
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.
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.
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.
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 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>'.
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 * 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.
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.
TGeoVolumeAssembly * MakeVolumeAssembly(const char *name)
Make an assembly of volumes.
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.
Int_t AddMaterial(TGeoMaterial *material)
Add a material to the list. Returns index of the material in list.
Definition: TGeoBuilder.cxx:88
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
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.
TGeoVolume * MakeArb8(const char *name, TGeoMedium *medium, Double_t dz, Double_t *vertices=0)
Make an TGeoArb8 volume.
TGeoVolume * Volume(const char *name, const char *shape, Int_t nmed, Float_t *upar, Int_t npar=0)
Create a volume in GEANT3 style.
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,...
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 RegisterMatrix(TGeoMatrix *matrix)
Register a matrix to the list of matrices.
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.
Class describing rotation + translation.
Definition: TGeoMatrix.h:292
Composite shapes are Boolean combinations of two or more shape components.
Table of elements.
Definition: TGeoElement.h:370
TGeoElement * GetElement(Int_t z)
Definition: TGeoElement.h:410
Base class for chemical elements.
Definition: TGeoElement.h:37
Bool_t IsDefined() const
Definition: TGeoElement.h:86
void SetDefined(Bool_t flag=kTRUE)
Definition: TGeoElement.h:90
Int_t Z() const
Definition: TGeoElement.h:73
void SetUsed(Bool_t flag=kTRUE)
Definition: TGeoElement.h:91
Bool_t IsUsed() const
Definition: TGeoElement.h:88
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition: TGeoMatrix.h:421
An identity transformation.
Definition: TGeoMatrix.h:384
A geometry iterator.
Definition: TGeoNode.h:245
Int_t GetLevel() const
Definition: TGeoNode.h:276
The manager class for any TGeo geometry.
Definition: TGeoManager.h:45
static void UnlockGeometry()
Unlock current geometry.
Double_t fPhimax
lowest range for phi cut
Definition: TGeoManager.h:67
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.
void Browse(TBrowser *b)
Describe how to browse this object.
Int_t fRaytraceMode
Flag for multi-threading.
Definition: TGeoManager.h:150
Double_t fVisDensity
particles to be drawn
Definition: TGeoManager.h:73
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.
TGeoNode * SearchNode(Bool_t downwards=kFALSE, const TGeoNode *skipnode=0)
Returns the deepest node containing fPoint, which must be set a priori.
TGeoPNEntry * GetAlignableEntry(const char *name) const
Retrieves an existing alignable object.
TGeoVolume * fMasterVolume
top physical node
Definition: TGeoManager.h:131
TVirtualGeoTrack * FindTrackWithId(Int_t id) const
Search the track hierarchy to find the track with the given id.
TObjArray * fArrayPNE
Definition: TGeoManager.h:143
virtual Int_t GetByteCount(Option_t *option=0)
Get total size of geometry in bytes.
void TestOverlaps(const char *path="")
Geometry overlap checker based on sampling.
static EDefaultUnits GetDefaultUnits()
void RemoveMaterial(Int_t index)
Remove material at given index.
Int_t CountNodes(const TGeoVolume *vol=0, Int_t nlevels=10000, Int_t option=0)
Count the total number of nodes starting from a volume, nlevels down.
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:78
THashList * fHashPNE
hash list of group volumes providing fast search
Definition: TGeoManager.h:142
TGeoVolume * MakeArb8(const char *name, TGeoMedium *medium, Double_t dz, Double_t *vertices=0)
Make an TGeoArb8 volume.
static Int_t fgVerboseLevel
Lock preventing a second geometry to be loaded.
Definition: TGeoManager.h:55
void Init()
Initialize manager class.
Bool_t InitArrayPNE() const
Initialize PNE array for fast access via index and unique-id.
TObjArray * fPhysicalNodes
Definition: TGeoManager.h:100
virtual ULong_t SizeOf(const TGeoNode *node, Option_t *option)
computes the total size in bytes of the branch starting with node.
TObjArray * fUniqueVolumes
Definition: TGeoManager.h:133
static UInt_t fgExportPrecision
Maximum number of Xtru vertices.
Definition: TGeoManager.h:59
TObjArray * fRegions
Definition: TGeoManager.h:113
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
Definition: TGeoManager.h:101
TGeoVolume * fPaintVolume
Definition: TGeoManager.h:138
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.
static TClass * Class()
ConstPropMap_t fProperties
Definition: TGeoManager.h:153
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
Definition: TGeoManager.h:109
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
Definition: TGeoManager.h:99
Int_t * fValuePNEId
Definition: TGeoManager.h:147
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:89
void AddBorderSurface(TGeoBorderSurface *surf)
Add border surface;.
void SetClippingShape(TGeoShape *clip)
Set a user-defined shape as clipping for ray tracing.
TGeoVolume * fCurrentVolume
current navigator
Definition: TGeoManager.h:128
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 volumes providing fast search
Definition: TGeoManager.h:141
Int_t fVisOption
Definition: TGeoManager.h:75
static std::mutex fgMutex
Definition: TGeoManager.h:53
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.
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
Definition: TGeoManager.h:543
Double_t fPhimin
Definition: TGeoManager.h:66
static Bool_t fgLockNavigators
Number of registered threads.
Definition: TGeoManager.h:126
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
Definition: TGeoManager.h:90
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
Definition: TGeoManager.h:134
TGeoNavigator * GetCurrentNavigator() const
Returns current navigator for the calling thread.
THashList * fHashVolumes
Definition: TGeoManager.h:140
TObjArray * fMatrices
current painter
Definition: TGeoManager.h:97
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 AddTrack(Int_t id, Int_t pdgcode, TObject *particle=0)
Add a track to the list of tracks.
Int_t AddTransformation(const TGeoMatrix *matrix)
Add a matrix to the list. Returns index of the matrix in list.
TObjArray * fOpticalSurfaces
Definition: TGeoManager.h:106
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
Definition: TGeoManager.h:114
static Int_t GetMaxLevels()
Return maximum number of levels used in the geometry.
Double_t fTmin
highest range for phi cut
Definition: TGeoManager.h:68
static Bool_t IsLocked()
Check lock state.
TGeoVolume * fTopVolume
current volume
Definition: TGeoManager.h:129
void RandomRays(Int_t nrays=1000, Double_t startx=0, Double_t starty=0, Double_t startz=0, const char *target_vol=0, Bool_t check_norm=kFALSE)
Randomly shoot nrays and plot intersections with surfaces for current top node.
TGeoVolume * fUserPaintVolume
volume currently painted
Definition: TGeoManager.h:139
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
Definition: TGeoManager.h:519
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
Definition: TGeoManager.h:108
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
mutex for navigator booking in MT mode
Definition: TGeoManager.h:54
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
Definition: TGeoManager.h:98
void AddOpticalSurface(TGeoOpticalSurface *optsurf)
Add optical surface;.
static void SetDefaultUnits(EDefaultUnits new_value)
Bool_t fLoopVolumes
flag that geometry is closed
Definition: TGeoManager.h:84
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 level in geometry.
Definition: TGeoManager.h:57
Bool_t fUsePWNav
Raytrace mode: 0=normal, 1=pass through, 2=transparent.
Definition: TGeoManager.h:151
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
void CountLevels()
Count maximum number of nodes per volume, maximum depth and maximum number of xtru vertices.
Int_t fMaxThreads
Definition: TGeoManager.h:148
Bool_t fIsGeomReading
Definition: TGeoManager.h:86
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
Definition: TGeoManager.h:152
void RegisterMatrix(const TGeoMatrix *matrix)
Register a matrix to the list of matrices.
TVirtualGeoTrack * GetTrack(Int_t index)
Definition: TGeoManager.h:398
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
flag that nodes are the selected objects in pad rather than volumes
Definition: TGeoManager.h:95
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
switch ON/OFF volume activity (default OFF - all volumes active))
Definition: TGeoManager.h:94
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
flag for GL reflections
Definition: TGeoManager.h:93
void GetBranchNames(Int_t *names) const
Fill volume names of current branch into an array.
static ThreadsMap_t * fgThreadId
Map between thread id's and navigator arrays.
Definition: TGeoManager.h:124
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
upper time limit for tracks drawing
Definition: TGeoManager.h:70
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute mouse actions on this manager.
Int_t fNLevel
table of elements
Definition: TGeoManager.h:137
void OptimizeVoxels(const char *filename="tgeovox.C")
Optimize voxelization type for all volumes. Save best choice in a macro.
void CheckPoint(Double_t x=0, Double_t y=0, Double_t z=0, Option_t *option="")
Classify a given point. See TGeoChecker::CheckPoint().
TGeoVolume * GetVolume(const char *name) const
Search for a named volume. All trailing blanks stripped.
void SetAnimateTracks(Bool_t flag=kTRUE)
Definition: TGeoManager.h:580
Bool_t fIsGeomCleaning
flag set when reading geometry
Definition: TGeoManager.h:87
Bool_t IsSameLocation() const
Definition: TGeoManager.h:415
void DefaultColors()
Set default volume colors according to A of material.
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 ...
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
clipping shape for raytracing
Definition: TGeoManager.h:135
static void SetNavigatorsLock(Bool_t flag)
Set the lock for navigators.
static Int_t fgMaxXtruVert
Maximum number of daughters.
Definition: TGeoManager.h:58
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.
static UInt_t GetExportPrecision()
Definition: TGeoManager.h:479
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.
Int_t fNPNEId
Definition: TGeoManager.h:145
void CheckShape(TGeoShape *shape, Int_t testNo, Int_t nsamples, Option_t *option)
Test for shape navigation methods.
static Int_t fgMaxLevel
Verbosity level for Info messages (no IO).
Definition: TGeoManager.h:56
Int_t fNpdg
current track
Definition: TGeoManager.h:81
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 pointin