Back to home page

EIC code displayed by LXR

 
 

    


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

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 <DD4hep/Detector.h>
0016 #include <DD4hep/Path.h>
0017 #include <DD4hep/Mutex.h>
0018 #include <DD4hep/Printout.h>
0019 #include <XML/Conversions.h>
0020 #include <XML/XMLParsers.h>
0021 #include <XML/DocumentHandler.h>
0022 #include <DD4hep/DetectorTools.h>
0023 #include <DD4hep/DetFactoryHelper.h>
0024 
0025 #include <DDAlign/AlignmentTags.h>
0026 #include <DDAlign/GlobalAlignmentStack.h>
0027 #include <DDAlign/GlobalAlignmentCache.h>
0028 #include <DDAlign/GlobalDetectorAlignment.h>
0029 
0030 // C/C++ include files
0031 #include <stdexcept>
0032 
0033 namespace dd4hep  {
0034 
0035   namespace   {
0036 
0037     /// Some utility class to specialize the convetrers:
0038     class alignment;
0039     class detelement;
0040     class include_file;
0041     class volume;
0042     class rotation;
0043     class position;
0044     class pivot;
0045     class alignment_delta;
0046     class debug;
0047   }
0048 
0049   /// Forward declarations for all specialized converters
0050   template <> void Converter<debug>::operator()(xml_h seq)  const;
0051   template <> void Converter<volume>::operator()(xml_h seq)  const;
0052   template <> void Converter<alignment>::operator()(xml_h seq)  const;
0053   template <> void Converter<detelement>::operator()(xml_h seq)  const;
0054   template <> void Converter<include_file>::operator()(xml_h seq)  const;
0055 
0056   static long setup_Alignment(Detector& description, const xml_h& e);
0057 }
0058 
0059 using namespace dd4hep::align;
0060 using StackEntry = GlobalAlignmentStack::StackEntry;
0061 
0062 
0063 /** Convert to enable/disable debugging.
0064  *
0065  *  @author  M.Frank
0066  *  @version 1.0
0067  *  @date    01/04/2014
0068  */
0069 template <> void dd4hep::Converter<dd4hep::debug>::operator()(xml_h e) const {
0070   bool value = e.attr<bool>(_U(value));
0071   GlobalDetectorAlignment::debug(value);
0072 }
0073 
0074 /** Convert volume objects
0075  *
0076  *      <volume subpath="layer4_0">
0077  *        <position x="0*mm" y="0*mm" z="0*mm"/>
0078  *        <rotation x="0.5"  y="0.1"  z="0.2"/>
0079  *        <pivot    x="0*mm" y="0*mm" z="100*mm"/>
0080  *      <volume>
0081  *         ...
0082  *      <volume>
0083  *      </volume>
0084  *
0085  *  @author  M.Frank
0086  *  @version 1.0
0087  *  @date    01/04/2014
0088  */
0089 template <> void dd4hep::Converter<dd4hep::volume>::operator()(xml_h e) const {
0090   Delta val;
0091   GlobalAlignmentStack* stack  = _option<GlobalAlignmentStack>();
0092   std::pair<DetElement,std::string>* elt = _param<std::pair<DetElement,std::string> >();
0093   std::string subpath = e.attr<std::string>(_ALU(path));
0094   bool   reset      = e.hasAttr(_ALU(reset)) ? e.attr<bool>(_ALU(reset)) : true;
0095   bool   reset_dau  = e.hasAttr(_ALU(reset_children)) ? e.attr<bool>(_ALU(reset_children)) : true;
0096   bool   check      = e.hasAttr(_ALU(check_overlaps));
0097   bool   check_val  = check ? e.attr<bool>(_ALU(check_overlaps)) : false;
0098   bool   overlap    = e.hasAttr(_ALU(overlap));
0099   double ovl        = overlap ? e.attr<double>(_ALU(overlap)) : 0.001;
0100   std::string elt_place  = elt->first.placementPath();
0101   std::string placement  = subpath[0]=='/' ? subpath : elt_place + "/" + subpath;
0102 
0103   printout(INFO,"Alignment<vol>","    path:%s placement:%s reset:%s children:%s",
0104            subpath.c_str(), placement.c_str(), yes_no(reset), yes_no(reset_dau));
0105 
0106   xml::parse(e,val);
0107   if ( val.flags ) val.flags |= GlobalAlignmentStack::MATRIX_DEFINED;
0108   if ( overlap   ) val.flags |= GlobalAlignmentStack::OVERLAP_DEFINED;
0109   if ( reset     ) val.flags |= GlobalAlignmentStack::RESET_VALUE;
0110   if ( reset_dau ) val.flags |= GlobalAlignmentStack::RESET_CHILDREN;
0111   if ( check     ) val.flags |= GlobalAlignmentStack::CHECKOVL_DEFINED;
0112   if ( check_val ) val.flags |= GlobalAlignmentStack::CHECKOVL_VALUE;
0113 
0114   dd4hep_ptr<StackEntry> entry(new StackEntry(elt->first,placement,val,ovl));
0115   stack->insert(entry);
0116   std::pair<DetElement,std::string> vol_param(elt->first,subpath);
0117   xml_coll_t(e,_U(volume)).for_each(Converter<volume>(description,&vol_param));
0118 }
0119 
0120 /** Convert detelement objects
0121  *
0122  *    Function entry expects as a parameter a valid DetElement handle
0123  *    pointing to the subdetector, which detector elements should be
0124  *    realigned.
0125  *
0126  *    <detelement path="/world/TPC/TPC_SideA/TPC_SideA_sector02">
0127  *      <position x="0*mm" y="0*mm" z="0*mm"/>
0128  *      <rotation x="0.5"  y="0.1"  z="0.2"/>
0129  *      <pivot    x="0*mm" y="0*mm" z="100*mm"/>
0130  *    </detelement>
0131  *
0132  *  @author  M.Frank
0133  *  @version 1.0
0134  *  @date    01/04/2014
0135  */
0136 template <> void dd4hep::Converter<dd4hep::detelement>::operator()(xml_h e) const {
0137   DetElement det(_param<DetElement::Object>());
0138   GlobalAlignmentStack* stack = _option<GlobalAlignmentStack>();
0139   std::string path = e.attr<std::string>(_ALU(path));
0140   bool   check     = e.hasAttr(_ALU(check_overlaps));
0141   bool   check_val = check ? e.attr<bool>(_ALU(check_overlaps)) : false;
0142   bool   reset     = e.hasAttr(_ALU(reset)) ? e.attr<bool>(_ALU(reset)) : false;
0143   bool   reset_dau = e.hasAttr(_ALU(reset_children)) ? e.attr<bool>(_ALU(reset_children)) : false;
0144   bool   overlap   = e.hasAttr(_ALU(overlap));
0145   double ovl       = overlap ? e.attr<double>(_ALU(overlap)) : 0.001;
0146   DetElement elt   = detail::tools::findDaughterElement(det,path);
0147   std::string placement = elt.isValid() ? elt.placementPath() : std::string("-----");
0148 
0149   if ( !elt.isValid() )   {
0150     except("GlocalAlignmentParser",
0151            "dd4hep: DetElement %s has no child: %s [No such child]", det.path().c_str(), path.c_str());
0152   }
0153 
0154   Delta delta;
0155   xml::parse(e, delta);
0156   if ( delta.flags )  {
0157     delta.flags |= GlobalAlignmentStack::MATRIX_DEFINED;
0158     reset = reset_dau = true;
0159   }
0160   if ( overlap     ) delta.flags |= GlobalAlignmentStack::OVERLAP_DEFINED;
0161   if ( check       ) delta.flags |= GlobalAlignmentStack::CHECKOVL_DEFINED;
0162   if ( reset       ) delta.flags |= GlobalAlignmentStack::RESET_VALUE;
0163   if ( reset_dau   ) delta.flags |= GlobalAlignmentStack::RESET_CHILDREN;
0164   if ( check_val   ) delta.flags |= GlobalAlignmentStack::CHECKOVL_VALUE;
0165 
0166   printout(INFO,
0167            "Alignment<det>","path:%s [%s] placement:%s matrix:%s reset:%s children:%s",
0168            path.c_str(),
0169            elt.isValid() ? elt.path().c_str() : "-----",
0170            placement.c_str(),
0171            yes_no(delta.checkFlag(GlobalAlignmentStack::MATRIX_DEFINED)),
0172            yes_no(reset), yes_no(reset_dau));
0173 
0174   dd4hep_ptr<StackEntry> entry(new StackEntry(elt,placement,delta,ovl));
0175   stack->insert(entry);
0176 
0177   std::pair<DetElement, std::string> vol_param(elt,"");
0178   xml_coll_t(e,_U(volume)).for_each(Converter<volume>(description,&vol_param,optional));
0179   xml_coll_t(e,_ALU(detelement)).for_each(Converter<detelement>(description,elt.ptr(),optional));
0180   xml_coll_t(e,_U(include)).for_each(Converter<include_file>(description,elt.ptr(),optional));
0181 }
0182 
0183 /** Convert detelement_include objects
0184  *
0185  *    <detelement path="/world/TPC/TPC_SideA/TPC_SideA_sector02">
0186  *      <position x="0*mm" y="0*mm" z="0*mm"/>
0187  *      <rotation x="0.5"  y="0.1"  z="0.2"/>
0188  *    </detelement>
0189  *
0190  *  @author  M.Frank
0191  *  @version 1.0
0192  *  @date    01/04/2014
0193  */
0194 template <> void dd4hep::Converter<dd4hep::include_file>::operator()(xml_h element) const {
0195   xml::DocumentHolder doc(xml::DocumentHandler().load(element, element.attr_value(_U(ref))));
0196   xml_h node = doc.root();
0197   std::string tag = node.tag();
0198   if ( tag == "alignment" )
0199     Converter<alignment>(description,param,optional)(node);
0200   else if ( tag == "global_alignment" )
0201     setup_Alignment(description, node);
0202   else if ( tag == "detelement" )
0203     Converter<detelement>(description,param,optional)(node);
0204   else if ( tag == "subdetectors" || tag == "detelements" )
0205     xml_coll_t(node,_ALU(detelements)).for_each(Converter<detelement>(description,param,optional));
0206   else
0207     except("GlocalAlignmentParser", "Undefined tag name in XML structure: %s XML parsing abandoned.", tag.c_str());
0208 }
0209 
0210 /** Convert alignment objects
0211  *
0212  *    <alignment>
0213  *      <detelement path="TPC">
0214  *        ...
0215  *      </detelement>
0216  *    </alignment>
0217  *
0218  *  @author  M.Frank
0219  *  @version 1.0
0220  *  @date    01/04/2014
0221  */
0222 template <> void dd4hep::Converter<dd4hep::alignment>::operator()(xml_h e)  const  {
0223   /// Now we process all allowed elements within the alignment tag:
0224   /// <detelement/>, <detelements/>, <subdetectors/> and <include/>
0225   xml_coll_t(e,_ALU(debug)).for_each(Converter<debug>(description,param,optional));
0226   xml_coll_t(e,_ALU(detelement)).for_each(Converter<detelement>(description,param,optional));
0227   xml_coll_t(e,_ALU(detelements)).for_each(_ALU(detelement),Converter<detelement>(description,param,optional));
0228   xml_coll_t(e,_ALU(subdetectors)).for_each(_ALU(detelement),Converter<detelement>(description,param,optional));
0229   xml_coll_t(e,_U(include)).for_each(Converter<include_file>(description,param,optional));
0230 }
0231 
0232 /** Basic entry point to read alignment files
0233  *
0234  *  @author  M.Frank
0235  *  @version 1.0
0236  *  @date    01/04/2014
0237  */
0238 long dd4hep::setup_Alignment(dd4hep::Detector& description, const xml_h& e)  {
0239   static dd4hep::dd4hep_mutex_t s_mutex;
0240   dd4hep::dd4hep_lock_t lock(s_mutex);
0241   bool open_trans  = e.hasChild(_ALU(open_transaction));
0242   bool close_trans = e.hasChild(_ALU(close_transaction));
0243 
0244   GlobalAlignmentCache* cache = GlobalAlignmentCache::install(description);
0245   /// Check if transaction already present. If not, open, else issue an error
0246   if ( open_trans )   {
0247     if ( GlobalAlignmentStack::exists() )  {
0248       except("GlobalAlignment","Request to open a second alignment transaction stack -- not allowed!");
0249     }
0250     GlobalAlignmentStack::create();
0251   }
0252   if ( !GlobalAlignmentStack::exists() )  {
0253     printout(ERROR,"GlobalAlignment",
0254              "Request process global alignments without cache.");
0255     printout(ERROR,"GlobalAlignment",
0256              "Call plugin DD4hep_GlobalAlignmentInstall first OR add XML tag <open_transaction/>");
0257     except("GlobalAlignment","Request process global alignments without cache.");
0258   }
0259   GlobalAlignmentStack& stack = GlobalAlignmentStack::get();
0260   (dd4hep::Converter<dd4hep::alignment>(description,description.world().ptr(),&stack))(e);
0261   if ( close_trans )  {
0262     cache->commit(stack);
0263     GlobalAlignmentStack::get().release();
0264   }
0265   if ( GlobalDetectorAlignment::debug() )  {
0266     xml_elt_t elt(e);
0267     Path uri = elt.document().uri();
0268     printout(INFO,"GlobalAlignment","+++ Successfully parsed XML: %s",
0269              uri.filename().c_str());
0270   }
0271   return 1;
0272 }
0273 DECLARE_XML_DOC_READER(global_alignment,setup_Alignment)
0274 
0275 /** Basic entry point to install the alignment cache in a Detector instance
0276  *
0277  *  @author  M.Frank
0278  *  @version 1.0
0279  *  @date    01/04/2014
0280  */
0281 static long install_Alignment(dd4hep::Detector& description, int, char**) {
0282   GlobalAlignmentCache::install(description);
0283   return 1;
0284 }
0285 DECLARE_APPLY(DD4hep_GlobalAlignmentInstall,install_Alignment)