13 #define TRG_SHORT_NAMES
14 #define TRGCDC_SHORT_NAMES
17 #include "trg/trg/Utilities.h"
18 #include "trg/trg/Debug.h"
19 #include "trg/cdc/Wire.h"
20 #include "trg/cdc/WireHit.h"
21 #include "trg/cdc/Segment.h"
22 #include "trg/cdc/SegmentHit.h"
23 #include "trg/cdc/LUT.h"
25 #include <framework/datastore/StoreArray.h>
26 #include <cdc/dataobjects/CDCHit.h>
27 #include <trg/cdc/dataobjects/CDCTriggerSegmentHit.h>
28 #include <mdst/dataobjects/MCParticle.h>
32 #define P3D HepGeom::Point3D<double>
40 TRGCDCSegment::TRGCDCSegment(
unsigned id,
44 const std::string& TSLUTFile,
45 const std::vector<const TCWire*>& cells)
50 w.backwardPosition()),
53 _signal(std::string(
"TS_") + TRGUtil::itostring(id), clock),
55 m_TSLUTFileName(TSLUTFile)
72 const string& pre)
const
75 if ((msg.find(
"geometry") != string::npos) ||
76 (msg.find(
"detail") != string::npos)) {
77 cout << pre <<
"id " <<
id();
84 if ((msg.find(
"hit") != string::npos) ||
85 (msg.find(
"detail") != string::npos)) {
86 cout << pre <<
"Wires ";
87 for (
unsigned i = 0; i <
_wires.size(); i++) {
94 if (
_hits.size() == 0) {
95 cout << pre <<
"no wire hit" << endl;
97 cout << pre <<
"WHit dump : ";
98 for (
unsigned i = 0; i <
_hits.size(); i++) {
99 cout <<
_hits[i]->cell().name();
100 if (i <
_hits.size() - 1)
105 for (
unsigned i = 0; i <
_hits.size(); i++) {
106 _hits[i]->dump(msg, pre +
" ");
110 cout << pre <<
"SHit dump" << endl;
113 cout << pre <<
"no TSHit" << endl;
122 if ((msg.find(
"trigger") != string::npos) ||
123 (msg.find(
"detail") != string::npos)) {
127 cout << pre <<
"no trigger signal" << endl;
148 string n0 = string(
"TS") + TRGUtil::itostring(
layerId());
149 string n1 = TRGUtil::itostring(
localId());
154 TCSegment::simulate(
bool clockSimulation,
bool logicLUTFlag,
155 const string& cdcCollectionName,
const string& tsCollectionName)
159 for (
unsigned i = 0, n = _wires.size(); i < n; i++) {
160 if (_wires[i]->signal().active())
168 if (clockSimulation) {
169 simulateWithClock(cdcCollectionName, tsCollectionName);
171 simulateWithoutClock(logicLUTFlag);
176 TCSegment::simulateWithoutClock(
bool logicLUTFlag)
181 const unsigned n = _wires.size();
183 vector<TRGSignal> signals;
184 for (
unsigned i = 0; i < n; i++) {
187 const TCWHit* h = _wires[i]->hit();
192 const TRGSignal& s = _wires[i]->signal();
193 signals.push_back(s);
196 const unsigned width = signals.back().clock().unit(1000);
197 signals.back().widen(width);
203 if (logicLUTFlag == 0) {
213 TRGSignal l0, l1, l2, l3, l4;
214 TRGSignal wo1, wo2, wo3, wo4;
219 l0 = signals[0] | signals[1] | signals[2];
220 l1 = signals[3] | signals[4];
222 l3 = signals[6] | signals[7];
223 l4 = signals[8] | signals[9] | signals[10];
233 all = l2 & (wo1 | wo2 | wo3 | wo4);
235 }
else if (n == 15) {
239 l1 = signals[1] | signals[2];
240 l2 = signals[3] | signals[4] | signals[5];
241 l3 = signals[6] | signals[7] | signals[8] | signals[9];
242 l4 = signals[10] | signals[11] | signals[12] | signals[13] | signals[14];
247 all = l0 & (wo1 | wo2 | wo3 | wo4);
263 if (logicLUTFlag == 1) {
266 vector<TRGSignal> hitSignals;
267 for (
unsigned iWire = 0; iWire < signals.size(); iWire++) {
268 if (signals[iWire].active()) hitSignals.push_back(signals[iWire]);
271 TRGSignal allSignals;
272 if (hitSignals.size() != 0) {
273 allSignals = hitSignals[0];
274 for (
unsigned iHitWire = 1; iHitWire < hitSignals.size(); iHitWire++) {
275 allSignals = allSignals & hitSignals[iHitWire];
279 int lutValue = LUT()->getValue(lutPattern());
280 if ((lutValue != 0) && (priority().signal().active() != 0)) {
281 allSignals.name(name());
282 _signal = allSignals;
291 TCSegment::simulateWithClock(
string cdcCollectionName,
string tsCollectionName)
294 if (m_TSLUT->getValue(lutPattern()) == 0)
return;
298 StoreArray<CDCHit> cdcHits(cdcCollectionName);
299 StoreArray<CDCTriggerSegmentHit> segmentHits(tsCollectionName);
302 const TRGClock& wireClock = _wires[0]->signal().clock();
305 for (
unsigned i = 0, n = _wires.size(); i < n; ++i) {
306 const TRGSignal& s = _wires[i]->signal();
308 int clk0 = s[0]->time();
309 int clk1 = s[s.nEdges() - 2]->time();
310 if (clk0 < clkMin) clkMin = clk0;
311 if (clk1 > clkMax) clkMax = clk1;
316 const int step = wireClock.frequency() / signal().clock().frequency();
317 const int width = 16 * step;
318 clkMin -= clkMin % step;
319 clkMax -= clkMax % step;
320 int lastLutValue = 0;
321 int lastPriority = 0;
323 for (
int iclk = clkMin; iclk <= clkMax; iclk += step) {
325 unsigned pattern = lutPattern(iclk - width, iclk + step);
326 int lutValue = m_TSLUT->getValue(pattern);
328 int priorityPos = priorityPosition(iclk - width, iclk + step);
329 int fastest = fastestTime(iclk - width);
332 if ((lastLutValue == 3 && lutValue != 3) ||
333 (lastPriority != 3 && priorityPos == 3) ||
334 fastest != lastFastest) {
336 TRGTime rise = TRGTime(wireClock.absoluteTime(iclk),
true, _signal.clock());
338 fall.shift(1).reverse();
339 _signal |= TRGSignal(rise & fall);
341 int ipr = (priorityPos == 3) ? 0 : priorityPos;
342 const TRGCDCWire* priorityWire = (_wires.size() == 15) ? _wires[ipr] : _wires[ipr + 5];
344 int tdc = priorityWire->signal()[0]->time();
345 if (tdc < iclk - width) {
346 for (
unsigned itdc = 2, edges = priorityWire->signal().nEdges(); itdc < edges; itdc += 2) {
347 tdc = priorityWire->signal()[itdc]->time();
348 if (tdc >= iclk - width)
break;
352 const CDCHit* priorityHit = cdcHits[priorityWire->hit()->iCDCHit()];
353 const CDCTriggerSegmentHit* storeHit =
354 segmentHits.appendNew(*priorityHit,
361 addStoreHit(storeHit);
363 for (
unsigned iw = 0; iw < _wires.size(); ++iw) {
364 if (_wires[iw]->signal().active(iclk - width, iclk + step)) {
366 double weight = (_wires[iw] == priorityWire) ? 2. : 1.;
367 storeHit->addRelationTo(cdcHits[_wires[iw]->hit()->iCDCHit()], weight);
371 RelationVector<MCParticle> mcrel = priorityHit->getRelationsFrom<MCParticle>();
372 for (
unsigned imc = 0; imc < mcrel.size(); ++imc) {
376 lastLutValue = lutValue;
377 lastPriority = priorityPos;
378 lastFastest = fastest;
387 TCSegment::fastestTime()
const
389 if ((LUT()->getValue(lutPattern()))) {
390 float tmpFastTime = 9999;
391 for (
unsigned i = 0; i < _wires.size(); i++) {
392 if (_wires[i]->signal().active()) {
393 float dt = _wires[i]->signal()[0]->time();
394 if (dt < tmpFastTime) {
405 TCSegment::fastestTime(
int clk0)
const
408 for (
unsigned iw = 0; iw < _wires.size(); ++iw) {
409 if (_wires[iw]->signal().active()) {
410 for (
unsigned itdc = 0, edges = _wires[iw]->signal().nEdges(); itdc < edges; itdc += 2) {
411 float dt = _wires[iw]->signal()[itdc]->time();
413 if (dt < fastest) fastest = dt;
423 TCSegment::foundTime()
const
425 if ((LUT()->getValue(lutPattern()))) {
426 float tmpFoundTime[5] = {9999, 9999, 9999, 9999, 9999};
427 for (
unsigned i = 0; i < _wires.size(); i++) {
428 if (!_wires[i]->signal().active())
continue;
429 float dt = _wires[i]->signal()[0]->time();
430 if (_wires.size() == 11) {
432 if (tmpFoundTime[0] > dt) tmpFoundTime[0] = dt;
434 if (tmpFoundTime[1] > dt) tmpFoundTime[1] = dt;
436 if (tmpFoundTime[2] > dt) tmpFoundTime[2] = dt;
438 if (tmpFoundTime[3] > dt) tmpFoundTime[3] = dt;
440 if (tmpFoundTime[4] > dt) tmpFoundTime[4] = dt;
444 if (tmpFoundTime[0] > dt) tmpFoundTime[0] = dt;
446 if (tmpFoundTime[1] > dt) tmpFoundTime[1] = dt;
448 if (tmpFoundTime[2] > dt) tmpFoundTime[2] = dt;
450 if (tmpFoundTime[3] > dt) tmpFoundTime[3] = dt;
452 if (tmpFoundTime[4] > dt) tmpFoundTime[4] = dt;
456 sort(tmpFoundTime, tmpFoundTime + 5);
457 return tmpFoundTime[3];
463 TCSegment::priorityTime()
const
465 const TRGSignal& prioritySignal = priority().signal();
466 if (prioritySignal.active()) {
467 return prioritySignal[0]->time();
473 TCSegment::priorityPosition()
const
475 if (center().signal().active()) {
478 const TRGCDCWire* priorityL;
479 const TRGCDCWire* priorityR;
480 if (_wires.size() == 15) {
481 priorityL = _wires[2];
482 priorityR = _wires[1];
484 priorityL = _wires[7];
485 priorityR = _wires[6];
487 if (priorityL->signal().active()) {
488 if (priorityR->signal().active()) {
489 if ((priorityL->signal()[0]->time()) >= (priorityR->signal()[0]->time()))
return 1;
492 }
else if (priorityR->signal().active()) {
499 TCSegment::priorityPosition(
int clk0,
int clk1)
const
501 if (center().signal().active(clk0, clk1)) {
504 const TRGCDCWire* priorityL;
505 const TRGCDCWire* priorityR;
506 if (_wires.size() == 15) {
507 priorityL = _wires[2];
508 priorityR = _wires[1];
510 priorityL = _wires[7];
511 priorityR = _wires[6];
513 if (priorityL->signal().active(clk0, clk1)) {
514 if (priorityR->signal().active(clk0, clk1)) {
515 if ((priorityL->signal()[0]->time()) >= (priorityR->signal()[0]->time()))
return 1;
518 }
else if (priorityR->signal().active(clk0, clk1)) {
525 TCSegment::priority()
const
527 int priority = priorityPosition();
528 int offset = (_wires.size() == 15) ? 0 : 5;
529 if (priority == 1 || priority == 2)
530 return *_wires[offset + priority];
531 return *_wires[offset];
538 for (
unsigned i = 0; i <
_wires.size(); i++) {
550 for (
unsigned i = 0; i <
_wires.size(); i++) {
552 if (s.active(clk0, clk1))
571 unsigned outValue = (
hitPattern(clk0, clk1)) * 2;
581 const unsigned n =
_wires.size();
582 for (
unsigned i = 0; i < n; i++) {
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).
std::vector< const TRGCDCWire * > _wires
LookUp Table.
std::vector< const CDCTriggerSegmentHit * > _storeHits
list of DataStore hits.
TRGSignal _signal
Trigger signal.
int priorityPosition(void) const
return priority cell position in TSHit. 0: no hit, 3: 1st priority, 1: 2nd right, 2: 2nd left
std::vector< const TRGCDCWireHit * > _hits
Wire hits.
std::string m_TSLUTFileName
TS LUT file name.
TRGCDCLUT * m_TSLUT
LookUp Table. 0: no hit, 1: right, 2: left, 3: not determined.
A class to represent a digitized signal. Unit is nano second.
A class to represent a digitized signal. Unit is nano second.
virtual bool hasMember(const std::string &a) const override
returns true this has member named a.
unsigned id(void) const
returns id.
virtual ~TRGCDCSegment()
Destructor.
unsigned layerId(void) const
returns layer id.
unsigned localLayerId(void) const
returns local layer id in a super layer.
unsigned hitPattern(void) const
returns hit pattern.
static void enterStage(const std::string &stageName)
Declare that you enter new stage.
unsigned superLayerId(void) const
returns super layer id.
static TRGCDCLUT * getLUT(const std::string &filename, int)
get LUT from dictionary, load new LUT if it doesn't exist
void initialize(void)
initilize variables.
std::string name(void) const override
returns name.
unsigned lutPattern(void) const
hit pattern containing bit for priority position
void dump(const std::string &message=std::string(""), const std::string &prefix=std::string("")) const override
dumps debug information.
void clear(void) override
clears information.
bool active(void) const
returns true if there is a signal.
static void leaveStage(const std::string &stageName)
Declare that you leave a stage.
void clear(void)
clears contents.
const TRGCDCSegmentHit * hit(void) const
returns a pointer to a TRGCDCSegmentHit.
bool axial(void) const
returns true if this wire is in an axial layer.
unsigned localId(void) const
returns local id in a layer.
void dump(const std::string &message="", const std::string &pre="") const
dumps contents.
Abstract base class for different kinds of events.