Logo ROOT  
Reference Guide
TGeoVolume.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Andrei Gheata 30/05/02
3 // Divide(), CheckOverlaps() implemented by Mihaela Gheata
4 
5 /*************************************************************************
6  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
7  * All rights reserved. *
8  * *
9  * For the licensing terms see $ROOTSYS/LICENSE. *
10  * For the list of contributors see $ROOTSYS/README/CREDITS. *
11  *************************************************************************/
12 
13 /** \class TGeoVolume
14 \ingroup Geometry_classes
15 
16 TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes
17 
18  Volumes are the basic objects used in building the geometrical hierarchy.
19 They represent unpositioned objects but store all information about the
20 placement of the other volumes they may contain. Therefore a volume can
21 be replicated several times in the geometry. In order to create a volume, one
22 has to put together a shape and a medium which are already defined. Volumes
23 have to be named by users at creation time. Every different name may represent a
24 an unique volume object, but may also represent more general a family (class)
25 of volume objects having the same shape type and medium, but possibly
26 different shape parameters. It is the user's task to provide different names
27 for different volume families in order to avoid ambiguities at tracking time.
28 A generic family rather than a single volume is created only in two cases :
29 when a generic shape is provided to the volume constructor or when a division
30 operation is applied. Each volume in the geometry stores an unique
31 ID corresponding to its family. In order to ease-up their creation, the manager
32 class is providing an API that allows making a shape and a volume in a single step.
33 
34  Volumes are objects that can be visualized, therefore having visibility,
35 colour, line and fill attributes that can be defined or modified any time after
36 the volume creation. It is advisable however to define these properties just
37 after the first creation of a volume namespace, since in case of volume families
38 any new member created by the modeler inherits these properties.
39 
40  In order to provide navigation features, volumes have to be able to find
41 the proper container of any point defined in the local reference frame. This
42 can be the volume itself, one of its positioned daughter volumes or none if
43 the point is actually outside. On the other hand, volumes have to provide also
44 other navigation methods such as finding the distances to its shape boundaries
45 or which daughter will be crossed first. The implementation of these features
46 is done at shape level, but the local mother-daughters management is handled
47 by volumes that builds additional optimisation structures upon geometry closure.
48 In order to have navigation features properly working one has to follow the
49 general rules for building a valid geometry (see TGeoManager class).
50 
51  Now let's make a simple volume representing a copper wire. We suppose that
52 a medium is already created (see TGeoMedium class on how to create media).
53 We will create a TUBE shape for our wire, having Rmin=0cm, Rmax=0.01cm
54 and a half-length dZ=1cm :
55 
56 ~~~ {.cpp}
57  TGeoTube *tube = new TGeoTube("wire_tube", 0, 0.01, 1);
58 ~~~
59 
60 One may omit the name for the shape if no retrieving by name is further needed
61 during geometry building. The same shape can be shared by different volumes
62 having different names and materials. Now let's make the volume for our wire.
63 The prototype for volumes constructor looks like :
64 
65  TGeoVolume::TGeoVolume(const char *name, TGeoShape *shape, TGeoMedium *med)
66 
67 Since TGeoTube derives from the base shape class, we can provide it to the volume
68 constructor :
69 
70 ~~~ {.cpp}
71  TGeoVolume *wire_co = new TGeoVolume("WIRE_CO", tube, ptrCOPPER);
72 ~~~
73 
74 Do not bother to delete neither the media, shapes or volumes that you have
75 created since all will be automatically cleaned on exit by the manager class.
76 If we would have taken a look inside TGeoManager::MakeTube() method, we would
77 have been able to create our wire with a single line :
78 
79 ~~~ {.cpp}
80  TGeoVolume *wire_co = gGeoManager->MakeTube("WIRE_CO", ptrCOPPER, 0, 0.01, 1);
81 ~~~
82 
83 The same applies for all primitive shapes, for which there can be found
84 corresponding MakeSHAPE() methods. Their usage is much more convenient unless
85 a shape has to be shared between more volumes. Let's make now an aluminium wire
86 having the same shape, supposing that we have created the copper wire with the
87 line above :
88 
89 ~~~ {.cpp}
90  TGeoVolume *wire_al = new TGeoVolume("WIRE_AL", wire_co->GetShape(), ptrAL);
91 ~~~
92 
93 Now that we have learned how to create elementary volumes, let's see how we
94 can create a geometrical hierarchy.
95 
96 
97 ### Positioning volumes
98 
99  When creating a volume one does not specify if this will contain or not other
100 volumes. Adding daughters to a volume implies creating those and adding them
101 one by one to the list of daughters. Since the volume has to know the position
102 of all its daughters, we will have to supply at the same time a geometrical
103 transformation with respect to its local reference frame for each of them.
104 The objects referencing a volume and a transformation are called NODES and
105 their creation is fully handled by the modeler. They represent the link
106 elements in the hierarchy of volumes. Nodes are unique and distinct geometrical
107 objects ONLY from their container point of view. Since volumes can be replicated
108 in the geometry, the same node may be found on different branches.
109 
110 \image html geom_t_example.png
111 
112  An important observation is that volume objects are owned by the TGeoManager
113 class. This stores a list of all volumes in the geometry, that is cleaned
114 upon destruction.
115 
116  Let's consider positioning now our wire in the middle of a gas chamber. We
117 need first to define the gas chamber :
118 
119 ~~~ {.cpp}
120  TGeoVolume *chamber = gGeoManager->MakeTube("CHAMBER", ptrGAS, 0, 1, 1);
121 ~~~
122 
123 Now we can put the wire inside :
124 
125 ~~~ {.cpp}
126  chamber->AddNode(wire_co, 1);
127 ~~~
128 
129 If we inspect now the chamber volume in a browser, we will notice that it has
130 one daughter. Of course the gas has some container also, but let's keep it like
131 that for the sake of simplicity. The full prototype of AddNode() is :
132 
133 ~~~ {.cpp}
134  TGeoVolume::AddNode(TGeoVolume *daughter, Int_t usernumber,
135  TGeoMatrix *matrix=gGeoIdentity)
136 ~~~
137 
138 Since we did not supplied the third argument, the wire will be positioned with
139 an identity transformation inside the chamber. One will notice that the inner
140 radii of the wire and chamber are both zero - therefore, aren't the two volumes
141 overlapping ? The answer is no, the modeler is even relaying on the fact that
142 any daughter is fully contained by its mother. On the other hand, neither of
143 the nodes positioned inside a volume should overlap with each other. We will
144 see that there are allowed some exceptions to those rules.
145 
146 ### Overlapping volumes
147 
148  Positioning volumes that does not overlap their neighbours nor extrude
149 their container is sometimes quite strong constraint. Some parts of the geometry
150 might overlap naturally, e.g. two crossing tubes. The modeller supports such
151 cases only if the overlapping nodes are declared by the user. In order to do
152 that, one should use TGeoVolume::AddNodeOverlap() instead of TGeoVolume::AddNode().
153  When 2 or more positioned volumes are overlapping, not all of them have to
154 be declared so, but at least one. A point inside an overlapping region equally
155 belongs to all overlapping nodes, but the way these are defined can enforce
156 the modeler to give priorities.
157  The general rule is that the deepest node in the hierarchy containing a point
158 have the highest priority. For the same geometry level, non-overlapping is
159 prioritised over overlapping. In order to illustrate this, we will consider
160 few examples. We will designate non-overlapping nodes as ONLY and the others
161 MANY as in GEANT3, where this concept was introduced:
162  1. The part of a MANY node B extruding its container A will never be "seen"
163 during navigation, as if B was in fact the result of the intersection of A and B.
164  2. If we have two nodes A (ONLY) and B (MANY) inside the same container, all
165 points in the overlapping region of A and B will be designated as belonging to A.
166  3. If A an B in the above case were both MANY, points in the overlapping
167 part will be designated to the one defined first. Both nodes must have the
168 same medium.
169  4. The slices of a divided MANY will be as well MANY.
170 
171 One needs to know that navigation inside geometry parts MANY nodes is much
172 slower. Any overlapping part can be defined based on composite shapes - this
173 is always recommended.
174 
175 ### Replicating volumes
176 
177  What can we do if our chamber contains two identical wires instead of one ?
178 What if then we would need 1000 chambers in our detector ? Should we create
179 2000 wires and 1000 chamber volumes ? No, we will just need to replicate the
180 ones that we have already created.
181 
182 ~~~ {.cpp}
183  chamber->AddNode(wire_co, 1, new TGeoTranslation(-0.2,0,0));
184  chamber->AddNode(wire_co, 2, new TGeoTranslation(0.2,0,0));
185 ~~~
186 
187  The 2 nodes that we have created inside chamber will both point to a wire_co
188 object, but will be completely distinct : WIRE_CO_1 and WIRE_CO_2. We will
189 want now to place symmetrically 1000 chambers on a pad, following a pattern
190 of 20 rows and 50 columns. One way to do this will be to replicate our chamber
191 by positioning it 1000 times in different positions of the pad. Unfortunately,
192 this is far from being the optimal way of doing what we want.
193 Imagine that we would like to find out which of the 1000 chambers is containing
194 a (x,y,z) point defined in the pad reference. You will never have to do that,
195 since the modeller will take care of it for you, but let's guess what it has
196 to do. The most simple algorithm will just loop over all daughters, convert
197 the point from mother to local reference and check if the current chamber
198 contains the point or not. This might be efficient for pads with few chambers,
199 but definitely not for 1000. Fortunately the modeler is smarter than that and
200 create for each volume some optimization structures called voxels (see Voxelization)
201 to minimize the penalty having too many daughters, but if you have 100 pads like
202 this in your geometry you will anyway loose a lot in your tracking performance.
203 
204  The way out when volumes can be arranged according to simple patterns is the
205 usage of divisions. We will describe them in detail later on. Let's think now
206 at a different situation : instead of 1000 chambers of the same type, we may
207 have several types of chambers. Let's say all chambers are cylindrical and have
208 a wire inside, but their dimensions are different. However, we would like all
209 to be represented by a single volume family, since they have the same properties.
210 */
211 
212 /** \class TGeoVolumeMulti
213 \ingroup Geometry_classes
214 
215 Volume families
216 
217 A volume family is represented by the class TGeoVolumeMulti. It represents
218 a class of volumes having the same shape type and each member will be
219 identified by the same name and volume ID. Any operation applied to a
220 TGeoVolume equally affects all volumes in that family. The creation of a
221 family is generally not a user task, but can be forced in particular cases:
222 
223 ~~~ {.cpp}
224  TGeoManager::Volume(const char *vname, const char *shape, Int_t nmed);
225 ~~~
226 
227 where VNAME is the family name, NMED is the medium number and SHAPE is the
228 shape type that can be:
229 
230 ~~~ {.cpp}
231  box - for TGeoBBox
232  trd1 - for TGeoTrd1
233  trd2 - for TGeoTrd2
234  trap - for TGeoTrap
235  gtra - for TGeoGtra
236  para - for TGeoPara
237  tube, tubs - for TGeoTube, TGeoTubeSeg
238  cone, cons - for TGeoCone, TgeoCons
239  eltu - for TGeoEltu
240  ctub - for TGeoCtub
241  pcon - for TGeoPcon
242  pgon - for TGeoPgon
243 ~~~
244 
245 Volumes are then added to a given family upon adding the generic name as node
246 inside other volume:
247 
248 ~~~ {.cpp}
249  TGeoVolume *box_family = gGeoManager->Volume("BOXES", "box", nmed);
250  ...
251  gGeoManager->Node("BOXES", Int_t copy_no, "mother_name",
252  Double_t x, Double_t y, Double_t z, Int_t rot_index,
253  Bool_t is_only, Double_t *upar, Int_t npar);
254 ~~~
255 
256 here:
257 
258 ~~~ {.cpp}
259  BOXES - name of the family of boxes
260  copy_no - user node number for the created node
261  mother_name - name of the volume to which we want to add the node
262  x,y,z - translation components
263  rot_index - indx of a rotation matrix in the list of matrices
264  upar - array of actual shape parameters
265  npar - number of parameters
266 ~~~
267 
268 The parameters order and number are the same as in the corresponding shape
269 constructors.
270 
271  Another particular case where volume families are used is when we want
272 that a volume positioned inside a container to match one ore more container
273 limits. Suppose we want to position the same box inside 2 different volumes
274 and we want the Z size to match the one of each container:
275 
276 ~~~ {.cpp}
277  TGeoVolume *container1 = gGeoManager->MakeBox("C1", imed, 10,10,30);
278  TGeoVolume *container2 = gGeoManager->MakeBox("C2", imed, 10,10,20);
279  TGeoVolume *pvol = gGeoManager->MakeBox("PVOL", jmed, 3,3,-1);
280  container1->AddNode(pvol, 1);
281  container2->AddNode(pvol, 1);
282 ~~~
283 
284  Note that the third parameter of PVOL is negative, which does not make sense
285 as half-length on Z. This is interpreted as: when positioned, create a box
286 replacing all invalid parameters with the corresponding dimensions of the
287 container. This is also internally handled by the TGeoVolumeMulti class, which
288 does not need to be instantiated by users.
289 
290 ### Dividing volumes
291 
292  Volumes can be divided according a pattern. The most simple division can
293 be done along one axis, that can be: X, Y, Z, Phi, Rxy or Rxyz. Let's take
294 the most simple case: we would like to divide a box in N equal slices along X
295 coordinate, representing a new volume family. Supposing we already have created
296 the initial box, this can be done like:
297 
298 ~~~ {.cpp}
299  TGeoVolume *slicex = box->Divide("SLICEX", 1, N);
300 ~~~
301 
302 where SLICE is the name of the new family representing all slices and 1 is the
303 slicing axis. The meaning of the axis index is the following: for all volumes
304 having shapes like box, trd1, trd2, trap, gtra or para - 1,2,3 means X,Y,Z; for
305 tube, tubs, cone, cons - 1 means Rxy, 2 means phi and 3 means Z; for pcon and
306 pgon - 2 means phi and 3 means Z; for spheres 1 means R and 2 means phi.
307  In fact, the division operation has the same effect as positioning volumes
308 in a given order inside the divided container - the advantage being that the
309 navigation in such a structure is much faster. When a volume is divided, a
310 volume family corresponding to the slices is created. In case all slices can
311 be represented by a single shape, only one volume is added to the family and
312 positioned N times inside the divided volume, otherwise, each slice will be
313 represented by a distinct volume in the family.
314  Divisions can be also performed in a given range of one axis. For that, one
315 have to specify also the starting coordinate value and the step:
316 
317 ~~~ {.cpp}
318  TGeoVolume *slicex = box->Divide("SLICEX", 1, N, start, step);
319 ~~~
320 
321 A check is always done on the resulting division range : if not fitting into
322 the container limits, an error message is posted. If we will browse the divided
323 volume we will notice that it will contain N nodes starting with index 1 upto
324 N. The first one has the lower X limit at START position, while the last one
325 will have the upper X limit at START+N*STEP. The resulting slices cannot
326 be positioned inside an other volume (they are by default positioned inside the
327 divided one) but can be further divided and may contain other volumes:
328 
329 ~~~ {.cpp}
330  TGeoVolume *slicey = slicex->Divide("SLICEY", 2, N1);
331  slicey->AddNode(other_vol, index, some_matrix);
332 ~~~
333 
334  When doing that, we have to remember that SLICEY represents a family, therefore
335 all members of the family will be divided on Y and the other volume will be
336 added as node inside all.
337  In the example above all the resulting slices had the same shape as the
338 divided volume (box). This is not always the case. For instance, dividing a
339 volume with TUBE shape on PHI axis will create equal slices having TUBESEG
340 shape. Other divisions can also create slices having shapes with different
341 dimensions, e.g. the division of a TRD1 volume on Z.
342  When positioning volumes inside slices, one can do it using the generic
343 volume family (e.g. slicey). This should be done as if the coordinate system
344 of the generic slice was the same as the one of the divided volume. The generic
345 slice in case of PHI division is centered with respect to X axis. If the
346 family contains slices of different sizes, any volume positioned inside should
347 fit into the smallest one.
348  Examples for specific divisions according to shape types can be found inside
349 shape classes.
350 
351 ~~~ {.cpp}
352  TGeoVolume::Divide(N, Xmin, Xmax, "X");
353 ~~~
354 
355  The GEANT3 option MANY is supported by TGeoVolumeOverlap class. An overlapping
356 volume is in fact a virtual container that does not represent a physical object.
357 It contains a list of nodes that are not its daughters but that must be checked
358 always before the container itself. This list must be defined by users and it
359 is checked and resolved in a priority order. Note that the feature is non-standard
360 to geometrical modelers and it was introduced just to support conversions of
361 GEANT3 geometries, therefore its extensive usage should be avoided.
362 */
363 
364 /** \class TGeoVolumeAssembly
365 \ingroup Geometry_classes
366 
367 Volume assemblies
368 
369 Assemblies a volumes that have neither a shape or a material/medium. Assemblies
370 behave exactly like normal volumes grouping several daughters together, but
371 the daughters can never extrude the assembly since this has no shape. However,
372 a bounding box and a voxelization structure are built for assemblies as for
373 normal volumes, so that navigation is still optimized. Assemblies are useful
374 for grouping hierarchically volumes which are otherwise defined in a flat
375 manner, but also to avoid clashes between container shapes.
376 To define an assembly one should just input a name, then start adding other
377 volumes (or volume assemblies) as content.
378 */
379 
380 #include <fstream>
381 #include <iomanip>
382 
383 #include "TString.h"
384 #include "TBuffer.h"
385 #include "TBrowser.h"
386 #include "TStyle.h"
387 #include "TH2F.h"
388 #include "TROOT.h"
389 #include "TEnv.h"
390 #include "TMap.h"
391 #include "TFile.h"
392 #include "TKey.h"
393 
394 #include "TGeoManager.h"
395 #include "TGeoNode.h"
396 #include "TGeoMatrix.h"
397 #include "TVirtualGeoPainter.h"
398 #include "TGeoVolume.h"
399 #include "TGeoShapeAssembly.h"
400 #include "TGeoScaledShape.h"
401 #include "TGeoCompositeShape.h"
402 #include "TGeoVoxelFinder.h"
403 #include "TGeoExtension.h"
404 
406 
408 
409 ////////////////////////////////////////////////////////////////////////////////
410 /// Create a dummy medium
411 
413 {
414  if (fgDummyMedium) return;
415  fgDummyMedium = new TGeoMedium();
416  fgDummyMedium->SetName("dummy");
417  TGeoMaterial *dummyMaterial = new TGeoMaterial();
418  dummyMaterial->SetName("dummy");
419  fgDummyMedium->SetMaterial(dummyMaterial);
420 }
421 
422 ////////////////////////////////////////////////////////////////////////////////
423 
425 {
427  if (fShape) fShape->ClearThreadData();
428 }
429 
430 ////////////////////////////////////////////////////////////////////////////////
431 
433 {
434  if (fFinder) fFinder->CreateThreadData(nthreads);
435  if (fShape) fShape->CreateThreadData(nthreads);
436 }
437 
438 ////////////////////////////////////////////////////////////////////////////////
439 
441 {
442  return fgDummyMedium;
443 }
444 
445 ////////////////////////////////////////////////////////////////////////////////
446 /// dummy constructor
447 
449 {
450  fNodes = 0;
451  fShape = 0;
452  fMedium = 0;
453  fFinder = 0;
454  fVoxels = 0;
456  fField = 0;
457  fOption = "";
458  fNumber = 0;
459  fNtotal = 0;
460  fRefCount = 0;
461  fUserExtension = 0;
462  fFWExtension = 0;
464 }
465 
466 ////////////////////////////////////////////////////////////////////////////////
467 /// default constructor
468 
469 TGeoVolume::TGeoVolume(const char *name, const TGeoShape *shape, const TGeoMedium *med)
470  :TNamed(name, "")
471 {
472  fName = fName.Strip();
473  fNodes = 0;
474  fShape = (TGeoShape*)shape;
475  if (fShape) {
477  Warning("Ctor", "volume %s has invalid shape", name);
478  }
479  if (!fShape->IsValid()) {
480  Fatal("ctor", "Shape of volume %s invalid. Aborting!", fName.Data());
481  }
482  }
483  fMedium = (TGeoMedium*)med;
485  fFinder = 0;
486  fVoxels = 0;
488  fField = 0;
489  fOption = "";
490  fNumber = 0;
491  fNtotal = 0;
492  fRefCount = 0;
493  fUserExtension = 0;
494  fFWExtension = 0;
497 }
498 
499 ////////////////////////////////////////////////////////////////////////////////
500 /// Destructor
501 
503 {
504  if (fNodes) {
506  fNodes->Delete();
507  }
508  delete fNodes;
509  }
511  if (fVoxels) delete fVoxels;
514 }
515 
516 ////////////////////////////////////////////////////////////////////////////////
517 /// How to browse a volume
518 
520 {
521  if (!b) return;
522 
523 // if (!GetNdaughters()) b->Add(this, GetName(), IsVisible());
524  TGeoVolume *daughter;
525  TString title;
526  for (Int_t i=0; i<GetNdaughters(); i++) {
527  daughter = GetNode(i)->GetVolume();
528  if(daughter->GetTitle()[0]) {
529  if (daughter->IsAssembly()) title.TString::Format("Assembly with %d daughter(s)",
530  daughter->GetNdaughters());
531  else if (daughter->GetFinder()) {
532  TString s1 = daughter->GetFinder()->ClassName();
533  s1.ReplaceAll("TGeoPattern","");
534  title.TString::Format("Volume having %s shape divided in %d %s slices",
535  daughter->GetShape()->ClassName(),daughter->GetNdaughters(), s1.Data());
536 
537  } else title.TString::Format("Volume with %s shape having %d daughter(s)",
538  daughter->GetShape()->ClassName(),daughter->GetNdaughters());
539  daughter->SetTitle(title.Data());
540  }
541  b->Add(daughter, daughter->GetName(), daughter->IsVisible());
542 // if (IsVisDaughters())
543 // b->AddCheckBox(daughter, daughter->IsVisible());
544 // else
545 // b->AddCheckBox(daughter, kFALSE);
546  }
547 }
548 
549 ////////////////////////////////////////////////////////////////////////////////
550 /// Computes the capacity of this [cm^3] as the capacity of its shape.
551 /// In case of assemblies, the capacity is computed as the sum of daughter's capacities.
552 
554 {
555  if (!IsAssembly()) return fShape->Capacity();
556  Double_t capacity = 0.0;
557  Int_t nd = GetNdaughters();
558  Int_t i;
559  for (i=0; i<nd; i++) capacity += GetNode(i)->GetVolume()->Capacity();
560  return capacity;
561 }
562 
563 ////////////////////////////////////////////////////////////////////////////////
564 /// Shoot nrays with random directions from starting point (startx, starty, startz)
565 /// in the reference frame of this volume. Track each ray until exiting geometry, then
566 /// shoot backwards from exiting point and compare boundary crossing points.
567 
568 void TGeoVolume::CheckGeometry(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) const
569 {
570  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
571  if (old_vol!=this) fGeoManager->SetTopVolume((TGeoVolume*)this);
572  else old_vol=0;
575  painter->CheckGeometry(nrays, startx, starty, startz);
576 }
577 
578 ////////////////////////////////////////////////////////////////////////////////
579 /// Overlap checking tool. Check for illegal overlaps within a limit OVLP.
580 /// Use option="s[number]" to force overlap checking by sampling volume with
581 /// [number] points.
582 ///
583 /// Ex:
584 /// ~~~ {.cpp}
585 /// myVol->CheckOverlaps(0.01, "s10000000"); // shoot 10000000 points
586 /// myVol->CheckOverlaps(0.01, "s"); // shoot the default value of 1e6 points
587 /// ~~~
588 
589 void TGeoVolume::CheckOverlaps(Double_t ovlp, Option_t *option) const
590 {
591  if (!GetNdaughters() || fFinder) return;
592  Bool_t sampling = kFALSE;
593  TString opt(option);
594  opt.ToLower();
595  if (opt.Contains("s")) sampling = kTRUE;
597  if (!sampling) fGeoManager->SetNsegments(80);
600 // Info("CheckOverlaps", "=== Checking overlaps for volume %s ===\n", GetName());
601  }
602  painter->CheckOverlaps(this, ovlp, option);
603 // if (sampling) return;
606  TObjArray *overlaps = fGeoManager->GetListOfOverlaps();
607  Int_t novlps = overlaps->GetEntriesFast();
608  TNamed *obj;
609  TString name;
610  for (Int_t i=0; i<novlps; i++) {
611  obj = (TNamed*)overlaps->At(i);
612  if (novlps<1000) name = TString::Format("ov%03d", i);
613  else name = TString::Format("ov%06d", i);
614  obj->SetName(name);
615  }
616  if (novlps) Info("CheckOverlaps", "Number of illegal overlaps/extrusions for volume %s: %d\n", GetName(), novlps);
617  }
618 }
619 
620 ////////////////////////////////////////////////////////////////////////////////
621 /// Tests for checking the shape navigation algorithms. See TGeoShape::CheckShape()
622 
623 void TGeoVolume::CheckShape(Int_t testNo, Int_t nsamples, Option_t *option)
624 {
625  fShape->CheckShape(testNo,nsamples,option);
626 }
627 
628 ////////////////////////////////////////////////////////////////////////////////
629 /// Clean data of the volume.
630 
632 {
633  ClearNodes();
634  ClearShape();
635 }
636 
637 ////////////////////////////////////////////////////////////////////////////////
638 /// Clear the shape of this volume from the list held by the current manager.
639 
641 {
643 }
644 
645 ////////////////////////////////////////////////////////////////////////////////
646 /// check for negative parameters in shapes.
647 
649 {
650  if (fShape->IsRunTimeShape()) {
651  Error("CheckShapes", "volume %s has run-time shape", GetName());
652  InspectShape();
653  return;
654  }
655  if (!fNodes) return;
657  TGeoNode *node = 0;
658  TGeoNode *new_node;
659  const TGeoShape *shape = 0;
660  TGeoVolume *old_vol;
661  for (Int_t i=0; i<nd; i++) {
662  node=(TGeoNode*)fNodes->At(i);
663  // check if node has name
664  if (!node->GetName()[0]) printf("Daughter %i of volume %s - NO NAME!!!\n",
665  i, GetName());
666  old_vol = node->GetVolume();
667  shape = old_vol->GetShape();
668  if (shape->IsRunTimeShape()) {
669 // printf(" Node %s/%s has shape with negative parameters. \n",
670 // GetName(), node->GetName());
671 // old_vol->InspectShape();
672  // make a copy of the node
673  new_node = node->MakeCopyNode();
674  if (!new_node) {
675  Fatal("CheckShapes", "Cannot make copy node for %s", node->GetName());
676  return;
677  }
678  TGeoShape *new_shape = shape->GetMakeRuntimeShape(fShape, node->GetMatrix());
679  if (!new_shape) {
680  Error("CheckShapes","cannot resolve runtime shape for volume %s/%s\n",
681  GetName(),old_vol->GetName());
682  continue;
683  }
684  TGeoVolume *new_volume = old_vol->MakeCopyVolume(new_shape);
685 // printf(" new volume %s shape params :\n", new_volume->GetName());
686 // new_volume->InspectShape();
687  new_node->SetVolume(new_volume);
688  // decouple the old node and put the new one instead
689  fNodes->AddAt(new_node, i);
690 // new_volume->CheckShapes();
691  }
692  }
693 }
694 
695 ////////////////////////////////////////////////////////////////////////////////
696 /// Count total number of subnodes starting from this volume, nlevels down
697 /// - option = 0 (default) - count only once per volume
698 /// - option = 1 - count every time
699 /// - option = 2 - count volumes on visible branches
700 /// - option = 3 - return maximum level counted already with option = 0
701 
703 {
704  static Int_t maxlevel = 0;
705  static Int_t nlev = 0;
706 
707  if (option<0 || option>3) option = 0;
708  Int_t visopt = 0;
709  Int_t nd = GetNdaughters();
710  Bool_t last = (!nlevels || !nd)?kTRUE:kFALSE;
711  switch (option) {
712  case 0:
713  if (fNtotal) return fNtotal;
714  case 1:
715  fNtotal = 1;
716  break;
717  case 2:
718  visopt = fGeoManager->GetVisOption();
719  if (!IsVisDaughters()) last = kTRUE;
720  switch (visopt) {
722  fNtotal = (IsVisible())?1:0;
723  break;
725  fNtotal = (IsVisible() && last)?1:0;
726  }
727  if (!IsVisibleDaughters()) return fNtotal;
728  break;
729  case 3:
730  return maxlevel;
731  }
732  if (last) return fNtotal;
733  if (gGeoManager->GetTopVolume() == this) {
734  maxlevel=0;
735  nlev = 0;
736  }
737  if (nlev>maxlevel) maxlevel = nlev;
738  TGeoNode *node;
739  TGeoVolume *vol;
740  nlev++;
741  for (Int_t i=0; i<nd; i++) {
742  node = GetNode(i);
743  vol = node->GetVolume();
744  fNtotal += vol->CountNodes(nlevels-1, option);
745  }
746  nlev--;
747  return fNtotal;
748 }
749 
750 ////////////////////////////////////////////////////////////////////////////////
751 /// Return TRUE if volume and all daughters are invisible.
752 
754 {
755  if (IsVisible()) return kFALSE;
756  Int_t nd = GetNdaughters();
757  for (Int_t i=0; i<nd; i++) if (GetNode(i)->GetVolume()->IsVisible()) return kFALSE;
758  return kTRUE;
759 }
760 
761 ////////////////////////////////////////////////////////////////////////////////
762 /// Make volume and each of it daughters (in)visible.
763 
765 {
766  SetAttVisibility(!flag);
767  Int_t nd = GetNdaughters();
768  TObjArray *list = new TObjArray(nd+1);
769  list->Add(this);
770  TGeoVolume *vol;
771  for (Int_t i=0; i<nd; i++) {
772  vol = GetNode(i)->GetVolume();
773  vol->SetAttVisibility(!flag);
774  list->Add(vol);
775  }
776  TIter next(gROOT->GetListOfBrowsers());
777  TBrowser *browser = 0;
778  while ((browser=(TBrowser*)next())) {
779  for (Int_t i=0; i<nd+1; i++) {
780  vol = (TGeoVolume*)list->At(i);
781  browser->CheckObjectItem(vol, !flag);
782  }
783  browser->Refresh();
784  }
785  delete list;
787 }
788 
789 ////////////////////////////////////////////////////////////////////////////////
790 /// Return TRUE if volume contains nodes
791 
793 {
794  return kTRUE;
795 }
796 
797 ////////////////////////////////////////////////////////////////////////////////
798 /// check if the visibility and attributes are the default ones
799 
801 {
802  if (!IsVisible()) return kFALSE;
803  if (GetLineColor() != gStyle->GetLineColor()) return kFALSE;
804  if (GetLineStyle() != gStyle->GetLineStyle()) return kFALSE;
805  if (GetLineWidth() != gStyle->GetLineWidth()) return kFALSE;
806  return kTRUE;
807 }
808 
809 ////////////////////////////////////////////////////////////////////////////////
810 /// True if this is the top volume of the geometry
811 
813 {
814  if (fGeoManager->GetTopVolume() == this) return kTRUE;
815  return kFALSE;
816 }
817 
818 ////////////////////////////////////////////////////////////////////////////////
819 /// Check if the painter is currently ray-tracing the content of this volume.
820 
822 {
823  return TGeoAtt::IsVisRaytrace();
824 }
825 
826 ////////////////////////////////////////////////////////////////////////////////
827 /// Inspect the material for this volume.
828 
830 {
831  GetMaterial()->Print();
832 }
833 
834 ////////////////////////////////////////////////////////////////////////////////
835 /// Import a volume from a file.
836 
837 TGeoVolume *TGeoVolume::Import(const char *filename, const char *name, Option_t * /*option*/)
838 {
839  if (!gGeoManager) gGeoManager = new TGeoManager("geometry","");
840  if (!filename) return 0;
841  TGeoVolume *volume = 0;
842  if (strstr(filename,".gdml")) {
843  // import from a gdml file
844  } else {
845  // import from a root file
847  TFile *f = TFile::Open(filename);
848  if (!f || f->IsZombie()) {
849  printf("Error: TGeoVolume::Import : Cannot open file %s\n", filename);
850  return 0;
851  }
852  if (name && name[0]) {
853  volume = (TGeoVolume*)f->Get(name);
854  } else {
855  TIter next(f->GetListOfKeys());
856  TKey *key;
857  while ((key = (TKey*)next())) {
858  if (strcmp(key->GetClassName(),"TGeoVolume") != 0) continue;
859  volume = (TGeoVolume*)key->ReadObj();
860  break;
861  }
862  }
863  delete f;
864  }
865  if (!volume) return NULL;
866  volume->RegisterYourself();
867  return volume;
868 }
869 
870 ////////////////////////////////////////////////////////////////////////////////
871 /// Export this volume to a file.
872 ///
873 /// - Case 1: root file or root/xml file
874 /// if filename end with ".root". The key will be named name
875 /// if filename end with ".xml" a root/xml file is produced.
876 ///
877 /// - Case 2: C++ script
878 /// if filename end with ".C"
879 ///
880 /// - Case 3: gdml file
881 /// if filename end with ".gdml"
882 ///
883 /// NOTE that to use this option, the PYTHONPATH must be defined like
884 /// export PYTHONPATH=$ROOTSYS/lib:$ROOTSYS/gdml
885 ///
886 
887 Int_t TGeoVolume::Export(const char *filename, const char *name, Option_t *option)
888 {
889  TString sfile(filename);
890  if (sfile.Contains(".C")) {
891  //Save volume as a C++ script
892  Info("Export","Exporting volume %s as C++ code", GetName());
893  SaveAs(filename, "");
894  return 1;
895  }
896  if (sfile.Contains(".gdml")) {
897  //Save geometry as a gdml file
898  Info("Export","Exporting %s as gdml code - not implemented yet", GetName());
899  return 0;
900  }
901  if (sfile.Contains(".root") || sfile.Contains(".xml")) {
902  //Save volume in a root file
903  Info("Export","Exporting %s as root file.", GetName());
904  TString opt(option);
905  if (!opt.Length()) opt = "recreate";
906  TFile *f = TFile::Open(filename,opt.Data());
907  if (!f || f->IsZombie()) {
908  Error("Export","Cannot open file");
909  return 0;
910  }
911  TString keyname(name);
912  if (keyname.IsNull()) keyname = GetName();
913  Int_t nbytes = Write(keyname);
914  delete f;
915  return nbytes;
916  }
917  return 0;
918 }
919 
920 ////////////////////////////////////////////////////////////////////////////////
921 /// Actualize matrix of node indexed <inode>
922 
923 void TGeoVolume::cd(Int_t inode) const
924 {
925  if (fFinder) fFinder->cd(inode-fFinder->GetDivIndex());
926 }
927 
928 ////////////////////////////////////////////////////////////////////////////////
929 /// Add a TGeoNode to the list of nodes. This is the usual method for adding
930 /// daughters inside the container volume.
931 
932 void TGeoVolume::AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t * /*option*/)
933 {
934  TGeoMatrix *matrix = mat;
935  if (matrix==0) matrix = gGeoIdentity;
936  else matrix->RegisterYourself();
937  if (!vol) {
938  Error("AddNode", "Volume is NULL");
939  return;
940  }
941  if (!vol->IsValid()) {
942  Error("AddNode", "Won't add node with invalid shape");
943  printf("### invalid volume was : %s\n", vol->GetName());
944  return;
945  }
946  if (!fNodes) fNodes = new TObjArray();
947 
948  if (fFinder) {
949  // volume already divided.
950  Error("AddNode", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no, GetName());
951  return;
952  }
953 
954  TGeoNodeMatrix *node = 0;
955  node = new TGeoNodeMatrix(vol, matrix);
956  node->SetMotherVolume(this);
957  fNodes->Add(node);
958  TString name = TString::Format("%s_%d", vol->GetName(), copy_no);
959 // if (fNodes->FindObject(name))
960 // Warning("AddNode", "Volume %s : added node %s with same name", GetName(), name.Data());
961  node->SetName(name);
962  node->SetNumber(copy_no);
963  fRefCount++;
964  vol->Grab();
965 }
966 
967 ////////////////////////////////////////////////////////////////////////////////
968 /// Add a division node to the list of nodes. The method is called by
969 /// TGeoVolume::Divide() for creating the division nodes.
970 
971 void TGeoVolume::AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset, Option_t * /*option*/)
972 {
973  if (!vol) {
974  Error("AddNodeOffset", "invalid volume");
975  return;
976  }
977  if (!vol->IsValid()) {
978  Error("AddNode", "Won't add node with invalid shape");
979  printf("### invalid volume was : %s\n", vol->GetName());
980  return;
981  }
982  if (!fNodes) fNodes = new TObjArray();
983  TGeoNode *node = new TGeoNodeOffset(vol, copy_no, offset);
984  node->SetMotherVolume(this);
985  fNodes->Add(node);
986  TString name = TString::Format("%s_%d", vol->GetName(), copy_no+1);
987  node->SetName(name);
988  node->SetNumber(copy_no+1);
989  vol->Grab();
990 }
991 
992 ////////////////////////////////////////////////////////////////////////////////
993 /// Add a TGeoNode to the list of nodes. This is the usual method for adding
994 /// daughters inside the container volume.
995 
997 {
998  if (!vol) {
999  Error("AddNodeOverlap", "Volume is NULL");
1000  return;
1001  }
1002  if (!vol->IsValid()) {
1003  Error("AddNodeOverlap", "Won't add node with invalid shape");
1004  printf("### invalid volume was : %s\n", vol->GetName());
1005  return;
1006  }
1007  if (vol->IsAssembly()) {
1008  Warning("AddNodeOverlap", "Declaring assembly %s as possibly overlapping inside %s not allowed. Using AddNode instead !",vol->GetName(),GetName());
1009  AddNode(vol, copy_no, mat, option);
1010  return;
1011  }
1012  TGeoMatrix *matrix = mat;
1013  if (matrix==0) matrix = gGeoIdentity;
1014  else matrix->RegisterYourself();
1015  if (!fNodes) fNodes = new TObjArray();
1016 
1017  if (fFinder) {
1018  // volume already divided.
1019  Error("AddNodeOverlap", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no, GetName());
1020  return;
1021  }
1022 
1023  TGeoNodeMatrix *node = new TGeoNodeMatrix(vol, matrix);
1024  node->SetMotherVolume(this);
1025  fNodes->Add(node);
1026  TString name = TString::Format("%s_%d", vol->GetName(), copy_no);
1027  if (fNodes->FindObject(name))
1028  Warning("AddNode", "Volume %s : added node %s with same name", GetName(), name.Data());
1029  node->SetName(name);
1030  node->SetNumber(copy_no);
1031  node->SetOverlapping();
1032  if (vol->GetMedium() == fMedium)
1033  node->SetVirtual();
1034  vol->Grab();
1035 }
1036 
1037 ////////////////////////////////////////////////////////////////////////////////
1038 /// Division a la G3. The volume will be divided along IAXIS (see shape classes), in NDIV
1039 /// slices, from START with given STEP. The division volumes will have medium number NUMED.
1040 /// If NUMED=0 they will get the medium number of the divided volume (this). If NDIV<=0,
1041 /// all range of IAXIS will be divided and the resulting number of divisions will be centered on
1042 /// IAXIS. If STEP<=0, the real STEP will be computed as the full range of IAXIS divided by NDIV.
1043 /// Options (case insensitive):
1044 /// - N - divide all range in NDIV cells (same effect as STEP<=0) (GSDVN in G3)
1045 /// - NX - divide range starting with START in NDIV cells (GSDVN2 in G3)
1046 /// - S - divide all range with given STEP. NDIV is computed and divisions will be centered
1047 /// in full range (same effect as NDIV<=0) (GSDVS, GSDVT in G3)
1048 /// - SX - same as DVS, but from START position. (GSDVS2, GSDVT2 in G3)
1049 
1050 TGeoVolume *TGeoVolume::Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed, Option_t *option)
1051 {
1052  if (fFinder) {
1053  // volume already divided.
1054  Fatal("Divide","volume %s already divided", GetName());
1055  return 0;
1056  }
1057  TString opt(option);
1058  opt.ToLower();
1059  TString stype = fShape->ClassName();
1060  if (!fNodes) fNodes = new TObjArray();
1061  Double_t xlo, xhi, range;
1062  range = fShape->GetAxisRange(iaxis, xlo, xhi);
1063  // for phi divisions correct the range
1064  if (!strcmp(fShape->GetAxisName(iaxis), "PHI")) {
1065  if ((start-xlo)<-1E-3) start+=360.;
1066  if (TGeoShape::IsSameWithinTolerance(range,360)) {
1067  xlo = start;
1068  xhi = start+range;
1069  }
1070  }
1071  if (range <=0) {
1072  InspectShape();
1073  Fatal("Divide", "cannot divide volume %s (%s) on %s axis", GetName(), stype.Data(), fShape->GetAxisName(iaxis));
1074  return 0;
1075  }
1076  if (ndiv<=0 || opt.Contains("s")) {
1077  if (step<=0) {
1078  Fatal("Divide", "invalid division type for volume %s : ndiv=%i, step=%g", GetName(), ndiv, step);
1079  return 0;
1080  }
1081  if (opt.Contains("x")) {
1082  if ((xlo-start)>1E-3 || (xhi-start)<-1E-3) {
1083  Fatal("Divide", "invalid START=%g for division on axis %s of volume %s. Range is (%g, %g)",
1084  start, fShape->GetAxisName(iaxis), GetName(), xlo, xhi);
1085  return 0;
1086  }
1087  xlo = start;
1088  range = xhi-xlo;
1089  }
1090  ndiv = Int_t((range+0.1*step)/step);
1091  Double_t ddx = range - ndiv*step;
1092  // always center the division in this case
1093  if (ddx>1E-3) Warning("Divide", "division of volume %s on %s axis (ndiv=%d) will be centered in the full range",
1094  GetName(), fShape->GetAxisName(iaxis), ndiv);
1095  start = xlo + 0.5*ddx;
1096  }
1097  if (step<=0 || opt.Contains("n")) {
1098  if (opt.Contains("x")) {
1099  if ((xlo-start)>1E-3 || (xhi-start)<-1E-3) {
1100  Fatal("Divide", "invalid START=%g for division on axis %s of volume %s. Range is (%g, %g)",
1101  start, fShape->GetAxisName(iaxis), GetName(), xlo, xhi);
1102  return 0;
1103  }
1104  xlo = start;
1105  range = xhi-xlo;
1106  }
1107  step = range/ndiv;
1108  start = xlo;
1109  }
1110 
1111  Double_t end = start+ndiv*step;
1112  if (((start-xlo)<-1E-3) || ((end-xhi)>1E-3)) {
1113  Fatal("Divide", "division of volume %s on axis %s exceed range (%g, %g)",
1114  GetName(), fShape->GetAxisName(iaxis), xlo, xhi);
1115  return 0;
1116  }
1117  TGeoVolume *voldiv = fShape->Divide(this, divname, iaxis, ndiv, start, step);
1118  if (numed) {
1119  TGeoMedium *medium = fGeoManager->GetMedium(numed);
1120  if (!medium) {
1121  Fatal("Divide", "invalid medium number %d for division volume %s", numed, divname);
1122  return voldiv;
1123  }
1124  voldiv->SetMedium(medium);
1125  if (medium->GetMaterial()) medium->GetMaterial()->SetUsed();
1126  }
1127  return voldiv;
1128 }
1129 
1130 ////////////////////////////////////////////////////////////////////////////////
1131 /// compute the closest distance of approach from point px,py to this volume
1132 
1134 {
1137  Int_t dist = 9999;
1138  if (!painter) return dist;
1139  dist = painter->DistanceToPrimitiveVol(this, px, py);
1140  return dist;
1141 }
1142 
1143 ////////////////////////////////////////////////////////////////////////////////
1144 /// draw top volume according to option
1145 
1147 {
1152  if (!IsVisContainers()) SetVisLeaves();
1153  if (option && option[0] > 0) {
1154  painter->DrawVolume(this, option);
1155  } else {
1156  painter->DrawVolume(this, gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
1157  }
1158 }
1159 
1160 ////////////////////////////////////////////////////////////////////////////////
1161 /// draw only this volume
1162 
1164 {
1165  if (IsAssembly()) {
1166  Info("DrawOnly", "Volume assemblies do not support this option.");
1167  return;
1168  }
1170  SetVisOnly();
1173  if (option && option[0] > 0) {
1174  painter->DrawVolume(this, option);
1175  } else {
1176  painter->DrawVolume(this, gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
1177  }
1178 }
1179 
1180 ////////////////////////////////////////////////////////////////////////////////
1181 /// Perform an extensive sampling to find which type of voxelization is
1182 /// most efficient.
1183 
1185 {
1186  printf("Optimizing volume %s ...\n", GetName());
1188  return painter->TestVoxels(this);
1189 }
1190 
1191 ////////////////////////////////////////////////////////////////////////////////
1192 /// Print volume info
1193 
1195 {
1196  printf("== Volume: %s type %s positioned %d times\n", GetName(), ClassName(), fRefCount);
1197  InspectShape();
1198  InspectMaterial();
1199 }
1200 
1201 ////////////////////////////////////////////////////////////////////////////////
1202 /// paint volume
1203 
1205 {
1207  painter->SetTopVolume(this);
1208 // painter->Paint(option);
1209  if (option && option[0] > 0) {
1210  painter->Paint(option);
1211  } else {
1212  painter->Paint(gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
1213  }
1214 }
1215 
1216 ////////////////////////////////////////////////////////////////////////////////
1217 /// Print the voxels for this volume.
1218 
1220 {
1221  if (fVoxels) fVoxels->Print();
1222 }
1223 
1224 ////////////////////////////////////////////////////////////////////////////////
1225 /// Recreate the content of the other volume without pointer copying. Voxels are
1226 /// ignored and supposed to be created in a later step via Voxelize.
1227 
1229 {
1230  Int_t nd = other->GetNdaughters();
1231  if (!nd) return;
1232  TGeoPatternFinder *finder = other->GetFinder();
1233  if (finder) {
1234  Int_t iaxis = finder->GetDivAxis();
1235  Int_t ndiv = finder->GetNdiv();
1236  Double_t start = finder->GetStart();
1237  Double_t step = finder->GetStep();
1238  Int_t numed = other->GetNode(0)->GetVolume()->GetMedium()->GetId();
1239  TGeoVolume *voldiv = Divide(other->GetNode(0)->GetVolume()->GetName(), iaxis, ndiv, start, step, numed);
1240  voldiv->ReplayCreation(other->GetNode(0)->GetVolume());
1241  return;
1242  }
1243  for (Int_t i=0; i<nd; i++) {
1244  TGeoNode *node = other->GetNode(i);
1245  if (node->IsOverlapping()) AddNodeOverlap(node->GetVolume(), node->GetNumber(), node->GetMatrix());
1246  else AddNode(node->GetVolume(), node->GetNumber(), node->GetMatrix());
1247  }
1248 }
1249 
1250 ////////////////////////////////////////////////////////////////////////////////
1251 /// print nodes
1252 
1254 {
1255  Int_t nd = GetNdaughters();
1256  for (Int_t i=0; i<nd; i++) {
1257  printf("%s\n", GetNode(i)->GetName());
1258  cd(i);
1259  GetNode(i)->GetMatrix()->Print();
1260  }
1261 }
1262 ////////////////////////////////////////////////////////////////////////////////
1263 /// Generate a lego plot fot the top volume, according to option.
1264 
1266  Int_t nphi, Double_t phimin, Double_t phimax,
1267  Double_t rmin, Double_t rmax, Option_t *option)
1268 {
1270  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
1271  if (old_vol!=this) fGeoManager->SetTopVolume(this);
1272  else old_vol=0;
1273  TH2F *hist = p->LegoPlot(ntheta, themin, themax, nphi, phimin, phimax, rmin, rmax, option);
1274  hist->Draw("lego1sph");
1275  return hist;
1276 }
1277 
1278 ////////////////////////////////////////////////////////////////////////////////
1279 /// Register the volume and all materials/media/matrices/shapes to the manager.
1280 
1282 {
1283  if (fGeoManager->GetListOfVolumes()->FindObject(this)) return;
1284  // Register volume
1285  fGeoManager->AddVolume(this);
1286  // Register shape
1288  if (fShape->IsComposite()) {
1290  comp->RegisterYourself();
1291  } else {
1293  }
1294  }
1295  // Register medium/material
1300  }
1301  // Register matrices for nodes.
1302  TGeoMatrix *matrix;
1303  TGeoNode *node;
1304  Int_t nd = GetNdaughters();
1305  Int_t i;
1306  for (i=0; i<nd; i++) {
1307  node = GetNode(i);
1308  matrix = node->GetMatrix();
1309  if (!matrix->IsRegistered()) matrix->RegisterYourself();
1310  else if (!fGeoManager->GetListOfMatrices()->FindObject(matrix)) {
1311  fGeoManager->GetListOfMatrices()->Add(matrix);
1312  }
1313  }
1314  // Call RegisterYourself recursively
1315  for (i=0; i<nd; i++) GetNode(i)->GetVolume()->RegisterYourself(option);
1316 }
1317 
1318 ////////////////////////////////////////////////////////////////////////////////
1319 /// Draw random points in the bounding box of this volume.
1320 
1322 {
1324  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
1325  if (old_vol!=this) fGeoManager->SetTopVolume(this);
1326  else old_vol=0;
1327  fGeoManager->RandomPoints(this, npoints, option);
1328  if (old_vol) fGeoManager->SetTopVolume(old_vol);
1329 }
1330 
1331 ////////////////////////////////////////////////////////////////////////////////
1332 /// Random raytracing method.
1333 
1334 void TGeoVolume::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm)
1335 {
1337  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
1338  if (old_vol!=this) fGeoManager->SetTopVolume(this);
1339  else old_vol=0;
1340  fGeoManager->RandomRays(nrays, startx, starty, startz, target_vol, check_norm);
1341  if (old_vol) fGeoManager->SetTopVolume(old_vol);
1342 }
1343 
1344 ////////////////////////////////////////////////////////////////////////////////
1345 /// Draw this volume with current settings and perform raytracing in the pad.
1346 
1348 {
1352  Bool_t drawn = (painter->GetDrawnVolume()==this)?kTRUE:kFALSE;
1353  if (!drawn) {
1354  painter->DrawVolume(this, "");
1356  painter->ModifiedPad();
1357  return;
1358  }
1360  painter->ModifiedPad();
1361 }
1362 
1363 ////////////////////////////////////////////////////////////////////////////////
1364 /// Save geometry having this as top volume as a C++ macro.
1365 
1366 void TGeoVolume::SaveAs(const char *filename, Option_t *option) const
1367 {
1368  if (!filename) return;
1369  std::ofstream out;
1370  out.open(filename, std::ios::out);
1371  if (out.bad()) {
1372  Error("SavePrimitive", "Bad file name: %s", filename);
1373  return;
1374  }
1375  if (fGeoManager->GetTopVolume() != this) fGeoManager->SetTopVolume((TGeoVolume*)this);
1376 
1377  TString fname(filename);
1378  Int_t ind = fname.Index(".");
1379  if (ind>0) fname.Remove(ind);
1380  out << "void "<<fname<<"() {" << std::endl;
1381  out << " gSystem->Load(\"libGeom\");" << std::endl;
1382  const UInt_t prec = TGeoManager::GetExportPrecision();
1383  out << std::setprecision(prec);
1384  ((TGeoVolume*)this)->SavePrimitive(out,option);
1385  out << "}" << std::endl;
1386 }
1387 
1388 ////////////////////////////////////////////////////////////////////////////////
1389 /// Connect user-defined extension to the volume. The volume "grabs" a copy, so
1390 /// the original object can be released by the producer. Release the previously
1391 /// connected extension if any.
1392 ///
1393 /// NOTE: This interface is intended for user extensions and is guaranteed not
1394 /// to be used by TGeo
1395 
1397 {
1399  fUserExtension = 0;
1400  if (ext) fUserExtension = ext->Grab();
1401 }
1402 
1403 ////////////////////////////////////////////////////////////////////////////////
1404 /// Connect framework defined extension to the volume. The volume "grabs" a copy,
1405 /// so the original object can be released by the producer. Release the previously
1406 /// connected extension if any.
1407 ///
1408 /// NOTE: This interface is intended for the use by TGeo and the users should
1409 /// NOT connect extensions using this method
1410 
1412 {
1414  fFWExtension = 0;
1415  if (ext) fFWExtension = ext->Grab();
1416 }
1417 
1418 ////////////////////////////////////////////////////////////////////////////////
1419 /// Get a copy of the user extension pointer. The user must call Release() on
1420 /// the copy pointer once this pointer is not needed anymore (equivalent to
1421 /// delete() after calling new())
1422 
1424 {
1425  if (fUserExtension) return fUserExtension->Grab();
1426  return 0;
1427 }
1428 
1429 ////////////////////////////////////////////////////////////////////////////////
1430 /// Get a copy of the framework extension pointer. The user must call Release() on
1431 /// the copy pointer once this pointer is not needed anymore (equivalent to
1432 /// delete() after calling new())
1433 
1435 {
1436  if (fFWExtension) return fFWExtension->Grab();
1437  return 0;
1438 }
1439 
1440 ////////////////////////////////////////////////////////////////////////////////
1441 /// Save a primitive as a C++ statement(s) on output stream "out".
1442 
1443 void TGeoVolume::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1444 {
1445  Int_t i,icopy;
1446  Int_t nd = GetNdaughters();
1447  TGeoVolume *dvol;
1448  TGeoNode *dnode;
1449  TGeoMatrix *matrix;
1450 
1451  // check if we need to save shape/volume
1452  Bool_t mustDraw = kFALSE;
1453  if (fGeoManager->GetGeomPainter()->GetTopVolume()==this) mustDraw = kTRUE;
1454  if (!option[0]) {
1456  out << " new TGeoManager(\"" << fGeoManager->GetName() << "\", \"" << fGeoManager->GetTitle() << "\");" << std::endl << std::endl;
1457 // if (mustDraw) out << " Bool_t mustDraw = kTRUE;" << std::endl;
1458 // else out << " Bool_t mustDraw = kFALSE;" << std::endl;
1459  out << " Double_t dx,dy,dz;" << std::endl;
1460  out << " Double_t dx1, dx2, dy1, dy2;" << std::endl;
1461  out << " Double_t vert[20], par[20];" << std::endl;
1462  out << " Double_t theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2;" << std::endl;
1463  out << " Double_t twist;" << std::endl;
1464  out << " Double_t origin[3];" << std::endl;
1465  out << " Double_t rmin, rmax, rmin1, rmax1, rmin2, rmax2;" << std::endl;
1466  out << " Double_t r, rlo, rhi;" << std::endl;
1467  out << " Double_t phi1, phi2;" << std::endl;
1468  out << " Double_t a,b;" << std::endl;
1469  out << " Double_t point[3], norm[3];" << std::endl;
1470  out << " Double_t rin, stin, rout, stout;" << std::endl;
1471  out << " Double_t thx, phx, thy, phy, thz, phz;" << std::endl;
1472  out << " Double_t alpha, theta1, theta2, phi1, phi2, dphi;" << std::endl;
1473  out << " Double_t tr[3], rot[9];" << std::endl;
1474  out << " Double_t z, density, radl, absl, w;" << std::endl;
1475  out << " Double_t lx,ly,lz,tx,ty,tz;" << std::endl;
1476  out << " Double_t xvert[50], yvert[50];" << std::endl;
1477  out << " Double_t zsect,x0,y0,scale0;" << std::endl;
1478  out << " Int_t nel, numed, nz, nedges, nvert;" << std::endl;
1479  out << " TGeoBoolNode *pBoolNode = 0;" << std::endl << std::endl;
1480  // first save materials/media
1481  out << " // MATERIALS, MIXTURES AND TRACKING MEDIA" << std::endl;
1482  SavePrimitive(out, "m");
1483  // then, save matrices
1484  out << std::endl << " // TRANSFORMATION MATRICES" << std::endl;
1485  SavePrimitive(out, "x");
1486  // save this volume and shape
1487  SavePrimitive(out, "s");
1488  out << std::endl << " // SET TOP VOLUME OF GEOMETRY" << std::endl;
1489  out << " gGeoManager->SetTopVolume(" << GetPointerName() << ");" << std::endl;
1490  // save daughters
1491  out << std::endl << " // SHAPES, VOLUMES AND GEOMETRICAL HIERARCHY" << std::endl;
1492  SavePrimitive(out, "d");
1493  out << std::endl << " // CLOSE GEOMETRY" << std::endl;
1494  out << " gGeoManager->CloseGeometry();" << std::endl;
1495  if (mustDraw) {
1496  if (!IsRaytracing()) out << " gGeoManager->GetTopVolume()->Draw();" << std::endl;
1497  else out << " gGeoManager->GetTopVolume()->Raytrace();" << std::endl;
1498  }
1499  return;
1500  }
1501  // check if we need to save shape/volume
1502  if (!strcmp(option, "s")) {
1503  // create the shape for this volume
1505  if (!IsAssembly()) {
1506  fShape->SavePrimitive(out,option);
1507  out << " // Volume: " << GetName() << std::endl;
1508  if (fMedium) out << " " << GetPointerName() << " = new TGeoVolume(\"" << GetName() << "\"," << fShape->GetPointerName() << ", "<< fMedium->GetPointerName() << ");" << std::endl;
1509  else out << " " << GetPointerName() << " = new TGeoVolume(\"" << GetName() << "\"," << fShape->GetPointerName() << ");" << std::endl;
1510 
1511  } else {
1512  out << " // Assembly: " << GetName() << std::endl;
1513  out << " " << GetPointerName() << " = new TGeoVolumeAssembly(\"" << GetName() << "\"" << ");" << std::endl;
1514  }
1515  if (fLineColor != 1) out << " " << GetPointerName() << "->SetLineColor(" << fLineColor << ");" << std::endl;
1516  if (fLineWidth != 1) out << " " << GetPointerName() << "->SetLineWidth(" << fLineWidth << ");" << std::endl;
1517  if (fLineStyle != 1) out << " " << GetPointerName() << "->SetLineStyle(" << fLineStyle << ");" << std::endl;
1518  if (!IsVisible() && !IsAssembly()) out << " " << GetPointerName() << "->SetVisibility(kFALSE);" << std::endl;
1519  if (!IsVisibleDaughters()) out << " " << GetPointerName() << "->VisibleDaughters(kFALSE);" << std::endl;
1520  if (IsVisContainers()) out << " " << GetPointerName() << "->SetVisContainers(kTRUE);" << std::endl;
1521  if (IsVisLeaves()) out << " " << GetPointerName() << "->SetVisLeaves(kTRUE);" << std::endl;
1523  }
1524  // check if we need to save the media
1525  if (!strcmp(option, "m")) {
1526  if (fMedium) fMedium->SavePrimitive(out,option);
1527  for (i=0; i<nd; i++) {
1528  dvol = GetNode(i)->GetVolume();
1529  dvol->SavePrimitive(out,option);
1530  }
1531  return;
1532  }
1533  // check if we need to save the matrices
1534  if (!strcmp(option, "x")) {
1535  if (fFinder) {
1536  dvol = GetNode(0)->GetVolume();
1537  dvol->SavePrimitive(out,option);
1538  return;
1539  }
1540  for (i=0; i<nd; i++) {
1541  dnode = GetNode(i);
1542  matrix = dnode->GetMatrix();
1543  if (!matrix->IsIdentity()) matrix->SavePrimitive(out,option);
1544  dnode->GetVolume()->SavePrimitive(out,option);
1545  }
1546  return;
1547  }
1548  // check if we need to save volume daughters
1549  if (!strcmp(option, "d")) {
1550  if (!nd) return;
1551  if (TestAttBit(TGeoAtt::kSaveNodesAtt)) return;
1553  if (fFinder) {
1554  // volume divided: generate volume->Divide()
1555  dnode = GetNode(0);
1556  dvol = dnode->GetVolume();
1557  out << " TGeoVolume *" << dvol->GetPointerName() << " = ";
1558  out << GetPointerName() << "->Divide(\"" << dvol->GetName() << "\", ";
1559  fFinder->SavePrimitive(out,option);
1560  if (fMedium != dvol->GetMedium()) {
1561  out << ", " << dvol->GetMedium()->GetId();
1562  }
1563  out << ");" << std::endl;
1564  dvol->SavePrimitive(out,"d");
1565  return;
1566  }
1567  for (i=0; i<nd; i++) {
1568  dnode = GetNode(i);
1569  dvol = dnode->GetVolume();
1570  dvol->SavePrimitive(out,"s");
1571  matrix = dnode->GetMatrix();
1572  icopy = dnode->GetNumber();
1573  // generate AddNode()
1574  out << " " << GetPointerName() << "->AddNode";
1575  if (dnode->IsOverlapping()) out << "Overlap";
1576  out << "(" << dvol->GetPointerName() << ", " << icopy;
1577  if (!matrix->IsIdentity()) out << ", " << matrix->GetPointerName();
1578  out << ");" << std::endl;
1579  }
1580  // Recursive loop to daughters
1581  for (i=0; i<nd; i++) {
1582  dnode = GetNode(i);
1583  dvol = dnode->GetVolume();
1584  dvol->SavePrimitive(out,"d");
1585  }
1586  }
1587 }
1588 
1589 ////////////////////////////////////////////////////////////////////////////////
1590 /// Reset SavePrimitive bits.
1591 
1593 {
1597 }
1598 
1599 ////////////////////////////////////////////////////////////////////////////////
1600 /// Execute mouse actions on this volume.
1601 
1603 {
1605  if (!painter) return;
1606  painter->ExecuteVolumeEvent(this, event, px, py);
1607 }
1608 
1609 ////////////////////////////////////////////////////////////////////////////////
1610 /// search a daughter inside the list of nodes
1611 
1613 {
1614  return ((TGeoNode*)fNodes->FindObject(name));
1615 }
1616 
1617 ////////////////////////////////////////////////////////////////////////////////
1618 /// Get the index of a daughter within check_list by providing the node pointer.
1619 
1620 Int_t TGeoVolume::GetNodeIndex(const TGeoNode *node, Int_t *check_list, Int_t ncheck) const
1621 {
1622  TGeoNode *current = 0;
1623  for (Int_t i=0; i<ncheck; i++) {
1624  current = (TGeoNode*)fNodes->At(check_list[i]);
1625  if (current==node) return check_list[i];
1626  }
1627  return -1;
1628 }
1629 
1630 ////////////////////////////////////////////////////////////////////////////////
1631 /// get index number for a given daughter
1632 
1634 {
1635  TGeoNode *current = 0;
1636  Int_t nd = GetNdaughters();
1637  if (!nd) return -1;
1638  for (Int_t i=0; i<nd; i++) {
1639  current = (TGeoNode*)fNodes->At(i);
1640  if (current==node) return i;
1641  }
1642  return -1;
1643 }
1644 
1645 ////////////////////////////////////////////////////////////////////////////////
1646 /// Get volume info for the browser.
1647 
1649 {
1650  TGeoVolume *vol = (TGeoVolume*)this;
1652  if (!painter) return 0;
1653  return (char*)painter->GetVolumeInfo(vol, px, py);
1654 }
1655 
1656 ////////////////////////////////////////////////////////////////////////////////
1657 /// Returns true if cylindrical voxelization is optimal.
1658 
1660 {
1661  Int_t nd = GetNdaughters();
1662  if (!nd) return kFALSE;
1663  Int_t id;
1664  Int_t ncyl = 0;
1665  TGeoNode *node;
1666  for (id=0; id<nd; id++) {
1667  node = (TGeoNode*)fNodes->At(id);
1668  ncyl += node->GetOptimalVoxels();
1669  }
1670  if (ncyl>(nd/2)) return kTRUE;
1671  return kFALSE;
1672 }
1673 
1674 ////////////////////////////////////////////////////////////////////////////////
1675 /// Provide a pointer name containing uid.
1676 
1678 {
1679  static TString name;
1680  name = TString::Format("p%s_%lx", GetName(), (ULong_t)this);
1681  return (char*)name.Data();
1682 }
1683 
1684 ////////////////////////////////////////////////////////////////////////////////
1685 /// Getter for optimization structure.
1686 
1688 {
1689  if (fVoxels && !fVoxels->IsInvalid()) return fVoxels;
1690  return NULL;
1691 }
1692 
1693 ////////////////////////////////////////////////////////////////////////////////
1694 /// Move perspective view focus to this volume
1695 
1697 {
1699  if (painter) painter->GrabFocus();
1700 }
1701 
1702 ////////////////////////////////////////////////////////////////////////////////
1703 /// Returns true if the volume is an assembly or a scaled assembly.
1704 
1706 {
1707  return fShape->IsAssembly();
1708 }
1709 
1710 ////////////////////////////////////////////////////////////////////////////////
1711 /// Clone this volume.
1712 /// build a volume with same name, shape and medium
1713 
1715 {
1716  TGeoVolume *vol = new TGeoVolume(GetName(), fShape, fMedium);
1717  Int_t i;
1718  // copy volume attributes
1719  vol->SetLineColor(GetLineColor());
1720  vol->SetLineStyle(GetLineStyle());
1721  vol->SetLineWidth(GetLineWidth());
1722  vol->SetFillColor(GetFillColor());
1723  vol->SetFillStyle(GetFillStyle());
1724  // copy other attributes
1725  Int_t nbits = 8*sizeof(UInt_t);
1726  for (i=0; i<nbits; i++)
1727  vol->SetAttBit(1<<i, TGeoAtt::TestAttBit(1<<i));
1728  for (i=14; i<24; i++)
1729  vol->SetBit(1<<i, TestBit(1<<i));
1730 
1731  // copy field
1732  vol->SetField(fField);
1733  // Set bits
1734  for (i=0; i<nbits; i++)
1735  vol->SetBit(1<<i, TObject::TestBit(1<<i));
1736  vol->SetBit(kVolumeClone);
1737  // copy nodes
1738 // CloneNodesAndConnect(vol);
1739  vol->MakeCopyNodes(this);
1740  // if volume is divided, copy finder
1741  vol->SetFinder(fFinder);
1742  // copy voxels
1743  TGeoVoxelFinder *voxels = 0;
1744  if (fVoxels) {
1745  voxels = new TGeoVoxelFinder(vol);
1746  vol->SetVoxelFinder(voxels);
1747  }
1748  // copy option, uid
1749  vol->SetOption(fOption);
1750  vol->SetNumber(fNumber);
1751  vol->SetNtotal(fNtotal);
1752  // copy extensions
1756  return vol;
1757 }
1758 
1759 ////////////////////////////////////////////////////////////////////////////////
1760 /// Clone the array of nodes.
1761 
1763 {
1764  if (!fNodes) return;
1765  TGeoNode *node;
1766  Int_t nd = fNodes->GetEntriesFast();
1767  if (!nd) return;
1768  // create new list of nodes
1769  TObjArray *list = new TObjArray(nd);
1770  // attach it to new volume
1771  newmother->SetNodes(list);
1772 // ((TObject*)newmother)->SetBit(kVolumeImportNodes);
1773  for (Int_t i=0; i<nd; i++) {
1774  //create copies of nodes and add them to list
1775  node = GetNode(i)->MakeCopyNode();
1776  if (!node) {
1777  Fatal("CloneNodesAndConnect", "cannot make copy node");
1778  return;
1779  }
1780  node->SetMotherVolume(newmother);
1781  list->Add(node);
1782  }
1783 }
1784 
1785 ////////////////////////////////////////////////////////////////////////////////
1786 /// make a new list of nodes and copy all nodes of other volume inside
1787 
1789 {
1790  Int_t nd = other->GetNdaughters();
1791  if (!nd) return;
1792  if (fNodes) {
1794  delete fNodes;
1795  }
1796  fNodes = new TObjArray();
1797  for (Int_t i=0; i<nd; i++) fNodes->Add(other->GetNode(i));
1799 }
1800 
1801 ////////////////////////////////////////////////////////////////////////////////
1802 /// make a copy of this volume
1803 /// build a volume with same name, shape and medium
1804 
1806 {
1807  TGeoVolume *vol = new TGeoVolume(GetName(), newshape, fMedium);
1808  // copy volume attributes
1809  vol->SetVisibility(IsVisible());
1810  vol->SetLineColor(GetLineColor());
1811  vol->SetLineStyle(GetLineStyle());
1812  vol->SetLineWidth(GetLineWidth());
1813  vol->SetFillColor(GetFillColor());
1814  vol->SetFillStyle(GetFillStyle());
1815  // copy field
1816  vol->SetField(fField);
1817  // if divided, copy division object
1818  if (fFinder) {
1819 // Error("MakeCopyVolume", "volume %s divided", GetName());
1820  vol->SetFinder(fFinder);
1821  }
1822  // Copy extensions
1825  CloneNodesAndConnect(vol);
1826 // ((TObject*)vol)->SetBit(kVolumeImportNodes);
1827  ((TObject*)vol)->SetBit(kVolumeClone);
1829  return vol;
1830 }
1831 
1832 ////////////////////////////////////////////////////////////////////////////////
1833 /// Make a copy of this volume which is reflected with respect to XY plane.
1834 
1835 TGeoVolume *TGeoVolume::MakeReflectedVolume(const char *newname) const
1836 {
1837  static TMap map(100);
1838  if (!fGeoManager->IsClosed()) {
1839  Error("MakeReflectedVolume", "Geometry must be closed.");
1840  return NULL;
1841  }
1842  TGeoVolume *vol = (TGeoVolume*)map.GetValue(this);
1843  if (vol) {
1844  if (newname && newname[0]) vol->SetName(newname);
1845  return vol;
1846  }
1847 // printf("Making reflection for volume: %s\n", GetName());
1848  vol = CloneVolume();
1849  if (!vol) {
1850  Fatal("MakeReflectedVolume", "Cannot clone volume %s\n", GetName());
1851  return 0;
1852  }
1853  map.Add((TObject*)this, vol);
1854  if (newname && newname[0]) vol->SetName(newname);
1855  delete vol->GetNodes();
1856  vol->SetNodes(NULL);
1858  CloneNodesAndConnect(vol);
1859  // The volume is now properly cloned, but with the same shape.
1860  // Reflect the shape (if any) and connect it.
1861  if (fShape) {
1862  TGeoShape *reflected_shape =
1863  TGeoScaledShape::MakeScaledShape("", fShape, new TGeoScale(1.,1.,-1.));
1864  vol->SetShape(reflected_shape);
1865  }
1866  // Reflect the daughters.
1867  Int_t nd = vol->GetNdaughters();
1868  if (!nd) return vol;
1869  TGeoNodeMatrix *node;
1870  TGeoMatrix *local, *local_cloned;
1871  TGeoVolume *new_vol;
1872  if (!vol->GetFinder()) {
1873  for (Int_t i=0; i<nd; i++) {
1874  node = (TGeoNodeMatrix*)vol->GetNode(i);
1875  local = node->GetMatrix();
1876 // printf("%s before\n", node->GetName());
1877 // local->Print();
1878  Bool_t reflected = local->IsReflection();
1879  local_cloned = new TGeoCombiTrans(*local);
1880  local_cloned->RegisterYourself();
1881  node->SetMatrix(local_cloned);
1882  if (!reflected) {
1883  // We need to reflect only the translation and propagate to daughters.
1884  // H' = Sz * H * Sz
1885  local_cloned->ReflectZ(kTRUE);
1886  local_cloned->ReflectZ(kFALSE);
1887 // printf("%s after\n", node->GetName());
1888 // node->GetMatrix()->Print();
1889  new_vol = node->GetVolume()->MakeReflectedVolume();
1890  node->SetVolume(new_vol);
1891  continue;
1892  }
1893  // The next daughter is already reflected, so reflect on Z everything and stop
1894  local_cloned->ReflectZ(kTRUE); // rot + tr
1895 // printf("%s already reflected... After:\n", node->GetName());
1896 // node->GetMatrix()->Print();
1897  }
1898  if (vol->GetVoxels()) vol->GetVoxels()->Voxelize();
1899  return vol;
1900  }
1901  // Volume is divided, so we have to reflect the division.
1902 // printf(" ... divided %s\n", fFinder->ClassName());
1903  TGeoPatternFinder *new_finder = fFinder->MakeCopy(kTRUE);
1904  if (!new_finder) {
1905  Fatal("MakeReflectedVolume", "Could not copy finder for volume %s", GetName());
1906  return 0;
1907  }
1908  new_finder->SetVolume(vol);
1909  vol->SetFinder(new_finder);
1910  TGeoNodeOffset *nodeoff;
1911  new_vol = 0;
1912  for (Int_t i=0; i<nd; i++) {
1913  nodeoff = (TGeoNodeOffset*)vol->GetNode(i);
1914  nodeoff->SetFinder(new_finder);
1915  new_vol = nodeoff->GetVolume()->MakeReflectedVolume();
1916  nodeoff->SetVolume(new_vol);
1917  }
1918  return vol;
1919 }
1920 
1921 ////////////////////////////////////////////////////////////////////////////////
1922 /// Set this volume as the TOP one (the whole geometry starts from here)
1923 
1925 {
1926  fGeoManager->SetTopVolume(this);
1927 }
1928 
1929 ////////////////////////////////////////////////////////////////////////////////
1930 /// Set the current tracking point.
1931 
1933 {
1935 }
1936 
1937 ////////////////////////////////////////////////////////////////////////////////
1938 /// set the shape associated with this volume
1939 
1941 {
1942  if (!shape) {
1943  Error("SetShape", "No shape");
1944  return;
1945  }
1946  fShape = (TGeoShape*)shape;
1947 }
1948 
1949 ////////////////////////////////////////////////////////////////////////////////
1950 /// sort nodes by decreasing volume of the bounding box. ONLY nodes comes first,
1951 /// then overlapping nodes and finally division nodes.
1952 
1954 {
1955  if (!Valid()) {
1956  Error("SortNodes", "Bounding box not valid");
1957  return;
1958  }
1959  Int_t nd = GetNdaughters();
1960 // printf("volume : %s, nd=%i\n", GetName(), nd);
1961  if (!nd) return;
1962  if (fFinder) return;
1963 // printf("Nodes for %s\n", GetName());
1964  Int_t id = 0;
1965  TGeoNode *node = 0;
1966  TObjArray *nodes = new TObjArray(nd);
1967  Int_t inode = 0;
1968  // first put ONLY's
1969  for (id=0; id<nd; id++) {
1970  node = GetNode(id);
1971  if (node->InheritsFrom(TGeoNodeOffset::Class()) || node->IsOverlapping()) continue;
1972  nodes->Add(node);
1973 // printf("inode %i ONLY\n", inode);
1974  inode++;
1975  }
1976  // second put overlapping nodes
1977  for (id=0; id<nd; id++) {
1978  node = GetNode(id);
1979  if (node->InheritsFrom(TGeoNodeOffset::Class()) || (!node->IsOverlapping())) continue;
1980  nodes->Add(node);
1981 // printf("inode %i MANY\n", inode);
1982  inode++;
1983  }
1984  // third put the divided nodes
1985  if (fFinder) {
1986  fFinder->SetDivIndex(inode);
1987  for (id=0; id<nd; id++) {
1988  node = GetNode(id);
1989  if (!node->InheritsFrom(TGeoNodeOffset::Class())) continue;
1990  nodes->Add(node);
1991 // printf("inode %i DIV\n", inode);
1992  inode++;
1993  }
1994  }
1995  if (inode != nd) printf(" volume %s : number of nodes does not match!!!\n", GetName());
1996  delete fNodes;
1997  fNodes = nodes;
1998 }
1999 
2000 ////////////////////////////////////////////////////////////////////////////////
2001 /// Stream an object of class TGeoVolume.
2002 
2003 void TGeoVolume::Streamer(TBuffer &R__b)
2004 {
2005  if (R__b.IsReading()) {
2006  R__b.ReadClassBuffer(TGeoVolume::Class(), this);
2007  if (fVoxels && fVoxels->IsInvalid()) Voxelize("");
2008  } else {
2009  if (!fVoxels) {
2010  R__b.WriteClassBuffer(TGeoVolume::Class(), this);
2011  } else {
2012  if (!fGeoManager->IsStreamingVoxels()) {
2013  TGeoVoxelFinder *voxels = fVoxels;
2014  fVoxels = 0;
2015  R__b.WriteClassBuffer(TGeoVolume::Class(), this);
2016  fVoxels = voxels;
2017  } else {
2018  R__b.WriteClassBuffer(TGeoVolume::Class(), this);
2019  }
2020  }
2021  }
2022 }
2023 
2024 ////////////////////////////////////////////////////////////////////////////////
2025 /// Set the current options (none implemented)
2026 
2027 void TGeoVolume::SetOption(const char *option)
2028 {
2029  fOption = option;
2030 }
2031 
2032 ////////////////////////////////////////////////////////////////////////////////
2033 /// Set the line color.
2034 
2036 {
2037  TAttLine::SetLineColor(lcolor);
2038 }
2039 
2040 ////////////////////////////////////////////////////////////////////////////////
2041 /// Set the line style.
2042 
2044 {
2045  TAttLine::SetLineStyle(lstyle);
2046 }
2047 
2048 ////////////////////////////////////////////////////////////////////////////////
2049 /// Set the line width.
2050 
2052 {
2053  TAttLine::SetLineWidth(lwidth);
2054 }
2055 
2056 ////////////////////////////////////////////////////////////////////////////////
2057 /// get the pointer to a daughter node
2058 
2059 TGeoNode *TGeoVolume::GetNode(const char *name) const
2060 {
2061  if (!fNodes) return 0;
2062  TGeoNode *node = (TGeoNode *)fNodes->FindObject(name);
2063  return node;
2064 }
2065 
2066 ////////////////////////////////////////////////////////////////////////////////
2067 /// get the total size in bytes for this volume
2068 
2070 {
2071  Int_t count = 28+2+6+4+0; // TNamed+TGeoAtt+TAttLine+TAttFill+TAtt3D
2072  count += fName.Capacity() + fTitle.Capacity(); // name+title
2073  count += 7*sizeof(char*); // fShape + fMedium + fFinder + fField + fNodes + 2 extensions
2074  count += fOption.Capacity(); // fOption
2075  if (fShape) count += fShape->GetByteCount();
2076  if (fFinder) count += fFinder->GetByteCount();
2077  if (fNodes) {
2078  count += 32 + 4*fNodes->GetEntries(); // TObjArray
2079  TIter next(fNodes);
2080  TGeoNode *node;
2081  while ((node=(TGeoNode*)next())) count += node->GetByteCount();
2082  }
2083  return count;
2084 }
2085 
2086 ////////////////////////////////////////////////////////////////////////////////
2087 /// loop all nodes marked as overlaps and find overlapping brothers
2088 
2090 {
2091  if (!Valid()) {
2092  Error("FindOverlaps","Bounding box not valid");
2093  return;
2094  }
2095  if (!fVoxels) return;
2096  Int_t nd = GetNdaughters();
2097  if (!nd) return;
2098  TGeoNode *node=0;
2099  Int_t inode = 0;
2100  for (inode=0; inode<nd; inode++) {
2101  node = GetNode(inode);
2102  if (!node->IsOverlapping()) continue;
2103  fVoxels->FindOverlaps(inode);
2104  }
2105 }
2106 
2107 ////////////////////////////////////////////////////////////////////////////////
2108 /// Remove an existing daughter.
2109 
2111 {
2112  if (!fNodes || !fNodes->GetEntriesFast()) return;
2113  if (!fNodes->Remove(node)) return;
2114  fNodes->Compress();
2115  if (fVoxels) fVoxels->SetNeedRebuild();
2116  if (IsAssembly()) fShape->ComputeBBox();
2117 }
2118 
2119 ////////////////////////////////////////////////////////////////////////////////
2120 /// Replace an existing daughter with a new volume having the same name but
2121 /// possibly a new shape, position or medium. Not allowed for positioned assemblies.
2122 /// For division cells, the new shape/matrix are ignored.
2123 
2125 {
2126  Int_t ind = GetIndex(nodeorig);
2127  if (ind < 0) return NULL;
2128  TGeoVolume *oldvol = nodeorig->GetVolume();
2129  if (oldvol->IsAssembly()) {
2130  Error("ReplaceNode", "Cannot replace node %s since it is an assembly", nodeorig->GetName());
2131  return NULL;
2132  }
2133  TGeoShape *shape = oldvol->GetShape();
2134  if (newshape && !nodeorig->IsOffset()) shape = newshape;
2135  TGeoMedium *med = oldvol->GetMedium();
2136  if (newmed) med = newmed;
2137  // Make a new volume
2138  TGeoVolume *vol = new TGeoVolume(oldvol->GetName(), shape, med);
2139  // copy volume attributes
2140  vol->SetVisibility(oldvol->IsVisible());
2141  vol->SetLineColor(oldvol->GetLineColor());
2142  vol->SetLineStyle(oldvol->GetLineStyle());
2143  vol->SetLineWidth(oldvol->GetLineWidth());
2144  vol->SetFillColor(oldvol->GetFillColor());
2145  vol->SetFillStyle(oldvol->GetFillStyle());
2146  // copy field
2147  vol->SetField(oldvol->GetField());
2148  // Make a copy of the node
2149  TGeoNode *newnode = nodeorig->MakeCopyNode();
2150  if (!newnode) {
2151  Fatal("ReplaceNode", "Cannot make copy node for %s", nodeorig->GetName());
2152  return 0;
2153  }
2154  // Change the volume for the new node
2155  newnode->SetVolume(vol);
2156  // Replace the matrix
2157  if (newpos && !nodeorig->IsOffset()) {
2158  TGeoNodeMatrix *nodemat = (TGeoNodeMatrix*)newnode;
2159  nodemat->SetMatrix(newpos);
2160  }
2161  // Replace nodeorig with new one
2162  fNodes->RemoveAt(ind);
2163  fNodes->AddAt(newnode, ind);
2164  if (fVoxels) fVoxels->SetNeedRebuild();
2165  if (IsAssembly()) fShape->ComputeBBox();
2166  return newnode;
2167 }
2168 
2169 ////////////////////////////////////////////////////////////////////////////////
2170 /// Select this volume as matching an arbitrary criteria. The volume is added to
2171 /// a static list and the flag TGeoVolume::kVolumeSelected is set. All flags need
2172 /// to be reset at the end by calling the method with CLEAR=true. This will also clear
2173 /// the list.
2174 
2176 {
2177  static TObjArray array(256);
2178  static Int_t len = 0;
2179  Int_t i;
2180  TObject *vol;
2181  if (clear) {
2182  for (i=0; i<len; i++) {
2183  vol = array.At(i);
2185  }
2186  array.Clear();
2187  len = 0;
2188  return;
2189  }
2191  array.AddAtAndExpand(this, len++);
2192 }
2193 
2194 ////////////////////////////////////////////////////////////////////////////////
2195 /// set visibility of this volume
2196 
2198 {
2202  TSeqCollection *brlist = gROOT->GetListOfBrowsers();
2203  TIter next(brlist);
2204  TBrowser *browser = 0;
2205  while ((browser=(TBrowser*)next())) {
2206  browser->CheckObjectItem(this, vis);
2207  browser->Refresh();
2208  }
2209 }
2210 
2211 ////////////////////////////////////////////////////////////////////////////////
2212 /// Set visibility for containers.
2213 
2215 {
2217  if (fGeoManager && fGeoManager->IsClosed()) {
2220  }
2221 }
2222 
2223 ////////////////////////////////////////////////////////////////////////////////
2224 /// Set visibility for leaves.
2225 
2227 {
2228  TGeoAtt::SetVisLeaves(flag);
2229  if (fGeoManager && fGeoManager->IsClosed()) {
2232  }
2233 }
2234 
2235 ////////////////////////////////////////////////////////////////////////////////
2236 /// Set visibility for leaves.
2237 
2239 {
2240  if (IsAssembly()) return;
2241  TGeoAtt::SetVisOnly(flag);
2242  if (fGeoManager && fGeoManager->IsClosed()) {
2245  }
2246 }
2247 
2248 ////////////////////////////////////////////////////////////////////////////////
2249 /// Check if the shape of this volume is valid.
2250 
2252 {
2253  return fShape->IsValidBox();
2254 }
2255 
2256 ////////////////////////////////////////////////////////////////////////////////
2257 /// Find a daughter node having VOL as volume and fill TGeoManager::fHMatrix
2258 /// with its global matrix.
2259 
2261 {
2262  if (vol == this) return kTRUE;
2263  Int_t nd = GetNdaughters();
2264  if (!nd) return kFALSE;
2265  TGeoHMatrix *global = fGeoManager->GetHMatrix();
2266  if (!global) return kFALSE;
2267  TGeoNode *dnode;
2268  TGeoVolume *dvol;
2269  TGeoMatrix *local;
2270  Int_t i;
2271  for (i=0; i<nd; i++) {
2272  dnode = GetNode(i);
2273  dvol = dnode->GetVolume();
2274  if (dvol == vol) {
2275  local = dnode->GetMatrix();
2276  global->MultiplyLeft(local);
2277  return kTRUE;
2278  }
2279  }
2280  for (i=0; i<nd; i++) {
2281  dnode = GetNode(i);
2282  dvol = dnode->GetVolume();
2283  if (dvol->FindMatrixOfDaughterVolume(vol)) return kTRUE;
2284  }
2285  return kFALSE;
2286 }
2287 
2288 ////////////////////////////////////////////////////////////////////////////////
2289 /// set visibility for daughters
2290 
2292 {
2293  SetVisDaughters(vis);
2296 }
2297 
2298 ////////////////////////////////////////////////////////////////////////////////
2299 /// build the voxels for this volume
2300 
2302 {
2303  if (!Valid()) {
2304  Error("Voxelize", "Bounding box not valid");
2305  return;
2306  }
2307  // do not voxelize divided volumes
2308  if (fFinder) return;
2309  // or final leaves
2310  Int_t nd = GetNdaughters();
2311  if (!nd) return;
2312  // If this is an assembly, re-compute bounding box
2313  if (IsAssembly()) fShape->ComputeBBox();
2314  // delete old voxelization if any
2315  if (fVoxels) {
2316  if (!TObject::TestBit(kVolumeClone)) delete fVoxels;
2317  fVoxels = 0;
2318  }
2319  // Create the voxels structure
2320  fVoxels = new TGeoVoxelFinder(this);
2321  fVoxels->Voxelize(option);
2322  if (fVoxels) {
2323  if (fVoxels->IsInvalid()) {
2324  delete fVoxels;
2325  fVoxels = 0;
2326  }
2327  }
2328 }
2329 
2330 ////////////////////////////////////////////////////////////////////////////////
2331 /// Estimate the weight of a volume (in kg) with SIGMA(M)/M better than PRECISION.
2332 /// Option can contain : v - verbose, a - analytical (default)
2333 
2335 {
2337  if (top != this) fGeoManager->SetTopVolume(this);
2338  else top = 0;
2339  Double_t weight = fGeoManager->Weight(precision, option);
2340  if (top) fGeoManager->SetTopVolume(top);
2341  return weight;
2342 }
2343 
2344 ////////////////////////////////////////////////////////////////////////////////
2345 /// Analytical computation of the weight.
2346 
2348 {
2349  Double_t capacity = Capacity();
2350  Double_t weight = 0.0;
2351  Int_t i;
2352  Int_t nd = GetNdaughters();
2353  TGeoVolume *daughter;
2354  for (i=0; i<nd; i++) {
2355  daughter = GetNode(i)->GetVolume();
2356  weight += daughter->WeightA();
2357  capacity -= daughter->Capacity();
2358  }
2359  Double_t density = 0.0;
2360  if (!IsAssembly()) {
2361  if (fMedium) density = fMedium->GetMaterial()->GetDensity();
2362  if (density<0.01) density = 0.0; // do not weight gases
2363  }
2364  weight += 0.001*capacity * density; //[kg]
2365  return weight;
2366 }
2367 
2369 
2370 
2371 ////////////////////////////////////////////////////////////////////////////////
2372 /// dummy constructor
2373 
2375 {
2376  fVolumes = 0;
2377  fDivision = 0;
2378  fNumed = 0;
2379  fNdiv = 0;
2380  fAxis = 0;
2381  fStart = 0;
2382  fStep = 0;
2383  fAttSet = kFALSE;
2385 }
2386 
2387 ////////////////////////////////////////////////////////////////////////////////
2388 /// default constructor
2389 
2391 {
2392  fVolumes = new TObjArray();
2393  fDivision = 0;
2394  fNumed = 0;
2395  fNdiv = 0;
2396  fAxis = 0;
2397  fStart = 0;
2398  fStep = 0;
2399  fAttSet = kFALSE;
2401  SetName(name);
2402  SetMedium(med);
2403  fGeoManager->AddVolume(this);
2404 // printf("--- volume multi %s created\n", name);
2405 }
2406 
2407 ////////////////////////////////////////////////////////////////////////////////
2408 /// Destructor
2409 
2411 {
2412  if (fVolumes) delete fVolumes;
2413 }
2414 
2415 ////////////////////////////////////////////////////////////////////////////////
2416 /// Add a volume with valid shape to the list of volumes. Copy all existing nodes
2417 /// to this volume
2418 
2420 {
2421  Int_t idx = fVolumes->GetEntriesFast();
2422  fVolumes->AddAtAndExpand(vol,idx);
2423  vol->SetUniqueID(idx+1);
2424  TGeoVolumeMulti *div;
2425  TGeoVolume *cell;
2426  if (fDivision) {
2428  if (!div) {
2429  Fatal("AddVolume", "Cannot divide volume %s", vol->GetName());
2430  return;
2431  }
2432  for (Int_t i=0; i<div->GetNvolumes(); i++) {
2433  cell = div->GetVolume(i);
2434  fDivision->AddVolume(cell);
2435  }
2436  }
2437  if (fNodes) {
2438  Int_t nd = fNodes->GetEntriesFast();
2439  for (Int_t id=0; id<nd; id++) {
2440  TGeoNode *node = (TGeoNode*)fNodes->At(id);
2441  Bool_t many = node->IsOverlapping();
2442  if (many) vol->AddNodeOverlap(node->GetVolume(), node->GetNumber(), node->GetMatrix());
2443  else vol->AddNode(node->GetVolume(), node->GetNumber(), node->GetMatrix());
2444  }
2445  }
2446 // vol->MakeCopyNodes(this);
2447 }
2448 
2449 
2450 ////////////////////////////////////////////////////////////////////////////////
2451 /// Add a new node to the list of nodes. This is the usual method for adding
2452 /// daughters inside the container volume.
2453 
2455 {
2456  TGeoVolume::AddNode(vol, copy_no, mat, option);
2457  Int_t nvolumes = fVolumes->GetEntriesFast();
2458  TGeoVolume *volume = 0;
2459  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2460  volume = GetVolume(ivo);
2461  volume->SetLineColor(GetLineColor());
2462  volume->SetLineStyle(GetLineStyle());
2463  volume->SetLineWidth(GetLineWidth());
2464  volume->SetVisibility(IsVisible());
2465  volume->AddNode(vol, copy_no, mat, option);
2466  }
2467 // printf("--- vmulti %s : node %s added to %i components\n", GetName(), vol->GetName(), nvolumes);
2468 }
2469 
2470 ////////////////////////////////////////////////////////////////////////////////
2471 /// Add a new node to the list of nodes, This node is possibly overlapping with other
2472 /// daughters of the volume or extruding the volume.
2473 
2475 {
2476  TGeoVolume::AddNodeOverlap(vol, copy_no, mat, option);
2477  Int_t nvolumes = fVolumes->GetEntriesFast();
2478  TGeoVolume *volume = 0;
2479  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2480  volume = GetVolume(ivo);
2481  volume->SetLineColor(GetLineColor());
2482  volume->SetLineStyle(GetLineStyle());
2483  volume->SetLineWidth(GetLineWidth());
2484  volume->SetVisibility(IsVisible());
2485  volume->AddNodeOverlap(vol, copy_no, mat, option);
2486  }
2487 // printf("--- vmulti %s : node ovlp %s added to %i components\n", GetName(), vol->GetName(), nvolumes);
2488 }
2489 
2490 ////////////////////////////////////////////////////////////////////////////////
2491 /// Returns the last shape.
2492 
2494 {
2496  if (!vol) return 0;
2497  return vol->GetShape();
2498 }
2499 
2500 ////////////////////////////////////////////////////////////////////////////////
2501 /// division of multiple volumes
2502 
2503 TGeoVolume *TGeoVolumeMulti::Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed, const char *option)
2504 {
2505  if (fDivision) {
2506  Error("Divide", "volume %s already divided", GetName());
2507  return 0;
2508  }
2509  Int_t nvolumes = fVolumes->GetEntriesFast();
2510  TGeoMedium *medium = fMedium;
2511  if (numed) {
2512  medium = fGeoManager->GetMedium(numed);
2513  if (!medium) {
2514  Error("Divide", "Invalid medium number %d for division volume %s", numed, divname);
2515  medium = fMedium;
2516  }
2517  }
2518  if (!nvolumes) {
2519  // this is a virtual volume
2520  fDivision = new TGeoVolumeMulti(divname, medium);
2521  fNumed = medium->GetId();
2522  fOption = option;
2523  fAxis = iaxis;
2524  fNdiv = ndiv;
2525  fStart = start;
2526  fStep = step;
2527  // nothing else to do at this stage
2528  return fDivision;
2529  }
2530  TGeoVolume *vol = 0;
2531  fDivision = new TGeoVolumeMulti(divname, medium);
2532  if (medium) fNumed = medium->GetId();
2533  fOption = option;
2534  fAxis = iaxis;
2535  fNdiv = ndiv;
2536  fStart = start;
2537  fStep = step;
2538  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2539  vol = GetVolume(ivo);
2540  vol->SetLineColor(GetLineColor());
2541  vol->SetLineStyle(GetLineStyle());
2542  vol->SetLineWidth(GetLineWidth());
2543  vol->SetVisibility(IsVisible());
2544  fDivision->AddVolume(vol->Divide(divname,iaxis,ndiv,start,step, numed, option));
2545  }
2546 // printf("--- volume multi %s (%i volumes) divided\n", GetName(), nvolumes);
2547  if (numed) fDivision->SetMedium(medium);
2548  return fDivision;
2549 }
2550 
2551 ////////////////////////////////////////////////////////////////////////////////
2552 /// Make a copy of this volume
2553 /// build a volume with same name, shape and medium
2554 
2556 {
2557  TGeoVolume *vol = new TGeoVolume(GetName(), newshape, fMedium);
2558  Int_t i=0;
2559  // copy volume attributes
2560  vol->SetVisibility(IsVisible());
2561  vol->SetLineColor(GetLineColor());
2562  vol->SetLineStyle(GetLineStyle());
2563  vol->SetLineWidth(GetLineWidth());
2564  vol->SetFillColor(GetFillColor());
2565  vol->SetFillStyle(GetFillStyle());
2566  // copy field
2567  vol->SetField(fField);
2568  // Copy extensions
2571  // if divided, copy division object
2572 // if (fFinder) {
2573 // Error("MakeCopyVolume", "volume %s divided", GetName());
2574 // vol->SetFinder(fFinder);
2575 // }
2576  if (fDivision) {
2577  TGeoVolume *cell;
2579  if (!div) {
2580  Fatal("MakeCopyVolume", "Cannot divide volume %s", vol->GetName());
2581  return 0;
2582  }
2583  for (i=0; i<div->GetNvolumes(); i++) {
2584  cell = div->GetVolume(i);
2585  fDivision->AddVolume(cell);
2586  }
2587  }
2588 
2589  if (!fNodes) return vol;
2590  TGeoNode *node;
2591  Int_t nd = fNodes->GetEntriesFast();
2592  if (!nd) return vol;
2593  // create new list of nodes
2594  TObjArray *list = new TObjArray();
2595  // attach it to new volume
2596  vol->SetNodes(list);
2597  ((TObject*)vol)->SetBit(kVolumeImportNodes);
2598  for (i=0; i<nd; i++) {
2599  //create copies of nodes and add them to list
2600  node = GetNode(i)->MakeCopyNode();
2601  if (!node) {
2602  Fatal("MakeCopyNode", "cannot make copy node for daughter %d of %s", i, GetName());
2603  return 0;
2604  }
2605  node->SetMotherVolume(vol);
2606  list->Add(node);
2607  }
2608  return vol;
2609 }
2610 
2611 ////////////////////////////////////////////////////////////////////////////////
2612 /// Set the line color for all components.
2613 
2615 {
2616  TGeoVolume::SetLineColor(lcolor);
2617  Int_t nvolumes = fVolumes->GetEntriesFast();
2618  TGeoVolume *vol = 0;
2619  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2620  vol = GetVolume(ivo);
2621  vol->SetLineColor(lcolor);
2622  }
2623 }
2624 
2625 ////////////////////////////////////////////////////////////////////////////////
2626 /// Set the line style for all components.
2627 
2629 {
2630  TGeoVolume::SetLineStyle(lstyle);
2631  Int_t nvolumes = fVolumes->GetEntriesFast();
2632  TGeoVolume *vol = 0;
2633  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2634  vol = GetVolume(ivo);
2635  vol->SetLineStyle(lstyle);
2636  }
2637 }
2638 
2639 ////////////////////////////////////////////////////////////////////////////////
2640 /// Set the line width for all components.
2641 
2643 {
2644  TGeoVolume::SetLineWidth(lwidth);
2645  Int_t nvolumes = fVolumes->GetEntriesFast();
2646  TGeoVolume *vol = 0;
2647  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2648  vol = GetVolume(ivo);
2649  vol->SetLineWidth(lwidth);
2650  }
2651 }
2652 
2653 ////////////////////////////////////////////////////////////////////////////////
2654 /// Set medium for a multiple volume.
2655 
2657 {
2658  TGeoVolume::SetMedium(med);
2659  Int_t nvolumes = fVolumes->GetEntriesFast();
2660  TGeoVolume *vol = 0;
2661  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2662  vol = GetVolume(ivo);
2663  vol->SetMedium(med);
2664  }
2665 }
2666 
2667 
2668 ////////////////////////////////////////////////////////////////////////////////
2669 /// Set visibility for all components.
2670 
2672 {
2674  Int_t nvolumes = fVolumes->GetEntriesFast();
2675  TGeoVolume *vol = 0;
2676  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2677  vol = GetVolume(ivo);
2678  vol->SetVisibility(vis);
2679  }
2680 }
2681 
2683 
2684 ////////////////////////////////////////////////////////////////////////////////
2685 /// Constructor.
2686 
2688  fCurrent(-1), fNext(-1)
2689 {
2690 }
2691 
2692 ////////////////////////////////////////////////////////////////////////////////
2693 /// Destructor.
2694 
2696 {
2697 }
2698 
2699 ////////////////////////////////////////////////////////////////////////////////
2700 
2702 {
2703  Int_t tid = TGeoManager::ThreadId();
2704  return *fThreadData[tid];
2705 }
2706 
2707 ////////////////////////////////////////////////////////////////////////////////
2708 
2710 {
2711  std::lock_guard<std::mutex> guard(fMutex);
2713  std::vector<ThreadData_t*>::iterator i = fThreadData.begin();
2714  while (i != fThreadData.end())
2715  {
2716  delete *i;
2717  ++i;
2718  }
2719  fThreadData.clear();
2720  fThreadSize = 0;
2721 }
2722 
2723 ////////////////////////////////////////////////////////////////////////////////
2724 
2726 {
2727  std::lock_guard<std::mutex> guard(fMutex);
2728  // Create assembly thread data here
2729  fThreadData.resize(nthreads);
2730  fThreadSize = nthreads;
2731  for (Int_t tid=0; tid<nthreads; tid++) {
2732  if (fThreadData[tid] == 0) {
2733  fThreadData[tid] = new ThreadData_t;
2734  }
2735  }
2736  TGeoVolume::CreateThreadData(nthreads);
2737 }
2738 
2739 ////////////////////////////////////////////////////////////////////////////////
2740 
2742 {
2743  return fThreadData[TGeoManager::ThreadId()]->fCurrent;
2744 }
2745 
2746 ////////////////////////////////////////////////////////////////////////////////
2747 
2749 {
2750  return fThreadData[TGeoManager::ThreadId()]->fNext;
2751 }
2752 
2753 ////////////////////////////////////////////////////////////////////////////////
2754 
2756 {
2757  fThreadData[TGeoManager::ThreadId()]->fCurrent = index;
2758 }
2759 
2760 ////////////////////////////////////////////////////////////////////////////////
2761 
2763 {
2764  fThreadData[TGeoManager::ThreadId()]->fNext = index;
2765 }
2766 
2767 ////////////////////////////////////////////////////////////////////////////////
2768 /// Default constructor
2769 
2771  :TGeoVolume()
2772 {
2773  fThreadSize = 0;
2774  CreateThreadData(1);
2775 }
2776 
2777 ////////////////////////////////////////////////////////////////////////////////
2778 /// Constructor. Just the name has to be provided. Assemblies does not have their own
2779 /// shape or medium.
2780 
2782  :TGeoVolume()
2783 {
2784  fName = name;
2785  fName = fName.Strip();
2786  fShape = new TGeoShapeAssembly(this);
2787  if (fGeoManager) fNumber = fGeoManager->AddVolume(this);
2788  fThreadSize = 0;
2789  CreateThreadData(1);
2790 }
2791 
2792 ////////////////////////////////////////////////////////////////////////////////
2793 /// Destructor. The assembly is owner of its "shape".
2794 
2796 {
2797  ClearThreadData();
2798  if (fShape) delete fShape;
2799 }
2800 
2801 ////////////////////////////////////////////////////////////////////////////////
2802 /// Add a component to the assembly.
2803 
2805 {
2806  TGeoVolume::AddNode(vol,copy_no,mat,option);
2807 // ((TGeoShapeAssembly*)fShape)->RecomputeBoxLast();
2808  ((TGeoShapeAssembly*)fShape)->NeedsBBoxRecompute();
2809 }
2810 
2811 ////////////////////////////////////////////////////////////////////////////////
2812 /// Add an overlapping node - not allowed for assemblies.
2813 
2815 {
2816  Warning("AddNodeOverlap", "Declaring assembly %s as possibly overlapping inside %s not allowed. Using AddNode instead !",vol->GetName(),GetName());
2817  AddNode(vol, copy_no, mat, option);
2818 }
2819 
2820 ////////////////////////////////////////////////////////////////////////////////
2821 /// Clone this volume.
2822 /// build a volume with same name, shape and medium
2823 
2825 {
2826  TGeoVolume *vol = new TGeoVolumeAssembly(GetName());
2827  Int_t i;
2828  // copy other attributes
2829  Int_t nbits = 8*sizeof(UInt_t);
2830  for (i=0; i<nbits; i++)
2831  vol->SetAttBit(1<<i, TGeoAtt::TestAttBit(1<<i));
2832  for (i=14; i<24; i++)
2833  vol->SetBit(1<<i, TestBit(1<<i));
2834 
2835  // copy field
2836  vol->SetField(fField);
2837  // Set bits
2838  for (i=0; i<nbits; i++)
2839  vol->SetBit(1<<i, TObject::TestBit(1<<i));
2840  vol->SetBit(kVolumeClone);
2841  // make copy nodes
2842  vol->MakeCopyNodes(this);
2843 // CloneNodesAndConnect(vol);
2844  ((TGeoShapeAssembly*)vol->GetShape())->NeedsBBoxRecompute();
2845  // copy voxels
2846  TGeoVoxelFinder *voxels = 0;
2847  if (fVoxels) {
2848  voxels = new TGeoVoxelFinder(vol);
2849  vol->SetVoxelFinder(voxels);
2850  }
2851  // copy option, uid
2852  vol->SetOption(fOption);
2853  vol->SetNumber(fNumber);
2854  vol->SetNtotal(fNtotal);
2855  return vol;
2856 }
2857 
2858 ////////////////////////////////////////////////////////////////////////////////
2859 /// Division makes no sense for assemblies.
2860 
2862 {
2863  Error("Divide","Assemblies cannot be divided");
2864  return 0;
2865 }
2866 
2867 ////////////////////////////////////////////////////////////////////////////////
2868 /// Assign to the assembly a collection of identical volumes positioned according
2869 /// a predefined pattern. The option can be spaced out or touching depending on the empty
2870 /// space between volumes.
2871 
2873 {
2874  if (fNodes) {
2875  Error("Divide", "Cannot divide assembly %s since it has nodes", GetName());
2876  return NULL;
2877  }
2878  if (fFinder) {
2879  Error("Divide", "Assembly %s already divided", GetName());
2880  return NULL;
2881  }
2882  Int_t ncells = pattern->GetNdiv();
2883  if (!ncells || pattern->GetStep()<=0) {
2884  Error("Divide", "Pattern finder for dividing assembly %s not initialized. Use SetRange() method.", GetName());
2885  return NULL;
2886  }
2887  fFinder = pattern;
2888  TString opt(option);
2889  opt.ToLower();
2890  if (opt.Contains("spacedout")) fFinder->SetSpacedOut(kTRUE);
2891  else fFinder->SetSpacedOut(kFALSE);
2892  // Position volumes
2893  for (Int_t i=0; i<ncells; i++) {
2894  fFinder->cd(i);
2895  TGeoNodeOffset *node = new TGeoNodeOffset(cell, i, 0.);
2896  node->SetFinder(fFinder);
2897  fNodes->Add(node);
2898  }
2899  return cell;
2900 }
2901 
2902 ////////////////////////////////////////////////////////////////////////////////
2903 /// Make a clone of volume VOL but which is an assembly.
2904 
2906 {
2907  if (volorig->IsAssembly() || volorig->IsVolumeMulti()) return 0;
2908  Int_t nd = volorig->GetNdaughters();
2909  if (!nd) return 0;
2910  TGeoVolumeAssembly *vol = new TGeoVolumeAssembly(volorig->GetName());
2911  Int_t i;
2912  // copy other attributes
2913  Int_t nbits = 8*sizeof(UInt_t);
2914  for (i=0; i<nbits; i++)
2915  vol->SetAttBit(1<<i, volorig->TestAttBit(1<<i));
2916  for (i=14; i<24; i++)
2917  vol->SetBit(1<<i, volorig->TestBit(1<<i));
2918 
2919  // copy field
2920  vol->SetField(volorig->GetField());
2921  // Set bits
2922  for (i=0; i<nbits; i++)
2923  vol->SetBit(1<<i, volorig->TestBit(1<<i));
2924  vol->SetBit(kVolumeClone);
2925  // make copy nodes
2926  vol->MakeCopyNodes(volorig);
2927 // volorig->CloneNodesAndConnect(vol);
2928  vol->GetShape()->ComputeBBox();
2929  // copy voxels
2930  TGeoVoxelFinder *voxels = 0;
2931  if (volorig->GetVoxels()) {
2932  voxels = new TGeoVoxelFinder(vol);
2933  vol->SetVoxelFinder(voxels);
2934  }
2935  // copy option, uid
2936  vol->SetOption(volorig->GetOption());
2937  vol->SetNumber(volorig->GetNumber());
2938  vol->SetNtotal(volorig->GetNtotal());
2939  return vol;
2940 }
TGeoVolume::SetVisOnly
virtual void SetVisOnly(Bool_t flag=kTRUE)
Set visibility for leaves.
Definition: TGeoVolume.cxx:2238
TGeoVolume::InspectMaterial
void InspectMaterial() const
Inspect the material for this volume.
Definition: TGeoVolume.cxx:829
TGeoAtt::SetAttBit
void SetAttBit(UInt_t f)
Definition: TGeoAtt.h:65
TGeoVoxelFinder::FindOverlaps
virtual void FindOverlaps(Int_t inode) const
create the list of nodes for which the bboxes overlap with inode's bbox
Definition: TGeoVoxelFinder.cxx:296
TAttLine::fLineColor
Color_t fLineColor
Line color.
Definition: TAttLine.h:21
TGeoVolumeMulti::fNdiv
Int_t fNdiv
Definition: TGeoVolume.h:259
TGeoAtt::SetVisibility
virtual void SetVisibility(Bool_t vis=kTRUE)
Set visibility for this object.
Definition: TGeoAtt.cxx:105
TGeoShape::IsValid
Bool_t IsValid() const
Definition: TGeoShape.h:140
TGeoCompositeShape::RegisterYourself
void RegisterYourself()
Register the shape and all components to TGeoManager class.
Definition: TGeoCompositeShape.cxx:455
TGeoManager::GetExportPrecision
static UInt_t GetExportPrecision()
Definition: TGeoManager.h:479
TGeoShapeAssembly.h
TGeoVolume::Import
static TGeoVolume * Import(const char *filename, const char *name="", Option_t *option="")
Import a volume from a file.
Definition: TGeoVolume.cxx:837
TGeoNode::SetVolume
void SetVolume(TGeoVolume *volume)
Definition: TGeoNode.h:115
TGeoVolumeAssembly::ThreadData_t
Definition: TGeoVolume.h:306
TGeoMaterial::GetDensity
virtual Double_t GetDensity() const
Definition: TGeoMaterial.h:108
TObject::SavePrimitive
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TObject.cxx:666
TGeoVolume::Browse
void Browse(TBrowser *b)
How to browse a volume.
Definition: TGeoVolume.cxx:519
TBrowser
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
TGeoManager::GetListOfOverlaps
TObjArray * GetListOfOverlaps()
Definition: TGeoManager.h:489
TGeoVolume::SetFinder
void SetFinder(TGeoPatternFinder *finder)
Definition: TGeoVolume.h:231
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TGeoPatternFinder::ClearThreadData
void ClearThreadData() const
Definition: TGeoPatternFinder.cxx:81
TGeoMatrix::ReflectZ
virtual void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to XY.
Definition: TGeoMatrix.cxx:519
Style_t
short Style_t
Definition: RtypesCore.h:80
TObjArray::Delete
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:356
TObject::TestBit
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
TGeoManager::GetTopVolume
TGeoVolume * GetTopVolume() const
Definition: TGeoManager.h:532
TGeoVolume::SetFWExtension
void SetFWExtension(TGeoExtension *ext)
Connect framework defined extension to the volume.
Definition: TGeoVolume.cxx:1411
TGeoPatternFinder::CreateThreadData
void CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
Definition: TGeoPatternFinder.cxx:97
TGeoVolume::DummyMedium
static TGeoMedium * DummyMedium()
Definition: TGeoVolume.cxx:440
TGeoManager::IsClosed
Bool_t IsClosed() const
Definition: TGeoManager.h:305
TGeoVolumeAssembly::~TGeoVolumeAssembly
virtual ~TGeoVolumeAssembly()
Destructor. The assembly is owner of its "shape".
Definition: TGeoVolume.cxx:2795
TGeoManager::ClearOverlaps
void ClearOverlaps()
Clear the list of overlaps.
Definition: TGeoManager.cxx:1454
TVirtualGeoPainter::GetDrawnVolume
virtual TGeoVolume * GetDrawnVolume() const =0
TGeoManager::AddVolume
Int_t AddVolume(TGeoVolume *volume)
Add a volume to the list. Returns index of the volume in list.
Definition: TGeoManager.cxx:672
TGeoVolumeAssembly::fThreadData
std::vector< ThreadData_t * > fThreadData
Definition: TGeoVolume.h:319
TGeoPatternFinder::GetByteCount
virtual Int_t GetByteCount() const
Definition: TGeoPatternFinder.h:81
gGeoIdentity
R__EXTERN TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.h:478
TGeoVolume::GetShape
TGeoShape * GetShape() const
Definition: TGeoVolume.h:188
TObjArray
An array of TObjects.
Definition: TObjArray.h:37
TGeoPatternFinder::GetNdiv
Int_t GetNdiv() const
Definition: TGeoPatternFinder.h:86
TGeoVolume::GetFinder
TGeoPatternFinder * GetFinder() const
Definition: TGeoVolume.h:175
TGeoManager::ThreadId
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
Definition: TGeoManager.cxx:904
TGeoVolume::fgDummyMedium
static TGeoMedium * fgDummyMedium
Definition: TGeoVolume.h:54
f
#define f(i)
Definition: RSha256.hxx:104
TGeoAtt::SetVisContainers
virtual void SetVisContainers(Bool_t flag=kTRUE)
Set branch type visibility.
Definition: TGeoAtt.cxx:77
TAttFill::SetFillStyle
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
TGeoMedium::GetPointerName
char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoMedium.cxx:127
TGeoVolume::GetNdaughters
Int_t GetNdaughters() const
Definition: TGeoVolume.h:349
TNamed::SetName
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
Option_t
const char Option_t
Definition: RtypesCore.h:66
TGeoCombiTrans
Class describing rotation + translation.
Definition: TGeoMatrix.h:292
TGeoVolume::kVolumeClone
@ kVolumeClone
Definition: TGeoVolume.h:85
TGeoManager::SetCurrentPoint
void SetCurrentPoint(Double_t *point)
Definition: TGeoManager.h:535
TGeoManager::GetListOfVolumes
TObjArray * GetListOfVolumes() const
Definition: TGeoManager.h:493
TString::Strip
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1106
TGeoVolumeAssembly::AddNodeOverlap
virtual void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option)
Add an overlapping node - not allowed for assemblies.
Definition: TGeoVolume.cxx:2814
TGeoShape::IsComposite
virtual Bool_t IsComposite() const
Definition: TGeoShape.h:130
gEnv
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
TVirtualGeoPainter::DrawVolume
virtual void DrawVolume(TGeoVolume *vol, Option_t *option="")=0
TGeoVolume::GetObjectInfo
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Get volume info for the browser.
Definition: TGeoVolume.cxx:1648
TH2F
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
gGeoManager
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:602
TList::FindObject
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:577
TString::Data
const char * Data() const
Definition: TString.h:369
TGeoVolumeMulti::SetMedium
virtual void SetMedium(TGeoMedium *medium)
Set medium for a multiple volume.
Definition: TGeoVolume.cxx:2656
TGeoVolume::GrabUserExtension
TGeoExtension * GrabUserExtension() const
Get a copy of the user extension pointer.
Definition: TGeoVolume.cxx:1423
TGeoVolume::Print
virtual void Print(Option_t *option="") const
Print volume info.
Definition: TGeoVolume.cxx:1194
TGeoVolumeMulti::fDivision
TGeoVolumeMulti * fDivision
Definition: TGeoVolume.h:257
TGeoVolume::Voxelize
void Voxelize(Option_t *option)
build the voxels for this volume
Definition: TGeoVolume.cxx:2301
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TGeoVolume::VisibleDaughters
void VisibleDaughters(Bool_t vis=kTRUE)
set visibility for daughters
Definition: TGeoVolume.cxx:2291
TObjArray::Remove
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:719
TNamed::GetTitle
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
TGeoVolumeAssembly::CreateThreadData
virtual void CreateThreadData(Int_t nthreads)
Definition: TGeoVolume.cxx:2725
TGeoVolume::DistancetoPrimitive
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute the closest distance of approach from point px,py to this volume
Definition: TGeoVolume.cxx:1133
TGeoManager::IsStreamingVoxels
Bool_t IsStreamingVoxels() const
Definition: TGeoManager.h:483
TObjArray::RemoveAt
virtual TObject * RemoveAt(Int_t idx)
Remove object at index idx.
Definition: TObjArray.cxx:694
TGeoVolume::fGeoManager
TGeoManager * fGeoManager
Definition: TGeoVolume.h:57
TGeoManager::GetVisOption
Int_t GetVisOption() const
Returns current depth to which geometry is drawn.
Definition: TGeoManager.cxx:1980
TBuffer::ReadClassBuffer
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
TGeoVolume::fNtotal
Int_t fNtotal
Definition: TGeoVolume.h:62
TGeoVolumeMulti::AddNode
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option="")
Add a new node to the list of nodes.
Definition: TGeoVolume.cxx:2454
TObject::Info
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:864
TVirtualGeoPainter::kGeoVisLeaves
@ kGeoVisLeaves
Definition: TVirtualGeoPainter.h:43
TGeoManager::IsCheckingOverlaps
Bool_t IsCheckingOverlaps() const
Definition: TGeoManager.h:411
TGeoVolume::kVolumeMulti
@ kVolumeMulti
Definition: TGeoVolume.h:82
TGeoAtt::TestAttBit
Bool_t TestAttBit(UInt_t f) const
Definition: TGeoAtt.h:68
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:890
TGeoVolume::GrabFWExtension
TGeoExtension * GrabFWExtension() const
Get a copy of the framework extension pointer.
Definition: TGeoVolume.cxx:1434
TGeoMedium::SavePrimitive
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoMedium.cxx:137
TGeoVolume::GetMaterial
TGeoMaterial * GetMaterial() const
Definition: TGeoVolume.h:172
TGeoVolume::GetIndex
Int_t GetIndex(const TGeoNode *node) const
get index number for a given daughter
Definition: TGeoVolume.cxx:1633
TGeoVolume::IsValid
Bool_t IsValid() const
Definition: TGeoVolume.h:152
TGeoNode::GetVolume
TGeoVolume * GetVolume() const
Definition: TGeoNode.h:97
TGeoVolume::SetNodes
void SetNodes(TObjArray *nodes)
Definition: TGeoVolume.h:214
TGeoVolume::InspectShape
void InspectShape() const
Definition: TGeoVolume.h:193
TGeoVolume::RandomPoints
void RandomPoints(Int_t npoints=1000000, Option_t *option="")
Draw random points in the bounding box of this volume.
Definition: TGeoVolume.cxx:1321
TMap::GetValue
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:236
TStyle.h
TGeoVolumeAssembly::TGeoVolumeAssembly
TGeoVolumeAssembly()
Default constructor.
Definition: TGeoVolume.cxx:2770
TFile::Open
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:3995
TGeoManager::SortOverlaps
void SortOverlaps()
Sort overlaps by decreasing overlap distance. Extrusions comes first.
Definition: TGeoManager.cxx:2263
TGeoVolumeMulti::fAttSet
Bool_t fAttSet
Definition: TGeoVolume.h:263
TObject::Fatal
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:918
TGeoVolume::CloneVolume
virtual TGeoVolume * CloneVolume() const
Clone this volume.
Definition: TGeoVolume.cxx:1714
Int_t
int Int_t
Definition: RtypesCore.h:45
TGeoVolume.h
TGeoVolume::GrabFocus
void GrabFocus()
Move perspective view focus to this volume.
Definition: TGeoVolume.cxx:1696
TGeoVolumeAssembly::ClearThreadData
virtual void ClearThreadData() const
Definition: TGeoVolume.cxx:2709
TGeoVolumeMulti::AddNodeOverlap
virtual void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option="")
Add a new node to the list of nodes, This node is possibly overlapping with other daughters of the vo...
Definition: TGeoVolume.cxx:2474
TGeoPatternFinder::SetVolume
void SetVolume(TGeoVolume *vol)
Definition: TGeoPatternFinder.h:103
TGeoVolume::IsStyleDefault
Bool_t IsStyleDefault() const
check if the visibility and attributes are the default ones
Definition: TGeoVolume.cxx:800
TBrowser.h
TGeoAtt::IsVisDaughters
Bool_t IsVisDaughters() const
Definition: TGeoAtt.h:89
TNamed::fName
TString fName
Definition: TNamed.h:32
TGeoVolume::SetLineWidth
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TGeoVolume.cxx:2051
TGeoVolume::AddNode
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a TGeoNode to the list of nodes.
Definition: TGeoVolume.cxx:932
TString::Contains
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
TGeoVolume::SetMedium
virtual void SetMedium(TGeoMedium *medium)
Definition: TGeoVolume.h:229
TGeoVolume::TGeoVolume
TGeoVolume()
dummy constructor
Definition: TGeoVolume.cxx:448
TObjArray::GetEntries
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:523
TGeoHMatrix::MultiplyLeft
void MultiplyLeft(const TGeoMatrix *left)
multiply to the left with an other transformation if right is identity matrix, just return
Definition: TGeoMatrix.cxx:2571
TGeoVolume::SaveAs
void SaveAs(const char *filename, Option_t *option="") const
Save geometry having this as top volume as a C++ macro.
Definition: TGeoVolume.cxx:1366
x
Double_t x[n]
Definition: legend1.C:17
TGeoVolume::SetVoxelFinder
void SetVoxelFinder(TGeoVoxelFinder *finder)
Definition: TGeoVolume.h:230
TString::Length
Ssiz_t Length() const
Definition: TString.h:410
TDirectory::TContext
Small helper to keep current directory context.
Definition: TDirectory.h:47
TGeoShape::Divide
virtual TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)=0
TVirtualGeoPainter::GetVolumeInfo
virtual const char * GetVolumeInfo(const TGeoVolume *volume, Int_t px, Int_t py) const =0
TGeoShape::CheckShape
void CheckShape(Int_t testNo, Int_t nsamples=10000, Option_t *option="")
Test for shape navigation methods.
Definition: TGeoShape.cxx:209
TGeoNode::IsOffset
Bool_t IsOffset() const
Definition: TGeoNode.h:103
TEnv::GetValue
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
TGeoAtt::IsVisRaytrace
Bool_t IsVisRaytrace() const
Definition: TGeoAtt.h:87
TGeoNodeOffset
Node containing an offset.
Definition: TGeoNode.h:184
TGeoVolume::CheckShapes
void CheckShapes()
check for negative parameters in shapes.
Definition: TGeoVolume.cxx:648
TVirtualGeoPainter::CheckOverlaps
virtual void CheckOverlaps(const TGeoVolume *vol, Double_t ovlp=0.1, Option_t *option="") const =0
TBuffer
Buffer base class used for serializing objects.
Definition: TBuffer.h:43
TAttLine::SetLineColor
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
TGeoVolumeMulti::SetLineStyle
virtual void SetLineStyle(Style_t lstyle)
Set the line style for all components.
Definition: TGeoVolume.cxx:2628
TGeoVolume::ClearShape
void ClearShape()
Clear the shape of this volume from the list held by the current manager.
Definition: TGeoVolume.cxx:640
TObjArray::At
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
TString::Format
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
TGeoVolume::fMedium
TGeoMedium * fMedium
Definition: TGeoVolume.h:53
TAttLine::fLineWidth
Width_t fLineWidth
Line width.
Definition: TAttLine.h:23
TMap::Add
void Add(TObject *obj)
This function may not be used (but we need to provide it since it is a pure virtual in TCollection).
Definition: TMap.cxx:54
TGeoNodeMatrix::GetMatrix
virtual TGeoMatrix * GetMatrix() const
Definition: TGeoNode.h:170
TEnv.h
TGeoMaterial::SetUsed
void SetUsed(Bool_t flag=kTRUE)
Definition: TGeoMaterial.h:138
TGeoNode::SetMotherVolume
void SetMotherVolume(TGeoVolume *mother)
Definition: TGeoNode.h:123
TGeoMatrix::Print
void Print(Option_t *option="") const
print the matrix in 4x4 format
Definition: TGeoMatrix.cxx:486
TGeoShape::GetAxisRange
virtual Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const =0
TString
Basic string class.
Definition: TString.h:136
TGeoVolumeMulti::Divide
virtual TGeoVolume * Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed=0, Option_t *option="")
division of multiple volumes
Definition: TGeoVolume.cxx:2503
TGeoNode::IsOverlapping
Bool_t IsOverlapping() const
Definition: TGeoNode.h:105
TGeoVolume::FindMatrixOfDaughterVolume
Bool_t FindMatrixOfDaughterVolume(TGeoVolume *vol) const
Find a daughter node having VOL as volume and fill TGeoManager::fHMatrix with its global matrix.
Definition: TGeoVolume.cxx:2260
TGeoVolume::fShape
TGeoShape * fShape
Definition: TGeoVolume.h:52
TGeoMatrix::IsRegistered
Bool_t IsRegistered() const
Definition: TGeoMatrix.h:77
TGeoMedium::SetMaterial
void SetMaterial(TGeoMaterial *mat)
Definition: TGeoMedium.h:55
TGeoShape::GetMakeRuntimeShape
virtual TGeoShape * GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix *mat) const =0
TGeoNode::MakeCopyNode
virtual TGeoNode * MakeCopyNode() const
Definition: TGeoNode.h:111
TGeoVolume::SetAsTopVolume
void SetAsTopVolume()
Set this volume as the TOP one (the whole geometry starts from here)
Definition: TGeoVolume.cxx:1924
TGeoNode::GetMatrix
virtual TGeoMatrix * GetMatrix() const =0
Color_t
short Color_t
Definition: RtypesCore.h:83
TGeoVolumeAssembly::GetCurrentNodeIndex
virtual Int_t GetCurrentNodeIndex() const
Definition: TGeoVolume.cxx:2741
TGeoVolumeAssembly::CloneVolume
virtual TGeoVolume * CloneVolume() const
Clone this volume.
Definition: TGeoVolume.cxx:2824
TObject::InheritsFrom
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
TGeoVolume::Capacity
Double_t Capacity() const
Computes the capacity of this [cm^3] as the capacity of its shape.
Definition: TGeoVolume.cxx:553
TGeoNode
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition: TGeoNode.h:41
b
#define b(i)
Definition: RSha256.hxx:100
TString.h
TFile.h
TGeoMaterial
Base class describing materials.
Definition: TGeoMaterial.h:36
TGeoPatternFinder
Base finder class for patterns.
Definition: TGeoPatternFinder.h:32
bool
TGeoShape::TestShapeBit
Bool_t TestShapeBit(UInt_t f) const
Definition: TGeoShape.h:163
TGeoCompositeShape
Class handling Boolean composition of shapes.
Definition: TGeoCompositeShape.h:28
TGeoVolume::GetMedium
TGeoMedium * GetMedium() const
Definition: TGeoVolume.h:173
TGeoShape::GetByteCount
virtual Int_t GetByteCount() const =0
TGeoNodeOffset::SetFinder
void SetFinder(TGeoPatternFinder *finder)
Definition: TGeoNode.h:206
TObjArray::Add
void Add(TObject *obj)
Definition: TObjArray.h:74
TGeoManager::SetNsegments
void SetNsegments(Int_t nseg)
Set number of segments for approximating circles in drawing.
Definition: TGeoManager.cxx:3339
TGeoVolume::SetNumber
void SetNumber(Int_t number)
Definition: TGeoVolume.h:232
id
XFontStruct * id
Definition: TGX11.cxx:109
TNamed::fTitle
TString fTitle
Definition: TNamed.h:33
TVirtualGeoPainter::TestVoxels
virtual Bool_t TestVoxels(TGeoVolume *vol)=0
TGeoVolumeMulti::AddVolume
void AddVolume(TGeoVolume *vol)
Add a volume with valid shape to the list of volumes.
Definition: TGeoVolume.cxx:2419
TGeoVolume::fNumber
Int_t fNumber
option - if any
Definition: TGeoVolume.h:61
TGeoVolume::SelectVolume
void SelectVolume(Bool_t clear=kFALSE)
Select this volume as matching an arbitrary criteria.
Definition: TGeoVolume.cxx:2175
TROOT.h
TVirtualGeoPainter::kGeoVisDefault
@ kGeoVisDefault
Definition: TVirtualGeoPainter.h:42
TGeoPatternFinder::MakeCopy
virtual TGeoPatternFinder * MakeCopy(Bool_t reflect=kFALSE)=0
TGeoExtension::Grab
virtual TGeoExtension * Grab()=0
TGeoVolume::SavePrimitive
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoVolume.cxx:1443
TGeoVolume::SetShape
void SetShape(const TGeoShape *shape)
set the shape associated with this volume
Definition: TGeoVolume.cxx:1940
TGeoAtt::kSavePrimitiveAtt
@ kSavePrimitiveAtt
Definition: TGeoAtt.h:52
TGeoVolume::GetPointerName
char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoVolume.cxx:1677
TGeoVolume::SetField
void SetField(TObject *field)
Definition: TGeoVolume.h:218
TGeoManager::Weight
Double_t Weight(Double_t precision=0.01, Option_t *option="va")
Estimate weight of volume VOL with a precision SIGMA(W)/W better than PRECISION.
Definition: TGeoManager.cxx:3625
ROOT::Math::gv_detail::dist
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
TGeoManager::AddMaterial
Int_t AddMaterial(const TGeoMaterial *material)
Add a material to the list. Returns index of the material in list.
Definition: TGeoManager.cxx:552
TGeoVolumeMulti::fStep
Double_t fStep
Definition: TGeoVolume.h:262
TGeoMatrix::IsIdentity
Bool_t IsIdentity() const
Definition: TGeoMatrix.h:66
TGeoShape::CreateThreadData
virtual void CreateThreadData(Int_t)
Definition: TGeoShape.h:68
TGeoVolume::fVoxels
TGeoVoxelFinder * fVoxels
Definition: TGeoVolume.h:56
TGeoVolume::IsFolder
virtual Bool_t IsFolder() const
Return TRUE if volume contains nodes.
Definition: TGeoVolume.cxx:792
TGeoManager::GetListOfMaterials
TList * GetListOfMaterials() const
Definition: TGeoManager.h:491
TGeoManager::SetTopVolume
void SetTopVolume(TGeoVolume *vol)
Set the top volume and corresponding node as starting point of the geometry.
Definition: TGeoManager.cxx:3397
TGeoVolume::SetAttVisibility
void SetAttVisibility(Bool_t vis)
Definition: TGeoVolume.h:220
TBrowser::CheckObjectItem
void CheckObjectItem(TObject *obj, Bool_t check=kFALSE)
Change status of checkbox for this item.
Definition: TBrowser.cxx:304
TGeoMedium::GetId
Int_t GetId() const
Definition: TGeoMedium.h:48
TGeoShape
Base abstract class for all shapes.
Definition: TGeoShape.h:26
TGeoVolume::DrawOnly
virtual void DrawOnly(Option_t *option="")
draw only this volume
Definition: TGeoVolume.cxx:1163
TBuffer.h
TGeoVolumeAssembly::SetNextNodeIndex
void SetNextNodeIndex(Int_t index)
Definition: TGeoVolume.cxx:2762
TGeoVolumeAssembly::AddNode
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a component to the assembly.
Definition: TGeoVolume.cxx:2804
TGeoVolume::ClearThreadData
virtual void ClearThreadData() const
Definition: TGeoVolume.cxx:424
gStyle
R__EXTERN TStyle * gStyle
Definition: TStyle.h:412
TGeoVolume::ReplayCreation
void ReplayCreation(const TGeoVolume *other)
Recreate the content of the other volume without pointer copying.
Definition: TGeoVolume.cxx:1228
TObject::ResetBit
void ResetBit(UInt_t f)
Definition: TObject.h:171
TGeoVolumeMulti::MakeCopyVolume
virtual TGeoVolume * MakeCopyVolume(TGeoShape *newshape)
Make a copy of this volume build a volume with same name, shape and medium.
Definition: TGeoVolume.cxx:2555
TGeoVolumeMulti::~TGeoVolumeMulti
virtual ~TGeoVolumeMulti()
Destructor.
Definition: TGeoVolume.cxx:2410
TGeoVoxelFinder::Print
virtual void Print(Option_t *option="") const
Print the voxels.
Definition: TGeoVoxelFinder.cxx:2082
TVirtualGeoPainter::GetTopVolume
virtual TGeoVolume * GetTopVolume() const =0
TKey::GetClassName
virtual const char * GetClassName() const
Definition: TKey.h:76
TGeoVolumeMulti::SetVisibility
virtual void SetVisibility(Bool_t vis=kTRUE)
Set visibility for all components.
Definition: TGeoVolume.cxx:2671
TGeoHMatrix
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition: TGeoMatrix.h:421
TGeoNodeMatrix::SetMatrix
void SetMatrix(const TGeoMatrix *matrix)
Matrix setter.
Definition: TGeoNode.cxx:766
TGeoManager::SetVisOption
void SetVisOption(Int_t option=0)
set drawing mode :
Definition: TGeoManager.cxx:2221
TGeoManager::GetGeomPainter
TVirtualGeoPainter * GetGeomPainter()
Make a default painter if none present. Returns pointer to it.
Definition: TGeoManager.cxx:2685
TAttLine::GetLineColor
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
TObject::SetBit
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:696
TGeoShape::ComputeBBox
virtual void ComputeBBox()=0
TGeoMatrix::IsReflection
Bool_t IsReflection() const
Definition: TGeoMatrix.h:69
TGeoVolumeAssembly::fThreadSize
Int_t fThreadSize
Thread specific data vector.
Definition: TGeoVolume.h:320
TGeoVolume::PrintVoxels
void PrintVoxels() const
Print the voxels for this volume.
Definition: TGeoVolume.cxx:1219
TGeoVolume::GetNodes
TObjArray * GetNodes()
Definition: TGeoVolume.h:167
TObjArray::GetEntriesFast
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
TGeoVolume::Draw
virtual void Draw(Option_t *option="")
draw top volume according to option
Definition: TGeoVolume.cxx:1146
TGeoExtension::Release
virtual void Release() const =0
TString::Remove
TString & Remove(Ssiz_t pos)
Definition: TString.h:673
TGeoAtt::SetVisDaughters
void SetVisDaughters(Bool_t vis=kTRUE)
Set visibility for the daughters.
Definition: TGeoAtt.cxx:114
TNamed
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TGeoVolume::ExecuteEvent
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute mouse actions on this volume.
Definition: TGeoVolume.cxx:1602
TGeoMaterial::Print
virtual void Print(const Option_t *option="") const
print characteristics of this material
Definition: TGeoMaterial.cxx:528
TAttLine::GetLineStyle
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
TGeoPatternFinder::GetStep
Double_t GetStep() const
Definition: TGeoPatternFinder.h:90
Width_t
short Width_t
Definition: RtypesCore.h:82
TGeoVolume::IsVisContainers
Bool_t IsVisContainers() const
Definition: TGeoVolume.h:155
TGeoVolume::kVolumeSelected
@ kVolumeSelected
Definition: TGeoVolume.h:78
TGeoAtt::SetVisTouched
void SetVisTouched(Bool_t vis=kTRUE)
Mark visualization attributes as "modified".
Definition: TGeoAtt.cxx:131
TBuffer::WriteClassBuffer
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
TVirtualGeoPainter::Paint
virtual void Paint(Option_t *option="")=0
This method must be overridden if a class wants to paint itself.
TGeoVolume::Raytrace
void Raytrace(Bool_t flag=kTRUE)
Draw this volume with current settings and perform raytracing in the pad.
Definition: TGeoVolume.cxx:1347
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TGeoAtt::SetVisLeaves
virtual void SetVisLeaves(Bool_t flag=kTRUE)
Set branch type visibility.
Definition: TGeoAtt.cxx:85
TGeoVolume::CheckShape
void CheckShape(Int_t testNo, Int_t nsamples=10000, Option_t *option="")
Tests for checking the shape navigation algorithms. See TGeoShape::CheckShape()
Definition: TGeoVolume.cxx:623
s1
#define s1(x)
Definition: RSha256.hxx:91
TVirtualGeoPainter::LegoPlot
virtual TH2F * LegoPlot(Int_t ntheta=60, Double_t themin=0., Double_t themax=180., Int_t nphi=90, Double_t phimin=0., Double_t phimax=360., Double_t rmin=0., Double_t rmax=9999999, Option_t *option="")=0
TGeoMatrix::GetPointerName
char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoMatrix.cxx:294
TGeoShape::kGeoSavePrimitive
@ kGeoSavePrimitive
Definition: TGeoShape.h:65
TGeoVolume::kVolumeImportNodes
@ kVolumeImportNodes
Definition: TGeoVolume.h:81
TGeoVolume::UnmarkSaved
void UnmarkSaved()
Reset SavePrimitive bits.
Definition: TGeoVolume.cxx:1592
TGeoVolumeAssembly::Divide
virtual TGeoVolume * Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed=0, Option_t *option="")
Division makes no sense for assemblies.
Definition: TGeoVolume.cxx:2861
TGeoVolume::ReplaceNode
TGeoNode * ReplaceNode(TGeoNode *nodeorig, TGeoShape *newshape=0, TGeoMatrix *newpos=0, TGeoMedium *newmed=0)
Replace an existing daughter with a new volume having the same name but possibly a new shape,...
Definition: TGeoVolume.cxx:2124
TGeoVolume::SetVisLeaves
virtual void SetVisLeaves(Bool_t flag=kTRUE)
Set visibility for leaves.
Definition: TGeoVolume.cxx:2226
TGeoVolume::CountNodes
Int_t CountNodes(Int_t nlevels=1000, Int_t option=0)
Count total number of subnodes starting from this volume, nlevels down.
Definition: TGeoVolume.cxx:702
TGeoNodeMatrix
A node containing local transformation.
Definition: TGeoNode.h:153
TGeoVolume::Grab
void Grab()
Definition: TGeoVolume.h:139
TGeoNode::GetNumber
Int_t GetNumber() const
Definition: TGeoNode.h:95
TObjArray::AddAtAndExpand
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Definition: TObjArray.cxx:235
TGeoPatternFinder::GetDivIndex
Int_t GetDivIndex()
Definition: TGeoPatternFinder.h:83
TGeoVolume::SortNodes
void SortNodes()
sort nodes by decreasing volume of the bounding box.
Definition: TGeoVolume.cxx:1953
TVirtualGeoPainter::kGeoVisOnly
@ kGeoVisOnly
Definition: TVirtualGeoPainter.h:44
TGeoNode::GetOptimalVoxels
virtual Int_t GetOptimalVoxels() const
Definition: TGeoNode.h:99
TGeoAtt::kSaveNodesAtt
@ kSaveNodesAtt
Definition: TGeoAtt.h:53
TGeoPatternFinder::SetDivIndex
void SetDivIndex(Int_t index)
Definition: TGeoPatternFinder.h:99
TGeoVolumeAssembly::ThreadData_t::ThreadData_t
ThreadData_t()
index of next node to be entered
Definition: TGeoVolume.cxx:2687
UInt_t
unsigned int UInt_t
Definition: RtypesCore.h:46
TGeoVolumeMulti::GetNvolumes
Int_t GetNvolumes() const
Definition: TGeoVolume.h:279
TVirtualGeoPainter::GrabFocus
virtual void GrabFocus(Int_t nfr=0, Double_t dlong=0, Double_t dlat=0, Double_t dpsi=0)=0
TGeoVolumeMulti::GetLastShape
TGeoShape * GetLastShape() const
Returns the last shape.
Definition: TGeoVolume.cxx:2493
TGeoShape::IsAssembly
virtual Bool_t IsAssembly() const
Definition: TGeoShape.h:129
TGeoVolume::SetOverlappingCandidate
void SetOverlappingCandidate(Bool_t flag)
Definition: TGeoVolume.h:215
TAttFill::GetFillStyle
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
y
Double_t y[n]
Definition: legend1.C:17
TGeoAtt::SetVisRaytrace
void SetVisRaytrace(Bool_t flag=kTRUE)
Definition: TGeoAtt.h:70
TGeoNode::SetOverlapping
void SetOverlapping(Bool_t flag=kTRUE)
Definition: TGeoNode.h:118
TVirtualGeoPainter::ExecuteVolumeEvent
virtual void ExecuteVolumeEvent(TGeoVolume *volume, Int_t event, Int_t px, Int_t py)=0
TGeoVolumeAssembly::MakeAssemblyFromVolume
static TGeoVolumeAssembly * MakeAssemblyFromVolume(TGeoVolume *vol)
Make a clone of volume VOL but which is an assembly.
Definition: TGeoVolume.cxx:2905
TGeoVolume::IsVisLeaves
Bool_t IsVisLeaves() const
Definition: TGeoVolume.h:156
ULong_t
unsigned long ULong_t
Definition: RtypesCore.h:55
TGeoCompositeShape.h
TGeoManager::GetHMatrix
TGeoHMatrix * GetHMatrix()
Return stored current matrix (global matrix of the next touched node).
Definition: TGeoManager.cxx:1963
TGeoVoxelFinder::SetNeedRebuild
void SetNeedRebuild(Bool_t flag=kTRUE)
Definition: TGeoVoxelFinder.h:111
TGeoVoxelFinder::Voxelize
virtual void Voxelize(Option_t *option="")
Voxelize attached volume according to option If the volume is an assembly, make sure the bbox is comp...
Definition: TGeoVoxelFinder.cxx:2221
TGeoVolume::fUserExtension
TGeoExtension * fUserExtension
Definition: TGeoVolume.h:64
TGeoVolume::IsAssembly
virtual Bool_t IsAssembly() const
Returns true if the volume is an assembly or a scaled assembly.
Definition: TGeoVolume.cxx:1705
TNamed::SetTitle
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
TGeoVoxelFinder.h
TVirtualGeoPainter::DistanceToPrimitiveVol
virtual Int_t DistanceToPrimitiveVol(TGeoVolume *vol, Int_t px, Int_t py)=0
TGeoVolume::SetCurrentPoint
void SetCurrentPoint(Double_t x, Double_t y, Double_t z)
Set the current tracking point.
Definition: TGeoVolume.cxx:1932
TObject::Warning
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:876
TGeoVolume::GetNumber
Int_t GetNumber() const
Definition: TGeoVolume.h:182
TH2F.h
TGeoVolumeAssembly::ThreadData_t::~ThreadData_t
~ThreadData_t()
Destructor.
Definition: TGeoVolume.cxx:2695
TGeoVolume::FindOverlaps
void FindOverlaps() const
loop all nodes marked as overlaps and find overlapping brothers
Definition: TGeoVolume.cxx:2089
TGeoVolumeMulti::fAxis
Int_t fAxis
Definition: TGeoVolume.h:260
TGeoVoxelFinder::IsInvalid
Bool_t IsInvalid() const
Definition: TGeoVoxelFinder.h:104
TFile
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:54
TGeoVolume::CreateDummyMedium
static void CreateDummyMedium()
Create a dummy medium.
Definition: TGeoVolume.cxx:412
unsigned int
TGeoMatrix.h
TGeoVolume::MakeCopyVolume
virtual TGeoVolume * MakeCopyVolume(TGeoShape *newshape)
make a copy of this volume build a volume with same name, shape and medium
Definition: TGeoVolume.cxx:1805
TGeoVolume::ClearNodes
void ClearNodes()
Definition: TGeoVolume.h:100
TGeoShape::IsRunTimeShape
Bool_t IsRunTimeShape() const
Definition: TGeoShape.h:139
TGeoVolume::SetVisContainers
virtual void SetVisContainers(Bool_t flag=kTRUE)
Set visibility for containers.
Definition: TGeoVolume.cxx:2214
TGeoManager::RandomRays
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.
Definition: TGeoManager.cxx:2835
TGeoVolume::fField
TObject * fField
pointer to TGeoManager owning this volume
Definition: TGeoVolume.h:59
TString::Index
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:639
TBrowser::Refresh
void Refresh()
Refresh browser contents.
Definition: TBrowser.cxx:377
TGeoPatternFinder::SetSpacedOut
void SetSpacedOut(Bool_t flag)
Definition: TGeoPatternFinder.h:102
TKey
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:28
TGeoManager.h
TKey::ReadObj
virtual TObject * ReadObj()
To read a TObject* from the file.
Definition: TKey.cxx:750
TSeqCollection
Sequenceable collection abstract base class.
Definition: TSeqCollection.h:28
TGeoVolumeAssembly::SetCurrentNodeIndex
void SetCurrentNodeIndex(Int_t index)
Definition: TGeoVolume.cxx:2755
TGeoVolume::SetLineStyle
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TGeoVolume.cxx:2043
TGeoVolume::RandomRays
void RandomRays(Int_t nrays=10000, Double_t startx=0, Double_t starty=0, Double_t startz=0, const char *target_vol=0, Bool_t check_norm=kFALSE)
Random raytracing method.
Definition: TGeoVolume.cxx:1334
TObjArray::AddAt
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:254
TGeoVolume::WeightA
Double_t WeightA() const
Analytical computation of the weight.
Definition: TGeoVolume.cxx:2347
TAttLine::SetLineWidth
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
TGeoAtt::SetVisOnly
virtual void SetVisOnly(Bool_t flag=kTRUE)
Set branch type visibility.
Definition: TGeoAtt.cxx:95
TGeoVolume::AddNodeOverlap
virtual void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a TGeoNode to the list of nodes.
Definition: TGeoVolume.cxx:996
TGeoVolume::IsVisibleDaughters
Bool_t IsVisibleDaughters() const
Definition: TGeoVolume.h:154
TObjArray::Clear
virtual void Clear(Option_t *option="")
Remove all objects from the array.
Definition: TObjArray.cxx:321
TBuffer::IsReading
Bool_t IsReading() const
Definition: TBuffer.h:86
TGeoVolume::Divide
virtual TGeoVolume * Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed=0, Option_t *option="")
Division a la G3.
Definition: TGeoVolume.cxx:1050
TGeoVolume::fOption
TString fOption
just a hook for now
Definition: TGeoVolume.h:60
TGeoScaledShape.h
TGeoShape::GetAxisName
virtual const char * GetAxisName(Int_t iaxis) const =0
TGeoPatternFinder::cd
virtual void cd(Int_t)
Definition: TGeoPatternFinder.h:78
TGeoPatternFinder::GetStart
Double_t GetStart() const
Definition: TGeoPatternFinder.h:89
TGeoShape::GetPointerName
const char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoShape.cxx:699
TVirtualGeoPainter::SetTopVolume
virtual void SetTopVolume(TGeoVolume *vol)=0
TString::IsNull
Bool_t IsNull() const
Definition: TString.h:407
TVirtualGeoPainter.h
TVirtualGeoPainter
Abstract class for geometry painters.
Definition: TVirtualGeoPainter.h:32
TGeoVolume::GetVoxels
TGeoVoxelFinder * GetVoxels() const
Getter for optimization structure.
Definition: TGeoVolume.cxx:1687
Double_t
double Double_t
Definition: RtypesCore.h:59
TGeoVolume::RegisterYourself
void RegisterYourself(Option_t *option="")
Register the volume and all materials/media/matrices/shapes to the manager.
Definition: TGeoVolume.cxx:1281
TGeoMatrix
Geometrical transformation package.
Definition: TGeoMatrix.h:41
TGeoVolume::GetOption
Option_t * GetOption() const
Definition: TGeoVolume.h:185
TGeoVolume::GetByteCount
virtual Int_t GetByteCount() const
get the total size in bytes for this volume
Definition: TGeoVolume.cxx:2069
TGeoVolume::CheckOverlaps
void CheckOverlaps(Double_t ovlp=0.1, Option_t *option="") const
Overlap checking tool.
Definition: TGeoVolume.cxx:589
TGeoVolumeMulti::SetLineWidth
virtual void SetLineWidth(Width_t lwidth)
Set the line width for all components.
Definition: TGeoVolume.cxx:2642
TGeoVolume::MakeReflectedVolume
TGeoVolume * MakeReflectedVolume(const char *newname="") const
Make a copy of this volume which is reflected with respect to XY plane.
Definition: TGeoVolume.cxx:1835
TGeoManager::SetAllIndex
void SetAllIndex()
Assigns uid's for all materials,media and matrices.
Definition: TGeoManager.cxx:1293
TGeoScale
Class describing scale transformations.
Definition: TGeoMatrix.h:245
TGeoManager::GetListOfMedia
TList * GetListOfMedia() const
Definition: TGeoManager.h:492
TGeoVolume::CleanAll
void CleanAll()
Clean data of the volume.
Definition: TGeoVolume.cxx:631
TGeoVolume::CloneNodesAndConnect
void CloneNodesAndConnect(TGeoVolume *newmother) const
Clone the array of nodes.
Definition: TGeoVolume.cxx:1762
TObjArray::FindObject
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:415
TGeoVolumeMulti
Volume families.
Definition: TGeoVolume.h:254
TGeoVolume::IsVisible
virtual Bool_t IsVisible() const
Definition: TGeoVolume.h:153
TGeoVolume::IsVolumeMulti
virtual Bool_t IsVolumeMulti() const
Definition: TGeoVolume.h:115
TGeoVolumeMulti::fVolumes
TObjArray * fVolumes
Definition: TGeoVolume.h:256
TGeoShapeAssembly
The shape encapsulating an assembly (union) of volumes.
Definition: TGeoShapeAssembly.h:20
TGeoVolume::GetNode
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
Definition: TGeoVolume.cxx:2059
TGeoShape::ClearThreadData
virtual void ClearThreadData() const
Definition: TGeoShape.h:67
TGeoVolume::SetUserExtension
void SetUserExtension(TGeoExtension *ext)
Connect user-defined extension to the volume.
Definition: TGeoVolume.cxx:1396
TAttFill::SetFillColor
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
TGeoShape::IsSameWithinTolerance
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
Definition: TGeoShape.cxx:326
TObject::Write
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:795
TGeoVolume::CheckGeometry
void CheckGeometry(Int_t nrays=1, Double_t startx=0, Double_t starty=0, Double_t startz=0) const
Shoot nrays with random directions from starting point (startx, starty, startz) in the reference fram...
Definition: TGeoVolume.cxx:568
TList::Add
virtual void Add(TObject *obj)
Definition: TList.h:87
TGeoVolume::FindNode
TGeoNode * FindNode(const char *name) const
search a daughter inside the list of nodes
Definition: TGeoVolume.cxx:1612
TGeoVolumeMulti::fNumed
Int_t fNumed
Definition: TGeoVolume.h:258
TGeoMedium::GetMaterial
TGeoMaterial * GetMaterial() const
Definition: TGeoMedium.h:52
TObject
Mother of all ROOT objects.
Definition: TObject.h:37
TGeoVolumeAssembly::GetNextNodeIndex
virtual Int_t GetNextNodeIndex() const
Definition: TGeoVolume.cxx:2748
TGeoManager::GetPainter
TVirtualGeoPainter * GetPainter() const
Definition: TGeoManager.h:213
TString::Capacity
Ssiz_t Capacity() const
Definition: TString.h:357
TGeoVolume::CreateThreadData
virtual void CreateThreadData(Int_t nthreads)
Definition: TGeoVolume.cxx:432
TGeoVolume::Paint
virtual void Paint(Option_t *option="")
paint volume
Definition: TGeoVolume.cxx:1204
TGeoVolume::fFinder
TGeoPatternFinder * fFinder
dummy medium
Definition: TGeoVolume.h:55
TGeoVolume::Valid
Bool_t Valid() const
Check if the shape of this volume is valid.
Definition: TGeoVolume.cxx:2251
TMap.h
TGeoVolumeAssembly::fMutex
std::mutex fMutex
Thread vector size.
Definition: TGeoVolume.h:321
TGeoVolume::InvisibleAll
void InvisibleAll(Bool_t flag=kTRUE)
Make volume and each of it daughters (in)visible.
Definition: TGeoVolume.cxx:764
name
char name[80]
Definition: TGX11.cxx:110
TGeoExtension.h
TGeoVolume::LegoPlot
TH2F * LegoPlot(Int_t ntheta=20, Double_t themin=0., Double_t themax=180., Int_t nphi=60, Double_t phimin=0., Double_t phimax=360., Double_t rmin=0., Double_t rmax=9999999, Option_t *option="")
Generate a lego plot fot the top volume, according to option.
Definition: TGeoVolume.cxx:1265
TGeoVolume::OptimizeVoxels
Bool_t OptimizeVoxels()
Perform an extensive sampling to find which type of voxelization is most efficient.
Definition: TGeoVolume.cxx:1184
TGeoManager::GetMedium
TGeoMedium * GetMedium(const char *medium) const
Search for a named tracking medium. All trailing blanks stripped.
Definition: TGeoManager.cxx:2782
TGeoVolume::SetNtotal
void SetNtotal(Int_t ntotal)
Definition: TGeoVolume.h:233
TGeoShape::kGeoBad
@ kGeoBad
Definition: TGeoShape.h:34
TGeoVolume::MakeCopyNodes
void MakeCopyNodes(const TGeoVolume *other)
make a new list of nodes and copy all nodes of other volume inside
Definition: TGeoVolume.cxx:1788
TGeoVolume::Export
Int_t Export(const char *filename, const char *name="", Option_t *option="")
Export this volume to a file.
Definition: TGeoVolume.cxx:887
TAttFill::GetFillColor
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
TGeoVolume::GetNodeIndex
Int_t GetNodeIndex(const TGeoNode *node, Int_t *check_list, Int_t ncheck) const
Get the index of a daughter within check_list by providing the node pointer.
Definition: TGeoVolume.cxx:1620
TGeoVolume::GetNtotal
Int_t GetNtotal() const
Definition: TGeoVolume.h:169
TIter
Definition: TCollection.h:233
TGeoShape::Capacity
virtual Double_t Capacity() const =0
TGeoPatternFinder::GetDivAxis
virtual Int_t GetDivAxis()
Definition: TGeoPatternFinder.h:84
TGeoVolume::IsRaytracing
Bool_t IsRaytracing() const
Check if the painter is currently ray-tracing the content of this volume.
Definition: TGeoVolume.cxx:821
TGeoNode::GetByteCount
virtual Int_t GetByteCount() const
Definition: TGeoNode.h:84
TObjArray::Compress
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:334
TGeoMatrix::RegisterYourself
virtual void RegisterYourself()
Register the matrix in the current manager, which will become the owner.
Definition: TGeoMatrix.cxx:526
TVirtualGeoPainter::CheckGeometry
virtual void CheckGeometry(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) const =0
TGeoExtension
ABC for user objects attached to TGeoVolume or TGeoNode.
Definition: TGeoExtension.h:20
TGeoVolume::SetOption
void SetOption(const char *option)
Set the current options (none implemented)
Definition: TGeoVolume.cxx:2027
TAttLine::GetLineWidth
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
TGeoVolume::RemoveNode
void RemoveNode(TGeoNode *node)
Remove an existing daughter.
Definition: TGeoVolume.cxx:2110
TGeoMedium
Media are used to store properties related to tracking and which are useful only when using geometry ...
Definition: TGeoMedium.h:24
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
TGeoVolume::~TGeoVolume
virtual ~TGeoVolume()
Destructor.
Definition: TGeoVolume.cxx:502
TGeoVolumeMulti::TGeoVolumeMulti
TGeoVolumeMulti()
dummy constructor
Definition: TGeoVolume.cxx:2374
TGeoVolume::AddNodeOffset
void AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset=0, Option_t *option="")
Add a division node to the list of nodes.
Definition: TGeoVolume.cxx:971
TAttLine::fLineStyle
Style_t fLineStyle
Line style.
Definition: TAttLine.h:22
TKey.h
TGeoManager::SetUserPaintVolume
void SetUserPaintVolume(TGeoVolume *vol)
Definition: TGeoManager.h:238
TGeoAtt::ResetAttBit
void ResetAttBit(UInt_t f)
Definition: TGeoAtt.h:67
Class
void Class()
Definition: Class.C:29
TGeoVolume::fFWExtension
TGeoExtension * fFWExtension
Transient user-defined extension to volumes.
Definition: TGeoVolume.h:65
TGeoVolume::SetLineColor
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TGeoVolume.cxx:2035
TString::ToLower
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
TGeoManager::GetListOfShapes
TObjArray * GetListOfShapes() const
Definition: TGeoManager.h:495
TGeoManager::GetListOfMatrices
TObjArray * GetListOfMatrices() const
Definition: TGeoManager.h:490
TGeoVolume::fRefCount
Int_t fRefCount
Definition: TGeoVolume.h:63
TAttLine::SetLineStyle
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
TGeoVolume::Weight
Double_t Weight(Double_t precision=0.01, Option_t *option="va")
Estimate the weight of a volume (in kg) with SIGMA(M)/M better than PRECISION.
Definition: TGeoVolume.cxx:2334
TGeoScaledShape::MakeScaledShape
static TGeoShape * MakeScaledShape(const char *name, TGeoShape *shape, TGeoScale *scale)
Create a scaled shape starting from a non-scaled one.
Definition: TGeoScaledShape.cxx:275
TGeoNode::SetNumber
void SetNumber(Int_t number)
Definition: TGeoNode.h:116
TGeoVoxelFinder
Finder class handling voxels.
Definition: TGeoVoxelFinder.h:21
TGeoVolume::IsOverlappingCandidate
Bool_t IsOverlappingCandidate() const
Definition: TGeoVolume.h:146
TVirtualGeoPainter::ModifiedPad
virtual void ModifiedPad(Bool_t update=kFALSE) const =0
TGeoManager
The manager class for any TGeo geometry.
Definition: TGeoManager.h:45
TGeoManager::AddShape
Int_t AddShape(const TGeoShape *shape)
Add a shape to the list. Returns index of the shape in list.
Definition: TGeoManager.cxx:632
TGeoVolumeMulti::SetLineColor
virtual void SetLineColor(Color_t lcolor)
Set the line color for all components.
Definition: TGeoVolume.cxx:2614
TObject::ClassName
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
TGeoVolume::GetOptimalVoxels
Bool_t GetOptimalVoxels() const
Returns true if cylindrical voxelization is optimal.
Definition: TGeoVolume.cxx:1659
TGeoVolume::SetVisibility
virtual void SetVisibility(Bool_t vis=kTRUE)
set visibility of this volume
Definition: TGeoVolume.cxx:2197
TGeoManager::ClearShape
void ClearShape(const TGeoShape *shape)
Remove a shape from the list of shapes.
Definition: TGeoManager.cxx:1466
TGeoVolume::GetField
TObject * GetField() const
Definition: TGeoVolume.h:174
TGeoVolume::IsTopVolume
Bool_t IsTopVolume() const
True if this is the top volume of the geometry.
Definition: TGeoVolume.cxx:812
TGeoVolume::cd
virtual void cd(Int_t inode) const
Actualize matrix of node indexed <inode>
Definition: TGeoVolume.cxx:923
TMath::E
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:96
TGeoShape::IsValidBox
virtual Bool_t IsValidBox() const =0
TGeoVolume
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition: TGeoVolume.h:49
TGeoVolumeAssembly
Volume assemblies.
Definition: TGeoVolume.h:303
TGeoNode::SetVirtual
void SetVirtual()
Definition: TGeoNode.h:119
TGeoNode.h
TGeoVolumeAssembly::GetThreadData
ThreadData_t & GetThreadData() const
Definition: TGeoVolume.cxx:2701
TGeoVolume::fNodes
TObjArray * fNodes
Definition: TGeoVolume.h:51
ROOT::TMetaUtils::propNames::pattern
static const std::string pattern("pattern")
TGeoVolume::IsAllInvisible
Bool_t IsAllInvisible() const
Return TRUE if volume and all daughters are invisible.
Definition: TGeoVolume.cxx:753
TObject::SetUniqueID
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:707
TGeoVolumeMulti::GetVolume
TGeoVolume * GetVolume(Int_t id) const
Definition: TGeoVolume.h:274
gROOT
#define gROOT
Definition: TROOT.h:406
int
TGeoManager::RandomPoints
void RandomPoints(const TGeoVolume *vol, Int_t npoints=10000, Option_t *option="")
Draw random points in the bounding box of a volume.
Definition: TGeoManager.cxx:1762
TH1::Draw
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:3050
TGeoVolumeMulti::fStart
Double_t fStart
Definition: TGeoVolume.h:261
TMap
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:40
TGeoVolume::PrintNodes
void PrintNodes() const
print nodes
Definition: TGeoVolume.cxx:1253