Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
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;
}