DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Volumes.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation for LCD
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework include files
15 #include "DD4hep/LCDD.h"
16 #include "DD4hep/Printout.h"
17 #include "DD4hep/InstanceCount.h"
18 #include "DD4hep/MatrixHelpers.h"
20 
21 // ROOT include files
22 #include "TColor.h"
23 #include "TGeoShape.h"
24 #include "TGeoVolume.h"
25 #include "TGeoNode.h"
26 #include "TGeoMatrix.h"
27 #include "TGeoMedium.h"
28 
29 #include "TGeoVoxelFinder.h"
30 #include "TGeoShapeAssembly.h"
31 
32 // C/C++ include files
33 #include <climits>
34 #include <iostream>
35 #include <stdexcept>
36 #include <sstream>
37 
38 using namespace std;
39 using namespace DD4hep::Geometry;
40 
41 #ifdef DD4HEP_EMULATE_TGEOEXTENSIONS
42 namespace DD4hep {
43  namespace Geometry {
44 
45  struct DDExtension {
46  TGeoExtension* m_extension;
47  DDExtension() : m_extension(0) {}
48  DDExtension(const DDExtension& c) : m_extension(0) {
49  if ( c.m_extension ) m_extension = c.m_extension->Grab();
50  }
51  virtual ~DDExtension() {
52  if ( m_extension ) m_extension->Release();
53  }
54  DDExtension& operator=(const DDExtension& c) {
55  if ( this != &c ) SetUserExtension(c.GetUserExtension());
56  return *this;
57  }
58  void SetUserExtension(TGeoExtension *ext) {
59  if (m_extension) m_extension->Release();
60  m_extension = 0;
61  if (ext) m_extension = ext->Grab();
62  }
63  TGeoExtension* GetUserExtension() const {
64  return m_extension;
65  }
66  };
67  struct DD_TGeoNodeMatrix : public TGeoNodeMatrix, public DDExtension {
68  private:
69  DD_TGeoNodeMatrix& operator=(const DD_TGeoNodeMatrix&) { return *this; }
70  public:
71  DD_TGeoNodeMatrix(const TGeoVolume* v, const TGeoMatrix* m)
72  : TGeoNodeMatrix(v, m), DDExtension() {
74  }
75  DD_TGeoNodeMatrix(const DD_TGeoNodeMatrix& c)
76  : TGeoNodeMatrix(c.GetVolume(), c.GetMatrix()), DDExtension(c) {
78  }
79  virtual ~DD_TGeoNodeMatrix() {
81  }
82  virtual TGeoNode *MakeCopyNode() const {
83  TGeoNodeMatrix *node = new DD_TGeoNodeMatrix(*this);
84  node->SetName(this->TGeoNodeMatrix::GetName());
85  // set the mother
86  node->SetMotherVolume(fMother);
87  // set the copy number
88  node->SetNumber(fNumber);
89  // copy overlaps
90  if (fNovlp > 0) {
91  if (fOverlaps) {
92  Int_t *ovlps = new Int_t[fNovlp];
93  memcpy(ovlps, fOverlaps, fNovlp * sizeof(Int_t));
94  node->SetOverlaps(ovlps, fNovlp);
95  }
96  else {
97  node->SetOverlaps(fOverlaps, fNovlp);
98  }
99  }
100  // copy VC
101  if (IsVirtual())
102  node->SetVirtual();
103  return node;
104  }
105  };
106 
107  template <class T> struct _VolWrap: public T, public DDExtension {
108  public:
109  _VolWrap(const char* name) : T(name), DDExtension() {
111  }
112  virtual ~_VolWrap() {
114  }
115  virtual void AddNode(const TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t* = "") {
116  TGeoMatrix *matrix = mat;
117  if (matrix == 0)
118  matrix = gGeoIdentity;
119  else
120  matrix->RegisterYourself();
121  if (!vol) {
122  this->T::Error("AddNode", "Volume is NULL");
123  return;
124  }
125  if (!vol->IsValid()) {
126  this->T::Error("AddNode", "Won't add node with invalid shape");
127  printf("### invalid volume was : %s\n", vol->GetName());
128  return;
129  }
130  if (!this->T::fNodes)
131  this->T::fNodes = new TObjArray();
132 
133  if (this->T::fFinder) {
134  // volume already divided.
135  this->T::Error("AddNode", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no,
136  this->T::GetName());
137  return;
138  }
139 
140  TGeoNodeMatrix *node = new DD_TGeoNodeMatrix(vol, matrix);
141  //node = new TGeoNodeMatrix(vol, matrix);
142  node->SetMotherVolume(this);
143  this->T::fNodes->Add(node);
144  TString name = TString::Format("%s_%d", vol->GetName(), copy_no);
145  if (this->T::fNodes->FindObject(name))
146  this->T::Warning("AddNode", "Volume %s : added node %s with same name", this->T::GetName(), name.Data());
147  node->SetName(name);
148  node->SetNumber(copy_no);
149  }
150  };
151 
152  template <> _VolWrap<TGeoVolume>::_VolWrap(const char* name) : TGeoVolume(name,0,0), DDExtension() {
154  }
155 
156  struct TGeoVolumeValue : public _VolWrap<TGeoVolume> {
157  TGeoVolumeValue(const char* name, TGeoShape* s, TGeoMedium* m) : _VolWrap<TGeoVolume>(name) {
158  SetShape(s);
159  SetMedium(m);
160  }
161  virtual ~TGeoVolumeValue() { }
162  TGeoVolume *_copyVol(TGeoShape *newshape) const {
163  TGeoVolumeValue *vol = new TGeoVolumeValue(this->TGeoVolume::GetName(),newshape,fMedium);
164  if ( m_extension ) vol->m_extension = m_extension->Grab();
165  //vol->copy(*this);
166  return vol;
167  }
168  virtual TGeoVolume* MakeCopyVolume(TGeoShape *newshape) {
169  // make a copy of this volume. build a volume with same name, shape and medium
170  TGeoVolume *vol = _copyVol(newshape);
171  vol->SetVisibility(IsVisible());
172  vol->SetLineColor(GetLineColor());
173  vol->SetLineStyle(GetLineStyle());
174  vol->SetLineWidth(GetLineWidth());
175  vol->SetFillColor(GetFillColor());
176  vol->SetFillStyle(GetFillStyle());
177  vol->SetField(fField);
178  if (fFinder)
179  vol->SetFinder(fFinder);
180  CloneNodesAndConnect(vol);
181  ((TObject*) vol)->SetBit(kVolumeClone);
182  return vol;
183  }
184  virtual TGeoVolume* CloneVolume() const {
185  TGeoVolume *vol = _copyVol(fShape);
186  Int_t i;
187  // copy volume attributes
188  vol->SetLineColor(GetLineColor());
189  vol->SetLineStyle(GetLineStyle());
190  vol->SetLineWidth(GetLineWidth());
191  vol->SetFillColor(GetFillColor());
192  vol->SetFillStyle(GetFillStyle());
193  // copy other attributes
194  Int_t nbits = 8 * sizeof(UInt_t);
195  for (i = 0; i < nbits; i++)
196  vol->SetAttBit(1 << i, TGeoAtt::TestAttBit(1 << i));
197  for (i = 14; i < 24; i++)
198  vol->SetBit(1 << i, this->TGeoVolume::TestBit(1 << i));
199 
200  // copy field
201  vol->SetField(fField);
202  // Set bits
203  for (i = 0; i < nbits; i++)
204  vol->SetBit(1 << i, this->TGeoVolume::TestBit(1 << i));
205  vol->SetBit(kVolumeClone);
206  // copy nodes
207  // CloneNodesAndConnect(vol);
208  vol->MakeCopyNodes(this);
209  // if volume is divided, copy finder
210  vol->SetFinder(fFinder);
211  // copy voxels
212  if (fVoxels) {
213  TGeoVoxelFinder *voxels = new TGeoVoxelFinder(vol);
214  vol->SetVoxelFinder(voxels);
215  }
216  // copy option, uid
217  vol->SetOption(fOption);
218  vol->SetNumber(fNumber);
219  vol->SetNtotal(fNtotal);
220  return vol;
221  }
222  };
223 
224  struct TGeoVolumeAssemblyValue : public _VolWrap<TGeoVolumeAssembly> {
225  TGeoVolumeAssemblyValue(const char* name) : _VolWrap<TGeoVolumeAssembly>(name) {
226  }
227  virtual ~TGeoVolumeAssemblyValue() {
228  }
229  TGeoVolume *CloneVolume() const {
230  TGeoVolumeAssemblyValue *vol = new TGeoVolumeAssemblyValue(this->TGeoVolume::GetName());
231  if ( m_extension ) vol->m_extension = m_extension->Grab();
232  Int_t i;
233  // copy other attributes
234  Int_t nbits = 8 * sizeof(UInt_t);
235  for (i = 0; i < nbits; i++)
236  vol->SetAttBit(1 << i, TGeoAtt::TestAttBit(1 << i));
237  for (i = 14; i < 24; i++)
238  vol->SetBit(1 << i, this->TGeoVolumeAssembly::TestBit(1 << i));
239 
240  // copy field
241  vol->SetField(fField);
242  // Set bits
243  for (i = 0; i < nbits; i++)
244  vol->SetBit(1 << i, this->TGeoVolumeAssembly::TestBit(1 << i));
245  vol->SetBit(kVolumeClone);
246  // make copy nodes
247  vol->MakeCopyNodes(this);
248  ((TGeoShapeAssembly*) vol->GetShape())->NeedsBBoxRecompute();
249  // copy voxels
250  if (fVoxels) {
251  TGeoVoxelFinder *voxels = new TGeoVoxelFinder(vol);
252  vol->SetVoxelFinder(voxels);
253  }
254  // copy option, uid
255  vol->SetOption(fOption);
256  vol->SetNumber(fNumber);
257  vol->SetNtotal(fNtotal);
258  return vol;
259  }
260  };
261 
262  }
263 }
264 typedef DD_TGeoNodeMatrix geo_node_t;
265 typedef TGeoVolumeValue geo_volume_t;
266 typedef TGeoVolumeAssemblyValue geo_assembly_t;
267 
268 template <typename T> static typename T::Object* _userExtension(const T& v) {
269  typedef typename T::Object O;
270  const DDExtension* p = dynamic_cast<const DDExtension*>(v.ptr());
271  O* o = (O*)(p ? p->GetUserExtension() : 0);
272  return o;
273 }
274 #else
275 
276 /*
277  * The section below uses the new ROOT features using user extensions to volumes
278  * and placements. Once this is common, the above mechanism should be thrown away....
279  *
280  * M.Frank
281  */
282 
283 typedef TGeoNode geo_node_t;
284 typedef TGeoVolume geo_volume_t;
285 typedef TGeoVolumeAssembly geo_assembly_t;
286 template <typename T> static typename T::Object* _userExtension(const T& v) {
287  typedef typename T::Object O;
288  O* o = (O*)(v.ptr()->GetUserExtension());
289  return o;
290 }
291 #endif
293 
294 static TGeoVolume* _createTGeoVolume(const string& name, TGeoShape* s, TGeoMedium* m) {
295  geo_volume_t* e = new geo_volume_t(name.c_str(),s,m);
296  e->SetUserExtension(new Volume::Object());
297  return e;
298 }
299 static TGeoVolume* _createTGeoVolumeAssembly(const string& name) {
300  geo_assembly_t* e = new geo_assembly_t(name.c_str()); // It is important to use the correct constructor!!
301  e->SetUserExtension(new Assembly::Object());
302  return e;
303 }
304 
306 PlacedVolumeExtension::PlacedVolumeExtension()
307  : TGeoExtension(), magic(0), refCount(0), volIDs() {
308  magic = magic_word();
310 }
311 
314  : TGeoExtension(), magic(c.magic), refCount(0), volIDs(c.volIDs) {
316 }
317 
321 }
322 
325  ++this->refCount;
326 #ifdef ___print_vols
327  else cout << "Placement grabbed....." << endl;
328 #endif
329  return this;
330 }
331 
334  PlacedVolumeExtension* ext = const_cast<PlacedVolumeExtension*>(this);
335  --ext->refCount;
336  if ( 0 == ext->refCount ) delete ext;
337 }
338 
340 vector<PlacedVolumeExtension::VolID>::const_iterator
341 PlacedVolumeExtension::VolIDs::find(const string& name) const {
342  for (Base::const_iterator i = this->Base::begin(); i != this->Base::end(); ++i)
343  if (name == (*i).first)
344  return i;
345  return this->end();
346 }
347 
349 std::pair<vector<PlacedVolumeExtension::VolID>::iterator, bool>
350 PlacedVolumeExtension::VolIDs::insert(const string& name, int value) {
351  Base::iterator i = this->Base::begin();
352  for (; i != this->Base::end(); ++i)
353  if (name == (*i).first)
354  break;
355  //
356  if (i != this->Base::end()) {
357  return make_pair(i, false);
358  }
359  i = this->Base::insert(this->Base::end(), make_pair(name, value));
360  return make_pair(i, true);
361 }
362 
365  if (o)
366  return o;
367  throw runtime_error("DD4hep: Attempt to access invalid handle of type: PlacedVolume");
368 }
369 
373  return o;
374 }
375 
377 PlacedVolume& PlacedVolume::addPhysVolID(const string& nam, int value) {
378  Object* obj = _data(*this);
379  obj->volIDs.push_back(VolID(nam, value));
380  return *this;
381 }
382 
385  return Material::handle_t(m_element ? m_element->GetMedium() : 0);
386 }
387 
390  return Volume::handle_t(m_element ? m_element->GetVolume() : 0);
391 }
392 
395  return Volume::handle_t(m_element ? m_element->GetMotherVolume() : 0);
396 }
397 
400  return _data(*this)->volIDs;
401 }
402 
404 string PlacedVolume::toString() const {
405  stringstream s;
406  Object* obj = _data(*this);
407  s << m_element->GetName() << ": vol='" << m_element->GetVolume()->GetName() << "' mat:'" << m_element->GetMatrix()->GetName()
408  << "' volID[" << obj->volIDs.size() << "] ";
409  for (VolIDs::const_iterator i = obj->volIDs.begin(); i != obj->volIDs.end(); ++i)
410  s << (*i).first << "=" << (*i).second << " ";
411  s << ends;
412  return s.str();
413 }
414 
417 
420 : TGeoExtension(), magic(0), refCount(0), region(), limits(), vis(), sens_det(), referenced(0) {
422 }
423 
426  region.clear();
427  limits.clear();
428  vis.clear();
429  sens_det.clear();
431 }
432 
435  VolumeExtension* ext = const_cast<VolumeExtension*>(this);
436  ++ext->refCount;
437 #ifdef ___print_vols
438  if ( ext->sens_det.isValid() )
439  cout << "Volume grabbed with valid sensitive detector....." << endl;
440  else
441  cout << "Volume grabbed....." << endl;
442 #endif
443  return ext;
444 }
445 
448  VolumeExtension* ext = const_cast<VolumeExtension*>(this);
449  --ext->refCount;
450  if ( 0 == ext->refCount ) {
451 #ifdef ___print_vols
452  cout << "Volume deleted....." << endl;
453 #endif
454  delete ext;
455  }
456  else {
457 #ifdef ___print_vols
458  cout << "VolumeExtension::Release::refCount:" << ext->refCount << endl;
459 #endif
460  }
461 }
462 
464 Volume::Object* _data(const Volume& v, bool throw_exception = true) {
465  //if ( v.ptr() && v.ptr()->IsA() == TGeoVolume::Class() ) return v.data<Volume::Object>();
467  if (o)
468  return o;
469  else if (!throw_exception)
470  return 0;
471  throw runtime_error("DD4hep: Attempt to access invalid handle of type: PlacedVolume");
472 }
473 
475 Volume::Volume(const string& nam) {
476  m_element = _createTGeoVolume(nam,0,0);
477 }
478 
480 Volume::Volume(const string& nam, const Solid& s, const Material& m) {
481  m_element = _createTGeoVolume(nam,s.ptr(),m.ptr());
482 }
483 
486  Volume::Object* o = _userExtension(*this);
487  return o;
488 }
489 
490 static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* transform) {
491  if ( !daughter ) {
492  throw runtime_error("DD4hep: Volume: Attempt to assign an invalid physical daughter volume.");
493  }
494  TGeoVolume* parent = par;
495  TObjArray* a = parent->GetNodes();
496  Int_t id = a ? a->GetEntries() : 0;
497  if (transform && transform != identityTransform()) {
498  string nam = string(daughter->GetName()) + "_placement";
499  transform->SetName(nam.c_str());
500  }
501  TGeoShape* shape = daughter->GetShape();
502  // Need to fix the daughter's BBox of assemblies, if the BBox was not calculated....
503  if ( shape->IsA() == TGeoShapeAssembly::Class() ) {
504  TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape;
505  if ( std::fabs(as->GetDX()) < numeric_limits<double>::epsilon() &&
506  std::fabs(as->GetDY()) < numeric_limits<double>::epsilon() &&
507  std::fabs(as->GetDZ()) < numeric_limits<double>::epsilon() ) {
508  as->NeedsBBoxRecompute();
509  as->ComputeBBox();
510  }
511  }
512  parent->AddNode(daughter, id, transform);
513  geo_node_t* n = static_cast<geo_node_t*>(parent->GetNode(id));
514  n->geo_node_t::SetUserExtension(new PlacedVolume::Object());
515  return PlacedVolume(n);
516 }
517 
519 PlacedVolume Volume::placeVolume(const Volume& volume, const Transform3D& trans) const {
520  return _addNode(m_element, volume, _transform(trans));
521 }
522 
525  return _addNode(m_element, volume, identityTransform());
526 }
527 
529 PlacedVolume Volume::placeVolume(const Volume& volume, const Position& pos) const {
530  return _addNode(m_element, volume, _translation(pos));
531 }
532 
534 PlacedVolume Volume::placeVolume(const Volume& volume, const RotationZYX& rot) const {
535  return _addNode(m_element, volume, _rotationZYX(rot));
536 }
537 
539 PlacedVolume Volume::placeVolume(const Volume& volume, const Rotation3D& rot) const {
540  return _addNode(m_element, volume, _rotation3D(rot));
541 }
542 
544 const Volume& Volume::setMaterial(const Material& m) const {
545  if (m.isValid()) {
546  TGeoMedium* medium = m._ptr<TGeoMedium>();
547  if (medium) {
548  m_element->SetMedium(medium);
549  return *this;
550  }
551  throw runtime_error("DD4hep: Volume: Medium " + string(m.name()) + " is not registered with geometry manager.");
552  }
553  throw runtime_error("DD4hep: Volume: Attempt to assign invalid material.");
554 }
555 
558  return Ref_t(m_element->GetMedium());
559 }
560 
561 #include "TROOT.h"
562 
564 const Volume& Volume::setVisAttributes(const VisAttr& attr) const {
565  if (attr.isValid()) {
566  VisAttr::Object* vis = attr.data<VisAttr::Object>();
567  Color_t bright = vis->color;//kBlue;//TColor::GetColorBright(vis->color);
568  Color_t dark = vis->color;//kRed;//TColor::GetColorDark(vis->color);
569  TColor* c = vis->col;//gROOT->GetColor(dark);
570  int draw_style = vis->drawingStyle;
571  int line_style = vis->lineStyle;
572 
573  m_element->SetVisibility(vis->visible ? kTRUE : kFALSE);
574  m_element->SetVisContainers(kTRUE);
575  //m_element->SetAttBit(TGeoAtt::kVisContainers, kTRUE);
576  m_element->SetVisDaughters(vis->showDaughters ? kTRUE : kFALSE);
577  printout(DEBUG,"setVisAttributes",
578  "Set color %3d [%02X,%02X,%02X] DrawingStyle:%9s LineStyle:%6s for volume %s",
579  int(vis->color),
580  c ? int(255*c->GetRed()) : 0xFF,
581  c ? int(255*c->GetGreen()) : 0xFF,
582  c ? int(255*c->GetBlue()) : 0xFF,
583  draw_style == VisAttr::SOLID ? "Solid" : "Wireframe",
584  line_style == VisAttr::SOLID ? "Solid" : "Dashed",
585  name()
586  );
587  m_element->SetLineWidth(10);
588  m_element->SetLineColor(dark);
589  if (draw_style == VisAttr::SOLID) {
590  m_element->SetLineColor(bright);
591 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,34,25)
592  m_element->SetFillColorAlpha(bright,vis->alpha);
593 #else
594  m_element->SetFillColor(bright);
595 #endif
596  m_element->SetFillStyle(1001); // Root: solid
597  // Suggested by Nikiforos. Not optimal.
598  //m_element->GetMedium()->GetMaterial()->SetTransparency((1-vis->alpha)*100);
599 
600 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,0,0)
601  // As suggested by Valentin Volkl https://sft.its.cern.ch/jira/browse/DDFORHEP-20
602  //
603  // According to https://root.cern.ch/phpBB3/viewtopic.php?t=2309#p66013
604  // a transparency>50 will make a volume invisible in the normal pad.
605  // Hence: possibly restrict transparency to a maximum of 50.
606  // but let's see first how this behaves.
607  m_element->SetTransparency((1-vis->alpha)*100);
608 #endif
609  }
610  else {
611  printout(DEBUG,"setVisAttributes","Set to wireframe vis:%s",name());
612  m_element->SetLineColor(kBlack);
613  m_element->SetFillColor(0);
614  m_element->SetFillStyle(0); // Root: hollow
615  }
616  if (line_style == VisAttr::SOLID) // Root line style: 1=solid, 2=dash, 3=dot, 4=dash-dot.
617  m_element->SetLineStyle(1);
618  else if (line_style == VisAttr::DASHED)
619  m_element->SetLineStyle(2);
620  else
621  m_element->SetLineStyle(line_style);
622 
623 
624  /*
625  m_element->SetVisibility(kTRUE);
626  m_element->SetAttBit(TGeoAtt::kVisContainers, kTRUE);
627  m_element->SetVisDaughters(kTRUE);
628  printout(INFO,"setVisAttributes","Set Line color for volume %s",name());
629  m_element->SetLineColor(bright);
630  m_element->SetFillColor(bright);
631  m_element->SetFillStyle(1001); // Root: solid
632  if (line_style == VisAttr::SOLID)
633  m_element->SetFillStyle(1);
634  else if (line_style == VisAttr::DASHED)
635  m_element->SetFillStyle(2);
636  else
637  m_element->SetFillStyle(line_style);
638  m_element->SetLineWidth(10);
639  */
640  }
641  Volume::Object* o = _userExtension(*this);
642  if ( o ) o->vis = attr;
643  return *this;
644 }
645 
647 const Volume& Volume::setVisAttributes(const LCDD& lcdd, const string& nam) const {
648  if (!nam.empty()) {
649  VisAttr attr = lcdd.visAttributes(nam);
650  setVisAttributes(attr);
651  }
652  else {
653  /*
654  string tag = this->name();
655  if ( ::strstr(tag.c_str(),"_slice") ) // Slices turned off by default
656  setVisAttributes(lcdd.visAttributes("InvisibleNoDaughters"));
657  else if ( ::strstr(tag.c_str(),"_layer") ) // Layers turned off, but daughters possibly visible
658  setVisAttributes(lcdd.visAttributes("InvisibleWithDaughters"));
659  else if ( ::strstr(tag.c_str(),"_module") ) // Tracker modules similar to layers
660  setVisAttributes(lcdd.visAttributes("InvisibleWithDaughters"));
661  else if ( ::strstr(tag.c_str(),"_module_component") ) // Tracker modules similar to layers
662  setVisAttributes(lcdd.visAttributes("InvisibleNoDaughters"));
663  */
664  }
665  return *this;
666 }
667 
669 const Volume& Volume::setAttributes(const LCDD& lcdd, const string& rg, const string& ls, const string& vis) const {
670  if (!rg.empty())
671  setRegion(lcdd.region(rg));
672  if (!ls.empty())
673  setLimitSet(lcdd.limitSet(ls));
674  setVisAttributes(lcdd, vis);
675  return *this;
676 }
677 
680  Object* o = _data(*this, false);
681  if (o)
682  return o->vis;
683  return VisAttr();
684 }
685 
687 const Volume& Volume::setSolid(const Solid& s) const {
688  m_element->SetShape(s);
689  return *this;
690 }
691 
694  return Solid((*this)->GetShape());
695 }
696 
698 const Volume& Volume::setRegion(const LCDD& lcdd, const string& nam) const {
699  if (!nam.empty()) {
700  return setRegion(lcdd.region(nam));
701  }
702  return *this;
703 }
704 
706 const Volume& Volume::setRegion(const Region& obj) const {
707  _data(*this)->region = obj;
708  return *this;
709 }
710 
713  return _data(*this)->region;
714 }
715 
717 const Volume& Volume::setLimitSet(const LCDD& lcdd, const string& nam) const {
718  if (!nam.empty()) {
719  return setLimitSet(lcdd.limitSet(nam));
720  }
721  return *this;
722 }
723 
725 const Volume& Volume::setLimitSet(const LimitSet& obj) const {
726  _data(*this)->limits = obj;
727  return *this;
728 }
729 
732  return _data(*this)->limits;
733 }
734 
737  //cout << "Setting sensitive detector '" << obj.name() << "' to volume:" << ptr() << " " << name() << endl;
738  _data(*this)->sens_det = obj;
739  return *this;
740 }
741 
744  const Object* o = _data(*this);
745  return o->sens_det;
746 }
747 
749 bool Volume::isSensitive() const {
750  return _data(*this)->sens_det.isValid();
751 }
752 
754 Assembly::Assembly(const string& nam) {
755  m_element = _createTGeoVolumeAssembly(nam);
756 }
757 
static PlacedVolume _addNode(TGeoVolume *par, TGeoVolume *daughter, TGeoMatrix *transform)
Definition: Volumes.cpp:490
Handle class to hold the information of a sensitive detector.
Definition: Detector.h:47
virtual ~PlacedVolumeExtension()
Default destructor.
Definition: Volumes.cpp:319
virtual void Release() const
TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore...
Definition: Volumes.cpp:447
VisAttr vis
Reference to visualization attributes.
Definition: Volumes.h:200
Ref_t sensitiveDetector() const
Access to the handle to the sensitive detector.
Definition: Volumes.cpp:743
const Volume & setLimitSet(const LCDD &lcdd, const std::string &name) const
Set the limits to the volume. Note: If the name string is empty, the action is ignored.
Definition: Volumes.cpp:717
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:135
Solid solid() const
Access to Solid (Shape)
Definition: Volumes.cpp:693
Volume volume() const
Logical volume of this placement.
Definition: Volumes.cpp:389
const VolIDs & volIDs() const
Access to the volume IDs.
Definition: Volumes.cpp:399
const char * name() const
Access the object name (or "" if not supported by the object)
Definition: Handle.inl:36
long refCount
Reference count on object (used to implement Grab/Release)
Definition: Volumes.h:194
Handle class describing a material.
Definition: Objects.h:300
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:124
LimitSet limitSet() const
Access to the limit set.
Definition: Volumes.cpp:731
TGeoVolume geo_volume_t
Definition: Volumes.cpp:284
#define INCREMENT_COUNTER
Definition: config.h:18
TGeoTranslation * _translation(const Geometry::Position &pos)
Convert a Position object to a TGeoTranslation
Q * data() const
Access to an unrelated object type.
Definition: Handle.h:157
virtual TGeoExtension * Grab()
TGeoExtension overload: Method called whenever requiring a pointer to the extension.
Definition: Volumes.cpp:434
TGeoRotation * _rotationZYX(const Geometry::RotationZYX &rot)
Convert a RotationZYX object to a TGeoRotation
Object * data() const
Check if placement is properly instrumented.
Definition: Volumes.cpp:371
Implementation class extending the ROOT placed volume.
Definition: Volumes.h:72
TGeoShape * s
Definition: Volumes.cpp:294
Ref_t sens_det
Reference to the sensitive detector.
Definition: Volumes.h:202
virtual void Release() const
TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore...
Definition: Volumes.cpp:333
return e
Definition: Volumes.cpp:297
VisAttr visAttributes() const
Access the visualisation attributes.
Definition: Volumes.cpp:679
ClassImp(PlacedVolumeExtension) static TGeoVolume *_createTGeoVolume(const string &name
static T::Object * _userExtension(const T &v)
Definition: Volumes.cpp:286
virtual TGeoExtension * Grab()
TGeoExtension overload: Method called whenever requiring a pointer to the extension.
Definition: Volumes.cpp:324
T * ptr() const
Access to the held object.
Definition: Handle.h:149
std::string toString() const
String dump.
Definition: Volumes.cpp:404
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:237
std::pair< std::vector< VolID >::iterator, bool > insert(const std::string &name, int value)
Inert new entry.
Definition: Volumes.cpp:350
Material material() const
Volume material.
Definition: Volumes.cpp:384
const Volume & setVisAttributes(const VisAttr &obj) const
Set Visualization attributes to the volume.
Definition: Volumes.cpp:564
virtual LimitSet limitSet(const std::string &name) const =0
Retrieve a limitset by it's name from the detector description.
long refCount
Reference count on object (used to implement Grab/Release)
Definition: Volumes.h:103
std::pair< std::string, int > VolID
Definition: Volumes.h:74
ROOT::Math::RotationZYX RotationZYX
Definition: Objects.h:98
Assembly()
Default constructor.
Definition: Volumes.h:351
const Volume & setMaterial(const Material &m) const
Set the volume's material.
Definition: Volumes.cpp:544
TGeoIdentity * identityTransform()
Access the TGeo identity transformation
static TGeoVolume * _createTGeoVolumeAssembly(const string &name)
Definition: Volumes.cpp:299
ROOT::Math::Rotation3D Rotation3D
Definition: Objects.h:106
const char * GetName(T *p)
Definition: Utilities.h:45
TGeoRotation * _rotation3D(const Geometry::Rotation3D &rot)
Convert a Rotation3D object to a TGeoRotation
Volume motherVol() const
Parent volume (envelope)
Definition: Volumes.cpp:394
TGeoHMatrix * _transform(const Geometry::Transform3D &trans)
Convert a Transform3D object to a TGeoHMatrix
Q * _ptr() const
Access to an unrelated object type.
Definition: Handle.h:153
TGeoVolumeAssembly geo_assembly_t
Definition: Volumes.cpp:285
virtual ~VolumeExtension()
Default destructor.
Definition: Volumes.cpp:425
const Volume & setAttributes(const LCDD &lcdd, const std::string &region, const std::string &limits, const std::string &vis) const
Attach attributes to the volume.
Definition: Volumes.cpp:669
#define DECREMENT_COUNTER
Definition: config.h:19
ROOT::Math::XYZVector Position
Definition: Objects.h:75
Volume()
Default constructor.
Definition: Volumes.h:245
Solid_type< TGeoShape > Solid
Definition: Shapes.h:108
Implementation class extending the ROOT volume (TGeoVolume)
Definition: Volumes.h:189
unsigned long magic
Magic word to detect memory corruptions.
Definition: Volumes.h:101
Region region() const
Access to the handle to the region structure.
Definition: Volumes.cpp:712
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: ROOTClasses.h:38
e SetUserExtension(new Volume::Object())
Handle< NamedObject > Ref_t
Default Ref_t definition describing named objects.
Definition: Handle.h:176
Handle< Implementation > handle_t
Declaration of 'self'.
Definition: Handle.h:93
virtual Region region(const std::string &name) const =0
Retrieve a region object by it's name from the detector description.
Handle class describing visualization attributes.
Definition: Objects.h:341
Object * data() const
Check if placement is properly instrumented.
Definition: Volumes.cpp:485
std::vector< VolID >::const_iterator find(const std::string &name) const
Find entry.
Definition: Volumes.cpp:341
virtual TGeoExtension * Grab()=0
TGeoExtension overload: Method called whenever requiring a pointer to the extension.
TGeoNode geo_node_t
Definition: Volumes.cpp:283
View * v
Definition: MultiView.cpp:30
Handle class describing a set of limits as they are used for simulation.
Definition: Objects.h:475
Handle class describing a region as used in simulation.
Definition: Objects.h:516
const Volume & setRegion(const LCDD &lcdd, const std::string &name) const
Set the regional attributes to the volume. Note: If the name string is empty, the action is ignored...
Definition: Volumes.cpp:698
PlacedVolume & addPhysVolID(const std::string &name, int value)
Add identifier.
Definition: Volumes.cpp:377
The main interface to the DD4hep detector description package.
Definition: LCDD.h:82
static PlacedVolume::Object * _data(const PlacedVolume &v)
Definition: Volumes.cpp:363
const Volume & setSensitiveDetector(const SensitiveDetector &obj) const
Assign the sensitive detector structure.
Definition: Volumes.cpp:736
virtual const HandleMap & visAttributes() const =0
Accessor to the map of visualisation attributes.
int printout(PrintLevel severity, const char *src, const char *fmt,...)
Calls the display action with a given severity level.
Definition: Printout.cpp:111
Material material() const
Access to the Volume material.
Definition: Volumes.cpp:557
ROOT::Math::Transform3D Transform3D
Definition: Objects.h:110
const Volume & setSolid(const Solid &s) const
Set the volume's solid shape.
Definition: Volumes.cpp:687
PlacedVolumeExtension()
Default constructor.
Definition: Volumes.cpp:306
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: Volumes.h:36
TGeoShape TGeoMedium * m
Definition: Volumes.cpp:294
PlacedVolume placeVolume(const Volume &vol) const
Place daughter volume. The position and rotation are the identity.
Definition: Volumes.cpp:524
unsigned long long int magic_word()
Access to the magic word, which is protecting some objects against memory corruptions.
Definition: Handle.h:55
Concrete object implementation of the VisAttr Handle.
bool isSensitive() const
Accessor if volume is sensitive (ie. is attached to a sensitive detector)
Definition: Volumes.cpp:749