Belle II Software  release-08-01-10
Signal.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 <cctype>
12 #include "trg/trg/Clock.h"
13 #include "trg/trg/Signal.h"
14 
15 using namespace std;
16 
17 namespace Belle2 {
23  TRGSignal::TRGSignal(const TRGClock& c) :
24  _name("?"),
25  _clock(& c),
26  _history()
27  {
28  }
29 
30  TRGSignal::TRGSignal(const TRGTime& t0, const TRGTime& t1) :
31  _name("?"),
32  _clock(& t0.clock()),
33  _history()
34  {
35 #if TRG_DEBUG
36  if ((& t0.clock()) != (& t1.clock()))
37  cout << "TRGSignal !!! signal is made with two different clocks"
38  << endl
39  << " t0.clock=" << t0.clock().name() << endl
40  << " t1.clock=" << t1.clock().name() << endl;
41 #endif
42 
43  _history.push_back(t0);
44  _history.push_back(t1);
45 
46 #if TRG_DEBUG
48 #endif
49  }
50 
51  TRGSignal::TRGSignal(const TRGClock& c, int t0, int t1) :
52  _name("?"),
53  _clock(& c),
54  _history()
55  {
56  TRGTime time0(t0, true, c);
57  TRGTime time1(t1, false, c);
58  _history.push_back(time0);
59  _history.push_back(time1);
60 
61 #if TRG_DEBUG
63 #endif
64  }
65 
66  TRGSignal::TRGSignal(const TRGClock& c, double t0, double t1) :
67  _name("?"),
68  _clock(& c),
69  _history()
70  {
71  TRGTime time0(t0, true, c);
72  TRGTime time1(t1, false, c);
73  _history.push_back(time0);
74  _history.push_back(time1);
75 
76 #if TRG_DEBUG
78 #endif
79  }
80 
81  TRGSignal::TRGSignal(const string& name, const TRGClock& c) :
82  _name(name),
83  _clock(& c),
84  _history()
85  {
86 #if TRG_DEBUG
88 #endif
89  }
90 
92 // _history(t._history),
93  _name(t._name),
94  _clock(t._clock)
95  {
96  const unsigned n = t._history.size();
97  for (unsigned i = 0; i < n; i++) {
98  _history.push_back(t._history[i]);
99  }
100 #if TRG_DEBUG
102 #endif
103  }
104 
106  _name(t.name()),
107  _clock(& t.clock())
108  {
109 
110  //...Check edge...
111  if (t.edge()) {
112 
113  //...Store itself...
114  _history.push_back(t);
115 
116  //...Set falling edge...
117  _history.push_back(t.clock().maxTRGTime(false));
118  } else {
119 
120  //...Set rising edge...
121  _history.push_back(t.clock().minTRGTime(true));
122 
123  //...Store itself...
124  _history.push_back(t);
125  }
126 #if TRG_DEBUG
128 #endif
129  }
130 
132  {
133 #if TRG_DEBUG
135 #endif
136  }
137 
138  void
139  TRGSignal::dump(const string& msg,
140  const string& pre) const
141  {
142 
143  string tmp;
144  tmp.resize(_name.size());
145  transform(_name.cbegin(), _name.cend(), tmp.begin(), ::toupper);
146 
147  const bool ctr = tmp.find("CLOCKCOUNTER") != string::npos;
148 
149  cout << pre << _name << ":#signal=" << _history.size();
150 
151  if (msg.find("clock") != string::npos ||
152  msg.find("detail") != string::npos) {
153  cout << ":clock=" << _clock->name();
154  }
155 
156  cout << endl;
157 
158  if (_history.size() && (! ctr)) {
159  for (unsigned i = 0; i < _history.size(); i++)
160  _history[i].dump(msg, pre + " ");
161  }
162  }
163 
164  TRGSignal
165  TRGSignal::operator&(const TRGSignal& left) const
166  {
167 
168  //...Collect state changes...
169  vector<int> sc0 = stateChanges();
170  vector<int> sc1 = left.stateChanges();
171  sc0.insert(sc0.end(), sc1.begin(), sc1.end());
172 
173  //...Sorting...
174  std::sort(sc0.begin(), sc0.end());
175 
176  //...Remove multiple same clock...
177  vector<int> sc2;
178  int last = _clock->min();
179  for (unsigned i = 0; i < sc0.size(); i++) {
180  const int j = sc0[i];
181  if (j != last) {
182  sc2.push_back(j);
183  last = j;
184  }
185  }
186 
187  //...Make a new signal...
188  string name = "(" + _name + ")&(" + left._name + ")";
189  TRGSignal t(name, * _clock);
190  bool active = false;
191  for (unsigned i = 0; i < sc2.size(); i++) {
192  const int j = sc2[i];
193  if ((! active) and state(j) and left.state(j)) {
194  active = true;
195  t._history.push_back(TRGTime(j, true, * _clock));
196  } else if (active and ((! state(j)) or (! left.state(j)))) {
197  active = false;
198  t._history.push_back(TRGTime(j, false, * _clock));
199  }
200  }
201 
202 #if TRG_DEBUG
204 #endif
205 
206  return t;
207  }
208 
209  TRGSignal&
211  {
212  TRGSignal t = (* this) & left;
213 
214  _history.clear();
215  _history = t._history;
216 
217 #if TRG_DEBUG
219 #endif
220 
221  return * this;
222  }
223 
224 // vector<TRGTime>
225 // TRGSignal::andOperation(const vector<TRGTime> & history) {
226 
227 // //...And operation...
228 // const unsigned n = history.size();
229 // unsigned riseC = 0;
230 // bool signal = false;
231 // vector<TRGTime> tmp;
232 // for (unsigned i = 0; i < n; i++) {
233 // const bool edge = history[i].edge();
234 
235 // if (edge)
236 // ++riseC;
237 // else
238 // --riseC;
239 
240 // // cout << "riseC,i,e,t=" << riseC << "," << i << "," << edge
241 // // << "," << history[i].time() << endl;
242 
243 // if (riseC == 2) {
244 // tmp.push_back(history[i]);
245 // signal = true;
246 // }
247 // else if (signal && (riseC == 1)) {
248 // tmp.push_back(history[i]);
249 // signal = false;
250 // }
251 // }
252 
253 // return tmp;
254 // }
255 
256  TRGSignal
257  TRGSignal::operator|(const TRGSignal& left) const
258  {
259  TRGSignal t(* this);
260  t._history.insert(t._history.end(),
261  left._history.begin(),
262  left._history.end());
263  t._name = "(" + t._name + ")|(" + left._name + ")";
264  std::sort(t._history.begin(), t._history.end(), TRGTime::sortByTime);
265 
266  //...And operation...
267  t._history = orOperation(t._history);
268 
269  return t;
270  }
271 
272  TRGSignal&
274  {
275  _history.insert(_history.end(),
276  left._history.begin(),
277  left._history.end());
278  this->_name = "(" + this->_name + ")&(" + left._name + ")";
279  std::sort(_history.begin(), _history.end(), TRGTime::sortByTime);
280 
281  //...And operation...
283 
284 #if TRG_DEBUG
286 #endif
287 
288  return * this;
289  }
290 
291  vector<TRGTime>
292  TRGSignal::orOperation(const vector<TRGTime>& history)
293  {
294 
295  //...And operation...
296  const unsigned n = history.size();
297  vector<TRGTime> tmp;
298  unsigned signal = 0;
299  for (unsigned i = 0; i < n; i++) {
300  const bool edge = history[i].edge();
301 
302  if (edge) {
303  if (signal == 0)
304  tmp.push_back(history[i]);
305  ++signal;
306  } else {
307  if (signal == 1)
308  tmp.push_back(history[i]);
309  --signal;
310  }
311 
312 // cout << "i,time,edge,signal=" << i << "," << history[i].time()
313 // << "," << edge << "," << signal << endl;
314 
315  }
316 
317  return tmp;
318  }
319 
320  TRGSignal&
321  TRGSignal::widen(unsigned width)
322  {
323 
324  //...Check rising edges...
325  const unsigned n = _history.size();
326  for (unsigned i = 0; i < n; i++) {
327  const bool edge = _history[i].edge();
328 
329  if (! edge) {
330  const int t0 = _history[i - 1].time();
331  const int t1 = _history[i].time();
332  if ((t1 - t0) < int(width))
333  _history[i].time(t0 + width);
334  }
335  }
336 
337  // Merge overlapping history
338  std::sort(_history.begin(), _history.end(), TRGTime::sortByTime);
340 
341 #if TRG_DEBUG
343 #endif
344 
345  return * this;
346  }
347 
348  std::vector<int>
350  {
351  std::vector<int> list;
352  const unsigned n = _history.size();
353  for (unsigned i = 0; i < n; i++)
354  list.push_back(_history[i].time());
355  return list;
356  }
357 
358  const TRGClock&
360  {
361  _clock = & c;
362 
363  const unsigned n = _history.size();
364  for (unsigned i = 0; i < n; i++)
365  _history[i].clock(c);
366 
367  //...Check pulse width...
368  for (unsigned i = 0; i < n; i++) {
369  const bool edge = _history[i].edge();
370 
371  if (! edge) {
372  const int t0 = _history[i - 1].time();
373  const int t1 = _history[i].time();
374  const unsigned w = t1 - t0;
375  if (w == 0)
376  _history[i].shift(1);
377  }
378  }
379 
380 #if TRG_DEBUG
382 #endif
383 
384  return * _clock;
385  }
386 
387  unsigned
388  TRGSignal::width(unsigned a) const
389  {
390  unsigned j = 0;
391  const unsigned n = _history.size();
392  for (unsigned i = 0; i < n; i++) {
393  const bool edge = _history[i].edge();
394 
395  if (! edge) {
396  const int t0 = _history[i - 1].time();
397  const int t1 = _history[i].time();
398  const unsigned w = t1 - t0;
399  if (j == a) {
400  return w;
401  }
402  ++j;
403  }
404  }
405  return 0;
406  }
407 
408  const TRGSignal&
409  TRGSignal::set(int t0, int t1, bool state)
410  {
411  if (! state)
412  return unset(t0, t1);
413 
414  TRGSignal s(clock(), t0, t1);
415  (* this) |= s;
416 
417 #if TRG_DEBUG
418  if (consistencyCheck())
419  cout << "TRGSignal::set ... t0, t1=" << t0 << "," << t1 << endl;
420 #endif
421 
422  return * this;
423  }
424 
425  const TRGSignal&
426  TRGSignal::unset(int t0, int t1)
427  {
428  if (active(t0, t1)) {
429  TRGSignal x(clock(), t0, t1);
430  x.invert();
431  (* this) &= x;
432  }
433 
434 #if TRG_DEBUG
436 #endif
437 
438  return * this;
439  }
440 
441  void
443  {
444  std::sort(_history.begin(), _history.end(), TRGTime::sortByTime);
445 
446 #if TRG_DEBUG
448 #endif
449  }
450 
451  bool
453  {
454  const unsigned n = _history.size();
455  if (n % 2) {
456  cout << "TRGSignal::consistencyCheck !!! "
457  << "history has odd number entires : n=" << n << endl;
458  dump("detail", "!!! ");
459  }
460 
461  if (n < 2)
462  return true;
463 
464  unsigned err = 0;
465  unsigned errTiming = 0;
466  for (unsigned i = 0; i < n; i++) {
467  if (i % 2)
468  continue;
469 
470  const TRGTime& t0 = _history[i];
471  const TRGTime& t1 = _history[i + 1];
472 
473  if (t0.edge() != true)
474  err |= (1 << i);
475  if (t1.edge() != false)
476  err |= (1 << (i + 1));
477 
478  if ((t0.time() == t1.time()) || (t0.time() > t1.time()))
479  errTiming |= (1 << (i + 1));
480  }
481 
482  if (err || errTiming) {
483  if (err) {
484  cout << "TRGSignal::consistencyCheck !!! err in edge history"
485  << endl;
486  }
487  if (errTiming) {
488  cout << "TRGSignal::consistencyCheck !!! err in time history"
489  << endl;
490  }
491  dump("detail", "!!! ");
492  return true;
493  }
494 
495  return false;
496  }
497 
498  const TRGSignal&
500  {
501  if (_history.size()) {
502  for (unsigned i = 0; i < _history.size(); i++)
503  _history[i].reverse();
504  if (_history[0].time() > _clock->min()) {
505  TRGTime t0(_clock->min(), true, * _clock);
506  _history.insert(_history.begin(), t0);
507  } else {
508  _history.erase(_history.begin());
509  }
510  if (_history.back().time() < _clock->max()) {
511  TRGTime t0(_clock->max(), false, * _clock);
512  _history.push_back(t0);
513  } else {
514  _history.erase(_history.end());
515  }
516  } else {
517  TRGTime time0(_clock->min(), true, * _clock);
518  TRGTime time1(_clock->max(), false, * _clock);
519  _history.push_back(time0);
520  _history.push_back(time1);
521  }
522 
523 #if TRG_DEBUG
525 #endif
526 
527  return * this;
528  }
529 
530  bool
532  {
533  if (_history.size() != a._history.size())
534  return false;
535 
536  for (unsigned i = 0; i < _history.size(); i++) {
537  if (_history[i] != a._history[i])
538  return false;
539  }
540 
541  return true;
542  }
543 
545 } // namespace Belle2
A class to represent a digitized signal. Unit is nano second.
Definition: Clock.h:38
A class to represent a digitized signal. Unit is nano second.
Definition: Signal.h:23
const TRGClock * _clock
Clock.
Definition: Signal.h:178
std::vector< TRGTime > _history
Timing history.
Definition: Signal.h:181
std::string _name
Name.
Definition: Signal.h:175
const TRGSignal & set(double t0, double t1)
makes a pulse with leading edge at t0 and with trailing edge at t1.
A class to represent a signal timing in the trigger system.
Definition: Time.h:25
TRGSignal & operator|=(const TRGSignal &)
returns OR result.
Definition: Signal.cc:273
static std::vector< TRGTime > orOperation(const std::vector< TRGTime > &)
Or operation.
Definition: Signal.cc:292
TRGSignal & operator&=(const TRGSignal &)
returns AND result.
Definition: Signal.cc:210
TRGSignal operator&(const TRGSignal &) const
returns AND result.
Definition: Signal.cc:165
const TRGClock & clock(void) const
returns clock.
Definition: Time.h:149
TRGSignal & widen(unsigned width)
returns widen signals. Signals wider than "width" will be untouched.
Definition: Signal.cc:321
const std::string & name(void) const
returns name.
Definition: Clock.h:157
std::vector< int > stateChanges(void) const
returns a list of clock position of state change.
Definition: Signal.cc:349
int min(void) const
returns min. clock point.
Definition: Clock.h:194
const TRGSignal & unset(int t0, int t1)
clear(or unset) with leading edge at clock t0 and with trailing edge at clock t1.
Definition: Signal.cc:426
unsigned width(unsigned i=0) const
returns width of i'th signal (i=0,1,2,...).
Definition: Signal.cc:388
int max(void) const
returns max. clock point.
Definition: Clock.h:201
TRGSignal(const TRGClock &=Belle2_GDL::GDLSystemClock)
Constructor.
Definition: Signal.cc:23
int time(void) const
returns timing in clock position.
Definition: Time.h:171
bool state(int clockPosition) const
returns true if signal is active in given clock position.
Definition: Signal.h:286
virtual ~TRGSignal()
Destructor.
Definition: Signal.cc:131
bool active(void) const
returns true if there is a signal.
Definition: Signal.h:277
bool edge(void) const
returns edge information.
Definition: Time.h:156
bool operator==(const TRGSignal &) const
returns true if two are the same.
Definition: Signal.cc:531
static bool sortByTime(const TRGTime &a, const TRGTime &b)
returns true if a is older than b.
Definition: Time.cc:107
void sort(void)
Sort operation.
Definition: Signal.cc:442
TRGSignal operator|(const TRGSignal &) const
returns OR result.
Definition: Signal.cc:257
bool consistencyCheck(void) const
Self-consitency check. True is return if something wrong.
Definition: Signal.cc:452
const TRGSignal & invert(void)
makes signal inverted.
Definition: Signal.cc:499
void dump(const std::string &message="", const std::string &pre="") const
dumps contents.
Definition: Signal.cc:139
Abstract base class for different kinds of events.