DD4hep  1.35.0
Detector Description Toolkit for High Energy Physics
GlobalDetectorAlignment.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
16 #include <DD4hep/DetectorTools.h>
17 #include <DD4hep/InstanceCount.h>
18 #include <DD4hep/MatrixHelpers.h>
19 #include <DD4hep/Printout.h>
20 #include <DD4hep/detail/Handle.inl>
22 
23 // ROOT include files
24 #include <TGeoMatrix.h>
25 #include <TGeoManager.h>
26 
27 #ifdef __GNUC__ // Disable some diagnostics.
28 #pragma GCC diagnostic ignored "-Wunused-function"
29 #endif
30 
31 using LevelElements = std::vector<std::pair<int,dd4hep::DetElement> >;
32 using namespace dd4hep::align;
33 using dd4hep::printout;
34 using dd4hep::INFO;
35 
37 namespace dd4hep {
38 
40  namespace align {
41 
43 
49  public:
51  std::vector<GlobalAlignment> volume_alignments;
52 
53  public:
54  GlobalAlignmentData(const std::string& path)
55  : NamedObject(path, "global-alignment")
56  {
57  this->global = GlobalAlignment( path );
58  }
60  detail::destroyHandle( this->global );
61  }
62  };
63  } /* End namespace Aligments */
64 } /* End namespace dd4hep */
65 
67 
68 namespace {
69 
70  static bool s_GlobalDetectorAlignment_debug = true;
71 
72  GlobalAlignment _align(const GlobalAlignment& a, TGeoHMatrix* transform, bool check, double overlap) {
73  TGeoPhysicalNode* node = a.ptr();
74  if ( node ) {
75  TGeoMatrix* mm = node->GetNode()->GetMatrix();
76  bool dbg = GlobalDetectorAlignment::debug();
77  if ( dbg ) {
78  printout( INFO, "Alignment", "DELTA matrix of %s", node->GetName() );
79  transform->Print();
80  printout( INFO, "Alignment", "OLD matrix of %s", node->GetName() );
81  mm->Print();
82  }
83  std::vector<dd4hep::PlacedVolume> places;
84  for( int i = 0; i < node->GetLevel(); ++i )
85  places.emplace_back( node->GetNode(i+1) );
86 
87  transform->MultiplyLeft(mm); // orig * delta
88  node->Align( transform, 0, check, overlap );
89  if ( dbg ) {
90  printout( INFO, "Alignment", "NEW matrix of %s", node->GetName() );
91  node->GetNode()->GetMatrix()->Print();
92  }
93  TGeoVolume* oldm;
94  dd4hep::PlacedVolume pv = node->GetNode(0);
95  dd4hep::Volume v = pv->GetVolume();
96  std::string path = "/";
97 
98  dbg = false;
99  // dbg = true;
100  path += pv->GetName();
101  for( int i = 0; i < node->GetLevel(); ++i ) {
103  pv = node->GetNode( i+1 );
104  if ( nullptr == pv->GetUserExtension() ) {
105  pv->SetUserExtension( places[i]->GetUserExtension() );
106  }
107  oldm = pv->GetMotherVolume();
108  if( dbg ) {
109  path += "/";
110  path += pv->GetName();
111  if( oldm != v.ptr() ) {
112  printout(dd4hep::ALWAYS, "GlobalAlignment",
113  // "+++ Mother relationship broken after alignment: %s place: %p volume: %p mother volume: old: %p new: %p",
114  "+++ Fix mother relationship after alignment: %s place: %p volume: %p mother volume: old: %p new: %p",
115  path.c_str(), (void*)pv.ptr(), (void*)pv->GetVolume(), (void*)oldm, (void*)v.ptr() );
116  }
117  }
118  pv->SetMotherVolume( v.ptr() );
120  v = pv->GetVolume();
122  for( int idau = 0; idau < v->GetNdaughters(); ++idau ) {
123  TGeoNode* dau = v->GetNode( idau );
124  if( v.ptr() != dau->GetMotherVolume() ) {
125  dau->SetMotherVolume( v );
126  if( dbg ) {
127  oldm = dau->GetMotherVolume();
128  if( oldm != v.ptr() ) {
129  printout(dd4hep::ALWAYS, "GlobalAlignment",
130  // "+++ Mother relationship broken after alignment: %s/%s place: %p volume: %p mother volume: old: %p --> new: %p",
131  "+++ Fix mother relationship after alignment: %s/%s place: %p volume: %p "
132  "mother volume: old: %p --> new: %p",
133  path.c_str(), dau->GetName(), (void*)dau, (void*)dau->GetVolume(),
134  (void*)oldm, (void*)v.ptr());
135  }
136  }
137  }
138  }
140  if ( nullptr == v->GetUserExtension() ) {
141  v->SetUserExtension( places[i].volume()->GetUserExtension() );
142  }
143  }
144  return GlobalAlignment(node);
145  }
146  dd4hep::except("GlobalDetectorAlignment", "Cannot align non existing physical node. [Invalid Handle]");
147  return { };
148  }
149 
150  GlobalAlignment _alignment(const GlobalDetectorAlignment& det) {
151  dd4hep::DetElement::Object& e = det._data();
152  if ( !e.global_alignment.isValid() ) {
153  std::string path = dd4hep::detail::tools::placementPath(det);
155  }
157  if ( h.isValid() && h->global.isValid() ) {
158  return h->global;
159  }
160  dd4hep::except("GlobalDetectorAlignment", "Cannot access global alignment data. [Invalid Handle]");
161  return { };
162  }
163 
164  void _dumpParentElements(GlobalDetectorAlignment& det, LevelElements& elements) {
165  int level = 0;
171  dd4hep::detail::tools::PlacementPath::const_reverse_iterator j=nodes.rbegin();
172  dd4hep::detail::tools::ElementPath::const_reverse_iterator k=det_nodes.rbegin();
173  for(; j!=nodes.rend(); ++j, ++level) {
174  //cout << "(" << level << ") " << (void*)((*j).ptr())
175  // << " " << string((*j)->GetName()) << " ";
176  if ( ::strcmp((*j).ptr()->GetName(), (*k).placement().ptr()->GetName()) ) {
177  //cout << "[DE]";
178  elements.emplace_back(level, *k);
179  ++k;
180  }
181  else {
182  //elements.emplace_back(level,DetElement());
183  }
184  //std::cout << " ";
185  }
186  //std::cout << std::endl;
187  }
188 }
189 
192  : DetElement(std::move(e))
193 {
194 }
195 
198  : DetElement(std::move(e))
199 {
200 }
201 
204  return s_GlobalDetectorAlignment_debug;
205 }
206 
209  bool tmp = s_GlobalDetectorAlignment_debug;
210  s_GlobalDetectorAlignment_debug = value;
211  return tmp;
212 }
213 
215 void GlobalDetectorAlignment::collectNodes(std::vector<PlacedVolume>& nodes) {
216  detail::tools::placementPath(*this, nodes);
217 }
218 
221  return _alignment(*this);
222 }
223 
225 std::vector<GlobalAlignment>& GlobalDetectorAlignment::volumeAlignments() {
226  Handle<GlobalAlignmentData> h(_data().global_alignment);
227  return h->volume_alignments;
228 }
229 
231 const std::vector<GlobalAlignment>& GlobalDetectorAlignment::volumeAlignments() const {
232  Handle<GlobalAlignmentData> h(_data().global_alignment);
233  return h->volume_alignments;
234 }
235 
237 GlobalAlignment GlobalDetectorAlignment::align(const Position& pos, bool chk, double overlap) {
238  return align(detail::matrix::_transform(pos), chk, overlap);
239 }
240 
242 GlobalAlignment GlobalDetectorAlignment::align(const RotationZYX& rot, bool chk, double overlap) {
243  return align(detail::matrix::_transform(rot), chk, overlap);
244 }
245 
247 GlobalAlignment GlobalDetectorAlignment::align(const Position& pos, const RotationZYX& rot, bool chk, double overlap) {
248  return align(detail::matrix::_transform(pos, rot), chk, overlap);
249 }
250 
252 GlobalAlignment GlobalDetectorAlignment::align(const Transform3D& transform, bool chk, double overlap) {
253  return align(detail::matrix::_transform(transform), chk, overlap);
254 }
255 
257 GlobalAlignment GlobalDetectorAlignment::align(TGeoHMatrix* matrix, bool chk, double overlap) {
258  return _align(_alignment(*this), matrix, chk, overlap);
259 }
260 
262 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, const Position& pos, bool chk, double overlap) {
263  return align(elt_path,detail::matrix::_transform(pos), chk, overlap);
264 }
265 
267 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, const RotationZYX& rot, bool chk, double overlap) {
268  return align(elt_path,detail::matrix::_transform(rot), chk, overlap);
269 }
270 
273 GlobalDetectorAlignment::align(const std::string& elt_path, const Position& pos, const RotationZYX& rot, bool chk, double overlap) {
274  return align(elt_path,detail::matrix::_transform(pos, rot), chk, overlap);
275 }
276 
278 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, const Transform3D& transform, bool chk, double overlap) {
279  return align(elt_path,detail::matrix::_transform(transform), chk, overlap);
280 }
281 
283 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, TGeoHMatrix* matrix, bool chk, double overlap) {
284  if ( elt_path.empty() )
285  return _align(_alignment(*this), matrix, chk, overlap);
286  else if ( elt_path == placementPath() )
287  return _align(_alignment(*this), matrix, chk, overlap);
288  else if ( elt_path[0] == '/' ) {
289  GlobalAlignment a(elt_path);
290  volumeAlignments().emplace_back(a);
291  return _align(a, matrix, chk, overlap);
292  }
293  GlobalAlignment a(placementPath() + '/' + elt_path);
294  volumeAlignments().emplace_back(a);
295  return _align(a, matrix, chk, overlap);
296 }
dd4hep::align::GlobalAlignmentData::global
GlobalAlignment global
Definition: GlobalDetectorAlignment.cpp:50
dd4hep::align::GlobalDetectorAlignment::volumeAlignments
std::vector< GlobalAlignment > & volumeAlignments()
Alignment entries for lower level volumes, which are NOT attached to daughter DetElements.
Definition: GlobalDetectorAlignment.cpp:225
dd4hep::align::GlobalDetectorAlignment
GlobalDetectorAlignment. DetElement Handle supporting alignment operations.
Definition: GlobalDetectorAlignment.h:35
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::align::GlobalDetectorAlignment::debug
static bool debug()
Access debugging flag.
Definition: GlobalDetectorAlignment.cpp:203
v
View * v
Definition: MultiView.cpp:28
dd4hep::align::GlobalAlignment
Main handle class to hold a TGeo alignment object of type TGeoPhysicalNode.
Definition: GlobalAlignment.h:38
LevelElements
std::vector< std::pair< int, dd4hep::DetElement > > LevelElements
Definition: GlobalDetectorAlignment.cpp:31
MatrixHelpers.h
dd4hep::align::GlobalDetectorAlignment::alignment
GlobalAlignment alignment() const
Access to the alignment block.
Definition: GlobalDetectorAlignment.cpp:220
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:164
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::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:126
dd4hep::Handle
Handle: a templated class like a shared pointer, which allows specialized access to tgeometry objects...
Definition: Handle.h:82
DetectorInterna.h
dd4hep::detail::matrix::_transform
TGeoHMatrix * _transform(const Transform3D &trans)
Convert a Transform3D object to a newly created TGeoHMatrix.
Definition: MatrixHelpers.cpp:140
dd4hep::DetElementObject
Data class with properties of a detector element.
Definition: DetectorInterna.h:81
dd4hep::align::GlobalAlignmentData
Global alignment data container.
Definition: GlobalDetectorAlignment.cpp:48
dd4hep::align::GlobalAlignmentData::volume_alignments
std::vector< GlobalAlignment > volume_alignments
Definition: GlobalDetectorAlignment.cpp:51
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:187
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:371
dd4hep::align::GlobalDetectorAlignment::align
GlobalAlignment align(const Position &pos, bool check=false, double overlap=0.001)
Align the PhysicalNode of the placement of the detector element (translation only)
Definition: GlobalDetectorAlignment.cpp:237
DetectorTools.h
dd4hep::DetElement::_data
Object & _data() const
Additional data accessor.
Definition: DetElement.h:316
dd4hep::DetElementObject::global_alignment
Ref_t global_alignment
Global alignment data.
Definition: DetectorInterna.h:142
dd4hep::DetElement::placementPath
const std::string & placementPath() const
Access to the full path to the placed object.
Definition: DetElement.cpp:85
dd4hep::Transform3D
ROOT::Math::Transform3D Transform3D
Definition: Objects.h:116
dd4hep::Position
ROOT::Math::XYZVector Position
Definition: Objects.h:80
dd4hep::Ref_t
Handle< NamedObject > Ref_t
Default Ref_t definition describing named objects.
Definition: Handle.h:180
dd4hep::detail::tools::elementPath
std::string elementPath(DetElement element)
Assemble the path of a particular detector element.
Definition: DetectorTools.cpp:214
std
Definition: Plugins.h:29
dd4hep::Handle::ptr
T * ptr() const
Access to the held object.
Definition: Handle.h:151
dd4hep::align::GlobalDetectorAlignment::GlobalDetectorAlignment
GlobalDetectorAlignment(DetElement e)
Initializing constructor.
Definition: GlobalDetectorAlignment.cpp:191
dd4hep::align::GlobalAlignmentData::GlobalAlignmentData
GlobalAlignmentData(const std::string &path)
Definition: GlobalDetectorAlignment.cpp:54
dd4hep::align::GlobalDetectorAlignment::collectNodes
void collectNodes(std::vector< PlacedVolume > &nodes)
Collect all placements from the detector element up to the world volume.
Definition: GlobalDetectorAlignment.cpp:215
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::NamedObject
Implementation of a named object.
Definition: NamedObject.h:30
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::detail::tools::PlacementPath
std::vector< PlacedVolume > PlacementPath
Definition: DetectorTools.h:39
dd4hep::RotationZYX
ROOT::Math::RotationZYX RotationZYX
Definition: Objects.h:104
InstanceCount.h
GlobalDetectorAlignment.h
dd4hep::align::GlobalAlignmentData::~GlobalAlignmentData
virtual ~GlobalAlignmentData()
Definition: GlobalDetectorAlignment.cpp:59
Printout.h
dd4hep::align
Namespace for implementation details of the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:31
DD4HEP_INSTANTIATE_HANDLE_NAMED
DD4HEP_INSTANTIATE_HANDLE_NAMED(GlobalAlignmentData)