File indexing completed on 2025-01-18 09:13:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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
0031 #include <stdexcept>
0032
0033 namespace dd4hep {
0034
0035 namespace {
0036
0037
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
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
0064
0065
0066
0067
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
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
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
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
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
0184
0185
0186
0187
0188
0189
0190
0191
0192
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
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 template <> void dd4hep::Converter<dd4hep::alignment>::operator()(xml_h e) const {
0223
0224
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
0233
0234
0235
0236
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
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
0276
0277
0278
0279
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)