Belle II Software  release-08-01-10
State.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <algorithm>
10 #include <iostream>
11 #include <ctype.h>
12 #include <cstring>
13 #include "trg/trg/Utilities.h"
14 #include "trg/trg/State.h"
15 
16 using namespace std;
17 
18 namespace Belle2 {
24  const unsigned
25  TRGState::_su = sizeof(unsigned);
26 
27  const unsigned
28  TRGState::_bsu = 8 * sizeof(unsigned);
29 
30  TRGState::TRGState(unsigned bitSize)
31  : _size(bitSize),
32  _n(0),
33  _state(0)
34  {
35  _n = _size / _bsu;
36  if (_size % _bsu) ++_n;
37  if (_n)
38  _state = (unsigned*) calloc(_n, _su);
39  }
40 
41  TRGState::TRGState(unsigned bitSize, unsigned value)
42  : _size(bitSize),
43  _n(0),
44  _state(0)
45  {
46  _n = _size / _bsu;
47  if (_size % _bsu) ++_n;
48  if (_n)
49  _state = (unsigned*) calloc(_n, _su);
50 
51  for (unsigned i = 0; i < bitSize; i++) {
52  const unsigned wp = i / _bsu;
53  const unsigned bp = i % _bsu;
54  if (value & (1 << i))
55  _state[wp] |= (1 << bp);
56  }
57  }
58 
59  TRGState::TRGState(unsigned bitSize, const bool* const s)
60  : _size(bitSize),
61  _n(0),
62  _state(0)
63  {
64 
65  _n = _size / _bsu;
66  if (_size % _bsu) ++_n;
67  _state = (unsigned*) calloc(_n, _su);
68 
69  for (unsigned i = 0; i < _size; i++) {
70  const unsigned wp = i / _bsu;
71  const unsigned bp = i % _bsu;
72  if (s[i])
73  _state[wp] |= (1 << bp);
74  else
75  _state[wp] &= ~(1 << bp);
76  }
77  }
78 
79  TRGState::TRGState(vector<bool> states)
80  : _size(0),
81  _n(0),
82  _state(0)
83  {
84 
85  _size = states.size();
86  _n = _size / _bsu;
87  if (_size % _bsu) ++_n;
88  _state = (unsigned*) calloc(_n, _su);
89 
90  for (unsigned i = 0; i < _size; i++) {
91  const unsigned wp = i / _bsu;
92  const unsigned bp = i % _bsu;
93  if (states[i])
94  _state[wp] |= (1 << bp);
95  else
96  _state[wp] &= ~(1 << bp);
97 
98 // cout << "size,given,states=" << _size << "," << states[i] << ","
99 // << _state[wp] << endl;
100 
101  }
102  }
103 
104  TRGState::TRGState(vector<unsigned>& states, unsigned order)
105  : _size(0),
106  _n(0),
107  _state(0)
108  {
109 
110  _size = states.size() * _bsu;
111  _n = _size / _bsu;
112  _state = (unsigned*) calloc(_n, _su);
113 
114  for (unsigned i = 0; i < _n; i++) {
115 
116  if (order == 0) _state[i] = states[i];
117  else _state[_n - 1 - i] = states[i];
118 // cout << "size,given,states=" << _size << "," << states[i] << ","
119 // << _state[wp] << endl;
120 
121  }
122  }
123 
124  TRGState::TRGState(const char* inChar, unsigned inType)
125  : _size(0),
126  _n(0),
127  _state(0)
128  {
129 
130  if (inType == 0) {
131  _size = strlen(inChar);
132  // Check if all values are binary
133  for (unsigned iBit = 0; iBit < _size; iBit++) {
134  if (!(inChar[iBit] == '0' || inChar[iBit] == '1')) {
135 #ifdef TRG_DEBUG
136  cout << "TRGState::TRGState !!! invalid char found : aborted"
137  << endl;
138  cout << " invalid char = [" << inChar[iBit]
139  << "]" << endl;
140 #endif
141  return;
142  }
143  }
144  } else if (inType == 1) {
145  _size = strlen(inChar) * 4;
146  // Check if all values are hex
147  for (unsigned iChar = 0; iChar < _size / 4; iChar++) {
148  if (!isxdigit(inChar[iChar])) {
149 #ifdef TRG_DEBUG
150  cout << "TRGState::TRGState !!! invalid char found : aborted"
151  << endl;
152  cout << " invalid char = ["
153  << inChar[iChar] << "]" << endl;
154 #endif
155  return;
156  }
157  }
158  } else {
159 #ifdef TRG_DEBUG
160  cout << "TRGState::TRGState !!! invalid type : aborted"
161  << endl;
162  cout << " invalid type = " << inType
163  << endl;
164 #endif
165  return;
166  }
167 
168  _n = _size / _bsu;
169  if (_size % _bsu) ++_n;
170  _state = (unsigned*) calloc(_n, _su);
171  if (inType == 0) {
172  for (unsigned iBit = 0; iBit < _size; iBit++) {
173  const unsigned wp = iBit / _bsu;
174  const unsigned bp = iBit % _bsu;
175  if (inChar[_size - 1 - iBit] == '1')
176  _state[wp] |= (1 << bp);
177  else
178  _state[wp] &= ~(1 << bp);
179  }
180  } else if (inType == 1) {
181  for (unsigned iChar = 0; iChar < _size / 4; iChar++) {
182  if (iChar % 8 == 0) _state[iChar / 8] = 0;
183  short unsigned t_int;
184  unsigned charP = _size / 4 - 1 - iChar;
185  if (inChar[charP] > 47 && inChar[charP] < 58) t_int = inChar[charP] - 48;
186  else t_int = inChar[charP] - 97 + 10;
187  _state[iChar / 8] += t_int << ((iChar % 8) * 4);
188  }
189  }
190  }
191 
193  {
194  if (_state)
195  free(_state);
196  }
197 
198  void
199  TRGState::dump(const string& msg,
200  const string& pre) const
201  {
202 
203 // bool bin = true;
204  bool large = (_size > 60) || msg.find("large") != string::npos;
205 
206  if (! large) {
207  cout << pre << "size=" << _size << ",";
208  for (unsigned i = 0; i < _size; i++) {
209  const unsigned j = _size - i - 1;
210  if ((j % 8) == 7)
211  cout << "_";
212  if ((* this)[j])
213  cout << "1";
214  else
215  cout << "0";
216  }
217  cout << dec << endl;
218  } else {
219  cout << pre << "size=" << _size << endl;
220 
221  const unsigned nPerLines = 64;
222  const unsigned lines = _size / nPerLines + 1;
223  const unsigned rem = _size % nPerLines;
224 
225  cout << "TRGState" <<
226  " +56 +48 +40 +32 +24 +16 +8"
227  << " +0" << endl;
228 
229  bool skipLast = false;
230  for (unsigned i = 0; i < lines; i++) {
231  const unsigned n0 = (i == 0) ? rem - 1 : nPerLines - 1;
232  const int n1 = 0;
233  const int os = (lines - i - 1) * nPerLines;
234 
235  const string b = TRGUtilities::itostring(os);
236 
237  TRGState s = subset(n1 + os, n0 - n1 + 1);
238 
239 // s.dump("", "*** ");
240 
241  bool skip = false;
242  if (! s.active())
243  skip = true;
244 
245  if (skip) {
246  if (!skipLast) {
247  cout << "... (all zero)" << endl;
248  }
249 
250  skipLast = true;
251  continue;
252  }
253 
254  skipLast = false;
255 
256  cout.width(5);
257  cout << b;
258  cout << " ";
259 
260  if (i == 0) {
261  unsigned n = nPerLines - rem + (nPerLines - rem) / 8;
262  if (rem % 8) ++n;
263  for (unsigned j = 0; j < n; j++)
264  cout << " ";
265  }
266 
267  for (int j = n0; j >= n1; --j) {
268  const unsigned v = (* this)[j + os];
269 
270  if ((j % 8) == 7)
271  cout << "_";
272  if (v)
273  cout << "1";
274  else
275  cout << "0";
276  }
277  cout << endl;
278  }
279  }
280 
281  // else {
282  // cout << pre << "size=" << _size << ",0x";
283  // bool first = true;
284  // for (unsigned i = 0; i < _n; i++) {
285  // const unsigned j = _n - i - 1;
286  // if (((j % 4) == 3) && (! first))
287  // cout << "_";
288  // cout << hex << _state[j];
289  // first = false;
290  // }
291  // cout << dec << endl;
292 
293  // cout << pre << "size=" << _size << ",0x";
294  // bool first = true;
295  // for (unsigned i = 0; i < _n; i++) {
296  // const unsigned j = _n - i - 1;
297  // if (! first)
298  // cout << "_";
299  // cout << hex << _state[j];
300  // cout << "(";
301  // for (unsigned k = 0; k < 4; k++) {
302  // unsigned c = ((_state[j] >> (4 - k + 1) * 8) & 0xff);
303  // if (c < 0x10)
304  // cout << ".";
305  // cout << c;
306  // }
307  // cout << ")";
308  // first = false;
309  // }
310  // cout << dec << endl;
311  // }
312  }
313 
314  TRGState&
316  {
317 
318  //...Check final size...
319  const unsigned sizeNew = _size + a.size();
320  const unsigned sizeMax = _n * _bsu;
321  const unsigned oldSize = _size;
322 
323  //...Necessary to extend...
324  if (sizeNew > sizeMax) {
325  unsigned nNew = sizeNew / _bsu;
326  if (sizeNew % _bsu) ++nNew;
327  unsigned* tmp = (unsigned*) calloc(nNew, _su);
328  for (unsigned i = 0; i < _n; i++) {
329  tmp[i] = _state[i];
330  }
331  if (_state)
332  free(_state);
333  _state = tmp;
334  _n = nNew;
335  }
336  _size = sizeNew;
337 
338  for (unsigned i = 0; i < a.size(); i++) {
339  unsigned j = i + oldSize;
340  const unsigned wp = j / _bsu;
341  const unsigned bp = j % _bsu;
342  if (a[i])
343  _state[wp] |= (1 << bp);
344  else
345  _state[wp] &= ~(1 << bp);
346 
347 // cout << "size,given,states=" << _size << "," << states[i] << ","
348 // << _state[wp] << endl;
349 
350  }
351 
352  return (* this);
353  }
354 
355  TRGState
356  TRGState::subset(unsigned s, unsigned n) const
357  {
358  vector<bool> stack;
359  for (unsigned i = s; i < s + n; i++) {
360  if ((* this)[i])
361  stack.push_back(true);
362  else
363  stack.push_back(false);
364  }
365  return TRGState(stack);
366  }
367 
369  {
370  if (_state)
371  free(_state);
372 
373  _size = a._size;
374  _n = a._n;
375  _state = (unsigned*) calloc(_n, _su);
376  for (unsigned i = 0; i < _n; i++) {
377  _state[i] = a._state[i];
378  }
379 
380  return * this;
381  }
382 
383  bool
384  TRGState::operator<(const TRGState& a) const
385  {
386  const unsigned long long n0(* this);
387  const unsigned long long n1(a);
388  if (n0 < n1)
389  return true;
390  return false;
391  }
392 
394 } // namespace Belle2
395 
396 namespace std {
397 
398  ostream&
399  operator<<(ostream& out, const Belle2::TRGState& s)
400  {
401  for (unsigned i = 0; i < s.size(); i++) {
402  const unsigned j = s.size() - i - 1;
403  if (s.active(j))
404  out << "1";
405  else
406  out << "0";
407  }
408  return out;
409  }
410 
411 }
A class to represent a state of multi bits.
Definition: State.h:24
unsigned _size
bit size.
Definition: State.h:136
unsigned _n
bit storage size.
Definition: State.h:139
unsigned * _state
bit state.
Definition: State.h:142
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
virtual ~TRGState()
Destructor.
Definition: State.cc:192
TRGState(unsigned bitSize=0)
Default constructor.
Definition: State.cc:30
TRGState subset(unsigned i, unsigned n) const
returns subset from i with n bits.
Definition: State.cc:356
static const unsigned _bsu
bit size of unsigned.
Definition: State.h:133
bool operator<(const TRGState &) const
Copy operator.
Definition: State.cc:384
static const unsigned _su
size of unsigned.
Definition: State.h:130
static std::string itostring(int i)
converts int to string. (Use boost::lexical_cast)
Definition: Utilities.cc:50
TRGState & operator+=(const TRGState &)
appends TRGState (as MSB).
Definition: State.cc:315
TRGState & operator=(const TRGState &)
Copy operator.
Definition: State.cc:368
void dump(const std::string &message="", const std::string &pre="") const
dumps contents.
Definition: State.cc:199
Abstract base class for different kinds of events.