DD4hep  1.35.0
Detector Description Toolkit for High Energy Physics
DetectorInterna.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/detail/Handle.inl>
19 #include <DD4hep/InstanceCount.h>
20 #include <DD4hep/DetectorTools.h>
21 #include <DD4hep/Printout.h>
22 
23 #include <TGeoVolume.h>
24 #include <TGeoMatrix.h>
25 #include <TGeoManager.h>
26 
27 using namespace dd4hep;
28 
31 
35 
39  verbose(0), combineHits(0), ecut(0.0), readout(), region(), limits(), hitsCollection()
40 {
41  printout(VERBOSE,"SensitiveDetectorObject","+++ Created new anonymous SensitiveDetectorObject()");
43 }
44 
48  verbose(0), combineHits(0), ecut(0.0), readout(), region(), limits(), hitsCollection()
49 {
50  SetName(nam.c_str());
51  printout(VERBOSE,"SensitiveDetectorObject","+++ Created new SensitiveDetectorObject('%s')",nam.c_str());
53 }
54 
57  readout.clear();
58  region.clear();
59  limits.clear();
62 }
63 
67  flag(0), id(0), combineHits(0), typeFlag(0), level(-1), key(0), path(), placementPath(),
68  idealPlace(), placement(), volumeID(0), parent(), children(),
69  nominal(), survey()
70 {
71  printout(VERBOSE,"DetElementObject","+++ Created new anonymous DetElementObject()");
73 }
74 
76 DetElementObject::DetElementObject(const std::string& nam, int ident)
78  flag(0), id(ident), combineHits(0), typeFlag(0), level(-1), key(0), path(), placementPath(),
79  idealPlace(), placement(), volumeID(0), parent(), children(),
80  nominal(), survey()
81 {
82  SetName(nam.c_str());
83  printout(VERBOSE,"DetElementObject","+++ Created new DetElementObject('%s', %d)",nam.c_str(),id);
85 }
86 
92  placement.clear();
93  idealPlace.clear();
94  parent.clear();
97 }
98 
100 DetElementObject* DetElementObject::clone(int new_id, int flg) const {
101  DetElementObject* obj = new DetElementObject();
102  obj->id = new_id;
103  obj->typeFlag = typeFlag;
104  obj->flag = 0;
105  obj->key = 0;
106  obj->level = -1;
107  obj->combineHits = combineHits;
108  obj->nominal = AlignmentCondition();
109  obj->survey = AlignmentCondition();
110  obj->parent = DetElement();
112  obj->placement = placement;
113  obj->idealPlace = idealPlace;
114  obj->placementPath = "";
115  }
116  // This implicitly assumes that the children do not access the parent's extensions!
117  obj->ObjectExtensions::clear();
118  obj->ObjectExtensions::copyFrom(extensions, obj);
119 
120  obj->children.clear();
121  for( const auto& i : children ) {
122  const DetElementObject& d = i.second._data();
123  int child_id = flg&DetElement::PROPAGATE_PARENT_ID ? obj->id : d.id;
125  c->SetName( d.GetName() );
126  c->SetTitle( d.GetTitle() );
127  bool r = obj->children.emplace(c.name(), c).second;
128  if ( r ) {
129  c._data().parent = obj;
130  continue;
131  }
132  except("DetElement",
133  "+++ DetElement::copy: Element %s is already present [Double-Insert]", c.name());
134  }
135  return obj;
136 }
137 
139 std::pair<DetElement,Volume> DetElementObject::reflect(const std::string& new_name, int new_id, SensitiveDetector sd) {
140  struct ChildMapper {
141  std::map<TGeoNode*,TGeoNode*> nodes;
142  void match(DetElement de_det, DetElement de_ref) const {
143  auto k = nodes.find(de_det.placement().ptr());
144  printout(DEBUG,"DetElement","reflect: Match %s %p ",de_det.name(), de_det.placement().ptr());
145  if ( k == nodes.end() ) {
146  except("DetElement","reflect: Something went wrong when reflecting the source volume!");
147  }
148  de_ref.setPlacement((*k).second);
149  const auto& childrens_det = de_det.children();
150  const auto& childrens_ref = de_ref.children();
151  for( auto i=childrens_det.begin(), j=childrens_ref.begin(); i!=childrens_det.end(); ++i, ++j )
152  match((*i).second, (*j).second);
153  }
154  void map(TGeoNode* n1, TGeoNode* n2) {
155  if ( nodes.find(n1) == nodes.end() ) {
156  TGeoVolume* v1 = n1->GetVolume();
157  TGeoVolume* v2 = n2->GetVolume();
158  nodes.insert(std::make_pair(n1,n2));
159  printout(DEBUG,"DetElement","reflect: Map %p --- %p ",n1,n2);
160  for( Int_t i=0; i<v1->GetNdaughters(); ++i )
161  map(v1->GetNode(i), v2->GetNode(i));
162  }
163  }
164  } mapper;
165  DetElement det(this);
166  DetElement det_ref = det.clone(new_name, new_id);
167  Volume vol = det.volume();
168  TGeoVolume* vol_det = vol.ptr();
169  TGeoVolume* vol_ref = vol.reflect(sd);
170  const auto& childrens_det = det.children();
171  const auto& childrens_ref = det_ref.children();
172 
173  for( Int_t i=0; i<vol_det->GetNdaughters(); ++i )
174  mapper.map(vol_det->GetNode(i), vol_ref->GetNode(i));
175  for( auto i=childrens_det.begin(), j=childrens_ref.begin(); i != childrens_det.end(); ++i, ++j )
176  mapper.match((*i).second, (*j).second);
177  return std::make_pair(det_ref,vol_ref);
178 }
179 
182  if ( !privateWorld.isValid() ) {
183  DetElementObject* p = parent.ptr();
184  if ( 0 == p ) {
185  privateWorld = (WorldObject*)this;
186  return privateWorld;
187  }
188  return p->world();
189  }
190  return privateWorld;
191 }
192 
194 void DetElementObject::revalidate(bool recurse_down) {
195  PlacementPath par_path;
196  DetElement det(this);
197  DetElement par(det.parent());
198  DetElement wrld = world();
199  std::string place = det.placementPath();
200 
201  detail::tools::placementPath(par, this, par_path);
202  PlacedVolume node = detail::tools::findNode(wrld.placement(),place);
203  if ( !node.isValid() ) {
204  except("DetElement","The placement %s is not part of the hierarchy.",place.c_str());
205  }
206  printout( (idealPlace.ptr() != node.ptr()) ? INFO : DEBUG,
207  "DetElement","+++ Revalidate DetElement chache of %s -> %s Placement:%p --> %p %s",
208  det.path().c_str(), detail::tools::placementPath(par_path).c_str(),
209  placement.ptr(), node.ptr(), (placement.ptr() == node.ptr()) ? "" : "[UPDATE]");
210  if ( idealPlace.ptr() != node.ptr() && 0 == node->GetUserExtension() ) {
211  auto ext = idealPlace->GetUserExtension();
212  node->SetUserExtension(ext);
213  }
214  Volume node_vol = node.volume();
215  Volume plac_vol = idealPlace.volume();
216  if ( node_vol.ptr() != plac_vol.ptr() && 0 == node_vol->GetUserExtension() ) {
217  auto ext = plac_vol->GetUserExtension();
218  node_vol->SetUserExtension(ext);
219  }
220  // Now we can assign the new placement to the object
221  placement = node;
222 
224  if( recurse_down ) {
225  for(const auto& i : children ) {
226  i.second->revalidate(recurse_down);
227  }
228  }
229 }
230 
233  DetElement det(this);
234  DetElement wrld = this->world();
235  while( det.isValid() && det != wrld ) {
236  det->revalidate(false);
237  det = det.parent();
238  }
239 }
240 
242 void DetElementObject::removeAtUpdate(unsigned int typ, void* pointer) {
243  for( auto i=updateCalls.begin(); i != updateCalls.end(); ++i ) {
244  if ( (typ&(i->second)) == typ && i->first.par == pointer ) {
245  updateCalls.erase(i);
246  return;
247  }
248  }
249 }
250 
252 void DetElementObject::update(unsigned int tags, void* param) {
253  DetElement det(this);
254  const void* args[3] = { (void*)((unsigned long)tags), this, param };
257  printout(INFO,"DetElement",
258  "++ Need to update local and child caches of %s",
259  det.path().c_str());
260  revalidate(true);
262  }
263  for ( const auto& i : updateCalls ) {
264  if ( (tags&i.second) )
265  i.first.execute(args);
266  }
267 }
268 
270 WorldObject::WorldObject(Detector& _description, const std::string& nam)
271  : DetElementObject(nam,0), description(&_description)
272 {
273 }
274 
277 }
dd4hep::World
Handle class to hold the information of the top DetElement object 'world'.
Definition: World.h:30
dd4hep::DetElement::children
const Children & children() const
Access to the list of children.
Definition: DetElement.cpp:207
dd4hep::SensitiveDetectorObject::~SensitiveDetectorObject
virtual ~SensitiveDetectorObject()
Internal object destructor: release extension object(s)
Definition: DetectorInterna.cpp:56
dd4hep::DetElementObject::children
DetElement::Children children
The array of children.
Definition: DetectorInterna.h:131
dd4hep::DetElement::COPY_PLACEMENT
@ COPY_PLACEMENT
Definition: DetElement.h:209
dd4hep::detail::destroyHandle
void destroyHandle(T &handle)
Helper to delete objects from heap and reset the handle.
Definition: Handle.h:183
dd4hep::detail::tools::ElementPath
std::vector< DetElement > ElementPath
Definition: DetectorTools.h:38
dd4hep::WorldObject
Data class with properties of a detector element.
Definition: DetectorInterna.h:187
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:43
ConditionsInterna.h
dd4hep::ObjectExtensions
Implementation of an object supporting arbitrary user extensions.
Definition: ObjectExtensions.h:33
dd4hep::DetElementObject::typeFlag
unsigned int typeFlag
Flag to encode detector types.
Definition: DetectorInterna.h:106
dd4hep::AlignmentCondition
Main handle class to hold an alignment conditions object.
Definition: Alignments.h:68
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:164
dd4hep::SensitiveDetectorObject::readout
Readout readout
Definition: DetectorInterna.h:60
dd4hep::NamedObject::GetName
const char * GetName() const
Access name.
Definition: NamedObject.h:58
dd4hep::DetElement::placement
PlacedVolume placement() const
Access to the physical volume of this detector element.
Definition: DetElement.cpp:321
dd4hep::detail::tools::placementPath
std::string placementPath(DetElement element)
Assemble the placement path from a given detector element to the world volume.
Definition: DetectorTools.cpp:283
dd4hep::DetElementObject::idealPlace
PlacedVolume idealPlace
The subdetector placement corresponding to the ideal detector element's volume.
Definition: DetectorInterna.h:117
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:126
DetectorInterna.h
dd4hep::InstanceCount::increment
static void increment(T *)
Increment count according to type information.
Definition: InstanceCount.h:98
dd4hep::magic_word
unsigned long long int magic_word()
Access to the magic word, which is protecting some objects against memory corruptions.
Definition: Handle.h:51
dd4hep::DetElementObject::removeAtUpdate
void removeAtUpdate(unsigned int type, void *pointer)
Remove callback from object.
Definition: DetectorInterna.cpp:242
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
dd4hep::DetElement::PLACEMENT_HIGHEST
@ PLACEMENT_HIGHEST
Definition: DetElement.h:221
dd4hep::DetElementObject
Data class with properties of a detector element.
Definition: DetectorInterna.h:81
dd4hep::NamedObject::SetName
void SetName(const char *nam)
Set name (used by Handle)
Definition: NamedObject.h:62
dd4hep::DetElementObject::survey
AlignmentCondition survey
Basic detector element alignment entry containing the survey data.
Definition: DetectorInterna.h:139
dd4hep::Handle::clear
Handle< T > & clear()
Release the object held by the handle.
Definition: Handle.h:134
dd4hep::SensitiveDetectorObject::limits
LimitSet limits
Definition: DetectorInterna.h:62
DD4HEP_INSTANTIATE_HANDLE_NAMED
DD4HEP_INSTANTIATE_HANDLE_NAMED(DetElementObject)
dd4hep::DetElementObject::parent
DetElement parent
Reference to the parent element.
Definition: DetectorInterna.h:129
dd4hep::DetElementObject::privateWorld
World privateWorld
Reference to the parent element.
Definition: DetectorInterna.h:127
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:187
dd4hep::ObjectExtensions::extensions
std::map< unsigned long long int, ExtensionEntry * > extensions
The extensions object.
Definition: ObjectExtensions.h:36
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:371
dd4hep::DetElementObject::i_access_world
World i_access_world()
Resolve the world object. Internal use ONLY.
Definition: DetectorInterna.cpp:181
dd4hep::DetElementObject::flag
unsigned int flag
Flag to remember internally calculated quatities.
Definition: DetectorInterna.h:100
DetectorTools.h
dd4hep::DetElement::_data
Object & _data() const
Additional data accessor.
Definition: DetElement.h:316
dd4hep::InstanceCount::decrement
static void decrement(T *)
Decrement count according to type information.
Definition: InstanceCount.h:102
dd4hep::detail::destroyHandles
void destroyHandles(M &arg)
Functional created of map destruction functors.
Definition: Handle.h:212
dd4hep::DetElementObject::level
int level
Hierarchical level within the detector description.
Definition: DetectorInterna.h:108
dd4hep::WorldObject::WorldObject
WorldObject()
Not persistent in ROOT.
Definition: DetectorInterna.h:205
dd4hep::WorldObject::~WorldObject
virtual ~WorldObject()
Internal object destructor: release extension object(s)
Definition: DetectorInterna.cpp:276
dd4hep::DetElementObject::placement
PlacedVolume placement
The subdetector placement corresponding to the actual detector element's volume.
Definition: DetectorInterna.h:119
dd4hep::verbose
std::size_t verbose(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:63
dd4hep::DetElement::PROPAGATE_PARENT_ID
@ PROPAGATE_PARENT_ID
Definition: DetElement.h:212
ElementPath
detail::tools::ElementPath ElementPath
Definition: DetectorInterna.cpp:30
dd4hep::DetElement::setPlacement
DetElement & setPlacement(const PlacedVolume &volume)
Set the physical volumes of the detector element.
Definition: DetElement.cpp:330
dd4hep::NamedObject::GetTitle
const char * GetTitle() const
Get name (used by Handle)
Definition: NamedObject.h:70
dd4hep::detail::tools::findNode
PlacedVolume findNode(PlacedVolume top_place, const std::string &place)
Find a given node in the hierarchy starting from the top node (absolute placement!...
Definition: DetectorTools.cpp:335
dd4hep::DetElementObject::id
int id
Unique integer identifier of the detector instance.
Definition: DetectorInterna.h:102
dd4hep::DetElementObject::reflect
std::pair< DetElement, Volume > reflect(const std::string &new_name, int new_id, SensitiveDetector sd)
Reflect all volumes in a DetElement sub-tree and re-attach the placements.
Definition: DetectorInterna.cpp:139
dd4hep::DetElementObject::revalidate
void revalidate(bool recurse_down=true)
Revalidate the caches.
Definition: DetectorInterna.cpp:194
dd4hep::DetElementObject::updateCalls
UpdateCallbacks updateCalls
Placeholder for structure with update callbacks.
Definition: DetectorInterna.h:133
key
unsigned char key
Definition: AlignmentsCalculator.cpp:69
dd4hep::DetElementObject::world
World world()
Access to the world object. Only possible once the geometry is closed.
Definition: DetectorInterna.h:164
dd4hep::DetElementObject::~DetElementObject
virtual ~DetElementObject()
Internal object destructor: release extension object(s)
Definition: DetectorInterna.cpp:88
dd4hep::Handle::ptr
T * ptr() const
Access to the held object.
Definition: Handle.h:151
dd4hep::ObjectExtensions::clear
void clear(bool destroy=true)
Clear all extensions.
Definition: ObjectExtensions.cpp:49
dd4hep::DetElementObject::revalidate_parents
void revalidate_parents()
Revalidate the parent caches.
Definition: DetectorInterna.cpp:232
dd4hep::SensitiveDetectorObject
Data class with properties of sensitive detectors.
Definition: DetectorInterna.h:54
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::NamedObject
Implementation of a named object.
Definition: NamedObject.h:30
dd4hep::DetElementObject::placementPath
std::string placementPath
The path to the placement of the detector element (if placed)
Definition: DetectorInterna.h:114
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::SensitiveDetectorObject::region
Region region
Definition: DetectorInterna.h:61
dd4hep::detail::tools::PlacementPath
std::vector< PlacedVolume > PlacementPath
Definition: DetectorTools.h:39
dd4hep::PlacedVolume::volume
Volume volume() const
Logical volume of this placement.
Definition: Volumes.cpp:468
dd4hep::DetElementObject::combineHits
int combineHits
Flag to process hits.
Definition: DetectorInterna.h:104
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::Volume::reflect
Volume reflect() const
Create a reflected volume tree. The reflected volume has left-handed coordinates.
Definition: Volumes.cpp:668
dd4hep::DetElementObject::DetElementObject
DetElementObject()
Default constructor.
Definition: DetectorInterna.cpp:65
dd4hep::SensitiveDetectorObject::SensitiveDetectorObject
SensitiveDetectorObject()
Default constructor.
Definition: DetectorInterna.cpp:37
AlignmentsInterna.h
InstanceCount.h
dd4hep::DetElementObject::nominal
AlignmentCondition nominal
Not ROOT persistent.
Definition: DetectorInterna.h:137
dd4hep::DetElementObject::clone
virtual DetElementObject * clone(int new_id, int flag) const
Deep object copy to replicate DetElement trees e.g. for reflection.
Definition: DetectorInterna.cpp:100
PlacementPath
detail::tools::PlacementPath PlacementPath
Definition: DetectorInterna.cpp:29
dd4hep::DetElementObject::update
void update(unsigned int tags, void *param)
Trigger update callbacks.
Definition: DetectorInterna.cpp:252
dd4hep::DetElementObject::key
unsigned int key
Access hash key of this detector element (Only valid once geometry is closed!)
Definition: DetectorInterna.h:110
Printout.h
dd4hep::DetElement::PLACEMENT_CHANGED
@ PLACEMENT_CHANGED
Definition: DetElement.h:218