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