diff --git a/DDCond/include/DDCond/ConditionsRepository.h b/DDCond/include/DDCond/ConditionsRepository.h index 15daaa004f14dfe6978ccbb2b3fc3b1e825ec781..9d34732c4f451a5d90051c56383f60c91a096e6e 100644 --- a/DDCond/include/DDCond/ConditionsRepository.h +++ b/DDCond/include/DDCond/ConditionsRepository.h @@ -1,4 +1,4 @@ -// $Id$ +// $Id: ConditionsRepository.h 2336 2016-09-07 17:27:40Z markus.frank@cern.ch $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -41,6 +41,11 @@ namespace DD4hep { */ class ConditionsRepository { public: + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ class Entry { public: std::string name, address; diff --git a/DDCond/include/DDCond/ConditionsTextRepository.h b/DDCond/include/DDCond/ConditionsTextRepository.h new file mode 100644 index 0000000000000000000000000000000000000000..b445fd83aea03eb8193e7dfab938bbbbd4967303 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsTextRepository.h @@ -0,0 +1,75 @@ +// $Id: ConditionsTextrepository.h 2336 2016-09-07 17:27:40Z markus.frank@cern.ch $ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights For. +// +// reserved the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_CONDITIONS_CONDITIONSTEXTREPOSITORY_H +#define DD4HEP_CONDITIONS_CONDITIONSTEXTREPOSITORY_H + +// Framework include files +#include "DDCond/ConditionsManager.h" + +// C/C++ include files + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Forward declarations + class IOV; + class IOVType; + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Forward declarations + + + /// Base class to be implemented by objects to listen on condition callbacks + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsTextRepository { + public: + class Entry { + public: + std::string name, address; + Condition::key_type key; + Entry() {} + Entry(const Entry& e) : name(e.name), address(e.address), key(e.key) {} + Entry& operator=(const Entry& e) { + if ( this != &e ) { + key = e.key; + name = e.name; + address = e.address; + } + return *this; + } + }; + typedef std::vector<Entry> Data; + + public: + /// Default constructor + ConditionsTextRepository(); + /// Default destructor + virtual ~ConditionsTextRepository(); + /// Save the textrepository to file + int save(ConditionsManager m, const std::string& output) const; + /// Load the textrepository from file and fill user passed data structory + int load(const std::string& input, Data& data) const; + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ + +#endif /* DD4HEP_CONDITIONS_CONDITIONSTEXTREPOSITORY_H */ diff --git a/DDCond/src/ConditionsTextRepository.cpp b/DDCond/src/ConditionsTextRepository.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d3cc1b8cd2eb2857d1bb2b25c4b692fc2dbe668a --- /dev/null +++ b/DDCond/src/ConditionsTextRepository.cpp @@ -0,0 +1,245 @@ +// $Id: ConditionsRepository.cpp 2336 2016-09-07 17:27:40Z markus.frank@cern.ch $ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DDCond/ConditionsTextRepository.h" +#include "DDCond/ConditionsIOVPool.h" +#include "DDCond/ConditionsTags.h" +#include "DD4hep/Printout.h" +#include "XML/DocumentHandler.h" +#include "XML/XMLTags.h" + +// C/C++ include files +#include <fstream> +#include <climits> +#include <cerrno> +#include <map> + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Conditions; +typedef XML::Handle_t xml_h; +typedef XML::Element xml_elt_t; +typedef XML::Document xml_doc_t; +typedef XML::Collection_t xml_coll_t; + +typedef map<Condition::key_type,Condition> AllConditions; + +/// Default constructor +ConditionsTextRepository::ConditionsTextRepository() { +} + +/// Default destructor +ConditionsTextRepository::~ConditionsTextRepository() { +} + +namespace { + + int createXML(const string& output, const AllConditions& all) { + const char comment[] = "\n" + " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" + " ++++ Linear collider detector description LCDD in C++ ++++\n" + " ++++ DD4hep Detector description generator. ++++\n" + " ++++ ++++\n" + " ++++ ++++\n" + " ++++ M.Frank CERN/LHCb ++++\n" + " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n "; + DD4hep::XML::DocumentHandler docH; + xml_doc_t doc = docH.create("collection", comment); + xml_elt_t root = doc.root(), cond(0); + for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i) { + char text[32]; + Condition c = (*i).second; + ::snprintf(text,sizeof(text),"0x%08X",c.key()); + root.append(cond = xml_elt_t(doc, _U(ref))); + cond.setAttr(_U(key), text); + cond.setAttr(_U(name), c.name()); + cond.setAttr(_U(ref), c.address()); + } + printout(ALWAYS,"ConditionsRepository","++ Handled %ld conditions.",all.size()); + if ( !output.empty() ) { + return docH.output(doc, output); + } + return 1; + } + + /// Load the repository from file and fill user passed data structory + int readXML(const string& input, ConditionsTextRepository::Data& data) { + struct Conv { + /// Reference to optional user defined parameter + ConditionsTextRepository::Data& data; + /// Initializing constructor of the functor + Conv(ConditionsTextRepository::Data& p) : data(p) {} + /// Callback operator to be specialized depending on the element type + void operator()(xml_h element) const { + string key = element.attr<string>(_U(key)); + size_t cap = data.capacity(); + ConditionsTextRepository::Entry e; + ::sscanf(key.c_str(),"0x%08X",&e.key); + e.name = element.attr<string>(_U(name)); + e.address = element.attr<string>(_U(ref)); + if ( data.size() == cap ) data.reserve(cap+500); + data.push_back(e); + } + }; + XML::DocumentHolder doc(XML::DocumentHandler().load(input)); + xml_h root = doc.root(); + xml_coll_t(root, _U(ref)).for_each(Conv(data)); + return 1; + } + + int createText(const string& output, const AllConditions& all, char sep) { + size_t siz_nam=0, siz_add=0, siz_tot=0; + char fmt[64], text[2*PATH_MAX+64]; + ofstream out(output); + if ( !out.good() ) { + except("ConditionsTextRepository", + "++ Failed to open output file:%s [errno:%d %s]", + output.c_str(), errno, ::strerror(errno)); + } + else if ( sep ) { + ::snprintf(fmt,sizeof(fmt),"%%08X%c%%s%c%%s%c",sep,sep,sep); + } + else { + for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i) { + Condition::Object* c = (*i).second.ptr(); + size_t siz_n = c->name.length(); + size_t siz_a = c->address.length(); + if ( siz_nam < siz_n ) siz_nam = siz_n; + if ( siz_add < siz_a ) siz_add = siz_a; + if ( siz_tot < (siz_n+siz_a) ) siz_tot = siz_n+siz_a; + } + siz_tot += 8+2+1; + ::snprintf(fmt,sizeof(fmt),"%%08X %%-%lds %%-%lds",long(siz_nam),long(siz_add)); + } + out << "dd4hep." << char(sep ? sep : '-') + << "." << long(siz_nam) + << "." << long(siz_add) + << "." << long(siz_tot) << endl; + for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i) { + Condition c = (*i).second; + ::snprintf(text, sizeof(text), fmt, c.key(), c.name().c_str(), c.address().c_str()); + out << text << endl; + } + out.close(); + return 1; + } + + /// Load the repository from file and fill user passed data structory + int readText(const string& input, ConditionsTextRepository::Data& data) { + size_t idx; + ConditionsTextRepository::Entry e; + long siz_nam, siz_add, siz_tot; + char sep, c, text[2*PATH_MAX+64]; + ifstream in(input); + in >> c >> c >> c >> c >> c >> c >> c >> sep + >> c >> siz_nam + >> c >> siz_add + >> c >> siz_tot; + text[0] = 0; + in.getline(text,sizeof(text),'\n'); + do { + text[0] = 0; + in.getline(text,sizeof(text),'\n'); + if ( in.good() ) { + if ( siz_tot ) { + // Direct access mode with fixed record size + text[8] = text[9+siz_nam] = text[10+siz_nam+siz_add] = 0; + e.name = text+9; + e.address = text+10+siz_nam; + if ( (idx=e.name.find(' ')) != string::npos ) + e.name[idx]=0; + if ( (idx=e.address.find(' ')) != string::npos ) + e.address[idx]=0; + } + else { + // Variable record size + e.name=text+9; + if ( (idx=e.name.find(sep)) != string::npos ) + text[9+idx]=0, e.address=text+idx+10, e.name=text+9; + if ( (idx=e.address.find(sep)) != string::npos ) + e.address[idx]=0; + else if ( (idx=e.address.find('\n')) != string::npos ) + e.address[idx]=0; + } + size_t cap = data.capacity(); + ::sscanf(text,"%08X",&e.key); + if ( data.size() == cap ) data.reserve(cap+500); + data.push_back(e); + } + } while(in.good() && !in.eof() ); + in.close(); + return 1; + } +} + +/// Save the repository to file +int ConditionsTextRepository::save(ConditionsManager manager, const string& output) const { + typedef vector<const IOVType*> _T; + typedef ConditionsIOVPool::Elements _E; + typedef RangeConditions _R; + AllConditions all; + const _T types = manager.iovTypesUsed(); + for( _T::const_iterator i = types.begin(); i != types.end(); ++i ) { + const IOVType* type = *i; + if ( type ) { + ConditionsIOVPool* pool = manager.iovPool(*type); + if ( pool ) { + const _E& e = pool->elements; + for (_E::const_iterator j=e.begin(); j != e.end(); ++j) { + ConditionsPool* cp = (*j).second; + _R rc; + cp->select_all(rc); + for(_R::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic) + all[(*ic).key()] = *ic; + } + } + } + } + + if ( output.find(".xml") != string::npos ) { + /// Write XML file with conditions addresses + return createXML(output, all); + } + else if ( output.find(".txt") != string::npos ) { + /// Write fixed records with conditions addresses + return createText(output, all, 0); + } + else if ( output.find(".daf") != string::npos ) { + /// Write fixed records with conditions addresses + return createText(output, all, 0); + } + else if ( output.find(".csv") != string::npos ) { + /// Write records separated by ';' with conditions addresses + return createText(output, all, ';'); + } + return 0; +} + +/// Load the repository from file and fill user passed data structory +int ConditionsTextRepository::load(const string& input, Data& data) const { + if ( input.find(".xml") != string::npos ) { + return readXML(input, data); + } + else if ( input.find(".txt") != string::npos ) { + return readText(input, data); + } + else if ( input.find(".daf") != string::npos ) { + return readText(input, data); + } + else if ( input.find(".csv") != string::npos ) { + return readText(input, data); + } + return 0; +}