Back to home page

EIC code displayed by LXR

 
 

    


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 //  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 #ifndef DD4HEP_DDCOND_CONDITIONSREPOSITORYWRITER_H
0014 #define DD4HEP_DDCOND_CONDITIONSREPOSITORYWRITER_H
0015 
0016 // Framework include files
0017 #include <DD4hep/Detector.h>
0018 #include <XML/XMLElements.h>
0019 #include <DDCond/ConditionsManager.h>
0020 
0021 // C/C++ include files
0022 
0023 /// Namespace for the AIDA detector description toolkit
0024 namespace dd4hep {
0025 
0026   /// Namespace for implementation details of the AIDA detector description toolkit
0027   namespace cond {
0028 
0029     // Forward declarations
0030     class ConditionsSlice;
0031     
0032     /// Conditions slice object. Defines which conditions should be loaded by the ConditionsManager.
0033     /**
0034      *  Object contains set of required conditions keys to be loaded to the user pool.
0035      *  It alkso contains the load information for the required conditions (conditions addresses).
0036      *  The address objects depend on the actual loader mechanism and must be specified the user.
0037      *  The information is then chained through the calls and made availible to the loader object.
0038      *
0039      *  On return it contains the individual condition load information.
0040      *
0041      *  Referenced by: ConditonsUserPool, ConditionsManager
0042      *
0043      *  \author  M.Frank
0044      *  \version 1.0
0045      *  \ingroup DD4HEP_CONDITIONS
0046      */
0047     class ConditionsXMLRepositoryWriter  {
0048       /// Debug counters: converted conditions
0049       long m_numConverted = 0;
0050       /// Debug counters: unconverted conditions
0051       long m_numUnconverted = 0;
0052     public:
0053       /// Default constructor
0054       ConditionsXMLRepositoryWriter() = default;
0055       /// Copy constructor (Special, partial copy only. Hence no assignment!)
0056       ConditionsXMLRepositoryWriter(const ConditionsXMLRepositoryWriter& copy) = default;
0057       /// Default destructor. 
0058       virtual ~ConditionsXMLRepositoryWriter();
0059      
0060       /// Dump the tree content into a XML document structure
0061       xml::Document dump(ConditionsSlice& slice);
0062       /// Dump the ConditionsManager configuration properties into a XML document structure
0063       xml::Document dump(ConditionsManager manager);
0064       /// Dump the tree content into an existing XML document structure
0065       size_t collect(xml::Element root,ConditionsSlice& slice,DetElement detector);
0066       /// Dump the ConditionsManager configuration properties into an existing XML document structure
0067       size_t collect(xml::Element root, ConditionsManager manager);
0068       /// Dump the conditions tree content into a XML document structure
0069       size_t collect(xml::Element root, ConditionsSlice& slice);
0070       /// Write the XML document structure to a file.
0071       long write(xml::Document doc, const std::string& output)  const;
0072     };
0073     
0074   }        /* End namespace cond                          */
0075 }          /* End namespace dd4hep                              */
0076 #endif     /* DD4HEP_DDCOND_CONDITIONSREPOSITORYWRITER_H        */
0077 
0078 
0079 //==========================================================================
0080 //  AIDA Detector description implementation 
0081 //--------------------------------------------------------------------------
0082 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0083 // All rights reserved.
0084 //
0085 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0086 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0087 //
0088 // Author     : M.Frank
0089 //
0090 //==========================================================================
0091 
0092 // Framework include files
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 // C/C++ include files
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 /// Anonymous local stuff only used in this module
0122 namespace {
0123 
0124   /// Module print level
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 /// Default destructor. 
0262 ConditionsXMLRepositoryWriter::~ConditionsXMLRepositoryWriter()    {
0263   printout(INFO,"ConditionsXMLWriter","++ Summary: Converted %ld conditions. %ld conditions without recipe.",
0264            m_numConverted, m_numUnconverted);
0265 }
0266 
0267 /// Dump the tree content into a XML document structure
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 /// Dump the ConditionsManager configuration properties into a XML document structure
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 /// Dump the conditions tree content into a XML document structure
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 /// Dump the ConditionsManager configuration properties into an existing XML document structure
0301 size_t ConditionsXMLRepositoryWriter::collect(xml::Element root,
0302                                               ConditionsManager manager)  
0303 {
0304   size_t count = 0;
0305   if ( manager.isValid() )  {
0306     /// Access to the property manager
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 /// Dump the conditions tree content into a XML document structure
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 /// Write the XML document structure to a file.
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 /// Basic entry point to read alignment conditions files
0441 /**
0442  *  \author  M.Frank
0443  *  \version 1.0
0444  *  \date    01/04/2014
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 /// Basic entry point to read alignment conditions files
0504 /**
0505  *  \author  M.Frank
0506  *  \version 1.0
0507  *  \date    01/04/2014
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 // ======================================================================================