File indexing completed on 2024-09-07 04:36:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "L1Trigger/DTTraco/interface/DTTracoChip.h"
0023
0024
0025
0026
0027 #include "L1Trigger/DTBti/interface/DTBtiTrigData.h"
0028 #include "L1Trigger/DTTraco/interface/DTTracoCand.h"
0029 #include "L1Trigger/DTTraco/interface/DTTracoCard.h"
0030 #include "L1Trigger/DTTraco/interface/DTTracoTrig.h"
0031 #include "L1Trigger/DTTraco/interface/DTTracoTrigData.h"
0032 #include "L1Trigger/DTTriggerServerTheta/interface/DTTSTheta.h"
0033 #include "L1TriggerConfig/DTTPGConfig/interface/BitArray.h"
0034
0035
0036
0037
0038 #include <algorithm>
0039 #include <cmath>
0040 #include <iostream>
0041 #include <string>
0042
0043
0044
0045
0046
0047 DTTracoChip::DTTracoChip(DTTracoCard *card, int n, DTConfigTraco *conf) : _card(card), _config(conf) {
0048 _geom = _card->geom();
0049
0050
0051 if (config()->debug() == 4) {
0052 std::cout << "DTTracoChip constructor called for TRACO number " << n << std::endl;
0053 }
0054
0055
0056 setTracoAcceptances();
0057
0058
0059 int i = 0;
0060 for (i = 0; i < DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF; i++) {
0061 _innerCand[i].reserve(DTConfigTraco::NBTITC);
0062 _outerCand[i].reserve(3 * DTConfigTraco::NBTITC);
0063 _tracotrig[i].reserve(2);
0064 }
0065
0066
0067 DTChamberId sid = _geom->statId();
0068 _id = DTTracoId(sid, n);
0069
0070
0071 _bxlts.zero();
0072 for (int is = 0; is < DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF + 1; is++) {
0073 _flag[is].zero();
0074 }
0075
0076
0077 if (config()->debug() == 4) {
0078 std::cout << "CMS position:" << CMSPosition() << std::endl;
0079 std::cout << " psiRad=" << psiRad() << " KRad=" << KRad() << std::endl;
0080 }
0081
0082
0083 _krad = config()->KRAD();
0084 _btic = config()->BTIC();
0085
0086
0087
0088 _ibtioff = static_cast<int>(config()->BTIC() / (_geom->cellPitch()) * (_geom->phiSLOffset() / 0.9999));
0089
0090
0091
0092 if (_card->lutFromDBFlag() == 1) {
0093
0094
0095
0096
0097 float xBTI1_3 = _geom->localPosition(DTBtiId(DTSuperLayerId(sid.wheel(), sid.station(), sid.sector(), 3), 1)).x();
0098 float xBTI1_1 = _geom->localPosition(DTBtiId(DTSuperLayerId(sid.wheel(), sid.station(), sid.sector(), 1), 1)).x();
0099 float SL_shift = xBTI1_3 - xBTI1_1;
0100
0101 _lutsCCB = new Lut(_card->config_luts(), n, SL_shift);
0102 _luts = nullptr;
0103 } else
0104
0105
0106 {
0107 _luts = nullptr;
0108 _lutsCCB = nullptr;
0109 }
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 }
0146
0147 DTTracoChip::DTTracoChip(const DTTracoChip &traco)
0148 : _geom(traco._geom), _id(traco._id), _card(traco._card), _luts(traco._luts) {
0149 int i = 0;
0150 for (i = 0; i < DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF; i++) {
0151 _innerCand[i].reserve(DTConfigTraco::NBTITC);
0152 std::vector<DTTracoCand>::const_iterator p;
0153 for (p = traco._innerCand[i].begin(); p < traco._innerCand[i].end(); p++) {
0154 _innerCand[i].push_back(*p);
0155 }
0156 _outerCand[i].reserve(3 * DTConfigTraco::NBTITC);
0157 for (p = traco._outerCand[i].begin(); p < traco._outerCand[i].end(); p++) {
0158 _outerCand[i].push_back(*p);
0159 }
0160 _tracotrig[i].reserve(2);
0161 std::vector<DTTracoTrig *>::const_iterator p1;
0162 for (p1 = traco._tracotrig[i].begin(); p1 < traco._tracotrig[i].end(); p1++) {
0163 _tracotrig[i].push_back(*p1);
0164 }
0165 }
0166 _bxlts = traco._bxlts;
0167 for (int is = 0; is < DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF + 1; is++) {
0168 _flag[is] = traco._flag[is];
0169 }
0170 }
0171
0172
0173
0174
0175 DTTracoChip::~DTTracoChip() {
0176 clear();
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 if (_card->lutFromDBFlag() == 1)
0188 delete _lutsCCB;
0189 }
0190
0191
0192
0193
0194
0195 DTTracoChip &DTTracoChip::operator=(const DTTracoChip &traco) {
0196 if (this != &traco) {
0197 _geom = traco._geom;
0198 _id = traco._id;
0199 _card = traco._card;
0200 int i = 0;
0201 for (i = 0; i < DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF; i++) {
0202 _innerCand[i].reserve(DTConfigTraco::NBTITC);
0203 std::vector<DTTracoCand>::const_iterator p;
0204 for (p = traco._innerCand[i].begin(); p < traco._innerCand[i].end(); p++) {
0205 _innerCand[i].push_back(*p);
0206 }
0207 _outerCand[i].reserve(3 * DTConfigTraco::NBTITC);
0208 for (p = traco._outerCand[i].begin(); p < traco._outerCand[i].end(); p++) {
0209 _outerCand[i].push_back(*p);
0210 }
0211 _tracotrig[i].reserve(2);
0212 std::vector<DTTracoTrig *>::const_iterator p1;
0213 for (p1 = traco._tracotrig[i].begin(); p1 < traco._tracotrig[i].end(); p1++) {
0214 _tracotrig[i].push_back(*p1);
0215 }
0216 }
0217 _bxlts = traco._bxlts;
0218 for (int is = 0; is < DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF + 1; is++) {
0219 _flag[is] = traco._flag[is];
0220 }
0221 }
0222 return *this;
0223 }
0224
0225 void DTTracoChip::clear() {
0226 std::vector<DTTracoTrig *>::iterator p1;
0227 for (int is = 0; is < DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF + 1; is++) {
0228 for (p1 = _tracotrig[is].begin(); p1 < _tracotrig[is].end(); p1++) {
0229 delete (*p1);
0230 }
0231 _tracotrig[is].clear();
0232 _innerCand[is].clear();
0233 _outerCand[is].clear();
0234 _flag[is].zero();
0235 }
0236 _bxlts.zero();
0237 }
0238
0239 void DTTracoChip::run() {
0240
0241 if (config()->debug() > 1) {
0242 std::cout << "DTTracoChip::run: Processing TRACO " << _id.traco() << std::endl;
0243 }
0244
0245
0246 int maxtc = static_cast<int>(ceil(float(geom()->nCell(1)) / float(DTConfigTraco::NBTITC)));
0247
0248 if (_id.traco() < 1 || _id.traco() > maxtc) {
0249 if (config()->debug() == 4)
0250 std::cout << "DTTracoChip::run: wrong TRACO number " << _id.traco() << std::endl;
0251 return;
0252 }
0253
0254
0255 for (int is = DTConfigTraco::NSTEPF; is <= DTConfigTraco::NSTEPL; is++) {
0256 if (config()->debug() > 1) {
0257 std::cout << "\n STEP: " << is << std::endl;
0258 std::cout << " ================" << std::endl;
0259 }
0260
0261
0262 if (_innerCand[is - DTConfigTraco::NSTEPF].empty() && _outerCand[is - DTConfigTraco::NSTEPF].empty())
0263 continue;
0264
0265
0266 if (config()->debug() == 4) {
0267 std::cout << " --> "
0268 << _innerCand[is - DTConfigTraco::NSTEPF].size() + _outerCand[is - DTConfigTraco::NSTEPF].size();
0269 std::cout << " candidates " << std::endl;
0270 }
0271
0272
0273
0274 setFlag(is);
0275
0276
0277 if (config()->LVALIDIFH()) {
0278 for (unsigned int e = 0; e < _innerCand[is - DTConfigTraco::NSTEPF].size(); e++) {
0279 if (_innerCand[is - DTConfigTraco::NSTEPF][e].BtiTrig()->code() == 8) {
0280 _flag[is - DTConfigTraco::NSTEPF].set(9);
0281 break;
0282 }
0283 }
0284 for (unsigned int e = 0; e < _outerCand[is - DTConfigTraco::NSTEPF].size(); e++) {
0285 if (_outerCand[is - DTConfigTraco::NSTEPF][e].BtiTrig()->code() == 8) {
0286 _flag[is - DTConfigTraco::NSTEPF].set(9);
0287 break;
0288 }
0289 }
0290 }
0291
0292
0293
0294
0295 for (int itk = 0; itk < 2; itk++) {
0296
0297 if (config()->debug() == 4)
0298 std::cout << "Inner:" << std::endl;
0299 DTTracoCand *inner = bestCand(itk, _innerCand[is - DTConfigTraco::NSTEPF]);
0300 if (config()->debug() == 4)
0301 std::cout << "Outer:" << std::endl;
0302 DTTracoCand *outer = bestCand(itk, _outerCand[is - DTConfigTraco::NSTEPF]);
0303
0304
0305 if (config()->debug() > 1) {
0306 if (inner || outer)
0307 std::cout << "Best candidates for track " << itk + 1 << " are:" << std::endl;
0308 if (inner) {
0309 std::cout << "inner->";
0310 inner->print();
0311 }
0312 if (outer) {
0313 std::cout << "outer->";
0314 outer->print();
0315 }
0316 }
0317
0318
0319 if (inner == nullptr && outer == nullptr)
0320 break;
0321
0322
0323
0324
0325
0326 if (inner) {
0327 DoAdjBtiLts(inner, _innerCand[is - DTConfigTraco::NSTEPF]);
0328 }
0329 if (outer) {
0330 DoAdjBtiLts(outer, _outerCand[is - DTConfigTraco::NSTEPF]);
0331 }
0332
0333
0334
0335 if (inner)
0336 inner->setUsed();
0337 if (outer)
0338 outer->setUsed();
0339
0340 DTTracoTrig *tct = setPV(itk, inner, outer);
0341
0342
0343 if (!tct)
0344 break;
0345
0346
0347 int stored = 0;
0348 if (inner && outer) {
0349 stored = storeCorr(tct, inner, outer, itk);
0350 }
0351
0352 if (!stored) {
0353
0354
0355 stored = storeUncorr(tct, inner, outer, itk);
0356 }
0357
0358
0359 if (stored) {
0360 addTrig(is, tct);
0361 } else {
0362 delete tct;
0363
0364 }
0365
0366 }
0367
0368
0369 if (config()->debug() == 4)
0370 std::cout << "Checking overlap I-II track..." << std::endl;
0371 if (!_tracotrig[is - DTConfigTraco::NSTEPF].empty() && is > DTConfigTraco::NSTEPF &&
0372 (_tracotrig[is - DTConfigTraco::NSTEPF])[0]->isFirst()) {
0373 if (nTrig(is - 1) > 0) {
0374 if (!(trigger(is - 1, 1)->isFirst()) ||
0375 (nTrig(is - 1) == 2 && !(trigger(is - 1, 2)->isFirst()))) {
0376 raiseOverlap(is);
0377 if (config()->debug() == 4) {
0378 std::cout << "II track at step " << std::hex << is - 1 << std::dec << "marked rej." << std::endl;
0379 std::cout << "I track overlap flag at step " << std::hex << is << std::dec << " setted" << std::endl;
0380 }
0381 }
0382 }
0383 }
0384
0385 for (int isd = 0; isd <= DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF + 1; isd++)
0386 if (config()->debug() == 4) {
0387 std::cout << "overlap flag step = " << isd + DTConfigTraco::NSTEPF << " " << _flag[isd].element(1)
0388 << std::endl;
0389 }
0390
0391 if (config()->debug() > 0) {
0392 if (nTrig(is) > 0) {
0393 for (int cc = 1; cc <= nTrig(is); cc++) {
0394 trigger(is, cc)->print();
0395 }
0396 }
0397 }
0398 }
0399 }
0400
0401 void DTTracoChip::raiseOverlap(int step) {
0402 _flag[step - DTConfigTraco::NSTEPF].set(1);
0403 _flag[step - DTConfigTraco::NSTEPF - 1].set(2);
0404 }
0405
0406 void DTTracoChip::setFlag(int step, int ext) {
0407 if (ext == 0) {
0408
0409 DTTracoChip *prevTraco = _card->getTRACO(_id.traco() - 1);
0410 if (prevTraco != nullptr) {
0411 if (prevTraco->edgeBTI(step, 1, 2))
0412 _flag[step - DTConfigTraco::NSTEPF].set(3);
0413 if (prevTraco->edgeBTI(step, 2, 2))
0414 _flag[step - DTConfigTraco::NSTEPF].set(5);
0415 }
0416 DTTracoChip *nextTraco = _card->getTRACO(_id.traco() + 1);
0417 if (nextTraco != nullptr) {
0418 if (nextTraco->edgeBTI(step, 1, 1))
0419 _flag[step - DTConfigTraco::NSTEPF].set(4);
0420 if (nextTraco->edgeBTI(step, 2, 1))
0421 _flag[step - DTConfigTraco::NSTEPF].set(6);
0422 }
0423 } else {
0424
0425 for (int i = 0; i < 6; i++) {
0426 int ibit = ext >> i;
0427 if (ibit & 0x01)
0428 _flag[step - DTConfigTraco::NSTEPF].set(i + 1 + 2);
0429 }
0430 }
0431
0432
0433 if (config()->debug() == 4) {
0434 std::cout << "Flags set for bx=" << step << std::endl;
0435 std::cout << _flag[step - DTConfigTraco::NSTEPF].element(1) << " ";
0436 std::cout << _flag[step - DTConfigTraco::NSTEPF].element(2) << " ";
0437 std::cout << _flag[step - DTConfigTraco::NSTEPF].element(3) << " ";
0438 std::cout << _flag[step - DTConfigTraco::NSTEPF].element(4) << " ";
0439 std::cout << _flag[step - DTConfigTraco::NSTEPF].element(5) << " ";
0440 std::cout << _flag[step - DTConfigTraco::NSTEPF].element(6) << " ";
0441 std::cout << _flag[step - DTConfigTraco::NSTEPF].element(7) << " ";
0442 std::cout << _flag[step - DTConfigTraco::NSTEPF].element(8) << " ";
0443 std::cout << _flag[step - DTConfigTraco::NSTEPF].element(9) << " " << std::endl;
0444 }
0445 }
0446
0447 DTTracoCand *DTTracoChip::bestCand(int itk, std::vector<DTTracoCand> &tclist) {
0448
0449 if (tclist.empty())
0450 return nullptr;
0451
0452
0453
0454
0455 stable_sort(tclist.begin(), tclist.end());
0456 if (config()->sortKascend(itk) && !(tclist.size() == 2 && tclist[0].K() == tclist[1].K())) {
0457 reverse(tclist.begin(), tclist.end());
0458 if (config()->debug() == 4)
0459 std::cout << "Reversing order of sorted candidate list..." << std::endl;
0460 }
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471 if (config()->debug() == 4) {
0472 std::cout << "DTTracoChip::findBest - Looking for track number " << itk + 1 << std::endl;
0473 std::cout << "Sorted std::vector of usable track candidates is:" << std::endl;
0474 int i = 1;
0475 for (std::vector<DTTracoCand>::iterator p = tclist.begin(); p < tclist.end(); p++) {
0476 if ((*p).usable()) {
0477 std::cout << " DTTracoChip Candidate # " << i++;
0478 (*p).print();
0479 }
0480 }
0481 std::cout << "--------------------------------------------------" << std::endl;
0482 }
0483
0484
0485
0486 int i = 0;
0487 DTTracoCand *bestltrig = nullptr;
0488 std::vector<DTTracoCand>::iterator p;
0489 for (p = tclist.begin(); p < tclist.end(); ++p) {
0490 i++;
0491
0492 if (AdjBtiLTSuppressed(&(*p)))
0493 if (config()->debug() == 4)
0494 std::cout << "Candidate # " << i << " supp. because next to H in adiacent Tracos" << std::endl;
0495 if ((*p).usable() && !AdjBtiLTSuppressed(&(*p))) {
0496
0497 if (!config()->prefHtrig(itk))
0498 return &(*p);
0499 if ((*p).BtiTrig()->code() == 8)
0500 return &(*p);
0501 if (bestltrig == nullptr)
0502 bestltrig = &(*p);
0503 }
0504 }
0505 return bestltrig;
0506 }
0507
0508 void DTTracoChip::DoAdjBtiLts(DTTracoCand *candidate, std::vector<DTTracoCand> &tclist) {
0509
0510
0511
0512
0513 if (candidate->BtiTrig()->code() == 8) {
0514 std::vector<DTTracoCand>::iterator p;
0515 for (p = tclist.begin(); p < tclist.end(); p++) {
0516 if ((*p).BtiTrig()->code() < 8 && abs((*p).BtiTrig()->btiNumber() - candidate->BtiTrig()->btiNumber()) < 2) {
0517 (*p).setUsed();
0518 if (config()->debug() == 4) {
0519 std::cout << "Candidate :";
0520 (*p).print();
0521 std::cout << "Suppressed because adiacent to H trig" << std::endl;
0522 }
0523 }
0524 }
0525 }
0526 }
0527
0528 int DTTracoChip::AdjBtiLTSuppressed(DTTracoCand *candidate) {
0529
0530
0531
0532 if (candidate->BtiTrig()->code() < 8) {
0533 if (_flag[candidate->step() - DTConfigTraco::NSTEPF].element(3) && candidate->position() == 1)
0534 return 1;
0535 if (_flag[candidate->step() - DTConfigTraco::NSTEPF].element(4) && candidate->position() == DTConfigTraco::NBTITC)
0536 return 1;
0537 if (_flag[candidate->step() - DTConfigTraco::NSTEPF].element(5) &&
0538 candidate->position() == DTConfigTraco::NBTITC + 1)
0539 return 1;
0540 if (_flag[candidate->step() - DTConfigTraco::NSTEPF].element(6) &&
0541 candidate->position() == DTConfigTraco::NBTITC * 4)
0542 return 1;
0543 }
0544
0545 return 0;
0546 }
0547
0548 DTTracoTrig *DTTracoChip::setPV(int itk, DTTracoCand *inner, DTTracoCand *outer) {
0549
0550 if (config()->debug() == 4) {
0551 std::cout << "DTTracoChip::setPV called for candidates : " << std::endl;
0552 if (inner)
0553 inner->print();
0554 if (outer)
0555 outer->print();
0556 std::cout << "--------------------------------------------------" << std::endl;
0557 }
0558
0559
0560
0561
0562
0563 int first = (itk == 0) ? 1 : 0;
0564
0565
0566
0567
0568 DTTracoCand *candidate = nullptr;
0569 if (inner != nullptr && outer != nullptr) {
0570
0571
0572
0573 if (inner->BtiTrig()->code() == 8 && outer->BtiTrig()->code() < 8) {
0574 candidate = inner;
0575 } else if (inner->BtiTrig()->code() < 8 && outer->BtiTrig()->code() == 8) {
0576 candidate = outer;
0577 } else {
0578 if (!config()->prefInner(itk)) {
0579 candidate = inner;
0580 } else {
0581 candidate = outer;
0582 }
0583 }
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594 } else if (inner == nullptr && outer != nullptr) {
0595 candidate = outer;
0596 } else if (inner != nullptr && outer == nullptr) {
0597 candidate = inner;
0598 } else {
0599 return nullptr;
0600 }
0601
0602
0603 DTTracoTrig *tct = new DTTracoTrig(this, candidate->step());
0604
0605 int cod = candidate->BtiTrig()->code();
0606 if (candidate->BtiTrig()->btiSL() == 1)
0607 cod *= 10;
0608
0609 int K = candidate->K();
0610 if (K > 31)
0611 K -= 32;
0612 int ioflag = 0;
0613 if (candidate->position() > 4)
0614 ioflag = 1;
0615 tct->setPV(first, cod, K, ioflag);
0616
0617 if (config()->debug() == 4) {
0618 std::cout << "Selected candidate stored for preview is: ";
0619 candidate->print();
0620 }
0621 return tct;
0622 }
0623
0624 int DTTracoChip::storeCorr(DTTracoTrig *tctrig, DTTracoCand *inner, DTTracoCand *outer, int tkn) {
0625
0626 int is = tctrig->step();
0627
0628
0629 if (config()->debug() == 4) {
0630 std::cout << "DTTracoChip::storeCorr called with candidates: " << std::endl;
0631 if (inner)
0632 inner->print();
0633 if (outer)
0634 outer->print();
0635 std::cout << "--------------------------------------------------" << std::endl;
0636 }
0637
0638
0639
0640 float shift = 0.;
0641
0642 shift = (int)(_geom->distSL() / _geom->cellH() + 0.5);
0643
0644
0645
0646 int kcor = 9999;
0647 int xcor = 0;
0648 int icor = 0;
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659 int xq1 = inner->X();
0660 int xq2 = outer->X();
0661 xcor = (xq2 + xq1) / 2;
0662 kcor = (xq1 - xq2) + 512;
0663 int kq1 = int(shift / 2.) * (inner->BtiTrig()->K() - BTIC()) + 512;
0664 int kq2 = int(shift / 2.) * (outer->BtiTrig()->K() - BTIC()) + 512;
0665
0666
0667 int kd1 = abs(kcor / 16 - kq1 / 16);
0668 int kd2 = abs(kcor / 16 - kq2 / 16);
0669
0670 icor = kd1 <= config()->TcKToll(tkn) && kd2 <= config()->TcKToll(tkn) && xcor > 0;
0671
0672
0673 if (config()->debug() == 4) {
0674 std::cout << "*************************************************************";
0675 std::cout << std::endl;
0676 std::cout << " shift = " << shift;
0677 std::cout << " xq1 = " << xq1;
0678 std::cout << " xq2 = " << xq2;
0679 std::cout << " xcor = " << xcor;
0680 std::cout << " kcor = " << kcor;
0681 std::cout << " kq1 = " << kq1;
0682 std::cout << " kq2 = " << kq2;
0683 std::cout << " kd1 = " << kd1;
0684 std::cout << " kd2 = " << kd2;
0685 std::cout << " icor = " << icor;
0686 std::cout << std::endl;
0687 std::cout << "*************************************************************";
0688 std::cout << std::endl;
0689 }
0690
0691
0692
0693 if (icor) {
0694
0695
0696 tctrig->setPVCorr(1);
0697
0698 tctrig->setK(kcor - 512);
0699
0700
0701 tctrig->setX(xcor);
0702
0703 tctrig->setCodeIn(inner->BtiTrig()->code());
0704 tctrig->setCodeOut(outer->BtiTrig()->code());
0705
0706
0707
0708
0709 tctrig->setPosIn(inner->BtiTrig()->btiNumber());
0710 tctrig->setPosOut(outer->BtiTrig()->btiNumber());
0711
0712 tctrig->setEqIn(inner->BtiTrig()->eq() + 1);
0713 tctrig->setEqOut(outer->BtiTrig()->eq() + 1);
0714
0715
0716 calculateAngles(tctrig);
0717
0718
0719 if (!insideAngWindow(tctrig)) {
0720
0721 tctrig->resetVar();
0722 }
0723
0724 else if (tctrig->qdec() == 4 &&
0725 config()->TcBxLts()) {
0726
0727 if (tkn == 0 && _bxlts.element(is))
0728 tctrig->resetVar();
0729 if (tkn == 1 && _bxlts.element(is + 1))
0730 tctrig->resetVar();
0731 } else {
0732
0733 tctrig->addDTBtiTrig(inner->BtiTrig());
0734 tctrig->addDTBtiTrig(outer->BtiTrig());
0735 }
0736
0737
0738 if (config()->debug() > 1) {
0739 std::cout << "*************************************************************";
0740 std::cout << std::endl;
0741 std::cout << " Correlation was successfull: ";
0742 std::cout << std::endl;
0743 std::cout << " Code = " << tctrig->code();
0744 std::cout << " K = " << tctrig->K();
0745 std::cout << " X = " << tctrig->X();
0746 std::cout << std::endl;
0747 std::cout << "*************************************************************";
0748 std::cout << std::endl;
0749 }
0750
0751
0752 } else {
0753
0754 if (config()->debug() > 1) {
0755 std::cout << "*************************************************************";
0756 std::cout << std::endl;
0757 std::cout << " No correlation possible ";
0758 std::cout << std::endl;
0759 std::cout << "*************************************************************";
0760 std::cout << std::endl;
0761 }
0762
0763 }
0764
0765 return icor;
0766 }
0767
0768 int DTTracoChip::storeUncorr(DTTracoTrig *tctrig, DTTracoCand *inner, DTTracoCand *outer, int tkn) {
0769
0770 int is = tctrig->step();
0771
0772
0773 if (config()->debug() == 4) {
0774 std::cout << "DTTracoChip::storeUncorr called with candidates: " << std::endl;
0775 if (inner)
0776 inner->print();
0777 if (outer)
0778 outer->print();
0779 std::cout << "--------------------------------------------------" << std::endl;
0780 }
0781
0782
0783
0784
0785
0786 DTTracoCand *candidate = nullptr;
0787 if (inner != nullptr && outer != nullptr) {
0788
0789
0790
0791 if (inner->BtiTrig()->code() == 8 && outer->BtiTrig()->code() < 8) {
0792 candidate = inner;
0793
0794 } else if (inner->BtiTrig()->code() < 8 && outer->BtiTrig()->code() == 8) {
0795 candidate = outer;
0796
0797 } else {
0798 if (!config()->prefInner(tkn)) {
0799 candidate = inner;
0800
0801 } else {
0802 candidate = outer;
0803
0804 }
0805 }
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817 } else if (inner == nullptr && outer != nullptr) {
0818 candidate = outer;
0819 } else if (inner != nullptr && outer == nullptr) {
0820 candidate = inner;
0821 } else {
0822 return 0;
0823 }
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833 if (candidate->BtiTrig()->code() < 8) {
0834
0835
0836 if (config()->LVALIDIFH() && _flag[is - DTConfigTraco::NSTEPF].element(9)) {
0837 if (config()->debug() > 1)
0838 std::cout << "Low accepted because LVALIDIFH on...." << std::endl;
0839 } else {
0840
0841 if (!config()->singleLenab(tkn)) {
0842
0843 if (config()->singleLflag(tkn) == 1 ||
0844 (config()->singleLflag(tkn) == 2 && !(_card->TSTh()->nHTrig(is))) ||
0845 (config()->singleLflag(tkn) == 0 && !(_card->TSTh()->nTrig(is)))) {
0846
0847
0848
0849
0850 if (config()->debug() > 1)
0851 std::cout << "Single low trigger discarded by preview and "
0852 << "priority selector for ltmsk!" << std::endl;
0853 return 0;
0854 }
0855
0856 }
0857
0858 }
0859
0860 if (candidate == inner && config()->TcReuse(1) && outer)
0861 outer->setUnused();
0862 if (candidate == outer && config()->TcReuse(0) && inner)
0863 inner->setUnused();
0864
0865
0866 if (config()->TcBxLts()) {
0867 if ((tkn == 0 && _bxlts.element(is))
0868 || (tkn == 1 && _bxlts.element(is + 1))) {
0869 tctrig->resetVar();
0870 if (config()->debug() > 1)
0871 std::cout << "Low trigger suppressed because H in next 4 bx "
0872 << " and LTS flag on...." << std::endl;
0873 return 1;
0874 }
0875 }
0876
0877
0878 }
0879
0880
0881
0882 else {
0883
0884 if (config()->singleHflag(tkn) == 1 && !(_card->TSTh()->nTrig(is)))
0885 return 0;
0886
0887
0888
0889 if (candidate == inner && config()->TcReuse(1) && outer)
0890 outer->setUnused();
0891 if (candidate == outer && config()->TcReuse(0) && inner)
0892 inner->setUnused();
0893 }
0894
0895
0896 float shift;
0897
0898 shift = (int)(_geom->distSL() / _geom->cellH() + 0.5);
0899
0900
0901 int kucor = (int)(0.5 * shift * (candidate->BtiTrig()->K() - BTIC()));
0902 tctrig->setK(kucor);
0903 tctrig->setX(candidate->X());
0904
0905
0906 tctrig->setPVCorr(0);
0907 if (candidate->BtiTrig()->btiSL() == 1) {
0908 tctrig->setCodeIn(candidate->BtiTrig()->code());
0909 tctrig->setCodeOut(0);
0910
0911
0912 tctrig->setPosIn(candidate->BtiTrig()->btiNumber());
0913 tctrig->setPosOut(0);
0914
0915 tctrig->setEqIn(candidate->BtiTrig()->eq() + 1);
0916 tctrig->setEqOut(0);
0917 } else {
0918 tctrig->setCodeIn(0);
0919 tctrig->setCodeOut(candidate->BtiTrig()->code());
0920 tctrig->setPosIn(0);
0921
0922 tctrig->setPosOut(candidate->BtiTrig()->btiNumber());
0923
0924
0925 tctrig->setEqIn(0);
0926 tctrig->setEqOut(candidate->BtiTrig()->eq() + 1);
0927 }
0928
0929
0930
0931 calculateAngles(tctrig);
0932
0933
0934 if (!insideAngWindow(tctrig)) {
0935
0936 tctrig->resetVar();
0937 if (config()->debug() > 1)
0938 std::cout << "L rejected because outside angular window!" << std::endl;
0939 } else {
0940
0941 tctrig->addDTBtiTrig(candidate->BtiTrig());
0942 }
0943
0944
0945 if (config()->debug() > 1) {
0946 std::cout << "*************************************************************";
0947 std::cout << std::endl;
0948 std::cout << " Single trigger stored: ";
0949 std::cout << std::endl;
0950 std::cout << " Code = " << tctrig->code();
0951 std::cout << " K = " << tctrig->K();
0952 std::cout << " X = " << tctrig->X();
0953 std::cout << std::endl;
0954 std::cout << "*************************************************************";
0955 std::cout << std::endl;
0956 }
0957
0958
0959 return 1;
0960 }
0961
0962 void DTTracoChip::add_btiT(int step, int pos, const DTBtiTrigData *btitrig) {
0963 if (pos < 1 || pos > 4 * DTConfigTraco::NBTITC) {
0964 std::cout << "DTTracoChip::add_btiT: wrong position: " << pos;
0965 std::cout << "trigger not added!" << std::endl;
0966 return;
0967 }
0968 if (step < DTConfigTraco::NSTEPF || step > DTConfigTraco::NSTEPL) {
0969 std::cout << "DTTracoChip::add_btiT: step out of range: " << step;
0970 std::cout << "trigger not added!" << std::endl;
0971 return;
0972 }
0973
0974 if (!config()->usedBti(pos)) {
0975 if (config()->debug() == 4) {
0976 std::cout << "DTTracoChip::add_btiT: position: " << pos;
0977 std::cout << "has disconnected bti" << std::endl;
0978 }
0979 return;
0980 }
0981
0982
0983
0984
0985 if (_card->useAcceptParamFlag() == false) {
0986
0987 if (btitrig->K() < _PSIMIN[pos - 1] || btitrig->K() > _PSIMAX[pos - 1]) {
0988 if (config()->debug() > 1) {
0989 std::cout << "In TRACO num. " << number() << " BTI trig. in pos " << pos << " outside K acceptance (";
0990 std::cout << _PSIMIN[pos - 1] << "-->";
0991 std::cout << _PSIMAX[pos - 1] << ") - Not added" << std::endl;
0992 }
0993 return;
0994 }
0995 }
0996
0997
0998 if (pos <= DTConfigTraco::NBTITC) {
0999 _innerCand[step - DTConfigTraco::NSTEPF].push_back(DTTracoCand(this, btitrig, pos, step));
1000 } else {
1001 _outerCand[step - DTConfigTraco::NSTEPF].push_back(DTTracoCand(this, btitrig, pos, step));
1002 }
1003
1004
1005 if (btitrig->code() == 8) {
1006 for (int is = step - 4; is < step; is++) {
1007 if (is > 0 && is <= DTConfigTraco::NSTEPL)
1008 _bxlts.set(is);
1009 }
1010
1011 _bxlts.set(step + 1);
1012
1013 if (config()->debug() == 4)
1014 for (int is = 0; is < DTConfigTraco::NSTEPL; is++)
1015 std::cout << "_bxlts[" << is << "]=" << _bxlts.element(is) << std::endl;
1016 }
1017
1018
1019 if (config()->debug() > 1) {
1020 std::cout << "BTI Trigger added at step " << step;
1021 std::cout << " to TRACO " << _id.traco() << " at position " << pos << std::endl;
1022 btitrig->print();
1023 }
1024 }
1025
1026 void DTTracoChip::addTrig(int step, DTTracoTrig *tctrig) {
1027 if (step < DTConfigTraco::NSTEPF || step > DTConfigTraco::NSTEPL) {
1028 std::cout << "DTTracoChip::addTrig: step out of range: " << step;
1029 std::cout << " trigger not added!" << std::endl;
1030 return;
1031 }
1032 _tracotrig[step - DTConfigTraco::NSTEPF].push_back(tctrig);
1033
1034
1035
1036 if (config()->debug() == 4) {
1037 std::cout << "DTTracoChip::addTrig: adding trigger:" << std::endl;
1038 tctrig->print();
1039 }
1040
1041 }
1042
1043 int DTTracoChip::nTrig(int step) const {
1044 if (step < DTConfigTraco::NSTEPF || step > DTConfigTraco::NSTEPL) {
1045 std::cout << "DTTracoChip::nTrig: step out of range: " << step;
1046 std::cout << " 0 returned!" << std::endl;
1047 return 0;
1048 }
1049 return _tracotrig[step - DTConfigTraco::NSTEPF].size();
1050 }
1051
1052 DTTracoTrig *DTTracoChip::trigger(int step, unsigned n) const {
1053 if (step < DTConfigTraco::NSTEPF || step > DTConfigTraco::NSTEPL) {
1054 std::cout << "DTTracoChip::trigger: step out of range: " << step;
1055 std::cout << " empty pointer returned!" << std::endl;
1056 return nullptr;
1057 }
1058 if (n < 1 || n > _tracotrig[step - DTConfigTraco::NSTEPF].size()) {
1059 std::cout << "DTTracoChip::trigger: requested trigger doesn't exist: " << n;
1060 std::cout << " empty pointer returned!" << std::endl;
1061 return nullptr;
1062 }
1063 std::vector<DTTracoTrig *>::const_iterator p = _tracotrig[step - DTConfigTraco::NSTEPF].begin() + n - 1;
1064 return *p;
1065 }
1066
1067 DTTracoTrigData DTTracoChip::triggerData(int step, unsigned n) const {
1068 if (step < DTConfigTraco::NSTEPF || step > DTConfigTraco::NSTEPL) {
1069 std::cout << "DTTracoChip::triggerData: step out of range: " << step;
1070 std::cout << " dummy trigger returned!" << std::endl;
1071 return DTTracoTrigData();
1072 }
1073 if (n < 1 || n > _tracotrig[step - DTConfigTraco::NSTEPF].size()) {
1074 std::cout << "DTTracoChip::trigger: requested trigger doesn't exist: " << n;
1075 std::cout << " dummy trigger returned!" << std::endl;
1076 return DTTracoTrigData();
1077 }
1078 std::vector<DTTracoTrig *>::const_iterator p = _tracotrig[step - DTConfigTraco::NSTEPF].begin() + n - 1;
1079 return (*p)->data();
1080 }
1081
1082 float DTTracoChip::psiRad(int sl) const {
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100 return 0.0;
1101 }
1102
1103 int DTTracoChip::KRad() const {
1104
1105
1106
1107
1108
1109
1110 int KRad = 0;
1111 return KRad;
1112 }
1113
1114 int DTTracoChip::useSecondTrack(int step) const {
1115
1116
1117 if (step < DTConfigTraco::NSTEPF || step > DTConfigTraco::NSTEPL) {
1118 std::cout << "DTTracoChip::useSecondTrack: step out of range: " << step;
1119 std::cout << " 0 returned!" << std::endl;
1120 return 0;
1121 }
1122 return !(_flag[step - DTConfigTraco::NSTEPF].element(2));
1123 }
1124
1125 int DTTracoChip::edgeBTI(int step, int io, int lr) const {
1126 if (step < DTConfigTraco::NSTEPF || step > DTConfigTraco::NSTEPL) {
1127 std::cout << "DTTracoChip::edgeBTI: step out of range: " << step;
1128 std::cout << " 0 returned!" << std::endl;
1129 return 0;
1130 }
1131
1132
1133
1134
1135 std::vector<DTTracoCand>::const_iterator p;
1136 if (io == 1) {
1137 if (!_innerCand[step - DTConfigTraco::NSTEPF].empty()) {
1138
1139 for (p = _innerCand[step - DTConfigTraco::NSTEPF].begin(); p < _innerCand[step - DTConfigTraco::NSTEPF].end();
1140 p++) {
1141 if (lr == 1 && (*p).position() == 1 && (*p).BtiTrig()->code() == 8)
1142 return 1;
1143 if (lr == 2 && (*p).position() == DTConfigTraco::NBTITC && (*p).BtiTrig()->code() == 8)
1144 return 1;
1145 }
1146 }
1147 } else {
1148 if (!_outerCand[step - DTConfigTraco::NSTEPF].empty()) {
1149 for (p = _outerCand[step - DTConfigTraco::NSTEPF].begin(); p < _outerCand[step - DTConfigTraco::NSTEPF].end();
1150 p++) {
1151
1152
1153
1154
1155
1156 if (lr == 1 && (*p).position() == DTConfigTraco::NBTITC * 3 + 1 && (*p).BtiTrig()->code() == 8)
1157 return 1;
1158 if (lr == 2 && (*p).position() == DTConfigTraco::NBTITC * 2 && (*p).BtiTrig()->code() == 8)
1159 return 1;
1160 }
1161 }
1162 }
1163 return 0;
1164 }
1165
1166 void DTTracoChip::calculateAngles(DTTracoTrig *tct) {
1167 int ipsi = 0;
1168 int iphir = 0;
1169 int idpsir = 0;
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208 if (_card->lutFromDBFlag() == 1) {
1209 ipsi = _lutsCCB->get_k((tct->K() + 512));
1210
1211 int flag = 0;
1212 int qual = tct->data().qdec();
1213 if (qual == 3 || qual == 1)
1214 flag = 0;
1215 if (qual == 2 || qual == 0)
1216 flag = 1;
1217 if (qual == 6 || qual == 5 || qual == 4)
1218 flag = 2;
1219
1220 iphir = _lutsCCB->get_x((tct->X() + 512 * flag));
1221
1222 idpsir = ipsi - iphir / 8;
1223 } else
1224
1225
1226 {
1227 DTTracoTrigData td = tct->data();
1228
1229
1230
1231 float fpsi = atan(_card->localDirection(&td).x() /
1232 _card->localDirection(&td).z());
1233
1234
1235 int mywh = tct->ChamberId().wheel();
1236 if (mywh < 0 || (mywh == 0 && (tct->ChamberId().sector() % 4) < 2))
1237 fpsi = -fpsi;
1238
1239 fpsi *= DTConfigTraco::RESOLPSI;
1240 if (fpsi <= 0)
1241 fpsi -= 1.0;
1242 ipsi = (int)fpsi;
1243
1244 if (ipsi >= DTConfigTraco::RESOLPSI || ipsi < -DTConfigTraco::RESOLPSI)
1245 ipsi = -DTConfigTraco::RESOLPSI;
1246
1247
1248 float fpsir = _card->CMSPosition(&td).phi() - _geom->phiCh();
1249
1250 if (fpsir < -M_PI)
1251 fpsir += M_PI * 2;
1252 if (fpsir > M_PI)
1253 fpsir -= M_PI * 2;
1254 fpsir *= DTConfigTraco::RESOLPSIR;
1255 if (fpsir <= 0)
1256 fpsir -= 1.0;
1257 iphir = (int)fpsir;
1258
1259 if (iphir >= DTConfigTraco::RESOLPSIR / 2 || iphir < -DTConfigTraco::RESOLPSIR / 2)
1260 iphir = -DTConfigTraco::RESOLPSIR / 2;
1261
1262
1263 int dpsir = (iphir * DTConfigTraco::RESOLPSI) / DTConfigTraco::RESOLPSIR;
1264 idpsir = ipsi - dpsir;
1265
1266 if (idpsir >= DTConfigTraco::RESOLPSI || idpsir < -DTConfigTraco::RESOLPSI)
1267 idpsir = -DTConfigTraco::RESOLPSI;
1268 }
1269
1270 tct->setAngles(ipsi, iphir, idpsir);
1271
1272
1273 if (config()->debug() == 4) {
1274 std::cout << "DTTracoChip::calculateAngles :" << std::endl;
1275 tct->print();
1276 std::cout << std::dec << "K = " << tct->K() << " X = " << tct->X();
1277 std::cout << " ipsi = " << ipsi << " iphir = " << iphir;
1278 std::cout << " idpsir = " << idpsir << std::endl;
1279 if (_card->lutFromDBFlag() == 1)
1280 std::cout << "Angles are calculated from LUT parameters from DB!" << std::endl;
1281 }
1282 }
1283
1284 int DTTracoChip::insideAngWindow(DTTracoTrig *tctrig) const {
1285
1286
1287
1288
1289 BitArray<10> bendAng;
1290 bendAng.assign(0, 10, tctrig->DeltaPsiR());
1291
1292 if (bendAng.element(9))
1293 bendAng.twoComplement();
1294 int bendAngINT = bendAng.read(0, 9);
1295
1296
1297 if (config()->BendingAngleCut() != -1 && bendAngINT > 2 * (config()->BendingAngleCut())) {
1298 int absBendAng = tctrig->DeltaPsiR() & 0x1FF;
1299 if (config()->debug() == 4)
1300 std::cout << "Attention: abs(bendAng)=" << absBendAng << " > " << 2 * config()->BendingAngleCut()
1301 << "!! reject trigger" << std::endl;
1302 return 0;
1303 }
1304 return 1;
1305 }
1306
1307 void DTTracoChip::setTracoAcceptances() {
1308
1309 float h = _geom->cellH();
1310 float pitch = _geom->cellPitch();
1311 float distsl = _geom->distSL();
1312 float K0 = config()->BTIC();
1313 float shiftSL = _geom->phiSLOffset() / pitch * K0;
1314
1315
1316
1317 {
1318
1319 int i = 0;
1320 for (i = 0; i < DTConfig::NBTITC; i++) {
1321 float Xin_min = (i + DTConfig::NBTITC) * K0 + shiftSL;
1322 float Xin_max = Xin_min + K0;
1323 float Xout_min = 0;
1324 float Xout_max = 3 * DTConfig::NBTITC * K0;
1325 _PSIMAX[i] = int(2. * h / distsl * (Xin_max - Xout_min) + K0 + 1.01);
1326 _PSIMIN[i] = int(2. * h / distsl * (Xin_min - Xout_max) + K0);
1327 }
1328
1329
1330 for (i = 0; i < 3 * DTConfig::NBTITC; i++) {
1331 float Xin_min = (DTConfig::NBTITC)*K0 + shiftSL;
1332 float Xin_max = 2. * DTConfig::NBTITC * K0 + shiftSL;
1333 float Xout_min = i * K0;
1334 float Xout_max = Xout_min + K0;
1335 _PSIMAX[DTConfig::NBTITC + i] = int(2. * h / distsl * (Xin_max - Xout_min) + K0 + 1.01);
1336 _PSIMIN[DTConfig::NBTITC + i] = int(2. * h / distsl * (Xin_min - Xout_max) + K0);
1337 }
1338 }
1339
1340
1341 if (config()->debug() == 4) {
1342
1343 std::cout << "Acceptance of mt ports for offset (cell unit) " << _geom->phiSLOffset() / pitch << std::endl;
1344 for (int i = 0; i < 4 * DTConfig::NBTITC; i++) {
1345 std::cout << "Port " << i + 1 << " : ";
1346 std::cout << _PSIMIN[i] << " --> " << _PSIMAX[i] << std::endl;
1347 }
1348
1349 }
1350 }