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 includes
0015 #include <DDAlign/GlobalAlignmentWriter.h>
0016 #include <DDAlign/GlobalAlignmentCache.h>
0017 #include <DDAlign/GlobalDetectorAlignment.h>
0018 #include <DDAlign/AlignmentTags.h>
0019 
0020 #include <DD4hep/Detector.h>
0021 #include <DD4hep/Printout.h>
0022 #include <DD4hep/MatrixHelpers.h>
0023 #include <DD4hep/detail/DetectorInterna.h>
0024 #include <XML/DocumentHandler.h>
0025 
0026 #include <TGeoMatrix.h>
0027 
0028 // C/C++ include files
0029 #include <stdexcept>
0030 
0031 using namespace dd4hep::align;
0032 namespace xml = dd4hep::xml;
0033 
0034 /// Initializing Constructor
0035 GlobalAlignmentWriter::GlobalAlignmentWriter(Detector& description) : m_detDesc(description)
0036 {
0037   m_cache = description.extension<align::GlobalAlignmentCache>();
0038   if ( m_cache ) m_cache->addRef();
0039 }
0040 
0041 /// Standard destructor
0042 GlobalAlignmentWriter::~GlobalAlignmentWriter()  {
0043   if ( m_cache ) m_cache->release();
0044 }
0045 
0046 /// Create the element corresponding to one single detector element without children
0047 xml::Element GlobalAlignmentWriter::createElement(xml::Document doc, DetElement element)  const  {
0048   xml::Element e(0), placement(0), elt = xml::Element(doc,_ALU(detelement));
0049   std::string path = element.placementPath();
0050   GlobalAlignment a = element->global_alignment;
0051   GlobalDetectorAlignment det(element);
0052 
0053   elt.setAttr(_ALU(path),element.path());
0054   if ( a.isValid() )  {
0055     addNode(elt,a);
0056   }
0057   const std::vector<GlobalAlignment>& vol_alignments = det.volumeAlignments();
0058   for(const auto& alignment : vol_alignments )  {
0059     e = xml::Element(doc,_U(volume));
0060     e.setAttr(_ALU(path), alignment->GetName());
0061     addNode(e, alignment);
0062     elt.append(e);
0063   }
0064   return elt;
0065 }
0066 
0067 /// Add single alignment node to the XML document
0068 void GlobalAlignmentWriter::addNode(xml::Element elt, GlobalAlignment a)  const   {
0069   TGeoNode* n = a->GetNode();
0070   TGeoHMatrix mat(a->GetOriginalMatrix()->Inverse());
0071   mat.Multiply(n->GetMatrix());
0072   const Double_t* t = mat.GetTranslation();
0073   xml::Element placement = xml::Element(elt.document(),_U(comment));
0074   placement.setAttr(_ALU(placement),a->GetName());
0075   elt.append(placement);
0076 
0077   printout(INFO,"GlobalAlignmentWriter","Write Delta constants for %s",a->GetName());
0078   //mat.Print();
0079   if ( fabs(t[0]) > std::numeric_limits<double>::epsilon() ||
0080        fabs(t[1]) > std::numeric_limits<double>::epsilon() ||
0081        fabs(t[2]) > std::numeric_limits<double>::epsilon() ) {
0082     xml::Element e = xml::Element(elt.document(),_U(position));
0083     e.setAttr(_U(x),_toString(t[0]/dd4hep::mm,"%f*mm"));
0084     e.setAttr(_U(y),_toString(t[1]/dd4hep::mm,"%f*mm"));
0085     e.setAttr(_U(z),_toString(t[2]/dd4hep::mm,"%f*mm"));
0086     elt.append(e);
0087   }
0088   if ( mat.IsRotation() )  {
0089     XYZAngles rot = detail::matrix::_xyzAngles(&mat);
0090     if ( fabs(rot.X()) > std::numeric_limits<double>::epsilon() ||
0091          fabs(rot.Y()) > std::numeric_limits<double>::epsilon() ||
0092          fabs(rot.Z()) > std::numeric_limits<double>::epsilon() )    {
0093 
0094       xml::Element e = xml::Element(elt.document(),_U(rotation));
0095       // Don't know why the angles have the wrong sign....
0096       rot *= -1;
0097       e.setAttr(_U(x),_toString(rot.X()/dd4hep::rad,"%f*rad"));
0098       e.setAttr(_U(y),_toString(rot.Y()/dd4hep::rad,"%f*rad"));
0099       e.setAttr(_U(z),_toString(rot.Z()/dd4hep::rad,"%f*rad"));
0100       elt.append(e);
0101     }
0102   }
0103 }
0104 
0105 /// Scan a DetElement subtree and add on the fly the XML entries
0106 xml::Element GlobalAlignmentWriter::scan(xml::Document doc, DetElement element)  const  {
0107   xml::Element elt(0);
0108   if ( element.isValid() )   {
0109     const DetElement::Children& c = element.children();
0110     GlobalAlignment alignment = element->global_alignment;
0111     if ( alignment.isValid() ) elt = createElement(doc,element);
0112     for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i)   {
0113       xml::Element daughter = scan(doc, (*i).second);
0114       if ( daughter )   {
0115         (elt ? (elt) : (elt=createElement(doc,element))).append(daughter);
0116       }
0117     }
0118   }
0119   return elt;
0120 }
0121 
0122 /// Dump the tree content into a XML document structure
0123 xml::Document GlobalAlignmentWriter::dump(DetElement top, bool enable_transactions)  const {
0124   xml::DocumentHandler docH;
0125   xml::Document doc = docH.create("alignment", docH.defaultComment());
0126   xml::Element elt(0), elements(0), root = doc.root();
0127   root.append(elements = xml::Element(doc, _ALU(detelements)));
0128   if ( enable_transactions ) root.append(xml::Element(doc,_ALU(open_transaction)));
0129   if ( (elt=scan(doc,top)) ) elements.append(elt);
0130   if ( enable_transactions ) root.append(xml::Element(doc,_ALU(close_transaction)));
0131   return doc;
0132 }
0133 
0134 /// Write the XML document structure to a file.
0135 long GlobalAlignmentWriter::write(xml::Document doc, const std::string& output)   const {
0136   xml::DocumentHandler docH;
0137   return docH.output(doc, output);
0138 }