Belle II Software  release-05-01-25
Segment.cc
1 //-----------------------------------------------------------------------------
2 // $Id$
3 //-----------------------------------------------------------------------------
4 // Filename : Segment.cc
5 // Section : TRG CDC
6 // Owner : Yoshihito Iwasaki
7 // Email : yoshihito.iwasaki@kek.jp
8 //-----------------------------------------------------------------------------
9 // Description : A class to represent a wire in CDC.
10 //-----------------------------------------------------------------------------
11 // $Log$
12 //-----------------------------------------------------------------------------
13 
14 #define TRG_SHORT_NAMES
15 #define TRGCDC_SHORT_NAMES
16 
17 #include <iostream>
18 #include "trg/trg/Utilities.h"
19 #include "trg/trg/Debug.h"
20 #include "trg/cdc/Wire.h"
21 #include "trg/cdc/WireHit.h"
22 #include "trg/cdc/Segment.h"
23 #include "trg/cdc/SegmentHit.h"
24 #include "trg/cdc/LUT.h"
25 
26 #include <framework/datastore/StoreArray.h>
27 #include <cdc/dataobjects/CDCHit.h>
28 #include <trg/cdc/dataobjects/CDCTriggerSegmentHit.h>
29 #include <mdst/dataobjects/MCParticle.h>
30 
31 using namespace std;
32 
33 #define P3D HepGeom::Point3D<double>
34 
35 namespace Belle2 {
41  TRGCDCSegment::TRGCDCSegment(unsigned id,
42  const TCLayer& layer,
43  const TCWire& w,
44  const TRGClock& clock,
45  const std::string& TSLUTFile,
46  const std::vector<const TCWire*>& cells)
47  : TCCell(id,
48  layer.size(),
49  layer,
50  w.forwardPosition(),
51  w.backwardPosition()),
52  _wires(cells),
53  _center(), // 2019/07/31 by ytlai
54  _signal(std::string("TS_") + TRGUtil::itostring(id), clock),
55  _storeHits{},
56  m_TSLUTFileName(TSLUTFile)
57  {
58  }
59 
60 
62  {
63  }
64 
65  void
67  {
69  }
70 
71  void
72  TRGCDCSegment::dump(const string& msg,
73  const string& pre) const
74  {
75  cout << pre << name() << " (ptn=" << hitPattern() << ")" << endl;
76  if ((msg.find("geometry") != string::npos) ||
77  (msg.find("detail") != string::npos)) {
78  cout << pre << "id " << id();
79  cout << ",local " << localId();
80  cout << ",layer " << layerId();
81  cout << ",super layer " << superLayerId();
82  cout << ",local layer " << localLayerId();
83  cout << endl;
84  }
85  if ((msg.find("hit") != string::npos) ||
86  (msg.find("detail") != string::npos)) {
87  cout << pre << "Wires ";
88  for (unsigned i = 0; i < _wires.size(); i++) {
89  cout << _wires[i]->name();
90  if (i < _wires.size() - 1)
91  cout << ",";
92  else
93  cout << endl;
94  }
95  if (_hits.size() == 0) {
96  cout << pre << "no wire hit" << endl;
97  } else {
98  cout << pre << "WHit dump : ";
99  for (unsigned i = 0; i < _hits.size(); i++) {
100  cout << _hits[i]->cell().name();
101  if (i < _hits.size() - 1)
102  cout << ",";
103  else
104  cout << endl;
105  }
106  for (unsigned i = 0; i < _hits.size(); i++) {
107  _hits[i]->dump(msg, pre + " ");
108  }
109  }
110  if (hit()) {
111  cout << pre << "SHit dump" << endl;
112  hit()->dump(msg, pre + " ");
113  } else {
114  cout << pre << "no TSHit" << endl;
115  }
116  }
117 // if (msg.find("neighbor") != string::npos ||
118 // msg.find("detail") != string::npos) {
119 // for (unsigned i = 0; i < 7; i++)
120 // if (neighbor(i))
121 // neighbor(i)->dump("", pre + TRGCDC::itostring(i) + " ");
122 // }
123  if ((msg.find("trigger") != string::npos) ||
124  (msg.find("detail") != string::npos)) {
125  if (_signal.active())
126  _signal.dump(msg, pre + " ");
127  else
128  cout << pre << "no trigger signal" << endl;
129  }
130  }
131 
132  void
134  {
135  TCCell::clear();
136  _signal.clear();
137  _hits.clear();
138  _storeHits.clear();
139  }
140 
141  string
143  {
144  string t;
145  if (axial())
146  t = "-";
147  else
148  t = "=";
149  string n0 = string("TS") + TRGUtil::itostring(layerId());
150  string n1 = TRGUtil::itostring(localId());
151  return n0 + t + n1;
152  }
153 
154  void
155  TCSegment::simulate(bool clockSimulation, bool logicLUTFlag,
156  string cdcCollectionName, string tsCollectionName)
157  {
158  //...Get wire informtion for speed-up...
159  unsigned nHits = 0;
160  for (unsigned i = 0, n = _wires.size(); i < n; i++) {
161  if (_wires[i]->signal().active())
162  ++nHits;
163  }
164 
165  //..No wire hit case...
166  if (nHits == 0)
167  return;
168 
169  if (clockSimulation) {
170  simulateWithClock(cdcCollectionName, tsCollectionName);
171  } else {
172  simulateWithoutClock(logicLUTFlag);
173  }
174  }
175 
176  void
177  TCSegment::simulateWithoutClock(bool logicLUTFlag)
178  {
179  TRGDebug::enterStage("TS sim");
180 
181  //...Get wire informtion...
182  const unsigned n = _wires.size();
183  unsigned nHits = 0;
184  vector<TRGSignal> signals;
185  for (unsigned i = 0; i < n; i++) {
186 
187  //...Store wire hit information...
188  const TCWHit* h = _wires[i]->hit();
189  if (h)
190  _hits.push_back(h);
191 
192  //...Copy signal from a wire...
193  const TRGSignal& s = _wires[i]->signal();
194  signals.push_back(s);
195 
196  //...Widen it...
197  const unsigned width = signals.back().clock().unit(1000);
198  signals.back().widen(width);
199 
200  if (s.active())
201  ++nHits;
202  }
203 
204  if (logicLUTFlag == 0) {
206  //...Check number of hit wires...
207  //cout<<"TSF: nHits is "<<nHits<<endl;
208  if (nHits < 4) {
209  TRGDebug::leaveStage("TS sim");
210  return;
211  }
212 
213  //...Signal simulation...
214  TRGSignal l0, l1, l2, l3, l4;
215  TRGSignal wo1, wo2, wo3, wo4;
216  TRGSignal all;
217  if (n == 11) {
218 
219  //...Simple simulation assuming 3:2:1:2:3 shape...
220  l0 = signals[0] | signals[1] | signals[2];
221  l1 = signals[3] | signals[4];
222  l2 = signals[5];
223  l3 = signals[6] | signals[7];
224  l4 = signals[8] | signals[9] | signals[10];
225  //l0.dump();
226  //l1.dump();
227  //l2.dump();
228  //l3.dump();
229  //l4.dump();
230  wo1 = l1 & l3 & l4;
231  wo2 = l0 & l3 & l4;
232  wo3 = l0 & l1 & l4;
233  wo4 = l0 & l1 & l3;
234  all = l2 & (wo1 | wo2 | wo3 | wo4);
235 
236  } else if (n == 15) {
237 
238  //...Simple simulation assuming 1:2:3:4:5 shape...
239  l0 = signals[0];
240  l1 = signals[1] | signals[2];
241  l2 = signals[3] | signals[4] | signals[5];
242  l3 = signals[6] | signals[7] | signals[8] | signals[9];
243  l4 = signals[10] | signals[11] | signals[12] | signals[13] | signals[14];
244  wo1 = l2 & l3 & l4;
245  wo2 = l1 & l3 & l4;
246  wo3 = l1 & l2 & l4;
247  wo4 = l1 & l2 & l3;
248  all = l0 & (wo1 | wo2 | wo3 | wo4);
249  }
250 
251  //...Coincidence of all layers...
252 // TRGSignal all = l0 & l1 & l2 & l3 & l4;
253 
254  if (all.nEdges()) {
255  //cout<<"TSF is found"<<endl;
256  all.name(name());
257  _signal = all;
258  //cout<<all.name()<<":#signals="<<all.nSignals()<<endl;;
259  //all.dump();
260  }
262  }
263 
264  if (logicLUTFlag == 1) {
266  //... Find hit wires ...
267  vector<TRGSignal> hitSignals;
268  for (unsigned iWire = 0; iWire < signals.size(); iWire++) {
269  if (signals[iWire].active()) hitSignals.push_back(signals[iWire]);
270  }
271  //... Coincidence all hit wires ...
272  TRGSignal allSignals;
273  if (hitSignals.size() != 0) {
274  allSignals = hitSignals[0];
275  for (unsigned iHitWire = 1; iHitWire < hitSignals.size(); iHitWire++) {
276  allSignals = allSignals & hitSignals[iHitWire];
277  }
278  }
279 
280  int lutValue = LUT()->getValue(lutPattern());
281  if ((lutValue != 0) && (priority().signal().active() != 0)) {
282  allSignals.name(name());
283  _signal = allSignals;
284  }
286  }
287 
288  TRGDebug::leaveStage("TS sim");
289  }
290 
291  void
292  TCSegment::simulateWithClock(string cdcCollectionName, string tsCollectionName)
293  {
294  // check LUT pattern without clock -> if there is no hit, skip clock simulation
295  if (m_TSLUT->getValue(lutPattern()) == 0) return;
296 
297  TRGDebug::enterStage("TS sim with clock");
298 
299  StoreArray<CDCHit> cdcHits(cdcCollectionName);
300  StoreArray<CDCTriggerSegmentHit> segmentHits(tsCollectionName);
301 
302  // get data clock of first and last hit
303  const TRGClock& wireClock = _wires[0]->signal().clock();
304  int clkMin = 1000;
305  int clkMax = -1000;
306  for (unsigned i = 0, n = _wires.size(); i < n; ++i) {
307  const TRGSignal& s = _wires[i]->signal();
308  if (s.active()) {
309  int clk0 = s[0]->time();
310  int clk1 = s[s.nEdges() - 2]->time();
311  if (clk0 < clkMin) clkMin = clk0;
312  if (clk1 > clkMax) clkMax = clk1;
313  }
314  }
315  // loop over data clock cycles
316  //const int step = wireClock.frequency() / TRGCDC::getTRGCDC()->dataClock().frequency();
317  const int step = wireClock.frequency() / signal().clock().frequency();
318  const int width = 16 * step;
319  clkMin -= clkMin % step;
320  clkMax -= clkMax % step;
321  int lastLutValue = 0;
322  int lastPriority = 0;
323  int lastFastest = 0;
324  for (int iclk = clkMin; iclk <= clkMax; iclk += step) {
325  // check pattern in the last width clock cycles
326  unsigned pattern = lutPattern(iclk - width, iclk + step);
327  int lutValue = m_TSLUT->getValue(pattern);
328  if (lutValue) {
329  int priorityPos = priorityPosition(iclk - width, iclk + step);
330  int fastest = fastestTime(iclk - width);
331  // make a new hit if L/R changes to known, if priority changes to first
332  // or if the fastest hit changes
333  if ((lastLutValue == 3 && lutValue != 3) ||
334  (lastPriority != 3 && priorityPos == 3) ||
335  fastest != lastFastest) {
336  // add new edge to signal
337  TRGTime rise = TRGTime(wireClock.absoluteTime(iclk), true, _signal.clock());
338  TRGTime fall = rise;
339  fall.shift(1).reverse();
340  _signal |= TRGSignal(rise & fall);
341  // get priority wire from position flag
342  int ipr = (priorityPos == 3) ? 0 : priorityPos;
343  const TRGCDCWire* priorityWire = (_wires.size() == 15) ? _wires[ipr] : _wires[ipr + 5];
344  // get priority time (first hit on priority wire in time window)
345  int tdc = priorityWire->signal()[0]->time();
346  if (tdc < iclk - width) {
347  for (unsigned itdc = 2, edges = priorityWire->signal().nEdges(); itdc < edges; itdc += 2) {
348  tdc = priorityWire->signal()[itdc]->time();
349  if (tdc >= iclk - width) break;
350  }
351  }
352  // create hit
353  const CDCHit* priorityHit = cdcHits[priorityWire->hit()->iCDCHit()];
354  const CDCTriggerSegmentHit* storeHit =
355  segmentHits.appendNew(*priorityHit,
356  id(),
357  priorityPos,
358  lutValue,
359  tdc,
360  fastest,
361  iclk + step);
362  addStoreHit(storeHit);
363  // relation to all CDCHits in segment
364  for (unsigned iw = 0; iw < _wires.size(); ++iw) {
365  if (_wires[iw]->signal().active(iclk - width, iclk + step)) {
366  // priority wire has relation weight 2
367  double weight = (_wires[iw] == priorityWire) ? 2. : 1.;
368  storeHit->addRelationTo(cdcHits[_wires[iw]->hit()->iCDCHit()], weight);
369  }
370  }
371  // relation to MCParticles (same as priority hit)
372  RelationVector<MCParticle> mcrel = priorityHit->getRelationsFrom<MCParticle>();
373  for (unsigned imc = 0; imc < mcrel.size(); ++imc) {
374  mcrel[imc]->addRelationTo(storeHit, mcrel.weight(imc));
375  }
376  // store values of this hit to compare with the next hit
377  lastLutValue = lutValue;
378  lastPriority = priorityPos;
379  lastFastest = fastest;
380  }
381  }
382  }
383 
384  TRGDebug::leaveStage("TS sim with clock");
385  }
386 
387  float
388  TCSegment::fastestTime() const
389  {
390  if ((LUT()->getValue(lutPattern()))) {
391  float tmpFastTime = 9999;
392  for (unsigned i = 0; i < _wires.size(); i++) {
393  if (_wires[i]->signal().active()) {
394  float dt = _wires[i]->signal()[0]->time();
395  if (dt < tmpFastTime) {
396  tmpFastTime = dt;
397  }
398  }
399  }
400  return tmpFastTime;
401  } else
402  return -1;
403  }
404 
405  float
406  TCSegment::fastestTime(int clk0) const
407  {
408  int fastest = 9999;
409  for (unsigned iw = 0; iw < _wires.size(); ++iw) {
410  if (_wires[iw]->signal().active()) {
411  for (unsigned itdc = 0, edges = _wires[iw]->signal().nEdges(); itdc < edges; itdc += 2) {
412  float dt = _wires[iw]->signal()[itdc]->time();
413  if (dt >= clk0) {
414  if (dt < fastest) fastest = dt;
415  break;
416  }
417  }
418  }
419  }
420  return fastest;
421  }
422 
423  float
424  TCSegment::foundTime() const
425  {
426  if ((LUT()->getValue(lutPattern()))) {
427  float tmpFoundTime[5] = {9999, 9999, 9999, 9999, 9999};
428  for (unsigned i = 0; i < _wires.size(); i++) {
429  if (!_wires[i]->signal().active()) continue;
430  float dt = _wires[i]->signal()[0]->time();
431  if (_wires.size() == 11) {
432  if (i < 3) {
433  if (tmpFoundTime[0] > dt) tmpFoundTime[0] = dt;
434  } else if (i < 5) {
435  if (tmpFoundTime[1] > dt) tmpFoundTime[1] = dt;
436  } else if (i == 5) {
437  if (tmpFoundTime[2] > dt) tmpFoundTime[2] = dt;
438  } else if (i < 8) {
439  if (tmpFoundTime[3] > dt) tmpFoundTime[3] = dt;
440  } else {
441  if (tmpFoundTime[4] > dt) tmpFoundTime[4] = dt;
442  }
443  } else {
444  if (i == 0) {
445  if (tmpFoundTime[0] > dt) tmpFoundTime[0] = dt;
446  } else if (i < 3) {
447  if (tmpFoundTime[1] > dt) tmpFoundTime[1] = dt;
448  } else if (i < 6) {
449  if (tmpFoundTime[2] > dt) tmpFoundTime[2] = dt;
450  } else if (i < 10) {
451  if (tmpFoundTime[3] > dt) tmpFoundTime[3] = dt;
452  } else {
453  if (tmpFoundTime[4] > dt) tmpFoundTime[4] = dt;
454  }
455  }
456  }
457  sort(tmpFoundTime, tmpFoundTime + 5);
458  return tmpFoundTime[3];
459  } else
460  return -1;
461  }
462 
463  float
464  TCSegment::priorityTime() const
465  {
466  const TRGSignal& prioritySignal = priority().signal();
467  if (prioritySignal.active()) {
468  return prioritySignal[0]->time();
469  }
470  return -1;
471  }
472 
473  int
474  TCSegment::priorityPosition() const
475  {
476  if (center().signal().active()) {
477  return 3;
478  } else {
479  const TRGCDCWire* priorityL;
480  const TRGCDCWire* priorityR;
481  if (_wires.size() == 15) {
482  priorityL = _wires[2];
483  priorityR = _wires[1];
484  } else {
485  priorityL = _wires[7];
486  priorityR = _wires[6];
487  }
488  if (priorityL->signal().active()) {
489  if (priorityR->signal().active()) {
490  if ((priorityL->signal()[0]->time()) >= (priorityR->signal()[0]->time())) return 1;
491  else return 2;
492  } else return 2;
493  } else if (priorityR->signal().active()) {
494  return 1;
495  } else return 0;
496  }
497  }
498 
499  int
500  TCSegment::priorityPosition(int clk0, int clk1) const
501  {
502  if (center().signal().active(clk0, clk1)) {
503  return 3;
504  } else {
505  const TRGCDCWire* priorityL;
506  const TRGCDCWire* priorityR;
507  if (_wires.size() == 15) {
508  priorityL = _wires[2];
509  priorityR = _wires[1];
510  } else {
511  priorityL = _wires[7];
512  priorityR = _wires[6];
513  }
514  if (priorityL->signal().active(clk0, clk1)) {
515  if (priorityR->signal().active(clk0, clk1)) {
516  if ((priorityL->signal()[0]->time()) >= (priorityR->signal()[0]->time())) return 1;
517  else return 2;
518  } else return 2;
519  } else if (priorityR->signal().active(clk0, clk1)) {
520  return 1;
521  } else return 0;
522  }
523  }
524 
525  const TRGCDCWire&
526  TCSegment::priority() const
527  {
528  int priority = priorityPosition();
529  int offset = (_wires.size() == 15) ? 0 : 5;
530  if (priority == 1 || priority == 2)
531  return *_wires[offset + priority];
532  return *_wires[offset];
533  }
534 
535  unsigned
537  {
538  unsigned ptn = 0;
539  for (unsigned i = 0; i < _wires.size(); i++) {
540  const TRGSignal& s = _wires[i]->signal();
541  if (s.active())
542  ptn |= (1 << i);
543  }
544  return ptn;
545  }
546 
547  unsigned
548  TRGCDCSegment::hitPattern(int clk0, int clk1) const
549  {
550  unsigned ptn = 0;
551  for (unsigned i = 0; i < _wires.size(); i++) {
552  const TRGSignal& s = _wires[i]->signal();
553  if (s.active(clk0, clk1))
554  ptn |= (1 << i);
555  }
556  return ptn;
557  }
558 
559  unsigned
561  {
562  unsigned outValue = (hitPattern()) * 2;
563  if (priorityPosition() == 2) {
564  outValue += 1;
565  }
566  return outValue;
567  }
568 
569  unsigned
570  TRGCDCSegment::lutPattern(int clk0, int clk1) const
571  {
572  unsigned outValue = (hitPattern(clk0, clk1)) * 2;
573  if (priorityPosition(clk0, clk1) == 2) {
574  outValue += 1;
575  }
576  return outValue;
577  }
578 
579  bool
580  TRGCDCSegment::hasMember(const std::string& a) const
581  {
582  const unsigned n = _wires.size();
583  for (unsigned i = 0; i < n; i++) {
584  if (_wires[i]->hasMember(a))
585  return true;
586  }
587  return false;
588  }
589 
591 } // namespace Belle2
Belle2::TRGCDCCell::localId
unsigned localId(void) const
returns local id in a layer.
Definition: Cell.h:205
Belle2::TRGSignal
A class to represent a digitized signal. Unit is nano second.
Definition: Signal.h:28
Belle2::TRGCDCSegment::clear
void clear(void) override
clears information.
Definition: Segment.cc:133
Belle2::TRGCDCSegment::_wires
std::vector< const TRGCDCWire * > _wires
LookUp Table.
Definition: Segment.h:166
Belle2::TRGCDCSegment::hitPattern
unsigned hitPattern(void) const
returns hit pattern.
Definition: Segment.cc:536
Belle2::RelationsInterface::addRelationTo
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
Definition: RelationsObject.h:144
Belle2::TRGCDCSegment::name
std::string name(void) const override
returns name.
Definition: Segment.cc:142
Belle2::TRGCDCSegment::_signal
TRGSignal _signal
Trigger signal.
Definition: Segment.h:172
Belle2::TRGCDCCell::localLayerId
unsigned localLayerId(void) const
returns local layer id in a super layer.
Definition: Cell.h:226
Belle2::TRGSignal::active
bool active(void) const
returns true if there is a signal.
Definition: Signal.h:279
Belle2::TRGSignal::dump
void dump(const std::string &message="", const std::string &pre="") const
dumps contents.
Definition: Signal.cc:144
Belle2::TRGCDCSegment::hit
const TRGCDCSegmentHit * hit(void) const
returns a pointer to a TRGCDCSegmentHit.
Definition: Segment.h:222
Belle2::TRGCDCSegment::dump
void dump(const std::string &message=std::string(""), const std::string &prefix=std::string("")) const override
dumps debug information.
Definition: Segment.cc:72
Belle2::TRGCDCSegment::m_TSLUT
TRGCDCLUT * m_TSLUT
LookUp Table. 0: no hit, 1: right, 2: left, 3: not determined.
Definition: Segment.h:160
Belle2::TRGCDCSegment::hasMember
virtual bool hasMember(const std::string &a) const override
returns true this has member named a.
Definition: Segment.cc:580
Belle2::TRGCDCSegment::~TRGCDCSegment
virtual ~TRGCDCSegment()
Destructor.
Definition: Segment.cc:61
Belle2::TRGCDCCell::axial
bool axial(void) const
returns true if this wire is in an axial layer.
Definition: Cell.h:254
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TRGCDCSegment::m_TSLUTFileName
std::string m_TSLUTFileName
TS LUT file name.
Definition: Segment.h:181
Belle2::TRGCDCCell::superLayerId
unsigned superLayerId(void) const
returns super layer id.
Definition: Cell.h:219
Belle2::TRGCDCSegment::priorityPosition
int priorityPosition(void) const
return priority cell position in TSHit. 0: no hit, 3: 1st priority, 1: 2nd right, 2: 2nd left
Belle2::TRGCDCCell::id
unsigned id(void) const
returns id.
Definition: Cell.h:198
Belle2::TRGSignal::clear
void clear(void)
clears contents.
Definition: Signal.h:267
Belle2::TRGCDCCell::layerId
unsigned layerId(void) const
returns layer id.
Definition: Cell.h:212
Belle2::TRGCDCLUT::getLUT
static TRGCDCLUT * getLUT(const std::string &filename, int)
get LUT from dictionary, load new LUT if it doesn't exist
Definition: LUT.cc:84
Belle2::TRGDebug::leaveStage
static void leaveStage(const std::string &stageName)
Declare that you leave a stage.
Definition: Debug.cc:39
Belle2::TRGDebug::enterStage
static void enterStage(const std::string &stageName)
Declare that you enter new stage.
Definition: Debug.cc:29
Belle2::TRGCDCSegment::lutPattern
unsigned lutPattern(void) const
hit pattern containing bit for priority position
Definition: Segment.cc:560
Belle2::TRGCDCSegment::_storeHits
std::vector< const CDCTriggerSegmentHit * > _storeHits
list of DataStore hits.
Definition: Segment.h:178
Belle2::TRGClock
A class to represent a digitized signal. Unit is nano second.
Definition: Clock.h:43
Belle2::TRGCDCSegment::_hits
std::vector< const TRGCDCWireHit * > _hits
Wire hits.
Definition: Segment.h:175
Belle2::TRGCDCSegment::initialize
void initialize(void)
initilize variables.
Definition: Segment.cc:66