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
580Bool_t TGeoManager::AddProperty(const char* property, Double_t value)
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
593Double_t TGeoManager::GetProperty(const char *property, Bool_t *error) const
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{
645 Int_t index = fNtracks;
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{
655 Int_t index = fNtracks;
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;
778 TGeoNavigator *nav = array->SetCurrentNavigator(index);
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("");
947 GetGeomPainter()->EditGeometry(option);
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 Voxelize("ALL");
1400 CountLevels();
1401 for (Int_t i=0; i<nnavigators; i++) {
1402 nav = (TGeoNavigator*)GetListOfNavigators()->At(i);
1403 nav->GetCache()->BuildInfoBranch();
1404 if (nodeid) nav->GetCache()->BuildIdArray();
1405 }
1406 if (!fHashVolumes) {
1407 Int_t nvol = fVolumes->GetEntriesFast();
1408 Int_t ngvol = fGVolumes->GetEntriesFast();
1409 fHashVolumes = new THashList(nvol+1);
1410 fHashGVolumes = new THashList(ngvol+1);
1411 Int_t i;
1412 for (i=0; i<ngvol; i++) fHashGVolumes->AddLast(fGVolumes->At(i));
1413 for (i=0; i<nvol; i++) fHashVolumes->AddLast(fVolumes->At(i));
1414 }
1415 fClosed = kTRUE;
1416 if (fParallelWorld) {
1417 if (fgVerboseLevel>0) Info("CloseGeometry","Recreating parallel world %s ...",fParallelWorld->GetName());
1419 }
1420
1421 if (fgVerboseLevel>0) Info("CloseGeometry","%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast()-1, GetTitle());
1422 if (fgVerboseLevel>0) Info("CloseGeometry","----------------modeler ready----------------");
1423 return;
1424 }
1425
1426 // Create a geometry navigator if not present
1428 nnavigators = GetListOfNavigators()->GetEntriesFast();
1430 CheckGeometry();
1431 if (fgVerboseLevel>0) Info("CloseGeometry","Counting nodes...");
1432 fNNodes = CountNodes();
1434 if (fNLevel<30) fNLevel = 100;
1435
1436// BuildIdArray();
1437 Voxelize("ALL");
1438 if (fgVerboseLevel>0) Info("CloseGeometry","Building cache...");
1439 CountLevels();
1440 for (Int_t i=0; i<nnavigators; i++) {
1441 nav = (TGeoNavigator*)GetListOfNavigators()->At(i);
1442 nav->GetCache()->BuildInfoBranch();
1443 if (nodeid) nav->GetCache()->BuildIdArray();
1444 }
1445 fClosed = kTRUE;
1446 if (fgVerboseLevel>0) {
1447 Info("CloseGeometry","%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast()-1, GetTitle());
1448 Info("CloseGeometry","----------------modeler ready----------------");
1449 }
1450}
1451
1452////////////////////////////////////////////////////////////////////////////////
1453/// Clear the list of overlaps.
1454
1456{
1457 if (fOverlaps) {
1458 fOverlaps->Delete();
1459 delete fOverlaps;
1460 }
1461 fOverlaps = new TObjArray();
1462}
1463
1464////////////////////////////////////////////////////////////////////////////////
1465/// Remove a shape from the list of shapes.
1466
1468{
1469 if (fShapes->FindObject(shape)) fShapes->Remove((TGeoShape*)shape);
1470 delete shape;
1471}
1472
1473////////////////////////////////////////////////////////////////////////////////
1474/// Clean temporary volumes and shapes from garbage collection.
1475
1477{
1478 if (!fGVolumes && !fGShapes) return;
1479 Int_t i,nentries;
1480 if (fGVolumes) {
1482 TGeoVolume *vol = 0;
1483 for (i=0; i<nentries; i++) {
1484 vol=(TGeoVolume*)fGVolumes->At(i);
1485 if (vol) vol->SetFinder(0);
1486 }
1487 fGVolumes->Delete();
1488 delete fGVolumes;
1489 fGVolumes = 0;
1490 }
1491 if (fGShapes) {
1492 fGShapes->Delete();
1493 delete fGShapes;
1494 fGShapes = 0;
1495 }
1496}
1497
1498////////////////////////////////////////////////////////////////////////////////
1499/// Change current path to point to the node having this id.
1500/// Node id has to be in range : 0 to fNNodes-1 (no check for performance reasons)
1501
1503{
1504 GetCurrentNavigator()->CdNode(nodeid);
1505}
1506
1507////////////////////////////////////////////////////////////////////////////////
1508/// Get the unique ID of the current node.
1509
1511{
1513}
1514
1515////////////////////////////////////////////////////////////////////////////////
1516/// Make top level node the current node. Updates the cache accordingly.
1517/// Determine the overlapping state of current node.
1518
1520{
1522}
1523
1524////////////////////////////////////////////////////////////////////////////////
1525/// Go one level up in geometry. Updates cache accordingly.
1526/// Determine the overlapping state of current node.
1527
1529{
1531}
1532
1533////////////////////////////////////////////////////////////////////////////////
1534/// Make a daughter of current node current. Can be called only with a valid
1535/// daughter index (no check). Updates cache accordingly.
1536
1538{
1539 GetCurrentNavigator()->CdDown(index);
1540}
1541
1542////////////////////////////////////////////////////////////////////////////////
1543/// Do a cd to the node found next by FindNextBoundary
1544
1546{
1548}
1549
1550////////////////////////////////////////////////////////////////////////////////
1551/// Browse the tree of nodes starting from fTopNode according to pathname.
1552/// Changes the path accordingly.
1553
1554Bool_t TGeoManager::cd(const char *path)
1555{
1556 return GetCurrentNavigator()->cd(path);
1557}
1558
1559////////////////////////////////////////////////////////////////////////////////
1560/// Check if a geometry path is valid without changing the state of the current navigator.
1561
1562Bool_t TGeoManager::CheckPath(const char *path) const
1563{
1564 return GetCurrentNavigator()->CheckPath(path);
1565}
1566
1567////////////////////////////////////////////////////////////////////////////////
1568/// Convert all reflections in geometry to normal rotations + reflected shapes.
1569
1571{
1572 if (!fTopNode) return;
1573 if (fgVerboseLevel>0) Info("ConvertReflections", "Converting reflections in: %s - %s ...", GetName(), GetTitle());
1575 TGeoNode *node;
1576 TGeoNodeMatrix *nodematrix;
1577 TGeoMatrix *matrix, *mclone;
1578 TGeoVolume *reflected;
1579 while ((node=next())) {
1580 matrix = node->GetMatrix();
1581 if (matrix->IsReflection()) {
1582// printf("%s before\n", node->GetName());
1583// matrix->Print();
1584 mclone = new TGeoCombiTrans(*matrix);
1585 mclone->RegisterYourself();
1586 // Reflect just the rotation component
1587 mclone->ReflectZ(kFALSE, kTRUE);
1588 nodematrix = (TGeoNodeMatrix*)node;
1589 nodematrix->SetMatrix(mclone);
1590// printf("%s after\n", node->GetName());
1591// node->GetMatrix()->Print();
1592 reflected = node->GetVolume()->MakeReflectedVolume();
1593 node->SetVolume(reflected);
1594 }
1595 }
1596 if (fgVerboseLevel>0) Info("ConvertReflections", "Done");
1597}
1598
1599////////////////////////////////////////////////////////////////////////////////
1600/// Count maximum number of nodes per volume, maximum depth and maximum
1601/// number of xtru vertices.
1602
1604{
1605 if (!fTopNode) {
1606 Error("CountLevels", "Top node not defined.");
1607 return;
1608 }
1610 Bool_t fixrefs = fIsGeomReading && (fMasterVolume->GetRefCount()==1);
1612 if (fgVerboseLevel>1 && fixrefs) Info("CountLevels", "Fixing volume reference counts");
1613 TGeoNode *node;
1614 Int_t maxlevel = 1;
1615 Int_t maxnodes = fTopVolume->GetNdaughters();
1616 Int_t maxvertices = 1;
1617 while ((node=next())) {
1618 if (fixrefs) {
1619 node->GetVolume()->Grab();
1620 for (Int_t ibit=10; ibit<14; ibit++) {
1621 node->SetBit(BIT(ibit+4), node->TestBit(BIT(ibit)));
1622// node->ResetBit(BIT(ibit)); // cannot overwrite old crap for reproducibility
1623 }
1624 }
1625 if (node->GetVolume()->GetVoxels()) {
1626 if (node->GetNdaughters()>maxnodes) maxnodes = node->GetNdaughters();
1627 }
1628 if (next.GetLevel()>maxlevel) maxlevel = next.GetLevel();
1629 if (node->GetVolume()->GetShape()->IsA()==TGeoXtru::Class()) {
1630 TGeoXtru *xtru = (TGeoXtru*)node->GetVolume()->GetShape();
1631 if (xtru->GetNvert()>maxvertices) maxvertices = xtru->GetNvert();
1632 }
1633 }
1634 fgMaxLevel = maxlevel;
1635 fgMaxDaughters = maxnodes;
1636 fgMaxXtruVert = maxvertices;
1637 if (fgVerboseLevel>0) Info("CountLevels", "max level = %d, max placements = %d", fgMaxLevel, fgMaxDaughters);
1638}
1639
1640////////////////////////////////////////////////////////////////////////////////
1641/// Count the total number of nodes starting from a volume, nlevels down.
1642
1644{
1645 TGeoVolume *top;
1646 if (!vol) {
1647 top = fTopVolume;
1648 } else {
1649 top = (TGeoVolume*)vol;
1650 }
1651 Int_t count = top->CountNodes(nlevels, option);
1652 return count;
1653}
1654
1655////////////////////////////////////////////////////////////////////////////////
1656/// Set default angles for a given view.
1657
1659{
1661}
1662
1663////////////////////////////////////////////////////////////////////////////////
1664/// Draw current point in the same view.
1665
1667{
1668 if (fPainter) fPainter->DrawCurrentPoint(color);
1669}
1670
1671////////////////////////////////////////////////////////////////////////////////
1672/// Draw animation of tracks
1673
1675{
1678 if (tmin<0 || tmin>=tmax || nframes<1) return;
1680 box[0] = box[1] = box[2] = 0;
1681 box[3] = box[4] = box[5] = 100;
1682 Double_t dt = (tmax-tmin)/Double_t(nframes);
1683 Double_t delt = 2E-9;
1684 Double_t t = tmin;
1685 Int_t i, j;
1686 TString opt(option);
1687 Bool_t save = kFALSE, geomanim=kFALSE;
1688 TString fname;
1689 if (opt.Contains("/S")) save = kTRUE;
1690
1691 if (opt.Contains("/G")) geomanim = kTRUE;
1692 SetTminTmax(0,0);
1693 DrawTracks(opt.Data());
1694 Double_t start[6] = {0,0,0,0,0,0};
1695 Double_t end[6] = {0,0,0,0,0,0};
1696 Double_t dd[6] = {0,0,0,0,0,0};
1697 Double_t dlat=0, dlong=0, dpsi=0;
1698 if (geomanim) {
1699 fPainter->EstimateCameraMove(tmin+5*dt, tmin+15*dt, start, end);
1700 for (i=0; i<3; i++) {
1701 start[i+3] = 20 + 1.3*start[i+3];
1702 end[i+3] = 20 + 0.9*end[i+3];
1703 }
1704 for (i=0; i<6; i++) {
1705 dd[i] = (end[i]-start[i])/10.;
1706 }
1707 memcpy(box, start, 6*sizeof(Double_t));
1708 fPainter->GetViewAngles(dlong,dlat,dpsi);
1709 dlong = (-206-dlong)/Double_t(nframes);
1710 dlat = (126-dlat)/Double_t(nframes);
1711 dpsi = (75-dpsi)/Double_t(nframes);
1713 }
1714
1715 for (i=0; i<nframes; i++) {
1716 if (t-delt<0) SetTminTmax(t-delt,t);
1717 else gGeoManager->SetTminTmax(t-delt,t);
1718 if (geomanim) {
1719 for (j=0; j<6; j++) box[j]+=dd[j];
1720 fPainter->GrabFocus(1,dlong,dlat,dpsi);
1721 } else {
1722 ModifiedPad();
1723 }
1724 if (save) {
1725 fname = TString::Format("anim%04d.gif", i);
1726 gPad->Print(fname);
1727 }
1728 t += dt;
1729 }
1731}
1732
1733////////////////////////////////////////////////////////////////////////////////
1734/// Draw tracks over the geometry, according to option. By default, only
1735/// primaries are drawn. See TGeoTrack::Draw() for additional options.
1736
1738{
1739 TVirtualGeoTrack *track;
1740 //SetVisLevel(1);
1741 //SetVisOption(1);
1743 for (Int_t i=0; i<fNtracks; i++) {
1744 track = GetTrack(i);
1745 if (track) track->Draw(option);
1746 }
1748 ModifiedPad();
1749}
1750
1751////////////////////////////////////////////////////////////////////////////////
1752/// Draw current path
1753
1754void TGeoManager::DrawPath(const char *path, Option_t *option)
1755{
1756 if (!fTopVolume) return;
1758 GetGeomPainter()->DrawPath(path, option);
1759}
1760
1761////////////////////////////////////////////////////////////////////////////////
1762/// Draw random points in the bounding box of a volume.
1763
1764void TGeoManager::RandomPoints(const TGeoVolume *vol, Int_t npoints, Option_t *option)
1765{
1766 GetGeomPainter()->RandomPoints((TGeoVolume*)vol, npoints, option);
1767}
1768
1769////////////////////////////////////////////////////////////////////////////////
1770/// Check time of finding "Where am I" for n points.
1771
1772void TGeoManager::Test(Int_t npoints, Option_t *option)
1773{
1774 GetGeomPainter()->Test(npoints, option);
1775}
1776
1777////////////////////////////////////////////////////////////////////////////////
1778/// Geometry overlap checker based on sampling.
1779
1780void TGeoManager::TestOverlaps(const char* path)
1781{
1783}
1784
1785////////////////////////////////////////////////////////////////////////////////
1786/// Fill volume names of current branch into an array.
1787
1789{
1791}
1792
1793////////////////////////////////////////////////////////////////////////////////
1794/// Get name for given pdg code;
1795
1796const char *TGeoManager::GetPdgName(Int_t pdg) const
1797{
1798 static char defaultname[5] = { "XXX" };
1799 if (!fPdgNames || !pdg) return defaultname;
1800 for (Int_t i=0; i<fNpdg; i++) {
1801 if (fPdgId[i]==pdg) return fPdgNames->At(i)->GetName();
1802 }
1803 return defaultname;
1804}
1805
1806////////////////////////////////////////////////////////////////////////////////
1807/// Set a name for a particle having a given pdg.
1808
1809void TGeoManager::SetPdgName(Int_t pdg, const char *name)
1810{
1811 if (!pdg) return;
1812 if (!fPdgNames) {
1813 fPdgNames = new TObjArray(1024);
1814 }
1815 if (!strcmp(name, GetPdgName(pdg))) return;
1816 // store pdg name
1817 if (fNpdg>1023) {
1818 Warning("SetPdgName", "No more than 256 different pdg codes allowed");
1819 return;
1820 }
1821 fPdgId[fNpdg] = pdg;
1822 TNamed *pdgname = new TNamed(name, "");
1823 fPdgNames->AddAtAndExpand(pdgname, fNpdg++);
1824}
1825
1826////////////////////////////////////////////////////////////////////////////////
1827/// Get GDML matrix with a given name;
1828
1830{
1832}
1833
1834////////////////////////////////////////////////////////////////////////////////
1835/// Add GDML matrix;
1837{
1838 if (GetGDMLMatrix(mat->GetName())) {
1839 Error("AddGDMLMatrix", "Matrix %s already added to manager", mat->GetName());
1840 return;
1841 }
1842 fGDMLMatrices->Add(mat);
1843}
1844
1845////////////////////////////////////////////////////////////////////////////////
1846/// Get optical surface with a given name;
1847
1849{
1851}
1852
1853////////////////////////////////////////////////////////////////////////////////
1854/// Add optical surface;
1856{
1857 if (GetOpticalSurface(optsurf->GetName())) {
1858 Error("AddOpticalSurface", "Surface %s already added to manager", optsurf->GetName());
1859 return;
1860 }
1861 fOpticalSurfaces->Add(optsurf);
1862}
1863
1864////////////////////////////////////////////////////////////////////////////////
1865/// Get skin surface with a given name;
1866
1868{
1870}
1871
1872////////////////////////////////////////////////////////////////////////////////
1873/// Add skin surface;
1875{
1876 if (GetSkinSurface(surf->GetName())) {
1877 Error("AddSkinSurface", "Surface %s already added to manager", surf->GetName());
1878 return;
1879 }
1880 fSkinSurfaces->Add(surf);
1881}
1882
1883////////////////////////////////////////////////////////////////////////////////
1884/// Get border surface with a given name;
1885
1887{
1889}
1890
1891////////////////////////////////////////////////////////////////////////////////
1892/// Add border surface;
1894{
1895 if (GetBorderSurface(surf->GetName())) {
1896 Error("AddBorderSurface", "Surface %s already added to manager", surf->GetName());
1897 return;
1898 }
1899 fBorderSurfaces->Add(surf);
1900}
1901
1902////////////////////////////////////////////////////////////////////////////////
1903/// Fill node copy numbers of current branch into an array.
1904
1905void TGeoManager::GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
1906{
1907 GetCurrentNavigator()->GetBranchNumbers(copyNumbers, volumeNumbers);
1908}
1909
1910////////////////////////////////////////////////////////////////////////////////
1911/// Fill node copy numbers of current branch into an array.
1912
1914{
1916}
1917
1918////////////////////////////////////////////////////////////////////////////////
1919/// Retrieve cartesian and radial bomb factors.
1920
1921void TGeoManager::GetBombFactors(Double_t &bombx, Double_t &bomby, Double_t &bombz, Double_t &bombr) const
1922{
1923 if (fPainter) {
1924 fPainter->GetBombFactors(bombx, bomby, bombz, bombr);
1925 return;
1926 }
1927 bombx = bomby = bombz = bombr = 1.3;
1928}
1929
1930////////////////////////////////////////////////////////////////////////////////
1931/// Return maximum number of daughters of a volume used in the geometry.
1932
1934{
1935 return fgMaxDaughters;
1936}
1937
1938////////////////////////////////////////////////////////////////////////////////
1939/// Return maximum number of levels used in the geometry.
1940
1942{
1943 return fgMaxLevel;
1944}
1945
1946////////////////////////////////////////////////////////////////////////////////
1947/// Return maximum number of vertices for an xtru shape used.
1948
1950{
1951 return fgMaxXtruVert;
1952}
1953
1954////////////////////////////////////////////////////////////////////////////////
1955/// Returns number of threads that were set to use geometry.
1956
1958{
1959 return fgNumThreads;
1960}
1961
1962////////////////////////////////////////////////////////////////////////////////
1963/// Return stored current matrix (global matrix of the next touched node).
1964
1966{
1967 if (!GetCurrentNavigator()) return NULL;
1968 return GetCurrentNavigator()->GetHMatrix();
1969}
1970
1971////////////////////////////////////////////////////////////////////////////////
1972/// Returns current depth to which geometry is drawn.
1973
1975{
1976 return fVisLevel;
1977}
1978
1979////////////////////////////////////////////////////////////////////////////////
1980/// Returns current depth to which geometry is drawn.
1981
1983{
1984 return fVisOption;
1985}
1986
1987////////////////////////////////////////////////////////////////////////////////
1988/// Find level of virtuality of current overlapping node (number of levels
1989/// up having the same tracking media.
1990
1992{
1994}
1995
1996////////////////////////////////////////////////////////////////////////////////
1997/// Search the track hierarchy to find the track with the
1998/// given id
1999///
2000/// if 'primsFirst' is true, then:
2001/// first tries TGeoManager::GetTrackOfId, then does a
2002/// recursive search if that fails. this would be faster
2003/// if the track is somehow known to be a primary
2004
2006{
2007 TVirtualGeoTrack* trk = 0;
2008 trk = GetTrackOfId(id);
2009 if (trk) return trk;
2010 // need recursive search
2011 TIter next(fTracks);
2012 TVirtualGeoTrack* prim;
2013 while ((prim = (TVirtualGeoTrack*)next())) {
2014 trk = prim->FindTrackWithId(id);
2015 if (trk) return trk;
2016 }
2017 return NULL;
2018}
2019
2020////////////////////////////////////////////////////////////////////////////////
2021/// Get track with a given ID.
2022
2024{
2025 TVirtualGeoTrack *track;
2026 for (Int_t i=0; i<fNtracks; i++) {
2027 if ((track = (TVirtualGeoTrack *)fTracks->UncheckedAt(i))) {
2028 if (track->GetId() == id) return track;
2029 }
2030 }
2031 return 0;
2032}
2033
2034////////////////////////////////////////////////////////////////////////////////
2035/// Get parent track with a given ID.
2036
2038{
2040 while ((track=track->GetMother())) {
2041 if (track->GetId()==id) return track;
2042 }
2043 return 0;
2044}
2045
2046////////////////////////////////////////////////////////////////////////////////
2047/// Get index for track id, -1 if not found.
2048
2050{
2051 TVirtualGeoTrack *track;
2052 for (Int_t i=0; i<fNtracks; i++) {
2053 if ((track = (TVirtualGeoTrack *)fTracks->UncheckedAt(i))) {
2054 if (track->GetId() == id) return i;
2055 }
2056 }
2057 return -1;
2058}
2059
2060////////////////////////////////////////////////////////////////////////////////
2061/// Go upwards the tree until a non-overlapping node
2062
2064{
2066}
2067
2068////////////////////////////////////////////////////////////////////////////////
2069/// Go upwards the tree until a non-overlapping node
2070
2072{
2074}
2075
2076////////////////////////////////////////////////////////////////////////////////
2077/// Set default volume colors according to A of material
2078
2080{
2081 const Int_t nmax = 110;
2082 Int_t col[nmax];
2083 for (Int_t i=0;i<nmax;i++) col[i] = kGray;
2084
2085 //here we should create a new TColor with the same rgb as in the default
2086 //ROOT colors used below
2087 col[ 3] = kYellow-10;
2088 col[ 4] = col[ 5] = kGreen-10;
2089 col[ 6] = col[ 7] = kBlue-7;
2090 col[ 8] = col[ 9] = kMagenta-3;
2091 col[10] = col[11] = kRed-10;
2092 col[12] = kGray+1;
2093 col[13] = kBlue-10;
2094 col[14] = kOrange+7;
2095 col[16] = kYellow+1;
2096 col[20] = kYellow-10;
2097 col[24] = col[25] = col[26] = kBlue-8;
2098 col[29] = kOrange+9;
2099 col[79] = kOrange-2;
2100
2101 TGeoVolume *vol;
2102 TIter next(fVolumes);
2103 while ((vol=(TGeoVolume*)next())) {
2104 TGeoMedium *med = vol->GetMedium();
2105 if (!med) continue;
2106 TGeoMaterial *mat = med->GetMaterial();
2107 Int_t matZ = (Int_t)mat->GetZ();
2108 vol->SetLineColor(col[matZ]);
2109 if (mat->GetDensity()<0.1) vol->SetTransparency(60);
2110 }
2111}
2112
2113////////////////////////////////////////////////////////////////////////////////
2114/// Compute safe distance from the current point. This represent the distance
2115/// from POINT to the closest boundary.
2116
2118{
2119 return GetCurrentNavigator()->Safety(inside);
2120}
2121
2122////////////////////////////////////////////////////////////////////////////////
2123/// Set volume attributes in G3 style.
2124
2125void TGeoManager::SetVolumeAttribute(const char *name, const char *att, Int_t val)
2126{
2127 TGeoVolume *volume;
2128 Bool_t all = kFALSE;
2129 if (strstr(name,"*")) all=kTRUE;
2130 Int_t ivo=0;
2131 TIter next(fVolumes);
2132 TString chatt = att;
2133 chatt.ToLower();
2134 while ((volume=(TGeoVolume*)next())) {
2135 if (strcmp(volume->GetName(), name) && !all) continue;
2136 ivo++;
2137 if (chatt.Contains("colo")) volume->SetLineColor(val);
2138 if (chatt.Contains("lsty")) volume->SetLineStyle(val);
2139 if (chatt.Contains("lwid")) volume->SetLineWidth(val);
2140 if (chatt.Contains("fill")) volume->SetFillColor(val);
2141 if (chatt.Contains("seen")) volume->SetVisibility(val);
2142 }
2143 TIter next1(fGVolumes);
2144 while ((volume=(TGeoVolume*)next1())) {
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 if (!ivo) {
2154 Warning("SetVolumeAttribute","volume: %s does not exist",name);
2155 }
2156}
2157
2158////////////////////////////////////////////////////////////////////////////////
2159/// Set factors that will "bomb" all translations in cartesian and cylindrical coordinates.
2160
2162{
2163 if (fPainter) fPainter->SetBombFactors(bombx, bomby, bombz, bombr);
2164}
2165
2166////////////////////////////////////////////////////////////////////////////////
2167/// Set a user-defined shape as clipping for ray tracing.
2168
2170{
2172 if (shape) {
2174 fClippingShape = shape;
2175 }
2176 painter->SetClippingShape(shape);
2177}
2178
2179////////////////////////////////////////////////////////////////////////////////
2180/// set the maximum number of visible nodes.
2181
2183 fMaxVisNodes = maxnodes;
2184 if (maxnodes>0 && fgVerboseLevel>0)
2185 Info("SetMaxVisNodes","Automatic visible depth for %d visible nodes", maxnodes);
2186 if (!fPainter) return;
2188 Int_t level = fPainter->GetVisLevel();
2189 if (level != fVisLevel) fVisLevel = level;
2190}
2191
2192////////////////////////////////////////////////////////////////////////////////
2193/// make top volume visible on screen
2194
2197 fPainter->SetTopVisible(vis);
2198}
2199
2200////////////////////////////////////////////////////////////////////////////////
2201/// Assign a given node to be checked for overlaps. Any other overlaps will be ignored.
2202
2205}
2206
2207////////////////////////////////////////////////////////////////////////////////
2208/// Set the number of points to be generated on the shape outline when checking
2209/// for overlaps.
2210
2212{
2213 GetGeomPainter()->SetNmeshPoints(npoints);
2214}
2215
2216////////////////////////////////////////////////////////////////////////////////
2217/// set drawing mode :
2218/// - option=0 (default) all nodes drawn down to vislevel
2219/// - option=1 leaves and nodes at vislevel drawn
2220/// - option=2 path is drawn
2221/// - option=4 visibility changed
2222
2224 if ((option>=0) && (option<3)) fVisOption=option;
2225 if (fPainter) fPainter->SetVisOption(option);
2226}
2227
2228////////////////////////////////////////////////////////////////////////////////
2229/// Set visualization option (leaves only OR all volumes)
2230
2232{
2233 if (flag) SetVisOption(1);
2234 else SetVisOption(0);
2235}
2236
2237////////////////////////////////////////////////////////////////////////////////
2238/// Set density threshold. Volumes with densities lower than this become
2239/// transparent.
2240
2242{
2243 fVisDensity = density;
2245}
2246
2247////////////////////////////////////////////////////////////////////////////////
2248/// set default level down to which visualization is performed
2249
2251 if (level>0) {
2252 fVisLevel = level;
2253 fMaxVisNodes = 0;
2254 if (fgVerboseLevel>0)
2255 Info("SetVisLevel","Automatic visible depth disabled");
2257 } else {
2259 }
2260}
2261
2262////////////////////////////////////////////////////////////////////////////////
2263/// Sort overlaps by decreasing overlap distance. Extrusions comes first.
2264
2266{
2267 fOverlaps->Sort();
2268}
2269
2270////////////////////////////////////////////////////////////////////////////////
2271/// Optimize voxelization type for all volumes. Save best choice in a macro.
2272
2273void TGeoManager::OptimizeVoxels(const char *filename)
2274{
2275 if (!fTopNode) {
2276 Error("OptimizeVoxels","Geometry must be closed first");
2277 return;
2278 }
2279 std::ofstream out;
2280 TString fname = filename;
2281 if (fname.IsNull()) fname = "tgeovox.C";
2282 out.open(fname, std::ios::out);
2283 if (!out.good()) {
2284 Error("OptimizeVoxels", "cannot open file");
2285 return;
2286 }
2287 // write header
2288 TDatime t;
2289 TString sname(fname);
2290 sname.ReplaceAll(".C", "");
2291 out << sname.Data()<<"()"<<std::endl;
2292 out << "{" << std::endl;
2293 out << "//=== Macro generated by ROOT version "<< gROOT->GetVersion()<<" : "<<t.AsString()<<std::endl;
2294 out << "//=== Voxel optimization for " << GetTitle() << " geometry"<<std::endl;
2295 out << "//===== <run this macro JUST BEFORE closing the geometry>"<<std::endl;
2296 out << " TGeoVolume *vol = 0;"<<std::endl;
2297 out << " // parse all voxelized volumes"<<std::endl;
2298 TGeoVolume *vol = 0;
2299 Bool_t cyltype;
2300 TIter next(fVolumes);
2301 while ((vol=(TGeoVolume*)next())) {
2302 if (!vol->GetVoxels()) continue;
2303 out<<" vol = gGeoManager->GetVolume(\""<<vol->GetName()<<"\");"<<std::endl;
2304 cyltype = vol->OptimizeVoxels();
2305 if (cyltype) {
2306 out<<" vol->SetCylVoxels();"<<std::endl;
2307 } else {
2308 out<<" vol->SetCylVoxels(kFALSE);"<<std::endl;
2309 }
2310 }
2311 out << "}" << std::endl;
2312 out.close();
2313}
2314////////////////////////////////////////////////////////////////////////////////
2315/// Parse a string boolean expression and do a syntax check. Find top
2316/// level boolean operator and returns its type. Fill the two
2317/// substrings to which this operator applies. The returned integer is :
2318/// - -1 : parse error
2319/// - 0 : no boolean operator
2320/// - 1 : union - represented as '+' in expression
2321/// - 2 : difference (subtraction) - represented as '-' in expression
2322/// - 3 : intersection - represented as '*' in expression.
2323/// Parentheses should be used to avoid ambiguities. For instance :
2324/// - A+B-C will be interpreted as (A+B)-C which is not the same as A+(B-C)
2325/// eliminate not needed parentheses
2326
2327Int_t TGeoManager::Parse(const char *expr, TString &expr1, TString &expr2, TString &expr3)
2328{
2329 TString startstr(expr);
2330 Int_t len = startstr.Length();
2331 Int_t i;
2332 TString e0 = "";
2333 expr3 = "";
2334 // eliminate blanks
2335 for (i=0; i< len; i++) {
2336 if (startstr(i)==' ') continue;
2337 e0 += startstr(i, 1);
2338 }
2339 Int_t level = 0;
2340 Int_t levmin = 999;
2341 Int_t boolop = 0;
2342 Int_t indop = 0;
2343 Int_t iloop = 1;
2344 Int_t lastop = 0;
2345 Int_t lastdp = 0;
2346 Int_t lastpp = 0;
2347 Bool_t foundmat = kFALSE;
2348 // check/eliminate parentheses
2349 while (iloop==1) {
2350 iloop = 0;
2351 lastop = 0;
2352 lastdp = 0;
2353 lastpp = 0;
2354 len = e0.Length();
2355 for (i=0; i<len; i++) {
2356 if (e0(i)=='(') {
2357 if (!level) iloop++;
2358 level++;
2359 continue;
2360 }
2361 if (e0(i)==')') {
2362 level--;
2363 if (level==0) lastpp=i;
2364 continue;
2365 }
2366 if ((e0(i)=='+') || (e0(i)=='-') || (e0(i)=='*')) {
2367 lastop = i;
2368 if (level<levmin) {
2369 levmin = level;
2370 indop = i;
2371 }
2372 continue;
2373 }
2374 if ((e0(i)==':') && (level==0)) {
2375 lastdp = i;
2376 continue;
2377 }
2378 }
2379 if (level!=0) {
2380 if (gGeoManager) gGeoManager->Error("Parse","parentheses does not match");
2381 return -1;
2382 }
2383 if (iloop==1 && (e0(0)=='(') && (e0(len-1)==')')) {
2384 // eliminate extra parentheses
2385 e0=e0(1, len-2);
2386 continue;
2387 }
2388 if (foundmat) break;
2389 if (((lastop==0) && (lastdp>0)) || ((lastpp>0) && (lastdp>lastpp) && (indop<lastpp))) {
2390 expr3 = e0(lastdp+1, len-lastdp);
2391 e0=e0(0, lastdp);
2392 foundmat = kTRUE;
2393 iloop = 1;
2394 continue;
2395 } else break;
2396 }
2397 // loop expression and search parentheses/operators
2398 levmin = 999;
2399 for (i=0; i<len; i++) {
2400 if (e0(i)=='(') {
2401 level++;
2402 continue;
2403 }
2404 if (e0(i)==')') {
2405 level--;
2406 continue;
2407 }
2408 // Take LAST operator at lowest level (revision 28/07/08)
2409 if (level<=levmin) {
2410 if (e0(i)=='+') {
2411 boolop = 1; // union
2412 levmin = level;
2413 indop = i;
2414 }
2415 if (e0(i)=='-') {
2416 boolop = 2; // difference
2417 levmin = level;
2418 indop = i;
2419 }
2420 if (e0(i)=='*') {
2421 boolop = 3; // intersection
2422 levmin = level;
2423 indop = i;
2424 }
2425 }
2426 }
2427 if (indop==0) {
2428 expr1=e0;
2429 return indop;
2430 }
2431 expr1 = e0(0, indop);
2432 expr2 = e0(indop+1, len-indop);
2433 return boolop;
2434}
2435
2436
2437////////////////////////////////////////////////////////////////////////////////
2438/// Save current attributes in a macro
2439
2440void TGeoManager::SaveAttributes(const char *filename)
2441{
2442 if (!fTopNode) {
2443 Error("SaveAttributes","geometry must be closed first\n");
2444 return;
2445 }
2446 std::ofstream out;
2447 TString fname(filename);
2448 if (fname.IsNull()) fname = "tgeoatt.C";
2449 out.open(fname, std::ios::out);
2450 if (!out.good()) {
2451 Error("SaveAttributes", "cannot open file");
2452 return;
2453 }
2454 // write header
2455 TDatime t;
2456 TString sname(fname);
2457 sname.ReplaceAll(".C", "");
2458 out << sname.Data()<<"()"<<std::endl;
2459 out << "{" << std::endl;
2460 out << "//=== Macro generated by ROOT version "<< gROOT->GetVersion()<<" : "<<t.AsString()<<std::endl;
2461 out << "//=== Attributes for " << GetTitle() << " geometry"<<std::endl;
2462 out << "//===== <run this macro AFTER loading the geometry in memory>"<<std::endl;
2463 // save current top volume
2464 out << " TGeoVolume *top = gGeoManager->GetVolume(\""<<fTopVolume->GetName()<<"\");"<<std::endl;
2465 out << " TGeoVolume *vol = 0;"<<std::endl;
2466 out << " TGeoNode *node = 0;"<<std::endl;
2467 out << " // clear all volume attributes and get painter"<<std::endl;
2468 out << " gGeoManager->ClearAttributes();"<<std::endl;
2469 out << " gGeoManager->GetGeomPainter();"<<std::endl;
2470 out << " // set visualization modes and bomb factors"<<std::endl;
2471 out << " gGeoManager->SetVisOption("<<GetVisOption()<<");"<<std::endl;
2472 out << " gGeoManager->SetVisLevel("<<GetVisLevel()<<");"<<std::endl;
2473 out << " gGeoManager->SetExplodedView("<<GetBombMode()<<");"<<std::endl;
2474 Double_t bombx, bomby, bombz, bombr;
2475 GetBombFactors(bombx, bomby, bombz, bombr);
2476 out << " gGeoManager->SetBombFactors("<<bombx<<","<<bomby<<","<<bombz<<","<<bombr<<");"<<std::endl;
2477 out << " // iterate volumes container and set new attributes"<<std::endl;
2478// out << " TIter next(gGeoManager->GetListOfVolumes());"<<std::endl;
2479 TGeoVolume *vol = 0;
2481
2482 TIter next(fVolumes);
2483 while ((vol=(TGeoVolume*)next())) {
2484 vol->SetVisStreamed(kFALSE);
2485 }
2486 out << " // draw top volume with new settings"<<std::endl;
2487 out << " top->Draw();"<<std::endl;
2488 out << " gPad->x3d();"<<std::endl;
2489 out << "}" << std::endl;
2490 out.close();
2491}
2492
2493////////////////////////////////////////////////////////////////////////////////
2494/// Returns the deepest node containing fPoint, which must be set a priori.
2495
2497{
2498 return GetCurrentNavigator()->SearchNode(downwards, skipnode);
2499}
2500
2501////////////////////////////////////////////////////////////////////////////////
2502/// Cross next boundary and locate within current node
2503/// The current point must be on the boundary of fCurrentNode.
2504
2506{
2507 return GetCurrentNavigator()->CrossBoundaryAndLocate(downwards, skipnode);
2508}
2509
2510////////////////////////////////////////////////////////////////////////////////
2511/// Compute distance to next boundary within STEPMAX. If no boundary is found,
2512/// propagate current point along current direction with fStep=STEPMAX. Otherwise
2513/// propagate with fStep=SNEXT (distance to boundary) and locate/return the next
2514/// node.
2515
2517{
2518 return GetCurrentNavigator()->FindNextBoundaryAndStep(stepmax, compsafe);
2519}
2520
2521////////////////////////////////////////////////////////////////////////////////
2522/// Find distance to next boundary and store it in fStep. Returns node to which this
2523/// boundary belongs. If PATH is specified, compute only distance to the node to which
2524/// PATH points. If STEPMAX is specified, compute distance only in case fSafety is smaller
2525/// than this value. STEPMAX represent the step to be made imposed by other reasons than
2526/// geometry (usually physics processes). Therefore in this case this method provides the
2527/// answer to the question : "Is STEPMAX a safe step ?" returning a NULL node and filling
2528/// fStep with a big number.
2529/// In case frombdr=kTRUE, the isotropic safety is set to zero.
2530///
2531/// Note : safety distance for the current point is computed ONLY in case STEPMAX is
2532/// specified, otherwise users have to call explicitly TGeoManager::Safety() if
2533/// they want this computed for the current point.
2534
2535TGeoNode *TGeoManager::FindNextBoundary(Double_t stepmax, const char *path, Bool_t frombdr)
2536{
2537 // convert current point and direction to local reference
2538 return GetCurrentNavigator()->FindNextBoundary(stepmax,path, frombdr);
2539}
2540
2541////////////////////////////////////////////////////////////////////////////////
2542/// Computes as fStep the distance to next daughter of the current volume.
2543/// The point and direction must be converted in the coordinate system of the current volume.
2544/// The proposed step limit is fStep.
2545
2547{
2548 return GetCurrentNavigator()->FindNextDaughterBoundary(point, dir, idaughter, compmatrix);
2549}
2550
2551////////////////////////////////////////////////////////////////////////////////
2552/// Reset current state flags.
2553
2555{
2557}
2558
2559////////////////////////////////////////////////////////////////////////////////
2560/// Returns deepest node containing current point.
2561
2563{
2564 return GetCurrentNavigator()->FindNode(safe_start);
2565}
2566
2567////////////////////////////////////////////////////////////////////////////////
2568/// Returns deepest node containing current point.
2569
2571{
2572 return GetCurrentNavigator()->FindNode(x, y, z);
2573}
2574
2575////////////////////////////////////////////////////////////////////////////////
2576/// Computes fast normal to next crossed boundary, assuming that the current point
2577/// is close enough to the boundary. Works only after calling FindNextBoundary.
2578
2580{
2582}
2583
2584////////////////////////////////////////////////////////////////////////////////
2585/// Computes normal vector to the next surface that will be or was already
2586/// crossed when propagating on a straight line from a given point/direction.
2587/// Returns the normal vector cosines in the MASTER coordinate system. The dot
2588/// product of the normal and the current direction is positive defined.
2589
2591{
2593}
2594
2595////////////////////////////////////////////////////////////////////////////////
2596/// Checks if point (x,y,z) is still in the current node.
2597
2599{
2600 return GetCurrentNavigator()->IsSameLocation(x,y,z,change);
2601}
2602
2603////////////////////////////////////////////////////////////////////////////////
2604/// Check if a new point with given coordinates is the same as the last located one.
2605
2607{
2608 return GetCurrentNavigator()->IsSamePoint(x,y,z);
2609}
2610
2611////////////////////////////////////////////////////////////////////////////////
2612/// True if current node is in phi range
2613
2615{
2616 if (!fPhiCut) return kTRUE;
2617 const Double_t *origin;
2619 origin = ((TGeoBBox*)GetCurrentNavigator()->GetCurrentVolume()->GetShape())->GetOrigin();
2620 Double_t point[3];
2621 LocalToMaster(origin, &point[0]);
2622 Double_t phi = TMath::ATan2(point[1], point[0])*TMath::RadToDeg();
2623 if (phi<0) phi+=360.;
2624 if ((phi>=fPhimin) && (phi<=fPhimax)) return kFALSE;
2625 return kTRUE;
2626}
2627
2628////////////////////////////////////////////////////////////////////////////////
2629/// Initialize current point and current direction vector (normalized)
2630/// in MARS. Return corresponding node.
2631
2633{
2634 return GetCurrentNavigator()->InitTrack(point, dir);
2635}
2636
2637////////////////////////////////////////////////////////////////////////////////
2638/// Initialize current point and current direction vector (normalized)
2639/// in MARS. Return corresponding node.
2640
2642{
2643 return GetCurrentNavigator()->InitTrack(x,y,z,nx,ny,nz);
2644}
2645
2646////////////////////////////////////////////////////////////////////////////////
2647/// Inspects path and all flags for the current state.
2648
2650{
2652}
2653
2654////////////////////////////////////////////////////////////////////////////////
2655/// Get path to the current node in the form /node0/node1/...
2656
2657const char *TGeoManager::GetPath() const
2658{
2659 return GetCurrentNavigator()->GetPath();
2660}
2661
2662////////////////////////////////////////////////////////////////////////////////
2663/// Get total size of geometry in bytes.
2664
2666{
2667 Int_t count = 0;
2668 TIter next(fVolumes);
2669 TGeoVolume *vol;
2670 while ((vol=(TGeoVolume*)next())) count += vol->GetByteCount();
2671 TIter next1(fMatrices);
2672 TGeoMatrix *matrix;
2673 while ((matrix=(TGeoMatrix*)next1())) count += matrix->GetByteCount();
2674 TIter next2(fMaterials);
2675 TGeoMaterial *mat;
2676 while ((mat=(TGeoMaterial*)next2())) count += mat->GetByteCount();
2677 TIter next3(fMedia);
2678 TGeoMedium *med;
2679 while ((med=(TGeoMedium*)next3())) count += med->GetByteCount();
2680 if (fgVerboseLevel>0) Info("GetByteCount","Total size of logical tree : %i bytes", count);
2681 return count;
2682}
2683
2684////////////////////////////////////////////////////////////////////////////////
2685/// Make a default painter if none present. Returns pointer to it.
2686
2688{
2689 if (!fPainter) {
2690 const char *kind = "root";
2691 if (gROOT->IsWebDisplay() && !gROOT->IsWebDisplayBatch()) kind = "web";
2692 if (auto h = gROOT->GetPluginManager()->FindHandler("TVirtualGeoPainter", kind)) {
2693 if (h->LoadPlugin() == -1) {
2694 Error("GetGeomPainter", "could not load plugin for %s geo_painter", kind);
2695 return nullptr;
2696 }
2697 fPainter = (TVirtualGeoPainter*)h->ExecPlugin(1,this);
2698 if (!fPainter) {
2699 Error("GetGeomPainter", "could not create %s geo_painter", kind);
2700 return nullptr;
2701 }
2702 } else {
2703 Error("GetGeomPainter", "not found plugin %s for geo_painter", kind);
2704 }
2705 }
2706 return fPainter;
2707}
2708
2709////////////////////////////////////////////////////////////////////////////////
2710/// Search for a named volume. All trailing blanks stripped.
2711
2713{
2714 TString sname = name;
2715 sname = sname.Strip();
2716 TGeoVolume *vol = (TGeoVolume*)fVolumes->FindObject(sname.Data());
2717 return vol;
2718}
2719
2720////////////////////////////////////////////////////////////////////////////////
2721/// Fast search for a named volume. All trailing blanks stripped.
2722
2724{
2725 if (!fHashVolumes) {
2726 Int_t nvol = fVolumes->GetEntriesFast();
2727 Int_t ngvol = fGVolumes->GetEntriesFast();
2728 fHashVolumes = new THashList(nvol+1);
2729 fHashGVolumes = new THashList(ngvol+1);
2730 Int_t i;
2731 for (i=0; i<ngvol; i++) fHashGVolumes->AddLast(fGVolumes->At(i));
2732 for (i=0; i<nvol; i++) fHashVolumes->AddLast(fVolumes->At(i));
2733 }
2734 TString sname = name;
2735 sname = sname.Strip();
2736 THashList *list = fHashVolumes;
2737 if (multi) list = fHashGVolumes;
2738 TGeoVolume *vol = (TGeoVolume*)list->FindObject(sname.Data());
2739 return vol;
2740}
2741
2742////////////////////////////////////////////////////////////////////////////////
2743/// Retrieve unique id for a volume name. Return -1 if name not found.
2744
2745Int_t TGeoManager::GetUID(const char *volname) const
2746{
2747 TGeoManager *geom = (TGeoManager*)this;
2748 TGeoVolume *vol = geom->FindVolumeFast(volname, kFALSE);
2749 if (!vol) vol = geom->FindVolumeFast(volname, kTRUE);
2750 if (!vol) return -1;
2751 return vol->GetNumber();
2752}
2753
2754////////////////////////////////////////////////////////////////////////////////
2755/// Find if a given material duplicates an existing one.
2756
2758{
2759 Int_t index = fMaterials->IndexOf(mat);
2760 if (index <= 0) return 0;
2761 TGeoMaterial *other;
2762 for (Int_t i=0; i<index; i++) {
2763 other = (TGeoMaterial*)fMaterials->At(i);
2764 if (other == mat) continue;
2765 if (other->IsEq(mat)) return other;
2766 }
2767 return 0;
2768}
2769
2770////////////////////////////////////////////////////////////////////////////////
2771/// Search for a named material. All trailing blanks stripped.
2772
2773TGeoMaterial *TGeoManager::GetMaterial(const char *matname) const
2774{
2775 TString sname = matname;
2776 sname = sname.Strip();
2778 return mat;
2779}
2780
2781////////////////////////////////////////////////////////////////////////////////
2782/// Search for a named tracking medium. All trailing blanks stripped.
2783
2784TGeoMedium *TGeoManager::GetMedium(const char *medium) const
2785{
2786 TString sname = medium;
2787 sname = sname.Strip();
2788 TGeoMedium *med = (TGeoMedium*)fMedia->FindObject(sname.Data());
2789 return med;
2790}
2791
2792////////////////////////////////////////////////////////////////////////////////
2793/// Search for a tracking medium with a given ID.
2794
2796{
2797 TIter next(fMedia);
2798 TGeoMedium *med;
2799 while ((med=(TGeoMedium*)next())) {
2800 if (med->GetId()==numed) return med;
2801 }
2802 return 0;
2803}
2804
2805////////////////////////////////////////////////////////////////////////////////
2806/// Return material at position id.
2807
2809{
2810 if (id<0 || id >= fMaterials->GetSize()) return 0;
2811 TGeoMaterial *mat = (TGeoMaterial*)fMaterials->At(id);
2812 return mat;
2813}
2814
2815////////////////////////////////////////////////////////////////////////////////
2816/// Return index of named material.
2817
2818Int_t TGeoManager::GetMaterialIndex(const char *matname) const
2819{
2820 TIter next(fMaterials);
2821 TGeoMaterial *mat;
2822 Int_t id = 0;
2823 TString sname = matname;
2824 sname = sname.Strip();
2825 while ((mat = (TGeoMaterial*)next())) {
2826 if (!strcmp(mat->GetName(),sname.Data()))
2827 return id;
2828 id++;
2829 }
2830 return -1; // fail
2831}
2832
2833////////////////////////////////////////////////////////////////////////////////
2834/// Randomly shoot nrays and plot intersections with surfaces for current
2835/// top node.
2836
2837void TGeoManager::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm)
2838{
2839 GetGeomPainter()->RandomRays(nrays, startx, starty, startz, target_vol, check_norm);
2840}
2841
2842////////////////////////////////////////////////////////////////////////////////
2843/// Remove material at given index.
2844
2846{
2847 TObject *obj = fMaterials->At(index);
2848 if (obj) fMaterials->Remove(obj);
2849}
2850
2851////////////////////////////////////////////////////////////////////////////////
2852/// Sets all pointers TGeoVolume::fField to NULL. User data becomes decoupled
2853/// from geometry. Deletion has to be managed by users.
2854
2856{
2857 TIter next(fVolumes);
2858 TGeoVolume *vol;
2859 while ((vol=(TGeoVolume*)next())) vol->SetField(0);
2860}
2861
2862////////////////////////////////////////////////////////////////////////////////
2863/// Change raytracing mode.
2864
2866{
2867 fRaytraceMode = mode;
2869}
2870
2871////////////////////////////////////////////////////////////////////////////////
2872/// Restore the master volume of the geometry.
2873
2875{
2876 if (fTopVolume == fMasterVolume) return;
2878}
2879
2880////////////////////////////////////////////////////////////////////////////////
2881/// Voxelize all non-divided volumes.
2882
2884{
2885 TGeoVolume *vol;
2886// TGeoVoxelFinder *vox = 0;
2887 if (!fStreamVoxels && fgVerboseLevel>0) Info("Voxelize","Voxelizing...");
2888// Int_t nentries = fVolumes->GetSize();
2889 TIter next(fVolumes);
2890 while ((vol = (TGeoVolume*)next())) {
2891 if (!fIsGeomReading) vol->SortNodes();
2892 if (!fStreamVoxels) {
2893 vol->Voxelize(option);
2894 }
2895 if (!fIsGeomReading) vol->FindOverlaps();
2896 }
2897}
2898
2899////////////////////////////////////////////////////////////////////////////////
2900/// Send "Modified" signal to painter.
2901
2903{
2904 if (!fPainter) return;
2906}
2907
2908////////////////////////////////////////////////////////////////////////////////
2909/// Make an TGeoArb8 volume.
2910
2912 Double_t dz, Double_t *vertices)
2913{
2914 return TGeoBuilder::Instance(this)->MakeArb8(name, medium, dz, vertices);
2915}
2916
2917////////////////////////////////////////////////////////////////////////////////
2918/// Make in one step a volume pointing to a box shape with given medium.
2919
2921 Double_t dx, Double_t dy, Double_t dz)
2922{
2923 return TGeoBuilder::Instance(this)->MakeBox(name, medium, dx, dy, dz);
2924}
2925
2926////////////////////////////////////////////////////////////////////////////////
2927/// Make in one step a volume pointing to a parallelepiped shape with given medium.
2928
2930 Double_t dx, Double_t dy, Double_t dz,
2931 Double_t alpha, Double_t theta, Double_t phi)
2932{
2933 return TGeoBuilder::Instance(this)->MakePara(name, medium, dx, dy, dz, alpha, theta, phi);
2934}
2935
2936////////////////////////////////////////////////////////////////////////////////
2937/// Make in one step a volume pointing to a sphere shape with given medium
2938
2940 Double_t rmin, Double_t rmax, Double_t themin, Double_t themax,
2941 Double_t phimin, Double_t phimax)
2942{
2943 return TGeoBuilder::Instance(this)->MakeSphere(name, medium, rmin, rmax, themin, themax, phimin, phimax);
2944}
2945
2946////////////////////////////////////////////////////////////////////////////////
2947/// Make in one step a volume pointing to a torus shape with given medium.
2948
2950 Double_t rmin, Double_t rmax, Double_t phi1, Double_t dphi)
2951{
2952 return TGeoBuilder::Instance(this)->MakeTorus(name, medium, r, rmin, rmax, phi1, dphi);
2953}
2954
2955////////////////////////////////////////////////////////////////////////////////
2956/// Make in one step a volume pointing to a tube shape with given medium.
2957
2959 Double_t rmin, Double_t rmax, Double_t dz)
2960{
2961 return TGeoBuilder::Instance(this)->MakeTube(name, medium, rmin, rmax, dz);
2962}
2963
2964////////////////////////////////////////////////////////////////////////////////
2965/// Make in one step a volume pointing to a tube segment shape with given medium.
2966/// The segment will be from phiStart to phiEnd, the angles are expressed in degree
2967
2969 Double_t rmin, Double_t rmax, Double_t dz,
2970 Double_t phiStart, Double_t phiEnd)
2971{
2972 return TGeoBuilder::Instance(this)->MakeTubs(name, medium, rmin, rmax, dz, phiStart, phiEnd);
2973}
2974
2975////////////////////////////////////////////////////////////////////////////////
2976/// Make in one step a volume pointing to a tube shape with given medium
2977
2980{
2981 return TGeoBuilder::Instance(this)->MakeEltu(name, medium, a, b, dz);
2982}
2983
2984////////////////////////////////////////////////////////////////////////////////
2985/// Make in one step a volume pointing to a tube shape with given medium
2986
2988 Double_t rin, Double_t stin, Double_t rout, Double_t stout, Double_t dz)
2989{
2990 return TGeoBuilder::Instance(this)->MakeHype(name, medium, rin, stin, rout, stout, dz);
2991}
2992
2993////////////////////////////////////////////////////////////////////////////////
2994/// Make in one step a volume pointing to a tube shape with given medium
2995
2997 Double_t rlo, Double_t rhi, Double_t dz)
2998{
2999 return TGeoBuilder::Instance(this)->MakeParaboloid(name, medium, rlo, rhi, dz);
3000}
3001
3002////////////////////////////////////////////////////////////////////////////////
3003/// Make in one step a volume pointing to a tube segment shape with given medium
3004
3006 Double_t rmin, Double_t rmax, Double_t dz, Double_t phi1, Double_t phi2,
3007 Double_t lx, Double_t ly, Double_t lz, Double_t tx, Double_t ty, Double_t tz)
3008{
3009 return TGeoBuilder::Instance(this)->MakeCtub(name, medium, rmin, rmax, dz, phi1, phi2, lx, ly, lz, tx, ty, tz);
3010}
3011
3012////////////////////////////////////////////////////////////////////////////////
3013/// Make in one step a volume pointing to a cone shape with given medium.
3014
3016 Double_t dz, Double_t rmin1, Double_t rmax1,
3017 Double_t rmin2, Double_t rmax2)
3018{
3019 return TGeoBuilder::Instance(this)->MakeCone(name, medium, dz, rmin1, rmax1, rmin2, rmax2);
3020}
3021
3022////////////////////////////////////////////////////////////////////////////////
3023/// Make in one step a volume pointing to a cone segment shape with given medium
3024
3026 Double_t dz, Double_t rmin1, Double_t rmax1,
3027 Double_t rmin2, Double_t rmax2,
3028 Double_t phi1, Double_t phi2)
3029{
3030 return TGeoBuilder::Instance(this)->MakeCons(name, medium, dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
3031}
3032
3033////////////////////////////////////////////////////////////////////////////////
3034/// Make in one step a volume pointing to a polycone shape with given medium.
3035
3037 Double_t phi, Double_t dphi, Int_t nz)
3038{
3039 return TGeoBuilder::Instance(this)->MakePcon(name, medium, phi, dphi, nz);
3040}
3041
3042////////////////////////////////////////////////////////////////////////////////
3043/// Make in one step a volume pointing to a polygone shape with given medium.
3044
3046 Double_t phi, Double_t dphi, Int_t nedges, Int_t nz)
3047{
3048 return TGeoBuilder::Instance(this)->MakePgon(name, medium, phi, dphi, nedges, nz);
3049}
3050
3051////////////////////////////////////////////////////////////////////////////////
3052/// Make in one step a volume pointing to a TGeoTrd1 shape with given medium.
3053
3055 Double_t dx1, Double_t dx2, Double_t dy, Double_t dz)
3056{
3057 return TGeoBuilder::Instance(this)->MakeTrd1(name, medium, dx1, dx2, dy, dz);
3058}
3059
3060////////////////////////////////////////////////////////////////////////////////
3061/// Make in one step a volume pointing to a TGeoTrd2 shape with given medium.
3062
3064 Double_t dx1, Double_t dx2, Double_t dy1, Double_t dy2,
3065 Double_t dz)
3066{
3067 return TGeoBuilder::Instance(this)->MakeTrd2(name, medium, dx1, dx2, dy1, dy2, dz);
3068}
3069
3070////////////////////////////////////////////////////////////////////////////////
3071/// Make in one step a volume pointing to a trapezoid shape with given medium.
3072
3074 Double_t dz, Double_t theta, Double_t phi, Double_t h1,
3075 Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
3076 Double_t tl2, Double_t alpha2)
3077{
3078 return TGeoBuilder::Instance(this)->MakeTrap(name, medium, dz, theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2);
3079}
3080
3081////////////////////////////////////////////////////////////////////////////////
3082/// Make in one step a volume pointing to a twisted trapezoid shape with given medium.
3083
3085 Double_t dz, Double_t theta, Double_t phi, Double_t twist, Double_t h1,
3086 Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
3087 Double_t tl2, Double_t alpha2)
3088{
3089 return TGeoBuilder::Instance(this)->MakeGtra(name, medium, dz, theta, phi, twist, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2);
3090}
3091
3092////////////////////////////////////////////////////////////////////////////////
3093/// Make a TGeoXtru-shaped volume with nz planes
3094
3096{
3097 return TGeoBuilder::Instance(this)->MakeXtru(name, medium, nz);
3098}
3099
3100////////////////////////////////////////////////////////////////////////////////
3101/// Creates an alignable object with unique name corresponding to a path
3102/// and adds it to the list of alignables. An optional unique ID can be
3103/// provided, in which case PN entries can be searched fast by uid.
3104
3105TGeoPNEntry *TGeoManager::SetAlignableEntry(const char *unique_name, const char *path,
3106 Int_t uid)
3107{
3108 if (!CheckPath(path)) return NULL;
3109 if (!fHashPNE) fHashPNE = new THashList(256,3);
3110 if (!fArrayPNE) fArrayPNE = new TObjArray(256);
3111 TGeoPNEntry *entry = GetAlignableEntry(unique_name);
3112 if (entry) {
3113 Error("SetAlignableEntry", "An alignable object with name %s already existing. NOT ADDED !", unique_name);
3114 return 0;
3115 }
3116 entry = new TGeoPNEntry(unique_name, path);
3117 Int_t ientry = fHashPNE->GetSize();
3118 fHashPNE->Add(entry);
3119 fArrayPNE->AddAtAndExpand(entry, ientry);
3120 if (uid>=0) {
3121 Bool_t added = InsertPNEId(uid, ientry);
3122 if (!added) Error("SetAlignableEntry", "A PN entry: has already uid=%i", uid);
3123 }
3124 return entry;
3125}
3126
3127////////////////////////////////////////////////////////////////////////////////
3128/// Retrieves an existing alignable object.
3129
3131{
3132 if (!fHashPNE) return 0;
3134}
3135
3136////////////////////////////////////////////////////////////////////////////////
3137/// Retrieves an existing alignable object at a given index.
3138
3140{
3141 if (!fArrayPNE && !InitArrayPNE()) return 0;
3142 return (TGeoPNEntry*)fArrayPNE->At(index);
3143}
3144
3145////////////////////////////////////////////////////////////////////////////////
3146/// Retrieves an existing alignable object having a preset UID.
3147
3149{
3150 if (!fNPNEId || (!fArrayPNE && !InitArrayPNE())) return NULL;
3152 if (index<0 || fKeyPNEId[index]!=uid) return NULL;
3153 return (TGeoPNEntry*)fArrayPNE->At(fValuePNEId[index]);
3154}
3155
3156////////////////////////////////////////////////////////////////////////////////
3157/// Retrieves number of PN entries with or without UID.
3158
3160{
3161 if (!fHashPNE) return 0;
3162 if (with_uid) return fNPNEId;
3163 return fHashPNE->GetSize();
3164}
3165
3166////////////////////////////////////////////////////////////////////////////////
3167/// Insert a PN entry in the sorted array of indexes.
3168
3170{
3171 if (!fSizePNEId) {
3172 // Create the arrays.
3173 fSizePNEId = 128;
3174 fKeyPNEId = new Int_t[fSizePNEId];
3175 memset(fKeyPNEId, 0, fSizePNEId*sizeof(Int_t));
3177 memset(fValuePNEId, 0, fSizePNEId*sizeof(Int_t));
3178 fKeyPNEId[fNPNEId] = uid;
3179 fValuePNEId[fNPNEId++] = ientry;
3180 return kTRUE;
3181 }
3182 // Search id in the existing array and return false if it already exists.
3184 if (index>0 && fKeyPNEId[index]==uid) return kFALSE;
3185 // Resize the arrays and insert the value
3186 Bool_t resize = (fNPNEId==fSizePNEId)?kTRUE:kFALSE;
3187 if (resize) {
3188 // Double the size of the array
3189 fSizePNEId *= 2;
3190 // Create new arrays of keys and values
3191 Int_t *keys = new Int_t[fSizePNEId];
3192 memset(keys, 0, fSizePNEId*sizeof(Int_t));
3193 Int_t *values = new Int_t[fSizePNEId];
3194 memset(values, 0, fSizePNEId*sizeof(Int_t));
3195 // Copy all keys<uid in the new keys array (0 to index)
3196 memcpy(keys, fKeyPNEId, (index+1)*sizeof(Int_t));
3197 memcpy(values, fValuePNEId, (index+1)*sizeof(Int_t));
3198 // Insert current key at index+1
3199 keys[index+1] = uid;
3200 values[index+1] = ientry;
3201 // Copy all remaining keys from the old to new array
3202 memcpy(&keys[index+2], &fKeyPNEId[index+1], (fNPNEId-index-1)*sizeof(Int_t));
3203 memcpy(&values[index+2], &fValuePNEId[index+1], (fNPNEId-index-1)*sizeof(Int_t));
3204 delete [] fKeyPNEId;
3205 fKeyPNEId = keys;
3206 delete [] fValuePNEId;
3207 fValuePNEId = values;
3208 fNPNEId++;
3209 return kTRUE;
3210 }
3211 // Insert the value in the existing arrays
3212 Int_t i;
3213 for (i=fNPNEId-1; i>index; i--) {
3214 fKeyPNEId[i+1] = fKeyPNEId[i];
3215 fValuePNEId[i+1] = fValuePNEId[i];
3216 }
3217 fKeyPNEId[index+1] = uid;
3218 fValuePNEId[index+1] = ientry;
3219 fNPNEId++;
3220 return kTRUE;
3221}
3222
3223////////////////////////////////////////////////////////////////////////////////
3224/// Make a physical node from the path pointed by an alignable object with a given name.
3225
3227{
3229 if (!entry) {
3230 Error("MakeAlignablePN","No alignable object named %s found !", name);
3231 return 0;
3232 }
3233 return MakeAlignablePN(entry);
3234}
3235
3236////////////////////////////////////////////////////////////////////////////////
3237/// Make a physical node from the path pointed by a given alignable object.
3238
3240{
3241 if (!entry) {
3242 Error("MakeAlignablePN","No alignable object specified !");
3243 return 0;
3244 }
3245 const char *path = entry->GetTitle();
3246 if (!cd(path)) {
3247 Error("MakeAlignablePN", "Alignable object %s poins to invalid path: %s",
3248 entry->GetName(), path);
3249 return 0;
3250 }
3251 TGeoPhysicalNode *node = MakePhysicalNode(path);
3252 entry->SetPhysicalNode(node);
3253 return node;
3254}
3255
3256////////////////////////////////////////////////////////////////////////////////
3257/// Makes a physical node corresponding to a path. If PATH is not specified,
3258/// makes physical node matching current modeller state.
3259
3261{
3262 TGeoPhysicalNode *node;
3263 if (path) {
3264 if (!CheckPath(path)) {
3265 Error("MakePhysicalNode", "path: %s not valid", path);
3266 return NULL;
3267 }
3268 node = new TGeoPhysicalNode(path);
3269 } else {
3270 node = new TGeoPhysicalNode(GetPath());
3271 }
3272 fPhysicalNodes->Add(node);
3273 return node;
3274}
3275
3276////////////////////////////////////////////////////////////////////////////////
3277/// Refresh physical nodes to reflect the actual geometry paths after alignment
3278/// was applied. Optionally locks physical nodes (default).
3279
3281{
3283 TGeoPhysicalNode *pn;
3284 while ((pn=(TGeoPhysicalNode*)next())) pn->Refresh();
3286 if (lock) LockGeometry();
3287}
3288
3289////////////////////////////////////////////////////////////////////////////////
3290/// Clear the current list of physical nodes, so that we can start over with a new list.
3291/// If MUSTDELETE is true, delete previous nodes.
3292
3294{
3295 if (mustdelete) fPhysicalNodes->Delete();
3296 else fPhysicalNodes->Clear();
3297}
3298
3299////////////////////////////////////////////////////////////////////////////////
3300/// Make an assembly of volumes.
3301
3303{
3305}
3306
3307////////////////////////////////////////////////////////////////////////////////
3308/// Make a TGeoVolumeMulti handling a list of volumes.
3309
3311{
3312 return TGeoBuilder::Instance(this)->MakeVolumeMulti(name, medium);
3313}
3314
3315////////////////////////////////////////////////////////////////////////////////
3316/// Set type of exploding view (see TGeoPainter::SetExplodedView())
3317
3319{
3320 if ((ibomb>=0) && (ibomb<4)) fExplodedView = ibomb;
3321 if (fPainter) fPainter->SetExplodedView(ibomb);
3322}
3323
3324////////////////////////////////////////////////////////////////////////////////
3325/// Set cut phi range
3326
3328{
3329 if ((phimin==0) && (phimax==360)) {
3330 fPhiCut = kFALSE;
3331 return;
3332 }
3333 fPhiCut = kTRUE;
3334 fPhimin = phimin;
3335 fPhimax = phimax;
3336}
3337
3338////////////////////////////////////////////////////////////////////////////////
3339/// Set number of segments for approximating circles in drawing.
3340
3342{
3343 if (fNsegments==nseg) return;
3344 if (nseg>2) fNsegments = nseg;
3345 if (fPainter) fPainter->SetNsegments(nseg);
3346}
3347
3348////////////////////////////////////////////////////////////////////////////////
3349/// Get number of segments approximating circles
3350
3352{
3353 return fNsegments;
3354}
3355
3356////////////////////////////////////////////////////////////////////////////////
3357/// Now just a shortcut for GetElementTable.
3358
3360{
3363}
3364
3365////////////////////////////////////////////////////////////////////////////////
3366/// Returns material table. Creates it if not existing.
3367
3369{
3371 return fElementTable;
3372}
3373
3374////////////////////////////////////////////////////////////////////////////////
3375/// Make a rectilinear step of length fStep from current point (fPoint) on current
3376/// direction (fDirection). If the step is imposed by geometry, is_geom flag
3377/// must be true (default). The cross flag specifies if the boundary should be
3378/// crossed in case of a geometry step (default true). Returns new node after step.
3379/// Set also on boundary condition.
3380
3382{
3383 return GetCurrentNavigator()->Step(is_geom, cross);
3384}
3385
3386////////////////////////////////////////////////////////////////////////////////
3387/// shoot npoints randomly in a box of 1E-5 around current point.
3388/// return minimum distance to points outside
3389
3391 const char* g3path)
3392{
3393 return GetGeomPainter()->SamplePoints(npoints, dist, epsil, g3path);
3394}
3395
3396////////////////////////////////////////////////////////////////////////////////
3397/// Set the top volume and corresponding node as starting point of the geometry.
3398
3400{
3401 if (fTopVolume==vol) return;
3402
3403 TSeqCollection *brlist = gROOT->GetListOfBrowsers();
3404 TIter next(brlist);
3405 TBrowser *browser = 0;
3406
3407 if (fTopVolume) fTopVolume->SetTitle("");
3408 fTopVolume = vol;
3409 vol->SetTitle("Top volume");
3410 if (fTopNode) {
3411 TGeoNode *topn = fTopNode;
3412 fTopNode = 0;
3413 while ((browser=(TBrowser*)next())) browser->RecursiveRemove(topn);
3414 delete topn;
3415 } else {
3416 fMasterVolume = vol;
3419 if (fgVerboseLevel>0) Info("SetTopVolume","Top volume is %s. Master volume is %s", fTopVolume->GetName(),
3421 }
3422// fMasterVolume->FindMatrixOfDaughterVolume(vol);
3423// fCurrentMatrix->Print();
3425 fTopNode->SetName(TString::Format("%s_1",vol->GetName()));
3426 fTopNode->SetNumber(1);
3427 fTopNode->SetTitle("Top logical node");
3428 fNodes->AddAt(fTopNode, 0);
3429 if (!GetCurrentNavigator()) {
3431 return;
3432 }
3433 Int_t nnavigators = 0;
3435 if (!arr) return;
3436 nnavigators = arr->GetEntriesFast();
3437 for (Int_t i=0; i<nnavigators; i++) {
3438 TGeoNavigator *nav = (TGeoNavigator*)arr->At(i);
3439 nav->ResetAll();
3440 if (fClosed) nav->GetCache()->BuildInfoBranch();
3441 }
3442}
3443
3444////////////////////////////////////////////////////////////////////////////////
3445/// Define different tracking media.
3446
3448{
3449/*
3450 Int_t nmat = fMaterials->GetSize();
3451 if (!nmat) {printf(" No materials !\n"); return;}
3452 Int_t *media = new Int_t[nmat];
3453 memset(media, 0, nmat*sizeof(Int_t));
3454 Int_t imedia = 1;
3455 TGeoMaterial *mat, *matref;
3456 mat = (TGeoMaterial*)fMaterials->At(0);
3457 if (mat->GetMedia()) {
3458 for (Int_t i=0; i<nmat; i++) {
3459 mat = (TGeoMaterial*)fMaterials->At(i);
3460 mat->Print();
3461 }
3462 return;
3463 }
3464 mat->SetMedia(imedia);
3465 media[0] = imedia++;
3466 mat->Print();
3467 for (Int_t i=0; i<nmat; i++) {
3468 mat = (TGeoMaterial*)fMaterials->At(i);
3469 for (Int_t j=0; j<i; j++) {
3470 matref = (TGeoMaterial*)fMaterials->At(j);
3471 if (mat->IsEq(matref)) {
3472 mat->SetMedia(media[j]);
3473 break;
3474 }
3475 if (j==(i-1)) {
3476 // different material
3477 mat->SetMedia(imedia);
3478 media[i] = imedia++;
3479 mat->Print();
3480 }
3481 }
3482 }
3483*/
3484}
3485
3486////////////////////////////////////////////////////////////////////////////////
3487/// Check pushes and pulls needed to cross the next boundary with respect to the
3488/// position given by FindNextBoundary. If radius is not mentioned the full bounding
3489/// box will be sampled.
3490
3492{
3493 GetGeomPainter()->CheckBoundaryErrors(ntracks, radius);
3494}
3495
3496////////////////////////////////////////////////////////////////////////////////
3497/// Check the boundary errors reference file created by CheckBoundaryErrors method.
3498/// The shape for which the crossing failed is drawn with the starting point in red
3499/// and the extrapolated point to boundary (+/- failing push/pull) in yellow.
3500
3502{
3504}
3505
3506////////////////////////////////////////////////////////////////////////////////
3507/// Classify a given point. See TGeoChecker::CheckPoint().
3508
3510{
3511 GetGeomPainter()->CheckPoint(x,y,z,option);
3512}
3513
3514////////////////////////////////////////////////////////////////////////////////
3515/// Test for shape navigation methods. Summary for test numbers:
3516/// - 1: DistFromInside/Outside. Sample points inside the shape. Generate
3517/// directions randomly in cos(theta). Compute DistFromInside and move the
3518/// point with bigger distance. Compute DistFromOutside back from new point.
3519/// Plot d-(d1+d2)
3520///
3521
3522void TGeoManager::CheckShape(TGeoShape *shape, Int_t testNo, Int_t nsamples, Option_t *option)
3523{
3524 GetGeomPainter()->CheckShape(shape, testNo, nsamples, option);
3525}
3526
3527////////////////////////////////////////////////////////////////////////////////
3528/// Geometry checking.
3529/// - if option contains 'o': Optional overlap checkings (by sampling and by mesh).
3530/// - if option contains 'b': Optional boundary crossing check + timing per volume.
3531///
3532/// STAGE 1: extensive overlap checking by sampling per volume. Stdout need to be
3533/// checked by user to get report, then TGeoVolume::CheckOverlaps(0.01, "s") can
3534/// be called for the suspicious volumes.
3535///
3536/// STAGE 2: normal overlap checking using the shapes mesh - fills the list of
3537/// overlaps.
3538///
3539/// STAGE 3: shooting NRAYS rays from VERTEX and counting the total number of
3540/// crossings per volume (rays propagated from boundary to boundary until
3541/// geometry exit). Timing computed and results stored in a histo.
3542///
3543/// STAGE 4: shooting 1 mil. random rays inside EACH volume and calling
3544/// FindNextBoundary() + Safety() for each call. The timing is normalized by the
3545/// number of crossings computed at stage 2 and presented as percentage.
3546/// One can get a picture on which are the most "burned" volumes during
3547/// transportation from geometry point of view. Another plot of the timing per
3548/// volume vs. number of daughters is produced.
3549
3551{
3552 TString opt(option);
3553 opt.ToLower();
3554 if (!opt.Length()) {
3555 Error("CheckGeometryFull","The option string must contain a letter. See method documentation.");
3556 return;
3557 }
3558 Bool_t checkoverlaps = opt.Contains("o");
3559 Bool_t checkcrossings = opt.Contains("b");
3560 Double_t vertex[3];
3561 vertex[0] = vx;
3562 vertex[1] = vy;
3563 vertex[2] = vz;
3564 GetGeomPainter()->CheckGeometryFull(checkoverlaps,checkcrossings,ntracks,vertex);
3565}
3566
3567////////////////////////////////////////////////////////////////////////////////
3568/// Perform last checks on the geometry
3569
3571{
3572 if (fgVerboseLevel>0) Info("CheckGeometry","Fixing runtime shapes...");
3573 TIter next(fShapes);
3574 TIter nextv(fVolumes);
3575 TGeoShape *shape;
3576 TGeoVolume *vol;
3577 Bool_t has_runtime = kFALSE;
3578 while ((shape = (TGeoShape*)next())) {
3579 if (shape->IsRunTimeShape()) {
3580 has_runtime = kTRUE;
3581 }
3582 if (fIsGeomReading) shape->AfterStreamer();
3585 }
3586 if (has_runtime) fTopNode->CheckShapes();
3587 else if (fgVerboseLevel>0) Info("CheckGeometry","...Nothing to fix");
3588 // Compute bounding box for assemblies
3590 while ((vol = (TGeoVolume*)nextv())) {
3591 if (vol->IsAssembly()) vol->GetShape()->ComputeBBox();
3592 else if (vol->GetMedium() == dummy) {
3593 Warning("CheckGeometry", "Volume \"%s\" has no medium: assigned dummy medium and material", vol->GetName());
3594 vol->SetMedium(dummy);
3595 }
3596 }
3597}
3598
3599////////////////////////////////////////////////////////////////////////////////
3600/// Check all geometry for illegal overlaps within a limit OVLP.
3601
3603{
3604 if (!fTopNode) {
3605 Error("CheckOverlaps","Top node not set");
3606 return;
3607 }
3608 fTopNode->CheckOverlaps(ovlp,option);
3609}
3610
3611////////////////////////////////////////////////////////////////////////////////
3612/// Prints the current list of overlaps.
3613
3615{
3616 if (!fOverlaps) return;
3617 Int_t novlp = fOverlaps->GetEntriesFast();
3618 if (!novlp) return;
3619 TGeoManager *geom = (TGeoManager*)this;
3620 geom->GetGeomPainter()->PrintOverlaps();
3621}
3622
3623////////////////////////////////////////////////////////////////////////////////
3624/// Estimate weight of volume VOL with a precision SIGMA(W)/W better than PRECISION.
3625/// Option can be "v" - verbose (default)
3626
3628{
3630 TString opt(option);
3631 opt.ToLower();
3632 Double_t weight;
3633 TGeoVolume *volume = fTopVolume;
3634 if (opt.Contains("v")) {
3635 if (opt.Contains("a")) {
3636 if (fgVerboseLevel>0) Info("Weight", "Computing analytically weight of %s", volume->GetName());
3637 weight = volume->WeightA();
3638 if (fgVerboseLevel>0) Info("Weight", "Computed weight: %f [kg]\n", weight);
3639 return weight;
3640 }
3641 if (fgVerboseLevel>0) {
3642 Info("Weight", "Estimating weight of %s with %g %% precision", fTopVolume->GetName(), 100.*precision);
3643 printf(" event weight err\n");
3644 printf("========================================\n");
3645 }
3646 }
3647 weight = fPainter->Weight(precision, option);
3648 return weight;
3649}
3650
3651////////////////////////////////////////////////////////////////////////////////
3652/// computes the total size in bytes of the branch starting with node.
3653/// The option can specify if all the branch has to be parsed or only the node
3654
3655ULong_t TGeoManager::SizeOf(const TGeoNode * /*node*/, Option_t * /*option*/)
3656{
3657 return 0;
3658}
3659
3660////////////////////////////////////////////////////////////////////////////////
3661/// Stream an object of class TGeoManager.
3662
3663void TGeoManager::Streamer(TBuffer &R__b)
3664{
3665 if (R__b.IsReading()) {
3666 R__b.ReadClassBuffer(TGeoManager::Class(), this);
3668 CloseGeometry();
3671 } else {
3673 }
3674}
3675
3676////////////////////////////////////////////////////////////////////////////////
3677/// Execute mouse actions on this manager.
3678
3680{
3681 if (!fPainter) return;
3682 fPainter->ExecuteManagerEvent(this, event, px, py);
3683}
3684
3685////////////////////////////////////////////////////////////////////////////////
3686/// Export this geometry to a file
3687///
3688/// - Case 1: root file or root/xml file
3689/// if filename end with ".root". The key will be named name
3690/// By default the geometry is saved without the voxelisation info.
3691/// Use option 'v" to save the voxelisation info.
3692/// if filename end with ".xml" a root/xml file is produced.
3693///
3694/// - Case 2: C++ script
3695/// if filename end with ".C"
3696///
3697/// - Case 3: gdml file
3698/// if filename end with ".gdml"
3699/// NOTE that to use this option, the PYTHONPATH must be defined like
3700/// export PYTHONPATH=$ROOTSYS/lib:$ROOTSYS/geom/gdml
3701///
3702
3703Int_t TGeoManager::Export(const char *filename, const char *name, Option_t *option)
3704{
3705 TString sfile(filename);
3706 if (sfile.Contains(".C")) {
3707 //Save geometry as a C++ script
3708 if (fgVerboseLevel>0) Info("Export","Exporting %s %s as C++ code", GetName(), GetTitle());
3709 fTopVolume->SaveAs(filename);
3710 return 1;
3711 }
3712 if (sfile.Contains(".gdml")) {
3713 //Save geometry as a gdml file
3714 if (fgVerboseLevel>0) Info("Export","Exporting %s %s as gdml code", GetName(), GetTitle());
3715 //C++ version
3716 TString cmd ;
3717 cmd = TString::Format("TGDMLWrite::StartGDMLWriting(gGeoManager,\"%s\",\"%s\")", filename, option);
3718 gROOT->ProcessLineFast(cmd);
3719 return 1;
3720 }
3721 if (sfile.Contains(".root") || sfile.Contains(".xml")) {
3722 //Save geometry as a root file
3723 TFile *f = TFile::Open(filename,"recreate");
3724 if (!f || f->IsZombie()) {
3725 Error("Export","Cannot open file");
3726 return 0;
3727 }
3728 TString keyname = name;
3729 if (keyname.IsNull()) keyname = GetName();
3730 TString opt = option;
3731 opt.ToLower();
3732 if (opt.Contains("v")) {
3734 if (fgVerboseLevel>0) Info("Export","Exporting %s %s as root file. Optimizations streamed.", GetName(), GetTitle());
3735 } else {
3737 if (fgVerboseLevel>0) Info("Export","Exporting %s %s as root file. Optimizations not streamed.", GetName(), GetTitle());
3738 }
3739
3740 const char *precision_dbl = TBufferText::GetDoubleFormat();
3741 const char *precision_flt = TBufferText::GetFloatFormat();
3742 TString new_format_dbl = TString::Format("%%.%dg", TGeoManager::GetExportPrecision());
3743 if (sfile.Contains(".xml")) {
3744 TBufferText::SetDoubleFormat(new_format_dbl.Data());
3745 TBufferText::SetFloatFormat(new_format_dbl.Data());
3746 }
3747 Int_t nbytes = Write(keyname);
3748 if (sfile.Contains(".xml")) {
3749 TBufferText::SetFloatFormat(precision_dbl);
3750 TBufferText::SetDoubleFormat(precision_flt);
3751 }
3752
3754 delete f;
3755 return nbytes;
3756 }
3757 return 0;
3758}
3759
3760////////////////////////////////////////////////////////////////////////////////
3761/// Lock current geometry so that no other geometry can be imported.
3762
3764{
3765 fgLock = kTRUE;
3766}
3767
3768////////////////////////////////////////////////////////////////////////////////
3769/// Unlock current geometry.
3770
3772{
3773 fgLock = kFALSE;
3774}
3775
3776////////////////////////////////////////////////////////////////////////////////
3777/// Check lock state.
3778
3780{
3781 return fgLock;
3782}
3783
3784////////////////////////////////////////////////////////////////////////////////
3785/// Set verbosity level (static function).
3786/// - 0 - suppress messages related to geom-painter visibility level
3787/// - 1 - default value
3788
3790{
3791 return fgVerboseLevel;
3792}
3793
3794////////////////////////////////////////////////////////////////////////////////
3795/// Return current verbosity level (static function).
3796
3798{
3799 fgVerboseLevel = vl;
3800}
3801
3802////////////////////////////////////////////////////////////////////////////////
3803///static function
3804///Import a geometry from a gdml or ROOT file
3805///
3806/// - Case 1: gdml
3807/// if filename ends with ".gdml" the foreign geometry described with gdml
3808/// is imported executing some python scripts in $ROOTSYS/gdml.
3809/// NOTE that to use this option, the PYTHONPATH must be defined like
3810/// export PYTHONPATH=$ROOTSYS/lib:$ROOTSYS/gdml
3811///
3812/// - Case 2: root file (.root) or root/xml file (.xml)
3813/// Import in memory from filename the geometry with key=name.
3814/// if name="" (default), the first TGeoManager object in the file is returned.
3815///
3816/// Note that this function deletes the current gGeoManager (if one)
3817/// before importing the new object.
3818
3819TGeoManager *TGeoManager::Import(const char *filename, const char *name, Option_t * /*option*/)
3820{
3821 if (fgLock) {
3822 ::Warning("TGeoManager::Import", "TGeoMananager in lock mode. NOT IMPORTING new geometry");
3823 return NULL;
3824 }
3825 if (!filename) return 0;
3826 if (fgVerboseLevel>0) ::Info("TGeoManager::Import","Reading geometry from file: %s",filename);
3827
3828 if (gGeoManager) delete gGeoManager;
3829 gGeoManager = 0;
3830
3831 if (strstr(filename,".gdml")) {
3832 // import from a gdml file
3833 new TGeoManager("GDMLImport", "Geometry imported from GDML");
3834 TString cmd = TString::Format("TGDMLParse::StartGDML(\"%s\")", filename);
3835 TGeoVolume* world = (TGeoVolume*)gROOT->ProcessLineFast(cmd);
3836
3837 if(world == 0) {
3838 ::Error("TGeoManager::Import", "Cannot open file");
3839 }
3840 else {
3841 gGeoManager->SetTopVolume(world);
3844 }
3845 } else {
3846 // import from a root file
3848 // in case a web file is specified, use the cacheread option to cache
3849 // this file in the cache directory
3850 TFile *f = 0;
3851 if (strstr(filename,"http")) f = TFile::Open(filename,"CACHEREAD");
3852 else f = TFile::Open(filename);
3853 if (!f || f->IsZombie()) {
3854 ::Error("TGeoManager::Import", "Cannot open file");
3855 return 0;
3856 }
3857 if (name && strlen(name) > 0) {
3858 gGeoManager = (TGeoManager*)f->Get(name);
3859 } else {
3860 TIter next(f->GetListOfKeys());
3861 TKey *key;
3862 while ((key = (TKey*)next())) {
3863 if (strcmp(key->GetClassName(),"TGeoManager") != 0) continue;
3864 gGeoManager = (TGeoManager*)key->ReadObj();
3865 break;
3866 }
3867 }
3868 delete f;
3869 }
3870 if (!gGeoManager) return 0;
3871 if (!gROOT->GetListOfGeometries()->FindObject(gGeoManager)) gROOT->GetListOfGeometries()->Add(gGeoManager);
3872 if (!gROOT->GetListOfBrowsables()->FindObject(gGeoManager)) gROOT->GetListOfBrowsables()->Add(gGeoManager);
3874 return gGeoManager;
3875}
3876
3877////////////////////////////////////////////////////////////////////////////////
3878/// Update element flags when geometry is loaded from a file.
3879
3881{
3882 if (!fElementTable) return;
3883 TIter next(fMaterials);
3884 TGeoMaterial *mat;
3885 TGeoMixture *mix;
3886 TGeoElement *elem, *elem_table;
3887 Int_t i, nelem;
3888 while ((mat=(TGeoMaterial*)next())) {
3889 if (mat->IsMixture()) {
3890 mix = (TGeoMixture*)mat;
3891 nelem = mix->GetNelements();
3892 for (i=0; i<nelem; i++) {
3893 elem = mix->GetElement(i);
3894 if (!elem) continue;
3895 elem_table = fElementTable->GetElement(elem->Z());
3896 if (!elem_table) continue;
3897 if (elem != elem_table) {
3898 elem_table->SetDefined(elem->IsDefined());
3899 elem_table->SetUsed(elem->IsUsed());
3900 } else {
3901 elem_table->SetDefined();
3902 }
3903 }
3904 } else {
3905 elem = mat->GetElement();
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->SetUsed();
3914 }
3915 }
3916 }
3917}
3918
3919////////////////////////////////////////////////////////////////////////////////
3920/// Initialize PNE array for fast access via index and unique-id.
3921
3923{
3924 if (fHashPNE) {
3926 TIter next(fHashPNE);
3927 TObject *obj;
3928 while ((obj = next())) {
3929 fArrayPNE->Add(obj);
3930 }
3931 return kTRUE;
3932 }
3933 return kFALSE;
3934}
3935
3936////////////////////////////////////////////////////////////////////////////////
3937/// Get time cut for drawing tracks.
3938
3940{
3941 tmin = fTmin;
3942 tmax = fTmax;
3943 return fTimeCut;
3944}
3945
3946////////////////////////////////////////////////////////////////////////////////
3947/// Set time cut interval for drawing tracks. If called with no arguments, time
3948/// cut will be disabled.
3949
3951{
3952 fTmin = tmin;
3953 fTmax = tmax;
3954 if (tmin==0 && tmax==999) fTimeCut = kFALSE;
3955 else fTimeCut = kTRUE;
3957}
3958
3959////////////////////////////////////////////////////////////////////////////////
3960/// Convert coordinates from master volume frame to top.
3961
3962void TGeoManager::MasterToTop(const Double_t *master, Double_t *top) const
3963{
3964 GetCurrentNavigator()->MasterToLocal(master, top);
3965}
3966
3967////////////////////////////////////////////////////////////////////////////////
3968/// Convert coordinates from top volume frame to master.
3969
3970void TGeoManager::TopToMaster(const Double_t *top, Double_t *master) const
3971{
3972 GetCurrentNavigator()->LocalToMaster(top, master);
3973}
3974
3975////////////////////////////////////////////////////////////////////////////////
3976/// Create a parallel world for prioritised navigation. This can be populated
3977/// with physical nodes and can be navigated independently using its API.
3978/// In case the flag SetUseParallelWorldNav is set, any navigation query in the
3979/// main geometry is checked against the parallel geometry, which gets priority
3980/// in case of overlaps with the main geometry volumes.
3981
3983{
3985 return fParallelWorld;
3986}
3987
3988////////////////////////////////////////////////////////////////////////////////
3989/// Activate/deactivate usage of parallel world navigation. Can only be done if
3990/// there is a parallel world. Activating navigation will automatically close
3991/// the parallel geometry.
3992
3994{
3995 if (!fParallelWorld) {
3996 Error("SetUseParallelWorldNav", "No parallel world geometry defined. Use CreateParallelWorld.");
3997 return;
3998 }
3999 if (!flag) {
4000 fUsePWNav = flag;
4001 return;
4002 }
4003 if (!fClosed) {
4004 Error("SetUseParallelWorldNav", "The geometry must be closed first");
4005 return;
4006 }
4007 // Closing the parallel world geometry is mandatory
4009}
4010
4012 Bool_t val = gGeometryLocked;
4013 gGeometryLocked = new_value;
4014 return val;
4015}
4016
4018{
4019 return fgDefaultUnits;
4020}
4021
4023{
4024 if ( fgDefaultUnits == new_value ) {
4025 return;
4026 }
4027 else if ( gGeometryLocked ) {
4028 ::Fatal("TGeoManager","The system of units may only be changed once, \n"
4029 "BEFORE any elements and materials are created! \n"
4030 "Alternatively unlock the default units at own risk.");
4031 }
4032 else if ( new_value == kG4Units ) {
4033 ::Warning("TGeoManager","Changing system of units to Geant4 units (mm, ns, MeV).");
4034 }
4035 else if ( new_value == kRootUnits ) {
4036 ::Warning("TGeoManager","Changing system of units to ROOT units (cm, s, GeV).");
4037 }
4038 fgDefaultUnits = new_value;
4039}
int Int_t
Definition: CPyCppyy.h:43
unsigned int UInt_t
Definition: CPyCppyy.h:44
unsigned long ULong_t
Definition: CPyCppyy.h:51
void Class()
Definition: Class.C:29
ROOT::R::TRInterface & r
Definition: Object.C:4
#define SafeDelete(p)
Definition: RConfig.hxx:536
#define b(i)
Definition: RSha256.hxx:100
#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
unsigned char UChar_t
Definition: RtypesCore.h:38
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
double Double_t
Definition: RtypesCore.h:59
float Float_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
#define BIT(n)
Definition: Rtypes.h:85
#define ClassImp(name)
Definition: Rtypes.h:364
@ 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
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:412
#define gPad
Definition: TVirtualPad.h:287
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
virtual void RecursiveRemove(TObject *obj)
Recursively remove obj from browser.
Definition: TBrowser.cxx:386
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:5895
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
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:4011
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
Class handling Boolean composition of shapes.
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.
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.
TGeoNode * GetCurrentNode() const
Definition: TGeoManager.h:519
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.
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.
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 pointing to a sphere shape with given medium.
void ResetUserData()
Sets all pointers TGeoVolume::fField to NULL.
TGeoVolume * FindVolumeFast(const char *name, Bool_t multi=kFALSE)
Fast search for a named volume. All trailing blanks stripped.
TList * fMedia
Definition: TGeoManager.h:110
Bool_t GetTminTmax(Double_t &tmin, Double_t &tmax) const
Get time cut for drawing tracks.
TGeoNode * InitTrack(const Double_t *point, const Double_t *dir)
Initialize current point and current direction vector (normalized) in MARS.
ThreadsMap_t::const_iterator ThreadsMapIt_t
Definition: TGeoManager.h:119
Bool_t fMatrixTransform
flag that the list of physical nodes has to be drawn
Definition: TGeoManager.h:91
void Voxelize(Option_t *option=0)
Voxelize all non-divided volumes.
void SetVisibility(TObject *obj, Bool_t vis)
Set visibility for a volume.
void SetTopVolume(TGeoVolume *vol)
Set the top volume and corresponding node as starting point of the geometry.
Bool_t fMatrixReflection
flag for using GL matrix
Definition: TGeoManager.h:92
TGeoPNEntry * SetAlignableEntry(const char *unique_name, const char *path, Int_t uid=-1)
Creates an alignable object with unique name corresponding to a path and adds it to the list of align...
void ClearShape(const TGeoShape *shape)
Remove a shape from the list of shapes.
void ModifiedPad() const
Send "Modified" signal to painter.
void BombTranslation(const Double_t *tr, Double_t *bombtr)
Get the new 'bombed' translation vector according current exploded view mode.
TGeoNavigator * fCurrentNavigator
Lock existing navigators.
Definition: TGeoManager.h:127
static Bool_t LockDefaultUnits(Bool_t new_value)
virtual ~TGeoManager()
Destructor.
Int_t fMaxVisNodes
Definition: TGeoManager.h:79
TGeoMedium * GetMedium(const char *medium) const
Search for a named tracking medium. All trailing blanks stripped.
Bool_t InsertPNEId(Int_t uid, Int_t ientry)
Insert a PN entry in the sorted array of indexes.
Int_t fVisLevel
Definition: TGeoManager.h:76
void ViewLeaves(Bool_t flag=kTRUE)
Set visualization option (leaves only OR all volumes)
TGeoVolume * MakeCtub(const char *name, TGeoMedium *medium, Double_t rmin, Double_t rmax, Double_t dz, Double_t phi1, Double_t phi2, Double_t lx, Double_t ly, Double_t lz, Double_t tx, Double_t ty, Double_t tz)
Make in one step a volume pointing to a tube segment shape with given medium.
void SetTminTmax(Double_t tmin=0, Double_t tmax=999)
Set time cut interval for drawing tracks.
NavigatorsMap_t fNavigators
Definition: TGeoManager.h:123
void GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
Fill node copy numbers of current branch into an array.
Bool_t fPhiCut
flag to notify that the manager is being destructed
Definition: TGeoManager.h:88
TGeoNode * CrossBoundaryAndLocate(Bool_t downwards, TGeoNode *skipnode)
Cross next boundary and locate within current node The current point must be on the boundary of fCurr...
void DrawTracks(Option_t *option="")
Draw tracks over the geometry, according to option.
TObjArray * GetListOfPhysicalNodes()
Definition: TGeoManager.h:488
void BuildDefaultMaterials()
Now just a shortcut for GetElementTable.
void SetMaxThreads(Int_t nthreads)
Set maximum number of threads for navigation.
TGeoMedium * Medium(const char *name, Int_t numed, Int_t nmat, Int_t isvol, Int_t ifield, Double_t fieldm, Double_t tmaxfd, Double_t stemax, Double_t deemax, Double_t epsil, Double_t stmin)
Create tracking medium.
void SetExplodedView(Int_t iopt=0)
Set type of exploding view (see TGeoPainter::SetExplodedView())
Double_t Weight(Double_t precision=0.01, Option_t *option="va")
Estimate weight of volume VOL with a precision SIGMA(W)/W better than PRECISION.
void ClearPhysicalNodes(Bool_t mustdelete=kFALSE)
Clear the current list of physical nodes, so that we can start over with a new list.
static Int_t Parse(const char *expr, TString &expr1, TString &expr2, TString &expr3)
Parse a string boolean expression and do a syntax check.
void GetBombFactors(Double_t &bombx, Double_t &bomby, Double_t &bombz, Double_t &bombr) const
Retrieve cartesian and radial bomb factors.
Double_t GetProperty(const char *name, Bool_t *error=nullptr) const
Get a user-defined property.
TObjArray * fTracks
list of runtime volumes
Definition: TGeoManager.h:103
Bool_t IsAnimatingTracks() const
Definition: TGeoManager.h:410
const char * GetPath() const
Get path to the current node in the form /node0/node1/...
static Int_t fgNumThreads
Thread id's map.
Definition: TGeoManager.h:125
TObjArray * fGDMLMatrices
Definition: TGeoManager.h:105
TGeoPhysicalNode * MakeAlignablePN(const char *name)
Make a physical node from the path pointed by an alignable object with a given name.
void SetCheckedNode(TGeoNode *node)
Assign a given node to be checked for overlaps. Any other overlaps will be ignored.
Int_t AddOverlap(const TNamed *ovlp)
Add an illegal overlap/extrusion to the list.
void CreateThreadData() const
Create thread private data for all geometry objects.
Int_t fNsegments
Definition: TGeoManager.h:77
TObjArray * fOverlaps
Definition: TGeoManager.h:112
TGeoNode * SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil=1E-5, const char *g3path="")
shoot npoints randomly in a box of 1E-5 around current point.
Bool_t IsMultiThread() const
Definition: TGeoManager.h:462
TGDMLMatrix * GetGDMLMatrix(const char *name) const
Get GDML matrix with a given name;.
Double_t fTmax
lower time limit for tracks drawing
Definition: TGeoManager.h:69
Int_t TransformVolumeToAssembly(const char *vname)
Transform all volumes named VNAME to assemblies. The volumes must be virtual.
Bool_t fMultiThread
Max number of threads.
Definition: TGeoManager.h:149
TGeoVolume * MakePgon(const char *name, TGeoMedium *medium, Double_t phi, Double_t dphi, Int_t nedges, Int_t nz)
Make in one step a volume pointing to a polygone shape with given medium.
TGeoVolume * MakeTrap(const char *name, TGeoMedium *medium, Double_t dz, Double_t theta, Double_t phi, Double_t h1, Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2, Double_t tl2, Double_t alpha2)
Make in one step a volume pointing to a trapezoid shape with given medium.
void DrawCurrentPoint(Int_t color=2)
Draw current point in the same view.
static void SetVerboseLevel(Int_t vl)
Return current verbosity level (static function).
TGeoOpticalSurface * GetOpticalSurface(const char *name) const
Get optical surface with a given name;.
void SetNsegments(Int_t nseg)
Set number of segments for approximating circles in drawing.
Bool_t IsSamePoint(Double_t x, Double_t y, Double_t z) const
Check if a new point with given coordinates is the same as the last located one.
void SetNmeshPoints(Int_t npoints=1000)
Set the number of points to be generated on the shape outline when checking for overlaps.
void CheckBoundaryReference(Int_t icheck=-1)
Check the boundary errors reference file created by CheckBoundaryErrors method.
static Int_t GetVerboseLevel()
Set verbosity level (static function).
Int_t GetVisLevel() const
Returns current depth to which geometry is drawn.
static EDefaultUnits fgDefaultUnits
Precision to be used in ASCII exports.
Definition: TGeoManager.h:60
virtual void Edit(Option_t *option="")
Append a pad for this geometry.
Bool_t AddProperty(const char *property, Double_t value)
Add a user-defined property. Returns true if added, false if existing.
TObjArray * fNodes
Definition: TGeoManager.h:111
TGeoMaterial * GetMaterial(const char *matname) const
Search for a named material. All trailing blanks stripped.
void CheckGeometry(Option_t *option="")
Perform last checks on the geometry.
TGeoVolumeAssembly * MakeVolumeAssembly(const char *name)
Make an assembly of volumes.
Int_t GetBombMode() const
Definition: TGeoManager.h:214
Int_t AddRegion(TGeoRegion *region)
Add a new region of volumes.
void SelectTrackingMedia()
Define different tracking media.
void CdNext()
Do a cd to the node found next by FindNextBoundary.
void CdTop()
Make top level node the current node.
Double_t Safety(Bool_t inside=kFALSE)
Compute safe distance from the current point.
Int_t * fKeyPNEId
Definition: T