Warning, file /DD4hep/DDCond/src/plugins/ConditionsRepositoryWriter.cpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef DD4HEP_DDCOND_CONDITIONSREPOSITORYWRITER_H
0014 #define DD4HEP_DDCOND_CONDITIONSREPOSITORYWRITER_H
0015
0016
0017 #include <DD4hep/Detector.h>
0018 #include <XML/XMLElements.h>
0019 #include <DDCond/ConditionsManager.h>
0020
0021
0022
0023
0024 namespace dd4hep {
0025
0026
0027 namespace cond {
0028
0029
0030 class ConditionsSlice;
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 class ConditionsXMLRepositoryWriter {
0048
0049 long m_numConverted = 0;
0050
0051 long m_numUnconverted = 0;
0052 public:
0053
0054 ConditionsXMLRepositoryWriter() = default;
0055
0056 ConditionsXMLRepositoryWriter(const ConditionsXMLRepositoryWriter& copy) = default;
0057
0058 virtual ~ConditionsXMLRepositoryWriter();
0059
0060
0061 xml::Document dump(ConditionsSlice& slice);
0062
0063 xml::Document dump(ConditionsManager manager);
0064
0065 size_t collect(xml::Element root,ConditionsSlice& slice,DetElement detector);
0066
0067 size_t collect(xml::Element root, ConditionsManager manager);
0068
0069 size_t collect(xml::Element root, ConditionsSlice& slice);
0070
0071 long write(xml::Document doc, const std::string& output) const;
0072 };
0073
0074 }
0075 }
0076 #endif
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 #include <XML/XMLElements.h>
0094 #include <XML/DocumentHandler.h>
0095 #include <DD4hep/Printout.h>
0096 #include <DD4hep/Alignments.h>
0097 #include <DD4hep/AlignmentData.h>
0098 #include <DD4hep/OpaqueDataBinder.h>
0099 #include <DD4hep/ConditionsProcessor.h>
0100 #include <DD4hep/DetFactoryHelper.h>
0101 #include <DD4hep/detail/ConditionsInterna.h>
0102 #include <DD4hep/detail/AlignmentsInterna.h>
0103
0104 #include <DDCond/ConditionsTags.h>
0105 #include <DDCond/ConditionsSlice.h>
0106 #include <DDCond/ConditionsManagerObject.h>
0107
0108
0109 #include <stdexcept>
0110 #include <memory>
0111 #include <sstream>
0112 #include <list>
0113 #include <set>
0114
0115 using namespace dd4hep::cond;
0116 namespace units = dd4hep;
0117 namespace xml = dd4hep::xml;
0118 using dd4hep::printout;
0119 using dd4hep::_toString;
0120
0121
0122 namespace {
0123
0124
0125 static dd4hep::PrintLevel s_printLevel = dd4hep::INFO;
0126
0127 class pressure;
0128 class temperature;
0129 class value;
0130 class sequence;
0131
0132 class PropertyDumper {
0133 xml::Element root;
0134 public:
0135 PropertyDumper(xml::Element p) : root(p) {}
0136 void operator()(const std::pair<std::string, dd4hep::Property>& p) const {
0137 xml::Element e = xml::Element(root.document(),_UC(property));
0138 std::string val = p.second.str();
0139 if ( val[0] == '\'' ) val = p.second.str().c_str()+1;
0140 if ( !val.empty() && val[val.length()-1] == '\'' ) val[val.length()-1] = 0;
0141 e.setAttr(_U(name), p.first);
0142 e.setAttr(_U(value), val);
0143 root.append(e);
0144 }
0145 };
0146
0147 template <typename T> xml::Element _convert(xml::Element par, dd4hep::Condition c);
0148
0149 xml::Element make(xml::Element e, dd4hep::Condition c) {
0150 char hash[64];
0151 std::string nam = c.name();
0152 std::string cn = nam.substr(nam.find('#')+1);
0153 ::snprintf(hash,sizeof(hash),"%llX",c.key());
0154 e.setAttr(_U(name),cn);
0155 e.setAttr(_U(key),hash);
0156 return e;
0157 }
0158 xml::Element _convert(xml::Element par, const dd4hep::Translation3D& tr) {
0159 xml::Element e = xml::Element(par.document(),_U(pivot));
0160 const dd4hep::Translation3D::Vector& v = tr.Vect();
0161 e.setAttr(_U(x),_toString(v.X()/dd4hep::mm,"%f*mm"));
0162 e.setAttr(_U(y),_toString(v.Y()/dd4hep::mm,"%f*mm"));
0163 e.setAttr(_U(z),_toString(v.Z()/dd4hep::mm,"%f*mm"));
0164 return e;
0165 }
0166 xml::Element _convert(xml::Element par, const dd4hep::Position& pos) {
0167 xml::Element e = xml::Element(par.document(),_U(position));
0168 e.setAttr(_U(x),_toString(pos.X()/dd4hep::mm,"%f*mm"));
0169 e.setAttr(_U(y),_toString(pos.Y()/dd4hep::mm,"%f*mm"));
0170 e.setAttr(_U(z),_toString(pos.Z()/dd4hep::mm,"%f*mm"));
0171 return e;
0172 }
0173 xml::Element _convert(xml::Element par, const dd4hep::RotationZYX& rot) {
0174 xml::Element e = xml::Element(par.document(),_U(rotation));
0175 double z, y, x;
0176 rot.GetComponents(z,y,x);
0177 e.setAttr(_U(x),_toString(x/dd4hep::rad,"%f*rad"));
0178 e.setAttr(_U(y),_toString(y/dd4hep::rad,"%f*rad"));
0179 e.setAttr(_U(z),_toString(z/dd4hep::rad,"%f*rad"));
0180 return e;
0181 }
0182 template <> xml::Element _convert<value>(xml::Element par, dd4hep::Condition c) {
0183 xml::Element v = make(xml::Element(par.document(),_U(value)),c);
0184 dd4hep::OpaqueData& data = c.data();
0185 v.setAttr(_U(type),data.dataType());
0186 v.setAttr(_U(value),data.str());
0187 return v;
0188 }
0189 template <> xml::Element _convert<pressure>(xml::Element par, dd4hep::Condition c) {
0190 xml::Element press = make(xml::Element(par.document(),_UC(pressure)),c);
0191 press.setAttr(_U(value),c.get<double>()/(100e0*units::pascal));
0192 press.setAttr(_U(unit),"hPa");
0193 return press;
0194 }
0195 template <> xml::Element _convert<temperature>(xml::Element par, dd4hep::Condition c) {
0196 xml::Element temp = make(xml::Element(par.document(),_UC(temperature)),c);
0197 temp.setAttr(_U(value),c.get<double>()/units::kelvin);
0198 temp.setAttr(_U(unit),"kelvin");
0199 return temp;
0200 }
0201 template <> xml::Element _convert<dd4hep::Delta>(xml::Element par, dd4hep::Condition c) {
0202 xml::Element align = make(xml::Element(par.document(),_UC(alignment_delta)),c);
0203 const dd4hep::Delta& delta = c.get<dd4hep::Delta>();
0204 if ( delta.flags&dd4hep::Delta::HAVE_TRANSLATION )
0205 align.append(_convert(align,delta.translation));
0206 if ( delta.flags&dd4hep::Delta::HAVE_ROTATION )
0207 align.append(_convert(align,delta.rotation));
0208 if ( delta.flags&dd4hep::Delta::HAVE_PIVOT )
0209 align.append(_convert(align,delta.pivot));
0210 return align;
0211 }
0212 template <> xml::Element _convert<dd4hep::Alignment>(xml::Element par, dd4hep::Condition c) {
0213 char hash[64];
0214 typedef dd4hep::ConditionKey::KeyMaker KM;
0215 dd4hep::AlignmentCondition acond = c;
0216 KM km(c.key());
0217 const dd4hep::Delta& delta = acond.data().delta;
0218 xml::Element align(xml::Element(par.document(),_UC(alignment_delta)));
0219 dd4hep::Condition::key_type key = KM(km.values.det_key,dd4hep::align::Keys::deltaKey).hash;
0220 ::snprintf(hash,sizeof(hash),"%llX",key);
0221 align.setAttr(_U(name), dd4hep::align::Keys::deltaName);
0222 align.setAttr(_U(key),hash);
0223 if ( delta.flags&dd4hep::Delta::HAVE_TRANSLATION )
0224 align.append(_convert(align,delta.translation));
0225 if ( delta.flags&dd4hep::Delta::HAVE_ROTATION )
0226 align.append(_convert(align,delta.rotation));
0227 if ( delta.flags&dd4hep::Delta::HAVE_PIVOT )
0228 align.append(_convert(align,delta.pivot));
0229 return align;
0230 }
0231 xml::Element _seq(xml::Element v, dd4hep::Condition c, const char* tag, const char* match) {
0232 dd4hep::OpaqueData& data = c.data();
0233 std::string typ = data.dataType();
0234 size_t len = ::strlen(match);
0235 size_t idx = typ.find(match);
0236 size_t idq = typ.find(',',idx+len);
0237 if ( idx != std::string::npos && idq != std::string::npos ) {
0238 std::string subtyp = tag;
0239 subtyp += "["+typ.substr(idx+len,idq-idx-len)+"]";
0240 v.setAttr(_U(type),subtyp);
0241 xml::Handle_t(v.ptr()).setText(data.str());
0242 return v;
0243 }
0244 dd4hep::except("Writer","++ Unknwon XML conversion to type: %s",typ.c_str());
0245 return v;
0246 }
0247 template <> xml::Element _convert<std::vector<void*> >(xml::Element par, dd4hep::Condition c) {
0248 xml::Element v = make(xml::Element(par.document(),_UC(sequence)),c);
0249 return _seq(v,c,"vector","::vector<");
0250 }
0251 template <> xml::Element _convert<std::list<void*> >(xml::Element par, dd4hep::Condition c) {
0252 xml::Element v = make(xml::Element(par.document(),_UC(sequence)),c);
0253 return _seq(v,c,"list","::list<");
0254 }
0255 template <> xml::Element _convert<std::set<void*> >(xml::Element par, dd4hep::Condition c) {
0256 xml::Element v = make(xml::Element(par.document(),_UC(sequence)),c);
0257 return _seq(v,c,"set","::set<");
0258 }
0259 }
0260
0261
0262 ConditionsXMLRepositoryWriter::~ConditionsXMLRepositoryWriter() {
0263 printout(INFO,"ConditionsXMLWriter","++ Summary: Converted %ld conditions. %ld conditions without recipe.",
0264 m_numConverted, m_numUnconverted);
0265 }
0266
0267
0268 xml::Document ConditionsXMLRepositoryWriter::dump(ConditionsSlice& slice) {
0269 xml::DocumentHandler docH;
0270 xml::Document doc = docH.create("conditions", docH.defaultComment());
0271 collect(doc.root(),slice);
0272 return doc;
0273 }
0274
0275
0276 xml::Document ConditionsXMLRepositoryWriter::dump(ConditionsManager manager) {
0277 xml::DocumentHandler docH;
0278 xml::Document doc = docH.create("conditions", docH.defaultComment());
0279 xml::Element root = doc.root();
0280 collect(root,manager);
0281 return doc;
0282 }
0283
0284
0285 size_t ConditionsXMLRepositoryWriter::collect(xml::Element root, ConditionsSlice& slice) {
0286 xml::Element repo(root.document(),_UC(repository));
0287 xml::Element iov (repo.document(),_UC(iov));
0288 const IOV& validity = slice.pool->validity();
0289 char text[128];
0290
0291 root.append(repo);
0292 repo.append(iov);
0293 std::snprintf(text,sizeof(text),"%ld,%ld#%s",
0294 long(validity.keyData.first), long(validity.keyData.second),
0295 validity.iovType->name.c_str());
0296 iov.setAttr(_UC(validity),text);
0297 return collect(iov,slice,slice.manager->detectorDescription().world());
0298 }
0299
0300
0301 size_t ConditionsXMLRepositoryWriter::collect(xml::Element root,
0302 ConditionsManager manager)
0303 {
0304 size_t count = 0;
0305 if ( manager.isValid() ) {
0306
0307 PropertyManager& prp = manager.properties();
0308 xml::Element rep(root.document(),_UC(repository));
0309 xml::Element mgr(rep.document(),_UC(manager));
0310 const auto iovs = manager.iovTypesUsed();
0311
0312 prp.for_each(PropertyDumper(mgr));
0313 rep.append(mgr);
0314 count += prp.size();
0315 for ( const auto t : iovs ) {
0316 xml::Element iov_typ(rep.document(),_UC(iov_type));
0317 iov_typ.setAttr(_U(name),t->name);
0318 iov_typ.setAttr(_U(id),int(t->type));
0319 rep.append(iov_typ);
0320 }
0321 root.append(rep);
0322 }
0323 return count;
0324 }
0325
0326
0327 size_t ConditionsXMLRepositoryWriter::collect(xml::Element root,
0328 ConditionsSlice& slice,
0329 DetElement detector)
0330 {
0331 size_t count = 0;
0332 if ( detector.isValid() ) {
0333 std::vector<Condition> conds;
0334 conditionsCollector(slice,conds)(detector);
0335 if ( !conds.empty() ) {
0336 std::stringstream comment;
0337 Condition cond_align, cond_delta;
0338 xml::Element conditions = xml::Element(root.document(),_UC(detelement));
0339 conditions.setAttr(_U(path),detector.path());
0340 printout(s_printLevel,"Writer","++ Conditions of DE %s [%d entries]",
0341 detector.path().c_str(), int(conds.size()));
0342 comment << " DDCond conditions for DetElement " << detector.path()
0343 << " Total of " << int(conds.size()) << " Entries. ";
0344 root.addComment(comment.str());
0345 root.append(conditions);
0346 for(const auto& c : conds ) {
0347 std::string nam = c.name();
0348 std::string cn = nam.substr(nam.find('#')+1);
0349 detail::ReferenceBitMask<Condition::mask_type> msk(c->flags);
0350
0351 printout(s_printLevel,"Writer","++ Condition %s [%16llX] -> %s",
0352 cn.c_str(), c.key(), c.name());
0353 if ( msk.isSet(Condition::TEMPERATURE) ) {
0354 conditions.append(_convert<temperature>(conditions,c));
0355 ++m_numConverted;
0356 }
0357 else if ( msk.isSet(Condition::PRESSURE) ) {
0358 conditions.append(_convert<pressure>(conditions,c));
0359 ++m_numConverted;
0360 }
0361 else if ( msk.isSet(Condition::ALIGNMENT_DERIVED) ) {
0362 cond_align = c;
0363 }
0364 else if ( msk.isSet(Condition::ALIGNMENT_DELTA) ) {
0365 cond_delta = c;
0366 }
0367 else {
0368 const dd4hep::OpaqueData& data = c.data();
0369 const std::type_info& typ = data.typeInfo();
0370 #if defined(DD4HEP_HAVE_ALL_PARSERS)
0371 if ( typ == typeid(char) || typ == typeid(unsigned char) ||
0372 typ == typeid(short) || typ == typeid(unsigned short) ||
0373 typ == typeid(int) || typ == typeid(unsigned int) ||
0374 typ == typeid(long) || typ == typeid(unsigned long) ||
0375 typ == typeid(float) || typ == typeid(double) ||
0376 typ == typeid(bool) || typ == typeid(std::string) )
0377 #else
0378 if ( typ == typeid(int) || typ == typeid(long) ||
0379 typ == typeid(float) || typ == typeid(double) ||
0380 typ == typeid(bool) || typ == typeid(std::string) )
0381 #endif
0382 {
0383 conditions.append(_convert<value>(conditions,c));
0384 ++m_numConverted;
0385 }
0386 else if ( ::strstr(data.dataType().c_str(),"::vector<") ) {
0387 conditions.append(_convert<std::vector<void*> >(conditions,c));
0388 ++m_numConverted;
0389 }
0390 else if ( ::strstr(data.dataType().c_str(),"::list<") ) {
0391 conditions.append(_convert<std::list<void*> >(conditions,c));
0392 ++m_numConverted;
0393 }
0394 else if ( ::strstr(data.dataType().c_str(),"::set<") ) {
0395 conditions.append(_convert<std::set<void*> >(conditions,c));
0396 ++m_numConverted;
0397 }
0398 else {
0399 comment.str("");
0400 comment << "\n ** Unconverted condition: "
0401 << "Unknown data type of condition: " << cn
0402 << " [" << (void*)c.key() << "] -> "
0403 << c.name() << " Flags:" << (unsigned int)c->flags << "\n";
0404 conditions.addComment(comment.str());
0405 printout(ERROR,"Writer",comment.str());
0406 comment.str("");
0407 comment << c.data().str() << " [" << c.data().dataType() << "]\n";
0408 conditions.addComment(comment.str());
0409 ++m_numUnconverted;
0410 }
0411 }
0412 }
0413 if ( cond_align.isValid() ) {
0414 conditions.append(_convert<Alignment>(conditions,cond_align));
0415 ++m_numConverted;
0416 }
0417 else if ( cond_delta.isValid() ) {
0418 conditions.append(_convert<dd4hep::Delta>(conditions,cond_delta));
0419 ++m_numConverted;
0420 }
0421 }
0422 for (const auto& i : detector.children())
0423 count += collect(root,slice,i.second);
0424 }
0425 return count;
0426 }
0427
0428
0429
0430 long ConditionsXMLRepositoryWriter::write(xml::Document doc, const std::string& output) const {
0431 xml_handler_t docH;
0432 long ret = docH.output(doc, output);
0433 if ( !output.empty() ) {
0434 printout(INFO,"Writer","++ Successfully wrote %ld conditions (%ld unconverted) to file: %s",
0435 m_numConverted,m_numUnconverted,output.c_str());
0436 }
0437 return ret;
0438 }
0439
0440
0441
0442
0443
0444
0445
0446 static long write_repository_conditions(dd4hep::Detector& description, int argc, char** argv) {
0447 ConditionsManager manager = ConditionsManager::from(description);
0448 const dd4hep::IOVType* iovtype = 0;
0449 long iovvalue = -1;
0450 long mgr_prop = 0;
0451 std::string output;
0452
0453 for(int i=0; i<argc; ++i) {
0454 if ( ::strncmp(argv[i],"-iov_type",7) == 0 )
0455 iovtype = manager.iovType(argv[++i]);
0456 else if ( ::strncmp(argv[i],"-iov_value",7) == 0 )
0457 iovvalue = ::atol(argv[++i]);
0458 else if ( ::strncmp(argv[i],"-output",4) == 0 && argc>i+1)
0459 output = argv[++i];
0460 else if ( ::strncmp(argv[i],"-manager",4) == 0 )
0461 mgr_prop = 1;
0462 else if ( ::strncmp(argv[i],"-help",2) == 0 ) {
0463 printout(dd4hep::ALWAYS,"Plugin-Help","Usage: dd4hep_XMLConditionsRepositoryWriter --opt [--opt] ");
0464 printout(dd4hep::ALWAYS,"Plugin-Help"," -output <string> Output file name. Default: stdout ");
0465 printout(dd4hep::ALWAYS,"Plugin-Help"," -manager <string> Add manager properties to the output. ");
0466 printout(dd4hep::ALWAYS,"Plugin-Help"," -iov_type <string> IOV type to be selected. ");
0467 printout(dd4hep::ALWAYS,"Plugin-Help"," -iov_value <string> IOV value to create the conditions snapshot.");
0468 ::exit(EINVAL);
0469 }
0470 }
0471 if ( 0 == iovtype )
0472 dd4hep::except("ConditionsPrepare","++ Unknown IOV type supplied.");
0473 if ( 0 > iovvalue )
0474 dd4hep::except("ConditionsPrepare",
0475 "++ Unknown IOV value supplied for iov type %s.",iovtype->str().c_str());
0476
0477 dd4hep::IOV iov(iovtype,iovvalue);
0478 std::shared_ptr<ConditionsContent> content(new ConditionsContent());
0479 std::shared_ptr<ConditionsSlice> slice(new ConditionsSlice(manager,content));
0480 dd4hep::cond::fill_content(manager,*content,*iovtype);
0481 ConditionsManager::Result cres = manager.prepare(iov, *slice);
0482 printout(dd4hep::INFO, "Conditions",
0483 "++ Selected conditions: %7ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) for IOV:%-12s",
0484 cres.total(), cres.selected, cres.loaded, cres.computed, cres.missing,
0485 iovtype ? iov.str().c_str() : "???");
0486
0487 ConditionsXMLRepositoryWriter writer;
0488 xml::Document doc(0);
0489 if ( mgr_prop ) {
0490 doc = writer.dump(manager);
0491 writer.collect(doc.root(), *slice);
0492 }
0493 else {
0494 doc = writer.dump(*slice);
0495 }
0496 writer.write(doc, output);
0497 return 1;
0498 }
0499 DECLARE_APPLY(DD4hep_ConditionsXMLRepositoryWriter,write_repository_conditions)
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509 static long write_repository_manager(dd4hep::Detector& description, int argc, char** argv) {
0510 ConditionsManager manager = ConditionsManager::from(description);
0511 std::string output;
0512
0513 for(int i=0; i<argc; ++i) {
0514 if ( ::strncmp(argv[i],"-output",4) == 0 && argc>i+1)
0515 output = argv[++i];
0516 else if ( ::strncmp(argv[i],"-help",2) == 0 ) {
0517 printout(dd4hep::ALWAYS,"Plugin-Help","Usage: dd4hep_XMLConditionsManagerWriter --opt [--opt] ");
0518 printout(dd4hep::ALWAYS,"Plugin-Help"," -output <string> Output file name. Default: stdout ");
0519 ::exit(EINVAL);
0520 }
0521 }
0522 ConditionsXMLRepositoryWriter writer;
0523 xml::Document doc = writer.dump(manager);
0524 writer.write(doc, output);
0525 return 1;
0526 }
0527 DECLARE_APPLY(DD4hep_ConditionsXMLManagerWriter,write_repository_manager)
0528