File indexing completed on 2025-01-18 09:13:25
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
0094 for( int i = 0; i < node->GetLevel(); ++i ) {
0095
0096 dd4hep::PlacedVolume p = node->GetNode(i+1);
0097 if ( nullptr == p->GetUserExtension() ) {
0098
0099 p->SetUserExtension(places[i]->GetUserExtension());
0100 }
0101 #if 0
0102 printout(INFO, "Alignment", "_align(places): %s Path[%d]: %-24s %p <-> %p %s",
0103 tag, i, p.name(), p.ptr(), places[i].ptr(), places[i].name());
0104 tag = " ";
0105 #endif
0106 dd4hep::Volume v = p->GetVolume();
0107 if ( nullptr == v->GetUserExtension() ) {
0108
0109 v->SetUserExtension(places[i].volume()->GetUserExtension());
0110 }
0111 #if 0
0112 printout(INFO, "Alignment", "_align(volumes): %s Path[%d]: %-24s %p <-> %p %s",
0113 tag, i, v.name(), v.ptr(), places[i].volume().ptr(), places[i].volume().name());
0114 p.access();
0115 v.access();
0116 places[i].access();
0117 places[i].volume().access();
0118 #endif
0119 }
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 return GlobalAlignment(node);
0134 }
0135 dd4hep::except("GlobalDetectorAlignment", "Cannot align non existing physical node. [Invalid Handle]");
0136 return { };
0137 }
0138
0139 GlobalAlignment _alignment(const GlobalDetectorAlignment& det) {
0140 dd4hep::DetElement::Object& e = det._data();
0141 if ( !e.global_alignment.isValid() ) {
0142 std::string path = dd4hep::detail::tools::placementPath(det);
0143 e.global_alignment = dd4hep::Ref_t(new GlobalAlignmentData(path));
0144 }
0145 dd4hep::Handle<GlobalAlignmentData> h(e.global_alignment);
0146 if ( h.isValid() && h->global.isValid() ) {
0147 return h->global;
0148 }
0149 dd4hep::except("GlobalDetectorAlignment", "Cannot access global alignment data. [Invalid Handle]");
0150 return { };
0151 }
0152
0153 void _dumpParentElements(GlobalDetectorAlignment& det, LevelElements& elements) {
0154 int level = 0;
0155 dd4hep::detail::tools::PlacementPath nodes;
0156 dd4hep::detail::tools::ElementPath det_nodes;
0157 dd4hep::detail::tools::placementPath(det, nodes);
0158 dd4hep::detail::tools::elementPath(det, det_nodes);
0159
0160 dd4hep::detail::tools::PlacementPath::const_reverse_iterator j=nodes.rbegin();
0161 dd4hep::detail::tools::ElementPath::const_reverse_iterator k=det_nodes.rbegin();
0162 for(; j!=nodes.rend(); ++j, ++level) {
0163
0164
0165 if ( ::strcmp((*j).ptr()->GetName(), (*k).placement().ptr()->GetName()) ) {
0166
0167 elements.emplace_back(level, *k);
0168 ++k;
0169 }
0170 else {
0171
0172 }
0173
0174 }
0175
0176 }
0177 }
0178
0179
0180 GlobalDetectorAlignment::GlobalDetectorAlignment(DetElement e)
0181 : DetElement(std::move(e))
0182 {
0183 }
0184
0185
0186 GlobalDetectorAlignment::GlobalDetectorAlignment(DetElement&& e)
0187 : DetElement(std::move(e))
0188 {
0189 }
0190
0191
0192 bool GlobalDetectorAlignment::debug() {
0193 return s_GlobalDetectorAlignment_debug;
0194 }
0195
0196
0197 bool GlobalDetectorAlignment::debug(bool value) {
0198 bool tmp = s_GlobalDetectorAlignment_debug;
0199 s_GlobalDetectorAlignment_debug = value;
0200 return tmp;
0201 }
0202
0203
0204 void GlobalDetectorAlignment::collectNodes(std::vector<PlacedVolume>& nodes) {
0205 detail::tools::placementPath(*this, nodes);
0206 }
0207
0208
0209 GlobalAlignment GlobalDetectorAlignment::alignment() const {
0210 return _alignment(*this);
0211 }
0212
0213
0214 std::vector<GlobalAlignment>& GlobalDetectorAlignment::volumeAlignments() {
0215 Handle<GlobalAlignmentData> h(_data().global_alignment);
0216 return h->volume_alignments;
0217 }
0218
0219
0220 const std::vector<GlobalAlignment>& GlobalDetectorAlignment::volumeAlignments() const {
0221 Handle<GlobalAlignmentData> h(_data().global_alignment);
0222 return h->volume_alignments;
0223 }
0224
0225
0226 GlobalAlignment GlobalDetectorAlignment::align(const Position& pos, bool chk, double overlap) {
0227 return align(detail::matrix::_transform(pos), chk, overlap);
0228 }
0229
0230
0231 GlobalAlignment GlobalDetectorAlignment::align(const RotationZYX& rot, bool chk, double overlap) {
0232 return align(detail::matrix::_transform(rot), chk, overlap);
0233 }
0234
0235
0236 GlobalAlignment GlobalDetectorAlignment::align(const Position& pos, const RotationZYX& rot, bool chk, double overlap) {
0237 return align(detail::matrix::_transform(pos, rot), chk, overlap);
0238 }
0239
0240
0241 GlobalAlignment GlobalDetectorAlignment::align(const Transform3D& transform, bool chk, double overlap) {
0242 return align(detail::matrix::_transform(transform), chk, overlap);
0243 }
0244
0245
0246 GlobalAlignment GlobalDetectorAlignment::align(TGeoHMatrix* matrix, bool chk, double overlap) {
0247 return _align(_alignment(*this), matrix, chk, overlap);
0248 }
0249
0250
0251 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, const Position& pos, bool chk, double overlap) {
0252 return align(elt_path,detail::matrix::_transform(pos), chk, overlap);
0253 }
0254
0255
0256 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, const RotationZYX& rot, bool chk, double overlap) {
0257 return align(elt_path,detail::matrix::_transform(rot), chk, overlap);
0258 }
0259
0260
0261 GlobalAlignment
0262 GlobalDetectorAlignment::align(const std::string& elt_path, const Position& pos, const RotationZYX& rot, bool chk, double overlap) {
0263 return align(elt_path,detail::matrix::_transform(pos, rot), chk, overlap);
0264 }
0265
0266
0267 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, const Transform3D& transform, bool chk, double overlap) {
0268 return align(elt_path,detail::matrix::_transform(transform), chk, overlap);
0269 }
0270
0271
0272 GlobalAlignment GlobalDetectorAlignment::align(const std::string& elt_path, TGeoHMatrix* matrix, bool chk, double overlap) {
0273 if ( elt_path.empty() )
0274 return _align(_alignment(*this), matrix, chk, overlap);
0275 else if ( elt_path == placementPath() )
0276 return _align(_alignment(*this), matrix, chk, overlap);
0277 else if ( elt_path[0] == '/' ) {
0278 GlobalAlignment a(elt_path);
0279 volumeAlignments().emplace_back(a);
0280 return _align(a, matrix, chk, overlap);
0281 }
0282 GlobalAlignment a(placementPath() + '/' + elt_path);
0283 volumeAlignments().emplace_back(a);
0284 return _align(a, matrix, chk, overlap);
0285 }