ATLAS Offline Software
Loading...
Searching...
No Matches
Arrayrep.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5// $Id: Arrayrep.cxx,v 1.3 2009-04-08 21:12:44 ssnyder Exp $
12
13
14#include "CxxUtils/Arrayrep.h"
16#include <stdexcept>
17#include <cassert>
18#include <sstream>
19
20
21namespace CaloRec {
22
23
34void Arrayrep::init_sizes (bool resize_data /*= false*/)
35{
36 // Don't do anything if we've already done this, or if the array
37 // is empty.
38 if (m_sizes.size() < m_shape.size())
39 {
40 // Calculate the m_sizes array.
41 unsigned int sz = 1;
42 unsigned int dim = m_shape.size();
43 m_sizes.resize (dim);
44 m_sizes[0] = 1;
45 for (unsigned int i=0; i < dim; i++) {
46 m_sizes[i] = sz;
47 sz *= m_shape[dim-1 - i];
48 }
49
50 if (resize_data) {
51 // Resize m_data to the proper size.
52 m_data.resize (sz);
53 }
54 else {
55 // Check that m_data has the correct size.
56 assert (sz == m_data.size());
57 }
58 }
59}
60
61
69Arrayrep::Arrayrep (const std::vector<unsigned int>& shape)
70 : m_shape (shape)
71{
72 // Set up m_sizes.
73 init_sizes (true);
74}
75
76
86Arrayrep::Arrayrep (const unsigned int shape[], unsigned int n)
87{
88 // Copy the data into m_shape.
89 m_shape.reserve (n);
90 for (unsigned int i=0; i < n; i++)
91 m_shape.push_back (shape[i]);
92
93 // Set up m_sizes.
94 init_sizes (true);
95}
96
97
98namespace {
99
100
108void error (const std::string& context,
109 const std::string& msg)
110{
111 throw std::runtime_error (msg + ": " + context);
112}
113
114
127void read_array (Arrayrep& rep,
128 ArrayScanner& s,
129 unsigned int nest,
130 const std::string& context)
131{
132 // The first time we handle a subarray at a given nesting, we don't
133 // know the size for that dimension, so we should just take what
134 // we're given. After that, though, we should be sure that the
135 // size matches what was used before (a rectangular array).
136 bool know_size = false;
137 if (rep.m_shape.size() > nest) {
138 // We know what the size should be.
139 know_size = true;
140 }
141 else {
142 // We don't know the size yet. Go ahead and push a dummy
143 // entry in m_shape; we'll update it later.
144 rep.m_shape.push_back (0);
145 }
146
147 // Number of array elements (each of which could be a subarray)
148 // which we're read.
149 unsigned int n = 0;
150
151 // Are we now looking at plain elements or at a nested subarray?
152 if (s.at_open()) {
153 // A nested subarray.
154 // Disallow constructions like
155 // [[1], [[2]]]
156 // Maximum nesting must be the same in all subarrays.
157 if (rep.m_data.size() > 0 && nest >= rep.m_shape.size())
158 error (context, "Bad array nesting");
159
160 // Read the subarrays as long as we keep seeing more.
161 do {
162 read_array (rep, s, nest+1, context);
163 ++n;
164 } while (s.at_open());
165 }
166 else {
167 // Plain elements. Read them as long as we keep seeing them.
168 Arrayelt elt;
169 while (s.at_num (elt)) {
170 rep.m_data.push_back (elt);
171 ++n;
172 }
173 }
174
175 // We should now be at a closing bracket.
176 if (!s.at_close())
177 error (context, "Missing close bracket");
178
179 if (!know_size) {
180 // We didn't yet know the size for this dimension. Fill it in now.
181 rep.m_shape[nest] = n;
182 }
183 else if (rep.m_shape[nest] != n) {
184 // What we got doesn't match the size for this dimension we've
185 // seen earlier. Complain.
186 error (context, "Array not rectangular");
187 }
188}
189
190
191} // anonymous namespace
192
193
202Arrayrep::Arrayrep (const std::string& str, const std::string& context /*=""*/)
203{
204 // Special cases for True and False.
205 if (str == "True")
206 m_data.push_back (1);
207 else if (str == "False")
208 m_data.push_back (0);
209 else {
210 // Make the token stream from which we're reading.
211 std::istringstream is (str);
212 ArrayScanner s (is);
213
214 // If we're looking at an open bracket, consume it, and proceed
215 // to read an array.
216 if (s.at_open())
217 read_array (*this, s, 0, context);
218 else {
219 // Otherwise, we're reading a scalar. So read a single number.
220 Arrayelt elt;
221 if (!s.at_num (elt))
222 error (context, "Number expected");
223 m_data.push_back (elt);
224 }
225
226 // We should now be at the end of the stream.
227 if (!s.at_end())
228 error (context, "End of vector before end of string");
229 }
230
231 // Set up the m_sizes vector.
232 init_sizes();
233}
234
235
244
245void Arrayrep::write_array(std::ostream& stream) const {
246 if (!m_data.size()) {//Empty array
247 stream << "[ ]" << std::endl;
248 return;
249 }
250
251 if (!m_shape.size()) {//Single element
252 stream << m_data[0] << std::endl;
253 return;
254 }
255
256 //All other cases: Array of dimension>=1
257 //check consistency of Array
258 unsigned totSize=m_shape[0];
259 for (unsigned i=1;i<m_shape.size();i++)
260 totSize=totSize*m_shape[i];
261 if (totSize!=m_data.size())
262 error("","Array is inconsistent!");
263
264 std::vector<Arrayelt>::size_type dataIndex=0;
265 write_subarray(stream,dataIndex,0);
266 stream << "]" << std::endl;
267 return;
268}
269
270
278
279void Arrayrep::write_subarray(std::ostream& stream, std::vector<Arrayelt>::size_type& idx, unsigned dimIndex) const {
280 if (dimIndex<(m_shape.size()-1)) {
281 stream << "[\n ";
282 for (unsigned i=0;i<m_shape[dimIndex];i++) {
283 write_subarray(stream,idx,dimIndex+1);
284 if (i==m_shape[dimIndex]-1)
285 stream << "]\n ";
286 else
287 stream << "],\n ";
288 }
289 }
290 else { // last dimension
291 stream << "[" << m_data[idx++];
292 for (unsigned i=1;i<m_shape[dimIndex];i++)
293 stream << ", " << m_data[idx++];
294 }
295 return;
296}
297
298
299
300} // namespace CxxUtils
Helper class for converting strings to Array's.
Representation class for Array's.
static Double_t sz
Helper class for converting strings to Array's.
Namespace for helper functions.
float Arrayelt
The type of an element of an Array.
void write_array(std::ostream &stream) const
Creates a text representation of the array content.
Definition Arrayrep.cxx:245
void write_subarray(std::ostream &stream, std::vector< Arrayelt >::size_type &idx, unsigned dimIndex) const
Helper function for write_array.
Definition Arrayrep.cxx:279
std::vector< Arrayelt > m_data
The array data, stored using the C array ordering.
void init_sizes(bool resize_data=false)
Initialize the m_sizes vector from the m_shape vector.
Definition Arrayrep.cxx:34
std::vector< unsigned int > m_sizes
Subarray sizes, for faster access.
std::vector< unsigned int > m_shape
The array shape.
MsgStream & msg
Definition testRead.cxx:32