Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:25

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 // Framework include files
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 // ROOT include files
0024 #include <TGeoMatrix.h>
0025 #include <TGeoManager.h>
0026 
0027 #ifdef __GNUC__    // Disable some diagnostics.
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 /// Namespace for the AIDA detector description toolkit
0037 namespace dd4hep {
0038 
0039   /// Namespace for the alignment part of the AIDA detector description toolkit
0040   namespace align {
0041 
0042     /// Global alignment data container
0043     /**
0044      *   \author  M.Frank
0045      *   \version 1.0
0046      *   \ingroup DD4HEP_DDALIGN
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   }   /* End namespace Aligments               */
0064 }     /* End namespace dd4hep                  */
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); // orig * delta
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         //const char *tag = "    ";
0096         dd4hep::PlacedVolume p = node->GetNode(i+1);
0097         if ( nullptr == p->GetUserExtension() )  {
0098           //tag = "SET ";
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           //tag = "SET ";
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         printout(INFO, "Alignment", "Apply new relative matrix  mother to daughter:");
0123         transform->Print();
0124         transform->MultiplyLeft(mm); // orig * delta
0125         printout(INFO, "Alignment", "With deltas %s ....", n->GetName());
0126         transform->Print();
0127         n->Align(transform, 0, check, overlap);
0128         
0129         Position local, global = a.toGlobal(local);
0130         cout << "Local:" << local << " Global: " << global
0131         << " and back:" << a.globalToLocal(global) << endl;
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     ///    std::cout << "Placement path:";
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       //cout << "(" << level << ") " << (void*)((*j).ptr())
0164       //           << " " << string((*j)->GetName()) << " ";
0165       if ( ::strcmp((*j).ptr()->GetName(), (*k).placement().ptr()->GetName()) )  {
0166         //cout << "[DE]";
0167         elements.emplace_back(level, *k);
0168         ++k;
0169       }
0170       else  {
0171         //elements.emplace_back(level,DetElement());
0172       }
0173       //std::cout << " ";
0174     }
0175     //std::cout << std::endl;
0176   }
0177 }
0178 
0179 /// Initializing constructor
0180 GlobalDetectorAlignment::GlobalDetectorAlignment(DetElement e)
0181   : DetElement(std::move(e))
0182 {
0183 }
0184 
0185 /// Initializing constructor
0186 GlobalDetectorAlignment::GlobalDetectorAlignment(DetElement&& e)
0187   : DetElement(std::move(e))
0188 {
0189 }
0190 
0191 /// Access debugging flag
0192 bool GlobalDetectorAlignment::debug()   {
0193   return s_GlobalDetectorAlignment_debug;
0194 }
0195 
0196 /// Set debugging flag
0197 bool GlobalDetectorAlignment::debug(bool value)   {
0198   bool tmp = s_GlobalDetectorAlignment_debug;
0199   s_GlobalDetectorAlignment_debug = value;
0200   return tmp;
0201 }
0202 
0203 /// Collect all placements from the detector element up to the world volume
0204 void GlobalDetectorAlignment::collectNodes(std::vector<PlacedVolume>& nodes)   {
0205   detail::tools::placementPath(*this, nodes);
0206 }
0207 
0208 /// Access to the alignment block
0209 GlobalAlignment GlobalDetectorAlignment::alignment() const   {
0210   return _alignment(*this);
0211 }
0212 
0213 /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements
0214 std::vector<GlobalAlignment>& GlobalDetectorAlignment::volumeAlignments()  {
0215   Handle<GlobalAlignmentData> h(_data().global_alignment);
0216   return h->volume_alignments;
0217 }
0218 
0219 /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements
0220 const std::vector<GlobalAlignment>& GlobalDetectorAlignment::volumeAlignments() const   {
0221   Handle<GlobalAlignmentData> h(_data().global_alignment);
0222   return h->volume_alignments;
0223 }
0224 
0225 /// Align the PhysicalNode of the placement of the detector element (translation only)
0226 GlobalAlignment GlobalDetectorAlignment::align(const Position& pos, bool chk, double overlap) {
0227   return align(detail::matrix::_transform(pos), chk, overlap);
0228 }
0229 
0230 /// Align the PhysicalNode of the placement of the detector element (rotation only)
0231 GlobalAlignment GlobalDetectorAlignment::align(const RotationZYX& rot, bool chk, double overlap) {
0232   return align(detail::matrix::_transform(rot), chk, overlap);
0233 }
0234 
0235 /// Align the PhysicalNode of the placement of the detector element (translation + rotation)
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 /// Align the physical node according to a generic Transform3D
0241 GlobalAlignment GlobalDetectorAlignment::align(const Transform3D& transform, bool chk, double overlap)  {
0242   return align(detail::matrix::_transform(transform), chk, overlap);
0243 }
0244 
0245 /// Align the physical node according to a generic TGeo matrix
0246 GlobalAlignment GlobalDetectorAlignment::align(TGeoHMatrix* matrix, bool chk, double overlap)  {
0247   return _align(_alignment(*this), matrix, chk, overlap);
0248 }
0249 
0250 /// Align the PhysicalNode of the placement of the detector element (translation only)
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 /// Align the PhysicalNode of the placement of the detector element (rotation only)
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 /// Align the PhysicalNode of the placement of the detector element (translation + rotation)
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 /// Align the physical node according to a generic Transform3D
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 /// Align the physical node according to a generic TGeo matrix
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 }