DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
VolumeManager.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
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/Detector.h>
16 #include <DD4hep/Printout.h>
17 #include <DD4hep/MatrixHelpers.h>
18 #include <DD4hep/detail/Handle.inl>
22 
23 // C/C++ includes
24 #include <set>
25 #include <cmath>
26 #include <sstream>
27 #include <iomanip>
28 
29 using namespace dd4hep;
30 using namespace dd4hep::detail;
31 
33 
35 namespace dd4hep {
36 
38  namespace detail {
39 
41 
46  typedef std::vector<TGeoNode*> Chain;
48  typedef std::pair<VolumeID, VolumeID> Encoding;
54  std::set<VolumeID> m_entries;
56  bool m_debug = false;
58  std::size_t m_numNodes = 0;
59 
60  public:
63  : m_detDesc(description), m_volManager(vm)
64  {
65  m_debug = (0 != ::getenv("DD4HEP_VOLMGR_DEBUG"));
66  }
67 
69  size_t numNodes() const { return m_numNodes; }
70 
72  void populate(DetElement e) {
73  //const char* typ = 0;//::getenv("VOLMGR_NEW");
74  SensitiveDetector parent_sd;
76  parent_sd = m_detDesc.sensitiveDetector(e.name());
77  }
78  //printout(INFO, "VolumeManager", "++ Executing %s plugin manager version",typ ? "***NEW***" : "***OLD***");
79  for (const auto& i : e.children() ) {
80  DetElement de = i.second;
81  PlacedVolume pv = de.placement();
82  if (pv.isValid()) {
83  Chain chain;
84  Encoding coding(0, 0);
85  SensitiveDetector sd = parent_sd;
86  m_entries.clear();
87  scanPhysicalVolume(de, de, pv, coding, sd, chain);
88  continue;
89  }
90  printout(WARNING, "VolumeManager", "++ Detector element %s of type %s has no placement.",
91  de.name(), de.type().c_str());
92  }
93  }
96  Encoding parent_encoding,
97  SensitiveDetector& sd, Chain& chain)
98  {
99  TGeoNode* node = pv.ptr();
100  size_t count = 0;
101  if (node) {
102  Volume vol = pv.volume();
103  const VolIDs& pv_ids = pv.volIDs();
104  Encoding vol_encoding = parent_encoding;
105  bool is_sensitive = vol.isSensitive();
106  bool have_encoding = pv_ids.empty();
107  bool compound = e.type() == "compound";
108 
109  if ( compound ) {
110  sd = SensitiveDetector(0);
111  vol_encoding = Encoding();
112  }
113  else if ( !sd.isValid() ) {
114  if ( is_sensitive )
115  sd = vol.sensitiveDetector();
116  else if ( (parent->flag&DetElement::Object::HAVE_SENSITIVE_DETECTOR) )
117  sd = m_detDesc.sensitiveDetector(parent.name());
118  else if ( (e->flag&DetElement::Object::HAVE_SENSITIVE_DETECTOR) )
119  sd = m_detDesc.sensitiveDetector(e.name());
120  }
121  chain.emplace_back(node);
122  if ( sd.isValid() && !pv_ids.empty() ) {
123  Readout ro = sd.readout();
124  if ( ro.isValid() ) {
125  vol_encoding = update_encoding(ro.idSpec(), pv_ids, parent_encoding);
126  have_encoding = true;
127  }
128  else {
129  printout(WARNING, "VolumeManager",
130  "%s: Strange constellation volume %s is sensitive, but has no readout! sd:%p",
131  parent.name(), pv.volume().name(), sd.ptr());
132  }
133  }
134  for (int idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) {
135  TGeoNode* daughter = node->GetDaughter(idau);
136  PlacedVolume placement(daughter);
137  if ( placement.data() ) {
138  PlacedVolume pv_dau(daughter);
139  DetElement de_dau;
143  for( const auto& de : e.children() ) {
144  if ( de.second.placement().ptr() == daughter ) {
145  de_dau = de.second;
146  break;
147  }
148  }
149  if ( de_dau.isValid() ) {
150  Chain dau_chain;
151  count += scanPhysicalVolume(parent, de_dau, pv_dau, vol_encoding, sd, dau_chain);
152  }
153  else {
154  count += scanPhysicalVolume(parent, e, pv_dau, vol_encoding, sd, chain);
155  }
156  }
157  else {
158  except("VolumeManager",
159  "Invalid not instrumented placement:"+std::string(daughter->GetName())+
160  " [Internal error -- bad detector constructor]");
161  }
162  if ( compound ) {
163  sd = SensitiveDetector(0);
164  }
165  }
166  if ( sd.isValid() ) {
167  if ( !have_encoding && !compound ) {
168  printout(ERROR, "VolumeManager","Element %s: Missing SD encoding. Volume manager won't work!",
169  e.path().c_str());
170  }
171  if ( is_sensitive || count > 0 ) {
174  if ( node == e.placement().ptr() ) {
175  // These here are placement nodes, which at the same time are DetElement placements
176  // 1) We recuperate volumes from lower levels by reusing the subdetector
177  // This only works if there is exactly one sensitive detector per subdetector!
178  // 2) DetElements in the upper hierarchy of the sensitive also get al volume id,
179  // and the volume is registered. (to be discussed)
180  //
181  // I hate this, but I could not talk Frank out of this! M.F.
182  //
183  e.object<DetElement::Object>().volumeID = vol_encoding.first;
184  }
185  else {
186  // These here are placement nodes, which are no DetElement placement
187  // used e.g. to model a very fine grained sensitive volume structure
188  // without always having DetElements.
189  }
190  add_entry(sd, parent, e, node, vol_encoding, chain);
191  ++count;
192  if ( m_debug ) {
193  IDDescriptor id(sd.readout().idSpec());
194  printout(INFO,"VolumeManager","Parent: %-44s id:%016llx Encoding: %s",
195  parent.path().c_str(), parent.volumeID(), id.str(parent_encoding.first,parent_encoding.second).c_str());
196  printout(INFO,"VolumeManager","Element:%-44s id:%016llx Encoding: %s",
197  e.path().c_str(), e.volumeID(), id.str(vol_encoding.first,vol_encoding.second).c_str());
198  printout(INFO, "VolumeManager", "%s SD:%s VolIDs:%s id:%016llx mask:%016llx",
199  node == e.placement().ptr() ? "DETELEMENT PLACEMENT" : "VOLUME PLACEMENT ",
200  sd.name(), pv_ids.str().c_str(), vol_encoding.first, vol_encoding.second);
201  }
202  }
203  }
204  chain.pop_back();
205  }
206  return count;
207  }
208 
210  static Encoding update_encoding(const IDDescriptor iddesc, const VolIDs& ids, const Encoding& initial) {
211  VolumeID volume_id = initial.first, mask = initial.second;
212  for (VolIDs::const_iterator i = ids.begin(); i != ids.end(); ++i) {
213  const auto& id = (*i);
214  const BitFieldElement* f = iddesc.field(id.first);
215  VolumeID msk = f->mask();
216  int off = f->offset();
217  VolumeID val = id.second; // Necessary to extend volume IDs > 32 bit
218  volume_id |= ((f->value(val << off) << off)&msk);
219  mask |= msk;
220  }
221  return std::make_pair(volume_id, mask);
222  }
224  static Encoding encoding(const IDDescriptor iddesc, const VolIDs& ids) {
225  VolumeID volume_id = 0, mask = 0;
226  for (VolIDs::const_iterator i = ids.begin(); i != ids.end(); ++i) {
227  const auto& id = (*i);
228  const BitFieldElement* f = iddesc.field(id.first);
229  VolumeID msk = f->mask();
230  int off = f->offset();
231  VolumeID val = id.second; // Necessary to extend volume IDs > 32 bit
232  volume_id |= ((f->value(val << off) << off)&msk);
233  mask |= msk;
234  }
235  return std::make_pair(volume_id, mask);
236  }
237 
239  const TGeoNode* n, const Encoding& code, Chain& nodes)
240  {
241  if ( sd.isValid() ) {
242  if (m_entries.find(code.first) == m_entries.end()) {
243  Readout ro = sd.readout();
244  std::string sd_name = sd.name();
245  DetElement sub_detector = m_detDesc.detector(sd_name);
246  VolumeManager section = m_volManager.addSubdetector(sub_detector, ro);
247 
248  //m_debug = true;
249  // This is the block, we effectively have to save for each physical volume with a VolID
250  VolumeManagerContext* context = nodes.empty()
253  context->identifier = code.first;
254  context->mask = code.second;
255  context->element = e;
256  context->flag = nodes.empty() ? 0 : 1;
257  if ( context->flag ) {
259  ext->placement = PlacedVolume(n);
260  for (std::size_t i = nodes.size(); i > 1; --i) { // Omit the placement of the parent DetElement
261  TGeoMatrix* m = nodes[i-1]->GetMatrix();
262  ext->toElement.MultiplyLeft(m);
263  }
264  }
265  if ( !section.adoptPlacement(context) || m_debug ) {
266  print_node(sd, parent, e, n, code, nodes);
267  }
268  m_entries.insert(code.first);
269  ++m_numNodes;
270  //if ( (m_numNodes%1000) == 0 ) {
271  // printout(INFO, "VolumeManager","++ Added %ld volume entries.",m_numNodes);
272  //}
273  }
274  }
275  }
276 
278  const TGeoNode* n, const Encoding& code, const Chain& nodes) const
279  {
280  PlacedVolume pv = n;
281  Readout ro = sd.readout();
282  bool sensitive = pv.volume().isSensitive();
283 
284  //if ( !sensitive ) return;
285  std::stringstream log;
286  log << m_entries.size() << ": Detector: " << e.path()
287  << " id:" << volumeID(code.first)
288  << " Nodes(" << int(nodes.size()) << "):" << ro.idSpec().str(code.first,code.second);
289  printout(m_debug ? INFO : DEBUG,"VolumeManager",log.str().c_str());
290  //for(const auto& i : nodes )
291  // log << i->GetName() << "/";
292 
293  log.str("");
294  log << m_entries.size() << ": " << parent.name()
295  << " ro:" << ro.name() << " pv:" << n->GetName()
296  << " Sensitive:" << yes_no(sensitive);
297  printout(m_debug ? INFO : DEBUG, "VolumeManager", log.str().c_str());
298  }
299  };
300  } /* End namespace detail */
301 } /* End namespace dd4hep */
302 
305  if ( 0 == flag ) return;
306 }
307 
310  return element.placement();
311 }
312 
315  if ( 0 == flag )
316  return element.placement();
318  return ext->placement;
319 }
320 
322 const TGeoHMatrix& VolumeManagerContext::toElement() const {
323  static TGeoHMatrix identity;
324  if ( 0 == flag ) return identity;
326  return ext->toElement;
327 }
328 
330 Position VolumeManagerContext::localToElement(const double local[3]) const {
331  double elt[3];
332  toElement().LocalToMaster(local, elt);
333  return { elt[0], elt[1], elt[2] };
334 }
335 
338  double loc[3];
339  local.GetCoordinates(loc);
340  return localToElement(loc);
341 }
342 
344 Position VolumeManagerContext::localToWorld(const double local[3]) const {
345  double elt[3];
346  toElement().LocalToMaster(local, elt);
347  return element.nominal().localToWorld(elt);
348 }
349 
352  double l[3];
353  local.GetCoordinates(l);
354  return localToWorld(l);
355 }
356 
358 Position VolumeManagerContext::worldToElement(const double world[3]) const {
359  return element.nominal().worldToLocal(world);
360 }
361 
364  return element.nominal().worldToLocal(world);
365 }
366 
368 void VolumeManagerContext::worldToElement(const double world[3], double elt[3]) const {
369  element.nominal().worldToLocal(world, elt);
370 }
371 
373 Position VolumeManagerContext::worldToLocal(const double world[3]) const {
374  double elt[3], local[3];
375  worldToElement(world, elt);
376  toElement().MasterToLocal(elt, local);
377  return { local[0], local[1], local[2] };
378 }
379 
382  double global[3];
383  world.GetCoordinates(global);
384  return worldToLocal(global);
385 }
386 
388 void VolumeManagerContext::worldToLocal(const double world[3], double local[3]) const {
389  double elt[3];
390  worldToElement(world, elt);
391  toElement().MasterToLocal(elt, local);
392 }
393 
395 VolumeManager::VolumeManager(const Detector& description, const std::string& nam, DetElement elt, Readout ro, int flags) {
396  printout(INFO, "VolumeManager", " - populating volume ids - be patient ..." );
397  std::size_t node_count = 0;
398  Object* obj_ptr = new Object();
399  assign(obj_ptr, nam, "VolumeManager");
400  if (elt.isValid()) {
401  detail::VolumeManager_Populator p(description, *this);
402  obj_ptr->detector = elt;
403  obj_ptr->id = ro.isValid() ? ro.idSpec() : IDDescriptor();
404  obj_ptr->top = obj_ptr;
405  obj_ptr->flags = flags;
406  p.populate(elt);
407  node_count = p.numNodes();
408  }
409  printout(INFO, "VolumeManager", " - populating volume ids - done. %ld nodes.",node_count);
410 }
411 
414  Object* obj_ptr = new Object();
415  obj_ptr->detector = sub_detector;
416  obj_ptr->id = ro.isValid() ? ro.idSpec() : IDDescriptor();
417  assign(obj_ptr, sub_detector.name(), "VolumeManager");
418 }
419 
421  if( not description.volumeManager().isValid() ) {
422  description.apply("DD4hepVolumeManager", 0, 0);
423  }
424  return description.volumeManager();
425 }
426 
429  if (isValid()) {
430  Object& o = _data();
431  if (!det.isValid()) {
432  throw std::runtime_error("dd4hep: VolumeManager::addSubdetector: Only valid subdetectors "
433  "are allowed. [Invalid DetElement]");
434  }
435  auto i = o.subdetectors.find(det);
436  if (i == o.subdetectors.end()) {
437  std::string det_name = det.name();
438  // First check all pre-conditions
439  if (!ro.isValid()) {
440  throw std::runtime_error("dd4hep: VolumeManager::addSubdetector: Only subdetectors with a "
441  "valid readout descriptor are allowed. [Invalid DetElement:" + det_name + "]");
442  }
443  PlacedVolume pv = det.placement();
444  if (!pv.isValid()) {
445  throw std::runtime_error("dd4hep: VolumeManager::addSubdetector: Only subdetectors with a "
446  "valid placement are allowed. [Invalid DetElement:" + det_name + "]");
447  }
448  auto vit = pv.volIDs().find("system");
449  if (vit == pv.volIDs().end()) {
450  throw std::runtime_error("dd4hep: VolumeManager::addSubdetector: Only subdetectors with "
451  "valid placement VolIDs are allowed. [Invalid DetElement:" + det_name + "]");
452  }
453 
454  i = o.subdetectors.emplace(det, VolumeManager(det,ro)).first;
455  const auto& id = (*vit);
456  VolumeManager mgr = (*i).second;
457  const BitFieldElement* field = ro.idSpec().field(id.first);
458  if (!field) {
459  throw std::runtime_error("dd4hep: VolumeManager::addSubdetector: IdDescriptor of " +
460  std::string(det.name()) + " has no field " + id.first);
461  }
462  Object& mo = mgr._data();
463  mo.top = o.top;
464  mo.flags = o.flags;
465  mo.system = field;
466  mo.sysID = id.second;
467  mo.detMask = mo.sysID;
468  o.managers[mo.sysID] = mgr;
470  &mo,&Object::update);
471  }
472  return (*i).second;
473  }
474  throw std::runtime_error("dd4hep: VolumeManager::addSubdetector: "
475  "Failed to add subdetector section. [Invalid Manager Handle]");
476 }
477 
480  if (isValid()) {
481  const Object& o = _data();
483  for (const auto& j : o.subdetectors ) {
484  const Object& mo = j.second._data();
485  VolumeID sys_id = mo.system->value(id << mo.system->offset());
486  if ( sys_id == mo.sysID )
487  return j.second;
488  }
489  throw std::runtime_error("dd4hep: VolumeManager::subdetector(VolID): "
490  "Attempt to access unknown subdetector section.");
491  }
492  throw std::runtime_error("dd4hep: VolumeManager::subdetector(VolID): "
493  "Cannot assign ID descriptor [Invalid Manager Handle]");
494 }
495 
498  if (isValid()) {
499  return _data().detector;
500  }
501  throw std::runtime_error("dd4hep: VolumeManager::detector: Cannot access DetElement [Invalid Handle]");
502 }
503 
506  return _data().id;
507 }
508 
511  std::stringstream err;
512  Object& o = _data();
513  VolumeID vid = context->identifier;
514  VolumeID mask = context->mask;
515  PlacedVolume pv = context->elementPlacement();
516  auto i = o.volumes.find(vid);
517 
518  if ( (vid&mask) != vid ) {
519  err << "Bad context mask:" << (void*)mask
520  << " id:" << (void*)vid
521  << " pv:" << pv.name()
522  << " Sensitive:" << yes_no(pv.volume().isSensitive())
523  << std::endl;
524  goto Fail;
525  }
526 
527  if ( i == o.volumes.end()) {
528  o.volumes[vid] = context;
529  o.detMask |= mask;
530  err << "Inserted new volume:" << std::setw(6) << std::left << o.volumes.size()
531  << " Ptr:" << (void*) pv.ptr()
532  << " [" << pv.name() << "]"
533  << " id:" << std::setw(16) << std::hex << std::right << std::setfill('0') << vid << std::dec << std::setfill(' ')
534  << " mask:" << std::setw(16) << std::hex << std::right << std::setfill('0') << mask << std::dec << std::setfill(' ')
535  << " Det:" << std::setw(4) << std::hex << std::right << std::setfill('0') << context->element.volumeID()
536  << " / " << std::setw(4) << sys_id << std::dec << std::setfill(' ') << ": " << context->element.path();
537  printout(VERBOSE, "VolumeManager", err.str().c_str());
538  //printout(ALWAYS, "VolumeManager", err.str().c_str());
539  return true;
540  }
541  err << "+++ Attempt to register duplicate"
542  << " id:" << std::setw(16) << std::hex << std::right << std::setfill('0') << vid << std::dec << std::setfill(' ')
543  << " mask:" << std::setw(16) << std::hex << std::right << std::setfill('0') << mask << std::dec << std::setfill(' ')
544  << " to detector " << o.detector.name()
545  << " ptr:" << (void*) pv.ptr()
546  << " Name:" << pv.name()
547  << " Sensitive:" << yes_no(pv.volume().isSensitive())
548  << std::endl;
549  printout(ERROR, "VolumeManager", "%s", err.str().c_str());
550  err.str("");
551  context = (*i).second;
552  //pv = context->placement;
553  err << " !!!!! +++ Clashing"
554  << " id:" << std::setw(16) << std::hex << std::right << std::setfill('0') << vid << std::dec << std::setfill(' ')
555  << " mask:" << std::setw(16) << std::hex << std::right << std::setfill('0') << mask << std::dec << std::setfill(' ')
556  << " to detector " << o.detector.name()
557  << " ptr:" << (void*) pv.ptr()
558  << " Name:" << pv.name()
559  << " Sensitive:" << yes_no(pv.volume().isSensitive())
560  << std::endl;
561  Fail:
562  printout(ERROR, "VolumeManager", "%s", err.str().c_str());
563  // throw std::runtime_error(err.str());
564  return false;
565 }
566 
569  std::stringstream err;
570  if ( isValid() ) {
571  Object& o = _data();
572  if ( context ) {
573  if ( (o.flags & ONE) == ONE ) {
574  VolumeManager top(o.top);
575  return top.adoptPlacement(context);
576  }
577  if ( (o.flags & TREE) == TREE ) {
578  bool isTop = ptr() == o.top;
579  if ( !isTop ) {
580  VolumeID sys_id = o.system->value(context->identifier);
581  if ( sys_id == o.sysID ) {
582  return adoptPlacement(sys_id, context);
583  }
584  VolumeManager top(o.top);
585  return top.adoptPlacement(context);
586  }
587  for( auto& j : o.managers ) {
588  Object& mgr = j.second._data();
589  VolumeID sid = mgr.system->value(context->identifier);
590  if ( j.first == sid ) {
591  return j.second.adoptPlacement(sid, context);
592  }
593  }
594  }
595  return false;
596  }
597  except("VolumeManager","dd4hep: Failed to add new physical volume to detector: %s "
598  "[Invalid Context]", o.detector.name());
599  }
600  except("VolumeManager","dd4hep: Failed to add new physical volume [Invalid Manager Handle]");
601  return false;
602 }
603 
606  if (isValid()) {
607  VolumeManagerContext* c = 0;
608  const Object& o = _data();
609  bool is_top = o.top == ptr();
610  bool one_tree = (o.flags & ONE) == ONE;
611  if ( !is_top && one_tree ) {
612  return VolumeManager(o.top).lookupContext(volume_id);
613  }
614  VolumeID id = volume_id;
616  c = o.search(id);
617  if (c)
618  return c;
620  if (!one_tree) {
621  for (const auto& j : o.subdetectors ) {
622  if ((c = j.second._data().search(id)) != 0)
623  return c;
624  }
625  }
626  except("VolumeManager","lookupContext: Failed to search Volume context %016llX [Unknown identifier]", (void*)volume_id);
627  }
628  except("VolumeManager","lookupContext: Failed to search Volume context [Invalid Manager Handle]");
629  return 0;
630 }
631 
634  VolumeManagerContext* c = lookupContext(volume_id); // Throws exception if not found!
635  return c->elementPlacement();
636 }
637 
640  VolumeManagerContext* c = lookupContext(volume_id); // Throws exception if not found!
641  return c->volumePlacement();
642 }
643 
646  if (isValid()) {
647  const Object& o = _data();
648  VolumeID sys_id = 0;
649  if ( o.system ) {
650  sys_id = o.system->value(volume_id);
651  }
652  else {
653  for (const auto& j : o.subdetectors ) {
654  if ( j.second->system ) {
655  VolumeID vid = volume_id&j.second->system->mask();
656  if ( (volume_id&j.second->sysID) == vid ) {
657  sys_id = j.second->sysID;
658  break;
659  }
660  }
661  }
662  }
663  VolumeID det_id = (volume_id&sys_id);
664  VolumeManagerContext* c = lookupContext(det_id); // Throws exception if not found!
665  return c->element;
666  }
667  except("VolumeManager","lookupContext: Failed to search Volume context [Invalid Manager Handle]");
668  return DetElement();
669 }
670 
673  VolumeManagerContext* c = lookupContext(volume_id); // Throws exception if not found!
674  return c->element;
675 }
676 
678 const TGeoMatrix&
680  VolumeID volume_id) const
681 {
682  VolumeManagerContext* c = lookupContext(volume_id); // Throws exception if not found!
684  return a.worldTransformation();
685 }
686 
688 std::ostream& dd4hep::operator<<(std::ostream& os, const VolumeManager& mgr) {
690  VolumeManager::Object* top = dynamic_cast<VolumeManager::Object*>(o.top);
691  bool isTop = top == &o;
692  //bool hasTop = (o.flags & VolumeManager::ONE) == VolumeManager::ONE;
693  //bool isSdet = (o.flags & VolumeManager::TREE) == VolumeManager::TREE && top != &o;
694  std::string prefix(isTop ? "" : "++ ");
695  os << prefix << (isTop ? "TOP Level " : "Secondary ") << "Volume manager:"
696  << &o << " " << o.detector.name() << " IDD:"
697  << o.id.toString() << " SysID:" << (void*) o.sysID << " "
698  << o.managers.size() << " subsections " << o.volumes.size()
699  << " placements ";
700  if (!(o.managers.empty() && o.volumes.empty()))
701  os << std::endl;
702  for ( const auto& i : o.volumes ) {
703  const VolumeManagerContext* c = i.second;
704  os << prefix
705  << "Element:" << std::setw(32) << std::left << c->element.path()
706  //<< " pv:" << std::setw(32) << std::left << c->placement().name()
707  << " id:" << std::setw(18) << std::left << (void*) c->identifier
708  << " mask:" << std::setw(18) << std::left << (void*) c->mask
709  << std::endl;
710  }
711  for( const auto& i : o.managers )
712  os << prefix << i.second << std::endl;
713  return os;
714 }
715 
719  destroyObjects(volumes);
722  managers.clear();
723  subdetectors.clear();
724 }
725 
727 void VolumeManagerObject::update(unsigned long tags, DetElement& det, void* param) {
729  printout(DEBUG,"VolumeManager","+++ Conditions update %s param:%p",det.path().c_str(),param);
731  printout(DEBUG,"VolumeManager","+++ Alignment update %s param:%p",det.path().c_str(),param);
732 
733  for(const auto& i : volumes )
734  printout(DEBUG,"VolumeManager","+++ Alignment update %s",i.second->elementPlacement().name());
735 }
736 
739  auto i = volumes.find(vol_id&detMask);
740  return (i == volumes.end()) ? 0 : (*i).second;
741 }
742 
dd4hep::DetElement::children
const Children & children() const
Access to the list of children.
Definition: DetElement.cpp:207
dd4hep::VolumeManagerContext::worldToElement
Position worldToElement(const Position &world) const
Transform world coordinates to the DetElement coordinates.
Definition: VolumeManager.cpp:363
dd4hep::DetElement::path
const std::string & path() const
Path of the detector element (not necessarily identical to placement path!)
Definition: DetElement.cpp:158
dd4hep::DDSegmentation::BitFieldElement::offset
unsigned offset() const
Definition: BitFieldCoder.h:64
dd4hep::detail::VolumeManagerContextExtension::placement
PlacedVolume placement
The placement of the (sensitive) volume.
Definition: VolumeManagerInterna.h:49
DD4HEP_INSTANTIATE_HANDLE_NAMED
DD4HEP_INSTANTIATE_HANDLE_NAMED(VolumeManagerObject)
dd4hep::VolumeManager::lookupDetElement
DetElement lookupDetElement(VolumeID volume_id) const
Convenience routine: Lookup the closest subdetector detector element in the hierarchy according to a ...
Definition: VolumeManager.cpp:672
dd4hep::detail::VolumeManagerObject::flags
int flags
Population flags.
Definition: VolumeManagerInterna.h:86
dd4hep::DDSegmentation::BitFieldElement
Helper class for BitFieldCoder that corresponds to one field value.
Definition: BitFieldCoder.h:32
dd4hep::VolumeManager::lookupContext
VolumeManagerContext * lookupContext(VolumeID volume_id) const
Lookup the context, which belongs to a registered physical volume.
Definition: VolumeManager.cpp:605
dd4hep::Detector::detector
virtual DetElement detector(const std::string &name) const =0
Retrieve a subdetector element by its name from the detector description.
dd4hep::detail::VolumeManagerObject::managers
std::map< VolumeID, VolumeManager > managers
The volume managers for the individual subdetector elements.
Definition: VolumeManagerInterna.h:70
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:44
MatrixHelpers.h
Detector.h
dd4hep::VolumeManager::adoptPlacement
bool adoptPlacement(VolumeManagerContext *context)
Register physical volume with the manager (normally: section manager)
Definition: VolumeManager.cpp:568
dd4hep::detail::VolumeManagerObject::system
const BitFieldElement * system
The system field descriptor.
Definition: VolumeManagerInterna.h:80
dd4hep::IDDescriptor::field
const BitFieldElement * field(const std::string &field_name) const
Get the field descriptor of one field by name.
Definition: IDDescriptor.cpp:96
dd4hep::DetElement::type
std::string type() const
Access detector type (structure, tracker, calorimeter, etc.).
Definition: DetElement.cpp:97
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:173
dd4hep::Handle::object
Q & object() const
Access to an unrelated object type.
Definition: Handle.h:165
dd4hep::detail::VolumeManager_Populator::encoding
static Encoding encoding(const IDDescriptor iddesc, const VolIDs &ids)
Compute the encoding for a set of VolIDs within a readout descriptor.
Definition: VolumeManager.cpp:224
dd4hep::DetElement::placement
PlacedVolume placement() const
Access to the physical volume of this detector element.
Definition: DetElement.cpp:321
VolumeManagerInterna.h
dd4hep::IDDescriptor
Class implementing the ID encoding of the detector response.
Definition: IDDescriptor.h:37
dd4hep::DDSegmentation::BitFieldElement::value
FieldID value(CellID bitfield) const
calculate this field's value given an external 64 bit bitmap
Definition: BitFieldCoder.cpp:55
dd4hep::VolumeManagerContext::element
DetElement element
Handle to the closest Detector element.
Definition: VolumeManager.h:53
dd4hep::VolumeManager::worldTransformation
const TGeoMatrix & worldTransformation(const ConditionsMap &map, VolumeID volume_id) const
Convenience routine: Access the transformation of a physical volume to the world coordinate system.
Definition: VolumeManager.cpp:679
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:128
dd4hep::detail::VolumeManager_Populator::update_encoding
static Encoding update_encoding(const IDDescriptor iddesc, const VolIDs &ids, const Encoding &initial)
Compute the encoding for a set of VolIDs within a readout descriptor.
Definition: VolumeManager.cpp:210
DetectorInterna.h
dd4hep::detail::VolumeManager_Populator::print_node
void print_node(SensitiveDetector sd, DetElement parent, DetElement e, const TGeoNode *n, const Encoding &code, const Chain &nodes) const
Definition: VolumeManager.cpp:277
dd4hep::detail::VolumeManagerObject::detector
DetElement detector
The Detector element handle managed by this instance.
Definition: VolumeManagerInterna.h:74
dd4hep::DetElement::CONDITIONS_CHANGED
@ CONDITIONS_CHANGED
Definition: DetElement.h:218
dd4hep::detail::VolumeManager_Populator::Encoding
std::pair< VolumeID, VolumeID > Encoding
Definition: VolumeManager.cpp:48
dd4hep::Volume::isSensitive
bool isSensitive() const
Accessor if volume is sensitive (ie. is attached to a sensitive detector)
Definition: Volumes.cpp:1293
dd4hep::VolumeManager::detector
DetElement detector() const
Access the top level detector element.
Definition: VolumeManager.cpp:497
dd4hep::DetElement::volumeID
VolumeID volumeID() const
The cached VolumeID of this subdetector element.
Definition: DetElement.cpp:344
dd4hep::VolumeManagerContext::volumePlacement
PlacedVolume volumePlacement() const
Acces the sensitive volume placement.
Definition: VolumeManager.cpp:314
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
dd4hep::detail::VolumeManagerObject::search
VolumeManagerContext * search(const VolumeID &id) const
Search the locally cached volumes for a matching ID.
Definition: VolumeManager.cpp:738
dd4hep::detail::VolumeManagerContextExtension
Extended context. Needs to be public for persistency reasons.
Definition: VolumeManagerInterna.h:46
dd4hep::detail::VolumeManagerObject
This structure describes the internal data of the volume manager object.
Definition: VolumeManagerInterna.h:65
dd4hep::Detector::volumeManager
virtual VolumeManager volumeManager() const =0
Return handle to the VolumeManager.
dd4hep::DetElementObject
Data class with properties of a detector element.
Definition: DetectorInterna.h:81
dd4hep::operator<<
std::ostream & operator<<(std::ostream &os, const DetType &t)
Definition: DetType.h:99
dd4hep::detail::VolumeManager_Populator::VolumeManager_Populator
VolumeManager_Populator(const Detector &description, VolumeManager vm)
Default constructor.
Definition: VolumeManager.cpp:62
dd4hep::Handle::clear
Handle< T > & clear()
Release the object held by the handle.
Definition: Handle.h:136
dd4hep::VolumeManager::VolumeManager
VolumeManager()=default
Default constructor.
dd4hep::detail::VolumeManager_Populator::numNodes
size_t numNodes() const
Access node count.
Definition: VolumeManager.cpp:69
dd4hep::detail::VolumeManager_Populator::Chain
std::vector< TGeoNode * > Chain
Definition: VolumeManager.cpp:46
dd4hep::VolumeManagerContext::mask
VolumeID mask
Ignore mask of the placement identifier.
Definition: VolumeManager.h:57
dd4hep::VolumeManagerContext::~VolumeManagerContext
virtual ~VolumeManagerContext()
Default destructor.
Definition: VolumeManager.cpp:304
dd4hep::detail::VolumeManager_Populator::scanPhysicalVolume
size_t scanPhysicalVolume(DetElement &parent, DetElement e, PlacedVolume pv, Encoding parent_encoding, SensitiveDetector &sd, Chain &chain)
Scan a single physical volume and look for sensitive elements below.
Definition: VolumeManager.cpp:95
dd4hep::detail::VolumeManager_Populator::m_detDesc
const Detector & m_detDesc
Reference to the Detector instance.
Definition: VolumeManager.cpp:50
dd4hep::VolumeManager::lookupVolumePlacement
PlacedVolume lookupVolumePlacement(VolumeID volume_id) const
Lookup a physical (placed) volume identified by its 64 bit hit ID.
Definition: VolumeManager.cpp:639
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:188
dd4hep::PlacedVolumeExtension::VolIDs
Volume ID container.
Definition: Volumes.h:88
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:378
dd4hep::VolumeManager
Class to support the retrieval of detector elements and volumes given a valid identifier.
Definition: VolumeManager.h:135
dd4hep::detail
DD4hep internal namespace.
Definition: Alignments.h:32
dd4hep::detail::VolumeManagerObject::subdetectors
std::map< DetElement, VolumeManager > subdetectors
The container of subdetector elements.
Definition: VolumeManagerInterna.h:68
dd4hep::VolumeManager::lookupDetector
DetElement lookupDetector(VolumeID volume_id) const
Convenience routine: Lookup a top level subdetector detector element according to a contained 64 bit ...
Definition: VolumeManager.cpp:645
dd4hep::Detector::apply
virtual long apply(const char *factory, int argc, char **argv) const =0
Manipulate geometry using factory converter.
dd4hep::detail::VolumeManagerContextExtension::toElement
TGeoHMatrix toElement
The transformation of space-points to the coordinate system of the closests detector element.
Definition: VolumeManagerInterna.h:51
dd4hep::align::Keys::alignmentKey
static const Condition::itemkey_type alignmentKey
Key value of an alignment condition object "alignment".
Definition: Alignments.h:56
dd4hep::Handle::data
Q * data() const
Access to an unrelated object type.
Definition: Handle.h:161
dd4hep::VolumeManager::getVolumeManager
static VolumeManager getVolumeManager(const Detector &description)
static accessor calling DD4hepVolumeManagerPlugin if necessary
Definition: VolumeManager.cpp:420
dd4hep::VolumeManager::subdetector
VolumeManager subdetector(VolumeID id) const
Access the volume manager by cell id.
Definition: VolumeManager.cpp:479
dd4hep::Alignment::worldTransformation
const TGeoHMatrix & worldTransformation() const
Create cached matrix to transform to world coordinates.
Definition: Alignments.cpp:68
dd4hep::Detector::sensitiveDetector
virtual SensitiveDetector sensitiveDetector(const std::string &name) const =0
Retrieve a sensitive detector by its name from the detector description.
dd4hep::detail::VolumeManager_Populator::add_entry
void add_entry(SensitiveDetector sd, DetElement parent, DetElement e, const TGeoNode *n, const Encoding &code, Chain &nodes)
Definition: VolumeManager.cpp:238
dd4hep::ConditionsMap::get
virtual Condition get(DetElement detector, Condition::itemkey_type key) const =0
Interface to access conditions by hash value. The detector element key and the item key make a unique...
dd4hep::detail::destroyHandles
void destroyHandles(M &arg)
Functional created of map destruction functors.
Definition: Handle.h:205
dd4hep::detail::VolumeManagerObject::id
IDDescriptor id
The ID descriptor object.
Definition: VolumeManagerInterna.h:76
dd4hep::IDDescriptor::str
std::string str(VolumeID vid) const
Decode volume IDs and return string reprensentation for debugging purposes.
Definition: IDDescriptor.cpp:174
dd4hep::detail::VolumeManager_Populator::m_entries
std::set< VolumeID > m_entries
Set of already added entries.
Definition: VolumeManager.cpp:54
dd4hep::Alignment
Main handle class to hold an alignment object.
Definition: Alignments.h:115
dd4hep::DDSegmentation::BitFieldElement::mask
CellID mask() const
Definition: BitFieldCoder.h:73
dd4hep::detail::VolumeManager_Populator::populate
void populate(DetElement e)
Populate the Volume manager.
Definition: VolumeManager.cpp:72
dd4hep::VolumeManagerContext::localToElement
Position localToElement(const double local[3]) const
Transform local coordinates to the DetElement coordinates.
Definition: VolumeManager.cpp:330
dd4hep::detail::VolumeManager_Populator::VolIDs
PlacedVolume::VolIDs VolIDs
Definition: VolumeManager.cpp:47
dd4hep::VolumeManagerContext::toElement
const TGeoHMatrix & toElement() const
Access the transformation to the closest detector element.
Definition: VolumeManager.cpp:322
dd4hep::VolumeManager::addSubdetector
VolumeManager addSubdetector(DetElement detector, Readout ro)
Add a new Volume manager section according to a new subdetector.
Definition: VolumeManager.cpp:428
dd4hep::VolumeManager::lookupDetElementPlacement
PlacedVolume lookupDetElementPlacement(VolumeID volume_id) const
Lookup a physical (placed) volume of the detector element containing a volume identified by its 64 bi...
Definition: VolumeManager.cpp:633
dd4hep::sim::IDDescriptor
IDDescriptor IDDescriptor
Definition: LCIOConversions.cpp:69
dd4hep::VolumeManagerContext::flag
long flag
Flag to indicate optional information.
Definition: VolumeManager.h:59
dd4hep::Position
ROOT::Math::XYZVector Position
Definition: Objects.h:81
dd4hep::detail::VolumeManagerObject::~VolumeManagerObject
virtual ~VolumeManagerObject()
Default destructor.
Definition: VolumeManager.cpp:717
VolumeID
dd4hep::DDSegmentation::VolumeID VolumeID
Definition: SegmentationDictionary.h:49
dd4hep::detail::VolumeManagerObject::top
VolumeManagerObject * top
The reference to the TOP level VolumeManager.
Definition: VolumeManagerInterna.h:78
dd4hep::VolumeManager::idSpec
IDDescriptor idSpec() const
Access IDDescription structure.
Definition: VolumeManager.cpp:505
dd4hep::detail::VolumeManager_Populator::m_volManager
VolumeManager m_volManager
Reference to the volume manager to be populated.
Definition: VolumeManager.cpp:52
dd4hep::Handle::ptr
T * ptr() const
Access to the held object.
Definition: Handle.h:153
ObjectsInterna.h
mapping
ConditionsMap & mapping
Definition: AlignmentsCalculator.cpp:82
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::PlacedVolumeExtension::VolIDs::str
std::string str() const
String representation for debugging.
Definition: Volumes.cpp:420
dd4hep::VolumeManagerContext::identifier
VolumeID identifier
Placement identifier.
Definition: VolumeManager.h:55
dd4hep::detail::VolumeManagerObject::detMask
VolumeID detMask
Sub-detector mask.
Definition: VolumeManagerInterna.h:84
dd4hep::detail::VolumeManagerObject::sysID
VolumeID sysID
System identifier.
Definition: VolumeManagerInterna.h:82
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::detail::VolumeManagerObject::volumes
std::map< VolumeID, VolumeManagerContext * > volumes
The container of placements managed by this instance.
Definition: VolumeManagerInterna.h:72
dd4hep::SensitiveDetector::readout
Readout readout() const
Access readout structure of the sensitive detector.
Definition: DetElement.cpp:420
dd4hep::PlacedVolume::volume
Volume volume() const
Logical volume of this placement.
Definition: Volumes.cpp:452
dd4hep::VolumeManager::_data
Object & _data() const
Additional data accessor.
Definition: VolumeManager.h:148
dd4hep::PlacedVolume::data
Object * data() const
Check if placement is properly instrumented.
Definition: Volumes.cpp:431
dd4hep::VolumeManagerContext
This structure describes the cached data for one placement held by the volume manager.
Definition: VolumeManager.h:50
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::Readout
Handle to the implementation of the readout structure of a subdetector.
Definition: Readout.h:38
dd4hep::VolumeManagerContext::worldToLocal
Position worldToLocal(const Position &world) const
Transform world coordinates to the local coordinates.
Definition: VolumeManager.cpp:381
Encoding
DetElementVolumeIDs::Encoding Encoding
Definition: DetElementVolumeIDs.cpp:136
dd4hep::Readout::idSpec
IDDescriptor idSpec() const
Access IDDescription structure.
Definition: Readout.cpp:112
dd4hep::PlacedVolume::volIDs
const PlacedVolumeExtension::VolIDs & volIDs() const
Access to the volume IDs.
Definition: Volumes.cpp:480
dd4hep::DetElementObject::HAVE_SENSITIVE_DETECTOR
@ HAVE_SENSITIVE_DETECTOR
Definition: DetectorInterna.h:92
dd4hep::detail::VolumeManagerObject::update
void update(unsigned long tags, DetElement &det, void *param)
Update callback when alignment has changed (called only for subdetectors....)
Definition: VolumeManager.cpp:727
dd4hep::VolumeManagerContext::localToWorld
Position localToWorld(const double local[3]) const
Transform local coordinates to the world coordinates.
Definition: VolumeManager.cpp:344
Printout.h
dd4hep::IDDescriptor::toString
std::string toString() const
Access string representation.
Definition: IDDescriptor.cpp:60
dd4hep::PlacedVolumeExtension::VolIDs::find
std::vector< VolID >::const_iterator find(const std::string &name) const
Find entry.
Definition: Volumes.cpp:397
dd4hep::ConditionsMap
ConditionsMap class.
Definition: ConditionsMap.h:59
dd4hep::detail::VolumeManager_Populator
Helper class to populate the volume manager.
Definition: VolumeManager.cpp:45
dd4hep::DetElement::PLACEMENT_CHANGED
@ PLACEMENT_CHANGED
Definition: DetElement.h:219
dd4hep::DetElement::PLACEMENT_DETECTOR
@ PLACEMENT_DETECTOR
Definition: DetElement.h:223
dd4hep::VolumeManagerContext::elementPlacement
PlacedVolume elementPlacement() const
Acces the detector element volume placement.
Definition: VolumeManager.cpp:309
dd4hep::Volume::sensitiveDetector
Handle< NamedObject > sensitiveDetector() const
Access to the handle to the sensitive detector.
Definition: Volumes.cpp:1287