File indexing completed on 2025-01-30 09:16:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/Detector.h>
0016 #include <XML/Conversions.h>
0017 #include <XML/XMLParsers.h>
0018 #include <XML/XML.h>
0019 #include <DD4hep/Path.h>
0020 #include <DD4hep/Printout.h>
0021 #include <DD4hep/DetectorTools.h>
0022 #include <DD4hep/AlignmentData.h>
0023 #include <DD4hep/OpaqueDataBinder.h>
0024 #include <DD4hep/DetFactoryHelper.h>
0025 #include <DD4hep/detail/ConditionsInterna.h>
0026
0027 #include <DDCond/ConditionsTags.h>
0028 #include <DDCond/ConditionsManager.h>
0029
0030
0031 #include <stdexcept>
0032 #include <climits>
0033
0034
0035 namespace dd4hep {
0036
0037
0038 namespace {
0039
0040 class iov;
0041 class iov_type;
0042 class manager;
0043 class repository;
0044 class detelement;
0045 class conditions;
0046 class arbitrary;
0047
0048
0049 class value;
0050 class pressure;
0051 class temperature;
0052 class mapping;
0053 class sequence;
0054 class alignment;
0055 }
0056
0057 template <> void Converter<iov>::operator()(xml_h seq) const;
0058 template <> void Converter<iov_type>::operator()(xml_h seq) const;
0059 template <> void Converter<repository>::operator()(xml_h seq) const;
0060 template <> void Converter<manager>::operator()(xml_h seq) const;
0061 template <> void Converter<value>::operator()(xml_h e) const;
0062 template <> void Converter<pressure>::operator()(xml_h e) const;
0063 template <> void Converter<temperature>::operator()(xml_h e) const;
0064 template <> void Converter<sequence>::operator()(xml_h e) const;
0065 template <> void Converter<mapping>::operator()(xml_h e) const;
0066 template <> void Converter<alignment>::operator()(xml_h e) const;
0067 template <> void Converter<conditions>::operator()(xml_h seq) const;
0068 template <> void Converter<arbitrary>::operator()(xml_h seq) const;
0069 }
0070
0071 using namespace dd4hep::cond;
0072
0073
0074 namespace {
0075
0076
0077 static dd4hep::PrintLevel s_parseLevel = dd4hep::DEBUG;
0078
0079
0080
0081
0082
0083
0084
0085 struct ConversionArg {
0086 dd4hep::DetElement detector;
0087 ConditionsPool* pool;
0088 ConditionsManager manager;
0089 ConversionArg() = delete;
0090 ConversionArg(const ConversionArg&) = delete;
0091 ConversionArg(dd4hep::DetElement det, ConditionsManager m) : detector(det), pool(0), manager(m)
0092 { }
0093 ConversionArg& operator=(const ConversionArg&) = delete;
0094 };
0095
0096
0097
0098
0099
0100
0101
0102 struct CurrentDetector {
0103 dd4hep::DetElement detector;
0104 ConversionArg* arg;
0105 CurrentDetector(ConversionArg* a) : arg(a) {
0106 detector = arg->detector;
0107 }
0108 ~CurrentDetector() {
0109 arg->detector = detector;
0110 }
0111 void set(const std::string& path) {
0112 if ( !path.empty() ) {
0113 arg->detector = dd4hep::detail::tools::findDaughterElement(detector,path);
0114 }
0115 }
0116 };
0117
0118
0119
0120
0121
0122
0123 struct CurrentPool {
0124 ConditionsPool* pool;
0125 ConversionArg* arg;
0126 CurrentPool(ConversionArg* a) : arg(a) {
0127 pool = arg->pool;
0128 }
0129 ~CurrentPool() {
0130 arg->pool = pool;
0131 }
0132 void set(ConditionsPool* p) {
0133 arg->pool = p;
0134 }
0135 };
0136
0137
0138
0139
0140
0141
0142
0143 dd4hep::Condition create_condition(dd4hep::DetElement det, xml_h e) {
0144 xml_dim_t elt(e);
0145 std::string tag = elt.tag();
0146 std::string typ = elt.hasAttr(_U(type)) ? elt.typeStr() : tag;
0147 std::string nam = elt.hasAttr(_U(name)) ? elt.nameStr() : tag;
0148 std::string add = xml_handler_t::system_path(e);
0149 std::string cond_nam = det.path()+"#"+nam;
0150 dd4hep::Condition cond(cond_nam, typ);
0151 cond->hash = dd4hep::ConditionKey::hashCode(det, nam);
0152 dd4hep::printout(s_parseLevel,"XMLConditions","++ Processing condition tag:%s name:%s type:%s [%s] hash:%016X det:%p",
0153 tag.c_str(), cond.name(), typ.c_str(),
0154 dd4hep::Path(add).filename().c_str(), cond.key(), det.ptr());
0155 #if !defined(DD4HEP_MINIMAL_CONDITIONS)
0156 cond->address = add;
0157 cond->value = "";
0158 cond->validity = "";
0159 if ( elt.hasAttr(_U(comment)) ) {
0160 cond->comment = elt.attr<std::string>(_U(comment));
0161 }
0162 #endif
0163
0164 return cond;
0165 }
0166
0167
0168
0169
0170
0171
0172
0173 template <typename BINDER> dd4hep::Condition bind_condition(const BINDER& bnd,
0174 dd4hep::DetElement det,
0175 xml_h e,
0176 const std::string& type="")
0177 {
0178 xml_dim_t elt(e);
0179 std::string typ = type.empty() ? elt.typeStr() : type;
0180 std::string val = elt.hasAttr(_U(value)) ? elt.valueStr() : elt.text();
0181 dd4hep::Condition con = create_condition(det, e);
0182 std::string unit = elt.hasAttr(_U(unit)) ? elt.attr<std::string>(_U(unit)) : std::string("");
0183 if ( !unit.empty() ) val += "*"+unit;
0184 con->value = val;
0185 dd4hep::detail::OpaqueDataBinder::bind(bnd, con, typ, val);
0186 return con;
0187 }
0188 }
0189
0190
0191 namespace dd4hep {
0192
0193
0194
0195
0196
0197
0198
0199 template <> void Converter<iov_type>::operator()(xml_h element) const {
0200 xml_dim_t e = element;
0201 std::string nam = e.nameStr();
0202 std::size_t id = e.id() >= 0 ? e.id() : INT_MAX;
0203 ConversionArg* arg = _param<ConversionArg>();
0204 dd4hep::printout(s_parseLevel,"XMLConditions","++ Registering IOV type: [%d]: %s",int(id),nam.c_str());
0205 const IOVType* iov_type = arg->manager.registerIOVType(id,nam).second;
0206 if ( !iov_type ) {
0207 except("XMLConditions","Failed to register iov type: [%d]: %s",int(id),nam.c_str());
0208 }
0209 }
0210
0211
0212
0213
0214
0215
0216
0217 template <> void Converter<iov>::operator()(xml_h element) const {
0218 xml_dim_t e = element;
0219 std::string val = e.attr<std::string>(_UC(validity));
0220 ConversionArg* arg = _param<ConversionArg>();
0221 CurrentPool pool(arg);
0222
0223 pool.set(arg->manager.registerIOV(val));
0224 if ( e.hasAttr(_U(ref)) ) {
0225 std::string ref = e.attr<std::string>(_U(ref));
0226 dd4hep::printout(s_parseLevel,"XMLConditions","++ Reading IOV file: %s -> %s",val.c_str(),ref.c_str());
0227 xml::DocumentHolder doc(xml::DocumentHandler().load(element, element.attr_value(_U(ref))));
0228 Converter<conditions>(description,param,optional)(doc.root());
0229 return;
0230 }
0231 xml_coll_t(e,_UC(detelement)).for_each(Converter<arbitrary>(description,param,optional));
0232 }
0233
0234
0235
0236
0237
0238
0239
0240 template <> void Converter<manager>::operator()(xml_h element) const {
0241 ConversionArg* arg = _param<ConversionArg>();
0242 if ( element.hasAttr(_U(ref)) ) {
0243 xml::DocumentHolder doc(xml::DocumentHandler().load(element, element.attr_value(_U(ref))));
0244 Converter<arbitrary>(description,param,optional)(doc.root());
0245 }
0246 for( xml_coll_t c(element,_UC(property)); c; ++c) {
0247 xml_dim_t d = c;
0248 std::string nam = d.nameStr();
0249 std::string val = d.valueStr();
0250 try {
0251 printout(s_parseLevel,"XMLConditions","++ Setup conditions Manager[%s] = %s",
0252 nam.c_str(),val.c_str());
0253 arg->manager[nam].str(val);
0254 }
0255 catch(const std::exception& e) {
0256 printout(ERROR,"XMLConditions","++ FAILED: conditions Manager[%s] = %s [%s]",
0257 nam.c_str(),val.c_str(),e.what());
0258 }
0259 }
0260 arg->manager.initialize();
0261 printout(s_parseLevel,"XMLConditions","++ Conditions Manager successfully initialized.");
0262 }
0263
0264
0265
0266
0267
0268
0269
0270 template <> void Converter<value>::operator()(xml_h e) const {
0271 ConversionArg* arg = _param<ConversionArg>();
0272 dd4hep::Condition con = bind_condition(detail::ValueBinder(), arg->detector, e);
0273 arg->manager.registerUnlocked(*arg->pool, con);
0274 }
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 template <> void Converter<pressure>::operator()(xml_h e) const {
0285 ConversionArg* arg = _param<ConversionArg>();
0286 dd4hep::Condition con = bind_condition(detail::ValueBinder(), arg->detector, e, "double");
0287 con->setFlag(Condition::PRESSURE);
0288 arg->manager.registerUnlocked(*arg->pool, con);
0289 }
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 template <> void Converter<temperature>::operator()(xml_h e) const {
0300 ConversionArg* arg = _param<ConversionArg>();
0301 dd4hep::Condition con = bind_condition(detail::ValueBinder(), arg->detector, e, "double");
0302 con->setFlag(Condition::TEMPERATURE);
0303 arg->manager.registerUnlocked(*arg->pool, con);
0304 }
0305
0306
0307
0308
0309
0310
0311
0312 template <> void Converter<sequence>::operator()(xml_h e) const {
0313 ConversionArg* arg = _param<ConversionArg>();
0314 dd4hep::Condition con = create_condition(arg->detector, e);
0315 xml::parse_sequence(e, con->data);
0316 arg->manager.registerUnlocked(*arg->pool, con);
0317 }
0318
0319
0320
0321
0322
0323
0324
0325 template <> void Converter<mapping>::operator()(xml_h e) const {
0326 ConversionArg* arg = _param<ConversionArg>();
0327 dd4hep::Condition con = create_condition(arg->detector, e);
0328 xml::parse_mapping(e, con->data);
0329 arg->manager.registerUnlocked(*arg->pool, con);
0330 }
0331
0332
0333
0334
0335
0336
0337
0338 template <> void Converter<alignment>::operator()(xml_h e) const {
0339 xml_h child_rot, child_pos, child_piv;
0340 ConversionArg* arg = _param<ConversionArg>();
0341 dd4hep::Condition con = create_condition(arg->detector, e);
0342
0343 xml::parse_delta(e, con->data);
0344 con->setFlag(Condition::ALIGNMENT_DELTA);
0345 arg->manager.registerUnlocked(*arg->pool, con);
0346 }
0347
0348
0349
0350
0351
0352
0353
0354 template <> void Converter<detelement>::operator()(xml_h e) const {
0355 xml_comp_t elt(e);
0356 ConversionArg* arg = _param<ConversionArg>();
0357 CurrentDetector detector(arg);
0358 if ( elt.hasAttr(_U(path)) ) {
0359 detector.set(e.attr<std::string>(_U(path)));
0360 printout(s_parseLevel,"XMLConditions","++ Processing condition for:%s",
0361 arg->detector.path().c_str());
0362 }
0363 if ( elt.hasAttr(_U(ref)) ) {
0364 xml::DocumentHolder doc(xml::DocumentHandler().load(e, e.attr_value(_U(ref))));
0365 (*this)(doc.root());
0366 }
0367 xml_coll_t(e,_U(value)).for_each(Converter<value>(description,param,optional));
0368 xml_coll_t(e,_UC(mapping)).for_each(Converter<mapping>(description,param,optional));
0369 xml_coll_t(e,_UC(sequence)).for_each(Converter<sequence>(description,param,optional));
0370 xml_coll_t(e,_UC(pressure)).for_each(Converter<pressure>(description,param,optional));
0371 xml_coll_t(e,_UC(alignment_delta)).for_each(Converter<alignment>(description,param,optional));
0372 xml_coll_t(e,_UC(temperature)).for_each(Converter<temperature>(description,param,optional));
0373 xml_coll_t(e,_UC(detelement)).for_each(Converter<detelement>(description,param,optional));
0374 }
0375
0376
0377
0378
0379
0380
0381
0382 template <> void Converter<repository>::operator()(xml_h element) const {
0383 xml_coll_t(element,_UC(manager)).for_each(Converter<manager>(description,param,optional));
0384 xml_coll_t(element,_UC(iov_type)).for_each(Converter<iov_type>(description,param,optional));
0385 xml_coll_t(element,_UC(iov)).for_each(Converter<iov>(description,param,optional));
0386 }
0387
0388
0389
0390
0391
0392
0393
0394 template <> void Converter<arbitrary>::operator()(xml_h e) const {
0395 xml_comp_t elt(e);
0396 std::string tag = elt.tag();
0397 if ( tag == "repository" )
0398 Converter<repository>(description,param,optional)(e);
0399 else if ( tag == "manager" )
0400 Converter<manager>(description,param,optional)(e);
0401 else if ( tag == "conditions" )
0402 Converter<conditions>(description,param,optional)(e);
0403 else if ( tag == "detelement" )
0404 Converter<detelement>(description,param,optional)(e);
0405 else if ( tag == "iov_type" )
0406 Converter<iov_type>(description,param,optional)(e);
0407 else if ( tag == "iov" )
0408 Converter<iov>(description,param,optional)(e);
0409 else
0410 except("XMLConditions",
0411 "++ Failed to handle unknown tag: %s",tag.c_str());
0412 }
0413
0414
0415
0416
0417
0418
0419
0420 template <> void Converter<conditions>::operator()(xml_h e) const {
0421 xml_coll_t(e,_U(star)).for_each(Converter<arbitrary>(description,param,optional));
0422 }
0423 }
0424
0425
0426
0427
0428
0429
0430
0431 static long setup_repository_loglevel(dd4hep::Detector& , int argc, char** argv) {
0432 if ( argc == 1 ) {
0433 s_parseLevel = dd4hep::printLevel(argv[0]);
0434 return 1;
0435 }
0436 dd4hep::except("ConditionsXMLRepositoryPrintLevel","++ Invalid plugin arguments: %s",
0437 dd4hep::arguments(argc,argv).c_str());
0438 return 0;
0439 }
0440 DECLARE_APPLY(DD4hep_ConditionsXMLRepositoryPrintLevel,setup_repository_loglevel)
0441
0442 #include <DD4hep/DD4hepUI.h>
0443
0444
0445
0446
0447
0448
0449 static long setup_repository_Conditions(dd4hep::Detector& description, int argc, char** argv) {
0450 if ( argc == 1 ) {
0451 dd4hep::detail::DD4hepUI ui(description);
0452 std::string fname(argv[0]);
0453 ConditionsManager mgr(ui.conditionsMgr());
0454 ConversionArg arg(description.world(), mgr);
0455 xml_doc_holder_t doc(xml_handler_t().load(fname));
0456 (dd4hep::Converter<dd4hep::conditions>(description,&arg))(doc.root());
0457 return 1;
0458 }
0459 dd4hep::except("XML_DOC_READER","Invalid number of arguments to interprete conditions: %d != %d.",argc,1);
0460 return 0;
0461 }
0462 DECLARE_APPLY(DD4hep_ConditionsXMLRepositoryParser,setup_repository_Conditions)