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 <stdlib.h>
238
239#include "Riostream.h"
240
241#include "TROOT.h"
242#include "TGeoManager.h"
243#include "TSystem.h"
244#include "TStyle.h"
245#include "TVirtualPad.h"
246#include "TBrowser.h"
247#include "TFile.h"
248#include "TKey.h"
249#include "THashList.h"
250#include "TClass.h"
251#include "ThreadLocalStorage.h"
252#include "TBufferText.h"
253
254#include "TGeoVoxelFinder.h"
255#include "TGeoElement.h"
256#include "TGeoMaterial.h"
257#include "TGeoMedium.h"
258#include "TGeoMatrix.h"
259#include "TGeoNode.h"
260#include "TGeoPhysicalNode.h"
261#include "TGeoPara.h"
262#include "TGeoParaboloid.h"
263#include "TGeoTube.h"
264#include "TGeoEltu.h"
265#include "TGeoHype.h"
266#include "TGeoCone.h"
267#include "TGeoSphere.h"
268#include "TGeoArb8.h"
269#include "TGeoPgon.h"
270#include "TGeoTrd1.h"
271#include "TGeoTrd2.h"
272#include "TGeoTorus.h"
273#include "TGeoXtru.h"
274#include "TGeoCompositeShape.h"
275#include "TGeoBoolNode.h"
276#include "TGeoBuilder.h"
277#include "TVirtualGeoPainter.h"
278#include "TPluginManager.h"
279#include "TVirtualGeoTrack.h"
280#include "TQObject.h"
281#include "TMath.h"
282#include "TEnv.h"
283#include "TGeoParallelWorld.h"
284#include "TGeoRegion.h"
285#include "TGDMLMatrix.h"
286#include "TGeoOpticalSurface.h"
287
288// statics and globals
289
291
293
294std::mutex TGeoManager::fgMutex;
306
307////////////////////////////////////////////////////////////////////////////////
308/// Default constructor.
309
311{
315 fTmin = 0.;
316 fTmax = 999.;
317 fPhiCut = kFALSE;
318 fPhimin = 0;
319 fPhimax = 360;
324 fClosed = kFALSE;
326 fBits = 0;
328 fMaterials = 0;
329 fHashPNE = 0;
330 fArrayPNE = 0;
331 fMatrices = 0;
332 fNodes = 0;
333 fOverlaps = 0;
334 fRegions = 0;
335 fNNodes = 0;
336 fMaxVisNodes = 10000;
337 fVolumes = 0;
338 fPhysicalNodes = 0;
339 fShapes = 0;
340 fGVolumes = 0;
341 fGShapes = 0;
342 fTracks = 0;
343 fMedia = 0;
344 fNtracks = 0;
345 fNpdg = 0;
346 fPdgNames = 0;
347 fGDMLMatrices = 0;
349 fSkinSurfaces = 0;
350 fBorderSurfaces = 0;
351 memset(fPdgId, 0, 1024*sizeof(Int_t));
352// TObjArray *fNavigators; //! list of navigators
353 fCurrentTrack = 0;
354 fCurrentVolume = 0;
355 fTopVolume = 0;
356 fTopNode = 0;
357 fMasterVolume = 0;
358 fPainter = 0;
361 fVisDensity = 0.;
362 fVisLevel = 3;
363 fVisOption = 1;
364 fExplodedView = 0;
365 fNsegments = 20;
366 fNLevel = 0;
367 fUniqueVolumes = 0;
368 fClippingShape = 0;
371 fGLMatrix = 0;
372 fPaintVolume = 0;
374 fElementTable = 0;
375 fHashVolumes = 0;
376 fHashGVolumes = 0;
377 fSizePNEId = 0;
378 fNPNEId = 0;
379 fKeyPNEId = 0;
380 fValuePNEId = 0;
382 fRaytraceMode = 0;
383 fMaxThreads = 0;
385 fParallelWorld = 0;
387 } else {
388 Init();
391 }
392}
393
394////////////////////////////////////////////////////////////////////////////////
395/// Constructor.
396
397TGeoManager::TGeoManager(const char *name, const char *title)
398 :TNamed(name, title)
399{
400 if (!gROOT->GetListOfGeometries()->FindObject(this)) gROOT->GetListOfGeometries()->Add(this);
401 if (!gROOT->GetListOfBrowsables()->FindObject(this)) gROOT->GetListOfBrowsables()->Add(this);
402 Init();
403 gGeoIdentity = new TGeoIdentity("Identity");
405 if (fgVerboseLevel>0) Info("TGeoManager","Geometry %s, %s created", GetName(), GetTitle());
406}
407
408////////////////////////////////////////////////////////////////////////////////
409/// Initialize manager class.
410
412{
413 if (gGeoManager) {
414 Warning("Init","Deleting previous geometry: %s/%s",gGeoManager->GetName(),gGeoManager->GetTitle());
415 delete gGeoManager;
416 if (fgLock) Fatal("Init", "New geometry created while the old one locked !!!");
417 }
418
419 gGeoManager = this;
422 fTmin = 0.;
423 fTmax = 999.;
424 fPhiCut = kFALSE;
425 fPhimin = 0;
426 fPhimax = 360;
431 fClosed = kFALSE;
433 fBits = new UChar_t[50000]; // max 25000 nodes per volume
435 fHashPNE = new THashList(256,3);
436 fArrayPNE = 0;
437 fMaterials = new THashList(200,3);
438 fMatrices = new TObjArray(256);
439 fNodes = new TObjArray(30);
440 fOverlaps = new TObjArray(256);
441 fRegions = new TObjArray(256);
442 fNNodes = 0;
443 fMaxVisNodes = 10000;
444 fVolumes = new TObjArray(256);
445 fPhysicalNodes = new TObjArray(256);
446 fShapes = new TObjArray(256);
447 fGVolumes = new TObjArray(256);
448 fGShapes = new TObjArray(256);
449 fTracks = new TObjArray(256);
450 fMedia = new THashList(200,3);
451 fNtracks = 0;
452 fNpdg = 0;
453 fPdgNames = 0;
454 fGDMLMatrices = new TObjArray();
456 fSkinSurfaces = new TObjArray();
458 memset(fPdgId, 0, 1024*sizeof(Int_t));
459 fCurrentTrack = 0;
460 fCurrentVolume = 0;
461 fTopVolume = 0;
462 fTopNode = 0;
463 fMasterVolume = 0;
464 fPainter = 0;
467 fVisDensity = 0.;
468 fVisLevel = 3;
469 fVisOption = 1;
470 fExplodedView = 0;
471 fNsegments = 20;
472 fNLevel = 0;
473 fUniqueVolumes = new TObjArray(256);
474 fClippingShape = 0;
477 fGLMatrix = new TGeoHMatrix();
478 fPaintVolume = 0;
480 fElementTable = 0;
481 fHashVolumes = 0;
482 fHashGVolumes = 0;
483 fSizePNEId = 0;
484 fNPNEId = 0;
485 fKeyPNEId = 0;
486 fValuePNEId = 0;
488 fRaytraceMode = 0;
489 fMaxThreads = 0;
491 fParallelWorld = 0;
493}
494
495////////////////////////////////////////////////////////////////////////////////
496/// Destructor
497
499{
500 if (gGeoManager != this) gGeoManager = this;
502
503 if (gROOT->GetListOfFiles()) { //in case this function is called from TROOT destructor
504 gROOT->GetListOfGeometries()->Remove(this);
505 gROOT->GetListOfBrowsables()->Remove(this);
506 }
507// TSeqCollection *brlist = gROOT->GetListOfBrowsers();
508// TIter next(brlist);
509// TBrowser *browser = 0;
510// while ((browser=(TBrowser*)next())) browser->RecursiveRemove(this);
513 delete TGeoBuilder::Instance(this);
514 if (fBits) delete [] fBits;
525 if (fArrayPNE) {delete fArrayPNE;}
538 CleanGarbage();
541 if (fSizePNEId) {
542 delete [] fKeyPNEId;
543 delete [] fValuePNEId;
544 }
545 delete fParallelWorld;
547 gGeoIdentity = 0;
548 gGeoManager = 0;
549}
550
551////////////////////////////////////////////////////////////////////////////////
552/// Add a material to the list. Returns index of the material in list.
553
555{
556 return TGeoBuilder::Instance(this)->AddMaterial((TGeoMaterial*)material);
557}
558
559////////////////////////////////////////////////////////////////////////////////
560/// Add an illegal overlap/extrusion to the list.
561
563{
565 fOverlaps->Add((TObject*)ovlp);
566 return size;
567}
568
569////////////////////////////////////////////////////////////////////////////////
570/// Add a new region of volumes.
572{
573 Int_t size = fRegions->GetEntriesFast();
574 fRegions->Add(region);
575 return size;
576}
577
578////////////////////////////////////////////////////////////////////////////////
579/// Add a user-defined property. Returns true if added, false if existing.
580
581Bool_t TGeoManager::AddProperty(const char* property, Double_t value)
582{
583 auto pos = fProperties.insert(ConstPropMap_t::value_type(property, value));
584 if (!pos.second) {
585 Warning("AddProperty", "Property \"%s\" already exists with value %g", property, (pos.first)->second);
586 return false;
587 }
588 return true;
589}
590
591////////////////////////////////////////////////////////////////////////////////
592/// Get a user-defined property
593
594Double_t TGeoManager::GetProperty(const char *property, Bool_t *error) const
595{
596 auto pos = fProperties.find(property);
597 if (pos == fProperties.end()) {
598 if (error) *error = kTRUE;
599 return 0.;
600 }
601 if (error) *error = kFALSE;
602 return pos->second;
603}
604
605////////////////////////////////////////////////////////////////////////////////
606/// Get a user-defined property from a given index
607
609{
610 // This is a quite inefficient way to access map elements, but needed for the GDML writer to
611 if (i >= fProperties.size()) {
612 if (error) *error = kTRUE;
613 return 0.;
614 }
615 size_t pos = 0;
616 auto it = fProperties.begin();
617 while (pos < i) { ++it; ++pos; }
618 if (error) *error = kFALSE;
619 name = (*it).first;
620 return (*it).second;
621}
622
623////////////////////////////////////////////////////////////////////////////////
624/// Add a matrix to the list. Returns index of the matrix in list.
625
627{
628 return TGeoBuilder::Instance(this)->AddTransformation((TGeoMatrix*)matrix);
629}
630
631////////////////////////////////////////////////////////////////////////////////
632/// Add a shape to the list. Returns index of the shape in list.
633
635{
636 return TGeoBuilder::Instance(this)->AddShape((TGeoShape*)shape);
637}
638
639////////////////////////////////////////////////////////////////////////////////
640/// Add a track to the list of tracks. Use this for primaries only. For secondaries,
641/// add them to the parent track. The method create objects that are registered
642/// to the analysis manager but have to be cleaned-up by the user via ClearTracks().
643
645{
646 Int_t index = fNtracks;
647 fTracks->AddAtAndExpand(GetGeomPainter()->AddTrack(id,pdgcode,particle),fNtracks++);
648 return index;
649}
650
651////////////////////////////////////////////////////////////////////////////////
652/// Add a track to the list of tracks
653
655{
656 Int_t index = fNtracks;
658 return index;
659}
660
661////////////////////////////////////////////////////////////////////////////////
662/// Makes a primary track but do not attach it to the list of tracks. The track
663/// can be attached as daughter to another one with TVirtualGeoTrack::AddTrack
664
666{
667 TVirtualGeoTrack *track = GetGeomPainter()->AddTrack(id,pdgcode,particle);
668 return track;
669}
670
671////////////////////////////////////////////////////////////////////////////////
672/// Add a volume to the list. Returns index of the volume in list.
673
675{
676 if (!volume) {
677 Error("AddVolume", "invalid volume");
678 return -1;
679 }
681 if (!uid) uid++;
682 if (!fCurrentVolume) {
683 fCurrentVolume = volume;
684 fUniqueVolumes->AddAtAndExpand(volume,uid);
685 } else {
686 if (!strcmp(volume->GetName(), fCurrentVolume->GetName())) {
687 uid = fCurrentVolume->GetNumber();
688 } else {
689 fCurrentVolume = volume;
690 Int_t olduid = GetUID(volume->GetName());
691 if (olduid<0) {
692 fUniqueVolumes->AddAtAndExpand(volume,uid);
693 } else {
694 uid = olduid;
695 }
696 }
697 }
698 volume->SetNumber(uid);
699 if (!fHashVolumes) {
700 fHashVolumes = new THashList(256);
701 fHashGVolumes = new THashList(256);
702 }
703 TObjArray *list = fVolumes;
704 if (!volume->GetShape() || volume->IsRunTime() || volume->IsVolumeMulti()) {
705 list = fGVolumes;
706 fHashGVolumes->Add(volume);
707 } else {
708 fHashVolumes->Add(volume);
709 }
710 Int_t index = list->GetEntriesFast();
711 list->AddAtAndExpand(volume,index);
712 return uid;
713}
714
715////////////////////////////////////////////////////////////////////////////////
716/// Add a navigator in the list of navigators. If it is the first one make it
717/// current navigator.
718
720{
721 if (fMultiThread) { TGeoManager::ThreadId(); fgMutex.lock(); }
722 std::thread::id threadId = std::this_thread::get_id();
723 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
724 TGeoNavigatorArray *array = 0;
725 if (it != fNavigators.end()) array = it->second;
726 else {
727 array = new TGeoNavigatorArray(this);
728 fNavigators.insert(NavigatorsMap_t::value_type(threadId, array));
729 }
730 TGeoNavigator *nav = array->AddNavigator();
731 if (fClosed) nav->GetCache()->BuildInfoBranch();
732 if (fMultiThread) fgMutex.unlock();
733 return nav;
734}
735
736////////////////////////////////////////////////////////////////////////////////
737/// Returns current navigator for the calling thread.
738
740{
741 TTHREAD_TLS(TGeoNavigator*) tnav = 0;
742 if (!fMultiThread) return fCurrentNavigator;
743 TGeoNavigator *nav = tnav; // TTHREAD_TLS_GET(TGeoNavigator*,tnav);
744 if (nav) return nav;
745 std::thread::id threadId = std::this_thread::get_id();
746 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
747 if (it == fNavigators.end()) return 0;
748 TGeoNavigatorArray *array = it->second;
749 nav = array->GetCurrentNavigator();
750 tnav = nav; // TTHREAD_TLS_SET(TGeoNavigator*,tnav,nav);
751 return nav;
752}
753
754////////////////////////////////////////////////////////////////////////////////
755/// Get list of navigators for the calling thread.
756
758{
759 std::thread::id threadId = std::this_thread::get_id();
760 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
761 if (it == fNavigators.end()) return 0;
762 TGeoNavigatorArray *array = it->second;
763 return array;
764}
765
766////////////////////////////////////////////////////////////////////////////////
767/// Switch to another existing navigator for the calling thread.
768
770{
771 std::thread::id threadId = std::this_thread::get_id();
772 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
773 if (it == fNavigators.end()) {
774 Error("SetCurrentNavigator", "No navigator defined for this thread\n");
775 std::cout << " thread id: " << threadId << std::endl;
776 return kFALSE;
777 }
778 TGeoNavigatorArray *array = it->second;
779 TGeoNavigator *nav = array->SetCurrentNavigator(index);
780 if (!nav) {
781 Error("SetCurrentNavigator", "Navigator %d not existing for this thread\n", index);
782 std::cout << " thread id: " << threadId << std::endl;
783 return kFALSE;
784 }
786 return kTRUE;
787}
788
789////////////////////////////////////////////////////////////////////////////////
790/// Set the lock for navigators.
791
793{
794 fgLockNavigators = flag;
795}
796
797////////////////////////////////////////////////////////////////////////////////
798/// Clear all navigators.
799
801{
802 if (fMultiThread) fgMutex.lock();
803 TGeoNavigatorArray *arr = 0;
804 for (NavigatorsMap_t::iterator it = fNavigators.begin();
805 it != fNavigators.end(); ++it) {
806 arr = (*it).second;
807 if (arr) delete arr;
808 }
809 fNavigators.clear();
810 if (fMultiThread) fgMutex.unlock();
811}
812
813////////////////////////////////////////////////////////////////////////////////
814/// Clear a single navigator.
815
817{
818 if (fMultiThread) fgMutex.lock();
819 for (NavigatorsMap_t::iterator it = fNavigators.begin(); it != fNavigators.end(); ++it) {
820 TGeoNavigatorArray *arr = (*it).second;
821 if (arr) {
822 if ((TGeoNavigator*)arr->Remove((TObject*)nav)) {
823 delete nav;
824 if (!arr->GetEntries()) fNavigators.erase(it);
825 if (fMultiThread) fgMutex.unlock();
826 return;
827 }
828 }
829 }
830 Error("Remove navigator", "Navigator %p not found", nav);
831 if (fMultiThread) fgMutex.unlock();
832}
833
834////////////////////////////////////////////////////////////////////////////////
835/// Set maximum number of threads for navigation.
836
838{
839 if (!fClosed) {
840 Error("SetMaxThreads", "Cannot set maximum number of threads before closing the geometry");
841 return;
842 }
843 if (!fMultiThread) {
845 std::thread::id threadId = std::this_thread::get_id();
846 NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
847 if (it != fNavigators.end()) {
848 TGeoNavigatorArray *array = it->second;
849 fNavigators.erase(it);
850 fNavigators.insert(NavigatorsMap_t::value_type(threadId, array));
851 }
852 }
853 if (fMaxThreads) {
856 }
857 fMaxThreads = nthreads+1;
858 if (fMaxThreads>0) {
861 }
862}
863
864////////////////////////////////////////////////////////////////////////////////
865
867{
868 if (!fMaxThreads) return;
869 fgMutex.lock();
870 TIter next(fVolumes);
871 TGeoVolume *vol;
872 while ((vol=(TGeoVolume*)next())) vol->ClearThreadData();
873 fgMutex.unlock();
874}
875
876////////////////////////////////////////////////////////////////////////////////
877/// Create thread private data for all geometry objects.
878
880{
881 if (!fMaxThreads) return;
882 fgMutex.lock();
883 TIter next(fVolumes);
884 TGeoVolume *vol;
885 while ((vol=(TGeoVolume*)next())) vol->CreateThreadData(fMaxThreads);
886 fgMutex.unlock();
887}
888
889////////////////////////////////////////////////////////////////////////////////
890/// Clear the current map of threads. This will be filled again by the calling
891/// threads via ThreadId calls.
892
894{
895 if (gGeoManager && !gGeoManager->IsMultiThread()) return;
896 fgMutex.lock();
897 if (!fgThreadId->empty()) fgThreadId->clear();
898 fgNumThreads = 0;
899 fgMutex.unlock();
900}
901
902////////////////////////////////////////////////////////////////////////////////
903/// Translates the current thread id to an ordinal number. This can be used to
904/// manage data which is specific for a given thread.
905
907{
908 TTHREAD_TLS(Int_t) tid = -1;
909 Int_t ttid = tid; // TTHREAD_TLS_GET(Int_t,tid);
910 if (ttid > -1) return ttid;
911 if (gGeoManager && !gGeoManager->IsMultiThread()) return 0;
912 std::thread::id threadId = std::this_thread::get_id();
913 TGeoManager::ThreadsMapIt_t it = fgThreadId->find(threadId);
914 if (it != fgThreadId->end()) return it->second;
915 // Map needs to be updated.
916 fgMutex.lock();
917 (*fgThreadId)[threadId] = fgNumThreads;
918 tid = fgNumThreads; // TTHREAD_TLS_SET(Int_t,tid,fgNumThreads);
919 ttid = fgNumThreads++;
920 fgMutex.unlock();
921 return ttid;
922}
923
924////////////////////////////////////////////////////////////////////////////////
925/// Describe how to browse this object.
926
928{
929 if (!b) return;
930 if (fMaterials) b->Add(fMaterials, "Materials");
931 if (fMedia) b->Add(fMedia, "Media");
932 if (fMatrices) b->Add(fMatrices, "Local transformations");
933 if (fOverlaps) b->Add(fOverlaps, "Illegal overlaps");
934 if (fTracks) b->Add(fTracks, "Tracks");
935 if (fMasterVolume) b->Add(fMasterVolume, "Master Volume", fMasterVolume->IsVisible());
936 if (fTopVolume) b->Add(fTopVolume, "Top Volume", fTopVolume->IsVisible());
937 if (fTopNode) b->Add(fTopNode);
938 TString browserImp(gEnv->GetValue("Browser.Name", "TRootBrowserLite"));
939 TQObject::Connect(browserImp.Data(), "Checked(TObject*,Bool_t)",
940 "TGeoManager", this, "SetVisibility(TObject*,Bool_t)");
941}
942
943////////////////////////////////////////////////////////////////////////////////
944/// Append a pad for this geometry.
945
947 AppendPad("");
948 GetGeomPainter()->EditGeometry(option);
949}
950
951////////////////////////////////////////////////////////////////////////////////
952/// Set visibility for a volume.
953
955{
956 if(obj->IsA() == TGeoVolume::Class()) {
957 TGeoVolume *vol = (TGeoVolume *) obj;
958 vol->SetVisibility(vis);
959 } else {
960 if (obj->InheritsFrom(TGeoNode::Class())) {
961 TGeoNode *node = (TGeoNode *) obj;
962 node->SetVisibility(vis);
963 } else return;
964 }
966}
967
968////////////////////////////////////////////////////////////////////////////////
969/// Get the new 'bombed' translation vector according current exploded view mode.
970
972{
973 if (fPainter) fPainter->BombTranslation(tr, bombtr);
974 return;
975}
976
977////////////////////////////////////////////////////////////////////////////////
978/// Get the new 'unbombed' translation vector according current exploded view mode.
979
981{
982 if (fPainter) fPainter->UnbombTranslation(tr, bombtr);
983 return;
984}
985
986////////////////////////////////////////////////////////////////////////////////
987/// Backup the current state without affecting the cache stack.
988
990{
992}
993
994////////////////////////////////////////////////////////////////////////////////
995/// Restore a backed-up state without affecting the cache stack.
996
998{
1000}
1001
1002////////////////////////////////////////////////////////////////////////////////
1003/// Register a matrix to the list of matrices. It will be cleaned-up at the
1004/// destruction TGeoManager.
1005
1007{
1008 return TGeoBuilder::Instance(this)->RegisterMatrix((TGeoMatrix*)matrix);
1009}
1010
1011////////////////////////////////////////////////////////////////////////////////
1012/// Replaces all occurrences of VORIG with VNEW in the geometry tree. The volume VORIG
1013/// is not replaced from the list of volumes, but all node referencing it will reference
1014/// VNEW instead. Returns number of occurrences changed.
1015
1017{
1018 Int_t nref = 0;
1019 if (!vorig || !vnew) return nref;
1020 TGeoMedium *morig = vorig->GetMedium();
1021 Bool_t checkmed = kFALSE;
1022 if (morig) checkmed = kTRUE;
1023 TGeoMedium *mnew = vnew->GetMedium();
1024 // Try to limit the damage produced by incorrect usage.
1025 if (!mnew && !vnew->IsAssembly()) {
1026 Error("ReplaceVolume","Replacement volume %s has no medium and it is not an assembly",
1027 vnew->GetName());
1028 return nref;
1029 }
1030 if (mnew && checkmed) {
1031 if (mnew->GetId() != morig->GetId())
1032 Warning("ReplaceVolume","Replacement volume %s has different medium than original volume %s",
1033 vnew->GetName(), vorig->GetName());
1034 checkmed = kFALSE;
1035 }
1036
1037 // Medium checking now performed only if replacement is an assembly and old volume a real one.
1038 // Check result is dependent on positioning.
1039 Int_t nvol = fVolumes->GetEntriesFast();
1040 Int_t i,j,nd;
1041 Int_t ierr = 0;
1042 TGeoVolume *vol;
1043 TGeoNode *node;
1044 TGeoVoxelFinder *voxels;
1045 for (i=0; i<nvol; i++) {
1046 vol = (TGeoVolume*)fVolumes->At(i);
1047 if (!vol) continue;
1048 if (vol==vorig || vol==vnew) continue;
1049 nd = vol->GetNdaughters();
1050 for (j=0; j<nd; j++) {
1051 node = vol->GetNode(j);
1052 if (node->GetVolume() == vorig) {
1053 if (checkmed) {
1054 mnew = node->GetMotherVolume()->GetMedium();
1055 if (mnew && mnew->GetId()!=morig->GetId()) ierr++;
1056 }
1057 nref++;
1058 if (node->IsOverlapping()) {
1059 node->SetOverlapping(kFALSE);
1060 Info("ReplaceVolume","%s replaced with assembly and declared NON-OVERLAPPING!",node->GetName());
1061 }
1062 node->SetVolume(vnew);
1063 voxels = node->GetMotherVolume()->GetVoxels();
1064 if (voxels) voxels->SetNeedRebuild();
1065 } else {
1066 if (node->GetMotherVolume() == vorig) {
1067 nref++;
1068 node->SetMotherVolume(vnew);
1069 if (node->IsOverlapping()) {
1070 node->SetOverlapping(kFALSE);
1071 Info("ReplaceVolume","%s inside substitute assembly %s declared NON-OVERLAPPING!",node->GetName(),vnew->GetName());
1072 }
1073 }
1074 }
1075 }
1076 }
1077 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",
1078 ierr, vorig->GetName());
1079 return nref;
1080}
1081
1082////////////////////////////////////////////////////////////////////////////////
1083/// Transform all volumes named VNAME to assemblies. The volumes must be virtual.
1084
1086{
1087 TGeoVolume *toTransform = FindVolumeFast(vname);
1088 if (!toTransform) {
1089 Warning("TransformVolumeToAssembly", "Volume %s not found", vname);
1090 return 0;
1091 }
1092 Int_t index = fVolumes->IndexOf(toTransform);
1093 Int_t count = 0;
1094 Int_t indmax = fVolumes->GetEntries();
1095 Bool_t replace = kTRUE;
1096 TGeoVolume *transformed;
1097 while (index<indmax) {
1098 if (replace) {
1099 replace = kFALSE;
1100 transformed = TGeoVolumeAssembly::MakeAssemblyFromVolume(toTransform);
1101 if (transformed) {
1102 ReplaceVolume(toTransform, transformed);
1103 count++;
1104 } else {
1105 if (toTransform->IsAssembly())
1106 Warning("TransformVolumeToAssembly", "Volume %s already assembly", toTransform->GetName());
1107 if (!toTransform->GetNdaughters())
1108 Warning("TransformVolumeToAssembly", "Volume %s has no daughters, cannot transform", toTransform->GetName());
1109 if (toTransform->IsVolumeMulti())
1110 Warning("TransformVolumeToAssembly", "Volume %s divided, cannot transform", toTransform->GetName());
1111 }
1112 }
1113 index++;
1114 if (index >= indmax) return count;
1115 toTransform = (TGeoVolume*)fVolumes->At(index);
1116 if (!strcmp(toTransform->GetName(),vname)) replace = kTRUE;
1117 }
1118 return count;
1119}
1120
1121////////////////////////////////////////////////////////////////////////////////
1122/// Create a new volume by dividing an existing one (GEANT3 like)
1123///
1124/// Divides MOTHER into NDIV divisions called NAME
1125/// along axis IAXIS starting at coordinate value START
1126/// and having size STEP. The created volumes will have tracking
1127/// media ID=NUMED (if NUMED=0 -> same media as MOTHER)
1128/// The behavior of the division operation can be triggered using OPTION :
1129///
1130/// OPTION (case insensitive) :
1131/// - N - divide all range in NDIV cells (same effect as STEP<=0) (GSDVN in G3)
1132/// - NX - divide range starting with START in NDIV cells (GSDVN2 in G3)
1133/// - S - divide all range with given STEP. NDIV is computed and divisions will be centered
1134/// in full range (same effect as NDIV<=0) (GSDVS, GSDVT in G3)
1135/// - SX - same as DVS, but from START position. (GSDVS2, GSDVT2 in G3)
1136
1137TGeoVolume *TGeoManager::Division(const char *name, const char *mother, Int_t iaxis,
1138 Int_t ndiv, Double_t start, Double_t step, Int_t numed, Option_t *option)
1139{
1140 return TGeoBuilder::Instance(this)->Division(name, mother, iaxis, ndiv, start, step, numed, option);
1141}
1142
1143////////////////////////////////////////////////////////////////////////////////
1144/// Create rotation matrix named 'mat<index>'.
1145///
1146/// - index rotation matrix number
1147/// - theta1 polar angle for axis X
1148/// - phi1 azimuthal angle for axis X
1149/// - theta2 polar angle for axis Y
1150/// - phi2 azimuthal angle for axis Y
1151/// - theta3 polar angle for axis Z
1152/// - phi3 azimuthal angle for axis Z
1153///
1154
1156 Double_t theta2, Double_t phi2,
1157 Double_t theta3, Double_t phi3)
1158{
1159 TGeoBuilder::Instance(this)->Matrix(index, theta1, phi1, theta2, phi2, theta3, phi3);
1160}
1161
1162////////////////////////////////////////////////////////////////////////////////
1163/// Create material with given A, Z and density, having an unique id.
1164
1166{
1167 return TGeoBuilder::Instance(this)->Material(name, a, z, dens, uid, radlen, intlen);
1168
1169}
1170
1171////////////////////////////////////////////////////////////////////////////////
1172/// Create mixture OR COMPOUND IMAT as composed by THE BASIC nelem
1173/// materials defined by arrays A,Z and WMAT, having an unique id.
1174
1176 Int_t nelem, Float_t *wmat, Int_t uid)
1177{
1178 return TGeoBuilder::Instance(this)->Mixture(name, a, z, dens, nelem, wmat, uid);
1179}
1180
1181////////////////////////////////////////////////////////////////////////////////
1182/// Create mixture OR COMPOUND IMAT as composed by THE BASIC nelem
1183/// materials defined by arrays A,Z and WMAT, having an unique id.
1184
1186 Int_t nelem, Double_t *wmat, Int_t uid)
1187{
1188 return TGeoBuilder::Instance(this)->Mixture(name, a, z, dens, nelem, wmat, uid);
1189}
1190
1191////////////////////////////////////////////////////////////////////////////////
1192/// Create tracking medium
1193///
1194/// - numed tracking medium number assigned
1195/// - name tracking medium name
1196/// - nmat material number
1197/// - isvol sensitive volume flag
1198/// - ifield magnetic field
1199/// - fieldm max. field value (kilogauss)
1200/// - tmaxfd max. angle due to field (deg/step)
1201/// - stemax max. step allowed
1202/// - deemax max. fraction of energy lost in a step
1203/// - epsil tracking precision (cm)
1204/// - stmin min. step due to continuous processes (cm)
1205///
1206/// - ifield = 0 if no magnetic field; ifield = -1 if user decision in guswim;
1207/// - ifield = 1 if tracking performed with g3rkuta; ifield = 2 if tracking
1208/// performed with g3helix; ifield = 3 if tracking performed with g3helx3.
1209///
1210
1211TGeoMedium *TGeoManager::Medium(const char *name, Int_t numed, Int_t nmat, Int_t isvol,
1212 Int_t ifield, Double_t fieldm, Double_t tmaxfd,
1213 Double_t stemax, Double_t deemax, Double_t epsil,
1214 Double_t stmin)
1215{
1216 return TGeoBuilder::Instance(this)->Medium(name, numed, nmat, isvol, ifield, fieldm, tmaxfd, stemax, deemax, epsil, stmin);
1217}
1218
1219////////////////////////////////////////////////////////////////////////////////
1220/// Create a node called <name_nr> pointing to the volume called <name>
1221/// as daughter of the volume called <mother> (gspos). The relative matrix is
1222/// made of : a translation (x,y,z) and a rotation matrix named <matIROT>.
1223/// In case npar>0, create the volume to be positioned in mother, according
1224/// its actual parameters (gsposp).
1225/// - NAME Volume name
1226/// - NUMBER Copy number of the volume
1227/// - MOTHER Mother volume name
1228/// - X X coord. of the volume in mother ref. sys.
1229/// - Y Y coord. of the volume in mother ref. sys.
1230/// - Z Z coord. of the volume in mother ref. sys.
1231/// - IROT Rotation matrix number w.r.t. mother ref. sys.
1232/// - ISONLY ONLY/MANY flag
1233
1234void TGeoManager::Node(const char *name, Int_t nr, const char *mother,
1235 Double_t x, Double_t y, Double_t z, Int_t irot,
1236 Bool_t isOnly, Float_t *upar, Int_t npar)
1237{
1238 TGeoBuilder::Instance(this)->Node(name, nr, mother, x, y, z, irot, isOnly, upar, npar);
1239}
1240
1241////////////////////////////////////////////////////////////////////////////////
1242/// Create a node called <name_nr> pointing to the volume called <name>
1243/// as daughter of the volume called <mother> (gspos). The relative matrix is
1244/// made of : a translation (x,y,z) and a rotation matrix named <matIROT>.
1245/// In case npar>0, create the volume to be positioned in mother, according
1246/// its actual parameters (gsposp).
1247/// - NAME Volume name
1248/// - NUMBER Copy number of the volume
1249/// - MOTHER Mother volume name
1250/// - X X coord. of the volume in mother ref. sys.
1251/// - Y Y coord. of the volume in mother ref. sys.
1252/// - Z Z coord. of the volume in mother ref. sys.
1253/// - IROT Rotation matrix number w.r.t. mother ref. sys.
1254/// - ISONLY ONLY/MANY flag
1255
1256void TGeoManager::Node(const char *name, Int_t nr, const char *mother,
1257 Double_t x, Double_t y, Double_t z, Int_t irot,
1258 Bool_t isOnly, Double_t *upar, Int_t npar)
1259{
1260 TGeoBuilder::Instance(this)->Node(name, nr, mother, x, y, z, irot, isOnly, upar, npar);
1261
1262}
1263
1264////////////////////////////////////////////////////////////////////////////////
1265/// Create a volume in GEANT3 style.
1266/// - NAME Volume name
1267/// - SHAPE Volume type
1268/// - NMED Tracking medium number
1269/// - NPAR Number of shape parameters
1270/// - UPAR Vector containing shape parameters
1271
1272TGeoVolume *TGeoManager::Volume(const char *name, const char *shape, Int_t nmed,
1273 Float_t *upar, Int_t npar)
1274{
1275 return TGeoBuilder::Instance(this)->Volume(name, shape, nmed, upar, npar);
1276}
1277
1278////////////////////////////////////////////////////////////////////////////////
1279/// Create a volume in GEANT3 style.
1280/// - NAME Volume name
1281/// - SHAPE Volume type
1282/// - NMED Tracking medium number
1283/// - NPAR Number of shape parameters
1284/// - UPAR Vector containing shape parameters
1285
1286TGeoVolume *TGeoManager::Volume(const char *name, const char *shape, Int_t nmed,
1287 Double_t *upar, Int_t npar)
1288{
1289 return TGeoBuilder::Instance(this)->Volume(name, shape, nmed, upar, npar);
1290}
1291
1292////////////////////////////////////////////////////////////////////////////////
1293/// Assigns uid's for all materials,media and matrices.
1294
1296{
1297 Int_t index = 1;
1298 TIter next(fMaterials);
1299 TGeoMaterial *mater;
1300 while ((mater=(TGeoMaterial*)next())) {
1301 mater->SetUniqueID(index++);
1303 }
1304 index = 1;
1305 TIter next1(fMedia);
1306 TGeoMedium *med;
1307 while ((med=(TGeoMedium*)next1())) {
1308 med->SetUniqueID(index++);
1310 }
1311 index = 1;
1312 TIter next2(fShapes);
1313 TGeoShape *shape;
1314 while ((shape=(TGeoShape*)next2())) {
1315 shape->SetUniqueID(index++);
1316 if (shape->IsComposite()) ((TGeoCompositeShape*)shape)->GetBoolNode()->RegisterMatrices();
1317 }
1318
1319 TIter next3(fMatrices);
1320 TGeoMatrix *matrix;
1321 while ((matrix=(TGeoMatrix*)next3())) {
1322 matrix->RegisterYourself();
1323 }
1324 TIter next4(fMatrices);
1325 index = 1;
1326 while ((matrix=(TGeoMatrix*)next4())) {
1327 matrix->SetUniqueID(index++);
1329 }
1330 TIter next5(fVolumes);
1331 TGeoVolume *vol;
1332 while ((vol=(TGeoVolume*)next5())) vol->UnmarkSaved();
1333}
1334
1335////////////////////////////////////////////////////////////////////////////////
1336/// Reset all attributes to default ones. Default attributes for visualization
1337/// are those defined before closing the geometry.
1338
1340{
1341 if (gPad) delete gPad;
1342 gPad = 0;
1343 SetVisOption(0);
1344 SetVisLevel(3);
1345 SetExplodedView(0);
1347 if (!gStyle) return;
1348 TIter next(fVolumes);
1349 TGeoVolume *vol = 0;
1350 while ((vol=(TGeoVolume*)next())) {
1351 if (!vol->IsVisTouched()) continue;
1352 vol->SetVisTouched(kFALSE);
1353 }
1354}
1355////////////////////////////////////////////////////////////////////////////////
1356/// Closing geometry implies checking the geometry validity, fixing shapes
1357/// with negative parameters (run-time shapes)building the cache manager,
1358/// voxelizing all volumes, counting the total number of physical nodes and
1359/// registering the manager class to the browser.
1360
1362{
1363 if (fClosed) {
1364 Warning("CloseGeometry", "geometry already closed");
1365 return;
1366 }
1367 if (!fMasterVolume) {
1368 Error("CloseGeometry","you MUST call SetTopVolume() first !");
1369 return;
1370 }
1371 if (!gROOT->GetListOfGeometries()->FindObject(this)) gROOT->GetListOfGeometries()->Add(this);
1372 if (!gROOT->GetListOfBrowsables()->FindObject(this)) gROOT->GetListOfBrowsables()->Add(this);
1373// TSeqCollection *brlist = gROOT->GetListOfBrowsers();
1374// TIter next(brlist);
1375// TBrowser *browser = 0;
1376// while ((browser=(TBrowser*)next())) browser->Refresh();
1377 TString opt(option);
1378 opt.ToLower();
1379// Bool_t dummy = opt.Contains("d");
1380 Bool_t nodeid = opt.Contains("i");
1381 // Create a geometry navigator if not present
1382 TGeoNavigator *nav = 0;
1383 Int_t nnavigators = 0;
1384 // Check if the geometry is streamed from file
1385 if (fIsGeomReading) {
1386 if (fgVerboseLevel>0) Info("CloseGeometry","Geometry loaded from file...");
1389 if (!fTopNode) {
1390 if (!fMasterVolume) {
1391 Error("CloseGeometry", "Master volume not streamed");
1392 return;
1393 }
1395 if (fStreamVoxels && fgVerboseLevel>0) Info("CloseGeometry","Voxelization retrieved from file");
1396 }
1397 // Create a geometry navigator if not present
1399 nnavigators = GetListOfNavigators()->GetEntriesFast();
1400 Voxelize("ALL");
1401 CountLevels();
1402 for (Int_t i=0; i<nnavigators; i++) {
1403 nav = (TGeoNavigator*)GetListOfNavigators()->At(i);
1404 nav->GetCache()->BuildInfoBranch();
1405 if (nodeid) nav->GetCache()->BuildIdArray();
1406 }
1407 if (!fHashVolumes) {
1408 Int_t nvol = fVolumes->GetEntriesFast();
1409 Int_t ngvol = fGVolumes->GetEntriesFast();
1410 fHashVolumes = new THashList(nvol+1);
1411 fHashGVolumes = new THashList(ngvol+1);
1412 Int_t i;
1413 for (i=0; i<ngvol; i++) fHashGVolumes->AddLast(fGVolumes->At(i));
1414 for (i=0; i<nvol; i++) fHashVolumes->AddLast(fVolumes->At(i));
1415 }
1416 fClosed = kTRUE;
1417 if (fParallelWorld) {
1418 if (fgVerboseLevel>0) Info("CloseGeometry","Recreating parallel world %s ...",fParallelWorld->GetName());
1420 }
1421
1422 if (fgVerboseLevel>0) Info("CloseGeometry","%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast()-1, GetTitle());
1423 if (fgVerboseLevel>0) Info("CloseGeometry","----------------modeler ready----------------");
1424 return;
1425 }
1426
1427 // Create a geometry navigator if not present
1429 nnavigators = GetListOfNavigators()->GetEntriesFast();
1431 CheckGeometry();
1432 if (fgVerboseLevel>0) Info("CloseGeometry","Counting nodes...");
1433 fNNodes = CountNodes();
1435 if (fNLevel<30) fNLevel = 100;
1436
1437// BuildIdArray();
1438 Voxelize("ALL");
1439 if (fgVerboseLevel>0) Info("CloseGeometry","Building cache...");
1440 CountLevels();
1441 for (Int_t i=0; i<nnavigators; i++) {
1442 nav = (TGeoNavigator*)GetListOfNavigators()->At(i);
1443 nav->GetCache()->BuildInfoBranch();
1444 if (nodeid) nav->GetCache()->BuildIdArray();
1445 }
1446 fClosed = kTRUE;
1447 if (fgVerboseLevel>0) {
1448 Info("CloseGeometry","%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast()-1, GetTitle());
1449 Info("CloseGeometry","----------------modeler ready----------------");
1450 }
1451}
1452
1453////////////////////////////////////////////////////////////////////////////////
1454/// Clear the list of overlaps.
1455
1457{
1458 if (fOverlaps) {
1459 fOverlaps->Delete();
1460 delete fOverlaps;
1461 }
1462 fOverlaps = new TObjArray();
1463}
1464
1465////////////////////////////////////////////////////////////////////////////////
1466/// Remove a shape from the list of shapes.
1467
1469{
1470 if (fShapes->FindObject(shape)) fShapes->Remove((TGeoShape*)shape);
1471 delete shape;
1472}
1473
1474////////////////////////////////////////////////////////////////////////////////
1475/// Clean temporary volumes and shapes from garbage collection.
1476
1478{
1479 if (!fGVolumes && !fGShapes) return;
1480 Int_t i,nentries;
1481 if (fGVolumes) {
1483 TGeoVolume *vol = 0;
1484 for (i=0; i<nentries; i++) {
1485 vol=(TGeoVolume*)fGVolumes->At(i);
1486 if (vol) vol->SetFinder(0);
1487 }
1488 fGVolumes->Delete();
1489 delete fGVolumes;
1490 fGVolumes = 0;
1491 }
1492 if (fGShapes) {
1493 fGShapes->Delete();
1494 delete fGShapes;
1495 fGShapes = 0;
1496 }
1497}
1498
1499////////////////////////////////////////////////////////////////////////////////
1500/// Change current path to point to the node having this id.
1501/// Node id has to be in range : 0 to fNNodes-1 (no check for performance reasons)
1502
1504{
1505 GetCurrentNavigator()->CdNode(nodeid);
1506}
1507
1508////////////////////////////////////////////////////////////////////////////////
1509/// Get the unique ID of the current node.
1510
1512{
1514}
1515
1516////////////////////////////////////////////////////////////////////////////////
1517/// Make top level node the current node. Updates the cache accordingly.
1518/// Determine the overlapping state of current node.
1519
1521{
1523}
1524
1525////////////////////////////////////////////////////////////////////////////////
1526/// Go one level up in geometry. Updates cache accordingly.
1527/// Determine the overlapping state of current node.
1528
1530{
1532}
1533
1534////////////////////////////////////////////////////////////////////////////////
1535/// Make a daughter of current node current. Can be called only with a valid
1536/// daughter index (no check). Updates cache accordingly.
1537
1539{
1540 GetCurrentNavigator()->CdDown(index);
1541}
1542
1543////////////////////////////////////////////////////////////////////////////////
1544/// Do a cd to the node found next by FindNextBoundary
1545
1547{
1549}
1550
1551////////////////////////////////////////////////////////////////////////////////
1552/// Browse the tree of nodes starting from fTopNode according to pathname.
1553/// Changes the path accordingly.
1554
1555Bool_t TGeoManager::cd(const char *path)
1556{
1557 return GetCurrentNavigator()->cd(path);
1558}
1559
1560////////////////////////////////////////////////////////////////////////////////
1561/// Check if a geometry path is valid without changing the state of the current navigator.
1562
1563Bool_t TGeoManager::CheckPath(const char *path) const
1564{
1565 return GetCurrentNavigator()->CheckPath(path);
1566}
1567
1568////////////////////////////////////////////////////////////////////////////////
1569/// Convert all reflections in geometry to normal rotations + reflected shapes.
1570
1572{
1573 if (!fTopNode) return;
1574 if (fgVerboseLevel>0) Info("ConvertReflections", "Converting reflections in: %s - %s ...", GetName(), GetTitle());
1576 TGeoNode *node;
1577 TGeoNodeMatrix *nodematrix;
1578 TGeoMatrix *matrix, *mclone;
1579 TGeoVolume *reflected;
1580 while ((node=next())) {
1581 matrix = node->GetMatrix();
1582 if (matrix->IsReflection()) {
1583// printf("%s before\n", node->GetName());
1584// matrix->Print();
1585 mclone = new TGeoCombiTrans(*matrix);
1586 mclone->RegisterYourself();
1587 // Reflect just the rotation component
1588 mclone->ReflectZ(kFALSE, kTRUE);
1589 nodematrix = (TGeoNodeMatrix*)node;
1590 nodematrix->SetMatrix(mclone);
1591// printf("%s after\n", node->GetName());
1592// node->GetMatrix()->Print();
1593 reflected = node->GetVolume()->MakeReflectedVolume();
1594 node->SetVolume(reflected);
1595 }
1596 }
1597 if (fgVerboseLevel>0) Info("ConvertReflections", "Done");
1598}
1599
1600////////////////////////////////////////////////////////////////////////////////
1601/// Count maximum number of nodes per volume, maximum depth and maximum
1602/// number of xtru vertices.
1603
1605{
1606 if (!fTopNode) {
1607 Error("CountLevels", "Top node not defined.");
1608 return;
1609 }
1611 Bool_t fixrefs = fIsGeomReading && (fMasterVolume->GetRefCount()==1);
1613 if (fgVerboseLevel>1 && fixrefs) Info("CountLevels", "Fixing volume reference counts");
1614 TGeoNode *node;
1615 Int_t maxlevel = 1;
1616 Int_t maxnodes = fTopVolume->GetNdaughters();
1617 Int_t maxvertices = 1;
1618 while ((node=next())) {
1619 if (fixrefs) {
1620 node->GetVolume()->Grab();
1621 for (Int_t ibit=10; ibit<14; ibit++) {
1622 node->SetBit(BIT(ibit+4), node->TestBit(BIT(ibit)));
1623// node->ResetBit(BIT(ibit)); // cannot overwrite old crap for reproducibility
1624 }
1625 }
1626 if (node->GetVolume()->GetVoxels()) {
1627 if (node->GetNdaughters()>maxnodes) maxnodes = node->GetNdaughters();
1628 }
1629 if (next.GetLevel()>maxlevel) maxlevel = next.GetLevel();
1630 if (node->GetVolume()->GetShape()->IsA()==TGeoXtru::Class()) {
1631 TGeoXtru *xtru = (TGeoXtru*)node->GetVolume()->GetShape();
1632 if (xtru->GetNvert()>maxvertices) maxvertices = xtru->GetNvert();
1633 }
1634 }
1635 fgMaxLevel = maxlevel;
1636 fgMaxDaughters = maxnodes;
1637 fgMaxXtruVert = maxvertices;
1638 if (fgVerboseLevel>0) Info("CountLevels", "max level = %d, max placements = %d", fgMaxLevel, fgMaxDaughters);
1639}
1640
1641////////////////////////////////////////////////////////////////////////////////
1642/// Count the total number of nodes starting from a volume, nlevels down.
1643
1645{
1646 TGeoVolume *top;
1647 if (!vol) {
1648 top = fTopVolume;
1649 } else {
1650 top = (TGeoVolume*)vol;
1651 }
1652 Int_t count = top->CountNodes(nlevels, option);
1653 return count;
1654}
1655
1656////////////////////////////////////////////////////////////////////////////////
1657/// Set default angles for a given view.
1658
1660{
1662}
1663
1664////////////////////////////////////////////////////////////////////////////////
1665/// Draw current point in the same view.
1666
1668{
1669 if (fPainter) fPainter->DrawCurrentPoint(color);
1670}
1671
1672////////////////////////////////////////////////////////////////////////////////
1673/// Draw animation of tracks
1674
1676{
1679 if (tmin<0 || tmin>=tmax || nframes<1) return;
1681 box[0] = box[1] = box[2] = 0;
1682 box[3] = box[4] = box[5] = 100;
1683 Double_t dt = (tmax-tmin)/Double_t(nframes);
1684 Double_t delt = 2E-9;
1685 Double_t t = tmin;
1686 Int_t i, j;
1687 TString opt(option);
1688 Bool_t save = kFALSE, geomanim=kFALSE;
1689 TString fname;
1690 if (opt.Contains("/S")) save = kTRUE;
1691
1692 if (opt.Contains("/G")) geomanim = kTRUE;
1693 SetTminTmax(0,0);
1694 DrawTracks(opt.Data());
1695 Double_t start[6], end[6];
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}
void Class()
Definition: Class.C:29
ROOT::R::TRInterface & r
Definition: Object.C:4
#define SafeDelete(p)
Definition: RConfig.hxx:543
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define h(i)
Definition: RSha256.hxx:106
static RooMathCoreReg dummy
int Int_t
Definition: RtypesCore.h:43
unsigned char UChar_t
Definition: RtypesCore.h:36
unsigned int UInt_t
Definition: RtypesCore.h:44
const Bool_t kFALSE
Definition: RtypesCore.h:90
unsigned long ULong_t
Definition: RtypesCore.h:53
bool Bool_t
Definition: RtypesCore.h:61
double Double_t
Definition: RtypesCore.h:57
float Float_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:89
const char Option_t
Definition: RtypesCore.h:64
#define BIT(n)
Definition: Rtypes.h:83
#define ClassImp(name)
Definition: Rtypes.h:361
@ kGray
Definition: Rtypes.h:63
@ kRed
Definition: Rtypes.h:64
@ kOrange
Definition: Rtypes.h:65
@ kGreen
Definition: Rtypes.h:64
@ kMagenta
Definition: Rtypes.h:64
@ kBlue
Definition: Rtypes.h:64
@ kYellow
Definition: Rtypes.h:64
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
XFontStruct * id
Definition: TGX11.cxx:108
char name[80]
Definition: TGX11.cxx:109
TGeoManager * gGeoManager
static Bool_t gGeometryLocked
R__EXTERN TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.h:478
int nentries
Definition: THbookFile.cxx:89
#define gROOT
Definition: TROOT.h:406
R__EXTERN TStyle * gStyle
Definition: TStyle.h:410
#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:366
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:42
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Bool_t IsReading() const
Definition: TBuffer.h:85
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:5872
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:101
Small helper to keep current directory context.
Definition: TDirectory.h:47
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:53
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:3942
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:43
static void UnlockGeometry()
Unlock current geometry.
Double_t fPhimax
lowest range for phi cut
Definition: TGeoManager.h:65
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:148
Double_t fVisDensity
particles to be drawn
Definition: TGeoManager.h:71
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:129
TVirtualGeoTrack * FindTrackWithId(Int_t id) const
Search the track hierarchy to find the track with the given id.
TObjArray * fArrayPNE
Definition: TGeoManager.h:141
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:76
THashList * fHashPNE
hash list of group volumes providing fast search
Definition: TGeoManager.h:140
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:53
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:98
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:131
static UInt_t fgExportPrecision
Maximum number of Xtru vertices.
Definition: TGeoManager.h:57
TObjArray * fRegions
Definition: TGeoManager.h:111
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:99
TGeoVolume * fPaintVolume
Definition: TGeoManager.h:136
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:151
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:107
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:97
Int_t * fValuePNEId
Definition: TGeoManager.h:145
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:87
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:126
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:139
Int_t fVisOption
Definition: TGeoManager.h:73
static std::mutex fgMutex
Definition: TGeoManager.h:51
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:541
Double_t fPhimin
Definition: TGeoManager.h:64
static Bool_t fgLockNavigators
Number of registered threads.
Definition: TGeoManager.h:124
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:88
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:132
TGeoNavigator * GetCurrentNavigator() const
Returns current navigator for the calling thread.
THashList * fHashVolumes
Definition: TGeoManager.h:138
TObjArray * fMatrices
current painter
Definition: TGeoManager.h:95
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:104
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:112
static Int_t GetMaxLevels()
Return maximum number of levels used in the geometry.
Double_t fTmin
highest range for phi cut
Definition: TGeoManager.h:66
static Bool_t IsLocked()
Check lock state.
TGeoVolume * fTopVolume
current volume
Definition: TGeoManager.h:127
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:137
TVirtualGeoPainter * GetGeomPainter()
Make a default painter if none present. Returns pointer to it.
void GetBranchOnlys(Int_t *isonly) const
Fill node copy numbers of current branch into an array.
TGeoNode * GetCurrentNode() const
Definition: TGeoManager.h:517
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:106
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:52
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:96
void AddOpticalSurface(TGeoOpticalSurface *optsurf)
Add optical surface;.
static void SetDefaultUnits(EDefaultUnits new_value)
Bool_t fLoopVolumes
flag that geometry is closed
Definition: TGeoManager.h:82
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:55
Bool_t fUsePWNav
Raytrace mode: 0=normal, 1=pass through, 2=transparent.
Definition: TGeoManager.h:149
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:146
Bool_t fIsGeomReading
Definition: TGeoManager.h:84
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:150
void RegisterMatrix(const TGeoMatrix *matrix)
Register a matrix to the list of matrices.
TVirtualGeoTrack * GetTrack(Int_t index)
Definition: TGeoManager.h:396
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:93
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:92
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:91
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:122
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:68
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:135
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:578
Bool_t fIsGeomCleaning
flag set when reading geometry
Definition: TGeoManager.h:85
Bool_t IsSameLocation() const
Definition: TGeoManager.h:413
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:133
static void SetNavigatorsLock(Bool_t flag)
Set the lock for navigators.
static Int_t fgMaxXtruVert
Maximum number of daughters.
Definition: TGeoManager.h:56
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:477
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:143
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:54
Int_t fNpdg
current track
Definition: TGeoManager.h:79
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:108
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:117