Belle II Software development
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
15using namespace std;
16
17namespace Belle2 {
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
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
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 TRGSignal & set(double t0, double t1)
makes a pulse with leading edge at t0 and with trailing edge at t1.
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
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.
STL namespace.