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