File indexing completed on 2026-09-08 08:22:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DDAlign/GlobalDetectorAlignment.h>
0016 #include <DD4hep/DetectorTools.h>
0017 #include <DD4hep/InstanceCount.h>
0018 #include <DD4hep/MatrixHelpers.h>
0019 #include <DD4hep/Printout.h>
0020 #include <DD4hep/detail/Handle.inl>
0021 #include <DD4hep/detail/DetectorInterna.h>
0022
0023
0024 #include <TGeoMatrix.h>
0025 #include <TGeoManager.h>
0026
0027 #ifdef __GNUC__
0028 #pragma GCC diagnostic ignored "-Wunused-function"
0029 #endif
0030
0031 using LevelElements = std::vector<std::pair<int,dd4hep::DetElement> >;
0032 using namespace dd4hep::align;
0033 using dd4hep::printout;
0034 using dd4hep::INFO;
0035
0036
0037 namespace dd4hep {
0038
0039
0040 namespace align {
0041
0042
0043
0044
0045
0046
0047
0048 class GlobalAlignmentData : public NamedObject {
0049 public:
0050 GlobalAlignment global;
0051 std::vector<GlobalAlignment> volume_alignments;
0052
0053 public:
0054 GlobalAlignmentData(const std::string& path)
0055 : NamedObject(path, "global-alignment")
0056 {
0057 this->global = GlobalAlignment( path );
0058 }
0059 virtual ~GlobalAlignmentData() {
0060 detail::destroyHandle( this->global );
0061 }
0062 };
0063 }
0064 }
0065
0066 DD4HEP_INSTANTIATE_HANDLE_NAMED(GlobalAlignmentData);
0067
0068 namespace {
0069
0070 static bool s_GlobalDetectorAlignment_debug = true;
0071
0072 GlobalAlignment _align(const GlobalAlignment& a, TGeoHMatrix* transform, bool check, double overlap) {
0073 TGeoPhysicalNode* node = a.ptr();
0074 if ( node ) {
0075 TGeoMatrix* mm = node->GetNode()->GetMatrix();
0076 bool dbg = GlobalDetectorAlignment::debug();
0077 if ( dbg ) {
0078 printout( INFO, "Alignment", "DELTA matrix of %s", node->GetName() );
0079 transform->Print();
0080 printout( INFO, "Alignment", "OLD matrix of %s", node->GetName() );
0081 mm->Print();
0082 }
0083 std::vector<dd4hep::PlacedVolume> places;
0084 for( int i = 0; i < node->GetLevel(); ++i )
0085 places.emplace_back( node->GetNode(i+1) );
0086
0087 transform->MultiplyLeft(mm);
0088 node->Align( transform, 0, check, overlap );
0089 if ( dbg ) {
0090 printout( INFO, "Alignment", "NEW matrix of %s", node->GetName() );
0091 node->GetNode()->GetMatrix()->Print();
0092 }
0093 TGeoVolume* oldm;
0094 dd4hep::PlacedVolume pv = node->GetNode(0);
0095 dd4hep::Volume v = pv->GetVolume();
0096 std::string path = "/";
0097
0098 dbg = false;
0099
0100 path += pv->GetName();
0101 for( int i = 0; i < node->GetLevel(); ++i ) {
0102
0103 pv = node->GetNode( i+1 );
0104 if ( nullptr == pv->GetUserExtension() ) {
0105 pv->SetUserExtension( places[i]->GetUserExtension() );
0106 }
0107 oldm = pv->GetMotherVolume();
0108 if( dbg ) {
0109 path += "/";
0110 path += pv->GetName();
0111 if( oldm != v.ptr() ) {
0112 printout(dd4hep::ALWAYS, "GlobalAlignment",
0113
0114 "+++ Fix mother relationship after alignment: %s place: %p volume: %p mother volume: old: %p new: %p",
0115 path.c_str(), (void*)pv.ptr(), (void*)pv->GetVolume(), (void*)oldm, (void*)v.ptr() );
0116 }
0117 }
0118 pv->SetMotherVolume( v.ptr() );
0119
0120 v = pv->GetVolume();
0121
0122 for( int idau = 0; idau < v->GetNdaughters(); ++idau ) {
0123 TGeoNode* dau = v->GetNode( idau );
0124 if( v.ptr() != dau->GetMotherVolume() ) {
0125 dau->SetMotherVolume( v );
0126 if( dbg ) {
0127 oldm = dau->GetMotherVolume();
0128 if( oldm != v.ptr() ) {
0129 printout(dd4hep::ALWAYS, "GlobalAlignment",
0130
0131 "+++ Fix mother relationship after alignment: %s/%s place: %p volume: %p "
0132 "mother volume: old: %p --> new: %p",
0133 path.c_str(), dau->GetName(), (void*)dau, (void*)dau->GetVolume(),
0134 (void*)oldm, (void*)v.ptr());
0135 }
0136 }
0137 }
0138 }
0139
0140 if ( nullptr == v->GetUserExtension() ) {
0141 v->SetUserExtension( places[i].volume()->GetUserExtension() );
0142 }
0143 }
0144 return GlobalAlignment(node);
0145 }
0146 dd4hep::except("GlobalDetectorAlignment", "Cannot align non existing physical node. [Invalid Handle]");
0147 return { };
0148 }
0149
0150 GlobalAlignment _alignment(const GlobalDetectorAlignment& det) {
0151 dd4hep::DetElement::Object& e = det._data();
0152 if ( !e.global_alignment.isValid() ) {
0153 std::string path = dd4hep::detail::tools::placementPath(det);
0154 e.global_alignment = dd4hep::Ref_t(new GlobalAlignmentData(path));
0155 }
0156 dd4hep::Handle<GlobalAlignmentData> h(e.global_alignment);
0157 if ( h.isValid() && h->global.isValid() ) {
0158 return h->global;
0159 }
0160 dd4hep::except("GlobalDetectorAlignment", "Cannot access global alignment data. [Invalid Handle]");
0161 return { };
0162 }
0163
0164 void _dumpParentElements(GlobalDetectorAlignment& det, LevelElements& elements) {
0165 int level = 0;
0166 dd4hep::detail::tools::PlacementPath nodes;
0167 dd4hep::detail::tools::ElementPath det_nodes;
0168 dd4hep::detail::tools::placementPath(det, nodes);
0169 dd4hep::detail::tools::elementPath(det, det_nodes);
0170
0171 dd4hep::detail::tools::PlacementPath::const_reverse_iterator j=nodes.rbegin();
0172 dd4hep::detail::tools::ElementPath::const_reverse_iterator k=det_nodes.rbegin();
0173 for(; j!=nodes.rend(); ++j, ++level) {
0174
0175
0176 if ( ::strcmp((*j).ptr()->GetName(), (*k).placement().ptr()->GetName()) ) {
0177
0178 elements.emplace_back(level, *k);
0179 ++k;
0180 }
0181 else {
0182
0183 }
0184
0185 }
0186
0187 }
0188 }
0189
0190
0191 GlobalDetectorAlignment::GlobalDetectorAlignment(DetElement e)
0192 : DetElement(std::move(e))
0193 {
0194 }
0195
0196
0197 GlobalDetectorAlignment::GlobalDetectorAlignment(DetElement&& e)
0198 : DetElement(std::move(e))
0199 {
0200 }
0201
0202
0203 bool GlobalDetectorAlignment::debug() {
0204 return s_GlobalDetectorAlignment_debug;
0205 }
0206
0207
0208 bool GlobalDetectorAlignment::debug(bool value) {
0209 bool tmp = s_GlobalDetectorAlignment_debug;
0210 s_GlobalDetectorAlignment_debug = value;
0211 return tmp;
0212 }
0213
0214
0215 void GlobalDetectorAlignment::collectNodes(std::vector<PlacedVolume>& nodes) {
0216 detail::tools::placementPath(*this, nodes);
0217 }
0218
0219
0220 GlobalAlignment GlobalDetectorAlignment::alignment() const {
0221 return _alignment(*this);
0222 }
0223
0224
0225 std::vector<GlobalAlignment>& GlobalDetectorAlignment::volumeAlignments() {
0226 Handle<GlobalAlignmentData> h(_data().global_alignment);
0227 return h->volume_alignments;
0228 }
0229
0230
0231 const std::vector<GlobalAlignment>& GlobalDetectorAlignment::volumeAlignments() const {
0232 Handle<GlobalAlignmentData> h(_data().global_alignment);
0233 return h->volume_alignments;
0234 }
0235
0236
0237 GlobalAlignment GlobalDetectorAlignment::align(const Position& pos, bool chk, double overlap) {
0238 return align(detail::matrix::_transform(pos), chk, overlap);
0239 }
0240
0241
0242 GlobalAlignment GlobalDetectorAlignment::align(const RotationZYX& rot, bool chk, double overlap) {
0243 return align(detail::matrix::_transform(rot), chk, overlap);
0244 }
0245
0246
0247 GlobalAlignment GlobalDetectorAlignment::align(const Position& pos, const RotationZYX& rot, bool chk, double overlap) {
0248 return align(detail::matrix::_transform(pos, rot), chk, overlap);
0249 }
0250
0251
0252 GlobalAlignment GlobalDetectorAlignment::align(const Transform3D& transform, bool chk, double overlap) {
0253 return align(detail::matrix::_transform(transform), chk, overlap);
0254 }
0255
0256
0257 GlobalAlignment GlobalDetectorAlignment::align(TGeoHMatrix* matrix, bool chk, double overlap) {
0258 return _align(_alignment(*this), matrix, chk, overlap);
0259 }
0260
0261
0262 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, const Position& pos, bool chk, double overlap) {
0263 return align(elt_path,detail::matrix::_transform(pos), chk, overlap);
0264 }
0265
0266
0267 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, const RotationZYX& rot, bool chk, double overlap) {
0268 return align(elt_path,detail::matrix::_transform(rot), chk, overlap);
0269 }
0270
0271
0272 GlobalAlignment
0273 GlobalDetectorAlignment::align(const std::string& elt_path, const Position& pos, const RotationZYX& rot, bool chk, double overlap) {
0274 return align(elt_path,detail::matrix::_transform(pos, rot), chk, overlap);
0275 }
0276
0277
0278 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, const Transform3D& transform, bool chk, double overlap) {
0279 return align(elt_path,detail::matrix::_transform(transform), chk, overlap);
0280 }
0281
0282
0283 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, TGeoHMatrix* matrix, bool chk, double overlap) {
0284 if ( elt_path.empty() )
0285 return _align(_alignment(*this), matrix, chk, overlap);
0286 else if ( elt_path == placementPath() )
0287 return _align(_alignment(*this), matrix, chk, overlap);
0288 else if ( elt_path[0] == '/' ) {
0289 GlobalAlignment a(elt_path);
0290 volumeAlignments().emplace_back(a);
0291 return _align(a, matrix, chk, overlap);
0292 }
0293 GlobalAlignment a(placementPath() + '/' + elt_path);
0294 volumeAlignments().emplace_back(a);
0295 return _align(a, matrix, chk, overlap);
0296 }