DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
ConditionsRepository.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework include files
18 #include <DDCond/ConditionsTags.h>
20 #include <DD4hep/Printout.h>
21 #include <XML/DocumentHandler.h>
22 #include <XML/XMLTags.h>
23 
24 // C/C++ include files
25 #include <cstring>
26 #include <fstream>
27 #include <climits>
28 #include <cerrno>
29 #include <map>
30 
31 using namespace dd4hep::cond;
36 
37 typedef std::map<dd4hep::Condition::key_type,dd4hep::Condition> AllConditions;
38 
41 }
42 
45 }
46 
47 namespace {
48 
49  int createXML(const std::string& output, const AllConditions& all) {
50  const char comment[] = "\n"
51  " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
52  " ++++ Linear collider detector description Detector in C++ ++++\n"
53  " ++++ dd4hep Detector description generator. ++++\n"
54  " ++++ ++++\n"
55  " ++++ ++++\n"
56  " ++++ M.Frank CERN/LHCb ++++\n"
57  " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n ";
59  xml_doc_t doc = docH.create("collection", comment);
60  xml_elt_t root = doc.root(), cond(0);
61  for( const auto& i : all ) {
62  char text[32];
63  dd4hep::Condition c = i.second;
64  std::snprintf(text,sizeof(text),"0x%16llX",c.key());
65  root.append(cond = xml_elt_t(doc, _U(ref)));
66  cond.setAttr(_U(key), text);
67 #if !defined(DD4HEP_MINIMAL_CONDITIONS)
68  cond.setAttr(_U(name), c.name());
69  cond.setAttr(_U(ref), c.address());
70 #endif
71  }
72  dd4hep::printout(dd4hep::ALWAYS,"ConditionsRepository","++ Handled %ld conditions.",all.size());
73  if ( !output.empty() ) {
74  return docH.output(doc, output);
75  }
76  return 1;
77  }
78 
80  int readXML(const std::string& input, ConditionsRepository::Data& data) {
81  struct Conv {
85  Conv(ConditionsRepository::Data& p) : data(p) {}
87  void operator()(xml_h element) const {
88  std::string key = element.attr<std::string>(_U(key));
89  std::size_t cap = data.capacity();
91  ::sscanf(key.c_str(),"0x%16llX",&e.key);
92  e.name = element.attr<std::string>(_U(name));
93  e.address = element.attr<std::string>(_U(ref));
94  if ( data.size() == cap ) data.reserve(cap+500);
95  data.emplace_back(e);
96  }
97  };
99  xml_h root = doc.root();
100  xml_coll_t(root, _U(ref)).for_each(Conv(data));
101  return 1;
102  }
103 
104 #if defined(DD4HEP_MINIMAL_CONDITIONS)
105  int createText(const std::string& output, const AllConditions&, char)
106 #else
107  int createText(const std::string& output, const AllConditions& all, char sep)
108 #endif
109  {
110  std::ofstream out(output);
111 #if !defined(DD4HEP_MINIMAL_CONDITIONS)
112  std::size_t siz_nam=0, siz_add=0, siz_tot=0;
113  char fmt[64], text[2*PATH_MAX+64];
114  if ( !out.good() ) {
115  dd4hep::except("ConditionsRepository",
116  "++ Failed to open output file:%s [errno:%d %s]",
117  output.c_str(), errno, ::strerror(errno));
118  }
119  else if ( sep ) {
120  std::snprintf(fmt,sizeof(fmt),"%%16llX%c%%s%c%%s%c",sep,sep,sep);
121  }
122  else {
123  for( const auto& i : all ) {
124  dd4hep::Condition::Object* c = i.second.ptr();
125  std::size_t siz_n = c->name.length();
126  std::size_t siz_a = c->address.length();
127  if ( siz_nam < siz_n ) siz_nam = siz_n;
128  if ( siz_add < siz_a ) siz_add = siz_a;
129  if ( siz_tot < (siz_n+siz_a) ) siz_tot = siz_n+siz_a;
130  }
131  siz_tot += 8+2+1;
132  std::snprintf(fmt,sizeof(fmt),"%%16llX %%-%lds %%-%lds",long(siz_nam),long(siz_add));
133  }
134  out << "dd4hep." << char(sep ? sep : '-')
135  << "." << long(siz_nam)
136  << "." << long(siz_add)
137  << "." << long(siz_tot) << std::endl;
138  for( const auto& i : all ) {
139  dd4hep::Condition c = i.second;
140  std::snprintf(text, sizeof(text), fmt, c.key(), c.name(), c.address().c_str());
141  out << text << std::endl;
142  }
143 #endif
144  out.close();
145  return 1;
146  }
147 
149  int readText(const std::string& input, ConditionsRepository::Data& data) {
150  std::size_t idx, siz_nam, siz_add, siz_tot;
151  char sep, c, text[2*PATH_MAX];
153  std::ifstream in(input);
154 
155  in >> c >> c >> c >> c >> c >> c >> c >> sep
156  >> c >> siz_nam
157  >> c >> siz_add
158  >> c >> siz_tot;
159  text[0] = 0;
160  siz_nam = std::min(siz_nam, 1024UL);
161  siz_add = std::min(siz_add, 1024UL);
162  in.getline(text,sizeof(text),'\n');
163  text[sizeof(text)-1] = 0;
164  do {
165  text[0] = 0;
166  in.getline(text,sizeof(text),'\n');
167  if ( in.good() ) {
168  text[sizeof(text)-1] = 0;
169  if ( siz_tot ) {
170  text[8] = 0;
171  // Direct access mode with fixed record size
172  if ( 9+siz_nam < sizeof(text) ) {
173  text[9+siz_nam] = 0;
174  e.name = text+9;
175  }
176  if ( 10+siz_nam+siz_add < (long)sizeof(text) ) {
177  text[10+siz_nam+siz_add] = 0;
178  e.address = text+10+siz_nam;
179  if ( (idx=e.name.find(' ')) != std::string::npos && idx < e.name.length() )
180  e.name[idx] = 0;
181  if ( (idx=e.address.find(' ')) != std::string::npos && idx < e.address.length() )
182  e.address[idx] = 0;
183  }
184  else {
185  dd4hep::except("ConditionsRepository","+++ Invalid record encountered. [Sever error]");
186  }
187  }
188  else {
189  // Variable record size
190  e.name=text+9;
191  if ( (idx=e.name.find(sep)) != std::string::npos && idx < sizeof(text)-10 )
192  text[9+idx] = 0, e.address=text+idx+10, e.name=text+9;
193  if ( (idx=e.address.find(sep)) != std::string::npos && idx < e.address.length() )
194  e.address[idx] = 0;
195  else if ( (idx=e.address.find('\n')) != std::string::npos && idx < e.address.length() )
196  e.address[idx] = 0;
197  }
198  size_t cap = data.capacity();
199  ::sscanf(text,"%16llX",&e.key);
200  if ( data.size() == cap ) data.reserve(cap+500);
201  data.emplace_back(e);
202  }
203  } while(in.good() && !in.eof() );
204  in.close();
205  return 1;
206  }
207 }
208 
210 int ConditionsRepository::save(ConditionsManager manager, const std::string& output) const {
211  AllConditions all;
212  const auto types = manager.iovTypesUsed();
213  for( const IOVType* type : types ) {
214  if ( type ) {
215  ConditionsIOVPool* pool = manager.iovPool(*type);
216  if ( pool ) {
217  for( const auto& cp : pool->elements ) {
218  RangeConditions rc;
219  cp.second->select_all(rc);
220  for( const auto& cond : rc )
221  all[cond.key()] = cond;
222  }
223  }
224  }
225  }
226 
227  if ( output.find(".xml") != std::string::npos ) {
229  return createXML(output, all);
230  }
231  else if ( output.find(".txt") != std::string::npos ) {
233  return createText(output, all, 0);
234  }
235  else if ( output.find(".daf") != std::string::npos ) {
237  return createText(output, all, 0);
238  }
239  else if ( output.find(".csv") != std::string::npos ) {
241  return createText(output, all, ';');
242  }
243  return 0;
244 }
245 
247 int ConditionsRepository::load(const std::string& input, Data& data) const {
248  if ( input.find(".xml") != std::string::npos ) {
249  return readXML(input, data);
250  }
251  else if ( input.find(".txt") != std::string::npos ) {
252  return readText(input, data);
253  }
254  else if ( input.find(".daf") != std::string::npos ) {
255  return readText(input, data);
256  }
257  else if ( input.find(".csv") != std::string::npos ) {
258  return readText(input, data);
259  }
260  return 0;
261 }
dd4hep::xml::DocumentHandler::create
Document create(const char *tag, const char *comment=0) const
Create new XML document by parsing empty xml buffer.
Definition: DocumentHandler.cpp:681
dd4hep::RangeConditions
std::vector< Condition > RangeConditions
Definition: Conditions.h:491
dd4hep::xml::Collection_t
Class to support the access to collections of XmlNodes (or XmlElements)
Definition: XMLElements.h:636
cond
AlignmentCondition::Object * cond
Definition: AlignmentsCalculator.cpp:68
dd4hep::cond::ConditionsRepository::Data
std::vector< Entry > Data
Definition of the entry collection.
Definition: ConditionsRepository.h:56
dd4hep::xml::Element::append
void append(Handle_t handle) const
Append a new element to the existing tree.
Definition: XMLElements.h:839
ConditionsInterna.h
dd4hep::cond::ConditionsRepository::ConditionsRepository
ConditionsRepository()
Default constructor.
Definition: ConditionsRepository.cpp:40
xml_doc_t
dd4hep::xml::Document xml_doc_t
Definition: ConditionsRepository.cpp:34
dd4hep::Condition::key
key_type key() const
Hash identifier.
Definition: Conditions.cpp:171
dd4hep::detail::ConditionObject::address
std::string address
Condition address.
Definition: ConditionsInterna.h:76
dd4hep::cond::ConditionsIOVPool::elements
Elements elements
Container of IOV dependent conditions pools.
Definition: ConditionsIOVPool.h:46
ConditionsRepository.h
dd4hep::xml::Handle_t
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:380
ConditionsManager.h
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
dd4hep::IOVType
Class describing the interval of validty type.
Definition: IOV.h:37
dd4hep::cond::ConditionsManager::iovTypesUsed
const std::vector< const IOVType * > iovTypesUsed() const
Access the used/registered IOV types.
Definition: ConditionsManager.cpp:209
xml_coll_t
dd4hep::xml::Collection_t xml_coll_t
Definition: ConditionsRepository.cpp:35
DocumentHandler.h
dd4hep::cond::ConditionsManager::iovPool
ConditionsIOVPool * iovPool(const IOVType &type) const
Access conditions multi IOV pool by iov type.
Definition: ConditionsManager.cpp:204
dd4hep::Condition
Main condition object handle.
Definition: Conditions.h:51
dd4hep::cond
Namespace for implementation details of the AIDA detector description toolkit.
Definition: ConditionsCleanup.h:23
dd4hep::xml::Collection_t::for_each
void for_each(T oper) const
Loop processor using function object.
Definition: XMLElements.h:667
dd4hep::cond::ConditionsRepository::~ConditionsRepository
virtual ~ConditionsRepository()
Default destructor.
Definition: ConditionsRepository.cpp:44
_U
#define _U(a)
Definition: Tags.h:23
dd4hep::cond::ConditionsRepository::Entry::name
std::string name
Definition: ConditionsRepository.h:48
ConditionsIOVPool.h
dd4hep::xml::DocumentHolder
Class supporting the basic functionality of an XML document including ownership.
Definition: XMLElements.h:741
dd4hep::xml::Document
Class supporting the basic functionality of an XML document.
Definition: XMLElements.h:697
dd4hep::detail::ConditionObject
The data class behind a conditions handle.
Definition: ConditionsInterna.h:68
dd4hep::cond::ConditionsManager
Manager class for condition handles.
Definition: ConditionsManager.h:46
xml_h
dd4hep::xml::Handle_t xml_h
Definition: ConditionsRepository.cpp:32
dd4hep::xml::DocumentHandler::output
virtual int output(Document doc, const std::string &fname) const
Write xml document to output file (stdout if file name empty)
Definition: DocumentHandler.cpp:396
key
unsigned char key
Definition: AlignmentsCalculator.cpp:69
dd4hep::xml::DocumentHandler
Class supporting to read and parse XML documents.
Definition: DocumentHandler.h:39
AllConditions
std::map< dd4hep::Condition::key_type, dd4hep::Condition > AllConditions
Definition: ConditionsRepository.cpp:37
dd4hep::Handle::ptr
T * ptr() const
Access to the held object.
Definition: Handle.h:153
dd4hep::cond::ConditionsRepository::save
int save(ConditionsManager m, const std::string &output) const
Save the repository to file.
Definition: ConditionsRepository.cpp:210
dd4hep::xml::Element
User abstraction class to manipulate XML elements within a document.
Definition: XMLElements.h:769
xml_elt_t
dd4hep::xml::Element xml_elt_t
Definition: ConditionsRepository.cpp:33
dd4hep::cond::ConditionsRepository::Entry::key
Condition::key_type key
Definition: ConditionsRepository.h:49
XMLTags.h
dd4hep::cond::ConditionsRepository::Entry
Definition of a single Entry in the conditions repository.
Definition: ConditionsRepository.h:46
ConditionsTags.h
dd4hep::cond::ConditionsIOVPool
Pool of conditions satisfying one IOV type (epoch, run, fill, etc)
Definition: ConditionsIOVPool.h:38
dd4hep::xml::Handle_t::attr
T attr(const Attribute a) const
Access typed attribute value by the XmlAttr.
Definition: XMLElements.h:454
dd4hep::Condition::address
const std::string & address() const
Access the address string [e.g. database identifier].
Definition: Conditions.cpp:160
Printout.h
dd4hep::cond::ConditionsRepository::Entry::address
std::string address
Definition: ConditionsRepository.h:48
dd4hep::xml::Document::root
Handle_t root() const
Access the ROOT eleemnt of the DOM document.
Definition: XMLElements.cpp:1040
dd4hep::cond::ConditionsRepository::load
int load(const std::string &input, Data &data) const
Load the repository from file and fill user passed data structory.
Definition: ConditionsRepository.cpp:247