ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
DetectorDescription
Identifier
src
DetectorDescription/Identifier/src/Range.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
6
// gcc12 gives false positive warnings from copying boost::small_vector,
7
// as the sort operation in show_all_ids.
8
#if __GNUC__ >= 12
9
# pragma GCC diagnostic ignored "-Wstringop-overread"
10
#endif
11
12
13
#include "
Identifier/Range.h
"
14
15
#include "GaudiKernel/MsgStream.h"
16
#include <algorithm>
17
#include <cstdio>
18
#include <string>
19
#include <vector>
20
#include <sstream>
21
#include <iostream>
22
#include <limits>
23
#include <iomanip>
24
#include <stdexcept>
25
#include <cassert>
26
27
28
29
//--------------------------------------------------------------------------
30
const
Range::field
&
Range::operator []
(
Range::size_type
index
)
const
{
31
if
(
index
>=
m_fields
.size ()){
32
static
const
field
f;
33
return
(f);
34
}
35
return
(
m_fields
[
index
]);
36
}
37
38
//-----------------------------------------------
39
Range::Range
(
const
Range
& other,
size_type
start) {
40
if
(start < other.fields ()) {
41
field_vector::const_iterator it = other.m_fields.begin ();
42
it += start;
43
m_fields
.insert (
m_fields
.end (), it, other.m_fields.end ());
44
}
45
}
46
47
Range::Range
(
const
std::string & text):
Range
(){
48
if
(text.empty())
return
;
49
std::istringstream in(text);
50
in>>*
this
;
51
}
52
53
//-----------------------------------------------
54
Range::Range
(
const
ExpandedIdentifier
& root) {
55
// Construct from a root (i.e. add wild card for below)
56
build
(root);
57
}
58
59
//-----------------------------------------------
60
void
Range::build
(
const
std::string& text) {
61
if
(text.empty())
return
;
62
std::istringstream in(text);
63
in>>*
this
;
64
}
65
66
//-----------------------------------------------
67
void
Range::build
(
const
ExpandedIdentifier
& root) {
68
// Construct from a root
69
m_fields
.clear ();
70
for
(
size_type
i = 0; i < root.fields (); ++i){
71
m_fields
.emplace_back(root[i]);
72
}
73
}
74
75
76
77
//-----------------------------------------------
78
void
Range::add
(
element_type
value) {
79
m_fields
.emplace_back (value);
80
}
81
82
//-----------------------------------------------
83
void
Range::add
(
element_type
minimum
,
element_type
maximum
) {
84
m_fields
.emplace_back (
minimum
,
maximum
);
85
}
86
87
88
90
void
Range::add
(
const
field
& f) {
91
m_fields
.emplace_back(f);
92
}
93
95
void
Range::add
(
field
&& f) {
96
m_fields
.emplace_back(std::move(f));
97
}
98
100
void
Range::add
(
const
Range
& subrange) {
101
for
(
size_t
i = 0; i < subrange.
fields
(); ++i) {
102
const
field
& f = subrange[i];
103
m_fields
.push_back (f);
104
}
105
}
106
107
void
Range::add
(
Range
&& subrange) {
108
if
(
m_fields
.empty())
109
m_fields
.swap (subrange.m_fields);
110
else
{
111
size_t
sz
= subrange.m_fields.size();
112
m_fields
.reserve (
m_fields
.size() +
sz
);
113
for
(
size_t
i = 0; i <
sz
; ++i) {
114
m_fields
.emplace_back (std::move(subrange.m_fields[i]));
115
}
116
}
117
}
118
119
120
121
122
//-----------------------------------------------
123
void
Range::clear
() {
124
m_fields
.clear ();
125
}
126
127
//-----------------------------------------------
128
int
Range::match
(
const
ExpandedIdentifier
&
id
)
const
{
129
130
size_type
my_fields =
m_fields
.size ();
131
const
size_type
id_fields =
id
.fields ();
132
133
// More fields in the range than in the identifier will never match.
134
//if (my_fields > id_fields) return (0);
135
136
// Allow match for id shorter than range - assume "wildcards" for
137
// missing id fields
138
size_type
nfields = (my_fields > id_fields) ? id_fields : my_fields;
139
// Test fields one by one.
140
for
(
size_type
field_number = 0; field_number < nfields; field_number++) {
141
const
field
& f =
m_fields
[field_number];
142
if
(!f.match (
id
[field_number]))
return
(0);
143
}
144
// All conditions match.
145
return
(1);
146
}
147
148
// Accessors
149
150
//-----------------------------------------------
151
ExpandedIdentifier
Range::minimum
()
const
{
152
size_type
my_fields =
m_fields
.size ();
153
ExpandedIdentifier
result;
154
// Copy fields to result
155
for
(
size_type
field_number = 0; field_number < my_fields; field_number++) {
156
const
field
& f =
m_fields
[field_number];
157
// Valued field
158
result << f.get_minimum ();
159
}
160
return
(result);
161
}
162
163
//-----------------------------------------------
164
ExpandedIdentifier
Range::maximum
()
const
{
165
size_type
my_fields =
m_fields
.size ();
166
ExpandedIdentifier
result;
167
// Copy fields to result
168
for
(
size_type
field_number = 0; field_number < my_fields; field_number++) {
169
const
field
& f =
m_fields
[field_number];
170
// Normal field
171
result << f.get_maximum ();
172
}
173
return
(result);
174
}
175
176
Range::size_type
Range::cardinality
()
const
{
177
size_type
result = 1;
178
const
Range
& me = *
this
;
179
for
(
size_type
i = 0; i <
fields
(); ++i) {
180
const
field
& f = me[i];
181
result *= f.get_indices ();
182
}
183
return
(result);
184
}
185
186
190
Range::size_type
Range::cardinalityUpTo
(
const
ExpandedIdentifier
&
id
)
const
{
191
size_type
result = 0;
192
if
(
id
.
fields
() !=
fields
())
return
(result);
193
const
Range
& me = *
this
;
194
// Check if we are above or below this range
195
if
(
id
<
minimum
())
return
0;
196
if
(
maximum
() <
id
)
return
cardinality
();
197
// Collect the indices of a match
198
std::vector<size_type> indices(
id
.
fields
(), 0);
199
bool
is_match =
true
;
200
size_type
level = 0;
201
for
(; level <
id
.fields (); ++level) {
202
const
field
& f = me[level];
203
// Require all fields to be bounded or enumerated
204
if
(f.empty())
return
0;
205
if
(f.isEnumerated()) {
206
// Continue testing for a match
207
size_type
max
= f.get_values().size() - 1;
208
if
(f.get_values()[
max
] <
id
[level]) {
209
// above max
210
is_match =
false
;
211
indices[level] =
max
+ 1;
212
}
else
{
213
for
(
size_type
j = 0; j < f.get_values().
size
(); ++j) {
214
if
(
id
[level] <= f.get_values()[j]) {
215
if
(
id
[level] != f.get_values()[j]) {
216
// between two values or below first one
217
is_match =
false
;
218
}
219
indices[level] = j;
220
break
;
221
}
222
}
223
}
224
}
else
{
225
if
(f.get_maximum() <
id
[level]) {
226
// above max
227
is_match =
false
;
228
indices[level] = f.get_maximum() - f.get_minimum() + 1;
229
}
else
if
(
id
[level] < f.get_minimum()) {
230
// below min
231
is_match =
false
;
232
indices[level] = 0;
233
}
else
{
234
indices[level] =
id
[level] - f.get_minimum();
235
}
236
}
237
if
(!is_match)
break
;
238
}
239
240
// Calculate the cardinality
241
if
(level <
id
.
fields
()) ++level;
242
for
(
size_type
j = 0; j < level; ++j) {
243
size_type
card = indices[j];
244
for
(
size_type
k = j + 1; k <
id
.fields(); ++k) {
245
const
field
& f = me[k];
246
card *= f.get_indices();
247
}
248
result += card;
249
}
250
return
result;
251
}
252
253
260
bool
Range::overlaps_with
(
const
Range
& other)
const
{
261
const
Range
& me = *
this
;
262
if
((
fields
() == 0) || (other.fields () == 0))
return
(
false
);
263
for
(
size_type
i = 0; i < std::min (
fields
(), other.fields ()); ++i){
264
const
field
& f1 = me[i];
265
const
field
& f2 = other[i];
266
if
(!f1.overlaps_with (f2))
return
(
false
);
267
}
268
return
(
true
);
269
}
270
271
272
273
void
274
Range::show
(std::ostream& s)
const
{
275
const
Range
& me = *
this
;
276
s << (std::string) me <<
" ("
;
277
int
allbits = 0;
278
for
(
size_type
i = 0; i <
fields
(); ++i) {
279
const
field
& f = me[i];
280
if
(i > 0) s <<
"+"
;
281
size_type
indices = f.get_indices ();
282
int
bits = 1;
283
indices--;
284
if
(indices > 0) {
285
bits = 0;
286
while
(indices > 0){
287
indices /= 2;
288
bits++;
289
}
290
}
291
allbits += bits;
292
s << bits;
293
}
294
s <<
"="
<< allbits <<
") "
;
295
}
296
297
void
298
Range::show
(MsgStream & out)
const
{
299
std::ostringstream os;
300
show
(os);
301
out << os.str();
302
}
303
304
//-----------------------------------------------
305
Range::operator std::string ()
const
{
306
std::string result;
307
size_type
my_fields =
m_fields
.size ();
308
if
(my_fields == 0)
return
(result);
309
// print fields one by one.
310
for
(
size_type
field_number = 0; field_number < my_fields; field_number++) {
311
const
field
& f =
m_fields
[field_number];
312
if
(field_number > 0) result +=
"/"
;
313
result += (std::string) f;
314
}
315
return
(result);
316
}
317
318
//-----------------------------------------------
319
bool
320
Range::operator ==
(
const
Range
& other)
const
{
321
if
(
m_fields
.size() != other.m_fields.size())
return
false
;
322
field_vector::const_iterator it1 =
m_fields
.begin();
323
field_vector::const_iterator it2 = other.m_fields.begin();
324
field_vector::const_iterator last =
m_fields
.end();
325
for
(; it1 != last; ++it1, ++it2) {
326
if
((*it1) != (*it2))
return
false
;
327
}
328
return
(
true
);
329
}
330
331
332
333
334
335
336
std::ostream &
337
operator <<
(std::ostream &out,
const
Range
&
r
){
338
out<<std::string(
r
);
339
return
out;
340
}
341
342
std::istream &
343
operator >>
(std::istream &in,
Range
&
r
){
344
r
.clear ();
345
for
(
int
c{}; c!=EOF;c=in.peek()){
346
Range::field
field;
347
in>>field;
348
r
.add(field);
349
if
(
int
c = in.peek();(c ==
'/'
) or (c ==
' '
)){
350
in.ignore();
351
}
352
}
353
return
in;
354
}
Range.h
operator<<
std::ostream & operator<<(std::ostream &out, const Range &r)
Definition
DetectorDescription/Identifier/src/Range.cxx:337
operator>>
std::istream & operator>>(std::istream &in, Range &r)
Definition
DetectorDescription/Identifier/src/Range.cxx:343
sz
static Double_t sz
Definition
LArPhysWaveHECTool.cxx:37
size
size_t size() const
Number of registered mappings.
max
#define max(a, b)
Definition
cfImp.cxx:41
ExpandedIdentifier
Definition
DetectorDescription/Identifier/Identifier/ExpandedIdentifier.h:105
Range
A Range describes the possible ranges for the field values of an ExpandedIdentifier.
Definition
DetectorDescription/Identifier/Identifier/Range.h:31
Range::maximum
ExpandedIdentifier maximum() const
Definition
DetectorDescription/Identifier/src/Range.cxx:164
Range::match
int match(const ExpandedIdentifier &id) const
Match an identifier.
Definition
DetectorDescription/Identifier/src/Range.cxx:128
Range::Range
Range()=default
Range::minimum
ExpandedIdentifier minimum() const
min and max ExpandedIdentifiers (if they exist, ie.
Definition
DetectorDescription/Identifier/src/Range.cxx:151
Range::show
void show(std::ostream &s) const
Definition
DetectorDescription/Identifier/src/Range.cxx:274
Range::operator==
bool operator==(const Range &other) const
Definition
DetectorDescription/Identifier/src/Range.cxx:320
Range::m_fields
field_vector m_fields
Definition
DetectorDescription/Identifier/Identifier/Range.h:144
Range::add
void add(element_type value)
Add a required value. (ie. low = high = value).
Definition
DetectorDescription/Identifier/src/Range.cxx:78
Range::element_type
ExpandedIdentifier::element_type element_type
Definition
DetectorDescription/Identifier/Identifier/Range.h:34
Range::cardinalityUpTo
size_type cardinalityUpTo(const ExpandedIdentifier &id) const
Get the cardinality from the beginning up to the given ExpandedIdentifier.
Definition
DetectorDescription/Identifier/src/Range.cxx:190
Range::size_type
ExpandedIdentifier::size_type size_type
Definition
DetectorDescription/Identifier/Identifier/Range.h:35
Range::field
IdentifierField field
Definition
DetectorDescription/Identifier/Identifier/Range.h:36
Range::build
void build(const std::string &text)
Build Range from a textual description.
Definition
DetectorDescription/Identifier/src/Range.cxx:60
Range::fields
size_type fields() const
Definition
DetectorDescription/Identifier/Identifier/Range.h:150
Range::operator[]
const field & operator[](size_type index) const
Access the field elements.
Definition
DetectorDescription/Identifier/src/Range.cxx:30
Range::overlaps_with
bool overlaps_with(const Range &other) const
Check if two Ranges overlap.
Definition
DetectorDescription/Identifier/src/Range.cxx:260
Range::cardinality
size_type cardinality() const
Computes a possible cardinality :
Definition
DetectorDescription/Identifier/src/Range.cxx:176
Range::clear
void clear()
Modifications.
Definition
DetectorDescription/Identifier/src/Range.cxx:123
r
int r
Definition
globals.cxx:22
index
Definition
index.py:1
Generated on
for ATLAS Offline Software by
1.17.0