DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ConditionsRepository.cpp
Go to the documentation of this file.
1 // $Id$
2 //==========================================================================
3 // AIDA Detector description implementation for LCD
4 //--------------------------------------------------------------------------
5 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
6 // All rights reserved.
7 //
8 // For the licensing terms see $DD4hepINSTALL/LICENSE.
9 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
10 //
11 // Author : M.Frank
12 //
13 //==========================================================================
14 
15 // Framework include files
18 #include "DDCond/ConditionsTags.h"
19 #include "DD4hep/Printout.h"
20 #include "XML/DocumentHandler.h"
21 #include "XML/XMLTags.h"
22 
23 // C/C++ include files
24 #include <fstream>
25 #include <climits>
26 #include <cerrno>
27 #include <map>
28 
29 using namespace std;
30 using namespace DD4hep;
31 using namespace DD4hep::Conditions;
36 
37 typedef map<Condition::key_type,Condition> AllConditions;
38 
40 ConditionsRepository::ConditionsRepository() {
41 }
42 
44 ConditionsRepository::~ConditionsRepository() {
45 }
46 
47 namespace {
48 
49  int createXML(const string& output, const AllConditions& all) {
50  const char comment[] = "\n"
51  " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
52  " ++++ Linear collider detector description LCDD 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(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i) {
62  char text[32];
63  Condition c = (*i).second;
64  ::snprintf(text,sizeof(text),"0x%08X",c.key());
65  root.append(cond = xml_elt_t(doc, _U(ref)));
66  cond.setAttr(_U(key), text);
67  cond.setAttr(_U(name), c.name());
68  cond.setAttr(_U(ref), c.address());
69  }
70  printout(ALWAYS,"ConditionsRepository","++ Handled %ld conditions.",all.size());
71  if ( !output.empty() ) {
72  return docH.output(doc, output);
73  }
74  return 1;
75  }
76 
78  int readXML(const string& input, ConditionsRepository::Data& data) {
79  struct Conv {
83  Conv(ConditionsRepository::Data& p) : data(p) {}
85  void operator()(xml_h element) const {
86  string key = element.attr<string>(_U(key));
87  size_t cap = data.capacity();
89  ::sscanf(key.c_str(),"0x%08X",&e.key);
90  e.name = element.attr<string>(_U(name));
91  e.address = element.attr<string>(_U(ref));
92  if ( data.size() == cap ) data.reserve(cap+500);
93  data.push_back(e);
94  }
95  };
97  xml_h root = doc.root();
98  xml_coll_t(root, _U(ref)).for_each(Conv(data));
99  return 1;
100  }
101 
102  int createText(const string& output, const AllConditions& all, char sep) {
103  size_t siz_nam=0, siz_add=0, siz_tot=0;
104  char fmt[64], text[2*PATH_MAX+64];
105  ofstream out(output);
106  if ( !out.good() ) {
107  except("ConditionsRepository",
108  "++ Failed to open output file:%s [errno:%d %s]",
109  output.c_str(), errno, ::strerror(errno));
110  }
111  else if ( sep ) {
112  ::snprintf(fmt,sizeof(fmt),"%%08X%c%%s%c%%s%c",sep,sep,sep);
113  }
114  else {
115  for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i) {
116  Condition::Object* c = (*i).second.ptr();
117  size_t siz_n = c->name.length();
118  size_t siz_a = c->address.length();
119  if ( siz_nam < siz_n ) siz_nam = siz_n;
120  if ( siz_add < siz_a ) siz_add = siz_a;
121  if ( siz_tot < (siz_n+siz_a) ) siz_tot = siz_n+siz_a;
122  }
123  siz_tot += 8+2+1;
124  ::snprintf(fmt,sizeof(fmt),"%%08X %%-%lds %%-%lds",long(siz_nam),long(siz_add));
125  }
126  out << "dd4hep." << char(sep ? sep : '-')
127  << "." << long(siz_nam)
128  << "." << long(siz_add)
129  << "." << long(siz_tot) << endl;
130  for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i) {
131  Condition c = (*i).second;
132  ::snprintf(text, sizeof(text), fmt, c.key(), c.name(), c.address().c_str());
133  out << text << endl;
134  }
135  out.close();
136  return 1;
137  }
138 
140  int readText(const string& input, ConditionsRepository::Data& data) {
141  size_t idx;
143  long siz_nam, siz_add, siz_tot;
144  char sep, c, text[2*PATH_MAX+64];
145  ifstream in(input);
146  in >> c >> c >> c >> c >> c >> c >> c >> sep
147  >> c >> siz_nam
148  >> c >> siz_add
149  >> c >> siz_tot;
150  text[0] = 0;
151  in.getline(text,sizeof(text),'\n');
152  do {
153  text[0] = 0;
154  in.getline(text,sizeof(text),'\n');
155  if ( in.good() ) {
156  if ( siz_tot ) {
157  // Direct access mode with fixed record size
158  text[8] = text[9+siz_nam] = text[10+siz_nam+siz_add] = 0;
159  e.name = text+9;
160  e.address = text+10+siz_nam;
161  if ( (idx=e.name.find(' ')) != string::npos )
162  e.name[idx] = 0;
163  if ( (idx=e.address.find(' ')) != string::npos )
164  e.address[idx] = 0;
165  }
166  else {
167  // Variable record size
168  e.name=text+9;
169  if ( (idx=e.name.find(sep)) != string::npos )
170  text[9+idx] = 0, e.address=text+idx+10, e.name=text+9;
171  if ( (idx=e.address.find(sep)) != string::npos )
172  e.address[idx] = 0;
173  else if ( (idx=e.address.find('\n')) != string::npos )
174  e.address[idx] = 0;
175  }
176  size_t cap = data.capacity();
177  ::sscanf(text,"%08X",&e.key);
178  if ( data.size() == cap ) data.reserve(cap+500);
179  data.push_back(e);
180  }
181  } while(in.good() && !in.eof() );
182  in.close();
183  return 1;
184  }
185 }
186 
188 int ConditionsRepository::save(ConditionsManager manager, const string& output) const {
189  typedef vector<const IOVType*> _T;
191  typedef RangeConditions _R;
192  AllConditions all;
193  const _T types = manager.iovTypesUsed();
194  for( _T::const_iterator i = types.begin(); i != types.end(); ++i ) {
195  const IOVType* type = *i;
196  if ( type ) {
197  ConditionsIOVPool* pool = manager.iovPool(*type);
198  if ( pool ) {
199  const _E& e = pool->elements;
200  for (_E::const_iterator j=e.begin(); j != e.end(); ++j) {
201  ConditionsPool* cp = (*j).second;
202  _R rc;
203  cp->select_all(rc);
204  for(_R::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic)
205  all[(*ic).key()] = *ic;
206  }
207  }
208  }
209  }
210 
211  if ( output.find(".xml") != string::npos ) {
213  return createXML(output, all);
214  }
215  else if ( output.find(".txt") != string::npos ) {
217  return createText(output, all, 0);
218  }
219  else if ( output.find(".daf") != string::npos ) {
221  return createText(output, all, 0);
222  }
223  else if ( output.find(".csv") != string::npos ) {
225  return createText(output, all, ';');
226  }
227  return 0;
228 }
229 
231 int ConditionsRepository::load(const string& input, Data& data) const {
232  if ( input.find(".xml") != string::npos ) {
233  return readXML(input, data);
234  }
235  else if ( input.find(".txt") != string::npos ) {
236  return readText(input, data);
237  }
238  else if ( input.find(".daf") != string::npos ) {
239  return readText(input, data);
240  }
241  else if ( input.find(".csv") != string::npos ) {
242  return readText(input, data);
243  }
244  return 0;
245 }
Document create(const char *tag, const char *comment=0) const
Create new XML document by parsing empty xml buffer.
virtual int output(Document doc, const std::string &fname) const
Write xml document to output file (stdout if file name empty)
virtual void select_all(RangeConditions &result)=0
Select all conditions contained.
const char * name() const
Access the object name (or "" if not supported by the object)
Definition: Handle.inl:36
T attr(const Attribute a) const
Access typed attribute value by the XmlAttr.
Definition: XMLElements.h:435
XML::Element xml_elt_t
The data class behind a conditions handle.
Class to support the access to collections of XmlNodes (or XmlElements)
Definition: XMLElements.h:556
const std::string & address() const
Access the address string [e.g. database identifier].
Definition: Conditions.cpp:122
Main condition object handle.
Definition: Conditions.h:70
#define _U(a)
Definition: XMLTags.h:27
Elements elements
Container of IOV dependent conditions pools.
#define _E(x)
Definition: XMLElements.cpp:46
void append(Handle_t handle) const
Append a new element to the existing tree.
Definition: XMLElements.h:752
Class supporting the basic functionality of an XML document including ownership.
Definition: XMLElements.h:660
User abstraction class to manipulate XML elements within a document.
Definition: XMLElements.h:686
return e
Definition: Volumes.cpp:297
Handle_t root() const
Access the ROOT eleemnt of the DOM document.
int except(const std::string &src, const std::string &fmt,...)
Calls the display action with ERROR and throws an std::runtime_error exception.
Definition: Printout.cpp:217
T * ptr() const
Access to the held object.
Definition: Handle.h:149
static pair< TClass *, void * > load(TBranch *branch, int entry)
Manager class for condition handles.
std::string name
The object name.
Definition: NamedObject.h:34
std::map< IOV::Key, Element > Elements
Class describing the interval of validty type.
Definition: IOV.h:33
Condition::key_type key
map< Condition::key_type, Condition > AllConditions
std::string address
Class implementing the conditions collection for a given IOV type.
key_type key() const
Hash identifier.
Definition: Conditions.cpp:132
XML::Collection_t xml_coll_t
Pool of conditions satisfying one IOV type (epoch, run, fill, etc)
std::vector< Condition > RangeConditions
Definition: Conditions.h:359
ConditionsIOVPool * iovPool(const IOVType &type) const
Access conditions multi IOV pool by iov type.
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:361
Class supporting the basic functionality of an XML document.
Definition: XMLElements.h:617
void for_each(T oper) const
Loop processor using function object.
Definition: XMLElements.h:587
static const char * _T(const std::string &s)
int printout(PrintLevel severity, const char *src, const char *fmt,...)
Calls the display action with a given severity level.
Definition: Printout.cpp:111
Class supporting to read and parse XML documents.
const std::vector< const IOVType * > iovTypesUsed() const
Access the used/registered IOV types.
std::string name
XML::Document xml_doc_t
XML::Handle_t xml_h