Logo ROOT   6.08/07
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 "Riostream.h"
381 #include "TString.h"
382 #include "TBrowser.h"
383 #include "TStyle.h"
384 #include "TH2F.h"
385 #include "TPad.h"
386 #include "TROOT.h"
387 #include "TClass.h"
388 #include "TEnv.h"
389 #include "TMap.h"
390 #include "TFile.h"
391 #include "TKey.h"
392 #include "TThread.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;
484  if (fMedium && fMedium->GetMaterial()) fMedium->GetMaterial()->SetUsed();
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 ///copy constructor
501 
503  TNamed(gv),
504  TGeoAtt(gv),
505  TAttLine(gv),
506  TAttFill(gv),
507  TAtt3D(gv),
508  fNodes(gv.fNodes),
509  fShape(gv.fShape),
510  fMedium(gv.fMedium),
511  fFinder(gv.fFinder),
512  fVoxels(gv.fVoxels),
514  fField(gv.fField),
515  fOption(gv.fOption),
516  fNumber(gv.fNumber),
517  fNtotal(gv.fNtotal),
518  fRefCount(0),
521 {
522 }
523 
524 ////////////////////////////////////////////////////////////////////////////////
525 ///assignment operator
526 
528 {
529  if(this!=&gv) {
530  TNamed::operator=(gv);
531  TGeoAtt::operator=(gv);
532  TAttLine::operator=(gv);
533  TAttFill::operator=(gv);
534  TAtt3D::operator=(gv);
535  fNodes=gv.fNodes;
536  fShape=gv.fShape;
537  fMedium=gv.fMedium;
538  fFinder=gv.fFinder;
539  fVoxels=gv.fVoxels;
541  fField=gv.fField;
542  fOption=gv.fOption;
543  fNumber=gv.fNumber;
544  fRefCount = 0;
545  fNtotal=gv.fNtotal;
548  }
549  return *this;
550 }
551 
552 ////////////////////////////////////////////////////////////////////////////////
553 /// Destructor
554 
556 {
557  if (fNodes) {
559  fNodes->Delete();
560  }
561  delete fNodes;
562  }
564  if (fVoxels) delete fVoxels;
567 }
568 
569 ////////////////////////////////////////////////////////////////////////////////
570 /// How to browse a volume
571 
573 {
574  if (!b) return;
575 
576 // if (!GetNdaughters()) b->Add(this, GetName(), IsVisible());
577  TGeoVolume *daughter;
578  TString title;
579  for (Int_t i=0; i<GetNdaughters(); i++) {
580  daughter = GetNode(i)->GetVolume();
581  if(daughter->GetTitle()[0]) {
582  if (daughter->IsAssembly()) title.TString::Format("Assembly with %d daughter(s)",
583  daughter->GetNdaughters());
584  else if (daughter->GetFinder()) {
585  TString s1 = daughter->GetFinder()->ClassName();
586  s1.ReplaceAll("TGeoPattern","");
587  title.TString::Format("Volume having %s shape divided in %d %s slices",
588  daughter->GetShape()->ClassName(),daughter->GetNdaughters(), s1.Data());
589 
590  } else title.TString::Format("Volume with %s shape having %d daughter(s)",
591  daughter->GetShape()->ClassName(),daughter->GetNdaughters());
592  daughter->SetTitle(title.Data());
593  }
594  b->Add(daughter, daughter->GetName(), daughter->IsVisible());
595 // if (IsVisDaughters())
596 // b->AddCheckBox(daughter, daughter->IsVisible());
597 // else
598 // b->AddCheckBox(daughter, kFALSE);
599  }
600 }
601 
602 ////////////////////////////////////////////////////////////////////////////////
603 /// Computes the capacity of this [cm^3] as the capacity of its shape.
604 /// In case of assemblies, the capacity is computed as the sum of daughter's capacities.
605 
607 {
608  if (!IsAssembly()) return fShape->Capacity();
609  Double_t capacity = 0.0;
610  Int_t nd = GetNdaughters();
611  Int_t i;
612  for (i=0; i<nd; i++) capacity += GetNode(i)->GetVolume()->Capacity();
613  return capacity;
614 }
615 
616 ////////////////////////////////////////////////////////////////////////////////
617 /// Shoot nrays with random directions from starting point (startx, starty, startz)
618 /// in the reference frame of this volume. Track each ray until exiting geometry, then
619 /// shoot backwards from exiting point and compare boundary crossing points.
620 
621 void TGeoVolume::CheckGeometry(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) const
622 {
623  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
624  if (old_vol!=this) fGeoManager->SetTopVolume((TGeoVolume*)this);
625  else old_vol=0;
628  painter->CheckGeometry(nrays, startx, starty, startz);
629 }
630 
631 ////////////////////////////////////////////////////////////////////////////////
632 /// Overlap checking tool. Check for illegal overlaps within a limit OVLP.
633 /// Use option="s[number]" to force overlap checking by sampling volume with
634 /// [number] points.
635 ///
636 /// Ex:
637 /// ~~~ {.cpp}
638 /// myVol->CheckOverlaps(0.01, "s10000000"); // shoot 10000000 points
639 /// myVol->CheckOverlaps(0.01, "s"); // shoot the default value of 1e6 points
640 /// ~~~
641 
642 void TGeoVolume::CheckOverlaps(Double_t ovlp, Option_t *option) const
643 {
644  if (!GetNdaughters() || fFinder) return;
645  Bool_t sampling = kFALSE;
646  TString opt(option);
647  opt.ToLower();
648  if (opt.Contains("s")) sampling = kTRUE;
650  if (!sampling) fGeoManager->SetNsegments(80);
653 // Info("CheckOverlaps", "=== Checking overlaps for volume %s ===\n", GetName());
654  }
655  painter->CheckOverlaps(this, ovlp, option);
656 // if (sampling) return;
659  TObjArray *overlaps = fGeoManager->GetListOfOverlaps();
660  Int_t novlps = overlaps->GetEntriesFast();
661  TNamed *obj;
662  TString name;
663  for (Int_t i=0; i<novlps; i++) {
664  obj = (TNamed*)overlaps->At(i);
665  if (novlps<1000) name = TString::Format("ov%03d", i);
666  else name = TString::Format("ov%06d", i);
667  obj->SetName(name);
668  }
669  if (novlps) Info("CheckOverlaps", "Number of illegal overlaps/extrusions for volume %s: %d\n", GetName(), novlps);
670  }
671 }
672 
673 ////////////////////////////////////////////////////////////////////////////////
674 /// Tests for checking the shape navigation algorithms. See TGeoShape::CheckShape()
675 
676 void TGeoVolume::CheckShape(Int_t testNo, Int_t nsamples, Option_t *option)
677 {
678  fShape->CheckShape(testNo,nsamples,option);
679 }
680 
681 ////////////////////////////////////////////////////////////////////////////////
682 /// Clean data of the volume.
683 
685 {
686  ClearNodes();
687  ClearShape();
688 }
689 
690 ////////////////////////////////////////////////////////////////////////////////
691 /// Clear the shape of this volume from the list held by the current manager.
692 
694 {
696 }
697 
698 ////////////////////////////////////////////////////////////////////////////////
699 /// check for negative parameters in shapes.
700 
702 {
703  if (fShape->IsRunTimeShape()) {
704  Error("CheckShapes", "volume %s has run-time shape", GetName());
705  InspectShape();
706  return;
707  }
708  if (!fNodes) return;
710  TGeoNode *node = 0;
711  TGeoNode *new_node;
712  const TGeoShape *shape = 0;
713  TGeoVolume *old_vol;
714  for (Int_t i=0; i<nd; i++) {
715  node=(TGeoNode*)fNodes->At(i);
716  // check if node has name
717  if (!node->GetName()[0]) printf("Daughter %i of volume %s - NO NAME!!!\n",
718  i, GetName());
719  old_vol = node->GetVolume();
720  shape = old_vol->GetShape();
721  if (shape->IsRunTimeShape()) {
722 // printf(" Node %s/%s has shape with negative parameters. \n",
723 // GetName(), node->GetName());
724 // old_vol->InspectShape();
725  // make a copy of the node
726  new_node = node->MakeCopyNode();
727  if (!new_node) {
728  Fatal("CheckShapes", "Cannot make copy node for %s", node->GetName());
729  return;
730  }
731  TGeoShape *new_shape = shape->GetMakeRuntimeShape(fShape, node->GetMatrix());
732  if (!new_shape) {
733  Error("CheckShapes","cannot resolve runtime shape for volume %s/%s\n",
734  GetName(),old_vol->GetName());
735  continue;
736  }
737  TGeoVolume *new_volume = old_vol->MakeCopyVolume(new_shape);
738 // printf(" new volume %s shape params :\n", new_volume->GetName());
739 // new_volume->InspectShape();
740  new_node->SetVolume(new_volume);
741  // decouple the old node and put the new one instead
742  fNodes->AddAt(new_node, i);
743 // new_volume->CheckShapes();
744  }
745  }
746 }
747 
748 ////////////////////////////////////////////////////////////////////////////////
749 /// Count total number of subnodes starting from this volume, nlevels down
750 /// - option = 0 (default) - count only once per volume
751 /// - option = 1 - count every time
752 /// - option = 2 - count volumes on visible branches
753 /// - option = 3 - return maximum level counted already with option = 0
754 
756 {
757  static Int_t maxlevel = 0;
758  static Int_t nlev = 0;
759 
760  if (option<0 || option>3) option = 0;
761  Int_t visopt = 0;
762  Int_t nd = GetNdaughters();
763  Bool_t last = (!nlevels || !nd)?kTRUE:kFALSE;
764  switch (option) {
765  case 0:
766  if (fNtotal) return fNtotal;
767  case 1:
768  fNtotal = 1;
769  break;
770  case 2:
771  visopt = fGeoManager->GetVisOption();
772  if (!IsVisDaughters()) last = kTRUE;
773  switch (visopt) {
775  fNtotal = (IsVisible())?1:0;
776  break;
778  fNtotal = (IsVisible() && last)?1:0;
779  }
780  if (!IsVisibleDaughters()) return fNtotal;
781  break;
782  case 3:
783  return maxlevel;
784  }
785  if (last) return fNtotal;
786  if (gGeoManager->GetTopVolume() == this) {
787  maxlevel=0;
788  nlev = 0;
789  }
790  if (nlev>maxlevel) maxlevel = nlev;
791  TGeoNode *node;
792  TGeoVolume *vol;
793  nlev++;
794  for (Int_t i=0; i<nd; i++) {
795  node = GetNode(i);
796  vol = node->GetVolume();
797  fNtotal += vol->CountNodes(nlevels-1, option);
798  }
799  nlev--;
800  return fNtotal;
801 }
802 
803 ////////////////////////////////////////////////////////////////////////////////
804 /// Return TRUE if volume and all daughters are invisible.
805 
807 {
808  if (IsVisible()) return kFALSE;
809  Int_t nd = GetNdaughters();
810  for (Int_t i=0; i<nd; i++) if (GetNode(i)->GetVolume()->IsVisible()) return kFALSE;
811  return kTRUE;
812 }
813 
814 ////////////////////////////////////////////////////////////////////////////////
815 /// Make volume and each of it daughters (in)visible.
816 
818 {
819  SetAttVisibility(!flag);
820  Int_t nd = GetNdaughters();
821  TObjArray *list = new TObjArray(nd+1);
822  list->Add(this);
823  TGeoVolume *vol;
824  for (Int_t i=0; i<nd; i++) {
825  vol = GetNode(i)->GetVolume();
826  vol->SetAttVisibility(!flag);
827  list->Add(vol);
828  }
829  TIter next(gROOT->GetListOfBrowsers());
830  TBrowser *browser = 0;
831  while ((browser=(TBrowser*)next())) {
832  for (Int_t i=0; i<nd+1; i++) {
833  vol = (TGeoVolume*)list->At(i);
834  browser->CheckObjectItem(vol, !flag);
835  }
836  browser->Refresh();
837  }
838  delete list;
840 }
841 
842 ////////////////////////////////////////////////////////////////////////////////
843 /// Return TRUE if volume contains nodes
844 
846 {
847  return kTRUE;
848 }
849 
850 ////////////////////////////////////////////////////////////////////////////////
851 /// check if the visibility and attributes are the default ones
852 
854 {
855  if (!IsVisible()) return kFALSE;
856  if (GetLineColor() != gStyle->GetLineColor()) return kFALSE;
857  if (GetLineStyle() != gStyle->GetLineStyle()) return kFALSE;
858  if (GetLineWidth() != gStyle->GetLineWidth()) return kFALSE;
859  return kTRUE;
860 }
861 
862 ////////////////////////////////////////////////////////////////////////////////
863 /// True if this is the top volume of the geometry
864 
866 {
867  if (fGeoManager->GetTopVolume() == this) return kTRUE;
868  return kFALSE;
869 }
870 
871 ////////////////////////////////////////////////////////////////////////////////
872 /// Check if the painter is currently ray-tracing the content of this volume.
873 
875 {
876  return TGeoAtt::IsVisRaytrace();
877 }
878 
879 ////////////////////////////////////////////////////////////////////////////////
880 /// Inspect the material for this volume.
881 
883 {
884  GetMaterial()->Print();
885 }
886 
887 ////////////////////////////////////////////////////////////////////////////////
888 /// Import a volume from a file.
889 
890 TGeoVolume *TGeoVolume::Import(const char *filename, const char *name, Option_t * /*option*/)
891 {
892  if (!gGeoManager) gGeoManager = new TGeoManager("geometry","");
893  if (!filename) return 0;
894  TGeoVolume *volume = 0;
895  if (strstr(filename,".gdml")) {
896  // import from a gdml file
897  } else {
898  // import from a root file
900  TFile *f = TFile::Open(filename);
901  if (!f || f->IsZombie()) {
902  printf("Error: TGeoVolume::Import : Cannot open file %s\n", filename);
903  return 0;
904  }
905  if (name && name[0]) {
906  volume = (TGeoVolume*)f->Get(name);
907  } else {
908  TIter next(f->GetListOfKeys());
909  TKey *key;
910  while ((key = (TKey*)next())) {
911  if (strcmp(key->GetClassName(),"TGeoVolume") != 0) continue;
912  volume = (TGeoVolume*)key->ReadObj();
913  break;
914  }
915  }
916  delete f;
917  }
918  if (!volume) return NULL;
919  volume->RegisterYourself();
920  return volume;
921 }
922 
923 ////////////////////////////////////////////////////////////////////////////////
924 /// Export this volume to a file.
925 ///
926 /// - Case 1: root file or root/xml file
927 /// if filename end with ".root". The key will be named name
928 /// if filename end with ".xml" a root/xml file is produced.
929 ///
930 /// - Case 2: C++ script
931 /// if filename end with ".C"
932 ///
933 /// - Case 3: gdml file
934 /// if filename end with ".gdml"
935 ///
936 /// NOTE that to use this option, the PYTHONPATH must be defined like
937 /// export PYTHONPATH=$ROOTSYS/lib:$ROOTSYS/gdml
938 ///
939 
940 Int_t TGeoVolume::Export(const char *filename, const char *name, Option_t *option)
941 {
942  TString sfile(filename);
943  if (sfile.Contains(".C")) {
944  //Save volume as a C++ script
945  Info("Export","Exporting volume %s as C++ code", GetName());
946  SaveAs(filename, "");
947  return 1;
948  }
949  if (sfile.Contains(".gdml")) {
950  //Save geometry as a gdml file
951  Info("Export","Exporting %s as gdml code - not implemented yet", GetName());
952  return 0;
953  }
954  if (sfile.Contains(".root") || sfile.Contains(".xml")) {
955  //Save volume in a root file
956  Info("Export","Exporting %s as root file.", GetName());
957  TString opt(option);
958  if (!opt.Length()) opt = "recreate";
959  TFile *f = TFile::Open(filename,opt.Data());
960  if (!f || f->IsZombie()) {
961  Error("Export","Cannot open file");
962  return 0;
963  }
964  TString keyname(name);
965  if (keyname.IsNull()) keyname = GetName();
966  Int_t nbytes = Write(keyname);
967  delete f;
968  return nbytes;
969  }
970  return 0;
971 }
972 
973 ////////////////////////////////////////////////////////////////////////////////
974 /// Actualize matrix of node indexed <inode>
975 
976 void TGeoVolume::cd(Int_t inode) const
977 {
978  if (fFinder) fFinder->cd(inode-fFinder->GetDivIndex());
979 }
980 
981 ////////////////////////////////////////////////////////////////////////////////
982 /// Add a TGeoNode to the list of nodes. This is the usual method for adding
983 /// daughters inside the container volume.
984 
985 void TGeoVolume::AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t * /*option*/)
986 {
987  TGeoMatrix *matrix = mat;
988  if (matrix==0) matrix = gGeoIdentity;
989  else matrix->RegisterYourself();
990  if (!vol) {
991  Error("AddNode", "Volume is NULL");
992  return;
993  }
994  if (!vol->IsValid()) {
995  Error("AddNode", "Won't add node with invalid shape");
996  printf("### invalid volume was : %s\n", vol->GetName());
997  return;
998  }
999  if (!fNodes) fNodes = new TObjArray();
1000 
1001  if (fFinder) {
1002  // volume already divided.
1003  Error("AddNode", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no, GetName());
1004  return;
1005  }
1006 
1007  TGeoNodeMatrix *node = 0;
1008  node = new TGeoNodeMatrix(vol, matrix);
1009  node->SetMotherVolume(this);
1010  fNodes->Add(node);
1011  TString name = TString::Format("%s_%d", vol->GetName(), copy_no);
1012 // if (fNodes->FindObject(name))
1013 // Warning("AddNode", "Volume %s : added node %s with same name", GetName(), name.Data());
1014  node->SetName(name);
1015  node->SetNumber(copy_no);
1016  fRefCount++;
1017  vol->Grab();
1018 }
1019 
1020 ////////////////////////////////////////////////////////////////////////////////
1021 /// Add a division node to the list of nodes. The method is called by
1022 /// TGeoVolume::Divide() for creating the division nodes.
1023 
1024 void TGeoVolume::AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset, Option_t * /*option*/)
1025 {
1026  if (!vol) {
1027  Error("AddNodeOffset", "invalid volume");
1028  return;
1029  }
1030  if (!vol->IsValid()) {
1031  Error("AddNode", "Won't add node with invalid shape");
1032  printf("### invalid volume was : %s\n", vol->GetName());
1033  return;
1034  }
1035  if (!fNodes) fNodes = new TObjArray();
1036  TGeoNode *node = new TGeoNodeOffset(vol, copy_no, offset);
1037  node->SetMotherVolume(this);
1038  fNodes->Add(node);
1039  TString name = TString::Format("%s_%d", vol->GetName(), copy_no+1);
1040  node->SetName(name);
1041  node->SetNumber(copy_no+1);
1042  vol->Grab();
1043 }
1044 
1045 ////////////////////////////////////////////////////////////////////////////////
1046 /// Add a TGeoNode to the list of nodes. This is the usual method for adding
1047 /// daughters inside the container volume.
1048 
1050 {
1051  if (!vol) {
1052  Error("AddNodeOverlap", "Volume is NULL");
1053  return;
1054  }
1055  if (!vol->IsValid()) {
1056  Error("AddNodeOverlap", "Won't add node with invalid shape");
1057  printf("### invalid volume was : %s\n", vol->GetName());
1058  return;
1059  }
1060  if (vol->IsAssembly()) {
1061  Warning("AddNodeOverlap", "Declaring assembly %s as possibly overlapping inside %s not allowed. Using AddNode instead !",vol->GetName(),GetName());
1062  AddNode(vol, copy_no, mat, option);
1063  return;
1064  }
1065  TGeoMatrix *matrix = mat;
1066  if (matrix==0) matrix = gGeoIdentity;
1067  else matrix->RegisterYourself();
1068  if (!fNodes) fNodes = new TObjArray();
1069 
1070  if (fFinder) {
1071  // volume already divided.
1072  Error("AddNodeOverlap", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no, GetName());
1073  return;
1074  }
1075 
1076  TGeoNodeMatrix *node = new TGeoNodeMatrix(vol, matrix);
1077  node->SetMotherVolume(this);
1078  fNodes->Add(node);
1079  TString name = TString::Format("%s_%d", vol->GetName(), copy_no);
1080  if (fNodes->FindObject(name))
1081  Warning("AddNode", "Volume %s : added node %s with same name", GetName(), name.Data());
1082  node->SetName(name);
1083  node->SetNumber(copy_no);
1084  node->SetOverlapping();
1085  if (vol->GetMedium() == fMedium)
1086  node->SetVirtual();
1087  vol->Grab();
1088 }
1089 
1090 ////////////////////////////////////////////////////////////////////////////////
1091 /// Division a la G3. The volume will be divided along IAXIS (see shape classes), in NDIV
1092 /// slices, from START with given STEP. The division volumes will have medium number NUMED.
1093 /// If NUMED=0 they will get the medium number of the divided volume (this). If NDIV<=0,
1094 /// all range of IAXIS will be divided and the resulting number of divisions will be centered on
1095 /// IAXIS. If STEP<=0, the real STEP will be computed as the full range of IAXIS divided by NDIV.
1096 /// Options (case insensitive):
1097 /// - N - divide all range in NDIV cells (same effect as STEP<=0) (GSDVN in G3)
1098 /// - NX - divide range starting with START in NDIV cells (GSDVN2 in G3)
1099 /// - S - divide all range with given STEP. NDIV is computed and divisions will be centered
1100 /// in full range (same effect as NDIV<=0) (GSDVS, GSDVT in G3)
1101 /// - SX - same as DVS, but from START position. (GSDVS2, GSDVT2 in G3)
1102 
1103 TGeoVolume *TGeoVolume::Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed, Option_t *option)
1104 {
1105  if (fFinder) {
1106  // volume already divided.
1107  Fatal("Divide","volume %s already divided", GetName());
1108  return 0;
1109  }
1110  TString opt(option);
1111  opt.ToLower();
1112  TString stype = fShape->ClassName();
1113  if (!fNodes) fNodes = new TObjArray();
1114  Double_t xlo, xhi, range;
1115  range = fShape->GetAxisRange(iaxis, xlo, xhi);
1116  // for phi divisions correct the range
1117  if (!strcmp(fShape->GetAxisName(iaxis), "PHI")) {
1118  if ((start-xlo)<-1E-3) start+=360.;
1119  if (TGeoShape::IsSameWithinTolerance(range,360)) {
1120  xlo = start;
1121  xhi = start+range;
1122  }
1123  }
1124  if (range <=0) {
1125  InspectShape();
1126  Fatal("Divide", "cannot divide volume %s (%s) on %s axis", GetName(), stype.Data(), fShape->GetAxisName(iaxis));
1127  return 0;
1128  }
1129  if (ndiv<=0 || opt.Contains("s")) {
1130  if (step<=0) {
1131  Fatal("Divide", "invalid division type for volume %s : ndiv=%i, step=%g", GetName(), ndiv, step);
1132  return 0;
1133  }
1134  if (opt.Contains("x")) {
1135  if ((xlo-start)>1E-3 || (xhi-start)<-1E-3) {
1136  Fatal("Divide", "invalid START=%g for division on axis %s of volume %s. Range is (%g, %g)",
1137  start, fShape->GetAxisName(iaxis), GetName(), xlo, xhi);
1138  return 0;
1139  }
1140  xlo = start;
1141  range = xhi-xlo;
1142  }
1143  ndiv = Int_t((range+0.1*step)/step);
1144  Double_t ddx = range - ndiv*step;
1145  // always center the division in this case
1146  if (ddx>1E-3) Warning("Divide", "division of volume %s on %s axis (ndiv=%d) will be centered in the full range",
1147  GetName(), fShape->GetAxisName(iaxis), ndiv);
1148  start = xlo + 0.5*ddx;
1149  }
1150  if (step<=0 || opt.Contains("n")) {
1151  if (opt.Contains("x")) {
1152  if ((xlo-start)>1E-3 || (xhi-start)<-1E-3) {
1153  Fatal("Divide", "invalid START=%g for division on axis %s of volume %s. Range is (%g, %g)",
1154  start, fShape->GetAxisName(iaxis), GetName(), xlo, xhi);
1155  return 0;
1156  }
1157  xlo = start;
1158  range = xhi-xlo;
1159  }
1160  step = range/ndiv;
1161  start = xlo;
1162  }
1163 
1164  Double_t end = start+ndiv*step;
1165  if (((start-xlo)<-1E-3) || ((end-xhi)>1E-3)) {
1166  Fatal("Divide", "division of volume %s on axis %s exceed range (%g, %g)",
1167  GetName(), fShape->GetAxisName(iaxis), xlo, xhi);
1168  return 0;
1169  }
1170  TGeoVolume *voldiv = fShape->Divide(this, divname, iaxis, ndiv, start, step);
1171  if (numed) {
1172  TGeoMedium *medium = fGeoManager->GetMedium(numed);
1173  if (!medium) {
1174  Fatal("Divide", "invalid medium number %d for division volume %s", numed, divname);
1175  return voldiv;
1176  }
1177  voldiv->SetMedium(medium);
1178  if (medium->GetMaterial()) medium->GetMaterial()->SetUsed();
1179  }
1180  return voldiv;
1181 }
1182 
1183 ////////////////////////////////////////////////////////////////////////////////
1184 /// compute the closest distance of approach from point px,py to this volume
1185 
1187 {
1190  Int_t dist = 9999;
1191  if (!painter) return dist;
1192  dist = painter->DistanceToPrimitiveVol(this, px, py);
1193  return dist;
1194 }
1195 
1196 ////////////////////////////////////////////////////////////////////////////////
1197 /// draw top volume according to option
1198 
1200 {
1205  if (!IsVisContainers()) SetVisLeaves();
1206  if (option && option[0] > 0) {
1207  painter->DrawVolume(this, option);
1208  } else {
1209  painter->DrawVolume(this, gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
1210  }
1211 }
1212 
1213 ////////////////////////////////////////////////////////////////////////////////
1214 /// draw only this volume
1215 
1217 {
1218  if (IsAssembly()) {
1219  Info("DrawOnly", "Volume assemblies do not support this option.");
1220  return;
1221  }
1223  SetVisOnly();
1226  if (option && option[0] > 0) {
1227  painter->DrawVolume(this, option);
1228  } else {
1229  painter->DrawVolume(this, gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
1230  }
1231 }
1232 
1233 ////////////////////////////////////////////////////////////////////////////////
1234 /// Perform an extensive sampling to find which type of voxelization is
1235 /// most efficient.
1236 
1238 {
1239  printf("Optimizing volume %s ...\n", GetName());
1241  return painter->TestVoxels(this);
1242 }
1243 
1244 ////////////////////////////////////////////////////////////////////////////////
1245 /// Print volume info
1246 
1248 {
1249  printf("== Volume: %s type %s positioned %d times\n", GetName(), ClassName(), fRefCount);
1250  InspectShape();
1251  InspectMaterial();
1252 }
1253 
1254 ////////////////////////////////////////////////////////////////////////////////
1255 /// paint volume
1256 
1258 {
1260  painter->SetTopVolume(this);
1261 // painter->Paint(option);
1262  if (option && option[0] > 0) {
1263  painter->Paint(option);
1264  } else {
1265  painter->Paint(gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
1266  }
1267 }
1268 
1269 ////////////////////////////////////////////////////////////////////////////////
1270 /// Print the voxels for this volume.
1271 
1273 {
1274  if (fVoxels) fVoxels->Print();
1275 }
1276 
1277 ////////////////////////////////////////////////////////////////////////////////
1278 /// Recreate the content of the other volume without pointer copying. Voxels are
1279 /// ignored and supposed to be created in a later step via Voxelize.
1280 
1282 {
1283  Int_t nd = other->GetNdaughters();
1284  if (!nd) return;
1285  TGeoPatternFinder *finder = other->GetFinder();
1286  if (finder) {
1287  Int_t iaxis = finder->GetDivAxis();
1288  Int_t ndiv = finder->GetNdiv();
1289  Double_t start = finder->GetStart();
1290  Double_t step = finder->GetStep();
1291  Int_t numed = other->GetNode(0)->GetVolume()->GetMedium()->GetId();
1292  TGeoVolume *voldiv = Divide(other->GetNode(0)->GetVolume()->GetName(), iaxis, ndiv, start, step, numed);
1293  voldiv->ReplayCreation(other->GetNode(0)->GetVolume());
1294  return;
1295  }
1296  for (Int_t i=0; i<nd; i++) {
1297  TGeoNode *node = other->GetNode(i);
1298  if (node->IsOverlapping()) AddNodeOverlap(node->GetVolume(), node->GetNumber(), node->GetMatrix());
1299  else AddNode(node->GetVolume(), node->GetNumber(), node->GetMatrix());
1300  }
1301 }
1302 
1303 ////////////////////////////////////////////////////////////////////////////////
1304 /// print nodes
1305 
1307 {
1308  Int_t nd = GetNdaughters();
1309  for (Int_t i=0; i<nd; i++) {
1310  printf("%s\n", GetNode(i)->GetName());
1311  cd(i);
1312  GetNode(i)->GetMatrix()->Print();
1313  }
1314 }
1315 ////////////////////////////////////////////////////////////////////////////////
1316 /// Generate a lego plot fot the top volume, according to option.
1317 
1319  Int_t nphi, Double_t phimin, Double_t phimax,
1320  Double_t rmin, Double_t rmax, Option_t *option)
1321 {
1323  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
1324  if (old_vol!=this) fGeoManager->SetTopVolume(this);
1325  else old_vol=0;
1326  TH2F *hist = p->LegoPlot(ntheta, themin, themax, nphi, phimin, phimax, rmin, rmax, option);
1327  hist->Draw("lego1sph");
1328  return hist;
1329 }
1330 
1331 ////////////////////////////////////////////////////////////////////////////////
1332 /// Register the volume and all materials/media/matrices/shapes to the manager.
1333 
1335 {
1336  if (fGeoManager->GetListOfVolumes()->FindObject(this)) return;
1337  // Register volume
1338  fGeoManager->AddVolume(this);
1339  // Register shape
1341  if (fShape->IsComposite()) {
1343  comp->RegisterYourself();
1344  } else {
1346  }
1347  }
1348  // Register medium/material
1353  }
1354  // Register matrices for nodes.
1355  TGeoMatrix *matrix;
1356  TGeoNode *node;
1357  Int_t nd = GetNdaughters();
1358  Int_t i;
1359  for (i=0; i<nd; i++) {
1360  node = GetNode(i);
1361  matrix = node->GetMatrix();
1362  if (!matrix->IsRegistered()) matrix->RegisterYourself();
1363  else if (!fGeoManager->GetListOfMatrices()->FindObject(matrix)) {
1364  fGeoManager->GetListOfMatrices()->Add(matrix);
1365  }
1366  }
1367  // Call RegisterYourself recursively
1368  for (i=0; i<nd; i++) GetNode(i)->GetVolume()->RegisterYourself(option);
1369 }
1370 
1371 ////////////////////////////////////////////////////////////////////////////////
1372 /// Draw random points in the bounding box of this volume.
1373 
1375 {
1377  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
1378  if (old_vol!=this) fGeoManager->SetTopVolume(this);
1379  else old_vol=0;
1380  fGeoManager->RandomPoints(this, npoints, option);
1381  if (old_vol) fGeoManager->SetTopVolume(old_vol);
1382 }
1383 
1384 ////////////////////////////////////////////////////////////////////////////////
1385 /// Random raytracing method.
1386 
1387 void TGeoVolume::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm)
1388 {
1390  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
1391  if (old_vol!=this) fGeoManager->SetTopVolume(this);
1392  else old_vol=0;
1393  fGeoManager->RandomRays(nrays, startx, starty, startz, target_vol, check_norm);
1394  if (old_vol) fGeoManager->SetTopVolume(old_vol);
1395 }
1396 
1397 ////////////////////////////////////////////////////////////////////////////////
1398 /// Draw this volume with current settings and perform raytracing in the pad.
1399 
1401 {
1405  Bool_t drawn = (painter->GetDrawnVolume()==this)?kTRUE:kFALSE;
1406  if (!drawn) {
1407  painter->DrawVolume(this, "");
1409  painter->ModifiedPad();
1410  return;
1411  }
1413  painter->ModifiedPad();
1414 }
1415 
1416 ////////////////////////////////////////////////////////////////////////////////
1417 /// Save geometry having this as top volume as a C++ macro.
1418 
1419 void TGeoVolume::SaveAs(const char *filename, Option_t *option) const
1420 {
1421  if (!filename) return;
1422  std::ofstream out;
1423  out.open(filename, std::ios::out);
1424  if (out.bad()) {
1425  Error("SavePrimitive", "Bad file name: %s", filename);
1426  return;
1427  }
1428  if (fGeoManager->GetTopVolume() != this) fGeoManager->SetTopVolume((TGeoVolume*)this);
1429 
1430  TString fname(filename);
1431  Int_t ind = fname.Index(".");
1432  if (ind>0) fname.Remove(ind);
1433  out << "void "<<fname<<"() {" << std::endl;
1434  out << " gSystem->Load(\"libGeom\");" << std::endl;
1435  ((TGeoVolume*)this)->SavePrimitive(out,option);
1436  out << "}" << std::endl;
1437 }
1438 
1439 ////////////////////////////////////////////////////////////////////////////////
1440 /// Connect user-defined extension to the volume. The volume "grabs" a copy, so
1441 /// the original object can be released by the producer. Release the previously
1442 /// connected extension if any.
1443 ///
1444 /// NOTE: This interface is intended for user extensions and is guaranteed not
1445 /// to be used by TGeo
1446 
1448 {
1450  fUserExtension = 0;
1451  if (ext) fUserExtension = ext->Grab();
1452 }
1453 
1454 ////////////////////////////////////////////////////////////////////////////////
1455 /// Connect framework defined extension to the volume. The volume "grabs" a copy,
1456 /// so the original object can be released by the producer. Release the previously
1457 /// connected extension if any.
1458 ///
1459 /// NOTE: This interface is intended for the use by TGeo and the users should
1460 /// NOT connect extensions using this method
1461 
1463 {
1465  fFWExtension = 0;
1466  if (ext) fFWExtension = ext->Grab();
1467 }
1468 
1469 ////////////////////////////////////////////////////////////////////////////////
1470 /// Get a copy of the user extension pointer. The user must call Release() on
1471 /// the copy pointer once this pointer is not needed anymore (equivalent to
1472 /// delete() after calling new())
1473 
1475 {
1476  if (fUserExtension) return fUserExtension->Grab();
1477  return 0;
1478 }
1479 
1480 ////////////////////////////////////////////////////////////////////////////////
1481 /// Get a copy of the framework extension pointer. The user must call Release() on
1482 /// the copy pointer once this pointer is not needed anymore (equivalent to
1483 /// delete() after calling new())
1484 
1486 {
1487  if (fFWExtension) return fFWExtension->Grab();
1488  return 0;
1489 }
1490 
1491 ////////////////////////////////////////////////////////////////////////////////
1492 /// Save a primitive as a C++ statement(s) on output stream "out".
1493 
1494 void TGeoVolume::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1495 {
1496  out.precision(6);
1497  out.setf(std::ios::fixed);
1498  Int_t i,icopy;
1499  Int_t nd = GetNdaughters();
1500  TGeoVolume *dvol;
1501  TGeoNode *dnode;
1502  TGeoMatrix *matrix;
1503 
1504  // check if we need to save shape/volume
1505  Bool_t mustDraw = kFALSE;
1506  if (fGeoManager->GetGeomPainter()->GetTopVolume()==this) mustDraw = kTRUE;
1507  if (!option[0]) {
1509  out << " new TGeoManager(\"" << fGeoManager->GetName() << "\", \"" << fGeoManager->GetTitle() << "\");" << std::endl << std::endl;
1510 // if (mustDraw) out << " Bool_t mustDraw = kTRUE;" << std::endl;
1511 // else out << " Bool_t mustDraw = kFALSE;" << std::endl;
1512  out << " Double_t dx,dy,dz;" << std::endl;
1513  out << " Double_t dx1, dx2, dy1, dy2;" << std::endl;
1514  out << " Double_t vert[20], par[20];" << std::endl;
1515  out << " Double_t theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2;" << std::endl;
1516  out << " Double_t twist;" << std::endl;
1517  out << " Double_t origin[3];" << std::endl;
1518  out << " Double_t rmin, rmax, rmin1, rmax1, rmin2, rmax2;" << std::endl;
1519  out << " Double_t r, rlo, rhi;" << std::endl;
1520  out << " Double_t phi1, phi2;" << std::endl;
1521  out << " Double_t a,b;" << std::endl;
1522  out << " Double_t point[3], norm[3];" << std::endl;
1523  out << " Double_t rin, stin, rout, stout;" << std::endl;
1524  out << " Double_t thx, phx, thy, phy, thz, phz;" << std::endl;
1525  out << " Double_t alpha, theta1, theta2, phi1, phi2, dphi;" << std::endl;
1526  out << " Double_t tr[3], rot[9];" << std::endl;
1527  out << " Double_t z, density, radl, absl, w;" << std::endl;
1528  out << " Double_t lx,ly,lz,tx,ty,tz;" << std::endl;
1529  out << " Double_t xvert[50], yvert[50];" << std::endl;
1530  out << " Double_t zsect,x0,y0,scale0;" << std::endl;
1531  out << " Int_t nel, numed, nz, nedges, nvert;" << std::endl;
1532  out << " TGeoBoolNode *pBoolNode = 0;" << std::endl << std::endl;
1533  // first save materials/media
1534  out << " // MATERIALS, MIXTURES AND TRACKING MEDIA" << std::endl;
1535  SavePrimitive(out, "m");
1536  // then, save matrices
1537  out << std::endl << " // TRANSFORMATION MATRICES" << std::endl;
1538  SavePrimitive(out, "x");
1539  // save this volume and shape
1540  SavePrimitive(out, "s");
1541  out << std::endl << " // SET TOP VOLUME OF GEOMETRY" << std::endl;
1542  out << " gGeoManager->SetTopVolume(" << GetPointerName() << ");" << std::endl;
1543  // save daughters
1544  out << std::endl << " // SHAPES, VOLUMES AND GEOMETRICAL HIERARCHY" << std::endl;
1545  SavePrimitive(out, "d");
1546  out << std::endl << " // CLOSE GEOMETRY" << std::endl;
1547  out << " gGeoManager->CloseGeometry();" << std::endl;
1548  if (mustDraw) {
1549  if (!IsRaytracing()) out << " gGeoManager->GetTopVolume()->Draw();" << std::endl;
1550  else out << " gGeoManager->GetTopVolume()->Raytrace();" << std::endl;
1551  }
1552  return;
1553  }
1554  // check if we need to save shape/volume
1555  if (!strcmp(option, "s")) {
1556  // create the shape for this volume
1558  if (!IsAssembly()) {
1559  fShape->SavePrimitive(out,option);
1560  out << " // Volume: " << GetName() << std::endl;
1561  if (fMedium) out << " " << GetPointerName() << " = new TGeoVolume(\"" << GetName() << "\"," << fShape->GetPointerName() << ", "<< fMedium->GetPointerName() << ");" << std::endl;
1562  else out << " " << GetPointerName() << " = new TGeoVolume(\"" << GetName() << "\"," << fShape->GetPointerName() << ");" << std::endl;
1563 
1564  } else {
1565  out << " // Assembly: " << GetName() << std::endl;
1566  out << " " << GetPointerName() << " = new TGeoVolumeAssembly(\"" << GetName() << "\"" << ");" << std::endl;
1567  }
1568  if (fLineColor != 1) out << " " << GetPointerName() << "->SetLineColor(" << fLineColor << ");" << std::endl;
1569  if (fLineWidth != 1) out << " " << GetPointerName() << "->SetLineWidth(" << fLineWidth << ");" << std::endl;
1570  if (fLineStyle != 1) out << " " << GetPointerName() << "->SetLineStyle(" << fLineStyle << ");" << std::endl;
1571  if (!IsVisible() && !IsAssembly()) out << " " << GetPointerName() << "->SetVisibility(kFALSE);" << std::endl;
1572  if (!IsVisibleDaughters()) out << " " << GetPointerName() << "->VisibleDaughters(kFALSE);" << std::endl;
1573  if (IsVisContainers()) out << " " << GetPointerName() << "->SetVisContainers(kTRUE);" << std::endl;
1574  if (IsVisLeaves()) out << " " << GetPointerName() << "->SetVisLeaves(kTRUE);" << std::endl;
1576  }
1577  // check if we need to save the media
1578  if (!strcmp(option, "m")) {
1579  if (fMedium) fMedium->SavePrimitive(out,option);
1580  for (i=0; i<nd; i++) {
1581  dvol = GetNode(i)->GetVolume();
1582  dvol->SavePrimitive(out,option);
1583  }
1584  return;
1585  }
1586  // check if we need to save the matrices
1587  if (!strcmp(option, "x")) {
1588  if (fFinder) {
1589  dvol = GetNode(0)->GetVolume();
1590  dvol->SavePrimitive(out,option);
1591  return;
1592  }
1593  for (i=0; i<nd; i++) {
1594  dnode = GetNode(i);
1595  matrix = dnode->GetMatrix();
1596  if (!matrix->IsIdentity()) matrix->SavePrimitive(out,option);
1597  dnode->GetVolume()->SavePrimitive(out,option);
1598  }
1599  return;
1600  }
1601  // check if we need to save volume daughters
1602  if (!strcmp(option, "d")) {
1603  if (!nd) return;
1604  if (TestAttBit(TGeoAtt::kSaveNodesAtt)) return;
1606  if (fFinder) {
1607  // volume divided: generate volume->Divide()
1608  dnode = GetNode(0);
1609  dvol = dnode->GetVolume();
1610  out << " TGeoVolume *" << dvol->GetPointerName() << " = ";
1611  out << GetPointerName() << "->Divide(\"" << dvol->GetName() << "\", ";
1612  fFinder->SavePrimitive(out,option);
1613  if (fMedium != dvol->GetMedium()) {
1614  out << ", " << dvol->GetMedium()->GetId();
1615  }
1616  out << ");" << std::endl;
1617  dvol->SavePrimitive(out,"d");
1618  return;
1619  }
1620  for (i=0; i<nd; i++) {
1621  dnode = GetNode(i);
1622  dvol = dnode->GetVolume();
1623  dvol->SavePrimitive(out,"s");
1624  matrix = dnode->GetMatrix();
1625  icopy = dnode->GetNumber();
1626  // generate AddNode()
1627  out << " " << GetPointerName() << "->AddNode";
1628  if (dnode->IsOverlapping()) out << "Overlap";
1629  out << "(" << dvol->GetPointerName() << ", " << icopy;
1630  if (!matrix->IsIdentity()) out << ", " << matrix->GetPointerName();
1631  out << ");" << std::endl;
1632  }
1633  // Recursive loop to daughters
1634  for (i=0; i<nd; i++) {
1635  dnode = GetNode(i);
1636  dvol = dnode->GetVolume();
1637  dvol->SavePrimitive(out,"d");
1638  }
1639  }
1640 }
1641 
1642 ////////////////////////////////////////////////////////////////////////////////
1643 /// Reset SavePrimitive bits.
1644 
1646 {
1650 }
1651 
1652 ////////////////////////////////////////////////////////////////////////////////
1653 /// Execute mouse actions on this volume.
1654 
1656 {
1658  if (!painter) return;
1659  painter->ExecuteVolumeEvent(this, event, px, py);
1660 }
1661 
1662 ////////////////////////////////////////////////////////////////////////////////
1663 /// search a daughter inside the list of nodes
1664 
1666 {
1667  return ((TGeoNode*)fNodes->FindObject(name));
1668 }
1669 
1670 ////////////////////////////////////////////////////////////////////////////////
1671 /// Get the index of a daughter within check_list by providing the node pointer.
1672 
1673 Int_t TGeoVolume::GetNodeIndex(const TGeoNode *node, Int_t *check_list, Int_t ncheck) const
1674 {
1675  TGeoNode *current = 0;
1676  for (Int_t i=0; i<ncheck; i++) {
1677  current = (TGeoNode*)fNodes->At(check_list[i]);
1678  if (current==node) return check_list[i];
1679  }
1680  return -1;
1681 }
1682 
1683 ////////////////////////////////////////////////////////////////////////////////
1684 /// get index number for a given daughter
1685 
1687 {
1688  TGeoNode *current = 0;
1689  Int_t nd = GetNdaughters();
1690  if (!nd) return -1;
1691  for (Int_t i=0; i<nd; i++) {
1692  current = (TGeoNode*)fNodes->At(i);
1693  if (current==node) return i;
1694  }
1695  return -1;
1696 }
1697 
1698 ////////////////////////////////////////////////////////////////////////////////
1699 /// Get volume info for the browser.
1700 
1702 {
1703  TGeoVolume *vol = (TGeoVolume*)this;
1705  if (!painter) return 0;
1706  return (char*)painter->GetVolumeInfo(vol, px, py);
1707 }
1708 
1709 ////////////////////////////////////////////////////////////////////////////////
1710 /// Returns true if cylindrical voxelization is optimal.
1711 
1713 {
1714  Int_t nd = GetNdaughters();
1715  if (!nd) return kFALSE;
1716  Int_t id;
1717  Int_t ncyl = 0;
1718  TGeoNode *node;
1719  for (id=0; id<nd; id++) {
1720  node = (TGeoNode*)fNodes->At(id);
1721  ncyl += node->GetOptimalVoxels();
1722  }
1723  if (ncyl>(nd/2)) return kTRUE;
1724  return kFALSE;
1725 }
1726 
1727 ////////////////////////////////////////////////////////////////////////////////
1728 /// Provide a pointer name containing uid.
1729 
1731 {
1732  static TString name;
1733  name = TString::Format("p%s_%lx", GetName(), (ULong_t)this);
1734  return (char*)name.Data();
1735 }
1736 
1737 ////////////////////////////////////////////////////////////////////////////////
1738 /// Getter for optimization structure.
1739 
1741 {
1742  if (fVoxels && !fVoxels->IsInvalid()) return fVoxels;
1743  return NULL;
1744 }
1745 
1746 ////////////////////////////////////////////////////////////////////////////////
1747 /// Move perspective view focus to this volume
1748 
1750 {
1752  if (painter) painter->GrabFocus();
1753 }
1754 
1755 ////////////////////////////////////////////////////////////////////////////////
1756 /// Returns true if the volume is an assembly or a scaled assembly.
1757 
1759 {
1760  return fShape->IsAssembly();
1761 }
1762 
1763 ////////////////////////////////////////////////////////////////////////////////
1764 /// Clone this volume.
1765 /// build a volume with same name, shape and medium
1766 
1768 {
1769  TGeoVolume *vol = new TGeoVolume(GetName(), fShape, fMedium);
1770  Int_t i;
1771  // copy volume attributes
1772  vol->SetLineColor(GetLineColor());
1773  vol->SetLineStyle(GetLineStyle());
1774  vol->SetLineWidth(GetLineWidth());
1775  vol->SetFillColor(GetFillColor());
1776  vol->SetFillStyle(GetFillStyle());
1777  // copy other attributes
1778  Int_t nbits = 8*sizeof(UInt_t);
1779  for (i=0; i<nbits; i++)
1780  vol->SetAttBit(1<<i, TGeoAtt::TestAttBit(1<<i));
1781  for (i=14; i<24; i++)
1782  vol->SetBit(1<<i, TestBit(1<<i));
1783 
1784  // copy field
1785  vol->SetField(fField);
1786  // Set bits
1787  for (i=0; i<nbits; i++)
1788  vol->SetBit(1<<i, TObject::TestBit(1<<i));
1789  vol->SetBit(kVolumeClone);
1790  // copy nodes
1791 // CloneNodesAndConnect(vol);
1792  vol->MakeCopyNodes(this);
1793  // if volume is divided, copy finder
1794  vol->SetFinder(fFinder);
1795  // copy voxels
1796  TGeoVoxelFinder *voxels = 0;
1797  if (fVoxels) {
1798  voxels = new TGeoVoxelFinder(vol);
1799  vol->SetVoxelFinder(voxels);
1800  }
1801  // copy option, uid
1802  vol->SetOption(fOption);
1803  vol->SetNumber(fNumber);
1804  vol->SetNtotal(fNtotal);
1805  // copy extensions
1809  return vol;
1810 }
1811 
1812 ////////////////////////////////////////////////////////////////////////////////
1813 /// Clone the array of nodes.
1814 
1816 {
1817  if (!fNodes) return;
1818  TGeoNode *node;
1819  Int_t nd = fNodes->GetEntriesFast();
1820  if (!nd) return;
1821  // create new list of nodes
1822  TObjArray *list = new TObjArray(nd);
1823  // attach it to new volume
1824  newmother->SetNodes(list);
1825 // ((TObject*)newmother)->SetBit(kVolumeImportNodes);
1826  for (Int_t i=0; i<nd; i++) {
1827  //create copies of nodes and add them to list
1828  node = GetNode(i)->MakeCopyNode();
1829  if (!node) {
1830  Fatal("CloneNodesAndConnect", "cannot make copy node");
1831  return;
1832  }
1833  node->SetMotherVolume(newmother);
1834  list->Add(node);
1835  }
1836 }
1837 
1838 ////////////////////////////////////////////////////////////////////////////////
1839 /// make a new list of nodes and copy all nodes of other volume inside
1840 
1842 {
1843  Int_t nd = other->GetNdaughters();
1844  if (!nd) return;
1845  if (fNodes) {
1847  delete fNodes;
1848  }
1849  fNodes = new TObjArray();
1850  for (Int_t i=0; i<nd; i++) fNodes->Add(other->GetNode(i));
1852 }
1853 
1854 ////////////////////////////////////////////////////////////////////////////////
1855 /// make a copy of this volume
1856 /// build a volume with same name, shape and medium
1857 
1859 {
1860  TGeoVolume *vol = new TGeoVolume(GetName(), newshape, fMedium);
1861  // copy volume attributes
1862  vol->SetVisibility(IsVisible());
1863  vol->SetLineColor(GetLineColor());
1864  vol->SetLineStyle(GetLineStyle());
1865  vol->SetLineWidth(GetLineWidth());
1866  vol->SetFillColor(GetFillColor());
1867  vol->SetFillStyle(GetFillStyle());
1868  // copy field
1869  vol->SetField(fField);
1870  // if divided, copy division object
1871  if (fFinder) {
1872 // Error("MakeCopyVolume", "volume %s divided", GetName());
1873  vol->SetFinder(fFinder);
1874  }
1875  // Copy extensions
1878  CloneNodesAndConnect(vol);
1879 // ((TObject*)vol)->SetBit(kVolumeImportNodes);
1880  ((TObject*)vol)->SetBit(kVolumeClone);
1882  return vol;
1883 }
1884 
1885 ////////////////////////////////////////////////////////////////////////////////
1886 /// Make a copy of this volume which is reflected with respect to XY plane.
1887 
1888 TGeoVolume *TGeoVolume::MakeReflectedVolume(const char *newname) const
1889 {
1890  static TMap map(100);
1891  if (!fGeoManager->IsClosed()) {
1892  Error("MakeReflectedVolume", "Geometry must be closed.");
1893  return NULL;
1894  }
1895  TGeoVolume *vol = (TGeoVolume*)map.GetValue(this);
1896  if (vol) {
1897  if (newname && newname[0]) vol->SetName(newname);
1898  return vol;
1899  }
1900 // printf("Making reflection for volume: %s\n", GetName());
1901  vol = CloneVolume();
1902  if (!vol) {
1903  Fatal("MakeReflectedVolume", "Cannot clone volume %s\n", GetName());
1904  return 0;
1905  }
1906  map.Add((TObject*)this, vol);
1907  if (newname && newname[0]) vol->SetName(newname);
1908  delete vol->GetNodes();
1909  vol->SetNodes(NULL);
1911  CloneNodesAndConnect(vol);
1912  // The volume is now properly cloned, but with the same shape.
1913  // Reflect the shape (if any) and connect it.
1914  if (fShape) {
1915  TGeoShape *reflected_shape =
1916  TGeoScaledShape::MakeScaledShape("", fShape, new TGeoScale(1.,1.,-1.));
1917  vol->SetShape(reflected_shape);
1918  }
1919  // Reflect the daughters.
1920  Int_t nd = vol->GetNdaughters();
1921  if (!nd) return vol;
1922  TGeoNodeMatrix *node;
1923  TGeoMatrix *local, *local_cloned;
1924  TGeoVolume *new_vol;
1925  if (!vol->GetFinder()) {
1926  for (Int_t i=0; i<nd; i++) {
1927  node = (TGeoNodeMatrix*)vol->GetNode(i);
1928  local = node->GetMatrix();
1929 // printf("%s before\n", node->GetName());
1930 // local->Print();
1931  Bool_t reflected = local->IsReflection();
1932  local_cloned = new TGeoCombiTrans(*local);
1933  local_cloned->RegisterYourself();
1934  node->SetMatrix(local_cloned);
1935  if (!reflected) {
1936  // We need to reflect only the translation and propagate to daughters.
1937  // H' = Sz * H * Sz
1938  local_cloned->ReflectZ(kTRUE);
1939  local_cloned->ReflectZ(kFALSE);
1940 // printf("%s after\n", node->GetName());
1941 // node->GetMatrix()->Print();
1942  new_vol = node->GetVolume()->MakeReflectedVolume();
1943  node->SetVolume(new_vol);
1944  continue;
1945  }
1946  // The next daughter is already reflected, so reflect on Z everything and stop
1947  local_cloned->ReflectZ(kTRUE); // rot + tr
1948 // printf("%s already reflected... After:\n", node->GetName());
1949 // node->GetMatrix()->Print();
1950  }
1951  if (vol->GetVoxels()) vol->GetVoxels()->Voxelize();
1952  return vol;
1953  }
1954  // Volume is divided, so we have to reflect the division.
1955 // printf(" ... divided %s\n", fFinder->ClassName());
1956  TGeoPatternFinder *new_finder = fFinder->MakeCopy(kTRUE);
1957  if (!new_finder) {
1958  Fatal("MakeReflectedVolume", "Could not copy finder for volume %s", GetName());
1959  return 0;
1960  }
1961  new_finder->SetVolume(vol);
1962  vol->SetFinder(new_finder);
1963  TGeoNodeOffset *nodeoff;
1964  new_vol = 0;
1965  for (Int_t i=0; i<nd; i++) {
1966  nodeoff = (TGeoNodeOffset*)vol->GetNode(i);
1967  nodeoff->SetFinder(new_finder);
1968  new_vol = nodeoff->GetVolume()->MakeReflectedVolume();
1969  nodeoff->SetVolume(new_vol);
1970  }
1971  return vol;
1972 }
1973 
1974 ////////////////////////////////////////////////////////////////////////////////
1975 /// Set this volume as the TOP one (the whole geometry starts from here)
1976 
1978 {
1979  fGeoManager->SetTopVolume(this);
1980 }
1981 
1982 ////////////////////////////////////////////////////////////////////////////////
1983 /// Set the current tracking point.
1984 
1986 {
1987  fGeoManager->SetCurrentPoint(x,y,z);
1988 }
1989 
1990 ////////////////////////////////////////////////////////////////////////////////
1991 /// set the shape associated with this volume
1992 
1994 {
1995  if (!shape) {
1996  Error("SetShape", "No shape");
1997  return;
1998  }
1999  fShape = (TGeoShape*)shape;
2000 }
2001 
2002 ////////////////////////////////////////////////////////////////////////////////
2003 /// sort nodes by decreasing volume of the bounding box. ONLY nodes comes first,
2004 /// then overlapping nodes and finally division nodes.
2005 
2007 {
2008  if (!Valid()) {
2009  Error("SortNodes", "Bounding box not valid");
2010  return;
2011  }
2012  Int_t nd = GetNdaughters();
2013 // printf("volume : %s, nd=%i\n", GetName(), nd);
2014  if (!nd) return;
2015  if (fFinder) return;
2016 // printf("Nodes for %s\n", GetName());
2017  Int_t id = 0;
2018  TGeoNode *node = 0;
2019  TObjArray *nodes = new TObjArray(nd);
2020  Int_t inode = 0;
2021  // first put ONLY's
2022  for (id=0; id<nd; id++) {
2023  node = GetNode(id);
2024  if (node->InheritsFrom(TGeoNodeOffset::Class()) || node->IsOverlapping()) continue;
2025  nodes->Add(node);
2026 // printf("inode %i ONLY\n", inode);
2027  inode++;
2028  }
2029  // second put overlapping nodes
2030  for (id=0; id<nd; id++) {
2031  node = GetNode(id);
2032  if (node->InheritsFrom(TGeoNodeOffset::Class()) || (!node->IsOverlapping())) continue;
2033  nodes->Add(node);
2034 // printf("inode %i MANY\n", inode);
2035  inode++;
2036  }
2037  // third put the divided nodes
2038  if (fFinder) {
2039  fFinder->SetDivIndex(inode);
2040  for (id=0; id<nd; id++) {
2041  node = GetNode(id);
2042  if (!node->InheritsFrom(TGeoNodeOffset::Class())) continue;
2043  nodes->Add(node);
2044 // printf("inode %i DIV\n", inode);
2045  inode++;
2046  }
2047  }
2048  if (inode != nd) printf(" volume %s : number of nodes does not match!!!\n", GetName());
2049  delete fNodes;
2050  fNodes = nodes;
2051 }
2052 
2053 ////////////////////////////////////////////////////////////////////////////////
2054 /// Stream an object of class TGeoVolume.
2055 
2056 void TGeoVolume::Streamer(TBuffer &R__b)
2057 {
2058  if (R__b.IsReading()) {
2059  R__b.ReadClassBuffer(TGeoVolume::Class(), this);
2060  if (fVoxels && fVoxels->IsInvalid()) Voxelize("");
2061  } else {
2062  if (!fVoxels) {
2063  R__b.WriteClassBuffer(TGeoVolume::Class(), this);
2064  } else {
2065  if (!fGeoManager->IsStreamingVoxels()) {
2066  TGeoVoxelFinder *voxels = fVoxels;
2067  fVoxels = 0;
2068  R__b.WriteClassBuffer(TGeoVolume::Class(), this);
2069  fVoxels = voxels;
2070  } else {
2071  R__b.WriteClassBuffer(TGeoVolume::Class(), this);
2072  }
2073  }
2074  }
2075 }
2076 
2077 ////////////////////////////////////////////////////////////////////////////////
2078 /// Set the current options (none implemented)
2079 
2080 void TGeoVolume::SetOption(const char *option)
2081 {
2082  fOption = option;
2083 }
2084 
2085 ////////////////////////////////////////////////////////////////////////////////
2086 /// Set the line color.
2087 
2089 {
2090  TAttLine::SetLineColor(lcolor);
2091 }
2092 
2093 ////////////////////////////////////////////////////////////////////////////////
2094 /// Set the line style.
2095 
2097 {
2098  TAttLine::SetLineStyle(lstyle);
2099 }
2100 
2101 ////////////////////////////////////////////////////////////////////////////////
2102 /// Set the line width.
2103 
2105 {
2106  TAttLine::SetLineWidth(lwidth);
2107 }
2108 
2109 ////////////////////////////////////////////////////////////////////////////////
2110 /// get the pointer to a daughter node
2111 
2112 TGeoNode *TGeoVolume::GetNode(const char *name) const
2113 {
2114  if (!fNodes) return 0;
2115  TGeoNode *node = (TGeoNode *)fNodes->FindObject(name);
2116  return node;
2117 }
2118 
2119 ////////////////////////////////////////////////////////////////////////////////
2120 /// get the total size in bytes for this volume
2121 
2123 {
2124  Int_t count = 28+2+6+4+0; // TNamed+TGeoAtt+TAttLine+TAttFill+TAtt3D
2125  count += fName.Capacity() + fTitle.Capacity(); // name+title
2126  count += 7*sizeof(char*); // fShape + fMedium + fFinder + fField + fNodes + 2 extensions
2127  count += fOption.Capacity(); // fOption
2128  if (fShape) count += fShape->GetByteCount();
2129  if (fFinder) count += fFinder->GetByteCount();
2130  if (fNodes) {
2131  count += 32 + 4*fNodes->GetEntries(); // TObjArray
2132  TIter next(fNodes);
2133  TGeoNode *node;
2134  while ((node=(TGeoNode*)next())) count += node->GetByteCount();
2135  }
2136  return count;
2137 }
2138 
2139 ////////////////////////////////////////////////////////////////////////////////
2140 /// loop all nodes marked as overlaps and find overlapping brothers
2141 
2143 {
2144  if (!Valid()) {
2145  Error("FindOverlaps","Bounding box not valid");
2146  return;
2147  }
2148  if (!fVoxels) return;
2149  Int_t nd = GetNdaughters();
2150  if (!nd) return;
2151  TGeoNode *node=0;
2152  Int_t inode = 0;
2153  for (inode=0; inode<nd; inode++) {
2154  node = GetNode(inode);
2155  if (!node->IsOverlapping()) continue;
2156  fVoxels->FindOverlaps(inode);
2157  }
2158 }
2159 
2160 ////////////////////////////////////////////////////////////////////////////////
2161 /// Remove an existing daughter.
2162 
2164 {
2165  if (!fNodes || !fNodes->GetEntriesFast()) return;
2166  if (!fNodes->Remove(node)) return;
2167  fNodes->Compress();
2168  if (fVoxels) fVoxels->SetNeedRebuild();
2169  if (IsAssembly()) fShape->ComputeBBox();
2170 }
2171 
2172 ////////////////////////////////////////////////////////////////////////////////
2173 /// Replace an existing daughter with a new volume having the same name but
2174 /// possibly a new shape, position or medium. Not allowed for positioned assemblies.
2175 /// For division cells, the new shape/matrix are ignored.
2176 
2178 {
2179  Int_t ind = GetIndex(nodeorig);
2180  if (ind < 0) return NULL;
2181  TGeoVolume *oldvol = nodeorig->GetVolume();
2182  if (oldvol->IsAssembly()) {
2183  Error("ReplaceNode", "Cannot replace node %s since it is an assembly", nodeorig->GetName());
2184  return NULL;
2185  }
2186  TGeoShape *shape = oldvol->GetShape();
2187  if (newshape && !nodeorig->IsOffset()) shape = newshape;
2188  TGeoMedium *med = oldvol->GetMedium();
2189  if (newmed) med = newmed;
2190  // Make a new volume
2191  TGeoVolume *vol = new TGeoVolume(oldvol->GetName(), shape, med);
2192  // copy volume attributes
2193  vol->SetVisibility(oldvol->IsVisible());
2194  vol->SetLineColor(oldvol->GetLineColor());
2195  vol->SetLineStyle(oldvol->GetLineStyle());
2196  vol->SetLineWidth(oldvol->GetLineWidth());
2197  vol->SetFillColor(oldvol->GetFillColor());
2198  vol->SetFillStyle(oldvol->GetFillStyle());
2199  // copy field
2200  vol->SetField(oldvol->GetField());
2201  // Make a copy of the node
2202  TGeoNode *newnode = nodeorig->MakeCopyNode();
2203  if (!newnode) {
2204  Fatal("ReplaceNode", "Cannot make copy node for %s", nodeorig->GetName());
2205  return 0;
2206  }
2207  // Change the volume for the new node
2208  newnode->SetVolume(vol);
2209  // Replace the matrix
2210  if (newpos && !nodeorig->IsOffset()) {
2211  TGeoNodeMatrix *nodemat = (TGeoNodeMatrix*)newnode;
2212  nodemat->SetMatrix(newpos);
2213  }
2214  // Replace nodeorig with new one
2215  fNodes->RemoveAt(ind);
2216  fNodes->AddAt(newnode, ind);
2217  if (fVoxels) fVoxels->SetNeedRebuild();
2218  if (IsAssembly()) fShape->ComputeBBox();
2219  return newnode;
2220 }
2221 
2222 ////////////////////////////////////////////////////////////////////////////////
2223 /// Select this volume as matching an arbitrary criteria. The volume is added to
2224 /// a static list and the flag TGeoVolume::kVolumeSelected is set. All flags need
2225 /// to be reset at the end by calling the method with CLEAR=true. This will also clear
2226 /// the list.
2227 
2229 {
2230  static TObjArray array(256);
2231  static Int_t len = 0;
2232  Int_t i;
2233  TObject *vol;
2234  if (clear) {
2235  for (i=0; i<len; i++) {
2236  vol = array.At(i);
2238  }
2239  array.Clear();
2240  len = 0;
2241  return;
2242  }
2244  array.AddAtAndExpand(this, len++);
2245 }
2246 
2247 ////////////////////////////////////////////////////////////////////////////////
2248 /// set visibility of this volume
2249 
2251 {
2255  TSeqCollection *brlist = gROOT->GetListOfBrowsers();
2256  TIter next(brlist);
2257  TBrowser *browser = 0;
2258  while ((browser=(TBrowser*)next())) {
2259  browser->CheckObjectItem(this, vis);
2260  browser->Refresh();
2261  }
2262 }
2263 
2264 ////////////////////////////////////////////////////////////////////////////////
2265 /// Set visibility for containers.
2266 
2268 {
2270  if (fGeoManager && fGeoManager->IsClosed()) {
2273  }
2274 }
2275 
2276 ////////////////////////////////////////////////////////////////////////////////
2277 /// Set visibility for leaves.
2278 
2280 {
2281  TGeoAtt::SetVisLeaves(flag);
2282  if (fGeoManager && fGeoManager->IsClosed()) {
2285  }
2286 }
2287 
2288 ////////////////////////////////////////////////////////////////////////////////
2289 /// Set visibility for leaves.
2290 
2292 {
2293  if (IsAssembly()) return;
2294  TGeoAtt::SetVisOnly(flag);
2295  if (fGeoManager && fGeoManager->IsClosed()) {
2298  }
2299 }
2300 
2301 ////////////////////////////////////////////////////////////////////////////////
2302 /// Check if the shape of this volume is valid.
2303 
2305 {
2306  return fShape->IsValidBox();
2307 }
2308 
2309 ////////////////////////////////////////////////////////////////////////////////
2310 /// Find a daughter node having VOL as volume and fill TGeoManager::fHMatrix
2311 /// with its global matrix.
2312 
2314 {
2315  if (vol == this) return kTRUE;
2316  Int_t nd = GetNdaughters();
2317  if (!nd) return kFALSE;
2318  TGeoHMatrix *global = fGeoManager->GetHMatrix();
2319  if (!global) return kFALSE;
2320  TGeoNode *dnode;
2321  TGeoVolume *dvol;
2322  TGeoMatrix *local;
2323  Int_t i;
2324  for (i=0; i<nd; i++) {
2325  dnode = GetNode(i);
2326  dvol = dnode->GetVolume();
2327  if (dvol == vol) {
2328  local = dnode->GetMatrix();
2329  global->MultiplyLeft(local);
2330  return kTRUE;
2331  }
2332  }
2333  for (i=0; i<nd; i++) {
2334  dnode = GetNode(i);
2335  dvol = dnode->GetVolume();
2336  if (dvol->FindMatrixOfDaughterVolume(vol)) return kTRUE;
2337  }
2338  return kFALSE;
2339 }
2340 
2341 ////////////////////////////////////////////////////////////////////////////////
2342 /// set visibility for daughters
2343 
2345 {
2346  SetVisDaughters(vis);
2349 }
2350 
2351 ////////////////////////////////////////////////////////////////////////////////
2352 /// build the voxels for this volume
2353 
2355 {
2356  if (!Valid()) {
2357  Error("Voxelize", "Bounding box not valid");
2358  return;
2359  }
2360  // do not voxelize divided volumes
2361  if (fFinder) return;
2362  // or final leaves
2363  Int_t nd = GetNdaughters();
2364  if (!nd) return;
2365  // If this is an assembly, re-compute bounding box
2366  if (IsAssembly()) fShape->ComputeBBox();
2367  // delete old voxelization if any
2368  if (fVoxels) {
2369  if (!TObject::TestBit(kVolumeClone)) delete fVoxels;
2370  fVoxels = 0;
2371  }
2372  // Create the voxels structure
2373  fVoxels = new TGeoVoxelFinder(this);
2374  fVoxels->Voxelize(option);
2375  if (fVoxels) {
2376  if (fVoxels->IsInvalid()) {
2377  delete fVoxels;
2378  fVoxels = 0;
2379  }
2380  }
2381 }
2382 
2383 ////////////////////////////////////////////////////////////////////////////////
2384 /// Estimate the weight of a volume (in kg) with SIGMA(M)/M better than PRECISION.
2385 /// Option can contain : v - verbose, a - analytical (default)
2386 
2388 {
2390  if (top != this) fGeoManager->SetTopVolume(this);
2391  else top = 0;
2392  Double_t weight = fGeoManager->Weight(precision, option);
2393  if (top) fGeoManager->SetTopVolume(top);
2394  return weight;
2395 }
2396 
2397 ////////////////////////////////////////////////////////////////////////////////
2398 /// Analytical computation of the weight.
2399 
2401 {
2402  Double_t capacity = Capacity();
2403  Double_t weight = 0.0;
2404  Int_t i;
2405  Int_t nd = GetNdaughters();
2406  TGeoVolume *daughter;
2407  for (i=0; i<nd; i++) {
2408  daughter = GetNode(i)->GetVolume();
2409  weight += daughter->WeightA();
2410  capacity -= daughter->Capacity();
2411  }
2412  Double_t density = 0.0;
2413  if (!IsAssembly()) {
2414  if (fMedium) density = fMedium->GetMaterial()->GetDensity();
2415  if (density<0.01) density = 0.0; // do not weight gases
2416  }
2417  weight += 0.001*capacity * density; //[kg]
2418  return weight;
2419 }
2420 
2422 
2423 
2424 ////////////////////////////////////////////////////////////////////////////////
2425 /// dummy constructor
2426 
2428 {
2429  fVolumes = 0;
2430  fDivision = 0;
2431  fNumed = 0;
2432  fNdiv = 0;
2433  fAxis = 0;
2434  fStart = 0;
2435  fStep = 0;
2436  fAttSet = kFALSE;
2438 }
2439 
2440 ////////////////////////////////////////////////////////////////////////////////
2441 /// default constructor
2442 
2444 {
2445  fVolumes = new TObjArray();
2446  fDivision = 0;
2447  fNumed = 0;
2448  fNdiv = 0;
2449  fAxis = 0;
2450  fStart = 0;
2451  fStep = 0;
2452  fAttSet = kFALSE;
2454  SetName(name);
2455  SetMedium(med);
2456  fGeoManager->AddVolume(this);
2457 // printf("--- volume multi %s created\n", name);
2458 }
2459 
2460 ////////////////////////////////////////////////////////////////////////////////
2461 ///copy constructor
2462 
2463 TGeoVolumeMulti::TGeoVolumeMulti(const TGeoVolumeMulti& vm) :
2464  TGeoVolume(vm),
2465  fVolumes(vm.fVolumes),
2466  fDivision(vm.fDivision),
2467  fNumed(vm.fNumed),
2468  fNdiv(vm.fNdiv),
2469  fAxis(vm.fAxis),
2470  fStart(vm.fStart),
2471  fStep(vm.fStep),
2472  fAttSet(vm.fAttSet)
2473 {
2474 }
2475 
2476 ////////////////////////////////////////////////////////////////////////////////
2477 ///assignment operator
2478 
2479 TGeoVolumeMulti& TGeoVolumeMulti::operator=(const TGeoVolumeMulti& vm)
2480 {
2481  if(this!=&vm) {
2483  fVolumes=vm.fVolumes;
2484  fDivision=vm.fDivision;
2485  fNumed=vm.fNumed;
2486  fNdiv=vm.fNdiv;
2487  fAxis=vm.fAxis;
2488  fStart=vm.fStart;
2489  fStep=vm.fStep;
2490  fAttSet=vm.fAttSet;
2491  }
2492  return *this;
2493 }
2494 
2495 ////////////////////////////////////////////////////////////////////////////////
2496 /// Destructor
2497 
2499 {
2500  if (fVolumes) delete fVolumes;
2501 }
2502 
2503 ////////////////////////////////////////////////////////////////////////////////
2504 /// Add a volume with valid shape to the list of volumes. Copy all existing nodes
2505 /// to this volume
2506 
2508 {
2509  Int_t idx = fVolumes->GetEntriesFast();
2510  fVolumes->AddAtAndExpand(vol,idx);
2511  vol->SetUniqueID(idx+1);
2512  TGeoVolumeMulti *div;
2513  TGeoVolume *cell;
2514  if (fDivision) {
2515  div = (TGeoVolumeMulti*)vol->Divide(fDivision->GetName(), fAxis, fNdiv, fStart, fStep, fNumed, fOption.Data());
2516  if (!div) {
2517  Fatal("AddVolume", "Cannot divide volume %s", vol->GetName());
2518  return;
2519  }
2520  for (Int_t i=0; i<div->GetNvolumes(); i++) {
2521  cell = div->GetVolume(i);
2522  fDivision->AddVolume(cell);
2523  }
2524  }
2525  if (fNodes) {
2526  Int_t nd = fNodes->GetEntriesFast();
2527  for (Int_t id=0; id<nd; id++) {
2528  TGeoNode *node = (TGeoNode*)fNodes->At(id);
2529  Bool_t many = node->IsOverlapping();
2530  if (many) vol->AddNodeOverlap(node->GetVolume(), node->GetNumber(), node->GetMatrix());
2531  else vol->AddNode(node->GetVolume(), node->GetNumber(), node->GetMatrix());
2532  }
2533  }
2534 // vol->MakeCopyNodes(this);
2535 }
2536 
2537 
2538 ////////////////////////////////////////////////////////////////////////////////
2539 /// Add a new node to the list of nodes. This is the usual method for adding
2540 /// daughters inside the container volume.
2541 
2543 {
2544  TGeoVolume::AddNode(vol, copy_no, mat, option);
2545  Int_t nvolumes = fVolumes->GetEntriesFast();
2546  TGeoVolume *volume = 0;
2547  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2548  volume = GetVolume(ivo);
2549  volume->SetLineColor(GetLineColor());
2550  volume->SetLineStyle(GetLineStyle());
2551  volume->SetLineWidth(GetLineWidth());
2552  volume->SetVisibility(IsVisible());
2553  volume->AddNode(vol, copy_no, mat, option);
2554  }
2555 // printf("--- vmulti %s : node %s added to %i components\n", GetName(), vol->GetName(), nvolumes);
2556 }
2557 
2558 ////////////////////////////////////////////////////////////////////////////////
2559 /// Add a new node to the list of nodes, This node is possibly overlapping with other
2560 /// daughters of the volume or extruding the volume.
2561 
2563 {
2564  TGeoVolume::AddNodeOverlap(vol, copy_no, mat, option);
2565  Int_t nvolumes = fVolumes->GetEntriesFast();
2566  TGeoVolume *volume = 0;
2567  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2568  volume = GetVolume(ivo);
2569  volume->SetLineColor(GetLineColor());
2570  volume->SetLineStyle(GetLineStyle());
2571  volume->SetLineWidth(GetLineWidth());
2572  volume->SetVisibility(IsVisible());
2573  volume->AddNodeOverlap(vol, copy_no, mat, option);
2574  }
2575 // printf("--- vmulti %s : node ovlp %s added to %i components\n", GetName(), vol->GetName(), nvolumes);
2576 }
2577 
2578 ////////////////////////////////////////////////////////////////////////////////
2579 /// Returns the last shape.
2580 
2582 {
2584  if (!vol) return 0;
2585  return vol->GetShape();
2586 }
2587 
2588 ////////////////////////////////////////////////////////////////////////////////
2589 /// division of multiple volumes
2590 
2591 TGeoVolume *TGeoVolumeMulti::Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed, const char *option)
2592 {
2593  if (fDivision) {
2594  Error("Divide", "volume %s already divided", GetName());
2595  return 0;
2596  }
2597  Int_t nvolumes = fVolumes->GetEntriesFast();
2598  TGeoMedium *medium = fMedium;
2599  if (numed) {
2600  medium = fGeoManager->GetMedium(numed);
2601  if (!medium) {
2602  Error("Divide", "Invalid medium number %d for division volume %s", numed, divname);
2603  medium = fMedium;
2604  }
2605  }
2606  if (!nvolumes) {
2607  // this is a virtual volume
2608  fDivision = new TGeoVolumeMulti(divname, medium);
2609  fNumed = medium->GetId();
2610  fOption = option;
2611  fAxis = iaxis;
2612  fNdiv = ndiv;
2613  fStart = start;
2614  fStep = step;
2615  // nothing else to do at this stage
2616  return fDivision;
2617  }
2618  TGeoVolume *vol = 0;
2619  fDivision = new TGeoVolumeMulti(divname, medium);
2620  if (medium) fNumed = medium->GetId();
2621  fOption = option;
2622  fAxis = iaxis;
2623  fNdiv = ndiv;
2624  fStart = start;
2625  fStep = step;
2626  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2627  vol = GetVolume(ivo);
2628  vol->SetLineColor(GetLineColor());
2629  vol->SetLineStyle(GetLineStyle());
2630  vol->SetLineWidth(GetLineWidth());
2631  vol->SetVisibility(IsVisible());
2632  fDivision->AddVolume(vol->Divide(divname,iaxis,ndiv,start,step, numed, option));
2633  }
2634 // printf("--- volume multi %s (%i volumes) divided\n", GetName(), nvolumes);
2635  if (numed) fDivision->SetMedium(medium);
2636  return fDivision;
2637 }
2638 
2639 ////////////////////////////////////////////////////////////////////////////////
2640 /// Make a copy of this volume
2641 /// build a volume with same name, shape and medium
2642 
2644 {
2645  TGeoVolume *vol = new TGeoVolume(GetName(), newshape, fMedium);
2646  Int_t i=0;
2647  // copy volume attributes
2648  vol->SetVisibility(IsVisible());
2649  vol->SetLineColor(GetLineColor());
2650  vol->SetLineStyle(GetLineStyle());
2651  vol->SetLineWidth(GetLineWidth());
2652  vol->SetFillColor(GetFillColor());
2653  vol->SetFillStyle(GetFillStyle());
2654  // copy field
2655  vol->SetField(fField);
2656  // Copy extensions
2659  // if divided, copy division object
2660 // if (fFinder) {
2661 // Error("MakeCopyVolume", "volume %s divided", GetName());
2662 // vol->SetFinder(fFinder);
2663 // }
2664  if (fDivision) {
2665  TGeoVolume *cell;
2666  TGeoVolumeMulti *div = (TGeoVolumeMulti*)vol->Divide(fDivision->GetName(), fAxis, fNdiv, fStart, fStep, fNumed, fOption.Data());
2667  if (!div) {
2668  Fatal("MakeCopyVolume", "Cannot divide volume %s", vol->GetName());
2669  return 0;
2670  }
2671  for (i=0; i<div->GetNvolumes(); i++) {
2672  cell = div->GetVolume(i);
2673  fDivision->AddVolume(cell);
2674  }
2675  }
2676 
2677  if (!fNodes) return vol;
2678  TGeoNode *node;
2679  Int_t nd = fNodes->GetEntriesFast();
2680  if (!nd) return vol;
2681  // create new list of nodes
2682  TObjArray *list = new TObjArray();
2683  // attach it to new volume
2684  vol->SetNodes(list);
2685  ((TObject*)vol)->SetBit(kVolumeImportNodes);
2686  for (i=0; i<nd; i++) {
2687  //create copies of nodes and add them to list
2688  node = GetNode(i)->MakeCopyNode();
2689  if (!node) {
2690  Fatal("MakeCopyNode", "cannot make copy node for daughter %d of %s", i, GetName());
2691  return 0;
2692  }
2693  node->SetMotherVolume(vol);
2694  list->Add(node);
2695  }
2696  return vol;
2697 }
2698 
2699 ////////////////////////////////////////////////////////////////////////////////
2700 /// Set the line color for all components.
2701 
2703 {
2704  TGeoVolume::SetLineColor(lcolor);
2705  Int_t nvolumes = fVolumes->GetEntriesFast();
2706  TGeoVolume *vol = 0;
2707  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2708  vol = GetVolume(ivo);
2709  vol->SetLineColor(lcolor);
2710  }
2711 }
2712 
2713 ////////////////////////////////////////////////////////////////////////////////
2714 /// Set the line style for all components.
2715 
2717 {
2718  TGeoVolume::SetLineStyle(lstyle);
2719  Int_t nvolumes = fVolumes->GetEntriesFast();
2720  TGeoVolume *vol = 0;
2721  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2722  vol = GetVolume(ivo);
2723  vol->SetLineStyle(lstyle);
2724  }
2725 }
2726 
2727 ////////////////////////////////////////////////////////////////////////////////
2728 /// Set the line width for all components.
2729 
2731 {
2732  TGeoVolume::SetLineWidth(lwidth);
2733  Int_t nvolumes = fVolumes->GetEntriesFast();
2734  TGeoVolume *vol = 0;
2735  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2736  vol = GetVolume(ivo);
2737  vol->SetLineWidth(lwidth);
2738  }
2739 }
2740 
2741 ////////////////////////////////////////////////////////////////////////////////
2742 /// Set medium for a multiple volume.
2743 
2745 {
2746  TGeoVolume::SetMedium(med);
2747  Int_t nvolumes = fVolumes->GetEntriesFast();
2748  TGeoVolume *vol = 0;
2749  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2750  vol = GetVolume(ivo);
2751  vol->SetMedium(med);
2752  }
2753 }
2754 
2755 
2756 ////////////////////////////////////////////////////////////////////////////////
2757 /// Set visibility for all components.
2758 
2760 {
2762  Int_t nvolumes = fVolumes->GetEntriesFast();
2763  TGeoVolume *vol = 0;
2764  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2765  vol = GetVolume(ivo);
2766  vol->SetVisibility(vis);
2767  }
2768 }
2769 
2771 
2772 ////////////////////////////////////////////////////////////////////////////////
2773 /// Constructor.
2774 
2776  fCurrent(-1), fNext(-1)
2777 {
2778 }
2779 
2780 ////////////////////////////////////////////////////////////////////////////////
2781 /// Destructor.
2782 
2784 {
2785 }
2786 
2787 ////////////////////////////////////////////////////////////////////////////////
2788 
2790 {
2791  Int_t tid = TGeoManager::ThreadId();
2792 /*
2793  TThread::Lock();
2794  if (tid >= fThreadSize)
2795  {
2796  Error("GetThreadData", "Thread id=%d bigger than maximum declared thread number %d. \nUse TGeoManager::SetMaxThreads properly !!!",
2797  tid, fThreadSize);
2798  fThreadData.resize(tid + 1);
2799  fThreadSize = tid + 1;
2800  }
2801  if (fThreadData[tid] == 0) fThreadData[tid] = new ThreadData_t;
2802  TThread::UnLock();
2803 */
2804  return *fThreadData[tid];
2805 }
2806 
2807 ////////////////////////////////////////////////////////////////////////////////
2808 
2810 {
2811  TThread::Lock();
2813  std::vector<ThreadData_t*>::iterator i = fThreadData.begin();
2814  while (i != fThreadData.end())
2815  {
2816  delete *i;
2817  ++i;
2818  }
2819  fThreadData.clear();
2820  fThreadSize = 0;
2821  TThread::UnLock();
2822 }
2823 
2824 ////////////////////////////////////////////////////////////////////////////////
2825 
2827 {
2828  TThread::Lock();
2829  // Create assembly thread data here
2830  fThreadData.resize(nthreads);
2831  fThreadSize = nthreads;
2832  for (Int_t tid=0; tid<nthreads; tid++) {
2833  if (fThreadData[tid] == 0) {
2834  fThreadData[tid] = new ThreadData_t;
2835  }
2836  }
2837  TGeoVolume::CreateThreadData(nthreads);
2838  TThread::UnLock();
2839 }
2840 
2841 ////////////////////////////////////////////////////////////////////////////////
2842 
2844 {
2845  return fThreadData[TGeoManager::ThreadId()]->fCurrent;
2846 }
2847 
2848 ////////////////////////////////////////////////////////////////////////////////
2849 
2851 {
2852  return fThreadData[TGeoManager::ThreadId()]->fNext;
2853 }
2854 
2855 ////////////////////////////////////////////////////////////////////////////////
2856 
2858 {
2859  fThreadData[TGeoManager::ThreadId()]->fCurrent = index;
2860 }
2861 
2862 ////////////////////////////////////////////////////////////////////////////////
2863 
2865 {
2866  fThreadData[TGeoManager::ThreadId()]->fNext = index;
2867 }
2868 
2869 ////////////////////////////////////////////////////////////////////////////////
2870 /// Default constructor
2871 
2873  :TGeoVolume()
2874 {
2875  fThreadSize = 0;
2876  CreateThreadData(1);
2877 }
2878 
2879 ////////////////////////////////////////////////////////////////////////////////
2880 /// Constructor. Just the name has to be provided. Assemblies does not have their own
2881 /// shape or medium.
2882 
2884  :TGeoVolume()
2885 {
2886  fName = name;
2887  fName = fName.Strip();
2888  fShape = new TGeoShapeAssembly(this);
2889  if (fGeoManager) fNumber = fGeoManager->AddVolume(this);
2890  fThreadSize = 0;
2891  CreateThreadData(1);
2892 }
2893 
2894 ////////////////////////////////////////////////////////////////////////////////
2895 /// Destructor. The assembly is owner of its "shape".
2896 
2898 {
2899  ClearThreadData();
2900  if (fShape) delete fShape;
2901 }
2902 
2903 ////////////////////////////////////////////////////////////////////////////////
2904 /// Add a component to the assembly.
2905 
2907 {
2908  TGeoVolume::AddNode(vol,copy_no,mat,option);
2909 // ((TGeoShapeAssembly*)fShape)->RecomputeBoxLast();
2910  ((TGeoShapeAssembly*)fShape)->NeedsBBoxRecompute();
2911 }
2912 
2913 ////////////////////////////////////////////////////////////////////////////////
2914 /// Add an overlapping node - not allowed for assemblies.
2915 
2917 {
2918  Warning("AddNodeOverlap", "Declaring assembly %s as possibly overlapping inside %s not allowed. Using AddNode instead !",vol->GetName(),GetName());
2919  AddNode(vol, copy_no, mat, option);
2920 }
2921 
2922 ////////////////////////////////////////////////////////////////////////////////
2923 /// Clone this volume.
2924 /// build a volume with same name, shape and medium
2925 
2927 {
2928  TGeoVolume *vol = new TGeoVolumeAssembly(GetName());
2929  Int_t i;
2930  // copy other attributes
2931  Int_t nbits = 8*sizeof(UInt_t);
2932  for (i=0; i<nbits; i++)
2933  vol->SetAttBit(1<<i, TGeoAtt::TestAttBit(1<<i));
2934  for (i=14; i<24; i++)
2935  vol->SetBit(1<<i, TestBit(1<<i));
2936 
2937  // copy field
2938  vol->SetField(fField);
2939  // Set bits
2940  for (i=0; i<nbits; i++)
2941  vol->SetBit(1<<i, TObject::TestBit(1<<i));
2942  vol->SetBit(kVolumeClone);
2943  // make copy nodes
2944  vol->MakeCopyNodes(this);
2945 // CloneNodesAndConnect(vol);
2946  ((TGeoShapeAssembly*)vol->GetShape())->NeedsBBoxRecompute();
2947  // copy voxels
2948  TGeoVoxelFinder *voxels = 0;
2949  if (fVoxels) {
2950  voxels = new TGeoVoxelFinder(vol);
2951  vol->SetVoxelFinder(voxels);
2952  }
2953  // copy option, uid
2954  vol->SetOption(fOption);
2955  vol->SetNumber(fNumber);
2956  vol->SetNtotal(fNtotal);
2957  return vol;
2958 }
2959 
2960 ////////////////////////////////////////////////////////////////////////////////
2961 /// Division makes no sense for assemblies.
2962 
2964 {
2965  Error("Divide","Assemblies cannot be divided");
2966  return 0;
2967 }
2968 
2969 ////////////////////////////////////////////////////////////////////////////////
2970 /// Assign to the assembly a collection of identical volumes positioned according
2971 /// a predefined pattern. The option can be spaced out or touching depending on the empty
2972 /// space between volumes.
2973 
2975 {
2976  if (fNodes) {
2977  Error("Divide", "Cannot divide assembly %s since it has nodes", GetName());
2978  return NULL;
2979  }
2980  if (fFinder) {
2981  Error("Divide", "Assembly %s already divided", GetName());
2982  return NULL;
2983  }
2984  Int_t ncells = pattern->GetNdiv();
2985  if (!ncells || pattern->GetStep()<=0) {
2986  Error("Divide", "Pattern finder for dividing assembly %s not initialized. Use SetRange() method.", GetName());
2987  return NULL;
2988  }
2989  fFinder = pattern;
2990  TString opt(option);
2991  opt.ToLower();
2992  if (opt.Contains("spacedout")) fFinder->SetSpacedOut(kTRUE);
2993  else fFinder->SetSpacedOut(kFALSE);
2994  // Position volumes
2995  for (Int_t i=0; i<ncells; i++) {
2996  fFinder->cd(i);
2997  TGeoNodeOffset *node = new TGeoNodeOffset(cell, i, 0.);
2998  node->SetFinder(fFinder);
2999  fNodes->Add(node);
3000  }
3001  return cell;
3002 }
3003 
3004 ////////////////////////////////////////////////////////////////////////////////
3005 /// Make a clone of volume VOL but which is an assembly.
3006 
3008 {
3009  if (volorig->IsAssembly() || volorig->IsVolumeMulti()) return 0;
3010  Int_t nd = volorig->GetNdaughters();
3011  if (!nd) return 0;
3012  TGeoVolumeAssembly *vol = new TGeoVolumeAssembly(volorig->GetName());
3013  Int_t i;
3014  // copy other attributes
3015  Int_t nbits = 8*sizeof(UInt_t);
3016  for (i=0; i<nbits; i++)
3017  vol->SetAttBit(1<<i, volorig->TestAttBit(1<<i));
3018  for (i=14; i<24; i++)
3019  vol->SetBit(1<<i, volorig->TestBit(1<<i));
3020 
3021  // copy field
3022  vol->SetField(volorig->GetField());
3023  // Set bits
3024  for (i=0; i<nbits; i++)
3025  vol->SetBit(1<<i, volorig->TestBit(1<<i));
3026  vol->SetBit(kVolumeClone);
3027  // make copy nodes
3028  vol->MakeCopyNodes(volorig);
3029 // volorig->CloneNodesAndConnect(vol);
3030  vol->GetShape()->ComputeBBox();
3031  // copy voxels
3032  TGeoVoxelFinder *voxels = 0;
3033  if (volorig->GetVoxels()) {
3034  voxels = new TGeoVoxelFinder(vol);
3035  vol->SetVoxelFinder(voxels);
3036  }
3037  // copy option, uid
3038  vol->SetOption(volorig->GetOption());
3039  vol->SetNumber(volorig->GetNumber());
3040  vol->SetNtotal(volorig->GetNtotal());
3041  return vol;
3042 }
TString fTitle
Definition: TNamed.h:37
void Add(TObject *obj, const char *name=0, Int_t check=-1)
Add object with name to browser.
Definition: TBrowser.cxx:261
TGeoManager * fGeoManager
Definition: TGeoVolume.h:74
TGeoVolume()
dummy constructor
Definition: TGeoVolume.cxx:448
void CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
virtual TGeoVolume * CloneVolume() const
Clone this volume.
virtual void Paint(Option_t *option="")=0
This method must be overridden if a class wants to paint itself.
void CleanAll()
Clean data of the volume.
Definition: TGeoVolume.cxx:684
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
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:830
TGeoVolumeAssembly()
Thread vector size.
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:49
void CheckShape(Int_t testNo, Int_t nsamples=10000, Option_t *option="")
Test for shape navigation methods.
Definition: TGeoShape.cxx:211
Bool_t IsReading() const
Definition: TBuffer.h:83
void PrintNodes() const
print nodes
Volume families.
Definition: TGeoVolume.h:269
A node containing local transformation.
Definition: TGeoNode.h:161
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
Bool_t IsCheckingOverlaps() const
Definition: TGeoManager.h:385
Ssiz_t Capacity() const
Definition: TString.h:337
An array of TObjects.
Definition: TObjArray.h:39
void SetNodes(TObjArray *nodes)
Definition: TGeoVolume.h:230
void ResetAttBit(UInt_t f)
Definition: TGeoAtt.h:69
virtual void SetLineColor(Color_t lcolor)
Set the line color for all components.
void Print(Option_t *option="") const
print the matrix in 4x4 format
Definition: TGeoMatrix.cxx:536
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
void ClearShape()
Clear the shape of this volume from the list held by the current manager.
Definition: TGeoVolume.cxx:693
virtual void SetLineWidth(Width_t lwidth)
Set the line width for all components.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:899
Bool_t TestAttBit(UInt_t f) const
Definition: TGeoAtt.h:70
static TGeoMedium * fgDummyMedium
Definition: TGeoVolume.h:71
The manager class for any TGeo geometry.
Definition: TGeoManager.h:38
virtual void CreateThreadData(Int_t nthreads)
Definition: TGeoVolume.cxx:432
virtual void SetVisContainers(Bool_t flag=kTRUE)
Set branch type visibility.
Definition: TGeoAtt.cxx:75
char * GetPointerName() const
Provide a pointer name containing uid.
Volume assemblies.
Definition: TGeoVolume.h:320
void Voxelize(Option_t *option)
build the voxels for this volume
void SetFinder(TGeoPatternFinder *finder)
Definition: TGeoVolume.h:247
virtual void ModifiedPad(Bool_t update=kFALSE) const =0
Bool_t IsValid() const
Definition: TGeoShape.h:142
short Style_t
Definition: RtypesCore.h:76
virtual TGeoNode * MakeCopyNode() const
Definition: TGeoNode.h:120
void SetAllIndex()
Assigns uid&#39;s for all materials,media and matrices.
virtual void Voxelize(Option_t *option="")
Voxelize attached volume according to option If the volume is an assembly, make sure the bbox is comp...
TGeoExtension * fUserExtension
Definition: TGeoVolume.h:81
virtual void ClearThreadData() const
TGeoVolume * GetVolume(Int_t id) const
Definition: TGeoVolume.h:291
virtual void ExecuteVolumeEvent(TGeoVolume *volume, Int_t event, Int_t px, Int_t py)=0
void SetVolume(TGeoVolume *vol)
virtual void Clear(Option_t *option="")
Remove all objects from the array.
Definition: TObjArray.cxx:298
void MultiplyLeft(const TGeoMatrix *left)
multiply to the left with an other transformation if right is identity matrix, just return ...
void AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset=0, Option_t *option="")
Add a division node to the list of nodes.
virtual Double_t GetDensity() const
Definition: TGeoMaterial.h:93
Bool_t IsOverlapping() const
Definition: TGeoNode.h:114
void SetVirtual()
Definition: TGeoNode.h:128
const char Option_t
Definition: RtypesCore.h:62
Geometrical transformation package.
Definition: TGeoMatrix.h:40
virtual Int_t GetByteCount() const =0
Visualization and tracking attributes for volumes and nodes.
Definition: TGeoAtt.h:19
ThreadData_t & GetThreadData() const
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:329
virtual void CheckGeometry(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) const =0
virtual Int_t GetByteCount() const
TGeoExtension * fFWExtension
Transient user-defined extension to volumes.
Definition: TGeoVolume.h:82
Bool_t IsStyleDefault() const
check if the visibility and attributes are the default ones
Definition: TGeoVolume.cxx:853
static TGeoMedium * DummyMedium()
Definition: TGeoVolume.cxx:440
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
virtual void CreateThreadData(Int_t)
Definition: TGeoShape.h:70
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
TVirtualGeoPainter * GetPainter() const
Definition: TGeoManager.h:187
virtual void CheckOverlaps(const TGeoVolume *vol, Double_t ovlp=0.1, Option_t *option="") const =0
R__EXTERN TStyle * gStyle
Definition: TStyle.h:418
TGeoVolumeMulti & operator=(const TGeoVolumeMulti &)
assignment operator
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:157
virtual void SetVisibility(Bool_t vis=kTRUE)
Set visibility for this object.
Definition: TGeoAtt.cxx:103
TGeoMaterial * GetMaterial() const
Definition: TGeoMedium.h:54
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
TGeoMedium * fMedium
Definition: TGeoVolume.h:70
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition: TGeoVolume.h:61
Double_t fStart
Definition: TGeoVolume.h:277
virtual void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a TGeoNode to the list of nodes.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:50
virtual void Draw(Option_t *option="")
draw top volume according to option
void RegisterYourself()
Register the shape and all components to TGeoManager class.
virtual void Print(Option_t *option="") const
Print volume info.
Use this attribute class when an object should have 3D capabilities.
Definition: TAtt3D.h:21
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
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:53
virtual void SetVisibility(Bool_t vis=kTRUE)
Set visibility for all components.
#define gROOT
Definition: TROOT.h:364
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:653
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
void InspectShape() const
Definition: TGeoVolume.h:209
void SetTopVolume(TGeoVolume *vol)
Set the top volume and corresponding node as starting point of the geometry.
Int_t GetId() const
Definition: TGeoMedium.h:50
virtual void SetTopVolume(TGeoVolume *vol)=0
Basic string class.
Definition: TString.h:137
Matrix class used for computing global transformations Should NOT be used for node definition...
Definition: TGeoMatrix.h:410
Base class describing materials.
Definition: TGeoMaterial.h:35
virtual void DrawOnly(Option_t *option="")
draw only this volume
virtual TGeoShape * GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix *mat) const =0
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1089
int Int_t
Definition: RtypesCore.h:41
void VisibleDaughters(Bool_t vis=kTRUE)
set visibility for daughters
bool Bool_t
Definition: RtypesCore.h:59
void SetOption(const char *option)
Set the current options (none implemented)
Double_t Capacity() const
Computes the capacity of this [cm^3] as the capacity of its shape.
Definition: TGeoVolume.cxx:606
virtual ~TGeoVolumeAssembly()
Destructor. The assembly is owner of its "shape".
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:44
Int_t GetNdiv() const
void RemoveNode(TGeoNode *node)
Remove an existing daughter.
Bool_t IsAllInvisible() const
Return TRUE if volume and all daughters are invisible.
Definition: TGeoVolume.cxx:806
void ReplayCreation(const TGeoVolume *other)
Recreate the content of the other volume without pointer copying.
void CheckObjectItem(TObject *obj, Bool_t check=kFALSE)
Change status of checkbox for this item.
Definition: TBrowser.cxx:304
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
const char * Class
Definition: TXMLSetup.cxx:64
Bool_t IsVisibleDaughters() const
Definition: TGeoVolume.h:170
Bool_t IsOffset() const
Definition: TGeoNode.h:112
The shape encapsulating an assembly (union) of volumes.
void SetAsTopVolume()
Set this volume as the TOP one (the whole geometry starts from here)
TGeoVoxelFinder * GetVoxels() const
Getter for optimization structure.
virtual Bool_t TestVoxels(TGeoVolume *vol)=0
Bool_t IsVisContainers() const
Definition: TGeoVolume.h:171
void RegisterYourself(Option_t *option="")
Register the volume and all materials/media/matrices/shapes to the manager.
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:41
void SetFWExtension(TGeoExtension *ext)
Connect framework defined extension to the volume.
void Raytrace(Bool_t flag=kTRUE)
Draw this volume with current settings and perform raytracing in the pad.
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
Definition: TGeoShape.cxx:328
TObject * GetField() const
Definition: TGeoVolume.h:190
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:739
virtual Int_t GetByteCount() const
get the total size in bytes for this volume
TList * GetListOfMaterials() const
Definition: TGeoManager.h:461
TGeoHMatrix * GetHMatrix()
Return stored current matrix (global matrix of the next touched node).
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:497
virtual Bool_t IsAssembly() const
Definition: TGeoShape.h:131
Bool_t IsRaytracing() const
Check if the painter is currently ray-tracing the content of this volume.
Definition: TGeoVolume.cxx:874
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3907
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:755
TObjArray * GetNodes()
Definition: TGeoVolume.h:183
Int_t fNtotal
Definition: TGeoVolume.h:79
void Browse(TBrowser *b)
How to browse a volume.
Definition: TGeoVolume.cxx:572
virtual void CreateThreadData(Int_t nthreads)
Int_t GetNdaughters() const
Definition: TGeoVolume.h:362
void SetVisRaytrace(Bool_t flag=kTRUE)
Definition: TGeoAtt.h:72
TList * GetListOfMedia() const
Definition: TGeoManager.h:462
TObject * fField
pointer to TGeoManager owning this volume
Definition: TGeoVolume.h:76
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:40
Sequenceable collection abstract base class.
virtual ~TGeoVolume()
Destructor.
Definition: TGeoVolume.cxx:555
void SetUserPaintVolume(TGeoVolume *vol)
Definition: TGeoManager.h:212
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:188
TGeoPatternFinder * GetFinder() const
Definition: TGeoVolume.h:191
Fill Area Attributes class.
Definition: TAttFill.h:24
Double_t x[n]
Definition: legend1.C:17
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...
virtual void SetVisLeaves(Bool_t flag=kTRUE)
Set visibility for leaves.
Int_t GetNvolumes() const
Definition: TGeoVolume.h:296
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:2335
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.
void SetMaterial(TGeoMaterial *mat)
Definition: TGeoMedium.h:57
virtual void GrabFocus(Int_t nfr=0, Double_t dlong=0, Double_t dlat=0, Double_t dpsi=0)=0
Bool_t FindMatrixOfDaughterVolume(TGeoVolume *vol) const
Find a daughter node having VOL as volume and fill TGeoManager::fHMatrix with its global matrix...
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.
void PrintVoxels() const
Print the voxels for this volume.
void SetCurrentPoint(Double_t *point)
Definition: TGeoManager.h:500
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
void AddVolume(TGeoVolume *vol)
Add a volume with valid shape to the list of volumes.
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:396
void InvisibleAll(Bool_t flag=kTRUE)
Make volume and each of it daughters (in)visible.
Definition: TGeoVolume.cxx:817
Int_t fThreadSize
Thread specific data vector.
Definition: TGeoVolume.h:338
void ClearShape(const TGeoShape *shape)
Remove a shape from the list of shapes.
void SortOverlaps()
Sort overlaps by decreasing overlap distance. Extrusions comes first.
Bool_t GetOptimalVoxels() const
Returns true if cylindrical voxelization is optimal.
TGeoVolume * MakeReflectedVolume(const char *newname="") const
Make a copy of this volume which is reflected with respect to XY plane.
TGeoMedium * GetMedium() const
Definition: TGeoVolume.h:189
Bool_t IsIdentity() const
Definition: TGeoMatrix.h:77
Int_t AddVolume(TGeoVolume *volume)
Add a volume to the list. Returns index of the volume in list.
virtual void SetVisLeaves(Bool_t flag=kTRUE)
Set branch type visibility.
Definition: TGeoAtt.cxx:83
static const std::string pattern("pattern")
virtual Bool_t IsVisible() const
Definition: TGeoVolume.h:169
virtual TGeoMatrix * GetMatrix() const =0
virtual TGeoVolume * MakeCopyVolume(TGeoShape *newshape)
Make a copy of this volume build a volume with same name, shape and medium.
TGeoMaterial * GetMaterial() const
Definition: TGeoVolume.h:188
Int_t GetVisOption() const
Returns current depth to which geometry is drawn.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:30
virtual void Print(Option_t *option="") const
Print the voxels.
XFontStruct * id
Definition: TGX11.cxx:108
char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoMatrix.cxx:344
void RandomPoints(Int_t npoints=1000000, Option_t *option="")
Draw random points in the bounding box of this volume.
virtual Int_t DistanceToPrimitiveVol(TGeoVolume *vol, Int_t px, Int_t py)=0
virtual void SetMedium(TGeoMedium *medium)
Set medium for a multiple volume.
virtual void Paint(Option_t *option="")
paint volume
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
virtual Bool_t IsValidBox() const =0
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.
TString fOption
just a hook for now
Definition: TGeoVolume.h:77
short Color_t
Definition: RtypesCore.h:79
static TGeoVolumeAssembly * MakeAssemblyFromVolume(TGeoVolume *vol)
Make a clone of volume VOL but which is an assembly.
virtual void ClearThreadData() const
Definition: TGeoVolume.cxx:424
TObjArray * fVolumes
Definition: TGeoVolume.h:272
void SortNodes()
sort nodes by decreasing volume of the bounding box.
const char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoShape.cxx:701
Option_t * GetOption() const
Definition: TGeoVolume.h:201
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:750
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute mouse actions on this volume.
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:985
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Get volume info for the browser.
Base finder class for patterns.
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option="")
Add a new node to the list of nodes.
void SetShape(const TGeoShape *shape)
set the shape associated with this volume
Class handling Boolean composition of shapes.
Double_t GetStep() const
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:46
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:41
virtual Int_t GetCurrentNodeIndex() const
virtual TGeoVolume * CloneVolume() const
Clone this volume.
Int_t GetNumber() const
Definition: TGeoNode.h:104
TGeoVoxelFinder * fVoxels
Definition: TGeoVolume.h:73
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...
virtual void Release() const =0
void SetNeedRebuild(Bool_t flag=kTRUE)
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute the closest distance of approach from point px,py to this volume
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition: TNamed.cxx:42
Style_t fLineStyle
Line style.
Definition: TAttLine.h:28
Base abstract class for all shapes.
Definition: TGeoShape.h:27
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Definition: TObjArray.cxx:222
void SetMotherVolume(TGeoVolume *mother)
Definition: TGeoNode.h:132
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2851
TGeoPatternFinder * fFinder
dummy medium
Definition: TGeoVolume.h:72
Class describing rotation + translation.
Definition: TGeoMatrix.h:285
void SetSpacedOut(Bool_t flag)
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:42
void SetField(TObject *field)
Definition: TGeoVolume.h:234
virtual void SetVisOnly(Bool_t flag=kTRUE)
Set branch type visibility.
Definition: TGeoAtt.cxx:93
ABC for user objects attached to TGeoVolume or TGeoNode.
Definition: TGeoExtension.h:21
virtual void FindOverlaps(Int_t inode) const
create the list of nodes for which the bboxes overlap with inode&#39;s bbox
virtual TObject * RemoveAt(Int_t idx)
Remove object at index idx.
Definition: TObjArray.cxx:630
Int_t GetIndex(const TGeoNode *node) const
get index number for a given daughter
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.
Color_t fLineColor
Line color.
Definition: TAttLine.h:27
virtual TGeoPatternFinder * MakeCopy(Bool_t reflect=kFALSE)=0
tomato 2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:255
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:496
virtual Bool_t IsComposite() const
Definition: TGeoShape.h:132
Double_t GetStart() const
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:488
TObjArray * GetListOfShapes() const
Definition: TGeoManager.h:465
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.
void SetMatrix(const TGeoMatrix *matrix)
Matrix setter.
Definition: TGeoNode.cxx:816
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t IsRegistered() const
Definition: TGeoMatrix.h:87
Width_t fLineWidth
Line width.
Definition: TAttLine.h:29
TGeoShape * fShape
Definition: TGeoVolume.h:69
Int_t GetEntriesFast() const
Definition: TObjArray.h:66
void UnmarkSaved()
Reset SavePrimitive bits.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
Bool_t IsInvalid() const
Ssiz_t Length() const
Definition: TString.h:390
virtual void RegisterYourself()
Register the matrix in the current manager, which will become the owner.
Definition: TGeoMatrix.cxx:575
Double_t E()
Definition: TMath.h:54
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1070
Bool_t IsVisRaytrace() const
Definition: TGeoAtt.h:89
virtual Bool_t IsFolder() const
Return TRUE if volume contains nodes.
Definition: TGeoVolume.cxx:845
void CheckOverlaps(Double_t ovlp=0.1, Option_t *option="") const
Overlap checking tool.
Definition: TGeoVolume.cxx:642
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:621
void CloneNodesAndConnect(TGeoVolume *newmother) const
Clone the array of nodes.
static Int_t Lock()
Static method to lock the main thread mutex.
Definition: TThread.cxx:758
virtual Int_t GetNextNodeIndex() const
TString fName
Definition: TNamed.h:36
void SetDivIndex(Int_t index)
virtual void DrawVolume(TGeoVolume *vol, Option_t *option="")=0
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a component to the assembly.
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:239
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
void SetUserExtension(TGeoExtension *ext)
Connect user-defined extension to the volume.
TObjArray * GetListOfMatrices() const
Definition: TGeoManager.h:460
virtual TGeoVolume * GetTopVolume() const =0
void RandomPoints(const TGeoVolume *vol, Int_t npoints=10000, Option_t *option="")
Draw random points in the bounding box of a volume.
virtual const char * GetAxisName(Int_t iaxis) const =0
virtual void ClearThreadData() const
Definition: TGeoShape.h:69
short Width_t
Definition: RtypesCore.h:78
void SetFinder(TGeoPatternFinder *finder)
Definition: TGeoNode.h:217
void SetAttVisibility(Bool_t vis)
Definition: TGeoVolume.h:236
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:39
TGeoMedium * GetMedium(const char *medium) const
Search for a named tracking medium. All trailing blanks stripped.
void SetOverlapping(Bool_t flag=kTRUE)
Definition: TGeoNode.h:127
Bool_t IsTopVolume() const
True if this is the top volume of the geometry.
Definition: TGeoVolume.cxx:865
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
void SetNextNodeIndex(Int_t index)
TGeoExtension * GrabUserExtension() const
Get a copy of the user extension pointer.
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.
static Int_t UnLock()
Static method to unlock the main thread mutex.
Definition: TThread.cxx:774
virtual void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to XY.
Definition: TGeoMatrix.cxx:568
Class describing scale transformations.
Definition: TGeoMatrix.h:246
#define ClassImp(name)
Definition: Rtypes.h:279
double f(double x)
Bool_t IsZombie() const
Definition: TObject.h:120
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:554
virtual TGeoVolume * MakeCopyVolume(TGeoShape *newshape)
make a copy of this volume build a volume with same name, shape and medium
Int_t Export(const char *filename, const char *name="", Option_t *option="")
Export this volume to a file.
Definition: TGeoVolume.cxx:940
double Double_t
Definition: RtypesCore.h:55
Int_t GetNumber() const
Definition: TGeoVolume.h:198
void SetVoxelFinder(TGeoVoxelFinder *finder)
Definition: TGeoVolume.h:246
TObjArray * fNodes
Definition: TGeoVolume.h:68
virtual void SetVisibility(Bool_t vis=kTRUE)
set visibility of this volume
void MakeCopyNodes(const TGeoVolume *other)
make a new list of nodes and copy all nodes of other volume inside
void SaveAs(const char *filename, Option_t *option="") const
Save geometry having this as top volume as a C++ macro.
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Bool_t TestShapeBit(UInt_t f) const
Definition: TGeoShape.h:165
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:44
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
TGeoExtension * GrabFWExtension() const
Get a copy of the framework extension pointer.
unsigned long ULong_t
Definition: RtypesCore.h:51
Bool_t Valid() const
Check if the shape of this volume is valid.
Int_t fNumber
option - if any
Definition: TGeoVolume.h:78
virtual const char * GetVolumeInfo(const TGeoVolume *volume, Int_t px, Int_t py) const =0
Double_t y[n]
Definition: legend1.C:17
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:35
Node containing an offset.
Definition: TGeoNode.h:193
void ClearNodes()
Definition: TGeoVolume.h:116
virtual void SetVisContainers(Bool_t flag=kTRUE)
Set visibility for containers.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
Finder class handling voxels.
virtual TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)=0
virtual void ComputeBBox()=0
Int_t AddShape(const TGeoShape *shape)
Add a shape to the list. Returns index of the shape in list.
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:48
Bool_t IsReflection() const
Definition: TGeoMatrix.h:80
Media are used to store properties related to tracking and which are useful only when using geometry ...
Definition: TGeoMedium.h:25
Bool_t IsVisLeaves() const
Definition: TGeoVolume.h:172
Bool_t IsNull() const
Definition: TString.h:387
virtual Double_t Capacity() const =0
virtual void SetLineColor(Color_t lcolor)
Set the line color.
void SetVolume(TGeoVolume *volume)
Definition: TGeoNode.h:124
void InspectMaterial() const
Inspect the material for this volume.
Definition: TGeoVolume.cxx:882
static void CreateDummyMedium()
Create a dummy medium.
Definition: TGeoVolume.cxx:412
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.
virtual Int_t GetDivAxis()
Double_t fStep
Definition: TGeoVolume.h:278
Mother of all ROOT objects.
Definition: TObject.h:37
static TGeoShape * MakeScaledShape(const char *name, TGeoShape *shape, TGeoScale *scale)
Create a scaled shape starting from a non-scaled one.
TGeoVolume & operator=(const TGeoVolume &)
assignment operator
Definition: TGeoVolume.cxx:527
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
void SetAttBit(UInt_t f)
Definition: TGeoAtt.h:67
virtual ~TGeoVolumeMulti()
Destructor.
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:676
static TGeoVolume * Import(const char *filename, const char *name="", Option_t *option="")
Import a volume from a file.
Definition: TGeoVolume.cxx:890
Abstract class for geometry painters.
void ClearOverlaps()
Clear the list of overlaps.
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition: TGeoNode.h:51
void SetNsegments(Int_t nseg)
Set number of segments for approximating circles in drawing.
TGeoVolumeMulti()
dummy constructor
virtual TGeoExtension * Grab()=0
char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoMedium.cxx:127
R__EXTERN TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.h:464
Bool_t IsVisDaughters() const
Definition: TGeoAtt.h:91
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
TGeoVolumeMulti * fDivision
Definition: TGeoVolume.h:273
virtual void Add(TObject *obj)
Definition: TList.h:81
void SetVisDaughters(Bool_t vis=kTRUE)
Set visibility for the daughters.
Definition: TGeoAtt.cxx:112
void SetUsed(Bool_t flag=kTRUE)
Definition: TGeoMaterial.h:123
virtual TList * GetListOfKeys() const
TObjArray * GetListOfVolumes() const
Definition: TGeoManager.h:463
void SetCurrentNodeIndex(Int_t index)
virtual void SetLineStyle(Style_t lstyle)
Set the line style for all components.
Bool_t IsOverlappingCandidate() const
Definition: TGeoVolume.h:162
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
#define NULL
Definition: Rtypes.h:82
void SetCurrentPoint(Double_t x, Double_t y, Double_t z)
Set the current tracking point.
Int_t AddMaterial(const TGeoMaterial *material)
Add a material to the list. Returns index of the material in list.
virtual Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const =0
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
Double_t WeightA() const
Analytical computation of the weight.
virtual Int_t GetByteCount() const
Definition: TGeoNode.h:93
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:235
void SetOverlappingCandidate(Bool_t flag)
Definition: TGeoVolume.h:231
void GrabFocus()
Move perspective view focus to this volume.
void Add(TObject *obj)
Definition: TObjArray.h:75
virtual void cd(Int_t)
virtual Bool_t IsVolumeMulti() const
Definition: TGeoVolume.h:131
void ResetBit(UInt_t f)
Definition: TObject.h:156
TObjArray * GetListOfOverlaps()
Definition: TGeoManager.h:459
void ClearThreadData() const
Bool_t IsStreamingVoxels() const
Definition: TGeoManager.h:453
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:36
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:953
virtual void SetMedium(TGeoMedium *medium)
Definition: TGeoVolume.h:245
TGeoVolume * GetTopVolume() const
Definition: TGeoManager.h:497
void FindOverlaps() const
loop all nodes marked as overlaps and find overlapping brothers
virtual TGeoVolume * GetDrawnVolume() const =0
Bool_t IsClosed() const
Definition: TGeoManager.h:279
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.
TGeoShape * GetShape() const
Definition: TGeoVolume.h:204
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:309
TGeoShape * GetLastShape() const
Returns the last shape.
virtual TGeoMatrix * GetMatrix() const
Definition: TGeoNode.h:180
const Bool_t kTRUE
Definition: Rtypes.h:91
void SetVisTouched(Bool_t vis=kTRUE)
Mark visualization attributes as "modified".
Definition: TGeoAtt.cxx:129
void SetNumber(Int_t number)
Definition: TGeoVolume.h:248
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:155
void CheckShapes()
check for negative parameters in shapes.
Definition: TGeoVolume.cxx:701
void Grab()
Definition: TGeoVolume.h:155
void SetVisOption(Int_t option=0)
set drawing mode :
void SelectVolume(Bool_t clear=kFALSE)
Select this volume as matching an arbitrary criteria.
TVirtualGeoPainter * GetGeomPainter()
Make a default painter if none present. Returns pointer to it.
Bool_t OptimizeVoxels()
Perform an extensive sampling to find which type of voxelization is most efficient.
TGeoNode * FindNode(const char *name) const
search a daughter inside the list of nodes
TGeoVolume * GetVolume() const
Definition: TGeoNode.h:106
virtual Int_t GetOptimalVoxels() const
Definition: TGeoNode.h:108
Line Attributes class.
Definition: TAttLine.h:24
virtual void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option)
Add an overlapping node - not allowed for assemblies.
void Refresh()
Refresh browser contents.
Definition: TBrowser.cxx:377
char name[80]
Definition: TGX11.cxx:109
virtual void cd(Int_t inode) const
Actualize matrix of node indexed <inode>
Definition: TGeoVolume.cxx:976
virtual void Print(const Option_t *option="") const
print characteristics of this material
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:911
Int_t GetNtotal() const
Definition: TGeoVolume.h:185
void SetNumber(Int_t number)
Definition: TGeoNode.h:125
virtual void SetVisOnly(Bool_t flag=kTRUE)
Set visibility for leaves.
Bool_t IsValid() const
Definition: TGeoVolume.h:168
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
Int_t fRefCount
Definition: TGeoVolume.h:80
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
Bool_t IsRunTimeShape() const
Definition: TGeoShape.h:141
const char * Data() const
Definition: TString.h:349
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TObject.cxx:709
void SetNtotal(Int_t ntotal)
Definition: TGeoVolume.h:249
virtual Bool_t IsAssembly() const
Returns true if the volume is an assembly or a scaled assembly.