VGM Version 5.3
Loading...
Searching...
No Matches
Placement.cxx
Go to the documentation of this file.
1// $Id$
2
3// -----------------------------------------------------------------------
4// The RootGM package of the Virtual Geometry Model
5// Copyright (C) 2007, Ivana Hrivnacova
6// All rights reserved.
7//
8// For the licensing terms see vgm/LICENSE.
9// Contact: ivana@ipno.in2p3.fr
10// -----------------------------------------------------------------------
11
12//
13// Class Placement
14// -------------------
15// The interface to positions of volumes.
16//
17// Author: Ivana Hrivnacova; IPN Orsay
18
20#include "VGM/volumes/IVolume.h"
21
23
24#include "RootGM/common/Units.h"
25#include "RootGM/common/axis.h"
30
31#include "TGeoBoolNode.h"
32#include "TGeoCompositeShape.h"
33#include "TGeoManager.h"
34#include "TGeoMatrix.h"
35#include "TGeoNode.h"
36#include "TGeoVolume.h"
37
38bool RootGM::Placement::fgIncludeAssembliesInNames = true;
39char RootGM::Placement::fgNameSeparator = '%';
40char RootGM::Placement::fgNamePrefix = '&';
41
42//
43// static methods
44//
45
46//_____________________________________________________________________________
48 bool includeAssembliesInNames)
49{
52
53 fgIncludeAssembliesInNames = includeAssembliesInNames;
54}
55
56//_____________________________________________________________________________
58{
61
62 return fgIncludeAssembliesInNames;
63}
64
65//_____________________________________________________________________________
67{
69
70 fgNameSeparator = nameSeparator;
71}
72
73//_____________________________________________________________________________
75{
77
78 fgNamePrefix = namePrefix;
79}
80
81//_____________________________________________________________________________
83{
85
86 return fgNameSeparator;
87}
88
89//_____________________________________________________________________________
91{
93
94 return fgNamePrefix;
95}
96
97//
98// ctors, dtor
99//
100
101//_____________________________________________________________________________
102RootGM::Placement::Placement(const std::string& name, int copyNo,
103 VGM::IVolume* volume, VGM::IVolume* motherVolume, TGeoMatrix* transformation)
104 : VGM::IPlacement(),
105 BaseVGM::VPlacement(volume, motherVolume),
106 fName(name),
107 fGeoNode(0),
108 fVGMMatrix(transformation),
109 fAssemblyNodes()
110{
117
118 if (!motherVolume) {
119
120 // Set top volume to TGeo
121 gGeoManager->SetTopVolume(RootGM::VolumeMap::Instance()->GetVolume(volume));
122
123 // Get top node
124 fGeoNode = gGeoManager->GetTopNode();
125 }
126 else {
127
128 // Get solid displacement, if present, and update transformation
129 // which will be used in Root node
130 //
131 TGeoMatrix* totalMatrix = transformation;
132 if (volume->Solid()->Type() == VGM::kDisplaced ||
133 motherVolume->Solid()->Type() == VGM::kDisplaced) {
134
135 totalMatrix = ComposeMatrix(volume, motherVolume, transformation);
136 totalMatrix->SetName(name.data());
137 totalMatrix->RegisterYourself();
138 }
139
140 // Get TGeo volumes from the volumes map
141 TGeoVolume* geoVolume = RootGM::VolumeMap::Instance()->GetVolume(volume);
142
143 TGeoVolume* geoMotherVolume =
144 RootGM::VolumeMap::Instance()->GetVolume(motherVolume);
145
146 // Create TGeo node
147 geoMotherVolume->AddNode(geoVolume, copyNo, totalMatrix);
148
149 // Retrieve the node created
150 fGeoNode = geoMotherVolume->GetNode(geoMotherVolume->GetNdaughters() - 1);
151 }
152
153 // Register physical volume in the map
155}
156
157//_____________________________________________________________________________
158RootGM::Placement::Placement(const std::string& name, VGM::IVolume* volume,
159 VGM::IVolume* motherVolume, VGM::Axis axis, int nofItems, double width,
160 double offset)
161 : VGM::IPlacement(),
162 BaseVGM::VPlacement(volume, motherVolume),
163 fName(name),
164 fGeoNode(0),
165 fVGMMatrix(0),
166 fAssemblyNodes()
167{
177
178 // Get TGeo volumes from the volumes map
179 TGeoVolume* geoMotherVolume =
180 RootGM::VolumeMap::Instance()->GetVolume(motherVolume);
181
182 // Apply units
183 width /= RootGM::Units::AxisUnit(axis);
184 offset /= RootGM::Units::AxisUnit(axis);
185
186 // Convert VGM parameters to TGeo
187 Int_t iAxis = RootGM::Axis(axis);
188 Double_t xlo, xhi;
189 geoMotherVolume->GetShape()->GetAxisRange(iAxis, xlo, xhi);
190 Double_t start = xlo + offset;
191
192 // Root division
193 geoMotherVolume->Divide(name.data(), iAxis, nofItems, start, width);
194
195 // Retrieve the node created
196 fGeoNode = geoMotherVolume->GetNode(geoMotherVolume->GetNdaughters() - 1);
197
198 // Register physical volume in the map
200}
201
202//_____________________________________________________________________________
204 VGM::IVolume* volume, VGM::IVolume* motherVolume, TGeoNode* node)
205 : VGM::IPlacement(),
206 BaseVGM::VPlacement(volume, motherVolume),
207 fName(),
208 fGeoNode(node),
209 fVGMMatrix(0),
210 fAssemblyNodes()
211{
213
214 if (volume) fName = volume->Name();
215 // Root nodes have not own name;
216 // use the volume name in this case
217
218 fVGMMatrix = node->GetMatrix();
219
220 // print warning if node includes overlaps
221 Int_t novlp;
222 node->GetOverlaps(novlp);
223 if (novlp) {
224 std::cerr << "*** Warning: node with overlaps ***" << std::endl
225 << "*** Overlaps may not be supported in exported geometry!!! ***"
226 << std::endl
227 << " Volume: " << volume->Name()
228 << " in mother: " << motherVolume->Name()
229 << " (TGeoNode name: " << node->GetName() << ")" << std::endl;
230 }
231
232 // Register physical volume in the map
234}
235
236//_____________________________________________________________________________
238 TGeoNode* node, std::vector<const TGeoNode*> assemblyNodes)
239 : VGM::IPlacement(),
240 BaseVGM::VPlacement(volume, motherVolume),
241 fName(),
242 fGeoNode(node),
243 fVGMMatrix(0),
244 fAssemblyNodes(assemblyNodes)
245{
247
248 if (volume) fName = volume->Name();
249 // Root nodes have not own name;
250 // use the volume name in this case
251
252 fVGMMatrix = node->GetMatrix();
253
254 // Register physical volume in the map
256}
257
258//_____________________________________________________________________________
259RootGM::Placement::Placement() : VGM::IPlacement(), BaseVGM::VPlacement()
260{
262}
263
264//_____________________________________________________________________________
266 : VGM::IPlacement(rhs), BaseVGM::VPlacement(rhs)
267{
269}
270
271//_____________________________________________________________________________
276
277//
278// private functions
279//
280
281//_____________________________________________________________________________
282TGeoMatrix* RootGM::Placement::ComposeMatrix(VGM::IVolume* volume,
283 VGM::IVolume* motherVolume, TGeoMatrix* transformation) const
284{
286
287 TGeoHMatrix motherTransform;
288 VGM::ISolid* mConstSolid = motherVolume->Solid();
289 while (mConstSolid->Type() == VGM::kDisplaced) {
290 VGM::IDisplacedSolid* displacedSolid =
291 dynamic_cast<VGM::IDisplacedSolid*>(mConstSolid);
292 TGeoHMatrix displacement(
293 *RootGM::CreateTransform(displacedSolid->Displacement()));
294 motherTransform = motherTransform * displacement;
295
296 mConstSolid = displacedSolid->ConstituentSolid();
297 }
298
299 TGeoHMatrix solidTransform;
300 VGM::ISolid* constSolid = volume->Solid();
301 while (constSolid->Type() == VGM::kDisplaced) {
302 VGM::IDisplacedSolid* displacedSolid =
303 dynamic_cast<VGM::IDisplacedSolid*>(constSolid);
304 TGeoHMatrix displacement(
305 *RootGM::CreateTransform(displacedSolid->Displacement()));
306 solidTransform = solidTransform * displacement;
307
308 constSolid = displacedSolid->ConstituentSolid();
309 }
310
311 TGeoHMatrix totalTransform =
312 motherTransform.Inverse() * TGeoHMatrix(*transformation) * solidTransform;
313
314 return new TGeoHMatrix(totalTransform);
315}
316
317//
318// public functions
319//
320
321//_____________________________________________________________________________
323{
324 // Top volume has not mother
325 if (!Mother()) return VGM::kSimplePlacement;
326
327 // Check if division is present
328 const TGeoPatternFinder* finder = fGeoNode->GetMotherVolume()->GetFinder();
329 if (!finder) return VGM::kSimplePlacement;
330
331 // Get division axis
332 VGM::Axis axis = RootGM::Axis(finder);
333 if (axis != VGM::kUnknownAxis)
335 else
337}
338
339//_____________________________________________________________________________
340std::string RootGM::Placement::Name() const
341{
342 //
343 TString name;
344 if (fgIncludeAssembliesInNames) {
345 for (unsigned i = 0; i < fAssemblyNodes.size(); i++) {
346 if (i == 0) name += fgNamePrefix;
347 name += fAssemblyNodes[i]->GetName();
348 name += fgNameSeparator;
349 }
350 }
351 name += fName.c_str();
352
353 return name.Data();
354}
355
356//_____________________________________________________________________________
358{
359 //
360 return fGeoNode->GetNumber();
361}
362
363//_____________________________________________________________________________
365{
366 //
367 // Boolean solids
368 TGeoHMatrix transform3D;
369 if (fGeoNode->GetVolume()->GetShape()->IsComposite()) {
370 TGeoCompositeShape* composite =
371 (TGeoCompositeShape*)fGeoNode->GetVolume()->GetShape();
372 TGeoMatrix* leftMatrix = composite->GetBoolNode()->GetLeftMatrix();
373
374 TGeoHMatrix t1(*leftMatrix);
375 TGeoHMatrix t2(*(fGeoNode->GetMatrix()));
376
377 transform3D = t2 * t1;
378
379 // If constituents are composite shapes,
380 // the displacement have to take into account the transformation
381 // of left constituent not passed to the solid
382
383 TGeoShape* shapeA = composite->GetBoolNode()->GetLeftShape();
384
385 while (shapeA->IsComposite()) {
386 TGeoBoolNode* boolNodeAC = ((TGeoCompositeShape*)shapeA)->GetBoolNode();
387
388 TGeoShape* shapeAC = boolNodeAC->GetLeftShape();
389 // left component of the shape A
390
391 TGeoMatrix* matrixAC = boolNodeAC->GetLeftMatrix();
392 TGeoHMatrix transformAC(*matrixAC);
393
394 transform3D = transform3D * transformAC;
395
396 shapeA = shapeAC;
397 }
398 }
399 else {
400 transform3D = fGeoNode->GetMatrix();
401 }
402
403 // Displaced solids
404 if (Volume()->Solid()->Type() == VGM::kDisplaced ||
405 (Mother() && Mother()->Solid()->Type() == VGM::kDisplaced)) {
406
407 transform3D = TGeoHMatrix(*fVGMMatrix);
408 }
409
410 // Assemblies
411 for (unsigned i = fAssemblyNodes.size(); i > 0; i--) {
412 TGeoMatrix* matrixAN = fAssemblyNodes[i - 1]->GetMatrix();
413 TGeoHMatrix transformAN(*matrixAN);
414 transform3D = transformAN * transform3D;
415 }
416
417 // work around to suppress a warning:
418 // Warning in <TGeoMatrix::dtor>: Registered matrix was removed
419 transform3D.SetBit(TGeoMatrix::kGeoRegistered, false);
420
421 return Transform(transform3D);
422}
423
424//_____________________________________________________________________________
426 double& width, double& offset, double& halfGap) const
427{
428 // Fill data only if multiple placement
429 const TGeoPatternFinder* finder = fGeoNode->GetMotherVolume()->GetFinder();
430 if (!finder) return false;
431
432 // Get division parameters
433 axis = RootGM::Axis(finder);
434 nofItems = finder->GetNdiv();
435 Double_t start = finder->GetStart();
436 Double_t xlo, xhi;
437 fGeoNode->GetMotherVolume()->GetShape()->GetAxisRange(
438 RootGM::Axis(axis), xlo, xhi);
439 offset = start - xlo;
440 width = finder->GetStep();
441 halfGap = 0;
442
443 // Convert units
444 offset *= RootGM::Units::AxisUnit(axis);
445 width *= RootGM::Units::AxisUnit(axis);
446 halfGap *= RootGM::Units::AxisUnit(axis);
447
448 return true;
449}
450
451//_____________________________________________________________________________
453 std::vector<VGM::Transform>& /*transforms*/,
454 std::vector<VGM::IVolume*>& /*volumes*/) const
455{
456 // I think this is not usefull in ROOT anyways but we need it here since the
457 // class would be abstract elsewise. If it turns out to be needed, this has to
458 // be implemented
459 std::cout << "Please implement RootGM::Placement::ParameterisedPlacementData "
460 "if you need to use it!"
461 << std::endl;
462 abort();
463}
static PlacementMap * Instance()
void AddPlacement(VGM::IPlacement *, TGeoNode *)
VGM implementation for Root positions of volumes.
Definition Placement.h:41
virtual ~Placement()
static bool GetIncludeAssembliesInNames()
Definition Placement.cxx:57
static void SetNamePrefix(char namePrefix)
Definition Placement.cxx:74
virtual VGM::Transform Transformation() const
Return the 3D transformation (if simple placement)
static void SetNameSeparator(char nameSeparator)
Definition Placement.cxx:66
static char GetNamePrefix()
Definition Placement.cxx:90
virtual VGM::PlacementType Type() const
Return the type of this placement.
static void SetIncludeAssembliesInNames(bool includeAssembliesInNames)
Definition Placement.cxx:47
virtual std::string Name() const
Return the name of this placement.
static char GetNameSeparator()
Definition Placement.cxx:82
virtual bool ParameterisedPlacementData(std::vector< VGM::Transform > &transforms, std::vector< VGM::IVolume * > &volumes) const
Fill the parameterised placement data if relevant and return true; return false if not parameterised ...
virtual int CopyNo() const
Return the copy number of this placement.
virtual bool MultiplePlacementData(VGM::Axis &axis, int &nofItems, double &width, double &offset, double &halfGap) const
Fill the multiple placement data if relevant and return true; return false if not multiple placement.
static double AxisUnit(VGM::Axis axis)
Return Root unit for the given axis in VGM units.
Definition Units.cxx:52
static VolumeMap * Instance()
Definition VolumeMap.cxx:28
TGeoVolume * GetVolume(VGM::IVolume *iVolume) const
Definition VolumeMap.cxx:92
VGM implementation for Root volume.
Definition Volume.h:36
VGM Axis enumeration.
The VGM interface to displaced solids.
virtual ISolid * ConstituentSolid() const =0
Return the constituent solid.
virtual Transform Displacement() const =0
Return the 3D displacement of the constituent solid.
The VGM interface to solids.
Definition ISolid.h:58
virtual SolidType Type() const =0
Return the type of this solid.
The VGM interface to volumes.
Definition IVolume.h:32
virtual ISolid * Solid() const =0
Return the associated solid.
virtual std::string Name() const =0
Return the name of this volume.
BaseVGM utilities.
Definition utilities.h:23
TGeoMatrix * CreateTransform(const VGM::Transform &transform)
VGM::Axis Axis(const TGeoPatternFinder *finder)
Definition axis.cxx:33
VGM::Transform Transform(const TGeoMatrix &matrix)
Definition transform.cxx:37
VGM interfaces.
Definition VMedium.h:28
std::vector< double > Transform
Definition Transform.h:40
@ kUnknownAxis
Definition Axis.h:42
PlacementType
Definition IPlacement.h:32
@ kSimplePlacement
Definition IPlacement.h:33
@ kMultiplePlacement
Definition IPlacement.h:34
@ kUnknownPlacement
Definition IPlacement.h:36
@ kDisplaced
Definition ISolid.h:49